@@ -511,7 +511,79 @@ private module Cached {
511
511
* that node is its successor in the new successor relation, and the Chi node's successors are
512
512
* the new instructions generated from the successors of the old instruction.
513
513
*
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}`.
515
587
*/
516
588
cached
517
589
Instruction getInstructionSuccessor ( Instruction instruction , EdgeKind kind ) {
0 commit comments