Skip to content

CorePrep does not actually freshen all local Ids

Item (6) of Note [CorePrep overview] says

6.  Clone all local Ids.
    This means that all such Ids are unique, rather than the
    weaker guarantee of no clashes which the simplifier provides.
    And that is what the code generator needs.

    We don't clone TyVars or CoVars. The code gen doesn't need that,
    and doing so would be tiresome because then we'd need
    to substitute in types and coercions.

But that doesn't really appear to be true. For one, !9089 exposed a bug, where we get code like this (prior to, and) after CorePrep

let go_123 x y = joinrec go_123 x y = ... in jump go_123 x y;
in ... go_123 ...

The joinrec-bound unique should have been cloned, but isn't. At first I thought it was simple to fix, because the NonRec case of cpeBind eagerly clones the binder but passes down the unaltered CpeEnv to cpePair:

  = do { (env1, bndr1) <- cpCloneBndr env bndr
       ; let dmd         = idDemandInfo bndr
             is_unlifted = isUnliftedType (idType bndr)
       ; (floats, rhs1) <- cpePair top_lvl NonRecursive
                                   dmd is_unlifted
                                   env bndr1 rhs

Note how line 1 clones the binder, but passes the unextended env to cpePair in line 6.

Instead cloning should happen after the call to cpePair, because bndr is not in scope until then. (I tried the alternative of simply passing down env1 which didn't work either.)

But while implementing the fix, I noticed that we don't get back any in-scope information from cpePair! That means that a program like the following will not clone the inner j_1:

let f x = let j_1 x = ... in j_1 42
    g x = let j_1 x = ... in j_1 64
in ...

because when cloning inside g we will have forgotten that we've seen j_1 in f.

CorePrep only seems to guarantee there is no shadowing, not that Ids are globally unique! But the latter is what CodeGen needs, and I think StgCSE assumes global uniqueness, too. At least it seems to be responsible for the strange reuse of the label .LX0 in !9089.

Puzzling. Did I miss something?

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