First steps to getting PredicateOperand's to work. This handles instruction

and pat pattern definitions.  Codegen is not right for them yet.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31444 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2006-11-04 01:35:50 +00:00
parent 5d52894783
commit dfdaeb276e

View File

@ -759,27 +759,40 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
MadeChange = UpdateNodeType(ConvertVTs(RC.getValueTypes()), TP); MadeChange = UpdateNodeType(ConvertVTs(RC.getValueTypes()), TP);
} }
if (getNumChildren() != Inst.getNumOperands()) unsigned ChildNo = 0;
TP.error("Instruction '" + getOperator()->getName() + " expects " + for (unsigned i = 0, e = Inst.getNumOperands(); i != e; ++i) {
utostr(Inst.getNumOperands()) + " operands, not " +
utostr(getNumChildren()) + " operands!");
for (unsigned i = 0, e = getNumChildren(); i != e; ++i) {
Record *OperandNode = Inst.getOperand(i); Record *OperandNode = Inst.getOperand(i);
// If the instruction expects a predicate operand, we codegen this by
// setting the predicate to it's "execute always" value.
if (OperandNode->isSubClassOf("PredicateOperand"))
continue;
// Verify that we didn't run out of provided operands.
if (ChildNo >= getNumChildren())
TP.error("Instruction '" + getOperator()->getName() +
"' expects more operands than were provided.");
MVT::ValueType VT; MVT::ValueType VT;
TreePatternNode *Child = getChild(ChildNo++);
if (OperandNode->isSubClassOf("RegisterClass")) { if (OperandNode->isSubClassOf("RegisterClass")) {
const CodeGenRegisterClass &RC = const CodeGenRegisterClass &RC =
ISE.getTargetInfo().getRegisterClass(OperandNode); ISE.getTargetInfo().getRegisterClass(OperandNode);
MadeChange |=getChild(i)->UpdateNodeType(ConvertVTs(RC.getValueTypes()), MadeChange |= Child->UpdateNodeType(ConvertVTs(RC.getValueTypes()), TP);
TP);
} else if (OperandNode->isSubClassOf("Operand")) { } else if (OperandNode->isSubClassOf("Operand")) {
VT = getValueType(OperandNode->getValueAsDef("Type")); VT = getValueType(OperandNode->getValueAsDef("Type"));
MadeChange |= getChild(i)->UpdateNodeType(VT, TP); MadeChange |= Child->UpdateNodeType(VT, TP);
} else { } else {
assert(0 && "Unknown operand type!"); assert(0 && "Unknown operand type!");
abort(); abort();
} }
MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters); MadeChange |= Child->ApplyTypeConstraints(TP, NotRegisters);
} }
if (ChildNo != getNumChildren())
TP.error("Instruction '" + getOperator()->getName() +
"' was provided too many operands!");
return MadeChange; return MadeChange;
} else { } else {
assert(getOperator()->isSubClassOf("SDNodeXForm") && "Unknown node type!"); assert(getOperator()->isSubClassOf("SDNodeXForm") && "Unknown node type!");
@ -1471,25 +1484,35 @@ void DAGISelEmitter::ParseInstructions() {
std::vector<TreePatternNode*> ResultNodeOperands; std::vector<TreePatternNode*> ResultNodeOperands;
std::vector<Record*> Operands; 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; CodeGenInstruction::OperandInfo &Op = CGI.OperandList[i];
const std::string &OpName = Op.Name;
if (OpName.empty()) if (OpName.empty())
I->error("Operand #" + utostr(i) + " in operands list has no name!"); I->error("Operand #" + utostr(i) + " in operands list has no name!");
if (!InstInputsCheck.count(OpName)) if (!InstInputsCheck.count(OpName)) {
// If this is an predicate operand with an ExecuteAlways set filled in,
// we can ignore this. When we codegen it, we will do so as always
// executed.
if (Op.Rec->isSubClassOf("PredicateOperand")) {
// Does it have a non-empty ExecuteAlways field? If so, ignore this
// operand.
if (Op.Rec->getValueAsDag("ExecuteAlways")->getNumArgs())
continue;
}
I->error("Operand $" + OpName + I->error("Operand $" + OpName +
" 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 (InVal->isLeaf() && if (InVal->isLeaf() &&
dynamic_cast<DefInit*>(InVal->getLeafValue())) { dynamic_cast<DefInit*>(InVal->getLeafValue())) {
Record *InRec = static_cast<DefInit*>(InVal->getLeafValue())->getDef(); Record *InRec = static_cast<DefInit*>(InVal->getLeafValue())->getDef();
if (CGI.OperandList[i].Rec != InRec && if (Op.Rec != InRec && !InRec->isSubClassOf("ComplexPattern"))
!InRec->isSubClassOf("ComplexPattern"))
I->error("Operand $" + OpName + "'s register class disagrees" I->error("Operand $" + OpName + "'s register class disagrees"
" between the operand and pattern"); " between the operand and pattern");
} }
Operands.push_back(CGI.OperandList[i].Rec); Operands.push_back(Op.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();