(store (op (load ...))) folding problem. In the generated matching code,

Chain is initially set to the chain operand of store node, when it reaches
load, if it matches the load then Chain is set to the chain operand of the
load.

However, if the matching code that follows this fails, isel moves on to the
next pattern but it does not restore Chain to the chain operand of the store.
So when it tries to match the next store / op / load pattern it would fail on
the Chain == load.getOperand(0) test.

The solution is for each chain operand to get a unique name. e.g. Chain10.

llvm-svn: 25931
This commit is contained in:
Evan Cheng 2006-02-03 06:22:41 +00:00
parent a23b04acdb
commit 717db484a5
1 changed files with 30 additions and 23 deletions

View File

@ -1848,6 +1848,7 @@ private:
/// [when false]. /// [when false].
std::vector<std::pair<bool, std::string> > &GeneratedCode; std::vector<std::pair<bool, std::string> > &GeneratedCode;
std::string ChainName;
unsigned TmpNo; unsigned TmpNo;
void emitCheck(const std::string &S) { void emitCheck(const std::string &S) {
@ -1869,7 +1870,8 @@ public:
/// 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
/// matches, and the SDNode for the result has the RootName specified name. /// matches, and the SDNode for the result has the RootName specified name.
void EmitMatchCode(TreePatternNode *N, const std::string &RootName, void EmitMatchCode(TreePatternNode *N, const std::string &RootName,
bool &FoundChain, bool isRoot = false) { const std::string &ChainSuffix, bool &FoundChain,
bool isRoot = false) {
// Emit instruction predicates. Each predicate is just a string for now. // Emit instruction predicates. Each predicate is just a string for now.
if (isRoot) { if (isRoot) {
@ -1947,13 +1949,13 @@ public:
utostr(CInfo.getNumResults()) + "))"); utostr(CInfo.getNumResults()) + "))");
} }
if (NodeHasChain) { if (NodeHasChain) {
if (!FoundChain) { if (FoundChain)
emitCode("SDOperand Chain = " + RootName + ".getOperand(0);");
FoundChain = true;
} else {
emitCheck("Chain.Val == " + RootName + ".Val"); emitCheck("Chain.Val == " + RootName + ".Val");
emitCode("Chain = " + RootName + ".getOperand(0);"); else
} FoundChain = true;
ChainName = "Chain" + ChainSuffix;
emitCode("SDOperand " + ChainName + " = " + RootName +
".getOperand(0);");
} }
} }
@ -1988,7 +1990,8 @@ public:
const SDNodeInfo &CInfo = ISE.getSDNodeInfo(Child->getOperator()); const SDNodeInfo &CInfo = ISE.getSDNodeInfo(Child->getOperator());
emitCheck(RootName + utostr(OpNo) + ".getOpcode() == " + emitCheck(RootName + utostr(OpNo) + ".getOpcode() == " +
CInfo.getEnumName()); CInfo.getEnumName());
EmitMatchCode(Child, RootName + utostr(OpNo), FoundChain); EmitMatchCode(Child, RootName + utostr(OpNo), ChainSuffix + utostr(OpNo),
FoundChain);
if (NodeHasProperty(Child, SDNodeInfo::SDNPHasChain, ISE)) if (NodeHasProperty(Child, SDNodeInfo::SDNPHasChain, ISE))
FoldedChains.push_back(std::make_pair(RootName + utostr(OpNo), FoldedChains.push_back(std::make_pair(RootName + utostr(OpNo),
CInfo.getNumResults())); CInfo.getNumResults()));
@ -2225,7 +2228,7 @@ public:
// Emit all the chain and CopyToReg stuff. // Emit all the chain and CopyToReg stuff.
bool ChainEmitted = HasChain; bool ChainEmitted = HasChain;
if (HasChain) if (HasChain)
emitCode("Chain = Select(Chain);"); emitCode(ChainName + " = Select(" + ChainName + ");");
if (HasInFlag || HasOptInFlag || HasImpInputs) if (HasInFlag || HasOptInFlag || HasImpInputs)
EmitInFlagSelectCode(Pattern, "N", ChainEmitted, true); EmitInFlagSelectCode(Pattern, "N", ChainEmitted, true);
@ -2248,7 +2251,7 @@ public:
emitCode(Code + ");"); emitCode(Code + ");");
if (HasChain) { if (HasChain) {
// Must have at least one result // Must have at least one result
emitCode("Chain = Tmp" + utostr(LastOp) + ".getValue(" + emitCode(ChainName + " = Tmp" + utostr(LastOp) + ".getValue(" +
utostr(NumResults) + ");"); utostr(NumResults) + ");");
} }
} else if (HasChain || NodeHasOutFlag) { } else if (HasChain || NodeHasOutFlag) {
@ -2273,7 +2276,7 @@ public:
// Inputs. // Inputs.
for (unsigned i = 0, e = Ops.size(); i != e; ++i) for (unsigned i = 0, e = Ops.size(); i != e; ++i)
Code += ", Tmp" + utostr(Ops[i]); Code += ", Tmp" + utostr(Ops[i]);
if (HasChain) Code += ", Chain"; if (HasChain) Code += ", " + ChainName;
emitCode(Code + ", InFlag);"); emitCode(Code + ", InFlag);");
emitCode("else"); emitCode("else");
@ -2292,7 +2295,7 @@ public:
// Inputs. // Inputs.
for (unsigned i = 0, e = Ops.size(); i != e; ++i) for (unsigned i = 0, e = Ops.size(); i != e; ++i)
Code += ", Tmp" + utostr(Ops[i]); Code += ", Tmp" + utostr(Ops[i]);
if (HasChain) Code += ", Chain);"; if (HasChain) Code += ", " + ChainName + ");";
emitCode(Code); emitCode(Code);
} else { } else {
std::string Code = "SDOperand Result = CurDAG->getTargetNode(" + std::string Code = "SDOperand Result = CurDAG->getTargetNode(" +
@ -2310,7 +2313,7 @@ public:
// Inputs. // Inputs.
for (unsigned i = 0, e = Ops.size(); i != e; ++i) for (unsigned i = 0, e = Ops.size(); i != e; ++i)
Code += ", Tmp" + utostr(Ops[i]); Code += ", Tmp" + utostr(Ops[i]);
if (HasChain) Code += ", Chain"; if (HasChain) Code += ", " + ChainName;
if (HasInFlag || HasImpInputs) Code += ", InFlag"; if (HasInFlag || HasImpInputs) Code += ", InFlag";
emitCode(Code + ");"); emitCode(Code + ");");
} }
@ -2323,7 +2326,7 @@ public:
} }
if (HasChain) if (HasChain)
emitCode("Chain = Result.getValue(" + utostr(ValNo) + ");"); emitCode(ChainName + " = Result.getValue(" + utostr(ValNo) + ");");
if (NodeHasOutFlag) if (NodeHasOutFlag)
emitCode("InFlag = Result.getValue(" + emitCode("InFlag = Result.getValue(" +
@ -2338,14 +2341,15 @@ public:
// User does not expect that the instruction produces a chain! // User does not expect that the instruction produces a chain!
bool AddedChain = HasChain && !NodeHasChain; bool AddedChain = HasChain && !NodeHasChain;
if (NodeHasChain) if (NodeHasChain)
emitCode("CodeGenMap[N.getValue(" + utostr(ValNo++) + ")] = Chain;"); emitCode("CodeGenMap[N.getValue(" + utostr(ValNo++) + ")] = " +
ChainName + ";");
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++)
Code += "CodeGenMap[" + FoldedChains[j].first + ".getValue(" + Code += "CodeGenMap[" + FoldedChains[j].first + ".getValue(" +
utostr(FoldedChains[j].second) + ")] = "; utostr(FoldedChains[j].second) + ")] = ";
emitCode(Code + "Chain;"); emitCode(Code + ChainName + ";");
} }
if (NodeHasOutFlag) if (NodeHasOutFlag)
@ -2467,14 +2471,16 @@ private:
} else { } else {
if (!ChainEmitted) { if (!ChainEmitted) {
emitCode("SDOperand Chain = CurDAG->getEntryNode();"); emitCode("SDOperand Chain = CurDAG->getEntryNode();");
ChainName = "Chain";
ChainEmitted = true; ChainEmitted = true;
} }
emitCode("SDOperand " + RootName + "CR" + utostr(i) + ";"); emitCode("SDOperand " + RootName + "CR" + utostr(i) + ";");
emitCode(RootName + "CR" + utostr(i) + emitCode(RootName + "CR" + utostr(i) +
" = CurDAG->getCopyToReg(Chain, CurDAG->getRegister(" + " = CurDAG->getCopyToReg(" + ChainName +
ISE.getQualifiedName(RR) + ", MVT::" + getEnumName(RVT) + ", CurDAG->getRegister(" + ISE.getQualifiedName(RR) +
"), Select(" + RootName + utostr(OpNo) + "), InFlag);"); ", MVT::" + getEnumName(RVT) + "), Select(" + RootName +
emitCode("Chain = " + RootName + "CR" + utostr(i) + utostr(OpNo) + "), InFlag);");
emitCode(ChainName + " = " + RootName + "CR" + utostr(i) +
".getValue(0);"); ".getValue(0);");
emitCode("InFlag = " + RootName + "CR" + utostr(i) + emitCode("InFlag = " + RootName + "CR" + utostr(i) +
".getValue(1);"); ".getValue(1);");
@ -2519,11 +2525,12 @@ private:
if (!ChainEmitted) { if (!ChainEmitted) {
emitCode("SDOperand Chain = CurDAG->getEntryNode();"); emitCode("SDOperand Chain = CurDAG->getEntryNode();");
ChainEmitted = true; ChainEmitted = true;
ChainName = "Chain";
} }
emitCode("Result = CurDAG->getCopyFromReg(Chain, " + emitCode("Result = CurDAG->getCopyFromReg(" + ChainName + ", " +
ISE.getQualifiedName(RR) + ", MVT::" + getEnumName(RVT) + ISE.getQualifiedName(RR) + ", MVT::" + getEnumName(RVT) +
", InFlag);"); ", InFlag);");
emitCode("Chain = Result.getValue(1);"); emitCode(ChainName + " = Result.getValue(1);");
emitCode("InFlag = Result.getValue(2);"); emitCode("InFlag = Result.getValue(2);");
RetVal = true; RetVal = true;
} }
@ -2545,7 +2552,7 @@ void DAGISelEmitter::GenerateCodeForPattern(PatternToMatch &Pattern,
// Emit the matcher, capturing named arguments in VariableMap. // Emit the matcher, capturing named arguments in VariableMap.
bool FoundChain = false; bool FoundChain = false;
Emitter.EmitMatchCode(Pattern.getSrcPattern(), "N", FoundChain, Emitter.EmitMatchCode(Pattern.getSrcPattern(), "N", "", FoundChain,
true /*the root*/); true /*the root*/);
// TP - Get *SOME* tree pattern, we don't care which. // TP - Get *SOME* tree pattern, we don't care which.