@@ -3,14 +3,18 @@ import Instruction
33import IRBlock
44import cpp
55import semmle.code.cpp.ir.implementation.MemoryAccessKind
6+ import semmle.code.cpp.ir.internal.Overlap
67private import semmle.code.cpp.ir.internal.OperandTag
78
89private newtype TOperand =
9- TNonPhiOperand ( Instruction useInstr , OperandTag tag , Instruction defInstr ) {
10- defInstr = Construction:: getInstructionOperandDefinition ( useInstr , tag )
10+ TRegisterOperand ( Instruction useInstr , RegisterOperandTag tag , Instruction defInstr ) {
11+ defInstr = Construction:: getRegisterOperandDefinition ( useInstr , tag )
1112 } or
12- TPhiOperand ( PhiInstruction useInstr , Instruction defInstr , IRBlock predecessorBlock ) {
13- defInstr = Construction:: getPhiInstructionOperandDefinition ( useInstr , predecessorBlock )
13+ TNonPhiMemoryOperand ( Instruction useInstr , MemoryOperandTag tag , Instruction defInstr , Overlap overlap ) {
14+ defInstr = Construction:: getMemoryOperandDefinition ( useInstr , tag , overlap )
15+ } or
16+ TPhiOperand ( PhiInstruction useInstr , Instruction defInstr , IRBlock predecessorBlock , Overlap overlap ) {
17+ defInstr = Construction:: getPhiOperandDefinition ( useInstr , predecessorBlock , overlap )
1418 }
1519
1620/**
@@ -25,8 +29,8 @@ class Operand extends TOperand {
2529 result = getUseInstruction ( ) .getLocation ( )
2630 }
2731
28- final IRFunction getEnclosingIRFunction ( ) {
29- result = getUseInstruction ( ) .getEnclosingIRFunction ( )
32+ final FunctionIR getEnclosingFunctionIR ( ) {
33+ result = getUseInstruction ( ) .getEnclosingFunctionIR ( )
3034 }
3135
3236 /**
@@ -43,6 +47,20 @@ class Operand extends TOperand {
4347 none ( )
4448 }
4549
50+ /**
51+ * Gets the overlap relationship between the operand's definition and its use.
52+ */
53+ Overlap getDefinitionOverlap ( ) {
54+ none ( )
55+ }
56+
57+ /**
58+ * Holds if the result of the definition instruction does not exactly overlap this use.
59+ */
60+ final predicate isDefinitionInexact ( ) {
61+ not getDefinitionOverlap ( ) instanceof MustExactlyOverlap
62+ }
63+
4664 /**
4765 * Gets a prefix to use when dumping the operand in an operand list.
4866 */
@@ -61,6 +79,13 @@ class Operand extends TOperand {
6179 result = getDumpLabel ( ) + getDefinitionInstruction ( ) .getResultId ( )
6280 }
6381
82+ private string getInexactSpecifier ( ) {
83+ if isDefinitionInexact ( ) then
84+ result = "~"
85+ else
86+ result = ""
87+ }
88+
6489 /**
6590 * Get the order in which the operand should be sorted in the operand list.
6691 */
@@ -104,10 +129,8 @@ class Operand extends TOperand {
104129 */
105130class MemoryOperand extends Operand {
106131 MemoryOperand ( ) {
107- exists ( MemoryOperandTag tag |
108- this = TNonPhiOperand ( _, tag , _)
109- ) or
110- this = TPhiOperand ( _, _, _)
132+ this = TNonPhiMemoryOperand ( _, _, _, _) or
133+ this = TPhiOperand ( _, _, _, _)
111134 }
112135
113136 override predicate isGLValue ( ) {
@@ -133,27 +156,17 @@ class MemoryOperand extends Operand {
133156 }
134157}
135158
136- /**
137- * An operand that consumes a register (non-memory) result.
138- */
139- class RegisterOperand extends Operand {
140- RegisterOperand ( ) {
141- exists ( RegisterOperandTag tag |
142- this = TNonPhiOperand ( _, tag , _)
143- )
144- }
145- }
146-
147159/**
148160 * An operand that is not an operand of a `PhiInstruction`.
149161 */
150- class NonPhiOperand extends Operand , TNonPhiOperand {
162+ class NonPhiOperand extends Operand {
151163 Instruction useInstr ;
152164 Instruction defInstr ;
153165 OperandTag tag ;
154166
155167 NonPhiOperand ( ) {
156- this = TNonPhiOperand ( useInstr , tag , defInstr )
168+ this = TRegisterOperand ( useInstr , tag , defInstr ) or
169+ this = TNonPhiMemoryOperand ( useInstr , tag , defInstr , _)
157170 }
158171
159172 override final Instruction getUseInstruction ( ) {
@@ -177,7 +190,32 @@ class NonPhiOperand extends Operand, TNonPhiOperand {
177190 }
178191}
179192
180- class TypedOperand extends NonPhiOperand , MemoryOperand {
193+ /**
194+ * An operand that consumes a register (non-memory) result.
195+ */
196+ class RegisterOperand extends NonPhiOperand , TRegisterOperand {
197+ override RegisterOperandTag tag ;
198+
199+ override final Overlap getDefinitionOverlap ( ) {
200+ // All register results overlap exactly with their uses.
201+ result instanceof MustExactlyOverlap
202+ }
203+ }
204+
205+ class NonPhiMemoryOperand extends NonPhiOperand , MemoryOperand , TNonPhiMemoryOperand {
206+ override MemoryOperandTag tag ;
207+ Overlap overlap ;
208+
209+ NonPhiMemoryOperand ( ) {
210+ this = TNonPhiMemoryOperand ( useInstr , tag , defInstr , overlap )
211+ }
212+
213+ override final Overlap getDefinitionOverlap ( ) {
214+ result = overlap
215+ }
216+ }
217+
218+ class TypedOperand extends NonPhiMemoryOperand {
181219 override TypedOperandTag tag ;
182220
183221 override final Type getType ( ) {
@@ -189,7 +227,7 @@ class TypedOperand extends NonPhiOperand, MemoryOperand {
189227 * The address operand of an instruction that loads or stores a value from
190228 * memory (e.g. `Load`, `Store`).
191229 */
192- class AddressOperand extends NonPhiOperand , RegisterOperand {
230+ class AddressOperand extends RegisterOperand {
193231 override AddressOperandTag tag ;
194232
195233 override string toString ( ) {
@@ -216,7 +254,7 @@ class LoadOperand extends TypedOperand {
216254/**
217255 * The source value operand of a `Store` instruction.
218256 */
219- class StoreValueOperand extends NonPhiOperand , RegisterOperand {
257+ class StoreValueOperand extends RegisterOperand {
220258 override StoreValueOperandTag tag ;
221259
222260 override string toString ( ) {
@@ -227,7 +265,7 @@ class StoreValueOperand extends NonPhiOperand, RegisterOperand {
227265/**
228266 * The sole operand of a unary instruction (e.g. `Convert`, `Negate`, `Copy`).
229267 */
230- class UnaryOperand extends NonPhiOperand , RegisterOperand {
268+ class UnaryOperand extends RegisterOperand {
231269 override UnaryOperandTag tag ;
232270
233271 override string toString ( ) {
@@ -238,7 +276,7 @@ class UnaryOperand extends NonPhiOperand, RegisterOperand {
238276/**
239277 * The left operand of a binary instruction (e.g. `Add`, `CompareEQ`).
240278 */
241- class LeftOperand extends NonPhiOperand , RegisterOperand {
279+ class LeftOperand extends RegisterOperand {
242280 override LeftOperandTag tag ;
243281
244282 override string toString ( ) {
@@ -249,7 +287,7 @@ class LeftOperand extends NonPhiOperand, RegisterOperand {
249287/**
250288 * The right operand of a binary instruction (e.g. `Add`, `CompareEQ`).
251289 */
252- class RightOperand extends NonPhiOperand , RegisterOperand {
290+ class RightOperand extends RegisterOperand {
253291 override RightOperandTag tag ;
254292
255293 override string toString ( ) {
@@ -260,7 +298,7 @@ class RightOperand extends NonPhiOperand, RegisterOperand {
260298/**
261299 * The condition operand of a `ConditionalBranch` or `Switch` instruction.
262300 */
263- class ConditionOperand extends NonPhiOperand , RegisterOperand {
301+ class ConditionOperand extends RegisterOperand {
264302 override ConditionOperandTag tag ;
265303
266304 override string toString ( ) {
@@ -272,7 +310,7 @@ class ConditionOperand extends NonPhiOperand, RegisterOperand {
272310 * An operand of the special `UnmodeledUse` instruction, representing a value
273311 * whose set of uses is unknown.
274312 */
275- class UnmodeledUseOperand extends NonPhiOperand , MemoryOperand {
313+ class UnmodeledUseOperand extends NonPhiMemoryOperand {
276314 override UnmodeledUseOperandTag tag ;
277315
278316 override string toString ( ) {
@@ -287,7 +325,7 @@ class UnmodeledUseOperand extends NonPhiOperand, MemoryOperand {
287325/**
288326 * The operand representing the target function of an `Call` instruction.
289327 */
290- class CallTargetOperand extends NonPhiOperand , RegisterOperand {
328+ class CallTargetOperand extends RegisterOperand {
291329 override CallTargetOperandTag tag ;
292330
293331 override string toString ( ) {
@@ -300,7 +338,7 @@ class CallTargetOperand extends NonPhiOperand, RegisterOperand {
300338 * positional arguments (represented by `PositionalArgumentOperand`) and the
301339 * implicit `this` argument, if any (represented by `ThisArgumentOperand`).
302340 */
303- class ArgumentOperand extends NonPhiOperand , RegisterOperand {
341+ class ArgumentOperand extends RegisterOperand {
304342 override ArgumentOperandTag tag ;
305343}
306344
@@ -379,13 +417,14 @@ class SideEffectOperand extends TypedOperand {
379417/**
380418 * An operand of a `PhiInstruction`.
381419 */
382- class PhiInputOperand extends MemoryOperand , TPhiOperand {
420+ class PhiOperand extends MemoryOperand , TPhiOperand {
383421 PhiInstruction useInstr ;
384422 Instruction defInstr ;
385423 IRBlock predecessorBlock ;
424+ Overlap overlap ;
386425
387- PhiInputOperand ( ) {
388- this = TPhiOperand ( useInstr , defInstr , predecessorBlock )
426+ PhiOperand ( ) {
427+ this = TPhiOperand ( useInstr , defInstr , predecessorBlock , overlap )
389428 }
390429
391430 override string toString ( ) {
@@ -400,6 +439,10 @@ class PhiInputOperand extends MemoryOperand, TPhiOperand {
400439 result = defInstr
401440 }
402441
442+ override final Overlap getDefinitionOverlap ( ) {
443+ result = overlap
444+ }
445+
403446 override final int getDumpSortOrder ( ) {
404447 result = 11 + getPredecessorBlock ( ) .getDisplayIndex ( )
405448 }
@@ -423,10 +466,8 @@ class PhiInputOperand extends MemoryOperand, TPhiOperand {
423466/**
424467 * The total operand of a Chi node, representing the previous value of the memory.
425468 */
426- class ChiTotalOperand extends MemoryOperand {
427- ChiTotalOperand ( ) {
428- this = TNonPhiOperand ( _, chiTotalOperand ( ) , _)
429- }
469+ class ChiTotalOperand extends NonPhiMemoryOperand {
470+ override ChiTotalOperandTag tag ;
430471
431472 override string toString ( ) {
432473 result = "ChiTotal"
@@ -441,10 +482,8 @@ class ChiTotalOperand extends MemoryOperand {
441482/**
442483 * The partial operand of a Chi node, representing the value being written to part of the memory.
443484 */
444- class ChiPartialOperand extends MemoryOperand {
445- ChiPartialOperand ( ) {
446- this = TNonPhiOperand ( _, chiPartialOperand ( ) , _)
447- }
485+ class ChiPartialOperand extends NonPhiMemoryOperand {
486+ override ChiPartialOperandTag tag ;
448487
449488 override string toString ( ) {
450489 result = "ChiPartial"
0 commit comments