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 commite6971df6
(cmTarget: Make the source files depend on the config., 2014-02-13). The results are cached for each context as of commitc5b26f3b
(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.
This commit is contained in:
parent
9b1abc543e
commit
b1c3ae33ea
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue