diff options
| author | Evan Cheng <evan.cheng@apple.com> | 2008-10-17 21:00:09 +0000 |
|---|---|---|
| committer | Evan Cheng <evan.cheng@apple.com> | 2008-10-17 21:00:09 +0000 |
| commit | b89be6150a8ea38fdaa2a242f6442e2d73326dab (patch) | |
| tree | cba747193ae2139ece5dfb5e25b79d64208c7c60 /utils/TableGen | |
| parent | af42fe36acaf21958bd283f7327a068bbd1016ba (diff) | |
Add RCBarriers to TargetInstrDesc. It's a list of register classes the given instruction can "clobber". For example, on x86 the call instruction can modify all of the XMM and fp stack registers.
TableGen has been taught to generate the lists from instruction definitions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@57722 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils/TableGen')
| -rw-r--r-- | utils/TableGen/InstrInfoEmitter.cpp | 56 | ||||
| -rw-r--r-- | utils/TableGen/InstrInfoEmitter.h | 5 |
2 files changed, 60 insertions, 1 deletions
diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp index c29f5c48bf..705901f91d 100644 --- a/utils/TableGen/InstrInfoEmitter.cpp +++ b/utils/TableGen/InstrInfoEmitter.cpp @@ -27,6 +27,14 @@ static void PrintDefList(const std::vector<Record*> &Uses, OS << "0 };\n"; } +static void PrintBarriers(std::vector<Record*> &Barriers, + unsigned Num, std::ostream &OS) { + OS << "static const TargetRegisterClass* Barriers" << Num << "[] = { "; + for (unsigned i = 0, e = Barriers.size(); i != e; ++i) + OS << "&" << getQualifiedName(Barriers[i]) << "RegClass, "; + OS << "NULL };\n"; +} + //===----------------------------------------------------------------------===// // Instruction Itinerary Information. //===----------------------------------------------------------------------===// @@ -137,6 +145,33 @@ void InstrInfoEmitter::EmitOperandInfo(std::ostream &OS, } } +void InstrInfoEmitter::DetectRegisterClassBarriers(std::vector<Record*> &Defs, + const std::vector<CodeGenRegisterClass> &RCs, + std::vector<Record*> &Barriers) { + std::set<Record*> DefSet; + unsigned NumDefs = Defs.size(); + for (unsigned i = 0; i < NumDefs; ++i) + DefSet.insert(Defs[i]); + + for (unsigned i = 0, e = RCs.size(); i != e; ++i) { + const CodeGenRegisterClass &RC = RCs[i]; + unsigned NumRegs = RC.Elements.size(); + if (NumRegs > NumDefs) + continue; // Can't possibly clobber this RC. + + bool Clobber = true; + for (unsigned j = 0; j < NumRegs; ++j) { + Record *Reg = RC.Elements[j]; + if (!DefSet.count(Reg)) { + Clobber = false; + break; + } + } + if (Clobber) + Barriers.push_back(RC.TheDef); + } +} + //===----------------------------------------------------------------------===// // Main Output. //===----------------------------------------------------------------------===// @@ -151,10 +186,14 @@ void InstrInfoEmitter::run(std::ostream &OS) { CodeGenTarget &Target = CDP.getTargetInfo(); const std::string &TargetName = Target.getName(); Record *InstrInfo = Target.getInstructionSet(); + const std::vector<CodeGenRegisterClass> &RCs = Target.getRegisterClasses(); // Keep track of all of the def lists we have emitted already. std::map<std::vector<Record*>, unsigned> EmittedLists; unsigned ListNumber = 0; + std::map<std::vector<Record*>, unsigned> EmittedBarriers; + unsigned BarrierNumber = 0; + std::map<Record*, unsigned> BarriersMap; // Emit all of the instruction's implicit uses and defs. for (CodeGenTarget::inst_iterator II = Target.inst_begin(), @@ -167,6 +206,14 @@ void InstrInfoEmitter::run(std::ostream &OS) { } std::vector<Record*> Defs = Inst->getValueAsListOfDefs("Defs"); if (!Defs.empty()) { + std::vector<Record*> RCBarriers; + DetectRegisterClassBarriers(Defs, RCs, RCBarriers); + if (!RCBarriers.empty()) { + unsigned &IB = EmittedBarriers[RCBarriers]; + if (!IB) PrintBarriers(RCBarriers, IB = ++BarrierNumber, OS); + BarriersMap.insert(std::make_pair(Inst, IB)); + } + unsigned &IL = EmittedLists[Defs]; if (!IL) PrintDefList(Defs, IL = ++ListNumber, OS); } @@ -186,7 +233,7 @@ void InstrInfoEmitter::run(std::ostream &OS) { for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) emitRecord(*NumberedInstructions[i], i, InstrInfo, EmittedLists, - OperandInfoIDs, OS); + BarriersMap, OperandInfoIDs, OS); OS << "};\n"; OS << "} // End llvm namespace \n"; } @@ -194,6 +241,7 @@ void InstrInfoEmitter::run(std::ostream &OS) { void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, Record *InstrInfo, std::map<std::vector<Record*>, unsigned> &EmittedLists, + std::map<Record*, unsigned> &BarriersMap, const OperandInfoMapTy &OpInfo, std::ostream &OS) { int MinOperands = 0; @@ -257,6 +305,12 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, else OS << "ImplicitList" << EmittedLists[DefList] << ", "; + std::map<Record*, unsigned>::iterator BI = BarriersMap.find(Inst.TheDef); + if (BI == BarriersMap.end()) + OS << "NULL, "; + else + OS << "Barriers" << BI->second << ", "; + // Emit the operand info. std::vector<std::string> OperandInfo = GetOperandInfo(Inst); if (OperandInfo.empty()) diff --git a/utils/TableGen/InstrInfoEmitter.h b/utils/TableGen/InstrInfoEmitter.h index 2dd3a0f44f..870ea0c587 100644 --- a/utils/TableGen/InstrInfoEmitter.h +++ b/utils/TableGen/InstrInfoEmitter.h @@ -44,6 +44,7 @@ private: void emitRecord(const CodeGenInstruction &Inst, unsigned Num, Record *InstrInfo, std::map<std::vector<Record*>, unsigned> &EL, + std::map<Record*, unsigned> &BM, const OperandInfoMapTy &OpInfo, std::ostream &OS); void emitShiftedValue(Record *R, StringInit *Val, IntInit *Shift, @@ -56,6 +57,10 @@ private: // Operand information. void EmitOperandInfo(std::ostream &OS, OperandInfoMapTy &OperandInfoIDs); std::vector<std::string> GetOperandInfo(const CodeGenInstruction &Inst); + + void DetectRegisterClassBarriers(std::vector<Record*> &Defs, + const std::vector<CodeGenRegisterClass> &RCs, + std::vector<Record*> &Barriers); }; } // End llvm namespace |
