[cfe-commits] r153297 - /cfe/trunk/lib/Analysis/CFG.cpp
Argyrios Kyrtzidis
kyrtzidis at apple.com
Mon Mar 26 10:49:25 PDT 2012
On Mar 24, 2012, at 11:36 PM, NAKAMURA Takumi wrote:
> 2012/3/23 Argyrios Kyrtzidis <akyrtzi at gmail.com>:
>> Author: akirtzidis
>> Date: Thu Mar 22 19:59:17 2012
>> New Revision: 153297
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=153297&view=rev
>> Log:
>> [CFG] Cache boolean evaluations of expressions to avoid multiple re-evaluations
>> during construction of branches for chained logical operators.
>>
>> This makes -fsyntax-only for test/Sema/many-logical-ops.c about 32x times faster.
>>
>> With measuring SemaExpr.cpp I see differences below the noise level.
>>
>> Modified:
>> cfe/trunk/lib/Analysis/CFG.cpp
>>
>> Modified: cfe/trunk/lib/Analysis/CFG.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=153297&r1=153296&r2=153297&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/Analysis/CFG.cpp (original)
>> +++ cfe/trunk/lib/Analysis/CFG.cpp Thu Mar 22 19:59:17 2012
>> @@ -286,6 +286,10 @@
>> CFG::BuildOptions::ForcedBlkExprs::value_type *cachedEntry;
>> const Stmt *lastLookup;
>>
>> + // Caches boolean evaluations of expressions to avoid multiple re-evaluations
>> + // during construction of branches for chained logical operators.
>> + llvm::DenseMap<Expr *, TryResult> CachedBoolEvals;
>> +
>> public:
>> explicit CFGBuilder(ASTContext *astContext,
>> const CFG::BuildOptions &buildOpts)
>> @@ -439,12 +443,65 @@
>> /// tryEvaluateBool - Try and evaluate the Stmt and return 0 or 1
>> /// if we can evaluate to a known value, otherwise return -1.
>> TryResult tryEvaluateBool(Expr *S) {
>> - bool Result;
>> if (!BuildOpts.PruneTriviallyFalseEdges ||
>> - S->isTypeDependent() || S->isValueDependent() ||
>> - !S->EvaluateAsBooleanCondition(Result, *Context))
>> + S->isTypeDependent() || S->isValueDependent())
>> return TryResult();
>> - return Result;
>> +
>> + if (BinaryOperator *Bop = dyn_cast<BinaryOperator>(S)) {
>> + if (Bop->isLogicalOp()) {
>> + // Check the cache first.
>> + typedef llvm::DenseMap<Expr *, TryResult>::iterator eval_iterator;
>> + eval_iterator I;
>> + bool Inserted;
>> + llvm::tie(I, Inserted) =
>> + CachedBoolEvals.insert(std::make_pair(S, TryResult()));
>
> Why to insert a placeholder with <S, TryResult()> at first?
It is more efficient when inserting since it does one lookup instead of 2 lookups (one find and one insert).
But it affected correctness, thank you for fixing it!
-Argyrios
> Rewritten in r153407. Lemme know if early insertion would be needed here anyway.
>
>> + if (!Inserted)
>> + return I->second; // already in map;
>> +
>> + return (I->second = evaluateAsBooleanConditionNoCache(S));
>
> The iterator *I* would be invalidated after
> evaluateAsBooleanConditionNoCache(S).
> It caused memory leak at compiling ARMAsmParser.cpp.
> Should be fixed in r153406.
>
> ...Takumi
More information about the cfe-commits
mailing list