mirror of
https://github.com/github/codeql.git
synced 2026-04-29 02:35:15 +02:00
C++/C#: Allow non-Phi memory operands to have no definition
This commit is contained in:
@@ -14,12 +14,8 @@ private newtype TOperand =
|
||||
not Construction::isInCycle(useInstr) and
|
||||
strictcount(Construction::getRegisterOperandDefinition(useInstr, tag)) = 1
|
||||
} or
|
||||
TNonPhiMemoryOperand(
|
||||
Instruction useInstr, MemoryOperandTag tag, Instruction defInstr, Overlap overlap
|
||||
) {
|
||||
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
|
||||
not Construction::isInCycle(useInstr) and
|
||||
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
|
||||
TNonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
|
||||
useInstr.getOpcode().hasOperand(tag)
|
||||
} or
|
||||
TPhiOperand(
|
||||
PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
|
||||
@@ -45,10 +41,8 @@ private class NonPhiMemoryOperandBase extends OperandBase, TNonPhiMemoryOperand
|
||||
abstract override string toString();
|
||||
}
|
||||
|
||||
private NonPhiMemoryOperandBase nonPhiMemoryOperand(
|
||||
Instruction useInstr, MemoryOperandTag tag, Instruction defInstr, Overlap overlap
|
||||
) {
|
||||
result = TNonPhiMemoryOperand(useInstr, tag, defInstr, overlap)
|
||||
private NonPhiMemoryOperandBase nonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
|
||||
result = TNonPhiMemoryOperand(useInstr, tag)
|
||||
}
|
||||
|
||||
private class PhiOperandBase extends OperandBase, TPhiOperand {
|
||||
@@ -234,18 +228,15 @@ class MemoryOperand extends Operand {
|
||||
*/
|
||||
class NonPhiOperand extends Operand {
|
||||
Instruction useInstr;
|
||||
Instruction defInstr;
|
||||
OperandTag tag;
|
||||
|
||||
NonPhiOperand() {
|
||||
this = registerOperand(useInstr, tag, defInstr) or
|
||||
this = nonPhiMemoryOperand(useInstr, tag, defInstr, _)
|
||||
this = registerOperand(useInstr, tag, _) or
|
||||
this = nonPhiMemoryOperand(useInstr, tag)
|
||||
}
|
||||
|
||||
final override Instruction getUse() { result = useInstr }
|
||||
|
||||
final override Instruction getAnyDef() { result = defInstr }
|
||||
|
||||
final override string getDumpLabel() { result = tag.getLabel() }
|
||||
|
||||
final override int getDumpSortOrder() { result = tag.getSortOrder() }
|
||||
@@ -258,9 +249,14 @@ class NonPhiOperand extends Operand {
|
||||
*/
|
||||
class RegisterOperand extends NonPhiOperand, RegisterOperandBase {
|
||||
override RegisterOperandTag tag;
|
||||
Instruction defInstr;
|
||||
|
||||
RegisterOperand() { this = registerOperand(useInstr, tag, defInstr) }
|
||||
|
||||
final override string toString() { result = tag.toString() }
|
||||
|
||||
final override Instruction getAnyDef() { result = defInstr }
|
||||
|
||||
final override Overlap getDefinitionOverlap() {
|
||||
// All register results overlap exactly with their uses.
|
||||
result instanceof MustExactlyOverlap
|
||||
@@ -269,13 +265,21 @@ class RegisterOperand extends NonPhiOperand, RegisterOperandBase {
|
||||
|
||||
class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, NonPhiMemoryOperandBase {
|
||||
override MemoryOperandTag tag;
|
||||
Overlap overlap;
|
||||
|
||||
NonPhiMemoryOperand() { this = TNonPhiMemoryOperand(useInstr, tag, defInstr, overlap) }
|
||||
NonPhiMemoryOperand() { this = nonPhiMemoryOperand(useInstr, tag) }
|
||||
|
||||
final override string toString() { result = tag.toString() }
|
||||
|
||||
final override Overlap getDefinitionOverlap() { result = overlap }
|
||||
final override Instruction getAnyDef() { hasDefinition(result, _) }
|
||||
|
||||
final override Overlap getDefinitionOverlap() { hasDefinition(_, result) }
|
||||
|
||||
pragma[noinline]
|
||||
private predicate hasDefinition(Instruction defInstr, Overlap overlap) {
|
||||
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
|
||||
not Construction::isInCycle(useInstr) and
|
||||
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
|
||||
}
|
||||
}
|
||||
|
||||
class TypedOperand extends NonPhiMemoryOperand {
|
||||
|
||||
@@ -14,12 +14,8 @@ private newtype TOperand =
|
||||
not Construction::isInCycle(useInstr) and
|
||||
strictcount(Construction::getRegisterOperandDefinition(useInstr, tag)) = 1
|
||||
} or
|
||||
TNonPhiMemoryOperand(
|
||||
Instruction useInstr, MemoryOperandTag tag, Instruction defInstr, Overlap overlap
|
||||
) {
|
||||
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
|
||||
not Construction::isInCycle(useInstr) and
|
||||
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
|
||||
TNonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
|
||||
useInstr.getOpcode().hasOperand(tag)
|
||||
} or
|
||||
TPhiOperand(
|
||||
PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
|
||||
@@ -45,10 +41,8 @@ private class NonPhiMemoryOperandBase extends OperandBase, TNonPhiMemoryOperand
|
||||
abstract override string toString();
|
||||
}
|
||||
|
||||
private NonPhiMemoryOperandBase nonPhiMemoryOperand(
|
||||
Instruction useInstr, MemoryOperandTag tag, Instruction defInstr, Overlap overlap
|
||||
) {
|
||||
result = TNonPhiMemoryOperand(useInstr, tag, defInstr, overlap)
|
||||
private NonPhiMemoryOperandBase nonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
|
||||
result = TNonPhiMemoryOperand(useInstr, tag)
|
||||
}
|
||||
|
||||
private class PhiOperandBase extends OperandBase, TPhiOperand {
|
||||
@@ -234,18 +228,15 @@ class MemoryOperand extends Operand {
|
||||
*/
|
||||
class NonPhiOperand extends Operand {
|
||||
Instruction useInstr;
|
||||
Instruction defInstr;
|
||||
OperandTag tag;
|
||||
|
||||
NonPhiOperand() {
|
||||
this = registerOperand(useInstr, tag, defInstr) or
|
||||
this = nonPhiMemoryOperand(useInstr, tag, defInstr, _)
|
||||
this = registerOperand(useInstr, tag, _) or
|
||||
this = nonPhiMemoryOperand(useInstr, tag)
|
||||
}
|
||||
|
||||
final override Instruction getUse() { result = useInstr }
|
||||
|
||||
final override Instruction getAnyDef() { result = defInstr }
|
||||
|
||||
final override string getDumpLabel() { result = tag.getLabel() }
|
||||
|
||||
final override int getDumpSortOrder() { result = tag.getSortOrder() }
|
||||
@@ -258,9 +249,14 @@ class NonPhiOperand extends Operand {
|
||||
*/
|
||||
class RegisterOperand extends NonPhiOperand, RegisterOperandBase {
|
||||
override RegisterOperandTag tag;
|
||||
Instruction defInstr;
|
||||
|
||||
RegisterOperand() { this = registerOperand(useInstr, tag, defInstr) }
|
||||
|
||||
final override string toString() { result = tag.toString() }
|
||||
|
||||
final override Instruction getAnyDef() { result = defInstr }
|
||||
|
||||
final override Overlap getDefinitionOverlap() {
|
||||
// All register results overlap exactly with their uses.
|
||||
result instanceof MustExactlyOverlap
|
||||
@@ -269,13 +265,21 @@ class RegisterOperand extends NonPhiOperand, RegisterOperandBase {
|
||||
|
||||
class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, NonPhiMemoryOperandBase {
|
||||
override MemoryOperandTag tag;
|
||||
Overlap overlap;
|
||||
|
||||
NonPhiMemoryOperand() { this = TNonPhiMemoryOperand(useInstr, tag, defInstr, overlap) }
|
||||
NonPhiMemoryOperand() { this = nonPhiMemoryOperand(useInstr, tag) }
|
||||
|
||||
final override string toString() { result = tag.toString() }
|
||||
|
||||
final override Overlap getDefinitionOverlap() { result = overlap }
|
||||
final override Instruction getAnyDef() { hasDefinition(result, _) }
|
||||
|
||||
final override Overlap getDefinitionOverlap() { hasDefinition(_, result) }
|
||||
|
||||
pragma[noinline]
|
||||
private predicate hasDefinition(Instruction defInstr, Overlap overlap) {
|
||||
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
|
||||
not Construction::isInCycle(useInstr) and
|
||||
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
|
||||
}
|
||||
}
|
||||
|
||||
class TypedOperand extends NonPhiMemoryOperand {
|
||||
|
||||
@@ -14,12 +14,8 @@ private newtype TOperand =
|
||||
not Construction::isInCycle(useInstr) and
|
||||
strictcount(Construction::getRegisterOperandDefinition(useInstr, tag)) = 1
|
||||
} or
|
||||
TNonPhiMemoryOperand(
|
||||
Instruction useInstr, MemoryOperandTag tag, Instruction defInstr, Overlap overlap
|
||||
) {
|
||||
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
|
||||
not Construction::isInCycle(useInstr) and
|
||||
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
|
||||
TNonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
|
||||
useInstr.getOpcode().hasOperand(tag)
|
||||
} or
|
||||
TPhiOperand(
|
||||
PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
|
||||
@@ -45,10 +41,8 @@ private class NonPhiMemoryOperandBase extends OperandBase, TNonPhiMemoryOperand
|
||||
abstract override string toString();
|
||||
}
|
||||
|
||||
private NonPhiMemoryOperandBase nonPhiMemoryOperand(
|
||||
Instruction useInstr, MemoryOperandTag tag, Instruction defInstr, Overlap overlap
|
||||
) {
|
||||
result = TNonPhiMemoryOperand(useInstr, tag, defInstr, overlap)
|
||||
private NonPhiMemoryOperandBase nonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
|
||||
result = TNonPhiMemoryOperand(useInstr, tag)
|
||||
}
|
||||
|
||||
private class PhiOperandBase extends OperandBase, TPhiOperand {
|
||||
@@ -234,18 +228,15 @@ class MemoryOperand extends Operand {
|
||||
*/
|
||||
class NonPhiOperand extends Operand {
|
||||
Instruction useInstr;
|
||||
Instruction defInstr;
|
||||
OperandTag tag;
|
||||
|
||||
NonPhiOperand() {
|
||||
this = registerOperand(useInstr, tag, defInstr) or
|
||||
this = nonPhiMemoryOperand(useInstr, tag, defInstr, _)
|
||||
this = registerOperand(useInstr, tag, _) or
|
||||
this = nonPhiMemoryOperand(useInstr, tag)
|
||||
}
|
||||
|
||||
final override Instruction getUse() { result = useInstr }
|
||||
|
||||
final override Instruction getAnyDef() { result = defInstr }
|
||||
|
||||
final override string getDumpLabel() { result = tag.getLabel() }
|
||||
|
||||
final override int getDumpSortOrder() { result = tag.getSortOrder() }
|
||||
@@ -258,9 +249,14 @@ class NonPhiOperand extends Operand {
|
||||
*/
|
||||
class RegisterOperand extends NonPhiOperand, RegisterOperandBase {
|
||||
override RegisterOperandTag tag;
|
||||
Instruction defInstr;
|
||||
|
||||
RegisterOperand() { this = registerOperand(useInstr, tag, defInstr) }
|
||||
|
||||
final override string toString() { result = tag.toString() }
|
||||
|
||||
final override Instruction getAnyDef() { result = defInstr }
|
||||
|
||||
final override Overlap getDefinitionOverlap() {
|
||||
// All register results overlap exactly with their uses.
|
||||
result instanceof MustExactlyOverlap
|
||||
@@ -269,13 +265,21 @@ class RegisterOperand extends NonPhiOperand, RegisterOperandBase {
|
||||
|
||||
class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, NonPhiMemoryOperandBase {
|
||||
override MemoryOperandTag tag;
|
||||
Overlap overlap;
|
||||
|
||||
NonPhiMemoryOperand() { this = TNonPhiMemoryOperand(useInstr, tag, defInstr, overlap) }
|
||||
NonPhiMemoryOperand() { this = nonPhiMemoryOperand(useInstr, tag) }
|
||||
|
||||
final override string toString() { result = tag.toString() }
|
||||
|
||||
final override Overlap getDefinitionOverlap() { result = overlap }
|
||||
final override Instruction getAnyDef() { hasDefinition(result, _) }
|
||||
|
||||
final override Overlap getDefinitionOverlap() { hasDefinition(_, result) }
|
||||
|
||||
pragma[noinline]
|
||||
private predicate hasDefinition(Instruction defInstr, Overlap overlap) {
|
||||
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
|
||||
not Construction::isInCycle(useInstr) and
|
||||
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
|
||||
}
|
||||
}
|
||||
|
||||
class TypedOperand extends NonPhiMemoryOperand {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
missingOperand
|
||||
unexpectedOperand
|
||||
duplicateOperand
|
||||
| ssa.cpp:301:27:301:30 | ReturnIndirection: argv | Instruction has 2 operands with tag 'SideEffect' in function '$@'. | ssa.cpp:301:5:301:8 | IR: main | int main(int, char**) |
|
||||
missingPhiOperand
|
||||
missingOperandType
|
||||
duplicateChiOperand
|
||||
|
||||
@@ -1480,7 +1480,7 @@ ssa.cpp:
|
||||
# 304| r304_5(char) = Load : &:r304_4, ~m303_8
|
||||
# 304| r304_6(int) = Convert : r304_5
|
||||
# 304| m304_7(int) = Store : &:r304_1, r304_6
|
||||
# 301| v301_12(void) = ReturnIndirection[argv] : &:r301_10, ~m303_11, m303_11
|
||||
# 301| v301_12(void) = ReturnIndirection[argv] : &:r301_10, m303_11
|
||||
# 301| r301_13(glval<int>) = VariableAddress[#return] :
|
||||
# 301| v301_14(void) = ReturnValue : &:r301_13, m304_7
|
||||
# 301| v301_15(void) = AliasedUse : ~m303_8
|
||||
|
||||
@@ -14,12 +14,8 @@ private newtype TOperand =
|
||||
not Construction::isInCycle(useInstr) and
|
||||
strictcount(Construction::getRegisterOperandDefinition(useInstr, tag)) = 1
|
||||
} or
|
||||
TNonPhiMemoryOperand(
|
||||
Instruction useInstr, MemoryOperandTag tag, Instruction defInstr, Overlap overlap
|
||||
) {
|
||||
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
|
||||
not Construction::isInCycle(useInstr) and
|
||||
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
|
||||
TNonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
|
||||
useInstr.getOpcode().hasOperand(tag)
|
||||
} or
|
||||
TPhiOperand(
|
||||
PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
|
||||
@@ -45,10 +41,8 @@ private class NonPhiMemoryOperandBase extends OperandBase, TNonPhiMemoryOperand
|
||||
abstract override string toString();
|
||||
}
|
||||
|
||||
private NonPhiMemoryOperandBase nonPhiMemoryOperand(
|
||||
Instruction useInstr, MemoryOperandTag tag, Instruction defInstr, Overlap overlap
|
||||
) {
|
||||
result = TNonPhiMemoryOperand(useInstr, tag, defInstr, overlap)
|
||||
private NonPhiMemoryOperandBase nonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
|
||||
result = TNonPhiMemoryOperand(useInstr, tag)
|
||||
}
|
||||
|
||||
private class PhiOperandBase extends OperandBase, TPhiOperand {
|
||||
@@ -234,18 +228,15 @@ class MemoryOperand extends Operand {
|
||||
*/
|
||||
class NonPhiOperand extends Operand {
|
||||
Instruction useInstr;
|
||||
Instruction defInstr;
|
||||
OperandTag tag;
|
||||
|
||||
NonPhiOperand() {
|
||||
this = registerOperand(useInstr, tag, defInstr) or
|
||||
this = nonPhiMemoryOperand(useInstr, tag, defInstr, _)
|
||||
this = registerOperand(useInstr, tag, _) or
|
||||
this = nonPhiMemoryOperand(useInstr, tag)
|
||||
}
|
||||
|
||||
final override Instruction getUse() { result = useInstr }
|
||||
|
||||
final override Instruction getAnyDef() { result = defInstr }
|
||||
|
||||
final override string getDumpLabel() { result = tag.getLabel() }
|
||||
|
||||
final override int getDumpSortOrder() { result = tag.getSortOrder() }
|
||||
@@ -258,9 +249,14 @@ class NonPhiOperand extends Operand {
|
||||
*/
|
||||
class RegisterOperand extends NonPhiOperand, RegisterOperandBase {
|
||||
override RegisterOperandTag tag;
|
||||
Instruction defInstr;
|
||||
|
||||
RegisterOperand() { this = registerOperand(useInstr, tag, defInstr) }
|
||||
|
||||
final override string toString() { result = tag.toString() }
|
||||
|
||||
final override Instruction getAnyDef() { result = defInstr }
|
||||
|
||||
final override Overlap getDefinitionOverlap() {
|
||||
// All register results overlap exactly with their uses.
|
||||
result instanceof MustExactlyOverlap
|
||||
@@ -269,13 +265,21 @@ class RegisterOperand extends NonPhiOperand, RegisterOperandBase {
|
||||
|
||||
class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, NonPhiMemoryOperandBase {
|
||||
override MemoryOperandTag tag;
|
||||
Overlap overlap;
|
||||
|
||||
NonPhiMemoryOperand() { this = TNonPhiMemoryOperand(useInstr, tag, defInstr, overlap) }
|
||||
NonPhiMemoryOperand() { this = nonPhiMemoryOperand(useInstr, tag) }
|
||||
|
||||
final override string toString() { result = tag.toString() }
|
||||
|
||||
final override Overlap getDefinitionOverlap() { result = overlap }
|
||||
final override Instruction getAnyDef() { hasDefinition(result, _) }
|
||||
|
||||
final override Overlap getDefinitionOverlap() { hasDefinition(_, result) }
|
||||
|
||||
pragma[noinline]
|
||||
private predicate hasDefinition(Instruction defInstr, Overlap overlap) {
|
||||
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
|
||||
not Construction::isInCycle(useInstr) and
|
||||
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
|
||||
}
|
||||
}
|
||||
|
||||
class TypedOperand extends NonPhiMemoryOperand {
|
||||
|
||||
@@ -14,12 +14,8 @@ private newtype TOperand =
|
||||
not Construction::isInCycle(useInstr) and
|
||||
strictcount(Construction::getRegisterOperandDefinition(useInstr, tag)) = 1
|
||||
} or
|
||||
TNonPhiMemoryOperand(
|
||||
Instruction useInstr, MemoryOperandTag tag, Instruction defInstr, Overlap overlap
|
||||
) {
|
||||
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
|
||||
not Construction::isInCycle(useInstr) and
|
||||
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
|
||||
TNonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
|
||||
useInstr.getOpcode().hasOperand(tag)
|
||||
} or
|
||||
TPhiOperand(
|
||||
PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
|
||||
@@ -45,10 +41,8 @@ private class NonPhiMemoryOperandBase extends OperandBase, TNonPhiMemoryOperand
|
||||
abstract override string toString();
|
||||
}
|
||||
|
||||
private NonPhiMemoryOperandBase nonPhiMemoryOperand(
|
||||
Instruction useInstr, MemoryOperandTag tag, Instruction defInstr, Overlap overlap
|
||||
) {
|
||||
result = TNonPhiMemoryOperand(useInstr, tag, defInstr, overlap)
|
||||
private NonPhiMemoryOperandBase nonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
|
||||
result = TNonPhiMemoryOperand(useInstr, tag)
|
||||
}
|
||||
|
||||
private class PhiOperandBase extends OperandBase, TPhiOperand {
|
||||
@@ -234,18 +228,15 @@ class MemoryOperand extends Operand {
|
||||
*/
|
||||
class NonPhiOperand extends Operand {
|
||||
Instruction useInstr;
|
||||
Instruction defInstr;
|
||||
OperandTag tag;
|
||||
|
||||
NonPhiOperand() {
|
||||
this = registerOperand(useInstr, tag, defInstr) or
|
||||
this = nonPhiMemoryOperand(useInstr, tag, defInstr, _)
|
||||
this = registerOperand(useInstr, tag, _) or
|
||||
this = nonPhiMemoryOperand(useInstr, tag)
|
||||
}
|
||||
|
||||
final override Instruction getUse() { result = useInstr }
|
||||
|
||||
final override Instruction getAnyDef() { result = defInstr }
|
||||
|
||||
final override string getDumpLabel() { result = tag.getLabel() }
|
||||
|
||||
final override int getDumpSortOrder() { result = tag.getSortOrder() }
|
||||
@@ -258,9 +249,14 @@ class NonPhiOperand extends Operand {
|
||||
*/
|
||||
class RegisterOperand extends NonPhiOperand, RegisterOperandBase {
|
||||
override RegisterOperandTag tag;
|
||||
Instruction defInstr;
|
||||
|
||||
RegisterOperand() { this = registerOperand(useInstr, tag, defInstr) }
|
||||
|
||||
final override string toString() { result = tag.toString() }
|
||||
|
||||
final override Instruction getAnyDef() { result = defInstr }
|
||||
|
||||
final override Overlap getDefinitionOverlap() {
|
||||
// All register results overlap exactly with their uses.
|
||||
result instanceof MustExactlyOverlap
|
||||
@@ -269,13 +265,21 @@ class RegisterOperand extends NonPhiOperand, RegisterOperandBase {
|
||||
|
||||
class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, NonPhiMemoryOperandBase {
|
||||
override MemoryOperandTag tag;
|
||||
Overlap overlap;
|
||||
|
||||
NonPhiMemoryOperand() { this = TNonPhiMemoryOperand(useInstr, tag, defInstr, overlap) }
|
||||
NonPhiMemoryOperand() { this = nonPhiMemoryOperand(useInstr, tag) }
|
||||
|
||||
final override string toString() { result = tag.toString() }
|
||||
|
||||
final override Overlap getDefinitionOverlap() { result = overlap }
|
||||
final override Instruction getAnyDef() { hasDefinition(result, _) }
|
||||
|
||||
final override Overlap getDefinitionOverlap() { hasDefinition(_, result) }
|
||||
|
||||
pragma[noinline]
|
||||
private predicate hasDefinition(Instruction defInstr, Overlap overlap) {
|
||||
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
|
||||
not Construction::isInCycle(useInstr) and
|
||||
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
|
||||
}
|
||||
}
|
||||
|
||||
class TypedOperand extends NonPhiMemoryOperand {
|
||||
|
||||
Reference in New Issue
Block a user