C++: semantic range analysis perf fixes

This commit is contained in:
Robert Marsh
2022-08-12 12:18:00 -04:00
parent 1d56330baa
commit e6aa2de977
4 changed files with 17 additions and 7 deletions

View File

@@ -169,7 +169,9 @@ module SemanticExprConfig {
final override predicate hasRead(SsaVariable v) {
exists(IR::Operand operand |
operand.getDef() = v and not operand instanceof IR::PhiInputOperand
operand.getDef() = v and
not operand instanceof IR::PhiInputOperand and
operand.getUse().getBlock() = block
)
}
}

View File

@@ -160,6 +160,7 @@ private predicate phiModulusInit(SemSsaPhiNode phi, SemBound b, int val, int mod
/**
* Holds if all inputs to `phi` numbered `1` to `rix` are equal to `b + val` modulo `mod`.
*/
pragma[nomagic]
private predicate phiModulusRankStep(SemSsaPhiNode phi, SemBound b, int val, int mod, int rix) {
rix = 0 and
phiModulusInit(phi, b, val, mod)
@@ -169,7 +170,7 @@ private predicate phiModulusRankStep(SemSsaPhiNode phi, SemBound b, int val, int
val = remainder(v1, mod)
|
exists(int v2, int m2 |
rankedPhiInput(phi, inp, edge, rix) and
rankedPhiInput(pragma[only_bind_out](phi), inp, edge, rix) and
phiModulusRankStep(phi, b, v1, m1, rix - 1) and
ssaModulus(inp, edge, b, v2, m2) and
mod = m1.gcd(m2).gcd(v1 - v2)

View File

@@ -342,7 +342,7 @@ private class ConvertOrBoxExpr extends SemUnaryExpr {
* A cast that can be ignored for the purpose of range analysis.
*/
private class SafeCastExpr extends ConvertOrBoxExpr {
SafeCastExpr() { conversionCannotOverflow(getTrackedType(getOperand()), getTrackedType(this)) }
SafeCastExpr() { conversionCannotOverflow(getTrackedType(pragma[only_bind_into](getOperand())), getTrackedType(this)) }
}
/**

View File

@@ -189,9 +189,12 @@ private class BinarySignExpr extends FlowSignExpr {
BinarySignExpr() { binary = this }
override Sign getSignRestriction() {
result =
semExprSign(binary.getLeftOperand())
.applyBinaryOp(semExprSign(binary.getRightOperand()), binary.getOpcode())
exists(SemExpr left, SemExpr right |
binaryExprOperands(binary, left, right) and
result =
semExprSign(pragma[only_bind_out](left))
.applyBinaryOp(semExprSign(pragma[only_bind_out](right)), binary.getOpcode())
)
or
exists(SemDivExpr div | div = binary |
result = semExprSign(div.getLeftOperand()) and
@@ -201,6 +204,10 @@ private class BinarySignExpr extends FlowSignExpr {
}
}
private predicate binaryExprOperands(SemBinaryExpr binary, SemExpr left, SemExpr right) {
binary.getLeftOperand() = left and binary.getRightOperand() = right
}
/**
* A `Convert`, `Box`, or `Unbox` expression.
*/
@@ -221,7 +228,7 @@ private class UnarySignExpr extends FlowSignExpr {
UnarySignExpr() { unary = this and not this instanceof SemCastExpr }
override Sign getSignRestriction() {
result = semExprSign(unary.getOperand()).applyUnaryOp(unary.getOpcode())
result = semExprSign(pragma[only_bind_out](unary.getOperand())).applyUnaryOp(unary.getOpcode())
}
}