TableGen: Generate an enum for all named Operand types in tblgen'd InstrInfo.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194978 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Ahmed Bougacha 2013-11-17 21:24:41 +00:00
parent 0df7f51365
commit b923d2f5f5
2 changed files with 75 additions and 0 deletions

View File

@ -955,6 +955,50 @@ XXXInstrInfo.h:
int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIndex);
} // End namespace XXX
Instruction Operand Types
^^^^^^^^^^^^^^^^^^^^^^^^^
TableGen will also generate an enumeration consisting of all named Operand
types defined in the backend, in the llvm::XXX::OpTypes namespace.
Some common immediate Operand types (for instance i8, i32, i64, f32, f64)
are defined for all targets in ``include/llvm/Target/Target.td``, and are
available in each Target's OpTypes enum. Also, only named Operand types appear
in the enumeration: anonymous types are ignored.
For example, the X86 backend defines ``brtarget`` and ``brtarget8``, both
instances of the TableGen ``Operand`` class, which represent branch target
operands:
.. code-block:: llvm
def brtarget : Operand<OtherVT>;
def brtarget8 : Operand<OtherVT>;
This results in:
.. code-block:: c++
namespace X86 {
namespace OpTypes {
enum OperandType {
...
brtarget,
brtarget8,
...
i32imm,
i64imm,
...
OPERAND_TYPE_LIST_END
} // End namespace OpTypes
} // End namespace X86
In typical TableGen fashion, to use the enum, you will need to define a
preprocessor macro:
.. code-block:: c++
#define GET_INSTRINFO_OPERAND_TYPES_ENUM // For OpTypes enum
#include "XXXGenInstrInfo.inc"
Instruction Scheduling
----------------------

View File

@ -57,6 +57,7 @@ private:
std::map<std::vector<Record*>, unsigned> &EL,
const OperandInfoMapTy &OpInfo,
raw_ostream &OS);
void emitOperandTypesEnum(raw_ostream &OS, const CodeGenTarget &Target);
void initOperandMapData(
const std::vector<const CodeGenInstruction *> NumberedInstructions,
const std::string &Namespace,
@ -311,6 +312,34 @@ void InstrInfoEmitter::emitOperandNameMappings(raw_ostream &OS,
}
/// Generate an enum for all the operand types for this target, under the
/// llvm::TargetNamespace::OpTypes namespace.
/// Operand types are all definitions derived of the Operand Target.td class.
void InstrInfoEmitter::emitOperandTypesEnum(raw_ostream &OS,
const CodeGenTarget &Target) {
const std::string &Namespace = Target.getInstNamespace();
std::vector<Record *> Operands = Records.getAllDerivedDefinitions("Operand");
OS << "\n#ifdef GET_INSTRINFO_OPERAND_TYPES_ENUM\n";
OS << "#undef GET_INSTRINFO_OPERAND_TYPES_ENUM\n";
OS << "namespace llvm {";
OS << "namespace " << Namespace << " {\n";
OS << "namespace OpTypes { \n";
OS << "enum OperandType {\n";
for (unsigned oi = 0, oe = Operands.size(); oi != oe; ++oi) {
if (!Operands[oi]->isAnonymous())
OS << " " << Operands[oi]->getName() << " = " << oi << ",\n";
}
OS << " OPERAND_TYPE_LIST_END" << "\n};\n";
OS << "} // End namespace OpTypes\n";
OS << "} // End namespace " << Namespace << "\n";
OS << "} // End namespace llvm\n";
OS << "#endif // GET_INSTRINFO_OPERAND_TYPES_ENUM\n";
}
//===----------------------------------------------------------------------===//
// Main Output.
//===----------------------------------------------------------------------===//
@ -432,6 +461,8 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
OS << "#endif // GET_INSTRINFO_CTOR_DTOR\n\n";
emitOperandNameMappings(OS, Target, NumberedInstructions);
emitOperandTypesEnum(OS, Target);
}
void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,