X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FCodeGenDAGPatterns.cpp;h=6941732aaac58f797f5f790271ac5aac6d4f6c8f;hb=ccbfd5b18a79a07229f11af478843eae16ac9b26;hp=b74144ebfdc801288743d1fe27696391d04eca2e;hpb=543790673c747ab2793fc657e239ce5f78419dc0;p=oota-llvm.git diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index b74144ebfdc..6941732aaac 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -13,12 +13,16 @@ //===----------------------------------------------------------------------===// #include "CodeGenDAGPatterns.h" -#include "Record.h" -#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/Twine.h" #include "llvm/Support/Debug.h" -#include +#include "llvm/Support/ErrorHandling.h" +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Record.h" #include +#include +#include using namespace llvm; //===----------------------------------------------------------------------===// @@ -26,16 +30,16 @@ using namespace llvm; //===----------------------------------------------------------------------===// static inline bool isInteger(MVT::SimpleValueType VT) { - return EVT(VT).isInteger(); + return MVT(VT).isInteger(); } static inline bool isFloatingPoint(MVT::SimpleValueType VT) { - return EVT(VT).isFloatingPoint(); + return MVT(VT).isFloatingPoint(); } static inline bool isVector(MVT::SimpleValueType VT) { - return EVT(VT).isVector(); + return MVT(VT).isVector(); } static inline bool isScalar(MVT::SimpleValueType VT) { - return !EVT(VT).isVector(); + return !MVT(VT).isVector(); } EEVT::TypeSet::TypeSet(MVT::SimpleValueType VT, TreePattern &TP) { @@ -53,7 +57,7 @@ EEVT::TypeSet::TypeSet(MVT::SimpleValueType VT, TreePattern &TP) { } -EEVT::TypeSet::TypeSet(const std::vector &VTList) { +EEVT::TypeSet::TypeSet(ArrayRef VTList) { assert(!VTList.empty() && "empty list?"); TypeVec.append(VTList.begin(), VTList.end()); @@ -72,17 +76,22 @@ bool EEVT::TypeSet::FillWithPossibleTypes(TreePattern &TP, bool (*Pred)(MVT::SimpleValueType), const char *PredicateName) { assert(isCompletelyUnknown()); - const std::vector &LegalTypes = + ArrayRef LegalTypes = TP.getDAGPatterns().getTargetInfo().getLegalValueTypes(); + if (TP.hasError()) + return false; + for (unsigned i = 0, e = LegalTypes.size(); i != e; ++i) if (Pred == 0 || Pred(LegalTypes[i])) TypeVec.push_back(LegalTypes[i]); // If we have nothing that matches the predicate, bail out. - if (TypeVec.empty()) + if (TypeVec.empty()) { TP.error("Type inference contradiction found, no " + std::string(PredicateName) + " types found"); + return false; + } // No need to sort with one element. if (TypeVec.size() == 1) return true; @@ -142,9 +151,9 @@ std::string EEVT::TypeSet::getName() const { /// MergeInTypeInfo - This merges in type information from the specified /// argument. If 'this' changes, it returns true. If the two types are -/// contradictory (e.g. merge f32 into i32) then this throws an exception. +/// contradictory (e.g. merge f32 into i32) then this flags an error. bool EEVT::TypeSet::MergeInTypeInfo(const EEVT::TypeSet &InVT, TreePattern &TP){ - if (InVT.isCompletelyUnknown() || *this == InVT) + if (InVT.isCompletelyUnknown() || *this == InVT || TP.hasError()) return false; if (isCompletelyUnknown()) { @@ -220,11 +229,13 @@ bool EEVT::TypeSet::MergeInTypeInfo(const EEVT::TypeSet &InVT, TreePattern &TP){ // FIXME: Really want an SMLoc here! TP.error("Type inference contradiction found, merging '" + InVT.getName() + "' into '" + InputSet.getName() + "'"); - return true; // unreachable + return false; } /// EnforceInteger - Remove all non-integer types from this set. bool EEVT::TypeSet::EnforceInteger(TreePattern &TP) { + if (TP.hasError()) + return false; // If we know nothing, then get the full set. if (TypeVec.empty()) return FillWithPossibleTypes(TP, isInteger, "integer"); @@ -238,14 +249,18 @@ bool EEVT::TypeSet::EnforceInteger(TreePattern &TP) { if (!isInteger(TypeVec[i])) TypeVec.erase(TypeVec.begin()+i--); - if (TypeVec.empty()) + if (TypeVec.empty()) { TP.error("Type inference contradiction found, '" + InputSet.getName() + "' needs to be integer"); + return false; + } return true; } /// EnforceFloatingPoint - Remove all integer types from this set. bool EEVT::TypeSet::EnforceFloatingPoint(TreePattern &TP) { + if (TP.hasError()) + return false; // If we know nothing, then get the full set. if (TypeVec.empty()) return FillWithPossibleTypes(TP, isFloatingPoint, "floating point"); @@ -260,14 +275,19 @@ bool EEVT::TypeSet::EnforceFloatingPoint(TreePattern &TP) { if (!isFloatingPoint(TypeVec[i])) TypeVec.erase(TypeVec.begin()+i--); - if (TypeVec.empty()) + if (TypeVec.empty()) { TP.error("Type inference contradiction found, '" + InputSet.getName() + "' needs to be floating point"); + return false; + } return true; } /// EnforceScalar - Remove all vector types from this. bool EEVT::TypeSet::EnforceScalar(TreePattern &TP) { + if (TP.hasError()) + return false; + // If we know nothing, then get the full set. if (TypeVec.empty()) return FillWithPossibleTypes(TP, isScalar, "scalar"); @@ -282,14 +302,19 @@ bool EEVT::TypeSet::EnforceScalar(TreePattern &TP) { if (!isScalar(TypeVec[i])) TypeVec.erase(TypeVec.begin()+i--); - if (TypeVec.empty()) + if (TypeVec.empty()) { TP.error("Type inference contradiction found, '" + InputSet.getName() + "' needs to be scalar"); + return false; + } return true; } /// EnforceVector - Remove all vector types from this. bool EEVT::TypeSet::EnforceVector(TreePattern &TP) { + if (TP.hasError()) + return false; + // If we know nothing, then get the full set. if (TypeVec.empty()) return FillWithPossibleTypes(TP, isVector, "vector"); @@ -304,9 +329,11 @@ bool EEVT::TypeSet::EnforceVector(TreePattern &TP) { MadeChange = true; } - if (TypeVec.empty()) + if (TypeVec.empty()) { TP.error("Type inference contradiction found, '" + InputSet.getName() + "' needs to be a vector"); + return false; + } return MadeChange; } @@ -315,6 +342,9 @@ bool EEVT::TypeSet::EnforceVector(TreePattern &TP) { /// EnforceSmallerThan - 'this' must be a smaller VT than Other. Update /// this an other based on this information. bool EEVT::TypeSet::EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP) { + if (TP.hasError()) + return false; + // Both operands must be integer or FP, but we don't care which. bool MadeChange = false; @@ -355,25 +385,27 @@ bool EEVT::TypeSet::EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP) { // Otherwise, if these are both vector types, either this vector // must have a larger bitsize than the other, or this element type // must be larger than the other. - EVT Type(TypeVec[0]); - EVT OtherType(Other.TypeVec[0]); + MVT Type(TypeVec[0]); + MVT OtherType(Other.TypeVec[0]); if (hasVectorTypes() && Other.hasVectorTypes()) { if (Type.getSizeInBits() >= OtherType.getSizeInBits()) if (Type.getVectorElementType().getSizeInBits() - >= OtherType.getVectorElementType().getSizeInBits()) + >= OtherType.getVectorElementType().getSizeInBits()) { TP.error("Type inference contradiction found, '" + getName() + "' element type not smaller than '" + Other.getName() +"'!"); - } - else + return false; + } + } else // For scalar types, the bitsize of this type must be larger // than that of the other. - if (Type.getSizeInBits() >= OtherType.getSizeInBits()) + if (Type.getSizeInBits() >= OtherType.getSizeInBits()) { TP.error("Type inference contradiction found, '" + getName() + "' is not smaller than '" + Other.getName() +"'!"); - + return false; + } } @@ -405,7 +437,7 @@ bool EEVT::TypeSet::EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP) { int OtherIntSize = 0; int OtherFPSize = 0; - for (SmallVector::iterator TVI = + for (SmallVectorImpl::iterator TVI = Other.TypeVec.begin(); TVI != Other.TypeVec.end(); /* NULL */) { @@ -417,8 +449,7 @@ bool EEVT::TypeSet::EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP) { MadeChange = true; continue; } - } - else if (isFloatingPoint(*TVI)) { + } else if (isFloatingPoint(*TVI)) { ++OtherFPSize; if (*TVI == SmallestFP) { TVI = Other.TypeVec.erase(TVI); @@ -432,10 +463,12 @@ bool EEVT::TypeSet::EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP) { // If this is the only type in the large set, the constraint can never be // satisfied. - if ((Other.hasIntegerTypes() && OtherIntSize == 0) - || (Other.hasFloatingPointTypes() && OtherFPSize == 0)) + if ((Other.hasIntegerTypes() && OtherIntSize == 0) || + (Other.hasFloatingPointTypes() && OtherFPSize == 0)) { TP.error("Type inference contradiction found, '" + Other.getName() + "' has nothing larger than '" + getName() +"'!"); + return false; + } // Okay, find the largest type in the Other set and remove it from the // current set. @@ -461,7 +494,7 @@ bool EEVT::TypeSet::EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP) { int IntSize = 0; int FPSize = 0; - for (SmallVector::iterator TVI = + for (SmallVectorImpl::iterator TVI = TypeVec.begin(); TVI != TypeVec.end(); /* NULL */) { @@ -473,8 +506,7 @@ bool EEVT::TypeSet::EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP) { MadeChange = true; continue; } - } - else if (isFloatingPoint(*TVI)) { + } else if (isFloatingPoint(*TVI)) { ++FPSize; if (*TVI == LargestFP) { TVI = TypeVec.erase(TVI); @@ -488,10 +520,12 @@ bool EEVT::TypeSet::EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP) { // If this is the only type in the small set, the constraint can never be // satisfied. - if ((hasIntegerTypes() && IntSize == 0) - || (hasFloatingPointTypes() && FPSize == 0)) + if ((hasIntegerTypes() && IntSize == 0) || + (hasFloatingPointTypes() && FPSize == 0)) { TP.error("Type inference contradiction found, '" + getName() + "' has nothing smaller than '" + Other.getName()+"'!"); + return false; + } return MadeChange; } @@ -500,6 +534,9 @@ bool EEVT::TypeSet::EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP) { /// whose element is specified by VTOperand. bool EEVT::TypeSet::EnforceVectorEltTypeIs(EEVT::TypeSet &VTOperand, TreePattern &TP) { + if (TP.hasError()) + return false; + // "This" must be a vector and "VTOperand" must be a scalar. bool MadeChange = false; MadeChange |= EnforceVector(TP); @@ -507,10 +544,10 @@ bool EEVT::TypeSet::EnforceVectorEltTypeIs(EEVT::TypeSet &VTOperand, // If we know the vector type, it forces the scalar to agree. if (isConcrete()) { - EVT IVT = getConcrete(); + MVT IVT = getConcrete(); IVT = IVT.getVectorElementType(); return MadeChange | - VTOperand.MergeInTypeInfo(IVT.getSimpleVT().SimpleTy, TP); + VTOperand.MergeInTypeInfo(IVT.SimpleTy, TP); } // If the scalar type is known, filter out vector types whose element types @@ -525,15 +562,17 @@ bool EEVT::TypeSet::EnforceVectorEltTypeIs(EEVT::TypeSet &VTOperand, // Filter out all the types which don't have the right element type. for (unsigned i = 0; i != TypeVec.size(); ++i) { assert(isVector(TypeVec[i]) && "EnforceVector didn't work"); - if (EVT(TypeVec[i]).getVectorElementType().getSimpleVT().SimpleTy != VT) { + if (MVT(TypeVec[i]).getVectorElementType().SimpleTy != VT) { TypeVec.erase(TypeVec.begin()+i--); MadeChange = true; } } - if (TypeVec.empty()) // FIXME: Really want an SMLoc here! + if (TypeVec.empty()) { // FIXME: Really want an SMLoc here! TP.error("Type inference contradiction found, forcing '" + InputSet.getName() + "' to have a vector element"); + return false; + } return MadeChange; } @@ -551,16 +590,16 @@ bool EEVT::TypeSet::EnforceVectorSubVectorTypeIs(EEVT::TypeSet &VTOperand, // If we know the vector type, it forces the scalar types to agree. if (isConcrete()) { - EVT IVT = getConcrete(); + MVT IVT = getConcrete(); IVT = IVT.getVectorElementType(); - EEVT::TypeSet EltTypeSet(IVT.getSimpleVT().SimpleTy, TP); + EEVT::TypeSet EltTypeSet(IVT.SimpleTy, TP); MadeChange |= VTOperand.EnforceVectorEltTypeIs(EltTypeSet, TP); } else if (VTOperand.isConcrete()) { - EVT IVT = VTOperand.getConcrete(); + MVT IVT = VTOperand.getConcrete(); IVT = IVT.getVectorElementType(); - EEVT::TypeSet EltTypeSet(IVT.getSimpleVT().SimpleTy, TP); + EEVT::TypeSet EltTypeSet(IVT.SimpleTy, TP); MadeChange |= EnforceVectorEltTypeIs(EltTypeSet, TP); } @@ -570,10 +609,6 @@ bool EEVT::TypeSet::EnforceVectorSubVectorTypeIs(EEVT::TypeSet &VTOperand, //===----------------------------------------------------------------------===// // Helpers for working with extended types. -bool RecordPtrCmp::operator()(const Record *LHS, const Record *RHS) const { - return LHS->getID() < RHS->getID(); -} - /// Dependent variable map for CodeGenDAGPattern variant generation typedef std::map DepVarMap; @@ -582,7 +617,7 @@ typedef DepVarMap::const_iterator DepVarMap_citer; static void FindDepVarsOf(TreePatternNode *N, DepVarMap &DepMap) { if (N->isLeaf()) { - if (dynamic_cast(N->getLeafValue()) != NULL) + if (isa(N->getLeafValue())) DepMap[N->getName()]++; } else { for (size_t i = 0, e = N->getNumChildren(); i != e; ++i) @@ -621,14 +656,24 @@ static void DumpDepVars(MultipleUseVarSet &DepVars) { // TreePredicateFn Implementation //===----------------------------------------------------------------------===// +/// TreePredicateFn constructor. Here 'N' is a subclass of PatFrag. +TreePredicateFn::TreePredicateFn(TreePattern *N) : PatFragRec(N) { + assert((getPredCode().empty() || getImmCode().empty()) && + ".td file corrupt: can't have a node predicate *and* an imm predicate"); +} + std::string TreePredicateFn::getPredCode() const { - return PatFragRec->getRecord()->getValueAsCode("PredicateCode"); + return PatFragRec->getRecord()->getValueAsString("PredicateCode"); +} + +std::string TreePredicateFn::getImmCode() const { + return PatFragRec->getRecord()->getValueAsString("ImmediateCode"); } /// isAlwaysTrue - Return true if this is a noop predicate. bool TreePredicateFn::isAlwaysTrue() const { - return getPredCode().empty(); + return getPredCode().empty() && getImmCode().empty(); } /// Return the name to use in the generated code to reference this, this is @@ -642,6 +687,16 @@ std::string TreePredicateFn::getFnName() const { /// not N. This handles casting and conversion to a concrete node type as /// appropriate. std::string TreePredicateFn::getCodeToRunOnSDNode() const { + // Handle immediate predicates first. + std::string ImmCode = getImmCode(); + if (!ImmCode.empty()) { + std::string Result = + " int64_t Imm = cast(Node)->getSExtValue();\n"; + return Result + ImmCode; + } + + // Handle arbitrary node predicates. + assert(!getPredCode().empty() && "Don't have any predicate code!"); std::string ClassName; if (PatFragRec->getOnlyTree()->isLeaf()) ClassName = "SDNode"; @@ -671,7 +726,7 @@ static unsigned getPatternSize(const TreePatternNode *P, unsigned Size = 3; // The node itself. // If the root node is a ConstantSDNode, increases its size. // e.g. (set R32:$dst, 0). - if (P->isLeaf() && dynamic_cast(P->getLeafValue())) + if (P->isLeaf() && isa(P->getLeafValue())) Size += 2; // FIXME: This is a hack to statically increase the priority of patterns @@ -695,7 +750,7 @@ static unsigned getPatternSize(const TreePatternNode *P, Child->getType(0) != MVT::Other) Size += getPatternSize(Child, CGP); else if (Child->isLeaf()) { - if (dynamic_cast(Child->getLeafValue())) + if (isa(Child->getLeafValue())) Size += 5; // Matches a ConstantSDNode (+3) and a specific value (+2). else if (Child->getComplexPatternInfo(CGP)) Size += getPatternSize(Child, CGP); @@ -721,13 +776,13 @@ getPatternComplexity(const CodeGenDAGPatterns &CGP) const { std::string PatternToMatch::getPredicateCheck() const { std::string PredicateCheck; for (unsigned i = 0, e = Predicates->getSize(); i != e; ++i) { - if (DefInit *Pred = dynamic_cast(Predicates->getElement(i))) { + if (DefInit *Pred = dyn_cast(Predicates->getElement(i))) { Record *Def = Pred->getDef(); if (!Def->isSubClassOf("Predicate")) { #ifndef NDEBUG Def->dump(); #endif - assert(0 && "Unknown predicate type!"); + llvm_unreachable("Unknown predicate type!"); } if (!PredicateCheck.empty()) PredicateCheck += " && "; @@ -749,7 +804,7 @@ SDTypeConstraint::SDTypeConstraint(Record *R) { ConstraintType = SDTCisVT; x.SDTCisVT_Info.VT = getValueType(R->getValueAsDef("VT")); if (x.SDTCisVT_Info.VT == MVT::isVoid) - throw TGError(R->getLoc(), "Cannot use 'Void' as type to SDTCisVT"); + PrintFatalError(R->getLoc(), "Cannot use 'Void' as type to SDTCisVT"); } else if (R->isSubClassOf("SDTCisPtrTy")) { ConstraintType = SDTCisPtrTy; @@ -809,16 +864,17 @@ static TreePatternNode *getOperandNum(unsigned OpNo, TreePatternNode *N, /// ApplyTypeConstraint - Given a node in a pattern, apply this type /// constraint to the nodes operands. This returns true if it makes a -/// change, false otherwise. If a type contradiction is found, throw an -/// exception. +/// change, false otherwise. If a type contradiction is found, flag an error. bool SDTypeConstraint::ApplyTypeConstraint(TreePatternNode *N, const SDNodeInfo &NodeInfo, TreePattern &TP) const { + if (TP.hasError()) + return false; + unsigned ResNo = 0; // The result number being referenced. TreePatternNode *NodeToApply = getOperandNum(OperandNo, N, NodeInfo, ResNo); switch (ConstraintType) { - default: assert(0 && "Unknown constraint type!"); case SDTCisVT: // Operand must be a particular type. return NodeToApply->UpdateNodeType(ResNo, x.SDTCisVT_Info.VT, TP); @@ -845,10 +901,12 @@ bool SDTypeConstraint::ApplyTypeConstraint(TreePatternNode *N, // The NodeToApply must be a leaf node that is a VT. OtherOperandNum must // have an integer type that is smaller than the VT. if (!NodeToApply->isLeaf() || - !dynamic_cast(NodeToApply->getLeafValue()) || + !isa(NodeToApply->getLeafValue()) || !static_cast(NodeToApply->getLeafValue())->getDef() - ->isSubClassOf("ValueType")) + ->isSubClassOf("ValueType")) { TP.error(N->getOperator()->getName() + " expects a VT operand!"); + return false; + } MVT::SimpleValueType VT = getValueType(static_cast(NodeToApply->getLeafValue())->getDef()); @@ -892,9 +950,43 @@ bool SDTypeConstraint::ApplyTypeConstraint(TreePatternNode *N, EnforceVectorSubVectorTypeIs(NodeToApply->getExtType(ResNo), TP); } } - return false; + llvm_unreachable("Invalid ConstraintType!"); } +// Update the node type to match an instruction operand or result as specified +// in the ins or outs lists on the instruction definition. Return true if the +// type was actually changed. +bool TreePatternNode::UpdateNodeTypeFromInst(unsigned ResNo, + Record *Operand, + TreePattern &TP) { + // The 'unknown' operand indicates that types should be inferred from the + // context. + if (Operand->isSubClassOf("unknown_class")) + return false; + + // The Operand class specifies a type directly. + if (Operand->isSubClassOf("Operand")) + return UpdateNodeType(ResNo, getValueType(Operand->getValueAsDef("Type")), + TP); + + // PointerLikeRegClass has a type that is determined at runtime. + if (Operand->isSubClassOf("PointerLikeRegClass")) + return UpdateNodeType(ResNo, MVT::iPTR, TP); + + // Both RegisterClass and RegisterOperand operands derive their types from a + // register class def. + Record *RC = 0; + if (Operand->isSubClassOf("RegisterClass")) + RC = Operand; + else if (Operand->isSubClassOf("RegisterOperand")) + RC = Operand->getValueAsDef("RegClass"); + + assert(RC && "Unknown operand type"); + CodeGenTarget &Tgt = TP.getDAGPatterns().getTargetInfo(); + return UpdateNodeType(ResNo, Tgt.getRegisterClass(RC).getValueTypes(), TP); +} + + //===----------------------------------------------------------------------===// // SDNodeInfo implementation // @@ -1002,8 +1094,9 @@ static unsigned GetNumNodeResults(Record *Operator, CodeGenDAGPatterns &CDP) { // Get the result tree. DagInit *Tree = Operator->getValueAsDag("Fragment"); Record *Op = 0; - if (Tree && dynamic_cast(Tree->getOperator())) - Op = dynamic_cast(Tree->getOperator())->getDef(); + if (Tree) + if (DefInit *DI = dyn_cast(Tree->getOperator())) + Op = DI->getDef(); assert(Op && "Invalid Fragment"); return GetNumNodeResults(Op, CDP); } @@ -1023,6 +1116,9 @@ static unsigned GetNumNodeResults(Record *Operator, CodeGenDAGPatterns &CDP) { if (Operator->isSubClassOf("SDNodeXForm")) return 1; // FIXME: Generalize SDNodeXForm + if (Operator->isSubClassOf("ValueType")) + return 1; // A type-cast of one result. + Operator->dump(); errs() << "Unhandled node in GetNumNodeResults\n"; exit(1); @@ -1077,8 +1173,8 @@ bool TreePatternNode::isIsomorphicTo(const TreePatternNode *N, return false; if (isLeaf()) { - if (DefInit *DI = dynamic_cast(getLeafValue())) { - if (DefInit *NDI = dynamic_cast(N->getLeafValue())) { + if (DefInit *DI = dyn_cast(getLeafValue())) { + if (DefInit *NDI = dyn_cast(N->getLeafValue())) { return ((DI->getDef() == NDI->getDef()) && (DepVars.find(getName()) == DepVars.end() || getName() == N->getName())); @@ -1135,8 +1231,8 @@ SubstituteFormalArguments(std::map &ArgMap) { TreePatternNode *Child = getChild(i); if (Child->isLeaf()) { Init *Val = Child->getLeafValue(); - if (dynamic_cast(Val) && - static_cast(Val)->getDef()->getName() == "node") { + if (isa(Val) && + cast(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!"); @@ -1156,7 +1252,11 @@ SubstituteFormalArguments(std::map &ArgMap) { /// fragments, inline them into place, giving us a pattern without any /// PatFrag references. TreePatternNode *TreePatternNode::InlinePatternFragments(TreePattern &TP) { - if (isLeaf()) return this; // nothing to do. + if (TP.hasError()) + return 0; + + if (isLeaf()) + return this; // nothing to do. Record *Op = getOperator(); if (!Op->isSubClassOf("PatFrag")) { @@ -1179,9 +1279,11 @@ TreePatternNode *TreePatternNode::InlinePatternFragments(TreePattern &TP) { TreePattern *Frag = TP.getDAGPatterns().getPatternFragment(Op); // Verify that we are passing the right number of operands. - if (Frag->getNumArgs() != Children.size()) + if (Frag->getNumArgs() != Children.size()) { TP.error("'" + Op->getName() + "' fragment requires " + utostr(Frag->getNumArgs()) + " operands!"); + return 0; + } TreePatternNode *FragTree = Frag->getOnlyTree()->clone(); @@ -1219,11 +1321,38 @@ TreePatternNode *TreePatternNode::InlinePatternFragments(TreePattern &TP) { /// type which should be applied to it. This will infer the type of register /// references from the register file information, for example. /// +/// When Unnamed is set, return the type of a DAG operand with no name, such as +/// the F8RC register class argument in: +/// +/// (COPY_TO_REGCLASS GPR:$src, F8RC) +/// +/// When Unnamed is false, return the type of a named DAG operand such as the +/// GPR:$src operand above. +/// static EEVT::TypeSet getImplicitType(Record *R, unsigned ResNo, - bool NotRegisters, TreePattern &TP) { + bool NotRegisters, + bool Unnamed, + TreePattern &TP) { + // Check to see if this is a register operand. + if (R->isSubClassOf("RegisterOperand")) { + assert(ResNo == 0 && "Regoperand ref only has one result!"); + if (NotRegisters) + return EEVT::TypeSet(); // Unknown. + Record *RegClass = R->getValueAsDef("RegClass"); + const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo(); + return EEVT::TypeSet(T.getRegisterClass(RegClass).getValueTypes()); + } + // Check to see if this is a register or a register class. if (R->isSubClassOf("RegisterClass")) { assert(ResNo == 0 && "Regclass ref only has one result!"); + // An unnamed register class represents itself as an i32 immediate, for + // example on a COPY_TO_REGCLASS instruction. + if (Unnamed) + return EEVT::TypeSet(MVT::i32, TP); + + // In a named operand, the register class provides the possible set of + // types. if (NotRegisters) return EEVT::TypeSet(); // Unknown. const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo(); @@ -1249,9 +1378,27 @@ static EEVT::TypeSet getImplicitType(Record *R, unsigned ResNo, return EEVT::TypeSet(); } - if (R->isSubClassOf("ValueType") || R->isSubClassOf("CondCode")) { + if (R->isSubClassOf("ValueType")) { + assert(ResNo == 0 && "This node only has one result!"); + // An unnamed VTSDNode represents itself as an MVT::Other immediate. + // + // (sext_inreg GPR:$src, i16) + // ~~~ + if (Unnamed) + return EEVT::TypeSet(MVT::Other, TP); + // With a name, the ValueType simply provides the type of the named + // variable. + // + // (sext_inreg i32:$src, i16) + // ~~~~~~~~ + if (NotRegisters) + return EEVT::TypeSet(); // Unknown. + return EEVT::TypeSet(getValueType(R), TP); + } + + if (R->isSubClassOf("CondCode")) { assert(ResNo == 0 && "This node only has one result!"); - // Using a VTSDNode or CondCodeSDNode. + // Using a CondCodeSDNode. return EEVT::TypeSet(MVT::Other, TP); } @@ -1287,8 +1434,7 @@ getIntrinsicInfo(const CodeGenDAGPatterns &CDP) const { getOperator() != CDP.get_intrinsic_wo_chain_sdnode()) return 0; - unsigned IID = - dynamic_cast(getChild(0)->getLeafValue())->getValue(); + unsigned IID = cast(getChild(0)->getLeafValue())->getValue(); return &CDP.getIntrinsicInfo(IID); } @@ -1298,7 +1444,7 @@ const ComplexPattern * TreePatternNode::getComplexPatternInfo(const CodeGenDAGPatterns &CGP) const { if (!isLeaf()) return 0; - DefInit *DI = dynamic_cast(getLeafValue()); + DefInit *DI = dyn_cast(getLeafValue()); if (DI && DI->getDef()->isSubClassOf("ComplexPattern")) return &CGP.getComplexPattern(DI->getDef()); return 0; @@ -1346,21 +1492,24 @@ TreePatternNode::isCommutativeIntrinsic(const CodeGenDAGPatterns &CDP) const { /// 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. +/// change, false otherwise. If a type contradiction is found, flag an error. bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { + if (TP.hasError()) + return false; + CodeGenDAGPatterns &CDP = TP.getDAGPatterns(); if (isLeaf()) { - if (DefInit *DI = dynamic_cast(getLeafValue())) { + if (DefInit *DI = dyn_cast(getLeafValue())) { // If it's a regclass or something else known, include the type. bool MadeChange = false; for (unsigned i = 0, e = Types.size(); i != e; ++i) MadeChange |= UpdateNodeType(i, getImplicitType(DI->getDef(), i, - NotRegisters, TP), TP); + NotRegisters, + !hasName(), TP), TP); return MadeChange; } - if (IntInit *II = dynamic_cast(getLeafValue())) { + if (IntInit *II = dyn_cast(getLeafValue())) { assert(Types.size() == 1 && "Invalid IntInit"); // Int inits are always integers. :) @@ -1373,25 +1522,19 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { if (VT == MVT::iPTR || VT == MVT::iPTRAny) return MadeChange; - unsigned Size = EVT(VT).getSizeInBits(); + unsigned Size = MVT(VT).getSizeInBits(); // Make sure that the value is representable for this type. if (Size >= 32) return MadeChange; - int Val = (II->getValue() << (32-Size)) >> (32-Size); - if (Val == II->getValue()) return MadeChange; - - // If sign-extended doesn't fit, does it fit as unsigned? - unsigned ValueMask; - unsigned UnsignedVal; - ValueMask = unsigned(~uint32_t(0UL) >> (32-Size)); - UnsignedVal = unsigned(II->getValue()); - - if ((ValueMask & UnsignedVal) == UnsignedVal) + // Check that the value doesn't use more bits than we have. It must either + // be a sign- or zero-extended equivalent of the original. + int64_t SignBitAndAbove = II->getValue() >> (Size - 1); + if (SignBitAndAbove == -1 || SignBitAndAbove == 0 || SignBitAndAbove == 1) return MadeChange; - TP.error("Integer value '" + itostr(II->getValue())+ + TP.error("Integer value '" + itostr(II->getValue()) + "' is out of range for type '" + getEnumName(getType(0)) + "'!"); - return MadeChange; + return false; } return false; } @@ -1425,25 +1568,6 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { return MadeChange; } - if (getOperator()->getName() == "COPY_TO_REGCLASS") { - bool MadeChange = false; - MadeChange |= getChild(0)->ApplyTypeConstraints(TP, NotRegisters); - MadeChange |= getChild(1)->ApplyTypeConstraints(TP, NotRegisters); - - assert(getChild(0)->getNumTypes() == 1 && - getChild(1)->getNumTypes() == 1 && "Unhandled case"); - - // child #1 of COPY_TO_REGCLASS should be a register class. We don't care - // what type it gets, so if it didn't get a concrete type just give it the - // first viable type from the reg class. - if (!getChild(1)->hasTypeSet(0) && - !getChild(1)->getExtType(0).isCompletelyUnknown()) { - MVT::SimpleValueType RCVT = getChild(1)->getExtType(0).getTypeList()[0]; - MadeChange |= getChild(1)->UpdateNodeType(0, RCVT, TP); - } - return MadeChange; - } - if (const CodeGenIntrinsic *Int = getIntrinsicInfo(CDP)) { bool MadeChange = false; @@ -1454,10 +1578,12 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { for (unsigned i = 0, e = NumRetVTs; i != e; ++i) MadeChange |= UpdateNodeType(i, Int->IS.RetVTs[i], TP); - if (getNumChildren() != NumParamVTs + 1) + if (getNumChildren() != NumParamVTs + 1) { TP.error("Intrinsic '" + Int->Name + "' expects " + utostr(NumParamVTs) + " operands, not " + utostr(getNumChildren() - 1) + " operands!"); + return false; + } // Apply type info to the intrinsic ID. MadeChange |= getChild(0)->UpdateNodeType(0, MVT::iPTR, TP); @@ -1477,9 +1603,11 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { // Check that the number of operands is sane. Negative operands -> varargs. if (NI.getNumOperands() >= 0 && - getNumChildren() != (unsigned)NI.getNumOperands()) + getNumChildren() != (unsigned)NI.getNumOperands()) { TP.error(getOperator()->getName() + " node requires exactly " + itostr(NI.getNumOperands()) + " operands!"); + return false; + } bool MadeChange = NI.ApplyTypeConstraints(this, TP); for (unsigned i = 0, e = getNumChildren(); i != e; ++i) @@ -1498,21 +1626,8 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { // (outs) list of the instruction. // FIXME: Cap at one result so far. unsigned NumResultsToAdd = InstInfo.Operands.NumDefs ? 1 : 0; - for (unsigned ResNo = 0; ResNo != NumResultsToAdd; ++ResNo) { - Record *ResultNode = Inst.getResult(ResNo); - - if (ResultNode->isSubClassOf("PointerLikeRegClass")) { - MadeChange |= UpdateNodeType(ResNo, MVT::iPTR, TP); - } else if (ResultNode->getName() == "unknown") { - // Nothing to do. - } else { - assert(ResultNode->isSubClassOf("RegisterClass") && - "Operands should be register classes!"); - const CodeGenRegisterClass &RC = - CDP.getTargetInfo().getRegisterClass(ResultNode); - MadeChange |= UpdateNodeType(ResNo, RC.getValueTypes(), TP); - } - } + for (unsigned ResNo = 0; ResNo != NumResultsToAdd; ++ResNo) + MadeChange |= UpdateNodeTypeFromInst(ResNo, Inst.getResult(ResNo), TP); // If the instruction has implicit defs, we apply the first one as a result. // FIXME: This sucks, it should apply all implicit defs. @@ -1543,51 +1658,76 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { // If the instruction expects a predicate or optional def operand, we // codegen this by setting the operand to it's default value if it has a // non-empty DefaultOps field. - if ((OperandNode->isSubClassOf("PredicateOperand") || - OperandNode->isSubClassOf("OptionalDefOperand")) && + if (OperandNode->isSubClassOf("OperandWithDefaultOps") && !CDP.getDefaultOperand(OperandNode).DefaultOps.empty()) continue; // Verify that we didn't run out of provided operands. - if (ChildNo >= getNumChildren()) + if (ChildNo >= getNumChildren()) { TP.error("Instruction '" + getOperator()->getName() + "' expects more operands than were provided."); + return false; + } - MVT::SimpleValueType VT; TreePatternNode *Child = getChild(ChildNo++); unsigned ChildResNo = 0; // Instructions always use res #0 of their op. - if (OperandNode->isSubClassOf("RegisterClass")) { - const CodeGenRegisterClass &RC = - CDP.getTargetInfo().getRegisterClass(OperandNode); - MadeChange |= Child->UpdateNodeType(ChildResNo, RC.getValueTypes(), TP); - } else if (OperandNode->isSubClassOf("Operand")) { - VT = getValueType(OperandNode->getValueAsDef("Type")); - MadeChange |= Child->UpdateNodeType(ChildResNo, VT, TP); - } else if (OperandNode->isSubClassOf("PointerLikeRegClass")) { - MadeChange |= Child->UpdateNodeType(ChildResNo, MVT::iPTR, TP); - } else if (OperandNode->getName() == "unknown") { - // Nothing to do. - } else { - assert(0 && "Unknown operand type!"); - abort(); + // If the operand has sub-operands, they may be provided by distinct + // child patterns, so attempt to match each sub-operand separately. + if (OperandNode->isSubClassOf("Operand")) { + DagInit *MIOpInfo = OperandNode->getValueAsDag("MIOperandInfo"); + if (unsigned NumArgs = MIOpInfo->getNumArgs()) { + // But don't do that if the whole operand is being provided by + // a single ComplexPattern. + const ComplexPattern *AM = Child->getComplexPatternInfo(CDP); + if (!AM || AM->getNumOperands() < NumArgs) { + // Match first sub-operand against the child we already have. + Record *SubRec = cast(MIOpInfo->getArg(0))->getDef(); + MadeChange |= + Child->UpdateNodeTypeFromInst(ChildResNo, SubRec, TP); + + // And the remaining sub-operands against subsequent children. + for (unsigned Arg = 1; Arg < NumArgs; ++Arg) { + if (ChildNo >= getNumChildren()) { + TP.error("Instruction '" + getOperator()->getName() + + "' expects more operands than were provided."); + return false; + } + Child = getChild(ChildNo++); + + SubRec = cast(MIOpInfo->getArg(Arg))->getDef(); + MadeChange |= + Child->UpdateNodeTypeFromInst(ChildResNo, SubRec, TP); + } + continue; + } + } } - MadeChange |= Child->ApplyTypeConstraints(TP, NotRegisters); + + // If we didn't match by pieces above, attempt to match the whole + // operand now. + MadeChange |= Child->UpdateNodeTypeFromInst(ChildResNo, OperandNode, TP); } - if (ChildNo != getNumChildren()) + if (ChildNo != getNumChildren()) { TP.error("Instruction '" + getOperator()->getName() + "' was provided too many operands!"); + return false; + } + for (unsigned i = 0, e = getNumChildren(); i != e; ++i) + MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters); return MadeChange; } assert(getOperator()->isSubClassOf("SDNodeXForm") && "Unknown node type!"); // Node transforms always take one operand. - if (getNumChildren() != 1) + if (getNumChildren() != 1) { TP.error("Node transform '" + getOperator()->getName() + "' requires one operand!"); + return false; + } bool MadeChange = getChild(0)->ApplyTypeConstraints(TP, NotRegisters); @@ -1610,7 +1750,7 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { static bool OnlyOnRHSOfCommutative(TreePatternNode *N) { if (!N->isLeaf() && N->getOperator()->getName() == "imm") return true; - if (N->isLeaf() && dynamic_cast(N->getLeafValue())) + if (N->isLeaf() && isa(N->getLeafValue())) return true; return false; } @@ -1661,27 +1801,30 @@ bool TreePatternNode::canPatternMatch(std::string &Reason, // TreePattern::TreePattern(Record *TheRec, ListInit *RawPat, bool isInput, - CodeGenDAGPatterns &cdp) : TheRecord(TheRec), CDP(cdp){ - isInputPattern = isInput; + CodeGenDAGPatterns &cdp) : TheRecord(TheRec), CDP(cdp), + isInputPattern(isInput), HasError(false) { for (unsigned i = 0, e = RawPat->getSize(); i != e; ++i) Trees.push_back(ParseTreePattern(RawPat->getElement(i), "")); } TreePattern::TreePattern(Record *TheRec, DagInit *Pat, bool isInput, - CodeGenDAGPatterns &cdp) : TheRecord(TheRec), CDP(cdp){ - isInputPattern = isInput; + CodeGenDAGPatterns &cdp) : TheRecord(TheRec), CDP(cdp), + isInputPattern(isInput), HasError(false) { Trees.push_back(ParseTreePattern(Pat, "")); } TreePattern::TreePattern(Record *TheRec, TreePatternNode *Pat, bool isInput, - CodeGenDAGPatterns &cdp) : TheRecord(TheRec), CDP(cdp){ - isInputPattern = isInput; + CodeGenDAGPatterns &cdp) : TheRecord(TheRec), CDP(cdp), + isInputPattern(isInput), HasError(false) { Trees.push_back(Pat); } -void TreePattern::error(const std::string &Msg) const { +void TreePattern::error(const std::string &Msg) { + if (HasError) + return; dump(); - throw TGError(TheRecord->getLoc(), "In " + TheRecord->getName() + ": " + Msg); + PrintError(TheRecord->getLoc(), "In " + TheRecord->getName() + ": " + Msg); + HasError = true; } void TreePattern::ComputeNamedNodes() { @@ -1699,16 +1842,17 @@ void TreePattern::ComputeNamedNodes(TreePatternNode *N) { TreePatternNode *TreePattern::ParseTreePattern(Init *TheInit, StringRef OpName){ - if (DefInit *DI = dynamic_cast(TheInit)) { + if (DefInit *DI = dyn_cast(TheInit)) { Record *R = DI->getDef(); // Direct reference to a leaf DagNode or PatFrag? Turn it into a - // TreePatternNode if its own. For example: + // TreePatternNode of its own. For example: /// (foo GPR, imm) -> (foo GPR, (imm)) if (R->isSubClassOf("SDNode") || R->isSubClassOf("PatFrag")) - return ParseTreePattern(new DagInit(DI, "", - std::vector >()), - OpName); + return ParseTreePattern( + DagInit::get(DI, "", + std::vector >()), + OpName); // Input argument? TreePatternNode *Res = new TreePatternNode(DI, 1); @@ -1722,26 +1866,36 @@ TreePatternNode *TreePattern::ParseTreePattern(Init *TheInit, StringRef OpName){ return Res; } - if (IntInit *II = dynamic_cast(TheInit)) { + // ?:$name or just $name. + if (TheInit == UnsetInit::get()) { + if (OpName.empty()) + error("'?' argument requires a name to match with operand list"); + TreePatternNode *Res = new TreePatternNode(TheInit, 1); + Args.push_back(OpName); + Res->setName(OpName); + return Res; + } + + if (IntInit *II = dyn_cast(TheInit)) { if (!OpName.empty()) error("Constant int argument should not have a name!"); return new TreePatternNode(II, 1); } - if (BitsInit *BI = dynamic_cast(TheInit)) { + if (BitsInit *BI = dyn_cast(TheInit)) { // Turn this into an IntInit. - Init *II = BI->convertInitializerTo(new IntRecTy()); - if (II == 0 || !dynamic_cast(II)) + Init *II = BI->convertInitializerTo(IntRecTy::get()); + if (II == 0 || !isa(II)) error("Bits value must be constants!"); return ParseTreePattern(II, OpName); } - DagInit *Dag = dynamic_cast(TheInit); + DagInit *Dag = dyn_cast(TheInit); if (!Dag) { TheInit->dump(); error("Pattern has unexpected init kind!"); } - DefInit *OpDef = dynamic_cast(Dag->getOperator()); + DefInit *OpDef = dyn_cast(Dag->getOperator()); if (!OpDef) error("Pattern has unexpected operator type!"); Record *Operator = OpDef->getDef(); @@ -1819,7 +1973,7 @@ TreePatternNode *TreePattern::ParseTreePattern(Init *TheInit, StringRef OpName){ else // Otherwise, no chain. Operator = getDAGPatterns().get_intrinsic_wo_chain_sdnode(); - TreePatternNode *IIDNode = new TreePatternNode(new IntInit(IID), 1); + TreePatternNode *IIDNode = new TreePatternNode(IntInit::get(IID), 1); Children.insert(Children.begin(), IIDNode); } @@ -1869,7 +2023,7 @@ static bool SimplifyTree(TreePatternNode *&N) { /// InferAllTypes - Infer/propagate as many types throughout the expression /// patterns as possible. Return true if all types are inferred, false -/// otherwise. Throw an exception if a type contradiction is found. +/// otherwise. Flags an error if a type contradiction is found. bool TreePattern:: InferAllTypes(const StringMap > *InNamedTypes) { if (NamedNodes.empty()) @@ -1906,8 +2060,9 @@ InferAllTypes(const StringMap > *InNamedTypes) { // us to match things like: // def : Pat<(v1i64 (bitconvert(v2i32 DPR:$src))), (v1i64 DPR:$src)>; if (Nodes[i] == Trees[0] && Nodes[i]->isLeaf()) { - DefInit *DI = dynamic_cast(Nodes[i]->getLeafValue()); - if (DI && DI->getDef()->isSubClassOf("RegisterClass")) + DefInit *DI = dyn_cast(Nodes[i]->getLeafValue()); + if (DI && (DI->getDef()->isSubClassOf("RegisterClass") || + DI->getDef()->isSubClassOf("RegisterOperand"))) continue; } @@ -1989,6 +2144,9 @@ CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R) : // stores, and side effects in many cases by examining an // instruction's pattern. InferInstructionFlags(); + + // Verify that instruction flags match the patterns. + VerifyInstructionFlags(); } CodeGenDAGPatterns::~CodeGenDAGPatterns() { @@ -2028,7 +2186,7 @@ void CodeGenDAGPatterns::ParseNodeTransforms() { while (!Xforms.empty()) { Record *XFormNode = Xforms.back(); Record *SDNode = XFormNode->getValueAsDef("Opcode"); - std::string Code = XFormNode->getValueAsCode("XFormFunction"); + std::string Code = XFormNode->getValueAsString("XFormFunction"); SDNodeXForms.insert(std::make_pair(XFormNode, NodeXForm(SDNode, Code))); Xforms.pop_back(); @@ -2067,7 +2225,7 @@ void CodeGenDAGPatterns::ParsePatternFragments() { // Parse the operands list. DagInit *OpsList = Fragments[i]->getValueAsDag("Operands"); - DefInit *OpsOp = dynamic_cast(OpsList->getOperator()); + DefInit *OpsOp = dyn_cast(OpsList->getOperator()); // Special cases: ops == outs == ins. Different names are used to // improve readability. if (!OpsOp || @@ -2079,9 +2237,8 @@ void CodeGenDAGPatterns::ParsePatternFragments() { // Copy over the arguments. Args.clear(); for (unsigned j = 0, e = OpsList->getNumArgs(); j != e; ++j) { - if (!dynamic_cast(OpsList->getArg(j)) || - static_cast(OpsList->getArg(j))-> - getDef()->getName() != "node") + if (!isa(OpsList->getArg(j)) || + cast(OpsList->getArg(j))->getDef()->getName() != "node") P->error("Operands list should all be 'node' values."); if (OpsList->getArgName(j).empty()) P->error("Operands list should have names for each operand!"); @@ -2117,14 +2274,8 @@ void CodeGenDAGPatterns::ParsePatternFragments() { // Infer as many types as possible. Don't worry about it if we don't infer // all of them, some may depend on the inputs of the pattern. - try { - ThePat->InferAllTypes(); - } catch (...) { - // If this pattern fragment is not supported by this target (no types can - // satisfy its constraints), just ignore it. If the bogus pattern is - // actually used by instructions, the type consistency error will be - // reported there. - } + ThePat->InferAllTypes(); + ThePat->resetError(); // If debugging, print out the pattern fragment result. DEBUG(ThePat->dump()); @@ -2132,53 +2283,46 @@ void CodeGenDAGPatterns::ParsePatternFragments() { } void CodeGenDAGPatterns::ParseDefaultOperands() { - std::vector DefaultOps[2]; - DefaultOps[0] = Records.getAllDerivedDefinitions("PredicateOperand"); - DefaultOps[1] = Records.getAllDerivedDefinitions("OptionalDefOperand"); + std::vector DefaultOps; + DefaultOps = Records.getAllDerivedDefinitions("OperandWithDefaultOps"); // Find some SDNode. assert(!SDNodes.empty() && "No SDNodes parsed?"); - Init *SomeSDNode = new DefInit(SDNodes.begin()->first); - - for (unsigned iter = 0; iter != 2; ++iter) { - for (unsigned i = 0, e = DefaultOps[iter].size(); i != e; ++i) { - DagInit *DefaultInfo = DefaultOps[iter][i]->getValueAsDag("DefaultOps"); - - // Clone the DefaultInfo dag node, changing the operator from 'ops' to - // SomeSDnode so that we can parse this. - std::vector > Ops; - 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); - - // Create a TreePattern to parse this. - TreePattern P(DefaultOps[iter][i], DI, false, *this); - assert(P.getNumTrees() == 1 && "This ctor can only produce one tree!"); - - // Copy the operands over into a DAGDefaultOperand. - DAGDefaultOperand DefaultOpInfo; - - TreePatternNode *T = P.getTree(0); - for (unsigned op = 0, e = T->getNumChildren(); op != e; ++op) { - TreePatternNode *TPN = T->getChild(op); - while (TPN->ApplyTypeConstraints(P, false)) - /* Resolve all types */; - - if (TPN->ContainsUnresolvedType()) { - if (iter == 0) - throw "Value #" + utostr(i) + " of PredicateOperand '" + - DefaultOps[iter][i]->getName() +"' doesn't have a concrete type!"; - else - throw "Value #" + utostr(i) + " of OptionalDefOperand '" + - DefaultOps[iter][i]->getName() +"' doesn't have a concrete type!"; - } - DefaultOpInfo.DefaultOps.push_back(TPN); + Init *SomeSDNode = DefInit::get(SDNodes.begin()->first); + + for (unsigned i = 0, e = DefaultOps.size(); i != e; ++i) { + DagInit *DefaultInfo = DefaultOps[i]->getValueAsDag("DefaultOps"); + + // Clone the DefaultInfo dag node, changing the operator from 'ops' to + // SomeSDnode so that we can parse this. + std::vector > Ops; + for (unsigned op = 0, e = DefaultInfo->getNumArgs(); op != e; ++op) + Ops.push_back(std::make_pair(DefaultInfo->getArg(op), + DefaultInfo->getArgName(op))); + DagInit *DI = DagInit::get(SomeSDNode, "", Ops); + + // Create a TreePattern to parse this. + TreePattern P(DefaultOps[i], DI, false, *this); + assert(P.getNumTrees() == 1 && "This ctor can only produce one tree!"); + + // Copy the operands over into a DAGDefaultOperand. + DAGDefaultOperand DefaultOpInfo; + + TreePatternNode *T = P.getTree(0); + for (unsigned op = 0, e = T->getNumChildren(); op != e; ++op) { + TreePatternNode *TPN = T->getChild(op); + while (TPN->ApplyTypeConstraints(P, false)) + /* Resolve all types */; + + if (TPN->ContainsUnresolvedType()) { + PrintFatalError("Value #" + utostr(i) + " of OperandWithDefaultOps '" + + DefaultOps[i]->getName() +"' doesn't have a concrete type!"); } - - // Insert it into the DefaultOperands map so we can find it later. - DefaultOperands[DefaultOps[iter][i]] = DefaultOpInfo; + DefaultOpInfo.DefaultOps.push_back(TPN); } + + // Insert it into the DefaultOperands map so we can find it later. + DefaultOperands[DefaultOps[i]] = DefaultOpInfo; } } @@ -2189,8 +2333,9 @@ static bool HandleUse(TreePattern *I, TreePatternNode *Pat, // No name -> not interesting. if (Pat->getName().empty()) { if (Pat->isLeaf()) { - DefInit *DI = dynamic_cast(Pat->getLeafValue()); - if (DI && DI->getDef()->isSubClassOf("RegisterClass")) + DefInit *DI = dyn_cast(Pat->getLeafValue()); + if (DI && (DI->getDef()->isSubClassOf("RegisterClass") || + DI->getDef()->isSubClassOf("RegisterOperand"))) I->error("Input " + DI->getDef()->getName() + " must be named!"); } return false; @@ -2198,7 +2343,7 @@ static bool HandleUse(TreePattern *I, TreePatternNode *Pat, Record *Rec; if (Pat->isLeaf()) { - DefInit *DI = dynamic_cast(Pat->getLeafValue()); + DefInit *DI = dyn_cast(Pat->getLeafValue()); if (!DI) I->error("Input $" + Pat->getName() + " must be an identifier!"); Rec = DI->getDef(); } else { @@ -2216,7 +2361,7 @@ static bool HandleUse(TreePattern *I, TreePatternNode *Pat, } Record *SlotRec; if (Slot->isLeaf()) { - SlotRec = dynamic_cast(Slot->getLeafValue())->getDef(); + SlotRec = cast(Slot->getLeafValue())->getDef(); } else { assert(Slot->getNumChildren() == 0 && "can't be a use with children!"); SlotRec = Slot->getOperator(); @@ -2251,7 +2396,7 @@ FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat, if (!Dest->isLeaf()) I->error("implicitly defined value should be a register!"); - DefInit *Val = dynamic_cast(Dest->getLeafValue()); + DefInit *Val = dyn_cast(Dest->getLeafValue()); if (!Val || !Val->getDef()->isSubClassOf("Register")) I->error("implicitly defined value should be a register!"); InstImpResults.push_back(Val->getDef()); @@ -2292,11 +2437,13 @@ FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat, if (!Dest->isLeaf()) I->error("set destination should be a register!"); - DefInit *Val = dynamic_cast(Dest->getLeafValue()); + DefInit *Val = dyn_cast(Dest->getLeafValue()); if (!Val) I->error("set destination should be a register!"); if (Val->getDef()->isSubClassOf("RegisterClass") || + Val->getDef()->isSubClassOf("ValueType") || + Val->getDef()->isSubClassOf("RegisterOperand") || Val->getDef()->isSubClassOf("PointerLikeRegClass")) { if (Dest->getName().empty()) I->error("set destination must have a name!"); @@ -2321,43 +2468,36 @@ FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat, class InstAnalyzer { const CodeGenDAGPatterns &CDP; - bool &mayStore; - bool &mayLoad; - bool &IsBitcast; - bool &HasSideEffects; - bool &IsVariadic; public: - InstAnalyzer(const CodeGenDAGPatterns &cdp, - bool &maystore, bool &mayload, bool &isbc, bool &hse, bool &isv) - : CDP(cdp), mayStore(maystore), mayLoad(mayload), IsBitcast(isbc), - HasSideEffects(hse), IsVariadic(isv) { - } - - /// Analyze - Analyze the specified instruction, returning true if the - /// instruction had a pattern. - bool Analyze(Record *InstRecord) { - const TreePattern *Pattern = CDP.getInstruction(InstRecord).getPattern(); - if (Pattern == 0) { - HasSideEffects = 1; - return false; // No pattern. - } + bool hasSideEffects; + bool mayStore; + bool mayLoad; + bool isBitcast; + bool isVariadic; - // FIXME: Assume only the first tree is the pattern. The others are clobber - // nodes. - AnalyzeNode(Pattern->getTree(0)); - return true; + InstAnalyzer(const CodeGenDAGPatterns &cdp) + : CDP(cdp), hasSideEffects(false), mayStore(false), mayLoad(false), + isBitcast(false), isVariadic(false) {} + + void Analyze(const TreePattern *Pat) { + // Assume only the first tree is the pattern. The others are clobber nodes. + AnalyzeNode(Pat->getTree(0)); + } + + void Analyze(const PatternToMatch *Pat) { + AnalyzeNode(Pat->getSrcPattern()); } private: bool IsNodeBitcast(const TreePatternNode *N) const { - if (HasSideEffects || mayLoad || mayStore || IsVariadic) + if (hasSideEffects || mayLoad || mayStore || isVariadic) return false; if (N->getNumChildren() != 2) return false; const TreePatternNode *N0 = N->getChild(0); - if (!N0->isLeaf() || !dynamic_cast(N0->getLeafValue())) + if (!N0->isLeaf() || !isa(N0->getLeafValue())) return false; const TreePatternNode *N1 = N->getChild(1); @@ -2372,16 +2512,17 @@ private: return OpInfo.getEnumName() == "ISD::BITCAST"; } +public: void AnalyzeNode(const TreePatternNode *N) { if (N->isLeaf()) { - if (DefInit *DI = dynamic_cast(N->getLeafValue())) { + if (DefInit *DI = dyn_cast(N->getLeafValue())) { Record *LeafRec = DI->getDef(); // Handle ComplexPattern leaves. if (LeafRec->isSubClassOf("ComplexPattern")) { const ComplexPattern &CP = CDP.getComplexPattern(LeafRec); if (CP.hasProperty(SDNPMayStore)) mayStore = true; if (CP.hasProperty(SDNPMayLoad)) mayLoad = true; - if (CP.hasProperty(SDNPSideEffect)) HasSideEffects = true; + if (CP.hasProperty(SDNPSideEffect)) hasSideEffects = true; } } return; @@ -2393,7 +2534,7 @@ private: // Ignore set nodes, which are not SDNodes. if (N->getOperator()->getName() == "set") { - IsBitcast = IsNodeBitcast(N); + isBitcast = IsNodeBitcast(N); return; } @@ -2403,8 +2544,8 @@ private: // Notice properties of the node. if (OpInfo.hasProperty(SDNPMayStore)) mayStore = true; if (OpInfo.hasProperty(SDNPMayLoad)) mayLoad = true; - if (OpInfo.hasProperty(SDNPSideEffect)) HasSideEffects = true; - if (OpInfo.hasProperty(SDNPVariadic)) IsVariadic = true; + if (OpInfo.hasProperty(SDNPSideEffect)) hasSideEffects = true; + if (OpInfo.hasProperty(SDNPVariadic)) isVariadic = true; if (const CodeGenIntrinsic *IntInfo = N->getIntrinsicInfo(CDP)) { // If this is an intrinsic, analyze it. @@ -2416,109 +2557,134 @@ private: if (IntInfo->ModRef >= CodeGenIntrinsic::ReadWriteMem) // WriteMem intrinsics can have other strange effects. - HasSideEffects = true; + hasSideEffects = true; } } }; -static void InferFromPattern(const CodeGenInstruction &Inst, - bool &MayStore, bool &MayLoad, - bool &IsBitcast, - bool &HasSideEffects, bool &IsVariadic, - const CodeGenDAGPatterns &CDP) { - MayStore = MayLoad = IsBitcast = HasSideEffects = IsVariadic = false; - - bool HadPattern = - InstAnalyzer(CDP, MayStore, MayLoad, IsBitcast, HasSideEffects, IsVariadic) - .Analyze(Inst.TheDef); - - // InstAnalyzer only correctly analyzes mayStore/mayLoad so far. - if (Inst.mayStore) { // If the .td file explicitly sets mayStore, use it. - // If we decided that this is a store from the pattern, then the .td file - // entry is redundant. - if (MayStore) - fprintf(stderr, - "Warning: mayStore flag explicitly set on instruction '%s'" - " but flag already inferred from pattern.\n", - Inst.TheDef->getName().c_str()); - MayStore = true; +static bool InferFromPattern(CodeGenInstruction &InstInfo, + const InstAnalyzer &PatInfo, + Record *PatDef) { + bool Error = false; + + // Remember where InstInfo got its flags. + if (InstInfo.hasUndefFlags()) + InstInfo.InferredFrom = PatDef; + + // Check explicitly set flags for consistency. + if (InstInfo.hasSideEffects != PatInfo.hasSideEffects && + !InstInfo.hasSideEffects_Unset) { + // Allow explicitly setting hasSideEffects = 1 on instructions, even when + // the pattern has no side effects. That could be useful for div/rem + // instructions that may trap. + if (!InstInfo.hasSideEffects) { + Error = true; + PrintError(PatDef->getLoc(), "Pattern doesn't match hasSideEffects = " + + Twine(InstInfo.hasSideEffects)); + } } - if (Inst.mayLoad) { // If the .td file explicitly sets mayLoad, use it. - // If we decided that this is a load from the pattern, then the .td file - // entry is redundant. - if (MayLoad) - fprintf(stderr, - "Warning: mayLoad flag explicitly set on instruction '%s'" - " but flag already inferred from pattern.\n", - Inst.TheDef->getName().c_str()); - MayLoad = true; + if (InstInfo.mayStore != PatInfo.mayStore && !InstInfo.mayStore_Unset) { + Error = true; + PrintError(PatDef->getLoc(), "Pattern doesn't match mayStore = " + + Twine(InstInfo.mayStore)); } - if (Inst.neverHasSideEffects) { - if (HadPattern) - fprintf(stderr, "Warning: neverHasSideEffects set on instruction '%s' " - "which already has a pattern\n", Inst.TheDef->getName().c_str()); - HasSideEffects = false; + if (InstInfo.mayLoad != PatInfo.mayLoad && !InstInfo.mayLoad_Unset) { + // Allow explicitly setting mayLoad = 1, even when the pattern has no loads. + // Some targets translate imediates to loads. + if (!InstInfo.mayLoad) { + Error = true; + PrintError(PatDef->getLoc(), "Pattern doesn't match mayLoad = " + + Twine(InstInfo.mayLoad)); + } } - if (Inst.hasSideEffects) { - if (HasSideEffects) - fprintf(stderr, "Warning: hasSideEffects set on instruction '%s' " - "which already inferred this.\n", Inst.TheDef->getName().c_str()); - HasSideEffects = true; + // Transfer inferred flags. + InstInfo.hasSideEffects |= PatInfo.hasSideEffects; + InstInfo.mayStore |= PatInfo.mayStore; + InstInfo.mayLoad |= PatInfo.mayLoad; + + // These flags are silently added without any verification. + InstInfo.isBitcast |= PatInfo.isBitcast; + + // Don't infer isVariadic. This flag means something different on SDNodes and + // instructions. For example, a CALL SDNode is variadic because it has the + // call arguments as operands, but a CALL instruction is not variadic - it + // has argument registers as implicit, not explicit uses. + + return Error; +} + +/// hasNullFragReference - Return true if the DAG has any reference to the +/// null_frag operator. +static bool hasNullFragReference(DagInit *DI) { + DefInit *OpDef = dyn_cast(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 = dyn_cast(DI->getArg(i)); + if (Arg && hasNullFragReference(Arg)) + return true; } - if (Inst.Operands.isVariadic) - IsVariadic = true; // Can warn if we want. + return false; } -/// ParseInstructions - Parse all of the instructions, inlining and resolving -/// any fragments involved. This populates the Instructions list with fully -/// resolved instructions. -void CodeGenDAGPatterns::ParseInstructions() { - std::vector Instrs = Records.getAllDerivedDefinitions("Instruction"); +/// 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 = dyn_cast(LI->getElement(i)); + assert(DI && "non-dag in an instruction Pattern list?!"); + if (hasNullFragReference(DI)) + return true; + } + return false; +} - for (unsigned i = 0, e = Instrs.size(); i != e; ++i) { - ListInit *LI = 0; +/// Get all the instructions in a tree. +static void +getInstructionsInTree(TreePatternNode *Tree, SmallVectorImpl &Instrs) { + if (Tree->isLeaf()) + return; + if (Tree->getOperator()->isSubClassOf("Instruction")) + Instrs.push_back(Tree->getOperator()); + for (unsigned i = 0, e = Tree->getNumChildren(); i != e; ++i) + getInstructionsInTree(Tree->getChild(i), Instrs); +} - if (dynamic_cast(Instrs[i]->getValueInit("Pattern"))) - LI = Instrs[i]->getValueAsListInit("Pattern"); +/// Check the class of a pattern leaf node against the instruction operand it +/// represents. +static bool checkOperandClass(CGIOperandList::OperandInfo &OI, + Record *Leaf) { + if (OI.Rec == Leaf) + return true; - // 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) { - std::vector Results; - std::vector Operands; + // Allow direct value types to be used in instruction set patterns. + // The type will be checked later. + if (Leaf->isSubClassOf("ValueType")) + return true; - CodeGenInstruction &InstInfo = Target.getInstruction(Instrs[i]); + // Patterns can also be ComplexPattern instances. + if (Leaf->isSubClassOf("ComplexPattern")) + return true; - if (InstInfo.Operands.size() != 0) { - if (InstInfo.Operands.NumDefs == 0) { - // These produce no results - for (unsigned j = 0, e = InstInfo.Operands.size(); j < e; ++j) - Operands.push_back(InstInfo.Operands[j].Rec); - } else { - // Assume the first operand is the result. - Results.push_back(InstInfo.Operands[0].Rec); + return false; +} - // The rest are inputs. - for (unsigned j = 1, e = InstInfo.Operands.size(); j < e; ++j) - Operands.push_back(InstInfo.Operands[j].Rec); - } - } +const DAGInstruction &CodeGenDAGPatterns::parseInstructionPattern( + CodeGenInstruction &CGI, ListInit *Pat, DAGInstMap &DAGInsts) { - // Create and insert the instruction. - std::vector ImpResults; - Instructions.insert(std::make_pair(Instrs[i], - DAGInstruction(0, Results, Operands, ImpResults))); - continue; // no pattern. - } + assert(!DAGInsts.count(CGI.TheDef) && "Instruction already parsed!"); // Parse the instruction. - TreePattern *I = new TreePattern(Instrs[i], LI, true, *this); + TreePattern *I = new TreePattern(CGI.TheDef, Pat, true, *this); // Inline pattern fragments into it. I->InlinePatternFragments(); @@ -2557,7 +2723,6 @@ void CodeGenDAGPatterns::ParseInstructions() { // Parse the operands list from the (ops) list, validating it. assert(I->getArgList().empty() && "Args list should still be empty here!"); - CodeGenInstruction &CGI = Target.getInstruction(Instrs[i]); // Check that all of the results occur first in the list. std::vector Results; @@ -2575,12 +2740,12 @@ void CodeGenDAGPatterns::ParseInstructions() { if (i == 0) Res0Node = RNode; - Record *R = dynamic_cast(RNode->getLeafValue())->getDef(); + Record *R = cast(RNode->getLeafValue())->getDef(); if (R == 0) I->error("Operand $" + OpName + " should be a set destination: all " "outputs must occur before inputs in operand list!"); - if (CGI.Operands[i].Rec != R) + if (!checkOperandClass(CGI.Operands[i], R)) I->error("Operand $" + OpName + " class mismatch!"); // Remember the return type. @@ -2603,11 +2768,9 @@ void CodeGenDAGPatterns::ParseInstructions() { I->error("Operand #" + utostr(i) + " in operands list has no name!"); if (!InstInputsCheck.count(OpName)) { - // If this is an predicate operand or optional def operand with an - // DefaultOps set filled in, we can ignore this. When we codegen it, - // we will do so as always executed. - if (Op.Rec->isSubClassOf("PredicateOperand") || - Op.Rec->isSubClassOf("OptionalDefOperand")) { + // If this is an operand with a DefaultOps set filled in, we can ignore + // this. When we codegen it, we will do so as always executed. + if (Op.Rec->isSubClassOf("OperandWithDefaultOps")) { // Does it have a non-empty DefaultOps field? If so, ignore this // operand. if (!getDefaultOperand(Op.Rec).DefaultOps.empty()) @@ -2619,10 +2782,9 @@ void CodeGenDAGPatterns::ParseInstructions() { TreePatternNode *InVal = InstInputsCheck[OpName]; InstInputsCheck.erase(OpName); // It occurred, remove from map. - if (InVal->isLeaf() && - dynamic_cast(InVal->getLeafValue())) { + if (InVal->isLeaf() && isa(InVal->getLeafValue())) { Record *InRec = static_cast(InVal->getLeafValue())->getDef(); - if (Op.Rec != InRec && !InRec->isSubClassOf("ComplexPattern")) + if (!checkOperandClass(Op, InRec)) I->error("Operand $" + OpName + "'s register class disagrees" " between the operand and pattern"); } @@ -2659,26 +2821,79 @@ void CodeGenDAGPatterns::ParseInstructions() { // Create and insert the instruction. // FIXME: InstImpResults should not be part of DAGInstruction. DAGInstruction TheInst(I, Results, Operands, InstImpResults); - Instructions.insert(std::make_pair(I->getRecord(), TheInst)); + DAGInsts.insert(std::make_pair(I->getRecord(), TheInst)); // Use a temporary tree pattern to infer all types and make sure that the // constructed result is correct. This depends on the instruction already - // being inserted into the Instructions map. + // being inserted into the DAGInsts map. TreePattern Temp(I->getRecord(), ResultPattern, false, *this); Temp.InferAllTypes(&I->getNamedNodesMap()); - DAGInstruction &TheInsertedInst = Instructions.find(I->getRecord())->second; + DAGInstruction &TheInsertedInst = DAGInsts.find(I->getRecord())->second; TheInsertedInst.setResultPattern(Temp.getOnlyTree()); - DEBUG(I->dump()); + return TheInsertedInst; + } + +/// ParseInstructions - Parse all of the instructions, inlining and resolving +/// any fragments involved. This populates the Instructions list with fully +/// resolved instructions. +void CodeGenDAGPatterns::ParseInstructions() { + std::vector Instrs = Records.getAllDerivedDefinitions("Instruction"); + + for (unsigned i = 0, e = Instrs.size(); i != e; ++i) { + ListInit *LI = 0; + + if (isa(Instrs[i]->getValueInit("Pattern"))) + LI = Instrs[i]->getValueAsListInit("Pattern"); + + // 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. 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 Results; + std::vector Operands; + + CodeGenInstruction &InstInfo = Target.getInstruction(Instrs[i]); + + if (InstInfo.Operands.size() != 0) { + if (InstInfo.Operands.NumDefs == 0) { + // These produce no results + for (unsigned j = 0, e = InstInfo.Operands.size(); j < e; ++j) + Operands.push_back(InstInfo.Operands[j].Rec); + } else { + // Assume the first operand is the result. + Results.push_back(InstInfo.Operands[0].Rec); + + // The rest are inputs. + for (unsigned j = 1, e = InstInfo.Operands.size(); j < e; ++j) + Operands.push_back(InstInfo.Operands[j].Rec); + } + } + + // Create and insert the instruction. + std::vector ImpResults; + Instructions.insert(std::make_pair(Instrs[i], + DAGInstruction(0, Results, Operands, ImpResults))); + continue; // no pattern. + } + + CodeGenInstruction &CGI = Target.getInstruction(Instrs[i]); + const DAGInstruction &DI = parseInstructionPattern(CGI, LI, Instructions); + + (void)DI; + DEBUG(DI.getPattern()->dump()); } // If we can, convert the instructions to be patterns that are matched! - for (std::map::iterator II = + for (std::map::iterator II = Instructions.begin(), E = Instructions.end(); II != E; ++II) { DAGInstruction &TheInst = II->second; - const TreePattern *I = TheInst.getPattern(); + TreePattern *I = TheInst.getPattern(); if (I == 0) continue; // No pattern. // FIXME: Assume only the first tree is the pattern. The others are clobber @@ -2709,7 +2924,7 @@ typedef std::pair NameRecord; static void FindNames(const TreePatternNode *P, std::map &Names, - const TreePattern *PatternTop) { + TreePattern *PatternTop) { if (!P->getName().empty()) { NameRecord &Rec = Names[P->getName()]; // If this is the first instance of the name, remember the node. @@ -2726,12 +2941,15 @@ static void FindNames(const TreePatternNode *P, } } -void CodeGenDAGPatterns::AddPatternToMatch(const TreePattern *Pattern, +void CodeGenDAGPatterns::AddPatternToMatch(TreePattern *Pattern, const PatternToMatch &PTM) { // Do some sanity checking on the pattern we're about to match. std::string Reason; - if (!PTM.getSrcPattern()->canPatternMatch(Reason, *this)) - Pattern->error("Pattern can never match: " + Reason); + if (!PTM.getSrcPattern()->canPatternMatch(Reason, *this)) { + PrintWarning(Pattern->getRecord()->getLoc(), + Twine("Pattern can never match: ") + Reason); + return; + } // If the source pattern's root is a complex pattern, that complex pattern // must specify the nodes it can potentially match. @@ -2772,19 +2990,156 @@ void CodeGenDAGPatterns::AddPatternToMatch(const TreePattern *Pattern, void CodeGenDAGPatterns::InferInstructionFlags() { const std::vector &Instructions = Target.getInstructionsByEnumValue(); + + // First try to infer flags from the primary instruction pattern, if any. + SmallVector Revisit; + unsigned Errors = 0; for (unsigned i = 0, e = Instructions.size(); i != e; ++i) { CodeGenInstruction &InstInfo = const_cast(*Instructions[i]); - // Determine properties of the instruction from its pattern. - bool MayStore, MayLoad, IsBitcast, HasSideEffects, IsVariadic; - InferFromPattern(InstInfo, MayStore, MayLoad, IsBitcast, - HasSideEffects, IsVariadic, *this); - InstInfo.mayStore = MayStore; - InstInfo.mayLoad = MayLoad; - InstInfo.isBitcast = IsBitcast; - InstInfo.hasSideEffects = HasSideEffects; - InstInfo.Operands.isVariadic = IsVariadic; + + // Treat neverHasSideEffects = 1 as the equivalent of hasSideEffects = 0. + // This flag is obsolete and will be removed. + if (InstInfo.neverHasSideEffects) { + assert(!InstInfo.hasSideEffects); + InstInfo.hasSideEffects_Unset = false; + } + + // Get the primary instruction pattern. + const TreePattern *Pattern = getInstruction(InstInfo.TheDef).getPattern(); + if (!Pattern) { + if (InstInfo.hasUndefFlags()) + Revisit.push_back(&InstInfo); + continue; + } + InstAnalyzer PatInfo(*this); + PatInfo.Analyze(Pattern); + Errors += InferFromPattern(InstInfo, PatInfo, InstInfo.TheDef); + } + + // Second, look for single-instruction patterns defined outside the + // instruction. + for (ptm_iterator I = ptm_begin(), E = ptm_end(); I != E; ++I) { + const PatternToMatch &PTM = *I; + + // We can only infer from single-instruction patterns, otherwise we won't + // know which instruction should get the flags. + SmallVector PatInstrs; + getInstructionsInTree(PTM.getDstPattern(), PatInstrs); + if (PatInstrs.size() != 1) + continue; + + // Get the single instruction. + CodeGenInstruction &InstInfo = Target.getInstruction(PatInstrs.front()); + + // Only infer properties from the first pattern. We'll verify the others. + if (InstInfo.InferredFrom) + continue; + + InstAnalyzer PatInfo(*this); + PatInfo.Analyze(&PTM); + Errors += InferFromPattern(InstInfo, PatInfo, PTM.getSrcRecord()); + } + + if (Errors) + PrintFatalError("pattern conflicts"); + + // Revisit instructions with undefined flags and no pattern. + if (Target.guessInstructionProperties()) { + for (unsigned i = 0, e = Revisit.size(); i != e; ++i) { + CodeGenInstruction &InstInfo = *Revisit[i]; + if (InstInfo.InferredFrom) + continue; + // The mayLoad and mayStore flags default to false. + // Conservatively assume hasSideEffects if it wasn't explicit. + if (InstInfo.hasSideEffects_Unset) + InstInfo.hasSideEffects = true; + } + return; + } + + // Complain about any flags that are still undefined. + for (unsigned i = 0, e = Revisit.size(); i != e; ++i) { + CodeGenInstruction &InstInfo = *Revisit[i]; + if (InstInfo.InferredFrom) + continue; + if (InstInfo.hasSideEffects_Unset) + PrintError(InstInfo.TheDef->getLoc(), + "Can't infer hasSideEffects from patterns"); + if (InstInfo.mayStore_Unset) + PrintError(InstInfo.TheDef->getLoc(), + "Can't infer mayStore from patterns"); + if (InstInfo.mayLoad_Unset) + PrintError(InstInfo.TheDef->getLoc(), + "Can't infer mayLoad from patterns"); + } +} + + +/// Verify instruction flags against pattern node properties. +void CodeGenDAGPatterns::VerifyInstructionFlags() { + unsigned Errors = 0; + for (ptm_iterator I = ptm_begin(), E = ptm_end(); I != E; ++I) { + const PatternToMatch &PTM = *I; + SmallVector Instrs; + getInstructionsInTree(PTM.getDstPattern(), Instrs); + if (Instrs.empty()) + continue; + + // Count the number of instructions with each flag set. + unsigned NumSideEffects = 0; + unsigned NumStores = 0; + unsigned NumLoads = 0; + for (unsigned i = 0, e = Instrs.size(); i != e; ++i) { + const CodeGenInstruction &InstInfo = Target.getInstruction(Instrs[i]); + NumSideEffects += InstInfo.hasSideEffects; + NumStores += InstInfo.mayStore; + NumLoads += InstInfo.mayLoad; + } + + // Analyze the source pattern. + InstAnalyzer PatInfo(*this); + PatInfo.Analyze(&PTM); + + // Collect error messages. + SmallVector Msgs; + + // Check for missing flags in the output. + // Permit extra flags for now at least. + if (PatInfo.hasSideEffects && !NumSideEffects) + Msgs.push_back("pattern has side effects, but hasSideEffects isn't set"); + + // Don't verify store flags on instructions with side effects. At least for + // intrinsics, side effects implies mayStore. + if (!PatInfo.hasSideEffects && PatInfo.mayStore && !NumStores) + Msgs.push_back("pattern may store, but mayStore isn't set"); + + // Similarly, mayStore implies mayLoad on intrinsics. + if (!PatInfo.mayStore && PatInfo.mayLoad && !NumLoads) + Msgs.push_back("pattern may load, but mayLoad isn't set"); + + // Print error messages. + if (Msgs.empty()) + continue; + ++Errors; + + for (unsigned i = 0, e = Msgs.size(); i != e; ++i) + PrintError(PTM.getSrcRecord()->getLoc(), Twine(Msgs[i]) + " on the " + + (Instrs.size() == 1 ? + "instruction" : "output instructions")); + // Provide the location of the relevant instruction definitions. + for (unsigned i = 0, e = Instrs.size(); i != e; ++i) { + if (Instrs[i] != PTM.getSrcRecord()) + PrintError(Instrs[i]->getLoc(), "defined here"); + const CodeGenInstruction &InstInfo = Target.getInstruction(Instrs[i]); + if (InstInfo.InferredFrom && + InstInfo.InferredFrom != InstInfo.TheDef && + InstInfo.InferredFrom != PTM.getSrcRecord()) + PrintError(InstInfo.InferredFrom->getLoc(), "inferred from patttern"); + } } + if (Errors) + PrintFatalError("Errors in DAG patterns"); } /// Given a pattern result with an unresolved type, see if we can find one @@ -2822,6 +3177,11 @@ void CodeGenDAGPatterns::ParsePatterns() { for (unsigned i = 0, e = Patterns.size(); i != e; ++i) { Record *CurPattern = Patterns[i]; DagInit *Tree = CurPattern->getValueAsDag("PatternToMatch"); + + // If the pattern references the null_frag, there's nothing to do. + if (hasNullFragReference(Tree)) + continue; + TreePattern *Pattern = new TreePattern(CurPattern, Tree, true, *this); // Inline pattern fragments into it. @@ -3139,7 +3499,7 @@ static void GenerateVariantsOf(TreePatternNode *N, for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) { TreePatternNode *Child = N->getChild(i); if (Child->isLeaf()) - if (DefInit *DI = dynamic_cast(Child->getLeafValue())) { + if (DefInit *DI = dyn_cast(Child->getLeafValue())) { Record *RR = DI->getDef(); if (RR->isSubClassOf("Register")) continue; @@ -3239,4 +3599,3 @@ void CodeGenDAGPatterns::GenerateVariants() { DEBUG(errs() << "\n"); } } -