diff options
Diffstat (limited to 'utils/TableGen/CodeGenDAGPatterns.cpp')
-rw-r--r-- | utils/TableGen/CodeGenDAGPatterns.cpp | 1048 |
1 files changed, 544 insertions, 504 deletions
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index 64cf23314497..1abe3a88bfbf 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -808,7 +808,7 @@ TypeSetByHwMode TypeInfer::getLegalTypes() { #ifndef NDEBUG TypeInfer::ValidateOnExit::~ValidateOnExit() { - if (!VTS.validate()) { + if (Infer.Validate && !VTS.validate()) { dbgs() << "Type set is empty for each HW mode:\n" "possible type contradiction in the pattern below " "(use -print-records with llvm-tblgen to see all " @@ -1134,6 +1134,14 @@ Record *TreePredicateFn::getScalarMemoryVT() const { return nullptr; return R->getValueAsDef("ScalarMemoryVT"); } +bool TreePredicateFn::hasGISelPredicateCode() const { + return !PatFragRec->getRecord() + ->getValueAsString("GISelPredicateCode") + .empty(); +} +std::string TreePredicateFn::getGISelPredicateCode() const { + return PatFragRec->getRecord()->getValueAsString("GISelPredicateCode"); +} StringRef TreePredicateFn::getImmType() const { if (immCodeUsesAPInt()) @@ -1305,7 +1313,7 @@ std::string PatternToMatch::getPredicateCheck() const { SmallVector<const Predicate*,4> PredList; for (const Predicate &P : Predicates) PredList.push_back(&P); - std::sort(PredList.begin(), PredList.end(), deref<llvm::less>()); + llvm::sort(PredList.begin(), PredList.end(), deref<llvm::less>()); std::string Check; for (unsigned i = 0, e = PredList.size(); i != e; ++i) { @@ -1564,7 +1572,7 @@ bool TreePatternNode::hasProperTypeByHwMode() const { for (const TypeSetByHwMode &S : Types) if (!S.isDefaultOnly()) return true; - for (TreePatternNode *C : Children) + for (const TreePatternNodePtr &C : Children) if (C->hasProperTypeByHwMode()) return true; return false; @@ -1574,7 +1582,7 @@ bool TreePatternNode::hasPossibleType() const { for (const TypeSetByHwMode &S : Types) if (!S.isPossible()) return false; - for (TreePatternNode *C : Children) + for (const TreePatternNodePtr &C : Children) if (!C->hasPossibleType()) return false; return true; @@ -1587,7 +1595,7 @@ bool TreePatternNode::setDefaultMode(unsigned Mode) { if (S.get(DefaultMode).empty()) return false; } - for (TreePatternNode *C : Children) + for (const TreePatternNodePtr &C : Children) if (!C->setDefaultMode(Mode)) return false; return true; @@ -1644,13 +1652,6 @@ MVT::SimpleValueType SDNodeInfo::getKnownType(unsigned ResNo) const { // TreePatternNode implementation // -TreePatternNode::~TreePatternNode() { -#if 0 // FIXME: implement refcounted tree nodes! - for (unsigned i = 0, e = getNumChildren(); i != e; ++i) - delete getChild(i); -#endif -} - static unsigned GetNumNodeResults(Record *Operator, CodeGenDAGPatterns &CDP) { if (Operator->getName() == "set" || Operator->getName() == "implicit") @@ -1662,21 +1663,31 @@ static unsigned GetNumNodeResults(Record *Operator, CodeGenDAGPatterns &CDP) { if (Operator->isSubClassOf("SDNode")) return CDP.getSDNodeInfo(Operator).getNumResults(); - if (Operator->isSubClassOf("PatFrag")) { + if (Operator->isSubClassOf("PatFrags")) { // If we've already parsed this pattern fragment, get it. Otherwise, handle // the forward reference case where one pattern fragment references another // before it is processed. - if (TreePattern *PFRec = CDP.getPatternFragmentIfRead(Operator)) - return PFRec->getOnlyTree()->getNumTypes(); + if (TreePattern *PFRec = CDP.getPatternFragmentIfRead(Operator)) { + // The number of results of a fragment with alternative records is the + // maximum number of results across all alternatives. + unsigned NumResults = 0; + for (auto T : PFRec->getTrees()) + NumResults = std::max(NumResults, T->getNumTypes()); + return NumResults; + } - // Get the result tree. - DagInit *Tree = Operator->getValueAsDag("Fragment"); - Record *Op = nullptr; - if (Tree) - if (DefInit *DI = dyn_cast<DefInit>(Tree->getOperator())) - Op = DI->getDef(); - assert(Op && "Invalid Fragment"); - return GetNumNodeResults(Op, CDP); + ListInit *LI = Operator->getValueAsListInit("Fragments"); + assert(LI && "Invalid Fragment"); + unsigned NumResults = 0; + for (Init *I : LI->getValues()) { + Record *Op = nullptr; + if (DagInit *Dag = dyn_cast<DagInit>(I)) + if (DefInit *DI = dyn_cast<DefInit>(Dag->getOperator())) + Op = DI->getDef(); + assert(Op && "Invalid Fragment"); + NumResults = std::max(NumResults, GetNumNodeResults(Op, CDP)); + } + return NumResults; } if (Operator->isSubClassOf("Instruction")) { @@ -1783,16 +1794,17 @@ bool TreePatternNode::isIsomorphicTo(const TreePatternNode *N, /// clone - Make a copy of this tree and all of its children. /// -TreePatternNode *TreePatternNode::clone() const { - TreePatternNode *New; +TreePatternNodePtr TreePatternNode::clone() const { + TreePatternNodePtr New; if (isLeaf()) { - New = new TreePatternNode(getLeafValue(), getNumTypes()); + New = std::make_shared<TreePatternNode>(getLeafValue(), getNumTypes()); } else { - std::vector<TreePatternNode*> CChildren; + std::vector<TreePatternNodePtr> CChildren; CChildren.reserve(Children.size()); for (unsigned i = 0, e = getNumChildren(); i != e; ++i) CChildren.push_back(getChild(i)->clone()); - New = new TreePatternNode(getOperator(), CChildren, getNumTypes()); + New = std::make_shared<TreePatternNode>(getOperator(), std::move(CChildren), + getNumTypes()); } New->setName(getName()); New->Types = Types; @@ -1813,8 +1825,8 @@ void TreePatternNode::RemoveAllTypes() { /// SubstituteFormalArguments - Replace the formal arguments in this tree /// with actual values specified by ArgMap. -void TreePatternNode:: -SubstituteFormalArguments(std::map<std::string, TreePatternNode*> &ArgMap) { +void TreePatternNode::SubstituteFormalArguments( + std::map<std::string, TreePatternNodePtr> &ArgMap) { if (isLeaf()) return; for (unsigned i = 0, e = getNumChildren(); i != e; ++i) { @@ -1826,12 +1838,12 @@ SubstituteFormalArguments(std::map<std::string, TreePatternNode*> &ArgMap) { 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()]; + TreePatternNodePtr NewChild = ArgMap[Child->getName()]; assert(NewChild && "Couldn't find formal argument!"); assert((Child->getPredicateFns().empty() || NewChild->getPredicateFns() == Child->getPredicateFns()) && "Non-empty child predicate clobbered!"); - setChild(i, NewChild); + setChild(i, std::move(NewChild)); } } else { getChild(i)->SubstituteFormalArguments(ArgMap); @@ -1841,29 +1853,81 @@ SubstituteFormalArguments(std::map<std::string, TreePatternNode*> &ArgMap) { /// InlinePatternFragments - If this pattern refers to any pattern -/// fragments, inline them into place, giving us a pattern without any -/// PatFrag references. -TreePatternNode *TreePatternNode::InlinePatternFragments(TreePattern &TP) { +/// fragments, return the set of inlined versions (this can be more than +/// one if a PatFrags record has multiple alternatives). +void TreePatternNode::InlinePatternFragments( + TreePatternNodePtr T, TreePattern &TP, + std::vector<TreePatternNodePtr> &OutAlternatives) { + if (TP.hasError()) - return nullptr; + return; + + if (isLeaf()) { + OutAlternatives.push_back(T); // nothing to do. + return; + } - if (isLeaf()) - return this; // nothing to do. Record *Op = getOperator(); - if (!Op->isSubClassOf("PatFrag")) { - // Just recursively inline children nodes. - for (unsigned i = 0, e = getNumChildren(); i != e; ++i) { - TreePatternNode *Child = getChild(i); - TreePatternNode *NewChild = Child->InlinePatternFragments(TP); + if (!Op->isSubClassOf("PatFrags")) { + if (getNumChildren() == 0) { + OutAlternatives.push_back(T); + return; + } - assert((Child->getPredicateFns().empty() || - NewChild->getPredicateFns() == Child->getPredicateFns()) && - "Non-empty child predicate clobbered!"); + // Recursively inline children nodes. + std::vector<std::vector<TreePatternNodePtr> > ChildAlternatives; + ChildAlternatives.resize(getNumChildren()); + for (unsigned i = 0, e = getNumChildren(); i != e; ++i) { + TreePatternNodePtr Child = getChildShared(i); + Child->InlinePatternFragments(Child, TP, ChildAlternatives[i]); + // If there are no alternatives for any child, there are no + // alternatives for this expression as whole. + if (ChildAlternatives[i].empty()) + return; - setChild(i, NewChild); + for (auto NewChild : ChildAlternatives[i]) + assert((Child->getPredicateFns().empty() || + NewChild->getPredicateFns() == Child->getPredicateFns()) && + "Non-empty child predicate clobbered!"); } - return this; + + // The end result is an all-pairs construction of the resultant pattern. + std::vector<unsigned> Idxs; + Idxs.resize(ChildAlternatives.size()); + bool NotDone; + do { + // Create the variant and add it to the output list. + std::vector<TreePatternNodePtr> NewChildren; + for (unsigned i = 0, e = ChildAlternatives.size(); i != e; ++i) + NewChildren.push_back(ChildAlternatives[i][Idxs[i]]); + TreePatternNodePtr R = std::make_shared<TreePatternNode>( + getOperator(), std::move(NewChildren), getNumTypes()); + + // Copy over properties. + R->setName(getName()); + R->setPredicateFns(getPredicateFns()); + R->setTransformFn(getTransformFn()); + for (unsigned i = 0, e = getNumTypes(); i != e; ++i) + R->setType(i, getExtType(i)); + + // Register alternative. + OutAlternatives.push_back(R); + + // Increment indices to the next permutation by incrementing the + // indices from last index backward, e.g., generate the sequence + // [0, 0], [0, 1], [1, 0], [1, 1]. + int IdxsIdx; + for (IdxsIdx = Idxs.size() - 1; IdxsIdx >= 0; --IdxsIdx) { + if (++Idxs[IdxsIdx] == ChildAlternatives[IdxsIdx].size()) + Idxs[IdxsIdx] = 0; + else + break; + } + NotDone = (IdxsIdx >= 0); + } while (NotDone); + + return; } // Otherwise, we found a reference to a fragment. First, look up its @@ -1874,39 +1938,42 @@ TreePatternNode *TreePatternNode::InlinePatternFragments(TreePattern &TP) { if (Frag->getNumArgs() != Children.size()) { TP.error("'" + Op->getName() + "' fragment requires " + Twine(Frag->getNumArgs()) + " operands!"); - return nullptr; + return; } - TreePatternNode *FragTree = Frag->getOnlyTree()->clone(); - - TreePredicateFn PredFn(Frag); - if (!PredFn.isAlwaysTrue()) - FragTree->addPredicateFn(PredFn); + // Compute the map of formal to actual arguments. + std::map<std::string, TreePatternNodePtr> ArgMap; + for (unsigned i = 0, e = Frag->getNumArgs(); i != e; ++i) { + const TreePatternNodePtr &Child = getChildShared(i); + ArgMap[Frag->getArgName(i)] = Child; + } - // Resolve formal arguments to their actual value. - if (Frag->getNumArgs()) { - // Compute the map of formal to actual arguments. - std::map<std::string, TreePatternNode*> ArgMap; - for (unsigned i = 0, e = Frag->getNumArgs(); i != e; ++i) - ArgMap[Frag->getArgName(i)] = getChild(i)->InlinePatternFragments(TP); + // Loop over all fragment alternatives. + for (auto Alternative : Frag->getTrees()) { + TreePatternNodePtr FragTree = Alternative->clone(); - FragTree->SubstituteFormalArguments(ArgMap); - } + TreePredicateFn PredFn(Frag); + if (!PredFn.isAlwaysTrue()) + FragTree->addPredicateFn(PredFn); - FragTree->setName(getName()); - for (unsigned i = 0, e = Types.size(); i != e; ++i) - FragTree->UpdateNodeType(i, getExtType(i), TP); + // Resolve formal arguments to their actual value. + if (Frag->getNumArgs()) + FragTree->SubstituteFormalArguments(ArgMap); - // Transfer in the old predicates. - for (const TreePredicateFn &Pred : getPredicateFns()) - FragTree->addPredicateFn(Pred); + // Transfer types. Note that the resolved alternative may have fewer + // (but not more) results than the PatFrags node. + FragTree->setName(getName()); + for (unsigned i = 0, e = FragTree->getNumTypes(); i != e; ++i) + FragTree->UpdateNodeType(i, getExtType(i), TP); - // Get a new copy of this fragment to stitch into here. - //delete this; // FIXME: implement refcounting! + // Transfer in the old predicates. + for (const TreePredicateFn &Pred : getPredicateFns()) + FragTree->addPredicateFn(Pred); - // The fragment we inlined could have recursive inlining that is needed. See - // if there are any pattern fragments in it and inline them as needed. - return FragTree->InlinePatternFragments(TP); + // The fragment we inlined could have recursive inlining that is needed. See + // if there are any pattern fragments in it and inline them as needed. + FragTree->InlinePatternFragments(FragTree, TP, OutAlternatives); + } } /// getImplicitType - Check to see if the specified record has an implicit @@ -1953,7 +2020,7 @@ static TypeSetByHwMode getImplicitType(Record *R, unsigned ResNo, return TypeSetByHwMode(T.getRegisterClass(R).getValueTypes()); } - if (R->isSubClassOf("PatFrag")) { + if (R->isSubClassOf("PatFrags")) { assert(ResNo == 0 && "FIXME: PatFrag with multiple results?"); // Pattern fragment types will be resolved when they are inlined. return TypeSetByHwMode(); // Unknown. @@ -2205,35 +2272,6 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { return false; } - // special handling for set, which isn't really an SDNode. - if (getOperator()->getName() == "set") { - assert(getNumTypes() == 0 && "Set doesn't produce a value"); - assert(getNumChildren() >= 2 && "Missing RHS of a set?"); - unsigned NC = getNumChildren(); - - TreePatternNode *SetVal = getChild(NC-1); - bool MadeChange = SetVal->ApplyTypeConstraints(TP, NotRegisters); - - for (unsigned i = 0; i < NC-1; ++i) { - TreePatternNode *Child = getChild(i); - MadeChange |= Child->ApplyTypeConstraints(TP, NotRegisters); - - // Types of operands must match. - MadeChange |= Child->UpdateNodeType(0, SetVal->getExtType(i), TP); - MadeChange |= SetVal->UpdateNodeType(i, Child->getExtType(0), TP); - } - return MadeChange; - } - - if (getOperator()->getName() == "implicit") { - assert(getNumTypes() == 0 && "Node doesn't produce a value"); - - bool MadeChange = false; - for (unsigned i = 0; i < getNumChildren(); ++i) - MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters); - return MadeChange; - } - if (const CodeGenIntrinsic *Int = getIntrinsicInfo(CDP)) { bool MadeChange = false; @@ -2508,10 +2546,10 @@ TreePattern::TreePattern(Record *TheRec, DagInit *Pat, bool isInput, Trees.push_back(ParseTreePattern(Pat, "")); } -TreePattern::TreePattern(Record *TheRec, TreePatternNode *Pat, bool isInput, - CodeGenDAGPatterns &cdp) : TheRecord(TheRec), CDP(cdp), - isInputPattern(isInput), HasError(false), - Infer(*this) { +TreePattern::TreePattern(Record *TheRec, TreePatternNodePtr Pat, bool isInput, + CodeGenDAGPatterns &cdp) + : TheRecord(TheRec), CDP(cdp), isInputPattern(isInput), HasError(false), + Infer(*this) { Trees.push_back(Pat); } @@ -2524,8 +2562,8 @@ void TreePattern::error(const Twine &Msg) { } void TreePattern::ComputeNamedNodes() { - for (TreePatternNode *Tree : Trees) - ComputeNamedNodes(Tree); + for (TreePatternNodePtr &Tree : Trees) + ComputeNamedNodes(Tree.get()); } void TreePattern::ComputeNamedNodes(TreePatternNode *N) { @@ -2536,22 +2574,22 @@ void TreePattern::ComputeNamedNodes(TreePatternNode *N) { ComputeNamedNodes(N->getChild(i)); } - -TreePatternNode *TreePattern::ParseTreePattern(Init *TheInit, StringRef OpName){ +TreePatternNodePtr TreePattern::ParseTreePattern(Init *TheInit, + StringRef OpName) { if (DefInit *DI = dyn_cast<DefInit>(TheInit)) { Record *R = DI->getDef(); // Direct reference to a leaf DagNode or PatFrag? Turn it into a // TreePatternNode of its own. For example: /// (foo GPR, imm) -> (foo GPR, (imm)) - if (R->isSubClassOf("SDNode") || R->isSubClassOf("PatFrag")) + if (R->isSubClassOf("SDNode") || R->isSubClassOf("PatFrags")) return ParseTreePattern( DagInit::get(DI, nullptr, std::vector<std::pair<Init*, StringInit*> >()), OpName); // Input argument? - TreePatternNode *Res = new TreePatternNode(DI, 1); + TreePatternNodePtr Res = std::make_shared<TreePatternNode>(DI, 1); if (R->getName() == "node" && !OpName.empty()) { if (OpName.empty()) error("'node' argument requires a name to match with operand list"); @@ -2566,16 +2604,18 @@ TreePatternNode *TreePattern::ParseTreePattern(Init *TheInit, StringRef OpName){ if (isa<UnsetInit>(TheInit)) { if (OpName.empty()) error("'?' argument requires a name to match with operand list"); - TreePatternNode *Res = new TreePatternNode(TheInit, 1); + TreePatternNodePtr Res = std::make_shared<TreePatternNode>(TheInit, 1); Args.push_back(OpName); Res->setName(OpName); return Res; } - if (IntInit *II = dyn_cast<IntInit>(TheInit)) { + if (isa<IntInit>(TheInit) || isa<BitInit>(TheInit)) { if (!OpName.empty()) - error("Constant int argument should not have a name!"); - return new TreePatternNode(II, 1); + error("Constant int or bit argument should not have a name!"); + if (isa<BitInit>(TheInit)) + TheInit = TheInit->convertInitializerTo(IntRecTy::get()); + return std::make_shared<TreePatternNode>(TheInit, 1); } if (BitsInit *BI = dyn_cast<BitsInit>(TheInit)) { @@ -2601,8 +2641,8 @@ TreePatternNode *TreePattern::ParseTreePattern(Init *TheInit, StringRef OpName){ if (Dag->getNumArgs() != 1) error("Type cast only takes one operand!"); - TreePatternNode *New = ParseTreePattern(Dag->getArg(0), - Dag->getArgNameStr(0)); + TreePatternNodePtr New = + ParseTreePattern(Dag->getArg(0), Dag->getArgNameStr(0)); // Apply the type cast. assert(New->getNumTypes() == 1 && "FIXME: Unhandled"); @@ -2615,7 +2655,7 @@ TreePatternNode *TreePattern::ParseTreePattern(Init *TheInit, StringRef OpName){ } // Verify that this is something that makes sense for an operator. - if (!Operator->isSubClassOf("PatFrag") && + if (!Operator->isSubClassOf("PatFrags") && !Operator->isSubClassOf("SDNode") && !Operator->isSubClassOf("Instruction") && !Operator->isSubClassOf("SDNodeXForm") && @@ -2650,13 +2690,17 @@ TreePatternNode *TreePattern::ParseTreePattern(Init *TheInit, StringRef OpName){ error("Cannot use '" + Operator->getName() + "' in an output pattern!"); } - std::vector<TreePatternNode*> Children; + std::vector<TreePatternNodePtr> Children; // Parse all the operands. for (unsigned i = 0, e = Dag->getNumArgs(); i != e; ++i) Children.push_back(ParseTreePattern(Dag->getArg(i), Dag->getArgNameStr(i))); - // If the operator is an intrinsic, then this is just syntactic sugar for for + // Get the actual number of results before Operator is converted to an intrinsic + // node (which is hard-coded to have either zero or one result). + unsigned NumResults = GetNumNodeResults(Operator, CDP); + + // If the operator is an intrinsic, then this is just syntactic sugar for // (intrinsic_* <number>, ..children..). Pick the right intrinsic node, and // convert the intrinsic name to a number. if (Operator->isSubClassOf("Intrinsic")) { @@ -2673,13 +2717,13 @@ TreePatternNode *TreePattern::ParseTreePattern(Init *TheInit, StringRef OpName){ else // Otherwise, no chain. Operator = getDAGPatterns().get_intrinsic_wo_chain_sdnode(); - TreePatternNode *IIDNode = new TreePatternNode(IntInit::get(IID), 1); - Children.insert(Children.begin(), IIDNode); + Children.insert(Children.begin(), + std::make_shared<TreePatternNode>(IntInit::get(IID), 1)); } if (Operator->isSubClassOf("ComplexPattern")) { for (unsigned i = 0; i < Children.size(); ++i) { - TreePatternNode *Child = Children[i]; + TreePatternNodePtr Child = Children[i]; if (Child->getName().empty()) error("All arguments to a ComplexPattern must be named"); @@ -2698,8 +2742,9 @@ TreePatternNode *TreePattern::ParseTreePattern(Init *TheInit, StringRef OpName){ } } - unsigned NumResults = GetNumNodeResults(Operator, CDP); - TreePatternNode *Result = new TreePatternNode(Operator, Children, NumResults); + TreePatternNodePtr Result = + std::make_shared<TreePatternNode>(Operator, std::move(Children), + NumResults); Result->setName(OpName); if (Dag->getName()) { @@ -2715,7 +2760,7 @@ TreePatternNode *TreePattern::ParseTreePattern(Init *TheInit, StringRef OpName){ /// more type generic things and have useless type casts fold away. /// /// This returns true if any change is made. -static bool SimplifyTree(TreePatternNode *&N) { +static bool SimplifyTree(TreePatternNodePtr &N) { if (N->isLeaf()) return false; @@ -2725,7 +2770,7 @@ static bool SimplifyTree(TreePatternNode *&N) { N->getExtType(0).isValueTypeByHwMode(false) && N->getExtType(0) == N->getChild(0)->getExtType(0) && N->getName().empty()) { - N = N->getChild(0); + N = N->getChildShared(0); SimplifyTree(N); return true; } @@ -2733,9 +2778,9 @@ static bool SimplifyTree(TreePatternNode *&N) { // Walk all children. bool MadeChange = false; for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) { - TreePatternNode *Child = N->getChild(i); + TreePatternNodePtr Child = N->getChildShared(i); MadeChange |= SimplifyTree(Child); - N->setChild(i, Child); + N->setChild(i, std::move(Child)); } return MadeChange; } @@ -2753,7 +2798,7 @@ InferAllTypes(const StringMap<SmallVector<TreePatternNode*,1> > *InNamedTypes) { bool MadeChange = true; while (MadeChange) { MadeChange = false; - for (TreePatternNode *&Tree : Trees) { + for (TreePatternNodePtr &Tree : Trees) { MadeChange |= Tree->ApplyTypeConstraints(*this, false); MadeChange |= SimplifyTree(Tree); } @@ -2781,7 +2826,7 @@ InferAllTypes(const StringMap<SmallVector<TreePatternNode*,1> > *InNamedTypes) { // changing the type of the input register in this case. This allows // us to match things like: // def : Pat<(v1i64 (bitconvert(v2i32 DPR:$src))), (v1i64 DPR:$src)>; - if (Node == Trees[0] && Node->isLeaf()) { + if (Node == Trees[0].get() && Node->isLeaf()) { DefInit *DI = dyn_cast<DefInit>(Node->getLeafValue()); if (DI && (DI->getDef()->isSubClassOf("RegisterClass") || DI->getDef()->isSubClassOf("RegisterOperand"))) @@ -2812,7 +2857,7 @@ InferAllTypes(const StringMap<SmallVector<TreePatternNode*,1> > *InNamedTypes) { } bool HasUnresolvedTypes = false; - for (const TreePatternNode *Tree : Trees) + for (const TreePatternNodePtr &Tree : Trees) HasUnresolvedTypes |= Tree->ContainsUnresolvedType(*this); return !HasUnresolvedTypes; } @@ -2829,7 +2874,7 @@ void TreePattern::print(raw_ostream &OS) const { if (Trees.size() > 1) OS << "[\n"; - for (const TreePatternNode *Tree : Trees) { + for (const TreePatternNodePtr &Tree : Trees) { OS << "\t"; Tree->print(OS); OS << "\n"; @@ -2933,17 +2978,17 @@ void CodeGenDAGPatterns::ParseComplexPatterns() { /// inside a pattern fragment to a pattern fragment. /// void CodeGenDAGPatterns::ParsePatternFragments(bool OutFrags) { - std::vector<Record*> Fragments = Records.getAllDerivedDefinitions("PatFrag"); + std::vector<Record*> Fragments = Records.getAllDerivedDefinitions("PatFrags"); // First step, parse all of the fragments. for (Record *Frag : Fragments) { if (OutFrags != Frag->isSubClassOf("OutPatFrag")) continue; - DagInit *Tree = Frag->getValueAsDag("Fragment"); + ListInit *LI = Frag->getValueAsListInit("Fragments"); TreePattern *P = (PatternFragments[Frag] = llvm::make_unique<TreePattern>( - Frag, Tree, !Frag->isSubClassOf("OutPatFrag"), + Frag, LI, !Frag->isSubClassOf("OutPatFrag"), *this)).get(); // Validate the argument list, converting it to set, to discard duplicates. @@ -2991,13 +3036,15 @@ void CodeGenDAGPatterns::ParsePatternFragments(bool OutFrags) { // this fragment uses it. TreePredicateFn PredFn(P); if (!PredFn.isAlwaysTrue()) - P->getOnlyTree()->addPredicateFn(PredFn); + for (auto T : P->getTrees()) + T->addPredicateFn(PredFn); // If there is a node transformation corresponding to this, keep track of // it. Record *Transform = Frag->getValueAsDef("OperandTransform"); if (!getSDNodeTransform(Transform).second.empty()) // not noop xform? - P->getOnlyTree()->setTransformFn(Transform); + for (auto T : P->getTrees()) + T->setTransformFn(Transform); } // Now that we've parsed all of the tree fragments, do a closure on them so @@ -3010,12 +3057,18 @@ void CodeGenDAGPatterns::ParsePatternFragments(bool OutFrags) { ThePat.InlinePatternFragments(); // 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. - ThePat.InferAllTypes(); - ThePat.resetError(); + // all of them, some may depend on the inputs of the pattern. Also, don't + // validate type sets; validation may cause spurious failures e.g. if a + // fragment needs floating-point types but the current target does not have + // any (this is only an error if that fragment is ever used!). + { + TypeInfer::SuppressValidation SV(ThePat.getInfer()); + ThePat.InferAllTypes(); + ThePat.resetError(); + } // If debugging, print out the pattern fragment result. - DEBUG(ThePat.dump()); + LLVM_DEBUG(ThePat.dump()); } } @@ -3045,9 +3098,9 @@ void CodeGenDAGPatterns::ParseDefaultOperands() { // Copy the operands over into a DAGDefaultOperand. DAGDefaultOperand DefaultOpInfo; - TreePatternNode *T = P.getTree(0); + const TreePatternNodePtr &T = P.getTree(0); for (unsigned op = 0, e = T->getNumChildren(); op != e; ++op) { - TreePatternNode *TPN = T->getChild(op); + TreePatternNodePtr TPN = T->getChildShared(op); while (TPN->ApplyTypeConstraints(P, false)) /* Resolve all types */; @@ -3056,7 +3109,7 @@ void CodeGenDAGPatterns::ParseDefaultOperands() { DefaultOps[i]->getName() + "' doesn't have a concrete type!"); } - DefaultOpInfo.DefaultOps.push_back(TPN); + DefaultOpInfo.DefaultOps.push_back(std::move(TPN)); } // Insert it into the DefaultOperands map so we can find it later. @@ -3066,15 +3119,15 @@ void CodeGenDAGPatterns::ParseDefaultOperands() { /// HandleUse - Given "Pat" a leaf in the pattern, check to see if it is an /// instruction input. Return true if this is a real use. -static bool HandleUse(TreePattern *I, TreePatternNode *Pat, - std::map<std::string, TreePatternNode*> &InstInputs) { +static bool HandleUse(TreePattern &I, TreePatternNodePtr Pat, + std::map<std::string, TreePatternNodePtr> &InstInputs) { // No name -> not interesting. if (Pat->getName().empty()) { if (Pat->isLeaf()) { DefInit *DI = dyn_cast<DefInit>(Pat->getLeafValue()); if (DI && (DI->getDef()->isSubClassOf("RegisterClass") || DI->getDef()->isSubClassOf("RegisterOperand"))) - I->error("Input " + DI->getDef()->getName() + " must be named!"); + I.error("Input " + DI->getDef()->getName() + " must be named!"); } return false; } @@ -3082,7 +3135,8 @@ static bool HandleUse(TreePattern *I, TreePatternNode *Pat, Record *Rec; if (Pat->isLeaf()) { DefInit *DI = dyn_cast<DefInit>(Pat->getLeafValue()); - if (!DI) I->error("Input $" + Pat->getName() + " must be an identifier!"); + if (!DI) + I.error("Input $" + Pat->getName() + " must be an identifier!"); Rec = DI->getDef(); } else { Rec = Pat->getOperator(); @@ -3092,7 +3146,7 @@ static bool HandleUse(TreePattern *I, TreePatternNode *Pat, if (Rec->getName() == "srcvalue") return false; - TreePatternNode *&Slot = InstInputs[Pat->getName()]; + TreePatternNodePtr &Slot = InstInputs[Pat->getName()]; if (!Slot) { Slot = Pat; return true; @@ -3107,24 +3161,38 @@ static bool HandleUse(TreePattern *I, TreePatternNode *Pat, // Ensure that the inputs agree if we've already seen this input. if (Rec != SlotRec) - I->error("All $" + Pat->getName() + " inputs must agree with each other"); + I.error("All $" + Pat->getName() + " inputs must agree with each other"); + // Ensure that the types can agree as well. + Slot->UpdateNodeType(0, Pat->getExtType(0), I); + Pat->UpdateNodeType(0, Slot->getExtType(0), I); if (Slot->getExtTypes() != Pat->getExtTypes()) - I->error("All $" + Pat->getName() + " inputs must agree with each other"); + I.error("All $" + Pat->getName() + " inputs must agree with each other"); return true; } /// FindPatternInputsAndOutputs - Scan the specified TreePatternNode (which is /// part of "I", the instruction), computing the set of inputs and outputs of /// the pattern. Report errors if we see anything naughty. -void CodeGenDAGPatterns:: -FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat, - std::map<std::string, TreePatternNode*> &InstInputs, - std::map<std::string, TreePatternNode*>&InstResults, - std::vector<Record*> &InstImpResults) { +void CodeGenDAGPatterns::FindPatternInputsAndOutputs( + TreePattern &I, TreePatternNodePtr Pat, + std::map<std::string, TreePatternNodePtr> &InstInputs, + std::map<std::string, TreePatternNodePtr> &InstResults, + std::vector<Record *> &InstImpResults) { + + // The instruction pattern still has unresolved fragments. For *named* + // nodes we must resolve those here. This may not result in multiple + // alternatives. + if (!Pat->getName().empty()) { + TreePattern SrcPattern(I.getRecord(), Pat, true, *this); + SrcPattern.InlinePatternFragments(); + SrcPattern.InferAllTypes(); + Pat = SrcPattern.getOnlyTree(); + } + if (Pat->isLeaf()) { bool isUse = HandleUse(I, Pat, InstInputs); if (!isUse && Pat->getTransformFn()) - I->error("Cannot specify a transform function for a non-input value!"); + I.error("Cannot specify a transform function for a non-input value!"); return; } @@ -3132,11 +3200,11 @@ FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat, for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i) { TreePatternNode *Dest = Pat->getChild(i); if (!Dest->isLeaf()) - I->error("implicitly defined value should be a register!"); + I.error("implicitly defined value should be a register!"); DefInit *Val = dyn_cast<DefInit>(Dest->getLeafValue()); if (!Val || !Val->getDef()->isSubClassOf("Register")) - I->error("implicitly defined value should be a register!"); + I.error("implicitly defined value should be a register!"); InstImpResults.push_back(Val->getDef()); } return; @@ -3147,9 +3215,9 @@ FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat, // and recurse. for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i) { if (Pat->getChild(i)->getNumTypes() == 0) - I->error("Cannot have void nodes inside of patterns!"); - FindPatternInputsAndOutputs(I, Pat->getChild(i), InstInputs, InstResults, - InstImpResults); + I.error("Cannot have void nodes inside of patterns!"); + FindPatternInputsAndOutputs(I, Pat->getChildShared(i), InstInputs, + InstResults, InstImpResults); } // If this is a non-leaf node with no children, treat it basically as if @@ -3157,27 +3225,33 @@ FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat, bool isUse = HandleUse(I, Pat, InstInputs); if (!isUse && Pat->getTransformFn()) - I->error("Cannot specify a transform function for a non-input value!"); + I.error("Cannot specify a transform function for a non-input value!"); return; } // Otherwise, this is a set, validate and collect instruction results. if (Pat->getNumChildren() == 0) - I->error("set requires operands!"); + I.error("set requires operands!"); if (Pat->getTransformFn()) - I->error("Cannot specify a transform function on a set node!"); + I.error("Cannot specify a transform function on a set node!"); // Check the set destinations. unsigned NumDests = Pat->getNumChildren()-1; for (unsigned i = 0; i != NumDests; ++i) { - TreePatternNode *Dest = Pat->getChild(i); + TreePatternNodePtr Dest = Pat->getChildShared(i); + // For set destinations we also must resolve fragments here. + TreePattern DestPattern(I.getRecord(), Dest, false, *this); + DestPattern.InlinePatternFragments(); + DestPattern.InferAllTypes(); + Dest = DestPattern.getOnlyTree(); + if (!Dest->isLeaf()) - I->error("set destination should be a register!"); + I.error("set destination should be a register!"); DefInit *Val = dyn_cast<DefInit>(Dest->getLeafValue()); if (!Val) { - I->error("set destination should be a register!"); + I.error("set destination should be a register!"); continue; } @@ -3186,20 +3260,20 @@ FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat, Val->getDef()->isSubClassOf("RegisterOperand") || Val->getDef()->isSubClassOf("PointerLikeRegClass")) { if (Dest->getName().empty()) - I->error("set destination must have a name!"); + I.error("set destination must have a name!"); if (InstResults.count(Dest->getName())) - I->error("cannot set '" + Dest->getName() +"' multiple times"); + I.error("cannot set '" + Dest->getName() + "' multiple times"); InstResults[Dest->getName()] = Dest; } else if (Val->getDef()->isSubClassOf("Register")) { InstImpResults.push_back(Val->getDef()); } else { - I->error("set destination should be a register!"); + I.error("set destination should be a register!"); } } // Verify and collect info from the computation. - FindPatternInputsAndOutputs(I, Pat->getChild(NumDests), - InstInputs, InstResults, InstImpResults); + FindPatternInputsAndOutputs(I, Pat->getChildShared(NumDests), InstInputs, + InstResults, InstImpResults); } //===----------------------------------------------------------------------===// @@ -3214,18 +3288,17 @@ public: bool mayLoad; bool isBitcast; bool isVariadic; + bool hasChain; 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)); - } + isBitcast(false), isVariadic(false), hasChain(false) {} void Analyze(const PatternToMatch &Pat) { - AnalyzeNode(Pat.getSrcPattern()); + const TreePatternNode *N = Pat.getSrcPattern(); + AnalyzeNode(N); + // These properties are detected only on the root node. + isBitcast = IsNodeBitcast(N); } private: @@ -3233,20 +3306,12 @@ private: if (hasSideEffects || mayLoad || mayStore || isVariadic) return false; - if (N->getNumChildren() != 2) + if (N->isLeaf()) return false; - - const TreePatternNode *N0 = N->getChild(0); - if (!N0->isLeaf() || !isa<DefInit>(N0->getLeafValue())) + if (N->getNumChildren() != 1 || !N->getChild(0)->isLeaf()) return false; - const TreePatternNode *N1 = N->getChild(1); - if (N1->isLeaf()) - return false; - if (N1->getNumChildren() != 1 || !N1->getChild(0)->isLeaf()) - return false; - - const SDNodeInfo &OpInfo = CDP.getSDNodeInfo(N1->getOperator()); + const SDNodeInfo &OpInfo = CDP.getSDNodeInfo(N->getOperator()); if (OpInfo.getNumResults() != 1 || OpInfo.getNumOperands() != 1) return false; return OpInfo.getEnumName() == "ISD::BITCAST"; @@ -3272,17 +3337,12 @@ public: for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) AnalyzeNode(N->getChild(i)); - // Ignore set nodes, which are not SDNodes. - if (N->getOperator()->getName() == "set") { - isBitcast = IsNodeBitcast(N); - return; - } - // Notice properties of the node. 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 (N->NodeHasProperty(SDNPHasChain, CDP)) hasChain = true; if (const CodeGenIntrinsic *IntInfo = N->getIntrinsicInfo(CDP)) { // If this is an intrinsic, analyze it. @@ -3345,7 +3405,13 @@ static bool InferFromPattern(CodeGenInstruction &InstInfo, InstInfo.mayLoad |= PatInfo.mayLoad; // These flags are silently added without any verification. - InstInfo.isBitcast |= PatInfo.isBitcast; + // FIXME: To match historical behavior of TableGen, for now add those flags + // only when we're inferring from the primary instruction pattern. + if (PatDef->isSubClassOf("Instruction")) { + InstInfo.isBitcast |= PatInfo.isBitcast; + InstInfo.hasChain |= PatInfo.hasChain; + InstInfo.hasChain_Inferred = true; + } // Don't infer isVariadic. This flag means something different on SDNodes and // instructions. For example, a CALL SDNode is variadic because it has the @@ -3416,37 +3482,30 @@ static bool checkOperandClass(CGIOperandList::OperandInfo &OI, return false; } -const DAGInstruction &CodeGenDAGPatterns::parseInstructionPattern( +void CodeGenDAGPatterns::parseInstructionPattern( CodeGenInstruction &CGI, ListInit *Pat, DAGInstMap &DAGInsts) { assert(!DAGInsts.count(CGI.TheDef) && "Instruction already parsed!"); // Parse the instruction. - TreePattern *I = new TreePattern(CGI.TheDef, Pat, true, *this); - // Inline pattern fragments into it. - I->InlinePatternFragments(); - - // Infer as many types as possible. If we cannot infer all of them, we can - // never do anything with this instruction pattern: report it to the user. - if (!I->InferAllTypes()) - I->error("Could not infer all types in pattern!"); + TreePattern I(CGI.TheDef, Pat, true, *this); // InstInputs - Keep track of all of the inputs of the instruction, along // with the record they are declared as. - std::map<std::string, TreePatternNode*> InstInputs; + std::map<std::string, TreePatternNodePtr> InstInputs; // InstResults - Keep track of all the virtual registers that are 'set' // in the instruction, including what reg class they are. - std::map<std::string, TreePatternNode*> InstResults; + std::map<std::string, TreePatternNodePtr> InstResults; std::vector<Record*> InstImpResults; // Verify that the top-level forms in the instruction are of void type, and // fill in the InstResults map. SmallString<32> TypesString; - for (unsigned j = 0, e = I->getNumTrees(); j != e; ++j) { + for (unsigned j = 0, e = I.getNumTrees(); j != e; ++j) { TypesString.clear(); - TreePatternNode *Pat = I->getTree(j); + TreePatternNodePtr Pat = I.getTree(j); if (Pat->getNumTypes() != 0) { raw_svector_ostream OS(TypesString); for (unsigned k = 0, ke = Pat->getNumTypes(); k != ke; ++k) { @@ -3454,7 +3513,7 @@ const DAGInstruction &CodeGenDAGPatterns::parseInstructionPattern( OS << ", "; Pat->getExtType(k).writeToStream(OS); } - I->error("Top-level forms in instruction pattern should have" + I.error("Top-level forms in instruction pattern should have" " void types, has types " + OS.str()); } @@ -3470,31 +3529,31 @@ const DAGInstruction &CodeGenDAGPatterns::parseInstructionPattern( unsigned NumResults = InstResults.size(); // Parse the operands list from the (ops) list, validating it. - assert(I->getArgList().empty() && "Args list should still be empty here!"); + assert(I.getArgList().empty() && "Args list should still be empty here!"); // Check that all of the results occur first in the list. std::vector<Record*> Results; - SmallVector<TreePatternNode *, 2> ResNodes; + SmallVector<TreePatternNodePtr, 2> ResNodes; for (unsigned i = 0; i != NumResults; ++i) { if (i == CGI.Operands.size()) - I->error("'" + InstResults.begin()->first + + I.error("'" + InstResults.begin()->first + "' set but does not appear in operand list!"); const std::string &OpName = CGI.Operands[i].Name; // Check that it exists in InstResults. - TreePatternNode *RNode = InstResults[OpName]; + TreePatternNodePtr RNode = InstResults[OpName]; if (!RNode) - I->error("Operand $" + OpName + " does not exist in operand list!"); + I.error("Operand $" + OpName + " does not exist in operand list!"); - ResNodes.push_back(RNode); Record *R = cast<DefInit>(RNode->getLeafValue())->getDef(); + ResNodes.push_back(std::move(RNode)); if (!R) - I->error("Operand $" + OpName + " should be a set destination: all " + I.error("Operand $" + OpName + " should be a set destination: all " "outputs must occur before inputs in operand list!"); if (!checkOperandClass(CGI.Operands[i], R)) - I->error("Operand $" + OpName + " class mismatch!"); + I.error("Operand $" + OpName + " class mismatch!"); // Remember the return type. Results.push_back(CGI.Operands[i].Rec); @@ -3503,19 +3562,16 @@ const DAGInstruction &CodeGenDAGPatterns::parseInstructionPattern( InstResults.erase(OpName); } - // Loop over the inputs next. Make a copy of InstInputs so we can destroy - // the copy while we're checking the inputs. - std::map<std::string, TreePatternNode*> InstInputsCheck(InstInputs); - - std::vector<TreePatternNode*> ResultNodeOperands; + // Loop over the inputs next. + std::vector<TreePatternNodePtr> ResultNodeOperands; std::vector<Record*> Operands; for (unsigned i = NumResults, e = CGI.Operands.size(); i != e; ++i) { CGIOperandList::OperandInfo &Op = CGI.Operands[i]; const std::string &OpName = Op.Name; if (OpName.empty()) - I->error("Operand #" + Twine(i) + " in operands list has no name!"); + I.error("Operand #" + Twine(i) + " in operands list has no name!"); - if (!InstInputsCheck.count(OpName)) { + if (!InstInputs.count(OpName)) { // 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")) { @@ -3524,22 +3580,22 @@ const DAGInstruction &CodeGenDAGPatterns::parseInstructionPattern( if (!getDefaultOperand(Op.Rec).DefaultOps.empty()) continue; } - I->error("Operand $" + OpName + + I.error("Operand $" + OpName + " does not appear in the instruction pattern"); } - TreePatternNode *InVal = InstInputsCheck[OpName]; - InstInputsCheck.erase(OpName); // It occurred, remove from map. + TreePatternNodePtr InVal = InstInputs[OpName]; + InstInputs.erase(OpName); // It occurred, remove from map. if (InVal->isLeaf() && isa<DefInit>(InVal->getLeafValue())) { Record *InRec = static_cast<DefInit*>(InVal->getLeafValue())->getDef(); if (!checkOperandClass(Op, InRec)) - I->error("Operand $" + OpName + "'s register class disagrees" + I.error("Operand $" + OpName + "'s register class disagrees" " between the operand and pattern"); } Operands.push_back(Op.Rec); // Construct the result for the dest-pattern operand list. - TreePatternNode *OpNode = InVal->clone(); + TreePatternNodePtr OpNode = InVal->clone(); // No predicate is useful on the result. OpNode->clearPredicateFns(); @@ -3547,42 +3603,47 @@ const DAGInstruction &CodeGenDAGPatterns::parseInstructionPattern( // Promote the xform function to be an explicit node if set. if (Record *Xform = OpNode->getTransformFn()) { OpNode->setTransformFn(nullptr); - std::vector<TreePatternNode*> Children; + std::vector<TreePatternNodePtr> Children; Children.push_back(OpNode); - OpNode = new TreePatternNode(Xform, Children, OpNode->getNumTypes()); + OpNode = std::make_shared<TreePatternNode>(Xform, std::move(Children), + OpNode->getNumTypes()); } - ResultNodeOperands.push_back(OpNode); + ResultNodeOperands.push_back(std::move(OpNode)); } - if (!InstInputsCheck.empty()) - I->error("Input operand $" + InstInputsCheck.begin()->first + - " occurs in pattern but not in operands list!"); + if (!InstInputs.empty()) + I.error("Input operand $" + InstInputs.begin()->first + + " occurs in pattern but not in operands list!"); - TreePatternNode *ResultPattern = - new TreePatternNode(I->getRecord(), ResultNodeOperands, - GetNumNodeResults(I->getRecord(), *this)); + TreePatternNodePtr ResultPattern = std::make_shared<TreePatternNode>( + I.getRecord(), std::move(ResultNodeOperands), + GetNumNodeResults(I.getRecord(), *this)); // Copy fully inferred output node types to instruction result pattern. for (unsigned i = 0; i != NumResults; ++i) { assert(ResNodes[i]->getNumTypes() == 1 && "FIXME: Unhandled"); ResultPattern->setType(i, ResNodes[i]->getExtType(0)); } + // FIXME: Assume only the first tree is the pattern. The others are clobber + // nodes. + TreePatternNodePtr Pattern = I.getTree(0); + TreePatternNodePtr SrcPattern; + if (Pattern->getOperator()->getName() == "set") { + SrcPattern = Pattern->getChild(Pattern->getNumChildren()-1)->clone(); + } else{ + // Not a set (store or something?) + SrcPattern = Pattern; + } + // Create and insert the instruction. // FIXME: InstImpResults should not be part of DAGInstruction. - DAGInstruction TheInst(I, Results, Operands, InstImpResults); - 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 DAGInsts map. - TreePattern Temp(I->getRecord(), ResultPattern, false, *this); - Temp.InferAllTypes(&I->getNamedNodesMap()); + Record *R = I.getRecord(); + DAGInsts.emplace(std::piecewise_construct, std::forward_as_tuple(R), + std::forward_as_tuple(Results, Operands, InstImpResults, + SrcPattern, ResultPattern)); - DAGInstruction &TheInsertedInst = DAGInsts.find(I->getRecord())->second; - TheInsertedInst.setResultPattern(Temp.getOnlyTree()); - - return TheInsertedInst; + LLVM_DEBUG(I.dump()); } /// ParseInstructions - Parse all of the instructions, inlining and resolving @@ -3622,51 +3683,32 @@ void CodeGenDAGPatterns::ParseInstructions() { // Create and insert the instruction. std::vector<Record*> ImpResults; Instructions.insert(std::make_pair(Instr, - DAGInstruction(nullptr, Results, Operands, ImpResults))); + DAGInstruction(Results, Operands, ImpResults))); continue; // no pattern. } CodeGenInstruction &CGI = Target.getInstruction(Instr); - const DAGInstruction &DI = parseInstructionPattern(CGI, LI, Instructions); - - (void)DI; - DEBUG(DI.getPattern()->dump()); + parseInstructionPattern(CGI, LI, Instructions); } // If we can, convert the instructions to be patterns that are matched! for (auto &Entry : Instructions) { + Record *Instr = Entry.first; DAGInstruction &TheInst = Entry.second; - TreePattern *I = TheInst.getPattern(); - if (!I) continue; // No pattern. - - if (PatternRewriter) - PatternRewriter(I); - // FIXME: Assume only the first tree is the pattern. The others are clobber - // nodes. - TreePatternNode *Pattern = I->getTree(0); - TreePatternNode *SrcPattern; - if (Pattern->getOperator()->getName() == "set") { - SrcPattern = Pattern->getChild(Pattern->getNumChildren()-1)->clone(); - } else{ - // Not a set (store or something?) - SrcPattern = Pattern; - } + TreePatternNodePtr SrcPattern = TheInst.getSrcPattern(); + TreePatternNodePtr ResultPattern = TheInst.getResultPattern(); - Record *Instr = Entry.first; - ListInit *Preds = Instr->getValueAsListInit("Predicates"); - int Complexity = Instr->getValueAsInt("AddedComplexity"); - AddPatternToMatch( - I, - PatternToMatch(Instr, makePredList(Preds), SrcPattern, - TheInst.getResultPattern(), TheInst.getImpResults(), - Complexity, Instr->getID())); + if (SrcPattern && ResultPattern) { + TreePattern Pattern(Instr, SrcPattern, true, *this); + TreePattern Result(Instr, ResultPattern, false, *this); + ParseOnePattern(Instr, Pattern, Result, TheInst.getImpResults()); + } } } +typedef std::pair<TreePatternNode *, unsigned> NameRecord; -typedef std::pair<const TreePatternNode*, unsigned> NameRecord; - -static void FindNames(const TreePatternNode *P, +static void FindNames(TreePatternNode *P, std::map<std::string, NameRecord> &Names, TreePattern *PatternTop) { if (!P->getName().empty()) { @@ -3695,7 +3737,7 @@ std::vector<Predicate> CodeGenDAGPatterns::makePredList(ListInit *L) { } // Sort so that different orders get canonicalized to the same string. - std::sort(Preds.begin(), Preds.end()); + llvm::sort(Preds.begin(), Preds.end()); return Preds; } @@ -3739,34 +3781,18 @@ void CodeGenDAGPatterns::AddPatternToMatch(TreePattern *Pattern, SrcNames[Entry.first].second == 1) Pattern->error("Pattern has dead named input: $" + Entry.first); - PatternsToMatch.push_back(std::move(PTM)); + PatternsToMatch.push_back(PTM); } void CodeGenDAGPatterns::InferInstructionFlags() { ArrayRef<const CodeGenInstruction*> Instructions = Target.getInstructionsByEnumValue(); - // First try to infer flags from the primary instruction pattern, if any. - SmallVector<CodeGenInstruction*, 8> Revisit; unsigned Errors = 0; - for (unsigned i = 0, e = Instructions.size(); i != e; ++i) { - CodeGenInstruction &InstInfo = - const_cast<CodeGenInstruction &>(*Instructions[i]); - - // 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. + // Try to infer flags from all patterns in PatternToMatch. These include + // both the primary instruction patterns (which always come first) and + // patterns defined outside the instruction. for (const PatternToMatch &PTM : ptms()) { // We can only infer from single-instruction patterns, otherwise we won't // know which instruction should get the flags. @@ -3790,9 +3816,11 @@ void CodeGenDAGPatterns::InferInstructionFlags() { if (Errors) PrintFatalError("pattern conflicts"); - // Revisit instructions with undefined flags and no pattern. + // If requested by the target, guess any undefined properties. if (Target.guessInstructionProperties()) { - for (CodeGenInstruction *InstInfo : Revisit) { + for (unsigned i = 0, e = Instructions.size(); i != e; ++i) { + CodeGenInstruction *InstInfo = + const_cast<CodeGenInstruction *>(Instructions[i]); if (InstInfo->InferredFrom) continue; // The mayLoad and mayStore flags default to false. @@ -3804,7 +3832,9 @@ void CodeGenDAGPatterns::InferInstructionFlags() { } // Complain about any flags that are still undefined. - for (CodeGenInstruction *InstInfo : Revisit) { + for (unsigned i = 0, e = Instructions.size(); i != e; ++i) { + CodeGenInstruction *InstInfo = + const_cast<CodeGenInstruction *>(Instructions[i]); if (InstInfo->InferredFrom) continue; if (InstInfo->hasSideEffects_Unset) @@ -3916,6 +3946,122 @@ static bool ForceArbitraryInstResultType(TreePatternNode *N, TreePattern &TP) { return false; } +void CodeGenDAGPatterns::ParseOnePattern(Record *TheDef, + TreePattern &Pattern, TreePattern &Result, + const std::vector<Record *> &InstImpResults) { + + // Inline pattern fragments and expand multiple alternatives. + Pattern.InlinePatternFragments(); + Result.InlinePatternFragments(); + + if (Result.getNumTrees() != 1) + Result.error("Cannot use multi-alternative fragments in result pattern!"); + + // Infer types. + bool IterateInference; + bool InferredAllPatternTypes, InferredAllResultTypes; + do { + // Infer as many types as possible. If we cannot infer all of them, we + // can never do anything with this pattern: report it to the user. + InferredAllPatternTypes = + Pattern.InferAllTypes(&Pattern.getNamedNodesMap()); + + // Infer as many types as possible. If we cannot infer all of them, we + // can never do anything with this pattern: report it to the user. + InferredAllResultTypes = + Result.InferAllTypes(&Pattern.getNamedNodesMap()); + + IterateInference = false; + + // Apply the type of the result to the source pattern. This helps us + // resolve cases where the input type is known to be a pointer type (which + // is considered resolved), but the result knows it needs to be 32- or + // 64-bits. Infer the other way for good measure. + for (auto T : Pattern.getTrees()) + for (unsigned i = 0, e = std::min(Result.getOnlyTree()->getNumTypes(), + T->getNumTypes()); + i != e; ++i) { + IterateInference |= T->UpdateNodeType( + i, Result.getOnlyTree()->getExtType(i), Result); + IterateInference |= Result.getOnlyTree()->UpdateNodeType( + i, T->getExtType(i), Result); + } + + // If our iteration has converged and the input pattern's types are fully + // resolved but the result pattern is not fully resolved, we may have a + // situation where we have two instructions in the result pattern and + // the instructions require a common register class, but don't care about + // what actual MVT is used. This is actually a bug in our modelling: + // output patterns should have register classes, not MVTs. + // + // In any case, to handle this, we just go through and disambiguate some + // arbitrary types to the result pattern's nodes. + if (!IterateInference && InferredAllPatternTypes && + !InferredAllResultTypes) + IterateInference = + ForceArbitraryInstResultType(Result.getTree(0).get(), 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) + Pattern.error("Could not infer all types in pattern!"); + if (!InferredAllResultTypes) { + Pattern.dump(); + Result.error("Could not infer all types in pattern result!"); + } + + // Promote the xform function to be an explicit node if set. + const TreePatternNodePtr &DstPattern = Result.getOnlyTree(); + std::vector<TreePatternNodePtr> ResultNodeOperands; + for (unsigned ii = 0, ee = DstPattern->getNumChildren(); ii != ee; ++ii) { + TreePatternNodePtr OpNode = DstPattern->getChildShared(ii); + if (Record *Xform = OpNode->getTransformFn()) { + OpNode->setTransformFn(nullptr); + std::vector<TreePatternNodePtr> Children; + Children.push_back(OpNode); + OpNode = std::make_shared<TreePatternNode>(Xform, std::move(Children), + OpNode->getNumTypes()); + } + ResultNodeOperands.push_back(OpNode); + } + + TreePatternNodePtr DstShared = + DstPattern->isLeaf() + ? DstPattern + : std::make_shared<TreePatternNode>(DstPattern->getOperator(), + std::move(ResultNodeOperands), + DstPattern->getNumTypes()); + + for (unsigned i = 0, e = Result.getOnlyTree()->getNumTypes(); i != e; ++i) + DstShared->setType(i, Result.getOnlyTree()->getExtType(i)); + + TreePattern Temp(Result.getRecord(), DstShared, false, *this); + Temp.InferAllTypes(); + + ListInit *Preds = TheDef->getValueAsListInit("Predicates"); + int Complexity = TheDef->getValueAsInt("AddedComplexity"); + + if (PatternRewriter) + PatternRewriter(&Pattern); + + // A pattern may end up with an "impossible" type, i.e. a situation + // where all types have been eliminated for some node in this pattern. + // This could occur for intrinsics that only make sense for a specific + // value type, and use a specific register class. If, for some mode, + // that register class does not accept that type, the type inference + // will lead to a contradiction, which is not an error however, but + // a sign that this pattern will simply never match. + if (Temp.getOnlyTree()->hasPossibleType()) + for (auto T : Pattern.getTrees()) + if (T->hasPossibleType()) + AddPatternToMatch(&Pattern, + PatternToMatch(TheDef, makePredList(Preds), + T, Temp.getOnlyTree(), + InstImpResults, Complexity, + TheDef->getID())); +} + void CodeGenDAGPatterns::ParsePatterns() { std::vector<Record*> Patterns = Records.getAllDerivedDefinitions("Pattern"); @@ -3926,10 +4072,7 @@ void CodeGenDAGPatterns::ParsePatterns() { if (hasNullFragReference(Tree)) continue; - TreePattern *Pattern = new TreePattern(CurPattern, Tree, true, *this); - - // Inline pattern fragments into it. - Pattern->InlinePatternFragments(); + TreePattern Pattern(CurPattern, Tree, true, *this); ListInit *LI = CurPattern->getValueAsListInit("ResultInstrs"); if (LI->empty()) continue; // no pattern. @@ -3937,119 +4080,19 @@ void CodeGenDAGPatterns::ParsePatterns() { // Parse the instruction. TreePattern Result(CurPattern, LI, false, *this); - // Inline pattern fragments into it. - Result.InlinePatternFragments(); - if (Result.getNumTrees() != 1) Result.error("Cannot handle instructions producing instructions " "with temporaries yet!"); - bool IterateInference; - bool InferredAllPatternTypes, InferredAllResultTypes; - do { - // Infer as many types as possible. If we cannot infer all of them, we - // can never do anything with this pattern: report it to the user. - InferredAllPatternTypes = - Pattern->InferAllTypes(&Pattern->getNamedNodesMap()); - - // Infer as many types as possible. If we cannot infer all of them, we - // can never do anything with this pattern: report it to the user. - InferredAllResultTypes = - Result.InferAllTypes(&Pattern->getNamedNodesMap()); - - IterateInference = false; - - // Apply the type of the result to the source pattern. This helps us - // resolve cases where the input type is known to be a pointer type (which - // is considered resolved), but the result knows it needs to be 32- or - // 64-bits. Infer the other way for good measure. - for (unsigned i = 0, e = std::min(Result.getTree(0)->getNumTypes(), - Pattern->getTree(0)->getNumTypes()); - i != e; ++i) { - IterateInference = Pattern->getTree(0)->UpdateNodeType( - i, Result.getTree(0)->getExtType(i), Result); - IterateInference |= Result.getTree(0)->UpdateNodeType( - i, Pattern->getTree(0)->getExtType(i), Result); - } - - // If our iteration has converged and the input pattern's types are fully - // resolved but the result pattern is not fully resolved, we may have a - // situation where we have two instructions in the result pattern and - // the instructions require a common register class, but don't care about - // what actual MVT is used. This is actually a bug in our modelling: - // output patterns should have register classes, not MVTs. - // - // In any case, to handle this, we just go through and disambiguate some - // arbitrary types to the result pattern's nodes. - if (!IterateInference && InferredAllPatternTypes && - !InferredAllResultTypes) - IterateInference = - ForceArbitraryInstResultType(Result.getTree(0), 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) - Pattern->error("Could not infer all types in pattern!"); - if (!InferredAllResultTypes) { - Pattern->dump(); - Result.error("Could not infer all types in pattern result!"); - } - // Validate that the input pattern is correct. - std::map<std::string, TreePatternNode*> InstInputs; - std::map<std::string, TreePatternNode*> InstResults; + std::map<std::string, TreePatternNodePtr> InstInputs; + std::map<std::string, TreePatternNodePtr> InstResults; std::vector<Record*> InstImpResults; - for (unsigned j = 0, ee = Pattern->getNumTrees(); j != ee; ++j) - FindPatternInputsAndOutputs(Pattern, Pattern->getTree(j), - InstInputs, InstResults, - InstImpResults); + for (unsigned j = 0, ee = Pattern.getNumTrees(); j != ee; ++j) + FindPatternInputsAndOutputs(Pattern, Pattern.getTree(j), InstInputs, + InstResults, InstImpResults); - // Promote the xform function to be an explicit node if set. - TreePatternNode *DstPattern = Result.getOnlyTree(); - std::vector<TreePatternNode*> ResultNodeOperands; - for (unsigned ii = 0, ee = DstPattern->getNumChildren(); ii != ee; ++ii) { - TreePatternNode *OpNode = DstPattern->getChild(ii); - if (Record *Xform = OpNode->getTransformFn()) { - OpNode->setTransformFn(nullptr); - std::vector<TreePatternNode*> Children; - Children.push_back(OpNode); - OpNode = new TreePatternNode(Xform, Children, OpNode->getNumTypes()); - } - ResultNodeOperands.push_back(OpNode); - } - DstPattern = Result.getOnlyTree(); - if (!DstPattern->isLeaf()) - DstPattern = new TreePatternNode(DstPattern->getOperator(), - ResultNodeOperands, - DstPattern->getNumTypes()); - - for (unsigned i = 0, e = Result.getOnlyTree()->getNumTypes(); i != e; ++i) - DstPattern->setType(i, Result.getOnlyTree()->getExtType(i)); - - TreePattern Temp(Result.getRecord(), DstPattern, false, *this); - Temp.InferAllTypes(); - - // A pattern may end up with an "impossible" type, i.e. a situation - // where all types have been eliminated for some node in this pattern. - // This could occur for intrinsics that only make sense for a specific - // value type, and use a specific register class. If, for some mode, - // that register class does not accept that type, the type inference - // will lead to a contradiction, which is not an error however, but - // a sign that this pattern will simply never match. - if (Pattern->getTree(0)->hasPossibleType() && - Temp.getOnlyTree()->hasPossibleType()) { - ListInit *Preds = CurPattern->getValueAsListInit("Predicates"); - int Complexity = CurPattern->getValueAsInt("AddedComplexity"); - if (PatternRewriter) - PatternRewriter(Pattern); - AddPatternToMatch( - Pattern, - PatternToMatch( - CurPattern, makePredList(Preds), Pattern->getTree(0), - Temp.getOnlyTree(), std::move(InstImpResults), Complexity, - CurPattern->getID())); - } + ParseOnePattern(CurPattern, Pattern, Result, InstImpResults); } } @@ -4068,25 +4111,24 @@ void CodeGenDAGPatterns::ExpandHwModeBasedTypes() { std::vector<PatternToMatch> Copy = PatternsToMatch; PatternsToMatch.clear(); - auto AppendPattern = [this,&ModeChecks](PatternToMatch &P, unsigned Mode) { - TreePatternNode *NewSrc = P.SrcPattern->clone(); - TreePatternNode *NewDst = P.DstPattern->clone(); + auto AppendPattern = [this, &ModeChecks](PatternToMatch &P, unsigned Mode) { + TreePatternNodePtr NewSrc = P.SrcPattern->clone(); + TreePatternNodePtr NewDst = P.DstPattern->clone(); if (!NewSrc->setDefaultMode(Mode) || !NewDst->setDefaultMode(Mode)) { - delete NewSrc; - delete NewDst; return; } std::vector<Predicate> Preds = P.Predicates; const std::vector<Predicate> &MC = ModeChecks[Mode]; Preds.insert(Preds.end(), MC.begin(), MC.end()); - PatternsToMatch.emplace_back(P.getSrcRecord(), Preds, NewSrc, NewDst, - P.getDstRegs(), P.getAddedComplexity(), - Record::getNewUID(), Mode); + PatternsToMatch.emplace_back(P.getSrcRecord(), Preds, std::move(NewSrc), + std::move(NewDst), P.getDstRegs(), + P.getAddedComplexity(), Record::getNewUID(), + Mode); }; for (PatternToMatch &P : Copy) { - TreePatternNode *SrcP = nullptr, *DstP = nullptr; + TreePatternNodePtr SrcP = nullptr, DstP = nullptr; if (P.SrcPattern->hasProperTypeByHwMode()) SrcP = P.SrcPattern; if (P.DstPattern->hasProperTypeByHwMode()) @@ -4098,9 +4140,9 @@ void CodeGenDAGPatterns::ExpandHwModeBasedTypes() { std::set<unsigned> Modes; if (SrcP) - collectModes(Modes, SrcP); + collectModes(Modes, SrcP.get()); if (DstP) - collectModes(Modes, DstP); + collectModes(Modes, DstP.get()); // The predicate for the default mode needs to be constructed for each // pattern separately. @@ -4168,13 +4210,13 @@ static void FindDepVars(TreePatternNode *N, MultipleUseVarSet &DepVars) { /// Dump the dependent variable set: static void DumpDepVars(MultipleUseVarSet &DepVars) { if (DepVars.empty()) { - DEBUG(errs() << "<empty set>"); + LLVM_DEBUG(errs() << "<empty set>"); } else { - DEBUG(errs() << "[ "); + LLVM_DEBUG(errs() << "[ "); for (const auto &DepVar : DepVars) { - DEBUG(errs() << DepVar.getKey() << " "); + LLVM_DEBUG(errs() << DepVar.getKey() << " "); } - DEBUG(errs() << "]"); + LLVM_DEBUG(errs() << "]"); } } #endif @@ -4182,11 +4224,11 @@ static void DumpDepVars(MultipleUseVarSet &DepVars) { /// CombineChildVariants - Given a bunch of permutations of each child of the /// 'operator' node, put them together in all possible ways. -static void CombineChildVariants(TreePatternNode *Orig, - const std::vector<std::vector<TreePatternNode*> > &ChildVariants, - std::vector<TreePatternNode*> &OutVariants, - CodeGenDAGPatterns &CDP, - const MultipleUseVarSet &DepVars) { +static void CombineChildVariants( + TreePatternNodePtr Orig, + const std::vector<std::vector<TreePatternNodePtr>> &ChildVariants, + std::vector<TreePatternNodePtr> &OutVariants, CodeGenDAGPatterns &CDP, + const MultipleUseVarSet &DepVars) { // Make sure that each operand has at least one variant to choose from. for (const auto &Variants : ChildVariants) if (Variants.empty()) @@ -4198,20 +4240,20 @@ static void CombineChildVariants(TreePatternNode *Orig, bool NotDone; do { #ifndef NDEBUG - DEBUG(if (!Idxs.empty()) { - errs() << Orig->getOperator()->getName() << ": Idxs = [ "; - for (unsigned Idx : Idxs) { - errs() << Idx << " "; - } - errs() << "]\n"; - }); + LLVM_DEBUG(if (!Idxs.empty()) { + errs() << Orig->getOperator()->getName() << ": Idxs = [ "; + for (unsigned Idx : Idxs) { + errs() << Idx << " "; + } + errs() << "]\n"; + }); #endif // Create the variant and add it to the output list. - std::vector<TreePatternNode*> NewChildren; + std::vector<TreePatternNodePtr> NewChildren; for (unsigned i = 0, e = ChildVariants.size(); i != e; ++i) NewChildren.push_back(ChildVariants[i][Idxs[i]]); - auto R = llvm::make_unique<TreePatternNode>( - Orig->getOperator(), NewChildren, Orig->getNumTypes()); + TreePatternNodePtr R = std::make_shared<TreePatternNode>( + Orig->getOperator(), std::move(NewChildren), Orig->getNumTypes()); // Copy over properties. R->setName(Orig->getName()); @@ -4227,10 +4269,10 @@ static void CombineChildVariants(TreePatternNode *Orig, // (and GPRC:$a, GPRC:$b) -> (and GPRC:$b, GPRC:$a) // which are the same pattern. Ignore the dups. if (R->canPatternMatch(ErrString, CDP) && - none_of(OutVariants, [&](TreePatternNode *Variant) { - return R->isIsomorphicTo(Variant, DepVars); + none_of(OutVariants, [&](TreePatternNodePtr Variant) { + return R->isIsomorphicTo(Variant.get(), DepVars); })) - OutVariants.push_back(R.release()); + OutVariants.push_back(R); // Increment indices to the next permutation by incrementing the // indices from last index backward, e.g., generate the sequence @@ -4248,21 +4290,21 @@ static void CombineChildVariants(TreePatternNode *Orig, /// CombineChildVariants - A helper function for binary operators. /// -static void CombineChildVariants(TreePatternNode *Orig, - const std::vector<TreePatternNode*> &LHS, - const std::vector<TreePatternNode*> &RHS, - std::vector<TreePatternNode*> &OutVariants, +static void CombineChildVariants(TreePatternNodePtr Orig, + const std::vector<TreePatternNodePtr> &LHS, + const std::vector<TreePatternNodePtr> &RHS, + std::vector<TreePatternNodePtr> &OutVariants, CodeGenDAGPatterns &CDP, const MultipleUseVarSet &DepVars) { - std::vector<std::vector<TreePatternNode*> > ChildVariants; + std::vector<std::vector<TreePatternNodePtr>> ChildVariants; ChildVariants.push_back(LHS); ChildVariants.push_back(RHS); CombineChildVariants(Orig, ChildVariants, OutVariants, CDP, DepVars); } - -static void GatherChildrenOfAssociativeOpcode(TreePatternNode *N, - std::vector<TreePatternNode *> &Children) { +static void +GatherChildrenOfAssociativeOpcode(TreePatternNodePtr N, + std::vector<TreePatternNodePtr> &Children) { assert(N->getNumChildren()==2 &&"Associative but doesn't have 2 children!"); Record *Operator = N->getOperator(); @@ -4274,21 +4316,21 @@ static void GatherChildrenOfAssociativeOpcode(TreePatternNode *N, } if (N->getChild(0)->isLeaf() || N->getChild(0)->getOperator() != Operator) - Children.push_back(N->getChild(0)); + Children.push_back(N->getChildShared(0)); else - GatherChildrenOfAssociativeOpcode(N->getChild(0), Children); + GatherChildrenOfAssociativeOpcode(N->getChildShared(0), Children); if (N->getChild(1)->isLeaf() || N->getChild(1)->getOperator() != Operator) - Children.push_back(N->getChild(1)); + Children.push_back(N->getChildShared(1)); else - GatherChildrenOfAssociativeOpcode(N->getChild(1), Children); + GatherChildrenOfAssociativeOpcode(N->getChildShared(1), Children); } /// GenerateVariantsOf - Given a pattern N, generate all permutations we can of /// the (potentially recursive) pattern by using algebraic laws. /// -static void GenerateVariantsOf(TreePatternNode *N, - std::vector<TreePatternNode*> &OutVariants, +static void GenerateVariantsOf(TreePatternNodePtr N, + std::vector<TreePatternNodePtr> &OutVariants, CodeGenDAGPatterns &CDP, const MultipleUseVarSet &DepVars) { // We cannot permute leaves or ComplexPattern uses. @@ -4303,14 +4345,14 @@ static void GenerateVariantsOf(TreePatternNode *N, // If this node is associative, re-associate. if (NodeInfo.hasProperty(SDNPAssociative)) { // Re-associate by pulling together all of the linked operators - std::vector<TreePatternNode*> MaximalChildren; + std::vector<TreePatternNodePtr> MaximalChildren; GatherChildrenOfAssociativeOpcode(N, MaximalChildren); // Only handle child sizes of 3. Otherwise we'll end up trying too many // permutations. if (MaximalChildren.size() == 3) { // Find the variants of all of our maximal children. - std::vector<TreePatternNode*> AVariants, BVariants, CVariants; + std::vector<TreePatternNodePtr> AVariants, BVariants, CVariants; GenerateVariantsOf(MaximalChildren[0], AVariants, CDP, DepVars); GenerateVariantsOf(MaximalChildren[1], BVariants, CDP, DepVars); GenerateVariantsOf(MaximalChildren[2], CVariants, CDP, DepVars); @@ -4320,12 +4362,12 @@ static void GenerateVariantsOf(TreePatternNode *N, // Within these forms, we can also permute A/B/C. // Generate legal pair permutations of A/B/C. - std::vector<TreePatternNode*> ABVariants; - std::vector<TreePatternNode*> BAVariants; - std::vector<TreePatternNode*> ACVariants; - std::vector<TreePatternNode*> CAVariants; - std::vector<TreePatternNode*> BCVariants; - std::vector<TreePatternNode*> CBVariants; + std::vector<TreePatternNodePtr> ABVariants; + std::vector<TreePatternNodePtr> BAVariants; + std::vector<TreePatternNodePtr> ACVariants; + std::vector<TreePatternNodePtr> CAVariants; + std::vector<TreePatternNodePtr> BCVariants; + std::vector<TreePatternNodePtr> CBVariants; CombineChildVariants(N, AVariants, BVariants, ABVariants, CDP, DepVars); CombineChildVariants(N, BVariants, AVariants, BAVariants, CDP, DepVars); CombineChildVariants(N, AVariants, CVariants, ACVariants, CDP, DepVars); @@ -4353,10 +4395,10 @@ static void GenerateVariantsOf(TreePatternNode *N, } // Compute permutations of all children. - std::vector<std::vector<TreePatternNode*> > ChildVariants; + std::vector<std::vector<TreePatternNodePtr>> ChildVariants; ChildVariants.resize(N->getNumChildren()); for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) - GenerateVariantsOf(N->getChild(i), ChildVariants[i], CDP, DepVars); + GenerateVariantsOf(N->getChildShared(i), ChildVariants[i], CDP, DepVars); // Build all permutations based on how the children were formed. CombineChildVariants(N, ChildVariants, OutVariants, CDP, DepVars); @@ -4385,19 +4427,19 @@ static void GenerateVariantsOf(TreePatternNode *N, // after those. assert(NC >= 3 && "Commutative intrinsic should have at least 3 children!"); - std::vector<std::vector<TreePatternNode*> > Variants; - Variants.push_back(ChildVariants[0]); // Intrinsic id. - Variants.push_back(ChildVariants[2]); - Variants.push_back(ChildVariants[1]); + std::vector<std::vector<TreePatternNodePtr>> Variants; + Variants.push_back(std::move(ChildVariants[0])); // Intrinsic id. + Variants.push_back(std::move(ChildVariants[2])); + Variants.push_back(std::move(ChildVariants[1])); for (unsigned i = 3; i != NC; ++i) - Variants.push_back(ChildVariants[i]); + Variants.push_back(std::move(ChildVariants[i])); CombineChildVariants(N, Variants, OutVariants, CDP, DepVars); } else if (NC == N->getNumChildren()) { - std::vector<std::vector<TreePatternNode*> > Variants; - Variants.push_back(ChildVariants[1]); - Variants.push_back(ChildVariants[0]); + std::vector<std::vector<TreePatternNodePtr>> Variants; + Variants.push_back(std::move(ChildVariants[1])); + Variants.push_back(std::move(ChildVariants[0])); for (unsigned i = 2; i != NC; ++i) - Variants.push_back(ChildVariants[i]); + Variants.push_back(std::move(ChildVariants[i])); CombineChildVariants(N, Variants, OutVariants, CDP, DepVars); } } @@ -4407,7 +4449,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() { - DEBUG(errs() << "Generating instruction variants.\n"); + LLVM_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 @@ -4420,28 +4462,26 @@ void CodeGenDAGPatterns::GenerateVariants() { // for (unsigned i = 0, e = PatternsToMatch.size(); i != e; ++i) { MultipleUseVarSet DepVars; - std::vector<TreePatternNode*> Variants; + std::vector<TreePatternNodePtr> Variants; FindDepVars(PatternsToMatch[i].getSrcPattern(), DepVars); - DEBUG(errs() << "Dependent/multiply used variables: "); - DEBUG(DumpDepVars(DepVars)); - DEBUG(errs() << "\n"); - GenerateVariantsOf(PatternsToMatch[i].getSrcPattern(), Variants, *this, - DepVars); + LLVM_DEBUG(errs() << "Dependent/multiply used variables: "); + LLVM_DEBUG(DumpDepVars(DepVars)); + LLVM_DEBUG(errs() << "\n"); + GenerateVariantsOf(PatternsToMatch[i].getSrcPatternShared(), Variants, + *this, DepVars); assert(!Variants.empty() && "Must create at least original variant!"); if (Variants.size() == 1) // No additional variants for this pattern. continue; - DEBUG(errs() << "FOUND VARIANTS OF: "; - PatternsToMatch[i].getSrcPattern()->dump(); - errs() << "\n"); + LLVM_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]; + TreePatternNodePtr Variant = Variants[v]; - DEBUG(errs() << " VAR#" << v << ": "; - Variant->dump(); - errs() << "\n"); + LLVM_DEBUG(errs() << " VAR#" << v << ": "; Variant->dump(); + errs() << "\n"); // Scan to see if an instruction or explicit pattern already matches this. bool AlreadyExists = false; @@ -4453,7 +4493,7 @@ void CodeGenDAGPatterns::GenerateVariants() { // Check to see if this variant already exists. if (Variant->isIsomorphicTo(PatternsToMatch[p].getSrcPattern(), DepVars)) { - DEBUG(errs() << " *** ALREADY EXISTS, ignoring variant.\n"); + LLVM_DEBUG(errs() << " *** ALREADY EXISTS, ignoring variant.\n"); AlreadyExists = true; break; } @@ -4464,11 +4504,11 @@ void CodeGenDAGPatterns::GenerateVariants() { // Otherwise, add it to the list of patterns we have. PatternsToMatch.push_back(PatternToMatch( PatternsToMatch[i].getSrcRecord(), PatternsToMatch[i].getPredicates(), - Variant, PatternsToMatch[i].getDstPattern(), + Variant, PatternsToMatch[i].getDstPatternShared(), PatternsToMatch[i].getDstRegs(), PatternsToMatch[i].getAddedComplexity(), Record::getNewUID())); } - DEBUG(errs() << "\n"); + LLVM_DEBUG(errs() << "\n"); } } |