summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaChecking.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2013-06-20 22:21:56 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2013-06-20 22:21:56 +0000
commit40238f04511443300a9470f97e0078a1c6538a18 (patch)
tree76a85dbf2809274f2e4cc4b62599a0e2fb17666c /clang/lib/Sema/SemaChecking.cpp
parent1efb69cdcaefea30be95beec8b4aa23f29dbf31c (diff)
downloadbcm5719-llvm-40238f04511443300a9470f97e0078a1c6538a18.tar.gz
bcm5719-llvm-40238f04511443300a9470f97e0078a1c6538a18.zip
Avoid repeatedly evaluating subexpressions when checking for unsequenced
operations in the case where evaluating a subexpression fails. No functionality change, but test/Sema/many-logical-ops.c gets ~100x faster with this change. llvm-svn: 184489
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r--clang/lib/Sema/SemaChecking.cpp44
1 files changed, 37 insertions, 7 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 729de0d1cd8..deb1ba1ba76 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -5387,6 +5387,35 @@ class SequenceChecker : public EvaluatedExprVisitor<SequenceChecker> {
llvm::SmallVectorImpl<std::pair<Object, Usage> > *OldModAsSideEffect;
};
+ /// RAII object wrapping the visitation of a subexpression which we might
+ /// choose to evaluate as a constant. If any subexpression is evaluated and
+ /// found to be non-constant, this allows us to suppress the evaluation of
+ /// the outer expression.
+ class EvaluationTracker {
+ public:
+ EvaluationTracker(SequenceChecker &Self)
+ : Self(Self), Prev(Self.EvalTracker), EvalOK(true) {
+ Self.EvalTracker = this;
+ }
+ ~EvaluationTracker() {
+ Self.EvalTracker = Prev;
+ if (Prev)
+ Prev->EvalOK &= EvalOK;
+ }
+
+ bool evaluate(const Expr *E, bool &Result) {
+ if (!EvalOK || E->isValueDependent())
+ return false;
+ EvalOK = E->EvaluateAsBooleanCondition(Result, Self.SemaRef.Context);
+ return EvalOK;
+ }
+
+ private:
+ SequenceChecker &Self;
+ EvaluationTracker *Prev;
+ bool EvalOK;
+ } *EvalTracker;
+
/// \brief Find the object which is produced by the specified expression,
/// if any.
Object getObject(Expr *E, bool Mod) const {
@@ -5468,7 +5497,8 @@ public:
SequenceChecker(Sema &S, Expr *E,
llvm::SmallVectorImpl<Expr*> &WorkList)
: EvaluatedExprVisitor<SequenceChecker>(S.Context), SemaRef(S),
- Region(Tree.root()), ModAsSideEffect(0), WorkList(WorkList) {
+ Region(Tree.root()), ModAsSideEffect(0), WorkList(WorkList),
+ EvalTracker(0) {
Visit(E);
}
@@ -5581,14 +5611,14 @@ public:
// value computation of the RHS, and hence before the value computation
// of the '&&' itself, unless the LHS evaluates to zero. We treat them
// as if they were unconditionally sequenced.
+ EvaluationTracker Eval(*this);
{
SequencedSubexpression Sequenced(*this);
Visit(BO->getLHS());
}
bool Result;
- if (!BO->getLHS()->isValueDependent() &&
- BO->getLHS()->EvaluateAsBooleanCondition(Result, SemaRef.Context)) {
+ if (Eval.evaluate(BO->getLHS(), Result)) {
if (!Result)
Visit(BO->getRHS());
} else {
@@ -5602,14 +5632,14 @@ public:
}
}
void VisitBinLAnd(BinaryOperator *BO) {
+ EvaluationTracker Eval(*this);
{
SequencedSubexpression Sequenced(*this);
Visit(BO->getLHS());
}
bool Result;
- if (!BO->getLHS()->isValueDependent() &&
- BO->getLHS()->EvaluateAsBooleanCondition(Result, SemaRef.Context)) {
+ if (Eval.evaluate(BO->getLHS(), Result)) {
if (Result)
Visit(BO->getRHS());
} else {
@@ -5620,12 +5650,12 @@ public:
// Only visit the condition, unless we can be sure which subexpression will
// be chosen.
void VisitAbstractConditionalOperator(AbstractConditionalOperator *CO) {
+ EvaluationTracker Eval(*this);
SequencedSubexpression Sequenced(*this);
Visit(CO->getCond());
bool Result;
- if (!CO->getCond()->isValueDependent() &&
- CO->getCond()->EvaluateAsBooleanCondition(Result, SemaRef.Context))
+ if (Eval.evaluate(CO->getCond(), Result))
Visit(Result ? CO->getTrueExpr() : CO->getFalseExpr());
else {
WorkList.push_back(CO->getTrueExpr());
OpenPOWER on IntegriCloud