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
This commit is contained in:
Nate Begeman 2005-12-01 00:06:14 +00:00
parent 8ef9d16d39
commit ddb395463c
3 changed files with 62 additions and 28 deletions

View File

@ -81,6 +81,15 @@ public:
if (RegisterClasses.empty()) ReadRegisterClasses(); if (RegisterClasses.empty()) ReadRegisterClasses();
return RegisterClasses; return RegisterClasses;
} }
const CodeGenRegisterClass &getRegisterClass(Record *R) const {
const std::vector<CodeGenRegisterClass> &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<MVT::ValueType> &getLegalValueTypes() const { const std::vector<MVT::ValueType> &getLegalValueTypes() const {
if (LegalValueTypes.empty()) ReadLegalValueTypes(); if (LegalValueTypes.empty()) ReadLegalValueTypes();

View File

@ -531,14 +531,34 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
assert(Inst.getNumResults() == 1 && "Only supports one result instrs!"); assert(Inst.getNumResults() == 1 && "Only supports one result instrs!");
// Apply the result type to the node // 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()) if (getNumChildren() != Inst.getNumOperands())
TP.error("Instruction '" + getOperator()->getName() + " expects " + TP.error("Instruction '" + getOperator()->getName() + " expects " +
utostr(Inst.getNumOperands()) + " operands, not " + utostr(Inst.getNumOperands()) + " operands, not " +
utostr(getNumChildren()) + " operands!"); utostr(getNumChildren()) + " operands!");
for (unsigned i = 0, e = getNumChildren(); i != e; ++i) { 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); MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
} }
return MadeChange; return MadeChange;
@ -1021,8 +1041,8 @@ void DAGISelEmitter::ParseInstructions() {
// instruction for its operand list. We have to assume that there is one // instruction for its operand list. We have to assume that there is one
// result, as we have no detailed info. // result, as we have no detailed info.
if (!LI || LI->getSize() == 0) { if (!LI || LI->getSize() == 0) {
std::vector<MVT::ValueType> ResultTypes; std::vector<Record*> Results;
std::vector<MVT::ValueType> OperandTypes; std::vector<Record*> Operands;
CodeGenInstruction &InstInfo =Target.getInstruction(Instrs[i]->getName()); CodeGenInstruction &InstInfo =Target.getInstruction(Instrs[i]->getName());
@ -1031,15 +1051,15 @@ void DAGISelEmitter::ParseInstructions() {
continue; continue;
// Assume the first operand is the result. // 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. // The rest are inputs.
for (unsigned j = 1, e = InstInfo.OperandList.size(); j != e; ++j) 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. // Create and insert the instruction.
Instructions.insert(std::make_pair(Instrs[i], Instructions.insert(std::make_pair(Instrs[i],
DAGInstruction(0, ResultTypes, OperandTypes))); DAGInstruction(0, Results, Operands)));
continue; // no pattern. continue; // no pattern.
} }
@ -1086,7 +1106,7 @@ void DAGISelEmitter::ParseInstructions() {
CodeGenInstruction &CGI = Target.getInstruction(Instrs[i]->getName()); CodeGenInstruction &CGI = Target.getInstruction(Instrs[i]->getName());
// Check that all of the results occur first in the list. // Check that all of the results occur first in the list.
std::vector<MVT::ValueType> ResultTypes; std::vector<Record*> Results;
for (unsigned i = 0; i != NumResults; ++i) { for (unsigned i = 0; i != NumResults; ++i) {
if (i == CGI.OperandList.size()) if (i == CGI.OperandList.size())
I->error("'" + InstResults.begin()->first + I->error("'" + InstResults.begin()->first +
@ -1103,7 +1123,7 @@ void DAGISelEmitter::ParseInstructions() {
I->error("Operand $" + OpName + " class mismatch!"); I->error("Operand $" + OpName + " class mismatch!");
// Remember the return type. // Remember the return type.
ResultTypes.push_back(CGI.OperandList[i].Ty); Results.push_back(CGI.OperandList[i].Rec);
// Okay, this one checks out. // Okay, this one checks out.
InstResults.erase(OpName); InstResults.erase(OpName);
@ -1114,7 +1134,7 @@ void DAGISelEmitter::ParseInstructions() {
std::map<std::string, TreePatternNode*> InstInputsCheck(InstInputs); std::map<std::string, TreePatternNode*> InstInputsCheck(InstInputs);
std::vector<TreePatternNode*> ResultNodeOperands; std::vector<TreePatternNode*> ResultNodeOperands;
std::vector<MVT::ValueType> OperandTypes; std::vector<Record*> Operands;
for (unsigned i = NumResults, e = CGI.OperandList.size(); i != e; ++i) { for (unsigned i = NumResults, e = CGI.OperandList.size(); i != e; ++i) {
const std::string &OpName = CGI.OperandList[i].Name; const std::string &OpName = CGI.OperandList[i].Name;
if (OpName.empty()) if (OpName.empty())
@ -1125,10 +1145,15 @@ void DAGISelEmitter::ParseInstructions() {
" does not appear in the instruction pattern"); " does not appear in the instruction pattern");
TreePatternNode *InVal = InstInputsCheck[OpName]; TreePatternNode *InVal = InstInputsCheck[OpName];
InstInputsCheck.erase(OpName); // It occurred, remove from map. InstInputsCheck.erase(OpName); // It occurred, remove from map.
if (CGI.OperandList[i].Ty != InVal->getExtType())
I->error("Operand $" + OpName + if (InVal->isLeaf() &&
"'s type disagrees between the operand and pattern"); dynamic_cast<DefInit*>(InVal->getLeafValue())) {
OperandTypes.push_back(InVal->getType()); Record *InRec = static_cast<DefInit*>(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. // Construct the result for the dest-pattern operand list.
TreePatternNode *OpNode = InVal->clone(); TreePatternNode *OpNode = InVal->clone();
@ -1155,7 +1180,7 @@ void DAGISelEmitter::ParseInstructions() {
new TreePatternNode(I->getRecord(), ResultNodeOperands); new TreePatternNode(I->getRecord(), ResultNodeOperands);
// Create and insert the instruction. // Create and insert the instruction.
DAGInstruction TheInst(I, ResultTypes, OperandTypes); DAGInstruction TheInst(I, Results, Operands);
Instructions.insert(std::make_pair(I->getRecord(), TheInst)); Instructions.insert(std::make_pair(I->getRecord(), TheInst));
// Use a temporary tree pattern to infer all types and make sure that the // Use a temporary tree pattern to infer all types and make sure that the

View File

@ -326,30 +326,30 @@ namespace llvm {
TreePattern *Pattern; TreePattern *Pattern;
unsigned NumResults; unsigned NumResults;
unsigned NumOperands; unsigned NumOperands;
std::vector<MVT::ValueType> ResultTypes; std::vector<Record*> Results;
std::vector<MVT::ValueType> OperandTypes; std::vector<Record*> Operands;
TreePatternNode *ResultPattern; TreePatternNode *ResultPattern;
public: public:
DAGInstruction(TreePattern *TP, DAGInstruction(TreePattern *TP,
const std::vector<MVT::ValueType> &resultTypes, const std::vector<Record*> &results,
const std::vector<MVT::ValueType> &operandTypes) const std::vector<Record*> &operands)
: Pattern(TP), ResultTypes(resultTypes), OperandTypes(operandTypes), : Pattern(TP), Results(results), Operands(operands),
ResultPattern(0) {} ResultPattern(0) {}
TreePattern *getPattern() const { return Pattern; } TreePattern *getPattern() const { return Pattern; }
unsigned getNumResults() const { return ResultTypes.size(); } unsigned getNumResults() const { return Results.size(); }
unsigned getNumOperands() const { return OperandTypes.size(); } unsigned getNumOperands() const { return Operands.size(); }
void setResultPattern(TreePatternNode *R) { ResultPattern = R; } void setResultPattern(TreePatternNode *R) { ResultPattern = R; }
MVT::ValueType getResultType(unsigned RN) const { Record *getResult(unsigned RN) const {
assert(RN < ResultTypes.size()); assert(RN < Results.size());
return ResultTypes[RN]; return Results[RN];
} }
MVT::ValueType getOperandType(unsigned ON) const { Record *getOperand(unsigned ON) const {
assert(ON < OperandTypes.size()); assert(ON < Operands.size());
return OperandTypes[ON]; return Operands[ON];
} }
TreePatternNode *getResultPattern() const { return ResultPattern; } TreePatternNode *getResultPattern() const { return ResultPattern; }
}; };