mirror of
https://github.com/github/codeql.git
synced 2025-12-20 10:46:30 +01:00
Merge pull request #2835 from MathiasVP/value-number-perf
C++: Value number performance fix
This commit is contained in:
@@ -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 |
|
||||||
|
|||||||
@@ -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 |
|
||||||
|
|||||||
@@ -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 |
|
||||||
|
|||||||
Reference in New Issue
Block a user