diff options
author | Dan Gohman <gohman@apple.com> | 2009-04-13 15:38:05 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2009-04-13 15:38:05 +0000 |
commit | f8c7394781f7cf27ac52ca087e289436d36844da (patch) | |
tree | edffc35fe9d9eb709e5582e809b3ad24363847fa /utils | |
parent | 8433df36fb9566a00e643a6cb8f5e77af453ea81 (diff) | |
download | external_llvm-f8c7394781f7cf27ac52ca087e289436d36844da.zip external_llvm-f8c7394781f7cf27ac52ca087e289436d36844da.tar.gz external_llvm-f8c7394781f7cf27ac52ca087e289436d36844da.tar.bz2 |
Add a new TargetInstrInfo MachineInstr opcode, COPY_TO_SUBCLASS.
This will be used to replace things like X86's MOV32to32_.
Enhance ScheduleDAGSDNodesEmit to be more flexible and robust
in the presense of subregister superclasses and subclasses. It
can now cope with the definition of a virtual register being in
a subclass of a use.
Re-introduce the code for recording register superreg classes and
subreg classes. This is needed because when subreg extracts and
inserts get coalesced away, the virtual registers are left in
the correct subclass.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@68961 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r-- | utils/TableGen/CodeEmitterGen.cpp | 13 | ||||
-rw-r--r-- | utils/TableGen/CodeGenDAGPatterns.cpp | 6 | ||||
-rw-r--r-- | utils/TableGen/CodeGenTarget.cpp | 11 | ||||
-rw-r--r-- | utils/TableGen/DAGISelEmitter.cpp | 9 | ||||
-rw-r--r-- | utils/TableGen/InstrInfoEmitter.cpp | 3 | ||||
-rw-r--r-- | utils/TableGen/RegisterInfoEmitter.cpp | 79 |
6 files changed, 113 insertions, 8 deletions
diff --git a/utils/TableGen/CodeEmitterGen.cpp b/utils/TableGen/CodeEmitterGen.cpp index ae4a6aa..912617b 100644 --- a/utils/TableGen/CodeEmitterGen.cpp +++ b/utils/TableGen/CodeEmitterGen.cpp @@ -33,8 +33,9 @@ void CodeEmitterGen::reverseBits(std::vector<Record*> &Insts) { R->getName() == "EXTRACT_SUBREG" || R->getName() == "INSERT_SUBREG" || R->getName() == "IMPLICIT_DEF" || - R->getName() == "SUBREG_TO_REG") continue; - + R->getName() == "SUBREG_TO_REG" || + R->getName() == "COPY_TO_SUBCLASS") continue; + BitsInit *BI = R->getValueAsBitsInit("Inst"); unsigned numBits = BI->getNumBits(); @@ -109,7 +110,8 @@ void CodeEmitterGen::run(std::ostream &o) { R->getName() == "EXTRACT_SUBREG" || R->getName() == "INSERT_SUBREG" || R->getName() == "IMPLICIT_DEF" || - R->getName() == "SUBREG_TO_REG") { + R->getName() == "SUBREG_TO_REG" || + R->getName() == "COPY_TO_SUBCLASS") { o << " 0U,\n"; continue; } @@ -146,8 +148,9 @@ void CodeEmitterGen::run(std::ostream &o) { InstName == "EXTRACT_SUBREG" || InstName == "INSERT_SUBREG" || InstName == "IMPLICIT_DEF" || - InstName == "SUBREG_TO_REG") continue; - + InstName == "SUBREG_TO_REG" || + InstName == "COPY_TO_SUBCLASS") continue; + BitsInit *BI = R->getValueAsBitsInit("Inst"); const std::vector<RecordVal> &Vals = R->getValues(); CodeGenInstruction &CGI = Target.getInstruction(InstName); diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index 5bb4ddb..eb0b099 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -884,6 +884,12 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { MadeChange = getChild(i)->ApplyTypeConstraints(TP, NotRegisters); MadeChange |= UpdateNodeType(MVT::isVoid, TP); return MadeChange; + } else if (getOperator()->getName() == "COPY_TO_SUBCLASS") { + bool MadeChange = false; + MadeChange |= getChild(0)->ApplyTypeConstraints(TP, NotRegisters); + MadeChange |= getChild(1)->ApplyTypeConstraints(TP, NotRegisters); + MadeChange |= UpdateNodeType(getChild(1)->getTypeNum(0), TP); + return MadeChange; } else if (const CodeGenIntrinsic *Int = getIntrinsicInfo(CDP)) { bool MadeChange = false; diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp index 9ef64d6..c5d4c49 100644 --- a/utils/TableGen/CodeGenTarget.cpp +++ b/utils/TableGen/CodeGenTarget.cpp @@ -344,7 +344,12 @@ getInstructionsByEnumValue(std::vector<const CodeGenInstruction*> if (I == Instructions.end()) throw "Could not find 'SUBREG_TO_REG' instruction!"; const CodeGenInstruction *SUBREG_TO_REG = &I->second; - + + I = getInstructions().find("COPY_TO_SUBCLASS"); + if (I == Instructions.end()) + throw "Could not find 'COPY_TO_SUBCLASS' instruction!"; + const CodeGenInstruction *COPY_TO_SUBCLASS = &I->second; + // Print out the rest of the instructions now. NumberedInstructions.push_back(PHI); NumberedInstructions.push_back(INLINEASM); @@ -356,6 +361,7 @@ getInstructionsByEnumValue(std::vector<const CodeGenInstruction*> NumberedInstructions.push_back(INSERT_SUBREG); NumberedInstructions.push_back(IMPLICIT_DEF); NumberedInstructions.push_back(SUBREG_TO_REG); + NumberedInstructions.push_back(COPY_TO_SUBCLASS); for (inst_iterator II = inst_begin(), E = inst_end(); II != E; ++II) if (&II->second != PHI && &II->second != INLINEASM && @@ -366,7 +372,8 @@ getInstructionsByEnumValue(std::vector<const CodeGenInstruction*> &II->second != EXTRACT_SUBREG && &II->second != INSERT_SUBREG && &II->second != IMPLICIT_DEF && - &II->second != SUBREG_TO_REG) + &II->second != SUBREG_TO_REG && + &II->second != COPY_TO_SUBCLASS) NumberedInstructions.push_back(&II->second); } diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp index 63912a1..3335d00 100644 --- a/utils/TableGen/DAGISelEmitter.cpp +++ b/utils/TableGen/DAGISelEmitter.cpp @@ -918,6 +918,15 @@ public: getEnumName(N->getTypeNum(0)) + ");"); NodeOps.push_back("Tmp" + utostr(ResNo)); return NodeOps; + } else if (DI->getDef()->isSubClassOf("RegisterClass")) { + // Handle a reference to a register class. This is used + // in COPY_TO_SUBREG instructions. + emitCode("SDValue Tmp" + utostr(ResNo) + + " = CurDAG->getTargetConstant(" + + getQualifiedName(DI->getDef()) + "RegClassID, " + + "MVT::i32);"); + NodeOps.push_back("Tmp" + utostr(ResNo)); + return NodeOps; } } else if (IntInit *II = dynamic_cast<IntInit*>(N->getLeafValue())) { unsigned ResNo = TmpNo++; diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp index 6201690..1a32828 100644 --- a/utils/TableGen/InstrInfoEmitter.cpp +++ b/utils/TableGen/InstrInfoEmitter.cpp @@ -340,7 +340,8 @@ void InstrInfoEmitter::emitShiftedValue(Record *R, StringInit *Val, R->getName() != "EXTRACT_SUBREG" && R->getName() != "INSERT_SUBREG" && R->getName() != "IMPLICIT_DEF" && - R->getName() != "SUBREG_TO_REG") + R->getName() != "SUBREG_TO_REG" && + R->getName() != "COPY_TO_SUBCLASS") throw R->getName() + " doesn't have a field named '" + Val->getValue() + "'!"; return; diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index d45f565..3c3b2e8 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -240,8 +240,85 @@ void RegisterInfoEmitter::run(std::ostream &OS) { << RegisterClasses[i].getName() << "RegClass;\n"; std::map<unsigned, std::set<unsigned> > SuperClassMap; + std::map<unsigned, std::set<unsigned> > SuperRegClassMap; OS << "\n"; + // Emit the sub-register classes for each RegisterClass + for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { + const CodeGenRegisterClass &RC = RegisterClasses[rc]; + + // Give the register class a legal C name if it's anonymous. + std::string Name = RC.TheDef->getName(); + + OS << " // " << Name + << " Sub-register Classes...\n" + << " static const TargetRegisterClass* const " + << Name << "SubRegClasses [] = {\n "; + + bool Empty = true; + + for (unsigned subrc = 0, subrcMax = RC.SubRegClasses.size(); + subrc != subrcMax; ++subrc) { + unsigned rc2 = 0, e2 = RegisterClasses.size(); + for (; rc2 != e2; ++rc2) { + const CodeGenRegisterClass &RC2 = RegisterClasses[rc2]; + if (RC.SubRegClasses[subrc]->getName() == RC2.getName()) { + if (!Empty) + OS << ", "; + OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass"; + Empty = false; + + std::map<unsigned, std::set<unsigned> >::iterator SCMI = + SuperRegClassMap.find(rc2); + if (SCMI == SuperRegClassMap.end()) { + SuperRegClassMap.insert(std::make_pair(rc2, + std::set<unsigned>())); + SCMI = SuperRegClassMap.find(rc2); + } + SCMI->second.insert(rc); + break; + } + } + if (rc2 == e2) + throw "Register Class member '" + + RC.SubRegClasses[subrc]->getName() + + "' is not a valid RegisterClass!"; + } + + OS << (!Empty ? ", " : "") << "NULL"; + OS << "\n };\n\n"; + } + + // Emit the super-register classes for each RegisterClass + for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { + const CodeGenRegisterClass &RC = RegisterClasses[rc]; + + // Give the register class a legal C name if it's anonymous. + std::string Name = RC.TheDef->getName(); + + OS << " // " << Name + << " Super-register Classes...\n" + << " static const TargetRegisterClass* const " + << Name << "SuperRegClasses [] = {\n "; + + bool Empty = true; + std::map<unsigned, std::set<unsigned> >::iterator I = + SuperRegClassMap.find(rc); + if (I != SuperRegClassMap.end()) { + for (std::set<unsigned>::iterator II = I->second.begin(), + EE = I->second.end(); II != EE; ++II) { + const CodeGenRegisterClass &RC2 = RegisterClasses[*II]; + if (!Empty) + OS << ", "; + OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass"; + Empty = false; + } + } + + OS << (!Empty ? ", " : "") << "NULL"; + OS << "\n };\n\n"; + } + // Emit the sub-classes array for each RegisterClass for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { const CodeGenRegisterClass &RC = RegisterClasses[rc]; @@ -323,6 +400,8 @@ void RegisterInfoEmitter::run(std::ostream &OS) { << RC.getName() + "VTs" << ", " << RC.getName() + "Subclasses" << ", " << RC.getName() + "Superclasses" << ", " + << RC.getName() + "SubRegClasses" << ", " + << RC.getName() + "SuperRegClasses" << ", " << RC.SpillSize/8 << ", " << RC.SpillAlignment/8 << ", " << RC.CopyCost << ", " |