HORIZON HASKELLDocslts/ghc-10.0.x77a86622026-10-31Search packagesCtrl K
Theme: |

GHC 10.0.0.20260917 · lts/ghc-10.0.x · 77a8662 · 2026-10-31

typetype CFG = EdgeInfoMap EdgeInfo

A control flow graph where edges have been annotated with a weight. Implemented as IntMap (IntMap <edgeData>) We must uphold the invariant that for each edge A -> B we must have: A entry B in the outer map. A entry B in the map we get when looking up A. Maintaining this invariant is useful as any failed lookup now indicates an actual error in code which might go unnoticed for a while otherwise.

datadata CfgEdge
#
Instances3Eq, Ord, Outputable
  • Eq CfgEdgeDefined in ghc-10.0.0.20260917 · GHC.CmmToAsm.CFG

    Careful! Since we assume there is at most one edge from A to B the Eq instance does not consider weight.

  • Ord CfgEdgeDefined in ghc-10.0.0.20260917 · GHC.CmmToAsm.CFG

    Edges are sorted ascending pointwise by weight, source and destination

  • Outputable CfgEdgeDefined in ghc-10.0.0.20260917 · GHC.CmmToAsm.CFG
newtypenewtype EdgeWeight
#
Instances7Enum, Eq, Fractional, Num, Ord, Real, …

Insert a block in the control flow between two other blocks. We pass a list of tuples (A,B,C) where * A -> C: Old edge * A -> B -> C : New Arc, where B is the new block. It's possible that a block has two jumps to the same block in the assembly code. However we still only store a single edge for these cases. We assign the old edge info to the edge A -> B and assign B -> C the weight of an unconditional jump.

valueedgeList :: CFG -> [Edge]

Returns a unordered list of all edges without weights

valueloopInfo :: HasDebugCallStack => CFG -> BlockId -> LoopInfo

Determine loop membership of blocks based on Dominator analysis. This is slower but gives loop levels instead of just loop membership. However it only detects natural loops. Irreducible control flow is not recognized even if it loops. But that is rare enough that we don't have to care about that special case.

We take in a CFG which has on its edges weights which are relative only to other edges originating from the same node.

We return a CFG for which each edge represents a GLOBAL weight. This means edge weights are comparable across the whole graph.

For irreducible control flow results might be imprecise, otherwise they are reliable.

The algorithm is based on the Paper "Static Branch Prediction and Program Profile Analysis" by Y Wu, JR Larus The only big change is that we go over the nodes in the body of loops in reverse post order. Which is required for diamond control flow to work probably.

We also apply a few prediction heuristics (based on the same paper)

The returned result represents frequences. For blocks it's the expected number of executions and for edges is the number of traversals.