@@ -26,9 +26,9 @@ private module Cached {
2626 * - `SsaPhiNode`, which represents phi nodes as computed by the shared SSA library.
2727 * - `IndirectArgumentOutNode`, which represents the value of an argument (and its indirections) after
2828 * it leaves a function call.
29- * - `IndirectOperand `, which represents the value of `operand` after loading the address a number
29+ * - `RawIndirectOperand `, which represents the value of `operand` after loading the address a number
3030 * of times.
31- * - `IndirectInstruction `, which represents the value of `instr` after loading the address a number
31+ * - `RawIndirectInstruction `, which represents the value of `instr` after loading the address a number
3232 * of times.
3333 */
3434 cached
@@ -52,11 +52,11 @@ private module Cached {
5252 Ssa:: isModifiableByCall ( operand ) and
5353 indirectionIndex = [ 1 .. Ssa:: countIndirectionsForCppType ( operand .getLanguageType ( ) ) ]
5454 } or
55- TIndirectOperand ( Operand op , int indirectionIndex ) {
56- Ssa:: hasIndirectOperand ( op , indirectionIndex )
55+ TRawIndirectOperand ( Operand op , int indirectionIndex ) {
56+ Ssa:: hasRawIndirectOperand ( op , indirectionIndex )
5757 } or
58- TIndirectInstruction ( Instruction instr , int indirectionIndex ) {
59- Ssa:: hasIndirectInstruction ( instr , indirectionIndex )
58+ TRawIndirectInstruction ( Instruction instr , int indirectionIndex ) {
59+ Ssa:: hasRawIndirectInstruction ( instr , indirectionIndex )
6060 }
6161}
6262
@@ -583,15 +583,15 @@ class IndirectArgumentOutNode extends Node, TIndirectArgumentOutNode, PartialDef
583583
584584pragma [ nomagic]
585585predicate indirectReturnOutNodeOperand0 ( CallInstruction call , Operand operand , int indirectionIndex ) {
586- Ssa:: hasIndirectInstruction ( call , indirectionIndex ) and
586+ Ssa:: hasRawIndirectInstruction ( call , indirectionIndex ) and
587587 operandForfullyConvertedCall ( operand , call )
588588}
589589
590590pragma [ nomagic]
591591predicate indirectReturnOutNodeInstruction0 (
592592 CallInstruction call , Instruction instr , int indirectionIndex
593593) {
594- Ssa:: hasIndirectInstruction ( call , indirectionIndex ) and
594+ Ssa:: hasRawIndirectInstruction ( call , indirectionIndex ) and
595595 instructionForfullyConvertedCall ( instr , call )
596596}
597597
@@ -637,11 +637,11 @@ private Type getTypeImpl(Type t, int indirectionIndex) {
637637 * A node that represents the indirect value of an operand in the IR
638638 * after `index` number of loads.
639639 */
640- class IndirectOperand extends Node , TIndirectOperand {
640+ private class RawIndirectOperand extends Node , TRawIndirectOperand {
641641 Operand operand ;
642642 int indirectionIndex ;
643643
644- IndirectOperand ( ) { this = TIndirectOperand ( operand , indirectionIndex ) }
644+ RawIndirectOperand ( ) { this = TRawIndirectOperand ( operand , indirectionIndex ) }
645645
646646 /** Gets the underlying instruction. */
647647 Operand getOperand ( ) { result = operand }
@@ -665,6 +665,30 @@ class IndirectOperand extends Node, TIndirectOperand {
665665 }
666666}
667667
668+ class IndirectOperand extends Node {
669+ Operand operand ;
670+ int indirectionIndex ;
671+
672+ IndirectOperand ( ) {
673+ this .( RawIndirectOperand ) .getOperand ( ) = operand and
674+ this .( RawIndirectOperand ) .getIndirectionIndex ( ) = indirectionIndex
675+ or
676+ this .( OperandNode ) .getOperand ( ) = Ssa:: getIRBackedIndirectOperand ( operand , indirectionIndex )
677+ }
678+
679+ Operand getOperand ( ) { result = operand }
680+
681+ int getIndirectionIndex ( ) { result = indirectionIndex }
682+
683+ predicate isIRBackedBy ( Operand op , int index ) {
684+ this instanceof OperandNode and
685+ (
686+ op = operand and
687+ index = indirectionIndex
688+ )
689+ }
690+ }
691+
668692/**
669693 * The value of an uninitialized local variable, viewed as a node in a data
670694 * flow graph.
@@ -690,11 +714,11 @@ class UninitializedNode extends Node {
690714 * A node that represents the indirect value of an instruction in the IR
691715 * after `index` number of loads.
692716 */
693- class IndirectInstruction extends Node , TIndirectInstruction {
717+ private class RawIndirectInstruction extends Node , TRawIndirectInstruction {
694718 Instruction instr ;
695719 int indirectionIndex ;
696720
697- IndirectInstruction ( ) { this = TIndirectInstruction ( instr , indirectionIndex ) }
721+ RawIndirectInstruction ( ) { this = TRawIndirectInstruction ( instr , indirectionIndex ) }
698722
699723 /** Gets the underlying instruction. */
700724 Instruction getInstruction ( ) { result = instr }
@@ -718,6 +742,31 @@ class IndirectInstruction extends Node, TIndirectInstruction {
718742 }
719743}
720744
745+ class IndirectInstruction extends Node {
746+ Instruction instr ;
747+ int indirectionIndex ;
748+
749+ IndirectInstruction ( ) {
750+ this .( RawIndirectInstruction ) .getInstruction ( ) = instr and
751+ this .( RawIndirectInstruction ) .getIndirectionIndex ( ) = indirectionIndex
752+ or
753+ this .( InstructionNode ) .getInstruction ( ) =
754+ Ssa:: getIRBackedIndirectInstruction ( instr , indirectionIndex )
755+ }
756+
757+ Instruction getInstruction ( ) { result = instr }
758+
759+ int getIndirectionIndex ( ) { result = indirectionIndex }
760+
761+ predicate isIRBackedBy ( Instruction i , int index ) {
762+ this instanceof InstructionNode and
763+ (
764+ i = instr and
765+ index = indirectionIndex
766+ )
767+ }
768+ }
769+
721770private predicate isFullyConvertedArgument ( Expr e ) {
722771 e = any ( Call call ) .getAnArgument ( ) .getFullyConverted ( )
723772}
@@ -732,32 +781,20 @@ private predicate convertedExprMustBeOperand(Expr e) {
732781}
733782
734783/** Holds if `node` is an `OperandNode` that should map `node.asExpr()` to `e`. */
735- predicate exprNodeShouldBeOperand ( Node node , Expr e ) {
736- e = node .asOperand ( ) .getDef ( ) .getConvertedResultExpression ( ) and
737- convertedExprMustBeOperand ( e )
738- }
739-
740- /**
741- * Holds if `load` is a `LoadInstruction` that is the result of evaluating `e`
742- * and `node` is an `IndirectOperandNode` that should map `node.asExpr()` to `e`.
743- *
744- * We map `e` to `node.asExpr()` when `node` semantically represents the
745- * same value as `load`. A subsequent flow step will flow `node` to
746- * the `LoadInstruction`.
747- */
748- private predicate exprNodeShouldBeIndirectOperand ( IndirectOperand node , Expr e , LoadInstruction load ) {
749- node .getIndirectionIndex ( ) = 1 and
750- e = load .getConvertedResultExpression ( ) and
751- load .getSourceAddressOperand ( ) = node .getOperand ( ) and
752- not convertedExprMustBeOperand ( e )
784+ predicate exprNodeShouldBeOperand ( OperandNode node , Expr e ) {
785+ exists ( Operand operand |
786+ node .getOperand ( ) = operand and
787+ e = operand .getDef ( ) .getConvertedResultExpression ( )
788+ |
789+ convertedExprMustBeOperand ( e )
790+ or
791+ node .( IndirectOperand ) .isIRBackedBy ( _, _)
792+ )
753793}
754794
755795/** Holds if `node` should be an `IndirectOperand` that maps `node.asIndirectExpr()` to `e`. */
756- private predicate indirectExprNodeShouldBeIndirectOperand ( IndirectOperand node , Expr e ) {
757- exists ( Instruction instr |
758- instr = node .getOperand ( ) .getDef ( ) and
759- not node instanceof ExprNode
760- |
796+ private predicate indirectExprNodeShouldBeIndirectOperand ( RawIndirectOperand node , Expr e ) {
797+ exists ( Instruction instr | instr = node .getOperand ( ) .getDef ( ) |
761798 e = instr .( VariableAddressInstruction ) .getAst ( ) .( Expr ) .getFullyConverted ( )
762799 or
763800 not instr instanceof VariableAddressInstruction and
@@ -777,7 +814,6 @@ private predicate exprNodeShouldBeIndirectOutNode(IndirectArgumentOutNode node,
777814predicate exprNodeShouldBeInstruction ( Node node , Expr e ) {
778815 e = node .asInstruction ( ) .getConvertedResultExpression ( ) and
779816 not exprNodeShouldBeOperand ( _, e ) and
780- not exprNodeShouldBeIndirectOperand ( _, e , _) and
781817 not exprNodeShouldBeIndirectOutNode ( _, e )
782818}
783819
@@ -821,23 +857,6 @@ private class OperandExprNode extends ExprNodeBase, OperandNode {
821857
822858 final override Expr getExpr ( ) { result = this .getConvertedExpr ( ) .getUnconverted ( ) }
823859
824- final override string toStringImpl ( ) {
825- // Avoid generating multiple `toString` results for `ArgumentNode`s
826- // since they have a better `toString`.
827- result = this .( ArgumentNode ) .toStringImpl ( )
828- or
829- not this instanceof ArgumentNode and
830- result = this .getConvertedExpr ( ) .toString ( )
831- }
832- }
833-
834- private class IndirectOperandExprNode extends ExprNodeBase , IndirectOperand {
835- IndirectOperandExprNode ( ) { exprNodeShouldBeIndirectOperand ( this , _, _) }
836-
837- final override Expr getConvertedExpr ( ) { exprNodeShouldBeIndirectOperand ( this , result , _) }
838-
839- final override Expr getExpr ( ) { result = this .getConvertedExpr ( ) .getUnconverted ( ) }
840-
841860 final override string toStringImpl ( ) { result = this .getConvertedExpr ( ) .toString ( ) }
842861}
843862
@@ -852,7 +871,7 @@ abstract private class IndirectExprNodeBase extends Node {
852871 abstract Expr getExpr ( int indirectionIndex ) ;
853872}
854873
855- private class IndirectOperandIndirectExprNode extends IndirectExprNodeBase , IndirectOperand {
874+ private class IndirectOperandIndirectExprNode extends IndirectExprNodeBase , RawIndirectOperand {
856875 IndirectOperandIndirectExprNode ( ) { indirectExprNodeShouldBeIndirectOperand ( this , _) }
857876
858877 final override Expr getConvertedExpr ( int index ) {
@@ -866,7 +885,8 @@ private class IndirectOperandIndirectExprNode extends IndirectExprNodeBase, Indi
866885 }
867886}
868887
869- private class IndirectInstructionIndirectExprNode extends IndirectExprNodeBase , IndirectInstruction {
888+ private class IndirectInstructionIndirectExprNode extends IndirectExprNodeBase ,
889+ RawIndirectInstruction {
870890 IndirectInstructionIndirectExprNode ( ) { indirectExprNodeShouldBeIndirectInstruction ( this , _) }
871891
872892 final override Expr getConvertedExpr ( int index ) {
@@ -886,8 +906,6 @@ private class IndirectArgumentOutExprNode extends ExprNodeBase, IndirectArgument
886906 final override Expr getConvertedExpr ( ) { exprNodeShouldBeIndirectOutNode ( this , result ) }
887907
888908 final override Expr getExpr ( ) { result = this .getConvertedExpr ( ) }
889-
890- final override string toStringImpl ( ) { result = this .getConvertedExpr ( ) .toString ( ) }
891909}
892910
893911/**
@@ -1154,7 +1172,7 @@ Node uninitializedNode(LocalVariable v) { none() }
11541172 */
11551173predicate localFlowStep = simpleLocalFlowStep / 2 ;
11561174
1157- private predicate indirectionOperandFlow ( IndirectOperand nodeFrom , Node nodeTo ) {
1175+ private predicate indirectionOperandFlow ( RawIndirectOperand nodeFrom , Node nodeTo ) {
11581176 // Reduce the indirection count by 1 if we're passing through a `LoadInstruction`.
11591177 exists ( int ind , LoadInstruction load |
11601178 hasOperandAndIndex ( nodeFrom , load .getSourceAddressOperand ( ) , ind ) and
@@ -1191,7 +1209,7 @@ predicate hasInstructionAndIndex(
11911209 indirectInstr .getIndirectionIndex ( ) = indirectionIndex
11921210}
11931211
1194- private predicate indirectionInstructionFlow ( IndirectInstruction nodeFrom , IndirectOperand nodeTo ) {
1212+ private predicate indirectionInstructionFlow ( RawIndirectInstruction nodeFrom , IndirectOperand nodeTo ) {
11951213 // If there's flow from an instruction to an operand, then there's also flow from the
11961214 // indirect instruction to the indirect operand.
11971215 exists ( Operand operand , Instruction instr , int indirectionIndex |
@@ -1470,9 +1488,9 @@ private IRBlock getBasicBlock(Node node) {
14701488 or
14711489 node .( SsaPhiNode ) .getPhiNode ( ) .getBasicBlock ( ) = result
14721490 or
1473- node .( IndirectOperand ) .getOperand ( ) .getUse ( ) .getBlock ( ) = result
1491+ node .( RawIndirectOperand ) .getOperand ( ) .getUse ( ) .getBlock ( ) = result
14741492 or
1475- node .( IndirectInstruction ) .getInstruction ( ) .getBlock ( ) = result
1493+ node .( RawIndirectInstruction ) .getInstruction ( ) .getBlock ( ) = result
14761494 or
14771495 result = getBasicBlock ( node .( PostUpdateNode ) .getPreUpdateNode ( ) )
14781496}
@@ -1518,10 +1536,11 @@ signature predicate instructionGuardChecksSig(IRGuardCondition g, Instruction in
15181536module InstructionBarrierGuard< instructionGuardChecksSig / 3 instructionGuardChecks> {
15191537 /** Gets a node that is safely guarded by the given guard check. */
15201538 ExprNode getABarrierNode ( ) {
1521- exists ( IRGuardCondition g , ValueNumber value , boolean edge |
1539+ exists ( IRGuardCondition g , ValueNumber value , boolean edge , Operand use |
15221540 instructionGuardChecks ( g , value .getAnInstruction ( ) , edge ) and
1523- result .asInstruction ( ) = value .getAnInstruction ( ) and
1524- g .controls ( result .asInstruction ( ) .getBlock ( ) , edge )
1541+ use = value .getAnInstruction ( ) .getAUse ( ) and
1542+ result .asOperand ( ) = use and
1543+ g .controls ( use .getDef ( ) .getBlock ( ) , edge )
15251544 )
15261545 }
15271546}
0 commit comments