summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorMikhail Glushenkov <foldr@codedgers.com>2008-11-17 17:29:18 +0000
committerMikhail Glushenkov <foldr@codedgers.com>2008-11-17 17:29:18 +0000
commit010887765a9a80ecb5e34b65a3aeacf098298cb3 (patch)
tree1884c821524db37b2afb76a081baa3853f074396 /utils
parent6560c000a1327b6a023badafed974f35fa1bdc3b (diff)
downloadllvm-010887765a9a80ecb5e34b65a3aeacf098298cb3.tar.gz
llvm-010887765a9a80ecb5e34b65a3aeacf098298cb3.tar.bz2
llvm-010887765a9a80ecb5e34b65a3aeacf098298cb3.tar.xz
Add a layer of indirection to make plugins more flexible.
Use strings instead of TableGen defs in the compilation graph definition. Makes it easier for the plugins to modify an existing graph. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@59447 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/LLVMCConfigurationEmitter.cpp113
1 files changed, 58 insertions, 55 deletions
diff --git a/utils/TableGen/LLVMCConfigurationEmitter.cpp b/utils/TableGen/LLVMCConfigurationEmitter.cpp
index bacde538da..f5a1cf8652 100644
--- a/utils/TableGen/LLVMCConfigurationEmitter.cpp
+++ b/utils/TableGen/LLVMCConfigurationEmitter.cpp
@@ -764,11 +764,11 @@ void CollectToolProperties (RecordVector::const_iterator B,
}
-/// CollectPropertiesFromOptionList - Gather information about
-/// *global* option properties from the OptionList.
-void CollectPropertiesFromOptionList (RecordVector::const_iterator B,
- RecordVector::const_iterator E,
- GlobalOptionDescriptions& OptDescs)
+/// CollectPropertiesFromOptionLists - Gather information about
+/// *global* option properties from all OptionLists.
+void CollectPropertiesFromOptionLists (RecordVector::const_iterator B,
+ RecordVector::const_iterator E,
+ GlobalOptionDescriptions& OptDescs)
{
// Iterate over a properties list of every Tool definition
for (;B!=E;++B) {
@@ -805,7 +805,7 @@ void CheckForSuperfluousOptions (const ToolPropertiesList& TPList,
const GlobalOptionDescription& Val = B->second;
if (!nonSuperfluousOptions.count(Val.Name)
&& Val.Type != OptionType::Alias)
- cerr << "Warning: option '-" << Val.Name << "' has no effect! "
+ llvm::cerr << "Warning: option '-" << Val.Name << "' has no effect! "
"Probable cause: this option is specified only in the OptionList.\n";
}
}
@@ -1448,29 +1448,31 @@ void EmitOptionDescriptions (const GlobalOptionDescriptions& descs,
/// EmitPopulateLanguageMap - Emit the PopulateLanguageMap() function.
void EmitPopulateLanguageMap (const RecordKeeper& Records, std::ostream& O)
{
+ // Generate code
+ O << "namespace {\n\n";
+ O << "void PopulateLanguageMapLocal(LanguageMap& langMap) {\n";
+
// Get the relevant field out of RecordKeeper
Record* LangMapRecord = Records.getDef("LanguageMap");
- if (!LangMapRecord)
- throw std::string("Language map definition not found!");
- ListInit* LangsToSuffixesList = LangMapRecord->getValueAsListInit("map");
- if (!LangsToSuffixesList)
- throw std::string("Error in the language map definition!");
+ // It is allowed for a plugin to have no language map.
+ if (LangMapRecord) {
- // Generate code
- O << "namespace {\n\n";
- O << "void PopulateLanguageMapLocal(LanguageMap& langMap) {\n";
+ ListInit* LangsToSuffixesList = LangMapRecord->getValueAsListInit("map");
+ if (!LangsToSuffixesList)
+ throw std::string("Error in the language map definition!");
- for (unsigned i = 0; i < LangsToSuffixesList->size(); ++i) {
- Record* LangToSuffixes = LangsToSuffixesList->getElementAsRecord(i);
+ for (unsigned i = 0; i < LangsToSuffixesList->size(); ++i) {
+ Record* LangToSuffixes = LangsToSuffixesList->getElementAsRecord(i);
- const std::string& Lang = LangToSuffixes->getValueAsString("lang");
- const ListInit* Suffixes = LangToSuffixes->getValueAsListInit("suffixes");
+ const std::string& Lang = LangToSuffixes->getValueAsString("lang");
+ const ListInit* Suffixes = LangToSuffixes->getValueAsListInit("suffixes");
- for (unsigned i = 0; i < Suffixes->size(); ++i)
- O << Indent1 << "langMap[\""
- << InitPtrToString(Suffixes->getElement(i))
- << "\"] = \"" << Lang << "\";\n";
+ for (unsigned i = 0; i < Suffixes->size(); ++i)
+ O << Indent1 << "langMap[\""
+ << InitPtrToString(Suffixes->getElement(i))
+ << "\"] = \"" << Lang << "\";\n";
+ }
}
O << "}\n\n}\n\n";
@@ -1492,13 +1494,11 @@ void FillInToolToLang (const ToolPropertiesList& TPList,
}
/// TypecheckGraph - Check that names for output and input languages
-/// on all edges do match.
-// TOFIX: It would be nice if this function also checked for cycles
-// and multiple default edges in the graph (better error
-// reporting). Unfortunately, it is awkward to do right now because
-// our intermediate representation is not sufficiently
-// sophisticated. Algorithms like these require a real graph instead of
-// an AST.
+/// on all edges do match. This doesn't do much when the information
+/// about the whole graph is not available (i.e. when compiling most
+/// plugins).
+// TODO: add a --check-graph switch to llvmc2. It would also make it
+// possible to detect cycles and multiple default edges.
void TypecheckGraph (Record* CompilationGraph,
const ToolPropertiesList& TPList) {
StringMap<StringSet<> > ToolToInLang;
@@ -1511,18 +1511,18 @@ void TypecheckGraph (Record* CompilationGraph,
for (unsigned i = 0; i < edges->size(); ++i) {
Record* Edge = edges->getElementAsRecord(i);
- Record* A = Edge->getValueAsDef("a");
- Record* B = Edge->getValueAsDef("b");
- StringMap<std::string>::iterator IA = ToolToOutLang.find(A->getName());
- StringMap<StringSet<> >::iterator IB = ToolToInLang.find(B->getName());
- if (IA == IAE)
- throw A->getName() + ": no such tool!";
- if (IB == IBE)
- throw B->getName() + ": no such tool!";
- if (A->getName() != "root" && IB->second.count(IA->second) == 0)
- throw "Edge " + A->getName() + "->" + B->getName()
- + ": output->input language mismatch";
- if (B->getName() == "root")
+ const std::string& A = Edge->getValueAsString("a");
+ const std::string& B = Edge->getValueAsString("b");
+ StringMap<std::string>::iterator IA = ToolToOutLang.find(A);
+ StringMap<StringSet<> >::iterator IB = ToolToInLang.find(B);
+
+ if (A != "root") {
+ if (IA != IAE && IB != IBE && IB->second.count(IA->second) == 0)
+ throw "Edge " + A + "->" + B
+ + ": output->input language mismatch";
+ }
+
+ if (B == "root")
throw std::string("Edges back to the root are not allowed!");
}
}
@@ -1578,13 +1578,13 @@ void EmitEdgeClasses (Record* CompilationGraph,
for (unsigned i = 0; i < edges->size(); ++i) {
Record* Edge = edges->getElementAsRecord(i);
- Record* B = Edge->getValueAsDef("b");
+ const std::string& B = Edge->getValueAsString("b");
DagInit* Weight = Edge->getValueAsDag("weight");
if (isDagEmpty(Weight))
continue;
- EmitEdgeClass(i, B->getName(), Weight, OptDescs, O);
+ EmitEdgeClass(i, B, Weight, OptDescs, O);
}
}
@@ -1605,13 +1605,12 @@ void EmitPopulateCompilationGraph (Record* CompilationGraph,
for (unsigned i = 0; i < edges->size(); ++i) {
Record* Edge = edges->getElementAsRecord(i);
- Record* A = Edge->getValueAsDef("a");
- Record* B = Edge->getValueAsDef("b");
+ const std::string& A = Edge->getValueAsString("a");
+ const std::string& B = Edge->getValueAsString("b");
- if (A->getName() != "root")
- ToolsInGraph.insert(A->getName());
- if (B->getName() != "root")
- ToolsInGraph.insert(B->getName());
+ if (A != "root")
+ ToolsInGraph.insert(A);
+ ToolsInGraph.insert(B);
}
for (llvm::StringSet<>::iterator B = ToolsInGraph.begin(),
@@ -1624,14 +1623,14 @@ void EmitPopulateCompilationGraph (Record* CompilationGraph,
for (unsigned i = 0; i < edges->size(); ++i) {
Record* Edge = edges->getElementAsRecord(i);
- Record* A = Edge->getValueAsDef("a");
- Record* B = Edge->getValueAsDef("b");
+ const std::string& A = Edge->getValueAsString("a");
+ const std::string& B = Edge->getValueAsString("b");
DagInit* Weight = Edge->getValueAsDag("weight");
- O << Indent1 << "G.insertEdge(\"" << A->getName() << "\", ";
+ O << Indent1 << "G.insertEdge(\"" << A << "\", ";
if (isDagEmpty(Weight))
- O << "new SimpleEdge(\"" << B->getName() << "\")";
+ O << "new SimpleEdge(\"" << B << "\")";
else
O << "new Edge" << i << "()";
@@ -1763,6 +1762,7 @@ void LLVMCConfigurationEmitter::run (std::ostream &O) {
EmitIncludes(O);
// Get a list of all defined Tools.
+
RecordVector Tools = Records.getAllDerivedDefinitions("Tool");
if (Tools.empty())
throw std::string("No tool definitions found!");
@@ -1773,8 +1773,8 @@ void LLVMCConfigurationEmitter::run (std::ostream &O) {
CollectToolProperties(Tools.begin(), Tools.end(), tool_props, opt_descs);
RecordVector OptionLists = Records.getAllDerivedDefinitions("OptionList");
- CollectPropertiesFromOptionList(OptionLists.begin(), OptionLists.end(),
- opt_descs);
+ CollectPropertiesFromOptionLists(OptionLists.begin(), OptionLists.end(),
+ opt_descs);
// Check that there are no options without side effects (specified
// only in the OptionList).
@@ -1795,6 +1795,9 @@ void LLVMCConfigurationEmitter::run (std::ostream &O) {
E = tool_props.end(); B!=E; ++B)
EmitToolClassDefinition(*(*B), opt_descs, O);
+ // TOTHINK: Nothing actually prevents us from having multiple
+ // compilation graphs in a single plugin; OTOH, I do not see how
+ // that could be useful.
Record* CompilationGraphRecord = Records.getDef("CompilationGraph");
if (!CompilationGraphRecord)
throw std::string("Compilation graph description not found!");