[llvm-commits] [llvm] r51742 - in /llvm/trunk: tools/llvmc2/CompilationGraph.cpp tools/llvmc2/Tool.h tools/llvmc2/examples/Clang.td utils/TableGen/LLVMCConfigurationEmitter.cpp
Mikhail Glushenkov
foldr at codedgers.com
Thu May 29 23:18:16 PDT 2008
Author: foldr
Date: Fri May 30 01:18:16 2008
New Revision: 51742
URL: http://llvm.org/viewvc/llvm-project?rev=51742&view=rev
Log:
Make it possible to have multiple input languages for a single tool.
Modified:
llvm/trunk/tools/llvmc2/CompilationGraph.cpp
llvm/trunk/tools/llvmc2/Tool.h
llvm/trunk/tools/llvmc2/examples/Clang.td
llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp
Modified: llvm/trunk/tools/llvmc2/CompilationGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/CompilationGraph.cpp?rev=51742&r1=51741&r2=51742&view=diff
==============================================================================
--- llvm/trunk/tools/llvmc2/CompilationGraph.cpp (original)
+++ llvm/trunk/tools/llvmc2/CompilationGraph.cpp Fri May 30 01:18:16 2008
@@ -115,16 +115,18 @@
}
}
-void CompilationGraph::insertEdge(const std::string& A, Edge* E) {
- Node& B = getNode(E->ToolName());
+void CompilationGraph::insertEdge(const std::string& A, Edge* Edg) {
+ Node& B = getNode(Edg->ToolName());
if (A == "root") {
- const std::string& InputLanguage = B.ToolPtr->InputLanguage();
- ToolsMap[InputLanguage].push_back(IntrusiveRefCntPtr<Edge>(E));
- NodesMap["root"].AddEdge(E);
+ const StrVector& InputLanguages = B.ToolPtr->InputLanguages();
+ for (StrVector::const_iterator B = InputLanguages.begin(),
+ E = InputLanguages.end(); B != E; ++B)
+ ToolsMap[*B].push_back(IntrusiveRefCntPtr<Edge>(Edg));
+ NodesMap["root"].AddEdge(Edg);
}
else {
Node& N = getNode(A);
- N.AddEdge(E);
+ N.AddEdge(Edg);
}
// Increase the inward edge counter.
B.IncrInEdges();
@@ -381,10 +383,23 @@
template<typename EdgeIter>
static std::string getEdgeSourceLabel(const Node* N, EdgeIter I) {
- if (N->ToolPtr)
+ if (N->ToolPtr) {
return N->ToolPtr->OutputLanguage();
- else
- return I->ToolPtr->InputLanguage();
+ }
+ else {
+ const StrVector& InputLanguages = I->ToolPtr->InputLanguages();
+ std::string ret;
+
+ for (StrVector::const_iterator B = InputLanguages.begin(),
+ E = InputLanguages.end(); B != E; ++B) {
+ if (llvm::next(B) != E)
+ ret += *B + ", ";
+ else
+ ret += *B;
+ }
+
+ return ret;
+ }
}
};
Modified: llvm/trunk/tools/llvmc2/Tool.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/Tool.h?rev=51742&r1=51741&r2=51742&view=diff
==============================================================================
--- llvm/trunk/tools/llvmc2/Tool.h (original)
+++ llvm/trunk/tools/llvmc2/Tool.h Fri May 30 01:18:16 2008
@@ -43,7 +43,7 @@
const InputLanguagesSet& InLangs) const = 0;
virtual const char* Name() const = 0;
- virtual const char* InputLanguage() const = 0;
+ virtual StrVector InputLanguages() const = 0;
virtual const char* OutputLanguage() const = 0;
virtual const char* OutputSuffix() const = 0;
Modified: llvm/trunk/tools/llvmc2/examples/Clang.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/examples/Clang.td?rev=51742&r1=51741&r2=51742&view=diff
==============================================================================
--- llvm/trunk/tools/llvmc2/examples/Clang.td (original)
+++ llvm/trunk/tools/llvmc2/examples/Clang.td Fri May 30 01:18:16 2008
@@ -4,12 +4,8 @@
include "Common.td"
-// TOFIX: It should be possible to use a string list in the 'in_language'
-// tool property. There should be also an 'in_language' test in the
-// 'case' construct.
-
def clang : Tool<
-[(in_language "c"),
+[(in_language ["c", "c++", "objective-c"]),
(out_language "llvm-bitcode"),
(output_suffix "bc"),
(cmd_line (case (switch_on "E"), "clang -E $INFILE -o $OUTFILE",
Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp?rev=51742&r1=51741&r2=51742&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Fri May 30 01:18:16 2008
@@ -18,6 +18,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Streams.h"
#include <algorithm>
@@ -53,17 +54,22 @@
//===----------------------------------------------------------------------===//
/// Helper functions
+int InitPtrToInt(const Init* ptr) {
+ const IntInit& val = dynamic_cast<const IntInit&>(*ptr);
+ return val.getValue();
+}
+
const std::string& InitPtrToString(const Init* ptr) {
const StringInit& val = dynamic_cast<const StringInit&>(*ptr);
return val.getValue();
}
-int InitPtrToInt(const Init* ptr) {
- const IntInit& val = dynamic_cast<const IntInit&>(*ptr);
- return val.getValue();
+const ListInit& InitPtrToList(const Init* ptr) {
+ const ListInit& val = dynamic_cast<const ListInit&>(*ptr);
+ return val;
}
-const DagInit& InitPtrToDagInitRef(const Init* ptr) {
+const DagInit& InitPtrToDag(const Init* ptr) {
const DagInit& val = dynamic_cast<const DagInit&>(*ptr);
return val;
}
@@ -308,7 +314,7 @@
struct ToolProperties : public RefCountedBase<ToolProperties> {
std::string Name;
Init* CmdLine;
- std::string InLanguage;
+ StrVector InLanguage;
std::string OutLanguage;
std::string OutputSuffix;
unsigned Flags;
@@ -412,7 +418,7 @@
/// operator() - Gets called for every tool property; Just forwards
/// to the corresponding property handler.
void operator() (Init* i) {
- const DagInit& d = InitPtrToDagInitRef(i);
+ const DagInit& d = InitPtrToDag(i);
const std::string& property_name = d.getOperator()->getAsString();
PropertyHandlerMap::iterator method
= propertyHandlers_.find(property_name);
@@ -439,7 +445,29 @@
void onInLanguage (const DagInit* d) {
checkNumberOfArguments(d, 1);
- toolProps_.InLanguage = InitPtrToString(d->getArg(0));
+ Init* arg = d->getArg(0);
+
+ // Find out the argument's type.
+ if (typeid(*arg) == typeid(StringInit)) {
+ // It's a string.
+ toolProps_.InLanguage.push_back(InitPtrToString(arg));
+ }
+ else {
+ // It's a list.
+ const ListInit& lst = InitPtrToList(arg);
+ StrVector& out = toolProps_.InLanguage;
+
+ // Copy strings to the output vector.
+ for (ListInit::const_iterator B = lst.begin(), E = lst.end();
+ B != E; ++B) {
+ out.push_back(InitPtrToString(*B));
+ }
+
+ // Remove duplicates.
+ std::sort(out.begin(), out.end());
+ StrVector::iterator newE = std::unique(out.begin(), out.end());
+ out.erase(newE, out.end());
+ }
}
void onJoin (const DagInit* d) {
@@ -573,7 +601,7 @@
for (unsigned B = 1, E = d->getNumArgs(); B!=E; ++B) {
const DagInit& option_property
- = InitPtrToDagInitRef(d->getArg(B));
+ = InitPtrToDag(d->getArg(B));
const std::string& option_property_name
= option_property.getOperator()->getAsString();
OptionPropertyHandlerMap::iterator method
@@ -691,7 +719,7 @@
std::ostream& O) {
O << '(';
for (unsigned j = 0, NumArgs = d.getNumArgs(); j < NumArgs; ++j) {
- const DagInit& InnerTest = InitPtrToDagInitRef(d.getArg(j));
+ const DagInit& InnerTest = InitPtrToDag(d.getArg(j));
EmitCaseTest(InnerTest, IndentLevel, OptDescs, O);
if (j != NumArgs - 1)
O << ")\n" << IndentLevel << Indent1 << ' ' << LogicOp << " (";
@@ -736,7 +764,7 @@
+ d->getAsString();
for (unsigned i = 0; i != numArgs; ++i) {
- const DagInit& Test = InitPtrToDagInitRef(d->getArg(i));
+ const DagInit& Test = InitPtrToDag(d->getArg(i));
// Emit the test.
if (Test.getOperator()->getAsString() == "default") {
@@ -996,7 +1024,7 @@
if (typeid(*P.CmdLine) == typeid(StringInit))
EmitCmdLineVecFill(P.CmdLine, P.Name, Version, Indent2, O);
else
- EmitCaseConstructHandler(&InitPtrToDagInitRef(P.CmdLine), Indent2,
+ EmitCaseConstructHandler(&InitPtrToDag(P.CmdLine), Indent2,
EmitCmdLineVecFillCallback(Version, P.Name),
true, OptDescs, O);
@@ -1061,8 +1089,15 @@
/// EmitInOutLanguageMethods - Emit the [Input,Output]Language()
/// methods for a given Tool class.
void EmitInOutLanguageMethods (const ToolProperties& P, std::ostream& O) {
- O << Indent1 << "const char* InputLanguage() const {\n"
- << Indent2 << "return \"" << P.InLanguage << "\";\n"
+ O << Indent1 << "StrVector InputLanguages() const {\n"
+ << Indent2 << "StrVector ret;\n";
+
+ for (StrVector::const_iterator B = P.InLanguage.begin(),
+ E = P.InLanguage.end(); B != E; ++B) {
+ O << Indent2 << "ret.push_back(\"" << *B << "\");\n";
+ }
+
+ O << Indent2 << "return ret;\n"
<< Indent1 << "}\n\n";
O << Indent1 << "const char* OutputLanguage() const {\n"
@@ -1207,41 +1242,47 @@
/// FillInToolToLang - Fills in two tables that map tool names to
/// (input, output) languages. Used by the typechecker.
void FillInToolToLang (const ToolPropertiesList& TPList,
- StringMap<std::string>& ToolToInLang,
+ StringMap<StringSet<> >& ToolToInLang,
StringMap<std::string>& ToolToOutLang) {
for (ToolPropertiesList::const_iterator B = TPList.begin(), E = TPList.end();
B != E; ++B) {
const ToolProperties& P = *(*B);
- ToolToInLang[P.Name] = P.InLanguage;
+ for (StrVector::const_iterator B = P.InLanguage.begin(),
+ E = P.InLanguage.end(); B != E; ++B)
+ ToolToInLang[P.Name].insert(*B);
ToolToOutLang[P.Name] = P.OutLanguage;
}
}
/// TypecheckGraph - Check that names for output and input languages
/// on all edges do match.
-// TOFIX: check for cycles.
-// TOFIX: check for multiple default edges.
+// 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
+// sofisticated. Algorithms like these should be run on a real graph
+// instead of AST.
void TypecheckGraph (Record* CompilationGraph,
const ToolPropertiesList& TPList) {
- StringMap<std::string> ToolToInLang;
+ StringMap<StringSet<> > ToolToInLang;
StringMap<std::string> ToolToOutLang;
FillInToolToLang(TPList, ToolToInLang, ToolToOutLang);
ListInit* edges = CompilationGraph->getValueAsListInit("edges");
- StringMap<std::string>::iterator IAE = ToolToInLang.end();
- StringMap<std::string>::iterator IBE = ToolToOutLang.end();
+ StringMap<std::string>::iterator IAE = ToolToOutLang.end();
+ StringMap<StringSet<> >::iterator IBE = ToolToInLang.end();
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<std::string>::iterator IB = ToolToInLang.find(B->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" && IA->second != IB->second)
+ if (A->getName() != "root" && IB->second.count(IA->second) == 0)
throw "Edge " + A->getName() + "->" + B->getName()
+ ": output->input language mismatch";
if (B->getName() == "root")
@@ -1253,7 +1294,7 @@
/// by EmitEdgeClass().
void IncDecWeight (const Init* i, const char* IndentLevel,
std::ostream& O) {
- const DagInit& d = InitPtrToDagInitRef(i);
+ const DagInit& d = InitPtrToDag(i);
const std::string& OpName = d.getOperator()->getAsString();
if (OpName == "inc_weight")
@@ -1389,7 +1430,7 @@
}
else {
// This is a 'case' construct.
- const DagInit& d = InitPtrToDagInitRef(P.CmdLine);
+ const DagInit& d = InitPtrToDag(P.CmdLine);
bool even = false;
for (DagInit::const_arg_iterator B = d.arg_begin(), E = d.arg_end();
B != E; ++B) {
More information about the llvm-commits
mailing list