C++: Handle inheritance conversions in IR GVN

This commit is contained in:
Dave Bartolomeo
2018-09-20 08:00:38 -07:00
parent bd156757d3
commit 27cee9bd80
6 changed files with 132 additions and 24 deletions

View File

@@ -45,6 +45,10 @@ newtype TValueNumber =
TUnaryValueNumber(FunctionIR funcIR, Opcode opcode, Type type, ValueNumber operand) {
unaryValueNumber(_, funcIR, opcode, type, operand)
} or
TInheritanceConversionValueNumber(FunctionIR funcIR, Opcode opcode, Class baseClass,
Class derivedClass, ValueNumber operand) {
inheritanceConversionValueNumber(_, funcIR, opcode, baseClass, derivedClass, operand)
} or
TUniqueValueNumber(FunctionIR funcIR, Instruction instr) {
uniqueValueNumber(instr, funcIR)
}
@@ -81,13 +85,6 @@ class ValueNumber extends TValueNumber {
}
}
class BinaryValueNumber extends ValueNumber, TBinaryValueNumber {}
class UnaryValueNumber extends ValueNumber, TUnaryValueNumber {}
class ConstantValueNumber extends ValueNumber, TConstantValueNumber {}
class FieldAddressValueNumber extends ValueNumber, TFieldAddressValueNumber {}
class PointerArithmeticValueNumber extends ValueNumber, TPointerArithmeticValueNumber {}
class UniqueValueNumber extends ValueNumber, TUniqueValueNumber {}
/**
* A `CopyInstruction` whose source operand's value is congruent to the definition of that source
* operand.
@@ -187,12 +184,20 @@ private predicate unaryValueNumber(UnaryInstruction instr, FunctionIR funcIR, Op
Type type, ValueNumber operand) {
instr.getFunctionIR() = funcIR and
(not instr instanceof InheritanceConversionInstruction) and
(not instr instanceof FieldAddressInstruction) and
instr.getOpcode() = opcode and
instr.getResultType() = type and
valueNumber(instr.getOperand()) = operand
}
private predicate inheritanceConversionValueNumber(InheritanceConversionInstruction instr,
FunctionIR funcIR, Opcode opcode, Class baseClass, Class derivedClass, ValueNumber operand) {
instr.getFunctionIR() = funcIR and
instr.getOpcode() = opcode and
instr.getBaseClass() = baseClass and
instr.getDerivedClass() = derivedClass and
valueNumber(instr.getOperand()) = operand
}
/**
* Holds if `instr` should be assigned a unique value number because this library does not know how
* to determine if two instances of that instruction are equivalent.
@@ -250,6 +255,11 @@ private ValueNumber nonUniqueValueNumber(Instruction instr) {
unaryValueNumber(instr, funcIR, opcode, type, operand) and
result = TUnaryValueNumber(funcIR, opcode, type, operand)
) or
exists(Opcode opcode, Class baseClass, Class derivedClass, ValueNumber operand |
inheritanceConversionValueNumber(instr, funcIR, opcode, baseClass, derivedClass,
operand) and
result = TInheritanceConversionValueNumber(funcIR, opcode, baseClass, derivedClass, operand)
) or
exists(Opcode opcode, Type type, int elementSize, ValueNumber leftOperand,
ValueNumber rightOperand |
pointerArithmeticValueNumber(instr, funcIR, opcode, type, elementSize, leftOperand,

View File

@@ -45,6 +45,10 @@ newtype TValueNumber =
TUnaryValueNumber(FunctionIR funcIR, Opcode opcode, Type type, ValueNumber operand) {
unaryValueNumber(_, funcIR, opcode, type, operand)
} or
TInheritanceConversionValueNumber(FunctionIR funcIR, Opcode opcode, Class baseClass,
Class derivedClass, ValueNumber operand) {
inheritanceConversionValueNumber(_, funcIR, opcode, baseClass, derivedClass, operand)
} or
TUniqueValueNumber(FunctionIR funcIR, Instruction instr) {
uniqueValueNumber(instr, funcIR)
}
@@ -81,13 +85,6 @@ class ValueNumber extends TValueNumber {
}
}
class BinaryValueNumber extends ValueNumber, TBinaryValueNumber {}
class UnaryValueNumber extends ValueNumber, TUnaryValueNumber {}
class ConstantValueNumber extends ValueNumber, TConstantValueNumber {}
class FieldAddressValueNumber extends ValueNumber, TFieldAddressValueNumber {}
class PointerArithmeticValueNumber extends ValueNumber, TPointerArithmeticValueNumber {}
class UniqueValueNumber extends ValueNumber, TUniqueValueNumber {}
/**
* A `CopyInstruction` whose source operand's value is congruent to the definition of that source
* operand.
@@ -187,12 +184,20 @@ private predicate unaryValueNumber(UnaryInstruction instr, FunctionIR funcIR, Op
Type type, ValueNumber operand) {
instr.getFunctionIR() = funcIR and
(not instr instanceof InheritanceConversionInstruction) and
(not instr instanceof FieldAddressInstruction) and
instr.getOpcode() = opcode and
instr.getResultType() = type and
valueNumber(instr.getOperand()) = operand
}
private predicate inheritanceConversionValueNumber(InheritanceConversionInstruction instr,
FunctionIR funcIR, Opcode opcode, Class baseClass, Class derivedClass, ValueNumber operand) {
instr.getFunctionIR() = funcIR and
instr.getOpcode() = opcode and
instr.getBaseClass() = baseClass and
instr.getDerivedClass() = derivedClass and
valueNumber(instr.getOperand()) = operand
}
/**
* Holds if `instr` should be assigned a unique value number because this library does not know how
* to determine if two instances of that instruction are equivalent.
@@ -250,6 +255,11 @@ private ValueNumber nonUniqueValueNumber(Instruction instr) {
unaryValueNumber(instr, funcIR, opcode, type, operand) and
result = TUnaryValueNumber(funcIR, opcode, type, operand)
) or
exists(Opcode opcode, Class baseClass, Class derivedClass, ValueNumber operand |
inheritanceConversionValueNumber(instr, funcIR, opcode, baseClass, derivedClass,
operand) and
result = TInheritanceConversionValueNumber(funcIR, opcode, baseClass, derivedClass, operand)
) or
exists(Opcode opcode, Type type, int elementSize, ValueNumber leftOperand,
ValueNumber rightOperand |
pointerArithmeticValueNumber(instr, funcIR, opcode, type, elementSize, leftOperand,

View File

@@ -45,6 +45,10 @@ newtype TValueNumber =
TUnaryValueNumber(FunctionIR funcIR, Opcode opcode, Type type, ValueNumber operand) {
unaryValueNumber(_, funcIR, opcode, type, operand)
} or
TInheritanceConversionValueNumber(FunctionIR funcIR, Opcode opcode, Class baseClass,
Class derivedClass, ValueNumber operand) {
inheritanceConversionValueNumber(_, funcIR, opcode, baseClass, derivedClass, operand)
} or
TUniqueValueNumber(FunctionIR funcIR, Instruction instr) {
uniqueValueNumber(instr, funcIR)
}
@@ -81,13 +85,6 @@ class ValueNumber extends TValueNumber {
}
}
class BinaryValueNumber extends ValueNumber, TBinaryValueNumber {}
class UnaryValueNumber extends ValueNumber, TUnaryValueNumber {}
class ConstantValueNumber extends ValueNumber, TConstantValueNumber {}
class FieldAddressValueNumber extends ValueNumber, TFieldAddressValueNumber {}
class PointerArithmeticValueNumber extends ValueNumber, TPointerArithmeticValueNumber {}
class UniqueValueNumber extends ValueNumber, TUniqueValueNumber {}
/**
* A `CopyInstruction` whose source operand's value is congruent to the definition of that source
* operand.
@@ -187,12 +184,20 @@ private predicate unaryValueNumber(UnaryInstruction instr, FunctionIR funcIR, Op
Type type, ValueNumber operand) {
instr.getFunctionIR() = funcIR and
(not instr instanceof InheritanceConversionInstruction) and
(not instr instanceof FieldAddressInstruction) and
instr.getOpcode() = opcode and
instr.getResultType() = type and
valueNumber(instr.getOperand()) = operand
}
private predicate inheritanceConversionValueNumber(InheritanceConversionInstruction instr,
FunctionIR funcIR, Opcode opcode, Class baseClass, Class derivedClass, ValueNumber operand) {
instr.getFunctionIR() = funcIR and
instr.getOpcode() = opcode and
instr.getBaseClass() = baseClass and
instr.getDerivedClass() = derivedClass and
valueNumber(instr.getOperand()) = operand
}
/**
* Holds if `instr` should be assigned a unique value number because this library does not know how
* to determine if two instances of that instruction are equivalent.
@@ -250,6 +255,11 @@ private ValueNumber nonUniqueValueNumber(Instruction instr) {
unaryValueNumber(instr, funcIR, opcode, type, operand) and
result = TUnaryValueNumber(funcIR, opcode, type, operand)
) or
exists(Opcode opcode, Class baseClass, Class derivedClass, ValueNumber operand |
inheritanceConversionValueNumber(instr, funcIR, opcode, baseClass, derivedClass,
operand) and
result = TInheritanceConversionValueNumber(funcIR, opcode, baseClass, derivedClass, operand)
) or
exists(Opcode opcode, Type type, int elementSize, ValueNumber leftOperand,
ValueNumber rightOperand |
pointerArithmeticValueNumber(instr, funcIR, opcode, type, elementSize, leftOperand,