C++: Factor out getConstantValueToPhi

This speeds up `getConstantValue`, the main predicate in
`ConstantAnalysis`, from 2.4s to 1.6s on comdb2.
This commit is contained in:
Jonas Jensen
2019-02-05 09:25:31 +01:00
parent 283bb2f6d0
commit be35c674a7
6 changed files with 66 additions and 9 deletions

View File

@@ -1484,6 +1484,17 @@ class PhiInstruction extends Instruction {
override final MemoryAccessKind getResultMemoryAccess() {
result instanceof PhiMemoryAccess
}
/**
* Gets an instruction that defines the input to one of the operands of this
* instruction. It's possible for more than one operand to have the same
* defining instruction, so this predicate will have the same number of
* results as `getAnOperand()` or fewer.
*/
pragma[noinline]
final Instruction getAnOperandDefinitionInstruction() {
result = this.getAnOperand().(PhiOperand).getDefinitionInstruction()
}
}
/**
@@ -1492,7 +1503,7 @@ class PhiInstruction extends Instruction {
*
* A `ChiInstruction` is inserted immediately after an instruction that writes to memory. The
* `ChiInstruction` has two operands. The first operand, given by `getTotalOperand()`, represents
* the previous state of all of the memory that might be alised by the memory write. The second
* the previous state of all of the memory that might be aliased by the memory write. The second
* operand, given by `getPartialOperand()`, represents the memory that was actually modified by the
* memory write. The result of the `ChiInstruction` represents the same memory as
* `getTotalOperand()`, updated to include the changes due to the value that was actually stored by

View File

@@ -16,8 +16,16 @@ int getConstantValue(Instruction instr) {
result = getConstantValue(instr.(CopyInstruction).getSourceValue()) or
exists(PhiInstruction phi |
phi = instr and
result = max(PhiOperand operand | operand = phi.getAnOperand() | getConstantValue(operand.getDefinitionInstruction())) and
result = min(PhiOperand operand | operand = phi.getAnOperand() | getConstantValue(operand.getDefinitionInstruction()))
result = max(Instruction def | def = phi.getAnOperandDefinitionInstruction() | getConstantValueToPhi(def)) and
result = min(Instruction def | def = phi.getAnOperandDefinitionInstruction() | getConstantValueToPhi(def))
)
}
pragma[noinline]
int getConstantValueToPhi(Instruction def) {
exists(PhiInstruction phi |
result = getConstantValue(def) and
def = phi.getAnOperandDefinitionInstruction()
)
}

View File

@@ -1484,6 +1484,17 @@ class PhiInstruction extends Instruction {
override final MemoryAccessKind getResultMemoryAccess() {
result instanceof PhiMemoryAccess
}
/**
* Gets an instruction that defines the input to one of the operands of this
* instruction. It's possible for more than one operand to have the same
* defining instruction, so this predicate will have the same number of
* results as `getAnOperand()` or fewer.
*/
pragma[noinline]
final Instruction getAnOperandDefinitionInstruction() {
result = this.getAnOperand().(PhiOperand).getDefinitionInstruction()
}
}
/**
@@ -1492,7 +1503,7 @@ class PhiInstruction extends Instruction {
*
* A `ChiInstruction` is inserted immediately after an instruction that writes to memory. The
* `ChiInstruction` has two operands. The first operand, given by `getTotalOperand()`, represents
* the previous state of all of the memory that might be alised by the memory write. The second
* the previous state of all of the memory that might be aliased by the memory write. The second
* operand, given by `getPartialOperand()`, represents the memory that was actually modified by the
* memory write. The result of the `ChiInstruction` represents the same memory as
* `getTotalOperand()`, updated to include the changes due to the value that was actually stored by

View File

@@ -16,8 +16,16 @@ int getConstantValue(Instruction instr) {
result = getConstantValue(instr.(CopyInstruction).getSourceValue()) or
exists(PhiInstruction phi |
phi = instr and
result = max(PhiOperand operand | operand = phi.getAnOperand() | getConstantValue(operand.getDefinitionInstruction())) and
result = min(PhiOperand operand | operand = phi.getAnOperand() | getConstantValue(operand.getDefinitionInstruction()))
result = max(Instruction def | def = phi.getAnOperandDefinitionInstruction() | getConstantValueToPhi(def)) and
result = min(Instruction def | def = phi.getAnOperandDefinitionInstruction() | getConstantValueToPhi(def))
)
}
pragma[noinline]
int getConstantValueToPhi(Instruction def) {
exists(PhiInstruction phi |
result = getConstantValue(def) and
def = phi.getAnOperandDefinitionInstruction()
)
}

View File

@@ -1484,6 +1484,17 @@ class PhiInstruction extends Instruction {
override final MemoryAccessKind getResultMemoryAccess() {
result instanceof PhiMemoryAccess
}
/**
* Gets an instruction that defines the input to one of the operands of this
* instruction. It's possible for more than one operand to have the same
* defining instruction, so this predicate will have the same number of
* results as `getAnOperand()` or fewer.
*/
pragma[noinline]
final Instruction getAnOperandDefinitionInstruction() {
result = this.getAnOperand().(PhiOperand).getDefinitionInstruction()
}
}
/**
@@ -1492,7 +1503,7 @@ class PhiInstruction extends Instruction {
*
* A `ChiInstruction` is inserted immediately after an instruction that writes to memory. The
* `ChiInstruction` has two operands. The first operand, given by `getTotalOperand()`, represents
* the previous state of all of the memory that might be alised by the memory write. The second
* the previous state of all of the memory that might be aliased by the memory write. The second
* operand, given by `getPartialOperand()`, represents the memory that was actually modified by the
* memory write. The result of the `ChiInstruction` represents the same memory as
* `getTotalOperand()`, updated to include the changes due to the value that was actually stored by

View File

@@ -16,8 +16,16 @@ int getConstantValue(Instruction instr) {
result = getConstantValue(instr.(CopyInstruction).getSourceValue()) or
exists(PhiInstruction phi |
phi = instr and
result = max(PhiOperand operand | operand = phi.getAnOperand() | getConstantValue(operand.getDefinitionInstruction())) and
result = min(PhiOperand operand | operand = phi.getAnOperand() | getConstantValue(operand.getDefinitionInstruction()))
result = max(Instruction def | def = phi.getAnOperandDefinitionInstruction() | getConstantValueToPhi(def)) and
result = min(Instruction def | def = phi.getAnOperandDefinitionInstruction() | getConstantValueToPhi(def))
)
}
pragma[noinline]
int getConstantValueToPhi(Instruction def) {
exists(PhiInstruction phi |
result = getConstantValue(def) and
def = phi.getAnOperandDefinitionInstruction()
)
}