mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-13 14:35:54 +00:00
* 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:
parent
0573bb5fd4
commit
3d51fa3305
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user