@@ -159,6 +159,12 @@ class Node extends TIRDataFlowNode {
159
159
/** Gets the operands corresponding to this node, if any. */
160
160
Operand asOperand ( ) { result = this .( OperandNode ) .getOperand ( ) }
161
161
162
+ /**
163
+ * Gets the operand that is indirectly tracked by this node behind `index`
164
+ * number of indirections.
165
+ */
166
+ Operand asIndirectOperand ( int index ) { hasOperandAndIndex ( this , result , index ) }
167
+
162
168
/**
163
169
* Holds if this node is at index `i` in basic block `block`.
164
170
*
@@ -2673,6 +2679,22 @@ class ContentSet instanceof Content {
2673
2679
}
2674
2680
}
2675
2681
2682
+ pragma [ nomagic]
2683
+ private predicate guardControlsPhiInput (
2684
+ IRGuardCondition g , boolean branch , Ssa:: Definition def , IRBlock input , Ssa:: PhiInputNodeExt phi
2685
+ ) {
2686
+ phi .hasInputFromBlock ( def , input ) and
2687
+ (
2688
+ g .controls ( input , branch )
2689
+ or
2690
+ exists ( EdgeKind kind |
2691
+ g .getBlock ( ) = input and
2692
+ kind = getConditionalEdge ( branch ) and
2693
+ input .getSuccessor ( kind ) = phi .getBasicBlock ( )
2694
+ )
2695
+ )
2696
+ }
2697
+
2676
2698
/**
2677
2699
* Holds if the guard `g` validates the expression `e` upon evaluating to `branch`.
2678
2700
*
@@ -2721,13 +2743,22 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
2721
2743
*
2722
2744
* NOTE: If an indirect expression is tracked, use `getAnIndirectBarrierNode` instead.
2723
2745
*/
2724
- ExprNode getABarrierNode ( ) {
2746
+ Node getABarrierNode ( ) {
2725
2747
exists ( IRGuardCondition g , Expr e , ValueNumber value , boolean edge |
2726
2748
e = value .getAnInstruction ( ) .getConvertedResultExpression ( ) and
2727
- result .getConvertedExpr ( ) = e and
2749
+ result .asConvertedExpr ( ) = e and
2728
2750
guardChecks ( g , value .getAnInstruction ( ) .getConvertedResultExpression ( ) , edge ) and
2729
2751
g .controls ( result .getBasicBlock ( ) , edge )
2730
2752
)
2753
+ or
2754
+ exists (
2755
+ IRGuardCondition g , boolean branch , Ssa:: DefinitionExt def , IRBlock input ,
2756
+ Ssa:: PhiInputNodeExt phi
2757
+ |
2758
+ guardChecks ( g , def .getARead ( ) .asOperand ( ) .getDef ( ) .getConvertedResultExpression ( ) , branch ) and
2759
+ guardControlsPhiInput ( g , branch , def , input , phi ) and
2760
+ result = TSsaPhiInputNode ( phi .getPhi ( ) , input )
2761
+ )
2731
2762
}
2732
2763
2733
2764
/**
@@ -2763,7 +2794,7 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
2763
2794
*
2764
2795
* NOTE: If a non-indirect expression is tracked, use `getABarrierNode` instead.
2765
2796
*/
2766
- IndirectExprNode getAnIndirectBarrierNode ( ) { result = getAnIndirectBarrierNode ( _) }
2797
+ Node getAnIndirectBarrierNode ( ) { result = getAnIndirectBarrierNode ( _) }
2767
2798
2768
2799
/**
2769
2800
* Gets an indirect expression node with indirection index `indirectionIndex` that is
@@ -2799,13 +2830,24 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
2799
2830
*
2800
2831
* NOTE: If a non-indirect expression is tracked, use `getABarrierNode` instead.
2801
2832
*/
2802
- IndirectExprNode getAnIndirectBarrierNode ( int indirectionIndex ) {
2833
+ Node getAnIndirectBarrierNode ( int indirectionIndex ) {
2803
2834
exists ( IRGuardCondition g , Expr e , ValueNumber value , boolean edge |
2804
2835
e = value .getAnInstruction ( ) .getConvertedResultExpression ( ) and
2805
- result .getConvertedExpr ( indirectionIndex ) = e and
2836
+ result .asIndirectConvertedExpr ( indirectionIndex ) = e and
2806
2837
guardChecks ( g , value .getAnInstruction ( ) .getConvertedResultExpression ( ) , edge ) and
2807
2838
g .controls ( result .getBasicBlock ( ) , edge )
2808
2839
)
2840
+ or
2841
+ exists (
2842
+ IRGuardCondition g , boolean branch , Ssa:: DefinitionExt def , IRBlock input ,
2843
+ Ssa:: PhiInputNodeExt phi
2844
+ |
2845
+ guardChecks ( g ,
2846
+ def .getARead ( ) .asIndirectOperand ( indirectionIndex ) .getDef ( ) .getConvertedResultExpression ( ) ,
2847
+ branch ) and
2848
+ guardControlsPhiInput ( g , branch , def , input , phi ) and
2849
+ result = TSsaPhiInputNode ( phi .getPhi ( ) , input )
2850
+ )
2809
2851
}
2810
2852
}
2811
2853
@@ -2814,6 +2856,14 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
2814
2856
*/
2815
2857
signature predicate instructionGuardChecksSig ( IRGuardCondition g , Instruction instr , boolean branch ) ;
2816
2858
2859
+ private EdgeKind getConditionalEdge ( boolean branch ) {
2860
+ branch = true and
2861
+ result instanceof TrueEdge
2862
+ or
2863
+ branch = false and
2864
+ result instanceof FalseEdge
2865
+ }
2866
+
2817
2867
/**
2818
2868
* Provides a set of barrier nodes for a guard that validates an instruction.
2819
2869
*
@@ -2822,12 +2872,21 @@ signature predicate instructionGuardChecksSig(IRGuardCondition g, Instruction in
2822
2872
*/
2823
2873
module InstructionBarrierGuard< instructionGuardChecksSig / 3 instructionGuardChecks> {
2824
2874
/** Gets a node that is safely guarded by the given guard check. */
2825
- ExprNode getABarrierNode ( ) {
2875
+ Node getABarrierNode ( ) {
2826
2876
exists ( IRGuardCondition g , ValueNumber value , boolean edge , Operand use |
2827
2877
instructionGuardChecks ( g , value .getAnInstruction ( ) , edge ) and
2828
2878
use = value .getAnInstruction ( ) .getAUse ( ) and
2829
2879
result .asOperand ( ) = use and
2830
- g .controls ( use .getDef ( ) .getBlock ( ) , edge )
2880
+ g .controls ( result .getBasicBlock ( ) , edge )
2881
+ )
2882
+ or
2883
+ exists (
2884
+ IRGuardCondition g , boolean branch , Ssa:: DefinitionExt def , IRBlock input ,
2885
+ Ssa:: PhiInputNodeExt phi
2886
+ |
2887
+ instructionGuardChecks ( g , def .getARead ( ) .asOperand ( ) .getDef ( ) , branch ) and
2888
+ guardControlsPhiInput ( g , branch , def , input , phi ) and
2889
+ result = TSsaPhiInputNode ( phi .getPhi ( ) , input )
2831
2890
)
2832
2891
}
2833
2892
}
0 commit comments