* Remove instruction fields hasInFlag / hasOutFlag and added SNDPInFlag and

SNDPOutFlag to DAG nodes. These properties do not belong to target specific
instructions.
* Added DAG node property SNDPOptInFlag. It's same as SNDPInFlag except it's
optional. Used by ret / call, etc.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25154 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2006-01-09 18:27:06 +00:00
parent baec98d00b
commit 51fecc80f7
4 changed files with 57 additions and 45 deletions

View File

@ -85,8 +85,6 @@ namespace llvm {
bool usesCustomDAGSchedInserter; bool usesCustomDAGSchedInserter;
bool hasVariableNumberOfOperands; bool hasVariableNumberOfOperands;
bool hasCtrlDep; bool hasCtrlDep;
bool hasInFlag;
bool hasOutFlag;
bool noResults; bool noResults;
CodeGenInstruction(Record *R, const std::string &AsmStr); CodeGenInstruction(Record *R, const std::string &AsmStr);

View File

@ -271,8 +271,6 @@ CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr)
hasDelaySlot = R->getValueAsBit("hasDelaySlot"); hasDelaySlot = R->getValueAsBit("hasDelaySlot");
usesCustomDAGSchedInserter = R->getValueAsBit("usesCustomDAGSchedInserter"); usesCustomDAGSchedInserter = R->getValueAsBit("usesCustomDAGSchedInserter");
hasCtrlDep = R->getValueAsBit("hasCtrlDep"); hasCtrlDep = R->getValueAsBit("hasCtrlDep");
hasInFlag = R->getValueAsBit("hasInFlag");
hasOutFlag = R->getValueAsBit("hasOutFlag");
noResults = R->getValueAsBit("noResults"); noResults = R->getValueAsBit("noResults");
hasVariableNumberOfOperands = false; hasVariableNumberOfOperands = false;

View File

@ -283,6 +283,12 @@ SDNodeInfo::SDNodeInfo(Record *R) : Def(R) {
Properties |= 1 << SDNPAssociative; Properties |= 1 << SDNPAssociative;
} else if (PropList[i]->getName() == "SDNPHasChain") { } else if (PropList[i]->getName() == "SDNPHasChain") {
Properties |= 1 << SDNPHasChain; Properties |= 1 << SDNPHasChain;
} else if (PropList[i]->getName() == "SDNPOutFlag") {
Properties |= 1 << SDNPOutFlag;
} else if (PropList[i]->getName() == "SDNPInFlag") {
Properties |= 1 << SDNPInFlag;
} else if (PropList[i]->getName() == "SDNPOptInFlag") {
Properties |= 1 << SDNPOptInFlag;
} else { } else {
std::cerr << "Unknown SD Node property '" << PropList[i]->getName() std::cerr << "Unknown SD Node property '" << PropList[i]->getName()
<< "' on node '" << R->getName() << "'!\n"; << "' on node '" << R->getName() << "'!\n";
@ -1779,29 +1785,29 @@ Record *DAGISelEmitter::getSDNodeNamed(const std::string &Name) const {
return N; return N;
} }
/// NodeHasChain - return true if TreePatternNode has the property /// NodeHasProperty - return true if TreePatternNode has the specified
/// 'hasChain', meaning it reads a ctrl-flow chain operand and writes /// property.
/// a chain result. static bool NodeHasProperty(TreePatternNode *N, SDNodeInfo::SDNP Property,
static bool NodeHasChain(TreePatternNode *N, DAGISelEmitter &ISE) DAGISelEmitter &ISE)
{ {
if (N->isLeaf()) return false; if (N->isLeaf()) return false;
Record *Operator = N->getOperator(); Record *Operator = N->getOperator();
if (!Operator->isSubClassOf("SDNode")) return false; if (!Operator->isSubClassOf("SDNode")) return false;
const SDNodeInfo &NodeInfo = ISE.getSDNodeInfo(Operator); const SDNodeInfo &NodeInfo = ISE.getSDNodeInfo(Operator);
return NodeInfo.hasProperty(SDNodeInfo::SDNPHasChain); return NodeInfo.hasProperty(Property);
} }
static bool PatternHasCtrlDep(TreePatternNode *N, DAGISelEmitter &ISE) static bool PatternHasProperty(TreePatternNode *N, SDNodeInfo::SDNP Property,
DAGISelEmitter &ISE)
{ {
if (NodeHasChain(N, ISE)) if (NodeHasProperty(N, Property, ISE))
return true; return true;
else {
for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) { for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) {
TreePatternNode *Child = N->getChild(i); TreePatternNode *Child = N->getChild(i);
if (PatternHasCtrlDep(Child, ISE)) if (PatternHasProperty(Child, Property, ISE))
return true; return true;
}
} }
return false; return false;
@ -1891,7 +1897,7 @@ public:
// 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 = 0; unsigned OpNo = 0;
bool HasChain = NodeHasChain(N, ISE); bool HasChain = NodeHasProperty(N, SDNodeInfo::SDNPHasChain, ISE);
if (HasChain) { if (HasChain) {
OpNo = 1; OpNo = 1;
if (!isRoot) { if (!isRoot) {
@ -1919,7 +1925,7 @@ public:
OS << " if (" << RootName << OpNo << ".getOpcode() != " OS << " if (" << RootName << OpNo << ".getOpcode() != "
<< CInfo.getEnumName() << ") goto P" << PatternNo << "Fail;\n"; << CInfo.getEnumName() << ") goto P" << PatternNo << "Fail;\n";
EmitMatchCode(Child, RootName + utostr(OpNo), FoundChain); EmitMatchCode(Child, RootName + utostr(OpNo), FoundChain);
if (NodeHasChain(Child, 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()));
} }
@ -2078,13 +2084,16 @@ public:
const DAGInstruction &Inst = ISE.getInstruction(Op); const DAGInstruction &Inst = ISE.getInstruction(Op);
bool HasImpInputs = Inst.getNumImpOperands() > 0; bool HasImpInputs = Inst.getNumImpOperands() > 0;
bool HasImpResults = Inst.getNumImpResults() > 0; bool HasImpResults = Inst.getNumImpResults() > 0;
bool HasInFlag = II.hasInFlag || HasImpInputs; bool HasOptInFlag = isRoot &&
bool HasOutFlag = II.hasOutFlag || HasImpResults; NodeHasProperty(Pattern, SDNodeInfo::SDNPOptInFlag, ISE);
bool HasChain = II.hasCtrlDep; bool HasInFlag = isRoot &&
NodeHasProperty(Pattern, SDNodeInfo::SDNPInFlag, ISE);
bool HasOutFlag = HasImpResults ||
(isRoot && PatternHasProperty(Pattern, SDNodeInfo::SDNPOutFlag, ISE));
bool HasChain = II.hasCtrlDep ||
(isRoot && PatternHasProperty(Pattern, SDNodeInfo::SDNPHasChain, ISE));
if (isRoot && PatternHasCtrlDep(Pattern, ISE)) if (HasOutFlag || HasInFlag || HasOptInFlag || HasImpInputs)
HasChain = true;
if (HasInFlag || HasOutFlag)
OS << " SDOperand InFlag = SDOperand(0, 0);\n"; OS << " SDOperand InFlag = SDOperand(0, 0);\n";
// Determine operand emission order. Complex pattern first. // Determine operand emission order. Complex pattern first.
@ -2121,8 +2130,16 @@ public:
// Emit all the chain and CopyToReg stuff. // Emit all the chain and CopyToReg stuff.
if (HasChain) if (HasChain)
OS << " Chain = Select(Chain);\n"; OS << " Chain = Select(Chain);\n";
if (HasInFlag) if (HasImpInputs)
EmitInFlags(Pattern, "N", HasChain, II.hasInFlag, true); EmitCopyToRegs(Pattern, "N", HasChain, true);
if (HasInFlag || HasOptInFlag) {
unsigned FlagNo = (unsigned) HasChain + Pattern->getNumChildren();
if (HasOptInFlag)
OS << " if (N.getNumOperands() == " << FlagNo+1 << ") ";
else
OS << " ";
OS << "InFlag = Select(N.getOperand(" << FlagNo << "));\n";
}
unsigned NumResults = Inst.getNumResults(); unsigned NumResults = Inst.getNumResults();
unsigned ResNo = TmpNo++; unsigned ResNo = TmpNo++;
@ -2164,7 +2181,7 @@ public:
for (unsigned i = 0, e = Ops.size(); i != e; ++i) for (unsigned i = 0, e = Ops.size(); i != e; ++i)
OS << ", Tmp" << Ops[i]; OS << ", Tmp" << Ops[i];
if (HasChain) OS << ", Chain"; if (HasChain) OS << ", Chain";
if (HasInFlag) OS << ", InFlag"; if (HasInFlag || HasImpInputs) OS << ", InFlag";
OS << ");\n"; OS << ");\n";
unsigned ValNo = 0; unsigned ValNo = 0;
@ -2191,8 +2208,10 @@ 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(Pattern, ISE); bool NodeHasChain =
if (NodeHasChain(Pattern, ISE)) NodeHasProperty(Pattern, SDNodeInfo::SDNPHasChain, ISE);
bool AddedChain = HasChain && !NodeHasChain;
if (NodeHasChain)
OS << " CodeGenMap[N.getValue(" << ValNo++ << ")] = Chain;\n"; OS << " CodeGenMap[N.getValue(" << ValNo++ << ")] = Chain;\n";
if (FoldedChains.size() > 0) { if (FoldedChains.size() > 0) {
@ -2230,7 +2249,7 @@ public:
OS << ", MVT::Flag"; OS << ", MVT::Flag";
for (unsigned i = 0, e = Ops.size(); i != e; ++i) for (unsigned i = 0, e = Ops.size(); i != e; ++i)
OS << ", Tmp" << Ops[i]; OS << ", Tmp" << Ops[i];
if (HasInFlag) if (HasInFlag || HasImpInputs)
OS << ", InFlag"; OS << ", InFlag";
OS << ");\n"; OS << ");\n";
OS << " } else {\n"; OS << " } else {\n";
@ -2242,7 +2261,7 @@ public:
OS << ", MVT::Flag"; OS << ", MVT::Flag";
for (unsigned i = 0, e = Ops.size(); i != e; ++i) for (unsigned i = 0, e = Ops.size(); i != e; ++i)
OS << ", Tmp" << Ops[i]; OS << ", Tmp" << Ops[i];
if (HasInFlag) if (HasInFlag || HasImpInputs)
OS << ", InFlag"; OS << ", InFlag";
OS << ");\n"; OS << ");\n";
OS << " }\n"; OS << " }\n";
@ -2282,7 +2301,8 @@ public:
return true; return true;
} }
unsigned OpNo = (unsigned) NodeHasChain(Pat, ISE); unsigned OpNo =
(unsigned) NodeHasProperty(Pat, SDNodeInfo::SDNPHasChain, 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),
Prefix + utostr(OpNo))) Prefix + utostr(OpNo)))
@ -2291,16 +2311,17 @@ public:
} }
private: private:
/// EmitInFlags - Emit the flag operands for the DAG that is /// EmitCopyToRegs - Emit the flag operands for the DAG that is
/// being built. /// being built.
void EmitInFlags(TreePatternNode *N, const std::string &RootName, void EmitCopyToRegs(TreePatternNode *N, const std::string &RootName,
bool HasChain, bool HasInFlag, bool isRoot = false) { bool HasChain, bool isRoot = false) {
const CodeGenTarget &T = ISE.getTargetInfo(); const CodeGenTarget &T = ISE.getTargetInfo();
unsigned OpNo = (unsigned) NodeHasChain(N, ISE); unsigned OpNo =
(unsigned) NodeHasProperty(N, SDNodeInfo::SDNPHasChain, ISE);
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()) {
EmitInFlags(Child, RootName + utostr(OpNo), HasChain, HasInFlag); EmitCopyToRegs(Child, RootName + utostr(OpNo), HasChain);
} else { } else {
if (DefInit *DI = dynamic_cast<DefInit*>(Child->getLeafValue())) { if (DefInit *DI = dynamic_cast<DefInit*>(Child->getLeafValue())) {
Record *RR = DI->getDef(); Record *RR = DI->getDef();
@ -2330,12 +2351,6 @@ private:
} }
} }
} }
if (isRoot && HasInFlag) {
OS << " SDOperand " << RootName << OpNo << " = " << RootName
<< ".getOperand(" << OpNo << ");\n";
OS << " InFlag = Select(" << RootName << OpNo << ");\n";
}
} }
/// EmitCopyFromRegs - Emit code to copy result to physical registers /// EmitCopyFromRegs - Emit code to copy result to physical registers

View File

@ -102,7 +102,8 @@ namespace llvm {
} }
// SelectionDAG node properties. // SelectionDAG node properties.
enum SDNP { SDNPCommutative, SDNPAssociative, SDNPHasChain }; enum SDNP { SDNPCommutative, SDNPAssociative, SDNPHasChain,
SDNPOutFlag, SDNPInFlag, SDNPOptInFlag };
/// hasProperty - Return true if this node has the specified property. /// hasProperty - Return true if this node has the specified property.
/// ///