X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=docs%2FWritingAnLLVMBackend.rst;h=fdadbb04e94f73bf4e7c6e415101dbc8a7a87e5b;hb=eab2da952c9cd17517e92bcd30323767daed2403;hp=a03a5e42c22d0a09109f20073b3c6dbfafc85a91;hpb=15a3c18623a05a8b9f2f4ea0b0c15965fda4fe6f;p=oota-llvm.git diff --git a/docs/WritingAnLLVMBackend.rst b/docs/WritingAnLLVMBackend.rst index a03a5e42c22..fdadbb04e94 100644 --- a/docs/WritingAnLLVMBackend.rst +++ b/docs/WritingAnLLVMBackend.rst @@ -1,6 +1,6 @@ -================================ -Writing an LLVM Compiler Backend -================================ +======================= +Writing an LLVM Backend +======================= .. toctree:: :hidden: @@ -51,7 +51,7 @@ These essential documents must be read before reading this document: Formation, SSA-based Optimization, Register Allocation, Prolog/Epilog Code Insertion, Late Machine Code Optimizations, and Code Emission. -* :doc:`TableGenFundamentals` --- a document that describes the TableGen +* :doc:`TableGen/index` --- a document that describes the TableGen (``tblgen``) application that manages domain-specific information to support LLVM code generation. TableGen processes input from a target description file (``.td`` suffix) and generates C++ code that can be used for code @@ -161,7 +161,7 @@ To get LLVM to actually build and link your target, you need to add it to the know about your target when parsing the ``--enable-targets`` option. Search the configure script for ``TARGETS_TO_BUILD``, add your target to the lists there (some creativity required), and then reconfigure. Alternatively, you can -change ``autotools/configure.ac`` and regenerate configure by running +change ``autoconf/configure.ac`` and regenerate configure by running ``./autoconf/AutoRegen.sh``. Target Machine @@ -238,6 +238,12 @@ For some targets, you also need to support the following methods: * ``getTargetLowering()`` * ``getJITInfo()`` +Some architectures, such as GPUs, do not support jumping to an arbitrary +program location and implement branching using masked execution and loop using +special instructions around the loop body. In order to avoid CFG modifications +that introduce irreducible control flow not handled by such hardware, a target +must call `setRequiresStructuredCFG(true)` when being initialized. + In addition, the ``XXXTargetMachine`` constructor should specify a ``TargetDescription`` string that determines the data layout for the target machine, including characteristics such as pointer size, alignment, and @@ -911,6 +917,103 @@ format instructions will bind the operands to the ``rd``, ``rs1``, and ``rs2`` fields. This results in the ``XNORrr`` instruction binding ``$dst``, ``$b``, and ``$c`` operands to the ``rd``, ``rs1``, and ``rs2`` fields respectively. +Instruction Operand Name Mapping +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +TableGen will also generate a function called getNamedOperandIdx() which +can be used to look up an operand's index in a MachineInstr based on its +TableGen name. Setting the UseNamedOperandTable bit in an instruction's +TableGen definition will add all of its operands to an enumeration in the +llvm::XXX:OpName namespace and also add an entry for it into the OperandMap +table, which can be queried using getNamedOperandIdx() + +.. code-block:: llvm + + int DstIndex = SP::getNamedOperandIdx(SP::XNORrr, SP::OpName::dst); // => 0 + int BIndex = SP::getNamedOperandIdx(SP::XNORrr, SP::OpName::b); // => 1 + int CIndex = SP::getNamedOperandIdx(SP::XNORrr, SP::OpName::c); // => 2 + int DIndex = SP::getNamedOperandIdx(SP::XNORrr, SP::OpName::d); // => -1 + + ... + +The entries in the OpName enum are taken verbatim from the TableGen definitions, +so operands with lowercase names will have lower case entries in the enum. + +To include the getNamedOperandIdx() function in your backend, you will need +to define a few preprocessor macros in XXXInstrInfo.cpp and XXXInstrInfo.h. +For example: + +XXXInstrInfo.cpp: + +.. code-block:: c++ + + #define GET_INSTRINFO_NAMED_OPS // For getNamedOperandIdx() function + #include "XXXGenInstrInfo.inc" + +XXXInstrInfo.h: + +.. code-block:: c++ + + #define GET_INSTRINFO_OPERAND_ENUM // For OpName enum + #include "XXXGenInstrInfo.inc" + + namespace XXX { + 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; + def brtarget8 : Operand; + +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 +---------------------- + +Instruction itineraries can be queried using MCDesc::getSchedClass(). The +value can be named by an enumemation in llvm::XXX::Sched namespace generated +by TableGen in XXXGenInstrInfo.inc. The name of the schedule classes are +the same as provided in XXXSchedule.td plus a default NoItinerary class. + Instruction Relation Mapping ----------------------------