Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1181848

Browse files
author
Dave Bartolomeo
committed
C++/C#: Use cached to ensure that IR is evaluated in a single stage
Before this change, evaluation of the IR was spread out across about 5 stages. This resulted in a lot of redundant evaluation, especially tuple numbering of large IPA types like `TInstruction`. This change makes two small changes that, when combined, ensure that the IR is evaluated all in one stage: First, we mark `TInstruction` as `cached`. This collapses all of the work to create instructions, across all three IR phases, into a single phase. Second, we make the `SSA` module in `SSAConstruction.qll` just contain aliases to `cached` predicates defined in the `Cached` module. This ensures that all of the `Operand`-related SSA computation happens in the same stage as all of the `Instruction`-related SSA computation.
1 parent cb2370c commit 1181848

5 files changed

Lines changed: 92 additions & 71 deletions

File tree

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,31 @@ import Cached
1616

1717
cached
1818
private module Cached {
19+
cached
20+
predicate hasPhiInstructionCached(
21+
IRFunction irFunc, OldInstruction blockStartInstr, Alias::MemoryLocation defLocation
22+
) {
23+
exists(OldBlock oldBlock |
24+
definitionHasPhiNode(defLocation, oldBlock) and
25+
irFunc = oldBlock.getEnclosingIRFunction() and
26+
blockStartInstr = oldBlock.getFirstInstruction()
27+
)
28+
}
29+
30+
cached
31+
predicate hasChiInstructionCached(IRFunctionBase irFunc, OldInstruction primaryInstruction) {
32+
hasChiNode(_, primaryInstruction) and
33+
irFunc = primaryInstruction.getEnclosingIRFunction()
34+
}
35+
36+
cached
37+
predicate hasUnreachedInstructionCached(IRFunction irFunc) {
38+
exists(OldInstruction oldInstruction |
39+
irFunc = oldInstruction.getEnclosingIRFunction() and
40+
Reachability::isInfeasibleInstructionSuccessor(oldInstruction, _)
41+
)
42+
}
43+
1944
class TStageInstruction =
2045
TRawInstruction or TPhiInstruction or TChiInstruction or TUnreachedInstruction;
2146

@@ -876,33 +901,15 @@ module SSAConsistency {
876901
/**
877902
* Provides the portion of the parameterized IR interface that is used to construct the SSA stages
878903
* of the IR. The raw stage of the IR does not expose these predicates.
904+
* These predicates are all just aliases for predicates defined in the `Cached` module. This ensures
905+
* that all of SSA construction will be evaluated in the same stage.
879906
*/
880-
cached
881907
module SSA {
882908
class MemoryLocation = Alias::MemoryLocation;
883909

884-
cached
885-
predicate hasPhiInstruction(
886-
IRFunction irFunc, OldInstruction blockStartInstr, Alias::MemoryLocation defLocation
887-
) {
888-
exists(OldBlock oldBlock |
889-
definitionHasPhiNode(defLocation, oldBlock) and
890-
irFunc = oldBlock.getEnclosingIRFunction() and
891-
blockStartInstr = oldBlock.getFirstInstruction()
892-
)
893-
}
910+
predicate hasPhiInstruction = Cached::hasPhiInstructionCached/3;
894911

895-
cached
896-
predicate hasChiInstruction(IRFunctionBase irFunc, OldInstruction primaryInstruction) {
897-
hasChiNode(_, primaryInstruction) and
898-
irFunc = primaryInstruction.getEnclosingIRFunction()
899-
}
912+
predicate hasChiInstruction = Cached::hasChiInstructionCached/2;
900913

901-
cached
902-
predicate hasUnreachedInstruction(IRFunction irFunc) {
903-
exists(OldInstruction oldInstruction |
904-
irFunc = oldInstruction.getEnclosingIRFunction() and
905-
Reachability::isInfeasibleInstructionSuccessor(oldInstruction, _)
906-
)
907-
}
914+
predicate hasUnreachedInstruction = Cached::hasUnreachedInstructionCached/1;
908915
}

cpp/ql/src/semmle/code/cpp/ir/implementation/internal/TInstruction.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ private import Imports::Opcode
1212
* all of the branches that can appear in that particular stage. The public `Instruction` class for
1313
* each phase extends the `TStageInstruction` type for that stage.
1414
*/
15-
newtype TInstruction =
15+
cached newtype TInstruction =
1616
TRawInstruction(
1717
IRFunctionBase irFunc, Opcode opcode, Language::AST ast,
1818
IRConstruction::Raw::InstructionTag1 tag1, IRConstruction::Raw::InstructionTag2 tag2

cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,31 @@ import Cached
1616

1717
cached
1818
private module Cached {
19+
cached
20+
predicate hasPhiInstructionCached(
21+
IRFunction irFunc, OldInstruction blockStartInstr, Alias::MemoryLocation defLocation
22+
) {
23+
exists(OldBlock oldBlock |
24+
definitionHasPhiNode(defLocation, oldBlock) and
25+
irFunc = oldBlock.getEnclosingIRFunction() and
26+
blockStartInstr = oldBlock.getFirstInstruction()
27+
)
28+
}
29+
30+
cached
31+
predicate hasChiInstructionCached(IRFunctionBase irFunc, OldInstruction primaryInstruction) {
32+
hasChiNode(_, primaryInstruction) and
33+
irFunc = primaryInstruction.getEnclosingIRFunction()
34+
}
35+
36+
cached
37+
predicate hasUnreachedInstructionCached(IRFunction irFunc) {
38+
exists(OldInstruction oldInstruction |
39+
irFunc = oldInstruction.getEnclosingIRFunction() and
40+
Reachability::isInfeasibleInstructionSuccessor(oldInstruction, _)
41+
)
42+
}
43+
1944
class TStageInstruction =
2045
TRawInstruction or TPhiInstruction or TChiInstruction or TUnreachedInstruction;
2146

@@ -876,33 +901,15 @@ module SSAConsistency {
876901
/**
877902
* Provides the portion of the parameterized IR interface that is used to construct the SSA stages
878903
* of the IR. The raw stage of the IR does not expose these predicates.
904+
* These predicates are all just aliases for predicates defined in the `Cached` module. This ensures
905+
* that all of SSA construction will be evaluated in the same stage.
879906
*/
880-
cached
881907
module SSA {
882908
class MemoryLocation = Alias::MemoryLocation;
883909

884-
cached
885-
predicate hasPhiInstruction(
886-
IRFunction irFunc, OldInstruction blockStartInstr, Alias::MemoryLocation defLocation
887-
) {
888-
exists(OldBlock oldBlock |
889-
definitionHasPhiNode(defLocation, oldBlock) and
890-
irFunc = oldBlock.getEnclosingIRFunction() and
891-
blockStartInstr = oldBlock.getFirstInstruction()
892-
)
893-
}
910+
predicate hasPhiInstruction = Cached::hasPhiInstructionCached/3;
894911

895-
cached
896-
predicate hasChiInstruction(IRFunctionBase irFunc, OldInstruction primaryInstruction) {
897-
hasChiNode(_, primaryInstruction) and
898-
irFunc = primaryInstruction.getEnclosingIRFunction()
899-
}
912+
predicate hasChiInstruction = Cached::hasChiInstructionCached/2;
900913

901-
cached
902-
predicate hasUnreachedInstruction(IRFunction irFunc) {
903-
exists(OldInstruction oldInstruction |
904-
irFunc = oldInstruction.getEnclosingIRFunction() and
905-
Reachability::isInfeasibleInstructionSuccessor(oldInstruction, _)
906-
)
907-
}
914+
predicate hasUnreachedInstruction = Cached::hasUnreachedInstructionCached/1;
908915
}

csharp/ql/src/semmle/code/csharp/ir/implementation/internal/TInstruction.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ private import Imports::Opcode
1212
* all of the branches that can appear in that particular stage. The public `Instruction` class for
1313
* each phase extends the `TStageInstruction` type for that stage.
1414
*/
15-
newtype TInstruction =
15+
cached newtype TInstruction =
1616
TRawInstruction(
1717
IRFunctionBase irFunc, Opcode opcode, Language::AST ast,
1818
IRConstruction::Raw::InstructionTag1 tag1, IRConstruction::Raw::InstructionTag2 tag2

csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,31 @@ import Cached
1616

1717
cached
1818
private module Cached {
19+
cached
20+
predicate hasPhiInstructionCached(
21+
IRFunction irFunc, OldInstruction blockStartInstr, Alias::MemoryLocation defLocation
22+
) {
23+
exists(OldBlock oldBlock |
24+
definitionHasPhiNode(defLocation, oldBlock) and
25+
irFunc = oldBlock.getEnclosingIRFunction() and
26+
blockStartInstr = oldBlock.getFirstInstruction()
27+
)
28+
}
29+
30+
cached
31+
predicate hasChiInstructionCached(IRFunctionBase irFunc, OldInstruction primaryInstruction) {
32+
hasChiNode(_, primaryInstruction) and
33+
irFunc = primaryInstruction.getEnclosingIRFunction()
34+
}
35+
36+
cached
37+
predicate hasUnreachedInstructionCached(IRFunction irFunc) {
38+
exists(OldInstruction oldInstruction |
39+
irFunc = oldInstruction.getEnclosingIRFunction() and
40+
Reachability::isInfeasibleInstructionSuccessor(oldInstruction, _)
41+
)
42+
}
43+
1944
class TStageInstruction =
2045
TRawInstruction or TPhiInstruction or TChiInstruction or TUnreachedInstruction;
2146

@@ -876,33 +901,15 @@ module SSAConsistency {
876901
/**
877902
* Provides the portion of the parameterized IR interface that is used to construct the SSA stages
878903
* of the IR. The raw stage of the IR does not expose these predicates.
904+
* These predicates are all just aliases for predicates defined in the `Cached` module. This ensures
905+
* that all of SSA construction will be evaluated in the same stage.
879906
*/
880-
cached
881907
module SSA {
882908
class MemoryLocation = Alias::MemoryLocation;
883909

884-
cached
885-
predicate hasPhiInstruction(
886-
IRFunction irFunc, OldInstruction blockStartInstr, Alias::MemoryLocation defLocation
887-
) {
888-
exists(OldBlock oldBlock |
889-
definitionHasPhiNode(defLocation, oldBlock) and
890-
irFunc = oldBlock.getEnclosingIRFunction() and
891-
blockStartInstr = oldBlock.getFirstInstruction()
892-
)
893-
}
910+
predicate hasPhiInstruction = Cached::hasPhiInstructionCached/3;
894911

895-
cached
896-
predicate hasChiInstruction(IRFunctionBase irFunc, OldInstruction primaryInstruction) {
897-
hasChiNode(_, primaryInstruction) and
898-
irFunc = primaryInstruction.getEnclosingIRFunction()
899-
}
912+
predicate hasChiInstruction = Cached::hasChiInstructionCached/2;
900913

901-
cached
902-
predicate hasUnreachedInstruction(IRFunction irFunc) {
903-
exists(OldInstruction oldInstruction |
904-
irFunc = oldInstruction.getEnclosingIRFunction() and
905-
Reachability::isInfeasibleInstructionSuccessor(oldInstruction, _)
906-
)
907-
}
914+
predicate hasUnreachedInstruction = Cached::hasUnreachedInstructionCached/1;
908915
}

0 commit comments

Comments
 (0)