std::map<std::string, std::string> VariableMap;
// Node to operator mapping
std::map<std::string, Record*> OperatorMap;
+ // Name of the folded node which produces a flag.
+ std::pair<std::string, unsigned> FoldedFlag;
// Names of all the folded nodes which produce chains.
std::vector<std::pair<std::string, unsigned> > FoldedChains;
// Original input chain(s).
emitCheck(RootName + ".getOpcode() == " +
CInfo.getEnumName());
EmitMatchCode(Child, Parent, RootName, ChainSuffix, FoundChain);
- if (NodeHasProperty(Child, SDNPHasChain, CGP))
+ bool HasChain = false;
+ if (NodeHasProperty(Child, SDNPHasChain, CGP)) {
+ HasChain = true;
FoldedChains.push_back(std::make_pair(RootName, CInfo.getNumResults()));
+ }
+ if (NodeHasProperty(Child, SDNPOutFlag, CGP)) {
+ assert(FoldedFlag.first == "" && FoldedFlag.second == 0 &&
+ "Pattern folded multiple nodes which produce flags?");
+ FoldedFlag = std::make_pair(RootName,
+ CInfo.getNumResults() + (unsigned)HasChain);
+ }
} else {
// If this child has a name associated with it, capture it in VarMap. If
// we already saw this in the pattern, emit code to verify dagness.
}
if (NodeHasOutFlag) {
- emitCode("ReplaceUses(SDOperand(N.Val, " +
- utostr(NumPatResults + (unsigned)InputHasChain)
- +"), InFlag);");
+ if (FoldedFlag.first != "") {
+ emitCode("ReplaceUses(SDOperand(" + FoldedFlag.first + ".Val, " +
+ utostr(FoldedFlag.second) + "), InFlag);");
+ } else {
+ assert(NodeHasProperty(Pattern, SDNPOutFlag, CGP));
+ emitCode("ReplaceUses(SDOperand(N.Val, " +
+ utostr(NumPatResults + (unsigned)InputHasChain)
+ +"), InFlag);");
+ }
NeedReplace = true;
}
<< "}\n\n";
OS << "SDNode *Select_DECLARE(const SDOperand &N) {\n"
- << " MachineModuleInfo *MMI = CurDAG->getMachineModuleInfo();\n"
<< " SDOperand Chain = N.getOperand(0);\n"
<< " SDOperand N1 = N.getOperand(1);\n"
<< " SDOperand N2 = N.getOperand(2);\n"
<< " }\n"
<< " int FI = cast<FrameIndexSDNode>(N1)->getIndex();\n"
<< " GlobalValue *GV = cast<GlobalAddressSDNode>(N2)->getGlobal();\n"
- << " // FIXME. Handle variable declarations later since it lives on.\n"
- << " MMI->RecordVariable(GV, FI);\n"
<< " SDOperand Tmp1 = "
<< "CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());\n"
<< " SDOperand Tmp2 = "
<< "// *** instruction selector class. These functions are really "
<< "methods.\n\n";
- OS << "#include \"llvm/Support/Compiler.h\"\n";
-
OS << "// Instruction selector priority queue:\n"
<< "std::vector<SDNode*> ISelQueue;\n";
OS << "/// Keep track of nodes which have already been added to queue.\n"
<< "unsigned char *ISelQueued;\n";
OS << "/// Keep track of nodes which have already been selected.\n"
<< "unsigned char *ISelSelected;\n";
- OS << "/// Dummy parameter to ReplaceAllUsesOfValueWith().\n"
- << "std::vector<SDNode*> ISelKilled;\n\n";
+
OS << "/// IsChainCompatible - Returns true if Chain is Op or Chain does\n";
OS << "/// not reach Op.\n";
OS << " }\n";
OS << "}\n\n";
- OS << "inline void RemoveKilled() {\n";
-OS << " unsigned NumKilled = ISelKilled.size();\n";
- OS << " if (NumKilled) {\n";
- OS << " for (unsigned i = 0; i != NumKilled; ++i) {\n";
- OS << " SDNode *Temp = ISelKilled[i];\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 << " }\n";
+
+ OS << "class VISIBILITY_HIDDEN ISelQueueUpdater :\n";
+ OS << " public SelectionDAG::DAGUpdateListener {\n";
+ OS << " std::vector<SDNode*> &ISelQueue;\n";
+ OS << " bool HadDelete;\n";
+ OS << " public:\n";
+ OS << " ISelQueueUpdater(std::vector<SDNode*> &isq)\n";
+ OS << " : ISelQueue(isq), HadDelete(false) {}\n";
+ OS << " \n";
+ OS << " bool hadDelete() const { return HadDelete; }\n";
+ OS << " \n";
+ OS << " virtual void NodeDeleted(SDNode *N) {\n";
+ OS << " ISelQueue.erase(std::remove(ISelQueue.begin(), ISelQueue.end(),";
+ OS << " N),\n ISelQueue.end());\n";
+ OS << " HadDelete = true;\n";
+ OS << " }\n";
+ OS << " \n";
+ OS << " // Ignore updates.\n";
+ OS << " virtual void NodeUpdated(SDNode *N) {}\n";
+ OS << " };\n";
+
+ OS << "inline void UpdateQueue(const ISelQueueUpdater &ISQU) {\n";
+ OS << " if (ISQU.hadDelete())\n";
+ OS << " std::make_heap(ISelQueue.begin(), ISelQueue.end(),isel_sort());\n";
OS << "}\n\n";
OS << "void ReplaceUses(SDOperand F, SDOperand T) DISABLE_INLINE {\n";
- OS << " CurDAG->ReplaceAllUsesOfValueWith(F, T, &ISelKilled);\n";
+ OS << " ISelQueueUpdater ISQU(ISelQueue);\n";
+ OS << " CurDAG->ReplaceAllUsesOfValueWith(F, T, &ISQU);\n";
OS << " setSelected(F.Val->getNodeId());\n";
- OS << " RemoveKilled();\n";
+ OS << " UpdateQueue(ISQU);\n";
OS << "}\n";
OS << "void ReplaceUses(SDNode *F, SDNode *T) DISABLE_INLINE {\n";
OS << " unsigned FNumVals = F->getNumValues();\n";
OS << " unsigned TNumVals = T->getNumValues();\n";
+ OS << " ISelQueueUpdater ISQU(ISelQueue);\n";
OS << " if (FNumVals != TNumVals) {\n";
OS << " for (unsigned i = 0, e = std::min(FNumVals, TNumVals); "
<< "i < e; ++i)\n";
OS << " CurDAG->ReplaceAllUsesOfValueWith(SDOperand(F, i), "
- << "SDOperand(T, i), &ISelKilled);\n";
+ << "SDOperand(T, i), &ISQU);\n";
OS << " } else {\n";
- OS << " CurDAG->ReplaceAllUsesWith(F, T, &ISelKilled);\n";
+ OS << " CurDAG->ReplaceAllUsesWith(F, T, &ISQU);\n";
OS << " }\n";
OS << " setSelected(F->getNodeId());\n";
- OS << " RemoveKilled();\n";
+ OS << " UpdateQueue(ISQU);\n";
OS << "}\n\n";
OS << "// SelectRoot - Top level entry to DAG isel.\n";
OS << " if (ResNode)\n";
OS << " ReplaceUses(Node, ResNode);\n";
OS << " if (Node->use_empty()) { // Don't delete EntryToken, etc.\n";
- OS << " CurDAG->RemoveDeadNode(Node, ISelKilled);\n";
- OS << " RemoveKilled();\n";
+ OS << " ISelQueueUpdater ISQU(ISelQueue);\n";
+ OS << " CurDAG->RemoveDeadNode(Node, &ISQU);\n";
+ OS << " UpdateQueue(ISQU);\n";
OS << " }\n";
OS << " }\n";
OS << " }\n";