Commit bec3c049 authored by Jan Stolarek's avatar Jan Stolarek

Drop proc-points that don't exist in the graph (#8205)

On some architectures it might happen that stack layout pass will
invalidate the list of calculated procpoints by dropping some of
them. We fix this by checking whether a proc-point is in a graph
at the beginning of proc-point analysis. This is a speculative
fix for #8205.
parent 43111a0b
...@@ -122,12 +122,12 @@ cpsTop hsc_env proc = ...@@ -122,12 +122,12 @@ cpsTop hsc_env proc =
splitAtProcPoints dflags l call_pps proc_points pp_map splitAtProcPoints dflags l call_pps proc_points pp_map
(CmmProc h l v g) (CmmProc h l v g)
dumps Opt_D_dump_cmm_split "Post splitting" gs dumps Opt_D_dump_cmm_split "Post splitting" gs
------------- Populate info tables with stack info ----------------- ------------- Populate info tables with stack info -----------------
gs <- {-# SCC "setInfoTableStackMap" #-} gs <- {-# SCC "setInfoTableStackMap" #-}
return $ map (setInfoTableStackMap dflags stackmaps) gs return $ map (setInfoTableStackMap dflags stackmaps) gs
dumps Opt_D_dump_cmm_info "after setInfoTableStackMap" gs dumps Opt_D_dump_cmm_info "after setInfoTableStackMap" gs
----------- Control-flow optimisations ----------------------------- ----------- Control-flow optimisations -----------------------------
gs <- {-# SCC "cmmCfgOpts(2)" #-} gs <- {-# SCC "cmmCfgOpts(2)" #-}
return $ if optLevel dflags >= 1 return $ if optLevel dflags >= 1
...@@ -147,7 +147,7 @@ cpsTop hsc_env proc = ...@@ -147,7 +147,7 @@ cpsTop hsc_env proc =
g <- {-# SCC "setInfoTableStackMap" #-} g <- {-# SCC "setInfoTableStackMap" #-}
return $ setInfoTableStackMap dflags stackmaps g return $ setInfoTableStackMap dflags stackmaps g
dump' Opt_D_dump_cmm_info "after setInfoTableStackMap" g dump' Opt_D_dump_cmm_info "after setInfoTableStackMap" g
----------- Control-flow optimisations ----------------------------- ----------- Control-flow optimisations -----------------------------
g <- {-# SCC "cmmCfgOpts(2)" #-} g <- {-# SCC "cmmCfgOpts(2)" #-}
return $ if optLevel dflags >= 1 return $ if optLevel dflags >= 1
......
...@@ -30,7 +30,7 @@ import Hoopl ...@@ -30,7 +30,7 @@ import Hoopl
-- Compute a minimal set of proc points for a control-flow graph. -- Compute a minimal set of proc points for a control-flow graph.
-- Determine a protocol for each proc point (which live variables will -- Determine a protocol for each proc point (which live variables will
-- be passed as arguments and which will be on the stack). -- be passed as arguments and which will be on the stack).
{- {-
A proc point is a basic block that, after CPS transformation, will A proc point is a basic block that, after CPS transformation, will
...@@ -83,6 +83,33 @@ most once per iteration, then recompute the reachability information. ...@@ -83,6 +83,33 @@ most once per iteration, then recompute the reachability information.
arbitrary, and I don't know if the choice affects the final solution, arbitrary, and I don't know if the choice affects the final solution,
so I don't know if the number of proc points chosen is the so I don't know if the number of proc points chosen is the
minimum---but the set will be minimal. minimum---but the set will be minimal.
Note [Proc-point analysis]
~~~~~~~~~~~~~~~~~~~~~~~~~~
Given a specified set of proc-points (a set of block-ids), "proc-point
analysis" figures out, for every block, which proc-point it belongs to.
All the blocks belonging to proc-point P will constitute a single
top-level C procedure.
A non-proc-point block B "belongs to" a proc-point P iff B is
reachable from P without going through another proc-point.
Invariant: a block B should belong to at most one proc-point; if it
belongs to two, that's a bug.
Note [Non-existing proc-points]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
On some architectures it might happen that the list of proc-points
computed before stack layout pass will be invalidated by the stack
layout. This will happen if stack layout removes from the graph
blocks that were determined to be proc-points. Later on in the pipeline
we use list of proc-points to perform [Proc-point analysis], but
if a proc-point does not exist anymore then we will get compiler panic.
See #8205.
-} -}
type ProcPointSet = BlockSet type ProcPointSet = BlockSet
...@@ -104,11 +131,14 @@ instance Outputable Status where ...@@ -104,11 +131,14 @@ instance Outputable Status where
procPointAnalysis :: ProcPointSet -> CmmGraph -> UniqSM (BlockEnv Status) procPointAnalysis :: ProcPointSet -> CmmGraph -> UniqSM (BlockEnv Status)
-- Once you know what the proc-points are, figure out -- Once you know what the proc-points are, figure out
-- what proc-points each block is reachable from -- what proc-points each block is reachable from
procPointAnalysis procPoints g = -- See Note [Proc-point analysis]
procPointAnalysis procPoints g@(CmmGraph {g_graph = graph}) =
-- pprTrace "procPointAnalysis" (ppr procPoints) $ -- pprTrace "procPointAnalysis" (ppr procPoints) $
dataflowAnalFwdBlocks g initProcPoints $ analFwd lattice forward dataflowAnalFwdBlocks g initProcPoints $ analFwd lattice forward
where initProcPoints = [(id, ProcPoint) | id <- setElems procPoints] where initProcPoints = [(id, ProcPoint) | id <- setElems procPoints,
id `setMember` labelsInGraph ]
-- See Note [Non-existing proc-points]
labelsInGraph = labelsDefined graph
-- transfer equations -- transfer equations
forward :: FwdTransfer CmmNode Status forward :: FwdTransfer CmmNode Status
...@@ -218,7 +248,7 @@ splitAtProcPoints dflags entry_label callPPs procPoints procMap ...@@ -218,7 +248,7 @@ splitAtProcPoints dflags entry_label callPPs procPoints procMap
Just (ReachedBy set) -> Just (ReachedBy set) ->
case setElems set of case setElems set of
[] -> graphEnv [] -> graphEnv
[id] -> add graphEnv id bid b [id] -> add graphEnv id bid b
_ -> panic "Each block should be reachable from only one ProcPoint" _ -> panic "Each block should be reachable from only one ProcPoint"
Nothing -> graphEnv Nothing -> graphEnv
where bid = entryLabel b where bid = entryLabel b
...@@ -396,9 +426,9 @@ dataflow pass. One might attempt to use this simple lattice: ...@@ -396,9 +426,9 @@ dataflow pass. One might attempt to use this simple lattice:
data Location = Unknown data Location = Unknown
| InProc BlockId -- node is in procedure headed by the named proc point | InProc BlockId -- node is in procedure headed by the named proc point
| ProcPoint -- node is itself a proc point | ProcPoint -- node is itself a proc point
At a join, a node in two different blocks becomes a proc point. At a join, a node in two different blocks becomes a proc point.
The difficulty is that the change of information during iterative The difficulty is that the change of information during iterative
computation may promote a node prematurely. Here's a program that computation may promote a node prematurely. Here's a program that
illustrates the difficulty: illustrates the difficulty:
...@@ -432,19 +462,19 @@ are no other proc points that directly reach L2. ...@@ -432,19 +462,19 @@ are no other proc points that directly reach L2.
It may be worthwhile to attempt the Adams optimization by rewriting It may be worthwhile to attempt the Adams optimization by rewriting
the graph before the assignment of proc-point protocols. Here are a the graph before the assignment of proc-point protocols. Here are a
couple of rules: couple of rules:
g() returns to k; g() returns to L;
k: CopyIn c ress; goto L:
... ==> ...
L: // no CopyIn node here L: CopyIn c ress;
g() returns to k; g() returns to L;
k: CopyIn c ress; goto L:
... ==> ...
L: // no CopyIn node here L: CopyIn c ress;
And when c == c' and ress == ress', this also: And when c == c' and ress == ress', this also:
g() returns to k; g() returns to L; g() returns to k; g() returns to L;
k: CopyIn c ress; goto L: k: CopyIn c ress; goto L:
... ==> ... ... ==> ...
L: CopyIn c' ress' L: CopyIn c' ress' ; L: CopyIn c' ress' L: CopyIn c' ress' ;
In both cases the goal is to eliminate k. In both cases the goal is to eliminate k.
-} -}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment