@@ -780,6 +780,217 @@ _lexical_ in order to specify this property for all contributing lifetimes.
780780For details see [ Variable Lifetimes] ( Ownership.md#variable-lifetimes ) in the
781781Ownership document.
782782
783+ # Dominance
784+
785+ ## Value and instruction dominance
786+
787+ Whenever an instruction uses a [ value] ( #values-and-operands ) as an
788+ operand, the definition of the value must dominate the instruction.
789+ This is a common concept across all SSA-like representations. SIL
790+ uses a standard definition of dominance, modified slightly to account
791+ for SIL's use of basic block arguments rather than phi instructions:
792+
793+ - The value ` undef ` always dominates an instruction.
794+
795+ - An instruction result ` R ` dominates an instruction ` I ` if the
796+ instruction that defines ` R ` dominates ` I ` .
797+
798+ - An argument of a basic block ` B ` dominates an instruction ` I ` if all
799+ initial paths passing through ` I ` must also pass through the start
800+ of ` B ` .
801+
802+ An instruction ` D ` dominates another instruction ` I ` if they are
803+ different instructions and all initial paths passing through ` I `
804+ must also pass through ` D ` .
805+
806+ See [ below] ( #definition-of-a-path ) for the formal definition of an
807+ initial path.
808+
809+ ## Basic block dominance
810+
811+ A basic block ` B1 ` dominates a basic block ` B2 ` if they are different
812+ blocks and if all initial paths passing through the start of ` B2 ` must
813+ also pass through through the start of ` B1 ` .
814+
815+ This relationship between blocks can be thought of as creating a
816+ directed acyclic graph of basic blocks, called the * dominance tree* .
817+ The dominance tree is not directly represented in SIL; it is just
818+ an emergent property of the dominance requirement on SIL functions.
819+
820+ ## Joint post-dominance
821+
822+ Certain instructions are required to have a * joint post-dominance*
823+ relationship with certain other instructions. Informally, this means
824+ that all terminating paths through the first instruction must
825+ eventually pass through one of the others. This is common for
826+ instructions that define a scope in the SIL function, such as
827+ ` alloc_stack ` and ` begin_access ` .
828+
829+ The dominating instruction is called the * scope instruction* ,
830+ and the post-dominating instructions are called the * scope-ending
831+ instructions* . The specific joint post-dominance requirement
832+ defines the set of instructions that count as scope-ending
833+ instructions for the begin instruction.
834+
835+ For example, an ` alloc_stack ` instruction must be jointly
836+ post-dominated by the set of ` dealloc_stack ` instructions
837+ whose operand is the result of the ` alloc_stack ` . The
838+ ` alloc_stack ` is the scope instruction, and the ` dealloc_stack ` s
839+ are the scope-ending instructions.
840+
841+ The * scope* of a joint post-dominance relationship is the set
842+ of all points in the function following the scope instruction
843+ but prior to a scope-ending instruction. Making this precisely
844+ defined is part of the point of the joint post-dominance rules.
845+ A formal definition is given later.
846+
847+ In SIL, if an instruction acts as a scope instruction, it always
848+ has exactly one set of scope-ending instructions associated
849+ with it, and so it forms exactly one scope. People will therefore
850+ often talk about, e.g., the scope of an ` alloc_stack ` , meaning
851+ the scope between it and its ` dealloc_stack ` s. Furthermore,
852+ there are no instructions in SIL which act as scope-ending
853+ instructions for multiple scopes.
854+
855+ A scope instruction ` I ` is jointly post-dominated by its
856+ scope-ending instructions if:
857+
858+ - All initial paths that pass through a scope-ending instruction
859+ of ` I ` must also pass through ` I ` . (This is just the normal
860+ dominance rule, and it is typically already required by the
861+ definition of the joint post-dominance relationship. For example,
862+ a ` dealloc_stack ` must be dominated by its associated
863+ ` alloc_stack ` because it uses its result as an operand.)
864+
865+ - All initial paths that pass through ` I ` twice must also pass
866+ through a scope-ending instruction of ` I ` in between.
867+
868+ - All initial paths that pass through a scope-ending instruction
869+ of ` I ` twice must also pass through ` I ` in between.
870+
871+ - All terminating initial paths that pass through ` I ` must also
872+ pass through a scope-ending instruction of ` I ` .
873+
874+ In other words, all paths must strictly alternate between ` I `
875+ and its scope-ending instructions, starting with ` I ` and (if
876+ the path exits) ending with a scope-ending instruction.
877+
878+ Note that a scope-ending instruction does not need to appear on
879+ a path following a scope instruction if the path doesn't exit
880+ the function. In fact, a function needn't include any scope-ending
881+ instructions for a particular scope instruction if all paths from
882+ that point are non-terminating, such as by ending in ` unreachable `
883+ or containing an infinite loop.
884+
885+ A scope instruction ` I ` is * coherently* jointly post-dominated
886+ by its scope-ending instructions if there is no point in the
887+ function for which it is possible to construct two paths, both
888+ ending in that point, which differ by whether they most recently
889+ passed through ` I ` or one of its scope-ending instructions.
890+ This is always true for points from which it is possible to
891+ construct a terminating path, but it can be false for dead-end
892+ points.
893+
894+ Several important joint post-dominance requirements in SIL
895+ do not require coherence, including the stack-allocation rule.
896+ Non-coherence allows optimizations to be more aggressive
897+ across control flow that enters dead-end regions. Note that
898+ control flow internal to a dead-end region is not special
899+ in this way, so SIL analyses must not not simply check
900+ whether a destination block is dead-end.
901+
902+ The * scope* defined by a joint post-dominance relationship for a
903+ scope instruction ` I ` is the set of points in the function for
904+ which:
905+
906+ - there exists an initial path that ends at that point and
907+ passes through ` I ` , but
908+
909+ - there does not an exist a simple initial path that ends at
910+ that point and passes through a scope-ending instruction
911+ of ` I ` .
912+
913+ In the absence of coherence, this second rule conservatively
914+ shrinks the scope to the set of points that cannot possibly
915+ have passed through a scope-ending instruction.
916+
917+ For a coherent joint post-dominance relationship, this
918+ definition simplifies to the set of points for which there
919+ exists an initial path that ends at that point and passes
920+ through ` I ` , but which does not pass through a scope-ending
921+ instruction of ` I ` .
922+
923+ Note that the point before a scope-ending instruction is always
924+ within the scope.
925+
926+ ## Definition of a path
927+
928+ A * point* in a SIL function is the moment before an instruction.
929+ Every basic block has an entry point, which is the point before
930+ its first instruction. The entry point of the entry block is also
931+ called the entry point of the function.
932+
933+ A path through a SIL function is a path (in the usual graph-theory
934+ sense) in the underlying directed graph of points, in which:
935+
936+ - every point in the SIL function is a vertex in the graph,
937+
938+ - each non-terminator instruction creates an edge from the point
939+ before it to the point after it, and
940+
941+ - each terminator instruction creates edges from the point before
942+ the terminator to the initial point of each its successor blocks.
943+
944+ A path is said to pass through an instruction if it includes
945+ any of the edges created by that instruction. A path is said to
946+ pass through the start of a basic block if it visits the entry
947+ point of that block.
948+
949+ An * initial path* is a path which begins at the entry point of the
950+ function. A * terminating path* is a path which ends at the point
951+ before an exiting instruction, such as ` return ` or ` throw ` .
952+
953+ Note that the dominance rules generally require only an initial path,
954+ not a terminating path. A path that simply stops in the middle of a
955+ block still counts for dominance. Among other things, this ensures that
956+ dominance holds in blocks that are part of an infinite loop.
957+
958+ A * dead-end point* is a point which cannot be included on any
959+ terminating path. A * dead-end block* is a block for which the
960+ entry point is a dead-end point. A * dead-end region* is a
961+ strongly-connected component of the CFG containing only dead-end
962+ blocks.
963+
964+ Note also that paths consider successors without regard to the
965+ nature of the terminator. Paths that are provably impossible because
966+ of value relationships still count for dominance. For example,
967+ consider the following function:
968+
969+ ```
970+ bb0(%cond : $Builtin.Int1):
971+ cond_br %cond, bb1, b22
972+ bb1:
973+ %value = integer_literal $Builtin.Int32, 0
974+ br bb3
975+ bb2:
976+ br bb3
977+ bb3:
978+ cond_br %cond, bb4, bb5
979+ bb4:
980+ %twice_value = builtin "add_Int32"(%value, %value) : $Builtin.Int32
981+ br bb6
982+ bb5:
983+ br bb6
984+ bb6:
985+ ret %cond
986+ ```
987+
988+ Dynamically, it is impossible to reach the ` builtin ` instruction
989+ without passing through the definition of ` %value ` : to reach
990+ the ` builtin ` , ` %cond ` must be ` true ` , and so the first ` cond_br `
991+ must have branched to ` bb1 ` . This is not taken into consideration
992+ by dominance, and so this function is ill-formed.
993+
783994# Debug Information
784995
785996Each instruction may have a debug location and a SIL scope reference at
@@ -1364,48 +1575,39 @@ stack deallocation instructions. It can even be paired with no
13641575instructions at all; by the rules below, this can only happen in
13651576non-terminating functions.
13661577
1367- - At any point in a SIL function, there is an ordered list of stack
1368- allocation instructions called the * active allocations list * .
1578+ - All stack allocation instructions must be jointly post-dominated
1579+ by stack deallocation instructions paired with them .
13691580
1370- - The active allocations list is defined to be empty at the initial
1371- point of the entry block of the function.
1581+ - No path through the function that passes through a stack allocation
1582+ instruction ` B ` , having already passed a stack allocation
1583+ instruction ` A ` , may subsequently pass through a stack deallocation
1584+ instruction paired with ` A ` without first passing through a stack
1585+ deallocation instruction paired with ` B ` .
13721586
1373- - The active allocations list is required to be the same at the
1374- initial point of any successor block as it is at the final point of
1375- any predecessor block. Note that this also requires all
1376- predecessors/successors of a given block to have the same
1377- final/initial active allocations lists.
1587+ These two rules statically enforce that all stack allocations are
1588+ properly nested. In simpler terms:
13781589
1379- In other words, the set of active stack allocations must be the same
1380- at a given place in the function no matter how it was reached .
1590+ - At every point in a SIL function, there is an ordered list of stack
1591+ allocation instructions called the * active allocations list * .
13811592
1382- - The active allocations list for the point following a stack
1383- allocation instruction is defined to be the result of adding that
1384- instruction to the end of the active allocations list for the point
1385- preceding the instruction.
1593+ - The active allocations list is empty at the start of the entry block
1594+ of the function, and it must be empty again whenever an instruction
1595+ that exits the function is reached, like ` return ` or ` throw ` .
13861596
1387- - The active allocations list for the point following a stack
1388- deallocation instruction is defined to be the result of removing the
1389- instruction from the end of the active allocations list for the
1390- point preceding the instruction. The active allocations list for the
1391- preceding point is required to be non-empty, and the last
1392- instruction in it must be paired with the deallocation instruction.
1597+ - Whenever a stack allocation instruction is reached, it is added to
1598+ the end of the list.
13931599
1394- In other words, all stack allocations must be deallocated in
1395- last-in, first-out order, aka stack order.
1600+ - Whenever a stack deallocation instruction is reached, its paired
1601+ stack allocation instruction must be at the end of the list, which it
1602+ is then removed from.
13961603
1397- - The active allocations list for the point following any other
1398- instruction is defined to be the same as the active allocations list
1399- for the point preceding the instruction.
1604+ - The active allocations list always be the same on both sides of a
1605+ control flow edge. This implies both that all successors of a block
1606+ must start with the same list and that all predecessors of a block
1607+ must end with the same list.
14001608
1401- - The active allocations list is required to be empty prior to
1402- ` return ` or ` throw ` instructions.
1403-
1404- In other words, all stack allocations must be deallocated prior to
1405- exiting the function.
1406-
1407- Note that these rules implicitly prevent an allocation instruction from
1408- still being active when it is reached.
1609+ Note that these rules implicitly prevent stack allocations from leaking
1610+ or being double-freed.
14091611
14101612The control-flow rule forbids certain patterns that would theoretically
14111613be useful, such as conditionally performing an allocation around an
@@ -1414,6 +1616,12 @@ to use, however, as it is illegal to locally abstract over addresses,
14141616and therefore a conditional allocation cannot be used in the
14151617intermediate operation anyway.
14161618
1619+ The stack discipline rules do not require coherent joint post-dominance.
1620+ This means that different control-flow paths entering a dead-end region
1621+ may disagree about the state of the stack. In such a region, the stack
1622+ discipline rules permit further allocation, but nothing that was not
1623+ allocated within the region can be deallocated.
1624+
14171625# Structural type matching for pack indices
14181626
14191627In order to catch type errors in applying pack indices, SIL requires the
0 commit comments