mirror of
https://github.com/github/codeql.git
synced 2026-04-29 18:55:14 +02:00
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:
@@ -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
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user