diff options
| author | Jonas Scholl <anselm.scholl@tu-harburg.de> | 2016-02-09 11:06:00 +0100 |
|---|---|---|
| committer | Ben Gamari <ben@smart-cactus.org> | 2016-02-09 11:06:10 +0100 |
| commit | 4ec61411930495fc109be27993c176fd7aaf486d (patch) | |
| tree | ec583752187ad83e975566f01f7cb31d6125cc56 | |
| parent | 16cf460ca6c4aa1ccb05703743f61242ee90c53f (diff) | |
| download | haskell-4ec61411930495fc109be27993c176fd7aaf486d.tar.gz | |
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
| -rw-r--r-- | compiler/cmm/CmmLayoutStack.hs | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/compiler/cmm/CmmLayoutStack.hs b/compiler/cmm/CmmLayoutStack.hs index 5fea0e71ac..25a0ad6169 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 |
