Merge branch 'rc/1.23' into mergeback-123-ql

This commit is contained in:
james
2019-12-12 15:05:28 +00:00
31 changed files with 232 additions and 149 deletions

View File

@@ -11,13 +11,13 @@ cached
private newtype TOperand =
TRegisterOperand(Instruction useInstr, RegisterOperandTag tag, Instruction defInstr) {
defInstr = Construction::getRegisterOperandDefinition(useInstr, tag) and
not isInCycle(useInstr)
not Construction::isInCycle(useInstr)
} or
TNonPhiMemoryOperand(
Instruction useInstr, MemoryOperandTag tag, Instruction defInstr, Overlap overlap
) {
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
not isInCycle(useInstr)
not Construction::isInCycle(useInstr)
} or
TPhiOperand(
PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
@@ -25,28 +25,6 @@ private newtype TOperand =
defInstr = Construction::getPhiOperandDefinition(useInstr, predecessorBlock, overlap)
}
/** Gets a non-phi instruction that defines an operand of `instr`. */
private Instruction getNonPhiOperandDef(Instruction instr) {
result = Construction::getRegisterOperandDefinition(instr, _)
or
result = Construction::getMemoryOperandDefinition(instr, _, _)
}
/**
* Holds if `instr` is part of a cycle in the operand graph that doesn't go
* through a phi instruction and therefore should be impossible.
*
* If such cycles are present, either due to a programming error in the IR
* generation or due to a malformed database, it can cause infinite loops in
* analyses that assume a cycle-free graph of non-phi operands. Therefore it's
* better to remove these operands than to leave cycles in the operand graph.
*/
pragma[noopt]
private predicate isInCycle(Instruction instr) {
instr instanceof Instruction and
getNonPhiOperandDef+(instr) = instr
}
/**
* A source operand of an `Instruction`. The operand represents a value consumed by the instruction.
*/

View File

@@ -133,6 +133,16 @@ private module Cached {
overlap instanceof MustExactlyOverlap
}
/**
* Holds if `instr` is part of a cycle in the operand graph that doesn't go
* through a phi instruction and therefore should be impossible.
*
* For performance reasons, this predicate is not implemented (never holds)
* for the SSA stages of the IR.
*/
cached
predicate isInCycle(Instruction instr) { none() }
cached
Language::LanguageType getInstructionOperandType(Instruction instr, TypedOperandTag tag) {
exists(OldInstruction oldInstruction, OldIR::TypedOperand oldOperand |

View File

@@ -11,13 +11,13 @@ cached
private newtype TOperand =
TRegisterOperand(Instruction useInstr, RegisterOperandTag tag, Instruction defInstr) {
defInstr = Construction::getRegisterOperandDefinition(useInstr, tag) and
not isInCycle(useInstr)
not Construction::isInCycle(useInstr)
} or
TNonPhiMemoryOperand(
Instruction useInstr, MemoryOperandTag tag, Instruction defInstr, Overlap overlap
) {
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
not isInCycle(useInstr)
not Construction::isInCycle(useInstr)
} or
TPhiOperand(
PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
@@ -25,28 +25,6 @@ private newtype TOperand =
defInstr = Construction::getPhiOperandDefinition(useInstr, predecessorBlock, overlap)
}
/** Gets a non-phi instruction that defines an operand of `instr`. */
private Instruction getNonPhiOperandDef(Instruction instr) {
result = Construction::getRegisterOperandDefinition(instr, _)
or
result = Construction::getMemoryOperandDefinition(instr, _, _)
}
/**
* Holds if `instr` is part of a cycle in the operand graph that doesn't go
* through a phi instruction and therefore should be impossible.
*
* If such cycles are present, either due to a programming error in the IR
* generation or due to a malformed database, it can cause infinite loops in
* analyses that assume a cycle-free graph of non-phi operands. Therefore it's
* better to remove these operands than to leave cycles in the operand graph.
*/
pragma[noopt]
private predicate isInCycle(Instruction instr) {
instr instanceof Instruction and
getNonPhiOperandDef+(instr) = instr
}
/**
* A source operand of an `Instruction`. The operand represents a value consumed by the instruction.
*/

View File

@@ -93,6 +93,29 @@ private module Cached {
overlap instanceof MustTotallyOverlap
}
/** Gets a non-phi instruction that defines an operand of `instr`. */
private Instruction getNonPhiOperandDef(Instruction instr) {
result = getRegisterOperandDefinition(instr, _)
or
result = getMemoryOperandDefinition(instr, _, _)
}
/**
* Holds if `instr` is part of a cycle in the operand graph that doesn't go
* through a phi instruction and therefore should be impossible.
*
* If such cycles are present, either due to a programming error in the IR
* generation or due to a malformed database, it can cause infinite loops in
* analyses that assume a cycle-free graph of non-phi operands. Therefore it's
* better to remove these operands than to leave cycles in the operand graph.
*/
pragma[noopt]
cached
predicate isInCycle(Instruction instr) {
instr instanceof Instruction and
getNonPhiOperandDef+(instr) = instr
}
cached
CppType getInstructionOperandType(Instruction instruction, TypedOperandTag tag) {
// For all `LoadInstruction`s, the operand type of the `LoadOperand` is the same as

View File

@@ -684,9 +684,17 @@ abstract class TranslatedElement extends TTranslatedElement {
* Gets the temporary variable generated by this element with tag `tag`.
*/
final IRTempVariable getTempVariable(TempVariableTag tag) {
result.getAST() = getAST() and
result.getTag() = tag and
hasTempVariable(tag, _)
exists(Locatable ast |
result.getAST() = ast and
result.getTag() = tag and
hasTempVariableAndAST(tag, ast)
)
}
pragma[noinline]
private predicate hasTempVariableAndAST(TempVariableTag tag, Locatable ast) {
hasTempVariable(tag, _) and
ast = getAST()
}
/**

View File

@@ -11,13 +11,13 @@ cached
private newtype TOperand =
TRegisterOperand(Instruction useInstr, RegisterOperandTag tag, Instruction defInstr) {
defInstr = Construction::getRegisterOperandDefinition(useInstr, tag) and
not isInCycle(useInstr)
not Construction::isInCycle(useInstr)
} or
TNonPhiMemoryOperand(
Instruction useInstr, MemoryOperandTag tag, Instruction defInstr, Overlap overlap
) {
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
not isInCycle(useInstr)
not Construction::isInCycle(useInstr)
} or
TPhiOperand(
PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
@@ -25,28 +25,6 @@ private newtype TOperand =
defInstr = Construction::getPhiOperandDefinition(useInstr, predecessorBlock, overlap)
}
/** Gets a non-phi instruction that defines an operand of `instr`. */
private Instruction getNonPhiOperandDef(Instruction instr) {
result = Construction::getRegisterOperandDefinition(instr, _)
or
result = Construction::getMemoryOperandDefinition(instr, _, _)
}
/**
* Holds if `instr` is part of a cycle in the operand graph that doesn't go
* through a phi instruction and therefore should be impossible.
*
* If such cycles are present, either due to a programming error in the IR
* generation or due to a malformed database, it can cause infinite loops in
* analyses that assume a cycle-free graph of non-phi operands. Therefore it's
* better to remove these operands than to leave cycles in the operand graph.
*/
pragma[noopt]
private predicate isInCycle(Instruction instr) {
instr instanceof Instruction and
getNonPhiOperandDef+(instr) = instr
}
/**
* A source operand of an `Instruction`. The operand represents a value consumed by the instruction.
*/

View File

@@ -133,6 +133,16 @@ private module Cached {
overlap instanceof MustExactlyOverlap
}
/**
* Holds if `instr` is part of a cycle in the operand graph that doesn't go
* through a phi instruction and therefore should be impossible.
*
* For performance reasons, this predicate is not implemented (never holds)
* for the SSA stages of the IR.
*/
cached
predicate isInCycle(Instruction instr) { none() }
cached
Language::LanguageType getInstructionOperandType(Instruction instr, TypedOperandTag tag) {
exists(OldInstruction oldInstruction, OldIR::TypedOperand oldOperand |