[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