summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorHal Finkel <hfinkel@anl.gov>2014-02-28 00:26:56 +0000
committerHal Finkel <hfinkel@anl.gov>2014-02-28 00:26:56 +0000
commitc72cf87285d46a60c3f672f5a99f1d85f6074f30 (patch)
tree7b52d83e3a3b4f66d411133bae5ae647b04eaf6f /utils
parent1a13499abfe3575b0602bfb159824241c6beaf0a (diff)
downloadllvm-c72cf87285d46a60c3f672f5a99f1d85f6074f30.tar.gz
llvm-c72cf87285d46a60c3f672f5a99f1d85f6074f30.tar.bz2
llvm-c72cf87285d46a60c3f672f5a99f1d85f6074f30.tar.xz
Add an OutPatFrag TableGen class
Unfortunately, it is currently impossible to use a PatFrag as part of an output pattern (the part of the pattern that has instructions in it) in TableGen. Looking at the current implementation, this was clearly intended to work (there is already code in place to expand patterns in the output DAG), but is currently broken by the baked-in type-checking assumption and the order in which the pattern fragments are processed (output pattern fragments need to be processed after the instruction definitions are processed). Fixing this is fairly simple, but requires some way of differentiating output patterns from the existing input patterns. The simplest way to handle this seems to be to create a subclass of PatFrag, and so that's what I've done here. As a simple example, this allows us to write: def crnot : OutPatFrag<(ops node:$in), (CRNOR $in, $in)>; def : Pat<(not i1:$in), (crnot $in)>; which captures the core use case: handling of repeated subexpressions inside of complicated output patterns. This will be used by an upcoming commit to the PowerPC backend. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202450 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.cpp19
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.h2
2 files changed, 16 insertions, 5 deletions
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index 0433230095..f9f3caf126 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -1232,8 +1232,10 @@ SubstituteFormalArguments(std::map<std::string, TreePatternNode*> &ArgMap) {
TreePatternNode *Child = getChild(i);
if (Child->isLeaf()) {
Init *Val = Child->getLeafValue();
- if (isa<DefInit>(Val) &&
- cast<DefInit>(Val)->getDef()->getName() == "node") {
+ // Note that, when substituting into an output pattern, Val might be an
+ // UnsetInit.
+ if (isa<UnsetInit>(Val) || (isa<DefInit>(Val) &&
+ cast<DefInit>(Val)->getDef()->getName() == "node")) {
// We found a use of a formal argument, replace it with its value.
TreePatternNode *NewChild = ArgMap[Child->getName()];
assert(NewChild && "Couldn't find formal argument!");
@@ -2135,6 +2137,7 @@ CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R) :
ParsePatternFragments();
ParseDefaultOperands();
ParseInstructions();
+ ParsePatternFragments(/*OutFrags*/true);
ParsePatterns();
// Generate variants. For example, commutative patterns can match
@@ -2208,13 +2211,18 @@ void CodeGenDAGPatterns::ParseComplexPatterns() {
/// inline fragments together as necessary, so that there are no references left
/// inside a pattern fragment to a pattern fragment.
///
-void CodeGenDAGPatterns::ParsePatternFragments() {
+void CodeGenDAGPatterns::ParsePatternFragments(bool OutFrags) {
std::vector<Record*> Fragments = Records.getAllDerivedDefinitions("PatFrag");
// First step, parse all of the fragments.
for (unsigned i = 0, e = Fragments.size(); i != e; ++i) {
+ if (OutFrags != Fragments[i]->isSubClassOf("OutPatFrag"))
+ continue;
+
DagInit *Tree = Fragments[i]->getValueAsDag("Fragment");
- TreePattern *P = new TreePattern(Fragments[i], Tree, true, *this);
+ TreePattern *P =
+ new TreePattern(Fragments[i], Tree,
+ !Fragments[i]->isSubClassOf("OutPatFrag"), *this);
PatternFragments[Fragments[i]] = P;
// Validate the argument list, converting it to set, to discard duplicates.
@@ -2270,6 +2278,9 @@ void CodeGenDAGPatterns::ParsePatternFragments() {
// Now that we've parsed all of the tree fragments, do a closure on them so
// that there are not references to PatFrags left inside of them.
for (unsigned i = 0, e = Fragments.size(); i != e; ++i) {
+ if (OutFrags != Fragments[i]->isSubClassOf("OutPatFrag"))
+ continue;
+
TreePattern *ThePat = PatternFragments[Fragments[i]];
ThePat->InlinePatternFragments();
diff --git a/utils/TableGen/CodeGenDAGPatterns.h b/utils/TableGen/CodeGenDAGPatterns.h
index 0533bb8bb5..d9953297cb 100644
--- a/utils/TableGen/CodeGenDAGPatterns.h
+++ b/utils/TableGen/CodeGenDAGPatterns.h
@@ -809,7 +809,7 @@ private:
void ParseNodeInfo();
void ParseNodeTransforms();
void ParseComplexPatterns();
- void ParsePatternFragments();
+ void ParsePatternFragments(bool OutFrags = false);
void ParseDefaultOperands();
void ParseInstructions();
void ParsePatterns();