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
This commit is contained in:
Jakob Stoklund Olesen 2012-06-11 15:37:55 +00:00
parent 20aedcdfa3
commit 6f36fa981a
34 changed files with 915 additions and 1085 deletions

View File

@ -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

View File

@ -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";
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -15,13 +15,46 @@
//
//===----------------------------------------------------------------------===//
#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
@ -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

View File

@ -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);
};
}

View File

@ -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 {
OS << "/*===- TableGen'erated file "
<< "---------------------------------------*- C -*-===*\n"
<< " *\n"
<< " * " << Target.getName() << " Disassembler\n"
<< " *\n"
<< " * Automatically generated file, do not edit!\n"
<< " *\n"
<< " *===---------------------------------------------------------------"
<< "-------===*/\n";
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);
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

View File

@ -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

View File

@ -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 //
///////////////////////////////////////////////////////////
// TODO: These classes are probably generally useful to other backends;
// add them to TableGen's "helper" API's.
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;
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";
}
i -= 2;
o.indent(i) << "};" << "\n";
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 emitAsFlags(raw_ostream &o, unsigned int &i) {
o.indent(i) << "enum " << Name.c_str() << " {" << "\n";
i += 2;
i -= 2;
o.indent(i) << "};" << "\n";
}
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;
i -= 2;
o.indent(i) << "};" << "\n";
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
namespace {
class ConstantEmitter {
public:
virtual ~ConstantEmitter() { }
virtual void emit(raw_ostream &o, unsigned int &i) = 0;
};
} // End anonymous namespace
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 ConstantEmitter {
public:
virtual ~ConstantEmitter() { }
virtual void emit(raw_ostream &o, unsigned int &i) = 0;
};
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 LiteralConstantEmitter : public ConstantEmitter {
private:
bool IsNumber;
union {
int Number;
const char* String;
};
public:
LiteralConstantEmitter(int number = 0) :
IsNumber(true),
Number(number) {
return *this;
}
~CompoundConstantEmitter() {
while (Entries.size()) {
ConstantEmitter *entry = Entries.back();
Entries.pop_back();
delete entry;
}
void set(const char *string) {
IsNumber = false;
Number = 0;
String = string;
}
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;
}
bool is(const char *string) {
return !strcmp(String, string);
}
void emit(raw_ostream &o, unsigned int &i) {
if (IsNumber)
o << Number;
for (index = 0; index < numToPrint; ++index) {
o.indent(i);
if (index < numEntries)
Entries[index]->emit(o, i);
else
o << String;
o << "-1";
if (index < (numToPrint - 1))
o << ",";
o << "\n";
}
};
class CompoundConstantEmitter : public ConstantEmitter {
private:
unsigned int Padding;
std::vector<ConstantEmitter *> Entries;
public:
CompoundConstantEmitter(unsigned int padding = 0) : Padding(padding) {
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 << " | ";
}
CompoundConstantEmitter &addEntry(ConstantEmitter *e) {
Entries.push_back(e);
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;
}
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";
}
i -= 2;
o.indent(i) << "}";
}
};
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 << " | ";
}
}
};
}
EDEmitter::EDEmitter(RecordKeeper &R) : Records(R) {
}
}
};
} // 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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
};
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");
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;
}
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);
}
};
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

View File

@ -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

View File

@ -9,16 +9,62 @@
#define DEBUG_TYPE "pseudo-lowering"
#include "CodeGenInstruction.h"
#include "PseudoLoweringEmitter.h"
#include "CodeGenTarget.h"
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Debug.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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}
};

View File

@ -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