X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2Fcmm%2FCmmOpt.hs;h=aa0c82180905adc0971446f68d5f9e92a5139f01;hb=207802589da0d23c3f16195f453b24a1e46e322d;hp=eba96531f3253131c153ee468b0c8baa7324f14f;hpb=d5c5c4eb1d9f6d382d3ef1a12be284a411451788;p=ghc-hetmet.git diff --git a/compiler/cmm/CmmOpt.hs b/compiler/cmm/CmmOpt.hs index eba9653..aa0c821 100644 --- a/compiler/cmm/CmmOpt.hs +++ b/compiler/cmm/CmmOpt.hs @@ -93,7 +93,7 @@ cmmMiniInline blocks = map do_inline blocks cmmMiniInlineStmts :: UniqFM Int -> [CmmStmt] -> [CmmStmt] cmmMiniInlineStmts uses [] = [] -cmmMiniInlineStmts uses (stmt@(CmmAssign (CmmLocal (LocalReg u _)) expr) : stmts) +cmmMiniInlineStmts uses (stmt@(CmmAssign (CmmLocal (LocalReg u _ _)) expr) : stmts) | Just 1 <- lookupUFM uses u, Just stmts' <- lookForInline u expr stmts = @@ -109,7 +109,7 @@ cmmMiniInlineStmts uses (stmt:stmts) -- Try to inline a temporary assignment. We can skip over assignments to -- other tempoararies, because we know that expressions aren't side-effecting -- and temporaries are single-assignment. -lookForInline u expr (stmt@(CmmAssign (CmmLocal (LocalReg u' _)) rhs) : rest) +lookForInline u expr (stmt@(CmmAssign (CmmLocal (LocalReg u' _ _)) rhs) : rest) | u /= u' = case lookupUFM (getExprUses rhs) u of Just 1 -> Just (inlineStmt u expr stmt : rest) @@ -140,7 +140,7 @@ lookForInline u expr (stmt:stmts) getStmtUses :: CmmStmt -> UniqFM Int getStmtUses (CmmAssign _ e) = getExprUses e getStmtUses (CmmStore e1 e2) = plusUFM_C (+) (getExprUses e1) (getExprUses e2) -getStmtUses (CmmCall target _ es _) +getStmtUses (CmmCall target _ es) = plusUFM_C (+) (uses target) (getExprsUses (map fst es)) where uses (CmmForeignCall e _) = getExprUses e uses _ = emptyUFM @@ -150,8 +150,8 @@ getStmtUses (CmmJump e _) = getExprUses e getStmtUses _ = emptyUFM getExprUses :: CmmExpr -> UniqFM Int -getExprUses (CmmReg (CmmLocal (LocalReg u _))) = unitUFM u 1 -getExprUses (CmmRegOff (CmmLocal (LocalReg u _)) _) = unitUFM u 1 +getExprUses (CmmReg (CmmLocal (LocalReg u _ _))) = unitUFM u 1 +getExprUses (CmmRegOff (CmmLocal (LocalReg u _ _)) _) = unitUFM u 1 getExprUses (CmmLoad e _) = getExprUses e getExprUses (CmmMachOp _ es) = getExprsUses es getExprUses _other = emptyUFM @@ -161,8 +161,8 @@ getExprsUses es = foldr (plusUFM_C (+)) emptyUFM (map getExprUses es) inlineStmt :: Unique -> CmmExpr -> CmmStmt -> CmmStmt inlineStmt u a (CmmAssign r e) = CmmAssign r (inlineExpr u a e) inlineStmt u a (CmmStore e1 e2) = CmmStore (inlineExpr u a e1) (inlineExpr u a e2) -inlineStmt u a (CmmCall target regs es vols) - = CmmCall (infn target) regs es' vols +inlineStmt u a (CmmCall target regs es) + = CmmCall (infn target) regs es' where infn (CmmForeignCall fn cconv) = CmmForeignCall fn cconv infn (CmmPrim p) = CmmPrim p es' = [ (inlineExpr u a e, hint) | (e,hint) <- es ] @@ -172,10 +172,10 @@ inlineStmt u a (CmmJump e d) = CmmJump (inlineExpr u a e) d inlineStmt u a other_stmt = other_stmt inlineExpr :: Unique -> CmmExpr -> CmmExpr -> CmmExpr -inlineExpr u a e@(CmmReg (CmmLocal (LocalReg u' _))) +inlineExpr u a e@(CmmReg (CmmLocal (LocalReg u' _ _))) | u == u' = a | otherwise = e -inlineExpr u a e@(CmmRegOff (CmmLocal (LocalReg u' rep)) off) +inlineExpr u a e@(CmmRegOff (CmmLocal (LocalReg u' rep _)) off) | u == u' = CmmMachOp (MO_Add rep) [a, CmmLit (CmmInt (fromIntegral off) rep)] | otherwise = e inlineExpr u a (CmmLoad e rep) = CmmLoad (inlineExpr u a e) rep @@ -339,6 +339,38 @@ cmmMachOpFold (MO_Add _) [CmmLit (CmmInt i rep), CmmLit (CmmLabel lbl)] cmmMachOpFold (MO_Sub _) [CmmLit (CmmLabel lbl), CmmLit (CmmInt i rep)] = CmmLit (CmmLabelOff lbl (fromIntegral (negate (narrowU rep i)))) + +-- Comparison of literal with narrowed/widened operand: perform +-- the comparison at a different width, as long as the literal is +-- within range. + +#if i386_TARGET_ARCH || x86_64_TARGET_ARCH +-- powerPC NCG has a TODO for I8/I16 comparisons, so don't try + +cmmMachOpFold cmp [CmmMachOp conv [x], CmmLit (CmmInt i _)] + | Just (rep, narrow) <- maybe_conversion conv, + Just narrow_cmp <- maybe_comparison cmp rep, + let narrow_i = narrow rep i, + narrow_i == i + = cmmMachOpFold narrow_cmp [x, CmmLit (CmmInt narrow_i rep)] + where + maybe_conversion (MO_U_Conv from _) = Just (from, narrowU) + maybe_conversion (MO_S_Conv from _) = Just (from, narrowS) + maybe_conversion _ = Nothing + + maybe_comparison (MO_U_Gt _) rep = Just (MO_U_Gt rep) + maybe_comparison (MO_U_Ge _) rep = Just (MO_U_Ge rep) + maybe_comparison (MO_U_Lt _) rep = Just (MO_U_Lt rep) + maybe_comparison (MO_U_Le _) rep = Just (MO_U_Le rep) + maybe_comparison (MO_S_Gt _) rep = Just (MO_S_Gt rep) + maybe_comparison (MO_S_Ge _) rep = Just (MO_S_Ge rep) + maybe_comparison (MO_S_Lt _) rep = Just (MO_S_Lt rep) + maybe_comparison (MO_S_Le _) rep = Just (MO_S_Le rep) + maybe_comparison (MO_Eq _) rep = Just (MO_Eq rep) + maybe_comparison _ _ = Nothing + +#endif + -- We can often do something with constants of 0 and 1 ... cmmMachOpFold mop args@[x, y@(CmmLit (CmmInt 0 _))]