CmmOpt.hs 18 KB
Newer Older
1
2
3
4
5
6
7
8
9
-----------------------------------------------------------------------------
--
-- Cmm optimisation
--
-- (c) The University of Glasgow 2006
--
-----------------------------------------------------------------------------

module CmmOpt (
10
        cmmMachOpFold,
11
        cmmMachOpFoldM
12
13
14
15
 ) where

#include "HsVersions.h"

16
import CmmUtils
17
import Cmm
Ian Lynagh's avatar
Ian Lynagh committed
18
import DynFlags
19

20
import FastTypes
21
import Outputable
22
import Platform
23

Simon Marlow's avatar
Simon Marlow committed
24
import Data.Bits
25
import Data.Maybe
26
27
28
29
30
31
32
33

-- -----------------------------------------------------------------------------
-- MachOp constant folder

-- Now, try to constant-fold the MachOps.  The arguments have already
-- been optimized and folded.

cmmMachOpFold
34
    :: DynFlags
Ian Lynagh's avatar
Ian Lynagh committed
35
    -> MachOp       -- The operation from an CmmMachOp
36
    -> [CmmExpr]    -- The optimized arguments
37
38
    -> CmmExpr

39
cmmMachOpFold dflags op args = fromMaybe (CmmMachOp op args) (cmmMachOpFoldM dflags op args)
40
41
42
43

-- Returns Nothing if no changes, useful for Hoopl, also reduces
-- allocation!
cmmMachOpFoldM
44
    :: DynFlags
Ian Lynagh's avatar
Ian Lynagh committed
45
    -> MachOp
46
47
48
    -> [CmmExpr]
    -> Maybe CmmExpr

Ian Lynagh's avatar
Ian Lynagh committed
49
cmmMachOpFoldM _ op [CmmLit (CmmInt x rep)]
50
  = Just $ case op of
Ian Lynagh's avatar
Ian Lynagh committed
51
52
      MO_S_Neg _ -> CmmLit (CmmInt (-x) rep)
      MO_Not _   -> CmmLit (CmmInt (complement x) rep)
53

Jan Stolarek's avatar
Jan Stolarek committed
54
        -- these are interesting: we must first narrow to the
55
56
57
        -- "from" type, in order to truncate to the correct size.
        -- The final narrow/widen to the destination type
        -- is implicit in the CmmLit.
Ian Lynagh's avatar
Ian Lynagh committed
58
59
60
      MO_SF_Conv _from to -> CmmLit (CmmFloat (fromInteger x) to)
      MO_SS_Conv  from to -> CmmLit (CmmInt (narrowS from x) to)
      MO_UU_Conv  from to -> CmmLit (CmmInt (narrowU from x) to)
61

62
      _ -> panic "cmmMachOpFoldM: unknown unary op"
63
64
65


-- Eliminate conversion NOPs
Ian Lynagh's avatar
Ian Lynagh committed
66
67
cmmMachOpFoldM _ (MO_SS_Conv rep1 rep2) [x] | rep1 == rep2 = Just x
cmmMachOpFoldM _ (MO_UU_Conv rep1 rep2) [x] | rep1 == rep2 = Just x
68
69

-- Eliminate nested conversions where possible
70
cmmMachOpFoldM dflags conv_outer [CmmMachOp conv_inner [x]]
71
72
73
  | Just (rep1,rep2,signed1) <- isIntConversion conv_inner,
    Just (_,   rep3,signed2) <- isIntConversion conv_outer
  = case () of
74
75
76
77
78
79
        -- widen then narrow to the same size is a nop
      _ | rep1 < rep2 && rep1 == rep3 -> Just x
        -- Widen then narrow to different size: collapse to single conversion
        -- but remember to use the signedness from the widening, just in case
        -- the final conversion is a widen.
        | rep1 < rep2 && rep2 > rep3 ->
80
            Just $ cmmMachOpFold dflags (intconv signed1 rep1 rep3) [x]
81
82
        -- Nested widenings: collapse if the signedness is the same
        | rep1 < rep2 && rep2 < rep3 && signed1 == signed2 ->
83
            Just $ cmmMachOpFold dflags (intconv signed1 rep1 rep3) [x]
84
85
        -- Nested narrowings: collapse
        | rep1 > rep2 && rep2 > rep3 ->
86
            Just $ cmmMachOpFold dflags (MO_UU_Conv rep1 rep3) [x]
87
88
        | otherwise ->
            Nothing
89
  where
Jan Stolarek's avatar
Jan Stolarek committed
90
        isIntConversion (MO_UU_Conv rep1 rep2)
91
92
93
94
          = Just (rep1,rep2,False)
        isIntConversion (MO_SS_Conv rep1 rep2)
          = Just (rep1,rep2,True)
        isIntConversion _ = Nothing
95

96
97
        intconv True  = MO_SS_Conv
        intconv False = MO_UU_Conv
98
99
100
101
102

-- ToDo: a narrow of a load can be collapsed into a narrow load, right?
-- but what if the architecture only supports word-sized loads, should
-- we do the transformation anyway?

103
cmmMachOpFoldM dflags mop [CmmLit (CmmInt x xrep), CmmLit (CmmInt y _)]
104
  = case mop of
105
106
        -- for comparisons: don't forget to narrow the arguments before
        -- comparing, since they might be out of range.
107
108
        MO_Eq _   -> Just $ CmmLit (CmmInt (if x_u == y_u then 1 else 0) (wordWidth dflags))
        MO_Ne _   -> Just $ CmmLit (CmmInt (if x_u /= y_u then 1 else 0) (wordWidth dflags))
109

110
111
112
113
        MO_U_Gt _ -> Just $ CmmLit (CmmInt (if x_u >  y_u then 1 else 0) (wordWidth dflags))
        MO_U_Ge _ -> Just $ CmmLit (CmmInt (if x_u >= y_u then 1 else 0) (wordWidth dflags))
        MO_U_Lt _ -> Just $ CmmLit (CmmInt (if x_u <  y_u then 1 else 0) (wordWidth dflags))
        MO_U_Le _ -> Just $ CmmLit (CmmInt (if x_u <= y_u then 1 else 0) (wordWidth dflags))
114

115
116
117
118
        MO_S_Gt _ -> Just $ CmmLit (CmmInt (if x_s >  y_s then 1 else 0) (wordWidth dflags))
        MO_S_Ge _ -> Just $ CmmLit (CmmInt (if x_s >= y_s then 1 else 0) (wordWidth dflags))
        MO_S_Lt _ -> Just $ CmmLit (CmmInt (if x_s <  y_s then 1 else 0) (wordWidth dflags))
        MO_S_Le _ -> Just $ CmmLit (CmmInt (if x_s <= y_s then 1 else 0) (wordWidth dflags))
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

        MO_Add r -> Just $ CmmLit (CmmInt (x + y) r)
        MO_Sub r -> Just $ CmmLit (CmmInt (x - y) r)
        MO_Mul r -> Just $ CmmLit (CmmInt (x * y) r)
        MO_U_Quot r | y /= 0 -> Just $ CmmLit (CmmInt (x_u `quot` y_u) r)
        MO_U_Rem  r | y /= 0 -> Just $ CmmLit (CmmInt (x_u `rem`  y_u) r)
        MO_S_Quot r | y /= 0 -> Just $ CmmLit (CmmInt (x `quot` y) r)
        MO_S_Rem  r | y /= 0 -> Just $ CmmLit (CmmInt (x `rem` y) r)

        MO_And   r -> Just $ CmmLit (CmmInt (x .&. y) r)
        MO_Or    r -> Just $ CmmLit (CmmInt (x .|. y) r)
        MO_Xor   r -> Just $ CmmLit (CmmInt (x `xor` y) r)

        MO_Shl   r -> Just $ CmmLit (CmmInt (x `shiftL` fromIntegral y) r)
        MO_U_Shr r -> Just $ CmmLit (CmmInt (x_u `shiftR` fromIntegral y) r)
        MO_S_Shr r -> Just $ CmmLit (CmmInt (x `shiftR` fromIntegral y) r)

Ian Lynagh's avatar
Ian Lynagh committed
136
        _          -> Nothing
137
138

   where
139
140
141
142
143
        x_u = narrowU xrep x
        y_u = narrowU xrep y
        x_s = narrowS xrep x
        y_s = narrowS xrep y

144
145
146
147
148
149

-- When possible, shift the constants to the right-hand side, so that we
-- can match for strength reductions.  Note that the code generator will
-- also assume that constants have been shifted to the right when
-- possible.

150
cmmMachOpFoldM dflags op [x@(CmmLit _), y]
151
   | not (isLit y) && isCommutableMachOp op
152
   = Just (cmmMachOpFold dflags op [y, x])
153
154
155
156
157
158
159
160
161
162
163
164
165
166

-- 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
-- opportunities for constant folding when the expression is
-- right-associated.
--
-- ToDo: this appears to introduce a quadratic behaviour due to the
-- nested cmmMachOpFold.  Can we fix this?
--
-- Why do we check isLit arg1?  If arg1 is a lit, it means that arg2
-- is also a lit (otherwise arg1 would be on the right).  If we
-- put arg1 on the left of the rearranged expression, we'll get into a
-- loop:  (x1+x2)+x3 => x1+(x2+x3)  => (x2+x3)+x1 => x2+(x3+x1) ...
--
167
168
169
-- Also don't do it if arg1 is PicBaseReg, so that we don't separate the
-- PicBaseReg from the corresponding label (or label difference).
--
170
cmmMachOpFoldM dflags mop1 [CmmMachOp mop2 [arg1,arg2], arg3]
171
   | mop2 `associates_with` mop1
172
     && not (isLit arg1) && not (isPicReg arg1)
173
   = Just (cmmMachOpFold dflags mop2 [arg1, cmmMachOpFold dflags mop1 [arg2,arg3]])
174
175
176
177
178
179
   where
     MO_Add{} `associates_with` MO_Sub{} = True
     mop1 `associates_with` mop2 =
        mop1 == mop2 && isAssociativeMachOp mop1

-- special case: (a - b) + c  ==>  a + (c - b)
180
cmmMachOpFoldM dflags mop1@(MO_Add{}) [CmmMachOp mop2@(MO_Sub{}) [arg1,arg2], arg3]
181
   | not (isLit arg1) && not (isPicReg arg1)
182
   = Just (cmmMachOpFold dflags mop1 [arg1, cmmMachOpFold dflags mop2 [arg3,arg2]])
183

Simon Marlow's avatar
Simon Marlow committed
184
185
186
187
188
189
190
191
192
193
194
195
196
197
-- special case: (PicBaseReg + lit) + N  ==>  PicBaseReg + (lit+N)
--
-- this is better because lit+N is a single link-time constant (e.g. a
-- CmmLabelOff), so the right-hand expression needs only one
-- instruction, whereas the left needs two.  This happens when pointer
-- tagging gives us label+offset, and PIC turns the label into
-- PicBaseReg + label.
--
cmmMachOpFoldM _ MO_Add{} [ CmmMachOp op@MO_Add{} [pic, CmmLit lit]
                          , CmmLit (CmmInt n rep) ]
  | isPicReg pic
  = Just $ CmmMachOp op [pic, CmmLit $ cmmOffsetLit lit off ]
  where off = fromIntegral (narrowS rep n)

198
-- Make a RegOff if we can
Ian Lynagh's avatar
Ian Lynagh committed
199
cmmMachOpFoldM _ (MO_Add _) [CmmReg reg, CmmLit (CmmInt n rep)]
200
  = Just $ cmmRegOff reg (fromIntegral (narrowS rep n))
Ian Lynagh's avatar
Ian Lynagh committed
201
cmmMachOpFoldM _ (MO_Add _) [CmmRegOff reg off, CmmLit (CmmInt n rep)]
202
  = Just $ cmmRegOff reg (off + fromIntegral (narrowS rep n))
Ian Lynagh's avatar
Ian Lynagh committed
203
cmmMachOpFoldM _ (MO_Sub _) [CmmReg reg, CmmLit (CmmInt n rep)]
204
  = Just $ cmmRegOff reg (- fromIntegral (narrowS rep n))
Ian Lynagh's avatar
Ian Lynagh committed
205
cmmMachOpFoldM _ (MO_Sub _) [CmmRegOff reg off, CmmLit (CmmInt n rep)]
206
  = Just $ cmmRegOff reg (off - fromIntegral (narrowS rep n))
207
208
209

-- Fold label(+/-)offset into a CmmLit where possible

210
211
212
213
214
215
cmmMachOpFoldM _ (MO_Add _) [CmmLit lit, CmmLit (CmmInt i rep)]
  = Just $ CmmLit (cmmOffsetLit lit (fromIntegral (narrowU rep i)))
cmmMachOpFoldM _ (MO_Add _) [CmmLit (CmmInt i rep), CmmLit lit]
  = Just $ CmmLit (cmmOffsetLit lit (fromIntegral (narrowU rep i)))
cmmMachOpFoldM _ (MO_Sub _) [CmmLit lit, CmmLit (CmmInt i rep)]
  = Just $ CmmLit (cmmOffsetLit lit (fromIntegral (negate (narrowU rep i))))
216

217

218
219
220
221
222
223
-- Comparison of literal with widened operand: perform the comparison
-- at the smaller width, as long as the literal is within range.

-- We can't do the reverse trick, when the operand is narrowed:
-- narrowing throws away bits from the operand, there's no way to do
-- the same comparison at the larger size.
224

225
cmmMachOpFoldM dflags cmp [CmmMachOp conv [x], CmmLit (CmmInt i _)]
Ian Lynagh's avatar
Ian Lynagh committed
226
  |     -- powerPC NCG has a TODO for I8/I16 comparisons, so don't try
227
    platformArch (targetPlatform dflags) `elem` [ArchX86, ArchX86_64],
Ian Lynagh's avatar
Ian Lynagh committed
228
        -- if the operand is widened:
229
230
231
232
233
234
    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
235
  = Just (cmmMachOpFold dflags narrow_cmp [x, CmmLit (CmmInt i rep)])
236
 where
237
    maybe_conversion (MO_UU_Conv from to)
238
239
        | to > from
        = Just (from, False, narrowU)
240
241
    maybe_conversion (MO_SS_Conv from to)
        | to > from
242
        = Just (from, True, narrowS)
243

Simon Marlow's avatar
Simon Marlow committed
244
245
        -- don't attempt to apply this optimisation when the source
        -- is a float; see #1916
246
    maybe_conversion _ = Nothing
247

248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
        -- careful (#2080): if the original comparison was signed, but
        -- we were doing an unsigned widen, then we must do an
        -- unsigned comparison at the smaller size.
    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_Eq   _) rep _     = Just (MO_Eq   rep)
    maybe_comparison (MO_S_Gt _) rep True  = Just (MO_S_Gt rep)
    maybe_comparison (MO_S_Ge _) rep True  = Just (MO_S_Ge rep)
    maybe_comparison (MO_S_Lt _) rep True  = Just (MO_S_Lt rep)
    maybe_comparison (MO_S_Le _) rep True  = Just (MO_S_Le rep)
    maybe_comparison (MO_S_Gt _) rep False = Just (MO_U_Gt rep)
    maybe_comparison (MO_S_Ge _) rep False = Just (MO_U_Ge rep)
    maybe_comparison (MO_S_Lt _) rep False = Just (MO_U_Lt rep)
    maybe_comparison (MO_S_Le _) rep False = Just (MO_U_Le rep)
    maybe_comparison _ _ _ = Nothing
265

266
267
-- We can often do something with constants of 0 and 1 ...

268
cmmMachOpFoldM dflags mop [x, y@(CmmLit (CmmInt 0 _))]
269
  = case mop of
Ian Lynagh's avatar
Ian Lynagh committed
270
271
272
273
274
275
276
277
278
279
280
281
282
        MO_Add   _ -> Just x
        MO_Sub   _ -> Just x
        MO_Mul   _ -> Just y
        MO_And   _ -> Just y
        MO_Or    _ -> Just x
        MO_Xor   _ -> Just x
        MO_Shl   _ -> Just x
        MO_S_Shr _ -> Just x
        MO_U_Shr _ -> Just x
        MO_Ne    _ | isComparisonExpr x -> Just x
        MO_Eq    _ | Just x' <- maybeInvertCmmExpr x -> Just x'
        MO_U_Gt  _ | isComparisonExpr x -> Just x
        MO_S_Gt  _ | isComparisonExpr x -> Just x
283
284
285
286
        MO_U_Lt  _ | isComparisonExpr x -> Just $ CmmLit (CmmInt 0 (wordWidth dflags))
        MO_S_Lt  _ | isComparisonExpr x -> Just $ CmmLit (CmmInt 0 (wordWidth dflags))
        MO_U_Ge  _ | isComparisonExpr x -> Just $ CmmLit (CmmInt 1 (wordWidth dflags))
        MO_S_Ge  _ | isComparisonExpr x -> Just $ CmmLit (CmmInt 1 (wordWidth dflags))
Ian Lynagh's avatar
Ian Lynagh committed
287
288
289
290
        MO_U_Le  _ | Just x' <- maybeInvertCmmExpr x -> Just x'
        MO_S_Le  _ | Just x' <- maybeInvertCmmExpr x -> Just x'
        _ -> Nothing

291
cmmMachOpFoldM dflags mop [x, (CmmLit (CmmInt 1 rep))]
292
  = case mop of
Ian Lynagh's avatar
Ian Lynagh committed
293
294
295
296
297
298
299
300
301
        MO_Mul    _ -> Just x
        MO_S_Quot _ -> Just x
        MO_U_Quot _ -> Just x
        MO_S_Rem  _ -> Just $ CmmLit (CmmInt 0 rep)
        MO_U_Rem  _ -> Just $ CmmLit (CmmInt 0 rep)
        MO_Ne    _ | Just x' <- maybeInvertCmmExpr x -> Just x'
        MO_Eq    _ | isComparisonExpr x -> Just x
        MO_U_Lt  _ | Just x' <- maybeInvertCmmExpr x -> Just x'
        MO_S_Lt  _ | Just x' <- maybeInvertCmmExpr x -> Just x'
302
303
304
305
        MO_U_Gt  _ | isComparisonExpr x -> Just $ CmmLit (CmmInt 0 (wordWidth dflags))
        MO_S_Gt  _ | isComparisonExpr x -> Just $ CmmLit (CmmInt 0 (wordWidth dflags))
        MO_U_Le  _ | isComparisonExpr x -> Just $ CmmLit (CmmInt 1 (wordWidth dflags))
        MO_S_Le  _ | isComparisonExpr x -> Just $ CmmLit (CmmInt 1 (wordWidth dflags))
Ian Lynagh's avatar
Ian Lynagh committed
306
307
308
        MO_U_Ge  _ | isComparisonExpr x -> Just x
        MO_S_Ge  _ | isComparisonExpr x -> Just x
        _ -> Nothing
309
310
311

-- Now look for multiplication/division by powers of 2 (integers).

312
cmmMachOpFoldM dflags mop [x, (CmmLit (CmmInt n _))]
313
  = case mop of
314
315
        MO_Mul rep
           | Just p <- exactLog2 n ->
316
                 Just (cmmMachOpFold dflags (MO_Shl rep) [x, CmmLit (CmmInt p rep)])
317
318
        MO_U_Quot rep
           | Just p <- exactLog2 n ->
319
                 Just (cmmMachOpFold dflags (MO_U_Shr rep) [x, CmmLit (CmmInt p rep)])
320
        MO_S_Quot rep
Jan Stolarek's avatar
Jan Stolarek committed
321
           | Just p <- exactLog2 n,
322
323
324
325
326
327
328
329
             CmmReg _ <- x ->   -- We duplicate x below, hence require
                                -- it is a reg.  FIXME: remove this restriction.
                -- shift right is not the same as quot, because it rounds
                -- to minus infinity, whereasq quot rounds toward zero.
                -- To fix this up, we add one less than the divisor to the
                -- dividend if it is a negative number.
                --
                -- to avoid a test/jump, we use the following sequence:
Ian Lynagh's avatar
Ian Lynagh committed
330
                --      x1 = x >> word_size-1  (all 1s if -ve, all 0s if +ve)
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
                --      x2 = y & (divisor-1)
                --      result = (x+x2) >>= log2(divisor)
                -- this could be done a bit more simply using conditional moves,
                -- but we're processor independent here.
                --
                -- we optimise the divide by 2 case slightly, generating
                --      x1 = x >> word_size-1  (unsigned)
                --      return = (x + x1) >>= log2(divisor)
                let
                    bits = fromIntegral (widthInBits rep) - 1
                    shr = if p == 1 then MO_U_Shr rep else MO_S_Shr rep
                    x1 = CmmMachOp shr [x, CmmLit (CmmInt bits rep)]
                    x2 = if p == 1 then x1 else
                         CmmMachOp (MO_And rep) [x1, CmmLit (CmmInt (n-1) rep)]
                    x3 = CmmMachOp (MO_Add rep) [x, x2]
                in
347
                Just (cmmMachOpFold dflags (MO_S_Shr rep) [x3, CmmLit (CmmInt p rep)])
Ian Lynagh's avatar
Ian Lynagh committed
348
        _ -> Nothing
349

Simon Marlow's avatar
comment    
Simon Marlow committed
350
351
352
353
354
-- ToDo (#7116): optimise floating-point multiplication, e.g. x*2.0 -> x+x
-- Unfortunately this needs a unique supply because x might not be a
-- register.  See #2253 (program 6) for an example.


355
356
-- Anything else is just too hard.

Ian Lynagh's avatar
Ian Lynagh committed
357
cmmMachOpFoldM _ _ _ = Nothing
358
359
360
361
362
363
364

-- -----------------------------------------------------------------------------
-- exactLog2

-- This algorithm for determining the $\log_2$ of exact powers of 2 comes
-- from GCC.  It requires bit manipulation primitives, and we use GHC
-- extensions.  Tough.
Jan Stolarek's avatar
Jan Stolarek committed
365
--
366
367
368
-- Used to be in MachInstrs --SDM.
-- ToDo: remove use of unboxery --SDM.

369
370
371
372
373
-- Unboxery removed in favor of FastInt; but is the function supposed to fail
-- on inputs >= 2147483648, or was that just an implementation artifact?
-- And is this speed-critical, or can we just use Integer operations
-- (including Data.Bits)?
--  --Isaac Dupree
374
375

exactLog2 :: Integer -> Maybe Integer
376
377
exactLog2 x_
  = if (x_ <= 0 || x_ >= 2147483648) then
378
379
       Nothing
    else
380
381
       case iUnbox (fromInteger x_) of { x ->
       if (x `bitAndFastInt` negateFastInt x) /=# x then
Ian Lynagh's avatar
Ian Lynagh committed
382
          Nothing
383
       else
Ian Lynagh's avatar
Ian Lynagh committed
384
          Just (toInteger (iBox (pow2 x)))
385
386
       }
  where
387
388
    pow2 x | x ==# _ILIT(1) = _ILIT(0)
           | otherwise = _ILIT(1) +# pow2 (x `shiftR_FastInt` _ILIT(1))
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416


-- -----------------------------------------------------------------------------
-- Loopify for C

{-
 This is a simple pass that replaces tail-recursive functions like this:

   fac() {
     ...
     jump fac();
   }

 with this:

  fac() {
   L:
     ...
     goto L;
  }

  the latter generates better C code, because the C compiler treats it
  like a loop, and brings full loop optimisation to bear.

  In my measurements this makes little or no difference to anything
  except factorial, but what the hell.
-}

417
{-
418
cmmLoopifyForC :: DynFlags -> RawCmmDecl -> RawCmmDecl
419
420
-- XXX: revisit if we actually want to do this
-- cmmLoopifyForC p@(CmmProc Nothing _ _) = p  -- only if there's an info table, ignore case alts
421
cmmLoopifyForC dflags (CmmProc infos entry_lbl live
422
                 (ListGraph blocks@(BasicBlock top_id _ : _))) =
423
--  pprTrace "jump_lbl" (ppr jump_lbl <+> ppr entry_lbl) $
424
  CmmProc infos entry_lbl live (ListGraph blocks')
425
  where blocks' = [ BasicBlock id (map do_stmt stmts)
Ian Lynagh's avatar
Ian Lynagh committed
426
                  | BasicBlock id stmts <- blocks ]
427

428
        do_stmt (CmmJump (CmmLit (CmmLabel lbl)) _) | lbl == jump_lbl
Ian Lynagh's avatar
Ian Lynagh committed
429
430
                = CmmBranch top_id
        do_stmt stmt = stmt
431

432
433
        jump_lbl | tablesNextToCode dflags = toInfoLbl entry_lbl
                 | otherwise               = entry_lbl
434

435
cmmLoopifyForC _ top = top
436
-}
437
438
439
440

-- -----------------------------------------------------------------------------
-- Utils

Ian Lynagh's avatar
Ian Lynagh committed
441
isLit :: CmmExpr -> Bool
442
443
444
445
446
isLit (CmmLit _) = True
isLit _          = False

isComparisonExpr :: CmmExpr -> Bool
isComparisonExpr (CmmMachOp op _) = isComparisonMachOp op
Ian Lynagh's avatar
Ian Lynagh committed
447
isComparisonExpr _                  = False
448

Ian Lynagh's avatar
Ian Lynagh committed
449
isPicReg :: CmmExpr -> Bool
450
isPicReg (CmmReg (CmmGlobal PicBaseReg)) = True
451
isPicReg _ = False