Skip to content

Commit 12577f0

Browse files
authored
Merge pull request #47 from jbj/ir-perf-blocks-etc
Approved by dave-bartolomeo
2 parents f904aed + dc22833 commit 12577f0

File tree

12 files changed

+202
-189
lines changed

12 files changed

+202
-189
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,24 +38,28 @@ class FunctionIR extends TFunctionIR {
3838
/**
3939
* Gets the entry point for this function.
4040
*/
41+
pragma[noinline]
4142
final EnterFunctionInstruction getEnterFunctionInstruction() {
4243
result.getFunctionIR() = this
4344
}
4445

4546
/**
4647
* Gets the exit point for this function.
4748
*/
49+
pragma[noinline]
4850
final ExitFunctionInstruction getExitFunctionInstruction() {
4951
result.getFunctionIR() = this
5052
}
5153

54+
pragma[noinline]
5255
final UnmodeledDefinitionInstruction getUnmodeledDefinitionInstruction() {
5356
result.getFunctionIR() = this
5457
}
5558

5659
/**
5760
* Gets the single return instruction for this function.
5861
*/
62+
pragma[noinline]
5963
final ReturnInstruction getReturnInstruction() {
6064
result.getFunctionIR() = this
6165
}
@@ -64,13 +68,15 @@ class FunctionIR extends TFunctionIR {
6468
* Gets the variable used to hold the return value of this function. If this
6569
* function does not return a value, this predicate does not hold.
6670
*/
71+
pragma[noinline]
6772
final IRReturnVariable getReturnVariable() {
6873
result.getFunctionIR() = this
6974
}
7075

7176
/**
7277
* Gets the block containing the entry point of this function.
7378
*/
79+
pragma[noinline]
7480
final IRBlock getEntryBlock() {
7581
result.getFirstInstruction() = getEnterFunctionInstruction()
7682
}

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

Lines changed: 12 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,27 @@
11
private import IRInternal
2+
private import IRBlockConstruction
23
import Instruction
3-
import cpp
44
import semmle.code.cpp.ir.EdgeKind
55

6-
private predicate startsBasicBlock(Instruction instr) {
7-
not instr instanceof PhiInstruction and
8-
(
9-
count(Instruction predecessor |
10-
instr = predecessor.getASuccessor()
11-
) != 1 or // Multiple predecessors or no predecessor
12-
exists(Instruction predecessor |
13-
instr = predecessor.getASuccessor() and
14-
strictcount(Instruction other |
15-
other = predecessor.getASuccessor()
16-
) > 1
17-
) or // Predecessor has multiple successors
18-
exists(Instruction predecessor, EdgeKind kind |
19-
instr = predecessor.getSuccessor(kind) and
20-
not kind instanceof GotoEdge
21-
) // Incoming edge is not a GotoEdge
22-
)
23-
}
24-
25-
private newtype TIRBlock =
26-
MkIRBlock(Instruction firstInstr) {
27-
startsBasicBlock(firstInstr)
28-
}
29-
30-
cached private predicate isEntryBlock(IRBlock block) {
31-
block.getFirstInstruction() instanceof EnterFunctionInstruction
32-
}
33-
34-
cached private predicate blockSuccessor(IRBlock pred, IRBlock succ) {
35-
succ = pred.getASuccessor()
36-
}
37-
38-
private predicate blockImmediatelyDominates(IRBlock dominator, IRBlock block) =
39-
idominance(isEntryBlock/1, blockSuccessor/2)(_, dominator, block)
40-
416
class IRBlock extends TIRBlock {
42-
Instruction firstInstr;
43-
44-
IRBlock() {
45-
this = MkIRBlock(firstInstr)
46-
}
47-
487
final string toString() {
49-
result = firstInstr.toString()
8+
result = getFirstInstruction(this).toString()
509
}
5110

5211
final Location getLocation() {
5312
result = getFirstInstruction().getLocation()
5413
}
5514

5615
final string getUniqueId() {
57-
result = firstInstr.getUniqueId()
16+
result = getFirstInstruction(this).getUniqueId()
5817
}
5918

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-
)
19+
final Instruction getInstruction(int index) {
20+
result = getInstruction(this, index)
7021
}
7122

7223
final PhiInstruction getAPhiInstruction() {
73-
Construction::getPhiInstructionBlockStart(result) =
74-
getFirstInstruction()
24+
Construction::getPhiInstructionBlockStart(result) = getFirstInstruction()
7525
}
7626

7727
final Instruction getAnInstruction() {
@@ -80,7 +30,7 @@ class IRBlock extends TIRBlock {
8030
}
8131

8232
final Instruction getFirstInstruction() {
83-
result = firstInstr
33+
result = getFirstInstruction(this)
8434
}
8535

8636
final Instruction getLastInstruction() {
@@ -92,23 +42,23 @@ class IRBlock extends TIRBlock {
9242
}
9343

9444
final FunctionIR getFunctionIR() {
95-
result = firstInstr.getFunctionIR()
45+
result = getFirstInstruction(this).getFunctionIR()
9646
}
9747

9848
final Function getFunction() {
99-
result = firstInstr.getFunction()
49+
result = getFirstInstruction(this).getFunction()
10050
}
10151

10252
final IRBlock getASuccessor() {
103-
result.getFirstInstruction() = getLastInstruction().getASuccessor()
53+
blockSuccessor(this, result)
10454
}
10555

10656
final IRBlock getAPredecessor() {
107-
firstInstr = result.getLastInstruction().getASuccessor()
57+
blockSuccessor(result, this)
10858
}
10959

11060
final IRBlock getSuccessor(EdgeKind kind) {
111-
result.getFirstInstruction() = getLastInstruction().getSuccessor(kind)
61+
blockSuccessor(this, result, kind)
11262
}
11363

11464
final predicate immediatelyDominates(IRBlock block) {
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
private import IRInternal
2+
import Instruction
3+
import cpp
4+
import semmle.code.cpp.ir.EdgeKind
5+
6+
private predicate startsBasicBlock(Instruction instr) {
7+
not instr instanceof PhiInstruction and
8+
(
9+
count(Instruction predecessor |
10+
instr = predecessor.getASuccessor()
11+
) != 1 or // Multiple predecessors or no predecessor
12+
exists(Instruction predecessor |
13+
instr = predecessor.getASuccessor() and
14+
strictcount(Instruction other |
15+
other = predecessor.getASuccessor()
16+
) > 1
17+
) or // Predecessor has multiple successors
18+
exists(Instruction predecessor, EdgeKind kind |
19+
instr = predecessor.getSuccessor(kind) and
20+
not kind instanceof GotoEdge
21+
) // Incoming edge is not a GotoEdge
22+
)
23+
}
24+
25+
private predicate isEntryBlock(TIRBlock block) {
26+
block = MkIRBlock(any(EnterFunctionInstruction enter))
27+
}
28+
29+
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+
)
46+
}
47+
48+
cached int getInstructionCount(TIRBlock block) {
49+
result = strictcount(getInstruction(block, _))
50+
}
51+
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+
}
63+
64+
cached predicate blockImmediatelyDominates(TIRBlock dominator, TIRBlock block) =
65+
idominance(isEntryBlock/1, blockSuccessor/2)(_, dominator, block)
66+
}
67+
68+
Instruction getFirstInstruction(TIRBlock block) {
69+
block = MkIRBlock(result)
70+
}

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import cpp
22
import semmle.code.cpp.ir.IR
33
private import InstructionTag
4-
private import Opcode
54
private import TempVariableTag
65
private import TranslatedElement
76
private import TranslatedFunction

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,24 +38,28 @@ class FunctionIR extends TFunctionIR {
3838
/**
3939
* Gets the entry point for this function.
4040
*/
41+
pragma[noinline]
4142
final EnterFunctionInstruction getEnterFunctionInstruction() {
4243
result.getFunctionIR() = this
4344
}
4445

4546
/**
4647
* Gets the exit point for this function.
4748
*/
49+
pragma[noinline]
4850
final ExitFunctionInstruction getExitFunctionInstruction() {
4951
result.getFunctionIR() = this
5052
}
5153

54+
pragma[noinline]
5255
final UnmodeledDefinitionInstruction getUnmodeledDefinitionInstruction() {
5356
result.getFunctionIR() = this
5457
}
5558

5659
/**
5760
* Gets the single return instruction for this function.
5861
*/
62+
pragma[noinline]
5963
final ReturnInstruction getReturnInstruction() {
6064
result.getFunctionIR() = this
6165
}
@@ -64,13 +68,15 @@ class FunctionIR extends TFunctionIR {
6468
* Gets the variable used to hold the return value of this function. If this
6569
* function does not return a value, this predicate does not hold.
6670
*/
71+
pragma[noinline]
6772
final IRReturnVariable getReturnVariable() {
6873
result.getFunctionIR() = this
6974
}
7075

7176
/**
7277
* Gets the block containing the entry point of this function.
7378
*/
79+
pragma[noinline]
7480
final IRBlock getEntryBlock() {
7581
result.getFirstInstruction() = getEnterFunctionInstruction()
7682
}

0 commit comments

Comments
 (0)