X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FCodeGenDAGPatterns.cpp;h=fab41c5f4c46fa3aea536c23e6d7e15a8b5f4d1a;hb=74f2ca8c4aa28cbb36c950b11416263eb6315593;hp=eb0b0990488bc3d8ae74e30f9df9ac7deb8b3784;hpb=f8c7394781f7cf27ac52ca087e289436d36844da;p=oota-llvm.git diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index eb0b0990488..fab41c5f4c4 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -16,9 +16,9 @@ #include "Record.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/Streams.h" #include #include +#include using namespace llvm; //===----------------------------------------------------------------------===// @@ -55,15 +55,15 @@ ConvertVTs(const std::vector &InVTs) { } static inline bool isInteger(MVT::SimpleValueType VT) { - return MVT(VT).isInteger(); + return EVT(VT).isInteger(); } static inline bool isFloatingPoint(MVT::SimpleValueType VT) { - return MVT(VT).isFloatingPoint(); + return EVT(VT).isFloatingPoint(); } static inline bool isVector(MVT::SimpleValueType VT) { - return MVT(VT).isVector(); + return EVT(VT).isVector(); } static bool LHSIsSubsetOfRHS(const std::vector &LHS, @@ -76,23 +76,33 @@ static bool LHSIsSubsetOfRHS(const std::vector &LHS, } namespace llvm { -namespace EMVT { +namespace EEVT { /// isExtIntegerInVTs - Return true if the specified extended value type vector -/// contains isInt or an integer value type. +/// contains iAny or an integer value type. bool isExtIntegerInVTs(const std::vector &EVTs) { assert(!EVTs.empty() && "Cannot check for integer in empty ExtVT list!"); - return EVTs[0] == isInt || !(FilterEVTs(EVTs, isInteger).empty()); + return EVTs[0] == MVT::iAny || !(FilterEVTs(EVTs, isInteger).empty()); } /// isExtFloatingPointInVTs - Return true if the specified extended value type -/// vector contains isFP or a FP value type. +/// vector contains fAny or a FP value type. bool isExtFloatingPointInVTs(const std::vector &EVTs) { - assert(!EVTs.empty() && "Cannot check for integer in empty ExtVT list!"); - return EVTs[0] == isFP || !(FilterEVTs(EVTs, isFloatingPoint).empty()); + assert(!EVTs.empty() && "Cannot check for FP in empty ExtVT list!"); + return EVTs[0] == MVT::fAny || !(FilterEVTs(EVTs, isFloatingPoint).empty()); +} + +/// isExtVectorInVTs - Return true if the specified extended value type +/// vector contains vAny or a vector value type. +bool isExtVectorInVTs(const std::vector &EVTs) { + assert(!EVTs.empty() && "Cannot check for vector in empty ExtVT list!"); + return EVTs[0] == MVT::vAny || !(FilterEVTs(EVTs, isVector).empty()); } -} // end namespace EMVT. +} // end namespace EEVT. } // end namespace llvm. +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; @@ -128,14 +138,14 @@ void FindDepVars(TreePatternNode *N, MultipleUseVarSet &DepVars) { //! Dump the dependent variable set: void DumpDepVars(MultipleUseVarSet &DepVars) { if (DepVars.empty()) { - DOUT << ""; + DEBUG(errs() << ""); } else { - DOUT << "[ "; + DEBUG(errs() << "[ "); for (MultipleUseVarSet::const_iterator i = DepVars.begin(), e = DepVars.end(); i != e; ++i) { - DOUT << (*i) << " "; + DEBUG(errs() << (*i) << " "); } - DOUT << "]"; + DEBUG(errs() << "]"); } } } @@ -183,6 +193,8 @@ SDTypeConstraint::SDTypeConstraint(Record *R) { ConstraintType = SDTCisInt; } else if (R->isSubClassOf("SDTCisFP")) { ConstraintType = SDTCisFP; + } else if (R->isSubClassOf("SDTCisVec")) { + ConstraintType = SDTCisVec; } else if (R->isSubClassOf("SDTCisSameAs")) { ConstraintType = SDTCisSameAs; x.SDTCisSameAs_Info.OtherOperandNum = R->getValueAsInt("OtherOperandNum"); @@ -194,16 +206,12 @@ SDTypeConstraint::SDTypeConstraint(Record *R) { ConstraintType = SDTCisOpSmallerThanOp; x.SDTCisOpSmallerThanOp_Info.BigOperandNum = R->getValueAsInt("BigOperandNum"); - } else if (R->isSubClassOf("SDTCisIntVectorOfSameSize")) { - ConstraintType = SDTCisIntVectorOfSameSize; - x.SDTCisIntVectorOfSameSize_Info.OtherOperandNum = - R->getValueAsInt("OtherOpNum"); } else if (R->isSubClassOf("SDTCisEltOfVec")) { ConstraintType = SDTCisEltOfVec; x.SDTCisEltOfVec_Info.OtherOperandNum = R->getValueAsInt("OtherOpNum"); } else { - cerr << "Unrecognized SDTypeConstraint '" << R->getName() << "'!\n"; + errs() << "Unrecognized SDTypeConstraint '" << R->getName() << "'!\n"; exit(1); } } @@ -217,9 +225,9 @@ TreePatternNode *SDTypeConstraint::getOperandNum(unsigned OpNo, "We only work with nodes with zero or one result so far!"); if (OpNo >= (NumResults + N->getNumChildren())) { - cerr << "Invalid operand number " << OpNo << " "; + errs() << "Invalid operand number " << OpNo << " "; N->dump(); - cerr << '\n'; + errs() << '\n'; exit(1); } @@ -268,7 +276,7 @@ bool SDTypeConstraint::ApplyTypeConstraint(TreePatternNode *N, // If we found exactly one supported integer type, apply it. if (IntVTs.size() == 1) return NodeToApply->UpdateNodeType(IntVTs[0], TP); - return NodeToApply->UpdateNodeType(EMVT::isInt, TP); + return NodeToApply->UpdateNodeType(MVT::iAny, TP); } case SDTCisFP: { // If there is only one FP type supported, this must be it. @@ -278,7 +286,17 @@ bool SDTypeConstraint::ApplyTypeConstraint(TreePatternNode *N, // If we found exactly one supported FP type, apply it. if (FPVTs.size() == 1) return NodeToApply->UpdateNodeType(FPVTs[0], TP); - return NodeToApply->UpdateNodeType(EMVT::isFP, TP); + return NodeToApply->UpdateNodeType(MVT::fAny, TP); + } + case SDTCisVec: { + // If there is only one vector type supported, this must be it. + std::vector VecVTs = + FilterVTs(CGT.getLegalValueTypes(), isVector); + + // If we found exactly one supported vector type, apply it. + if (VecVTs.size() == 1) + return NodeToApply->UpdateNodeType(VecVTs[0], TP); + return NodeToApply->UpdateNodeType(MVT::vAny, TP); } case SDTCisSameAs: { TreePatternNode *OtherNode = @@ -304,7 +322,7 @@ bool SDTypeConstraint::ApplyTypeConstraint(TreePatternNode *N, // It must be integer. bool MadeChange = false; - MadeChange |= OtherNode->UpdateNodeType(EMVT::isInt, TP); + MadeChange |= OtherNode->UpdateNodeType(MVT::iAny, 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 @@ -324,25 +342,25 @@ bool SDTypeConstraint::ApplyTypeConstraint(TreePatternNode *N, // 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(!(EMVT::isExtIntegerInVTs(NodeToApply->getExtTypes()) && - EMVT::isExtFloatingPointInVTs(NodeToApply->getExtTypes())) && - !(EMVT::isExtIntegerInVTs(BigOperand->getExtTypes()) && - EMVT::isExtFloatingPointInVTs(BigOperand->getExtTypes())) && + assert(!(EEVT::isExtIntegerInVTs(NodeToApply->getExtTypes()) && + EEVT::isExtFloatingPointInVTs(NodeToApply->getExtTypes())) && + !(EEVT::isExtIntegerInVTs(BigOperand->getExtTypes()) && + EEVT::isExtFloatingPointInVTs(BigOperand->getExtTypes())) && "SDTCisOpSmallerThanOp does not handle mixed int/fp types!"); - 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); + if (EEVT::isExtIntegerInVTs(NodeToApply->getExtTypes())) + MadeChange |= BigOperand->UpdateNodeType(MVT::iAny, TP); + else if (EEVT::isExtFloatingPointInVTs(NodeToApply->getExtTypes())) + MadeChange |= BigOperand->UpdateNodeType(MVT::fAny, TP); + if (EEVT::isExtIntegerInVTs(BigOperand->getExtTypes())) + MadeChange |= NodeToApply->UpdateNodeType(MVT::iAny, TP); + else if (EEVT::isExtFloatingPointInVTs(BigOperand->getExtTypes())) + MadeChange |= NodeToApply->UpdateNodeType(MVT::fAny, TP); std::vector VTs = CGT.getLegalValueTypes(); - if (EMVT::isExtIntegerInVTs(NodeToApply->getExtTypes())) { + if (EEVT::isExtIntegerInVTs(NodeToApply->getExtTypes())) { VTs = FilterVTs(VTs, isInteger); - } else if (EMVT::isExtFloatingPointInVTs(NodeToApply->getExtTypes())) { + } else if (EEVT::isExtFloatingPointInVTs(NodeToApply->getExtTypes())) { VTs = FilterVTs(VTs, isFloatingPoint); } else { VTs.clear(); @@ -365,30 +383,16 @@ bool SDTypeConstraint::ApplyTypeConstraint(TreePatternNode *N, } return MadeChange; } - case SDTCisIntVectorOfSameSize: { - TreePatternNode *OtherOperand = - getOperandNum(x.SDTCisIntVectorOfSameSize_Info.OtherOperandNum, - N, NumResults); - if (OtherOperand->hasTypeSet()) { - if (!isVector(OtherOperand->getTypeNum(0))) - TP.error(N->getOperator()->getName() + " VT operand must be a vector!"); - MVT IVT = OtherOperand->getTypeNum(0); - unsigned NumElements = IVT.getVectorNumElements(); - IVT = MVT::getIntVectorWithNumElements(NumElements); - return NodeToApply->UpdateNodeType(IVT.getSimpleVT(), TP); - } - return false; - } case SDTCisEltOfVec: { TreePatternNode *OtherOperand = - getOperandNum(x.SDTCisIntVectorOfSameSize_Info.OtherOperandNum, + getOperandNum(x.SDTCisEltOfVec_Info.OtherOperandNum, N, NumResults); if (OtherOperand->hasTypeSet()) { if (!isVector(OtherOperand->getTypeNum(0))) TP.error(N->getOperator()->getName() + " VT operand must be a vector!"); - MVT IVT = OtherOperand->getTypeNum(0); + EVT IVT = OtherOperand->getTypeNum(0); IVT = IVT.getVectorElementType(); - return NodeToApply->UpdateNodeType(IVT.getSimpleVT(), TP); + return NodeToApply->UpdateNodeType(IVT.getSimpleVT().SimpleTy, TP); } return false; } @@ -431,8 +435,8 @@ SDNodeInfo::SDNodeInfo(Record *R) : Def(R) { } else if (PropList[i]->getName() == "SDNPMemOperand") { Properties |= 1 << SDNPMemOperand; } else { - cerr << "Unknown SD Node property '" << PropList[i]->getName() - << "' on node '" << R->getName() << "'!\n"; + errs() << "Unknown SD Node property '" << PropList[i]->getName() + << "' on node '" << R->getName() << "'!\n"; exit(1); } } @@ -463,7 +467,7 @@ bool TreePatternNode::UpdateNodeType(const std::vector &ExtVTs, TreePattern &TP) { assert(!ExtVTs.empty() && "Cannot update node type with empty type vector!"); - if (ExtVTs[0] == EMVT::isUnknown || LHSIsSubsetOfRHS(getExtTypes(), ExtVTs)) + if (ExtVTs[0] == EEVT::isUnknown || LHSIsSubsetOfRHS(getExtTypes(), ExtVTs)) return false; if (isTypeCompletelyUnknown() || LHSIsSubsetOfRHS(ExtVTs, getExtTypes())) { setTypes(ExtVTs); @@ -472,9 +476,9 @@ bool TreePatternNode::UpdateNodeType(const std::vector &ExtVTs, if (getExtTypeNum(0) == MVT::iPTR || getExtTypeNum(0) == MVT::iPTRAny) { if (ExtVTs[0] == MVT::iPTR || ExtVTs[0] == MVT::iPTRAny || - ExtVTs[0] == EMVT::isInt) + ExtVTs[0] == MVT::iAny) return false; - if (EMVT::isExtIntegerInVTs(ExtVTs)) { + if (EEVT::isExtIntegerInVTs(ExtVTs)) { std::vector FVTs = FilterEVTs(ExtVTs, isInteger); if (FVTs.size()) { setTypes(ExtVTs); @@ -483,8 +487,19 @@ bool TreePatternNode::UpdateNodeType(const std::vector &ExtVTs, } } - if ((ExtVTs[0] == EMVT::isInt || ExtVTs[0] == MVT::iAny) && - EMVT::isExtIntegerInVTs(getExtTypes())) { + // Merge vAny with iAny/fAny. The latter include vector types so keep them + // as the more specific information. + if (ExtVTs[0] == MVT::vAny && + (getExtTypeNum(0) == MVT::iAny || getExtTypeNum(0) == MVT::fAny)) + return false; + if (getExtTypeNum(0) == MVT::vAny && + (ExtVTs[0] == MVT::iAny || ExtVTs[0] == MVT::fAny)) { + setTypes(ExtVTs); + return true; + } + + if (ExtVTs[0] == MVT::iAny && + EEVT::isExtIntegerInVTs(getExtTypes())) { assert(hasTypeSet() && "should be handled above!"); std::vector FVTs = FilterEVTs(getExtTypes(), isInteger); if (getExtTypes() == FVTs) @@ -493,7 +508,7 @@ bool TreePatternNode::UpdateNodeType(const std::vector &ExtVTs, return true; } if ((ExtVTs[0] == MVT::iPTR || ExtVTs[0] == MVT::iPTRAny) && - EMVT::isExtIntegerInVTs(getExtTypes())) { + EEVT::isExtIntegerInVTs(getExtTypes())) { //assert(hasTypeSet() && "should be handled above!"); std::vector FVTs = FilterEVTs(getExtTypes(), isInteger); if (getExtTypes() == FVTs) @@ -503,8 +518,8 @@ bool TreePatternNode::UpdateNodeType(const std::vector &ExtVTs, return true; } } - if ((ExtVTs[0] == EMVT::isFP || ExtVTs[0] == MVT::fAny) && - EMVT::isExtFloatingPointInVTs(getExtTypes())) { + if (ExtVTs[0] == MVT::fAny && + EEVT::isExtFloatingPointInVTs(getExtTypes())) { assert(hasTypeSet() && "should be handled above!"); std::vector FVTs = FilterEVTs(getExtTypes(), isFloatingPoint); @@ -513,20 +528,31 @@ bool TreePatternNode::UpdateNodeType(const std::vector &ExtVTs, setTypes(FVTs); return true; } - - // If we know this is an int or fp type, and we are told it is a specific one, - // take the advice. + if (ExtVTs[0] == MVT::vAny && + EEVT::isExtVectorInVTs(getExtTypes())) { + assert(hasTypeSet() && "should be handled above!"); + std::vector FVTs = FilterEVTs(getExtTypes(), isVector); + if (getExtTypes() == FVTs) + return false; + setTypes(FVTs); + return true; + } + + // If we know this is an int, FP, or vector type, and we are told it is a + // specific one, take the advice. // // Similarly, we should probably set the type here to the intersection of - // {isInt|isFP} and ExtVTs - if (((getExtTypeNum(0) == EMVT::isInt || getExtTypeNum(0) == MVT::iAny) && - EMVT::isExtIntegerInVTs(ExtVTs)) || - ((getExtTypeNum(0) == EMVT::isFP || getExtTypeNum(0) == MVT::fAny) && - EMVT::isExtFloatingPointInVTs(ExtVTs))) { + // {iAny|fAny|vAny} and ExtVTs + if ((getExtTypeNum(0) == MVT::iAny && + EEVT::isExtIntegerInVTs(ExtVTs)) || + (getExtTypeNum(0) == MVT::fAny && + EEVT::isExtFloatingPointInVTs(ExtVTs)) || + (getExtTypeNum(0) == MVT::vAny && + EEVT::isExtVectorInVTs(ExtVTs))) { setTypes(ExtVTs); return true; } - if (getExtTypeNum(0) == EMVT::isInt && + if (getExtTypeNum(0) == MVT::iAny && (ExtVTs[0] == MVT::iPTR || ExtVTs[0] == MVT::iPTRAny)) { setTypes(ExtVTs); return true; @@ -534,7 +560,7 @@ bool TreePatternNode::UpdateNodeType(const std::vector &ExtVTs, if (isLeaf()) { dump(); - cerr << " "; + errs() << " "; TP.error("Type inference contradiction found in node!"); } else { TP.error("Type inference contradiction found in node " + @@ -544,7 +570,7 @@ bool TreePatternNode::UpdateNodeType(const std::vector &ExtVTs, } -void TreePatternNode::print(std::ostream &OS) const { +void TreePatternNode::print(raw_ostream &OS) const { if (isLeaf()) { OS << *getLeafValue(); } else { @@ -555,14 +581,15 @@ void TreePatternNode::print(std::ostream &OS) const { // nodes that are multiply typed. switch (getExtTypeNum(0)) { case MVT::Other: OS << ":Other"; break; - case EMVT::isInt: OS << ":isInt"; break; - case EMVT::isFP : OS << ":isFP"; break; - case EMVT::isUnknown: ; /*OS << ":?";*/ break; + case MVT::iAny: OS << ":iAny"; break; + case MVT::fAny : OS << ":fAny"; break; + case MVT::vAny: OS << ":vAny"; break; + case EEVT::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. + // Strip off EVT:: prefix if present. if (VTName.substr(0,5) == "MVT::") VTName = VTName.substr(5); OS << ":" << VTName; @@ -591,7 +618,7 @@ void TreePatternNode::print(std::ostream &OS) const { } void TreePatternNode::dump() const { - print(*cerr.stream()); + print(errs()); } /// isIsomorphicTo - Return true if this node is recursively @@ -738,13 +765,13 @@ TreePatternNode *TreePatternNode::InlinePatternFragments(TreePattern &TP) { } /// getImplicitType - Check to see if the specified record has an implicit -/// type which should be applied to it. This infer the type of register +/// type which should be applied to it. This will infer the type of register /// references from the register file information, for example. /// static std::vector getImplicitType(Record *R, bool NotRegisters, TreePattern &TP) { // Some common return values - std::vector Unknown(1, EMVT::isUnknown); + std::vector Unknown(1, EEVT::isUnknown); std::vector Other(1, MVT::Other); // Check to see if this is a register or a register class... @@ -771,7 +798,7 @@ static std::vector getImplicitType(Record *R, bool NotRegisters, std::vector ComplexPat(1, TP.getDAGPatterns().getComplexPattern(R).getValueType()); return ComplexPat; - } else if (R->getName() == "ptr_rc") { + } else if (R->isSubClassOf("PointerLikeRegClass")) { Other[0] = MVT::iPTR; return Other; } else if (R->getName() == "node" || R->getName() == "srcvalue" || @@ -821,7 +848,7 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { return UpdateNodeType(getImplicitType(DI->getDef(), NotRegisters, TP),TP); } else if (IntInit *II = dynamic_cast(getLeafValue())) { // Int inits are always integers. :) - bool MadeChange = UpdateNodeType(EMVT::isInt, TP); + bool MadeChange = UpdateNodeType(MVT::iAny, TP); if (hasTypeSet()) { // At some point, it may make sense for this tree pattern to have @@ -834,7 +861,7 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { VT = getTypeNum(0); if (VT != MVT::iPTR && VT != MVT::iPTRAny) { - unsigned Size = MVT(VT).getSizeInBits(); + unsigned Size = EVT(VT).getSizeInBits(); // Make sure that the value is representable for this type. if (Size < 32) { int Val = (II->getValue() << (32-Size)) >> (32-Size); @@ -851,8 +878,8 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { getEnumName(getTypeNum(0)) + "'!"); } } - } - } + } + } } return MadeChange; @@ -884,11 +911,10 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { MadeChange = getChild(i)->ApplyTypeConstraints(TP, NotRegisters); MadeChange |= UpdateNodeType(MVT::isVoid, TP); return MadeChange; - } else if (getOperator()->getName() == "COPY_TO_SUBCLASS") { + } else if (getOperator()->getName() == "COPY_TO_REGCLASS") { bool MadeChange = false; MadeChange |= getChild(0)->ApplyTypeConstraints(TP, NotRegisters); MadeChange |= getChild(1)->ApplyTypeConstraints(TP, NotRegisters); - MadeChange |= UpdateNodeType(getChild(1)->getTypeNum(0), TP); return MadeChange; } else if (const CodeGenIntrinsic *Int = getIntrinsicInfo(CDP)) { bool MadeChange = false; @@ -925,25 +951,6 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { if (NI.getNumResults() == 0) MadeChange |= UpdateNodeType(MVT::isVoid, TP); - // If this is a vector_shuffle operation, apply types to the build_vector - // operation. The types of the integers don't matter, but this ensures they - // won't get checked. - if (getOperator()->getName() == "vector_shuffle" && - getChild(2)->getOperator()->getName() == "build_vector") { - TreePatternNode *BV = getChild(2); - const std::vector &LegalVTs - = CDP.getTargetInfo().getLegalValueTypes(); - MVT::SimpleValueType LegalIntVT = MVT::Other; - for (unsigned i = 0, e = LegalVTs.size(); i != e; ++i) - if (isInteger(LegalVTs[i]) && !isVector(LegalVTs[i])) { - LegalIntVT = LegalVTs[i]; - break; - } - assert(LegalIntVT != MVT::Other && "No legal integer VT?"); - - for (unsigned i = 0, e = BV->getNumChildren(); i != e; ++i) - MadeChange |= BV->getChild(i)->UpdateNodeType(LegalIntVT, TP); - } return MadeChange; } else if (getOperator()->isSubClassOf("Instruction")) { const DAGInstruction &Inst = CDP.getInstruction(getOperator()); @@ -961,13 +968,13 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { } else { Record *ResultNode = Inst.getResult(0); - if (ResultNode->getName() == "ptr_rc") { + if (ResultNode->isSubClassOf("PointerLikeRegClass")) { std::vector VT; VT.push_back(MVT::iPTR); MadeChange = UpdateNodeType(VT, TP); } else if (ResultNode->getName() == "unknown") { std::vector VT; - VT.push_back(EMVT::isUnknown); + VT.push_back(EEVT::isUnknown); MadeChange = UpdateNodeType(VT, TP); } else { assert(ResultNode->isSubClassOf("RegisterClass") && @@ -1005,10 +1012,10 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { } else if (OperandNode->isSubClassOf("Operand")) { VT = getValueType(OperandNode->getValueAsDef("Type")); MadeChange |= Child->UpdateNodeType(VT, TP); - } else if (OperandNode->getName() == "ptr_rc") { + } else if (OperandNode->isSubClassOf("PointerLikeRegClass")) { MadeChange |= Child->UpdateNodeType(MVT::iPTR, TP); } else if (OperandNode->getName() == "unknown") { - MadeChange |= Child->UpdateNodeType(EMVT::isUnknown, TP); + MadeChange |= Child->UpdateNodeType(EEVT::isUnknown, TP); } else { assert(0 && "Unknown operand type!"); abort(); @@ -1231,9 +1238,9 @@ TreePatternNode *TreePattern::ParseTreePattern(DagInit *Dag) { error("Constant int argument should not have a name!"); Children.push_back(Node); } else { - cerr << '"'; + errs() << '"'; Arg->dump(); - cerr << "\": "; + errs() << "\": "; error("Unknown leaf value for tree pattern!"); } } @@ -1283,7 +1290,7 @@ bool TreePattern::InferAllTypes() { return !HasUnresolvedTypes; } -void TreePattern::print(std::ostream &OS) const { +void TreePattern::print(raw_ostream &OS) const { OS << getRecord()->getName(); if (!Args.empty()) { OS << "(" << Args[0]; @@ -1305,7 +1312,7 @@ void TreePattern::print(std::ostream &OS) const { OS << "]\n"; } -void TreePattern::dump() const { print(*cerr.stream()); } +void TreePattern::dump() const { print(errs()); } //===----------------------------------------------------------------------===// // CodeGenDAGPatterns implementation @@ -1334,7 +1341,7 @@ CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R) : Records(R) { } CodeGenDAGPatterns::~CodeGenDAGPatterns() { - for (std::map::iterator I = PatternFragments.begin(), + for (pf_iterator I = PatternFragments.begin(), E = PatternFragments.end(); I != E; ++I) delete I->second; } @@ -1343,7 +1350,7 @@ CodeGenDAGPatterns::~CodeGenDAGPatterns() { Record *CodeGenDAGPatterns::getSDNodeNamed(const std::string &Name) const { Record *N = Records.getDef(Name); if (!N || !N->isSubClassOf("SDNode")) { - cerr << "Error getting SDNode '" << Name << "'!\n"; + errs() << "Error getting SDNode '" << Name << "'!\n"; exit(1); } return N; @@ -1639,7 +1646,7 @@ FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat, I->error("set destination should be a register!"); if (Val->getDef()->isSubClassOf("RegisterClass") || - Val->getDef()->getName() == "ptr_rc") { + Val->getDef()->isSubClassOf("PointerLikeRegClass")) { if (Dest->getName().empty()) I->error("set destination must have a name!"); if (InstResults.count(Dest->getName())) @@ -1986,7 +1993,8 @@ void CodeGenDAGPatterns::ParseInstructions() { } // If we can, convert the instructions to be patterns that are matched! - for (std::map::iterator II = Instructions.begin(), + for (std::map::iterator II = + Instructions.begin(), E = Instructions.end(); II != E; ++II) { DAGInstruction &TheInst = II->second; const TreePattern *I = TheInst.getPattern(); @@ -2044,9 +2052,28 @@ void CodeGenDAGPatterns::ParsePatterns() { Pattern = new TreePattern(Patterns[i], Tree, true, *this); else { std::vector Values; - for (unsigned j = 0, ee = Tree->getNumArgs(); j != ee; ++j) + RecTy *ListTy = 0; + for (unsigned j = 0, ee = Tree->getNumArgs(); j != ee; ++j) { Values.push_back(Tree->getArg(j)); - ListInit *LI = new ListInit(Values); + TypedInit *TArg = dynamic_cast(Tree->getArg(j)); + if (TArg == 0) { + errs() << "In dag: " << Tree->getAsString(); + errs() << " -- Untyped argument in pattern\n"; + assert(0 && "Untyped argument in pattern"); + } + if (ListTy != 0) { + ListTy = resolveTypes(ListTy, TArg->getType()); + if (ListTy == 0) { + errs() << "In dag: " << Tree->getAsString(); + errs() << " -- Incompatible types in pattern arguments\n"; + assert(0 && "Incompatible types in pattern arguments"); + } + } + else { + ListTy = TArg->getType(); + } + } + ListInit *LI = new ListInit(Values, new ListRecTy(ListTy)); Pattern = new TreePattern(Patterns[i], LI, true, *this); } @@ -2086,7 +2113,7 @@ void CodeGenDAGPatterns::ParsePatterns() { IterateInference |= Result->getTree(0)-> UpdateNodeType(Pattern->getTree(0)->getExtTypes(), *Result); } while (IterateInference); - + // Verify that we inferred enough types that we can do something with the // pattern and result. If these fire the user has to add type casts. if (!InferredAllPatternTypes) @@ -2156,11 +2183,11 @@ static void CombineChildVariants(TreePatternNode *Orig, do { #ifndef NDEBUG if (DebugFlag && !Idxs.empty()) { - cerr << Orig->getOperator()->getName() << ": Idxs = [ "; + errs() << Orig->getOperator()->getName() << ": Idxs = [ "; for (unsigned i = 0; i < Idxs.size(); ++i) { - cerr << Idxs[i] << " "; + errs() << Idxs[i] << " "; } - cerr << "]\n"; + errs() << "]\n"; } #endif // Create the variant and add it to the output list. @@ -2368,7 +2395,7 @@ static void GenerateVariantsOf(TreePatternNode *N, // GenerateVariants - Generate variants. For example, commutative patterns can // match multiple ways. Add them to PatternsToMatch as well. void CodeGenDAGPatterns::GenerateVariants() { - DOUT << "Generating instruction variants.\n"; + DEBUG(errs() << "Generating instruction variants.\n"); // Loop over all of the patterns we've collected, checking to see if we can // generate variants of the instruction, through the exploitation of @@ -2383,9 +2410,9 @@ void CodeGenDAGPatterns::GenerateVariants() { MultipleUseVarSet DepVars; std::vector Variants; FindDepVars(PatternsToMatch[i].getSrcPattern(), DepVars); - DOUT << "Dependent/multiply used variables: "; + DEBUG(errs() << "Dependent/multiply used variables: "); DEBUG(DumpDepVars(DepVars)); - DOUT << "\n"; + DEBUG(errs() << "\n"); GenerateVariantsOf(PatternsToMatch[i].getSrcPattern(), Variants, *this, DepVars); assert(!Variants.empty() && "Must create at least original variant!"); @@ -2394,23 +2421,27 @@ void CodeGenDAGPatterns::GenerateVariants() { if (Variants.empty()) // No variants for this pattern. continue; - DOUT << "FOUND VARIANTS OF: "; - DEBUG(PatternsToMatch[i].getSrcPattern()->dump()); - DOUT << "\n"; + DEBUG(errs() << "FOUND VARIANTS OF: "; + PatternsToMatch[i].getSrcPattern()->dump(); + errs() << "\n"); for (unsigned v = 0, e = Variants.size(); v != e; ++v) { TreePatternNode *Variant = Variants[v]; - DOUT << " VAR#" << v << ": "; - DEBUG(Variant->dump()); - DOUT << "\n"; + DEBUG(errs() << " VAR#" << v << ": "; + Variant->dump(); + errs() << "\n"); // Scan to see if an instruction or explicit pattern already matches this. bool AlreadyExists = false; for (unsigned p = 0, e = PatternsToMatch.size(); p != e; ++p) { + // Skip if the top level predicates do not match. + if (PatternsToMatch[i].getPredicates() != + PatternsToMatch[p].getPredicates()) + continue; // Check to see if this variant already exists. if (Variant->isIsomorphicTo(PatternsToMatch[p].getSrcPattern(), DepVars)) { - DOUT << " *** ALREADY EXISTS, ignoring variant.\n"; + DEBUG(errs() << " *** ALREADY EXISTS, ignoring variant.\n"); AlreadyExists = true; break; } @@ -2426,7 +2457,7 @@ void CodeGenDAGPatterns::GenerateVariants() { PatternsToMatch[i].getAddedComplexity())); } - DOUT << "\n"; + DEBUG(errs() << "\n"); } }