summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorStephen Kelly <steveire@gmail.com>2014-04-08 22:05:36 (GMT)
committerStephen Kelly <steveire@gmail.com>2014-04-09 08:37:00 (GMT)
commitb1c3ae33eacb55a54a7ce28c5a5d6aa8903fbac2 (patch)
treee02d733bfc9e400853009984b2fe89e37763210d /Source
parent9b1abc543e9aee946e093229e1715c4b8a961514 (diff)
downloadCMake-b1c3ae33eacb55a54a7ce28c5a5d6aa8903fbac2.zip
CMake-b1c3ae33eacb55a54a7ce28c5a5d6aa8903fbac2.tar.gz
CMake-b1c3ae33eacb55a54a7ce28c5a5d6aa8903fbac2.tar.bz2
cmTarget: Short-circuit language computation if context independent.
Computing the language involves computing the source files, which is an expensive operation. It requires calling cmMakefile::GetOrCreateSource many times, which involves creating and matching on many cmSourceFileLocation objects. Source files of a target may depend on the head-target and the config as of commit e6971df6 (cmTarget: Make the source files depend on the config., 2014-02-13). The results are cached for each context as of commit c5b26f3b (cmTarget: Cache the cmSourceFiles in GetSourceFiles., 2014-04-05). Each target in the build graph causes language computation of all of its dependents with itself as the head-target. This means that for 'core' libraries on which everything depends, the source files are computed once for every transitive target-level-dependee and the result is not cached because the head-target is different. This was observed in the VTK buildsystem. Short circuit the computation for targets which have a source-list that is independent of the head-target. If the source-list has already been computed and the generator expression evaluation reports that it was context-independent, return the only source-list already cached for the target. Reset the short-circuit logic when sources are added and when the link libraries are re-computed.
Diffstat (limited to 'Source')
-rw-r--r--Source/cmTarget.cxx36
-rw-r--r--Source/cmTarget.h2
2 files changed, 32 insertions, 6 deletions
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index d28ac3f..4903f8b 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -229,6 +229,7 @@ cmTarget::cmTarget()
this->DebugCompileOptionsDone = false;
this->DebugCompileDefinitionsDone = false;
this->DebugSourcesDone = false;
+ this->LinkImplementationLanguageIsContextDependent = true;
}
//----------------------------------------------------------------------------
@@ -461,6 +462,7 @@ void cmTarget::FinishConfigure()
//----------------------------------------------------------------------------
void cmTarget::ClearLinkMaps()
{
+ this->LinkImplementationLanguageIsContextDependent = true;
this->Internal->LinkImplMap.clear();
this->Internal->LinkInterfaceMap.clear();
this->Internal->LinkClosureMap.clear();
@@ -552,7 +554,7 @@ bool cmTarget::IsBundleOnApple() const
}
//----------------------------------------------------------------------------
-static void processSources(cmTarget const* tgt,
+static bool processSources(cmTarget const* tgt,
const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
std::vector<std::string> &srcs,
std::set<std::string> &uniqueSrcs,
@@ -562,6 +564,8 @@ static void processSources(cmTarget const* tgt,
{
cmMakefile *mf = tgt->GetMakefile();
+ bool contextDependent = false;
+
for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
it = entries.begin(), end = entries.end(); it != end; ++it)
{
@@ -576,8 +580,12 @@ static void processSources(cmTarget const* tgt,
tgt,
dagChecker),
entrySources);
- if (mf->IsGeneratingBuildSystem()
- && !(*it)->ge->GetHadContextSensitiveCondition())
+
+ if ((*it)->ge->GetHadContextSensitiveCondition())
+ {
+ contextDependent = true;
+ }
+ else if (mf->IsGeneratingBuildSystem())
{
cacheSources = true;
}
@@ -598,7 +606,7 @@ static void processSources(cmTarget const* tgt,
cm->IssueMessage(cmake::FATAL_ERROR, e,
tgt->GetBacktrace());
}
- return;
+ return contextDependent;
}
}
if (cacheSources)
@@ -629,6 +637,7 @@ static void processSources(cmTarget const* tgt,
+ usedSources, (*it)->ge->GetBacktrace());
}
}
+ return contextDependent;
}
//----------------------------------------------------------------------------
@@ -664,7 +673,7 @@ void cmTarget::GetSourceFiles(std::vector<std::string> &files,
"SOURCES", 0, 0);
std::set<std::string> uniqueSrcs;
- processSources(this,
+ bool contextDependentDirectSources = processSources(this,
this->Internal->SourceEntries,
files,
uniqueSrcs,
@@ -716,7 +725,8 @@ void cmTarget::GetSourceFiles(std::vector<std::string> &files,
}
}
- processSources(this,
+ std::vector<std::string>::size_type numFilesBefore = files.size();
+ bool contextDependentInterfaceSources = processSources(this,
this->Internal->CachedLinkInterfaceSourcesEntries[config],
files,
uniqueSrcs,
@@ -725,6 +735,12 @@ void cmTarget::GetSourceFiles(std::vector<std::string> &files,
config,
debugSources);
+ if (!contextDependentDirectSources
+ && !(contextDependentInterfaceSources && numFilesBefore < files.size()))
+ {
+ this->LinkImplementationLanguageIsContextDependent = false;
+ }
+
if (!this->Makefile->IsGeneratingBuildSystem())
{
deleteAndClear(this->Internal->CachedLinkInterfaceSourcesEntries);
@@ -801,6 +817,12 @@ void cmTarget::GetSourceFiles(std::vector<cmSourceFile*> &files,
// Lookup any existing link implementation for this configuration.
TargetConfigPair key(head, cmSystemTools::UpperCase(config));
+ if(!this->LinkImplementationLanguageIsContextDependent)
+ {
+ files = this->Internal->SourceFilesMap.begin()->second;
+ return;
+ }
+
cmTargetInternals::SourceFilesMapType::iterator
it = this->Internal->SourceFilesMap.find(key);
if(it != this->Internal->SourceFilesMap.end())
@@ -854,6 +876,7 @@ void cmTarget::AddSources(std::vector<std::string> const& srcs)
if (!srcFiles.empty())
{
this->Internal->SourceFilesMap.clear();
+ this->LinkImplementationLanguageIsContextDependent = true;
cmListFileBacktrace lfbt;
this->Makefile->GetBacktrace(lfbt);
cmGeneratorExpression ge(lfbt);
@@ -989,6 +1012,7 @@ cmSourceFile* cmTarget::AddSource(const std::string& src)
== this->Internal->SourceEntries.end())
{
this->Internal->SourceFilesMap.clear();
+ this->LinkImplementationLanguageIsContextDependent = true;
cmListFileBacktrace lfbt;
this->Makefile->GetBacktrace(lfbt);
cmGeneratorExpression ge(lfbt);
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index da9d0a1..868e260 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -784,6 +784,8 @@ private:
std::string const& suffix,
std::string const& name,
const char* version) const;
+
+ mutable bool LinkImplementationLanguageIsContextDependent;
};
typedef std::map<std::string,cmTarget> cmTargets;