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

Skip to content

Commit bbadf4b

Browse files
author
Dave Bartolomeo
committed
C#: Port TInstruction-sharing support from C++
This updates C#'s IR to share `TInstruction` across stages the same way C++ does. The only interesting part is that, since we have not yet ported full alias analysis to C#, I stubbed out the required parts of the aliased SSA interface in `AliasedSSAStub.qll`.
1 parent e65a5c9 commit bbadf4b

15 files changed

Lines changed: 298 additions & 102 deletions

config/identical-files.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,18 @@
9696
"cpp/ql/src/semmle/code/cpp/ir/implementation/UseSoundEscapeAnalysis.qll",
9797
"csharp/ql/src/semmle/code/csharp/ir/implementation/UseSoundEscapeAnalysis.qll"
9898
],
99+
"IR IRFunctionBase": [
100+
"cpp/ql/src/semmle/code/cpp/ir/implementation/internal/IRFunctionBase.qll",
101+
"csharp/ql/src/semmle/code/csharp/ir/implementation/internal/IRFunctionBase.qll"
102+
],
99103
"IR Operand Tag": [
100104
"cpp/ql/src/semmle/code/cpp/ir/implementation/internal/OperandTag.qll",
101105
"csharp/ql/src/semmle/code/csharp/ir/implementation/internal/OperandTag.qll"
102106
],
107+
"IR TInstruction":[
108+
"cpp/ql/src/semmle/code/cpp/ir/implementation/internal/TInstruction.qll",
109+
"csharp/ql/src/semmle/code/csharp/ir/implementation/internal/TInstruction.qll"
110+
],
103111
"IR TIRVariable":[
104112
"cpp/ql/src/semmle/code/cpp/ir/implementation/internal/TIRVariable.qll",
105113
"csharp/ql/src/semmle/code/csharp/ir/implementation/internal/TIRVariable.qll"
@@ -292,6 +300,10 @@
292300
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/IRBlockImports.qll",
293301
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/IRBlockImports.qll"
294302
],
303+
"C# IR IRFunctionImports": [
304+
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/IRFunctionImports.qll",
305+
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/IRFunctionImports.qll"
306+
],
295307
"C# IR IRVariableImports": [
296308
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/IRVariableImports.qll",
297309
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/IRVariableImports.qll"
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* Provides a stub implementation of the required aliased SSA interface until we implement aliased
3+
* SSA construction for C#.
4+
*/
5+
6+
private import IRFunctionBase
7+
private import TInstruction
8+
9+
module SSA {
10+
class MemoryLocation = boolean;
11+
12+
predicate hasPhiInstruction(
13+
IRFunctionBase irFunc, TRawInstruction blockStartInstr, MemoryLocation memoryLocation
14+
) {
15+
none()
16+
}
17+
18+
predicate hasChiInstruction(IRFunctionBase irFunc, TRawInstruction primaryInstruction) { none() }
19+
20+
predicate hasUnreachedInstruction(IRFunctionBase irFunc) { none() }
21+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* Provides a base class, `IRFunctionBase`, for the stage-independent portions of `IRFunction`.
3+
*/
4+
private import IRFunctionBaseInternal
5+
6+
private newtype TIRFunction =
7+
MkIRFunction(Language::Function func) { IRConstruction::Raw::functionHasIR(func) }
8+
9+
/**
10+
* The IR for a function. This base class contains only the predicates that are the same between all
11+
* phases of the IR. Each instantiation of `IRFunction` extends this class.
12+
*/
13+
class IRFunctionBase extends TIRFunction {
14+
Language::Function func;
15+
16+
IRFunctionBase() { this = MkIRFunction(func) }
17+
18+
/** Gets a textual representation of this element. */
19+
final string toString() { result = "IR: " + func.toString() }
20+
21+
/** Gets the function whose IR is represented. */
22+
final Language::Function getFunction() { result = func }
23+
24+
/** Gets the location of the function. */
25+
final Language::Location getLocation() { result = func.getLocation() }
26+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import semmle.code.csharp.ir.internal.IRCSharpLanguage as Language
2+
import semmle.code.csharp.ir.implementation.raw.internal.IRConstruction as IRConstruction

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import semmle.code.csharp.ir.internal.IRCSharpLanguage as Language
2-
import semmle.code.csharp.ir.implementation.raw.internal.IRConstruction as Construction
2+
import semmle.code.csharp.ir.implementation.raw.internal.IRConstruction::Raw as Construction
33
private import semmle.code.csharp.ir.implementation.TempVariableTag as TempVariableTag_
44

55
module Imports {
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
private import TInstructionInternal
2+
private import IRFunctionBase
3+
private import TInstructionImports as Imports
4+
private import Imports::IRType
5+
private import Imports::Opcode
6+
7+
/**
8+
* An IR instruction. `TInstruction` is shared across all phases of the IR. There are individual
9+
* branches of this type for instructions created directly from the AST (`TRawInstruction`) and for
10+
* instructions added by each stage of SSA construction (`T*PhiInstruction`, `T*ChiInstruction`,
11+
* `T*UnreachedInstruction`). Each stage then defines a `TStageInstruction` type that is a union of
12+
* all of the branches that can appear in that particular stage. The public `Instruction` class for
13+
* each phase extends the `TStageInstruction` type for that stage.
14+
*/
15+
newtype TInstruction =
16+
TRawInstruction(
17+
IRFunctionBase irFunc, Opcode opcode, Language::AST ast,
18+
IRConstruction::Raw::InstructionTag1 tag1, IRConstruction::Raw::InstructionTag2 tag2
19+
) {
20+
IRConstruction::Raw::hasInstruction(irFunc.getFunction(), opcode, ast, tag1, tag2)
21+
} or
22+
TUnaliasedSSAPhiInstruction(
23+
IRFunctionBase irFunc, TRawInstruction blockStartInstr,
24+
UnaliasedSSA::SSA::MemoryLocation memoryLocation
25+
) {
26+
UnaliasedSSA::SSA::hasPhiInstruction(irFunc, blockStartInstr, memoryLocation)
27+
} or
28+
TUnaliasedSSAChiInstruction(IRFunctionBase irFunc, TRawInstruction primaryInstruction) { none() } or
29+
TUnaliasedSSAUnreachedInstruction(IRFunctionBase irFunc) {
30+
UnaliasedSSA::SSA::hasUnreachedInstruction(irFunc)
31+
} or
32+
TAliasedSSAPhiInstruction(
33+
IRFunctionBase irFunc, TRawInstruction blockStartInstr,
34+
AliasedSSA::SSA::MemoryLocation memoryLocation
35+
) {
36+
AliasedSSA::SSA::hasPhiInstruction(irFunc, blockStartInstr, memoryLocation)
37+
} or
38+
TAliasedSSAChiInstruction(IRFunctionBase irFunc, TRawInstruction primaryInstruction) {
39+
AliasedSSA::SSA::hasChiInstruction(irFunc, primaryInstruction)
40+
} or
41+
TAliasedSSAUnreachedInstruction(IRFunctionBase irFunc) {
42+
AliasedSSA::SSA::hasUnreachedInstruction(irFunc)
43+
}
44+
45+
/**
46+
* Provides wrappers for the constructors of each branch of `TInstruction` that is used by the
47+
* unaliased SSA stage.
48+
* These wrappers are not parameterized because it is not possible to invoke an IPA constructor via
49+
* a class alias.
50+
*/
51+
module UnaliasedSSAInstructions {
52+
class TPhiInstruction = TUnaliasedSSAPhiInstruction;
53+
54+
TPhiInstruction phiInstruction(
55+
IRFunctionBase irFunc, TRawInstruction blockStartInstr,
56+
UnaliasedSSA::SSA::MemoryLocation memoryLocation
57+
) {
58+
result = TUnaliasedSSAPhiInstruction(irFunc, blockStartInstr, memoryLocation)
59+
}
60+
61+
class TChiInstruction = TUnaliasedSSAChiInstruction;
62+
63+
TChiInstruction chiInstruction(IRFunctionBase irFunc, TRawInstruction primaryInstruction) {
64+
result = TUnaliasedSSAChiInstruction(irFunc, primaryInstruction)
65+
}
66+
67+
class TUnreachedInstruction = TUnaliasedSSAUnreachedInstruction;
68+
69+
TUnreachedInstruction unreachedInstruction(IRFunctionBase irFunc) {
70+
result = TUnaliasedSSAUnreachedInstruction(irFunc)
71+
}
72+
}
73+
74+
/**
75+
* Provides wrappers for the constructors of each branch of `TInstruction` that is used by the
76+
* aliased SSA stage.
77+
* These wrappers are not parameterized because it is not possible to invoke an IPA constructor via
78+
* a class alias.
79+
*/
80+
module AliasedSSAInstructions {
81+
class TPhiInstruction = TAliasedSSAPhiInstruction;
82+
83+
TPhiInstruction phiInstruction(
84+
IRFunctionBase irFunc, TRawInstruction blockStartInstr,
85+
AliasedSSA::SSA::MemoryLocation memoryLocation
86+
) {
87+
result = TAliasedSSAPhiInstruction(irFunc, blockStartInstr, memoryLocation)
88+
}
89+
90+
class TChiInstruction = TAliasedSSAChiInstruction;
91+
92+
TChiInstruction chiInstruction(IRFunctionBase irFunc, TRawInstruction primaryInstruction) {
93+
result = TAliasedSSAChiInstruction(irFunc, primaryInstruction)
94+
}
95+
96+
class TUnreachedInstruction = TAliasedSSAUnreachedInstruction;
97+
98+
TUnreachedInstruction unreachedInstruction(IRFunctionBase irFunc) {
99+
result = TAliasedSSAUnreachedInstruction(irFunc)
100+
}
101+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import semmle.code.csharp.ir.implementation.IRType as IRType
2+
import semmle.code.csharp.ir.implementation.Opcode as Opcode
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import semmle.code.csharp.ir.internal.IRCSharpLanguage as Language
2+
import semmle.code.csharp.ir.implementation.raw.internal.IRConstruction as IRConstruction
3+
import semmle.code.csharp.ir.implementation.unaliased_ssa.internal.SSAConstruction as UnaliasedSSA
4+
import AliasedSSAStub as AliasedSSA

0 commit comments

Comments
 (0)