@@ -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,31 @@ 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 ( ) =
677+ Ssa:: getIRRepresentationOfIndirectOperand ( operand , indirectionIndex )
678+ }
679+
680+ Operand getOperand ( ) { result = operand }
681+
682+ int getIndirectionIndex ( ) { result = indirectionIndex }
683+
684+ predicate isIRRepresentationOf ( Operand op , int index ) {
685+ this instanceof OperandNode and
686+ (
687+ op = operand and
688+ index = indirectionIndex
689+ )
690+ }
691+ }
692+
668693/**
669694 * The value of an uninitialized local variable, viewed as a node in a data
670695 * flow graph.
@@ -690,11 +715,11 @@ class UninitializedNode extends Node {
690715 * A node that represents the indirect value of an instruction in the IR
691716 * after `index` number of loads.
692717 */
693- class IndirectInstruction extends Node , TIndirectInstruction {
718+ private class RawIndirectInstruction extends Node , TRawIndirectInstruction {
694719 Instruction instr ;
695720 int indirectionIndex ;
696721
697- IndirectInstruction ( ) { this = TIndirectInstruction ( instr , indirectionIndex ) }
722+ RawIndirectInstruction ( ) { this = TRawIndirectInstruction ( instr , indirectionIndex ) }
698723
699724 /** Gets the underlying instruction. */
700725 Instruction getInstruction ( ) { result = instr }
@@ -718,6 +743,31 @@ class IndirectInstruction extends Node, TIndirectInstruction {
718743 }
719744}
720745
746+ class IndirectInstruction extends Node {
747+ Instruction instr ;
748+ int indirectionIndex ;
749+
750+ IndirectInstruction ( ) {
751+ this .( RawIndirectInstruction ) .getInstruction ( ) = instr and
752+ this .( RawIndirectInstruction ) .getIndirectionIndex ( ) = indirectionIndex
753+ or
754+ this .( InstructionNode ) .getInstruction ( ) =
755+ Ssa:: getIRRepresentationOfIndirectInstruction ( instr , indirectionIndex )
756+ }
757+
758+ Instruction getInstruction ( ) { result = instr }
759+
760+ int getIndirectionIndex ( ) { result = indirectionIndex }
761+
762+ predicate isIRRepresentationOf ( Instruction i , int index ) {
763+ this instanceof InstructionNode and
764+ (
765+ i = instr and
766+ index = indirectionIndex
767+ )
768+ }
769+ }
770+
721771private predicate isFullyConvertedArgument ( Expr e ) {
722772 e = any ( Call call ) .getAnArgument ( ) .getFullyConverted ( )
723773}
@@ -732,32 +782,20 @@ private predicate convertedExprMustBeOperand(Expr e) {
732782}
733783
734784/** 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 )
785+ predicate exprNodeShouldBeOperand ( OperandNode node , Expr e ) {
786+ exists ( Operand operand |
787+ node .getOperand ( ) = operand and
788+ e = operand .getDef ( ) .getConvertedResultExpression ( )
789+ |
790+ convertedExprMustBeOperand ( e )
791+ or
792+ node .( IndirectOperand ) .isIRRepresentationOf ( _, _)
793+ )
753794}
754795
755796/** 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- |
797+ private predicate indirectExprNodeShouldBeIndirectOperand ( RawIndirectOperand node , Expr e ) {
798+ exists ( Instruction instr | instr = node .getOperand ( ) .getDef ( ) |
761799 e = instr .( VariableAddressInstruction ) .getAst ( ) .( Expr ) .getFullyConverted ( )
762800 or
763801 not instr instanceof VariableAddressInstruction and
@@ -777,7 +815,6 @@ private predicate exprNodeShouldBeIndirectOutNode(IndirectArgumentOutNode node,
777815predicate exprNodeShouldBeInstruction ( Node node , Expr e ) {
778816 e = node .asInstruction ( ) .getConvertedResultExpression ( ) and
779817 not exprNodeShouldBeOperand ( _, e ) and
780- not exprNodeShouldBeIndirectOperand ( _, e , _) and
781818 not exprNodeShouldBeIndirectOutNode ( _, e )
782819}
783820
@@ -821,23 +858,6 @@ private class OperandExprNode extends ExprNodeBase, OperandNode {
821858
822859 final override Expr getExpr ( ) { result = this .getConvertedExpr ( ) .getUnconverted ( ) }
823860
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-
841861 final override string toStringImpl ( ) { result = this .getConvertedExpr ( ) .toString ( ) }
842862}
843863
@@ -852,7 +872,7 @@ abstract private class IndirectExprNodeBase extends Node {
852872 abstract Expr getExpr ( int indirectionIndex ) ;
853873}
854874
855- private class IndirectOperandIndirectExprNode extends IndirectExprNodeBase , IndirectOperand {
875+ private class IndirectOperandIndirectExprNode extends IndirectExprNodeBase , RawIndirectOperand {
856876 IndirectOperandIndirectExprNode ( ) { indirectExprNodeShouldBeIndirectOperand ( this , _) }
857877
858878 final override Expr getConvertedExpr ( int index ) {
@@ -866,7 +886,8 @@ private class IndirectOperandIndirectExprNode extends IndirectExprNodeBase, Indi
866886 }
867887}
868888
869- private class IndirectInstructionIndirectExprNode extends IndirectExprNodeBase , IndirectInstruction {
889+ private class IndirectInstructionIndirectExprNode extends IndirectExprNodeBase ,
890+ RawIndirectInstruction {
870891 IndirectInstructionIndirectExprNode ( ) { indirectExprNodeShouldBeIndirectInstruction ( this , _) }
871892
872893 final override Expr getConvertedExpr ( int index ) {
@@ -886,8 +907,6 @@ private class IndirectArgumentOutExprNode extends ExprNodeBase, IndirectArgument
886907 final override Expr getConvertedExpr ( ) { exprNodeShouldBeIndirectOutNode ( this , result ) }
887908
888909 final override Expr getExpr ( ) { result = this .getConvertedExpr ( ) }
889-
890- final override string toStringImpl ( ) { result = this .getConvertedExpr ( ) .toString ( ) }
891910}
892911
893912/**
@@ -1154,7 +1173,7 @@ Node uninitializedNode(LocalVariable v) { none() }
11541173 */
11551174predicate localFlowStep = simpleLocalFlowStep / 2 ;
11561175
1157- private predicate indirectionOperandFlow ( IndirectOperand nodeFrom , Node nodeTo ) {
1176+ private predicate indirectionOperandFlow ( RawIndirectOperand nodeFrom , Node nodeTo ) {
11581177 // Reduce the indirection count by 1 if we're passing through a `LoadInstruction`.
11591178 exists ( int ind , LoadInstruction load |
11601179 hasOperandAndIndex ( nodeFrom , load .getSourceAddressOperand ( ) , ind ) and
@@ -1191,7 +1210,7 @@ predicate hasInstructionAndIndex(
11911210 indirectInstr .getIndirectionIndex ( ) = indirectionIndex
11921211}
11931212
1194- private predicate indirectionInstructionFlow ( IndirectInstruction nodeFrom , IndirectOperand nodeTo ) {
1213+ private predicate indirectionInstructionFlow ( RawIndirectInstruction nodeFrom , IndirectOperand nodeTo ) {
11951214 // If there's flow from an instruction to an operand, then there's also flow from the
11961215 // indirect instruction to the indirect operand.
11971216 exists ( Operand operand , Instruction instr , int indirectionIndex |
@@ -1470,9 +1489,9 @@ private IRBlock getBasicBlock(Node node) {
14701489 or
14711490 node .( SsaPhiNode ) .getPhiNode ( ) .getBasicBlock ( ) = result
14721491 or
1473- node .( IndirectOperand ) .getOperand ( ) .getUse ( ) .getBlock ( ) = result
1492+ node .( RawIndirectOperand ) .getOperand ( ) .getUse ( ) .getBlock ( ) = result
14741493 or
1475- node .( IndirectInstruction ) .getInstruction ( ) .getBlock ( ) = result
1494+ node .( RawIndirectInstruction ) .getInstruction ( ) .getBlock ( ) = result
14761495 or
14771496 result = getBasicBlock ( node .( PostUpdateNode ) .getPreUpdateNode ( ) )
14781497}
@@ -1518,10 +1537,11 @@ signature predicate instructionGuardChecksSig(IRGuardCondition g, Instruction in
15181537module InstructionBarrierGuard< instructionGuardChecksSig / 3 instructionGuardChecks> {
15191538 /** Gets a node that is safely guarded by the given guard check. */
15201539 ExprNode getABarrierNode ( ) {
1521- exists ( IRGuardCondition g , ValueNumber value , boolean edge |
1540+ exists ( IRGuardCondition g , ValueNumber value , boolean edge , Operand use |
15221541 instructionGuardChecks ( g , value .getAnInstruction ( ) , edge ) and
1523- result .asInstruction ( ) = value .getAnInstruction ( ) and
1524- g .controls ( result .asInstruction ( ) .getBlock ( ) , edge )
1542+ use = value .getAnInstruction ( ) .getAUse ( ) and
1543+ result .asOperand ( ) = use and
1544+ g .controls ( use .getDef ( ) .getBlock ( ) , edge )
15251545 )
15261546 }
15271547}
0 commit comments