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

Skip to content

Commit 7b1d136

Browse files
committed
C++ IR: Fully cache IRBlock and use cached module
Before this PR, the caching and computation of `IRBlock` spanned three cache stages and was also separate from `SSAConstruction` even though it shared some computations with it. They are now all cached together, so the number of stages is reduced by 2 for each layer of IR. I made the choice of what to cache be similar to what we do for `PrimitiveBasicBlock` as I've recently benchmarked this and found it to be a good choice.
1 parent bbee9a8 commit 7b1d136

3 files changed

Lines changed: 129 additions & 72 deletions

File tree

cpp/ql/src/semmle/code/cpp/ir/internal/IRBlock.qll

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,48 @@ private predicate startsBasicBlock(Instruction instr) {
2222
)
2323
}
2424

25-
private newtype TIRBlock =
26-
MkIRBlock(Instruction firstInstr) {
27-
startsBasicBlock(firstInstr)
25+
private predicate isEntryBlock(TIRBlock block) {
26+
block = MkIRBlock(any(EnterFunctionInstruction enter))
27+
}
28+
29+
private import Cached
30+
private cached module Cached {
31+
cached newtype TIRBlock =
32+
MkIRBlock(Instruction firstInstr) {
33+
startsBasicBlock(firstInstr)
34+
}
35+
36+
cached Instruction getInstruction(TIRBlock block, int index) {
37+
index = 0 and block = MkIRBlock(result) or
38+
(
39+
index > 0 and
40+
not startsBasicBlock(result) and
41+
exists(Instruction predecessor, GotoEdge edge |
42+
predecessor = getInstruction(block, index - 1) and
43+
result = predecessor.getSuccessor(edge)
44+
)
45+
)
2846
}
2947

30-
cached private predicate isEntryBlock(IRBlock block) {
31-
block.getFirstInstruction() instanceof EnterFunctionInstruction
32-
}
48+
cached int getInstructionCount(TIRBlock block) {
49+
result = strictcount(getInstruction(block, _))
50+
}
3351

34-
cached private predicate blockSuccessor(IRBlock pred, IRBlock succ) {
35-
succ = pred.getASuccessor()
36-
}
52+
cached predicate blockSuccessor(TIRBlock pred, TIRBlock succ, EdgeKind kind) {
53+
exists(Instruction predLast, Instruction succFirst |
54+
predLast = getInstruction(pred, getInstructionCount(pred) - 1) and
55+
succFirst = predLast.getSuccessor(kind) and
56+
succ = MkIRBlock(succFirst)
57+
)
58+
}
59+
60+
cached predicate blockSuccessor(TIRBlock pred, TIRBlock succ) {
61+
blockSuccessor(pred, succ, _)
62+
}
3763

38-
private predicate blockImmediatelyDominates(IRBlock dominator, IRBlock block) =
39-
idominance(isEntryBlock/1, blockSuccessor/2)(_, dominator, block)
64+
cached predicate blockImmediatelyDominates(TIRBlock dominator, TIRBlock block) =
65+
idominance(isEntryBlock/1, blockSuccessor/2)(_, dominator, block)
66+
}
4067

4168
class IRBlock extends TIRBlock {
4269
Instruction firstInstr;
@@ -57,16 +84,8 @@ class IRBlock extends TIRBlock {
5784
result = firstInstr.getUniqueId()
5885
}
5986

60-
final cached Instruction getInstruction(int index) {
61-
index = 0 and result = firstInstr or
62-
(
63-
index > 0 and
64-
not startsBasicBlock(result) and
65-
exists(Instruction predecessor, GotoEdge edge |
66-
predecessor = getInstruction(index - 1) and
67-
result = predecessor.getSuccessor(edge)
68-
)
69-
)
87+
final Instruction getInstruction(int index) {
88+
result = getInstruction(this, index)
7089
}
7190

7291
final PhiInstruction getAPhiInstruction() {
@@ -100,15 +119,15 @@ class IRBlock extends TIRBlock {
100119
}
101120

102121
final IRBlock getASuccessor() {
103-
result.getFirstInstruction() = getLastInstruction().getASuccessor()
122+
blockSuccessor(this, result)
104123
}
105124

106125
final IRBlock getAPredecessor() {
107-
firstInstr = result.getLastInstruction().getASuccessor()
126+
blockSuccessor(result, this)
108127
}
109128

110129
final IRBlock getSuccessor(EdgeKind kind) {
111-
result.getFirstInstruction() = getLastInstruction().getSuccessor(kind)
130+
blockSuccessor(this, result, kind)
112131
}
113132

114133
final predicate immediatelyDominates(IRBlock block) {

cpp/ql/src/semmle/code/cpp/ssa/internal/aliased_ssa/IRBlock.qll

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,48 @@ private predicate startsBasicBlock(Instruction instr) {
2222
)
2323
}
2424

25-
private newtype TIRBlock =
26-
MkIRBlock(Instruction firstInstr) {
27-
startsBasicBlock(firstInstr)
25+
private predicate isEntryBlock(TIRBlock block) {
26+
block = MkIRBlock(any(EnterFunctionInstruction enter))
27+
}
28+
29+
private import Cached
30+
private cached module Cached {
31+
cached newtype TIRBlock =
32+
MkIRBlock(Instruction firstInstr) {
33+
startsBasicBlock(firstInstr)
34+
}
35+
36+
cached Instruction getInstruction(TIRBlock block, int index) {
37+
index = 0 and block = MkIRBlock(result) or
38+
(
39+
index > 0 and
40+
not startsBasicBlock(result) and
41+
exists(Instruction predecessor, GotoEdge edge |
42+
predecessor = getInstruction(block, index - 1) and
43+
result = predecessor.getSuccessor(edge)
44+
)
45+
)
2846
}
2947

30-
cached private predicate isEntryBlock(IRBlock block) {
31-
block.getFirstInstruction() instanceof EnterFunctionInstruction
32-
}
48+
cached int getInstructionCount(TIRBlock block) {
49+
result = strictcount(getInstruction(block, _))
50+
}
3351

34-
cached private predicate blockSuccessor(IRBlock pred, IRBlock succ) {
35-
succ = pred.getASuccessor()
36-
}
52+
cached predicate blockSuccessor(TIRBlock pred, TIRBlock succ, EdgeKind kind) {
53+
exists(Instruction predLast, Instruction succFirst |
54+
predLast = getInstruction(pred, getInstructionCount(pred) - 1) and
55+
succFirst = predLast.getSuccessor(kind) and
56+
succ = MkIRBlock(succFirst)
57+
)
58+
}
59+
60+
cached predicate blockSuccessor(TIRBlock pred, TIRBlock succ) {
61+
blockSuccessor(pred, succ, _)
62+
}
3763

38-
private predicate blockImmediatelyDominates(IRBlock dominator, IRBlock block) =
39-
idominance(isEntryBlock/1, blockSuccessor/2)(_, dominator, block)
64+
cached predicate blockImmediatelyDominates(TIRBlock dominator, TIRBlock block) =
65+
idominance(isEntryBlock/1, blockSuccessor/2)(_, dominator, block)
66+
}
4067

4168
class IRBlock extends TIRBlock {
4269
Instruction firstInstr;
@@ -57,16 +84,8 @@ class IRBlock extends TIRBlock {
5784
result = firstInstr.getUniqueId()
5885
}
5986

60-
final cached Instruction getInstruction(int index) {
61-
index = 0 and result = firstInstr or
62-
(
63-
index > 0 and
64-
not startsBasicBlock(result) and
65-
exists(Instruction predecessor, GotoEdge edge |
66-
predecessor = getInstruction(index - 1) and
67-
result = predecessor.getSuccessor(edge)
68-
)
69-
)
87+
final Instruction getInstruction(int index) {
88+
result = getInstruction(this, index)
7089
}
7190

7291
final PhiInstruction getAPhiInstruction() {
@@ -100,15 +119,15 @@ class IRBlock extends TIRBlock {
100119
}
101120

102121
final IRBlock getASuccessor() {
103-
result.getFirstInstruction() = getLastInstruction().getASuccessor()
122+
blockSuccessor(this, result)
104123
}
105124

106125
final IRBlock getAPredecessor() {
107-
firstInstr = result.getLastInstruction().getASuccessor()
126+
blockSuccessor(result, this)
108127
}
109128

110129
final IRBlock getSuccessor(EdgeKind kind) {
111-
result.getFirstInstruction() = getLastInstruction().getSuccessor(kind)
130+
blockSuccessor(this, result, kind)
112131
}
113132

114133
final predicate immediatelyDominates(IRBlock block) {

cpp/ql/src/semmle/code/cpp/ssa/internal/ssa/IRBlock.qll

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,48 @@ private predicate startsBasicBlock(Instruction instr) {
2222
)
2323
}
2424

25-
private newtype TIRBlock =
26-
MkIRBlock(Instruction firstInstr) {
27-
startsBasicBlock(firstInstr)
25+
private predicate isEntryBlock(TIRBlock block) {
26+
block = MkIRBlock(any(EnterFunctionInstruction enter))
27+
}
28+
29+
private import Cached
30+
private cached module Cached {
31+
cached newtype TIRBlock =
32+
MkIRBlock(Instruction firstInstr) {
33+
startsBasicBlock(firstInstr)
34+
}
35+
36+
cached Instruction getInstruction(TIRBlock block, int index) {
37+
index = 0 and block = MkIRBlock(result) or
38+
(
39+
index > 0 and
40+
not startsBasicBlock(result) and
41+
exists(Instruction predecessor, GotoEdge edge |
42+
predecessor = getInstruction(block, index - 1) and
43+
result = predecessor.getSuccessor(edge)
44+
)
45+
)
2846
}
2947

30-
cached private predicate isEntryBlock(IRBlock block) {
31-
block.getFirstInstruction() instanceof EnterFunctionInstruction
32-
}
48+
cached int getInstructionCount(TIRBlock block) {
49+
result = strictcount(getInstruction(block, _))
50+
}
3351

34-
cached private predicate blockSuccessor(IRBlock pred, IRBlock succ) {
35-
succ = pred.getASuccessor()
36-
}
52+
cached predicate blockSuccessor(TIRBlock pred, TIRBlock succ, EdgeKind kind) {
53+
exists(Instruction predLast, Instruction succFirst |
54+
predLast = getInstruction(pred, getInstructionCount(pred) - 1) and
55+
succFirst = predLast.getSuccessor(kind) and
56+
succ = MkIRBlock(succFirst)
57+
)
58+
}
59+
60+
cached predicate blockSuccessor(TIRBlock pred, TIRBlock succ) {
61+
blockSuccessor(pred, succ, _)
62+
}
3763

38-
private predicate blockImmediatelyDominates(IRBlock dominator, IRBlock block) =
39-
idominance(isEntryBlock/1, blockSuccessor/2)(_, dominator, block)
64+
cached predicate blockImmediatelyDominates(TIRBlock dominator, TIRBlock block) =
65+
idominance(isEntryBlock/1, blockSuccessor/2)(_, dominator, block)
66+
}
4067

4168
class IRBlock extends TIRBlock {
4269
Instruction firstInstr;
@@ -57,16 +84,8 @@ class IRBlock extends TIRBlock {
5784
result = firstInstr.getUniqueId()
5885
}
5986

60-
final cached Instruction getInstruction(int index) {
61-
index = 0 and result = firstInstr or
62-
(
63-
index > 0 and
64-
not startsBasicBlock(result) and
65-
exists(Instruction predecessor, GotoEdge edge |
66-
predecessor = getInstruction(index - 1) and
67-
result = predecessor.getSuccessor(edge)
68-
)
69-
)
87+
final Instruction getInstruction(int index) {
88+
result = getInstruction(this, index)
7089
}
7190

7291
final PhiInstruction getAPhiInstruction() {
@@ -100,15 +119,15 @@ class IRBlock extends TIRBlock {
100119
}
101120

102121
final IRBlock getASuccessor() {
103-
result.getFirstInstruction() = getLastInstruction().getASuccessor()
122+
blockSuccessor(this, result)
104123
}
105124

106125
final IRBlock getAPredecessor() {
107-
firstInstr = result.getLastInstruction().getASuccessor()
126+
blockSuccessor(result, this)
108127
}
109128

110129
final IRBlock getSuccessor(EdgeKind kind) {
111-
result.getFirstInstruction() = getLastInstruction().getSuccessor(kind)
130+
blockSuccessor(this, result, kind)
112131
}
113132

114133
final predicate immediatelyDominates(IRBlock block) {

0 commit comments

Comments
 (0)