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

Skip to content

Commit 6ee3def

Browse files
committed
C++ IR: Speed up getInstructionOperand
The `SSAConstruction::Cached::getInstructionOperand` predicate took 1m27s on a postgres snapshot before this change and was the slowest predicate in SSAIR. It now takes 4.5s. The slowdown was caused by its use of `getUnmodeledDefinitionInstruction`, which got inlined into a place where join orderer had little choice but to join the `MkInstruction` relation with itself, creating a large intermediate relation. I've added `pragma[noinline]` to `getUnmodeledDefinitionInstruction` and also to similar predicates that are likely to cause the same problem in the future.
1 parent 7b1d136 commit 6ee3def

3 files changed

Lines changed: 18 additions & 0 deletions

File tree

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/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
}

cpp/ql/src/semmle/code/cpp/ssa/internal/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)