From e48d84209cde93b43fcfb305897b4f52cd18a55f Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Sun, 3 Feb 2013 07:33:15 +0100 Subject: [PATCH] Cache context-independent includes on evaluation. Generator expressions whose output depends on the configuration now record that fact. The GetIncludeDirectories method can use that result to cache the include directories for later calls. GetIncludeDirectories is called multiple times for a target for each configuration, so this should restore performance for multi-config generators. --- Source/cmGeneratorExpression.cxx | 8 ++++- Source/cmGeneratorExpression.h | 5 +++ Source/cmGeneratorExpressionEvaluator.cxx | 25 ++++++++++++-- Source/cmGeneratorExpressionEvaluator.h | 1 + Source/cmTarget.cxx | 41 +++++++++++++++++------ 5 files changed, 66 insertions(+), 14 deletions(-) diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index 78ae8f258..7add1bf39 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx @@ -88,6 +88,7 @@ const char *cmCompiledGeneratorExpression::Evaluate( context.Config = config; context.Quiet = quiet; context.HadError = false; + context.HadContextSensitiveCondition = false; context.HeadTarget = headTarget; context.CurrentTarget = currentTarget ? currentTarget : headTarget; context.Backtrace = this->Backtrace; @@ -109,6 +110,10 @@ const char *cmCompiledGeneratorExpression::Evaluate( break; } } + if (!context.HadError) + { + this->HadContextSensitiveCondition = context.HadContextSensitiveCondition; + } this->Targets = context.Targets; // TODO: Return a std::string from here instead? @@ -118,7 +123,8 @@ const char *cmCompiledGeneratorExpression::Evaluate( cmCompiledGeneratorExpression::cmCompiledGeneratorExpression( cmListFileBacktrace const& backtrace, const char *input) - : Backtrace(backtrace), Input(input ? input : "") + : Backtrace(backtrace), Input(input ? input : ""), + HadContextSensitiveCondition(false) { cmGeneratorExpressionLexer l; std::vector tokens = diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h index 8f1aef677..700fe033b 100644 --- a/Source/cmGeneratorExpression.h +++ b/Source/cmGeneratorExpression.h @@ -100,6 +100,10 @@ public: { return this->Backtrace; } + bool GetHadContextSensitiveCondition() const + { + return this->HadContextSensitiveCondition; + } private: cmCompiledGeneratorExpression(cmListFileBacktrace const& backtrace, @@ -118,6 +122,7 @@ private: mutable std::set Targets; mutable std::map SeenTargetProperties; mutable std::string Output; + mutable bool HadContextSensitiveCondition; }; #endif diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index cd4b7d805..5d9471883 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -238,6 +238,7 @@ static const struct ConfigurationNode : public cmGeneratorExpressionNode const GeneratorExpressionContent *, cmGeneratorExpressionDAGChecker *) const { + context->HadContextSensitiveCondition = true; return context->Config ? context->Config : ""; } } configurationNode; @@ -262,6 +263,7 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode "Expression syntax not recognized."); return std::string(); } + context->HadContextSensitiveCondition = true; if (!context->Config) { return parameters.front().empty() ? "1" : "0"; @@ -455,12 +457,14 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode } if (propertyName == "POSITION_INDEPENDENT_CODE") { + context->HadContextSensitiveCondition = true; return target->GetLinkInterfaceDependentBoolProperty( "POSITION_INDEPENDENT_CODE", context->Config) ? "1" : "0"; } if (target->IsLinkInterfaceDependentBoolProperty(propertyName, context->Config)) { + context->HadContextSensitiveCondition = true; return target->GetLinkInterfaceDependentBoolProperty( propertyName, context->Config) ? "1" : "0"; @@ -468,6 +472,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode if (target->IsLinkInterfaceDependentStringProperty(propertyName, context->Config)) { + context->HadContextSensitiveCondition = true; const char *propContent = target->GetLinkInterfaceDependentStringProperty( propertyName, @@ -486,12 +491,19 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode if (targetPropertyTransitiveWhitelist[i] == propertyName) { cmGeneratorExpression ge(context->Backtrace); - return ge.Parse(prop)->Evaluate(context->Makefile, + cmsys::auto_ptr cge = ge.Parse(prop); + std::string result = cge->Evaluate(context->Makefile, context->Config, context->Quiet, context->HeadTarget, target, &dagChecker); + + if (cge->GetHadContextSensitiveCondition()) + { + context->HadContextSensitiveCondition = true; + } + return result; } } return prop; @@ -585,6 +597,9 @@ static const struct TargetPolicyNode : public cmGeneratorExpressionNode "be used with add_custom_command."); return std::string(); } + + context->HadContextSensitiveCondition = true; + for (size_t i = 0; i < (sizeof(targetPolicyWhitelist) / sizeof(*targetPolicyWhitelist)); @@ -716,12 +731,18 @@ private: } cmGeneratorExpression ge(context->Backtrace); - return ge.Parse(propContent)->Evaluate(context->Makefile, + cmsys::auto_ptr cge = ge.Parse(propContent); + std::string result = cge->Evaluate(context->Makefile, context->Config, context->Quiet, context->HeadTarget, target, &dagChecker); + if (cge->GetHadContextSensitiveCondition()) + { + context->HadContextSensitiveCondition = true; + } + return result; } } linkedNode; diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h index fb6c7eee5..37d5c864f 100644 --- a/Source/cmGeneratorExpressionEvaluator.h +++ b/Source/cmGeneratorExpressionEvaluator.h @@ -32,6 +32,7 @@ struct cmGeneratorExpressionContext // directly or indirectly in the property. bool Quiet; bool HadError; + bool HadContextSensitiveCondition; }; struct cmGeneratorExpressionDAGChecker; diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 566987236..1a6b7cead 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -134,6 +134,7 @@ public: : ge(cge) {} const cmsys::auto_ptr ge; + std::vector CachedIncludes; }; std::vector IncludeDirectoriesEntries; }; @@ -2778,22 +2779,36 @@ std::vector cmTarget::GetIncludeDirectories(const char *config) end = this->Internal->IncludeDirectoriesEntries.end(); it != end; ++it) { - std::vector entryIncludes; - cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(this->Makefile, - config, - false, - this, - &dagChecker), - entryIncludes); + + bool testIsOff = true; + bool cacheIncludes = false; + std::vector entryIncludes = (*it)->CachedIncludes; + if(!entryIncludes.empty()) + { + testIsOff = false; + } + else + { + cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(this->Makefile, + config, + false, + this, + &dagChecker), + entryIncludes); + if (!(*it)->ge->GetHadContextSensitiveCondition()) + { + cacheIncludes = true; + } + } std::string usedIncludes; - for(std::vector::const_iterator + for(std::vector::iterator li = entryIncludes.begin(); li != entryIncludes.end(); ++li) { - std::string inc = *li; - if (!cmSystemTools::IsOff(inc.c_str())) + if (testIsOff && !cmSystemTools::IsOff(li->c_str())) { - cmSystemTools::ConvertToUnixSlashes(inc); + cmSystemTools::ConvertToUnixSlashes(*li); } + std::string inc = *li; if(uniqueIncludes.insert(inc).second) { @@ -2804,6 +2819,10 @@ std::vector cmTarget::GetIncludeDirectories(const char *config) } } } + if (cacheIncludes) + { + (*it)->CachedIncludes = entryIncludes; + } if (!usedIncludes.empty()) { this->Makefile->GetCMakeInstance()->IssueMessage(cmake::LOG,