X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FRegisterInfoEmitter.cpp;h=487890d374dc3dc77d210b06f003bb56e79123c3;hb=551ccae044b0ff658fe629dd67edd5ffe75d10e8;hp=043fb3b5bebd20ff33492ba5b4e49a2749cff60a;hpb=a8af7799dd4b9dda7016f72b2e5f7b7d07780a8a;p=oota-llvm.git diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index 043fb3b5beb..487890d374d 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -1,4 +1,11 @@ //===- RegisterInfoEmitter.cpp - Generate a Register File Desc. -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// // // This tablegen backend is responsible for emitting a description of a target // register file for a code generator. It uses instances of the Register, @@ -7,82 +14,80 @@ //===----------------------------------------------------------------------===// #include "RegisterInfoEmitter.h" +#include "CodeGenTarget.h" +#include "CodeGenRegisters.h" #include "Record.h" -#include "Support/StringExtras.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/STLExtras.h" #include - -static void EmitSourceHeader(const std::string &Desc, std::ostream &o) { - o << "//===- TableGen'erated file -------------------------------------*-" - " C++ -*-===//\n//\n// " << Desc << "\n//\n// Automatically generate" - "d file, do not edit!\n//\n//===------------------------------------" - "----------------------------------===//\n\n"; -} +using namespace llvm; // runEnums - Print out enum values for all of the registers. void RegisterInfoEmitter::runEnums(std::ostream &OS) { - std::vector Registers = Records.getAllDerivedDefinitions("Register"); - - if (Registers.size() == 0) - throw std::string("No 'Register' subclasses defined!"); + CodeGenTarget Target; + const std::vector &Registers = Target.getRegisters(); - std::string Namespace = Registers[0]->getValueAsString("Namespace"); + std::string Namespace = Registers[0].TheDef->getValueAsString("Namespace"); - EmitSourceHeader("Target Register Enum Values", OS); + EmitSourceFileHeader("Target Register Enum Values", OS); + OS << "namespace llvm {\n\n"; if (!Namespace.empty()) OS << "namespace " << Namespace << " {\n"; OS << " enum {\n NoRegister,\n"; for (unsigned i = 0, e = Registers.size(); i != e; ++i) - OS << " " << Registers[i]->getName() << ", \t// " << i+1 << "\n"; + OS << " " << Registers[i].getName() << ", \t// " << i+1 << "\n"; OS << " };\n"; if (!Namespace.empty()) OS << "}\n"; -} - -static Record *getTarget(RecordKeeper &RC) { - std::vector Targets = RC.getAllDerivedDefinitions("Target"); - - if (Targets.size() != 1) - throw std::string("ERROR: Multiple subclasses of Target defined!"); - return Targets[0]; -} - -static std::string getQualifiedName(Record *R) { - std::string Namespace = R->getValueAsString("Namespace"); - if (Namespace.empty()) return R->getName(); - return Namespace + "::" + R->getName(); + OS << "} // End llvm namespace \n"; } void RegisterInfoEmitter::runHeader(std::ostream &OS) { - EmitSourceHeader("Register Information Header Fragment", OS); - - std::string ClassName = getTarget(Records)->getName() + "GenRegisterInfo"; + EmitSourceFileHeader("Register Information Header Fragment", OS); + CodeGenTarget Target; + const std::string &TargetName = Target.getName(); + std::string ClassName = TargetName + "GenRegisterInfo"; OS << "#include \"llvm/Target/MRegisterInfo.h\"\n\n"; + OS << "namespace llvm {\n\n"; + OS << "struct " << ClassName << " : public MRegisterInfo {\n" << " " << ClassName << "(int CallFrameSetupOpcode = -1, int CallFrameDestroyOpcode = -1);\n" << " const unsigned* getCalleeSaveRegs() const;\n" << "};\n\n"; + + std::vector RegisterClasses = + Records.getAllDerivedDefinitions("RegisterClass"); + + OS << "namespace " << TargetName << " { // Register classes\n"; + for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) { + const std::string &Name = RegisterClasses[i]->getName(); + if (Name.size() < 9 || Name[9] != '.') // Ignore anonymous classes + OS << " extern TargetRegisterClass *" << Name << "RegisterClass;\n"; + } + OS << "} // end of namespace " << TargetName << "\n\n"; + OS << "} // End llvm namespace \n"; } // RegisterInfoEmitter::run - Main register file description emitter. // void RegisterInfoEmitter::run(std::ostream &OS) { - EmitSourceHeader("Register Information Source Fragment", OS); + CodeGenTarget Target; + EmitSourceFileHeader("Register Information Source Fragment", OS); + + OS << "namespace llvm {\n\n"; // Start out by emitting each of the register classes... to do this, we build // a set of registers which belong to a register class, this is to ensure that // each register is only in a single register class. // - std::vector RegisterClasses = - Records.getAllDerivedDefinitions("RegisterClass"); - - std::vector Registers = Records.getAllDerivedDefinitions("Register"); - Record *RegisterClass = Records.getClass("Register"); + const std::vector &RegisterClasses = + Target.getRegisterClasses(); std::set RegistersFound; std::vector RegClassNames; @@ -90,9 +95,14 @@ void RegisterInfoEmitter::run(std::ostream &OS) { // Loop over all of the register classes... emitting each one. OS << "namespace { // Register classes...\n"; + // RegClassesBelongedTo - Keep track of which register classes each reg + // belongs to. + std::multimap RegClassesBelongedTo; + for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { - Record *RC = RegisterClasses[rc]; - std::string Name = RC->getName(); + const CodeGenRegisterClass &RC = RegisterClasses[rc]; + + std::string Name = RC.getName(); if (Name.size() > 9 && Name[9] == '.') { static unsigned AnonCounter = 0; Name = "AnonRegClass_"+utostr(AnonCounter++); @@ -103,35 +113,24 @@ void RegisterInfoEmitter::run(std::ostream &OS) { // Emit the register list now... OS << " // " << Name << " Register Class...\n const unsigned " << Name << "[] = {\n "; - ListInit *RegList = RC->getValueAsListInit("MemberList"); - for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) { - DefInit *RegDef = dynamic_cast(RegList->getElement(i)); - if (!RegDef) throw "Register class member is not a record!"; - Record *Reg = RegDef->getDef(); - if (!Reg->isSubClassOf(RegisterClass)) - throw "Register Class member '" + Reg->getName() + - " does not derive from the Register class!"; + for (unsigned i = 0, e = RC.Elements.size(); i != e; ++i) { + Record *Reg = RC.Elements[i]; if (RegistersFound.count(Reg)) throw "Register '" + Reg->getName() + "' included in multiple register classes!"; RegistersFound.insert(Reg); OS << getQualifiedName(Reg) << ", "; + + // Keep track of which regclasses this register is in. + RegClassesBelongedTo.insert(std::make_pair(Reg, &RC)); } OS << "\n };\n\n"; OS << " struct " << Name << "Class : public TargetRegisterClass {\n" << " " << Name << "Class() : TargetRegisterClass(" - << RC->getValueAsInt("Size")/8 << ", " << RC->getValueAsInt("Alignment") - << ", " << Name << ", " << Name << " + " << RegList->getSize() - << ") {}\n"; - - if (CodeInit *CI = dynamic_cast(RC->getValueInit("Methods"))) - OS << CI->getValue(); - else - throw "Expected 'code' fragment for 'Methods' value in register class '"+ - RC->getName() + "'!"; - - OS << " } " << Name << "Instance;\n\n"; + << RC.SpillSize/8 << ", " << RC.SpillAlignment/8 << ", " << Name << ", " + << Name << " + " << RC.Elements.size() << ") {}\n" + << RC.MethodDefinitions << " } " << Name << "Instance;\n\n"; } OS << " const TargetRegisterClass* const RegisterClasses[] = {\n"; @@ -143,7 +142,7 @@ void RegisterInfoEmitter::run(std::ostream &OS) { std::vector RegisterAliasesRecs = Records.getAllDerivedDefinitions("RegisterAliases"); std::map > RegisterAliases; - + for (unsigned i = 0, e = RegisterAliasesRecs.size(); i != e; ++i) { Record *AS = RegisterAliasesRecs[i]; Record *R = AS->getValueAsDef("Reg"); @@ -171,6 +170,8 @@ void RegisterInfoEmitter::run(std::ostream &OS) { if (!RegisterAliases.empty()) OS << "\n\n // Register Alias Sets...\n"; + // Emit the empty alias list + OS << " const unsigned Empty_AliasSet[] = { 0 };\n"; // Loop over all of the registers which have aliases, emitting the alias list // to memory. for (std::map >::iterator @@ -184,27 +185,64 @@ void RegisterInfoEmitter::run(std::ostream &OS) { OS << "\n const MRegisterDesc RegisterDescriptors[] = { // Descriptors\n"; OS << " { \"NOREG\",\t0,\t\t0,\t0 },\n"; + + // Now that register alias sets have been emitted, emit the register // descriptors now. + const std::vector &Registers = Target.getRegisters(); for (unsigned i = 0, e = Registers.size(); i != e; ++i) { - Record *Reg = Registers[i]; + const CodeGenRegister &Reg = Registers[i]; OS << " { \""; - if (!Reg->getValueAsString("Name").empty()) - OS << Reg->getValueAsString("Name"); + if (!Reg.TheDef->getValueAsString("Name").empty()) + OS << Reg.TheDef->getValueAsString("Name"); else - OS << Reg->getName(); + OS << Reg.getName(); OS << "\",\t"; - if (RegisterAliases.count(Reg)) - OS << Reg->getName() << "_AliasSet,\t"; + if (RegisterAliases.count(Reg.TheDef)) + OS << Reg.getName() << "_AliasSet,\t"; else - OS << "0,\t\t"; - OS << "0, 0 },\n"; + OS << "Empty_AliasSet,\t"; + + // Figure out what the size and alignment of the spill slots are for this + // reg. This may be explicitly declared in the register, or it may be + // inferred from the register classes it is part of. + std::multimap::iterator I, E; + tie(I, E) = RegClassesBelongedTo.equal_range(Reg.TheDef); + unsigned SpillSize = Reg.DeclaredSpillSize; + unsigned SpillAlign = Reg.DeclaredSpillAlignment; + for (; I != E; ++I) { // For each reg class this belongs to. + const CodeGenRegisterClass *RC = I->second; + if (SpillSize == 0) + SpillSize = RC->SpillSize; + else if (SpillSize != RC->SpillSize) + throw "Spill size for regclass '" + RC->getName() + + "' doesn't match spill sized already inferred for register '" + + Reg.getName() + "'!"; + if (SpillAlign == 0) + SpillAlign = RC->SpillAlignment; + else if (SpillAlign != RC->SpillAlignment) + throw "Spill alignment for regclass '" + RC->getName() + + "' doesn't match spill sized already inferred for register '" + + Reg.getName() + "'!"; + } + + OS << SpillSize << ", " << SpillAlign << " },\n"; } OS << " };\n"; // End of register descriptors... OS << "}\n\n"; // End of anonymous namespace... - Record *Target = getTarget(Records); - std::string ClassName = Target->getName() + "GenRegisterInfo"; + OS << "namespace " << Target.getName() << " { // Register classes\n"; + for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) { + const std::string &Name = RegisterClasses[i].getName(); + if (Name.size() < 9 || Name[9] != '.') // Ignore anonymous classes + OS << " TargetRegisterClass *" << Name << "RegisterClass = &" + << Name << "Instance;\n"; + } + OS << "} // end of namespace " << Target.getName() << "\n\n"; + + + + std::string ClassName = Target.getName() + "GenRegisterInfo"; // Emit the constructor of the class... OS << ClassName << "::" << ClassName @@ -217,11 +255,9 @@ void RegisterInfoEmitter::run(std::ostream &OS) { OS << "const unsigned* " << ClassName << "::getCalleeSaveRegs() const {\n" << " static const unsigned CalleeSaveRegs[] = {\n "; - ListInit *LI = Target->getValueAsListInit("CalleeSavedRegisters"); - for (unsigned i = 0, e = LI->getSize(); i != e; ++i) - if (DefInit *DI = dynamic_cast(LI->getElement(i))) - OS << getQualifiedName(DI->getDef()) << ", "; - else - throw "Expected register definition in CalleeSavedRegisters list!"; + const std::vector &CSR = Target.getCalleeSavedRegisters(); + for (unsigned i = 0, e = CSR.size(); i != e; ++i) + OS << getQualifiedName(CSR[i]) << ", "; OS << " 0\n };\n return CalleeSaveRegs;\n}\n\n"; + OS << "} // End llvm namespace \n"; }