summaryrefslogtreecommitdiff
path: root/utils/TableGen
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2012-07-17 00:47:06 +0000
committerJim Grosbach <grosbach@apple.com>2012-07-17 00:47:06 +0000
commitac915b48d8ba73a5d734be5c4a0e1d25cea93252 (patch)
tree063d21fed58fe8b3515fc4f0b5bebcbc65f4d005 /utils/TableGen
parent1bda7863e37180d5c371bab58ceaab0bd8c290d1 (diff)
downloadllvm-ac915b48d8ba73a5d734be5c4a0e1d25cea93252.tar.gz
llvm-ac915b48d8ba73a5d734be5c4a0e1d25cea93252.tar.bz2
llvm-ac915b48d8ba73a5d734be5c4a0e1d25cea93252.tar.xz
TableGen: Allow conditional instruction pattern in multiclass.
Define a 'null_frag' SDPatternOperator node, which if referenced in an instruction Pattern, results in the pattern being collapsed to be as-if '[]' had been specified instead. This allows supporting a multiclass definition where some instaniations have ISel patterns associated and others do not. For example, multiclass myMulti<RegisterClass rc, SDPatternOperator OpNode = null_frag> { def _x : myI<(outs rc:), (ins rc:), []>; def _r : myI<(outs rc:), (ins rc:), [(set rc:, (OpNode rc:))]>; } defm foo : myMulti<GRa, not>; defm bar : myMulti<GRb>; git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@160333 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils/TableGen')
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.cpp38
1 files changed, 36 insertions, 2 deletions
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index d4b02fbd2f..09c00dd4f7 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -2520,6 +2520,37 @@ static void InferFromPattern(const CodeGenInstruction &Inst,
IsVariadic = true; // Can warn if we want.
}
+/// hasNullFragReference - Return true if the DAG has any reference to the
+/// null_frag operator.
+static bool hasNullFragReference(DagInit *DI) {
+ DefInit *OpDef = dynamic_cast<DefInit*>(DI->getOperator());
+ if (!OpDef) return false;
+ Record *Operator = OpDef->getDef();
+
+ // If this is the null fragment, return true.
+ if (Operator->getName() == "null_frag") return true;
+ // If any of the arguments reference the null fragment, return true.
+ for (unsigned i = 0, e = DI->getNumArgs(); i != e; ++i) {
+ DagInit *Arg = dynamic_cast<DagInit*>(DI->getArg(i));
+ if (Arg && hasNullFragReference(Arg))
+ return true;
+ }
+
+ return false;
+}
+
+/// hasNullFragReference - Return true if any DAG in the list references
+/// the null_frag operator.
+static bool hasNullFragReference(ListInit *LI) {
+ for (unsigned i = 0, e = LI->getSize(); i != e; ++i) {
+ DagInit *DI = dynamic_cast<DagInit*>(LI->getElement(i));
+ assert(DI && "non-dag in an instruction Pattern list?!");
+ if (hasNullFragReference(DI))
+ return true;
+ }
+ return false;
+}
+
/// ParseInstructions - Parse all of the instructions, inlining and resolving
/// any fragments involved. This populates the Instructions list with fully
/// resolved instructions.
@@ -2534,8 +2565,11 @@ void CodeGenDAGPatterns::ParseInstructions() {
// If there is no pattern, only collect minimal information about the
// instruction for its operand list. We have to assume that there is one
- // result, as we have no detailed info.
- if (!LI || LI->getSize() == 0) {
+ // result, as we have no detailed info. A pattern which references the
+ // null_frag operator is as-if no pattern were specified. Normally this
+ // is from a multiclass expansion w/ a SDPatternOperator passed in as
+ // null_frag.
+ if (!LI || LI->getSize() == 0 || hasNullFragReference(LI)) {
std::vector<Record*> Results;
std::vector<Record*> Operands;