diff options
author | Evan Cheng <evan.cheng@apple.com> | 2006-04-28 02:08:10 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2006-04-28 02:08:10 +0000 |
commit | 61a0209a8ac7b55a40f291f30679f16b3eb1d83c (patch) | |
tree | 2091be010b89e53c05a73a418b8791f134e4f55c /utils | |
parent | addc55af6c7f8b71eedd68d48f6a93ceecff2840 (diff) | |
download | llvm-61a0209a8ac7b55a40f291f30679f16b3eb1d83c.tar.gz llvm-61a0209a8ac7b55a40f291f30679f16b3eb1d83c.tar.bz2 llvm-61a0209a8ac7b55a40f291f30679f16b3eb1d83c.tar.xz |
When isel'ing a node, mark its operands "InFlight" before selecting them. These
nodes should not be folded into other nodes.
This fixes the miscompilation of PR 749.
Temporarily under flag control.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28002 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r-- | utils/TableGen/DAGISelEmitter.cpp | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp index e814211191..b4317ff4fa 100644 --- a/utils/TableGen/DAGISelEmitter.cpp +++ b/utils/TableGen/DAGISelEmitter.cpp @@ -2022,6 +2022,8 @@ private: // Names of all the folded nodes which produce chains. std::vector<std::pair<std::string, unsigned> > FoldedChains; std::set<std::string> Duplicates; + /// These nodes are being marked "in-flight" so they cannot be folded. + std::vector<std::string> InflightNodes; /// GeneratedCode - This is the buffer that we emit code to. The first bool /// indicates whether this is an exit predicate (something that should be @@ -2128,6 +2130,9 @@ public: OpNo = 1; if (!isRoot) { const SDNodeInfo &CInfo = ISE.getSDNodeInfo(N->getOperator()); + // Not in flight? + emitCheck("(FoldNodeInFlight || InFlightSet.count(" + + RootName + ".Val) == 0)"); // Multiple uses of actual result? emitCheck(RootName + ".hasOneUse()"); EmittedUseCheck = true; @@ -2381,6 +2386,10 @@ public: Code += ", Tmp" + utostr(i + ResNo); emitCheck(Code + ")"); + for (unsigned i = 0; i < NumRes; ++i) { + emitCode("InFlightSet.insert(Tmp" + utostr(i+ResNo) + ".Val);"); + InflightNodes.push_back("Tmp" + utostr(i+ResNo)); + } for (unsigned i = 0; i < NumRes; ++i) emitCode("Select(Tmp" + utostr(i+ResNo) + ", Tmp" + utostr(i+ResNo) + ");"); @@ -2392,8 +2401,9 @@ public: // node even if it isn't one. Don't select it. if (LikeLeaf) emitCode("Tmp" + utostr(ResNo) + " = " + Val + ";"); - else + else { emitCode("Select(Tmp" + utostr(ResNo) + ", " + Val + ");"); + } if (isRoot && N->isLeaf()) { emitCode("Result = Tmp" + utostr(ResNo) + ";"); @@ -2477,9 +2487,24 @@ public: } } - // Emit all of the operands. + // Make sure these operands which would be selected won't be folded while + // the isel traverses the DAG upward. std::vector<std::pair<unsigned, unsigned> > NumTemps(EmitOrder.size()); for (unsigned i = 0, e = EmitOrder.size(); i != e; ++i) { + TreePatternNode *Child = EmitOrder[i].second; + if (!Child->getName().empty()) { + std::string &Val = VariableMap[Child->getName()]; + assert(!Val.empty() && + "Variable referenced but not defined and not caught earlier!"); + if (Child->isLeaf() && !NodeGetComplexPattern(Child, ISE)) { + emitCode("InFlightSet.insert(" + Val + ".Val);"); + InflightNodes.push_back(Val); + } + } + } + + // Emit all of the operands. + for (unsigned i = 0, e = EmitOrder.size(); i != e; ++i) { unsigned OpOrder = EmitOrder[i].first; TreePatternNode *Child = EmitOrder[i].second; std::pair<unsigned, unsigned> NumTemp = EmitResultCode(Child); @@ -2500,6 +2525,10 @@ public: if (HasInFlag || HasOptInFlag || HasImpInputs) EmitInFlagSelectCode(Pattern, "N", ChainEmitted, true); + // The operands have been selected. Remove them from InFlightSet. + for (std::vector<std::string>::iterator AI = InflightNodes.begin(), + AE = InflightNodes.end(); AI != AE; ++AI) + emitCode("InFlightSet.erase(" + *AI + ".Val);"); unsigned NumResults = Inst.getNumResults(); unsigned ResNo = TmpNo++; if (!isRoot) { @@ -3373,6 +3402,9 @@ void DAGISelEmitter::run(std::ostream &OS) { OS << "// Instance var to keep track of mapping of place handle nodes\n" << "// and their replacement nodes.\n"; OS << "std::map<SDOperand, SDOperand> ReplaceMap;\n"; + OS << "// Keep track of nodes that are currently being selecte and therefore\n" + << "// should not be folded.\n"; + OS << "std::set<SDNode*> InFlightSet;\n"; OS << "\n"; OS << "static void findNonImmUse(SDNode* Use, SDNode* Def, bool &found, " |