[commit: ghc] master: Fix the removal of unnecessary stack checks (4ec6141)

git at git.haskell.org git at git.haskell.org
Tue Feb 9 14:41:09 UTC 2016


Repository : ssh://git@git.haskell.org/ghc

On branch  : master
Link       : http://ghc.haskell.org/trac/ghc/changeset/4ec61411930495fc109be27993c176fd7aaf486d/ghc

>---------------------------------------------------------------

commit 4ec61411930495fc109be27993c176fd7aaf486d
Author: Jonas Scholl <anselm.scholl at tu-harburg.de>
Date:   Tue Feb 9 11:06:00 2016 +0100

    Fix the removal of unnecessary stack checks
    
    The module CmmLayoutStack removes stack checks if a function does not
    use stack space. However, it can only recognize checks of the form
    Sp < SpLim. However, these checks get sometimes rewritten to
    Sp >= SpLim (with both branches swapped), so we better recognize these
    checks too.
    
    Test Plan: ./validate
    
    Reviewers: austin, bgamari, simonpj
    
    Reviewed By: simonpj
    
    Subscribers: simonpj, thomie
    
    Differential Revision: https://phabricator.haskell.org/D1881
    
    GHC Trac Issues: #11533


>---------------------------------------------------------------

4ec61411930495fc109be27993c176fd7aaf486d
 compiler/cmm/CmmLayoutStack.hs | 27 +++++++++++++++++++++------
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/compiler/cmm/CmmLayoutStack.hs b/compiler/cmm/CmmLayoutStack.hs
index 5fea0e7..25a0ad6 100644
--- a/compiler/cmm/CmmLayoutStack.hs
+++ b/compiler/cmm/CmmLayoutStack.hs
@@ -855,18 +855,26 @@ areaToSp dflags _ sp_hwm _ (CmmLit CmmHighStackMark)
     -- Replace CmmHighStackMark with the number of bytes of stack used,
     -- the sp_hwm.   See Note [Stack usage] in StgCmmHeap
 
-areaToSp dflags _ _ _ (CmmMachOp (MO_U_Lt _)
-                          [CmmMachOp (MO_Sub _)
-                                  [ CmmRegOff (CmmGlobal Sp) x_off
-                                  , CmmLit (CmmInt y_lit _)],
-                           CmmReg (CmmGlobal SpLim)])
-  | fromIntegral x_off >= y_lit
+areaToSp dflags _ _ _ (CmmMachOp (MO_U_Lt _) args)
+  | falseStackCheck args
   = zeroExpr dflags
+areaToSp dflags _ _ _ (CmmMachOp (MO_U_Ge _) args)
+  | falseStackCheck args
+  = mkIntExpr dflags 1
     -- Replace a stack-overflow test that cannot fail with a no-op
     -- See Note [Always false stack check]
 
 areaToSp _ _ _ _ other = other
 
+-- | Determine whether a stack check cannot fail.
+falseStackCheck :: [CmmExpr] -> Bool
+falseStackCheck [ CmmMachOp (MO_Sub _)
+                      [ CmmRegOff (CmmGlobal Sp) x_off
+                      , CmmLit (CmmInt y_lit _)]
+                , CmmReg (CmmGlobal SpLim)]
+  = fromIntegral x_off >= y_lit
+falseStackCheck _ = False
+
 -- Note [Always false stack check]
 -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 -- We can optimise stack checks of the form
@@ -879,11 +887,18 @@ areaToSp _ _ _ _ other = other
 -- A subsequent sinking pass will later drop the dead code.
 -- Optimising this away depends on knowing that SpLim <= Sp, so it is
 -- really the job of the stack layout algorithm, hence we do it now.
+--
+-- The control flow optimiser may negate a conditional to increase
+-- the likelihood of a fallthrough if the branch is not taken.  But
+-- not every conditional is inverted as the control flow optimiser
+-- places some requirements on the predecessors of both branch targets.
+-- So we better look for the inverted comparison too.
 
 optStackCheck :: CmmNode O C -> CmmNode O C
 optStackCheck n = -- Note [Always false stack check]
  case n of
    CmmCondBranch (CmmLit (CmmInt 0 _)) _true false _ -> CmmBranch false
+   CmmCondBranch (CmmLit (CmmInt _ _)) true _false _ -> CmmBranch true
    other -> other
 
 



More information about the ghc-commits mailing list