@@ -159,6 +159,12 @@ class Node extends TIRDataFlowNode {
159159 /** Gets the operands corresponding to this node, if any. */
160160 Operand asOperand ( ) { result = this .( OperandNode ) .getOperand ( ) }
161161
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+
162168 /**
163169 * Holds if this node is at index `i` in basic block `block`.
164170 *
@@ -2673,6 +2679,22 @@ class ContentSet instanceof Content {
26732679 }
26742680}
26752681
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+
26762698/**
26772699 * Holds if the guard `g` validates the expression `e` upon evaluating to `branch`.
26782700 *
@@ -2721,13 +2743,22 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
27212743 *
27222744 * NOTE: If an indirect expression is tracked, use `getAnIndirectBarrierNode` instead.
27232745 */
2724- ExprNode getABarrierNode ( ) {
2746+ Node getABarrierNode ( ) {
27252747 exists ( IRGuardCondition g , Expr e , ValueNumber value , boolean edge |
27262748 e = value .getAnInstruction ( ) .getConvertedResultExpression ( ) and
2727- result .getConvertedExpr ( ) = e and
2749+ result .asConvertedExpr ( ) = e and
27282750 guardChecks ( g , value .getAnInstruction ( ) .getConvertedResultExpression ( ) , edge ) and
27292751 g .controls ( result .getBasicBlock ( ) , edge )
27302752 )
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+ )
27312762 }
27322763
27332764 /**
@@ -2763,7 +2794,7 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
27632794 *
27642795 * NOTE: If a non-indirect expression is tracked, use `getABarrierNode` instead.
27652796 */
2766- IndirectExprNode getAnIndirectBarrierNode ( ) { result = getAnIndirectBarrierNode ( _) }
2797+ Node getAnIndirectBarrierNode ( ) { result = getAnIndirectBarrierNode ( _) }
27672798
27682799 /**
27692800 * Gets an indirect expression node with indirection index `indirectionIndex` that is
@@ -2799,13 +2830,24 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
27992830 *
28002831 * NOTE: If a non-indirect expression is tracked, use `getABarrierNode` instead.
28012832 */
2802- IndirectExprNode getAnIndirectBarrierNode ( int indirectionIndex ) {
2833+ Node getAnIndirectBarrierNode ( int indirectionIndex ) {
28032834 exists ( IRGuardCondition g , Expr e , ValueNumber value , boolean edge |
28042835 e = value .getAnInstruction ( ) .getConvertedResultExpression ( ) and
2805- result .getConvertedExpr ( indirectionIndex ) = e and
2836+ result .asIndirectConvertedExpr ( indirectionIndex ) = e and
28062837 guardChecks ( g , value .getAnInstruction ( ) .getConvertedResultExpression ( ) , edge ) and
28072838 g .controls ( result .getBasicBlock ( ) , edge )
28082839 )
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+ )
28092851 }
28102852}
28112853
@@ -2814,6 +2856,14 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
28142856 */
28152857signature predicate instructionGuardChecksSig ( IRGuardCondition g , Instruction instr , boolean branch ) ;
28162858
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+
28172867/**
28182868 * Provides a set of barrier nodes for a guard that validates an instruction.
28192869 *
@@ -2822,12 +2872,21 @@ signature predicate instructionGuardChecksSig(IRGuardCondition g, Instruction in
28222872 */
28232873module InstructionBarrierGuard< instructionGuardChecksSig / 3 instructionGuardChecks> {
28242874 /** Gets a node that is safely guarded by the given guard check. */
2825- ExprNode getABarrierNode ( ) {
2875+ Node getABarrierNode ( ) {
28262876 exists ( IRGuardCondition g , ValueNumber value , boolean edge , Operand use |
28272877 instructionGuardChecks ( g , value .getAnInstruction ( ) , edge ) and
28282878 use = value .getAnInstruction ( ) .getAUse ( ) and
28292879 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 )
28312890 )
28322891 }
28332892}
0 commit comments