aboutsummaryrefslogtreecommitdiff
path: root/utils/TableGen/InstrInfoEmitter.cpp
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2008-10-17 21:00:09 +0000
committerEvan Cheng <evan.cheng@apple.com>2008-10-17 21:00:09 +0000
commitb89be6150a8ea38fdaa2a242f6442e2d73326dab (patch)
treecba747193ae2139ece5dfb5e25b79d64208c7c60 /utils/TableGen/InstrInfoEmitter.cpp
parentaf42fe36acaf21958bd283f7327a068bbd1016ba (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/InstrInfoEmitter.cpp')
-rw-r--r--utils/TableGen/InstrInfoEmitter.cpp56
1 files changed, 55 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())