1 -----------------------------------------------------------------------------
5 -- (c) The University of Glasgow 2004
7 -----------------------------------------------------------------------------
10 CmmStmts, noStmts, oneStmt, mkStmts, plusStmts, stmtList,
13 isTrivialCmmExpr, hasNoGlobalRegs,
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 hasNoGlobalRegs :: CmmExpr -> Bool
94 hasNoGlobalRegs (CmmLoad e _) = hasNoGlobalRegs e
95 hasNoGlobalRegs (CmmMachOp _ es) = all hasNoGlobalRegs es
96 hasNoGlobalRegs (CmmLit _) = True
97 hasNoGlobalRegs (CmmReg (CmmLocal _)) = True
98 hasNoGlobalRegs (CmmRegOff (CmmLocal _) _) = True
99 hasNoGlobalRegs _ = False
101 ---------------------------------------------------
103 -- Expr Construction helpers
105 ---------------------------------------------------
107 cmmOffsetExpr :: CmmExpr -> CmmExpr -> CmmExpr
108 -- assumes base and offset have the same MachRep
109 cmmOffsetExpr e (CmmLit (CmmInt n _)) = cmmOffset e (fromInteger n)
110 cmmOffsetExpr e byte_off = CmmMachOp (MO_Add (cmmExprRep e)) [e, byte_off]
112 -- NB. Do *not* inspect the value of the offset in these smart constructors!!!
114 -- because the offset is sometimes involved in a loop in the code generator
115 -- (we don't know the real Hp offset until we've generated code for the entire
116 -- basic block, for example). So we cannot eliminate zero offsets at this
117 -- stage; they're eliminated later instead (either during printing or
118 -- a later optimisation step on Cmm).
120 cmmOffset :: CmmExpr -> Int -> CmmExpr
121 cmmOffset (CmmReg reg) byte_off = cmmRegOff reg byte_off
122 cmmOffset (CmmRegOff reg m) byte_off = cmmRegOff reg (m+byte_off)
123 cmmOffset (CmmLit lit) byte_off = CmmLit (cmmOffsetLit lit byte_off)
124 cmmOffset (CmmMachOp (MO_Add rep) [expr, CmmLit (CmmInt byte_off1 _rep)]) byte_off2
125 = CmmMachOp (MO_Add rep)
126 [expr, CmmLit (CmmInt (byte_off1 + toInteger byte_off2) rep)]
127 cmmOffset expr byte_off
128 = CmmMachOp (MO_Add rep) [expr, CmmLit (CmmInt (toInteger byte_off) rep)]
130 rep = cmmExprRep expr
132 -- Smart constructor for CmmRegOff. Same caveats as cmmOffset above.
133 cmmRegOff :: CmmReg -> Int -> CmmExpr
134 cmmRegOff reg byte_off = CmmRegOff reg byte_off
136 cmmOffsetLit :: CmmLit -> Int -> CmmLit
137 cmmOffsetLit (CmmLabel l) byte_off = cmmLabelOff l byte_off
138 cmmOffsetLit (CmmLabelOff l m) byte_off = cmmLabelOff l (m+byte_off)
139 cmmOffsetLit (CmmInt m rep) byte_off = CmmInt (m + fromIntegral byte_off) rep
140 cmmOffsetLit other byte_off = pprPanic "cmmOffsetLit" (ppr byte_off)
142 cmmLabelOff :: CLabel -> Int -> CmmLit
143 -- Smart constructor for CmmLabelOff
144 cmmLabelOff lbl 0 = CmmLabel lbl
145 cmmLabelOff lbl byte_off = CmmLabelOff lbl byte_off
147 -- | Useful for creating an index into an array, with a staticaly known offset.
148 cmmIndex :: MachRep -> CmmExpr -> Int -> CmmExpr
149 cmmIndex rep base idx = cmmOffset base (idx * machRepByteWidth rep)
151 -- | Useful for creating an index into an array, with an unknown offset.
152 cmmIndexExpr :: MachRep -> CmmExpr -> CmmExpr -> CmmExpr
153 cmmIndexExpr rep base (CmmLit (CmmInt n _)) = cmmIndex rep base (fromInteger n)
154 cmmIndexExpr rep base idx =
155 cmmOffsetExpr base byte_off
157 idx_rep = cmmExprRep idx
158 byte_off = CmmMachOp (MO_Shl idx_rep) [
159 idx, CmmLit (mkIntCLit (machRepLogWidth rep))]
161 cmmLoadIndex :: MachRep -> CmmExpr -> Int -> CmmExpr
162 cmmLoadIndex rep expr ix = CmmLoad (cmmIndex rep expr ix) rep
164 ---------------------------------------------------
166 -- Literal construction functions
168 ---------------------------------------------------
170 mkIntCLit :: Int -> CmmLit
171 mkIntCLit i = CmmInt (toInteger i) wordRep
174 zeroCLit = CmmInt 0 wordRep
176 mkLblExpr :: CLabel -> CmmExpr
177 mkLblExpr lbl = CmmLit (CmmLabel lbl)