forked from OSchip/llvm-project
[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:
parent
c00e44656d
commit
1b465767d6
File diff suppressed because it is too large
Load Diff
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 =
|
||||
|
|
Loading…
Reference in New Issue