From 66a48bbc3565b40ea0e6f2d58cf5e3a8e64802ef Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Thu, 1 Dec 2005 00:18:45 +0000 Subject: [PATCH] Teach tblgen to accept register source operands in patterns, e.g. def SHL8rCL : I<0xD2, MRM4r, (ops R8 :$dst, R8 :$src), "shl{b} {%cl, $dst|$dst, %CL}", [(set R8:$dst, (shl R8:$src, CL))]>, Imp<[CL],[]>; This generates a CopyToReg operand and added its 2nd result to the shl as a flag operand. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24557 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/SelectionDAG.h | 14 ++++++ utils/TableGen/DAGISelEmitter.cpp | 72 ++++++++++++++++++++++++++--- utils/TableGen/DAGISelEmitter.h | 5 +- 3 files changed, 83 insertions(+), 8 deletions(-) diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index 5f7d2d72499..546b990eb91 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -143,6 +143,20 @@ public: if (Flag.Val) Ops.push_back(Flag); return getNode(ISD::CopyToReg, VTs, Ops); } + + // Similar to last getCopyToReg() except parameter Reg is a SDOperand + SDOperand getCopyToReg(SDOperand Chain, SDOperand Reg, SDOperand N, + SDOperand Flag) { + std::vector VTs; + VTs.push_back(MVT::Other); + VTs.push_back(MVT::Flag); + std::vector Ops; + Ops.push_back(Chain); + Ops.push_back(Reg); + Ops.push_back(N); + if (Flag.Val) Ops.push_back(Flag); + return getNode(ISD::CopyToReg, VTs, Ops); + } SDOperand getCopyFromReg(SDOperand Chain, unsigned Reg, MVT::ValueType VT) { std::vector ResultTys; diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp index d7d8fd8b956..4b40561b268 100644 --- a/utils/TableGen/DAGISelEmitter.cpp +++ b/utils/TableGen/DAGISelEmitter.cpp @@ -1574,7 +1574,7 @@ struct PatternSortingPredicate { /// matches, and the SDNode for the result has the RootName specified name. void DAGISelEmitter::EmitMatchForPattern(TreePatternNode *N, const std::string &RootName, - std::map &VarMap, + std::map &VarMap, unsigned PatternNo, std::ostream &OS) { if (N->isLeaf()) { if (IntInit *II = dynamic_cast(N->getLeafValue())) { @@ -1637,7 +1637,8 @@ void DAGISelEmitter::EmitMatchForPattern(TreePatternNode *N, // Handle leaves of various types. if (DefInit *DI = dynamic_cast(Child->getLeafValue())) { Record *LeafRec = DI->getDef(); - if (LeafRec->isSubClassOf("RegisterClass")) { + if (LeafRec->isSubClassOf("RegisterClass") || + LeafRec->isSubClassOf("Register")) { // Handle register references. Nothing to do here. } else if (LeafRec->isSubClassOf("ValueType")) { // Make sure this is the specified value type. @@ -1671,12 +1672,60 @@ void DAGISelEmitter::EmitMatchForPattern(TreePatternNode *N, << ".Val)) goto P" << PatternNo << "Fail;\n"; } +/// getRegisterValueType - Look up and return ValueType of specified record +static MVT::ValueType getRegisterValueType(Record *R, const CodeGenTarget &T) { + const std::vector &RegisterClasses = + T.getRegisterClasses(); + + for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) { + const CodeGenRegisterClass &RC = RegisterClasses[i]; + for (unsigned ei = 0, ee = RC.Elements.size(); ei != ee; ++ei) { + if (R == RC.Elements[ei]) { + return RC.VT; + } + } + } + + return MVT::Other; +} + + +/// EmitCopyToRegsForPattern - Emit the flag operands for the DAG that will be +/// built in CodeGenPatternResult. +void DAGISelEmitter::EmitCopyToRegsForPattern(TreePatternNode *N, + const std::string &RootName, + std::ostream &OS, bool &InFlag) { + const CodeGenTarget &T = getTargetInfo(); + for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) { + TreePatternNode *Child = N->getChild(i); + if (!Child->isLeaf()) { + EmitCopyToRegsForPattern(Child, RootName + utostr(i), OS, InFlag); + } else { + if (DefInit *DI = dynamic_cast(Child->getLeafValue())) { + Record *RR = DI->getDef(); + if (RR->isSubClassOf("Register")) { + MVT::ValueType RVT = getRegisterValueType(RR, T); + if (!InFlag) { + OS << " SDOperand InFlag; // Null incoming flag value.\n"; + InFlag = true; + } + OS << " InFlag = CurDAG->getCopyToReg(CurDAG->getEntryNode()" + << ", CurDAG->getRegister(" << getQualifiedName(RR) + << ", MVT::" << getEnumName(RVT) << ")" + << ", " << RootName << i << ", InFlag).getValue(1);\n"; + + } + } + } + } +} + /// CodeGenPatternResult - Emit the action for a pattern. Now that it has /// matched, we actually have to build a DAG! unsigned DAGISelEmitter:: CodeGenPatternResult(TreePatternNode *N, unsigned &Ctr, std::map &VariableMap, - std::ostream &OS, bool isRoot) { + std::ostream &OS, bool InFlag, bool isRoot) { // This is something selected from the pattern we matched. if (!N->getName().empty()) { assert(!isRoot && "Root of pattern cannot be a leaf!"); @@ -1742,7 +1791,8 @@ CodeGenPatternResult(TreePatternNode *N, unsigned &Ctr, // Emit all of the operands. std::vector Ops; for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) - Ops.push_back(CodeGenPatternResult(N->getChild(i), Ctr, VariableMap, OS)); + Ops.push_back(CodeGenPatternResult(N->getChild(i), + Ctr, VariableMap, OS, InFlag)); CodeGenInstruction &II = Target.getInstruction(Op->getName()); unsigned ResNo = Ctr++; @@ -1763,6 +1813,8 @@ CodeGenPatternResult(TreePatternNode *N, unsigned &Ctr, << getEnumName(N->getType()); for (unsigned i = 0, e = Ops.size(); i != e; ++i) OS << ", Tmp" << Ops[i]; + if (InFlag) + OS << ", InFlag"; OS << ");\n"; OS << " } else {\n"; OS << " return CodeGenMap[N] = CurDAG->getTargetNode(" @@ -1770,13 +1822,16 @@ CodeGenPatternResult(TreePatternNode *N, unsigned &Ctr, << getEnumName(N->getType()); for (unsigned i = 0, e = Ops.size(); i != e; ++i) OS << ", Tmp" << Ops[i]; + if (InFlag) + OS << ", InFlag"; OS << ");\n"; OS << " }\n"; } return ResNo; } else if (Op->isSubClassOf("SDNodeXForm")) { assert(N->getNumChildren() == 1 && "node xform should have one child!"); - unsigned OpVal = CodeGenPatternResult(N->getChild(0), Ctr, VariableMap, OS); + unsigned OpVal = CodeGenPatternResult(N->getChild(0), + Ctr, VariableMap, OS, InFlag); unsigned ResNo = Ctr++; OS << " SDOperand Tmp" << ResNo << " = Transform_" << Op->getName() @@ -1886,10 +1941,13 @@ void DAGISelEmitter::EmitCodeForPattern(PatternToMatch &Pattern, // an unresolved type to add a check for, this returns true and we iterate, // otherwise we are done. } while (InsertOneTypeCheck(Pat, Pattern.first, "N", PatternNo, OS)); + + bool InFlag = false; + EmitCopyToRegsForPattern(Pattern.first, "N", OS, InFlag); unsigned TmpNo = 0; - CodeGenPatternResult(Pattern.second, TmpNo, - VariableMap, OS, true /*the root*/); + CodeGenPatternResult(Pattern.second, + TmpNo, VariableMap, OS, InFlag, true /*the root*/); delete Pat; OS << " }\n P" << PatternNo << "Fail:\n"; diff --git a/utils/TableGen/DAGISelEmitter.h b/utils/TableGen/DAGISelEmitter.h index 404b00b5223..ed1e97804cd 100644 --- a/utils/TableGen/DAGISelEmitter.h +++ b/utils/TableGen/DAGISelEmitter.h @@ -418,9 +418,12 @@ private: void EmitMatchForPattern(TreePatternNode *N, const std::string &RootName, std::map &VarMap, unsigned PatternNo, std::ostream &OS); + void EmitCopyToRegsForPattern(TreePatternNode *N, const std::string &RootName, + std::ostream &OS, bool &InFlag); unsigned CodeGenPatternResult(TreePatternNode *N, unsigned &Ctr, std::map &VariableMap, - std::ostream &OS, bool isRoot = false); + std::ostream &OS, bool InFlag, + bool isRoot = false); void EmitCodeForPattern(PatternToMatch &Pattern, std::ostream &OS); void EmitInstructionSelector(std::ostream &OS); };