diff options
Diffstat (limited to 'utils/TableGen')
-rw-r--r-- | utils/TableGen/DAGISelEmitter.cpp | 43 | ||||
-rw-r--r-- | utils/TableGen/DAGISelEmitter.h | 9 |
2 files changed, 49 insertions, 3 deletions
diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp index 4aa6f7f..8dd9eba 100644 --- a/utils/TableGen/DAGISelEmitter.cpp +++ b/utils/TableGen/DAGISelEmitter.cpp @@ -691,6 +691,25 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters); } return MadeChange; + } else if (getOperator()->isSubClassOf("Intrinsic")) { + const CodeGenIntrinsic &Int = + TP.getDAGISelEmitter().getIntrinsic(getOperator()); + // FIXME: get type information! + bool MadeChange = false; + + // Apply the result type to the node. + MadeChange = UpdateNodeType(Int.ArgVTs[0], TP); + + if (getNumChildren() != Int.ArgVTs.size()-1) + TP.error("Intrinsic '" + getOperator()->getName() + " expects " + + utostr(Int.ArgVTs.size()-1) + " operands, not " + + utostr(getNumChildren()) + " operands!"); + for (unsigned i = 0, e = getNumChildren(); i != e; ++i) { + MVT::ValueType OpVT = Int.ArgVTs[i+1]; + MadeChange |= getChild(i)->UpdateNodeType(OpVT, TP); + MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters); + } + return MadeChange; } else { assert(getOperator()->isSubClassOf("SDNodeXForm") && "Unknown node type!"); @@ -723,6 +742,13 @@ bool TreePatternNode::canPatternMatch(std::string &Reason, DAGISelEmitter &ISE){ if (!getChild(i)->canPatternMatch(Reason, ISE)) return false; + // If this is an intrinsic, handle cases that would make it not match. For + // example, if an operand is required to be an immediate. + if (getOperator()->isSubClassOf("Intrinsic")) { + // TODO: + return true; + } + // If this node is a commutative operator, check that the LHS isn't an // immediate. const SDNodeInfo &NodeInfo = ISE.getSDNodeInfo(getOperator()); @@ -811,6 +837,7 @@ TreePatternNode *TreePattern::ParseTreePattern(DagInit *Dag) { if (!Operator->isSubClassOf("PatFrag") && !Operator->isSubClassOf("SDNode") && !Operator->isSubClassOf("Instruction") && !Operator->isSubClassOf("SDNodeXForm") && + !Operator->isSubClassOf("Intrinsic") && Operator->getName() != "set") error("Unrecognized node '" + Operator->getName() + "'!"); @@ -1592,10 +1619,13 @@ static void GenerateVariantsOf(TreePatternNode *N, } // Look up interesting info about the node. - const SDNodeInfo &NodeInfo = ISE.getSDNodeInfo(N->getOperator()); + const SDNodeInfo *NodeInfo = 0; + + if (!N->getOperator()->isSubClassOf("Intrinsic")) + NodeInfo = &ISE.getSDNodeInfo(N->getOperator()); // If this node is associative, reassociate. - if (NodeInfo.hasProperty(SDNodeInfo::SDNPAssociative)) { + if (NodeInfo && NodeInfo->hasProperty(SDNodeInfo::SDNPAssociative)) { // Reassociate by pulling together all of the linked operators std::vector<TreePatternNode*> MaximalChildren; GatherChildrenOfAssociativeOpcode(N, MaximalChildren); @@ -1656,7 +1686,7 @@ static void GenerateVariantsOf(TreePatternNode *N, CombineChildVariants(N, ChildVariants, OutVariants, ISE); // If this node is commutative, consider the commuted order. - if (NodeInfo.hasProperty(SDNodeInfo::SDNPCommutative)) { + if (NodeInfo && NodeInfo->hasProperty(SDNodeInfo::SDNPCommutative)) { assert(N->getNumChildren()==2 &&"Commutative but doesn't have 2 children!"); // Consider the commuted order. CombineChildVariants(N, ChildVariants[1], ChildVariants[0], @@ -2955,6 +2985,9 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) { for (std::map<Record*, std::vector<PatternToMatch*>, CompareByRecordName>::iterator PBOI = PatternsByOpcode.begin(), E = PatternsByOpcode.end(); PBOI != E; ++PBOI) { + if (PBOI->first->isSubClassOf("Intrinsic")) + continue; // Skip intrinsics here. + const std::string &OpName = PBOI->first->getName(); OS << "void Select_" << OpName << "(SDOperand &Result, SDOperand N) {\n"; @@ -3201,6 +3234,9 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) { for (std::map<Record*, std::vector<PatternToMatch*>, CompareByRecordName>::iterator PBOI = PatternsByOpcode.begin(), E = PatternsByOpcode.end(); PBOI != E; ++PBOI) { + if (PBOI->first->isSubClassOf("Intrinsic")) + continue; + const SDNodeInfo &OpcodeInfo = getSDNodeInfo(PBOI->first); OS << " case " << OpcodeInfo.getEnumName() << ": " << std::string(std::max(0, int(24-OpcodeInfo.getEnumName().size())), ' ') @@ -3363,6 +3399,7 @@ void DAGISelEmitter::run(std::ostream &OS) { OS << " return ResNode;\n"; OS << "}\n"; + Intrinsics = LoadIntrinsics(Records); ParseNodeInfo(); ParseNodeTransforms(OS); ParseComplexPatterns(); diff --git a/utils/TableGen/DAGISelEmitter.h b/utils/TableGen/DAGISelEmitter.h index 35606f7..10b997d 100644 --- a/utils/TableGen/DAGISelEmitter.h +++ b/utils/TableGen/DAGISelEmitter.h @@ -16,6 +16,7 @@ #include "TableGenBackend.h" #include "CodeGenTarget.h" +#include "CodeGenIntrinsics.h" #include <set> namespace llvm { @@ -412,6 +413,7 @@ class DAGISelEmitter : public TableGenBackend { private: RecordKeeper &Records; CodeGenTarget Target; + std::vector<CodeGenIntrinsic> Intrinsics; std::map<Record*, SDNodeInfo> SDNodes; std::map<Record*, std::pair<Record*, std::string> > SDNodeXForms; @@ -448,6 +450,13 @@ public: return ComplexPatterns.find(R)->second; } + const CodeGenIntrinsic &getIntrinsic(Record *R) const { + for (unsigned i = 0, e = Intrinsics.size(); i != e; ++i) + if (Intrinsics[i].TheDef == R) return Intrinsics[i]; + assert(0 && "Unknown intrinsic!"); + abort(); + } + TreePattern *getPatternFragment(Record *R) const { assert(PatternFragments.count(R) && "Invalid pattern fragment request!"); return PatternFragments.find(R)->second; |