diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-06-11 15:37:55 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-06-11 15:37:55 +0000 |
commit | 6f36fa981a59461466e12e5056ba209d289b81b1 (patch) | |
tree | 98c6c1505f31c05227dfbc7b6d84f991a9364ca5 | |
parent | 20aedcdfa35f4b6494d4990cf6dd4459d7172c49 (diff) |
Write llvm-tblgen backends as functions instead of sub-classes.
The TableGenBackend base class doesn't do much, and will be removed
completely soon.
Patch by Sean Silva!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@158311 91177308-0d34-0410-b5e6-96231b3b80d8
34 files changed, 912 insertions, 1082 deletions
diff --git a/include/llvm/TableGen/TableGenBackend.h b/include/llvm/TableGen/TableGenBackend.h index 3ebcd92d0e..751a7cf750 100644 --- a/include/llvm/TableGen/TableGenBackend.h +++ b/include/llvm/TableGen/TableGenBackend.h @@ -38,6 +38,10 @@ public: // Useful helper routines... }; +/// emitSourceFileHeader - Output a LLVM style file header to the specified +/// ostream. +void emitSourceFileHeader(StringRef Desc, raw_ostream &OS); + } // End llvm namespace #endif diff --git a/lib/TableGen/TableGenBackend.cpp b/lib/TableGen/TableGenBackend.cpp index 09bcc7a5b5..8117250819 100644 --- a/lib/TableGen/TableGenBackend.cpp +++ b/lib/TableGen/TableGenBackend.cpp @@ -19,9 +19,12 @@ void TableGenBackend::anchor() { } void TableGenBackend::EmitSourceFileHeader(StringRef Desc, raw_ostream &OS) const { + emitSourceFileHeader(Desc, OS); +} + +void llvm::emitSourceFileHeader(StringRef Desc, raw_ostream &OS) { OS << "//===- TableGen'erated file -------------------------------------*-" " C++ -*-===//\n//\n// " << Desc << "\n//\n// Automatically generate" "d file, do not edit!\n//\n//===------------------------------------" "----------------------------------===//\n\n"; } - diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index 96e882b19f..e980b1a7d9 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -96,7 +96,6 @@ // //===----------------------------------------------------------------------===// -#include "AsmMatcherEmitter.h" #include "CodeGenTarget.h" #include "StringToOffsetTable.h" #include "llvm/ADT/OwningPtr.h" @@ -111,6 +110,8 @@ #include "llvm/TableGen/Error.h" #include "llvm/TableGen/Record.h" #include "llvm/TableGen/StringMatcher.h" +#include "llvm/TableGen/TableGenBackend.h" +#include <cassert> #include <map> #include <set> using namespace llvm; @@ -123,6 +124,14 @@ namespace { class AsmMatcherInfo; struct SubtargetFeatureInfo; +class AsmMatcherEmitter { + RecordKeeper &Records; +public: + AsmMatcherEmitter(RecordKeeper &R) : Records(R) {} + + void run(raw_ostream &o); +}; + /// ClassInfo - Helper class for storing the information about a particular /// class of operands which can be matched. struct ClassInfo { @@ -642,7 +651,7 @@ public: } }; -} +} // End anonymous namespace void MatchableInfo::dump() { errs() << TheDef->getName() << " -- " << "flattened:\"" << AsmString <<"\"\n"; @@ -2353,8 +2362,6 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { // Write the output. - EmitSourceFileHeader("Assembly Matcher Source Fragment", OS); - // Information for the class declaration. OS << "\n#ifdef GET_ASSEMBLER_HEADER\n"; OS << "#undef GET_ASSEMBLER_HEADER\n"; @@ -2659,3 +2666,12 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << "#endif // GET_MATCHER_IMPLEMENTATION\n\n"; } + +namespace llvm { + +void EmitAsmMatcher(RecordKeeper &RK, raw_ostream &OS) { + emitSourceFileHeader("Assembly Matcher Source Fragment", OS); + AsmMatcherEmitter(RK).run(OS); +} + +} // End llvm namespace diff --git a/utils/TableGen/AsmMatcherEmitter.h b/utils/TableGen/AsmMatcherEmitter.h deleted file mode 100644 index e04ac103a4..0000000000 --- a/utils/TableGen/AsmMatcherEmitter.h +++ /dev/null @@ -1,31 +0,0 @@ -//===- AsmMatcherEmitter.h - Generate an assembly matcher -------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This tablegen backend emits a target specifier matcher for converting parsed -// assembly operands in the MCInst structures. -// -//===----------------------------------------------------------------------===// - -#ifndef ASMMATCHER_EMITTER_H -#define ASMMATCHER_EMITTER_H - -#include "llvm/TableGen/TableGenBackend.h" -#include <cassert> - -namespace llvm { - class AsmMatcherEmitter : public TableGenBackend { - RecordKeeper &Records; - public: - AsmMatcherEmitter(RecordKeeper &R) : Records(R) {} - - // run - Output the matcher, returning true on failure. - void run(raw_ostream &o); - }; -} -#endif diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp index d079b45e8d..bd153a855c 100644 --- a/utils/TableGen/AsmWriterEmitter.cpp +++ b/utils/TableGen/AsmWriterEmitter.cpp @@ -12,7 +12,6 @@ // //===----------------------------------------------------------------------===// -#include "AsmWriterEmitter.h" #include "AsmWriterInst.h" #include "CodeGenTarget.h" #include "StringToOffsetTable.h" @@ -22,9 +21,41 @@ #include "llvm/Support/MathExtras.h" #include "llvm/TableGen/Error.h" #include "llvm/TableGen/Record.h" +#include "llvm/TableGen/TableGenBackend.h" #include <algorithm> +#include <cassert> +#include <map> +#include <vector> using namespace llvm; +namespace { +class AsmWriterEmitter { + RecordKeeper &Records; + std::map<const CodeGenInstruction*, AsmWriterInst*> CGIAWIMap; + std::vector<const CodeGenInstruction*> NumberedInstructions; +public: + AsmWriterEmitter(RecordKeeper &R) : Records(R) {} + + void run(raw_ostream &o); + +private: + void EmitPrintInstruction(raw_ostream &o); + void EmitGetRegisterName(raw_ostream &o); + void EmitPrintAliasInstruction(raw_ostream &O); + + AsmWriterInst *getAsmWriterInstByID(unsigned ID) const { + assert(ID < NumberedInstructions.size()); + std::map<const CodeGenInstruction*, AsmWriterInst*>::const_iterator I = + CGIAWIMap.find(NumberedInstructions[ID]); + assert(I != CGIAWIMap.end() && "Didn't find inst!"); + return I->second; + } + void FindUniqueOperandCommands(std::vector<std::string> &UOC, + std::vector<unsigned> &InstIdxs, + std::vector<unsigned> &InstOpsUsed) const; +}; +} // end anonymous namespace + static void PrintCases(std::vector<std::pair<std::string, AsmWriterOperand> > &OpsToPrint, raw_ostream &O) { O << " case " << OpsToPrint.back().first << ": "; @@ -928,10 +959,17 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { } void AsmWriterEmitter::run(raw_ostream &O) { - EmitSourceFileHeader("Assembly Writer Source Fragment", O); - EmitPrintInstruction(O); EmitGetRegisterName(O); EmitPrintAliasInstruction(O); } + +namespace llvm { + +void EmitAsmWriter(RecordKeeper &RK, raw_ostream &OS) { + emitSourceFileHeader("Assembly Writer Source Fragment", OS); + AsmWriterEmitter(RK).run(OS); +} + +} // End llvm namespace diff --git a/utils/TableGen/AsmWriterEmitter.h b/utils/TableGen/AsmWriterEmitter.h deleted file mode 100644 index 9719b202fa..0000000000 --- a/utils/TableGen/AsmWriterEmitter.h +++ /dev/null @@ -1,54 +0,0 @@ -//===- AsmWriterEmitter.h - Generate an assembly writer ---------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This tablegen backend is responsible for emitting an assembly printer for the -// code generator. -// -//===----------------------------------------------------------------------===// - -#ifndef ASMWRITER_EMITTER_H -#define ASMWRITER_EMITTER_H - -#include "llvm/TableGen/TableGenBackend.h" -#include <map> -#include <vector> -#include <cassert> - -namespace llvm { - class AsmWriterInst; - class CodeGenInstruction; - - class AsmWriterEmitter : public TableGenBackend { - RecordKeeper &Records; - std::map<const CodeGenInstruction*, AsmWriterInst*> CGIAWIMap; - std::vector<const CodeGenInstruction*> NumberedInstructions; - public: - AsmWriterEmitter(RecordKeeper &R) : Records(R) {} - - // run - Output the asmwriter, returning true on failure. - void run(raw_ostream &o); - -private: - void EmitPrintInstruction(raw_ostream &o); - void EmitGetRegisterName(raw_ostream &o); - void EmitPrintAliasInstruction(raw_ostream &O); - - AsmWriterInst *getAsmWriterInstByID(unsigned ID) const { - assert(ID < NumberedInstructions.size()); - std::map<const CodeGenInstruction*, AsmWriterInst*>::const_iterator I = - CGIAWIMap.find(NumberedInstructions[ID]); - assert(I != CGIAWIMap.end() && "Didn't find inst!"); - return I->second; - } - void FindUniqueOperandCommands(std::vector<std::string> &UOC, - std::vector<unsigned> &InstIdxs, - std::vector<unsigned> &InstOpsUsed) const; - }; -} -#endif diff --git a/utils/TableGen/CallingConvEmitter.cpp b/utils/TableGen/CallingConvEmitter.cpp index afbb3a8708..e9c4bd30f9 100644 --- a/utils/TableGen/CallingConvEmitter.cpp +++ b/utils/TableGen/CallingConvEmitter.cpp @@ -12,13 +12,28 @@ // //===----------------------------------------------------------------------===// -#include "CallingConvEmitter.h" #include "CodeGenTarget.h" #include "llvm/TableGen/Record.h" +#include "llvm/TableGen/TableGenBackend.h" +#include <cassert> using namespace llvm; +namespace { +class CallingConvEmitter { + RecordKeeper &Records; +public: + explicit CallingConvEmitter(RecordKeeper &R) : Records(R) {} + + void run(raw_ostream &o); + +private: + void EmitCallingConv(Record *CC, raw_ostream &O); + void EmitAction(Record *Action, unsigned Indent, raw_ostream &O); + unsigned Counter; +}; +} // End anonymous namespace + void CallingConvEmitter::run(raw_ostream &O) { - EmitSourceFileHeader("Calling Convention Implementation Fragment", O); std::vector<Record*> CCs = Records.getAllDerivedDefinitions("CallingConv"); @@ -210,3 +225,12 @@ void CallingConvEmitter::EmitAction(Record *Action, } } } + +namespace llvm { + +void EmitCallingConv(RecordKeeper &RK, raw_ostream &OS) { + emitSourceFileHeader("Calling Convention Implementation Fragment", OS); + CallingConvEmitter(RK).run(OS); +} + +} // End llvm namespace diff --git a/utils/TableGen/CallingConvEmitter.h b/utils/TableGen/CallingConvEmitter.h deleted file mode 100644 index 7bddd6c93e..0000000000 --- a/utils/TableGen/CallingConvEmitter.h +++ /dev/null @@ -1,36 +0,0 @@ -//===- CallingConvEmitter.h - Generate calling conventions ------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This tablegen backend is responsible for emitting descriptions of the calling -// conventions supported by this target. -// -//===----------------------------------------------------------------------===// - -#ifndef CALLINGCONV_EMITTER_H -#define CALLINGCONV_EMITTER_H - -#include "llvm/TableGen/TableGenBackend.h" -#include <cassert> - -namespace llvm { - class CallingConvEmitter : public TableGenBackend { - RecordKeeper &Records; - public: - explicit CallingConvEmitter(RecordKeeper &R) : Records(R) {} - - // run - Output the asmwriter, returning true on failure. - void run(raw_ostream &o); - - private: - void EmitCallingConv(Record *CC, raw_ostream &O); - void EmitAction(Record *Action, unsigned Indent, raw_ostream &O); - unsigned Counter; - }; -} -#endif diff --git a/utils/TableGen/CodeEmitterGen.cpp b/utils/TableGen/CodeEmitterGen.cpp index 3943e8a40f..31a39b1f04 100644 --- a/utils/TableGen/CodeEmitterGen.cpp +++ b/utils/TableGen/CodeEmitterGen.cpp @@ -13,13 +13,15 @@ // //===----------------------------------------------------------------------===// -#include "CodeEmitterGen.h" #include "CodeGenTarget.h" #include "llvm/TableGen/Record.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/TableGen/TableGenBackend.h" #include <map> +#include <string> +#include <vector> using namespace llvm; // FIXME: Somewhat hackish to use a command line option for this. There should @@ -30,6 +32,27 @@ MCEmitter("mc-emitter", cl::desc("Generate CodeEmitter for use with the MC library."), cl::init(false)); +namespace { + +class CodeEmitterGen { + RecordKeeper &Records; +public: + CodeEmitterGen(RecordKeeper &R) : Records(R) {} + + void run(raw_ostream &o); +private: + void emitMachineOpEmitter(raw_ostream &o, const std::string &Namespace); + void emitGetValueBit(raw_ostream &o, const std::string &Namespace); + void reverseBits(std::vector<Record*> &Insts); + int getVariableBit(const std::string &VarName, BitsInit *BI, int bit); + std::string getInstructionCase(Record *R, CodeGenTarget &Target); + void AddCodeToMergeInOperand(Record *R, BitsInit *BI, + const std::string &VarName, + unsigned &NumberedOp, + std::string &Case, CodeGenTarget &Target); + +}; + void CodeEmitterGen::reverseBits(std::vector<Record*> &Insts) { for (std::vector<Record*>::iterator I = Insts.begin(), E = Insts.end(); I != E; ++I) { @@ -214,7 +237,6 @@ void CodeEmitterGen::run(raw_ostream &o) { // For little-endian instruction bit encodings, reverse the bit order if (Target.isLittleEndianEncoding()) reverseBits(Insts); - EmitSourceFileHeader("Machine Code Emitter", o); const std::vector<const CodeGenInstruction*> &NumberedInstructions = Target.getInstructionsByEnumValue(); @@ -304,3 +326,14 @@ void CodeEmitterGen::run(raw_ostream &o) { << " return Value;\n" << "}\n\n"; } + +} // End anonymous namespace + +namespace llvm { + +void EmitCodeEmitter(RecordKeeper &RK, raw_ostream &OS) { + emitSourceFileHeader("Machine Code Emitter", OS); + CodeEmitterGen(RK).run(OS); +} + +} // End llvm namespace diff --git a/utils/TableGen/CodeEmitterGen.h b/utils/TableGen/CodeEmitterGen.h deleted file mode 100644 index 7f6ee2a1b4..0000000000 --- a/utils/TableGen/CodeEmitterGen.h +++ /dev/null @@ -1,49 +0,0 @@ -//===- CodeEmitterGen.h - Code Emitter Generator ----------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// FIXME: document -// -//===----------------------------------------------------------------------===// - -#ifndef CODEMITTERGEN_H -#define CODEMITTERGEN_H - -#include "llvm/TableGen/TableGenBackend.h" -#include <vector> -#include <string> - -namespace llvm { - -class RecordVal; -class BitsInit; -class CodeGenTarget; - -class CodeEmitterGen : public TableGenBackend { - RecordKeeper &Records; -public: - CodeEmitterGen(RecordKeeper &R) : Records(R) {} - - // run - Output the code emitter - void run(raw_ostream &o); -private: - void emitMachineOpEmitter(raw_ostream &o, const std::string &Namespace); - void emitGetValueBit(raw_ostream &o, const std::string &Namespace); - void reverseBits(std::vector<Record*> &Insts); - int getVariableBit(const std::string &VarName, BitsInit *BI, int bit); - std::string getInstructionCase(Record *R, CodeGenTarget &Target); - void - AddCodeToMergeInOperand(Record *R, BitsInit *BI, const std::string &VarName, - unsigned &NumberedOp, - std::string &Case, CodeGenTarget &Target); - -}; - -} // End llvm namespace - -#endif diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp index 7db9003499..b47dd71e88 100644 --- a/utils/TableGen/DAGISelEmitter.cpp +++ b/utils/TableGen/DAGISelEmitter.cpp @@ -11,12 +11,24 @@ // //===----------------------------------------------------------------------===// -#include "DAGISelEmitter.h" +#include "CodeGenDAGPatterns.h" #include "DAGISelMatcher.h" -#include "llvm/TableGen/Record.h" #include "llvm/Support/Debug.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/TableGenBackend.h" using namespace llvm; +namespace { +/// DAGISelEmitter - The top-level class which coordinates construction +/// and emission of the instruction selector. +class DAGISelEmitter { + CodeGenDAGPatterns CGP; +public: + explicit DAGISelEmitter(RecordKeeper &R) : CGP(R) {} + void run(raw_ostream &OS); +}; +} // End anonymous namespace + //===----------------------------------------------------------------------===// // DAGISelEmitter Helper methods // @@ -104,11 +116,11 @@ struct PatternSortingPredicate { return LHS->ID < RHS->ID; } }; -} +} // End anonymous namespace void DAGISelEmitter::run(raw_ostream &OS) { - EmitSourceFileHeader("DAG Instruction Selector for the " + + emitSourceFileHeader("DAG Instruction Selector for the " + CGP.getTargetInfo().getName() + " target", OS); OS << "// *** NOTE: This file is #included into the middle of the target\n" @@ -153,3 +165,11 @@ void DAGISelEmitter::run(raw_ostream &OS) { EmitMatcherTable(TheMatcher, CGP, OS); delete TheMatcher; } + +namespace llvm { + +void EmitDAGISel(RecordKeeper &RK, raw_ostream &OS) { + DAGISelEmitter(RK).run(OS); +} + +} // End llvm namespace diff --git a/utils/TableGen/DAGISelEmitter.h b/utils/TableGen/DAGISelEmitter.h deleted file mode 100644 index 5204bb135d..0000000000 --- a/utils/TableGen/DAGISelEmitter.h +++ /dev/null @@ -1,36 +0,0 @@ -//===- DAGISelEmitter.h - Generate an instruction selector ------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This tablegen backend emits a DAG instruction selector. -// -//===----------------------------------------------------------------------===// - -#ifndef DAGISEL_EMITTER_H -#define DAGISEL_EMITTER_H - -#include "llvm/TableGen/TableGenBackend.h" -#include "CodeGenDAGPatterns.h" - -namespace llvm { - -/// DAGISelEmitter - The top-level class which coordinates construction -/// and emission of the instruction selector. -/// -class DAGISelEmitter : public TableGenBackend { - CodeGenDAGPatterns CGP; -public: - explicit DAGISelEmitter(RecordKeeper &R) : CGP(R) {} - - // run - Output the isel, returning true on failure. - void run(raw_ostream &OS); -}; - -} // End llvm namespace - -#endif diff --git a/utils/TableGen/DFAPacketizerEmitter.cpp b/utils/TableGen/DFAPacketizerEmitter.cpp index 4abf54ebae..26ab76390e 100644 --- a/utils/TableGen/DFAPacketizerEmitter.cpp +++ b/utils/TableGen/DFAPacketizerEmitter.cpp @@ -15,14 +15,47 @@ // //===----------------------------------------------------------------------===// -#include "llvm/TableGen/Record.h" #include "CodeGenTarget.h" -#include "DFAPacketizerEmitter.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/TableGenBackend.h" #include <list> - +#include <map> +#include <string> using namespace llvm; // +// class DFAPacketizerEmitter: class that generates and prints out the DFA +// for resource tracking. +// +namespace { +class DFAPacketizerEmitter { +private: + std::string TargetName; + // + // allInsnClasses is the set of all possible resources consumed by an + // InstrStage. + // + DenseSet<unsigned> allInsnClasses; + RecordKeeper &Records; + +public: + DFAPacketizerEmitter(RecordKeeper &R); + + // + // collectAllInsnClasses: Populate allInsnClasses which is a set of units + // used in each stage. + // + void collectAllInsnClasses(const std::string &Name, + Record *ItinData, + unsigned &NStages, + raw_ostream &OS); + + void run(raw_ostream &OS); +}; +} // End anonymous namespace. + +// // // State represents the usage of machine resources if the packet contains // a set of instruction classes. @@ -266,7 +299,7 @@ bool DFA::isValidTransition(State *From, unsigned InsnClass) { int State::currentStateNum = 0; int Transition::currentTransitionNum = 0; -DFAGen::DFAGen(RecordKeeper &R): +DFAPacketizerEmitter::DFAPacketizerEmitter(RecordKeeper &R): TargetName(CodeGenTarget(R).getName()), allInsnClasses(), Records(R) {} @@ -346,7 +379,7 @@ void DFA::writeTableAndAPI(raw_ostream &OS, const std::string &TargetName) { // collectAllInsnClasses - Populate allInsnClasses which is a set of units // used in each stage. // -void DFAGen::collectAllInsnClasses(const std::string &Name, +void DFAPacketizerEmitter::collectAllInsnClasses(const std::string &Name, Record *ItinData, unsigned &NStages, raw_ostream &OS) { @@ -402,8 +435,7 @@ void DFAGen::collectAllInsnClasses(const std::string &Name, // // Run the worklist algorithm to generate the DFA. // -void DFAGen::run(raw_ostream &OS) { - EmitSourceFileHeader("Target DFA Packetizer Tables", OS); +void DFAPacketizerEmitter::run(raw_ostream &OS) { // Collect processor iteraries. std::vector<Record*> ProcItinList = @@ -510,3 +542,12 @@ void DFAGen::run(raw_ostream &OS) { // Print out the table. D.writeTableAndAPI(OS, TargetName); } + +namespace llvm { + +void EmitDFAPacketizer(RecordKeeper &RK, raw_ostream &OS) { + emitSourceFileHeader("Target DFA Packetizer Tables", OS); + DFAPacketizerEmitter(RK).run(OS); +} + +} // End llvm namespace diff --git a/utils/TableGen/DFAPacketizerEmitter.h b/utils/TableGen/DFAPacketizerEmitter.h deleted file mode 100644 index 1727150ae9..0000000000 --- a/utils/TableGen/DFAPacketizerEmitter.h +++ /dev/null @@ -1,52 +0,0 @@ -//===- DFAPacketizerEmitter.h - Packetization DFA for a VLIW machine-------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This class parses the Schedule.td file and produces an API that can be used -// to reason about whether an instruction can be added to a packet on a VLIW -// architecture. The class internally generates a deterministic finite -// automaton (DFA) that models all possible mappings of machine instructions -// to functional units as instructions are added to a packet. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ADT/DenseSet.h" -#include "llvm/TableGen/TableGenBackend.h" -#include <map> -#include <string> - -namespace llvm { -// -// class DFAGen: class that generates and prints out the DFA for resource -// tracking. -// -class DFAGen : public TableGenBackend { -private: - std::string TargetName; - // - // allInsnClasses is the set of all possible resources consumed by an - // InstrStage. - // - DenseSet<unsigned> allInsnClasses; - RecordKeeper &Records; - -public: - DFAGen(RecordKeeper &R); - - // - // collectAllInsnClasses: Populate allInsnClasses which is a set of units - // used in each stage. - // - void collectAllInsnClasses(const std::string &Name, - Record *ItinData, - unsigned &NStages, - raw_ostream &OS); - - void run(raw_ostream &OS); -}; -} diff --git a/utils/TableGen/DisassemblerEmitter.cpp b/utils/TableGen/DisassemblerEmitter.cpp index 4650197ae7..826465a516 100644 --- a/utils/TableGen/DisassemblerEmitter.cpp +++ b/utils/TableGen/DisassemblerEmitter.cpp @@ -7,13 +7,12 @@ // //===----------------------------------------------------------------------===// -#include "DisassemblerEmitter.h" #include "CodeGenTarget.h" #include "X86DisassemblerTables.h" #include "X86RecognizableInstr.h" -#include "FixedLenDecoderEmitter.h" #include "llvm/TableGen/Error.h" #include "llvm/TableGen/Record.h" +#include "llvm/TableGen/TableGenBackend.h" using namespace llvm; using namespace llvm::X86Disassembler; @@ -94,26 +93,27 @@ using namespace llvm::X86Disassembler; /// X86RecognizableInstr.cpp contains the implementation for a single /// instruction. -void DisassemblerEmitter::run(raw_ostream &OS) { - CodeGenTarget Target(Records); +namespace llvm { + +extern void EmitFixedLenDecoder(RecordKeeper &RK, raw_ostream &OS, + std::string PredicateNamespace, + std::string GPrefix, + std::string GPostfix, + std::string ROK, + std::string RFail, + std::string L); - OS << "/*===- TableGen'erated file " - << "---------------------------------------*- C -*-===*\n" - << " *\n" - << " * " << Target.getName() << " Disassembler\n" - << " *\n" - << " * Automatically generated file, do not edit!\n" - << " *\n" - << " *===---------------------------------------------------------------" - << "-------===*/\n"; +void EmitDisassembler(RecordKeeper &Records, raw_ostream &OS) { + CodeGenTarget Target(Records); + emitSourceFileHeader(" * " + Target.getName() + " Disassembler", OS); // X86 uses a custom disassembler. if (Target.getName() == "X86") { DisassemblerTables Tables; - + const std::vector<const CodeGenInstruction*> &numberedInstructions = Target.getInstructionsByEnumValue(); - + for (unsigned i = 0, e = numberedInstructions.size(); i != e; ++i) RecognizableInstr::processInstr(Tables, *numberedInstructions[i], i); @@ -130,13 +130,18 @@ void DisassemblerEmitter::run(raw_ostream &OS) { // ARM and Thumb have a CHECK() macro to deal with DecodeStatuses. if (Target.getName() == "ARM" || Target.getName() == "Thumb") { - FixedLenDecoderEmitter(Records, - "ARM", - "if (!Check(S, ", ")) return MCDisassembler::Fail;", - "S", "MCDisassembler::Fail", - " MCDisassembler::DecodeStatus S = MCDisassembler::Success;\n(void)S;").run(OS); + EmitFixedLenDecoder(Records, OS, "ARM", + "if (!Check(S, ", ")) return MCDisassembler::Fail;", + "S", "MCDisassembler::Fail", + " MCDisassembler::DecodeStatus S = " + "MCDisassembler::Success;\n(void)S;"); return; } - FixedLenDecoderEmitter(Records, Target.getName()).run(OS); + EmitFixedLenDecoder(Records, OS, Target.getName(), + "if (", " == MCDisassembler::Fail)" + " return MCDisassembler::Fail;", + "MCDisassembler::Success", "MCDisassembler::Fail", ""); } + +} // End llvm namespace diff --git a/utils/TableGen/DisassemblerEmitter.h b/utils/TableGen/DisassemblerEmitter.h deleted file mode 100644 index 63ee55264a..0000000000 --- a/utils/TableGen/DisassemblerEmitter.h +++ /dev/null @@ -1,28 +0,0 @@ -//===- DisassemblerEmitter.h - Disassembler Generator -----------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef DISASSEMBLEREMITTER_H -#define DISASSEMBLEREMITTER_H - -#include "llvm/TableGen/TableGenBackend.h" - -namespace llvm { - - class DisassemblerEmitter : public TableGenBackend { - RecordKeeper &Records; - public: - DisassemblerEmitter(RecordKeeper &R) : Records(R) {} - - /// run - Output the disassembler. - void run(raw_ostream &o); - }; - -} // end llvm namespace - -#endif diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp index fe484ca8cf..bd98308aea 100644 --- a/utils/TableGen/EDEmitter.cpp +++ b/utils/TableGen/EDEmitter.cpp @@ -13,192 +13,199 @@ // //===----------------------------------------------------------------------===// -#include "EDEmitter.h" - #include "AsmWriterInst.h" #include "CodeGenTarget.h" - -#include "llvm/TableGen/Record.h" #include "llvm/MC/EDInstInfo.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" - +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/TableGenBackend.h" #include <string> #include <vector> using namespace llvm; +// TODO: There's a suspiciously large amount of "table" data in this +// backend which should probably be in the TableGen file itself. + /////////////////////////////////////////////////////////// // Support classes for emitting nested C data structures // /////////////////////////////////////////////////////////// -namespace { +// TODO: These classes are probably generally useful to other backends; +// add them to TableGen's "helper" API's. - class EnumEmitter { - private: - std::string Name; - std::vector<std::string> Entries; - public: - EnumEmitter(const char *N) : Name(N) { - } - int addEntry(const char *e) { - Entries.push_back(std::string(e)); - return Entries.size() - 1; +namespace { +class EnumEmitter { +private: + std::string Name; + std::vector<std::string> Entries; +public: + EnumEmitter(const char *N) : Name(N) { + } + int addEntry(const char *e) { + Entries.push_back(std::string(e)); + return Entries.size() - 1; + } + void emit(raw_ostream &o, unsigned int &i) { + o.indent(i) << "enum " << Name.c_str() << " {" << "\n"; + i += 2; + + unsigned int index = 0; + unsigned int numEntries = Entries.size(); + for (index = 0; index < numEntries; ++index) { + o.indent(i) << Entries[index]; + if (index < (numEntries - 1)) + o << ","; + o << "\n"; } - void emit(raw_ostream &o, unsigned int &i) { - o.indent(i) << "enum " << Name.c_str() << " {" << "\n"; - i += 2; - - unsigned int index = 0; - unsigned int numEntries = Entries.size(); - for (index = 0; index < numEntries; ++index) { - o.indent(i) << Entries[index]; - if (index < (numEntries - 1)) - o << ","; - o << "\n"; - } - i -= 2; - o.indent(i) << "};" << "\n"; + i -= 2; + o.indent(i) << "};" << "\n"; + } + + void emitAsFlags(raw_ostream &o, unsigned int &i) { + o.indent(i) << "enum " << Name.c_str() << " {" << "\n"; + i += 2; + + unsigned int index = 0; + unsigned int numEntries = Entries.size(); + unsigned int flag = 1; + for (index = 0; index < numEntries; ++index) { + o.indent(i) << Entries[index] << " = " << format("0x%x", flag); + if (index < (numEntries - 1)) + o << ","; + o << "\n"; + flag <<= 1; } - void emitAsFlags(raw_ostream &o, unsigned int &i) { - o.indent(i) << "enum " << Name.c_str() << " {" << "\n"; - i += 2; - - unsigned int index = 0; - unsigned int numEntries = Entries.size(); - unsigned int flag = 1; - for (index = 0; index < numEntries; ++index) { - o.indent(i) << Entries[index] << " = " << format("0x%x", flag); - if (index < (numEntries - 1)) - o << ","; - o << "\n"; - flag <<= 1; - } + i -= 2; + o.indent(i) << "};" << "\n"; + } +}; +} // End anonymous namespace - i -= 2; - o.indent(i) << "};" << "\n"; - } - }; +namespace { +class ConstantEmitter { +public: + virtual ~ConstantEmitter() { } + virtual void emit(raw_ostream &o, unsigned int &i) = 0; +}; +} // End anonymous namespace - class ConstantEmitter { - public: - virtual ~ConstantEmitter() { } - virtual void emit(raw_ostream &o, unsigned int &i) = 0; +namespace { +class LiteralConstantEmitter : public ConstantEmitter { +private: + bool IsNumber; + union { + int Number; + const char* String; }; +public: + LiteralConstantEmitter(int number = 0) : + IsNumber(true), + Number(number) { + } + void set(const char *string) { + IsNumber = false; + Number = 0; + String = string; + } + bool is(const char *string) { + return !strcmp(String, string); + } + void emit(raw_ostream &o, unsigned int &i) { + if (IsNumber) + o << Number; + else + o << String; + } +}; +} // End anonymous namespace - class LiteralConstantEmitter : public ConstantEmitter { - private: - bool IsNumber; - union { - int Number; - const char* String; - }; - public: - LiteralConstantEmitter(int number = 0) : - IsNumber(true), - Number(number) { - } - void set(const char *string) { - IsNumber = false; - Number = 0; - String = string; - } - bool is(const char *string) { - return !strcmp(String, string); - } - void emit(raw_ostream &o, unsigned int &i) { - if (IsNumber) - o << Number; - else - o << String; - } - }; +namespace { +class CompoundConstantEmitter : public ConstantEmitter { +private: + unsigned int Padding; + std::vector<ConstantEmitter *> Entries; +public: + CompoundConstantEmitter(unsigned int padding = 0) : Padding(padding) { + } + CompoundConstantEmitter &addEntry(ConstantEmitter *e) { + Entries.push_back(e); - class CompoundConstantEmitter : public ConstantEmitter { - private: - unsigned int Padding; - std::vector<ConstantEmitter *> Entries; - public: - CompoundConstantEmitter(unsigned int padding = 0) : Padding(padding) { + return *this; + } + ~CompoundConstantEmitter() { + while (Entries.size()) { + ConstantEmitter *entry = Entries.back(); + Entries.pop_back(); + delete entry; } - CompoundConstantEmitter &addEntry(ConstantEmitter *e) { - Entries.push_back(e); + } + void emit(raw_ostream &o, unsigned int &i) { + o << "{" << "\n"; + i += 2; - return *this; - } - ~CompoundConstantEmitter() { - while (Entries.size()) { - ConstantEmitter *entry = Entries.back(); - Entries.pop_back(); - delete entry; - } - } - void emit(raw_ostream &o, unsigned int &i) { - o << "{" << "\n"; - i += 2; - - unsigned int index; - unsigned int numEntries = Entries.size(); - - unsigned int numToPrint; - - if (Padding) { - if (numEntries > Padding) { - fprintf(stderr, "%u entries but %u padding\n", numEntries, Padding); - llvm_unreachable("More entries than padding"); - } - numToPrint = Padding; - } else { - numToPrint = numEntries; - } + unsigned int index; + unsigned int numEntries = Entries.size(); - for (index = 0; index < numToPrint; ++index) { - o.indent(i); - if (index < numEntries) - Entries[index]->emit(o, i); - else - o << "-1"; + unsigned int numToPrint; - if (index < (numToPrint - 1)) - o << ","; - o << "\n"; + if (Padding) { + if (numEntries > Padding) { + fprintf(stderr, "%u entries but %u padding\n", numEntries, Padding); + llvm_unreachable("More entries than padding"); } - - i -= 2; - o.indent(i) << "}"; + numToPrint = Padding; + } else { + numToPrint = numEntries; } - }; - class FlagsConstantEmitter : public ConstantEmitter { - private: - std::vector<std::string> Flags; - public: - FlagsConstantEmitter() { - } - FlagsConstantEmitter &addEntry(const char *f) { - Flags.push_back(std::string(f)); - return *this; - } - void emit(raw_ostream &o, unsigned int &i) { - unsigned int index; - unsigned int numFlags = Flags.size(); - if (numFlags == 0) - o << "0"; - - for (index = 0; index < numFlags; ++index) { - o << Flags[index].c_str(); - if (index < (numFlags - 1)) - o << " | "; - } + for (index = 0; index < numToPrint; ++index) { + o.indent(i); + if (index < numEntries) + Entries[index]->emit(o, i); + else + o << "-1"; + + if (index < (numToPrint - 1)) + o << ","; + o << "\n"; } - }; -} -EDEmitter::EDEmitter(RecordKeeper &R) : Records(R) { -} + i -= 2; + o.indent(i) << "}"; + } +}; +} // End anonymous namespace + +namespace { +class FlagsConstantEmitter : public ConstantEmitter { +private: + std::vector<std::string> Flags; +public: + FlagsConstantEmitter() { + } + FlagsConstantEmitter &addEntry(const char *f) { + Flags.push_back(std::string(f)); + return *this; + } + void emit(raw_ostream &o, unsigned int &i) { + unsigned int index; + unsigned int numFlags = Flags.size(); + if (numFlags == 0) + o << "0"; + + for (index = 0; index < numFlags; ++index) { + o << Flags[index].c_str(); + if (index < (numFlags - 1)) + o << " | "; + } + } +}; +} // End anonymous namespace /// populateOperandOrder - Accepts a CodeGenInstruction and generates its /// AsmWriterInst for the desired assembly syntax, giving an ordered list of @@ -213,9 +220,9 @@ EDEmitter::EDEmitter(RecordKeeper &R) : Records(R) { /// representing an index in the operand descriptor array. /// @arg inst - The instruction to use when looking up the operands /// @arg syntax - The syntax to use, according to LLVM's enumeration -void populateOperandOrder(CompoundConstantEmitter *operandOrder, - const CodeGenInstruction &inst, - unsigned syntax) { +static void populateOperandOrder(CompoundConstantEmitter *operandOrder, + const CodeGenInstruction &inst, + unsigned syntax) { unsigned int numArgs = 0; AsmWriterInst awInst(inst, syntax, -1, -1); @@ -975,17 +982,23 @@ static void emitCommonEnums(raw_ostream &o, unsigned int &i) { o << "\n"; } -void EDEmitter::run(raw_ostream &o) { +namespace llvm { + +void EmitEnhancedDisassemblerInfo(RecordKeeper &RK, raw_ostream &OS) { + emitSourceFileHeader("Enhanced Disassembler Info", OS); unsigned int i = 0; CompoundConstantEmitter infoArray; - CodeGenTarget target(Records); + CodeGenTarget target(RK); populateInstInfo(infoArray, target); - emitCommonEnums(o, i); + emitCommonEnums(OS, i); - o << "static const llvm::EDInstInfo instInfo" << target.getName() << "[] = "; - infoArray.emit(o, i); - o << ";" << "\n"; + OS << "static const llvm::EDInstInfo instInfo" + << target.getName() << "[] = "; + infoArray.emit(OS, i); + OS << ";" << "\n"; } + +} // End llvm namespace diff --git a/utils/TableGen/EDEmitter.h b/utils/TableGen/EDEmitter.h deleted file mode 100644 index f268375547..0000000000 --- a/utils/TableGen/EDEmitter.h +++ /dev/null @@ -1,34 +0,0 @@ -//===- EDEmitter.h - Generate instruction descriptions for ED ---*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file 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 each -// instruction in a format that the semantic disassembler can use to tokenize -// and parse instructions. -// -//===----------------------------------------------------------------------===// - -#ifndef SEMANTIC_INFO_EMITTER_H -#define SEMANTIC_INFO_EMITTER_H - -#include "llvm/TableGen/TableGenBackend.h" - -namespace llvm { - - class EDEmitter : public TableGenBackend { - RecordKeeper &Records; - public: - EDEmitter(RecordKeeper &R); - - // run - Output the instruction table. - void run(raw_ostream &o); - }; - -} // End llvm namespace - -#endif diff --git a/utils/TableGen/FastISelEmitter.cpp b/utils/TableGen/FastISelEmitter.cpp index 0253484b6f..ca784d0dda 100644 --- a/utils/TableGen/FastISelEmitter.cpp +++ b/utils/TableGen/FastISelEmitter.cpp @@ -17,28 +17,31 @@ // //===----------------------------------------------------------------------===// -#include "FastISelEmitter.h" -#include "llvm/TableGen/Error.h" -#include "llvm/TableGen/Record.h" +#include "CodeGenDAGPatterns.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/TableGenBackend.h" using namespace llvm; -namespace { /// InstructionMemo - This class holds additional information about an /// instruction needed to emit code for it. /// +namespace { struct InstructionMemo { std::string Name; const CodeGenRegisterClass *RC; std::string SubRegNo; std::vector<std::string>* PhysRegs; }; - +} // End anonymous namespace + /// ImmPredicateSet - This uniques predicates (represented as a string) and /// gives them unique (small) integer ID's that start at 0. +namespace { class ImmPredicateSet { DenseMap<TreePattern *, unsigned> ImmIDs; std::vector<TreePredicateFn> PredsByName; @@ -63,10 +66,12 @@ public: iterator end() const { return PredsByName.end(); } }; +} // End anonymous namespace /// OperandsSignature - This class holds a description of a list of operand /// types. It has utility methods for emitting text based on the operands. /// +namespace { struct OperandsSignature { class OpKind { enum { OK_Reg, OK_FP, OK_Imm, OK_Invalid = -1 }; @@ -352,7 +357,9 @@ struct OperandsSignature { Operands[i].printManglingSuffix(OS, ImmPredicates, StripImmCodes); } }; +} // End anonymous namespace +namespace { class FastISelMap { typedef std::map<std::string, InstructionMemo> PredMap; typedef std::map<MVT::SimpleValueType, PredMap> RetPredMap; @@ -375,8 +382,7 @@ public: void printImmediatePredicates(raw_ostream &OS); void printFunctionDefinitions(raw_ostream &OS); }; - -} +} // End anonymous namespace static std::string getOpcodeName(Record *Op, CodeGenDAGPatterns &CGP) { return CGP.getSDNodeInfo(Op).getEnumName(); @@ -850,23 +856,22 @@ void FastISelMap::printFunctionDefinitions(raw_ostream &OS) { // TODO: SignaturesWithConstantForms should be empty here. } -void FastISelEmitter::run(raw_ostream &OS) { +namespace llvm { + +void EmitFastISel(RecordKeeper &RK, raw_ostream &OS) { + CodeGenDAGPatterns CGP(RK); const CodeGenTarget &Target = CGP.getTargetInfo(); + emitSourceFileHeader("\"Fast\" Instruction Selector for the " + + Target.getName() + " target", OS); // Determine the target's namespace name. std::string InstNS = Target.getInstNamespace() + "::"; assert(InstNS.size() > 2 && "Can't determine target-specific namespace!"); - EmitSourceFileHeader("\"Fast\" Instruction Selector for the " + - Target.getName() + " target", OS); - FastISelMap F(InstNS); F.collectPatterns(CGP); F.printImmediatePredicates(OS); F.printFunctionDefinitions(OS); } -FastISelEmitter::FastISelEmitter(RecordKeeper &R) - : CGP(R) { -} - +} // End llvm namespace diff --git a/utils/TableGen/FastISelEmitter.h b/utils/TableGen/FastISelEmitter.h deleted file mode 100644 index 9e042db16f..0000000000 --- a/utils/TableGen/FastISelEmitter.h +++ /dev/null @@ -1,38 +0,0 @@ -//===- FastISelEmitter.h - Generate an instruction selector -----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This tablegen backend emits a "fast" instruction selector. -// -//===----------------------------------------------------------------------===// - -#ifndef FASTISEL_EMITTER_H -#define FASTISEL_EMITTER_H - -#include "CodeGenDAGPatterns.h" -#include "llvm/TableGen/TableGenBackend.h" - -namespace llvm { - -class CodeGenTarget; - -/// FastISelEmitter - The top-level class which coordinates construction -/// and emission of the instruction selector. -/// -class FastISelEmitter : public TableGenBackend { - CodeGenDAGPatterns CGP; -public: - explicit FastISelEmitter(RecordKeeper &R); - - // run - Output the isel, returning true on failure. - void run(raw_ostream &OS); -}; - -} // End llvm namespace - -#endif diff --git a/utils/TableGen/FixedLenDecoderEmitter.cpp b/utils/TableGen/FixedLenDecoderEmitter.cpp index 9b676f21a1..2cdde55009 100644 --- a/utils/TableGen/FixedLenDecoderEmitter.cpp +++ b/utils/TableGen/FixedLenDecoderEmitter.cpp @@ -14,13 +14,14 @@ #define DEBUG_TYPE "decoder-emitter" -#include "FixedLenDecoderEmitter.h" #include "CodeGenTarget.h" #include "llvm/TableGen/Record.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/Support/DataTypes.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/TableGen/TableGenBackend.h" #include <vector> #include <map> @@ -28,6 +29,67 @@ using namespace llvm; +namespace { +struct EncodingField { + unsigned Base, Width, Offset; + EncodingField(unsigned B, unsigned W, unsigned O) + : Base(B), Width(W), Offset(O) { } +}; +} // End anonymous namespace + +namespace { +struct OperandInfo { + std::vector<EncodingField> Fields; + std::string Decoder; + + OperandInfo(std::string D) + : Decoder(D) { } + + void addField(unsigned Base, unsigned Width, unsigned Offset) { + Fields.push_back(EncodingField(Base, Width, Offset)); + } + + unsigned numFields() const { return Fields.size(); } + + typedef std::vector<EncodingField>::const_iterator const_iterator; + + const_iterator begin() const { return Fields.begin(); } + const_iterator end() const { return Fields.end(); } +}; +} // End anonymous namespace + +namespace { +class FixedLenDecoderEmitter { +public: + + // Defaults preserved here for documentation, even though they aren't + // strictly necessary given the way that this is currently being called. + FixedLenDecoderEmitter(RecordKeeper &R, + std::string PredicateNamespace, + std::string GPrefix = "if (", + std::string GPostfix = " == MCDisassembler::Fail)" + " return MCDisassembler::Fail;", + std::string ROK = "MCDisassembler::Success", + std::string RFail = "MCDisassembler::Fail", + std::string L = "") : + Target(R), + PredicateNamespace(PredicateNamespace), + GuardPrefix(GPrefix), GuardPostfix(GPostfix), + ReturnOK(ROK), ReturnFail(RFail), Locals(L) {} + + // run - Output the code emitter + void run(raw_ostream &o); + +private: + CodeGenTarget Target; +public: + std::string PredicateNamespace; + std::string GuardPrefix, GuardPostfix; + std::string ReturnOK, ReturnFail; + std::string Locals; +}; +} // End anonymous namespace + // The set (BIT_TRUE, BIT_FALSE, BIT_UNSET) represents a ternary logic system // for a bit value. // @@ -83,7 +145,9 @@ static BitsInit &getBitsField(const Record &def, const char *str) { } // Forward declaration. +namespace { class FilterChooser; +} // End anonymous namespace // Representation of the instruction to work on. typedef std::vector<bit_value_t> insn_t; @@ -124,6 +188,7 @@ typedef std::vector<bit_value_t> insn_t; /// decoder could try to decode the even/odd register numbering and assign to /// VST4q8a or VST4q8b, but for the time being, the decoder chooses the "a" /// version and return the Opcode since the two have the same Asm format string. +namespace { class Filter { protected: const FilterChooser *Owner;// points to the FilterChooser who owns this filter @@ -180,6 +245,7 @@ public: // the filter distinguishes more categories of instructions. unsigned usefulness() const; }; // End of class Filter +} // End anonymous namespace // These are states of our finite state machines used in FilterChooser's // filterProcessor() which produces the filter candidates to use. @@ -206,6 +272,7 @@ typedef enum { /// It is useful to think of a Filter as governing the switch stmts of the /// decoding tree. And each case is delegated to an inferior FilterChooser to /// decide what further remaining bits to look at. +namespace { class FilterChooser { protected: friend class Filter; @@ -385,6 +452,7 @@ protected: // the instruction at this level or the instruction is not decodeable. bool emit(raw_ostream &o, unsigned &Indentation) const; }; +} // End anonymous namespace /////////////////////////// // // @@ -1573,3 +1641,18 @@ void FixedLenDecoderEmitter::run(raw_ostream &o) { o << "\n} // End llvm namespace \n"; } + +namespace llvm { + +void EmitFixedLenDecoder(RecordKeeper &RK, raw_ostream &OS, + std::string PredicateNamespace, + std::string GPrefix, + std::string GPostfix, + std::string ROK, + std::string RFail, + std::string L) { + FixedLenDecoderEmitter(RK, PredicateNamespace, GPrefix, GPostfix, + ROK, RFail, L).run(OS); +} + +} // End llvm namespace diff --git a/utils/TableGen/FixedLenDecoderEmitter.h b/utils/TableGen/FixedLenDecoderEmitter.h deleted file mode 100644 index 195297c966..0000000000 --- a/utils/TableGen/FixedLenDecoderEmitter.h +++ /dev/null @@ -1,79 +0,0 @@ -//===------------ FixedLenDecoderEmitter.h - Decoder Generator --*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// It contains the tablegen backend that emits the decoder functions for -// targets with fixed length instruction set. -// -//===----------------------------------------------------------------------===// - -#ifndef FixedLenDECODEREMITTER_H -#define FixedLenDECODEREMITTER_H - -#include "CodeGenTarget.h" - -#include "llvm/TableGen/TableGenBackend.h" -#include "llvm/Support/DataTypes.h" - -namespace llvm { - -struct EncodingField { - unsigned Base, Width, Offset; - EncodingField(unsigned B, unsigned W, unsigned O) - : Base(B), Width(W), Offset(O) { } -}; - -struct OperandInfo { - std::vector<EncodingField> Fields; - std::string Decoder; - - OperandInfo(std::string D) - : Decoder(D) { } - - void addField(unsigned Base, unsigned Width, unsigned Offset) { - Fields.push_back(EncodingField(Base, Width, Offset)); - } - - unsigned numFields() const { return Fields.size(); } - - typedef std::vector<EncodingField>::const_iterator const_iterator; - - const_iterator begin() const { return Fields.begin(); } - const_iterator end() const { return Fields.end(); } -}; - -class FixedLenDecoderEmitter : public TableGenBackend { -public: - FixedLenDecoderEmitter(RecordKeeper &R, - std::string PredicateNamespace, - std::string GPrefix = "if (", - std::string GPostfix = " == MCDisassembler::Fail)" - " return MCDisassembler::Fail;", - std::string ROK = "MCDisassembler::Success", - std::string RFail = "MCDisassembler::Fail", - std::string L = "") : - Target(R), - PredicateNamespace(PredicateNamespace), - GuardPrefix(GPrefix), GuardPostfix(GPostfix), - ReturnOK(ROK), ReturnFail(RFail), Locals(L) {} - - // run - Output the code emitter - void run(raw_ostream &o); - -private: - CodeGenTarget Target; -public: - std::string PredicateNamespace; - std::string GuardPrefix, GuardPostfix; - std::string ReturnOK, ReturnFail; - std::string Locals; -}; - -} // end llvm namespace - -#endif diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp index 8b3efd33f4..600586ff4a 100644 --- a/utils/TableGen/InstrInfoEmitter.cpp +++ b/utils/TableGen/InstrInfoEmitter.cpp @@ -12,15 +12,51 @@ // //===----------------------------------------------------------------------===// -#include "InstrInfoEmitter.h" + +#include "CodeGenDAGPatterns.h" #include "CodeGenTarget.h" #include "SequenceToOffsetTable.h" -#include "llvm/TableGen/Record.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/TableGenBackend.h" #include <algorithm> #include <cstdio> +#include <map> +#include <vector> using namespace llvm; +namespace { +class InstrInfoEmitter { + RecordKeeper &Records; + CodeGenDAGPatterns CDP; + std::map<std::string, unsigned> ItinClassMap; + +public: + InstrInfoEmitter(RecordKeeper &R) : Records(R), CDP(R) { } + + // run - Output the instruction set description. + void run(raw_ostream &OS); + +private: + void emitEnums(raw_ostream &OS); + + typedef std::map<std::vector<std::string>, unsigned> OperandInfoMapTy; + void emitRecord(const CodeGenInstruction &Inst, unsigned Num, + Record *InstrInfo, + std::map<std::vector<Record*>, unsigned> &EL, + const OperandInfoMapTy &OpInfo, + raw_ostream &OS); + + // Itinerary information. + void GatherItinClasses(); + unsigned getItinClassNumber(const Record *InstRec); + + // Operand information. + void EmitOperandInfo(raw_ostream &OS, OperandInfoMapTy &OperandInfoIDs); + std::vector<std::string> GetOperandInfo(const CodeGenInstruction &Inst); +}; +} // End anonymous namespace + static void PrintDefList(const std::vector<Record*> &Uses, unsigned Num, raw_ostream &OS) { OS << "static const uint16_t ImplicitList" << Num << "[] = { "; @@ -163,11 +199,12 @@ void InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS, // run - Emit the main instruction description records for the target... void InstrInfoEmitter::run(raw_ostream &OS) { + emitSourceFileHeader("Target Instruction Enum Values", OS); emitEnums(OS); GatherItinClasses(); - EmitSourceFileHeader("Target Instruction Descriptors", OS); + emitSourceFileHeader("Target Instruction Descriptors", OS); OS << "\n#ifdef GET_INSTRINFO_MC_DESC\n"; OS << "#undef GET_INSTRINFO_MC_DESC\n"; @@ -362,7 +399,6 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, // emitEnums - Print out enum values for all of the instructions. void InstrInfoEmitter::emitEnums(raw_ostream &OS) { - EmitSourceFileHeader("Target Instruction Enum Values", OS); OS << "\n#ifdef GET_INSTRINFO_ENUM\n"; OS << "#undef GET_INSTRINFO_ENUM\n"; @@ -394,3 +430,11 @@ void InstrInfoEmitter::emitEnums(raw_ostream &OS) { OS << "#endif // GET_INSTRINFO_ENUM\n\n"; } + +namespace llvm { + +void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS) { + InstrInfoEmitter(RK).run(OS); +} + +} // End llvm namespace diff --git a/utils/TableGen/InstrInfoEmitter.h b/utils/TableGen/InstrInfoEmitter.h deleted file mode 100644 index f8d3ea51c8..0000000000 --- a/utils/TableGen/InstrInfoEmitter.h +++ /dev/null @@ -1,62 +0,0 @@ -//===- InstrInfoEmitter.h - Generate a Instruction Set Desc. ----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file 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 the target -// instruction set for the code generator. -// -//===----------------------------------------------------------------------===// - -#ifndef INSTRINFO_EMITTER_H -#define INSTRINFO_EMITTER_H - -#include "CodeGenDAGPatterns.h" -#include "llvm/TableGen/TableGenBackend.h" -#include <vector> -#include <map> - -namespace llvm { - -class StringInit; -class IntInit; -class ListInit; -class CodeGenInstruction; - -class InstrInfoEmitter : public TableGenBackend { - RecordKeeper &Records; - CodeGenDAGPatterns CDP; - std::map<std::string, unsigned> ItinClassMap; - -public: - InstrInfoEmitter(RecordKeeper &R) : Records(R), CDP(R) { } - - // run - Output the instruction set description. - void run(raw_ostream &OS); - -private: - void emitEnums(raw_ostream &OS); - - typedef std::map<std::vector<std::string>, unsigned> OperandInfoMapTy; - void emitRecord(const CodeGenInstruction &Inst, unsigned Num, - Record *InstrInfo, - std::map<std::vector<Record*>, unsigned> &EL, - const OperandInfoMapTy &OpInfo, - raw_ostream &OS); - - // Itinerary information. - void GatherItinClasses(); - unsigned getItinClassNumber(const Record *InstRec); - - // Operand information. - void EmitOperandInfo(raw_ostream &OS, OperandInfoMapTy &OperandInfoIDs); - std::vector<std::string> GetOperandInfo(const CodeGenInstruction &Inst); -}; - -} // End llvm namespace - -#endif diff --git a/utils/TableGen/IntrinsicEmitter.cpp b/utils/TableGen/IntrinsicEmitter.cpp index 748573e367..155d1abea3 100644 --- a/utils/TableGen/IntrinsicEmitter.cpp +++ b/utils/TableGen/IntrinsicEmitter.cpp @@ -11,24 +11,62 @@ // //===----------------------------------------------------------------------===// +#include "CodeGenIntrinsics.h" #include "CodeGenTarget.h" -#include "IntrinsicEmitter.h" #include "SequenceToOffsetTable.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/TableGen/Record.h" #include "llvm/TableGen/StringMatcher.h" -#include "llvm/ADT/StringExtras.h" +#include "llvm/TableGen/TableGenBackend.h" #include <algorithm> using namespace llvm; +namespace { +class IntrinsicEmitter { + RecordKeeper &Records; + bool TargetOnly; + std::string TargetPrefix; + +public: + IntrinsicEmitter(RecordKeeper &R, bool T) + : Records(R), TargetOnly(T) {} + + void run(raw_ostream &OS); + + void EmitPrefix(raw_ostream &OS); + + void EmitEnumInfo(const std::vector<CodeGenIntrinsic> &Ints, + raw_ostream &OS); + + void EmitFnNameRecognizer(const std::vector<CodeGenIntrinsic> &Ints, + raw_ostream &OS); + void EmitIntrinsicToNameTable(const std::vector<CodeGenIntrinsic> &Ints, + raw_ostream &OS); + void EmitIntrinsicToOverloadTable(const std::vector<CodeGenIntrinsic> &Ints, + raw_ostream &OS); + void EmitVerifier(const std::vector<CodeGenIntrinsic> &Ints, + raw_ostream &OS); + void EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints, + raw_ostream &OS); + void EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, + raw_ostream &OS); + void EmitModRefBehavior(const std::vector<CodeGenIntrinsic> &Ints, + raw_ostream &OS); + void EmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints, + raw_ostream &OS); + void EmitSuffix(raw_ostream &OS); +}; +} // End anonymous namespace + //===----------------------------------------------------------------------===// // IntrinsicEmitter Implementation //===----------------------------------------------------------------------===// void IntrinsicEmitter::run(raw_ostream &OS) { - EmitSourceFileHeader("Intrinsic Function Source Fragment", OS); - + emitSourceFileHeader("Intrinsic Function Source Fragment", OS); + std::vector<CodeGenIntrinsic> Ints = LoadIntrinsics(Records, TargetOnly); - + if (TargetOnly && !Ints.empty()) TargetPrefix = Ints[0].TargetPrefix; @@ -338,7 +376,7 @@ static void ComputeFixedEncoding(const CodeGenIntrinsic &Int, EncodeFixedType(Int.IS.ParamTypeDefs[i], ArgCodes, TypeSig); } -void printIITEntry(raw_ostream &OS, unsigned char X) { +static void printIITEntry(raw_ostream &OS, unsigned char X) { OS << (unsigned)X; } @@ -424,48 +462,48 @@ void IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints, OS << "#endif\n\n"; // End of GET_INTRINSIC_GENERATOR_GLOBAL } -namespace { - enum ModRefKind { - MRK_none, - MRK_readonly, - MRK_readnone - }; - - ModRefKind getModRefKind(const CodeGenIntrinsic &intrinsic) { - switch (intrinsic.ModRef) { - case CodeGenIntrinsic::NoMem: - return MRK_readnone; - case CodeGenIntrinsic::ReadArgMem: - case CodeGenIntrinsic::ReadMem: - return MRK_readonly; - case CodeGenIntrinsic::ReadWriteArgMem: - case CodeGenIntrinsic::ReadWriteMem: - return MRK_none; - } - llvm_unreachable("bad mod-ref kind"); - } - - struct AttributeComparator { - bool operator()(const CodeGenIntrinsic *L, const CodeGenIntrinsic *R) const { - // Sort throwing intrinsics after non-throwing intrinsics. - if (L->canThrow != R->canThrow) - return R->canThrow; - - if (L->isNoReturn != R->isNoReturn) - return R->isNoReturn; - - // Try to order by readonly/readnone attribute. - ModRefKind LK = getModRefKind(*L); - ModRefKind RK = getModRefKind(*R); - if (LK != RK) return (LK > RK); +enum ModRefKind { + MRK_none, + MRK_readonly, + MRK_readnone +}; - // Order by argument attributes. - // This is reliable because each side is already sorted internally. - return (L->ArgumentAttributes < R->ArgumentAttributes); - } - }; +static ModRefKind getModRefKind(const CodeGenIntrinsic &intrinsic) { + switch (intrinsic.ModRef) { + case CodeGenIntrinsic::NoMem: + return MRK_readnone; + case CodeGenIntrinsic::ReadArgMem: + case CodeGenIntrinsic::ReadMem: + return MRK_readonly; + case CodeGenIntrinsic::ReadWriteArgMem: + case CodeGenIntrinsic::ReadWriteMem: + return MRK_none; + } + llvm_unreachable("bad mod-ref kind"); } +namespace { +struct AttributeComparator { + bool operator()(const CodeGenIntrinsic *L, const CodeGenIntrinsic *R) const { + // Sort throwing intrinsics after non-throwing intrinsics. + if (L->canThrow != R->canThrow) + return R->canThrow; + + if (L->isNoReturn != R->isNoReturn) + return R->isNoReturn; + + // Try to order by readonly/readnone attribute. + ModRefKind LK = getModRefKind(*L); + ModRefKind RK = getModRefKind(*R); + if (LK != RK) return (LK > RK); + + // Order by argument attributes. + // This is reliable because each side is already sorted internally. + return (L->ArgumentAttributes < R->ArgumentAttributes); + } +}; +} // End anonymous namespace + /// EmitAttributes - This emits the Intrinsic::getAttributes method. void IntrinsicEmitter:: EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) { @@ -705,3 +743,11 @@ EmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints, OS << "}\n"; OS << "#endif\n\n"; } + +namespace llvm { + +void EmitIntrinsics(RecordKeeper &RK, raw_ostream &OS, bool TargetOnly = false) { + IntrinsicEmitter(RK, TargetOnly).run(OS); +} + +} // End llvm namespace diff --git a/utils/TableGen/IntrinsicEmitter.h b/utils/TableGen/IntrinsicEmitter.h deleted file mode 100644 index f9bcd59802..0000000000 --- a/utils/TableGen/IntrinsicEmitter.h +++ /dev/null @@ -1,61 +0,0 @@ -//===- IntrinsicEmitter.h - Generate intrinsic information ------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This tablegen backend emits information about intrinsic functions. -// -//===----------------------------------------------------------------------===// - -#ifndef INTRINSIC_EMITTER_H -#define INTRINSIC_EMITTER_H - -#include "CodeGenIntrinsics.h" -#include "llvm/TableGen/TableGenBackend.h" - -namespace llvm { - class IntrinsicEmitter : public TableGenBackend { - RecordKeeper &Records; - bool TargetOnly; - std::string TargetPrefix; - - public: - IntrinsicEmitter(RecordKeeper &R, bool T = false) - : Records(R), TargetOnly(T) {} - - void run(raw_ostream &OS); - - void EmitPrefix(raw_ostream &OS); - - void EmitEnumInfo(const std::vector<CodeGenIntrinsic> &Ints, - raw_ostream &OS); - - void EmitFnNameRecognizer(const std::vector<CodeGenIntrinsic> &Ints, - raw_ostream &OS); - void EmitIntrinsicToNameTable(const std::vector<CodeGenIntrinsic> &Ints, - raw_ostream &OS); - void EmitIntrinsicToOverloadTable(const std::vector<CodeGenIntrinsic> &Ints, - raw_ostream &OS); - void EmitVerifier(const std::vector<CodeGenIntrinsic> &Ints, - raw_ostream &OS); - void EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints, - raw_ostream &OS); - void EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, - raw_ostream &OS); - void EmitModRefBehavior(const std::vector<CodeGenIntrinsic> &Ints, - raw_ostream &OS); - void EmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints, - raw_ostream &OS); - void EmitSuffix(raw_ostream &OS); - }; - -} // End llvm namespace - -#endif - - - diff --git a/utils/TableGen/PseudoLoweringEmitter.cpp b/utils/TableGen/PseudoLoweringEmitter.cpp index 802d112108..8d9d419544 100644 --- a/utils/TableGen/PseudoLoweringEmitter.cpp +++ b/utils/TableGen/PseudoLoweringEmitter.cpp @@ -9,16 +9,62 @@ #define DEBUG_TYPE "pseudo-lowering" #include "CodeGenInstruction.h" -#include "PseudoLoweringEmitter.h" -#include "llvm/TableGen/Error.h" -#include "llvm/TableGen/Record.h" +#include "CodeGenTarget.h" #include "llvm/ADT/IndexedMap.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" -#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/TableGenBackend.h" #include <vector> using namespace llvm; +namespace { +class PseudoLoweringEmitter { + struct OpData { + enum MapKind { Operand, Imm, Reg }; + MapKind Kind; + union { + unsigned Operand; // Operand number mapped to. + uint64_t Imm; // Integer immedate value. + Record *Reg; // Physical register. + } Data; + }; + struct PseudoExpansion { + CodeGenInstruction Source; // The source pseudo instruction definition. + CodeGenInstruction Dest; // The destination instruction to lower to. + IndexedMap<OpData> OperandMap; + + PseudoExpansion(CodeGenInstruction &s, CodeGenInstruction &d, + IndexedMap<OpData> &m) : + Source(s), Dest(d), OperandMap(m) {} + }; + + RecordKeeper &Records; + + // It's overkill to have an instance of the full CodeGenTarget object, + // but it loads everything on demand, not in the constructor, so it's + // lightweight in performance, so it works out OK. + CodeGenTarget Target; + + SmallVector<PseudoExpansion, 64> Expansions; + + unsigned addDagOperandMapping(Record *Rec, DagInit *Dag, + CodeGenInstruction &Insn, + IndexedMap<OpData> &OperandMap, + unsigned BaseIdx); + void evaluateExpansion(Record *Pseudo); + void emitLoweringEmitter(raw_ostream &o); +public: + PseudoLoweringEmitter(RecordKeeper &R) : Records(R), Target(R) {} + + /// run - Output the pseudo-lowerings. + void run(raw_ostream &o); +}; +} // End anonymous namespace + // FIXME: This pass currently can only expand a pseudo to a single instruction. // The pseudo expansion really should take a list of dags, not just // a single dag, so we can do fancier things. @@ -150,7 +196,7 @@ void PseudoLoweringEmitter::evaluateExpansion(Record *Rec) { void PseudoLoweringEmitter::emitLoweringEmitter(raw_ostream &o) { // Emit file header. - EmitSourceFileHeader("Pseudo-instruction MC lowering Source Fragment", o); + emitSourceFileHeader("Pseudo-instruction MC lowering Source Fragment", o); o << "bool " << Target.getName() + "AsmPrinter" << "::\n" << "emitPseudoExpansionLowering(MCStreamer &OutStreamer,\n" @@ -242,3 +288,10 @@ void PseudoLoweringEmitter::run(raw_ostream &o) { emitLoweringEmitter(o); } +namespace llvm { + +void EmitPseudoLowering(RecordKeeper &RK, raw_ostream &OS) { + PseudoLoweringEmitter(RK).run(OS); +} + +} // End llvm namespace diff --git a/utils/TableGen/PseudoLoweringEmitter.h b/utils/TableGen/PseudoLoweringEmitter.h deleted file mode 100644 index 325bc8be14..0000000000 --- a/utils/TableGen/PseudoLoweringEmitter.h +++ /dev/null @@ -1,65 +0,0 @@ -//===- PseudoLoweringEmitter.h - PseudoLowering Generator -------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef PSEUDOLOWERINGEMITTER_H -#define PSEUDOLOWERINGEMITTER_H - -#include "CodeGenInstruction.h" -#include "CodeGenTarget.h" -#include "llvm/TableGen/TableGenBackend.h" -#include "llvm/ADT/IndexedMap.h" -#include "llvm/ADT/SmallVector.h" - -namespace llvm { - -class PseudoLoweringEmitter : public TableGenBackend { - struct OpData { - enum MapKind { Operand, Imm, Reg }; - MapKind Kind; - union { - unsigned Operand; // Operand number mapped to. - uint64_t Imm; // Integer immedate value. - Record *Reg; // Physical register. - } Data; - }; - struct PseudoExpansion { - CodeGenInstruction Source; // The source pseudo instruction definition. - CodeGenInstruction Dest; // The destination instruction to lower to. - IndexedMap<OpData> OperandMap; - - PseudoExpansion(CodeGenInstruction &s, CodeGenInstruction &d, - IndexedMap<OpData> &m) : - Source(s), Dest(d), OperandMap(m) {} - }; - - RecordKeeper &Records; - - // It's overkill to have an instance of the full CodeGenTarget object, - // but it loads everything on demand, not in the constructor, so it's - // lightweight in performance, so it works out OK. - CodeGenTarget Target; - - SmallVector<PseudoExpansion, 64> Expansions; - - unsigned addDagOperandMapping(Record *Rec, DagInit *Dag, - CodeGenInstruction &Insn, - IndexedMap<OpData> &OperandMap, - unsigned BaseIdx); - void evaluateExpansion(Record *Pseudo); - void emitLoweringEmitter(raw_ostream &o); -public: - PseudoLoweringEmitter(RecordKeeper &R) : Records(R), Target(R) {} - - /// run - Output the pseudo-lowerings. - void run(raw_ostream &o); -}; - -} // end llvm namespace - -#endif diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index 780ca398b3..3d8d515f83 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -13,21 +13,58 @@ // //===----------------------------------------------------------------------===// -#include "RegisterInfoEmitter.h" -#include "CodeGenTarget.h" #include "CodeGenRegisters.h" +#include "CodeGenTarget.h" #include "SequenceToOffsetTable.h" -#include "llvm/TableGen/Error.h" -#include "llvm/TableGen/Record.h" #include "llvm/ADT/BitVector.h" -#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/Format.h" +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/TableGenBackend.h" #include <algorithm> #include <set> +#include <vector> using namespace llvm; +namespace { +class RegisterInfoEmitter { + RecordKeeper &Records; +public: + RegisterInfoEmitter(RecordKeeper &R) : Records(R) {} + + // runEnums - Print out enum values for all of the registers. + void runEnums(raw_ostream &o, CodeGenTarget &Target, CodeGenRegBank &Bank); + + // runMCDesc - Print out MC register descriptions. + void runMCDesc(raw_ostream &o, CodeGenTarget &Target, CodeGenRegBank &Bank); + + // runTargetHeader - Emit a header fragment for the register info emitter. + void runTargetHeader(raw_ostream &o, CodeGenTarget &Target, + CodeGenRegBank &Bank); + + // runTargetDesc - Output the target register and register file descriptions. + void runTargetDesc(raw_ostream &o, CodeGenTarget &Target, + CodeGenRegBank &Bank); + + // run - Output the register file description. + void run(raw_ostream &o); + +private: + void EmitRegMapping(raw_ostream &o, + const std::vector<CodeGenRegister*> &Regs, bool isCtor); + void EmitRegMappingTables(raw_ostream &o, + const std::vector<CodeGenRegister*> &Regs, + bool isCtor); + void EmitRegClasses(raw_ostream &OS, CodeGenTarget &Target); + + void EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank, + const std::string &ClassName); +}; +} // End anonymous namespace + // runEnums - Print out enum values for all of the registers. void RegisterInfoEmitter::runEnums(raw_ostream &OS, CodeGenTarget &Target, CodeGenRegBank &Bank) { @@ -38,7 +75,7 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS, std::string Namespace = Registers[0]->TheDef->getValueAsString("Namespace"); - EmitSourceFileHeader("Target Register Enum Values", OS); + emitSourceFileHeader("Target Register Enum Values", OS); OS << "\n#ifdef GET_REGINFO_ENUM\n"; OS << "#undef GET_REGINFO_ENUM\n"; @@ -490,7 +527,7 @@ static void printDiff16(raw_ostream &OS, uint16_t Val) { void RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, CodeGenRegBank &RegBank) { - EmitSourceFileHeader("MC Register Information", OS); + emitSourceFileHeader("MC Register Information", OS); OS << "\n#ifdef GET_REGINFO_MC_DESC\n"; OS << "#undef GET_REGINFO_MC_DESC\n"; @@ -774,7 +811,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, void RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target, CodeGenRegBank &RegBank) { - EmitSourceFileHeader("Register Information Header Fragment", OS); + emitSourceFileHeader("Register Information Header Fragment", OS); OS << "\n#ifdef GET_REGINFO_HEADER\n"; OS << "#undef GET_REGINFO_HEADER\n"; @@ -830,7 +867,7 @@ RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target, void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, CodeGenRegBank &RegBank){ - EmitSourceFileHeader("Target Register and Register Classes Information", OS); + emitSourceFileHeader("Target Register and Register Classes Information", OS); OS << "\n#ifdef GET_REGINFO_TARGET_DESC\n"; OS << "#undef GET_REGINFO_TARGET_DESC\n"; @@ -1186,3 +1223,11 @@ void RegisterInfoEmitter::run(raw_ostream &OS) { runTargetHeader(OS, Target, RegBank); runTargetDesc(OS, Target, RegBank); } + +namespace llvm { + +void EmitRegisterInfo(RecordKeeper &RK, raw_ostream &OS) { + RegisterInfoEmitter(RK).run(OS); +} + +} // End llvm namespace diff --git a/utils/TableGen/RegisterInfoEmitter.h b/utils/TableGen/RegisterInfoEmitter.h deleted file mode 100644 index ee9903cac7..0000000000 --- a/utils/TableGen/RegisterInfoEmitter.h +++ /dev/null @@ -1,64 +0,0 @@ -//===- RegisterInfoEmitter.h - Generate a Register File Desc. ---*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file 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, -// RegisterAliases, and RegisterClass classes to gather this information. -// -//===----------------------------------------------------------------------===// - -#ifndef REGISTER_INFO_EMITTER_H -#define REGISTER_INFO_EMITTER_H - -#include "llvm/TableGen/TableGenBackend.h" -#include <vector> - -namespace llvm { - -class CodeGenRegBank; -struct CodeGenRegister; -class CodeGenTarget; - -class RegisterInfoEmitter : public TableGenBackend { - RecordKeeper &Records; -public: - RegisterInfoEmitter(RecordKeeper &R) : Records(R) {} - - // runEnums - Print out enum values for all of the registers. - void runEnums(raw_ostream &o, CodeGenTarget &Target, CodeGenRegBank &Bank); - - // runMCDesc - Print out MC register descriptions. - void runMCDesc(raw_ostream &o, CodeGenTarget &Target, CodeGenRegBank &Bank); - - // runTargetHeader - Emit a header fragment for the register info emitter. - void runTargetHeader(raw_ostream &o, CodeGenTarget &Target, - CodeGenRegBank &Bank); - - // runTargetDesc - Output the target register and register file descriptions. - void runTargetDesc(raw_ostream &o, CodeGenTarget &Target, - CodeGenRegBank &Bank); - - // run - Output the register file description. - void run(raw_ostream &o); - -private: - void EmitRegMapping(raw_ostream &o, - const std::vector<CodeGenRegister*> &Regs, bool isCtor); - void EmitRegMappingTables(raw_ostream &o, - const std::vector<CodeGenRegister*> &Regs, - bool isCtor); - void EmitRegClasses(raw_ostream &OS, CodeGenTarget &Target); - - void EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank, - const std::string &ClassName); -}; - -} // End llvm namespace - -#endif diff --git a/utils/TableGen/SubtargetEmitter.cpp b/utils/TableGen/SubtargetEmitter.cpp index 5911d9856f..c58fc6b8fd 100644 --- a/utils/TableGen/SubtargetEmitter.cpp +++ b/utils/TableGen/SubtargetEmitter.cpp @@ -11,14 +11,61 @@ // //===----------------------------------------------------------------------===// -#include "SubtargetEmitter.h" #include "CodeGenTarget.h" -#include "llvm/TableGen/Record.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/MC/MCInstrItineraries.h" #include "llvm/Support/Debug.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/TableGenBackend.h" #include <algorithm> +#include <map> +#include <string> +#include <vector> using namespace llvm; +namespace { +class SubtargetEmitter { + + RecordKeeper &Records; + std::string Target; + bool HasItineraries; + + void Enumeration(raw_ostream &OS, const char *ClassName, bool isBits); + unsigned FeatureKeyValues(raw_ostream &OS); + unsigned CPUKeyValues(raw_ostream &OS); + unsigned CollectAllItinClasses(raw_ostream &OS, + std::map<std::string,unsigned> &ItinClassesMap, + std::vector<Record*> &ItinClassList); + void FormItineraryStageString(const std::string &Names, + Record *ItinData, std::string &ItinString, + unsigned &NStages); + void FormItineraryOperandCycleString(Record *ItinData, std::string &ItinString, + unsigned &NOperandCycles); + void FormItineraryBypassString(const std::string &Names, + Record *ItinData, + std::string &ItinString, unsigned NOperandCycles); + void EmitStageAndOperandCycleData(raw_ostream &OS, unsigned NItinClasses, + std::map<std::string, unsigned> &ItinClassesMap, + std::vector<Record*> &ItinClassList, + std::vector<std::vector<InstrItinerary> > &ProcList); + void EmitItineraryProp(raw_ostream &OS, const Record *R, const char *Name, + char Separator); + void EmitProcessorData(raw_ostream &OS, + std::vector<Record*> &ItinClassList, + std::vector<std::vector<InstrItinerary> > &ProcList); + void EmitProcessorLookup(raw_ostream &OS); + void EmitData(raw_ostream &OS); + void ParseFeaturesFunction(raw_ostream &OS, unsigned NumFeatures, + unsigned NumProcs); + +public: + SubtargetEmitter(RecordKeeper &R) : Records(R), HasItineraries(false) {} + + void run(raw_ostream &o); + +}; +} // End anonymous namespace + // // Enumeration - Emit the specified class as an enumeration. // @@ -685,7 +732,7 @@ void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS, void SubtargetEmitter::run(raw_ostream &OS) { Target = CodeGenTarget(Records).getName(); - EmitSourceFileHeader("Subtarget Enumeration Source Fragment", OS); + emitSourceFileHeader("Subtarget Enumeration Source Fragment", OS); OS << "\n#ifdef GET_SUBTARGETINFO_ENUM\n"; OS << "#undef GET_SUBTARGETINFO_ENUM\n"; @@ -802,3 +849,11 @@ void SubtargetEmitter::run(raw_ostream &OS) { OS << "#endif // GET_SUBTARGETINFO_CTOR\n\n"; } + +namespace llvm { + +void EmitSubtarget(RecordKeeper &RK, raw_ostream &OS) { + SubtargetEmitter(RK).run(OS); +} + +} // End llvm namespace diff --git a/utils/TableGen/SubtargetEmitter.h b/utils/TableGen/SubtargetEmitter.h deleted file mode 100644 index b153cde6d5..0000000000 --- a/utils/TableGen/SubtargetEmitter.h +++ /dev/null @@ -1,74 +0,0 @@ -//===- SubtargetEmitter.h - Generate subtarget enumerations -----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This tablegen backend emits subtarget enumerations. -// -//===----------------------------------------------------------------------===// - -#ifndef SUBTARGET_EMITTER_H -#define SUBTARGET_EMITTER_H - -#include "llvm/TableGen/TableGenBackend.h" -#include "llvm/MC/MCInstrItineraries.h" -#include <vector> -#include <map> -#include <string> - - -namespace llvm { - -class SubtargetEmitter : public TableGenBackend { - - RecordKeeper &Records; - std::string Target; - bool HasItineraries; - - void Enumeration(raw_ostream &OS, const char *ClassName, bool isBits); - unsigned FeatureKeyValues(raw_ostream &OS); - unsigned CPUKeyValues(raw_ostream &OS); - unsigned CollectAllItinClasses(raw_ostream &OS, - std::map<std::string,unsigned> &ItinClassesMap, - std::vector<Record*> &ItinClassList); - void FormItineraryStageString(const std::string &Names, - Record *ItinData, std::string &ItinString, - unsigned &NStages); - void FormItineraryOperandCycleString(Record *ItinData, std::string &ItinString, - unsigned &NOperandCycles); - void FormItineraryBypassString(const std::string &Names, - Record *ItinData, - std::string &ItinString, unsigned NOperandCycles); - void EmitStageAndOperandCycleData(raw_ostream &OS, unsigned NItinClasses, - std::map<std::string, unsigned> &ItinClassesMap, - std::vector<Record*> &ItinClassList, - std::vector<std::vector<InstrItinerary> > &ProcList); - void EmitItineraryProp(raw_ostream &OS, const Record *R, const char *Name, - char Separator); - void EmitProcessorData(raw_ostream &OS, - std::vector<Record*> &ItinClassList, - std::vector<std::vector<InstrItinerary> > &ProcList); - void EmitProcessorLookup(raw_ostream &OS); - void EmitData(raw_ostream &OS); - void ParseFeaturesFunction(raw_ostream &OS, unsigned NumFeatures, - unsigned NumProcs); - -public: - SubtargetEmitter(RecordKeeper &R) : Records(R), HasItineraries(false) {} - - // run - Output the subtarget enumerations, returning true on failure. - void run(raw_ostream &o); - -}; - - -} // End llvm namespace - -#endif - - - diff --git a/utils/TableGen/TableGen.cpp b/utils/TableGen/TableGen.cpp index 8c41358e3d..9695b4a351 100644 --- a/utils/TableGen/TableGen.cpp +++ b/utils/TableGen/TableGen.cpp @@ -11,22 +11,9 @@ // //===----------------------------------------------------------------------===// -#include "AsmMatcherEmitter.h" -#include "AsmWriterEmitter.h" -#include "CallingConvEmitter.h" -#include "CodeEmitterGen.h" -#include "DAGISelEmitter.h" -#include "DFAPacketizerEmitter.h" -#include "DisassemblerEmitter.h" -#include "EDEmitter.h" -#include "FastISelEmitter.h" -#include "InstrInfoEmitter.h" -#include "IntrinsicEmitter.h" -#include "PseudoLoweringEmitter.h" -#include "RegisterInfoEmitter.h" -#include "SubtargetEmitter.h" -#include "SetTheory.h" +#include "TableGenBackends.h" // Declares all backends. +#include "SetTheory.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Signals.h" @@ -102,7 +89,7 @@ namespace { cl::opt<std::string> Class("class", cl::desc("Print Enum list for this class"), cl::value_desc("class name")); - + class LLVMTableGenAction : public TableGenAction { public: bool operator()(raw_ostream &OS, RecordKeeper &Records) { @@ -111,49 +98,49 @@ namespace { OS << Records; // No argument, dump all contents break; case GenEmitter: - CodeEmitterGen(Records).run(OS); + EmitCodeEmitter(Records, OS); break; case GenRegisterInfo: - RegisterInfoEmitter(Records).run(OS); + EmitRegisterInfo(Records, OS); break; case GenInstrInfo: - InstrInfoEmitter(Records).run(OS); + EmitInstrInfo(Records, OS); break; case GenCallingConv: - CallingConvEmitter(Records).run(OS); + EmitCallingConv(Records, OS); break; case GenAsmWriter: - AsmWriterEmitter(Records).run(OS); + EmitAsmWriter(Records, OS); break; case GenAsmMatcher: - AsmMatcherEmitter(Records).run(OS); + EmitAsmMatcher(Records, OS); break; case GenDisassembler: - DisassemblerEmitter(Records).run(OS); + EmitDisassembler(Records, OS); break; case GenPseudoLowering: - PseudoLoweringEmitter(Records).run(OS); + EmitPseudoLowering(Records, OS); break; case GenDAGISel: - DAGISelEmitter(Records).run(OS); + EmitDAGISel(Records, OS); break; case GenDFAPacketizer: - DFAGen(Records).run(OS); + EmitDFAPacketizer(Records, OS); break; case GenFastISel: - FastISelEmitter(Records).run(OS); + EmitFastISel(Records, OS); break; case GenSubtarget: - SubtargetEmitter(Records).run(OS); + EmitSubtarget(Records, OS); break; case GenIntrinsic: - IntrinsicEmitter(Records).run(OS); + EmitIntrinsics(Records, OS); break; case GenTgtIntrinsic: - IntrinsicEmitter(Records, true).run(OS); + EmitIntrinsics(Records, OS, true); break; case GenEDInfo: - EDEmitter(Records).run(OS); + EmitEnhancedDisassemblerInfo(Records, OS); break; case PrintEnums: { @@ -179,7 +166,7 @@ namespace { break; } } - + return false; } }; diff --git a/utils/TableGen/TableGenBackends.h b/utils/TableGen/TableGenBackends.h new file mode 100644 index 0000000000..2c00c40cfe --- /dev/null +++ b/utils/TableGen/TableGenBackends.h @@ -0,0 +1,78 @@ +//===- TableGenBackends.h - Declarations for LLVM TableGen Backends -------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the declarations for all of the LLVM TableGen +// backends. A "TableGen backend" is just a function. See below for a +// precise description. +// +//===----------------------------------------------------------------------===// + + +// A TableGen backend is a function that looks like +// +// EmitFoo(RecordKeeper &RK, raw_ostream &OS /*, anything else you need */ ) +// +// What you do inside of that function is up to you, but it will usually +// involve generating C++ code to the provided raw_ostream. +// +// The RecordKeeper is just a top-level container for an in-memory +// representation of the data encoded in the TableGen file. What a TableGen +// backend does is walk around that in-memory representation and generate +// stuff based on the information it contains. +// +// The in-memory representation is a node-graph (think of it like JSON but +// with a richer ontology of types), where the nodes are subclasses of +// Record. The methods `getClass`, `getDef` are the basic interface to +// access the node-graph. RecordKeeper also provides a handy method +// `getAllDerivedDefinitions`. Consult "include/llvm/TableGen/Record.h" for +// the exact interfaces provided by Record's and RecordKeeper. +// +// A common pattern for TableGen backends is for the EmitFoo function to +// instantiate a class which holds some context for the generation process, +// and then have most of the work happen in that class's methods. This +// pattern partly has historical roots in the previous TableGen backend API +// that involved a class and an invocation like `FooEmitter(RK).run(OS)`. +// +// Remember to wrap private things in an anonymous namespace. For most +// backends, this means that the EmitFoo function is the only thing not in +// the anonymous namespace. + + +// FIXME: Reorganize TableGen so that build dependencies can be more +// accurately expressed. Currently, touching any of the emitters (or +// anything that they transitively depend on) causes everything dependent +// on TableGen to be rebuilt (this includes all the targets!). Perhaps have +// a standalone TableGen binary and have the backends be loadable modules +// of some sort; then the dependency could be expressed as being on the +// module, and all the modules would have a common dependency on the +// TableGen binary with as few dependencies as possible on the rest of +// LLVM. + + +namespace llvm { + +class raw_ostream; +class RecordKeeper; + +void EmitIntrinsics(RecordKeeper &RK, raw_ostream &OS, bool TargetOnly = false); +void EmitAsmMatcher(RecordKeeper &RK, raw_ostream &OS); +void EmitAsmWriter(RecordKeeper &RK, raw_ostream &OS); +void EmitCallingConv(RecordKeeper &RK, raw_ostream &OS); +void EmitCodeEmitter(RecordKeeper &RK, raw_ostream &OS); +void EmitDAGISel(RecordKeeper &RK, raw_ostream &OS); +void EmitDFAPacketizer(RecordKeeper &RK, raw_ostream &OS); +void EmitDisassembler(RecordKeeper &RK, raw_ostream &OS); +void EmitEnhancedDisassemblerInfo(RecordKeeper &RK, raw_ostream &OS); +void EmitFastISel(RecordKeeper &RK, raw_ostream &OS); +void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS); +void EmitPseudoLowering(RecordKeeper &RK, raw_ostream &OS); +void EmitRegisterInfo(RecordKeeper &RK, raw_ostream &OS); +void EmitSubtarget(RecordKeeper &RK, raw_ostream &OS); + +} // End llvm namespace |