mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-03-04 21:31:03 +00:00
Divide select methods into groups by SelectionDAG node opcodes (ISD::ADD,
X86ISD::CMP, etc.) instead of SDNode names (add, x86cmp, etc). We now allow multiple SDNodes to map to the same SelectionDAG node (e.g. store, indexed store). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31575 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
d8e01971d3
commit
892aaf8d74
@ -3374,19 +3374,16 @@ void DAGISelEmitter::EmitPatterns(std::vector<std::pair<PatternToMatch*,
|
|||||||
OS << std::string(Indent-2, ' ') << "}\n";
|
OS << std::string(Indent-2, ' ') << "}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string getOpcodeName(Record *Op, DAGISelEmitter &ISE) {
|
||||||
|
const SDNodeInfo &OpcodeInfo = ISE.getSDNodeInfo(Op);
|
||||||
|
return OpcodeInfo.getEnumName();
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string getLegalCName(std::string OpName) {
|
||||||
namespace {
|
std::string::size_type pos = OpName.find("::");
|
||||||
/// CompareByRecordName - An ordering predicate that implements less-than by
|
if (pos != std::string::npos)
|
||||||
/// comparing the names records.
|
OpName.replace(pos, 2, "_");
|
||||||
struct CompareByRecordName {
|
return OpName;
|
||||||
bool operator()(const Record *LHS, const Record *RHS) const {
|
|
||||||
// Sort by name first.
|
|
||||||
if (LHS->getName() < RHS->getName()) return true;
|
|
||||||
// If both names are equal, sort by pointer.
|
|
||||||
return LHS->getName() == RHS->getName() && LHS < RHS;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
|
void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
|
||||||
@ -3394,23 +3391,25 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
|
|||||||
if (!InstNS.empty()) InstNS += "::";
|
if (!InstNS.empty()) InstNS += "::";
|
||||||
|
|
||||||
// Group the patterns by their top-level opcodes.
|
// Group the patterns by their top-level opcodes.
|
||||||
std::map<Record*, std::vector<PatternToMatch*>,
|
std::map<std::string, std::vector<PatternToMatch*> > PatternsByOpcode;
|
||||||
CompareByRecordName> PatternsByOpcode;
|
|
||||||
// All unique target node emission functions.
|
// All unique target node emission functions.
|
||||||
std::map<std::string, unsigned> EmitFunctions;
|
std::map<std::string, unsigned> EmitFunctions;
|
||||||
for (unsigned i = 0, e = PatternsToMatch.size(); i != e; ++i) {
|
for (unsigned i = 0, e = PatternsToMatch.size(); i != e; ++i) {
|
||||||
TreePatternNode *Node = PatternsToMatch[i].getSrcPattern();
|
TreePatternNode *Node = PatternsToMatch[i].getSrcPattern();
|
||||||
if (!Node->isLeaf()) {
|
if (!Node->isLeaf()) {
|
||||||
PatternsByOpcode[Node->getOperator()].push_back(&PatternsToMatch[i]);
|
PatternsByOpcode[getOpcodeName(Node->getOperator(), *this)].
|
||||||
|
push_back(&PatternsToMatch[i]);
|
||||||
} else {
|
} else {
|
||||||
const ComplexPattern *CP;
|
const ComplexPattern *CP;
|
||||||
if (dynamic_cast<IntInit*>(Node->getLeafValue())) {
|
if (dynamic_cast<IntInit*>(Node->getLeafValue())) {
|
||||||
PatternsByOpcode[getSDNodeNamed("imm")].push_back(&PatternsToMatch[i]);
|
PatternsByOpcode[getOpcodeName(getSDNodeNamed("imm"), *this)].
|
||||||
|
push_back(&PatternsToMatch[i]);
|
||||||
} else if ((CP = NodeGetComplexPattern(Node, *this))) {
|
} else if ((CP = NodeGetComplexPattern(Node, *this))) {
|
||||||
std::vector<Record*> OpNodes = CP->getRootNodes();
|
std::vector<Record*> OpNodes = CP->getRootNodes();
|
||||||
for (unsigned j = 0, e = OpNodes.size(); j != e; j++) {
|
for (unsigned j = 0, e = OpNodes.size(); j != e; j++) {
|
||||||
PatternsByOpcode[OpNodes[j]]
|
PatternsByOpcode[getOpcodeName(OpNodes[j], *this)]
|
||||||
.insert(PatternsByOpcode[OpNodes[j]].begin(), &PatternsToMatch[i]);
|
.insert(PatternsByOpcode[getOpcodeName(OpNodes[j], *this)].begin(),
|
||||||
|
&PatternsToMatch[i]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "Unrecognized opcode '";
|
std::cerr << "Unrecognized opcode '";
|
||||||
@ -3432,11 +3431,10 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
|
|||||||
// Emit one Select_* method for each top-level opcode. We do this instead of
|
// Emit one Select_* method for each top-level opcode. We do this instead of
|
||||||
// emitting one giant switch statement to support compilers where this will
|
// emitting one giant switch statement to support compilers where this will
|
||||||
// result in the recursive functions taking less stack space.
|
// result in the recursive functions taking less stack space.
|
||||||
for (std::map<Record*, std::vector<PatternToMatch*>,
|
for (std::map<std::string, std::vector<PatternToMatch*> >::iterator
|
||||||
CompareByRecordName>::iterator PBOI = PatternsByOpcode.begin(),
|
PBOI = PatternsByOpcode.begin(), E = PatternsByOpcode.end();
|
||||||
E = PatternsByOpcode.end(); PBOI != E; ++PBOI) {
|
PBOI != E; ++PBOI) {
|
||||||
const std::string &OpName = PBOI->first->getName();
|
const std::string &OpName = PBOI->first;
|
||||||
const SDNodeInfo &OpcodeInfo = getSDNodeInfo(PBOI->first);
|
|
||||||
std::vector<PatternToMatch*> &PatternsOfOp = PBOI->second;
|
std::vector<PatternToMatch*> &PatternsOfOp = PBOI->second;
|
||||||
assert(!PatternsOfOp.empty() && "No patterns but map has entry?");
|
assert(!PatternsOfOp.empty() && "No patterns but map has entry?");
|
||||||
|
|
||||||
@ -3451,8 +3449,6 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
|
|||||||
for (unsigned i = 0, e = PatternsOfOp.size(); i != e; ++i) {
|
for (unsigned i = 0, e = PatternsOfOp.size(); i != e; ++i) {
|
||||||
PatternToMatch *Pat = PatternsOfOp[i];
|
PatternToMatch *Pat = PatternsOfOp[i];
|
||||||
TreePatternNode *SrcPat = Pat->getSrcPattern();
|
TreePatternNode *SrcPat = Pat->getSrcPattern();
|
||||||
if (OpcodeInfo.getNumResults() == 0 && SrcPat->getNumChildren() > 0)
|
|
||||||
SrcPat = SrcPat->getChild(0);
|
|
||||||
MVT::ValueType VT = SrcPat->getTypeNum(0);
|
MVT::ValueType VT = SrcPat->getTypeNum(0);
|
||||||
std::map<MVT::ValueType, std::vector<PatternToMatch*> >::iterator TI =
|
std::map<MVT::ValueType, std::vector<PatternToMatch*> >::iterator TI =
|
||||||
PatternsByType.find(VT);
|
PatternsByType.find(VT);
|
||||||
@ -3595,7 +3591,8 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
|
|||||||
} else
|
} else
|
||||||
OpVTI->second.push_back(OpVTStr);
|
OpVTI->second.push_back(OpVTStr);
|
||||||
|
|
||||||
OS << "SDNode *Select_" << OpName << (OpVTStr != "" ? "_" : "")
|
OS << "SDNode *Select_" << getLegalCName(OpName)
|
||||||
|
<< (OpVTStr != "" ? "_" : "")
|
||||||
<< OpVTStr << "(const SDOperand &N) {\n";
|
<< OpVTStr << "(const SDOperand &N) {\n";
|
||||||
|
|
||||||
// Loop through and reverse all of the CodeList vectors, as we will be
|
// Loop through and reverse all of the CodeList vectors, as we will be
|
||||||
@ -3616,9 +3613,9 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
|
|||||||
// catch the case where nothing handles a pattern.
|
// catch the case where nothing handles a pattern.
|
||||||
if (mightNotMatch) {
|
if (mightNotMatch) {
|
||||||
OS << " std::cerr << \"Cannot yet select: \";\n";
|
OS << " std::cerr << \"Cannot yet select: \";\n";
|
||||||
if (OpcodeInfo.getEnumName() != "ISD::INTRINSIC_W_CHAIN" &&
|
if (OpName != "ISD::INTRINSIC_W_CHAIN" &&
|
||||||
OpcodeInfo.getEnumName() != "ISD::INTRINSIC_WO_CHAIN" &&
|
OpName != "ISD::INTRINSIC_WO_CHAIN" &&
|
||||||
OpcodeInfo.getEnumName() != "ISD::INTRINSIC_VOID") {
|
OpName != "ISD::INTRINSIC_VOID") {
|
||||||
OS << " N.Val->dump(CurDAG);\n";
|
OS << " N.Val->dump(CurDAG);\n";
|
||||||
} else {
|
} else {
|
||||||
OS << " unsigned iid = cast<ConstantSDNode>(N.getOperand("
|
OS << " unsigned iid = cast<ConstantSDNode>(N.getOperand("
|
||||||
@ -3657,6 +3654,7 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
|
|||||||
<< "INSTRUCTION_LIST_END)) {\n"
|
<< "INSTRUCTION_LIST_END)) {\n"
|
||||||
<< " return NULL; // Already selected.\n"
|
<< " return NULL; // Already selected.\n"
|
||||||
<< " }\n\n"
|
<< " }\n\n"
|
||||||
|
<< " MVT::ValueType NVT = N.Val->getValueType(0);\n"
|
||||||
<< " switch (N.getOpcode()) {\n"
|
<< " switch (N.getOpcode()) {\n"
|
||||||
<< " default: break;\n"
|
<< " default: break;\n"
|
||||||
<< " case ISD::EntryToken: // These leaves remain the same.\n"
|
<< " case ISD::EntryToken: // These leaves remain the same.\n"
|
||||||
@ -3688,31 +3686,22 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
|
|||||||
|
|
||||||
// Loop over all of the case statements, emiting a call to each method we
|
// Loop over all of the case statements, emiting a call to each method we
|
||||||
// emitted above.
|
// emitted above.
|
||||||
for (std::map<Record*, std::vector<PatternToMatch*>,
|
for (std::map<std::string, std::vector<PatternToMatch*> >::iterator
|
||||||
CompareByRecordName>::iterator PBOI = PatternsByOpcode.begin(),
|
PBOI = PatternsByOpcode.begin(), E = PatternsByOpcode.end();
|
||||||
E = PatternsByOpcode.end(); PBOI != E; ++PBOI) {
|
PBOI != E; ++PBOI) {
|
||||||
const SDNodeInfo &OpcodeInfo = getSDNodeInfo(PBOI->first);
|
const std::string &OpName = PBOI->first;
|
||||||
const std::string &OpName = PBOI->first->getName();
|
|
||||||
// Potentially multiple versions of select for this opcode. One for each
|
// Potentially multiple versions of select for this opcode. One for each
|
||||||
// ValueType of the node (or its first true operand if it doesn't produce a
|
// ValueType of the node (or its first true operand if it doesn't produce a
|
||||||
// result.
|
// result.
|
||||||
std::map<std::string, std::vector<std::string> >::iterator OpVTI =
|
std::map<std::string, std::vector<std::string> >::iterator OpVTI =
|
||||||
OpcodeVTMap.find(OpName);
|
OpcodeVTMap.find(OpName);
|
||||||
std::vector<std::string> &OpVTs = OpVTI->second;
|
std::vector<std::string> &OpVTs = OpVTI->second;
|
||||||
OS << " case " << OpcodeInfo.getEnumName() << ": {\n";
|
OS << " case " << OpName << ": {\n";
|
||||||
if (OpVTs.size() == 1) {
|
if (OpVTs.size() == 1) {
|
||||||
std::string &VTStr = OpVTs[0];
|
std::string &VTStr = OpVTs[0];
|
||||||
OS << " return Select_" << OpName
|
OS << " return Select_" << getLegalCName(OpName)
|
||||||
<< (VTStr != "" ? "_" : "") << VTStr << "(N);\n";
|
<< (VTStr != "" ? "_" : "") << VTStr << "(N);\n";
|
||||||
} else {
|
} else {
|
||||||
if (OpcodeInfo.getNumResults())
|
|
||||||
OS << " MVT::ValueType NVT = N.Val->getValueType(0);\n";
|
|
||||||
else if (OpcodeInfo.hasProperty(SDNPHasChain))
|
|
||||||
OS << " MVT::ValueType NVT = (N.getNumOperands() > 1) ?"
|
|
||||||
<< " N.getOperand(1).Val->getValueType(0) : MVT::isVoid;\n";
|
|
||||||
else
|
|
||||||
OS << " MVT::ValueType NVT = (N.getNumOperands() > 0) ?"
|
|
||||||
<< " N.getOperand(0).Val->getValueType(0) : MVT::isVoid;\n";
|
|
||||||
int Default = -1;
|
int Default = -1;
|
||||||
OS << " switch (NVT) {\n";
|
OS << " switch (NVT) {\n";
|
||||||
for (unsigned i = 0, e = OpVTs.size(); i < e; ++i) {
|
for (unsigned i = 0, e = OpVTs.size(); i < e; ++i) {
|
||||||
@ -3722,12 +3711,12 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
OS << " case MVT::" << VTStr << ":\n"
|
OS << " case MVT::" << VTStr << ":\n"
|
||||||
<< " return Select_" << OpName
|
<< " return Select_" << getLegalCName(OpName)
|
||||||
<< "_" << VTStr << "(N);\n";
|
<< "_" << VTStr << "(N);\n";
|
||||||
}
|
}
|
||||||
OS << " default:\n";
|
OS << " default:\n";
|
||||||
if (Default != -1)
|
if (Default != -1)
|
||||||
OS << " return Select_" << OpName << "(N);\n";
|
OS << " return Select_" << getLegalCName(OpName) << "(N);\n";
|
||||||
else
|
else
|
||||||
OS << " break;\n";
|
OS << " break;\n";
|
||||||
OS << " }\n";
|
OS << " }\n";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user