diff options
author | dim <dim@FreeBSD.org> | 2014-11-24 17:02:24 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2014-11-24 17:02:24 +0000 |
commit | 2c8643c6396b0a3db33430cf9380e70bbb9efce0 (patch) | |
tree | 4df130b28021d86e13bf4565ef58c1c5a5e093b4 /contrib/llvm/utils/TableGen/CodeGenDAGPatterns.cpp | |
parent | 678318cd20f7db4e6c6b85d83fe00fa327b04fca (diff) | |
parent | e27feadae0885aa074df58ebfda2e7a7f7a7d590 (diff) | |
download | FreeBSD-src-2c8643c6396b0a3db33430cf9380e70bbb9efce0.zip FreeBSD-src-2c8643c6396b0a3db33430cf9380e70bbb9efce0.tar.gz |
Merge llvm 3.5.0 release from ^/vendor/llvm/dist, resolve conflicts, and
preserve our customizations, where necessary.
Diffstat (limited to 'contrib/llvm/utils/TableGen/CodeGenDAGPatterns.cpp')
-rw-r--r-- | contrib/llvm/utils/TableGen/CodeGenDAGPatterns.cpp | 454 |
1 files changed, 270 insertions, 184 deletions
diff --git a/contrib/llvm/utils/TableGen/CodeGenDAGPatterns.cpp b/contrib/llvm/utils/TableGen/CodeGenDAGPatterns.cpp index 717090a..2602bbc 100644 --- a/contrib/llvm/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/contrib/llvm/utils/TableGen/CodeGenDAGPatterns.cpp @@ -25,6 +25,8 @@ #include <set> using namespace llvm; +#define DEBUG_TYPE "dag-patterns" + //===----------------------------------------------------------------------===// // EEVT::TypeSet Implementation //===----------------------------------------------------------------------===// @@ -83,7 +85,7 @@ bool EEVT::TypeSet::FillWithPossibleTypes(TreePattern &TP, return false; for (unsigned i = 0, e = LegalTypes.size(); i != e; ++i) - if (Pred == 0 || Pred(LegalTypes[i])) + if (!Pred || Pred(LegalTypes[i])) TypeVec.push_back(LegalTypes[i]); // If we have nothing that matches the predicate, bail out. @@ -120,6 +122,14 @@ bool EEVT::TypeSet::hasFloatingPointTypes() const { return false; } +/// hasScalarTypes - Return true if this TypeSet contains a scalar value type. +bool EEVT::TypeSet::hasScalarTypes() const { + for (unsigned i = 0, e = TypeVec.size(); i != e; ++i) + if (isScalar(TypeVec[i])) + return true; + return false; +} + /// hasVectorTypes - Return true if this TypeSet contains a vAny or a vector /// value type. bool EEVT::TypeSet::hasVectorTypes() const { @@ -339,8 +349,9 @@ bool EEVT::TypeSet::EnforceVector(TreePattern &TP) { -/// EnforceSmallerThan - 'this' must be a smaller VT than Other. Update -/// this an other based on this information. +/// EnforceSmallerThan - 'this' must be a smaller VT than Other. For vectors +/// this shoud be based on the element type. Update this and other based on +/// this information. bool EEVT::TypeSet::EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP) { if (TP.hasError()) return false; @@ -371,159 +382,100 @@ bool EEVT::TypeSet::EnforceSmallerThan(EEVT::TypeSet &Other, TreePattern &TP) { // If one contains vectors but the other doesn't pull vectors out. if (!hasVectorTypes()) MadeChange |= Other.EnforceScalar(TP); - if (!hasVectorTypes()) + else if (!hasScalarTypes()) + MadeChange |= Other.EnforceVector(TP); + if (!Other.hasVectorTypes()) MadeChange |= EnforceScalar(TP); + else if (!Other.hasScalarTypes()) + MadeChange |= EnforceVector(TP); - if (TypeVec.size() == 1 && Other.TypeVec.size() == 1) { - // If we are down to concrete types, 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(!(hasIntegerTypes() && hasFloatingPointTypes()) && - !(Other.hasIntegerTypes() && Other.hasFloatingPointTypes()) && - "SDTCisOpSmallerThanOp does not handle mixed int/fp types!"); - - // 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. - 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()) { - TP.error("Type inference contradiction found, '" + - getName() + "' element type not smaller than '" + - Other.getName() +"'!"); - return false; - } - } else - // For scalar types, the bitsize of this type must be larger - // than that of the other. - if (Type.getSizeInBits() >= OtherType.getSizeInBits()) { - TP.error("Type inference contradiction found, '" + - getName() + "' is not smaller than '" + - Other.getName() +"'!"); - return false; - } - } - - - // Handle int and fp as disjoint sets. This won't work for patterns - // that have mixed fp/int types but those are likely rare and would - // not have been accepted by this code previously. + // For vectors we need to ensure that smaller size doesn't produce larger + // vector and vice versa. + if (isConcrete() && isVector(getConcrete())) { + MVT IVT = getConcrete(); + unsigned Size = IVT.getSizeInBits(); - // Okay, find the smallest type from the current set and remove it from the - // largest set. - MVT::SimpleValueType SmallestInt = MVT::LAST_VALUETYPE; - for (unsigned i = 0, e = TypeVec.size(); i != e; ++i) - if (isInteger(TypeVec[i])) { - SmallestInt = TypeVec[i]; - break; - } - for (unsigned i = 1, e = TypeVec.size(); i != e; ++i) - if (isInteger(TypeVec[i]) && TypeVec[i] < SmallestInt) - SmallestInt = TypeVec[i]; + // Only keep types that have at least as many bits. + TypeSet InputSet(Other); - MVT::SimpleValueType SmallestFP = MVT::LAST_VALUETYPE; - for (unsigned i = 0, e = TypeVec.size(); i != e; ++i) - if (isFloatingPoint(TypeVec[i])) { - SmallestFP = TypeVec[i]; - break; - } - for (unsigned i = 1, e = TypeVec.size(); i != e; ++i) - if (isFloatingPoint(TypeVec[i]) && TypeVec[i] < SmallestFP) - SmallestFP = TypeVec[i]; - - int OtherIntSize = 0; - int OtherFPSize = 0; - for (SmallVectorImpl<MVT::SimpleValueType>::iterator TVI = - Other.TypeVec.begin(); - TVI != Other.TypeVec.end(); - /* NULL */) { - if (isInteger(*TVI)) { - ++OtherIntSize; - if (*TVI == SmallestInt) { - TVI = Other.TypeVec.erase(TVI); - --OtherIntSize; + for (unsigned i = 0; i != Other.TypeVec.size(); ++i) { + assert(isVector(Other.TypeVec[i]) && "EnforceVector didn't work"); + if (MVT(Other.TypeVec[i]).getSizeInBits() < Size) { + Other.TypeVec.erase(Other.TypeVec.begin()+i--); MadeChange = true; - continue; } - } else if (isFloatingPoint(*TVI)) { - ++OtherFPSize; - if (*TVI == SmallestFP) { - TVI = Other.TypeVec.erase(TVI); - --OtherFPSize; + } + + if (Other.TypeVec.empty()) { // FIXME: Really want an SMLoc here! + TP.error("Type inference contradiction found, forcing '" + + InputSet.getName() + "' to have at least as many bits as " + + getName() + "'"); + return false; + } + } else if (Other.isConcrete() && isVector(Other.getConcrete())) { + MVT IVT = Other.getConcrete(); + unsigned Size = IVT.getSizeInBits(); + + // Only keep types with the same or fewer total bits + TypeSet InputSet(*this); + + for (unsigned i = 0; i != TypeVec.size(); ++i) { + assert(isVector(TypeVec[i]) && "EnforceVector didn't work"); + if (MVT(TypeVec[i]).getSizeInBits() > Size) { + TypeVec.erase(TypeVec.begin()+i--); MadeChange = true; - continue; } } - ++TVI; + + if (TypeVec.empty()) { // FIXME: Really want an SMLoc here! + TP.error("Type inference contradiction found, forcing '" + + InputSet.getName() + "' to have the same or fewer bits than " + + Other.getName() + "'"); + return false; + } } - // 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)) { - TP.error("Type inference contradiction found, '" + - Other.getName() + "' has nothing larger than '" + getName() +"'!"); + // 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(!(hasIntegerTypes() && hasFloatingPointTypes()) && + !(Other.hasIntegerTypes() && Other.hasFloatingPointTypes()) && + "SDTCisOpSmallerThanOp does not handle mixed int/fp types!"); + + if (TP.hasError()) return false; + + // Okay, find the smallest scalar type from the other set and remove + // anything the same or smaller from the current set. + TypeSet InputSet(Other); + MVT::SimpleValueType Smallest = TypeVec[0]; + for (unsigned i = 0; i != Other.TypeVec.size(); ++i) { + if (Other.TypeVec[i] <= Smallest) { + Other.TypeVec.erase(Other.TypeVec.begin()+i--); + MadeChange = true; + } } - // Okay, find the largest type in the Other set and remove it from the - // current set. - MVT::SimpleValueType LargestInt = MVT::Other; - for (unsigned i = 0, e = Other.TypeVec.size(); i != e; ++i) - if (isInteger(Other.TypeVec[i])) { - LargestInt = Other.TypeVec[i]; - break; - } - for (unsigned i = 1, e = Other.TypeVec.size(); i != e; ++i) - if (isInteger(Other.TypeVec[i]) && Other.TypeVec[i] > LargestInt) - LargestInt = Other.TypeVec[i]; - - MVT::SimpleValueType LargestFP = MVT::Other; - for (unsigned i = 0, e = Other.TypeVec.size(); i != e; ++i) - if (isFloatingPoint(Other.TypeVec[i])) { - LargestFP = Other.TypeVec[i]; - break; - } - for (unsigned i = 1, e = Other.TypeVec.size(); i != e; ++i) - if (isFloatingPoint(Other.TypeVec[i]) && Other.TypeVec[i] > LargestFP) - LargestFP = Other.TypeVec[i]; - - int IntSize = 0; - int FPSize = 0; - for (SmallVectorImpl<MVT::SimpleValueType>::iterator TVI = - TypeVec.begin(); - TVI != TypeVec.end(); - /* NULL */) { - if (isInteger(*TVI)) { - ++IntSize; - if (*TVI == LargestInt) { - TVI = TypeVec.erase(TVI); - --IntSize; - MadeChange = true; - continue; - } - } else if (isFloatingPoint(*TVI)) { - ++FPSize; - if (*TVI == LargestFP) { - TVI = TypeVec.erase(TVI); - --FPSize; - MadeChange = true; - continue; - } + if (Other.TypeVec.empty()) { + TP.error("Type inference contradiction found, '" + InputSet.getName() + + "' has nothing larger than '" + getName() +"'!"); + return false; + } + + // Okay, find the largest scalar type from the other set and remove + // anything the same or larger from the current set. + InputSet = TypeSet(*this); + MVT::SimpleValueType Largest = Other.TypeVec[Other.TypeVec.size()-1]; + for (unsigned i = 0; i != TypeVec.size(); ++i) { + if (TypeVec[i] >= Largest) { + TypeVec.erase(TypeVec.begin()+i--); + MadeChange = true; } - ++TVI; } - // If this is the only type in the small set, the constraint can never be - // satisfied. - if ((hasIntegerTypes() && IntSize == 0) || - (hasFloatingPointTypes() && FPSize == 0)) { - TP.error("Type inference contradiction found, '" + - getName() + "' has nothing smaller than '" + Other.getName()+"'!"); + if (TypeVec.empty()) { + TP.error("Type inference contradiction found, '" + InputSet.getName() + + "' has nothing smaller than '" + Other.getName() +"'!"); return false; } @@ -580,27 +532,78 @@ bool EEVT::TypeSet::EnforceVectorEltTypeIs(EEVT::TypeSet &VTOperand, /// vector type specified by VTOperand. bool EEVT::TypeSet::EnforceVectorSubVectorTypeIs(EEVT::TypeSet &VTOperand, TreePattern &TP) { + if (TP.hasError()) + return false; + // "This" must be a vector and "VTOperand" must be a vector. bool MadeChange = false; MadeChange |= EnforceVector(TP); MadeChange |= VTOperand.EnforceVector(TP); - // "This" must be larger than "VTOperand." - MadeChange |= VTOperand.EnforceSmallerThan(*this, TP); + // If one side is known to be integer or known to be FP but the other side has + // no information, get at least the type integrality info in there. + if (!hasFloatingPointTypes()) + MadeChange |= VTOperand.EnforceInteger(TP); + else if (!hasIntegerTypes()) + MadeChange |= VTOperand.EnforceFloatingPoint(TP); + if (!VTOperand.hasFloatingPointTypes()) + MadeChange |= EnforceInteger(TP); + else if (!VTOperand.hasIntegerTypes()) + MadeChange |= EnforceFloatingPoint(TP); + + assert(!isCompletelyUnknown() && !VTOperand.isCompletelyUnknown() && + "Should have a type list now"); // If we know the vector type, it forces the scalar types to agree. + // Also force one vector to have more elements than the other. if (isConcrete()) { MVT IVT = getConcrete(); + unsigned NumElems = IVT.getVectorNumElements(); IVT = IVT.getVectorElementType(); EEVT::TypeSet EltTypeSet(IVT.SimpleTy, TP); MadeChange |= VTOperand.EnforceVectorEltTypeIs(EltTypeSet, TP); + + // Only keep types that have less elements than VTOperand. + TypeSet InputSet(VTOperand); + + for (unsigned i = 0; i != VTOperand.TypeVec.size(); ++i) { + assert(isVector(VTOperand.TypeVec[i]) && "EnforceVector didn't work"); + if (MVT(VTOperand.TypeVec[i]).getVectorNumElements() >= NumElems) { + VTOperand.TypeVec.erase(VTOperand.TypeVec.begin()+i--); + MadeChange = true; + } + } + if (VTOperand.TypeVec.empty()) { // FIXME: Really want an SMLoc here! + TP.error("Type inference contradiction found, forcing '" + + InputSet.getName() + "' to have less vector elements than '" + + getName() + "'"); + return false; + } } else if (VTOperand.isConcrete()) { MVT IVT = VTOperand.getConcrete(); + unsigned NumElems = IVT.getVectorNumElements(); IVT = IVT.getVectorElementType(); EEVT::TypeSet EltTypeSet(IVT.SimpleTy, TP); MadeChange |= EnforceVectorEltTypeIs(EltTypeSet, TP); + + // Only keep types that have more elements than 'this'. + TypeSet InputSet(*this); + + for (unsigned i = 0; i != TypeVec.size(); ++i) { + assert(isVector(TypeVec[i]) && "EnforceVector didn't work"); + if (MVT(TypeVec[i]).getVectorNumElements() <= NumElems) { + TypeVec.erase(TypeVec.begin()+i--); + MadeChange = true; + } + } + if (TypeVec.empty()) { // FIXME: Really want an SMLoc here! + TP.error("Type inference contradiction found, forcing '" + + InputSet.getName() + "' to have more vector elements than '" + + VTOperand.getName() + "'"); + return false; + } } return MadeChange; @@ -735,9 +738,13 @@ static unsigned getPatternSize(const TreePatternNode *P, // specified. To get best possible pattern match we'll need to dynamically // calculate the complexity of all patterns a dag can potentially map to. const ComplexPattern *AM = P->getComplexPatternInfo(CGP); - if (AM) + if (AM) { Size += AM->getNumOperands() * 3; + // We don't want to count any children twice, so return early. + return Size; + } + // If this node has some predicate function that must match, it adds to the // complexity of this node. if (!P->getPredicateFns().empty()) @@ -975,7 +982,7 @@ bool TreePatternNode::UpdateNodeTypeFromInst(unsigned ResNo, // Both RegisterClass and RegisterOperand operands derive their types from a // register class def. - Record *RC = 0; + Record *RC = nullptr; if (Operand->isSubClassOf("RegisterClass")) RC = Operand; else if (Operand->isSubClassOf("RegisterOperand")) @@ -1093,7 +1100,7 @@ static unsigned GetNumNodeResults(Record *Operator, CodeGenDAGPatterns &CDP) { // Get the result tree. DagInit *Tree = Operator->getValueAsDag("Fragment"); - Record *Op = 0; + Record *Op = nullptr; if (Tree) if (DefInit *DI = dyn_cast<DefInit>(Tree->getOperator())) Op = DI->getDef(); @@ -1116,6 +1123,12 @@ 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. + + if (Operator->isSubClassOf("ComplexPattern")) + return 1; + Operator->dump(); errs() << "Unhandled node in GetNumNodeResults\n"; exit(1); @@ -1228,8 +1241,10 @@ SubstituteFormalArguments(std::map<std::string, TreePatternNode*> &ArgMap) { TreePatternNode *Child = getChild(i); if (Child->isLeaf()) { Init *Val = Child->getLeafValue(); - if (isa<DefInit>(Val) && - cast<DefInit>(Val)->getDef()->getName() == "node") { + // Note that, when substituting into an output pattern, Val might be an + // UnsetInit. + if (isa<UnsetInit>(Val) || (isa<DefInit>(Val) && + cast<DefInit>(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!"); @@ -1250,7 +1265,7 @@ SubstituteFormalArguments(std::map<std::string, TreePatternNode*> &ArgMap) { /// PatFrag references. TreePatternNode *TreePatternNode::InlinePatternFragments(TreePattern &TP) { if (TP.hasError()) - return 0; + return nullptr; if (isLeaf()) return this; // nothing to do. @@ -1279,7 +1294,7 @@ TreePatternNode *TreePatternNode::InlinePatternFragments(TreePattern &TP) { if (Frag->getNumArgs() != Children.size()) { TP.error("'" + Op->getName() + "' fragment requires " + utostr(Frag->getNumArgs()) + " operands!"); - return 0; + return nullptr; } TreePatternNode *FragTree = Frag->getOnlyTree()->clone(); @@ -1417,6 +1432,9 @@ static EEVT::TypeSet getImplicitType(Record *R, unsigned ResNo, return EEVT::TypeSet(); // Unknown. } + if (R->isSubClassOf("Operand")) + return EEVT::TypeSet(getValueType(R->getValueAsDef("Type"))); + TP.error("Unknown node flavor used in pattern: " + R->getName()); return EEVT::TypeSet(MVT::Other, TP); } @@ -1429,7 +1447,7 @@ getIntrinsicInfo(const CodeGenDAGPatterns &CDP) const { if (getOperator() != CDP.get_intrinsic_void_sdnode() && getOperator() != CDP.get_intrinsic_w_chain_sdnode() && getOperator() != CDP.get_intrinsic_wo_chain_sdnode()) - return 0; + return nullptr; unsigned IID = cast<IntInit>(getChild(0)->getLeafValue())->getValue(); return &CDP.getIntrinsicInfo(IID); @@ -1439,12 +1457,37 @@ getIntrinsicInfo(const CodeGenDAGPatterns &CDP) const { /// return the ComplexPattern information, otherwise return null. const ComplexPattern * TreePatternNode::getComplexPatternInfo(const CodeGenDAGPatterns &CGP) const { - if (!isLeaf()) return 0; + Record *Rec; + if (isLeaf()) { + DefInit *DI = dyn_cast<DefInit>(getLeafValue()); + if (!DI) + return nullptr; + Rec = DI->getDef(); + } else + Rec = getOperator(); - DefInit *DI = dyn_cast<DefInit>(getLeafValue()); - if (DI && DI->getDef()->isSubClassOf("ComplexPattern")) - return &CGP.getComplexPattern(DI->getDef()); - return 0; + if (!Rec->isSubClassOf("ComplexPattern")) + return nullptr; + return &CGP.getComplexPattern(Rec); +} + +unsigned TreePatternNode::getNumMIResults(const CodeGenDAGPatterns &CGP) const { + // A ComplexPattern specifically declares how many results it fills in. + if (const ComplexPattern *CP = getComplexPatternInfo(CGP)) + return CP->getNumOperands(); + + // If MIOperandInfo is specified, that gives the count. + if (isLeaf()) { + DefInit *DI = dyn_cast<DefInit>(getLeafValue()); + if (DI && DI->getDef()->isSubClassOf("Operand")) { + DagInit *MIOps = DI->getDef()->getValueAsDag("MIOperandInfo"); + if (MIOps->getNumArgs()) + return MIOps->getNumArgs(); + } + } + + // Otherwise there is just one result. + return 1; } /// NodeHasProperty - Return true if this node has the specified property. @@ -1675,9 +1718,9 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { 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) { + // a single ComplexPattern-related Operand. + + if (Child->getNumMIResults(CDP) < NumArgs) { // Match first sub-operand against the child we already have. Record *SubRec = cast<DefInit>(MIOpInfo->getArg(0))->getDef(); MadeChange |= @@ -1717,6 +1760,15 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { return MadeChange; } + if (getOperator()->isSubClassOf("ComplexPattern")) { + bool MadeChange = false; + + for (unsigned i = 0; i < getNumChildren(); ++i) + MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters); + + return MadeChange; + } + assert(getOperator()->isSubClassOf("SDNodeXForm") && "Unknown node type!"); // Node transforms always take one operand. @@ -1773,6 +1825,9 @@ bool TreePatternNode::canPatternMatch(std::string &Reason, return true; } + if (getOperator()->isSubClassOf("ComplexPattern")) + return true; + // If this node is a commutative operator, check that the LHS isn't an // immediate. const SDNodeInfo &NodeInfo = CDP.getSDNodeInfo(getOperator()); @@ -1882,7 +1937,7 @@ TreePatternNode *TreePattern::ParseTreePattern(Init *TheInit, StringRef OpName){ if (BitsInit *BI = dyn_cast<BitsInit>(TheInit)) { // Turn this into an IntInit. Init *II = BI->convertInitializerTo(IntRecTy::get()); - if (II == 0 || !isa<IntInit>(II)) + if (!II || !isa<IntInit>(II)) error("Bits value must be constants!"); return ParseTreePattern(II, OpName); } @@ -1919,6 +1974,7 @@ TreePatternNode *TreePattern::ParseTreePattern(Init *TheInit, StringRef OpName){ !Operator->isSubClassOf("Instruction") && !Operator->isSubClassOf("SDNodeXForm") && !Operator->isSubClassOf("Intrinsic") && + !Operator->isSubClassOf("ComplexPattern") && Operator->getName() != "set" && Operator->getName() != "implicit") error("Unrecognized node '" + Operator->getName() + "'!"); @@ -1974,6 +2030,27 @@ TreePatternNode *TreePattern::ParseTreePattern(Init *TheInit, StringRef OpName){ Children.insert(Children.begin(), IIDNode); } + if (Operator->isSubClassOf("ComplexPattern")) { + for (unsigned i = 0; i < Children.size(); ++i) { + TreePatternNode *Child = Children[i]; + + if (Child->getName().empty()) + error("All arguments to a ComplexPattern must be named"); + + // Check that the ComplexPattern uses are consistent: "(MY_PAT $a, $b)" + // and "(MY_PAT $b, $a)" should not be allowed in the same pattern; + // neither should "(MY_PAT_1 $a, $b)" and "(MY_PAT_2 $a, $b)". + auto OperandId = std::make_pair(Operator, i); + auto PrevOp = ComplexPatternOperands.find(Child->getName()); + if (PrevOp != ComplexPatternOperands.end()) { + if (PrevOp->getValue() != OperandId) + error("All ComplexPattern operands must appear consistently: " + "in the same order in just one ComplexPattern instance."); + } else + ComplexPatternOperands[Child->getName()] = OperandId; + } + } + unsigned NumResults = GetNumNodeResults(Operator, CDP); TreePatternNode *Result = new TreePatternNode(Operator, Children, NumResults); Result->setName(OpName); @@ -2042,9 +2119,11 @@ InferAllTypes(const StringMap<SmallVector<TreePatternNode*,1> > *InNamedTypes) { // If we have input named node types, propagate their types to the named // values here. if (InNamedTypes) { - // FIXME: Should be error? - assert(InNamedTypes->count(I->getKey()) && - "Named node in output pattern but not input pattern?"); + if (!InNamedTypes->count(I->getKey())) { + error("Node '" + std::string(I->getKey()) + + "' in output pattern but not input pattern"); + return true; + } const SmallVectorImpl<TreePatternNode*> &InNodes = InNamedTypes->find(I->getKey())->second; @@ -2131,6 +2210,7 @@ CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R) : ParsePatternFragments(); ParseDefaultOperands(); ParseInstructions(); + ParsePatternFragments(/*OutFrags*/true); ParsePatterns(); // Generate variants. For example, commutative patterns can match @@ -2204,13 +2284,18 @@ void CodeGenDAGPatterns::ParseComplexPatterns() { /// inline fragments together as necessary, so that there are no references left /// inside a pattern fragment to a pattern fragment. /// -void CodeGenDAGPatterns::ParsePatternFragments() { +void CodeGenDAGPatterns::ParsePatternFragments(bool OutFrags) { std::vector<Record*> Fragments = Records.getAllDerivedDefinitions("PatFrag"); // First step, parse all of the fragments. for (unsigned i = 0, e = Fragments.size(); i != e; ++i) { + if (OutFrags != Fragments[i]->isSubClassOf("OutPatFrag")) + continue; + DagInit *Tree = Fragments[i]->getValueAsDag("Fragment"); - TreePattern *P = new TreePattern(Fragments[i], Tree, true, *this); + TreePattern *P = + new TreePattern(Fragments[i], Tree, + !Fragments[i]->isSubClassOf("OutPatFrag"), *this); PatternFragments[Fragments[i]] = P; // Validate the argument list, converting it to set, to discard duplicates. @@ -2266,6 +2351,9 @@ void CodeGenDAGPatterns::ParsePatternFragments() { // Now that we've parsed all of the tree fragments, do a closure on them so // that there are not references to PatFrags left inside of them. for (unsigned i = 0, e = Fragments.size(); i != e; ++i) { + if (OutFrags != Fragments[i]->isSubClassOf("OutPatFrag")) + continue; + TreePattern *ThePat = PatternFragments[Fragments[i]]; ThePat->InlinePatternFragments(); @@ -2312,8 +2400,9 @@ void CodeGenDAGPatterns::ParseDefaultOperands() { /* Resolve all types */; if (TPN->ContainsUnresolvedType()) { - PrintFatalError("Value #" + utostr(i) + " of OperandWithDefaultOps '" + - DefaultOps[i]->getName() +"' doesn't have a concrete type!"); + PrintFatalError("Value #" + Twine(i) + " of OperandWithDefaultOps '" + + DefaultOps[i]->getName() + + "' doesn't have a concrete type!"); } DefaultOpInfo.DefaultOps.push_back(TPN); } @@ -2535,14 +2624,11 @@ public: return; } - // Get information about the SDNode for the operator. - const SDNodeInfo &OpInfo = CDP.getSDNodeInfo(N->getOperator()); - // 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 (N->NodeHasProperty(SDNPMayStore, CDP)) mayStore = true; + if (N->NodeHasProperty(SDNPMayLoad, CDP)) mayLoad = true; + if (N->NodeHasProperty(SDNPSideEffect, CDP)) hasSideEffects = true; + if (N->NodeHasProperty(SDNPVariadic, CDP)) isVariadic = true; if (const CodeGenIntrinsic *IntInfo = N->getIntrinsicInfo(CDP)) { // If this is an intrinsic, analyze it. @@ -2723,7 +2809,7 @@ const DAGInstruction &CodeGenDAGPatterns::parseInstructionPattern( // Check that all of the results occur first in the list. std::vector<Record*> Results; - TreePatternNode *Res0Node = 0; + TreePatternNode *Res0Node = nullptr; for (unsigned i = 0; i != NumResults; ++i) { if (i == CGI.Operands.size()) I->error("'" + InstResults.begin()->first + @@ -2732,13 +2818,13 @@ const DAGInstruction &CodeGenDAGPatterns::parseInstructionPattern( // Check that it exists in InstResults. TreePatternNode *RNode = InstResults[OpName]; - if (RNode == 0) + if (!RNode) I->error("Operand $" + OpName + " does not exist in operand list!"); if (i == 0) Res0Node = RNode; Record *R = cast<DefInit>(RNode->getLeafValue())->getDef(); - if (R == 0) + if (!R) I->error("Operand $" + OpName + " should be a set destination: all " "outputs must occur before inputs in operand list!"); @@ -2795,7 +2881,7 @@ const DAGInstruction &CodeGenDAGPatterns::parseInstructionPattern( // Promote the xform function to be an explicit node if set. if (Record *Xform = OpNode->getTransformFn()) { - OpNode->setTransformFn(0); + OpNode->setTransformFn(nullptr); std::vector<TreePatternNode*> Children; Children.push_back(OpNode); OpNode = new TreePatternNode(Xform, Children, OpNode->getNumTypes()); @@ -2839,7 +2925,7 @@ void CodeGenDAGPatterns::ParseInstructions() { std::vector<Record*> Instrs = Records.getAllDerivedDefinitions("Instruction"); for (unsigned i = 0, e = Instrs.size(); i != e; ++i) { - ListInit *LI = 0; + ListInit *LI = nullptr; if (isa<ListInit>(Instrs[i]->getValueInit("Pattern"))) LI = Instrs[i]->getValueAsListInit("Pattern"); @@ -2874,7 +2960,7 @@ void CodeGenDAGPatterns::ParseInstructions() { // Create and insert the instruction. std::vector<Record*> ImpResults; Instructions.insert(std::make_pair(Instrs[i], - DAGInstruction(0, Results, Operands, ImpResults))); + DAGInstruction(nullptr, Results, Operands, ImpResults))); continue; // no pattern. } @@ -2891,7 +2977,7 @@ void CodeGenDAGPatterns::ParseInstructions() { E = Instructions.end(); II != E; ++II) { DAGInstruction &TheInst = II->second; TreePattern *I = TheInst.getPattern(); - if (I == 0) continue; // No pattern. + if (!I) continue; // No pattern. // FIXME: Assume only the first tree is the pattern. The others are clobber // nodes. @@ -2967,7 +3053,7 @@ void CodeGenDAGPatterns::AddPatternToMatch(TreePattern *Pattern, // they don't exist in the input pattern. for (std::map<std::string, NameRecord>::iterator I = DstNames.begin(), E = DstNames.end(); I != E; ++I) { - if (SrcNames[I->first].first == 0) + if (SrcNames[I->first].first == nullptr) Pattern->error("Pattern has input without matching name in output: $" + I->first); } @@ -2976,7 +3062,7 @@ void CodeGenDAGPatterns::AddPatternToMatch(TreePattern *Pattern, // name isn't used in the dest, and isn't used to tie two values together. for (std::map<std::string, NameRecord>::iterator I = SrcNames.begin(), E = SrcNames.end(); I != E; ++I) - if (DstNames[I->first].first == 0 && SrcNames[I->first].second == 1) + if (DstNames[I->first].first == nullptr && SrcNames[I->first].second == 1) Pattern->error("Pattern has dead named input: $" + I->first); PatternsToMatch.push_back(PTM); @@ -3264,7 +3350,7 @@ void CodeGenDAGPatterns::ParsePatterns() { for (unsigned ii = 0, ee = DstPattern->getNumChildren(); ii != ee; ++ii) { TreePatternNode *OpNode = DstPattern->getChild(ii); if (Record *Xform = OpNode->getTransformFn()) { - OpNode->setTransformFn(0); + OpNode->setTransformFn(nullptr); std::vector<TreePatternNode*> Children; Children.push_back(OpNode); OpNode = new TreePatternNode(Xform, Children, OpNode->getNumTypes()); @@ -3416,8 +3502,8 @@ static void GenerateVariantsOf(TreePatternNode *N, std::vector<TreePatternNode*> &OutVariants, CodeGenDAGPatterns &CDP, const MultipleUseVarSet &DepVars) { - // We cannot permute leaves. - if (N->isLeaf()) { + // We cannot permute leaves or ComplexPattern uses. + if (N->isLeaf() || N->getOperator()->isSubClassOf("ComplexPattern")) { OutVariants.push_back(N); return; } |