summaryrefslogtreecommitdiff
path: root/utils/TableGen/CodeGenDAGPatterns.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/TableGen/CodeGenDAGPatterns.cpp')
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.cpp1048
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");
}
}