[GHC] #14283: Remove the special case for tagToEnum# in the code generator?

#14283: Remove the special case for tagToEnum# in the code generator? -------------------------------------+------------------------------------- Reporter: dfeuer | Owner: (none) Type: task | Status: new Priority: normal | Milestone: 8.4.1 Component: Compiler | Version: 8.2.1 Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: None/Unknown Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- The only remaining primop (aside from `unsafeCoerce#` and `seq`) that produces an enumeration type is `tagToEnum#`. There is some magic in the code generator to make garbage collection relating to this work as it has historically. We want to get rid of the special case. Simply removing it altogether actually does seem to work, but the code we generate likely isn't quite the same. The challenge here is that (despite what I thought earlier) we definitely ''can'' end up in code generation, under certain circumstances, with {{{#!hs case tagToEnum# @t x of ... }}} How does this happen? After all, in `caseRules` we carefully remove every case on `tagToEnum#` and `dataToTag#` applications! The trouble comes when CorePrep puts everything in A-normal form. Strict function applications are transformed into `case` forms, so {{{#!hs f (tagToEnum# x) }}} will become {{{#!hs case tagToEnum# x of y DEFAULT -> f y }}} Suddenly we have that ugly case! Hmph. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14283 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14283: Remove the special case for tagToEnum# in the code generator? -------------------------------------+------------------------------------- Reporter: dfeuer | Owner: (none) Type: task | Status: new Priority: normal | Milestone: 8.4.1 Component: Compiler | Version: 8.2.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Description changed by dfeuer: Old description:
The only remaining primop (aside from `unsafeCoerce#` and `seq`) that produces an enumeration type is `tagToEnum#`. There is some magic in the code generator to make garbage collection relating to this work as it has historically. We want to get rid of the special case. Simply removing it altogether actually does seem to work, but the code we generate likely isn't quite the same. The challenge here is that (despite what I thought earlier) we definitely ''can'' end up in code generation, under certain circumstances, with
{{{#!hs case tagToEnum# @t x of ... }}}
How does this happen? After all, in `caseRules` we carefully remove every case on `tagToEnum#` and `dataToTag#` applications! The trouble comes when CorePrep puts everything in A-normal form. Strict function applications are transformed into `case` forms, so
{{{#!hs f (tagToEnum# x) }}}
will become
{{{#!hs case tagToEnum# x of y DEFAULT -> f y }}}
Suddenly we have that ugly case! Hmph.
New description: The only remaining primop (aside from `unsafeCoerce#` and `seq`) that produces an enumeration type is `tagToEnum#`. There is some magic in the code generator to make garbage collection relating to this work as it has historically. We want to get rid of the special case. Simply removing it altogether actually does seem to work (in that CI doesn't complain, see Phab:D3980, although I don't yet know why), but the code we generate likely isn't quite the same. The challenge here is that (despite what I thought earlier) we definitely ''can'' end up in code generation, under certain circumstances, with {{{#!hs case tagToEnum# @t x of ... }}} How does this happen? After all, in `caseRules` we carefully remove every case on `tagToEnum#` and `dataToTag#` applications! The trouble comes when CorePrep puts everything in A-normal form. Strict function applications are transformed into `case` forms, so {{{#!hs f (tagToEnum# x) }}} will become {{{#!hs case tagToEnum# x of y DEFAULT -> f y }}} Suddenly we have that ugly case! Hmph. -- -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14283#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

The only remaining primop (aside from unsafeCoerce# and seq) that
#14283: Remove the special case for tagToEnum# in the code generator? -------------------------------------+------------------------------------- Reporter: dfeuer | Owner: (none) Type: task | Status: new Priority: normal | Milestone: 8.4.1 Component: Compiler | Version: 8.2.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by simonpj): produces an enumeration type is tagToEnum#. There is some magic in the code generator to make garbage collection relating to this work as it has historically. What/where is the magic you want to remove? I think it might be {{{ cgCase (StgOpApp (StgPrimOp op) args _) bndr (AlgAlt tycon) alts | isEnumerationTyCon tycon -- Note [case on bool] = do { tag_expr <- do_enum_primop op args -- If the binder is not dead, convert the tag to a constructor -- and assign it. ; unless (isDeadBinder bndr) $ do { dflags <- getDynFlags ; tmp_reg <- bindArgToReg (NonVoid bndr) ; emitAssign (CmmLocal tmp_reg) (tagToClosure dflags tycon tag_expr) } ; (mb_deflt, branches) <- cgAlgAltRhss (NoGcInAlts,AssignedDirectly) (NonVoid bndr) alts -- See Note [GC for conditionals] ; emitSwitch tag_expr branches mb_deflt 0 (tyConFamilySize tycon - 1) ; return AssignedDirectly } where do_enum_primop :: PrimOp -> [StgArg] -> FCode CmmExpr do_enum_primop TagToEnumOp [arg] -- No code! = getArgAmode (NonVoid arg) do_enum_primop primop args = do dflags <- getDynFlags tmp <- newTemp (bWord dflags) cgPrimOp [tmp] primop args return (CmmReg (CmmLocal tmp)) }}} in `StgCmmExpr`. Right? If so, what is the effect of just removing it? Why is it bad to have {{{ case tagToEnum# x of y DEFAULT -> f y }}} ? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14283#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14283: Remove the special case for tagToEnum# in the code generator? -------------------------------------+------------------------------------- Reporter: dfeuer | Owner: (none) Type: task | Status: infoneeded Priority: normal | Milestone: 8.6.1 Component: Compiler | Version: 8.2.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by bgamari): * status: new => infoneeded Comment: David, perhaps you could summarise what you meant here? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14283#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC