From ddb395463c08b39090bbee4ed22433f5990a6331 Mon Sep 17 00:00:00 2001 From: Nate Begeman Date: Thu, 1 Dec 2005 00:06:14 +0000 Subject: [PATCH] Stop checking the ValueType of the CodeGenInstruction. Instead, use the ValueType from the RegisterClass or Operands. This step is necessary to allow RegisterClasses to have multiple ValueTypes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24555 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/CodeGenTarget.h | 9 +++++ utils/TableGen/DAGISelEmitter.cpp | 55 ++++++++++++++++++++++--------- utils/TableGen/DAGISelEmitter.h | 26 +++++++-------- 3 files changed, 62 insertions(+), 28 deletions(-) diff --git a/utils/TableGen/CodeGenTarget.h b/utils/TableGen/CodeGenTarget.h index aaa6c7a426f..ba538245c6f 100644 --- a/utils/TableGen/CodeGenTarget.h +++ b/utils/TableGen/CodeGenTarget.h @@ -81,6 +81,15 @@ public: if (RegisterClasses.empty()) ReadRegisterClasses(); return RegisterClasses; } + + const CodeGenRegisterClass &getRegisterClass(Record *R) const { + const std::vector &RC = getRegisterClasses(); + for (unsigned i = 0, e = RC.size(); i != e; ++i) + if (RC[i].TheDef == R) + return RC[i]; + assert(0 && "Didn't find the register class"); + abort(); + } const std::vector &getLegalValueTypes() const { if (LegalValueTypes.empty()) ReadLegalValueTypes(); diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp index 6a14685a308..d7d8fd8b956 100644 --- a/utils/TableGen/DAGISelEmitter.cpp +++ b/utils/TableGen/DAGISelEmitter.cpp @@ -531,14 +531,34 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { assert(Inst.getNumResults() == 1 && "Only supports one result instrs!"); // Apply the result type to the node - bool MadeChange = UpdateNodeType(Inst.getResultType(0), TP); + Record *ResultNode = Inst.getResult(0); + assert(ResultNode->isSubClassOf("RegisterClass") && + "Operands should be register classes!"); + + const CodeGenRegisterClass &RC = + TP.getDAGISelEmitter().getTargetInfo().getRegisterClass(ResultNode); + + bool MadeChange = UpdateNodeType(RC.VT, TP); if (getNumChildren() != Inst.getNumOperands()) TP.error("Instruction '" + getOperator()->getName() + " expects " + utostr(Inst.getNumOperands()) + " operands, not " + utostr(getNumChildren()) + " operands!"); for (unsigned i = 0, e = getNumChildren(); i != e; ++i) { - MadeChange |= getChild(i)->UpdateNodeType(Inst.getOperandType(i), TP); + Record *OperandNode = Inst.getOperand(i); + MVT::ValueType VT; + if (OperandNode->isSubClassOf("RegisterClass")) { + const CodeGenRegisterClass &RC = + TP.getDAGISelEmitter().getTargetInfo().getRegisterClass(OperandNode); + VT = RC.VT; + } else if (OperandNode->isSubClassOf("Operand")) { + VT = getValueType(OperandNode->getValueAsDef("Type")); + } else { + assert(0 && "Unknown operand type!"); + abort(); + } + + MadeChange |= getChild(i)->UpdateNodeType(VT, TP); MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters); } return MadeChange; @@ -1021,8 +1041,8 @@ void DAGISelEmitter::ParseInstructions() { // instruction for its operand list. We have to assume that there is one // result, as we have no detailed info. if (!LI || LI->getSize() == 0) { - std::vector ResultTypes; - std::vector OperandTypes; + std::vector Results; + std::vector Operands; CodeGenInstruction &InstInfo =Target.getInstruction(Instrs[i]->getName()); @@ -1031,15 +1051,15 @@ void DAGISelEmitter::ParseInstructions() { continue; // Assume the first operand is the result. - ResultTypes.push_back(InstInfo.OperandList[0].Ty); + Results.push_back(InstInfo.OperandList[0].Rec); // The rest are inputs. for (unsigned j = 1, e = InstInfo.OperandList.size(); j != e; ++j) - OperandTypes.push_back(InstInfo.OperandList[j].Ty); + Operands.push_back(InstInfo.OperandList[j].Rec); // Create and insert the instruction. Instructions.insert(std::make_pair(Instrs[i], - DAGInstruction(0, ResultTypes, OperandTypes))); + DAGInstruction(0, Results, Operands))); continue; // no pattern. } @@ -1086,7 +1106,7 @@ void DAGISelEmitter::ParseInstructions() { CodeGenInstruction &CGI = Target.getInstruction(Instrs[i]->getName()); // Check that all of the results occur first in the list. - std::vector ResultTypes; + std::vector Results; for (unsigned i = 0; i != NumResults; ++i) { if (i == CGI.OperandList.size()) I->error("'" + InstResults.begin()->first + @@ -1103,7 +1123,7 @@ void DAGISelEmitter::ParseInstructions() { I->error("Operand $" + OpName + " class mismatch!"); // Remember the return type. - ResultTypes.push_back(CGI.OperandList[i].Ty); + Results.push_back(CGI.OperandList[i].Rec); // Okay, this one checks out. InstResults.erase(OpName); @@ -1114,7 +1134,7 @@ void DAGISelEmitter::ParseInstructions() { std::map InstInputsCheck(InstInputs); std::vector ResultNodeOperands; - std::vector OperandTypes; + std::vector Operands; for (unsigned i = NumResults, e = CGI.OperandList.size(); i != e; ++i) { const std::string &OpName = CGI.OperandList[i].Name; if (OpName.empty()) @@ -1125,10 +1145,15 @@ void DAGISelEmitter::ParseInstructions() { " does not appear in the instruction pattern"); TreePatternNode *InVal = InstInputsCheck[OpName]; InstInputsCheck.erase(OpName); // It occurred, remove from map. - if (CGI.OperandList[i].Ty != InVal->getExtType()) - I->error("Operand $" + OpName + - "'s type disagrees between the operand and pattern"); - OperandTypes.push_back(InVal->getType()); + + if (InVal->isLeaf() && + dynamic_cast(InVal->getLeafValue())) { + Record *InRec = static_cast(InVal->getLeafValue())->getDef(); + if (CGI.OperandList[i].Rec != InRec) + I->error("Operand $" + OpName + + "'s register class disagrees between the operand and pattern"); + } + Operands.push_back(CGI.OperandList[i].Rec); // Construct the result for the dest-pattern operand list. TreePatternNode *OpNode = InVal->clone(); @@ -1155,7 +1180,7 @@ void DAGISelEmitter::ParseInstructions() { new TreePatternNode(I->getRecord(), ResultNodeOperands); // Create and insert the instruction. - DAGInstruction TheInst(I, ResultTypes, OperandTypes); + DAGInstruction TheInst(I, Results, Operands); Instructions.insert(std::make_pair(I->getRecord(), TheInst)); // Use a temporary tree pattern to infer all types and make sure that the diff --git a/utils/TableGen/DAGISelEmitter.h b/utils/TableGen/DAGISelEmitter.h index be307141d82..404b00b5223 100644 --- a/utils/TableGen/DAGISelEmitter.h +++ b/utils/TableGen/DAGISelEmitter.h @@ -326,30 +326,30 @@ namespace llvm { TreePattern *Pattern; unsigned NumResults; unsigned NumOperands; - std::vector ResultTypes; - std::vector OperandTypes; + std::vector Results; + std::vector Operands; TreePatternNode *ResultPattern; public: DAGInstruction(TreePattern *TP, - const std::vector &resultTypes, - const std::vector &operandTypes) - : Pattern(TP), ResultTypes(resultTypes), OperandTypes(operandTypes), + const std::vector &results, + const std::vector &operands) + : Pattern(TP), Results(results), Operands(operands), ResultPattern(0) {} TreePattern *getPattern() const { return Pattern; } - unsigned getNumResults() const { return ResultTypes.size(); } - unsigned getNumOperands() const { return OperandTypes.size(); } + unsigned getNumResults() const { return Results.size(); } + unsigned getNumOperands() const { return Operands.size(); } void setResultPattern(TreePatternNode *R) { ResultPattern = R; } - MVT::ValueType getResultType(unsigned RN) const { - assert(RN < ResultTypes.size()); - return ResultTypes[RN]; + Record *getResult(unsigned RN) const { + assert(RN < Results.size()); + return Results[RN]; } - MVT::ValueType getOperandType(unsigned ON) const { - assert(ON < OperandTypes.size()); - return OperandTypes[ON]; + Record *getOperand(unsigned ON) const { + assert(ON < Operands.size()); + return Operands[ON]; } TreePatternNode *getResultPattern() const { return ResultPattern; } };