@@ -15,6 +15,43 @@ private class OldInstruction = Reachability::ReachableInstruction;
15
15
16
16
import Cached
17
17
18
+ /**
19
+ * Holds if `instruction` is the first instruction that may be followed by
20
+ * an `InitializeGroup` instruction, and the enclosing function of
21
+ * `instruction` is `func`.
22
+ */
23
+ private predicate isFirstInstructionBeforeInitializeGroup ( Instruction instruction , IRFunction func ) {
24
+ instruction = getChi ( any ( OldIR:: InitializeNonLocalInstruction init ) ) and
25
+ func = instruction .getEnclosingIRFunction ( )
26
+ }
27
+
28
+ /** Gets the `i`'th `InitializeGroup` instruction in `func`. */
29
+ private InitializeGroupInstruction getInitGroupInstruction ( int i , IRFunction func ) {
30
+ exists ( Alias:: VariableGroup vg |
31
+ vg .getIRFunction ( ) = func and
32
+ vg .getInitializationOrder ( ) = i and
33
+ result = initializeGroup ( vg )
34
+ )
35
+ }
36
+
37
+ /**
38
+ * Holds if `instruction` is the last instruction in the chain of `InitializeGroup`
39
+ * instructions in `func`. The chain of instructions may be empty in which case
40
+ * `instruction` satisfies
41
+ * ```
42
+ * isFirstInstructionBeforeInitializeGroup(instruction, func)
43
+ * ```
44
+ */
45
+ predicate isLastInstructionForInitializeGroups ( Instruction instruction , IRFunction func ) {
46
+ exists ( int i |
47
+ instruction = getInitGroupInstruction ( i , func ) and
48
+ not exists ( getInitGroupInstruction ( i + 1 , func ) )
49
+ )
50
+ or
51
+ isFirstInstructionBeforeInitializeGroup ( instruction , func ) and
52
+ not exists ( getInitGroupInstruction ( 0 , func ) )
53
+ }
54
+
18
55
cached
19
56
private module Cached {
20
57
cached
@@ -356,14 +393,28 @@ private module Cached {
356
393
)
357
394
}
358
395
359
- /*
360
- * This adds Chi nodes to the instruction successor relation; if an instruction has a Chi node,
361
- * that node is its successor in the new successor relation, and the Chi node's successors are
362
- * the new instructions generated from the successors of the old instruction
363
- */
396
+ private InitializeGroupInstruction firstInstructionToInitializeGroup (
397
+ Instruction instruction , EdgeKind kind
398
+ ) {
399
+ exists ( IRFunction func |
400
+ isFirstInstructionBeforeInitializeGroup ( instruction , func ) and
401
+ result = getInitGroupInstruction ( 0 , func ) and
402
+ kind instanceof GotoEdge
403
+ )
404
+ }
364
405
365
- cached
366
- Instruction getInstructionSuccessor ( Instruction instruction , EdgeKind kind ) {
406
+ private Instruction getNextInitializeGroupInstruction ( Instruction instruction , EdgeKind kind ) {
407
+ exists ( int i , IRFunction func |
408
+ func = instruction .getEnclosingIRFunction ( ) and
409
+ instruction = getInitGroupInstruction ( i , func ) and
410
+ result = getInitGroupInstruction ( i + 1 , func ) and
411
+ kind instanceof GotoEdge
412
+ )
413
+ }
414
+
415
+ private Instruction getInstructionSuccessorAfterInitializeGroup0 (
416
+ Instruction instruction , EdgeKind kind
417
+ ) {
367
418
if hasChiNode ( _, getOldInstruction ( instruction ) )
368
419
then
369
420
result = getChi ( getOldInstruction ( instruction ) ) and
@@ -383,6 +434,35 @@ private module Cached {
383
434
)
384
435
}
385
436
437
+ private Instruction getInstructionSuccessorAfterInitializeGroup (
438
+ Instruction instruction , EdgeKind kind
439
+ ) {
440
+ exists ( IRFunction func , Instruction firstBeforeInitializeGroup |
441
+ isLastInstructionForInitializeGroups ( instruction , func ) and
442
+ isFirstInstructionBeforeInitializeGroup ( firstBeforeInitializeGroup , func ) and
443
+ result = getInstructionSuccessorAfterInitializeGroup0 ( firstBeforeInitializeGroup , kind )
444
+ )
445
+ }
446
+
447
+ /**
448
+ * This adds Chi nodes to the instruction successor relation; if an instruction has a Chi node,
449
+ * that node is its successor in the new successor relation, and the Chi node's successors are
450
+ * the new instructions generated from the successors of the old instruction.
451
+ *
452
+ * Furthermore, the entry block is augmented with `InitializeGroup` instructions.
453
+ */
454
+ cached
455
+ Instruction getInstructionSuccessor ( Instruction instruction , EdgeKind kind ) {
456
+ result = firstInstructionToInitializeGroup ( instruction , kind )
457
+ or
458
+ result = getNextInitializeGroupInstruction ( instruction , kind )
459
+ or
460
+ result = getInstructionSuccessorAfterInitializeGroup ( instruction , kind )
461
+ or
462
+ not isFirstInstructionBeforeInitializeGroup ( instruction , _) and
463
+ result = getInstructionSuccessorAfterInitializeGroup0 ( instruction , kind )
464
+ }
465
+
386
466
cached
387
467
Instruction getInstructionBackEdgeSuccessor ( Instruction instruction , EdgeKind kind ) {
388
468
exists ( OldInstruction oldInstruction |
@@ -699,7 +779,13 @@ private import DefUse
699
779
module DefUse {
700
780
bindingset [ index, block]
701
781
pragma [ inline_late]
702
- private int getNonChiOffset ( int index , OldBlock block ) { result = 2 * index }
782
+ private int getNonChiOffset ( int index , OldBlock block ) {
783
+ exists ( IRFunction func | func = block .getEnclosingIRFunction ( ) |
784
+ if getNewBlock ( block ) = func .getEntryBlock ( )
785
+ then result = 2 * ( index + count ( VariableGroup vg | vg .getIRFunction ( ) = func ) )
786
+ else result = 2 * index
787
+ )
788
+ }
703
789
704
790
bindingset [ index, block]
705
791
pragma [ inline_late]
@@ -736,6 +822,26 @@ module DefUse {
736
822
hasDefinition ( _, defLocation , defBlock , defOffset ) and
737
823
result = getPhi ( defBlock , defLocation ) and
738
824
actualDefLocation = defLocation
825
+ or
826
+ exists (
827
+ Alias:: VariableGroup vg , int index , InitializeGroupInstruction initGroup ,
828
+ Alias:: GroupedMemoryLocation gml
829
+ |
830
+ // Add 3 to account for the function prologue:
831
+ // v1(void) = EnterFunction
832
+ // m1(unknown) = AliasedDefinition
833
+ // m2(unknown) = InitializeNonLocal
834
+ index = 3 + vg .getInitializationOrder ( ) and
835
+ not gml .isMayAccess ( ) and
836
+ gml .isSome ( ) and
837
+ gml .getGroup ( ) = vg and
838
+ vg .getIRFunction ( ) .getEntryBlock ( ) = defBlock and
839
+ initGroup = initializeGroup ( vg ) and
840
+ ( defLocation = gml or defLocation = gml .getVirtualVariable ( ) ) and
841
+ result = initGroup and
842
+ defOffset = 2 * index and
843
+ actualDefLocation = defLocation
844
+ )
739
845
}
740
846
741
847
/**
@@ -879,6 +985,16 @@ module DefUse {
879
985
then offset = getChiOffset ( index , block ) // The use will be connected to the definition on the `Chi` instruction.
880
986
else offset = getNonChiOffset ( index , block ) // The use will be connected to the definition on the original instruction.
881
987
)
988
+ or
989
+ exists ( InitializeGroupInstruction initGroup , int index , VariableGroup vg |
990
+ initGroup .getEnclosingIRFunction ( ) .getEntryBlock ( ) = getNewBlock ( block ) and
991
+ vg = defLocation .( Alias:: GroupedMemoryLocation ) .getGroup ( ) and
992
+ // EnterFunction + AliasedDefinition + InitializeNonLocal + index
993
+ index = 3 + vg .getInitializationOrder ( ) and
994
+ initGroup = initializeGroup ( vg ) and
995
+ exists ( Alias:: getOverlap ( defLocation , useLocation ) ) and
996
+ offset = 2 * index
997
+ )
882
998
}
883
999
884
1000
/**
0 commit comments