C++: IR sanity query unnecessaryPhiInstruction

Have `Instruction.getResultSize()` return zero for `void`.
This commit is contained in:
Dave Bartolomeo
2018-08-17 15:37:19 -07:00
parent f4a060099b
commit 650539dbb6
6 changed files with 65 additions and 41 deletions

View File

@@ -68,17 +68,14 @@ module InstructionSanity {
} }
/** /**
* Holds if `Phi` instruction `instr` has fewer than two operands. * Holds if `Phi` instruction `instr` is missing an operand corresponding to
* the predecessor block `pred`.
*/ */
query predicate missingPhiOperands(PhiInstruction instr, int predIndex, Location predLoc) { query predicate missingPhiOperand(PhiInstruction instr, IRBlock pred) {
exists(IRBlock pred | pred = instr.getBlock().getAPredecessor() and
pred = instr.getBlock().getAPredecessor() and not exists(PhiOperand operand |
predLoc = pred.getLocation() and exists(instr.getOperand(operand)) and
predIndex = pred.getDisplayIndex() and operand.getPredecessorBlock() = pred
not exists(PhiOperand operand |
exists(instr.getOperand(operand)) and
operand.getPredecessorBlock() = pred
)
) )
} }
@@ -92,6 +89,18 @@ module InstructionSanity {
not instr instanceof PhiInstruction not instr instanceof PhiInstruction
} }
/**
* Holds if a `Phi` instruction is present in a block with fewer than two
* predecessors.
*/
query predicate unnecessaryPhiInstruction(PhiInstruction instr) {
count(instr.getBlock().getAPredecessor()) < 2
}
/**
* Holds if instruction `op` consumes an operand `operand` that was defined in
* a different function.
*/
query predicate operandAcrossFunctions( query predicate operandAcrossFunctions(
Instruction op, Instruction operand, OperandTag tag Instruction op, Instruction operand, OperandTag tag
) { ) {
@@ -321,8 +330,7 @@ class Instruction extends Construction::TInstruction {
/** /**
* Gets the size of the result produced by this instruction, in bytes. If the * Gets the size of the result produced by this instruction, in bytes. If the
* instruction does not produce a result, or if the result does not have a * result does not have a known constant size, this predicate does not hold.
* known constant size, this predicate does not hold.
* *
* If `this.isGLValue()` holds for this instruction, the value of * If `this.isGLValue()` holds for this instruction, the value of
* `getResultSize()` will always be the size of a pointer. * `getResultSize()` will always be the size of a pointer.
@@ -337,7 +345,6 @@ class Instruction extends Construction::TInstruction {
else if resultType instanceof UnknownType then else if resultType instanceof UnknownType then
result = Construction::getInstructionResultSize(this) result = Construction::getInstructionResultSize(this)
else ( else (
not resultType instanceof VoidType and
result = resultType.getSize() result = resultType.getSize()
) )
} }

View File

@@ -68,17 +68,14 @@ module InstructionSanity {
} }
/** /**
* Holds if `Phi` instruction `instr` has fewer than two operands. * Holds if `Phi` instruction `instr` is missing an operand corresponding to
* the predecessor block `pred`.
*/ */
query predicate missingPhiOperand(PhiInstruction instr, int predIndex, Location predLoc) { query predicate missingPhiOperand(PhiInstruction instr, IRBlock pred) {
exists(IRBlock pred | pred = instr.getBlock().getAPredecessor() and
pred = instr.getBlock().getAPredecessor() and not exists(PhiOperand operand |
predLoc = pred.getLocation() and exists(instr.getOperand(operand)) and
predIndex = pred.getDisplayIndex() and operand.getPredecessorBlock() = pred
not exists(PhiOperand operand |
exists(instr.getOperand(operand)) and
operand.getPredecessorBlock() = pred
)
) )
} }
@@ -92,6 +89,18 @@ module InstructionSanity {
not instr instanceof PhiInstruction not instr instanceof PhiInstruction
} }
/**
* Holds if a `Phi` instruction is present in a block with fewer than two
* predecessors.
*/
query predicate unnecessaryPhiInstruction(PhiInstruction instr) {
count(instr.getBlock().getAPredecessor()) < 2
}
/**
* Holds if instruction `op` consumes an operand `operand` that was defined in
* a different function.
*/
query predicate operandAcrossFunctions( query predicate operandAcrossFunctions(
Instruction op, Instruction operand, OperandTag tag Instruction op, Instruction operand, OperandTag tag
) { ) {
@@ -321,8 +330,7 @@ class Instruction extends Construction::TInstruction {
/** /**
* Gets the size of the result produced by this instruction, in bytes. If the * Gets the size of the result produced by this instruction, in bytes. If the
* instruction does not produce a result, or if the result does not have a * result does not have a known constant size, this predicate does not hold.
* known constant size, this predicate does not hold.
* *
* If `this.isGLValue()` holds for this instruction, the value of * If `this.isGLValue()` holds for this instruction, the value of
* `getResultSize()` will always be the size of a pointer. * `getResultSize()` will always be the size of a pointer.
@@ -337,7 +345,6 @@ class Instruction extends Construction::TInstruction {
else if resultType instanceof UnknownType then else if resultType instanceof UnknownType then
result = Construction::getInstructionResultSize(this) result = Construction::getInstructionResultSize(this)
else ( else (
not resultType instanceof VoidType and
result = resultType.getSize() result = resultType.getSize()
) )
} }

View File

@@ -68,17 +68,14 @@ module InstructionSanity {
} }
/** /**
* Holds if `Phi` instruction `instr` has fewer than two operands. * Holds if `Phi` instruction `instr` is missing an operand corresponding to
* the predecessor block `pred`.
*/ */
query predicate missingPhiOperands(PhiInstruction instr, int predIndex, Location predLoc) { query predicate missingPhiOperand(PhiInstruction instr, IRBlock pred) {
exists(IRBlock pred | pred = instr.getBlock().getAPredecessor() and
pred = instr.getBlock().getAPredecessor() and not exists(PhiOperand operand |
predLoc = pred.getLocation() and exists(instr.getOperand(operand)) and
predIndex = pred.getDisplayIndex() and operand.getPredecessorBlock() = pred
not exists(PhiOperand operand |
exists(instr.getOperand(operand)) and
operand.getPredecessorBlock() = pred
)
) )
} }
@@ -92,6 +89,18 @@ module InstructionSanity {
not instr instanceof PhiInstruction not instr instanceof PhiInstruction
} }
/**
* Holds if a `Phi` instruction is present in a block with fewer than two
* predecessors.
*/
query predicate unnecessaryPhiInstruction(PhiInstruction instr) {
count(instr.getBlock().getAPredecessor()) < 2
}
/**
* Holds if instruction `op` consumes an operand `operand` that was defined in
* a different function.
*/
query predicate operandAcrossFunctions( query predicate operandAcrossFunctions(
Instruction op, Instruction operand, OperandTag tag Instruction op, Instruction operand, OperandTag tag
) { ) {
@@ -321,8 +330,7 @@ class Instruction extends Construction::TInstruction {
/** /**
* Gets the size of the result produced by this instruction, in bytes. If the * Gets the size of the result produced by this instruction, in bytes. If the
* instruction does not produce a result, or if the result does not have a * result does not have a known constant size, this predicate does not hold.
* known constant size, this predicate does not hold.
* *
* If `this.isGLValue()` holds for this instruction, the value of * If `this.isGLValue()` holds for this instruction, the value of
* `getResultSize()` will always be the size of a pointer. * `getResultSize()` will always be the size of a pointer.
@@ -337,7 +345,6 @@ class Instruction extends Construction::TInstruction {
else if resultType instanceof UnknownType then else if resultType instanceof UnknownType then
result = Construction::getInstructionResultSize(this) result = Construction::getInstructionResultSize(this)
else ( else (
not resultType instanceof VoidType and
result = resultType.getSize() result = resultType.getSize()
) )
} }

View File

@@ -3,4 +3,5 @@ unexpectedOperand
duplicateOperand duplicateOperand
missingPhiOperand missingPhiOperand
instructionWithoutSuccessor instructionWithoutSuccessor
unnecessaryPhiInstruction
operandAcrossFunctions operandAcrossFunctions

View File

@@ -1,6 +1,7 @@
missingOperand missingOperand
unexpectedOperand unexpectedOperand
duplicateOperand duplicateOperand
missingPhiOperands missingPhiOperand
instructionWithoutSuccessor instructionWithoutSuccessor
unnecessaryPhiInstruction
operandAcrossFunctions operandAcrossFunctions

View File

@@ -1,6 +1,7 @@
missingOperand missingOperand
unexpectedOperand unexpectedOperand
duplicateOperand duplicateOperand
missingPhiOperands missingPhiOperand
instructionWithoutSuccessor instructionWithoutSuccessor
unnecessaryPhiInstruction
operandAcrossFunctions operandAcrossFunctions