[llvm-commits] [llvm] r84352 - in /llvm/trunk: include/llvm/CompilerDriver/Common.td include/llvm/CompilerDriver/Plugin.h lib/CompilerDriver/Main.cpp lib/CompilerDriver/Plugin.cpp tools/llvmc/plugins/Base/Base.td.in utils/TableGen/LLVMCConfigurationEmitter.cpp

Mikhail Glushenkov foldr at codedgers.com
Sat Oct 17 13:09:29 PDT 2009


Author: foldr
Date: Sat Oct 17 15:09:29 2009
New Revision: 84352

URL: http://llvm.org/viewvc/llvm-project?rev=84352&view=rev
Log:
First draft of the OptionPreprocessor.

More to follow...

Modified:
    llvm/trunk/include/llvm/CompilerDriver/Common.td
    llvm/trunk/include/llvm/CompilerDriver/Plugin.h
    llvm/trunk/lib/CompilerDriver/Main.cpp
    llvm/trunk/lib/CompilerDriver/Plugin.cpp
    llvm/trunk/tools/llvmc/plugins/Base/Base.td.in
    llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp

Modified: llvm/trunk/include/llvm/CompilerDriver/Common.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CompilerDriver/Common.td?rev=84352&r1=84351&r2=84352&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CompilerDriver/Common.td (original)
+++ llvm/trunk/include/llvm/CompilerDriver/Common.td Sat Oct 17 15:09:29 2009
@@ -68,6 +68,8 @@
 def default;
 def single_input_file;
 def multiple_input_files;
+def any_switch_on;
+def any_not_empty;
 
 // Possible actions.
 
@@ -76,7 +78,9 @@
 def forward_as;
 def stop_compilation;
 def unpack_values;
+def warning;
 def error;
+def unset_option;
 
 // Increase/decrease the edge weight.
 def inc_weight;
@@ -90,11 +94,16 @@
       int priority = p;
 }
 
-// Option list - used to specify aliases and sometimes help strings.
+// Option list - a single place to specify options.
 class OptionList<list<dag> l> {
       list<dag> options = l;
 }
 
+// Option preprocessor - actions taken during plugin loading.
+class OptionPreprocessor<dag d> {
+      dag preprocessor = d;
+}
+
 // Map from suffixes to language names
 
 class LangToSuffixes<string str, list<string> lst> {

Modified: llvm/trunk/include/llvm/CompilerDriver/Plugin.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CompilerDriver/Plugin.h?rev=84352&r1=84351&r2=84352&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CompilerDriver/Plugin.h (original)
+++ llvm/trunk/include/llvm/CompilerDriver/Plugin.h Sat Oct 17 15:09:29 2009
@@ -29,6 +29,11 @@
     /// first.
     virtual int Priority() const { return 0; }
 
+    /// PreprocessOptions - The auto-generated function that performs various
+    /// consistency checks on options (like ensuring that -O2 and -O3 are not
+    /// used together).
+    virtual void PreprocessOptions() const = 0;
+
     /// PopulateLanguageMap - The auto-generated function that fills in
     /// the language map (map from file extensions to language names).
     virtual void PopulateLanguageMap(LanguageMap&) const = 0;
@@ -60,13 +65,10 @@
     PluginLoader();
     ~PluginLoader();
 
-    /// PopulateLanguageMap - Fills in the language map by calling
-    /// PopulateLanguageMap methods of all plugins.
-    void PopulateLanguageMap(LanguageMap& langMap);
-
-    /// PopulateCompilationGraph - Populates the compilation graph by
-    /// calling PopulateCompilationGraph methods of all plugins.
-    void PopulateCompilationGraph(CompilationGraph& tools);
+    /// RunInitialization - Calls PreprocessOptions, PopulateLanguageMap and
+    /// PopulateCompilationGraph methods of all plugins. This populates the
+    /// global language map and the compilation graph.
+    void RunInitialization(LanguageMap& langMap, CompilationGraph& graph) const;
 
   private:
     // noncopyable

Modified: llvm/trunk/lib/CompilerDriver/Main.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CompilerDriver/Main.cpp?rev=84352&r1=84351&r2=84352&view=diff

==============================================================================
--- llvm/trunk/lib/CompilerDriver/Main.cpp (original)
+++ llvm/trunk/lib/CompilerDriver/Main.cpp Sat Oct 17 15:09:29 2009
@@ -95,8 +95,7 @@
       (argc, argv, "LLVM Compiler Driver (Work In Progress)", true);
 
     PluginLoader Plugins;
-    Plugins.PopulateLanguageMap(langMap);
-    Plugins.PopulateCompilationGraph(graph);
+    Plugins.RunInitialization(langMap, graph);
 
     if (CheckGraph) {
       int ret = graph.Check();

Modified: llvm/trunk/lib/CompilerDriver/Plugin.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CompilerDriver/Plugin.cpp?rev=84352&r1=84351&r2=84352&view=diff

==============================================================================
--- llvm/trunk/lib/CompilerDriver/Plugin.cpp (original)
+++ llvm/trunk/lib/CompilerDriver/Plugin.cpp Sat Oct 17 15:09:29 2009
@@ -62,18 +62,17 @@
     pluginListInitialized = false;
   }
 
-  void PluginLoader::PopulateLanguageMap(LanguageMap& langMap) {
+  void PluginLoader::RunInitialization(LanguageMap& langMap,
+                                       CompilationGraph& graph) const
+  {
     llvm::sys::SmartScopedLock<true> Lock(*PluginMutex);
     for (PluginList::iterator B = Plugins.begin(), E = Plugins.end();
-         B != E; ++B)
-      (*B)->PopulateLanguageMap(langMap);
-  }
-
-  void PluginLoader::PopulateCompilationGraph(CompilationGraph& graph) {
-    llvm::sys::SmartScopedLock<true> Lock(*PluginMutex);
-    for (PluginList::iterator B = Plugins.begin(), E = Plugins.end();
-         B != E; ++B)
-      (*B)->PopulateCompilationGraph(graph);
+         B != E; ++B) {
+      const BasePlugin* BP = *B;
+      BP->PreprocessOptions();
+      BP->PopulateLanguageMap(langMap);
+      BP->PopulateCompilationGraph(graph);
+    }
   }
 
 }

Modified: llvm/trunk/tools/llvmc/plugins/Base/Base.td.in
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/plugins/Base/Base.td.in?rev=84352&r1=84351&r2=84352&view=diff

==============================================================================
--- llvm/trunk/tools/llvmc/plugins/Base/Base.td.in (original)
+++ llvm/trunk/tools/llvmc/plugins/Base/Base.td.in Sat Oct 17 15:09:29 2009
@@ -65,6 +65,18 @@
     (help "Pass options to opt"))
 ]>;
 
+// Option preprocessor.
+
+def Preprocess : OptionPreprocessor<
+(case (and (switch_on "O3"), (any_switch_on ["O0", "O1", "O2"])),
+           (unset_option ["O0", "O1", "O2"]),
+      (and (switch_on "O2"), (any_switch_on ["O0", "O1"])),
+           (unset_option ["O0", "O1"]),
+      (and (switch_on "O1"), (switch_on "O0")),
+           (unset_option "O0"))
+>;
+
+
 // Tools
 
 class llvm_gcc_based <string cmd_prefix, string in_lang, string E_ext> : Tool<

Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp?rev=84352&r1=84351&r2=84352&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Sat Oct 17 15:09:29 2009
@@ -351,6 +351,9 @@
 public:
   /// FindOption - exception-throwing wrapper for find().
   const OptionDescription& FindOption(const std::string& OptName) const;
+  /// FindSwitch - wrapper for FindOption that throws in case the option is not
+  /// a switch.
+  const OptionDescription& FindSwitch(const std::string& OptName) const;
 
   /// insertDescription - Insert new OptionDescription into
   /// OptionDescriptions list
@@ -372,6 +375,15 @@
     throw OptName + ": no such option!";
 }
 
+const OptionDescription&
+OptionDescriptions::FindSwitch(const std::string& OptName) const
+{
+  const OptionDescription& OptDesc = this->FindOption(OptName);
+  if (!OptDesc.isSwitch())
+    throw OptName + ": incorrect option type - should be a switch!";
+  return OptDesc;
+}
+
 void OptionDescriptions::InsertDescription (const OptionDescription& o)
 {
   container_type::iterator I = Descriptions.find(o.Name);
@@ -996,32 +1008,31 @@
   return false;
 }
 
-
-/// EmitCaseTest1Arg - Helper function used by EmitCaseConstructHandler().
-bool EmitCaseTest1Arg(const std::string& TestName,
-                      const DagInit& d,
-                      const OptionDescriptions& OptDescs,
-                      raw_ostream& O) {
-  checkNumberOfArguments(&d, 1);
+/// EmitCaseTest1ArgStr - Helper function used by EmitCaseTest1Arg();
+bool EmitCaseTest1ArgStr(const std::string& TestName,
+                         const DagInit& d,
+                         const OptionDescriptions& OptDescs,
+                         raw_ostream& O) {
   const std::string& OptName = InitPtrToString(d.getArg(0));
 
   if (TestName == "switch_on") {
-    const OptionDescription& OptDesc = OptDescs.FindOption(OptName);
-    if (!OptDesc.isSwitch())
-      throw OptName + ": incorrect option type - should be a switch!";
+    const OptionDescription& OptDesc = OptDescs.FindSwitch(OptName);
     O << OptDesc.GenVariableName();
     return true;
-  } else if (TestName == "input_languages_contain") {
+  }
+  else if (TestName == "input_languages_contain") {
     O << "InLangs.count(\"" << OptName << "\") != 0";
     return true;
-  } else if (TestName == "in_language") {
+  }
+  else if (TestName == "in_language") {
     // This works only for single-argument Tool::GenerateAction. Join
     // tools can process several files in different languages simultaneously.
 
     // TODO: make this work with Edge::Weight (if possible).
     O << "LangMap.GetLanguage(inFile) == \"" << OptName << '\"';
     return true;
-  } else if (TestName == "not_empty" || TestName == "empty") {
+  }
+  else if (TestName == "not_empty" || TestName == "empty") {
     const char* Test = (TestName == "empty") ? "" : "!";
 
     if (OptName == "o") {
@@ -1041,6 +1052,47 @@
   return false;
 }
 
+/// EmitCaseTest1ArgList - Helper function used by EmitCaseTest1Arg();
+bool EmitCaseTest1ArgList(const std::string& TestName,
+                          const DagInit& d,
+                          const OptionDescriptions& OptDescs,
+                          raw_ostream& O) {
+  const ListInit& L = *static_cast<ListInit*>(d.getArg(0));
+
+  if (TestName == "any_switch_on") {
+    bool isFirst = true;
+
+    for (ListInit::const_iterator B = L.begin(), E = L.end(); B != E; ++B) {
+      const std::string& OptName = InitPtrToString(*B);
+      const OptionDescription& OptDesc = OptDescs.FindSwitch(OptName);
+
+      if (isFirst)
+        isFirst = false;
+      else
+        O << " || ";
+      O << OptDesc.GenVariableName();
+    }
+
+    return true;
+  }
+
+  // TODO: implement any_not_empty, any_empty, switch_on [..], empty [..]
+
+  return false;
+}
+
+/// EmitCaseTest1Arg - Helper function used by EmitCaseConstructHandler();
+bool EmitCaseTest1Arg(const std::string& TestName,
+                      const DagInit& d,
+                      const OptionDescriptions& OptDescs,
+                      raw_ostream& O) {
+  checkNumberOfArguments(&d, 1);
+  if (typeid(*d.getArg(0)) == typeid(ListInit))
+    return EmitCaseTest1ArgList(TestName, d, OptDescs, O);
+  else
+    return EmitCaseTest1ArgStr(TestName, d, OptDescs, O);
+}
+
 /// EmitCaseTest2Args - Helper function used by EmitCaseConstructHandler().
 bool EmitCaseTest2Args(const std::string& TestName,
                        const DagInit& d,
@@ -1130,10 +1182,14 @@
     throw TestName + ": unknown edge property!";
 }
 
-// Emit code that handles the 'case' construct.
-// Takes a function object that should emit code for every case clause.
-// Callback's type is
-// void F(Init* Statement, unsigned IndentLevel, raw_ostream& O).
+/// EmitCaseConstructHandler - Emit code that handles the 'case'
+/// construct. Takes a function object that should emit code for every case
+/// clause.
+/// Callback's type is void F(Init* Statement, unsigned IndentLevel,
+/// raw_ostream& O).
+/// EmitElseIf parameter controls the type of condition that is emitted ('if
+/// (..) {...} else if (...) {} ... else {...}' vs. 'if (..)  {...} if(...)
+/// {...} ...').
 template <typename F>
 void EmitCaseConstructHandler(const Init* Dag, unsigned IndentLevel,
                               F Callback, bool EmitElseIf,
@@ -1876,10 +1932,108 @@
   O << '\n';
 }
 
-/// EmitPopulateLanguageMap - Emit the PopulateLanguageMap() function.
+/// PreprocessOptionsCallback - Helper function passed to
+/// EmitCaseConstructHandler() by EmitPreprocessOptions().
+class PreprocessOptionsCallback {
+  const OptionDescriptions& OptDescs_;
+
+  void onUnsetOption(Init* i, unsigned IndentLevel, raw_ostream& O) {
+    const std::string& OptName = InitPtrToString(i);
+    const OptionDescription& OptDesc = OptDescs_.FindOption(OptName);
+    const OptionType::OptionType OptType = OptDesc.Type;
+
+    if (OptType == OptionType::Switch) {
+      O.indent(IndentLevel) << OptDesc.GenVariableName() << " = false;\n";
+    }
+    else if (OptType == OptionType::Parameter
+             || OptType == OptionType::Prefix) {
+      O.indent(IndentLevel) << OptDesc.GenVariableName() << " = \"\";\n";
+    }
+    else {
+      throw std::string("'unset_option' can only be applied to "
+                        "switches or parameter/prefix options.");
+    }
+  }
+
+  void processDag(const Init* I, unsigned IndentLevel, raw_ostream& O)
+  {
+    const DagInit& d = InitPtrToDag(I);
+    const std::string& OpName = d.getOperator()->getAsString();
+
+    // TOFIX: there is some duplication between this function and
+    // EmitActionHandler.
+    if (OpName == "warning") {
+      checkNumberOfArguments(&d, 1);
+      O.indent(IndentLevel) << "llvm::errs() << \""
+                            << InitPtrToString(d.getArg(0)) << "\";\n";
+    }
+    else if (OpName == "error") {
+      checkNumberOfArguments(&d, 1);
+      O.indent(IndentLevel) << "throw std::runtime_error(\""
+                            << InitPtrToString(d.getArg(0))
+                            << "\");\n";
+    }
+    else if (OpName == "unset_option") {
+      checkNumberOfArguments(&d, 1);
+      Init* I = d.getArg(0);
+      if (typeid(*I) == typeid(ListInit)) {
+        const ListInit& DagList = *static_cast<const ListInit*>(I);
+        for (ListInit::const_iterator B = DagList.begin(), E = DagList.end();
+             B != E; ++B)
+          this->onUnsetOption(*B, IndentLevel, O);
+      }
+      else {
+        this->onUnsetOption(I, IndentLevel, O);
+      }
+    }
+    else {
+      throw "Unknown operator in the option preprocessor: '" + OpName + "'!"
+        "\nOnly 'warning', 'error' and 'unset_option' are allowed.";
+    }
+  }
+
+public:
+
+  // TODO: Remove duplication.
+  void operator()(const Init* I, unsigned IndentLevel, raw_ostream& O) {
+    if (typeid(*I) == typeid(ListInit)) {
+      const ListInit& DagList = *static_cast<const ListInit*>(I);
+      for (ListInit::const_iterator B = DagList.begin(), E = DagList.end();
+           B != E; ++B)
+        this->processDag(*B, IndentLevel, O);
+    }
+    else {
+      this->processDag(I, IndentLevel, O);
+    }
+  }
+
+  PreprocessOptionsCallback(const OptionDescriptions& OptDescs)
+  : OptDescs_(OptDescs)
+  {}
+};
+
+/// EmitPreprocessOptions - Emit the PreprocessOptionsLocal() function.
+void EmitPreprocessOptions (const RecordKeeper& Records,
+                            const OptionDescriptions& OptDecs, raw_ostream& O)
+{
+  O << "void PreprocessOptionsLocal() {\n";
+
+  const RecordVector& OptionPreprocessors =
+    Records.getAllDerivedDefinitions("OptionPreprocessor");
+
+  for (RecordVector::const_iterator B = OptionPreprocessors.begin(),
+         E = OptionPreprocessors.end(); B!=E; ++B) {
+    DagInit* Case = (*B)->getValueAsDag("preprocessor");
+    EmitCaseConstructHandler(Case, Indent1, PreprocessOptionsCallback(OptDecs),
+                             false, OptDecs, O);
+  }
+
+  O << "}\n\n";
+}
+
+/// EmitPopulateLanguageMap - Emit the PopulateLanguageMapLocal() function.
 void EmitPopulateLanguageMap (const RecordKeeper& Records, raw_ostream& O)
 {
-  // Generate code
   O << "void PopulateLanguageMapLocal(LanguageMap& langMap) {\n";
 
   // Get the relevant field out of RecordKeeper
@@ -1922,17 +2076,16 @@
     O.indent(IndentLevel) << "ret -= ";
   }
   else if (OpName == "error") {
-    O.indent(IndentLevel)
-      << "throw std::runtime_error(\"" <<
-      (d.getNumArgs() >= 1 ? InitPtrToString(d.getArg(0))
-       : "Unknown error!")
-      << "\");\n";
+    checkNumberOfArguments(&d, 1);
+    O.indent(IndentLevel) << "throw std::runtime_error(\""
+                          << InitPtrToString(d.getArg(0))
+                          << "\");\n";
     return;
   }
-
-  else
-    throw "Unknown operator in edge properties list: " + OpName + '!' +
+  else {
+    throw "Unknown operator in edge properties list: '" + OpName + "'!"
       "\nOnly 'inc_weight', 'dec_weight' and 'error' are allowed.";
+  }
 
   if (d.getNumArgs() > 0)
     O << InitPtrToInt(d.getArg(0)) << ";\n";
@@ -1981,7 +2134,7 @@
   }
 }
 
-/// EmitPopulateCompilationGraph - Emit the PopulateCompilationGraph()
+/// EmitPopulateCompilationGraph - Emit the PopulateCompilationGraphLocal()
 /// function.
 void EmitPopulateCompilationGraph (const RecordVector& EdgeVector,
                                    const ToolDescriptions& ToolDescs,
@@ -2110,6 +2263,8 @@
   O << "struct Plugin : public llvmc::BasePlugin {\n\n";
   O.indent(Indent1) << "int Priority() const { return "
                     << Priority << "; }\n\n";
+  O.indent(Indent1) << "void PreprocessOptions() const\n";
+  O.indent(Indent1) << "{ PreprocessOptionsLocal(); }\n\n";
   O.indent(Indent1) << "void PopulateLanguageMap(LanguageMap& langMap) const\n";
   O.indent(Indent1) << "{ PopulateLanguageMapLocal(langMap); }\n\n";
   O.indent(Indent1)
@@ -2129,7 +2284,8 @@
     << "#include \"llvm/CompilerDriver/Tool.h\"\n\n"
 
     << "#include \"llvm/ADT/StringExtras.h\"\n"
-    << "#include \"llvm/Support/CommandLine.h\"\n\n"
+    << "#include \"llvm/Support/CommandLine.h\"\n"
+    << "#include \"llvm/Support/raw_ostream.h\"\n\n"
 
     << "#include <cstdlib>\n"
     << "#include <stdexcept>\n\n"
@@ -2229,8 +2385,11 @@
 
   O << "namespace {\n\n";
 
-  // Emit PopulateLanguageMap() function
-  // (a language map maps from file extensions to language names).
+  // Emit PreprocessOptionsLocal() function.
+  EmitPreprocessOptions(Records, Data.OptDescs, O);
+
+  // Emit PopulateLanguageMapLocal() function
+  // (language map maps from file extensions to language names).
   EmitPopulateLanguageMap(Records, O);
 
   // Emit Tool classes.
@@ -2241,7 +2400,7 @@
   // Emit Edge# classes.
   EmitEdgeClasses(Data.Edges, Data.OptDescs, O);
 
-  // Emit PopulateCompilationGraph() function.
+  // Emit PopulateCompilationGraphLocal() function.
   EmitPopulateCompilationGraph(Data.Edges, Data.ToolDescs, O);
 
   // Emit code for plugin registration.





More information about the llvm-commits mailing list