@@ -48,6 +48,16 @@ private module SourceVariables {
48
48
* indirections) of this source variable.
49
49
*/
50
50
abstract BaseSourceVariable getBaseVariable ( ) ;
51
+
52
+ /** Holds if this variable is a glvalue. */
53
+ predicate isGLValue ( ) { none ( ) }
54
+
55
+ /**
56
+ * Gets the type of this source variable. If `isGLValue()` holds, then
57
+ * the type of this source variable should be thought of as "pointer
58
+ * to `getType()`".
59
+ */
60
+ abstract DataFlowType getType ( ) ;
51
61
}
52
62
53
63
class SourceIRVariable extends SourceVariable , TSourceIRVariable {
@@ -66,6 +76,12 @@ private module SourceVariables {
66
76
ind > 0 and
67
77
result = this .getIRVariable ( ) .toString ( ) + " indirection"
68
78
}
79
+
80
+ override predicate isGLValue ( ) { ind = 0 }
81
+
82
+ override DataFlowType getType ( ) {
83
+ if ind = 0 then result = var .getType ( ) else result = getTypeImpl ( var .getType ( ) , ind - 1 )
84
+ }
69
85
}
70
86
71
87
class CallVariable extends SourceVariable , TCallVariable {
@@ -84,6 +100,8 @@ private module SourceVariables {
84
100
ind > 0 and
85
101
result = "Call indirection"
86
102
}
103
+
104
+ override DataFlowType getType ( ) { result = getTypeImpl ( call .getResultType ( ) , ind ) }
87
105
}
88
106
}
89
107
@@ -530,15 +548,15 @@ predicate adjacentDefRead(DefOrUse defOrUse1, UseOrPhi use) {
530
548
exists ( IRBlock bb1 , int i1 , SourceVariable v |
531
549
defOrUse1 .asDefOrUse ( ) .hasIndexInBlock ( bb1 , i1 , v )
532
550
|
533
- exists ( IRBlock bb2 , int i2 , Definition def |
534
- adjacentDefRead ( pragma [ only_bind_into ] ( def ) , pragma [ only_bind_into ] ( bb1 ) ,
551
+ exists ( IRBlock bb2 , int i2 , DefinitionExt def |
552
+ adjacentDefReadExt ( pragma [ only_bind_into ] ( def ) , pragma [ only_bind_into ] ( bb1 ) ,
535
553
pragma [ only_bind_into ] ( i1 ) , pragma [ only_bind_into ] ( bb2 ) , pragma [ only_bind_into ] ( i2 ) ) and
536
554
def .getSourceVariable ( ) = v and
537
555
use .asDefOrUse ( ) .( UseImpl ) .hasIndexInBlock ( bb2 , i2 , v )
538
556
)
539
557
or
540
558
exists ( PhiNode phi |
541
- lastRefRedef ( _, bb1 , i1 , phi ) and
559
+ lastRefRedefExt ( _, bb1 , i1 , phi ) and
542
560
use .asPhi ( ) = phi and
543
561
phi .getSourceVariable ( ) = pragma [ only_bind_into ] ( v )
544
562
)
@@ -550,11 +568,18 @@ predicate adjacentDefRead(DefOrUse defOrUse1, UseOrPhi use) {
550
568
* flows to `useOrPhi`.
551
569
*/
552
570
private predicate globalDefToUse ( GlobalDef globalDef , UseOrPhi useOrPhi ) {
553
- exists ( IRBlock bb1 , int i1 , IRBlock bb2 , int i2 , SourceVariable v |
554
- globalDef .hasIndexInBlock ( bb1 , i1 , v ) and
555
- adjacentDefRead ( _, pragma [ only_bind_into ] ( bb1 ) , pragma [ only_bind_into ] ( i1 ) ,
556
- pragma [ only_bind_into ] ( bb2 ) , pragma [ only_bind_into ] ( i2 ) ) and
557
- useOrPhi .asDefOrUse ( ) .hasIndexInBlock ( bb2 , i2 , v )
571
+ exists ( IRBlock bb1 , int i1 , SourceVariable v | globalDef .hasIndexInBlock ( bb1 , i1 , v ) |
572
+ exists ( IRBlock bb2 , int i2 |
573
+ adjacentDefReadExt ( _, pragma [ only_bind_into ] ( bb1 ) , pragma [ only_bind_into ] ( i1 ) ,
574
+ pragma [ only_bind_into ] ( bb2 ) , pragma [ only_bind_into ] ( i2 ) ) and
575
+ useOrPhi .asDefOrUse ( ) .hasIndexInBlock ( bb2 , i2 , v )
576
+ )
577
+ or
578
+ exists ( PhiNode phi |
579
+ lastRefRedefExt ( _, bb1 , i1 , phi ) and
580
+ useOrPhi .asPhi ( ) = phi and
581
+ phi .getSourceVariable ( ) = pragma [ only_bind_into ] ( v )
582
+ )
558
583
)
559
584
}
560
585
@@ -666,17 +691,17 @@ private predicate ssaFlowImpl(SsaDefOrUse defOrUse, Node nodeFrom, Node nodeTo,
666
691
* Holds if `def` is the corresponding definition of
667
692
* the SSA library's `definition`.
668
693
*/
669
- private Definition ssaDefinition ( Def def ) {
694
+ private DefinitionExt ssaDefinition ( Def def ) {
670
695
exists ( IRBlock block , int i , SourceVariable sv |
671
696
def .hasIndexInBlock ( block , i , sv ) and
672
- result .definesAt ( sv , block , i )
697
+ result .definesAt ( sv , block , i , _ )
673
698
)
674
699
}
675
700
676
701
/** Gets a node that represents the prior definition of `node`. */
677
702
private Node getAPriorDefinition ( SsaDefOrUse defOrUse ) {
678
- exists ( IRBlock bb , int i , SourceVariable sv , Definition def , DefOrUse defOrUse0 |
679
- SsaCached :: lastRefRedef ( pragma [ only_bind_into ] ( def ) , pragma [ only_bind_into ] ( bb ) ,
703
+ exists ( IRBlock bb , int i , SourceVariable sv , DefinitionExt def , DefOrUse defOrUse0 |
704
+ lastRefRedefExt ( pragma [ only_bind_into ] ( def ) , pragma [ only_bind_into ] ( bb ) ,
680
705
pragma [ only_bind_into ] ( i ) , ssaDefinition ( defOrUse ) ) and
681
706
def .getSourceVariable ( ) = sv and
682
707
defOrUse0 .hasIndexInBlock ( bb , i , sv ) and
@@ -702,7 +727,7 @@ pragma[nomagic]
702
727
private predicate fromPhiNodeToUse ( PhiNode phi , SourceVariable sv , IRBlock bb1 , int i1 , UseOrPhi use ) {
703
728
exists ( IRBlock bb2 , int i2 |
704
729
use .asDefOrUse ( ) .hasIndexInBlock ( bb2 , i2 , sv ) and
705
- adjacentDefRead ( pragma [ only_bind_into ] ( phi ) , pragma [ only_bind_into ] ( bb1 ) ,
730
+ adjacentDefReadExt ( pragma [ only_bind_into ] ( phi ) , pragma [ only_bind_into ] ( bb1 ) ,
706
731
pragma [ only_bind_into ] ( i1 ) , pragma [ only_bind_into ] ( bb2 ) , pragma [ only_bind_into ] ( i2 ) )
707
732
)
708
733
}
@@ -711,13 +736,13 @@ private predicate fromPhiNodeToUse(PhiNode phi, SourceVariable sv, IRBlock bb1,
711
736
predicate fromPhiNode ( SsaPhiNode nodeFrom , Node nodeTo ) {
712
737
exists ( PhiNode phi , SourceVariable sv , IRBlock bb1 , int i1 , UseOrPhi use |
713
738
phi = nodeFrom .getPhiNode ( ) and
714
- phi .definesAt ( sv , bb1 , i1 ) and
739
+ phi .definesAt ( sv , bb1 , i1 , _ ) and
715
740
useToNode ( use , nodeTo )
716
741
|
717
742
fromPhiNodeToUse ( phi , sv , bb1 , i1 , use )
718
743
or
719
744
exists ( PhiNode phiTo |
720
- lastRefRedef ( phi , _, _, phiTo ) and
745
+ lastRefRedefExt ( phi , _, _, phiTo ) and
721
746
nodeTo .( SsaPhiNode ) .getPhiNode ( ) = phiTo
722
747
)
723
748
)
@@ -796,8 +821,8 @@ module SsaCached {
796
821
* path between them without any read of `def`.
797
822
*/
798
823
cached
799
- predicate adjacentDefRead ( Definition def , IRBlock bb1 , int i1 , IRBlock bb2 , int i2 ) {
800
- SsaImpl:: adjacentDefRead ( def , bb1 , i1 , bb2 , i2 )
824
+ predicate adjacentDefReadExt ( DefinitionExt def , IRBlock bb1 , int i1 , IRBlock bb2 , int i2 ) {
825
+ SsaImpl:: adjacentDefReadExt ( def , _ , bb1 , i1 , bb2 , i2 )
801
826
}
802
827
803
828
/**
@@ -806,8 +831,8 @@ module SsaCached {
806
831
* without passing through another read or write.
807
832
*/
808
833
cached
809
- predicate lastRefRedef ( Definition def , IRBlock bb , int i , Definition next ) {
810
- SsaImpl:: lastRefRedef ( def , bb , i , next )
834
+ predicate lastRefRedefExt ( DefinitionExt def , IRBlock bb , int i , DefinitionExt next ) {
835
+ SsaImpl:: lastRefRedefExt ( def , _ , bb , i , next )
811
836
}
812
837
}
813
838
@@ -818,8 +843,8 @@ private newtype TSsaDefOrUse =
818
843
or
819
844
// Like in the pruning stage, we only include definition that's live after the
820
845
// write as the final definitions computed by SSA.
821
- exists ( Definition def , SourceVariable sv , IRBlock bb , int i |
822
- def .definesAt ( sv , bb , i ) and
846
+ exists ( DefinitionExt def , SourceVariable sv , IRBlock bb , int i |
847
+ def .definesAt ( sv , bb , i , _ ) and
823
848
defOrUse .( DefImpl ) .hasIndexInBlock ( bb , i , sv )
824
849
)
825
850
} or
@@ -967,9 +992,14 @@ class Def extends DefOrUse {
967
992
968
993
private module SsaImpl = SsaImplCommon:: Make< SsaInput > ;
969
994
970
- class PhiNode = SsaImpl:: PhiNode ;
995
+ class PhiNode extends SsaImpl:: DefinitionExt {
996
+ PhiNode ( ) {
997
+ this instanceof SsaImpl:: PhiNode or
998
+ this instanceof SsaImpl:: PhiReadNode
999
+ }
1000
+ }
971
1001
972
- class Definition = SsaImpl:: Definition ;
1002
+ class DefinitionExt = SsaImpl:: DefinitionExt ;
973
1003
974
1004
class UncertainWriteDefinition = SsaImpl:: UncertainWriteDefinition ;
975
1005
0 commit comments