[commit: ghc] ghc-8.0: Fix the removal of unnecessary stack checks (d0b4ead)
git at git.haskell.org
git at git.haskell.org
Thu Feb 11 17:42:21 UTC 2016
Repository : ssh://git@git.haskell.org/ghc
On branch : ghc-8.0
Link : http://ghc.haskell.org/trac/ghc/changeset/d0b4eade3410a09459c4c101546f58e06f9aebcc/ghc
>---------------------------------------------------------------
commit d0b4eade3410a09459c4c101546f58e06f9aebcc
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
(cherry picked from commit 4ec61411930495fc109be27993c176fd7aaf486d)
>---------------------------------------------------------------
d0b4eade3410a09459c4c101546f58e06f9aebcc
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 cf96156..f55d76a 100644
--- a/compiler/cmm/CmmLayoutStack.hs
+++ b/compiler/cmm/CmmLayoutStack.hs
@@ -856,18 +856,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
@@ -880,11 +888,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