/// getPatternSize - Return the 'size' of this pattern. We want to match large
/// patterns before small ones. This is used to determine the size of a
/// pattern.
-static unsigned getPatternSize(const TreePatternNode &P,
+static unsigned getPatternSize(const TreePatternNode *P,
const CodeGenDAGPatterns &CGP) {
unsigned Size = 3; // The node itself.
// If the root node is a ConstantSDNode, increases its size.
// e.g. (set R32:$dst, 0).
- if (P.isLeaf() && isa<IntInit>(P.getLeafValue()))
+ if (P->isLeaf() && isa<IntInit>(P->getLeafValue()))
Size += 2;
- if (const ComplexPattern *AM = P.getComplexPatternInfo(CGP)) {
+ if (const ComplexPattern *AM = P->getComplexPatternInfo(CGP)) {
Size += AM->getComplexity();
// We don't want to count any children twice, so return early.
return Size;
// If this node has some predicate function that must match, it adds to the
// complexity of this node.
- if (!P.getPredicateFns().empty())
+ if (!P->getPredicateFns().empty())
++Size;
// Count children in the count if they are also nodes.
- for (unsigned i = 0, e = P.getNumChildren(); i != e; ++i) {
- const TreePatternNode &Child = P.getChild(i);
- if (!Child.isLeaf() && Child.getNumTypes()) {
- const TypeSetByHwMode &T0 = Child.getType(0);
+ for (unsigned i = 0, e = P->getNumChildren(); i != e; ++i) {
+ const TreePatternNode *Child = P->getChild(i);
+ if (!Child->isLeaf() && Child->getNumTypes()) {
+ const TypeSetByHwMode &T0 = Child->getType(0);
// At this point, all variable type sets should be simple, i.e. only
// have a default mode.
if (T0.getMachineValueType() != MVT::Other) {
continue;
}
}
- if (Child.isLeaf()) {
- if (isa<IntInit>(Child.getLeafValue()))
+ if (Child->isLeaf()) {
+ if (isa<IntInit>(Child->getLeafValue()))
Size += 5; // Matches a ConstantSDNode (+3) and a specific value (+2).
- else if (Child.getComplexPatternInfo(CGP))
+ else if (Child->getComplexPatternInfo(CGP))
Size += getPatternSize(Child, CGP);
- else if (!Child.getPredicateFns().empty())
+ else if (!Child->getPredicateFns().empty())
++Size;
}
}
/// corresponds to the number of nodes that are covered.
int PatternToMatch::
getPatternComplexity(const CodeGenDAGPatterns &CGP) const {
- return getPatternSize(*getSrcPattern(), CGP) + getAddedComplexity();
+ return getPatternSize(getSrcPattern(), CGP) + getAddedComplexity();
}
/// getPredicateCheck - Return a single string containing all of this
/// getOperandNum - Return the node corresponding to operand #OpNo in tree
/// N, and the result number in ResNo.
-static TreePatternNode &getOperandNum(unsigned OpNo, TreePatternNode &N,
+static TreePatternNode *getOperandNum(unsigned OpNo, TreePatternNode *N,
const SDNodeInfo &NodeInfo,
unsigned &ResNo) {
unsigned NumResults = NodeInfo.getNumResults();
OpNo -= NumResults;
- if (OpNo >= N.getNumChildren()) {
+ if (OpNo >= N->getNumChildren()) {
std::string S;
raw_string_ostream OS(S);
OS << "Invalid operand number in type constraint "
<< (OpNo+NumResults) << " ";
- N.print(OS);
+ N->print(OS);
PrintFatalError(OS.str());
}
- return N.getChild(OpNo);
+ return N->getChild(OpNo);
}
/// ApplyTypeConstraint - Given a node in a pattern, apply this type
/// constraint to the nodes operands. This returns true if it makes a
/// change, false otherwise. If a type contradiction is found, flag an error.
-bool SDTypeConstraint::ApplyTypeConstraint(TreePatternNode &N,
+bool SDTypeConstraint::ApplyTypeConstraint(TreePatternNode *N,
const SDNodeInfo &NodeInfo,
TreePattern &TP) const {
if (TP.hasError())
return false;
unsigned ResNo = 0; // The result number being referenced.
- TreePatternNode &NodeToApply = getOperandNum(OperandNo, N, NodeInfo, ResNo);
+ TreePatternNode *NodeToApply = getOperandNum(OperandNo, N, NodeInfo, ResNo);
TypeInfer &TI = TP.getInfer();
switch (ConstraintType) {
case SDTCisVT:
// Operand must be a particular type.
- return NodeToApply.UpdateNodeType(ResNo, VVT, TP);
+ return NodeToApply->UpdateNodeType(ResNo, VVT, TP);
case SDTCisPtrTy:
// Operand must be same as target pointer type.
- return NodeToApply.UpdateNodeType(ResNo, MVT::iPTR, TP);
+ return NodeToApply->UpdateNodeType(ResNo, MVT::iPTR, TP);
case SDTCisInt:
// Require it to be one of the legal integer VTs.
- return TI.EnforceInteger(NodeToApply.getExtType(ResNo));
+ return TI.EnforceInteger(NodeToApply->getExtType(ResNo));
case SDTCisFP:
// Require it to be one of the legal fp VTs.
- return TI.EnforceFloatingPoint(NodeToApply.getExtType(ResNo));
+ return TI.EnforceFloatingPoint(NodeToApply->getExtType(ResNo));
case SDTCisVec:
// Require it to be one of the legal vector VTs.
- return TI.EnforceVector(NodeToApply.getExtType(ResNo));
+ return TI.EnforceVector(NodeToApply->getExtType(ResNo));
case SDTCisSameAs: {
unsigned OResNo = 0;
- TreePatternNode &OtherNode =
+ TreePatternNode *OtherNode =
getOperandNum(x.SDTCisSameAs_Info.OtherOperandNum, N, NodeInfo, OResNo);
- return NodeToApply.UpdateNodeType(ResNo, OtherNode.getExtType(OResNo),TP)|
- OtherNode.UpdateNodeType(OResNo,NodeToApply.getExtType(ResNo),TP);
+ return NodeToApply->UpdateNodeType(ResNo, OtherNode->getExtType(OResNo),TP)|
+ OtherNode->UpdateNodeType(OResNo,NodeToApply->getExtType(ResNo),TP);
}
case SDTCisVTSmallerThanOp: {
// The NodeToApply must be a leaf node that is a VT. OtherOperandNum must
// have an integer type that is smaller than the VT.
- if (!NodeToApply.isLeaf() ||
- !isa<DefInit>(NodeToApply.getLeafValue()) ||
- !static_cast<DefInit*>(NodeToApply.getLeafValue())->getDef()
+ if (!NodeToApply->isLeaf() ||
+ !isa<DefInit>(NodeToApply->getLeafValue()) ||
+ !static_cast<DefInit*>(NodeToApply->getLeafValue())->getDef()
->isSubClassOf("ValueType")) {
- TP.error(N.getOperator()->getName() + " expects a VT operand!");
+ TP.error(N->getOperator()->getName() + " expects a VT operand!");
return false;
}
- DefInit *DI = static_cast<DefInit*>(NodeToApply.getLeafValue());
+ DefInit *DI = static_cast<DefInit*>(NodeToApply->getLeafValue());
const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo();
auto VVT = getValueTypeByHwMode(DI->getDef(), T.getHwModes());
TypeSetByHwMode TypeListTmp(VVT);
unsigned OResNo = 0;
- TreePatternNode &OtherNode =
+ TreePatternNode *OtherNode =
getOperandNum(x.SDTCisVTSmallerThanOp_Info.OtherOperandNum, N, NodeInfo,
OResNo);
- return TI.EnforceSmallerThan(TypeListTmp, OtherNode.getExtType(OResNo));
+ return TI.EnforceSmallerThan(TypeListTmp, OtherNode->getExtType(OResNo));
}
case SDTCisOpSmallerThanOp: {
unsigned BResNo = 0;
- TreePatternNode &BigOperand =
+ TreePatternNode *BigOperand =
getOperandNum(x.SDTCisOpSmallerThanOp_Info.BigOperandNum, N, NodeInfo,
BResNo);
- return TI.EnforceSmallerThan(NodeToApply.getExtType(ResNo),
- BigOperand.getExtType(BResNo));
+ return TI.EnforceSmallerThan(NodeToApply->getExtType(ResNo),
+ BigOperand->getExtType(BResNo));
}
case SDTCisEltOfVec: {
unsigned VResNo = 0;
- TreePatternNode &VecOperand =
+ TreePatternNode *VecOperand =
getOperandNum(x.SDTCisEltOfVec_Info.OtherOperandNum, N, NodeInfo,
VResNo);
// Filter vector types out of VecOperand that don't have the right element
// type.
- return TI.EnforceVectorEltTypeIs(VecOperand.getExtType(VResNo),
- NodeToApply.getExtType(ResNo));
+ return TI.EnforceVectorEltTypeIs(VecOperand->getExtType(VResNo),
+ NodeToApply->getExtType(ResNo));
}
case SDTCisSubVecOfVec: {
unsigned VResNo = 0;
- TreePatternNode &BigVecOperand =
+ TreePatternNode *BigVecOperand =
getOperandNum(x.SDTCisSubVecOfVec_Info.OtherOperandNum, N, NodeInfo,
VResNo);
// Filter vector types out of BigVecOperand that don't have the
// right subvector type.
- return TI.EnforceVectorSubVectorTypeIs(BigVecOperand.getExtType(VResNo),
- NodeToApply.getExtType(ResNo));
+ return TI.EnforceVectorSubVectorTypeIs(BigVecOperand->getExtType(VResNo),
+ NodeToApply->getExtType(ResNo));
}
case SDTCVecEltisVT: {
- return TI.EnforceVectorEltTypeIs(NodeToApply.getExtType(ResNo), VVT);
+ return TI.EnforceVectorEltTypeIs(NodeToApply->getExtType(ResNo), VVT);
}
case SDTCisSameNumEltsAs: {
unsigned OResNo = 0;
- TreePatternNode &OtherNode =
+ TreePatternNode *OtherNode =
getOperandNum(x.SDTCisSameNumEltsAs_Info.OtherOperandNum,
N, NodeInfo, OResNo);
- return TI.EnforceSameNumElts(OtherNode.getExtType(OResNo),
- NodeToApply.getExtType(ResNo));
+ return TI.EnforceSameNumElts(OtherNode->getExtType(OResNo),
+ NodeToApply->getExtType(ResNo));
}
case SDTCisSameSizeAs: {
unsigned OResNo = 0;
- TreePatternNode &OtherNode =
+ TreePatternNode *OtherNode =
getOperandNum(x.SDTCisSameSizeAs_Info.OtherOperandNum,
N, NodeInfo, OResNo);
- return TI.EnforceSameSize(OtherNode.getExtType(OResNo),
- NodeToApply.getExtType(ResNo));
+ return TI.EnforceSameSize(OtherNode->getExtType(OResNo),
+ NodeToApply->getExtType(ResNo));
}
}
llvm_unreachable("Invalid ConstraintType!");
if (!TP.getInfer().isConcrete(Types[i], true))
return true;
for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
- if (getChild(i).ContainsUnresolvedType(TP))
+ if (getChild(i)->ContainsUnresolvedType(TP))
return true;
return false;
}
if (!isLeaf()) {
if (getNumChildren() != 0) {
OS << " ";
- getChild(0).print(OS);
+ getChild(0)->print(OS);
for (unsigned i = 1, e = getNumChildren(); i != e; ++i) {
OS << ", ";
- getChild(i).print(OS);
+ getChild(i)->print(OS);
}
}
OS << ")";
/// the assigned name is present in the dependent variable set, then
/// the assigned name is considered significant and the node is
/// isomorphic if the names match.
-bool TreePatternNode::isIsomorphicTo(const TreePatternNode &N,
+bool TreePatternNode::isIsomorphicTo(const TreePatternNode *N,
const MultipleUseVarSet &DepVars) const {
- if (&N == this) return true;
- if (N.isLeaf() != isLeaf() || getExtTypes() != N.getExtTypes() ||
- getPredicateFns() != N.getPredicateFns() ||
- getTransformFn() != N.getTransformFn())
+ if (N == this) return true;
+ if (N->isLeaf() != isLeaf() || getExtTypes() != N->getExtTypes() ||
+ getPredicateFns() != N->getPredicateFns() ||
+ getTransformFn() != N->getTransformFn())
return false;
if (isLeaf()) {
if (DefInit *DI = dyn_cast<DefInit>(getLeafValue())) {
- if (DefInit *NDI = dyn_cast<DefInit>(N.getLeafValue())) {
+ if (DefInit *NDI = dyn_cast<DefInit>(N->getLeafValue())) {
return ((DI->getDef() == NDI->getDef())
&& (DepVars.find(getName()) == DepVars.end()
- || getName() == N.getName()));
+ || getName() == N->getName()));
}
}
- return getLeafValue() == N.getLeafValue();
+ return getLeafValue() == N->getLeafValue();
}
- if (N.getOperator() != getOperator() ||
- N.getNumChildren() != getNumChildren()) return false;
+ if (N->getOperator() != getOperator() ||
+ N->getNumChildren() != getNumChildren()) return false;
for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
- if (!getChild(i).isIsomorphicTo(N.getChild(i), DepVars))
+ if (!getChild(i)->isIsomorphicTo(N->getChild(i), DepVars))
return false;
return true;
}
std::vector<TreePatternNodePtr> CChildren;
CChildren.reserve(Children.size());
for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
- CChildren.push_back(getChild(i).clone());
+ CChildren.push_back(getChild(i)->clone());
New = std::make_shared<TreePatternNode>(getOperator(), CChildren,
getNumTypes());
}
std::fill(Types.begin(), Types.end(), TypeSetByHwMode());
if (isLeaf()) return;
for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
- getChild(i).RemoveAllTypes();
+ getChild(i)->RemoveAllTypes();
}
if (isLeaf()) return;
for (unsigned i = 0, e = getNumChildren(); i != e; ++i) {
- TreePatternNode &Child = getChild(i);
- if (Child.isLeaf()) {
- Init *Val = Child.getLeafValue();
+ TreePatternNode *Child = getChild(i);
+ if (Child->isLeaf()) {
+ Init *Val = Child->getLeafValue();
// Note that, when substituting into an output pattern, Val might be an
// UnsetInit.
if (isa<UnsetInit>(Val) || (isa<DefInit>(Val) &&
cast<DefInit>(Val)->getDef()->getName() == "node")) {
// We found a use of a formal argument, replace it with its value.
- TreePatternNodePtr NewChild = ArgMap[Child.getName()];
+ TreePatternNodePtr NewChild = ArgMap[Child->getName()];
assert(NewChild && "Couldn't find formal argument!");
- assert((Child.getPredicateFns().empty() ||
- NewChild->getPredicateFns() == Child.getPredicateFns()) &&
+ assert((Child->getPredicateFns().empty() ||
+ NewChild->getPredicateFns() == Child->getPredicateFns()) &&
"Non-empty child predicate clobbered!");
setChild(i, std::move(NewChild));
}
} else {
- getChild(i).SubstituteFormalArguments(ArgMap);
+ getChild(i)->SubstituteFormalArguments(ArgMap);
}
}
}
getOperator() != CDP.get_intrinsic_wo_chain_sdnode())
return nullptr;
- unsigned IID = cast<IntInit>(getChild(0).getLeafValue())->getValue();
+ unsigned IID = cast<IntInit>(getChild(0)->getLeafValue())->getValue();
return &CDP.getIntrinsicInfo(IID);
}
if (NodeHasProperty(Property, CGP))
return true;
for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
- if (getChild(i).TreeHasProperty(Property, CGP))
+ if (getChild(i)->TreeHasProperty(Property, CGP))
return true;
return false;
}
return false;
}
-static bool isOperandClass(const TreePatternNode &N, StringRef Class) {
- if (!N.isLeaf())
- return N.getOperator()->isSubClassOf(Class);
+static bool isOperandClass(const TreePatternNode *N, StringRef Class) {
+ if (!N->isLeaf())
+ return N->getOperator()->isSubClassOf(Class);
- DefInit *DI = dyn_cast<DefInit>(N.getLeafValue());
+ DefInit *DI = dyn_cast<DefInit>(N->getLeafValue());
if (DI && DI->getDef()->isSubClassOf(Class))
return true;
assert(getNumChildren() >= 2 && "Missing RHS of a set?");
unsigned NC = getNumChildren();
- TreePatternNode &SetVal = getChild(NC-1);
- bool MadeChange = SetVal.ApplyTypeConstraints(TP, NotRegisters);
+ 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);
+ 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);
+ MadeChange |= Child->UpdateNodeType(0, SetVal->getExtType(i), TP);
+ MadeChange |= SetVal->UpdateNodeType(i, Child->getExtType(0), TP);
}
return MadeChange;
}
bool MadeChange = false;
for (unsigned i = 0; i < getNumChildren(); ++i)
- MadeChange |= getChild(i).ApplyTypeConstraints(TP, NotRegisters);
+ MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
return MadeChange;
}
}
// Apply type info to the intrinsic ID.
- MadeChange |= getChild(0).UpdateNodeType(0, MVT::iPTR, TP);
+ MadeChange |= getChild(0)->UpdateNodeType(0, MVT::iPTR, TP);
for (unsigned i = 0, e = getNumChildren()-1; i != e; ++i) {
- MadeChange |= getChild(i+1).ApplyTypeConstraints(TP, NotRegisters);
+ MadeChange |= getChild(i+1)->ApplyTypeConstraints(TP, NotRegisters);
MVT::SimpleValueType OpVT = Int->IS.ParamVTs[i];
- assert(getChild(i+1).getNumTypes() == 1 && "Unhandled case");
- MadeChange |= getChild(i+1).UpdateNodeType(0, OpVT, TP);
+ assert(getChild(i+1)->getNumTypes() == 1 && "Unhandled case");
+ MadeChange |= getChild(i+1)->UpdateNodeType(0, OpVT, TP);
}
return MadeChange;
}
bool MadeChange = false;
for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
- MadeChange |= getChild(i).ApplyTypeConstraints(TP, NotRegisters);
- MadeChange |= NI.ApplyTypeConstraints(*this, TP);
+ MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
+ MadeChange |= NI.ApplyTypeConstraints(this, TP);
return MadeChange;
}
// If this is an INSERT_SUBREG, constrain the source and destination VTs to
// be the same.
if (getOperator()->getName() == "INSERT_SUBREG") {
- assert(getChild(0).getNumTypes() == 1 && "FIXME: Unhandled");
- MadeChange |= UpdateNodeType(0, getChild(0).getExtType(0), TP);
- MadeChange |= getChild(0).UpdateNodeType(0, getExtType(0), TP);
+ assert(getChild(0)->getNumTypes() == 1 && "FIXME: Unhandled");
+ MadeChange |= UpdateNodeType(0, getChild(0)->getExtType(0), TP);
+ MadeChange |= getChild(0)->UpdateNodeType(0, getExtType(0), TP);
} else if (getOperator()->getName() == "REG_SEQUENCE") {
// We need to do extra, custom typechecking for REG_SEQUENCE since it is
// variadic.
}
for (unsigned I = 1; I < NChild; I += 2) {
- TreePatternNode &SubIdxChild = getChild(I + 1);
+ TreePatternNode *SubIdxChild = getChild(I + 1);
if (!isOperandClass(SubIdxChild, "SubRegIndex")) {
TP.error("REG_SEQUENCE requires a SubRegIndex for operand " +
Twine(I + 1) + "!");
return false;
}
- TreePatternNode *Child = &getChild(ChildNo++);
+ TreePatternNode *Child = getChild(ChildNo++);
unsigned ChildResNo = 0; // Instructions always use res #0 of their op.
// If the operand has sub-operands, they may be provided by distinct
getNumChildren());
return false;
}
- Child = &getChild(ChildNo++);
+ Child = getChild(ChildNo++);
SubRec = cast<DefInit>(MIOpInfo->getArg(Arg))->getDef();
MadeChange |=
}
for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
- MadeChange |= getChild(i).ApplyTypeConstraints(TP, NotRegisters);
+ MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
return MadeChange;
}
bool MadeChange = false;
for (unsigned i = 0; i < getNumChildren(); ++i)
- MadeChange |= getChild(i).ApplyTypeConstraints(TP, NotRegisters);
+ MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
return MadeChange;
}
return false;
}
- bool MadeChange = getChild(0).ApplyTypeConstraints(TP, NotRegisters);
+ bool MadeChange = getChild(0)->ApplyTypeConstraints(TP, NotRegisters);
return MadeChange;
}
/// OnlyOnRHSOfCommutative - Return true if this value is only allowed on the
/// RHS of a commutative operation, not the on LHS.
-static bool OnlyOnRHSOfCommutative(const TreePatternNode &N) {
- if (!N.isLeaf() && N.getOperator()->getName() == "imm")
+static bool OnlyOnRHSOfCommutative(TreePatternNode *N) {
+ if (!N->isLeaf() && N->getOperator()->getName() == "imm")
return true;
- if (N.isLeaf() && isa<IntInit>(N.getLeafValue()))
+ if (N->isLeaf() && isa<IntInit>(N->getLeafValue()))
return true;
return false;
}
if (isLeaf()) return true;
for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
- if (!getChild(i).canPatternMatch(Reason, CDP))
+ if (!getChild(i)->canPatternMatch(Reason, CDP))
return false;
// If this is an intrinsic, handle cases that would make it not match. For
}
void TreePattern::ComputeNamedNodes() {
- for (const TreePatternNodePtr &Tree : Trees)
- ComputeNamedNodes(Tree);
+ for (TreePatternNodePtr &Tree : Trees)
+ ComputeNamedNodes(Tree.get());
}
-void TreePattern::ComputeNamedNodes(const TreePatternNodePtr &N) {
+void TreePattern::ComputeNamedNodes(TreePatternNode *N) {
if (!N->getName().empty())
- NamedNodes[N->getName()].push_back(N.get());
+ NamedNodes[N->getName()].push_back(N);
for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
- ComputeNamedNodes(N->getChildShared(i));
+ ComputeNamedNodes(N->getChild(i));
}
TreePatternNodePtr TreePattern::ParseTreePattern(Init *TheInit,
if (Operator->isSubClassOf("ComplexPattern")) {
for (unsigned i = 0; i < Children.size(); ++i) {
- TreePatternNodePtr &Child = Children[i];
+ TreePatternNodePtr Child = Children[i];
if (Child->getName().empty())
error("All arguments to a ComplexPattern must be named");
}
}
- auto Result =
+ TreePatternNodePtr Result =
std::make_shared<TreePatternNode>(Operator, Children, NumResults);
Result->setName(OpName);
// destination types are the same, then the bitconvert is useless, remove it.
if (N->getOperator()->getName() == "bitconvert" &&
N->getExtType(0).isValueTypeByHwMode(false) &&
- N->getExtType(0) == N->getChild(0).getExtType(0) &&
+ N->getExtType(0) == N->getChild(0)->getExtType(0) &&
N->getName().empty()) {
N = N->getChildShared(0);
SimplifyTree(N);
/// 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, const TreePatternNodePtr &Pat,
+ TreePattern &I, TreePatternNodePtr Pat,
std::map<std::string, TreePatternNodePtr> &InstInputs,
std::map<std::string, TreePatternNodePtr> &InstResults,
std::vector<Record *> &InstImpResults) {
if (Pat->getOperator()->getName() == "implicit") {
for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i) {
- TreePatternNode &Dest = Pat->getChild(i);
- if (!Dest.isLeaf())
+ TreePatternNode *Dest = Pat->getChild(i);
+ if (!Dest->isLeaf())
I.error("implicitly defined value should be a register!");
- DefInit *Val = dyn_cast<DefInit>(Dest.getLeafValue());
+ DefInit *Val = dyn_cast<DefInit>(Dest->getLeafValue());
if (!Val || !Val->getDef()->isSubClassOf("Register"))
I.error("implicitly defined value should be a register!");
InstImpResults.push_back(Val->getDef());
// If this is not a set, verify that the children nodes are not void typed,
// and recurse.
for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i) {
- if (Pat->getChild(i).getNumTypes() == 0)
+ if (Pat->getChild(i)->getNumTypes() == 0)
I.error("Cannot have void nodes inside of patterns!");
FindPatternInputsAndOutputs(I, Pat->getChildShared(i), InstInputs,
InstResults, InstImpResults);
// Check the set destinations.
unsigned NumDests = Pat->getNumChildren()-1;
for (unsigned i = 0; i != NumDests; ++i) {
- const TreePatternNodePtr &Dest = Pat->getChildShared(i);
+ TreePatternNodePtr Dest = Pat->getChildShared(i);
if (!Dest->isLeaf())
I.error("set destination should be a register!");
void Analyze(const TreePattern *Pat) {
// Assume only the first tree is the pattern. The others are clobber nodes.
- AnalyzeNode(*Pat->getTree(0));
+ AnalyzeNode(Pat->getTree(0).get());
}
void Analyze(const PatternToMatch &Pat) {
- AnalyzeNode(*Pat.getSrcPatternShared());
+ AnalyzeNode(Pat.getSrcPattern());
}
private:
- bool IsNodeBitcast(const TreePatternNode &N) const {
+ bool IsNodeBitcast(const TreePatternNode *N) const {
if (hasSideEffects || mayLoad || mayStore || isVariadic)
return false;
- if (N.getNumChildren() != 2)
+ if (N->getNumChildren() != 2)
return false;
- const TreePatternNode &N0 = N.getChild(0);
- if (!N0.isLeaf() || !isa<DefInit>(N0.getLeafValue()))
+ const TreePatternNode *N0 = N->getChild(0);
+ if (!N0->isLeaf() || !isa<DefInit>(N0->getLeafValue()))
return false;
- const TreePatternNode &N1 = N.getChild(1);
- if (N1.isLeaf())
+ const TreePatternNode *N1 = N->getChild(1);
+ if (N1->isLeaf())
return false;
- if (N1.getNumChildren() != 1 || !N1.getChild(0).isLeaf())
+ if (N1->getNumChildren() != 1 || !N1->getChild(0)->isLeaf())
return false;
- const SDNodeInfo &OpInfo = CDP.getSDNodeInfo(N1.getOperator());
+ const SDNodeInfo &OpInfo = CDP.getSDNodeInfo(N1->getOperator());
if (OpInfo.getNumResults() != 1 || OpInfo.getNumOperands() != 1)
return false;
return OpInfo.getEnumName() == "ISD::BITCAST";
}
public:
- void AnalyzeNode(const TreePatternNode &N) {
- if (N.isLeaf()) {
- if (DefInit *DI = dyn_cast<DefInit>(N.getLeafValue())) {
+ void AnalyzeNode(const TreePatternNode *N) {
+ if (N->isLeaf()) {
+ if (DefInit *DI = dyn_cast<DefInit>(N->getLeafValue())) {
Record *LeafRec = DI->getDef();
// Handle ComplexPattern leaves.
if (LeafRec->isSubClassOf("ComplexPattern")) {
}
// Analyze children.
- for (unsigned i = 0, e = N.getNumChildren(); i != e; ++i)
- AnalyzeNode(*N.getChildShared(i));
+ 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") {
+ 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(SDNPMayStore, CDP)) mayStore = true;
+ if (N->NodeHasProperty(SDNPMayLoad, CDP)) mayLoad = true;
+ if (N->NodeHasProperty(SDNPSideEffect, CDP)) hasSideEffects = true;
+ if (N->NodeHasProperty(SDNPVariadic, CDP)) isVariadic = true;
- if (const CodeGenIntrinsic *IntInfo = N.getIntrinsicInfo(CDP)) {
+ if (const CodeGenIntrinsic *IntInfo = N->getIntrinsicInfo(CDP)) {
// If this is an intrinsic, analyze it.
if (IntInfo->ModRef & CodeGenIntrinsic::MR_Ref)
mayLoad = true;// These may load memory.
/// Get all the instructions in a tree.
static void
-getInstructionsInTree(const TreePatternNode &Tree, SmallVectorImpl<Record*> &Instrs) {
- if (Tree.isLeaf())
+getInstructionsInTree(TreePatternNode *Tree, SmallVectorImpl<Record*> &Instrs) {
+ if (Tree->isLeaf())
return;
- if (Tree.getOperator()->isSubClassOf("Instruction"))
- Instrs.push_back(Tree.getOperator());
- for (unsigned i = 0, e = Tree.getNumChildren(); i != e; ++i)
- getInstructionsInTree(Tree.getChild(i), Instrs);
+ if (Tree->getOperator()->isSubClassOf("Instruction"))
+ Instrs.push_back(Tree->getOperator());
+ for (unsigned i = 0, e = Tree->getNumChildren(); i != e; ++i)
+ getInstructionsInTree(Tree->getChild(i), Instrs);
}
/// Check the class of a pattern leaf node against the instruction operand it
SmallString<32> TypesString;
for (unsigned j = 0, e = I->getNumTrees(); j != e; ++j) {
TypesString.clear();
- const TreePatternNodePtr &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) {
I->error("Operand $" + OpName +
" does not appear in the instruction pattern");
}
- TreePatternNodePtr &InVal = InstInputsCheck[OpName];
+ TreePatternNodePtr InVal = InstInputsCheck[OpName];
InstInputsCheck.erase(OpName); // It occurred, remove from map.
if (InVal->isLeaf() && isa<DefInit>(InVal->getLeafValue())) {
if (Record *Xform = OpNode->getTransformFn()) {
OpNode->setTransformFn(nullptr);
std::vector<TreePatternNodePtr> Children;
- unsigned NumTypes = OpNode->getNumTypes();
Children.push_back(OpNode);
OpNode = std::make_shared<TreePatternNode>(Xform, Children,
- NumTypes);
+ OpNode->getNumTypes());
}
ResultNodeOperands.push_back(std::move(OpNode));
I->error("Input operand $" + InstInputsCheck.begin()->first +
" occurs in pattern but not in operands list!");
- auto ResultPattern = std::make_shared<TreePatternNode>(
+ TreePatternNodePtr ResultPattern = std::make_shared<TreePatternNode>(
I->getRecord(), ResultNodeOperands,
GetNumNodeResults(I->getRecord(), *this));
// Copy fully inferred output node types to instruction result pattern.
DAGInstruction &TheInst =
DAGInsts.emplace(std::piecewise_construct, std::forward_as_tuple(R),
std::forward_as_tuple(std::move(I), Results, Operands,
- std::move(InstImpResults))).first->second;
+ InstImpResults)).first->second;
// Use a temporary tree pattern to infer all types and make sure that the
// constructed result is correct. This depends on the instruction already
PatternRewriter(I);
// FIXME: Assume only the first tree is the pattern. The others are clobber
// nodes.
- const TreePatternNodePtr &Pattern = I->getTree(0);
+ TreePatternNodePtr Pattern = I->getTree(0);
TreePatternNodePtr SrcPattern;
if (Pattern->getOperator()->getName() == "set") {
- SrcPattern = Pattern->getChild(Pattern->getNumChildren()-1).clone();
+ SrcPattern = Pattern->getChild(Pattern->getNumChildren()-1)->clone();
} else{
// Not a set (store or something?)
SrcPattern = Pattern;
}
}
-typedef std::pair<const TreePatternNode *, unsigned> NameRecord;
+typedef std::pair<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()) {
- NameRecord &Rec = Names[P.getName()];
+ if (!P->getName().empty()) {
+ NameRecord &Rec = Names[P->getName()];
// If this is the first instance of the name, remember the node.
if (Rec.second++ == 0)
- Rec.first = &P;
- else if (Rec.first->getExtTypes() != P.getExtTypes())
- PatternTop->error("repetition of value: $" + P.getName() +
+ Rec.first = P;
+ else if (Rec.first->getExtTypes() != P->getExtTypes())
+ PatternTop->error("repetition of value: $" + P->getName() +
" where different uses have different types!");
}
- if (!P.isLeaf()) {
- for (unsigned i = 0, e = P.getNumChildren(); i != e; ++i)
- FindNames(P.getChild(i), Names, PatternTop);
+ if (!P->isLeaf()) {
+ for (unsigned i = 0, e = P->getNumChildren(); i != e; ++i)
+ FindNames(P->getChild(i), Names, PatternTop);
}
}
// Find all of the named values in the input and output, ensure they have the
// same type.
std::map<std::string, NameRecord> SrcNames, DstNames;
- FindNames(*PTM.getSrcPattern(), SrcNames, Pattern);
- FindNames(*PTM.getDstPattern(), DstNames, Pattern);
+ FindNames(PTM.getSrcPattern(), SrcNames, Pattern);
+ FindNames(PTM.getDstPattern(), DstNames, Pattern);
// Scan all of the named values in the destination pattern, rejecting them if
// they don't exist in the input pattern.
// We can only infer from single-instruction patterns, otherwise we won't
// know which instruction should get the flags.
SmallVector<Record*, 8> PatInstrs;
- getInstructionsInTree(*PTM.getDstPattern(), PatInstrs);
+ getInstructionsInTree(PTM.getDstPattern(), PatInstrs);
if (PatInstrs.size() != 1)
continue;
for (ptm_iterator I = ptm_begin(), E = ptm_end(); I != E; ++I) {
const PatternToMatch &PTM = *I;
SmallVector<Record*, 8> Instrs;
- getInstructionsInTree(*PTM.getDstPattern(), Instrs);
+ getInstructionsInTree(PTM.getDstPattern(), Instrs);
if (Instrs.empty())
continue;
/// Given a pattern result with an unresolved type, see if we can find one
/// instruction with an unresolved result type. Force this result type to an
/// arbitrary element if it's possible types to converge results.
-static bool ForceArbitraryInstResultType(TreePatternNode &N, TreePattern &TP) {
- if (N.isLeaf())
+static bool ForceArbitraryInstResultType(TreePatternNode *N, TreePattern &TP) {
+ if (N->isLeaf())
return false;
// Analyze children.
- for (unsigned i = 0, e = N.getNumChildren(); i != e; ++i)
- if (ForceArbitraryInstResultType(N.getChild(i), TP))
+ for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
+ if (ForceArbitraryInstResultType(N->getChild(i), TP))
return true;
- if (!N.getOperator()->isSubClassOf("Instruction"))
+ if (!N->getOperator()->isSubClassOf("Instruction"))
return false;
// If this type is already concrete or completely unknown we can't do
// anything.
TypeInfer &TI = TP.getInfer();
- for (unsigned i = 0, e = N.getNumTypes(); i != e; ++i) {
- if (N.getExtType(i).empty() || TI.isConcrete(N.getExtType(i), false))
+ for (unsigned i = 0, e = N->getNumTypes(); i != e; ++i) {
+ if (N->getExtType(i).empty() || TI.isConcrete(N->getExtType(i), false))
continue;
// Otherwise, force its type to an arbitrary choice.
- if (TI.forceArbitrary(N.getExtType(i)))
+ if (TI.forceArbitrary(N->getExtType(i)))
return true;
}
if (!IterateInference && InferredAllPatternTypes &&
!InferredAllResultTypes)
IterateInference =
- ForceArbitraryInstResultType(*Result.getTree(0), Result);
+ ForceArbitraryInstResultType(Result.getTree(0).get(), Result);
} while (IterateInference);
// Verify that we inferred enough types that we can do something with the
AddPatternToMatch(&Pattern,
PatternToMatch(CurPattern, makePredList(Preds),
Pattern.getTree(0), Temp.getOnlyTree(),
- //std::move(InstImpResults), Complexity,
- InstImpResults, Complexity,
+ std::move(InstImpResults), Complexity,
CurPattern->getID()));
}
}
}
-static void collectModes(std::set<unsigned> &Modes, TreePatternNode *N) {
+static void collectModes(std::set<unsigned> &Modes, const TreePatternNode *N) {
for (const TypeSetByHwMode &VTS : N->getExtTypes())
for (const auto &I : VTS)
Modes.insert(I.first);
for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
- collectModes(Modes, &N->getChild(i));
+ collectModes(Modes, N->getChild(i));
}
void CodeGenDAGPatterns::ExpandHwModeBasedTypes() {
for (PatternToMatch &P : Copy) {
TreePatternNodePtr SrcP = nullptr, DstP = nullptr;
- bool SrcHasProperType = P.SrcPattern->hasProperTypeByHwMode();
- bool DstHasProperType = P.DstPattern->hasProperTypeByHwMode();
- if (!SrcHasProperType && !DstHasProperType) {
+ if (P.SrcPattern->hasProperTypeByHwMode())
+ SrcP = P.SrcPattern;
+ if (P.DstPattern->hasProperTypeByHwMode())
+ DstP = P.DstPattern;
+ if (!SrcP && !DstP) {
PatternsToMatch.push_back(P);
continue;
}
std::set<unsigned> Modes;
- if (SrcHasProperType)
- collectModes(Modes, &*P.SrcPattern);
- if (DstHasProperType)
- collectModes(Modes, &*P.DstPattern);
+ if (SrcP)
+ collectModes(Modes, SrcP.get());
+ if (DstP)
+ collectModes(Modes, DstP.get());
// The predicate for the default mode needs to be constructed for each
// pattern separately.
/// Dependent variable map for CodeGenDAGPattern variant generation
typedef StringMap<int> DepVarMap;
-static void FindDepVarsOf(const TreePatternNode &N, DepVarMap &DepMap) {
- if (N.isLeaf()) {
- if (N.hasName() && isa<DefInit>(N.getLeafValue()))
- DepMap[N.getName()]++;
+static void FindDepVarsOf(TreePatternNode *N, DepVarMap &DepMap) {
+ if (N->isLeaf()) {
+ if (N->hasName() && isa<DefInit>(N->getLeafValue()))
+ DepMap[N->getName()]++;
} else {
- for (size_t i = 0, e = N.getNumChildren(); i != e; ++i)
- FindDepVarsOf(N.getChild(i), DepMap);
+ for (size_t i = 0, e = N->getNumChildren(); i != e; ++i)
+ FindDepVarsOf(N->getChild(i), DepMap);
}
}
/// Find dependent variables within child patterns
-static void FindDepVars(const TreePatternNode &N, MultipleUseVarSet &DepVars) {
+static void FindDepVars(TreePatternNode *N, MultipleUseVarSet &DepVars) {
DepVarMap depcounts;
FindDepVarsOf(N, depcounts);
for (const auto &Pair : depcounts) {
/// CombineChildVariants - Given a bunch of permutations of each child of the
/// 'operator' node, put them together in all possible ways.
static void CombineChildVariants(
- const TreePatternNode &Orig,
+ TreePatternNodePtr Orig,
const std::vector<std::vector<TreePatternNodePtr>> &ChildVariants,
std::vector<TreePatternNodePtr> &OutVariants, CodeGenDAGPatterns &CDP,
const MultipleUseVarSet &DepVars) {
do {
#ifndef NDEBUG
LLVM_DEBUG(if (!Idxs.empty()) {
- errs() << Orig.getOperator()->getName() << ": Idxs = [ ";
+ errs() << Orig->getOperator()->getName() << ": Idxs = [ ";
for (unsigned Idx : Idxs) {
errs() << Idx << " ";
}
for (unsigned i = 0, e = ChildVariants.size(); i != e; ++i)
NewChildren.push_back(ChildVariants[i][Idxs[i]]);
TreePatternNodePtr R = std::make_shared<TreePatternNode>(
- Orig.getOperator(), NewChildren, Orig.getNumTypes());
+ Orig->getOperator(), NewChildren, Orig->getNumTypes());
// Copy over properties.
- R->setName(Orig.getName());
- R->setPredicateFns(Orig.getPredicateFns());
- R->setTransformFn(Orig.getTransformFn());
- for (unsigned i = 0, e = Orig.getNumTypes(); i != e; ++i)
- R->setType(i, Orig.getExtType(i));
+ R->setName(Orig->getName());
+ R->setPredicateFns(Orig->getPredicateFns());
+ R->setTransformFn(Orig->getTransformFn());
+ for (unsigned i = 0, e = Orig->getNumTypes(); i != e; ++i)
+ R->setType(i, Orig->getExtType(i));
// If this pattern cannot match, do not include it as a variant.
std::string ErrString;
// which are the same pattern. Ignore the dups.
if (R->canPatternMatch(ErrString, CDP) &&
none_of(OutVariants, [&](TreePatternNodePtr Variant) {
- return R->isIsomorphicTo(*Variant, DepVars);
+ return R->isIsomorphicTo(Variant.get(), DepVars);
}))
OutVariants.push_back(R);
/// CombineChildVariants - A helper function for binary operators.
///
-static void CombineChildVariants(const TreePatternNode &Orig,
+static void CombineChildVariants(TreePatternNodePtr Orig,
const std::vector<TreePatternNodePtr> &LHS,
const std::vector<TreePatternNodePtr> &RHS,
std::vector<TreePatternNodePtr> &OutVariants,
}
static void
-GatherChildrenOfAssociativeOpcode(const TreePatternNodePtr &N,
+GatherChildrenOfAssociativeOpcode(TreePatternNodePtr N,
std::vector<TreePatternNodePtr> &Children) {
assert(N->getNumChildren()==2 &&"Associative but doesn't have 2 children!");
Record *Operator = N->getOperator();
return;
}
- if (N->getChild(0).isLeaf() || N->getChild(0).getOperator() != Operator)
+ if (N->getChild(0)->isLeaf() || N->getChild(0)->getOperator() != Operator)
Children.push_back(N->getChildShared(0));
else
GatherChildrenOfAssociativeOpcode(N->getChildShared(0), Children);
- if (N->getChild(1).isLeaf() || N->getChild(1).getOperator() != Operator)
+ if (N->getChild(1)->isLeaf() || N->getChild(1)->getOperator() != Operator)
Children.push_back(N->getChildShared(1));
else
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(const TreePatternNodePtr &N,
+static void GenerateVariantsOf(TreePatternNodePtr N,
std::vector<TreePatternNodePtr> &OutVariants,
CodeGenDAGPatterns &CDP,
const MultipleUseVarSet &DepVars) {
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);
- CombineChildVariants(*N, CVariants, AVariants, CAVariants, CDP, DepVars);
- CombineChildVariants(*N, BVariants, CVariants, BCVariants, CDP, DepVars);
- CombineChildVariants(*N, CVariants, BVariants, CBVariants, CDP, DepVars);
+ CombineChildVariants(N, AVariants, BVariants, ABVariants, CDP, DepVars);
+ CombineChildVariants(N, BVariants, AVariants, BAVariants, CDP, DepVars);
+ CombineChildVariants(N, AVariants, CVariants, ACVariants, CDP, DepVars);
+ CombineChildVariants(N, CVariants, AVariants, CAVariants, CDP, DepVars);
+ CombineChildVariants(N, BVariants, CVariants, BCVariants, CDP, DepVars);
+ CombineChildVariants(N, CVariants, BVariants, CBVariants, CDP, DepVars);
// Combine those into the result: (x op x) op x
- CombineChildVariants(*N, ABVariants, CVariants, OutVariants, CDP, DepVars);
- CombineChildVariants(*N, BAVariants, CVariants, OutVariants, CDP, DepVars);
- CombineChildVariants(*N, ACVariants, BVariants, OutVariants, CDP, DepVars);
- CombineChildVariants(*N, CAVariants, BVariants, OutVariants, CDP, DepVars);
- CombineChildVariants(*N, BCVariants, AVariants, OutVariants, CDP, DepVars);
- CombineChildVariants(*N, CBVariants, AVariants, OutVariants, CDP, DepVars);
+ CombineChildVariants(N, ABVariants, CVariants, OutVariants, CDP, DepVars);
+ CombineChildVariants(N, BAVariants, CVariants, OutVariants, CDP, DepVars);
+ CombineChildVariants(N, ACVariants, BVariants, OutVariants, CDP, DepVars);
+ CombineChildVariants(N, CAVariants, BVariants, OutVariants, CDP, DepVars);
+ CombineChildVariants(N, BCVariants, AVariants, OutVariants, CDP, DepVars);
+ CombineChildVariants(N, CBVariants, AVariants, OutVariants, CDP, DepVars);
// Combine those into the result: x op (x op x)
- CombineChildVariants(*N, CVariants, ABVariants, OutVariants, CDP, DepVars);
- CombineChildVariants(*N, CVariants, BAVariants, OutVariants, CDP, DepVars);
- CombineChildVariants(*N, BVariants, ACVariants, OutVariants, CDP, DepVars);
- CombineChildVariants(*N, BVariants, CAVariants, OutVariants, CDP, DepVars);
- CombineChildVariants(*N, AVariants, BCVariants, OutVariants, CDP, DepVars);
- CombineChildVariants(*N, AVariants, CBVariants, OutVariants, CDP, DepVars);
+ CombineChildVariants(N, CVariants, ABVariants, OutVariants, CDP, DepVars);
+ CombineChildVariants(N, CVariants, BAVariants, OutVariants, CDP, DepVars);
+ CombineChildVariants(N, BVariants, ACVariants, OutVariants, CDP, DepVars);
+ CombineChildVariants(N, BVariants, CAVariants, OutVariants, CDP, DepVars);
+ CombineChildVariants(N, AVariants, BCVariants, OutVariants, CDP, DepVars);
+ CombineChildVariants(N, AVariants, CBVariants, OutVariants, CDP, DepVars);
return;
}
}
GenerateVariantsOf(N->getChildShared(i), ChildVariants[i], CDP, DepVars);
// Build all permutations based on how the children were formed.
- CombineChildVariants(*N, ChildVariants, OutVariants, CDP, DepVars);
+ CombineChildVariants(N, ChildVariants, OutVariants, CDP, DepVars);
// If this node is commutative, consider the commuted order.
bool isCommIntrinsic = N->isCommutativeIntrinsic(CDP);
// Don't count children which are actually register references.
unsigned NC = 0;
for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) {
- const TreePatternNode &Child = N->getChild(i);
- if (Child.isLeaf())
- if (DefInit *DI = dyn_cast<DefInit>(Child.getLeafValue())) {
+ TreePatternNode *Child = N->getChild(i);
+ if (Child->isLeaf())
+ if (DefInit *DI = dyn_cast<DefInit>(Child->getLeafValue())) {
Record *RR = DI->getDef();
if (RR->isSubClassOf("Register"))
continue;
Variants.push_back(std::move(ChildVariants[1]));
for (unsigned i = 3; i != NC; ++i)
Variants.push_back(std::move(ChildVariants[i]));
- CombineChildVariants(*N, Variants, OutVariants, CDP, DepVars);
+ CombineChildVariants(N, Variants, OutVariants, CDP, DepVars);
} else if (NC == N->getNumChildren()) {
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(std::move(ChildVariants[i]));
- CombineChildVariants(*N, Variants, OutVariants, CDP, DepVars);
+ CombineChildVariants(N, Variants, OutVariants, CDP, DepVars);
}
}
}
for (unsigned i = 0, e = PatternsToMatch.size(); i != e; ++i) {
MultipleUseVarSet DepVars;
std::vector<TreePatternNodePtr> Variants;
- FindDepVars(*PatternsToMatch[i].getSrcPattern(), DepVars);
+ FindDepVars(PatternsToMatch[i].getSrcPattern(), DepVars);
LLVM_DEBUG(errs() << "Dependent/multiply used variables: ");
LLVM_DEBUG(DumpDepVars(DepVars));
LLVM_DEBUG(errs() << "\n");
PatternsToMatch[i].getSrcPattern()->dump(); errs() << "\n");
for (unsigned v = 0, e = Variants.size(); v != e; ++v) {
- TreePatternNodePtr &Variant = Variants[v];
+ TreePatternNodePtr Variant = Variants[v];
LLVM_DEBUG(errs() << " VAR#" << v << ": "; Variant->dump();
errs() << "\n");
PatternsToMatch[p].getPredicates())
continue;
// Check to see if this variant already exists.
- if (Variant->isIsomorphicTo(*PatternsToMatch[p].getSrcPattern(),
+ if (Variant->isIsomorphicTo(PatternsToMatch[p].getSrcPattern(),
DepVars)) {
LLVM_DEBUG(errs() << " *** ALREADY EXISTS, ignoring variant.\n");
AlreadyExists = true;
/// constraint to the nodes operands. This returns true if it makes a
/// change, false otherwise. If a type contradiction is found, an error
/// is flagged.
- bool ApplyTypeConstraint(TreePatternNode &N, const SDNodeInfo &NodeInfo,
+ bool ApplyTypeConstraint(TreePatternNode *N, const SDNodeInfo &NodeInfo,
TreePattern &TP) const;
};
/// constraints for this node to the operands of the node. This returns
/// true if it makes a change, false otherwise. If a type contradiction is
/// found, an error is flagged.
- bool ApplyTypeConstraints(TreePatternNode &N, TreePattern &TP) const;
+ bool ApplyTypeConstraints(TreePatternNode *N, TreePattern &TP) const;
};
/// TreePredicateFn - This is an abstraction that represents the predicates on
Record *getOperator() const { assert(!isLeaf()); return Operator; }
unsigned getNumChildren() const { return Children.size(); }
- const TreePatternNode &getChild(unsigned N) const { return *Children[N]; }
- TreePatternNode &getChild(unsigned N) { return *Children[N]; }
+ TreePatternNode *getChild(unsigned N) const { return Children[N].get(); }
const TreePatternNodePtr &getChildShared(unsigned N) const {
return Children[N];
}
/// the specified node. For this comparison, all of the state of the node
/// is considered, except for the assigned name. Nodes with differing names
/// that are otherwise identical are considered isomorphic.
- bool isIsomorphicTo(const TreePatternNode &N,
+ bool isIsomorphicTo(const TreePatternNode *N,
const MultipleUseVarSet &DepVars) const;
/// SubstituteFormalArguments - Replace the formal arguments in this tree
private:
TreePatternNodePtr ParseTreePattern(Init *DI, StringRef OpName);
void ComputeNamedNodes();
- void ComputeNamedNodes(const TreePatternNodePtr &N);
+ void ComputeNamedNodes(TreePatternNode *N);
};
void AddPatternToMatch(TreePattern *Pattern, PatternToMatch &&PTM);
void FindPatternInputsAndOutputs(
- TreePattern &I, const TreePatternNodePtr &Pat,
+ TreePattern &I, TreePatternNodePtr Pat,
std::map<std::string, TreePatternNodePtr> &InstInputs,
std::map<std::string, TreePatternNodePtr> &InstResults,
std::vector<Record *> &InstImpResults);
};
-inline bool SDNodeInfo::ApplyTypeConstraints(TreePatternNode &N,
+inline bool SDNodeInfo::ApplyTypeConstraints(TreePatternNode *N,
TreePattern &TP) const {
bool MadeChange = false;
for (unsigned i = 0, e = TypeConstraints.size(); i != e; ++i)
/// getResultPatternCost - Compute the number of instructions for this pattern.
/// This is a temporary hack. We should really include the instruction
/// latencies in this calculation.
-static unsigned getResultPatternCost(const TreePatternNode &P,
+static unsigned getResultPatternCost(TreePatternNode *P,
CodeGenDAGPatterns &CGP) {
- if (P.isLeaf()) return 0;
+ if (P->isLeaf()) return 0;
unsigned Cost = 0;
- Record *Op = P.getOperator();
+ Record *Op = P->getOperator();
if (Op->isSubClassOf("Instruction")) {
Cost++;
CodeGenInstruction &II = CGP.getTargetInfo().getInstruction(Op);
if (II.usesCustomInserter)
Cost += 10;
}
- for (unsigned i = 0, e = P.getNumChildren(); i != e; ++i)
- Cost += getResultPatternCost(P.getChild(i), CGP);
+ for (unsigned i = 0, e = P->getNumChildren(); i != e; ++i)
+ Cost += getResultPatternCost(P->getChild(i), CGP);
return Cost;
}
/// getResultPatternCodeSize - Compute the code size of instructions for this
/// pattern.
-static unsigned getResultPatternSize(const TreePatternNode &P,
+static unsigned getResultPatternSize(TreePatternNode *P,
CodeGenDAGPatterns &CGP) {
- if (P.isLeaf()) return 0;
+ if (P->isLeaf()) return 0;
unsigned Cost = 0;
- Record *Op = P.getOperator();
+ Record *Op = P->getOperator();
if (Op->isSubClassOf("Instruction")) {
Cost += Op->getValueAsInt("CodeSize");
}
- for (unsigned i = 0, e = P.getNumChildren(); i != e; ++i)
- Cost += getResultPatternSize(P.getChild(i), CGP);
+ for (unsigned i = 0, e = P->getNumChildren(); i != e; ++i)
+ Cost += getResultPatternSize(P->getChild(i), CGP);
return Cost;
}
if (LHSSize < RHSSize) return false;
// If the patterns have equal complexity, compare generated instruction cost
- unsigned LHSCost = getResultPatternCost(*LHS->getDstPattern(), CGP);
- unsigned RHSCost = getResultPatternCost(*RHS->getDstPattern(), CGP);
+ unsigned LHSCost = getResultPatternCost(LHS->getDstPattern(), CGP);
+ unsigned RHSCost = getResultPatternCost(RHS->getDstPattern(), CGP);
if (LHSCost < RHSCost) return true;
if (LHSCost > RHSCost) return false;
- unsigned LHSPatSize = getResultPatternSize(*LHS->getDstPattern(), CGP);
- unsigned RHSPatSize = getResultPatternSize(*RHS->getDstPattern(), CGP);
+ unsigned LHSPatSize = getResultPatternSize(LHS->getDstPattern(), CGP);
+ unsigned RHSPatSize = getResultPatternSize(RHS->getDstPattern(), CGP);
if (LHSPatSize < RHSPatSize) return true;
if (LHSPatSize > RHSPatSize) return false;
void InferPossibleTypes(unsigned ForceMode);
// Matcher Generation.
- void EmitMatchCode(const TreePatternNode &N, TreePatternNode &NodeNoTypes,
+ void EmitMatchCode(const TreePatternNode *N, TreePatternNode *NodeNoTypes,
unsigned ForceMode);
- void EmitLeafMatchCode(const TreePatternNode &N);
- void EmitOperatorMatchCode(const TreePatternNode &N,
- TreePatternNode &NodeNoTypes,
+ void EmitLeafMatchCode(const TreePatternNode *N);
+ void EmitOperatorMatchCode(const TreePatternNode *N,
+ TreePatternNode *NodeNoTypes,
unsigned ForceMode);
/// If this is the first time a node with unique identifier Name has been
/// GetInstPatternNode - Get the pattern for an instruction.
const TreePatternNode *GetInstPatternNode(const DAGInstruction &Ins,
- const TreePatternNode &N);
+ const TreePatternNode *N);
- void EmitResultOperand(const TreePatternNode &N,
+ void EmitResultOperand(const TreePatternNode *N,
SmallVectorImpl<unsigned> &ResultOps);
- void EmitResultOfNamedOperand(const TreePatternNode &N,
+ void EmitResultOfNamedOperand(const TreePatternNode *N,
SmallVectorImpl<unsigned> &ResultOps);
- void EmitResultLeafAsOperand(const TreePatternNode &N,
+ void EmitResultLeafAsOperand(const TreePatternNode *N,
SmallVectorImpl<unsigned> &ResultOps);
- void EmitResultInstructionAsOperand(const TreePatternNode &N,
+ void EmitResultInstructionAsOperand(const TreePatternNode *N,
SmallVectorImpl<unsigned> &ResultOps);
- void EmitResultSDNodeXFormAsOperand(const TreePatternNode &N,
+ void EmitResultSDNodeXFormAsOperand(const TreePatternNode *N,
SmallVectorImpl<unsigned> &ResultOps);
};
//===----------------------------------------------------------------------===//
/// EmitLeafMatchCode - Generate matching code for leaf nodes.
-void MatcherGen::EmitLeafMatchCode(const TreePatternNode &N) {
- assert(N.isLeaf() && "Not a leaf?");
+void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) {
+ assert(N->isLeaf() && "Not a leaf?");
// Direct match against an integer constant.
- if (IntInit *II = dyn_cast<IntInit>(N.getLeafValue())) {
+ if (IntInit *II = dyn_cast<IntInit>(N->getLeafValue())) {
// If this is the root of the dag we're matching, we emit a redundant opcode
// check to ensure that this gets folded into the normal top-level
// OpcodeSwitch.
- if (&N == Pattern.getSrcPattern()) {
+ if (N == Pattern.getSrcPattern()) {
const SDNodeInfo &NI = CGP.getSDNodeInfo(CGP.getSDNodeNamed("imm"));
AddMatcher(new CheckOpcodeMatcher(NI));
}
}
// An UnsetInit represents a named node without any constraints.
- if (isa<UnsetInit>(N.getLeafValue())) {
- assert(N.hasName() && "Unnamed ? leaf");
+ if (isa<UnsetInit>(N->getLeafValue())) {
+ assert(N->hasName() && "Unnamed ? leaf");
return;
}
- DefInit *DI = dyn_cast<DefInit>(N.getLeafValue());
+ DefInit *DI = dyn_cast<DefInit>(N->getLeafValue());
if (!DI) {
- errs() << "Unknown leaf kind: " << N << "\n";
+ errs() << "Unknown leaf kind: " << *N << "\n";
abort();
}
// unnamed.
if (LeafRec->isSubClassOf("ValueType")) {
// A named ValueType leaf always matches: (add i32:$a, i32:$b).
- if (N.hasName())
+ if (N->hasName())
return;
// An unnamed ValueType as in (sext_inreg GPR:$foo, i8).
return AddMatcher(new CheckValueTypeMatcher(LeafRec->getName()));
if (LeafRec->isSubClassOf("ComplexPattern")) {
// We can't model ComplexPattern uses that don't have their name taken yet.
// The OPC_CheckComplexPattern operation implicitly records the results.
- if (N.getName().empty()) {
+ if (N->getName().empty()) {
std::string S;
raw_string_ostream OS(S);
- OS << "We expect complex pattern uses to have names: " << N;
+ OS << "We expect complex pattern uses to have names: " << *N;
PrintFatalError(OS.str());
}
// Remember this ComplexPattern so that we can emit it after all the other
// structural matches are done.
- unsigned InputOperand = VariableMap[N.getName()] - 1;
- MatchedComplexPatterns.push_back(std::make_pair(&N, InputOperand));
+ unsigned InputOperand = VariableMap[N->getName()] - 1;
+ MatchedComplexPatterns.push_back(std::make_pair(N, InputOperand));
return;
}
- errs() << "Unknown leaf kind: " << N << "\n";
+ errs() << "Unknown leaf kind: " << *N << "\n";
abort();
}
-void MatcherGen::EmitOperatorMatchCode(const TreePatternNode &N,
- TreePatternNode &NodeNoTypes,
+void MatcherGen::EmitOperatorMatchCode(const TreePatternNode *N,
+ TreePatternNode *NodeNoTypes,
unsigned ForceMode) {
- assert(!N.isLeaf() && "Not an operator?");
+ assert(!N->isLeaf() && "Not an operator?");
- if (N.getOperator()->isSubClassOf("ComplexPattern")) {
+ if (N->getOperator()->isSubClassOf("ComplexPattern")) {
// The "name" of a non-leaf complex pattern (MY_PAT $op1, $op2) is
// "MY_PAT:op1:op2". We should already have validated that the uses are
// consistent.
- std::string PatternName = N.getOperator()->getName();
- for (unsigned i = 0; i < N.getNumChildren(); ++i) {
+ std::string PatternName = N->getOperator()->getName();
+ for (unsigned i = 0; i < N->getNumChildren(); ++i) {
PatternName += ":";
- PatternName += N.getChild(i).getName();
+ PatternName += N->getChild(i)->getName();
}
if (recordUniqueNode(PatternName)) {
- auto NodeAndOpNum = std::make_pair(&N, NextRecordedOperandNo - 1);
+ auto NodeAndOpNum = std::make_pair(N, NextRecordedOperandNo - 1);
MatchedComplexPatterns.push_back(NodeAndOpNum);
}
return;
}
- const SDNodeInfo &CInfo = CGP.getSDNodeInfo(N.getOperator());
+ const SDNodeInfo &CInfo = CGP.getSDNodeInfo(N->getOperator());
// If this is an 'and R, 1234' where the operation is AND/OR and the RHS is
// a constant without a predicate fn that has more than one bit set, handle
// them from the mask in the dag. For example, it might turn 'AND X, 255'
// into 'AND X, 254' if it knows the low bit is set. Emit code that checks
// to handle this.
- if ((N.getOperator()->getName() == "and" ||
- N.getOperator()->getName() == "or") &&
- N.getChild(1).isLeaf() && N.getChild(1).getPredicateFns().empty() &&
- N.getPredicateFns().empty()) {
- if (IntInit *II = dyn_cast<IntInit>(N.getChild(1).getLeafValue())) {
+ if ((N->getOperator()->getName() == "and" ||
+ N->getOperator()->getName() == "or") &&
+ N->getChild(1)->isLeaf() && N->getChild(1)->getPredicateFns().empty() &&
+ N->getPredicateFns().empty()) {
+ if (IntInit *II = dyn_cast<IntInit>(N->getChild(1)->getLeafValue())) {
if (!isPowerOf2_32(II->getValue())) { // Don't bother with single bits.
// If this is at the root of the pattern, we emit a redundant
// CheckOpcode so that the following checks get factored properly under
// a single opcode check.
- if (&N == Pattern.getSrcPattern())
+ if (N == Pattern.getSrcPattern())
AddMatcher(new CheckOpcodeMatcher(CInfo));
// Emit the CheckAndImm/CheckOrImm node.
- if (N.getOperator()->getName() == "and")
+ if (N->getOperator()->getName() == "and")
AddMatcher(new CheckAndImmMatcher(II->getValue()));
else
AddMatcher(new CheckOrImmMatcher(II->getValue()));
// Match the LHS of the AND as appropriate.
AddMatcher(new MoveChildMatcher(0));
- EmitMatchCode(N.getChild(0), NodeNoTypes.getChild(0), ForceMode);
+ EmitMatchCode(N->getChild(0), NodeNoTypes->getChild(0), ForceMode);
AddMatcher(new MoveParentMatcher());
return;
}
// If this node has memory references (i.e. is a load or store), tell the
// interpreter to capture them in the memref array.
- if (N.NodeHasProperty(SDNPMemOperand, CGP))
+ if (N->NodeHasProperty(SDNPMemOperand, CGP))
AddMatcher(new RecordMemRefMatcher());
// If this node has a chain, then the chain is operand #0 is the SDNode, and
// the child numbers of the node are all offset by one.
unsigned OpNo = 0;
- if (N.NodeHasProperty(SDNPHasChain, CGP)) {
+ if (N->NodeHasProperty(SDNPHasChain, CGP)) {
// Record the node and remember it in our chained nodes list.
- AddMatcher(new RecordMatcher("'" + N.getOperator()->getName().str() +
+ AddMatcher(new RecordMatcher("'" + N->getOperator()->getName().str() +
"' chained node",
NextRecordedOperandNo));
// Remember all of the input chains our pattern will match.
// this to be folded.
//
const TreePatternNode *Root = Pattern.getSrcPattern();
- if (&N != Root) { // Not the root of the pattern.
+ if (N != Root) { // Not the root of the pattern.
// If there is a node between the root and this node, then we definitely
// need to emit the check.
- bool NeedCheck = !Root->hasChild(&N);
+ bool NeedCheck = !Root->hasChild(N);
// If it *is* an immediate child of the root, we can still need a check if
// the root SDNode has multiple inputs. For us, this means that it is an
}
// If this node has an output glue and isn't the root, remember it.
- if (N.NodeHasProperty(SDNPOutGlue, CGP) &&
- &N != Pattern.getSrcPattern()) {
+ if (N->NodeHasProperty(SDNPOutGlue, CGP) &&
+ N != Pattern.getSrcPattern()) {
// TODO: This redundantly records nodes with both glues and chains.
// Record the node and remember it in our chained nodes list.
- AddMatcher(new RecordMatcher("'" + N.getOperator()->getName().str() +
+ AddMatcher(new RecordMatcher("'" + N->getOperator()->getName().str() +
"' glue output node",
NextRecordedOperandNo));
}
// If this node is known to have an input glue or if it *might* have an input
// glue, capture it as the glue input of the pattern.
- if (N.NodeHasProperty(SDNPOptInGlue, CGP) ||
- N.NodeHasProperty(SDNPInGlue, CGP))
+ if (N->NodeHasProperty(SDNPOptInGlue, CGP) ||
+ N->NodeHasProperty(SDNPInGlue, CGP))
AddMatcher(new CaptureGlueInputMatcher());
- for (unsigned i = 0, e = N.getNumChildren(); i != e; ++i, ++OpNo) {
+ for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) {
// Get the code suitable for matching this child. Move to the child, check
// it then move back to the parent.
AddMatcher(new MoveChildMatcher(OpNo));
- EmitMatchCode(N.getChild(i), NodeNoTypes.getChild(i), ForceMode);
+ EmitMatchCode(N->getChild(i), NodeNoTypes->getChild(i), ForceMode);
AddMatcher(new MoveParentMatcher());
}
}
return false;
}
-void MatcherGen::EmitMatchCode(const TreePatternNode &N,
- TreePatternNode &NodeNoTypes,
+void MatcherGen::EmitMatchCode(const TreePatternNode *N,
+ TreePatternNode *NodeNoTypes,
unsigned ForceMode) {
// If N and NodeNoTypes don't agree on a type, then this is a case where we
// need to do a type check. Emit the check, apply the type to NodeNoTypes and
// reinfer any correlated types.
SmallVector<unsigned, 2> ResultsToTypeCheck;
- for (unsigned i = 0, e = NodeNoTypes.getNumTypes(); i != e; ++i) {
- if (NodeNoTypes.getExtType(i) == N.getExtType(i)) continue;
- NodeNoTypes.setType(i, N.getExtType(i));
+ for (unsigned i = 0, e = NodeNoTypes->getNumTypes(); i != e; ++i) {
+ if (NodeNoTypes->getExtType(i) == N->getExtType(i)) continue;
+ NodeNoTypes->setType(i, N->getExtType(i));
InferPossibleTypes(ForceMode);
ResultsToTypeCheck.push_back(i);
}
// If this node has a name associated with it, capture it in VariableMap. If
// we already saw this in the pattern, emit code to verify dagness.
- if (!N.getName().empty())
- if (!recordUniqueNode(N.getName()))
+ if (!N->getName().empty())
+ if (!recordUniqueNode(N->getName()))
return;
- if (N.isLeaf())
+ if (N->isLeaf())
EmitLeafMatchCode(N);
else
EmitOperatorMatchCode(N, NodeNoTypes, ForceMode);
// If there are node predicates for this node, generate their checks.
- for (unsigned i = 0, e = N.getPredicateFns().size(); i != e; ++i)
- AddMatcher(new CheckPredicateMatcher(N.getPredicateFns()[i]));
+ for (unsigned i = 0, e = N->getPredicateFns().size(); i != e; ++i)
+ AddMatcher(new CheckPredicateMatcher(N->getPredicateFns()[i]));
for (unsigned i = 0, e = ResultsToTypeCheck.size(); i != e; ++i)
- AddMatcher(new CheckTypeMatcher(N.getSimpleType(ResultsToTypeCheck[i]),
+ AddMatcher(new CheckTypeMatcher(N->getSimpleType(ResultsToTypeCheck[i]),
ResultsToTypeCheck[i]));
}
}
// Emit the matcher for the pattern structure and types.
- EmitMatchCode(*Pattern.getSrcPattern(), *PatWithNoTypes,
+ EmitMatchCode(Pattern.getSrcPattern(), PatWithNoTypes.get(),
Pattern.ForceMode);
// If the pattern has a predicate on it (e.g. only enabled when a subtarget
} else {
unsigned CurOp = NextRecordedOperandNo;
for (unsigned i = 0; i < N->getNumChildren(); ++i) {
- NamedComplexPatternOperands[N->getChild(i).getName()] = CurOp + 1;
- CurOp += N->getChild(i).getNumMIResults(CGP);
+ NamedComplexPatternOperands[N->getChild(i)->getName()] = CurOp + 1;
+ CurOp += N->getChild(i)->getNumMIResults(CGP);
}
}
// Node Result Generation
//===----------------------------------------------------------------------===//
-void MatcherGen::EmitResultOfNamedOperand(const TreePatternNode &N,
+void MatcherGen::EmitResultOfNamedOperand(const TreePatternNode *N,
SmallVectorImpl<unsigned> &ResultOps){
- assert(!N.getName().empty() && "Operand not named!");
+ assert(!N->getName().empty() && "Operand not named!");
- if (unsigned SlotNo = NamedComplexPatternOperands[N.getName()]) {
+ if (unsigned SlotNo = NamedComplexPatternOperands[N->getName()]) {
// Complex operands have already been completely selected, just find the
// right slot ant add the arguments directly.
- for (unsigned i = 0; i < N.getNumMIResults(CGP); ++i)
+ for (unsigned i = 0; i < N->getNumMIResults(CGP); ++i)
ResultOps.push_back(SlotNo - 1 + i);
return;
}
- unsigned SlotNo = getNamedArgumentSlot(N.getName());
+ unsigned SlotNo = getNamedArgumentSlot(N->getName());
// If this is an 'imm' or 'fpimm' node, make sure to convert it to the target
// version of the immediate so that it doesn't get selected due to some other
// node use.
- if (!N.isLeaf()) {
- StringRef OperatorName = N.getOperator()->getName();
+ if (!N->isLeaf()) {
+ StringRef OperatorName = N->getOperator()->getName();
if (OperatorName == "imm" || OperatorName == "fpimm") {
AddMatcher(new EmitConvertToTargetMatcher(SlotNo));
ResultOps.push_back(NextRecordedOperandNo++);
}
}
- for (unsigned i = 0; i < N.getNumMIResults(CGP); ++i)
+ for (unsigned i = 0; i < N->getNumMIResults(CGP); ++i)
ResultOps.push_back(SlotNo + i);
}
-void MatcherGen::EmitResultLeafAsOperand(const TreePatternNode &N,
+void MatcherGen::EmitResultLeafAsOperand(const TreePatternNode *N,
SmallVectorImpl<unsigned> &ResultOps) {
- assert(N.isLeaf() && "Must be a leaf");
+ assert(N->isLeaf() && "Must be a leaf");
- if (IntInit *II = dyn_cast<IntInit>(N.getLeafValue())) {
- AddMatcher(new EmitIntegerMatcher(II->getValue(), N.getSimpleType(0)));
+ if (IntInit *II = dyn_cast<IntInit>(N->getLeafValue())) {
+ AddMatcher(new EmitIntegerMatcher(II->getValue(), N->getSimpleType(0)));
ResultOps.push_back(NextRecordedOperandNo++);
return;
}
// If this is an explicit register reference, handle it.
- if (DefInit *DI = dyn_cast<DefInit>(N.getLeafValue())) {
+ if (DefInit *DI = dyn_cast<DefInit>(N->getLeafValue())) {
Record *Def = DI->getDef();
if (Def->isSubClassOf("Register")) {
const CodeGenRegister *Reg =
CGP.getTargetInfo().getRegBank().getReg(Def);
- AddMatcher(new EmitRegisterMatcher(Reg, N.getSimpleType(0)));
+ AddMatcher(new EmitRegisterMatcher(Reg, N->getSimpleType(0)));
ResultOps.push_back(NextRecordedOperandNo++);
return;
}
if (Def->getName() == "zero_reg") {
- AddMatcher(new EmitRegisterMatcher(nullptr, N.getSimpleType(0)));
+ AddMatcher(new EmitRegisterMatcher(nullptr, N->getSimpleType(0)));
ResultOps.push_back(NextRecordedOperandNo++);
return;
}
}
errs() << "unhandled leaf node: \n";
- N.dump();
+ N->dump();
}
/// GetInstPatternNode - Get the pattern for an instruction.
///
const TreePatternNode *MatcherGen::
-GetInstPatternNode(const DAGInstruction &Inst, const TreePatternNode &N) {
+GetInstPatternNode(const DAGInstruction &Inst, const TreePatternNode *N) {
const TreePattern *InstPat = Inst.getPattern();
// FIXME2?: Assume actual pattern comes before "implicit".
TreePatternNode *InstPatNode;
if (InstPat)
InstPatNode = InstPat->getTree(0).get();
- else if (/*isRoot*/ &N == Pattern.getDstPattern())
+ else if (/*isRoot*/ N == Pattern.getDstPattern())
InstPatNode = Pattern.getSrcPattern();
else
return nullptr;
if (InstPatNode && !InstPatNode->isLeaf() &&
InstPatNode->getOperator()->getName() == "set")
- InstPatNode = &InstPatNode->getChild(InstPatNode->getNumChildren()-1);
+ InstPatNode = InstPatNode->getChild(InstPatNode->getNumChildren()-1);
return InstPatNode;
}
static bool
-mayInstNodeLoadOrStore(const TreePatternNode &N,
+mayInstNodeLoadOrStore(const TreePatternNode *N,
const CodeGenDAGPatterns &CGP) {
- Record *Op = N.getOperator();
+ Record *Op = N->getOperator();
const CodeGenTarget &CGT = CGP.getTargetInfo();
CodeGenInstruction &II = CGT.getInstruction(Op);
return II.mayLoad || II.mayStore;
}
static unsigned
-numNodesThatMayLoadOrStore(const TreePatternNode &N,
+numNodesThatMayLoadOrStore(const TreePatternNode *N,
const CodeGenDAGPatterns &CGP) {
- if (N.isLeaf())
+ if (N->isLeaf())
return 0;
- Record *OpRec = N.getOperator();
+ Record *OpRec = N->getOperator();
if (!OpRec->isSubClassOf("Instruction"))
return 0;
if (mayInstNodeLoadOrStore(N, CGP))
++Count;
- for (unsigned i = 0, e = N.getNumChildren(); i != e; ++i)
- Count += numNodesThatMayLoadOrStore(N.getChild(i), CGP);
+ for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
+ Count += numNodesThatMayLoadOrStore(N->getChild(i), CGP);
return Count;
}
void MatcherGen::
-EmitResultInstructionAsOperand(const TreePatternNode &N,
+EmitResultInstructionAsOperand(const TreePatternNode *N,
SmallVectorImpl<unsigned> &OutputOps) {
- Record *Op = N.getOperator();
+ Record *Op = N->getOperator();
const CodeGenTarget &CGT = CGP.getTargetInfo();
CodeGenInstruction &II = CGT.getInstruction(Op);
const DAGInstruction &Inst = CGP.getInstruction(Op);
II.hasSideEffects))
NodeHasChain = true;
- bool isRoot = &N == Pattern.getDstPattern();
+ bool isRoot = N == Pattern.getDstPattern();
// TreeHasOutGlue - True if this tree has glue.
bool TreeHasInGlue = false, TreeHasOutGlue = false;
const DAGDefaultOperand &DefaultOp
= CGP.getDefaultOperand(OperandNode);
for (unsigned i = 0, e = DefaultOp.DefaultOps.size(); i != e; ++i)
- EmitResultOperand(*DefaultOp.DefaultOps[i], InstOps);
+ EmitResultOperand(DefaultOp.DefaultOps[i].get(), InstOps);
continue;
}
unsigned FinalNumOps = InstOps.size() + NumSubOps;
while (InstOps.size() < FinalNumOps) {
- const TreePatternNode &Child = N.getChild(ChildNo);
+ const TreePatternNode *Child = N->getChild(ChildNo);
unsigned BeforeAddingNumOps = InstOps.size();
EmitResultOperand(Child, InstOps);
assert(InstOps.size() > BeforeAddingNumOps && "Didn't add any operands");
// If the operand is an instruction and it produced multiple results, just
// take the first one.
- if (!Child.isLeaf() && Child.getOperator()->isSubClassOf("Instruction"))
+ if (!Child->isLeaf() && Child->getOperator()->isSubClassOf("Instruction"))
InstOps.resize(BeforeAddingNumOps+1);
++ChildNo;
// above. Emit the remaining instructions implicitly added by the use for
// variable_ops.
if (II.Operands.isVariadic) {
- for (unsigned I = ChildNo, E = N.getNumChildren(); I < E; ++I)
- EmitResultOperand(N.getChild(I), InstOps);
+ for (unsigned I = ChildNo, E = N->getNumChildren(); I < E; ++I)
+ EmitResultOperand(N->getChild(I), InstOps);
}
// If this node has input glue or explicitly specified input physregs, we
// Determine the result types.
SmallVector<MVT::SimpleValueType, 4> ResultVTs;
- for (unsigned i = 0, e = N.getNumTypes(); i != e; ++i)
- ResultVTs.push_back(N.getSimpleType(i));
+ for (unsigned i = 0, e = N->getNumTypes(); i != e; ++i)
+ ResultVTs.push_back(N->getSimpleType(i));
// If this is the root instruction of a pattern that has physical registers in
// its result pattern, add output VTs for them. For example, X86 has:
bool NodeHasMemRefs = false;
if (PatternHasMemOperands) {
unsigned NumNodesThatLoadOrStore =
- numNodesThatMayLoadOrStore(*Pattern.getDstPattern(), CGP);
+ numNodesThatMayLoadOrStore(Pattern.getDstPattern(), CGP);
bool NodeIsUniqueLoadOrStore = mayInstNodeLoadOrStore(N, CGP) &&
NumNodesThatLoadOrStore == 1;
NodeHasMemRefs =
}
void MatcherGen::
-EmitResultSDNodeXFormAsOperand(const TreePatternNode &N,
+EmitResultSDNodeXFormAsOperand(const TreePatternNode *N,
SmallVectorImpl<unsigned> &ResultOps) {
- assert(N.getOperator()->isSubClassOf("SDNodeXForm") && "Not SDNodeXForm?");
+ assert(N->getOperator()->isSubClassOf("SDNodeXForm") && "Not SDNodeXForm?");
// Emit the operand.
SmallVector<unsigned, 8> InputOps;
// FIXME2: Could easily generalize this to support multiple inputs and outputs
// to the SDNodeXForm. For now we just support one input and one output like
// the old instruction selector.
- assert(N.getNumChildren() == 1);
- EmitResultOperand(N.getChild(0), InputOps);
+ assert(N->getNumChildren() == 1);
+ EmitResultOperand(N->getChild(0), InputOps);
// The input currently must have produced exactly one result.
assert(InputOps.size() == 1 && "Unexpected input to SDNodeXForm");
- AddMatcher(new EmitNodeXFormMatcher(InputOps[0], N.getOperator()));
+ AddMatcher(new EmitNodeXFormMatcher(InputOps[0], N->getOperator()));
ResultOps.push_back(NextRecordedOperandNo++);
}
-void MatcherGen::EmitResultOperand(const TreePatternNode &N,
+void MatcherGen::EmitResultOperand(const TreePatternNode *N,
SmallVectorImpl<unsigned> &ResultOps) {
// This is something selected from the pattern we matched.
- if (!N.getName().empty())
+ if (!N->getName().empty())
return EmitResultOfNamedOperand(N, ResultOps);
- if (N.isLeaf())
+ if (N->isLeaf())
return EmitResultLeafAsOperand(N, ResultOps);
- Record *OpRec = N.getOperator();
+ Record *OpRec = N->getOperator();
if (OpRec->isSubClassOf("Instruction"))
return EmitResultInstructionAsOperand(N, ResultOps);
if (OpRec->isSubClassOf("SDNodeXForm"))
return EmitResultSDNodeXFormAsOperand(N, ResultOps);
- errs() << "Unknown result node to emit code for: " << N << '\n';
+ errs() << "Unknown result node to emit code for: " << *N << '\n';
PrintFatalError("Unknown node in result pattern!");
}
// Codegen the root of the result pattern, capturing the resulting values.
SmallVector<unsigned, 8> Ops;
- EmitResultOperand(*Pattern.getDstPattern(), Ops);
+ EmitResultOperand(Pattern.getDstPattern(), Ops);
// At this point, we have however many values the result pattern produces.
// However, the input pattern might not need all of these. If there are
const CodeGenRegisterClass *DstRC = nullptr;
for (unsigned i = 0, e = InstPatNode->getNumChildren(); i != e; ++i) {
- const TreePatternNode &Op = InstPatNode->getChild(i);
+ TreePatternNode *Op = InstPatNode->getChild(i);
// Handle imm operands specially.
- if (!Op.isLeaf() && Op.getOperator()->getName() == "imm") {
+ if (!Op->isLeaf() && Op->getOperator()->getName() == "imm") {
unsigned PredNo = 0;
- if (!Op.getPredicateFns().empty()) {
- TreePredicateFn PredFn = Op.getPredicateFns()[0];
+ if (!Op->getPredicateFns().empty()) {
+ TreePredicateFn PredFn = Op->getPredicateFns()[0];
// If there is more than one predicate weighing in on this operand
// then we don't handle it. This doesn't typically happen for
// immediates anyway.
- if (Op.getPredicateFns().size() > 1 || !PredFn.isImmediatePattern())
+ if (Op->getPredicateFns().size() > 1 ||
+ !PredFn.isImmediatePattern())
return false;
// Ignore any instruction with 'FastIselShouldIgnore', these are
// not needed and just bloat the fast instruction selector. For
// For now, filter out any operand with a predicate.
// For now, filter out any operand with multiple values.
- if (!Op.getPredicateFns().empty() || Op.getNumTypes() != 1)
+ if (!Op->getPredicateFns().empty() || Op->getNumTypes() != 1)
return false;
- if (!Op.isLeaf()) {
- if (Op.getOperator()->getName() == "fpimm") {
+ if (!Op->isLeaf()) {
+ if (Op->getOperator()->getName() == "fpimm") {
Operands.push_back(OpKind::getFP());
continue;
}
return false;
}
- assert(Op.hasConcreteType(0) && "Type infererence not done?");
+ assert(Op->hasConcreteType(0) && "Type infererence not done?");
// For now, all the operands must have the same type (if they aren't
// immediates). Note that this causes us to reject variable sized shifts
// on X86.
- if (Op.getSimpleType(0) != VT)
+ if (Op->getSimpleType(0) != VT)
return false;
- DefInit *OpDI = dyn_cast<DefInit>(Op.getLeafValue());
+ DefInit *OpDI = dyn_cast<DefInit>(Op->getLeafValue());
if (!OpDI)
return false;
Record *OpLeafRec = OpDI->getDef();
FastISelMap::FastISelMap(StringRef instns) : InstNS(instns) {}
-static std::string PhyRegForNode(const TreePatternNode &Op,
+static std::string PhyRegForNode(TreePatternNode *Op,
const CodeGenTarget &Target) {
std::string PhysReg;
- if (!Op.isLeaf())
+ if (!Op->isLeaf())
return PhysReg;
- Record *OpLeafRec = cast<DefInit>(Op.getLeafValue())->getDef();
+ Record *OpLeafRec = cast<DefInit>(Op->getLeafValue())->getDef();
if (!OpLeafRec->isSubClassOf("Register"))
return PhysReg;
// For now, ignore multi-instruction patterns.
bool MultiInsts = false;
for (unsigned i = 0, e = Dst->getNumChildren(); i != e; ++i) {
- const TreePatternNode &ChildOp = Dst->getChild(i);
- if (ChildOp.isLeaf())
+ TreePatternNode *ChildOp = Dst->getChild(i);
+ if (ChildOp->isLeaf())
continue;
- if (ChildOp.getOperator()->isSubClassOf("Instruction")) {
+ if (ChildOp->getOperator()->isSubClassOf("Instruction")) {
MultiInsts = true;
break;
}
} else {
// If this isn't a leaf, then continue since the register classes are
// a bit too complicated for now.
- if (!Dst->getChild(1).isLeaf()) continue;
+ if (!Dst->getChild(1)->isLeaf()) continue;
- DefInit *SR = dyn_cast<DefInit>(Dst->getChild(1).getLeafValue());
+ DefInit *SR = dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue());
if (SR)
SubRegNo = getQualifiedName(SR->getDef());
else
- SubRegNo = Dst->getChild(1).getLeafValue()->getAsString();
+ SubRegNo = Dst->getChild(1)->getLeafValue()->getAsString();
}
// Inspect the pattern.
if (InstPatNode->getNumTypes()) RetVT = InstPatNode->getSimpleType(0);
MVT::SimpleValueType VT = RetVT;
if (InstPatNode->getNumChildren()) {
- assert(InstPatNode->getChild(0).getNumTypes() == 1);
- VT = InstPatNode->getChild(0).getSimpleType(0);
+ assert(InstPatNode->getChild(0)->getNumTypes() == 1);
+ VT = InstPatNode->getChild(0)->getSimpleType(0);
}
// For now, filter out any instructions with predicates.
std::string PhysReg = PhyRegForNode(InstPatNode->getChild(i), Target);
if (PhysReg.empty()) {
if (DstIndex >= Dst->getNumChildren() ||
- Dst->getChild(DstIndex).getName() !=
- InstPatNode->getChild(i).getName()) {
+ Dst->getChild(DstIndex)->getName() !=
+ InstPatNode->getChild(i)->getName()) {
FoundNonSimplePattern = true;
break;
}
return None;
}
-static std::string explainPredicates(const TreePatternNode &N) {
+static std::string explainPredicates(const TreePatternNode *N) {
std::string Explanation = "";
StringRef Separator = "";
- for (const auto &P : N.getPredicateFns()) {
+ for (const auto &P : N->getPredicateFns()) {
Explanation +=
(Separator + P.getOrigPatFragRecord()->getRecord()->getName()).str();
Separator = ", ";
return make_error<StringError>(Reason, inconvertibleErrorCode());
}
-static Error isTrivialOperatorNode(const TreePatternNode &N) {
+static Error isTrivialOperatorNode(const TreePatternNode *N) {
std::string Explanation = "";
std::string Separator = "";
bool HasUnsupportedPredicate = false;
- for (const auto &Predicate : N.getPredicateFns()) {
+ for (const auto &Predicate : N->getPredicateFns()) {
if (Predicate.isAlwaysTrue())
continue;
void gatherNodeEquivs();
Record *findNodeEquiv(Record *N) const;
const CodeGenInstruction *getEquivNode(Record &Equiv,
- const TreePatternNode &N) const;
+ const TreePatternNode *N) const;
Error importRulePredicates(RuleMatcher &M, ArrayRef<Predicate> Predicates);
Expected<InstructionMatcher &> createAndImportSelDAGMatcher(
RuleMatcher &Rule, InstructionMatcher &InsnMatcher,
- const TreePatternNode &Src, unsigned &TempOpIdx) const;
+ const TreePatternNode *Src, unsigned &TempOpIdx) const;
Error importComplexPatternOperandMatcher(OperandMatcher &OM, Record *R,
unsigned &TempOpIdx) const;
Error importChildMatcher(RuleMatcher &Rule, InstructionMatcher &InsnMatcher,
- const TreePatternNode &SrcChild,
+ const TreePatternNode *SrcChild,
bool OperandIsAPointer, unsigned OpIdx,
unsigned &TempOpIdx) const;
Expected<BuildMIAction &>
createAndImportInstructionRenderer(RuleMatcher &M,
- const TreePatternNode &Dst);
+ const TreePatternNode *Dst);
Expected<action_iterator> createAndImportSubInstructionRenderer(
- action_iterator InsertPt, RuleMatcher &M, const TreePatternNode &Dst,
+ action_iterator InsertPt, RuleMatcher &M, const TreePatternNode *Dst,
unsigned TempReg);
Expected<action_iterator>
createInstructionRenderer(action_iterator InsertPt, RuleMatcher &M,
- const TreePatternNode &Dst);
+ const TreePatternNode *Dst);
void importExplicitDefRenderers(BuildMIAction &DstMIBuilder);
Expected<action_iterator>
importExplicitUseRenderers(action_iterator InsertPt, RuleMatcher &M,
BuildMIAction &DstMIBuilder,
- const llvm::TreePatternNode &Dst);
+ const llvm::TreePatternNode *Dst);
Expected<action_iterator>
importExplicitUseRenderer(action_iterator InsertPt, RuleMatcher &Rule,
BuildMIAction &DstMIBuilder,
- const TreePatternNode &DstChild);
+ TreePatternNode *DstChild);
Error importDefaultOperandRenderers(BuildMIAction &DstMIBuilder,
DagInit *DefaultOps) const;
Error
}
const CodeGenInstruction *
-GlobalISelEmitter::getEquivNode(Record &Equiv, const TreePatternNode &N) const {
- for (const auto &Predicate : N.getPredicateFns()) {
+GlobalISelEmitter::getEquivNode(Record &Equiv, const TreePatternNode *N) const {
+ for (const auto &Predicate : N->getPredicateFns()) {
if (!Equiv.isValueUnset("IfSignExtend") && Predicate.isLoad() &&
Predicate.isSignExtLoad())
return &Target.getInstruction(Equiv.getValueAsDef("IfSignExtend"));
Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher(
RuleMatcher &Rule, InstructionMatcher &InsnMatcher,
- const TreePatternNode &Src, unsigned &TempOpIdx) const {
+ const TreePatternNode *Src, unsigned &TempOpIdx) const {
Record *SrcGIEquivOrNull = nullptr;
const CodeGenInstruction *SrcGIOrNull = nullptr;
// Start with the defined operands (i.e., the results of the root operator).
- if (Src.getExtTypes().size() > 1)
+ if (Src->getExtTypes().size() > 1)
return failedImport("Src pattern has multiple results");
- if (Src.isLeaf()) {
- Init *SrcInit = Src.getLeafValue();
+ if (Src->isLeaf()) {
+ Init *SrcInit = Src->getLeafValue();
if (isa<IntInit>(SrcInit)) {
InsnMatcher.addPredicate<InstructionOpcodeMatcher>(
&Target.getInstruction(RK.getDef("G_CONSTANT")));
return failedImport(
"Unable to deduce gMIR opcode to handle Src (which is a leaf)");
} else {
- SrcGIEquivOrNull = findNodeEquiv(Src.getOperator());
+ SrcGIEquivOrNull = findNodeEquiv(Src->getOperator());
if (!SrcGIEquivOrNull)
return failedImport("Pattern operator lacks an equivalent Instruction" +
- explainOperator(Src.getOperator()));
+ explainOperator(Src->getOperator()));
SrcGIOrNull = getEquivNode(*SrcGIEquivOrNull, Src);
// The operators look good: match the opcode
}
unsigned OpIdx = 0;
- for (const TypeSetByHwMode &VTy : Src.getExtTypes()) {
+ for (const TypeSetByHwMode &VTy : Src->getExtTypes()) {
// Results don't have a name unless they are the root node. The caller will
// set the name if appropriate.
OperandMatcher &OM = InsnMatcher.addOperand(OpIdx++, "", TempOpIdx);
" for result of Src pattern operator");
}
- for (const auto &Predicate : Src.getPredicateFns()) {
+ for (const auto &Predicate : Src->getPredicateFns()) {
if (Predicate.isAlwaysTrue())
continue;
if (SrcGIEquivOrNull && SrcGIEquivOrNull->getValueAsBit("CheckMMOIsNonAtomic"))
InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("NotAtomic");
- if (Src.isLeaf()) {
- Init *SrcInit = Src.getLeafValue();
+ if (Src->isLeaf()) {
+ Init *SrcInit = Src->getLeafValue();
if (IntInit *SrcIntInit = dyn_cast<IntInit>(SrcInit)) {
OperandMatcher &OM =
- InsnMatcher.addOperand(OpIdx++, Src.getName(), TempOpIdx);
+ InsnMatcher.addOperand(OpIdx++, Src->getName(), TempOpIdx);
OM.addPredicate<LiteralIntOperandMatcher>(SrcIntInit->getValue());
} else
return failedImport(
}
// Match the used operands (i.e. the children of the operator).
- for (unsigned i = 0, e = Src.getNumChildren(); i != e; ++i) {
- const TreePatternNode &SrcChild = Src.getChild(i);
+ for (unsigned i = 0, e = Src->getNumChildren(); i != e; ++i) {
+ TreePatternNode *SrcChild = Src->getChild(i);
// SelectionDAG allows pointers to be represented with iN since it doesn't
// distinguish between pointers and integers but they are different types in GlobalISel.
if ((SrcGIOrNull->TheDef->getName() == "G_INTRINSIC" ||
SrcGIOrNull->TheDef->getName() == "G_INTRINSIC_W_SIDE_EFFECTS") &&
i == 0) {
- if (const CodeGenIntrinsic *II = Src.getIntrinsicInfo(CGP)) {
+ if (const CodeGenIntrinsic *II = Src->getIntrinsicInfo(CGP)) {
OperandMatcher &OM =
- InsnMatcher.addOperand(OpIdx++, SrcChild.getName(), TempOpIdx);
+ InsnMatcher.addOperand(OpIdx++, SrcChild->getName(), TempOpIdx);
OM.addPredicate<IntrinsicIDOperandMatcher>(II);
continue;
}
Error GlobalISelEmitter::importChildMatcher(RuleMatcher &Rule,
InstructionMatcher &InsnMatcher,
- const TreePatternNode &SrcChild,
+ const TreePatternNode *SrcChild,
bool OperandIsAPointer,
unsigned OpIdx,
unsigned &TempOpIdx) const {
OperandMatcher &OM =
- InsnMatcher.addOperand(OpIdx, SrcChild.getName(), TempOpIdx);
+ InsnMatcher.addOperand(OpIdx, SrcChild->getName(), TempOpIdx);
if (OM.isSameAsAnotherOperand())
return Error::success();
- ArrayRef<TypeSetByHwMode> ChildTypes = SrcChild.getExtTypes();
+ ArrayRef<TypeSetByHwMode> ChildTypes = SrcChild->getExtTypes();
if (ChildTypes.size() != 1)
return failedImport("Src pattern child has multiple results");
// Check MBB's before the type check since they are not a known type.
- if (!SrcChild.isLeaf()) {
- if (SrcChild.getOperator()->isSubClassOf("SDNode")) {
- auto &ChildSDNI = CGP.getSDNodeInfo(SrcChild.getOperator());
+ if (!SrcChild->isLeaf()) {
+ if (SrcChild->getOperator()->isSubClassOf("SDNode")) {
+ auto &ChildSDNI = CGP.getSDNodeInfo(SrcChild->getOperator());
if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
OM.addPredicate<MBBOperandMatcher>();
return Error::success();
if (auto Error =
OM.addTypeCheckPredicate(ChildTypes.front(), OperandIsAPointer))
return failedImport(toString(std::move(Error)) + " for Src operand (" +
- to_string(SrcChild) + ")");
+ to_string(*SrcChild) + ")");
// Check for nested instructions.
- if (!SrcChild.isLeaf()) {
- if (SrcChild.getOperator()->isSubClassOf("ComplexPattern")) {
+ if (!SrcChild->isLeaf()) {
+ if (SrcChild->getOperator()->isSubClassOf("ComplexPattern")) {
// When a ComplexPattern is used as an operator, it should do the same
// thing as when used as a leaf. However, the children of the operator
// name the sub-operands that make up the complex operand and we must
// prepare to reference them in the renderer too.
unsigned RendererID = TempOpIdx;
if (auto Error = importComplexPatternOperandMatcher(
- OM, SrcChild.getOperator(), TempOpIdx))
+ OM, SrcChild->getOperator(), TempOpIdx))
return Error;
- for (unsigned i = 0, e = SrcChild.getNumChildren(); i != e; ++i) {
- const auto &SubOperand = SrcChild.getChild(i);
- if (!SubOperand.getName().empty())
- Rule.defineComplexSubOperand(SubOperand.getName(),
- SrcChild.getOperator(), RendererID, i);
+ for (unsigned i = 0, e = SrcChild->getNumChildren(); i != e; ++i) {
+ auto *SubOperand = SrcChild->getChild(i);
+ if (!SubOperand->getName().empty())
+ Rule.defineComplexSubOperand(SubOperand->getName(),
+ SrcChild->getOperator(), RendererID, i);
}
return Error::success();
}
auto MaybeInsnOperand = OM.addPredicate<InstructionOperandMatcher>(
- InsnMatcher.getRuleMatcher(), SrcChild.getName());
+ InsnMatcher.getRuleMatcher(), SrcChild->getName());
if (!MaybeInsnOperand.hasValue()) {
// This isn't strictly true. If the user were to provide exactly the same
// matchers as the original operand then we could allow it. However, it's
return Error::success();
}
- if (SrcChild.hasAnyPredicate())
+ if (SrcChild->hasAnyPredicate())
return failedImport("Src pattern child has unsupported predicate");
// Check for constant immediates.
- if (auto *ChildInt = dyn_cast<IntInit>(SrcChild.getLeafValue())) {
+ if (auto *ChildInt = dyn_cast<IntInit>(SrcChild->getLeafValue())) {
OM.addPredicate<ConstantIntOperandMatcher>(ChildInt->getValue());
return Error::success();
}
// Check for def's like register classes or ComplexPattern's.
- if (auto *ChildDefInit = dyn_cast<DefInit>(SrcChild.getLeafValue())) {
+ if (auto *ChildDefInit = dyn_cast<DefInit>(SrcChild->getLeafValue())) {
auto *ChildRec = ChildDefInit->getDef();
// Check for register classes.
Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderer(
action_iterator InsertPt, RuleMatcher &Rule, BuildMIAction &DstMIBuilder,
- const TreePatternNode &DstChild) {
+ TreePatternNode *DstChild) {
- const auto &SubOperand = Rule.getComplexSubOperand(DstChild.getName());
+ const auto &SubOperand = Rule.getComplexSubOperand(DstChild->getName());
if (SubOperand.hasValue()) {
DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
- *std::get<0>(*SubOperand), DstChild.getName(),
+ *std::get<0>(*SubOperand), DstChild->getName(),
std::get<1>(*SubOperand), std::get<2>(*SubOperand));
return InsertPt;
}
- if (!DstChild.isLeaf()) {
+ if (!DstChild->isLeaf()) {
- if (DstChild.getOperator()->isSubClassOf("SDNodeXForm")) {
- const auto &Child = DstChild.getChild(0);
- auto I = SDNodeXFormEquivs.find(DstChild.getOperator());
+ if (DstChild->getOperator()->isSubClassOf("SDNodeXForm")) {
+ auto Child = DstChild->getChild(0);
+ auto I = SDNodeXFormEquivs.find(DstChild->getOperator());
if (I != SDNodeXFormEquivs.end()) {
- DstMIBuilder.addRenderer<CustomRenderer>(*I->second, Child.getName());
+ DstMIBuilder.addRenderer<CustomRenderer>(*I->second, Child->getName());
return InsertPt;
}
- return failedImport("SDNodeXForm " + Child.getName() +
+ return failedImport("SDNodeXForm " + Child->getName() +
" has no custom renderer");
}
// We accept 'bb' here. It's an operator because BasicBlockSDNode isn't
// inline, but in MI it's just another operand.
- if (DstChild.getOperator()->isSubClassOf("SDNode")) {
- auto &ChildSDNI = CGP.getSDNodeInfo(DstChild.getOperator());
+ if (DstChild->getOperator()->isSubClassOf("SDNode")) {
+ auto &ChildSDNI = CGP.getSDNodeInfo(DstChild->getOperator());
if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
- DstMIBuilder.addRenderer<CopyRenderer>(DstChild.getName());
+ DstMIBuilder.addRenderer<CopyRenderer>(DstChild->getName());
return InsertPt;
}
}
// rendered as operands.
// FIXME: The target should be able to choose sign-extended when appropriate
// (e.g. on Mips).
- if (DstChild.getOperator()->getName() == "imm") {
- DstMIBuilder.addRenderer<CopyConstantAsImmRenderer>(DstChild.getName());
+ if (DstChild->getOperator()->getName() == "imm") {
+ DstMIBuilder.addRenderer<CopyConstantAsImmRenderer>(DstChild->getName());
return InsertPt;
- } else if (DstChild.getOperator()->getName() == "fpimm") {
+ } else if (DstChild->getOperator()->getName() == "fpimm") {
DstMIBuilder.addRenderer<CopyFConstantAsFPImmRenderer>(
- DstChild.getName());
+ DstChild->getName());
return InsertPt;
}
- if (DstChild.getOperator()->isSubClassOf("Instruction")) {
- ArrayRef<TypeSetByHwMode> ChildTypes = DstChild.getExtTypes();
+ if (DstChild->getOperator()->isSubClassOf("Instruction")) {
+ ArrayRef<TypeSetByHwMode> ChildTypes = DstChild->getExtTypes();
if (ChildTypes.size() != 1)
return failedImport("Dst pattern child has multiple results");
return InsertPtOrError.get();
}
- return failedImport("Dst pattern child isn't a leaf node or an MBB" + llvm::to_string(DstChild));
+ return failedImport("Dst pattern child isn't a leaf node or an MBB" + llvm::to_string(*DstChild));
}
// It could be a specific immediate in which case we should just check for
// that immediate.
if (const IntInit *ChildIntInit =
- dyn_cast<IntInit>(DstChild.getLeafValue())) {
+ dyn_cast<IntInit>(DstChild->getLeafValue())) {
DstMIBuilder.addRenderer<ImmRenderer>(ChildIntInit->getValue());
return InsertPt;
}
// Otherwise, we're looking for a bog-standard RegisterClass operand.
- if (auto *ChildDefInit = dyn_cast<DefInit>(DstChild.getLeafValue())) {
+ if (auto *ChildDefInit = dyn_cast<DefInit>(DstChild->getLeafValue())) {
auto *ChildRec = ChildDefInit->getDef();
- ArrayRef<TypeSetByHwMode> ChildTypes = DstChild.getExtTypes();
+ ArrayRef<TypeSetByHwMode> ChildTypes = DstChild->getExtTypes();
if (ChildTypes.size() != 1)
return failedImport("Dst pattern child has multiple results");
if (ChildRec->isSubClassOf("RegisterOperand") &&
!ChildRec->isValueUnset("GIZeroRegister")) {
DstMIBuilder.addRenderer<CopyOrAddZeroRegRenderer>(
- DstChild.getName(), ChildRec->getValueAsDef("GIZeroRegister"));
+ DstChild->getName(), ChildRec->getValueAsDef("GIZeroRegister"));
return InsertPt;
}
- DstMIBuilder.addRenderer<CopyRenderer>(DstChild.getName());
+ DstMIBuilder.addRenderer<CopyRenderer>(DstChild->getName());
return InsertPt;
}
return failedImport(
"SelectionDAG ComplexPattern not mapped to GlobalISel");
- const OperandMatcher &OM = Rule.getOperandMatcher(DstChild.getName());
+ const OperandMatcher &OM = Rule.getOperandMatcher(DstChild->getName());
DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
- *ComplexPattern->second, DstChild.getName(),
+ *ComplexPattern->second, DstChild->getName(),
OM.getAllocatedTemporariesBaseID());
return InsertPt;
}
}
Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer(
- RuleMatcher &M, const TreePatternNode &Dst) {
+ RuleMatcher &M, const TreePatternNode *Dst) {
auto InsertPtOrError = createInstructionRenderer(M.actions_end(), M, Dst);
if (auto Error = InsertPtOrError.takeError())
return std::move(Error);
Expected<action_iterator>
GlobalISelEmitter::createAndImportSubInstructionRenderer(
- const action_iterator InsertPt, RuleMatcher &M, const TreePatternNode &Dst,
+ const action_iterator InsertPt, RuleMatcher &M, const TreePatternNode *Dst,
unsigned TempRegID) {
auto InsertPtOrError = createInstructionRenderer(InsertPt, M, Dst);
}
Expected<action_iterator> GlobalISelEmitter::createInstructionRenderer(
- action_iterator InsertPt, RuleMatcher &M, const TreePatternNode &Dst) {
- Record *DstOp = Dst.getOperator();
+ action_iterator InsertPt, RuleMatcher &M, const TreePatternNode *Dst) {
+ Record *DstOp = Dst->getOperator();
if (!DstOp->isSubClassOf("Instruction")) {
if (DstOp->isSubClassOf("ValueType"))
return failedImport(
Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderers(
action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder,
- const llvm::TreePatternNode &Dst) {
+ const llvm::TreePatternNode *Dst) {
const CodeGenInstruction *DstI = DstMIBuilder.getCGI();
- CodeGenInstruction *OrigDstI = &Target.getInstruction(Dst.getOperator());
+ CodeGenInstruction *OrigDstI = &Target.getInstruction(Dst->getOperator());
// EXTRACT_SUBREG needs to use a subregister COPY.
if (OrigDstI->TheDef->getName() == "EXTRACT_SUBREG") {
- if (!Dst.getChild(0).isLeaf())
+ if (!Dst->getChild(0)->isLeaf())
return failedImport("EXTRACT_SUBREG child #1 is not a leaf");
if (DefInit *SubRegInit =
- dyn_cast<DefInit>(Dst.getChild(1).getLeafValue())) {
- Record *RCDef = getInitValueAsRegClass(Dst.getChild(0).getLeafValue());
+ dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue())) {
+ Record *RCDef = getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
if (!RCDef)
return failedImport("EXTRACT_SUBREG child #0 could not "
"be coerced to a register class");
return failedImport("EXTRACT_SUBREG requires an additional COPY");
}
- DstMIBuilder.addRenderer<CopySubRegRenderer>(Dst.getChild(0).getName(),
+ DstMIBuilder.addRenderer<CopySubRegRenderer>(Dst->getChild(0)->getName(),
SubIdx);
return InsertPt;
}
// Render the explicit uses.
unsigned DstINumUses = OrigDstI->Operands.size() - OrigDstI->Operands.NumDefs;
- unsigned ExpectedDstINumUses = Dst.getNumChildren();
+ unsigned ExpectedDstINumUses = Dst->getNumChildren();
if (OrigDstI->TheDef->getName() == "COPY_TO_REGCLASS") {
DstINumUses--; // Ignore the class constraint.
ExpectedDstINumUses--;
}
auto InsertPtOrError = importExplicitUseRenderer(InsertPt, M, DstMIBuilder,
- Dst.getChild(Child));
+ Dst->getChild(Child));
if (auto Error = InsertPtOrError.takeError())
return std::move(Error);
InsertPt = InsertPtOrError.get();
return std::move(Error);
// Next, analyze the pattern operators.
- const TreePatternNode &Src = *P.getSrcPattern();
- const TreePatternNode &Dst = *P.getDstPattern();
+ TreePatternNode *Src = P.getSrcPattern();
+ TreePatternNode *Dst = P.getDstPattern();
// If the root of either pattern isn't a simple operator, ignore it.
if (auto Err = isTrivialOperatorNode(Dst))
// the capture accross rules. The downside is that it would
// introduce a dependency between predicates (captures must happen
// before their first use.)
- InstructionMatcher &InsnMatcherTemp = M.addInstructionMatcher(Src.getName());
+ InstructionMatcher &InsnMatcherTemp = M.addInstructionMatcher(Src->getName());
unsigned TempOpIdx = 0;
auto InsnMatcherOrError =
createAndImportSelDAGMatcher(M, InsnMatcherTemp, Src, TempOpIdx);
return std::move(Error);
InstructionMatcher &InsnMatcher = InsnMatcherOrError.get();
- if (Dst.isLeaf()) {
- Record *RCDef = getInitValueAsRegClass(Dst.getLeafValue());
+ if (Dst->isLeaf()) {
+ Record *RCDef = getInitValueAsRegClass(Dst->getLeafValue());
const CodeGenRegisterClass &RC = Target.getRegisterClass(RCDef);
if (RCDef) {
auto &DstMIBuilder =
M.addAction<BuildMIAction>(M.allocateOutputInsnID(), &DstI);
DstMIBuilder.addRenderer<CopyRenderer>(DstIOperand.Name);
- DstMIBuilder.addRenderer<CopyRenderer>(Dst.getName());
+ DstMIBuilder.addRenderer<CopyRenderer>(Dst->getName());
M.addAction<ConstrainOperandToRegClassAction>(0, 0, RC);
// We're done with this pattern! It's eligible for GISel emission; return
}
// Start with the defined operands (i.e., the results of the root operator).
- Record *DstOp = Dst.getOperator();
+ Record *DstOp = Dst->getOperator();
if (!DstOp->isSubClassOf("Instruction"))
return failedImport("Pattern operator isn't an instruction");
auto &DstI = Target.getInstruction(DstOp);
- if (DstI.Operands.NumDefs != Src.getExtTypes().size())
+ if (DstI.Operands.NumDefs != Src->getExtTypes().size())
return failedImport("Src pattern results and dst MI defs are different (" +
- to_string(Src.getExtTypes().size()) + " def(s) vs " +
+ to_string(Src->getExtTypes().size()) + " def(s) vs " +
to_string(DstI.Operands.NumDefs) + " def(s))");
// The root of the match also has constraints on the register bank so that it
// matches the result instruction.
unsigned OpIdx = 0;
- for (const TypeSetByHwMode &VTy : Src.getExtTypes()) {
+ for (const TypeSetByHwMode &VTy : Src->getExtTypes()) {
(void)VTy;
const auto &DstIOperand = DstI.Operands[OpIdx];
Record *DstIOpRec = DstIOperand.Rec;
if (DstI.TheDef->getName() == "COPY_TO_REGCLASS") {
- DstIOpRec = getInitValueAsRegClass(Dst.getChild(1).getLeafValue());
+ DstIOpRec = getInitValueAsRegClass(Dst->getChild(1)->getLeafValue());
if (DstIOpRec == nullptr)
return failedImport(
"COPY_TO_REGCLASS operand #1 isn't a register class");
} else if (DstI.TheDef->getName() == "EXTRACT_SUBREG") {
- if (!Dst.getChild(0).isLeaf())
+ if (!Dst->getChild(0)->isLeaf())
return failedImport("EXTRACT_SUBREG operand #0 isn't a leaf");
// We can assume that a subregister is in the same bank as it's super
// register.
- DstIOpRec = getInitValueAsRegClass(Dst.getChild(0).getLeafValue());
+ DstIOpRec = getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
if (DstIOpRec == nullptr)
return failedImport(
} else if (DstIOpRec->isSubClassOf("RegisterOperand"))
DstIOpRec = DstIOpRec->getValueAsDef("RegClass");
else if (!DstIOpRec->isSubClassOf("RegisterClass"))
- return failedImport("Dst MI def isn't a register class" + to_string(Dst));
+ return failedImport("Dst MI def isn't a register class" +
+ to_string(*Dst));
OperandMatcher &OM = InsnMatcher.getOperand(OpIdx);
OM.setSymbolicName(DstIOperand.Name);
// COPY_TO_REGCLASS does not provide operand constraints itself but the
// result is constrained to the class given by the second child.
Record *DstIOpRec =
- getInitValueAsRegClass(Dst.getChild(1).getLeafValue());
+ getInitValueAsRegClass(Dst->getChild(1)->getLeafValue());
if (DstIOpRec == nullptr)
return failedImport("COPY_TO_REGCLASS operand #1 isn't a register class");
// instructions, the result register class is controlled by the
// subregisters of the operand. As a result, we must constrain the result
// class rather than check that it's already the right one.
- if (!Dst.getChild(0).isLeaf())
+ if (!Dst->getChild(0)->isLeaf())
return failedImport("EXTRACT_SUBREG child #1 is not a leaf");
- DefInit *SubRegInit = dyn_cast<DefInit>(Dst.getChild(1).getLeafValue());
+ DefInit *SubRegInit = dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue());
if (!SubRegInit)
return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
// Constrain the result to the same register bank as the operand.
Record *DstIOpRec =
- getInitValueAsRegClass(Dst.getChild(0).getLeafValue());
+ getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
if (DstIOpRec == nullptr)
return failedImport("EXTRACT_SUBREG operand #1 isn't a register class");
//
// FIXME: This may introduce an extra copy if the chosen class doesn't
// actually contain the subregisters.
- assert(Src.getExtTypes().size() == 1 &&
+ assert(Src->getExtTypes().size() == 1 &&
"Expected Src of EXTRACT_SUBREG to have one result type");
const auto &SrcRCDstRCPair =