aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-09-13 21:51:00 +0000
committerChris Lattner <sabre@nondot.org>2005-09-13 21:51:00 +0000
commit24eeeb8c3e80e22cb2fd311580ae22b5e3ae7b51 (patch)
tree5244cc8cf6342deee48e5d4fed4d1b69e69f4e41
parent8f493130bb51dea34c49e08aeab161e6a32dfdc6 (diff)
downloadexternal_llvm-24eeeb8c3e80e22cb2fd311580ae22b5e3ae7b51.zip
external_llvm-24eeeb8c3e80e22cb2fd311580ae22b5e3ae7b51.tar.gz
external_llvm-24eeeb8c3e80e22cb2fd311580ae22b5e3ae7b51.tar.bz2
Start parsing node transformation information
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23337 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--utils/TableGen/DAGISelEmitter.cpp43
-rw-r--r--utils/TableGen/DAGISelEmitter.h9
2 files changed, 46 insertions, 6 deletions
diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp
index 4d32af9..af9dc95 100644
--- a/utils/TableGen/DAGISelEmitter.cpp
+++ b/utils/TableGen/DAGISelEmitter.cpp
@@ -202,7 +202,9 @@ void TreePatternNode::print(std::ostream &OS) const {
}
if (!PredicateFn.empty())
- OS << "<<" << PredicateFn << ">>";
+ OS << "<<P:" << PredicateFn << ">>";
+ if (!TransformFn.empty())
+ OS << "<<X:" << TransformFn << ">>";
if (!getName().empty())
OS << ":$" << getName();
@@ -227,6 +229,7 @@ TreePatternNode *TreePatternNode::clone() const {
New->setName(getName());
New->setType(getType());
New->setPredicateFn(getPredicateFn());
+ New->setTransformFn(getTransformFn());
return New;
}
@@ -494,6 +497,35 @@ void DAGISelEmitter::ParseNodeInfo() {
}
}
+/// ParseNodeTransforms - Parse all SDNodeXForm instances into the SDNodeXForms
+/// map, and emit them to the file as functions.
+void DAGISelEmitter::ParseNodeTransforms(std::ostream &OS) {
+ OS << "\n// Node transformations.\n";
+ std::vector<Record*> Xforms = Records.getAllDerivedDefinitions("SDNodeXForm");
+ while (!Xforms.empty()) {
+ Record *XFormNode = Xforms.back();
+ Record *SDNode = XFormNode->getValueAsDef("Opcode");
+ std::string Code = XFormNode->getValueAsCode("XFormFunction");
+ SDNodeXForms.insert(std::make_pair(XFormNode,
+ std::make_pair(SDNode, Code)));
+
+ if (!Code.empty()) {
+ std::string ClassName = getSDNodeInfo(SDNode).getSDClassName();
+ const char *C2 = ClassName == "SDNode" ? "N" : "inN";
+
+ OS << "static inline SDOperand Transform_" << XFormNode->getName()
+ << "(SDNode *" << C2 << ") {\n";
+ if (ClassName != "SDNode")
+ OS << " " << ClassName << " *N = cast<" << ClassName << ">(inN);\n";
+ OS << Code << "\n}\n";
+ }
+
+ Xforms.pop_back();
+ }
+}
+
+
+
/// ParseAndResolvePatternFragments - Parse all of the PatFrag definitions in
/// the .td file, building up the PatternFragments map. After we've collected
/// them all, inline fragments together as necessary, so that there are no
@@ -546,9 +578,8 @@ void DAGISelEmitter::ParseAndResolvePatternFragments(std::ostream &OS) {
// If there is a code init for this fragment, emit the predicate code and
// keep track of the fact that this fragment uses it.
- CodeInit *CI =
- dynamic_cast<CodeInit*>(Fragments[i]->getValueInit("Predicate"));
- if (!CI->getValue().empty()) {
+ std::string Code = Fragments[i]->getValueAsCode("Predicate");
+ if (!Code.empty()) {
assert(!P->getOnlyTree()->isLeaf() && "Can't be a leaf!");
std::string ClassName =
getSDNodeInfo(P->getOnlyTree()->getOperator()).getSDClassName();
@@ -558,7 +589,7 @@ void DAGISelEmitter::ParseAndResolvePatternFragments(std::ostream &OS) {
<< "(SDNode *" << C2 << ") {\n";
if (ClassName != "SDNode")
OS << " " << ClassName << " *N = cast<" << ClassName << ">(inN);\n";
- OS << CI->getValue() << "\n}\n";
+ OS << Code << "\n}\n";
P->getOnlyTree()->setPredicateFn("Predicate_"+Fragments[i]->getName());
}
}
@@ -657,12 +688,12 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
<< "}\n";
}
-
void DAGISelEmitter::run(std::ostream &OS) {
EmitSourceFileHeader("DAG Instruction Selector for the " + Target.getName() +
" target", OS);
ParseNodeInfo();
+ ParseNodeTransforms(OS);
ParseAndResolvePatternFragments(OS);
ParseAndResolveInstructions();
diff --git a/utils/TableGen/DAGISelEmitter.h b/utils/TableGen/DAGISelEmitter.h
index 6e39a5f..d160522 100644
--- a/utils/TableGen/DAGISelEmitter.h
+++ b/utils/TableGen/DAGISelEmitter.h
@@ -120,6 +120,10 @@ namespace llvm {
/// for a match. If this string is empty, no predicate is involved.
std::string PredicateFn;
+ /// TransformFn - The transformation function to execute on this node before
+ /// it can be substituted into the resulting instruction on a pattern match.
+ std::string TransformFn;
+
std::vector<TreePatternNode*> Children;
public:
TreePatternNode(Record *Op, const std::vector<TreePatternNode*> &Ch)
@@ -147,6 +151,9 @@ namespace llvm {
const std::string &getPredicateFn() const { return PredicateFn; }
void setPredicateFn(const std::string &Fn) { PredicateFn = Fn; }
+
+ const std::string &getTransformFn() const { return TransformFn; }
+ void setTransformFn(const std::string &Fn) { TransformFn = Fn; }
void print(std::ostream &OS) const;
void dump() const;
@@ -276,6 +283,7 @@ class DAGISelEmitter : public TableGenBackend {
CodeGenTarget Target;
std::map<Record*, SDNodeInfo> SDNodes;
+ std::map<Record*, std::pair<Record*, std::string> > SDNodeXForms;
std::map<Record*, TreePattern*> PatternFragments;
std::vector<TreePattern*> Instructions;
public:
@@ -296,6 +304,7 @@ public:
private:
void ParseNodeInfo();
+ void ParseNodeTransforms(std::ostream &OS);
void ParseAndResolvePatternFragments(std::ostream &OS);
void ParseAndResolveInstructions();
void EmitInstructionSelector(std::ostream &OS);