[TableGen] Make TreePatternNode::getChild return a reference (NFC)

The return value of TreePatternNode::getChild is never null. This patch also
updates various places that use return values of getChild to also use
references. Those changes were suggested post-commit for D47463.

llvm-svn: 334764
This commit is contained in:
Florian Hahn 2018-06-14 20:23:48 +00:00
parent c00e44656d
commit 1b465767d6
6 changed files with 502 additions and 503 deletions

File diff suppressed because it is too large Load Diff

View File

@ -392,7 +392,7 @@ struct SDTypeConstraint {
/// 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;
};
@ -437,7 +437,7 @@ public:
/// 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
@ -626,7 +626,8 @@ public:
Record *getOperator() const { assert(!isLeaf()); return Operator; }
unsigned getNumChildren() const { return Children.size(); }
TreePatternNode *getChild(unsigned N) const { return Children[N].get(); }
const TreePatternNode &getChild(unsigned N) const { return *Children[N]; }
TreePatternNode &getChild(unsigned N) { return *Children[N]; }
const TreePatternNodePtr &getChildShared(unsigned N) const {
return Children[N];
}
@ -705,7 +706,7 @@ public: // Higher level manipulation routines.
/// 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
@ -871,7 +872,7 @@ public:
private:
TreePatternNodePtr ParseTreePattern(Init *DI, StringRef OpName);
void ComputeNamedNodes();
void ComputeNamedNodes(TreePatternNode *N);
void ComputeNamedNodes(const TreePatternNodePtr &N);
};
@ -1193,14 +1194,14 @@ private:
void AddPatternToMatch(TreePattern *Pattern, PatternToMatch &&PTM);
void FindPatternInputsAndOutputs(
TreePattern &I, TreePatternNodePtr Pat,
TreePattern &I, const 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)

View File

@ -38,36 +38,36 @@ public:
/// 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(TreePatternNode *P,
static unsigned getResultPatternCost(const 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(TreePatternNode *P,
static unsigned getResultPatternSize(const 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;
}
@ -100,13 +100,13 @@ struct PatternSortingPredicate {
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;

View File

@ -110,11 +110,11 @@ namespace {
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
@ -132,17 +132,17 @@ namespace {
/// 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);
};
@ -204,15 +204,15 @@ void MatcherGen::AddMatcher(Matcher *NewNode) {
//===----------------------------------------------------------------------===//
/// 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));
}
@ -221,14 +221,14 @@ void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) {
}
// 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();
}
@ -238,7 +238,7 @@ void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) {
// 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()));
@ -268,48 +268,48 @@ void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) {
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
@ -321,27 +321,27 @@ void MatcherGen::EmitOperatorMatchCode(const TreePatternNode *N,
// 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;
}
@ -353,15 +353,15 @@ void MatcherGen::EmitOperatorMatchCode(const TreePatternNode *N,
// 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.
@ -393,10 +393,10 @@ void MatcherGen::EmitOperatorMatchCode(const TreePatternNode *N,
// 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
@ -420,27 +420,27 @@ void MatcherGen::EmitOperatorMatchCode(const TreePatternNode *N,
}
// 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());
}
}
@ -462,38 +462,38 @@ bool MatcherGen::recordUniqueNode(const std::string &Name) {
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]));
}
@ -517,7 +517,7 @@ bool MatcherGen::EmitMatcherCode(unsigned Variant) {
}
// Emit the matcher for the pattern structure and types.
EmitMatchCode(Pattern.getSrcPattern(), PatWithNoTypes.get(),
EmitMatchCode(*Pattern.getSrcPattern(), *PatWithNoTypes,
Pattern.ForceMode);
// If the pattern has a predicate on it (e.g. only enabled when a subtarget
@ -538,8 +538,8 @@ bool MatcherGen::EmitMatcherCode(unsigned Variant) {
} 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);
}
}
@ -579,26 +579,26 @@ bool MatcherGen::EmitMatcherCode(unsigned Variant) {
// 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++);
@ -606,33 +606,33 @@ void MatcherGen::EmitResultOfNamedOperand(const TreePatternNode *N,
}
}
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;
}
@ -658,47 +658,47 @@ void MatcherGen::EmitResultLeafAsOperand(const TreePatternNode *N,
}
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;
@ -706,16 +706,16 @@ numNodesThatMayLoadOrStore(const TreePatternNode *N,
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);
@ -739,7 +739,7 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
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;
@ -781,7 +781,7 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
const DAGDefaultOperand &DefaultOp
= CGP.getDefaultOperand(OperandNode);
for (unsigned i = 0, e = DefaultOp.DefaultOps.size(); i != e; ++i)
EmitResultOperand(DefaultOp.DefaultOps[i].get(), InstOps);
EmitResultOperand(*DefaultOp.DefaultOps[i], InstOps);
continue;
}
@ -800,14 +800,14 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
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;
@ -820,8 +820,8 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
// 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
@ -842,8 +842,8 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
// 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:
@ -884,7 +884,7 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
bool NodeHasMemRefs = false;
if (PatternHasMemOperands) {
unsigned NumNodesThatLoadOrStore =
numNodesThatMayLoadOrStore(Pattern.getDstPattern(), CGP);
numNodesThatMayLoadOrStore(*Pattern.getDstPattern(), CGP);
bool NodeIsUniqueLoadOrStore = mayInstNodeLoadOrStore(N, CGP) &&
NumNodesThatLoadOrStore == 1;
NodeHasMemRefs =
@ -909,9 +909,9 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
}
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;
@ -919,31 +919,31 @@ EmitResultSDNodeXFormAsOperand(const TreePatternNode *N,
// 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!");
}
@ -956,7 +956,7 @@ void MatcherGen::EmitResultCode() {
// 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

View File

@ -204,18 +204,17 @@ struct OperandsSignature {
const CodeGenRegisterClass *DstRC = nullptr;
for (unsigned i = 0, e = InstPatNode->getNumChildren(); i != e; ++i) {
TreePatternNode *Op = InstPatNode->getChild(i);
const 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
@ -235,11 +234,11 @@ struct OperandsSignature {
// 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;
}
@ -247,15 +246,15 @@ struct OperandsSignature {
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();
@ -426,14 +425,14 @@ static std::string getLegalCName(std::string OpName) {
FastISelMap::FastISelMap(StringRef instns) : InstNS(instns) {}
static std::string PhyRegForNode(TreePatternNode *Op,
static std::string PhyRegForNode(const 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;
@ -473,10 +472,10 @@ void FastISelMap::collectPatterns(CodeGenDAGPatterns &CGP) {
// For now, ignore multi-instruction patterns.
bool MultiInsts = false;
for (unsigned i = 0, e = Dst->getNumChildren(); i != e; ++i) {
TreePatternNode *ChildOp = Dst->getChild(i);
if (ChildOp->isLeaf())
const TreePatternNode &ChildOp = Dst->getChild(i);
if (ChildOp.isLeaf())
continue;
if (ChildOp->getOperator()->isSubClassOf("Instruction")) {
if (ChildOp.getOperator()->isSubClassOf("Instruction")) {
MultiInsts = true;
break;
}
@ -500,13 +499,13 @@ void FastISelMap::collectPatterns(CodeGenDAGPatterns &CGP) {
} 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.
@ -523,8 +522,8 @@ void FastISelMap::collectPatterns(CodeGenDAGPatterns &CGP) {
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.
@ -550,8 +549,8 @@ void FastISelMap::collectPatterns(CodeGenDAGPatterns &CGP) {
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;
}

View File

@ -195,10 +195,10 @@ static Optional<LLTCodeGen> MVTToLLT(MVT::SimpleValueType SVT) {
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 = ", ";
@ -277,12 +277,12 @@ static Error failedImport(const Twine &Reason) {
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;
@ -2956,37 +2956,37 @@ private:
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,
TreePatternNode *DstChild);
const TreePatternNode &DstChild);
Error importDefaultOperandRenderers(BuildMIAction &DstMIBuilder,
DagInit *DefaultOps) const;
Error
@ -3073,8 +3073,8 @@ Record *GlobalISelEmitter::findNodeEquiv(Record *N) const {
}
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"));
@ -3106,16 +3106,16 @@ GlobalISelEmitter::importRulePredicates(RuleMatcher &M,
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")));
@ -3123,10 +3123,10 @@ Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher(
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
@ -3134,7 +3134,7 @@ Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher(
}
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);
@ -3143,7 +3143,7 @@ Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher(
" for result of Src pattern operator");
}
for (const auto &Predicate : Src->getPredicateFns()) {
for (const auto &Predicate : Src.getPredicateFns()) {
if (Predicate.isAlwaysTrue())
continue;
@ -3257,11 +3257,11 @@ Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher(
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(
@ -3279,8 +3279,8 @@ Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher(
}
// Match the used operands (i.e. the children of the operator).
for (unsigned i = 0, e = Src->getNumChildren(); i != e; ++i) {
TreePatternNode *SrcChild = Src->getChild(i);
for (unsigned i = 0, e = Src.getNumChildren(); i != e; ++i) {
const 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.
@ -3292,9 +3292,9 @@ Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher(
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;
}
@ -3326,23 +3326,23 @@ Error GlobalISelEmitter::importComplexPatternOperandMatcher(
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();
@ -3353,32 +3353,32 @@ Error GlobalISelEmitter::importChildMatcher(RuleMatcher &Rule,
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) {
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) {
const 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
@ -3396,17 +3396,17 @@ Error GlobalISelEmitter::importChildMatcher(RuleMatcher &Rule,
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.
@ -3442,35 +3442,35 @@ Error GlobalISelEmitter::importChildMatcher(RuleMatcher &Rule,
Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderer(
action_iterator InsertPt, RuleMatcher &Rule, BuildMIAction &DstMIBuilder,
TreePatternNode *DstChild) {
const 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")) {
auto Child = DstChild->getChild(0);
auto I = SDNodeXFormEquivs.find(DstChild->getOperator());
if (DstChild.getOperator()->isSubClassOf("SDNodeXForm")) {
const 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;
}
}
@ -3479,17 +3479,17 @@ Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderer(
// 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");
@ -3512,22 +3512,22 @@ Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderer(
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");
@ -3548,11 +3548,11 @@ Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderer(
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;
}
@ -3562,9 +3562,9 @@ Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderer(
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;
}
@ -3577,7 +3577,7 @@ Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderer(
}
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);
@ -3596,7 +3596,7 @@ Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer(
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);
@ -3622,8 +3622,8 @@ GlobalISelEmitter::createAndImportSubInstructionRenderer(
}
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(
@ -3656,18 +3656,18 @@ void GlobalISelEmitter::importExplicitDefRenderers(
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");
@ -3683,7 +3683,7 @@ Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderers(
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;
}
@ -3693,7 +3693,7 @@ Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderers(
// 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--;
@ -3719,7 +3719,7 @@ Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderers(
}
auto InsertPtOrError = importExplicitUseRenderer(InsertPt, M, DstMIBuilder,
Dst->getChild(Child));
Dst.getChild(Child));
if (auto Error = InsertPtOrError.takeError())
return std::move(Error);
InsertPt = InsertPtOrError.get();
@ -3785,8 +3785,8 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
return std::move(Error);
// Next, analyze the pattern operators.
TreePatternNode *Src = P.getSrcPattern();
TreePatternNode *Dst = P.getDstPattern();
const TreePatternNode &Src = *P.getSrcPattern();
const TreePatternNode &Dst = *P.getDstPattern();
// If the root of either pattern isn't a simple operator, ignore it.
if (auto Err = isTrivialOperatorNode(Dst))
@ -3817,7 +3817,7 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
// 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);
@ -3825,8 +3825,8 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
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) {
@ -3844,7 +3844,7 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
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
@ -3857,37 +3857,37 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
}
// 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(
@ -3895,8 +3895,7 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
} 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);
@ -3924,7 +3923,7 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
// 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");
@ -3943,16 +3942,16 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
// 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");
@ -3966,7 +3965,7 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
//
// 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 =