aboutsummaryrefslogtreecommitdiffstats
path: root/utils/TableGen/DAGISelMatcherEmitter.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-02-21 03:22:59 +0000
committerChris Lattner <sabre@nondot.org>2010-02-21 03:22:59 +0000
commit8e946bea146c15333ce5f9f1b7a9efe5e75fd892 (patch)
tree7e76ff9ee8246e7a5a55eff25928f2330d118478 /utils/TableGen/DAGISelMatcherEmitter.cpp
parenta170b5e818bef4841084297960334eaea64e7081 (diff)
downloadexternal_llvm-8e946bea146c15333ce5f9f1b7a9efe5e75fd892.zip
external_llvm-8e946bea146c15333ce5f9f1b7a9efe5e75fd892.tar.gz
external_llvm-8e946bea146c15333ce5f9f1b7a9efe5e75fd892.tar.bz2
Lots of improvements to the new dagisel emitter. This gets it to
the point where it is to the 95% feature complete mark, it just needs result updating to be done (then testing, optimization etc). More specificallly, this adds support for chain and flag handling on the result nodes, support for sdnodexforms, support for variadic nodes, memrefs, pinned physreg inputs, and probably lots of other stuff. In the old DAGISelEmitter, this deletes the dead code related to OperatorMap, cleans up a variety of dead stuff handling "implicit remapping" from things like globaladdr -> targetglobaladdr (which is no longer used because globaladdr always needs to be legalized), and some minor formatting fixes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96716 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils/TableGen/DAGISelMatcherEmitter.cpp')
-rw-r--r--utils/TableGen/DAGISelMatcherEmitter.cpp144
1 files changed, 126 insertions, 18 deletions
diff --git a/utils/TableGen/DAGISelMatcherEmitter.cpp b/utils/TableGen/DAGISelMatcherEmitter.cpp
index 4b16db3..077dd5d 100644
--- a/utils/TableGen/DAGISelMatcherEmitter.cpp
+++ b/utils/TableGen/DAGISelMatcherEmitter.cpp
@@ -13,6 +13,7 @@
#include "DAGISelMatcher.h"
#include "CodeGenDAGPatterns.h"
+#include "Record.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
@@ -39,7 +40,7 @@ static unsigned EmitInt(int64_t Val, formatted_raw_ostream &OS) {
unsigned BytesEmitted = 1;
OS << (int)(unsigned char)Val << ", ";
if (Val == int8_t(Val)) {
- OS << "\n";
+ OS << '\n';
return BytesEmitted;
}
@@ -47,20 +48,21 @@ static unsigned EmitInt(int64_t Val, formatted_raw_ostream &OS) {
++BytesEmitted;
if (Val != int16_t(Val)) {
- OS << (int)(unsigned char)(Val >> 16) << ','
- << (int)(unsigned char)(Val >> 24) << ',';
+ OS << (int)(unsigned char)(Val >> 16) << ", "
+ << (int)(unsigned char)(Val >> 24) << ", ";
BytesEmitted += 2;
if (Val != int32_t(Val)) {
- OS << (int)(unsigned char)(Val >> 32) << ','
- << (int)(unsigned char)(Val >> 40) << ','
- << (int)(unsigned char)(Val >> 48) << ','
- << (int)(unsigned char)(Val >> 56) << ',';
+ OS << (int)(unsigned char)(Val >> 32) << ", "
+ << (int)(unsigned char)(Val >> 40) << ", "
+ << (int)(unsigned char)(Val >> 48) << ", "
+ << (int)(unsigned char)(Val >> 56) << ", ";
BytesEmitted += 4;
}
}
- OS.PadToColumn(CommentIndent) << "// " << Val << '\n';
+ OS.PadToColumn(CommentIndent) << "// " << Val << " aka 0x";
+ OS.write_hex(Val) << '\n';
return BytesEmitted;
}
@@ -73,6 +75,11 @@ class MatcherTableEmitter {
DenseMap<const ComplexPattern*, unsigned> ComplexPatternMap;
std::vector<const ComplexPattern*> ComplexPatterns;
+
+
+ DenseMap<Record*, unsigned> NodeXFormMap;
+ std::vector<const Record*> NodeXForms;
+
public:
MatcherTableEmitter(formatted_raw_ostream &os) : OS(os) {}
@@ -107,6 +114,16 @@ private:
}
return Entry-1;
}
+
+ unsigned getNodeXFormID(Record *Rec) {
+ unsigned &Entry = NodeXFormMap[Rec];
+ if (Entry == 0) {
+ NodeXForms.push_back(Rec);
+ Entry = NodeXForms.size();
+ }
+ return Entry-1;
+ }
+
};
} // end anonymous namespace.
@@ -118,18 +135,20 @@ EmitMatcher(const MatcherNode *N, unsigned Indent) {
switch (N->getKind()) {
case MatcherNode::Push: assert(0 && "Should be handled by caller");
- case MatcherNode::EmitNode:
- OS << "// Src: "
- << *cast<EmitNodeMatcherNode>(N)->getPattern().getSrcPattern() << '\n';
- OS.PadToColumn(Indent*2) << "// Dst: "
- << *cast<EmitNodeMatcherNode>(N)->getPattern().getDstPattern() << "\n";
- OS.PadToColumn(Indent*2) << "OPC_Emit, /*XXX*/\n\n";
- return 1;
case MatcherNode::RecordNode:
OS << "OPC_RecordNode,";
OS.PadToColumn(CommentIndent) << "// "
<< cast<RecordMatcherNode>(N)->getWhatFor() << '\n';
return 1;
+
+ case MatcherNode::RecordMemRef:
+ OS << "OPC_RecordMemRef,\n";
+ return 1;
+
+ case MatcherNode::CaptureFlagInput:
+ OS << "OPC_CaptureFlagInput,\n";
+ return 1;
+
case MatcherNode::MoveChild:
OS << "OPC_MoveChild, "
<< cast<MoveChildMatcherNode>(N)->getChildNo() << ",\n";
@@ -219,6 +238,14 @@ EmitMatcher(const MatcherNode *N, unsigned Indent) {
<< getEnumName(cast<EmitIntegerMatcherNode>(N)->getVT()) << ", ";
return EmitInt(Val, OS)+2;
}
+ case MatcherNode::EmitStringInteger: {
+ const std::string &Val = cast<EmitStringIntegerMatcherNode>(N)->getValue();
+ // These should always fit into one byte.
+ OS << "OPC_EmitInteger1, "
+ << getEnumName(cast<EmitStringIntegerMatcherNode>(N)->getVT()) << ", "
+ << Val << ",\n";
+ return 3;
+ }
case MatcherNode::EmitRegister:
OS << "OPC_EmitRegister, "
@@ -228,6 +255,62 @@ EmitMatcher(const MatcherNode *N, unsigned Indent) {
else
OS << "0 /*zero_reg*/,\n";
return 3;
+
+ case MatcherNode::EmitConvertToTarget:
+ OS << "OPC_EmitConvertToTarget, "
+ << cast<EmitConvertToTargetMatcherNode>(N)->getSlot() << ",\n";
+ return 2;
+
+ case MatcherNode::EmitMergeInputChains: {
+ const EmitMergeInputChainsMatcherNode *MN =
+ cast<EmitMergeInputChainsMatcherNode>(N);
+ OS << "OPC_EmitMergeInputChains, " << MN->getNumNodes() << ", ";
+ for (unsigned i = 0, e = MN->getNumNodes(); i != e; ++i)
+ OS << MN->getNode(i) << ", ";
+ OS << '\n';
+ return 2+MN->getNumNodes();
+ }
+ case MatcherNode::EmitCopyToReg:
+ OS << "OPC_EmitCopyToReg, "
+ << cast<EmitCopyToRegMatcherNode>(N)->getSrcSlot() << ", "
+ << getQualifiedName(cast<EmitCopyToRegMatcherNode>(N)->getDestPhysReg())
+ << ",\n";
+ return 3;
+ case MatcherNode::EmitNodeXForm: {
+ const EmitNodeXFormMatcherNode *XF = cast<EmitNodeXFormMatcherNode>(N);
+ OS << "OPC_EmitNodeXForm, " << getNodeXFormID(XF->getNodeXForm()) << ", "
+ << XF->getSlot() << ',';
+ OS.PadToColumn(CommentIndent) << "// "<<XF->getNodeXForm()->getName()<<'\n';
+ return 3;
+ }
+
+ case MatcherNode::EmitNode: {
+ const EmitNodeMatcherNode *EN = cast<EmitNodeMatcherNode>(N);
+ OS << "OPC_EmitNode, TARGET_OPCODE(" << EN->getOpcodeName() << "), 0";
+
+ if (EN->hasChain()) OS << "|OPFL_Chain";
+ if (EN->hasFlag()) OS << "|OPFL_Flag";
+ if (EN->hasMemRefs()) OS << "|OPFL_MemRefs";
+ if (EN->getNumFixedArityOperands() != -1)
+ OS << "|OPFL_Variadic" << EN->getNumFixedArityOperands();
+ OS << ",\n";
+
+ OS.PadToColumn(Indent*2+4) << EN->getNumVTs() << "/*#VTs*/, ";
+ for (unsigned i = 0, e = EN->getNumVTs(); i != e; ++i)
+ OS << getEnumName(EN->getVT(i)) << ", ";
+
+ OS << EN->getNumOperands() << "/*#Ops*/, ";
+ for (unsigned i = 0, e = EN->getNumOperands(); i != e; ++i)
+ OS << EN->getOperand(i) << ", ";
+ OS << '\n';
+ return 5+EN->getNumVTs()+EN->getNumOperands();
+ }
+ case MatcherNode::PatternMarker:
+ OS << "// Src: "
+ << *cast<PatternMarkerMatcherNode>(N)->getPattern().getSrcPattern() << '\n';
+ OS.PadToColumn(Indent*2) << "// Dst: "
+ << *cast<PatternMarkerMatcherNode>(N)->getPattern().getDstPattern() << '\n';
+ return 0;
}
assert(0 && "Unreachable");
return 0;
@@ -255,7 +338,7 @@ EmitMatcherList(const MatcherNode *N, unsigned Indent) {
if (NextSize > 255) {
errs() <<
"Tblgen internal error: can't handle predicate this complex yet\n";
- exit(1);
+ // FIXME: exit(1);
}
OS.PadToColumn(Indent*2);
@@ -300,6 +383,7 @@ void MatcherTableEmitter::EmitPredicateFunctions() {
OS << "}\n\n";
// Emit CompletePattern matchers.
+ // FIXME: This should be const.
OS << "bool CheckComplexPattern(SDNode *Root, SDValue N,\n";
OS << " unsigned PatternNo, SmallVectorImpl<SDValue> &Result) {\n";
OS << " switch (PatternNo) {\n";
@@ -307,17 +391,38 @@ void MatcherTableEmitter::EmitPredicateFunctions() {
for (unsigned i = 0, e = ComplexPatterns.size(); i != e; ++i) {
const ComplexPattern &P = *ComplexPatterns[i];
unsigned NumOps = P.getNumOperands();
+
if (P.hasProperty(SDNPHasChain))
- NumOps += 2; // Input and output chains.
+ ++NumOps; // Get the chained node too.
+
OS << " case " << i << ":\n";
OS << " Result.resize(Result.size()+" << NumOps << ");\n";
- OS << " return " << P.getSelectFunc() << "(Root, N";
+ OS << " return " << P.getSelectFunc();
+
+ // FIXME: Temporary hack until old isel dies.
+ if (P.hasProperty(SDNPHasChain))
+ OS << "XXX";
+
+ OS << "(Root, N";
for (unsigned i = 0; i != NumOps; ++i)
OS << ", Result[Result.size()-" << (NumOps-i) << ']';
OS << ");\n";
}
OS << " }\n";
OS << "}\n\n";
+
+ // Emit SDNodeXForm handlers.
+ // FIXME: This should be const.
+ OS << "SDValue RunSDNodeXForm(SDValue V, unsigned XFormNo) {\n";
+ OS << " switch (XFormNo) {\n";
+ OS << " default: assert(0 && \"Invalid xform # in table?\");\n";
+
+ // FIXME: The node xform could take SDValue's instead of SDNode*'s.
+ for (unsigned i = 0, e = NodeXForms.size(); i != e; ++i)
+ OS << " case " << i << ": return Transform_" << NodeXForms[i]->getName()
+ << "(V.getNode());\n";
+ OS << " }\n";
+ OS << "}\n\n";
}
@@ -329,9 +434,12 @@ void llvm::EmitMatcherTable(const MatcherNode *Matcher, raw_ostream &O) {
MatcherTableEmitter MatcherEmitter(OS);
+ OS << " // Opcodes are emitted as 2 bytes, TARGET_OPCODE handles this.\n";
+ OS << " #define TARGET_OPCODE(X) X & 255, unsigned(X) >> 8\n";
OS << " static const unsigned char MatcherTable[] = {\n";
unsigned TotalSize = MatcherEmitter.EmitMatcherList(Matcher, 2);
OS << " 0\n }; // Total Array size is " << (TotalSize+1) << " bytes\n\n";
+ OS << " #undef TARGET_OPCODE\n";
OS << " return SelectCodeCommon(N, MatcherTable,sizeof(MatcherTable));\n}\n";
OS << "\n";