1 -----------------------------------------------------------------------------
5 -- (c) The University of Glasgow 2004
7 -----------------------------------------------------------------------------
10 CmmStmts, noStmts, oneStmt, mkStmts, plusStmts, stmtList,
15 cmmRegOff, cmmLabelOff, cmmOffset, cmmOffsetLit, cmmIndex,
16 cmmOffsetExpr, cmmIndexExpr, cmmLoadIndex,
23 #include "HsVersions.h"
25 import CLabel ( CLabel )
31 ---------------------------------------------------
35 ---------------------------------------------------
37 type CmmStmts = OrdList CmmStmt
42 oneStmt :: CmmStmt -> CmmStmts
45 mkStmts :: [CmmStmt] -> CmmStmts
48 plusStmts :: CmmStmts -> CmmStmts -> CmmStmts
51 stmtList :: CmmStmts -> [CmmStmt]
55 ---------------------------------------------------
59 ---------------------------------------------------
61 isNopStmt :: CmmStmt -> Bool
62 -- If isNopStmt returns True, the stmt is definitely a no-op;
63 -- but it might be a no-op even if isNopStmt returns False
64 isNopStmt CmmNop = True
65 isNopStmt (CmmAssign r e) = cheapEqReg r e
66 isNopStmt (CmmStore e1 (CmmLoad e2 _)) = cheapEqExpr e1 e2
69 cheapEqExpr :: CmmExpr -> CmmExpr -> Bool
70 cheapEqExpr (CmmReg r) e = cheapEqReg r e
71 cheapEqExpr (CmmRegOff r 0) e = cheapEqReg r e
72 cheapEqExpr (CmmRegOff r n) (CmmRegOff r' n') = r==r' && n==n'
73 cheapEqExpr e1 e2 = False
75 cheapEqReg :: CmmReg -> CmmExpr -> Bool
76 cheapEqReg r (CmmReg r') = r==r'
77 cheapEqReg r (CmmRegOff r' 0) = r==r'
78 cheapEqReg r e = False
80 ---------------------------------------------------
84 ---------------------------------------------------
86 isTrivialCmmExpr :: CmmExpr -> Bool
87 isTrivialCmmExpr (CmmLoad _ _) = False
88 isTrivialCmmExpr (CmmMachOp _ _) = False
89 isTrivialCmmExpr (CmmLit _) = True
90 isTrivialCmmExpr (CmmReg _) = True
91 isTrivialCmmExpr (CmmRegOff _ _) = True
93 ---------------------------------------------------
95 -- Expr Construction helpers
97 ---------------------------------------------------
99 cmmOffsetExpr :: CmmExpr -> CmmExpr -> CmmExpr
100 -- assumes base and offset have the same MachRep
101 cmmOffsetExpr e (CmmLit (CmmInt n _)) = cmmOffset e (fromInteger n)
102 cmmOffsetExpr e byte_off = CmmMachOp (MO_Add (cmmExprRep e)) [e, byte_off]
104 -- NB. Do *not* inspect the value of the offset in these smart constructors!!!
106 -- because the offset is sometimes involved in a loop in the code generator
107 -- (we don't know the real Hp offset until we've generated code for the entire
108 -- basic block, for example). So we cannot eliminate zero offsets at this
109 -- stage; they're eliminated later instead (either during printing or
110 -- a later optimisation step on Cmm).
112 cmmOffset :: CmmExpr -> Int -> CmmExpr
113 cmmOffset (CmmReg reg) byte_off = cmmRegOff reg byte_off
114 cmmOffset (CmmRegOff reg m) byte_off = cmmRegOff reg (m+byte_off)
115 cmmOffset (CmmLit lit) byte_off = CmmLit (cmmOffsetLit lit byte_off)
116 cmmOffset (CmmMachOp (MO_Add rep) [expr, CmmLit (CmmInt byte_off1 _rep)]) byte_off2
117 = CmmMachOp (MO_Add rep)
118 [expr, CmmLit (CmmInt (byte_off1 + toInteger byte_off2) rep)]
119 cmmOffset expr byte_off
120 = CmmMachOp (MO_Add rep) [expr, CmmLit (CmmInt (toInteger byte_off) rep)]
122 rep = cmmExprRep expr
124 -- Smart constructor for CmmRegOff. Same caveats as cmmOffset above.
125 cmmRegOff :: CmmReg -> Int -> CmmExpr
126 cmmRegOff reg byte_off = CmmRegOff reg byte_off
128 cmmOffsetLit :: CmmLit -> Int -> CmmLit
129 cmmOffsetLit (CmmLabel l) byte_off = cmmLabelOff l byte_off
130 cmmOffsetLit (CmmLabelOff l m) byte_off = cmmLabelOff l (m+byte_off)
131 cmmOffsetLit (CmmInt m rep) byte_off = CmmInt (m + fromIntegral byte_off) rep
132 cmmOffsetLit other byte_off = pprPanic "cmmOffsetLit" (ppr byte_off)
134 cmmLabelOff :: CLabel -> Int -> CmmLit
135 -- Smart constructor for CmmLabelOff
136 cmmLabelOff lbl 0 = CmmLabel lbl
137 cmmLabelOff lbl byte_off = CmmLabelOff lbl byte_off
139 -- | Useful for creating an index into an array, with a staticaly known offset.
140 cmmIndex :: MachRep -> CmmExpr -> Int -> CmmExpr
141 cmmIndex rep base idx = cmmOffset base (idx * machRepByteWidth rep)
143 -- | Useful for creating an index into an array, with an unknown offset.
144 cmmIndexExpr :: MachRep -> CmmExpr -> CmmExpr -> CmmExpr
145 cmmIndexExpr rep base (CmmLit (CmmInt n _)) = cmmIndex rep base (fromInteger n)
146 cmmIndexExpr rep base idx =
147 cmmOffsetExpr base byte_off
149 idx_rep = cmmExprRep idx
150 byte_off = CmmMachOp (MO_Shl idx_rep) [
151 idx, CmmLit (mkIntCLit (machRepLogWidth rep))]
153 cmmLoadIndex :: MachRep -> CmmExpr -> Int -> CmmExpr
154 cmmLoadIndex rep expr ix = CmmLoad (cmmIndex rep expr ix) rep
156 ---------------------------------------------------
158 -- Literal construction functions
160 ---------------------------------------------------
162 mkIntCLit :: Int -> CmmLit
163 mkIntCLit i = CmmInt (toInteger i) wordRep
166 zeroCLit = CmmInt 0 wordRep
168 mkLblExpr :: CLabel -> CmmExpr
169 mkLblExpr lbl = CmmLit (CmmLabel lbl)