summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/CompilerDriver/Common.td1
-rw-r--r--test/LLVMC/OptionPreprocessor.td21
-rw-r--r--tools/llvmc/doc/LLVMC-Reference.rst43
-rw-r--r--tools/llvmc/plugins/Base/Base.td.in4
-rw-r--r--utils/TableGen/LLVMCConfigurationEmitter.cpp80
5 files changed, 109 insertions, 40 deletions
diff --git a/include/llvm/CompilerDriver/Common.td b/include/llvm/CompilerDriver/Common.td
index 8d2f63b330..9c3e861c22 100644
--- a/include/llvm/CompilerDriver/Common.td
+++ b/include/llvm/CompilerDriver/Common.td
@@ -84,6 +84,7 @@ def stop_compilation;
def unpack_values;
def warning;
def error;
+def set_option;
def unset_option;
// Increase/decrease the edge weight.
diff --git a/test/LLVMC/OptionPreprocessor.td b/test/LLVMC/OptionPreprocessor.td
index 5661db865d..44ebfa49bb 100644
--- a/test/LLVMC/OptionPreprocessor.td
+++ b/test/LLVMC/OptionPreprocessor.td
@@ -11,20 +11,30 @@ def OptList : OptionList<[
(switch_option "baz", (help "dummy")),
(parameter_option "foo_p", (help "dummy")),
(parameter_option "bar_p", (help "dummy")),
-(parameter_option "baz_p", (help "dummy"))
+(parameter_option "baz_p", (help "dummy")),
+(parameter_list_option "foo_l", (help "dummy"))
]>;
def Preprocess : OptionPreprocessor<
(case
// CHECK: W1
+ // CHECK: foo = false;
+ // CHECK: foo_p = "";
+ // CHECK: foo_l.clear();
(and (switch_on "foo"), (any_switch_on ["bar", "baz"])),
- (warning "W1"),
+ [(warning "W1"), (unset_option "foo"),
+ (unset_option "foo_p"), (unset_option "foo_l")],
// CHECK: W2
+ // CHECK: foo = true;
+ // CHECK: foo_p = "asdf";
(and (switch_on ["foo", "bar"]), (any_empty ["foo_p", "bar_p"])),
- (warning "W2"),
+ [(warning "W2"), (set_option "foo"), (set_option "foo_p", "asdf")],
// CHECK: W3
+ // CHECK: foo = true;
+ // CHECK: bar = true;
+ // CHECK: baz = true;
(and (empty ["foo_p", "bar_p"]), (any_not_empty ["baz_p"])),
- (warning "W3"))
+ [(warning "W3"), (set_option ["foo", "bar", "baz"])])
>;
// Shut up warnings...
@@ -38,7 +48,8 @@ def dummy : Tool<
(switch_on "baz"), (error),
(not_empty "foo_p"), (error),
(not_empty "bar_p"), (error),
- (not_empty "baz_p"), (error)))
+ (not_empty "baz_p"), (error),
+ (not_empty "foo_l"), (error)))
]>;
def Graph : CompilationGraph<[Edge<"root", "dummy">]>;
diff --git a/tools/llvmc/doc/LLVMC-Reference.rst b/tools/llvmc/doc/LLVMC-Reference.rst
index 4d80a2a6e1..7336195dfe 100644
--- a/tools/llvmc/doc/LLVMC-Reference.rst
+++ b/tools/llvmc/doc/LLVMC-Reference.rst
@@ -656,10 +656,10 @@ For example, without those definitions the following command wouldn't work::
$ llvmc hello.cpp
llvmc: Unknown suffix: cpp
-The language map entries should be added only for tools that are
-linked with the root node. Since tools are not allowed to have
-multiple output languages, for nodes "inside" the graph the input and
-output languages should match. This is enforced at compile-time.
+The language map entries are needed only for the tools that are linked from the
+root node. Since a tool can't have multiple output languages, for inner nodes of
+the graph the input and output languages should match. This is enforced at
+compile-time.
Option preprocessor
===================
@@ -672,24 +672,31 @@ the driver with both of these options enabled.
The ``OptionPreprocessor`` feature is reserved specially for these
occasions. Example (adapted from the built-in Base plugin)::
- def Preprocess : OptionPreprocessor<
- (case (and (switch_on "O3"), (any_switch_on ["O0", "O1", "O2"])),
- [(unset_option ["O0", "O1", "O2"]),
- (warning "Multiple -O options specified, defaulted to -O3.")],
- (and (switch_on "O2"), (any_switch_on ["O0", "O1"])),
- (unset_option ["O0", "O1"]),
- (and (switch_on "O1"), (switch_on "O0")),
- (unset_option "O0"))
- >;
-Here, ``OptionPreprocessor`` is used to unset all spurious optimization options
-(so that they are not forwarded to the compiler).
+ def Preprocess : OptionPreprocessor<
+ (case (not (any_switch_on ["O0", "O1", "O2", "O3"])),
+ (set_option "O2"),
+ (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"))
+ >;
+
+Here, ``OptionPreprocessor`` is used to unset all spurious ``-O`` options so
+that they are not forwarded to the compiler. If no optimization options are
+specified, ``-O2`` is enabled.
``OptionPreprocessor`` is basically a single big ``case`` expression, which is
evaluated only once right after the plugin is loaded. The only allowed actions
-in ``OptionPreprocessor`` are ``error``, ``warning`` and a special action
-``unset_option``, which, as the name suggests, unsets a given option. For
-convenience, ``unset_option`` also works on lists.
+in ``OptionPreprocessor`` are ``error``, ``warning`` and two special actions:
+``unset_option`` and ``set_option``. As their names suggest, they can be used to
+set or unset a given option. To set a parameter option with ``set_option``, use
+the two-argument form: ``(set_option "parameter", "value")``. For convenience,
+``set_option`` and ``unset_option`` also work on lists (that is, instead of
+``[(unset_option "A"), (unset_option "B")]`` you can use ``(unset_option ["A",
+"B"])``).
More advanced topics
diff --git a/tools/llvmc/plugins/Base/Base.td.in b/tools/llvmc/plugins/Base/Base.td.in
index 8f928cc40c..1413593bdf 100644
--- a/tools/llvmc/plugins/Base/Base.td.in
+++ b/tools/llvmc/plugins/Base/Base.td.in
@@ -91,7 +91,9 @@ def OptList : OptionList<[
// Option preprocessor.
def Preprocess : OptionPreprocessor<
-(case (and (switch_on "O3"), (any_switch_on ["O0", "O1", "O2"])),
+(case (not (any_switch_on ["O0", "O1", "O2", "O3"])),
+ (set_option "O2"),
+ (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"]),
diff --git a/utils/TableGen/LLVMCConfigurationEmitter.cpp b/utils/TableGen/LLVMCConfigurationEmitter.cpp
index be3382c29d..3ff7bc4d2e 100644
--- a/utils/TableGen/LLVMCConfigurationEmitter.cpp
+++ b/utils/TableGen/LLVMCConfigurationEmitter.cpp
@@ -2303,11 +2303,32 @@ class EmitPreprocessOptionsCallback :
public HandlerTable<EmitPreprocessOptionsCallbackHandler>
{
typedef EmitPreprocessOptionsCallbackHandler Handler;
+ typedef void
+ (EmitPreprocessOptionsCallback::* HandlerImpl)
+ (const Init*, unsigned, raw_ostream&) const;
const OptionDescriptions& OptDescs_;
- void onUnsetOptionStr(const Init* I,
- unsigned IndentLevel, raw_ostream& O) const
+ void onListOrDag(HandlerImpl h,
+ const DagInit& d, unsigned IndentLevel, raw_ostream& O) const
+ {
+ checkNumberOfArguments(d, 1);
+ const Init* I = d.getArg(0);
+
+ // If I is a list, apply h to each element.
+ if (typeid(*I) == typeid(ListInit)) {
+ const ListInit& L = *static_cast<const ListInit*>(I);
+ for (ListInit::const_iterator B = L.begin(), E = L.end(); B != E; ++B)
+ ((this)->*(h))(*B, IndentLevel, O);
+ }
+ // Otherwise, apply h to I.
+ else {
+ ((this)->*(h))(I, IndentLevel, O);
+ }
+ }
+
+ void onUnsetOptionImpl(const Init* I,
+ unsigned IndentLevel, raw_ostream& O) const
{
const std::string& OptName = InitPtrToString(I);
const OptionDescription& OptDesc = OptDescs_.FindOption(OptName);
@@ -2326,26 +2347,52 @@ class EmitPreprocessOptionsCallback :
}
}
- void onUnsetOptionList(const ListInit& L,
- unsigned IndentLevel, raw_ostream& O) const
+ void onUnsetOption(const DagInit& d,
+ unsigned IndentLevel, raw_ostream& O) const
{
- for (ListInit::const_iterator B = L.begin(), E = L.end(); B != E; ++B)
- this->onUnsetOptionStr(*B, IndentLevel, O);
+ this->onListOrDag(&EmitPreprocessOptionsCallback::onUnsetOptionImpl,
+ d, IndentLevel, O);
}
- void onUnsetOption(const DagInit& d,
- unsigned IndentLevel, raw_ostream& O) const
+ void onSetParameter(const DagInit& d,
+ unsigned IndentLevel, raw_ostream& O) const {
+ checkNumberOfArguments(d, 2);
+ const std::string& OptName = InitPtrToString(d.getArg(0));
+ const std::string& Value = InitPtrToString(d.getArg(1));
+ const OptionDescription& OptDesc = OptDescs_.FindOption(OptName);
+
+ if (OptDesc.isParameter())
+ O.indent(IndentLevel) << OptDesc.GenVariableName()
+ << " = \"" << Value << "\";\n";
+ else
+ throw "Two-argument 'set_option' "
+ "can be only applied to parameter options!";
+ }
+
+ void onSetSwitch(const Init* I,
+ unsigned IndentLevel, raw_ostream& O) const {
+ const std::string& OptName = InitPtrToString(I);
+ const OptionDescription& OptDesc = OptDescs_.FindOption(OptName);
+
+ if (OptDesc.isSwitch())
+ O.indent(IndentLevel) << OptDesc.GenVariableName() << " = true;\n";
+ else
+ throw "One-argument 'set_option' can be only applied to switch options!";
+ }
+
+ void onSetOption(const DagInit& d,
+ unsigned IndentLevel, raw_ostream& O) const
{
checkNumberOfArguments(d, 1);
- Init* I = d.getArg(0);
- if (typeid(*I) == typeid(ListInit)) {
- const ListInit& L = *static_cast<const ListInit*>(I);
- this->onUnsetOptionList(L, IndentLevel, O);
- }
- else {
- this->onUnsetOptionStr(I, IndentLevel, O);
- }
+ // Two arguments: (set_option "parameter", "value")
+ if (d.getNumArgs() > 1)
+ this->onSetParameter(d, IndentLevel, O);
+ // One argument: (set_option "switch")
+ // or (set_option ["switch1", "switch2", ...])
+ else
+ this->onListOrDag(&EmitPreprocessOptionsCallback::onSetSwitch,
+ d, IndentLevel, O);
}
public:
@@ -2357,6 +2404,7 @@ public:
AddHandler("error", &EmitPreprocessOptionsCallback::onErrorDag);
AddHandler("warning", &EmitPreprocessOptionsCallback::onWarningDag);
AddHandler("unset_option", &EmitPreprocessOptionsCallback::onUnsetOption);
+ AddHandler("set_option", &EmitPreprocessOptionsCallback::onSetOption);
staticMembersInitialized_ = true;
}