diff options
author | dias@cs.tufts.edu <unknown> | 2009-12-17 21:04:43 +0000 |
---|---|---|
committer | dias@cs.tufts.edu <unknown> | 2009-12-17 21:04:43 +0000 |
commit | bfb346895846c5b79ecfb1e7503815146b8a4071 (patch) | |
tree | 6f9507bc0d537cb43fb388ba9accf88ecca33e09 /compiler/codeGen/StgCmmExpr.hs | |
parent | 0417404f5d1230c9d291ea9f73e2831121c8ec99 (diff) | |
download | haskell-bfb346895846c5b79ecfb1e7503815146b8a4071.tar.gz |
missed a case in a previous fix
Here's the obscure problem:
-- However, we also want to allow an assignment to be generated
-- in the case when the types are compatible, because this allows
-- some slightly-dodgy but occasionally-useful casts to be used,
-- such as in RtClosureInspect where we cast an HValue to a MutVar#
-- so we can print out the contents of the MutVar#. If we generate
-- code that enters the HValue, then we'll get a runtime panic, because
-- the HValue really is a MutVar#. The types are compatible though,
-- so we can just generate an assignment.
Diffstat (limited to 'compiler/codeGen/StgCmmExpr.hs')
-rw-r--r-- | compiler/codeGen/StgCmmExpr.hs | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/compiler/codeGen/StgCmmExpr.hs b/compiler/codeGen/StgCmmExpr.hs index 0c958b3805..28c74427b0 100644 --- a/compiler/codeGen/StgCmmExpr.hs +++ b/compiler/codeGen/StgCmmExpr.hs @@ -292,19 +292,41 @@ cgCase (OpApp ) bndr srt AlgAlt [(DataAlt flase, a2] -- The Sequel is a type-correct assignment, albeit bogus. -- The (dead) continuation loops; it would be better to invoke some kind -- of panic function here. + -- + -- However, we also want to allow an assignment to be generated + -- in the case when the types are compatible, because this allows + -- some slightly-dodgy but occasionally-useful casts to be used, + -- such as in RtClosureInspect where we cast an HValue to a MutVar# + -- so we can print out the contents of the MutVar#. If we generate + -- code that enters the HValue, then we'll get a runtime panic, because + -- the HValue really is a MutVar#. The types are compatible though, + -- so we can just generate an assignment. +cgCase scrut@(StgApp v []) bndr _ alt_type@(PrimAlt _) alts + | isUnLiftedType (idType v) + || reps_compatible + = -- assignment instruction suffices for unlifted types + do { v_info <- getCgIdInfo v + ; emit $ mkComment $ mkFastString "New case:" + ; emit (mkAssign (CmmLocal (idToReg (NonVoid bndr))) (idInfoToAmode v_info)) + ; _ <- bindArgsToRegs [NonVoid bndr] + ; cgAlts NoGcInAlts (NonVoid bndr) alt_type alts } + where + reps_compatible = idCgRep v == idCgRep bndr + cgCase scrut@(StgApp v []) bndr _ (PrimAlt _) _ - | not (isUnLiftedType (idType v)) && reps_incompatible - = + | lifted + = -- fail at run-time, not compile-time do { mb_cc <- maybeSaveCostCentre True ; withSequel (AssignTo [idToReg (NonVoid v)] False) (cgExpr scrut) ; restoreCurrentCostCentre mb_cc ; emit $ mkComment $ mkFastString "should be unreachable code" ; emit $ withFreshLabel "l" (\l -> mkLabel l <*> mkBranch l)} where - reps_incompatible = idCgRep v /= idCgRep bndr + lifted = not (isUnLiftedType (idType v)) cgCase scrut bndr srt alt_type alts - = do { up_hp_usg <- getVirtHp -- Upstream heap usage + = -- the general case + do { up_hp_usg <- getVirtHp -- Upstream heap usage ; let ret_bndrs = chooseReturnBndrs bndr alt_type alts alt_regs = map idToReg ret_bndrs simple_scrut = isSimpleScrut scrut alt_type |