diff --git a/llvm/utils/TableGen/DAGISelEmitter.cpp b/llvm/utils/TableGen/DAGISelEmitter.cpp index 4d32af93ff0c..af9dc95e97ca 100644 --- a/llvm/utils/TableGen/DAGISelEmitter.cpp +++ b/llvm/utils/TableGen/DAGISelEmitter.cpp @@ -202,7 +202,9 @@ void TreePatternNode::print(std::ostream &OS) const { } if (!PredicateFn.empty()) - OS << "<<" << PredicateFn << ">>"; + OS << "<>"; + if (!TransformFn.empty()) + OS << "<>"; 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 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(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/llvm/utils/TableGen/DAGISelEmitter.h b/llvm/utils/TableGen/DAGISelEmitter.h index 6e39a5ff0e7c..d16052286791 100644 --- a/llvm/utils/TableGen/DAGISelEmitter.h +++ b/llvm/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 Children; public: TreePatternNode(Record *Op, const std::vector &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 SDNodes; + std::map > SDNodeXForms; std::map PatternFragments; std::vector 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);