Skip to content

Tag top-level bindings even when optimizations are disabled

One complication in implementing top-level unlifted bindings (#23637) concerns missing tags on imported bindings. For example if we have this Core:

b :: B Bool
b = B a

Where B :: Type -> UnliftedType and a :: Bool. Currently, if a is imported from a module that has been compiled with optimizations disabled then this Stg tag inference will rewrite b to:

b :: B Bool = \r [] case a of a_tCP { __DEFAULT -> B [a_tCP]; };

Which means b is not fully evaluated, but it is also unlifted so there is no thunk that can postpone that evaluation. This is a problem.

To avoid this, SPJ proposes a new invariant:

All toplevel values are properly tagged, so that x will never be eval'd by the STG-rewrite pass.

This can be done cheaply, so it shouldn't add that much extra time and space usage to unoptimized builds.

However, we should still be careful. @simonmar warned that exporting more information in interface files can cause more recompilation:

Similar arguments about recompilation apply to LFInfo - we should be careful to minimize the impact this might have on recompilation. So long as we only expose the tag I think we should be OK, the only impact will be changing something from a constructor to non-constructor or vice-versa while keeping its type unchanged, which I imagine is rare.

SPJ also suggested that @clyring might have already done some work in this direction. Is that right?

Edited by Jaro Reinders
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information