OS << ")";
}
- if (!PredicateFn.empty())
- OS << "<<P:" << PredicateFn << ">>";
+ for (unsigned i = 0, e = PredicateFns.size(); i != e; ++i)
+ OS << "<<P:" << PredicateFns[i] << ">>";
if (TransformFn)
OS << "<<X:" << TransformFn->getName() << ">>";
if (!getName().empty())
const MultipleUseVarSet &DepVars) const {
if (N == this) return true;
if (N->isLeaf() != isLeaf() || getExtTypes() != N->getExtTypes() ||
- getPredicateFn() != N->getPredicateFn() ||
+ getPredicateFns() != N->getPredicateFns() ||
getTransformFn() != N->getTransformFn())
return false;
}
New->setName(getName());
New->setTypes(getExtTypes());
- New->setPredicateFn(getPredicateFn());
+ New->setPredicateFns(getPredicateFns());
New->setTransformFn(getTransformFn());
return New;
}
if (dynamic_cast<DefInit*>(Val) &&
static_cast<DefInit*>(Val)->getDef()->getName() == "node") {
// We found a use of a formal argument, replace it with its value.
- Child = ArgMap[Child->getName()];
- assert(Child && "Couldn't find formal argument!");
- setChild(i, Child);
+ TreePatternNode *NewChild = ArgMap[Child->getName()];
+ assert(NewChild && "Couldn't find formal argument!");
+ assert((Child->getPredicateFns().empty() ||
+ NewChild->getPredicateFns() == Child->getPredicateFns()) &&
+ "Non-empty child predicate clobbered!");
+ setChild(i, NewChild);
}
} else {
getChild(i)->SubstituteFormalArguments(ArgMap);
if (!Op->isSubClassOf("PatFrag")) {
// Just recursively inline children nodes.
- for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
- setChild(i, getChild(i)->InlinePatternFragments(TP));
+ for (unsigned i = 0, e = getNumChildren(); i != e; ++i) {
+ TreePatternNode *Child = getChild(i);
+ TreePatternNode *NewChild = Child->InlinePatternFragments(TP);
+
+ assert((Child->getPredicateFns().empty() ||
+ NewChild->getPredicateFns() == Child->getPredicateFns()) &&
+ "Non-empty child predicate clobbered!");
+
+ setChild(i, NewChild);
+ }
return this;
}
TreePatternNode *FragTree = Frag->getOnlyTree()->clone();
+ std::string Code = Op->getValueAsCode("Predicate");
+ if (!Code.empty())
+ FragTree->addPredicateFn("Predicate_"+Op->getName());
+
// Resolve formal arguments to their actual value.
if (Frag->getNumArgs()) {
// Compute the map of formal to actual arguments.
FragTree->setName(getName());
FragTree->UpdateNodeType(getExtTypes(), TP);
-
+
+ // Transfer in the old predicates.
+ for (unsigned i = 0, e = getPredicateFns().size(); i != e; ++i)
+ FragTree->addPredicateFn(getPredicateFns()[i]);
+
// Get a new copy of this fragment to stitch into here.
//delete this; // FIXME: implement refcounting!
// this fragment uses it.
std::string Code = Fragments[i]->getValueAsCode("Predicate");
if (!Code.empty())
- P->getOnlyTree()->setPredicateFn("Predicate_"+Fragments[i]->getName());
+ P->getOnlyTree()->addPredicateFn("Predicate_"+Fragments[i]->getName());
// If there is a node transformation corresponding to this, keep track of
// it.
TreePatternNode *OpNode = InVal->clone();
// No predicate is useful on the result.
- OpNode->setPredicateFn("");
+ OpNode->clearPredicateFns();
// Promote the xform function to be an explicit node if set.
if (Record *Xform = OpNode->getTransformFn()) {
// Copy over properties.
R->setName(Orig->getName());
- R->setPredicateFn(Orig->getPredicateFn());
+ R->setPredicateFns(Orig->getPredicateFns());
R->setTransformFn(Orig->getTransformFn());
R->setTypes(Orig->getExtTypes());
Record *Operator = N->getOperator();
// Only permit raw nodes.
- if (!N->getName().empty() || !N->getPredicateFn().empty() ||
+ if (!N->getName().empty() || !N->getPredicateFns().empty() ||
N->getTransformFn()) {
Children.push_back(N);
return;
// If this node has some predicate function that must match, it adds to the
// complexity of this node.
- if (!P->getPredicateFn().empty())
+ if (!P->getPredicateFns().empty())
++Size;
// Count children in the count if they are also nodes.
Size += 5; // Matches a ConstantSDNode (+3) and a specific value (+2).
else if (NodeIsComplexPattern(Child))
Size += getPatternSize(Child, CGP);
- else if (!Child->getPredicateFn().empty())
+ else if (!Child->getPredicateFns().empty())
++Size;
}
}
PatternSortingPredicate(CodeGenDAGPatterns &cgp) : CGP(cgp) {}
CodeGenDAGPatterns &CGP;
- bool operator()(const PatternToMatch *LHS,
- const PatternToMatch *RHS) {
+ typedef std::pair<unsigned, std::string> CodeLine;
+ typedef std::vector<CodeLine> CodeList;
+ typedef std::vector<std::pair<const PatternToMatch*, CodeList> > PatternList;
+
+ bool operator()(const std::pair<const PatternToMatch*, CodeList> &LHSPair,
+ const std::pair<const PatternToMatch*, CodeList> &RHSPair) {
+ const PatternToMatch *LHS = LHSPair.first;
+ const PatternToMatch *RHS = RHSPair.first;
+
unsigned LHSSize = getPatternSize(LHS->getSrcPattern(), CGP);
unsigned RHSSize = getPatternSize(RHS->getSrcPattern(), CGP);
LHSSize += LHS->getAddedComplexity();
}
}
- // If there is a node predicate for this, emit the call.
- if (!N->getPredicateFn().empty())
- emitCheck(N->getPredicateFn() + "(" + RootName + ".getNode())");
+ // If there are node predicates for this, emit the calls.
+ for (unsigned i = 0, e = N->getPredicateFns().size(); i != e; ++i)
+ emitCheck(N->getPredicateFns()[i] + "(" + RootName + ".getNode())");
-
// If this is an 'and R, 1234' where the operation is AND/OR and the RHS is
// a constant without a predicate fn that has more that one bit set, handle
// this as a special case. This is usually for targets that have special
(N->getOperator()->getName() == "and" ||
N->getOperator()->getName() == "or") &&
N->getChild(1)->isLeaf() &&
- N->getChild(1)->getPredicateFn().empty()) {
+ N->getChild(1)->getPredicateFns().empty()) {
if (IntInit *II = dynamic_cast<IntInit*>(N->getChild(1)->getLeafValue())) {
if (!isPowerOf2_32(II->getValue())) { // Don't bother with single bits.
emitInit("SDValue " + RootName + "0" + " = " +
assert(0 && "Unknown leaf type!");
}
- // If there is a node predicate for this, emit the call.
- if (!Child->getPredicateFn().empty())
- emitCheck(Child->getPredicateFn() + "(" + RootName +
+ // If there are node predicates for this, emit the calls.
+ for (unsigned i = 0, e = Child->getPredicateFns().size(); i != e; ++i)
+ emitCheck(Child->getPredicateFns()[i] + "(" + RootName +
".getNode())");
} else if (IntInit *II =
dynamic_cast<IntInit*>(Child->getLeafValue())) {
emitCode(After[i]);
return NodeOps;
- } else if (Op->isSubClassOf("SDNodeXForm")) {
+ }
+ if (Op->isSubClassOf("SDNodeXForm")) {
assert(N->getNumChildren() == 1 && "node xform should have one child!");
// PatLeaf node - the operand may or may not be a leaf node. But it should
// behave like one.
if (isRoot)
emitCode("return Tmp" + utostr(ResNo) + ".getNode();");
return NodeOps;
- } else {
- N->dump();
- cerr << "\n";
- throw std::string("Unknown node in result pattern!");
}
+
+ N->dump();
+ cerr << "\n";
+ throw std::string("Unknown node in result pattern!");
}
/// InsertOneTypeCheck - Insert a type-check for an unresolved type in 'Pat'
std::vector<const PatternToMatch*> &PatternsOfOp = PBOI->second;
assert(!PatternsOfOp.empty() && "No patterns but map has entry?");
- // We want to emit all of the matching code now. However, we want to emit
- // the matches in order of minimal cost. Sort the patterns so the least
- // cost one is at the start.
- std::stable_sort(PatternsOfOp.begin(), PatternsOfOp.end(),
- PatternSortingPredicate(CGP));
-
// Split them into groups by type.
std::map<MVT::SimpleValueType,
std::vector<const PatternToMatch*> > PatternsByType;
++II) {
MVT::SimpleValueType OpVT = II->first;
std::vector<const PatternToMatch*> &Patterns = II->second;
- typedef std::vector<std::pair<unsigned,std::string> > CodeList;
- typedef std::vector<std::pair<unsigned,std::string> >::iterator CodeListI;
+ typedef std::pair<unsigned, std::string> CodeLine;
+ typedef std::vector<CodeLine> CodeList;
+ typedef CodeList::iterator CodeListI;
std::vector<std::pair<const PatternToMatch*, CodeList> > CodeForPatterns;
std::vector<std::vector<std::string> > PatternOpcodes;
NumInputRootOpsCounts.push_back(NumInputRootOps);
}
- // Scan the code to see if all of the patterns are reachable and if it is
- // possible that the last one might not match.
- bool mightNotMatch = true;
- for (unsigned i = 0, e = CodeForPatterns.size(); i != e; ++i) {
- CodeList &GeneratedCode = CodeForPatterns[i].second;
- mightNotMatch = false;
-
- for (unsigned j = 0, e = GeneratedCode.size(); j != e; ++j) {
- if (GeneratedCode[j].first == 1) { // predicate.
- mightNotMatch = true;
- break;
- }
- }
-
- // If this pattern definitely matches, and if it isn't the last one, the
- // patterns after it CANNOT ever match. Error out.
- if (mightNotMatch == false && i != CodeForPatterns.size()-1) {
- cerr << "Pattern '";
- CodeForPatterns[i].first->getSrcPattern()->print(*cerr.stream());
- cerr << "' is impossible to select!\n";
- exit(1);
- }
- }
-
// Factor target node emission code (emitted by EmitResultCode) into
// separate functions. Uniquing and share them among all instruction
// selection routines.
OS << "SDNode *Select_" << getLegalCName(OpName)
<< OpVTStr << "(const SDValue &N) {\n";
+ // We want to emit all of the matching code now. However, we want to emit
+ // the matches in order of minimal cost. Sort the patterns so the least
+ // cost one is at the start.
+ std::stable_sort(CodeForPatterns.begin(), CodeForPatterns.end(),
+ PatternSortingPredicate(CGP));
+
+ // Scan the code to see if all of the patterns are reachable and if it is
+ // possible that the last one might not match.
+ bool mightNotMatch = true;
+ for (unsigned i = 0, e = CodeForPatterns.size(); i != e; ++i) {
+ CodeList &GeneratedCode = CodeForPatterns[i].second;
+ mightNotMatch = false;
+
+ for (unsigned j = 0, e = GeneratedCode.size(); j != e; ++j) {
+ if (GeneratedCode[j].first == 1) { // predicate.
+ mightNotMatch = true;
+ break;
+ }
+ }
+
+ // If this pattern definitely matches, and if it isn't the last one, the
+ // patterns after it CANNOT ever match. Error out.
+ if (mightNotMatch == false && i != CodeForPatterns.size()-1) {
+ cerr << "Pattern '";
+ CodeForPatterns[i].first->getSrcPattern()->print(*cerr.stream());
+ cerr << "' is impossible to select!\n";
+ exit(1);
+ }
+ }
+
// Loop through and reverse all of the CodeList vectors, as we will be
// accessing them from their logical front, but accessing the end of a
// vector is more efficient.