Commit d09e2b76 authored by Ian Lynagh's avatar Ian Lynagh

Finish de-CPPing CmmOpt.hs

parent 5fc9ac61
......@@ -198,7 +198,7 @@ cmmMiniInlineStmts platform uses (stmt@(CmmAssign (CmmLocal (LocalReg u _)) expr
ncgDebugTrace ("nativeGen: inlining " ++ showSDoc (pprStmt platform stmt)) $
cmmMiniInlineStmts platform uses stmts'
where
foldExp (CmmMachOp op args) = cmmMachOpFold op args
foldExp (CmmMachOp op args) = cmmMachOpFold platform op args
foldExp e = e
ncgDebugTrace str x = if ncgDebugIsOn then trace str x else x
......@@ -305,20 +305,22 @@ inlineExpr u a other_expr = other_expr
-- been optimized and folded.
cmmMachOpFold
:: MachOp -- The operation from an CmmMachOp
:: Platform
-> MachOp -- The operation from an CmmMachOp
-> [CmmExpr] -- The optimized arguments
-> CmmExpr
cmmMachOpFold op args = fromMaybe (CmmMachOp op args) (cmmMachOpFoldM op args)
cmmMachOpFold platform op args = fromMaybe (CmmMachOp op args) (cmmMachOpFoldM platform op args)
-- Returns Nothing if no changes, useful for Hoopl, also reduces
-- allocation!
cmmMachOpFoldM
:: MachOp
:: Platform
-> MachOp
-> [CmmExpr]
-> Maybe CmmExpr
cmmMachOpFoldM op arg@[CmmLit (CmmInt x rep)]
cmmMachOpFoldM _ op arg@[CmmLit (CmmInt x rep)]
= Just $ case op of
MO_S_Neg r -> CmmLit (CmmInt (-x) rep)
MO_Not r -> CmmLit (CmmInt (complement x) rep)
......@@ -335,11 +337,11 @@ cmmMachOpFoldM op arg@[CmmLit (CmmInt x rep)]
-- Eliminate conversion NOPs
cmmMachOpFoldM (MO_SS_Conv rep1 rep2) [x] | rep1 == rep2 = Just x
cmmMachOpFoldM (MO_UU_Conv rep1 rep2) [x] | rep1 == rep2 = Just x
cmmMachOpFoldM _ (MO_SS_Conv rep1 rep2) [x] | rep1 == rep2 = Just x
cmmMachOpFoldM _ (MO_UU_Conv rep1 rep2) [x] | rep1 == rep2 = Just x
-- Eliminate nested conversions where possible
cmmMachOpFoldM conv_outer args@[CmmMachOp conv_inner [x]]
cmmMachOpFoldM platform conv_outer args@[CmmMachOp conv_inner [x]]
| Just (rep1,rep2,signed1) <- isIntConversion conv_inner,
Just (_, rep3,signed2) <- isIntConversion conv_outer
= case () of
......@@ -349,13 +351,13 @@ cmmMachOpFoldM conv_outer args@[CmmMachOp conv_inner [x]]
-- but remember to use the signedness from the widening, just in case
-- the final conversion is a widen.
| rep1 < rep2 && rep2 > rep3 ->
Just $ cmmMachOpFold (intconv signed1 rep1 rep3) [x]
Just $ cmmMachOpFold platform (intconv signed1 rep1 rep3) [x]
-- Nested widenings: collapse if the signedness is the same
| rep1 < rep2 && rep2 < rep3 && signed1 == signed2 ->
Just $ cmmMachOpFold (intconv signed1 rep1 rep3) [x]
Just $ cmmMachOpFold platform (intconv signed1 rep1 rep3) [x]
-- Nested narrowings: collapse
| rep1 > rep2 && rep2 > rep3 ->
Just $ cmmMachOpFold (MO_UU_Conv rep1 rep3) [x]
Just $ cmmMachOpFold platform (MO_UU_Conv rep1 rep3) [x]
| otherwise ->
Nothing
where
......@@ -372,7 +374,7 @@ cmmMachOpFoldM conv_outer args@[CmmMachOp conv_inner [x]]
-- but what if the architecture only supports word-sized loads, should
-- we do the transformation anyway?
cmmMachOpFoldM mop args@[CmmLit (CmmInt x xrep), CmmLit (CmmInt y _)]
cmmMachOpFoldM _ mop args@[CmmLit (CmmInt x xrep), CmmLit (CmmInt y _)]
= case mop of
-- for comparisons: don't forget to narrow the arguments before
-- comparing, since they might be out of range.
......@@ -419,9 +421,9 @@ cmmMachOpFoldM mop args@[CmmLit (CmmInt x xrep), CmmLit (CmmInt y _)]
-- also assume that constants have been shifted to the right when
-- possible.
cmmMachOpFoldM op [x@(CmmLit _), y]
cmmMachOpFoldM platform op [x@(CmmLit _), y]
| not (isLit y) && isCommutableMachOp op
= Just (cmmMachOpFold op [y, x])
= Just (cmmMachOpFold platform op [y, x])
-- Turn (a+b)+c into a+(b+c) where possible. Because literals are
-- moved to the right, it is more likely that we will find
......@@ -439,37 +441,37 @@ cmmMachOpFoldM op [x@(CmmLit _), y]
-- Also don't do it if arg1 is PicBaseReg, so that we don't separate the
-- PicBaseReg from the corresponding label (or label difference).
--
cmmMachOpFoldM mop1 [CmmMachOp mop2 [arg1,arg2], arg3]
cmmMachOpFoldM platform mop1 [CmmMachOp mop2 [arg1,arg2], arg3]
| mop2 `associates_with` mop1
&& not (isLit arg1) && not (isPicReg arg1)
= Just (cmmMachOpFold mop2 [arg1, cmmMachOpFold mop1 [arg2,arg3]])
= Just (cmmMachOpFold platform mop2 [arg1, cmmMachOpFold platform mop1 [arg2,arg3]])
where
MO_Add{} `associates_with` MO_Sub{} = True
mop1 `associates_with` mop2 =
mop1 == mop2 && isAssociativeMachOp mop1
-- special case: (a - b) + c ==> a + (c - b)
cmmMachOpFoldM mop1@(MO_Add{}) [CmmMachOp mop2@(MO_Sub{}) [arg1,arg2], arg3]
cmmMachOpFoldM platform mop1@(MO_Add{}) [CmmMachOp mop2@(MO_Sub{}) [arg1,arg2], arg3]
| not (isLit arg1) && not (isPicReg arg1)
= Just (cmmMachOpFold mop1 [arg1, cmmMachOpFold mop2 [arg3,arg2]])
= Just (cmmMachOpFold platform mop1 [arg1, cmmMachOpFold platform mop2 [arg3,arg2]])
-- Make a RegOff if we can
cmmMachOpFoldM (MO_Add _) [CmmReg reg, CmmLit (CmmInt n rep)]
cmmMachOpFoldM _ (MO_Add _) [CmmReg reg, CmmLit (CmmInt n rep)]
= Just $ CmmRegOff reg (fromIntegral (narrowS rep n))
cmmMachOpFoldM (MO_Add _) [CmmRegOff reg off, CmmLit (CmmInt n rep)]
cmmMachOpFoldM _ (MO_Add _) [CmmRegOff reg off, CmmLit (CmmInt n rep)]
= Just $ CmmRegOff reg (off + fromIntegral (narrowS rep n))
cmmMachOpFoldM (MO_Sub _) [CmmReg reg, CmmLit (CmmInt n rep)]
cmmMachOpFoldM _ (MO_Sub _) [CmmReg reg, CmmLit (CmmInt n rep)]
= Just $ CmmRegOff reg (- fromIntegral (narrowS rep n))
cmmMachOpFoldM (MO_Sub _) [CmmRegOff reg off, CmmLit (CmmInt n rep)]
cmmMachOpFoldM _ (MO_Sub _) [CmmRegOff reg off, CmmLit (CmmInt n rep)]
= Just $ CmmRegOff reg (off - fromIntegral (narrowS rep n))
-- Fold label(+/-)offset into a CmmLit where possible
cmmMachOpFoldM (MO_Add _) [CmmLit (CmmLabel lbl), CmmLit (CmmInt i rep)]
cmmMachOpFoldM _ (MO_Add _) [CmmLit (CmmLabel lbl), CmmLit (CmmInt i rep)]
= Just $ CmmLit (CmmLabelOff lbl (fromIntegral (narrowU rep i)))
cmmMachOpFoldM (MO_Add _) [CmmLit (CmmInt i rep), CmmLit (CmmLabel lbl)]
cmmMachOpFoldM _ (MO_Add _) [CmmLit (CmmInt i rep), CmmLit (CmmLabel lbl)]
= Just $ CmmLit (CmmLabelOff lbl (fromIntegral (narrowU rep i)))
cmmMachOpFoldM (MO_Sub _) [CmmLit (CmmLabel lbl), CmmLit (CmmInt i rep)]
cmmMachOpFoldM _ (MO_Sub _) [CmmLit (CmmLabel lbl), CmmLit (CmmInt i rep)]
= Just $ CmmLit (CmmLabelOff lbl (fromIntegral (negate (narrowU rep i))))
......@@ -480,18 +482,17 @@ cmmMachOpFoldM (MO_Sub _) [CmmLit (CmmLabel lbl), CmmLit (CmmInt i rep)]
-- narrowing throws away bits from the operand, there's no way to do
-- the same comparison at the larger size.
#if i386_TARGET_ARCH || x86_64_TARGET_ARCH
-- powerPC NCG has a TODO for I8/I16 comparisons, so don't try
cmmMachOpFoldM cmp [CmmMachOp conv [x], CmmLit (CmmInt i _)]
| -- if the operand is widened:
cmmMachOpFoldM platform cmp [CmmMachOp conv [x], CmmLit (CmmInt i _)]
| -- powerPC NCG has a TODO for I8/I16 comparisons, so don't try
platformArch platform `elem` [ArchX86, ArchX86_64],
-- if the operand is widened:
Just (rep, signed, narrow_fn) <- maybe_conversion conv,
-- and this is a comparison operation:
Just narrow_cmp <- maybe_comparison cmp rep signed,
-- and the literal fits in the smaller size:
i == narrow_fn rep i
-- then we can do the comparison at the smaller size
= Just (cmmMachOpFold narrow_cmp [x, CmmLit (CmmInt i rep)])
= Just (cmmMachOpFold platform narrow_cmp [x, CmmLit (CmmInt i rep)])
where
maybe_conversion (MO_UU_Conv from to)
| to > from
......@@ -522,11 +523,9 @@ cmmMachOpFoldM cmp [CmmMachOp conv [x], CmmLit (CmmInt i _)]
maybe_comparison (MO_S_Le _) rep False = Just (MO_U_Le rep)
maybe_comparison _ _ _ = Nothing
#endif
-- We can often do something with constants of 0 and 1 ...
cmmMachOpFoldM mop args@[x, y@(CmmLit (CmmInt 0 _))]
cmmMachOpFoldM _ mop args@[x, y@(CmmLit (CmmInt 0 _))]
= case mop of
MO_Add r -> Just x
MO_Sub r -> Just x
......@@ -549,7 +548,7 @@ cmmMachOpFoldM mop args@[x, y@(CmmLit (CmmInt 0 _))]
MO_S_Le r | Just x' <- maybeInvertCmmExpr x -> Just x'
other -> Nothing
cmmMachOpFoldM mop args@[x, y@(CmmLit (CmmInt 1 rep))]
cmmMachOpFoldM _ mop args@[x, y@(CmmLit (CmmInt 1 rep))]
= case mop of
MO_Mul r -> Just x
MO_S_Quot r -> Just x
......@@ -570,14 +569,14 @@ cmmMachOpFoldM mop args@[x, y@(CmmLit (CmmInt 1 rep))]
-- Now look for multiplication/division by powers of 2 (integers).
cmmMachOpFoldM mop args@[x, y@(CmmLit (CmmInt n _))]
cmmMachOpFoldM platform mop args@[x, y@(CmmLit (CmmInt n _))]
= case mop of
MO_Mul rep
| Just p <- exactLog2 n ->
Just (cmmMachOpFold (MO_Shl rep) [x, CmmLit (CmmInt p rep)])
Just (cmmMachOpFold platform (MO_Shl rep) [x, CmmLit (CmmInt p rep)])
MO_U_Quot rep
| Just p <- exactLog2 n ->
Just (cmmMachOpFold (MO_U_Shr rep) [x, CmmLit (CmmInt p rep)])
Just (cmmMachOpFold platform (MO_U_Shr rep) [x, CmmLit (CmmInt p rep)])
MO_S_Quot rep
| Just p <- exactLog2 n,
CmmReg _ <- x -> -- We duplicate x below, hence require
......@@ -605,13 +604,13 @@ cmmMachOpFoldM mop args@[x, y@(CmmLit (CmmInt n _))]
CmmMachOp (MO_And rep) [x1, CmmLit (CmmInt (n-1) rep)]
x3 = CmmMachOp (MO_Add rep) [x, x2]
in
Just (cmmMachOpFold (MO_S_Shr rep) [x3, CmmLit (CmmInt p rep)])
Just (cmmMachOpFold platform (MO_S_Shr rep) [x3, CmmLit (CmmInt p rep)])
other
-> Nothing
-- Anything else is just too hard.
cmmMachOpFoldM _ _ = Nothing
cmmMachOpFoldM _ _ _ = Nothing
-- -----------------------------------------------------------------------------
-- exactLog2
......
......@@ -114,7 +114,7 @@ cpsTop hsc_env (CmmProc h@(TopInfo {stack_info=StackInfo {arg_space=entry_off}})
dumpPlatform platform Opt_D_dump_cmmz_spills "Post spills and reloads" g
----------- Sink and inline assignments -------------------
g <- runOptimization $ rewriteAssignments g
g <- runOptimization $ rewriteAssignments platform g
dumpPlatform platform Opt_D_dump_cmmz_rewrite "Post rewrite assignments" g
----------- Eliminate dead assignments -------------------
......
......@@ -22,6 +22,7 @@ import OptimizationFuel
import StgCmmUtils
import Control.Monad
import Platform
import UniqFM
import Unique
import BlockId
......@@ -33,8 +34,8 @@ import Prelude hiding (succ, zip)
----------------------------------------------------------------
--- Main function
rewriteAssignments :: CmmGraph -> FuelUniqSM CmmGraph
rewriteAssignments g = do
rewriteAssignments :: Platform -> CmmGraph -> FuelUniqSM CmmGraph
rewriteAssignments platform g = do
-- Because we need to act on forwards and backwards information, we
-- first perform usage analysis and bake this information into the
-- graph (backwards transform), and then do a forwards transform
......@@ -43,7 +44,7 @@ rewriteAssignments g = do
g'' <- liftM fst $ dataflowPassFwd g' [(g_entry g, fact_bot assignmentLattice)] $
analRewFwd assignmentLattice
assignmentTransfer
(assignmentRewrite `thenFwdRw` machOpFoldRewrite)
(assignmentRewrite `thenFwdRw` machOpFoldRewrite platform)
return (modifyGraph eraseRegUsage g'')
----------------------------------------------------------------
......@@ -611,8 +612,8 @@ assignmentRewrite = mkFRewrite3 first middle last
-- in literals, which we can inline more aggressively, and inlining
-- gives us opportunities for more folding. However, we don't need any
-- facts to do MachOp folding.
machOpFoldRewrite :: FwdRewrite FuelUniqSM (WithRegUsage CmmNode) a
machOpFoldRewrite = mkFRewrite3 first middle last
machOpFoldRewrite :: Platform -> FwdRewrite FuelUniqSM (WithRegUsage CmmNode) a
machOpFoldRewrite platform = mkFRewrite3 first middle last
where first _ _ = return Nothing
middle :: WithRegUsage CmmNode O O -> a -> GenCmmReplGraph (WithRegUsage CmmNode) O O
middle (Plain m) _ = return (fmap (mkMiddle . Plain) (foldNode m))
......@@ -622,7 +623,7 @@ machOpFoldRewrite = mkFRewrite3 first middle last
last (Plain l) _ = return (fmap (mkLast . Plain) (foldNode l))
foldNode :: CmmNode e x -> Maybe (CmmNode e x)
foldNode n = mapExpDeepM foldExp n
foldExp (CmmMachOp op args) = cmmMachOpFoldM op args
foldExp (CmmMachOp op args) = cmmMachOpFoldM platform op args
foldExp _ = Nothing
-- ToDo: Outputable instance for UsageMap and AssignmentMap
......@@ -922,20 +922,22 @@ cmmExprConFold referenceKind expr = do
-- (this optimization is done in Hoopl)
let expr' = if dopt Opt_TryNewCodeGen dflags
then expr
else cmmExprCon expr
else cmmExprCon (targetPlatform dflags) expr
cmmExprNative referenceKind expr'
cmmExprCon :: CmmExpr -> CmmExpr
cmmExprCon (CmmLoad addr rep) = CmmLoad (cmmExprCon addr) rep
cmmExprCon (CmmMachOp mop args) = cmmMachOpFold mop (map cmmExprCon args)
cmmExprCon other = other
cmmExprCon :: Platform -> CmmExpr -> CmmExpr
cmmExprCon platform (CmmLoad addr rep) = CmmLoad (cmmExprCon platform addr) rep
cmmExprCon platform (CmmMachOp mop args)
= cmmMachOpFold platform mop (map (cmmExprCon platform) args)
cmmExprCon _ other = other
-- handles both PIC and non-PIC cases... a very strange mixture
-- of things to do.
cmmExprNative :: ReferenceKind -> CmmExpr -> CmmOptM CmmExpr
cmmExprNative referenceKind expr = do
dflags <- getDynFlagsCmmOpt
let arch = platformArch (targetPlatform dflags)
let platform = targetPlatform dflags
arch = platformArch platform
case expr of
CmmLoad addr rep
-> do addr' <- cmmExprNative DataReference addr
......@@ -952,7 +954,7 @@ cmmExprNative referenceKind expr = do
-> do
dynRef <- cmmMakeDynamicReference dflags addImportCmmOpt referenceKind lbl
-- need to optimize here, since it's late
return $ cmmMachOpFold (MO_Add wordWidth) [
return $ cmmMachOpFold platform (MO_Add wordWidth) [
dynRef,
(CmmLit $ CmmInt (fromIntegral off) wordWidth)
]
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment