/// FilterVTs - Filter a list of VT's according to a predicate.
///
template<typename T>
-static std::vector<MVT::ValueType>
-FilterVTs(const std::vector<MVT::ValueType> &InVTs, T Filter) {
- std::vector<MVT::ValueType> Result;
+static std::vector<MVT::SimpleValueType>
+FilterVTs(const std::vector<MVT::SimpleValueType> &InVTs, T Filter) {
+ std::vector<MVT::SimpleValueType> Result;
for (unsigned i = 0, e = InVTs.size(); i != e; ++i)
if (Filter(InVTs[i]))
Result.push_back(InVTs[i]);
FilterEVTs(const std::vector<unsigned char> &InVTs, T Filter) {
std::vector<unsigned char> Result;
for (unsigned i = 0, e = InVTs.size(); i != e; ++i)
- if (Filter((MVT::ValueType)InVTs[i]))
+ if (Filter((MVT::SimpleValueType)InVTs[i]))
Result.push_back(InVTs[i]);
return Result;
}
static std::vector<unsigned char>
-ConvertVTs(const std::vector<MVT::ValueType> &InVTs) {
+ConvertVTs(const std::vector<MVT::SimpleValueType> &InVTs) {
std::vector<unsigned char> Result;
for (unsigned i = 0, e = InVTs.size(); i != e; ++i)
Result.push_back(InVTs[i]);
return Result;
}
+static inline bool isInteger(MVT::SimpleValueType VT) {
+ return MVT(VT).isInteger();
+}
+
+static inline bool isFloatingPoint(MVT::SimpleValueType VT) {
+ return MVT(VT).isFloatingPoint();
+}
+
+static inline bool isVector(MVT::SimpleValueType VT) {
+ return MVT(VT).isVector();
+}
+
static bool LHSIsSubsetOfRHS(const std::vector<unsigned char> &LHS,
const std::vector<unsigned char> &RHS) {
if (LHS.size() > RHS.size()) return false;
/// isExtIntegerVT - Return true if the specified extended value type vector
/// contains isInt or an integer value type.
namespace llvm {
-namespace MVT {
+namespace EMVT {
bool isExtIntegerInVTs(const std::vector<unsigned char> &EVTs) {
assert(!EVTs.empty() && "Cannot check for integer in empty ExtVT list!");
return EVTs[0] == isInt || !(FilterEVTs(EVTs, isInteger).empty());
assert(!EVTs.empty() && "Cannot check for integer in empty ExtVT list!");
return EVTs[0] == isFP || !(FilterEVTs(EVTs, isFloatingPoint).empty());
}
-} // end namespace MVT.
+} // end namespace EMVT.
} // end namespace llvm.
}
}
+//===----------------------------------------------------------------------===//
+// 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
//
}
case SDTCisInt: {
// If there is only one integer type supported, this must be it.
- std::vector<MVT::ValueType> IntVTs =
- FilterVTs(CGT.getLegalValueTypes(), MVT::isInteger);
+ std::vector<MVT::SimpleValueType> IntVTs =
+ FilterVTs(CGT.getLegalValueTypes(), isInteger);
// If we found exactly one supported integer type, apply it.
if (IntVTs.size() == 1)
return NodeToApply->UpdateNodeType(IntVTs[0], TP);
- return NodeToApply->UpdateNodeType(MVT::isInt, TP);
+ return NodeToApply->UpdateNodeType(EMVT::isInt, TP);
}
case SDTCisFP: {
// If there is only one FP type supported, this must be it.
- std::vector<MVT::ValueType> FPVTs =
- FilterVTs(CGT.getLegalValueTypes(), MVT::isFloatingPoint);
+ std::vector<MVT::SimpleValueType> FPVTs =
+ FilterVTs(CGT.getLegalValueTypes(), isFloatingPoint);
// If we found exactly one supported FP type, apply it.
if (FPVTs.size() == 1)
return NodeToApply->UpdateNodeType(FPVTs[0], TP);
- return NodeToApply->UpdateNodeType(MVT::isFP, TP);
+ return NodeToApply->UpdateNodeType(EMVT::isFP, TP);
}
case SDTCisSameAs: {
TreePatternNode *OtherNode =
!static_cast<DefInit*>(NodeToApply->getLeafValue())->getDef()
->isSubClassOf("ValueType"))
TP.error(N->getOperator()->getName() + " expects a VT operand!");
- MVT::ValueType VT =
+ MVT::SimpleValueType VT =
getValueType(static_cast<DefInit*>(NodeToApply->getLeafValue())->getDef());
- if (!MVT::isInteger(VT))
+ if (!isInteger(VT))
TP.error(N->getOperator()->getName() + " VT operand must be integer!");
TreePatternNode *OtherNode =
// It must be integer.
bool MadeChange = false;
- MadeChange |= OtherNode->UpdateNodeType(MVT::isInt, TP);
+ MadeChange |= OtherNode->UpdateNodeType(EMVT::isInt, TP);
// This code only handles nodes that have one type set. Assert here so
// that we can change this if we ever need to deal with multiple value
// This code does not currently handle nodes which have multiple types,
// where some types are integer, and some are fp. Assert that this is not
// the case.
- assert(!(MVT::isExtIntegerInVTs(NodeToApply->getExtTypes()) &&
- MVT::isExtFloatingPointInVTs(NodeToApply->getExtTypes())) &&
- !(MVT::isExtIntegerInVTs(BigOperand->getExtTypes()) &&
- MVT::isExtFloatingPointInVTs(BigOperand->getExtTypes())) &&
+ assert(!(EMVT::isExtIntegerInVTs(NodeToApply->getExtTypes()) &&
+ EMVT::isExtFloatingPointInVTs(NodeToApply->getExtTypes())) &&
+ !(EMVT::isExtIntegerInVTs(BigOperand->getExtTypes()) &&
+ EMVT::isExtFloatingPointInVTs(BigOperand->getExtTypes())) &&
"SDTCisOpSmallerThanOp does not handle mixed int/fp types!");
- if (MVT::isExtIntegerInVTs(NodeToApply->getExtTypes()))
- MadeChange |= BigOperand->UpdateNodeType(MVT::isInt, TP);
- else if (MVT::isExtFloatingPointInVTs(NodeToApply->getExtTypes()))
- MadeChange |= BigOperand->UpdateNodeType(MVT::isFP, TP);
- if (MVT::isExtIntegerInVTs(BigOperand->getExtTypes()))
- MadeChange |= NodeToApply->UpdateNodeType(MVT::isInt, TP);
- else if (MVT::isExtFloatingPointInVTs(BigOperand->getExtTypes()))
- MadeChange |= NodeToApply->UpdateNodeType(MVT::isFP, TP);
-
- std::vector<MVT::ValueType> VTs = CGT.getLegalValueTypes();
-
- if (MVT::isExtIntegerInVTs(NodeToApply->getExtTypes())) {
- VTs = FilterVTs(VTs, MVT::isInteger);
- } else if (MVT::isExtFloatingPointInVTs(NodeToApply->getExtTypes())) {
- VTs = FilterVTs(VTs, MVT::isFloatingPoint);
+ if (EMVT::isExtIntegerInVTs(NodeToApply->getExtTypes()))
+ MadeChange |= BigOperand->UpdateNodeType(EMVT::isInt, TP);
+ else if (EMVT::isExtFloatingPointInVTs(NodeToApply->getExtTypes()))
+ MadeChange |= BigOperand->UpdateNodeType(EMVT::isFP, TP);
+ if (EMVT::isExtIntegerInVTs(BigOperand->getExtTypes()))
+ MadeChange |= NodeToApply->UpdateNodeType(EMVT::isInt, TP);
+ else if (EMVT::isExtFloatingPointInVTs(BigOperand->getExtTypes()))
+ MadeChange |= NodeToApply->UpdateNodeType(EMVT::isFP, TP);
+
+ std::vector<MVT::SimpleValueType> VTs = CGT.getLegalValueTypes();
+
+ if (EMVT::isExtIntegerInVTs(NodeToApply->getExtTypes())) {
+ VTs = FilterVTs(VTs, isInteger);
+ } else if (EMVT::isExtFloatingPointInVTs(NodeToApply->getExtTypes())) {
+ VTs = FilterVTs(VTs, isFloatingPoint);
} else {
VTs.clear();
}
getOperandNum(x.SDTCisIntVectorOfSameSize_Info.OtherOperandNum,
N, NumResults);
if (OtherOperand->hasTypeSet()) {
- if (!MVT::isVector(OtherOperand->getTypeNum(0)))
+ if (!isVector(OtherOperand->getTypeNum(0)))
TP.error(N->getOperator()->getName() + " VT operand must be a vector!");
- MVT::ValueType IVT = OtherOperand->getTypeNum(0);
- IVT = MVT::getIntVectorWithNumElements(MVT::getVectorNumElements(IVT));
- return NodeToApply->UpdateNodeType(IVT, TP);
+ MVT IVT = OtherOperand->getTypeNum(0);
+ unsigned NumElements = IVT.getVectorNumElements();
+ IVT = MVT::getIntVectorWithNumElements(NumElements);
+ return NodeToApply->UpdateNodeType(IVT.getSimpleVT(), TP);
}
return false;
}
getOperandNum(x.SDTCisIntVectorOfSameSize_Info.OtherOperandNum,
N, NumResults);
if (OtherOperand->hasTypeSet()) {
- if (!MVT::isVector(OtherOperand->getTypeNum(0)))
+ if (!isVector(OtherOperand->getTypeNum(0)))
TP.error(N->getOperator()->getName() + " VT operand must be a vector!");
- MVT::ValueType IVT = OtherOperand->getTypeNum(0);
- IVT = MVT::getVectorElementType(IVT);
- return NodeToApply->UpdateNodeType(IVT, TP);
+ MVT IVT = OtherOperand->getTypeNum(0);
+ IVT = IVT.getVectorElementType();
+ return NodeToApply->UpdateNodeType(IVT.getSimpleVT(), TP);
}
return false;
}
Properties |= 1 << SDNPMayLoad;
} else if (PropList[i]->getName() == "SDNPSideEffect") {
Properties |= 1 << SDNPSideEffect;
+ } else if (PropList[i]->getName() == "SDNPMemOperand") {
+ Properties |= 1 << SDNPMemOperand;
} else {
cerr << "Unknown SD Node property '" << PropList[i]->getName()
<< "' on node '" << R->getName() << "'!\n";
TreePattern &TP) {
assert(!ExtVTs.empty() && "Cannot update node type with empty type vector!");
- if (ExtVTs[0] == MVT::isUnknown || LHSIsSubsetOfRHS(getExtTypes(), ExtVTs))
+ if (ExtVTs[0] == EMVT::isUnknown || LHSIsSubsetOfRHS(getExtTypes(), ExtVTs))
return false;
if (isTypeCompletelyUnknown() || LHSIsSubsetOfRHS(ExtVTs, getExtTypes())) {
setTypes(ExtVTs);
return true;
}
- if (getExtTypeNum(0) == MVT::iPTR) {
- if (ExtVTs[0] == MVT::iPTR || ExtVTs[0] == MVT::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 (MVT::isExtIntegerInVTs(ExtVTs)) {
- std::vector<unsigned char> FVTs = FilterEVTs(ExtVTs, MVT::isInteger);
+ if (EMVT::isExtIntegerInVTs(ExtVTs)) {
+ std::vector<unsigned char> FVTs = FilterEVTs(ExtVTs, isInteger);
if (FVTs.size()) {
setTypes(ExtVTs);
return true;
}
}
}
-
- if (ExtVTs[0] == MVT::isInt && MVT::isExtIntegerInVTs(getExtTypes())) {
+
+ if ((ExtVTs[0] == EMVT::isInt || ExtVTs[0] == MVT::iAny) &&
+ EMVT::isExtIntegerInVTs(getExtTypes())) {
assert(hasTypeSet() && "should be handled above!");
- std::vector<unsigned char> FVTs = FilterEVTs(getExtTypes(), MVT::isInteger);
+ std::vector<unsigned char> FVTs = FilterEVTs(getExtTypes(), isInteger);
if (getExtTypes() == FVTs)
return false;
setTypes(FVTs);
return true;
}
- if (ExtVTs[0] == MVT::iPTR && MVT::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(), MVT::isInteger);
+ std::vector<unsigned char> FVTs = FilterEVTs(getExtTypes(), isInteger);
if (getExtTypes() == FVTs)
return false;
if (FVTs.size()) {
return true;
}
}
- if (ExtVTs[0] == MVT::isFP && MVT::isExtFloatingPointInVTs(getExtTypes())) {
+ if ((ExtVTs[0] == EMVT::isFP || ExtVTs[0] == MVT::fAny) &&
+ EMVT::isExtFloatingPointInVTs(getExtTypes())) {
assert(hasTypeSet() && "should be handled above!");
std::vector<unsigned char> FVTs =
- FilterEVTs(getExtTypes(), MVT::isFloatingPoint);
+ FilterEVTs(getExtTypes(), isFloatingPoint);
if (getExtTypes() == FVTs)
return false;
setTypes(FVTs);
//
// Similarly, we should probably set the type here to the intersection of
// {isInt|isFP} and ExtVTs
- if ((getExtTypeNum(0) == MVT::isInt && MVT::isExtIntegerInVTs(ExtVTs)) ||
- (getExtTypeNum(0) == MVT::isFP && MVT::isExtFloatingPointInVTs(ExtVTs))){
+ if (((getExtTypeNum(0) == EMVT::isInt || getExtTypeNum(0) == MVT::iAny) &&
+ EMVT::isExtIntegerInVTs(ExtVTs)) ||
+ ((getExtTypeNum(0) == EMVT::isFP || getExtTypeNum(0) == MVT::fAny) &&
+ EMVT::isExtFloatingPointInVTs(ExtVTs))) {
setTypes(ExtVTs);
return true;
}
- if (getExtTypeNum(0) == MVT::isInt && ExtVTs[0] == MVT::iPTR) {
+ if (getExtTypeNum(0) == EMVT::isInt &&
+ (ExtVTs[0] == MVT::iPTR || ExtVTs[0] == MVT::iPTRAny)) {
setTypes(ExtVTs);
return true;
}
// nodes that are multiply typed.
switch (getExtTypeNum(0)) {
case MVT::Other: OS << ":Other"; break;
- case MVT::isInt: OS << ":isInt"; break;
- case MVT::isFP : OS << ":isFP"; break;
- case MVT::isUnknown: ; /*OS << ":?";*/ break;
+ case EMVT::isInt: OS << ":isInt"; break;
+ 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
static std::vector<unsigned char> getImplicitType(Record *R, bool NotRegisters,
TreePattern &TP) {
// Some common return values
- std::vector<unsigned char> Unknown(1, MVT::isUnknown);
+ std::vector<unsigned char> Unknown(1, EMVT::isUnknown);
std::vector<unsigned char> Other(1, MVT::Other);
// Check to see if this is a register or a register class...
return &CDP.getIntrinsicInfo(IID);
}
+/// isCommutativeIntrinsic - Return true if the node corresponds to a
+/// commutative intrinsic.
+bool
+TreePatternNode::isCommutativeIntrinsic(const CodeGenDAGPatterns &CDP) const {
+ if (const CodeGenIntrinsic *Int = getIntrinsicInfo(CDP))
+ return Int->isCommutative;
+ return false;
+}
-/// 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.
return UpdateNodeType(getImplicitType(DI->getDef(), NotRegisters, TP),TP);
} else if (IntInit *II = dynamic_cast<IntInit*>(getLeafValue())) {
// Int inits are always integers. :)
- bool MadeChange = UpdateNodeType(MVT::isInt, TP);
+ bool MadeChange = UpdateNodeType(EMVT::isInt, TP);
if (hasTypeSet()) {
// At some point, it may make sense for this tree pattern to have
// multiple types. Assert here that it does not, so we revisit this
// code when appropriate.
assert(getExtTypes().size() >= 1 && "TreePattern doesn't have a type!");
- MVT::ValueType VT = getTypeNum(0);
+ MVT::SimpleValueType VT = getTypeNum(0);
for (unsigned i = 1, e = getExtTypes().size(); i != e; ++i)
assert(getTypeNum(i) == VT && "TreePattern has too many types!");
VT = getTypeNum(0);
- if (VT != MVT::iPTR) {
- unsigned Size = MVT::getSizeInBits(VT);
+ 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) {
int Val = (II->getValue() << (32-Size)) >> (32-Size);
if (Val != II->getValue()) {
// If sign-extended doesn't fit, does it fit as unsigned?
- unsigned ValueMask = unsigned(MVT::getIntVTBitMask(VT));
- unsigned UnsignedVal = unsigned(II->getValue());
+ unsigned ValueMask;
+ unsigned UnsignedVal;
+ ValueMask = unsigned(~uint32_t(0UL) >> (32-Size));
+ UnsignedVal = unsigned(II->getValue());
if ((ValueMask & UnsignedVal) != UnsignedVal) {
TP.error("Integer value '" + itostr(II->getValue())+
return MadeChange;
} else if (const CodeGenIntrinsic *Int = getIntrinsicInfo(CDP)) {
bool MadeChange = false;
-
+
// Apply the result type to the node.
- MadeChange = UpdateNodeType(Int->ArgVTs[0], TP);
-
- if (getNumChildren() != Int->ArgVTs.size())
+ unsigned NumRetVTs = Int->IS.RetVTs.size();
+ unsigned NumParamVTs = Int->IS.ParamVTs.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::ValueType 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 (getOperator()->getName() == "vector_shuffle" &&
getChild(2)->getOperator()->getName() == "build_vector") {
TreePatternNode *BV = getChild(2);
- const std::vector<MVT::ValueType> &LegalVTs
+ const std::vector<MVT::SimpleValueType> &LegalVTs
= CDP.getTargetInfo().getLegalValueTypes();
- MVT::ValueType LegalIntVT = MVT::Other;
+ MVT::SimpleValueType LegalIntVT = MVT::Other;
for (unsigned i = 0, e = LegalVTs.size(); i != e; ++i)
- if (MVT::isInteger(LegalVTs[i]) && !MVT::isVector(LegalVTs[i])) {
+ if (isInteger(LegalVTs[i]) && !isVector(LegalVTs[i])) {
LegalIntVT = LegalVTs[i];
break;
}
MadeChange = UpdateNodeType(VT, TP);
} else if (ResultNode->getName() == "unknown") {
std::vector<unsigned char> VT;
- VT.push_back(MVT::isUnknown);
+ VT.push_back(EMVT::isUnknown);
MadeChange = UpdateNodeType(VT, TP);
} else {
assert(ResultNode->isSubClassOf("RegisterClass") &&
TP.error("Instruction '" + getOperator()->getName() +
"' expects more operands than were provided.");
- MVT::ValueType VT;
+ MVT::SimpleValueType VT;
TreePatternNode *Child = getChild(ChildNo++);
if (OperandNode->isSubClassOf("RegisterClass")) {
const CodeGenRegisterClass &RC =
} else if (OperandNode->getName() == "ptr_rc") {
MadeChange |= Child->UpdateNodeType(MVT::iPTR, TP);
} else if (OperandNode->getName() == "unknown") {
- MadeChange |= Child->UpdateNodeType(MVT::isUnknown, TP);
- } else if (OperandNode->getName() == "discard") {
- MadeChange |= Child->UpdateNodeType(MVT::isUnknown, TP);
+ MadeChange |= Child->UpdateNodeType(EMVT::isUnknown, TP);
} else {
assert(0 && "Unknown operand type!");
abort();
// If this node is a commutative operator, check that the LHS isn't an
// immediate.
const SDNodeInfo &NodeInfo = CDP.getSDNodeInfo(getOperator());
- if (NodeInfo.hasProperty(SDNPCommutative)) {
+ bool isCommIntrinsic = isCommutativeIntrinsic(CDP);
+ if (NodeInfo.hasProperty(SDNPCommutative) || isCommIntrinsic) {
// Scan all of the operands of the node and make sure that only the last one
// is a constant node, unless the RHS also is.
if (!OnlyOnRHSOfCommutative(getChild(getNumChildren()-1))) {
- for (unsigned i = 0, e = getNumChildren()-1; i != e; ++i)
+ bool Skip = isCommIntrinsic ? 1 : 0; // First operand is intrinsic id.
+ for (unsigned i = Skip, e = getNumChildren()-1; i != e; ++i)
if (OnlyOnRHSOfCommutative(getChild(i))) {
Reason="Immediate value must be on the RHS of commutative operators!";
return false;
void TreePattern::error(const std::string &Msg) const {
dump();
- throw "In " + TheRecord->getName() + ": " + Msg;
+ throw TGError(TheRecord->getLoc(), "In " + TheRecord->getName() + ": " + Msg);
}
TreePatternNode *TreePattern::ParseTreePattern(DagInit *Dag) {
if (DefInit *DI = dynamic_cast<DefInit*>(Arg)) {
Record *R = DI->getDef();
if (R->isSubClassOf("SDNode") || R->isSubClassOf("PatFrag")) {
- Dag->setArg(0, new DagInit(DI,
+ Dag->setArg(0, new DagInit(DI, "",
std::vector<std::pair<Init*, std::string> >()));
return ParseTreePattern(Dag);
}
// Apply the type cast.
New->UpdateNodeType(getValueType(Operator), *this);
- New->setName(Dag->getArgName(0));
+ if (New->getNumChildren() == 0)
+ New->setName(Dag->getArgName(0));
return New;
}
// Verify that this is something that makes sense for an operator.
- if (!Operator->isSubClassOf("PatFrag") && !Operator->isSubClassOf("SDNode") &&
+ if (!Operator->isSubClassOf("PatFrag") &&
+ !Operator->isSubClassOf("SDNode") &&
!Operator->isSubClassOf("Instruction") &&
!Operator->isSubClassOf("SDNodeXForm") &&
!Operator->isSubClassOf("Intrinsic") &&
// Direct reference to a leaf DagNode or PatFrag? Turn it into a
// TreePatternNode if its own.
if (R->isSubClassOf("SDNode") || R->isSubClassOf("PatFrag")) {
- Dag->setArg(i, new DagInit(DefI,
+ Dag->setArg(i, new DagInit(DefI, "",
std::vector<std::pair<Init*, std::string> >()));
--i; // Revisit this node...
} else {
// 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.
Children.insert(Children.begin(), IIDNode);
}
- return new TreePatternNode(Operator, Children);
+ TreePatternNode *Result = new TreePatternNode(Operator, Children);
+ Result->setName(Dag->getName());
+ return Result;
}
/// InferAllTypes - Infer/propagate as many types throughout the expression
// FIXME: REMOVE OSTREAM ARGUMENT
CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R) : Records(R) {
- Intrinsics = LoadIntrinsics(Records);
+ Intrinsics = LoadIntrinsics(Records, false);
+ TgtIntrinsics = LoadIntrinsics(Records, true);
ParseNodeInfo();
ParseNodeTransforms();
ParseComplexPatterns();
// 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
for (unsigned op = 0, e = DefaultInfo->getNumArgs(); op != e; ++op)
Ops.push_back(std::make_pair(DefaultInfo->getArg(op),
DefaultInfo->getArgName(op)));
- DagInit *DI = new DagInit(SomeSDNode, Ops);
+ DagInit *DI = new DagInit(SomeSDNode, "", Ops);
// Create a TreePattern to parse this.
TreePattern P(DefaultOps[iter][i], DI, false, *this);
I->error("Input " + DI->getDef()->getName() + " must be named!");
else if (DI && DI->getDef()->isSubClassOf("Register"))
InstImpInputs.push_back(DI->getDef());
- ;
}
return false;
}
if (!DI) I->error("Input $" + Pat->getName() + " must be an identifier!");
Rec = DI->getDef();
} else {
- assert(Pat->getNumChildren() == 0 && "can't be a use with children!");
Rec = Pat->getOperator();
}
// If this is a non-leaf node with no children, treat it basically as if
// it were a leaf. This handles nodes like (imm).
- bool isUse = false;
- if (Pat->getNumChildren() == 0)
- isUse = HandleUse(I, Pat, InstInputs, InstImpInputs);
+ bool isUse = HandleUse(I, Pat, InstInputs, InstImpInputs);
if (!isUse && Pat->getTransformFn())
I->error("Cannot specify a transform function for a non-input value!");
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;
CombineChildVariants(N, ChildVariants, OutVariants, CDP, DepVars);
// If this node is commutative, consider the commuted order.
- if (NodeInfo.hasProperty(SDNPCommutative)) {
- assert(N->getNumChildren()==2 &&"Commutative but doesn't have 2 children!");
+ bool isCommIntrinsic = N->isCommutativeIntrinsic(CDP);
+ if (NodeInfo.hasProperty(SDNPCommutative) || isCommIntrinsic) {
+ assert((N->getNumChildren()==2 || isCommIntrinsic) &&
+ "Commutative but doesn't have 2 children!");
// Don't count children which are actually register references.
unsigned NC = 0;
for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) {
NC++;
}
// Consider the commuted order.
- if (NC == 2)
+ if (isCommIntrinsic) {
+ // Commutative intrinsic. First operand is the intrinsic id, 2nd and 3rd
+ // operands are the commutative operands, and there might be more operands
+ // after those.
+ assert(NC >= 3 &&
+ "Commutative intrinsic should have at least 3 childrean!");
+ std::vector<std::vector<TreePatternNode*> > Variants;
+ Variants.push_back(ChildVariants[0]); // Intrinsic id.
+ Variants.push_back(ChildVariants[2]);
+ Variants.push_back(ChildVariants[1]);
+ for (unsigned i = 3; i != NC; ++i)
+ Variants.push_back(ChildVariants[i]);
+ CombineChildVariants(N, Variants, OutVariants, CDP, DepVars);
+ } else if (NC == 2)
CombineChildVariants(N, ChildVariants[1], ChildVariants[0],
OutVariants, CDP, DepVars);
}