@@ -45,6 +45,12 @@ private InitializeGroupInstruction getInitGroupInstruction(int i, IRFunction fun
45
45
predicate isLastInstructionForInitializeGroups ( Instruction instruction , IRFunction func ) {
46
46
exists ( int i |
47
47
instruction = getInitGroupInstruction ( i , func ) and
48
+ not exists ( getChi ( instruction ) ) and
49
+ not exists ( getInitGroupInstruction ( i + 1 , func ) )
50
+ )
51
+ or
52
+ exists ( int i |
53
+ instruction = getChi ( getInitGroupInstruction ( i , func ) ) and
48
54
not exists ( getInitGroupInstruction ( i + 1 , func ) )
49
55
)
50
56
or
@@ -69,6 +75,11 @@ private module Cached {
69
75
hasChiNode ( _, primaryInstruction )
70
76
}
71
77
78
+ cached
79
+ predicate hasChiNodeAfterInitializeGroup ( InitializeGroupInstruction initGroup ) {
80
+ hasChiNodeAfterInitializeGroup ( _, initGroup )
81
+ }
82
+
72
83
cached
73
84
predicate hasUnreachedInstructionCached ( IRFunction irFunc ) {
74
85
exists ( OldIR:: Instruction oldInstruction |
@@ -175,9 +186,18 @@ private module Cached {
175
186
or
176
187
// Chi instructions track virtual variables, and therefore a chi instruction is
177
188
// conflated if it's associated with the aliased virtual variable.
178
- exists ( OldInstruction oldInstruction | instruction = getChi ( oldInstruction ) |
179
- Alias:: getResultMemoryLocation ( oldInstruction ) .getVirtualVariable ( ) instanceof
189
+ exists ( Instruction input | instruction = getChi ( input ) |
190
+ instruction = getChi ( input ) and
191
+ Alias:: getResultMemoryLocation ( input ) .getVirtualVariable ( ) instanceof
180
192
Alias:: AliasedVirtualVariable
193
+ or
194
+ // A chi following an `InitializeGroupInstruction` only happens when the virtual
195
+ // variable of the grouped memory location is `{AllAliasedMemory}`.
196
+ exists ( Alias:: GroupedMemoryLocation gml |
197
+ instruction = getChi ( input ) and
198
+ input = initializeGroup ( gml .getGroup ( ) ) and
199
+ gml .getVirtualVariable ( ) instanceof Alias:: AliasedVirtualVariable
200
+ )
181
201
)
182
202
or
183
203
// Phi instructions track locations, and therefore a phi instruction is
@@ -246,7 +266,11 @@ private module Cached {
246
266
hasMemoryOperandDefinition ( oldInstruction , oldOperand , overlap , result )
247
267
)
248
268
or
249
- instruction = getChi ( getOldInstruction ( result ) ) and
269
+ (
270
+ instruction = getChi ( getOldInstruction ( result ) )
271
+ or
272
+ instruction = getChi ( result .( InitializeGroupInstruction ) )
273
+ ) and
250
274
tag instanceof ChiPartialOperandTag and
251
275
overlap instanceof MustExactlyOverlap
252
276
or
@@ -365,6 +389,18 @@ private module Cached {
365
389
result = getNewPhiOperandDefinitionFromOldSsa ( instr , newPredecessorBlock , overlap )
366
390
}
367
391
392
+ private ChiInstruction getChiAfterInitializeGroup ( int i , IRFunction func ) {
393
+ result =
394
+ rank [ i + 1 ] ( VariableGroup vg , InitializeGroupInstruction initGroup , ChiInstruction chi , int r |
395
+ initGroup .getEnclosingIRFunction ( ) = func and
396
+ chi = getChi ( initGroup ) and
397
+ initGroup = initializeGroup ( vg ) and
398
+ r = vg .getInitializationOrder ( )
399
+ |
400
+ chi order by r
401
+ )
402
+ }
403
+
368
404
cached
369
405
Instruction getChiInstructionTotalOperand ( ChiInstruction chiInstr ) {
370
406
exists (
@@ -378,6 +414,19 @@ private module Cached {
378
414
definitionReachesUse ( vvar , defBlock , defRank , useBlock , useRank ) and
379
415
result = getDefinitionOrChiInstruction ( defBlock , defOffset , vvar , _)
380
416
)
417
+ or
418
+ exists ( InitializeGroupInstruction initGroup , IRFunction func |
419
+ chiInstr = getChi ( initGroup ) and
420
+ func = initGroup .getEnclosingIRFunction ( )
421
+ |
422
+ chiInstr = getChiAfterInitializeGroup ( 0 , func ) and
423
+ isFirstInstructionBeforeInitializeGroup ( result , func )
424
+ or
425
+ exists ( int i |
426
+ chiInstr = getChiAfterInitializeGroup ( i + 1 , func ) and
427
+ result = getChiAfterInitializeGroup ( i , func )
428
+ )
429
+ )
381
430
}
382
431
383
432
cached
@@ -407,8 +456,20 @@ private module Cached {
407
456
exists ( int i , IRFunction func |
408
457
func = instruction .getEnclosingIRFunction ( ) and
409
458
instruction = getInitGroupInstruction ( i , func ) and
410
- result = getInitGroupInstruction ( i + 1 , func ) and
411
459
kind instanceof GotoEdge
460
+ |
461
+ if hasChiNodeAfterInitializeGroup ( _, instruction )
462
+ then result = getChi ( instruction )
463
+ else result = getInitGroupInstruction ( i + 1 , func )
464
+ )
465
+ or
466
+ exists ( int i , IRFunction func , InitializeGroupInstruction initGroup |
467
+ func = instruction .getEnclosingIRFunction ( ) and
468
+ instruction = getChi ( initGroup ) and
469
+ initGroup = getInitGroupInstruction ( i , func ) and
470
+ kind instanceof GotoEdge
471
+ |
472
+ result = getInitGroupInstruction ( i + 1 , func )
412
473
)
413
474
}
414
475
@@ -503,6 +564,11 @@ private module Cached {
503
564
instr = initializeGroup ( vg ) and
504
565
result = vg .getIRFunction ( ) .getFunction ( )
505
566
)
567
+ or
568
+ exists ( InitializeGroupInstruction initGroup |
569
+ instr = chiInstruction ( initGroup ) and
570
+ result = getInstructionAst ( initGroup )
571
+ )
506
572
}
507
573
508
574
cached
@@ -515,9 +581,11 @@ private module Cached {
515
581
)
516
582
or
517
583
exists ( Instruction primaryInstr , Alias:: VirtualVariable vvar |
518
- instr = chiInstruction ( primaryInstr ) and
519
- hasChiNode ( vvar , primaryInstr ) and
520
- result = vvar .getType ( )
584
+ instr = chiInstruction ( primaryInstr ) and result = vvar .getType ( )
585
+ |
586
+ hasChiNode ( vvar , primaryInstr )
587
+ or
588
+ hasChiNodeAfterInitializeGroup ( vvar , primaryInstr )
521
589
)
522
590
or
523
591
exists ( Alias:: VariableGroup vg |
@@ -564,7 +632,7 @@ private module Cached {
564
632
result = blockStartInstr .getEnclosingIRFunction ( )
565
633
)
566
634
or
567
- exists ( OldInstruction primaryInstr |
635
+ exists ( Instruction primaryInstr |
568
636
instr = chiInstruction ( primaryInstr ) and result = primaryInstr .getEnclosingIRFunction ( )
569
637
)
570
638
or
@@ -587,14 +655,16 @@ private module Cached {
587
655
instruction = getChi ( oldInstruction ) and
588
656
result = getNewInstruction ( oldInstruction )
589
657
)
658
+ or
659
+ instruction = getChi ( result .( InitializeGroupInstruction ) )
590
660
}
591
661
}
592
662
593
663
private Instruction getNewInstruction ( OldInstruction instr ) { getOldInstruction ( result ) = instr }
594
664
595
665
private OldInstruction getOldInstruction ( Instruction instr ) { instr = result }
596
666
597
- private ChiInstruction getChi ( OldInstruction primaryInstr ) { result = chiInstruction ( primaryInstr ) }
667
+ private ChiInstruction getChi ( Instruction primaryInstr ) { result = chiInstruction ( primaryInstr ) }
598
668
599
669
private PhiInstruction getPhi ( OldBlock defBlock , Alias:: MemoryLocation defLocation ) {
600
670
result = phiInstruction ( defBlock .getFirstInstruction ( ) , defLocation )
@@ -615,6 +685,16 @@ private predicate hasChiNode(Alias::VirtualVariable vvar, OldInstruction def) {
615
685
)
616
686
}
617
687
688
+ private predicate hasChiNodeAfterInitializeGroup (
689
+ Alias:: AliasedVirtualVariable vvar , InitializeGroupInstruction initGroup
690
+ ) {
691
+ exists ( Alias:: GroupedMemoryLocation defLocation |
692
+ initGroup = initializeGroup ( defLocation .getGroup ( ) ) and
693
+ defLocation .getVirtualVariable ( ) = vvar and
694
+ Alias:: getOverlap ( defLocation , vvar ) instanceof MayPartiallyOverlap
695
+ )
696
+ }
697
+
618
698
private import PhiInsertion
619
699
620
700
/**
@@ -781,7 +861,10 @@ module DefUse {
781
861
pragma [ inline_late]
782
862
private int getNonChiOffset ( int index , OldBlock block ) {
783
863
exists ( IRFunction func | func = block .getEnclosingIRFunction ( ) |
784
- if getNewBlock ( block ) = func .getEntryBlock ( )
864
+ if
865
+ getNewBlock ( block ) = func .getEntryBlock ( ) and
866
+ not block .getInstruction ( index ) instanceof InitializeNonLocalInstruction and
867
+ not block .getInstruction ( index ) instanceof AliasedDefinitionInstruction
785
868
then result = 2 * ( index + count ( VariableGroup vg | vg .getIRFunction ( ) = func ) )
786
869
else result = 2 * index
787
870
)
@@ -794,7 +877,7 @@ module DefUse {
794
877
/**
795
878
* Gets the `Instruction` for the definition at offset `defOffset` in block `defBlock`.
796
879
*/
797
- Instruction getDefinitionOrChiInstruction (
880
+ private Instruction getDefinitionOrChiInstruction0 (
798
881
OldBlock defBlock , int defOffset , Alias:: MemoryLocation defLocation ,
799
882
Alias:: MemoryLocation actualDefLocation
800
883
) {
@@ -837,10 +920,38 @@ module DefUse {
837
920
gml .getGroup ( ) = vg and
838
921
vg .getIRFunction ( ) .getEntryBlock ( ) = defBlock and
839
922
initGroup = initializeGroup ( vg ) and
840
- ( defLocation = gml or defLocation = gml .getVirtualVariable ( ) ) and
923
+ ( defLocation = gml or defLocation = gml .getVirtualVariable ( ) )
924
+ |
841
925
result = initGroup and
842
926
defOffset = 2 * index and
843
927
actualDefLocation = defLocation
928
+ or
929
+ result = getChi ( initGroup ) and
930
+ defOffset = 2 * index + 1 and
931
+ actualDefLocation = defLocation .getVirtualVariable ( )
932
+ )
933
+ }
934
+
935
+ private ChiInstruction remapGetDefinitionOrChiInstruction ( Instruction oldResult ) {
936
+ exists ( IRFunction func |
937
+ isFirstInstructionBeforeInitializeGroup ( oldResult , func ) and
938
+ isLastInstructionForInitializeGroups ( result , func )
939
+ )
940
+ }
941
+
942
+ Instruction getDefinitionOrChiInstruction (
943
+ OldBlock defBlock , int defOffset , Alias:: MemoryLocation defLocation ,
944
+ Alias:: MemoryLocation actualDefLocation
945
+ ) {
946
+ exists ( Instruction oldResult |
947
+ oldResult =
948
+ getDefinitionOrChiInstruction0 ( defBlock , defOffset , defLocation , actualDefLocation ) and
949
+ (
950
+ result = remapGetDefinitionOrChiInstruction ( oldResult )
951
+ or
952
+ not exists ( remapGetDefinitionOrChiInstruction ( oldResult ) ) and
953
+ result = oldResult
954
+ )
844
955
)
845
956
}
846
957
@@ -986,14 +1097,16 @@ module DefUse {
986
1097
else offset = getNonChiOffset ( index , block ) // The use will be connected to the definition on the original instruction.
987
1098
)
988
1099
or
989
- exists ( InitializeGroupInstruction initGroup , int index , VariableGroup vg |
1100
+ exists ( InitializeGroupInstruction initGroup , int index , Overlap overlap , VariableGroup vg |
990
1101
initGroup .getEnclosingIRFunction ( ) .getEntryBlock ( ) = getNewBlock ( block ) and
991
1102
vg = defLocation .( Alias:: GroupedMemoryLocation ) .getGroup ( ) and
992
1103
// EnterFunction + AliasedDefinition + InitializeNonLocal + index
993
1104
index = 3 + vg .getInitializationOrder ( ) and
994
1105
initGroup = initializeGroup ( vg ) and
995
- exists ( Alias:: getOverlap ( defLocation , useLocation ) ) and
996
- offset = 2 * index
1106
+ overlap = Alias:: getOverlap ( defLocation , useLocation ) and
1107
+ if overlap instanceof MayPartiallyOverlap and hasChiNodeAfterInitializeGroup ( initGroup )
1108
+ then offset = 2 * index + 1 // The use will be connected to the definition on the `Chi` instruction.
1109
+ else offset = 2 * index // The use will be connected to the definition on the original instruction.
997
1110
)
998
1111
}
999
1112
@@ -1208,6 +1321,8 @@ module Ssa {
1208
1321
1209
1322
predicate hasChiInstruction = Cached:: hasChiInstructionCached / 1 ;
1210
1323
1324
+ predicate hasChiNodeAfterInitializeGroup = Cached:: hasChiNodeAfterInitializeGroup / 1 ;
1325
+
1211
1326
predicate hasUnreachedInstruction = Cached:: hasUnreachedInstructionCached / 1 ;
1212
1327
1213
1328
class VariableGroup = Alias:: VariableGroup ;
0 commit comments