summaryrefslogtreecommitdiff
path: root/utils/TableGen/DAGISelMatcherGen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/TableGen/DAGISelMatcherGen.cpp')
-rw-r--r--utils/TableGen/DAGISelMatcherGen.cpp141
1 files changed, 84 insertions, 57 deletions
diff --git a/utils/TableGen/DAGISelMatcherGen.cpp b/utils/TableGen/DAGISelMatcherGen.cpp
index ed41631456b0..97e37ba68952 100644
--- a/utils/TableGen/DAGISelMatcherGen.cpp
+++ b/utils/TableGen/DAGISelMatcherGen.cpp
@@ -62,6 +62,13 @@ namespace {
/// insertion easier.
StringMap<unsigned> VariableMap;
+ /// This maintains the recorded operand number that OPC_CheckComplexPattern
+ /// drops each sub-operand into. We don't want to insert these into
+ /// VariableMap because that leads to identity checking if they are
+ /// encountered multiple times. Biased by 1 like VariableMap for
+ /// consistency.
+ StringMap<unsigned> NamedComplexPatternOperands;
+
/// NextRecordedOperandNo - As we emit opcodes to record matched values in
/// the RecordedNodes array, this keeps track of which slot will be next to
/// record into.
@@ -76,10 +83,8 @@ namespace {
SmallVector<unsigned, 2> MatchedGlueResultNodes;
/// MatchedComplexPatterns - This maintains a list of all of the
- /// ComplexPatterns that we need to check. The patterns are known to have
- /// names which were recorded. The second element of each pair is the first
- /// slot number that the OPC_CheckComplexPat opcode drops the matched
- /// results into.
+ /// ComplexPatterns that we need to check. The second element of each pair
+ /// is the recorded operand number of the input node.
SmallVector<std::pair<const TreePatternNode*,
unsigned>, 2> MatchedComplexPatterns;
@@ -115,6 +120,11 @@ namespace {
void EmitOperatorMatchCode(const TreePatternNode *N,
TreePatternNode *NodeNoTypes);
+ /// If this is the first time a node with unique identifier Name has been
+ /// seen, record it. Otherwise, emit a check to make sure this is the same
+ /// node. Returns true if this is the first encounter.
+ bool recordUniqueNode(std::string Name);
+
// Result Code Generation.
unsigned getNamedArgumentSlot(StringRef Name) {
unsigned VarMapEntry = VariableMap[Name];
@@ -144,7 +154,7 @@ namespace {
MatcherGen::MatcherGen(const PatternToMatch &pattern,
const CodeGenDAGPatterns &cgp)
: Pattern(pattern), CGP(cgp), NextRecordedOperandNo(0),
- TheMatcher(0), CurPredicate(0) {
+ TheMatcher(nullptr), CurPredicate(nullptr) {
// We need to produce the matcher tree for the patterns source pattern. To do
// this we need to match the structure as well as the types. To do the type
// matching, we want to figure out the fewest number of type checks we need to
@@ -182,7 +192,7 @@ void MatcherGen::InferPossibleTypes() {
/// AddMatcher - Add a matcher node to the current graph we're building.
void MatcherGen::AddMatcher(Matcher *NewNode) {
- if (CurPredicate != 0)
+ if (CurPredicate)
CurPredicate->setNext(NewNode);
else
TheMatcher = NewNode;
@@ -218,7 +228,7 @@ void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) {
}
DefInit *DI = dyn_cast<DefInit>(N->getLeafValue());
- if (DI == 0) {
+ if (!DI) {
errs() << "Unknown leaf kind: " << *N << "\n";
abort();
}
@@ -266,7 +276,8 @@ void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) {
// Remember this ComplexPattern so that we can emit it after all the other
// structural matches are done.
- MatchedComplexPatterns.push_back(std::make_pair(N, 0));
+ unsigned InputOperand = VariableMap[N->getName()] - 1;
+ MatchedComplexPatterns.push_back(std::make_pair(N, InputOperand));
return;
}
@@ -277,6 +288,25 @@ void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) {
void MatcherGen::EmitOperatorMatchCode(const TreePatternNode *N,
TreePatternNode *NodeNoTypes) {
assert(!N->isLeaf() && "Not an operator?");
+
+ 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) {
+ PatternName += ":";
+ PatternName += N->getChild(i)->getName();
+ }
+
+ if (recordUniqueNode(PatternName)) {
+ auto NodeAndOpNum = std::make_pair(N, NextRecordedOperandNo - 1);
+ MatchedComplexPatterns.push_back(NodeAndOpNum);
+ }
+
+ return;
+ }
+
const SDNodeInfo &CInfo = CGP.getSDNodeInfo(N->getOperator());
// If this is an 'and R, 1234' where the operation is AND/OR and the RHS is
@@ -415,11 +445,27 @@ void MatcherGen::EmitOperatorMatchCode(const TreePatternNode *N,
}
}
+bool MatcherGen::recordUniqueNode(std::string Name) {
+ unsigned &VarMapEntry = VariableMap[Name];
+ if (VarMapEntry == 0) {
+ // If it is a named node, we must emit a 'Record' opcode.
+ AddMatcher(new RecordMatcher("$" + Name, NextRecordedOperandNo));
+ VarMapEntry = ++NextRecordedOperandNo;
+ return true;
+ }
+
+ // If we get here, this is a second reference to a specific name. Since
+ // we already have checked that the first reference is valid, we don't
+ // have to recursively match it, just check that it's the same as the
+ // previously named thing.
+ AddMatcher(new CheckSameMatcher(VarMapEntry-1));
+ return false;
+}
void MatcherGen::EmitMatchCode(const TreePatternNode *N,
TreePatternNode *NodeNoTypes) {
// 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 tyep to NodeNoTypes and
+ // need to do a type check. Emit the check, apply the type to NodeNoTypes and
// reinfer any correlated types.
SmallVector<unsigned, 2> ResultsToTypeCheck;
@@ -432,21 +478,9 @@ void MatcherGen::EmitMatchCode(const TreePatternNode *N,
// 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()) {
- unsigned &VarMapEntry = VariableMap[N->getName()];
- if (VarMapEntry == 0) {
- // If it is a named node, we must emit a 'Record' opcode.
- AddMatcher(new RecordMatcher("$" + N->getName(), NextRecordedOperandNo));
- VarMapEntry = ++NextRecordedOperandNo;
- } else {
- // If we get here, this is a second reference to a specific name. Since
- // we already have checked that the first reference is valid, we don't
- // have to recursively match it, just check that it's the same as the
- // previously named thing.
- AddMatcher(new CheckSameMatcher(VarMapEntry-1));
+ if (!N->getName().empty())
+ if (!recordUniqueNode(N->getName()))
return;
- }
- }
if (N->isLeaf())
EmitLeafMatchCode(N);
@@ -497,16 +531,20 @@ bool MatcherGen::EmitMatcherCode(unsigned Variant) {
const TreePatternNode *N = MatchedComplexPatterns[i].first;
// Remember where the results of this match get stuck.
- MatchedComplexPatterns[i].second = NextRecordedOperandNo;
+ if (N->isLeaf()) {
+ NamedComplexPatternOperands[N->getName()] = NextRecordedOperandNo + 1;
+ } 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);
+ }
+ }
// Get the slot we recorded the value in from the name on the node.
- unsigned RecNodeEntry = VariableMap[N->getName()];
- assert(!N->getName().empty() && RecNodeEntry &&
- "Complex pattern should have a name and slot");
- --RecNodeEntry; // Entries in VariableMap are biased.
+ unsigned RecNodeEntry = MatchedComplexPatterns[i].second;
- const ComplexPattern &CP =
- CGP.getComplexPattern(((DefInit*)N->getLeafValue())->getDef());
+ const ComplexPattern &CP = *N->getComplexPatternInfo(CGP);
// Emit a CheckComplexPat operation, which does the match (aborting if it
// fails) and pushes the matched operands onto the recorded nodes list.
@@ -543,21 +581,12 @@ void MatcherGen::EmitResultOfNamedOperand(const TreePatternNode *N,
SmallVectorImpl<unsigned> &ResultOps){
assert(!N->getName().empty() && "Operand not named!");
- // A reference to a complex pattern gets all of the results of the complex
- // pattern's match.
- if (const ComplexPattern *CP = N->getComplexPatternInfo(CGP)) {
- unsigned SlotNo = 0;
- for (unsigned i = 0, e = MatchedComplexPatterns.size(); i != e; ++i)
- if (MatchedComplexPatterns[i].first->getName() == N->getName()) {
- SlotNo = MatchedComplexPatterns[i].second;
- break;
- }
- assert(SlotNo != 0 && "Didn't get a slot number assigned?");
+ 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)
+ ResultOps.push_back(SlotNo - 1 + i);
- // The first slot entry is the node itself, the subsequent entries are the
- // matched values.
- for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i)
- ResultOps.push_back(SlotNo+i);
return;
}
@@ -575,7 +604,8 @@ void MatcherGen::EmitResultOfNamedOperand(const TreePatternNode *N,
}
}
- ResultOps.push_back(SlotNo);
+ for (unsigned i = 0; i < N->getNumMIResults(CGP); ++i)
+ ResultOps.push_back(SlotNo + i);
}
void MatcherGen::EmitResultLeafAsOperand(const TreePatternNode *N,
@@ -600,7 +630,7 @@ void MatcherGen::EmitResultLeafAsOperand(const TreePatternNode *N,
}
if (Def->getName() == "zero_reg") {
- AddMatcher(new EmitRegisterMatcher(0, N->getType(0)));
+ AddMatcher(new EmitRegisterMatcher(nullptr, N->getType(0)));
ResultOps.push_back(NextRecordedOperandNo++);
return;
}
@@ -642,7 +672,7 @@ GetInstPatternNode(const DAGInstruction &Inst, const TreePatternNode *N) {
else if (/*isRoot*/ N == Pattern.getDstPattern())
InstPatNode = Pattern.getSrcPattern();
else
- return 0;
+ return nullptr;
if (InstPatNode && !InstPatNode->isLeaf() &&
InstPatNode->getOperator()->getName() == "set")
@@ -806,7 +836,7 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
if (isRoot && !Pattern.getDstRegs().empty()) {
// If the root came from an implicit def in the instruction handling stuff,
// don't re-add it.
- Record *HandledReg = 0;
+ Record *HandledReg = nullptr;
if (II.HasOneImplicitDefWithKnownVT(CGT) != MVT::Other)
HandledReg = II.ImplicitDefs[0];
@@ -850,8 +880,7 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
"Node has no result");
AddMatcher(new EmitNodeMatcher(II.Namespace+"::"+II.TheDef->getName(),
- ResultVTs.data(), ResultVTs.size(),
- InstOps.data(), InstOps.size(),
+ ResultVTs, InstOps,
NodeHasChain, TreeHasInGlue, TreeHasOutGlue,
NodeHasMemRefs, NumFixedArityOperands,
NextRecordedOperandNo));
@@ -907,8 +936,7 @@ void MatcherGen::EmitResultCode() {
// merge them together into a token factor. This informs the generated code
// what all the chained nodes are.
if (!MatchedChainNodes.empty())
- AddMatcher(new EmitMergeInputChainsMatcher
- (MatchedChainNodes.data(), MatchedChainNodes.size()));
+ AddMatcher(new EmitMergeInputChainsMatcher(MatchedChainNodes));
// Codegen the root of the result pattern, capturing the resulting values.
SmallVector<unsigned, 8> Ops;
@@ -926,7 +954,7 @@ void MatcherGen::EmitResultCode() {
if (!Pattern.getDstRegs().empty()) {
// If the root came from an implicit def in the instruction handling stuff,
// don't re-add it.
- Record *HandledReg = 0;
+ Record *HandledReg = nullptr;
const TreePatternNode *DstPat = Pattern.getDstPattern();
if (!DstPat->isLeaf() &&DstPat->getOperator()->isSubClassOf("Instruction")){
const CodeGenTarget &CGT = CGP.getTargetInfo();
@@ -949,10 +977,9 @@ void MatcherGen::EmitResultCode() {
// If the matched pattern covers nodes which define a glue result, emit a node
// that tells the matcher about them so that it can update their results.
if (!MatchedGlueResultNodes.empty())
- AddMatcher(new MarkGlueResultsMatcher(MatchedGlueResultNodes.data(),
- MatchedGlueResultNodes.size()));
+ AddMatcher(new MarkGlueResultsMatcher(MatchedGlueResultNodes));
- AddMatcher(new CompleteMatchMatcher(Ops.data(), Ops.size(), Pattern));
+ AddMatcher(new CompleteMatchMatcher(Ops, Pattern));
}
@@ -965,7 +992,7 @@ Matcher *llvm::ConvertPatternToMatcher(const PatternToMatch &Pattern,
// Generate the code for the matcher.
if (Gen.EmitMatcherCode(Variant))
- return 0;
+ return nullptr;
// FIXME2: Kill extra MoveParent commands at the end of the matcher sequence.
// FIXME2: Split result code out to another table, and make the matcher end