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

Skip to content

Commit 1e863ac

Browse files
author
Dave Bartolomeo
committed
C++: Share TInstruction across IR stages
Each stage of the IR reuses the majority of the instructions from previous stages. Previously, we've been wrapping each reused old instruction in a branch of the `TInstruction` type for the next stage. This causes use to create roughly three times as many `TInstruction` objects as we actually need. Now that IPA union types are supported in the compiler, we can share a single `TInstruction` IPA type across stages. We create a single `TInstruction` IPA type, with individual branches of this type for instructions created directly from the AST (`TRawInstruction`) and for instructions added by each stage of SSA construction (`T*PhiInstruction`, `T*ChiInstruction`, `T*UnreachedInstruction`). Each stage then defines a `TStageInstruction` type that is a union of all of the branches that can appear in that particular stage. The public `Instruction` class for each phase extends the `TStageInstruction` type for that stage. The interface that each stage exposes to the pyrameterized modules in the IR is now split into three pieces: - The `Raw` module, exposed only by the original IR construction stage. This module identifies which functions have IR, which `TRawInstruction`s exist, and which `IRVariable`s exist. - The `SSA` module, exposed only by the two SSA construction stages. This identifiers which `Phi`, `Chi`, and `Unreached` instructions exist. - The global module, exposed by all three stages. This module has all of the predicates whose implementation is different for each stage, like gathering definitions of `MemoryOperand`s. Similarly, there is now a single `TIRFunction` IPA type that is shared across all three stages. There is a single `IRFunctionBase` class that exposes the stage-indepdendent predicates; the `IRFunction` class for each stage extends `IRFunctionBase`. Most of the other changes are largely mechanical.
1 parent 7265e94 commit 1e863ac

28 files changed

Lines changed: 627 additions & 463 deletions

config/identical-files.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,11 @@
177177
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/IRBlockImports.qll",
178178
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/IRBlockImports.qll"
179179
],
180+
"C++ IR IRFunctionImports": [
181+
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/IRFunctionImports.qll",
182+
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/IRFunctionImports.qll",
183+
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/IRFunctionImports.qll"
184+
],
180185
"C++ IR IRVariableImports": [
181186
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/IRVariableImports.qll",
182187
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/IRVariableImports.qll",

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRFunction.qll

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,12 @@
11
private import internal.IRInternal
2+
private import internal.IRFunctionImports as Imports
3+
import Imports::IRFunctionBase
24
import Instruction
35

4-
private newtype TIRFunction =
5-
MkIRFunction(Language::Function func) { Construction::functionHasIR(func) }
6-
76
/**
8-
* Represents the IR for a function.
7+
* The IR for a function.
98
*/
10-
class IRFunction extends TIRFunction {
11-
Language::Function func;
12-
13-
IRFunction() { this = MkIRFunction(func) }
14-
15-
final string toString() { result = "IR: " + func.toString() }
16-
17-
/**
18-
* Gets the function whose IR is represented.
19-
*/
20-
final Language::Function getFunction() { result = func }
21-
22-
/**
23-
* Gets the location of the function.
24-
*/
25-
final Language::Location getLocation() { result = func.getLocation() }
26-
9+
class IRFunction extends IRFunctionBase {
2710
/**
2811
* Gets the entry point for this function.
2912
*/

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,13 @@ private Instruction getAnInstructionAtLine(IRFunction irFunc, Language::File fil
2929
/**
3030
* Represents a single operation in the IR.
3131
*/
32-
class Instruction extends Construction::TInstruction {
32+
class Instruction extends Construction::TStageInstruction {
33+
Instruction() {
34+
// The base `TStageInstruction` type is a superset of the actual instructions appearing in this
35+
// stage. This call lets the stage filter out the ones that are not reused from raw IR.
36+
Construction::hasInstruction(this)
37+
}
38+
3339
final string toString() { result = getOpcode().toString() + ": " + getAST().toString() }
3440

3541
/**
@@ -250,7 +256,7 @@ class Instruction extends Construction::TInstruction {
250256
* result of the `Load` instruction is a prvalue of type `int`, representing
251257
* the integer value loaded from variable `x`.
252258
*/
253-
final predicate isGLValue() { Construction::getInstructionResultType(this).hasType(_, true) }
259+
final predicate isGLValue() { getResultLanguageType().hasType(_, true) }
254260

255261
/**
256262
* Gets the size of the result produced by this instruction, in bytes. If the
@@ -259,7 +265,7 @@ class Instruction extends Construction::TInstruction {
259265
* If `this.isGLValue()` holds for this instruction, the value of
260266
* `getResultSize()` will always be the size of a pointer.
261267
*/
262-
final int getResultSize() { result = Construction::getInstructionResultType(this).getByteSize() }
268+
final int getResultSize() { result = getResultLanguageType().getByteSize() }
263269

264270
/**
265271
* Gets the opcode that specifies the operation performed by this instruction.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import semmle.code.cpp.ir.implementation.internal.IRFunctionBase as IRFunctionBase

0 commit comments

Comments
 (0)