Merge pull request #2835 from MathiasVP/value-number-perf

C++: Value number performance fix
This commit is contained in:
Jonas Jensen
2020-02-15 20:40:53 +01:00
committed by GitHub
3 changed files with 135 additions and 99 deletions

View File

@@ -19,19 +19,18 @@ newtype TValueNumber =
fieldAddressValueNumber(_, irFunc, field, objectAddress) fieldAddressValueNumber(_, irFunc, field, objectAddress)
} or } or
TBinaryValueNumber( TBinaryValueNumber(
IRFunction irFunc, Opcode opcode, IRType type, TValueNumber leftOperand, IRFunction irFunc, Opcode opcode, TValueNumber leftOperand, TValueNumber rightOperand
TValueNumber rightOperand
) { ) {
binaryValueNumber(_, irFunc, opcode, type, leftOperand, rightOperand) binaryValueNumber(_, irFunc, opcode, leftOperand, rightOperand)
} or } or
TPointerArithmeticValueNumber( TPointerArithmeticValueNumber(
IRFunction irFunc, Opcode opcode, IRType type, int elementSize, TValueNumber leftOperand, IRFunction irFunc, Opcode opcode, int elementSize, TValueNumber leftOperand,
TValueNumber rightOperand TValueNumber rightOperand
) { ) {
pointerArithmeticValueNumber(_, irFunc, opcode, type, elementSize, leftOperand, rightOperand) pointerArithmeticValueNumber(_, irFunc, opcode, elementSize, leftOperand, rightOperand)
} or } or
TUnaryValueNumber(IRFunction irFunc, Opcode opcode, IRType type, TValueNumber operand) { TUnaryValueNumber(IRFunction irFunc, Opcode opcode, TValueNumber operand) {
unaryValueNumber(_, irFunc, opcode, type, operand) unaryValueNumber(_, irFunc, opcode, operand)
} or } or
TInheritanceConversionValueNumber( TInheritanceConversionValueNumber(
IRFunction irFunc, Opcode opcode, Class baseClass, Class derivedClass, TValueNumber operand IRFunction irFunc, Opcode opcode, Class baseClass, Class derivedClass, TValueNumber operand
@@ -99,6 +98,19 @@ private predicate numberableInstruction(Instruction instr) {
instr instanceof LoadTotalOverlapInstruction instr instanceof LoadTotalOverlapInstruction
} }
private predicate filteredNumberableInstruction(Instruction instr) {
// count rather than strictcount to handle missing AST elements
// separate instanceof and inline casts to avoid failed casts with a count of 0
instr instanceof VariableAddressInstruction and
count(instr.(VariableAddressInstruction).getIRVariable().getAST()) != 1
or
instr instanceof ConstantInstruction and
count(instr.getResultIRType()) != 1
or
instr instanceof FieldAddressInstruction and
count(instr.(FieldAddressInstruction).getField()) != 1
}
private predicate variableAddressValueNumber( private predicate variableAddressValueNumber(
VariableAddressInstruction instr, IRFunction irFunc, Language::AST ast VariableAddressInstruction instr, IRFunction irFunc, Language::AST ast
) { ) {
@@ -106,7 +118,8 @@ private predicate variableAddressValueNumber(
// The underlying AST element is used as value-numbering key instead of the // The underlying AST element is used as value-numbering key instead of the
// `IRVariable` to work around a problem where a variable or expression with // `IRVariable` to work around a problem where a variable or expression with
// multiple types gives rise to multiple `IRVariable`s. // multiple types gives rise to multiple `IRVariable`s.
instr.getIRVariable().getAST() = ast instr.getIRVariable().getAST() = ast and
strictcount(instr.getIRVariable().getAST()) = 1
} }
private predicate initializeParameterValueNumber( private predicate initializeParameterValueNumber(
@@ -123,10 +136,11 @@ private predicate initializeThisValueNumber(InitializeThisInstruction instr, IRF
instr.getEnclosingIRFunction() = irFunc instr.getEnclosingIRFunction() = irFunc
} }
private predicate constantValueNumber( predicate constantValueNumber(
ConstantInstruction instr, IRFunction irFunc, IRType type, string value ConstantInstruction instr, IRFunction irFunc, IRType type, string value
) { ) {
instr.getEnclosingIRFunction() = irFunc and instr.getEnclosingIRFunction() = irFunc and
strictcount(instr.getResultIRType()) = 1 and
instr.getResultIRType() = type and instr.getResultIRType() = type and
instr.getValue() = value instr.getValue() = value
} }
@@ -145,42 +159,40 @@ private predicate fieldAddressValueNumber(
) { ) {
instr.getEnclosingIRFunction() = irFunc and instr.getEnclosingIRFunction() = irFunc and
instr.getField() = field and instr.getField() = field and
strictcount(instr.getField()) = 1 and
tvalueNumber(instr.getObjectAddress()) = objectAddress tvalueNumber(instr.getObjectAddress()) = objectAddress
} }
private predicate binaryValueNumber( private predicate binaryValueNumber(
BinaryInstruction instr, IRFunction irFunc, Opcode opcode, IRType type, TValueNumber leftOperand, BinaryInstruction instr, IRFunction irFunc, Opcode opcode, TValueNumber leftOperand,
TValueNumber rightOperand TValueNumber rightOperand
) { ) {
instr.getEnclosingIRFunction() = irFunc and instr.getEnclosingIRFunction() = irFunc and
not instr instanceof PointerArithmeticInstruction and not instr instanceof PointerArithmeticInstruction and
instr.getOpcode() = opcode and instr.getOpcode() = opcode and
instr.getResultIRType() = type and
tvalueNumber(instr.getLeft()) = leftOperand and tvalueNumber(instr.getLeft()) = leftOperand and
tvalueNumber(instr.getRight()) = rightOperand tvalueNumber(instr.getRight()) = rightOperand
} }
private predicate pointerArithmeticValueNumber( private predicate pointerArithmeticValueNumber(
PointerArithmeticInstruction instr, IRFunction irFunc, Opcode opcode, IRType type, PointerArithmeticInstruction instr, IRFunction irFunc, Opcode opcode, int elementSize,
int elementSize, TValueNumber leftOperand, TValueNumber rightOperand TValueNumber leftOperand, TValueNumber rightOperand
) { ) {
instr.getEnclosingIRFunction() = irFunc and instr.getEnclosingIRFunction() = irFunc and
instr.getOpcode() = opcode and instr.getOpcode() = opcode and
instr.getResultIRType() = type and
instr.getElementSize() = elementSize and instr.getElementSize() = elementSize and
tvalueNumber(instr.getLeft()) = leftOperand and tvalueNumber(instr.getLeft()) = leftOperand and
tvalueNumber(instr.getRight()) = rightOperand tvalueNumber(instr.getRight()) = rightOperand
} }
private predicate unaryValueNumber( private predicate unaryValueNumber(
UnaryInstruction instr, IRFunction irFunc, Opcode opcode, IRType type, TValueNumber operand UnaryInstruction instr, IRFunction irFunc, Opcode opcode, TValueNumber operand
) { ) {
instr.getEnclosingIRFunction() = irFunc and instr.getEnclosingIRFunction() = irFunc and
not instr instanceof InheritanceConversionInstruction and not instr instanceof InheritanceConversionInstruction and
not instr instanceof CopyInstruction and not instr instanceof CopyInstruction and
not instr instanceof FieldAddressInstruction and not instr instanceof FieldAddressInstruction and
instr.getOpcode() = opcode and instr.getOpcode() = opcode and
instr.getResultIRType() = type and
tvalueNumber(instr.getUnary()) = operand tvalueNumber(instr.getUnary()) = operand
} }
@@ -200,9 +212,9 @@ private predicate loadTotalOverlapValueNumber(
TValueNumber operand TValueNumber operand
) { ) {
instr.getEnclosingIRFunction() = irFunc and instr.getEnclosingIRFunction() = irFunc and
instr.getResultIRType() = type and
tvalueNumber(instr.getAnOperand().(MemoryOperand).getAnyDef()) = memOperand and tvalueNumber(instr.getAnOperand().(MemoryOperand).getAnyDef()) = memOperand and
tvalueNumberOfOperand(instr.getAnOperand().(AddressOperand)) = operand tvalueNumberOfOperand(instr.getAnOperand().(AddressOperand)) = operand and
instr.getResultIRType() = type
} }
/** /**
@@ -212,7 +224,11 @@ private predicate loadTotalOverlapValueNumber(
private predicate uniqueValueNumber(Instruction instr, IRFunction irFunc) { private predicate uniqueValueNumber(Instruction instr, IRFunction irFunc) {
instr.getEnclosingIRFunction() = irFunc and instr.getEnclosingIRFunction() = irFunc and
not instr.getResultIRType() instanceof IRVoidType and not instr.getResultIRType() instanceof IRVoidType and
not numberableInstruction(instr) (
not numberableInstruction(instr)
or
filteredNumberableInstruction(instr)
)
} }
/** /**
@@ -255,7 +271,7 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
initializeThisValueNumber(instr, irFunc) and initializeThisValueNumber(instr, irFunc) and
result = TInitializeThisValueNumber(irFunc) result = TInitializeThisValueNumber(irFunc)
or or
exists(IRType type, string value | exists(string value, IRType type |
constantValueNumber(instr, irFunc, type, value) and constantValueNumber(instr, irFunc, type, value) and
result = TConstantValueNumber(irFunc, type, value) result = TConstantValueNumber(irFunc, type, value)
) )
@@ -270,14 +286,14 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
result = TFieldAddressValueNumber(irFunc, field, objectAddress) result = TFieldAddressValueNumber(irFunc, field, objectAddress)
) )
or or
exists(Opcode opcode, IRType type, TValueNumber leftOperand, TValueNumber rightOperand | exists(Opcode opcode, TValueNumber leftOperand, TValueNumber rightOperand |
binaryValueNumber(instr, irFunc, opcode, type, leftOperand, rightOperand) and binaryValueNumber(instr, irFunc, opcode, leftOperand, rightOperand) and
result = TBinaryValueNumber(irFunc, opcode, type, leftOperand, rightOperand) result = TBinaryValueNumber(irFunc, opcode, leftOperand, rightOperand)
) )
or or
exists(Opcode opcode, IRType type, TValueNumber operand | exists(Opcode opcode, TValueNumber operand |
unaryValueNumber(instr, irFunc, opcode, type, operand) and unaryValueNumber(instr, irFunc, opcode, operand) and
result = TUnaryValueNumber(irFunc, opcode, type, operand) result = TUnaryValueNumber(irFunc, opcode, operand)
) )
or or
exists( exists(
@@ -287,14 +303,10 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
result = TInheritanceConversionValueNumber(irFunc, opcode, baseClass, derivedClass, operand) result = TInheritanceConversionValueNumber(irFunc, opcode, baseClass, derivedClass, operand)
) )
or or
exists( exists(Opcode opcode, int elementSize, TValueNumber leftOperand, TValueNumber rightOperand |
Opcode opcode, IRType type, int elementSize, TValueNumber leftOperand, pointerArithmeticValueNumber(instr, irFunc, opcode, elementSize, leftOperand, rightOperand) and
TValueNumber rightOperand
|
pointerArithmeticValueNumber(instr, irFunc, opcode, type, elementSize, leftOperand,
rightOperand) and
result = result =
TPointerArithmeticValueNumber(irFunc, opcode, type, elementSize, leftOperand, rightOperand) TPointerArithmeticValueNumber(irFunc, opcode, elementSize, leftOperand, rightOperand)
) )
or or
exists(IRType type, TValueNumber memOperand, TValueNumber operand | exists(IRType type, TValueNumber memOperand, TValueNumber operand |

View File

@@ -19,19 +19,18 @@ newtype TValueNumber =
fieldAddressValueNumber(_, irFunc, field, objectAddress) fieldAddressValueNumber(_, irFunc, field, objectAddress)
} or } or
TBinaryValueNumber( TBinaryValueNumber(
IRFunction irFunc, Opcode opcode, IRType type, TValueNumber leftOperand, IRFunction irFunc, Opcode opcode, TValueNumber leftOperand, TValueNumber rightOperand
TValueNumber rightOperand
) { ) {
binaryValueNumber(_, irFunc, opcode, type, leftOperand, rightOperand) binaryValueNumber(_, irFunc, opcode, leftOperand, rightOperand)
} or } or
TPointerArithmeticValueNumber( TPointerArithmeticValueNumber(
IRFunction irFunc, Opcode opcode, IRType type, int elementSize, TValueNumber leftOperand, IRFunction irFunc, Opcode opcode, int elementSize, TValueNumber leftOperand,
TValueNumber rightOperand TValueNumber rightOperand
) { ) {
pointerArithmeticValueNumber(_, irFunc, opcode, type, elementSize, leftOperand, rightOperand) pointerArithmeticValueNumber(_, irFunc, opcode, elementSize, leftOperand, rightOperand)
} or } or
TUnaryValueNumber(IRFunction irFunc, Opcode opcode, IRType type, TValueNumber operand) { TUnaryValueNumber(IRFunction irFunc, Opcode opcode, TValueNumber operand) {
unaryValueNumber(_, irFunc, opcode, type, operand) unaryValueNumber(_, irFunc, opcode, operand)
} or } or
TInheritanceConversionValueNumber( TInheritanceConversionValueNumber(
IRFunction irFunc, Opcode opcode, Class baseClass, Class derivedClass, TValueNumber operand IRFunction irFunc, Opcode opcode, Class baseClass, Class derivedClass, TValueNumber operand
@@ -99,6 +98,19 @@ private predicate numberableInstruction(Instruction instr) {
instr instanceof LoadTotalOverlapInstruction instr instanceof LoadTotalOverlapInstruction
} }
private predicate filteredNumberableInstruction(Instruction instr) {
// count rather than strictcount to handle missing AST elements
// separate instanceof and inline casts to avoid failed casts with a count of 0
instr instanceof VariableAddressInstruction and
count(instr.(VariableAddressInstruction).getIRVariable().getAST()) != 1
or
instr instanceof ConstantInstruction and
count(instr.getResultIRType()) != 1
or
instr instanceof FieldAddressInstruction and
count(instr.(FieldAddressInstruction).getField()) != 1
}
private predicate variableAddressValueNumber( private predicate variableAddressValueNumber(
VariableAddressInstruction instr, IRFunction irFunc, Language::AST ast VariableAddressInstruction instr, IRFunction irFunc, Language::AST ast
) { ) {
@@ -106,7 +118,8 @@ private predicate variableAddressValueNumber(
// The underlying AST element is used as value-numbering key instead of the // The underlying AST element is used as value-numbering key instead of the
// `IRVariable` to work around a problem where a variable or expression with // `IRVariable` to work around a problem where a variable or expression with
// multiple types gives rise to multiple `IRVariable`s. // multiple types gives rise to multiple `IRVariable`s.
instr.getIRVariable().getAST() = ast instr.getIRVariable().getAST() = ast and
strictcount(instr.getIRVariable().getAST()) = 1
} }
private predicate initializeParameterValueNumber( private predicate initializeParameterValueNumber(
@@ -123,10 +136,11 @@ private predicate initializeThisValueNumber(InitializeThisInstruction instr, IRF
instr.getEnclosingIRFunction() = irFunc instr.getEnclosingIRFunction() = irFunc
} }
private predicate constantValueNumber( predicate constantValueNumber(
ConstantInstruction instr, IRFunction irFunc, IRType type, string value ConstantInstruction instr, IRFunction irFunc, IRType type, string value
) { ) {
instr.getEnclosingIRFunction() = irFunc and instr.getEnclosingIRFunction() = irFunc and
strictcount(instr.getResultIRType()) = 1 and
instr.getResultIRType() = type and instr.getResultIRType() = type and
instr.getValue() = value instr.getValue() = value
} }
@@ -145,42 +159,40 @@ private predicate fieldAddressValueNumber(
) { ) {
instr.getEnclosingIRFunction() = irFunc and instr.getEnclosingIRFunction() = irFunc and
instr.getField() = field and instr.getField() = field and
strictcount(instr.getField()) = 1 and
tvalueNumber(instr.getObjectAddress()) = objectAddress tvalueNumber(instr.getObjectAddress()) = objectAddress
} }
private predicate binaryValueNumber( private predicate binaryValueNumber(
BinaryInstruction instr, IRFunction irFunc, Opcode opcode, IRType type, TValueNumber leftOperand, BinaryInstruction instr, IRFunction irFunc, Opcode opcode, TValueNumber leftOperand,
TValueNumber rightOperand TValueNumber rightOperand
) { ) {
instr.getEnclosingIRFunction() = irFunc and instr.getEnclosingIRFunction() = irFunc and
not instr instanceof PointerArithmeticInstruction and not instr instanceof PointerArithmeticInstruction and
instr.getOpcode() = opcode and instr.getOpcode() = opcode and
instr.getResultIRType() = type and
tvalueNumber(instr.getLeft()) = leftOperand and tvalueNumber(instr.getLeft()) = leftOperand and
tvalueNumber(instr.getRight()) = rightOperand tvalueNumber(instr.getRight()) = rightOperand
} }
private predicate pointerArithmeticValueNumber( private predicate pointerArithmeticValueNumber(
PointerArithmeticInstruction instr, IRFunction irFunc, Opcode opcode, IRType type, PointerArithmeticInstruction instr, IRFunction irFunc, Opcode opcode, int elementSize,
int elementSize, TValueNumber leftOperand, TValueNumber rightOperand TValueNumber leftOperand, TValueNumber rightOperand
) { ) {
instr.getEnclosingIRFunction() = irFunc and instr.getEnclosingIRFunction() = irFunc and
instr.getOpcode() = opcode and instr.getOpcode() = opcode and
instr.getResultIRType() = type and
instr.getElementSize() = elementSize and instr.getElementSize() = elementSize and
tvalueNumber(instr.getLeft()) = leftOperand and tvalueNumber(instr.getLeft()) = leftOperand and
tvalueNumber(instr.getRight()) = rightOperand tvalueNumber(instr.getRight()) = rightOperand
} }
private predicate unaryValueNumber( private predicate unaryValueNumber(
UnaryInstruction instr, IRFunction irFunc, Opcode opcode, IRType type, TValueNumber operand UnaryInstruction instr, IRFunction irFunc, Opcode opcode, TValueNumber operand
) { ) {
instr.getEnclosingIRFunction() = irFunc and instr.getEnclosingIRFunction() = irFunc and
not instr instanceof InheritanceConversionInstruction and not instr instanceof InheritanceConversionInstruction and
not instr instanceof CopyInstruction and not instr instanceof CopyInstruction and
not instr instanceof FieldAddressInstruction and not instr instanceof FieldAddressInstruction and
instr.getOpcode() = opcode and instr.getOpcode() = opcode and
instr.getResultIRType() = type and
tvalueNumber(instr.getUnary()) = operand tvalueNumber(instr.getUnary()) = operand
} }
@@ -200,9 +212,9 @@ private predicate loadTotalOverlapValueNumber(
TValueNumber operand TValueNumber operand
) { ) {
instr.getEnclosingIRFunction() = irFunc and instr.getEnclosingIRFunction() = irFunc and
instr.getResultIRType() = type and
tvalueNumber(instr.getAnOperand().(MemoryOperand).getAnyDef()) = memOperand and tvalueNumber(instr.getAnOperand().(MemoryOperand).getAnyDef()) = memOperand and
tvalueNumberOfOperand(instr.getAnOperand().(AddressOperand)) = operand tvalueNumberOfOperand(instr.getAnOperand().(AddressOperand)) = operand and
instr.getResultIRType() = type
} }
/** /**
@@ -212,7 +224,11 @@ private predicate loadTotalOverlapValueNumber(
private predicate uniqueValueNumber(Instruction instr, IRFunction irFunc) { private predicate uniqueValueNumber(Instruction instr, IRFunction irFunc) {
instr.getEnclosingIRFunction() = irFunc and instr.getEnclosingIRFunction() = irFunc and
not instr.getResultIRType() instanceof IRVoidType and not instr.getResultIRType() instanceof IRVoidType and
not numberableInstruction(instr) (
not numberableInstruction(instr)
or
filteredNumberableInstruction(instr)
)
} }
/** /**
@@ -255,7 +271,7 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
initializeThisValueNumber(instr, irFunc) and initializeThisValueNumber(instr, irFunc) and
result = TInitializeThisValueNumber(irFunc) result = TInitializeThisValueNumber(irFunc)
or or
exists(IRType type, string value | exists(string value, IRType type |
constantValueNumber(instr, irFunc, type, value) and constantValueNumber(instr, irFunc, type, value) and
result = TConstantValueNumber(irFunc, type, value) result = TConstantValueNumber(irFunc, type, value)
) )
@@ -270,14 +286,14 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
result = TFieldAddressValueNumber(irFunc, field, objectAddress) result = TFieldAddressValueNumber(irFunc, field, objectAddress)
) )
or or
exists(Opcode opcode, IRType type, TValueNumber leftOperand, TValueNumber rightOperand | exists(Opcode opcode, TValueNumber leftOperand, TValueNumber rightOperand |
binaryValueNumber(instr, irFunc, opcode, type, leftOperand, rightOperand) and binaryValueNumber(instr, irFunc, opcode, leftOperand, rightOperand) and
result = TBinaryValueNumber(irFunc, opcode, type, leftOperand, rightOperand) result = TBinaryValueNumber(irFunc, opcode, leftOperand, rightOperand)
) )
or or
exists(Opcode opcode, IRType type, TValueNumber operand | exists(Opcode opcode, TValueNumber operand |
unaryValueNumber(instr, irFunc, opcode, type, operand) and unaryValueNumber(instr, irFunc, opcode, operand) and
result = TUnaryValueNumber(irFunc, opcode, type, operand) result = TUnaryValueNumber(irFunc, opcode, operand)
) )
or or
exists( exists(
@@ -287,14 +303,10 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
result = TInheritanceConversionValueNumber(irFunc, opcode, baseClass, derivedClass, operand) result = TInheritanceConversionValueNumber(irFunc, opcode, baseClass, derivedClass, operand)
) )
or or
exists( exists(Opcode opcode, int elementSize, TValueNumber leftOperand, TValueNumber rightOperand |
Opcode opcode, IRType type, int elementSize, TValueNumber leftOperand, pointerArithmeticValueNumber(instr, irFunc, opcode, elementSize, leftOperand, rightOperand) and
TValueNumber rightOperand
|
pointerArithmeticValueNumber(instr, irFunc, opcode, type, elementSize, leftOperand,
rightOperand) and
result = result =
TPointerArithmeticValueNumber(irFunc, opcode, type, elementSize, leftOperand, rightOperand) TPointerArithmeticValueNumber(irFunc, opcode, elementSize, leftOperand, rightOperand)
) )
or or
exists(IRType type, TValueNumber memOperand, TValueNumber operand | exists(IRType type, TValueNumber memOperand, TValueNumber operand |

View File

@@ -19,19 +19,18 @@ newtype TValueNumber =
fieldAddressValueNumber(_, irFunc, field, objectAddress) fieldAddressValueNumber(_, irFunc, field, objectAddress)
} or } or
TBinaryValueNumber( TBinaryValueNumber(
IRFunction irFunc, Opcode opcode, IRType type, TValueNumber leftOperand, IRFunction irFunc, Opcode opcode, TValueNumber leftOperand, TValueNumber rightOperand
TValueNumber rightOperand
) { ) {
binaryValueNumber(_, irFunc, opcode, type, leftOperand, rightOperand) binaryValueNumber(_, irFunc, opcode, leftOperand, rightOperand)
} or } or
TPointerArithmeticValueNumber( TPointerArithmeticValueNumber(
IRFunction irFunc, Opcode opcode, IRType type, int elementSize, TValueNumber leftOperand, IRFunction irFunc, Opcode opcode, int elementSize, TValueNumber leftOperand,
TValueNumber rightOperand TValueNumber rightOperand
) { ) {
pointerArithmeticValueNumber(_, irFunc, opcode, type, elementSize, leftOperand, rightOperand) pointerArithmeticValueNumber(_, irFunc, opcode, elementSize, leftOperand, rightOperand)
} or } or
TUnaryValueNumber(IRFunction irFunc, Opcode opcode, IRType type, TValueNumber operand) { TUnaryValueNumber(IRFunction irFunc, Opcode opcode, TValueNumber operand) {
unaryValueNumber(_, irFunc, opcode, type, operand) unaryValueNumber(_, irFunc, opcode, operand)
} or } or
TInheritanceConversionValueNumber( TInheritanceConversionValueNumber(
IRFunction irFunc, Opcode opcode, Class baseClass, Class derivedClass, TValueNumber operand IRFunction irFunc, Opcode opcode, Class baseClass, Class derivedClass, TValueNumber operand
@@ -99,6 +98,19 @@ private predicate numberableInstruction(Instruction instr) {
instr instanceof LoadTotalOverlapInstruction instr instanceof LoadTotalOverlapInstruction
} }
private predicate filteredNumberableInstruction(Instruction instr) {
// count rather than strictcount to handle missing AST elements
// separate instanceof and inline casts to avoid failed casts with a count of 0
instr instanceof VariableAddressInstruction and
count(instr.(VariableAddressInstruction).getIRVariable().getAST()) != 1
or
instr instanceof ConstantInstruction and
count(instr.getResultIRType()) != 1
or
instr instanceof FieldAddressInstruction and
count(instr.(FieldAddressInstruction).getField()) != 1
}
private predicate variableAddressValueNumber( private predicate variableAddressValueNumber(
VariableAddressInstruction instr, IRFunction irFunc, Language::AST ast VariableAddressInstruction instr, IRFunction irFunc, Language::AST ast
) { ) {
@@ -106,7 +118,8 @@ private predicate variableAddressValueNumber(
// The underlying AST element is used as value-numbering key instead of the // The underlying AST element is used as value-numbering key instead of the
// `IRVariable` to work around a problem where a variable or expression with // `IRVariable` to work around a problem where a variable or expression with
// multiple types gives rise to multiple `IRVariable`s. // multiple types gives rise to multiple `IRVariable`s.
instr.getIRVariable().getAST() = ast instr.getIRVariable().getAST() = ast and
strictcount(instr.getIRVariable().getAST()) = 1
} }
private predicate initializeParameterValueNumber( private predicate initializeParameterValueNumber(
@@ -123,10 +136,11 @@ private predicate initializeThisValueNumber(InitializeThisInstruction instr, IRF
instr.getEnclosingIRFunction() = irFunc instr.getEnclosingIRFunction() = irFunc
} }
private predicate constantValueNumber( predicate constantValueNumber(
ConstantInstruction instr, IRFunction irFunc, IRType type, string value ConstantInstruction instr, IRFunction irFunc, IRType type, string value
) { ) {
instr.getEnclosingIRFunction() = irFunc and instr.getEnclosingIRFunction() = irFunc and
strictcount(instr.getResultIRType()) = 1 and
instr.getResultIRType() = type and instr.getResultIRType() = type and
instr.getValue() = value instr.getValue() = value
} }
@@ -145,42 +159,40 @@ private predicate fieldAddressValueNumber(
) { ) {
instr.getEnclosingIRFunction() = irFunc and instr.getEnclosingIRFunction() = irFunc and
instr.getField() = field and instr.getField() = field and
strictcount(instr.getField()) = 1 and
tvalueNumber(instr.getObjectAddress()) = objectAddress tvalueNumber(instr.getObjectAddress()) = objectAddress
} }
private predicate binaryValueNumber( private predicate binaryValueNumber(
BinaryInstruction instr, IRFunction irFunc, Opcode opcode, IRType type, TValueNumber leftOperand, BinaryInstruction instr, IRFunction irFunc, Opcode opcode, TValueNumber leftOperand,
TValueNumber rightOperand TValueNumber rightOperand
) { ) {
instr.getEnclosingIRFunction() = irFunc and instr.getEnclosingIRFunction() = irFunc and
not instr instanceof PointerArithmeticInstruction and not instr instanceof PointerArithmeticInstruction and
instr.getOpcode() = opcode and instr.getOpcode() = opcode and
instr.getResultIRType() = type and
tvalueNumber(instr.getLeft()) = leftOperand and tvalueNumber(instr.getLeft()) = leftOperand and
tvalueNumber(instr.getRight()) = rightOperand tvalueNumber(instr.getRight()) = rightOperand
} }
private predicate pointerArithmeticValueNumber( private predicate pointerArithmeticValueNumber(
PointerArithmeticInstruction instr, IRFunction irFunc, Opcode opcode, IRType type, PointerArithmeticInstruction instr, IRFunction irFunc, Opcode opcode, int elementSize,
int elementSize, TValueNumber leftOperand, TValueNumber rightOperand TValueNumber leftOperand, TValueNumber rightOperand
) { ) {
instr.getEnclosingIRFunction() = irFunc and instr.getEnclosingIRFunction() = irFunc and
instr.getOpcode() = opcode and instr.getOpcode() = opcode and
instr.getResultIRType() = type and
instr.getElementSize() = elementSize and instr.getElementSize() = elementSize and
tvalueNumber(instr.getLeft()) = leftOperand and tvalueNumber(instr.getLeft()) = leftOperand and
tvalueNumber(instr.getRight()) = rightOperand tvalueNumber(instr.getRight()) = rightOperand
} }
private predicate unaryValueNumber( private predicate unaryValueNumber(
UnaryInstruction instr, IRFunction irFunc, Opcode opcode, IRType type, TValueNumber operand UnaryInstruction instr, IRFunction irFunc, Opcode opcode, TValueNumber operand
) { ) {
instr.getEnclosingIRFunction() = irFunc and instr.getEnclosingIRFunction() = irFunc and
not instr instanceof InheritanceConversionInstruction and not instr instanceof InheritanceConversionInstruction and
not instr instanceof CopyInstruction and not instr instanceof CopyInstruction and
not instr instanceof FieldAddressInstruction and not instr instanceof FieldAddressInstruction and
instr.getOpcode() = opcode and instr.getOpcode() = opcode and
instr.getResultIRType() = type and
tvalueNumber(instr.getUnary()) = operand tvalueNumber(instr.getUnary()) = operand
} }
@@ -200,9 +212,9 @@ private predicate loadTotalOverlapValueNumber(
TValueNumber operand TValueNumber operand
) { ) {
instr.getEnclosingIRFunction() = irFunc and instr.getEnclosingIRFunction() = irFunc and
instr.getResultIRType() = type and
tvalueNumber(instr.getAnOperand().(MemoryOperand).getAnyDef()) = memOperand and tvalueNumber(instr.getAnOperand().(MemoryOperand).getAnyDef()) = memOperand and
tvalueNumberOfOperand(instr.getAnOperand().(AddressOperand)) = operand tvalueNumberOfOperand(instr.getAnOperand().(AddressOperand)) = operand and
instr.getResultIRType() = type
} }
/** /**
@@ -212,7 +224,11 @@ private predicate loadTotalOverlapValueNumber(
private predicate uniqueValueNumber(Instruction instr, IRFunction irFunc) { private predicate uniqueValueNumber(Instruction instr, IRFunction irFunc) {
instr.getEnclosingIRFunction() = irFunc and instr.getEnclosingIRFunction() = irFunc and
not instr.getResultIRType() instanceof IRVoidType and not instr.getResultIRType() instanceof IRVoidType and
not numberableInstruction(instr) (
not numberableInstruction(instr)
or
filteredNumberableInstruction(instr)
)
} }
/** /**
@@ -255,7 +271,7 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
initializeThisValueNumber(instr, irFunc) and initializeThisValueNumber(instr, irFunc) and
result = TInitializeThisValueNumber(irFunc) result = TInitializeThisValueNumber(irFunc)
or or
exists(IRType type, string value | exists(string value, IRType type |
constantValueNumber(instr, irFunc, type, value) and constantValueNumber(instr, irFunc, type, value) and
result = TConstantValueNumber(irFunc, type, value) result = TConstantValueNumber(irFunc, type, value)
) )
@@ -270,14 +286,14 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
result = TFieldAddressValueNumber(irFunc, field, objectAddress) result = TFieldAddressValueNumber(irFunc, field, objectAddress)
) )
or or
exists(Opcode opcode, IRType type, TValueNumber leftOperand, TValueNumber rightOperand | exists(Opcode opcode, TValueNumber leftOperand, TValueNumber rightOperand |
binaryValueNumber(instr, irFunc, opcode, type, leftOperand, rightOperand) and binaryValueNumber(instr, irFunc, opcode, leftOperand, rightOperand) and
result = TBinaryValueNumber(irFunc, opcode, type, leftOperand, rightOperand) result = TBinaryValueNumber(irFunc, opcode, leftOperand, rightOperand)
) )
or or
exists(Opcode opcode, IRType type, TValueNumber operand | exists(Opcode opcode, TValueNumber operand |
unaryValueNumber(instr, irFunc, opcode, type, operand) and unaryValueNumber(instr, irFunc, opcode, operand) and
result = TUnaryValueNumber(irFunc, opcode, type, operand) result = TUnaryValueNumber(irFunc, opcode, operand)
) )
or or
exists( exists(
@@ -287,14 +303,10 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
result = TInheritanceConversionValueNumber(irFunc, opcode, baseClass, derivedClass, operand) result = TInheritanceConversionValueNumber(irFunc, opcode, baseClass, derivedClass, operand)
) )
or or
exists( exists(Opcode opcode, int elementSize, TValueNumber leftOperand, TValueNumber rightOperand |
Opcode opcode, IRType type, int elementSize, TValueNumber leftOperand, pointerArithmeticValueNumber(instr, irFunc, opcode, elementSize, leftOperand, rightOperand) and
TValueNumber rightOperand
|
pointerArithmeticValueNumber(instr, irFunc, opcode, type, elementSize, leftOperand,
rightOperand) and
result = result =
TPointerArithmeticValueNumber(irFunc, opcode, type, elementSize, leftOperand, rightOperand) TPointerArithmeticValueNumber(irFunc, opcode, elementSize, leftOperand, rightOperand)
) )
or or
exists(IRType type, TValueNumber memOperand, TValueNumber operand | exists(IRType type, TValueNumber memOperand, TValueNumber operand |