MadeChange = UpdateNodeType(ConvertVTs(RC.getValueTypes()), 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) {
+ unsigned ChildNo = 0;
+ for (unsigned i = 0, e = Inst.getNumOperands(); i != e; ++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;
+ TreePatternNode *Child = getChild(ChildNo++);
if (OperandNode->isSubClassOf("RegisterClass")) {
const CodeGenRegisterClass &RC =
ISE.getTargetInfo().getRegisterClass(OperandNode);
- MadeChange |=getChild(i)->UpdateNodeType(ConvertVTs(RC.getValueTypes()),
- TP);
+ MadeChange |= Child->UpdateNodeType(ConvertVTs(RC.getValueTypes()), TP);
} else if (OperandNode->isSubClassOf("Operand")) {
VT = getValueType(OperandNode->getValueAsDef("Type"));
- MadeChange |= getChild(i)->UpdateNodeType(VT, TP);
+ MadeChange |= Child->UpdateNodeType(VT, TP);
} else {
assert(0 && "Unknown operand type!");
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;
} else {
assert(getOperator()->isSubClassOf("SDNodeXForm") && "Unknown node type!");
std::vector<TreePatternNode*> ResultNodeOperands;
std::vector<Record*> Operands;
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())
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 +
" does not appear in the instruction pattern");
+ }
TreePatternNode *InVal = InstInputsCheck[OpName];
InstInputsCheck.erase(OpName); // It occurred, remove from map.
if (InVal->isLeaf() &&
dynamic_cast<DefInit*>(InVal->getLeafValue())) {
Record *InRec = static_cast<DefInit*>(InVal->getLeafValue())->getDef();
- if (CGI.OperandList[i].Rec != InRec &&
- !InRec->isSubClassOf("ComplexPattern"))
+ if (Op.Rec != InRec && !InRec->isSubClassOf("ComplexPattern"))
I->error("Operand $" + OpName + "'s register class disagrees"
" 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.
TreePatternNode *OpNode = InVal->clone();
/// if the match fails. At this point, we already know that the opcode for N
/// matches, and the SDNode for the result has the RootName specified name.
void EmitMatchCode(TreePatternNode *N, TreePatternNode *P,
- const std::string &RootName,
- const std::string &ChainSuffix, bool &FoundChain) {
+ const std::string &RootName, const std::string &ChainSuffix,
+ bool &FoundChain) {
bool isRoot = (P == NULL);
// Emit instruction predicates. Each predicate is just a string for now.
if (isRoot) {
unsigned OpNo = 0;
bool NodeHasChain = NodeHasProperty (N, SDNPHasChain, ISE);
bool HasChain = PatternHasProperty(N, SDNPHasChain, ISE);
- bool HasOutFlag = PatternHasProperty(N, SDNPOutFlag, ISE);
bool EmittedUseCheck = false;
if (HasChain) {
if (NodeHasChain)
OpNo = 1;
if (!isRoot) {
- const SDNodeInfo &CInfo = ISE.getSDNodeInfo(N->getOperator());
// Multiple uses of actual result?
emitCheck(RootName + ".hasOneUse()");
EmittedUseCheck = true;
// / [YY]
// | ^
// [XX]-------|
- const SDNodeInfo &PInfo = ISE.getSDNodeInfo(P->getOperator());
- if (PInfo.getNumOperands() > 1 ||
+ bool NeedCheck = false;
+ if (P != Pattern)
+ NeedCheck = true;
+ else {
+ const SDNodeInfo &PInfo = ISE.getSDNodeInfo(P->getOperator());
+ NeedCheck =
+ P->getOperator() == ISE.get_intrinsic_void_sdnode() ||
+ P->getOperator() == ISE.get_intrinsic_w_chain_sdnode() ||
+ P->getOperator() == ISE.get_intrinsic_wo_chain_sdnode() ||
+ PInfo.getNumOperands() > 1 ||
PInfo.hasProperty(SDNPHasChain) ||
PInfo.hasProperty(SDNPInFlag) ||
- PInfo.hasProperty(SDNPOptInFlag)) {
+ PInfo.hasProperty(SDNPOptInFlag);
+ }
+
+ if (NeedCheck) {
std::string ParentName(RootName.begin(), RootName.end()-1);
emitCheck("CanBeFoldedBy(" + RootName + ".Val, " + ParentName +
- ".Val)");
+ ".Val, N.Val)");
}
}
}
(PatternHasProperty(N, SDNPInFlag, ISE) ||
PatternHasProperty(N, SDNPOptInFlag, ISE) ||
PatternHasProperty(N, SDNPOutFlag, ISE))) {
- const SDNodeInfo &CInfo = ISE.getSDNodeInfo(N->getOperator());
if (!EmittedUseCheck) {
// Multiple uses of actual result?
emitCheck(RootName + ".hasOneUse()");
emitCode("SDOperand " + ChainName + ";");
}
- std::string Code = Fn + "(" + RootName;
+ std::string Code = Fn + "(";
+ if (CP->hasProperty(SDNPHasChain)) {
+ std::string ParentName(RootName.begin(), RootName.end()-1);
+ Code += "N, " + ParentName + ", ";
+ }
+ Code += RootName;
for (unsigned i = 0; i < NumOps; i++)
Code += ", CPTmp" + utostr(i);
if (CP->hasProperty(SDNPHasChain))
PatternsByOpcode[Node->getOperator()].push_back(&PatternsToMatch[i]);
} else {
const ComplexPattern *CP;
- if (IntInit *II =
- dynamic_cast<IntInit*>(Node->getLeafValue())) {
+ if (dynamic_cast<IntInit*>(Node->getLeafValue())) {
PatternsByOpcode[getSDNodeNamed("imm")].push_back(&PatternsToMatch[i]);
} else if ((CP = NodeGetComplexPattern(Node, *this))) {
std::vector<Record*> OpNodes = CP->getRootNodes();
OS << " if (NumKilled) {\n";
OS << " for (unsigned i = 0; i != NumKilled; ++i) {\n";
OS << " SDNode *Temp = ISelKilled[i];\n";
- OS << " std::remove(ISelQueue.begin(), ISelQueue.end(), Temp);\n";
+ OS << " ISelQueue.erase(std::remove(ISelQueue.begin(), ISelQueue.end(), "
+ << "Temp), ISelQueue.end());\n";
OS << " };\n";
OS << " std::make_heap(ISelQueue.begin(), ISelQueue.end(), isel_sort());\n";
OS << " ISelKilled.clear();\n";
OS << " RemoveKilled();\n";
OS << "}\n\n";
- OS << "void DeleteNode(SDNode *N) {\n";
- OS << " CurDAG->DeleteNode(N);\n";
- OS << " for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); "
- << "I != E; ++I) {\n";
- OS << " SDNode *Operand = I->Val;\n";
- OS << " if (Operand->use_empty())\n";
- OS << " DeleteNode(Operand);\n";
- OS << " }\n";
- OS << "}\n";
-
OS << "// SelectRoot - Top level entry to DAG isel.\n";
OS << "SDOperand SelectRoot(SDOperand Root) {\n";
OS << " SelectRootInit();\n";
OS << " if (ResNode != Node) {\n";
OS << " if (ResNode)\n";
OS << " ReplaceUses(Node, ResNode);\n";
- OS << " if (Node->use_empty()) // Don't delete EntryToken, etc.\n";
- OS << " DeleteNode(Node);\n";
+ OS << " if (Node->use_empty()) { // Don't delete EntryToken, etc.\n";
+ OS << " CurDAG->RemoveDeadNode(Node, ISelKilled);\n";
+ OS << " RemoveKilled();\n";
+ OS << " }\n";
OS << " }\n";
OS << " }\n";
OS << " }\n";