}
}
+//===----------------------------------------------------------------------===//
+// PatternToMatch implementation
+//
+
+/// getPredicateCheck - Return a single string containing all of this
+/// pattern's predicates concatenated with "&&" operators.
+///
+std::string PatternToMatch::getPredicateCheck() const {
+ std::string PredicateCheck;
+ for (unsigned i = 0, e = Predicates->getSize(); i != e; ++i) {
+ if (DefInit *Pred = dynamic_cast<DefInit*>(Predicates->getElement(i))) {
+ Record *Def = Pred->getDef();
+ if (!Def->isSubClassOf("Predicate")) {
+#ifndef NDEBUG
+ Def->dump();
+#endif
+ assert(0 && "Unknown predicate type!");
+ }
+ if (!PredicateCheck.empty())
+ PredicateCheck += " && ";
+ PredicateCheck += "(" + Def->getValueAsString("CondString") + ")";
+ }
+ }
+
+ return PredicateCheck;
+}
+
//===----------------------------------------------------------------------===//
// SDTypeConstraint implementation
//
return true;
}
- if (getExtTypeNum(0) == MVT::iPTR) {
- if (ExtVTs[0] == MVT::iPTR || ExtVTs[0] == EMVT::isInt)
+ if (getExtTypeNum(0) == MVT::iPTR || getExtTypeNum(0) == MVT::iPTRAny) {
+ if (ExtVTs[0] == MVT::iPTR || ExtVTs[0] == MVT::iPTRAny ||
+ ExtVTs[0] == EMVT::isInt)
return false;
if (EMVT::isExtIntegerInVTs(ExtVTs)) {
std::vector<unsigned char> FVTs = FilterEVTs(ExtVTs, isInteger);
setTypes(FVTs);
return true;
}
- if (ExtVTs[0] == MVT::iPTR && EMVT::isExtIntegerInVTs(getExtTypes())) {
+ if ((ExtVTs[0] == MVT::iPTR || ExtVTs[0] == MVT::iPTRAny) &&
+ EMVT::isExtIntegerInVTs(getExtTypes())) {
//assert(hasTypeSet() && "should be handled above!");
std::vector<unsigned char> FVTs = FilterEVTs(getExtTypes(), isInteger);
if (getExtTypes() == FVTs)
setTypes(ExtVTs);
return true;
}
- if (getExtTypeNum(0) == EMVT::isInt && ExtVTs[0] == MVT::iPTR) {
+ if (getExtTypeNum(0) == EMVT::isInt &&
+ (ExtVTs[0] == MVT::iPTR || ExtVTs[0] == MVT::iPTRAny)) {
setTypes(ExtVTs);
return true;
}
case EMVT::isFP : OS << ":isFP"; break;
case EMVT::isUnknown: ; /*OS << ":?";*/ break;
case MVT::iPTR: OS << ":iPTR"; break;
+ case MVT::iPTRAny: OS << ":iPTRAny"; break;
default: {
std::string VTName = llvm::getName(getTypeNum(0));
// Strip off MVT:: prefix if present.
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!
- return FragTree;
+
+ // The fragment we inlined could have recursive inlining that is needed. See
+ // if there are any pattern fragments in it and inline them as needed.
+ return FragTree->InlinePatternFragments(TP);
}
/// getImplicitType - Check to see if the specified record has an implicit
}
-/// ApplyTypeConstraints - Apply all of the type constraints relevent to
+/// ApplyTypeConstraints - Apply all of the type constraints relevant to
/// this node and its children in the tree. This returns true if it makes a
/// change, false otherwise. If a type contradiction is found, throw an
/// exception.
assert(getTypeNum(i) == VT && "TreePattern has too many types!");
VT = getTypeNum(0);
- if (VT != MVT::iPTR) {
+ if (VT != MVT::iPTR && VT != MVT::iPTRAny) {
unsigned Size = MVT(VT).getSizeInBits();
// Make sure that the value is representable for this type.
if (Size < 32) {
bool MadeChange = false;
// Apply the result type to the node.
- MadeChange = UpdateNodeType(Int->ArgVTs[0], TP);
+ unsigned NumRetVTs = Int->IS.RetVTs.size();
+ unsigned NumParamVTs = Int->IS.ParamVTs.size();
- if (getNumChildren() != Int->ArgVTs.size())
+ for (unsigned i = 0, e = NumRetVTs; i != e; ++i)
+ MadeChange |= UpdateNodeType(Int->IS.RetVTs[i], TP);
+
+ if (getNumChildren() != NumParamVTs + NumRetVTs)
TP.error("Intrinsic '" + Int->Name + "' expects " +
- utostr(Int->ArgVTs.size()-1) + " operands, not " +
- utostr(getNumChildren()-1) + " operands!");
+ utostr(NumParamVTs + NumRetVTs - 1) + " operands, not " +
+ utostr(getNumChildren() - 1) + " operands!");
// Apply type info to the intrinsic ID.
MadeChange |= getChild(0)->UpdateNodeType(MVT::iPTR, TP);
- for (unsigned i = 1, e = getNumChildren(); i != e; ++i) {
- MVT::SimpleValueType OpVT = Int->ArgVTs[i];
+ for (unsigned i = NumRetVTs, e = getNumChildren(); i != e; ++i) {
+ MVT::SimpleValueType OpVT = Int->IS.ParamVTs[i - NumRetVTs];
MadeChange |= getChild(i)->UpdateNodeType(OpVT, TP);
MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
}
// If this intrinsic returns void, it must have side-effects and thus a
// chain.
- if (Int.ArgVTs[0] == MVT::isVoid) {
+ if (Int.IS.RetVTs[0] == MVT::isVoid) {
Operator = getDAGPatterns().get_intrinsic_void_sdnode();
} else if (Int.ModRef != CodeGenIntrinsic::NoMem) {
// Has side-effects, requires chain.
// 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.
// 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 (std::map<Record*, TreePattern*>::iterator I = PatternFragments.begin(),
- E = PatternFragments.end(); I != E; ++I) {
- TreePattern *ThePat = I->second;
+ for (unsigned i = 0, e = Fragments.size(); i != e; ++i) {
+ TreePattern *ThePat = PatternFragments[Fragments[i]];
ThePat->InlinePatternFragments();
// Infer as many types as possible. Don't worry about it if we don't infer
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;