diff options
author | Jim Grosbach <grosbach@apple.com> | 2012-07-17 00:47:06 +0000 |
---|---|---|
committer | Jim Grosbach <grosbach@apple.com> | 2012-07-17 00:47:06 +0000 |
commit | ac915b48d8ba73a5d734be5c4a0e1d25cea93252 (patch) | |
tree | 063d21fed58fe8b3515fc4f0b5bebcbc65f4d005 /utils/TableGen | |
parent | 1bda7863e37180d5c371bab58ceaab0bd8c290d1 (diff) | |
download | external_llvm-ac915b48d8ba73a5d734be5c4a0e1d25cea93252.zip external_llvm-ac915b48d8ba73a5d734be5c4a0e1d25cea93252.tar.gz external_llvm-ac915b48d8ba73a5d734be5c4a0e1d25cea93252.tar.bz2 |
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.cpp | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index d4b02fb..09c00dd 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; |