@@ -511,7 +511,79 @@ private module Cached {
511511 * that node is its successor in the new successor relation, and the Chi node's successors are
512512 * the new instructions generated from the successors of the old instruction.
513513 *
514- * Furthermore, the entry block is augmented with `UninitializedGroup` instructions.
514+ * Furthermore, the entry block is augmented with `UninitializedGroup` instructions and `Chi`
515+ * instructions. For example, consider this example:
516+ * ```cpp
517+ * int x, y;
518+ * int* p;
519+ * if(b) {
520+ * p = &x;
521+ * escape(&x);
522+ * } else {
523+ * p = &y;
524+ * }
525+ * *p = 42;
526+ *
527+ * int z, w;
528+ * int* q;
529+ * if(b) {
530+ * q = &z;
531+ * } else {
532+ * q = &w;
533+ * }
534+ * *q = 43;
535+ * ```
536+ *
537+ * the unaliased IR for the entry block of this snippet is:
538+ * ```
539+ * v1(void) = EnterFunction :
540+ * m1(unknown) = AliasedDefinition :
541+ * m2(unknown) = InitializeNonLocal :
542+ * r1(glval<bool>) = VariableAddress[b] :
543+ * m3(bool) = InitializeParameter[b] : &:r1
544+ * r2(glval<int>) = VariableAddress[x] :
545+ * m4(int) = Uninitialized[x] : &:r2
546+ * r3(glval<int>) = VariableAddress[y] :
547+ * m5(int) = Uninitialized[y] : &:r3
548+ * r4(glval<int *>) = VariableAddress[p] :
549+ * m6(int *) = Uninitialized[p] : &:r4
550+ * r5(glval<bool>) = VariableAddress[b] :
551+ * r6(bool) = Load[b] : &:r5, m3
552+ * v2(void) = ConditionalBranch : r6
553+ * ```
554+ * and we need to transform this to aliased IR by inserting an `UninitializedGroup`
555+ * instruction for every `VariableGroup` memory location in the function. Furthermore,
556+ * if the `VariableGroup` memory location contains an allocation that escapes we need
557+ * to insert a `Chi` that writes the memory produced by `UninitializedGroup` into
558+ * `{AllAliasedMemory}`. For the above snippet we then end up with:
559+ * ```
560+ * v1(void) = EnterFunction :
561+ * m2(unknown) = AliasedDefinition :
562+ * m3(unknown) = InitializeNonLocal :
563+ * m4(unknown) = Chi : total:m2, partial:m3
564+ * m5(int) = UninitializedGroup[x,y] :
565+ * m6(unknown) = Chi : total:m4, partial:m5
566+ * m7(int) = UninitializedGroup[w,z] :
567+ * r1(glval<bool>) = VariableAddress[b] :
568+ * m8(bool) = InitializeParameter[b] : &:r1
569+ * r2(glval<int>) = VariableAddress[x] :
570+ * m10(int) = Uninitialized[x] : &:r2
571+ * m11(unknown) = Chi : total:m6, partial:m10
572+ * r3(glval<int>) = VariableAddress[y] :
573+ * m12(int) = Uninitialized[y] : &:r3
574+ * m13(unknown) = Chi : total:m11, partial:m12
575+ * r4(glval<int *>) = VariableAddress[p] :
576+ * m14(int *) = Uninitialized[p] : &:r4
577+ * r5(glval<bool>) = VariableAddress[b] :
578+ * r6(bool) = Load[b] : &:r5, m8
579+ * v2(void) = ConditionalBranch : r6
580+ * ```
581+ *
582+ * Here, the group `{x, y}` contains an allocation that escapes (`x`), so there
583+ * is a `Chi` after the `UninitializedGroup` that initializes the memory for the
584+ * `VariableGroup` containing `x`. None of the allocations in `{w, z}` escape so
585+ * there is no `Chi` following that the `UninitializedGroup` that initializes the
586+ * memory of `{w, z}`.
515587 */
516588 cached
517589 Instruction getInstructionSuccessor ( Instruction instruction , EdgeKind kind ) {
0 commit comments