Temporary hack to enable more (store (op (load ...))) folding. This makes

it possible when a TokenFactor is between the load and store. But is still
missing some cases due to ordering issue.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26638 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2006-03-09 08:19:11 +00:00
parent 571340633f
commit ed66e855ec

View File

@ -1866,6 +1866,7 @@ private:
std::set<std::pair<bool, std::string> > &GeneratedDecl; std::set<std::pair<bool, std::string> > &GeneratedDecl;
std::string ChainName; std::string ChainName;
bool NewTF;
bool DoReplace; bool DoReplace;
unsigned TmpNo; unsigned TmpNo;
@ -1888,7 +1889,8 @@ public:
std::set<std::pair<bool, std::string> > &gd, std::set<std::pair<bool, std::string> > &gd,
bool dorep) bool dorep)
: ISE(ise), Predicates(preds), Pattern(pattern), Instruction(instr), : ISE(ise), Predicates(preds), Pattern(pattern), Instruction(instr),
GeneratedCode(gc), GeneratedDecl(gd), DoReplace(dorep), TmpNo(0) {} GeneratedCode(gc), GeneratedDecl(gd),
NewTF(false), DoReplace(dorep), TmpNo(0) {}
/// EmitMatchCode - Emit a matcher for N, going to the label for PatternNo /// EmitMatchCode - Emit a matcher for N, going to the label for PatternNo
/// if the match fails. At this point, we already know that the opcode for N /// if the match fails. At this point, we already know that the opcode for N
@ -2018,14 +2020,19 @@ public:
} }
if (NodeHasChain) { if (NodeHasChain) {
if (FoundChain)
emitCheck("Chain.Val == " + RootName + ".Val");
else
FoundChain = true;
ChainName = "Chain" + ChainSuffix; ChainName = "Chain" + ChainSuffix;
emitDecl(ChainName); emitDecl(ChainName);
emitCode(ChainName + " = " + RootName + if (FoundChain) {
".getOperand(0);"); // FIXME: temporary workaround for a common case where chain
// is a TokenFactor and the previous "inner" chain is an operand.
NewTF = true;
emitDecl("OldTF", true);
emitCheck("(" + ChainName + " = UpdateFoldedChain(CurDAG, " +
RootName + ".Val, Chain.Val, OldTF)).Val");
} else {
FoundChain = true;
emitCode(ChainName + " = " + RootName + ".getOperand(0);");
}
} }
} }
@ -2272,11 +2279,11 @@ public:
emitCode("bool HasOptInFlag = false;"); emitCode("bool HasOptInFlag = false;");
// How many results is this pattern expected to produce? // How many results is this pattern expected to produce?
unsigned NumExpectedResults = 0; unsigned PatResults = 0;
for (unsigned i = 0, e = Pattern->getExtTypes().size(); i != e; i++) { for (unsigned i = 0, e = Pattern->getExtTypes().size(); i != e; i++) {
MVT::ValueType VT = Pattern->getTypeNum(i); MVT::ValueType VT = Pattern->getTypeNum(i);
if (VT != MVT::isVoid && VT != MVT::Flag) if (VT != MVT::isVoid && VT != MVT::Flag)
NumExpectedResults++; PatResults++;
} }
// Determine operand emission order. Complex pattern first. // Determine operand emission order. Complex pattern first.
@ -2405,61 +2412,64 @@ public:
emitCode(Code + ");"); emitCode(Code + ");");
} }
unsigned ValNo = 0; if (NewTF)
for (unsigned i = 0; i < NumResults; i++) { emitCode("if (OldTF) "
"SelectionDAG::InsertISelMapEntry(CodeGenMap, OldTF, 0, " +
ChainName + ".Val, 0);");
for (unsigned i = 0; i < NumResults; i++)
emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, " + emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, " +
utostr(ValNo) + ", ResNode, " + utostr(ValNo) + ");"); utostr(i) + ", ResNode, " + utostr(i) + ");");
ValNo++;
}
if (NodeHasOutFlag) if (NodeHasOutFlag)
emitCode("InFlag = SDOperand(ResNode, " + emitCode("InFlag = SDOperand(ResNode, " +
utostr(ValNo + (unsigned)HasChain) + ");"); utostr(NumResults + (unsigned)HasChain) + ");");
if (HasImpResults && EmitCopyFromRegs(N, ChainEmitted)) { if (HasImpResults && EmitCopyFromRegs(N, ChainEmitted)) {
emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, " + emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, "
utostr(ValNo) + ", ResNode, " + utostr(ValNo) + ");"); "0, ResNode, 0);");
ValNo++; NumResults = 1;
} }
// User does not expect the instruction would produce a chain!
bool AddedChain = HasChain && !NodeHasChain;
if (NodeHasChain) { if (NodeHasChain) {
emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, " + emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, " +
utostr(ValNo) + ", ResNode, " + utostr(ValNo) + ");"); utostr(PatResults) + ", ResNode, " +
utostr(NumResults) + ");");
if (DoReplace) if (DoReplace)
emitCode("if (N.ResNo == 0) AddHandleReplacement(N.Val, " emitCode("if (N.ResNo == 0) AddHandleReplacement(N.Val, " +
+ utostr(ValNo) + ", " + "ResNode, " + utostr(ValNo) + ");"); utostr(PatResults) + ", " + "ResNode, " +
ValNo++; utostr(NumResults) + ");");
} }
if (FoldedChains.size() > 0) { if (FoldedChains.size() > 0) {
std::string Code; std::string Code;
for (unsigned j = 0, e = FoldedChains.size(); j < e; j++) for (unsigned j = 0, e = FoldedChains.size(); j < e; j++)
emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, " + emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, " +
FoldedChains[j].first + ".Val, " + FoldedChains[j].first + ".Val, " +
utostr(FoldedChains[j].second) + ", ResNode, " + utostr(FoldedChains[j].second) + ", ResNode, " +
utostr(ValNo) + ");"); utostr(NumResults) + ");");
for (unsigned j = 0, e = FoldedChains.size(); j < e; j++) { for (unsigned j = 0, e = FoldedChains.size(); j < e; j++) {
std::string Code = std::string Code =
FoldedChains[j].first + ".Val, " + FoldedChains[j].first + ".Val, " +
utostr(FoldedChains[j].second) + ", "; utostr(FoldedChains[j].second) + ", ";
emitCode("AddHandleReplacement(" + Code + "ResNode, " + emitCode("AddHandleReplacement(" + Code + "ResNode, " +
utostr(ValNo) + ");"); utostr(NumResults) + ");");
} }
} }
if (NodeHasOutFlag) if (NodeHasOutFlag)
emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, " + emitCode("SelectionDAG::InsertISelMapEntry(CodeGenMap, N.Val, " +
utostr(ValNo) + ", InFlag.Val, InFlag.ResNo);"); utostr(PatResults + (unsigned)NodeHasChain) +
", InFlag.Val, InFlag.ResNo);");
// User does not expect the instruction would produce a chain!
bool AddedChain = HasChain && !NodeHasChain;
if (AddedChain && NodeHasOutFlag) { if (AddedChain && NodeHasOutFlag) {
if (NumExpectedResults == 0) { if (PatResults == 0) {
emitCode("Result = SDOperand(ResNode, N.ResNo+1);"); emitCode("Result = SDOperand(ResNode, N.ResNo+1);");
} else { } else {
emitCode("if (N.ResNo < " + utostr(NumExpectedResults) + ")"); emitCode("if (N.ResNo < " + utostr(PatResults) + ")");
emitCode(" Result = SDOperand(ResNode, N.ResNo);"); emitCode(" Result = SDOperand(ResNode, N.ResNo);");
emitCode("else"); emitCode("else");
emitCode(" Result = SDOperand(ResNode, N.ResNo+1);"); emitCode(" Result = SDOperand(ResNode, N.ResNo+1);");
@ -3247,6 +3257,40 @@ void DAGISelEmitter::run(std::ostream &OS) {
OS << " }\n"; OS << " }\n";
OS << "}\n"; OS << "}\n";
OS << "\n";
OS << "// UpdateFoldedChain - return a SDOperand of the new chain created\n";
OS << "// if the folding were to happen. This is called when, for example,\n";
OS << "// a load is folded into a store. If the store's chain is the load,\n";
OS << "// then the resulting node's input chain would be the load's input\n";
OS << "// chain. If the store's chain is a TokenFactor and the load's\n";
OS << "// output chain feeds into in, then the new chain is a TokenFactor\n";
OS << "// with the other operands along with the input chain of the load.\n";
OS << "SDOperand UpdateFoldedChain(SelectionDAG *DAG, SDNode *N, "
<< "SDNode *Chain, SDNode* &OldTF) {\n";
OS << " OldTF = NULL;\n";
OS << " if (N == Chain) {\n";
OS << " return N->getOperand(0);\n";
OS << " } else if (Chain->getOpcode() == ISD::TokenFactor &&\n";
OS << " N->isOperand(Chain)) {\n";
OS << " SDOperand Ch = SDOperand(Chain, 0);\n";
OS << " std::map<SDOperand, SDOperand>::iterator CGMI = "
<< "CodeGenMap.find(Ch);\n";
OS << " if (CGMI != CodeGenMap.end())\n";
OS << " return SDOperand(0, 0);\n";
OS << " OldTF = Chain;\n";
OS << " std::vector<SDOperand> Ops;\n";
OS << " for (unsigned i = 0; i < Chain->getNumOperands(); ++i) {\n";
OS << " SDOperand Op = Chain->getOperand(i);\n";
OS << " if (Op.Val == N)\n";
OS << " Ops.push_back(N->getOperand(0));\n";
OS << " else\n";
OS << " Ops.push_back(Op);\n";
OS << " }\n";
OS << " return DAG->getNode(ISD::TokenFactor, MVT::Other, Ops);\n";
OS << " }\n";
OS << " return SDOperand(0, 0);\n";
OS << "}\n";
OS << "\n"; OS << "\n";
OS << "// SelectRoot - Top level entry to DAG isel.\n"; OS << "// SelectRoot - Top level entry to DAG isel.\n";
OS << "SDOperand SelectRoot(SDOperand N) {\n"; OS << "SDOperand SelectRoot(SDOperand N) {\n";