* Infer instruction property hasCtrlDep from pattern if it has one.

* Fixed a bug related to hasCtrlDep property use.

llvm-svn: 24610
This commit is contained in:
Evan Cheng 2005-12-05 23:08:55 +00:00
parent 0573bb5fd4
commit 3d51fa3305

View File

@ -1045,6 +1045,34 @@ FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat,
} }
} }
/// NodeHasChain - return true if TreePatternNode has the property
/// 'hasChain', meaning it reads a ctrl-flow chain operand and writes
/// a chain result.
static bool NodeHasChain(TreePatternNode *N, DAGISelEmitter &ISE)
{
if (N->isLeaf()) return false;
Record *Operator = N->getOperator();
if (!Operator->isSubClassOf("SDNode")) return false;
const SDNodeInfo &NodeInfo = ISE.getSDNodeInfo(Operator);
return NodeInfo.hasProperty(SDNodeInfo::SDNPHasChain);
}
static bool PatternHasCtrlDep(TreePatternNode *N, DAGISelEmitter &ISE)
{
if (NodeHasChain(N, ISE))
return true;
else {
for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) {
TreePatternNode *Child = N->getChild(i);
if (PatternHasCtrlDep(Child, ISE))
return true;
}
}
return false;
}
/// ParseInstructions - Parse all of the instructions, inlining and resolving /// ParseInstructions - Parse all of the instructions, inlining and resolving
/// any fragments involved. This populates the Instructions list with fully /// any fragments involved. This populates the Instructions list with fully
@ -1228,7 +1256,7 @@ void DAGISelEmitter::ParseInstructions() {
DAGInstruction &TheInst = II->second; DAGInstruction &TheInst = II->second;
TreePattern *I = TheInst.getPattern(); TreePattern *I = TheInst.getPattern();
if (I == 0) continue; // No pattern. if (I == 0) continue; // No pattern.
if (I->getNumTrees() != 1) { if (I->getNumTrees() != 1) {
std::cerr << "CANNOT HANDLE: " << I->getRecord()->getName() << " yet!"; std::cerr << "CANNOT HANDLE: " << I->getRecord()->getName() << " yet!";
continue; continue;
@ -1253,6 +1281,12 @@ void DAGISelEmitter::ParseInstructions() {
TreePatternNode *DstPattern = TheInst.getResultPattern(); TreePatternNode *DstPattern = TheInst.getResultPattern();
PatternsToMatch.push_back(std::make_pair(SrcPattern, DstPattern)); PatternsToMatch.push_back(std::make_pair(SrcPattern, DstPattern));
if (PatternHasCtrlDep(Pattern, *this)) {
Record *Instr = II->first;
CodeGenInstruction &InstInfo = Target.getInstruction(Instr->getName());
InstInfo.hasCtrlDep = true;
}
} }
} }
@ -1602,17 +1636,6 @@ struct PatternSortingPredicate {
} }
}; };
/// nodeHasChain - return true if TreePatternNode has the property
/// 'hasChain', meaning it reads a ctrl-flow chain operand and writes
/// a chain result.
static bool nodeHasChain(TreePatternNode *N, DAGISelEmitter &ISE)
{
if (N->isLeaf()) return false;
const SDNodeInfo &NodeInfo = ISE.getSDNodeInfo(N->getOperator());
return NodeInfo.hasProperty(SDNodeInfo::SDNPHasChain);
}
/// EmitMatchForPattern - Emit a matcher for N, going to the label for PatternNo /// EmitMatchForPattern - 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
/// matches, and the SDNode for the result has the RootName specified name. /// matches, and the SDNode for the result has the RootName specified name.
@ -1650,7 +1673,7 @@ void DAGISelEmitter::EmitMatchForPattern(TreePatternNode *N,
// Emit code to load the child nodes and match their contents recursively. // Emit code to load the child nodes and match their contents recursively.
unsigned OpNo = (unsigned) nodeHasChain(N, *this); unsigned OpNo = (unsigned) NodeHasChain(N, *this);
for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) { for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) {
OS << " SDOperand " << RootName << OpNo <<" = " << RootName OS << " SDOperand " << RootName << OpNo <<" = " << RootName
<< ".getOperand(" << OpNo << ");\n"; << ".getOperand(" << OpNo << ");\n";
@ -1735,19 +1758,16 @@ void DAGISelEmitter::EmitLeadChainForPattern(TreePatternNode *N,
std::ostream &OS, std::ostream &OS,
bool &HasChain) { bool &HasChain) {
if (!N->isLeaf()) { if (!N->isLeaf()) {
Record *Op = N->getOperator(); bool hc = NodeHasChain(N, *this);
if (Op->isSubClassOf("Instruction")) { unsigned OpNo = (unsigned) hc;
bool HasCtrlDep = Op->getValueAsBit("hasCtrlDep"); for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
unsigned OpNo = (unsigned) HasCtrlDep; EmitLeadChainForPattern(N->getChild(i), RootName + utostr(OpNo),
for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) OS, HasChain);
EmitLeadChainForPattern(N->getChild(i), RootName + utostr(OpNo),
OS, HasChain);
if (!HasChain && HasCtrlDep) { if (!HasChain && hc) {
OS << " SDOperand Chain = Select(" OS << " SDOperand Chain = Select("
<< RootName << ".getOperand(0));\n"; << RootName << ".getOperand(0));\n";
HasChain = true; HasChain = true;
}
} }
} }
} }
@ -1759,7 +1779,7 @@ void DAGISelEmitter::EmitCopyToRegsForPattern(TreePatternNode *N,
std::ostream &OS, std::ostream &OS,
bool &HasChain, bool &InFlag) { bool &HasChain, bool &InFlag) {
const CodeGenTarget &T = getTargetInfo(); const CodeGenTarget &T = getTargetInfo();
unsigned OpNo = (unsigned) nodeHasChain(N, *this); unsigned OpNo = (unsigned) NodeHasChain(N, *this);
for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) { for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) {
TreePatternNode *Child = N->getChild(i); TreePatternNode *Child = N->getChild(i);
if (!Child->isLeaf()) { if (!Child->isLeaf()) {
@ -1866,8 +1886,6 @@ CodeGenPatternResult(TreePatternNode *N, unsigned &Ctr,
Record *Op = N->getOperator(); Record *Op = N->getOperator();
if (Op->isSubClassOf("Instruction")) { if (Op->isSubClassOf("Instruction")) {
bool HasCtrlDep = Op->getValueAsBit("hasCtrlDep");
// Emit all of the operands. // Emit all of the operands.
std::vector<unsigned> Ops; std::vector<unsigned> Ops;
for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
@ -1875,6 +1893,7 @@ CodeGenPatternResult(TreePatternNode *N, unsigned &Ctr,
VariableMap, OS, HasChain, InFlag)); VariableMap, OS, HasChain, InFlag));
CodeGenInstruction &II = Target.getInstruction(Op->getName()); CodeGenInstruction &II = Target.getInstruction(Op->getName());
bool HasCtrlDep = II.hasCtrlDep;
unsigned ResNo = Ctr++; unsigned ResNo = Ctr++;
const DAGInstruction &Inst = getInstruction(Op); const DAGInstruction &Inst = getInstruction(Op);
@ -1993,7 +2012,7 @@ static bool InsertOneTypeCheck(TreePatternNode *Pat, TreePatternNode *Other,
return false; return false;
} }
unsigned OpNo = (unsigned) nodeHasChain(Pat, ISE); unsigned OpNo = (unsigned) NodeHasChain(Pat, ISE);
for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i, ++OpNo) for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i, ++OpNo)
if (InsertOneTypeCheck(Pat->getChild(i), Other->getChild(i), if (InsertOneTypeCheck(Pat->getChild(i), Other->getChild(i),
ISE, Prefix + utostr(OpNo), PatternNo, OS)) ISE, Prefix + utostr(OpNo), PatternNo, OS))
@ -2062,7 +2081,7 @@ void DAGISelEmitter::EmitCodeForPattern(PatternToMatch &Pattern,
} while (InsertOneTypeCheck(Pat, Pattern.first, *this, "N", PatternNo, OS)); } while (InsertOneTypeCheck(Pat, Pattern.first, *this, "N", PatternNo, OS));
bool HasChain = false; bool HasChain = false;
EmitLeadChainForPattern(Pattern.second, "N", OS, HasChain); EmitLeadChainForPattern(Pattern.first, "N", OS, HasChain);
bool InFlag = false; bool InFlag = false;
EmitCopyToRegsForPattern(Pattern.first, "N", OS, HasChain, InFlag); EmitCopyToRegsForPattern(Pattern.first, "N", OS, HasChain, InFlag);