Home | History | Annotate | Download | only in CodeGen
      1 //===-- CodeGen/MachineInstBuilder.h - Simplify creation of MIs -*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file exposes a function named BuildMI, which is useful for dramatically
     11 // simplifying how MachineInstr's are created.  It allows use of code like this:
     12 //
     13 //   M = BuildMI(X86::ADDrr8, 2).addReg(argVal1).addReg(argVal2);
     14 //
     15 //===----------------------------------------------------------------------===//
     16 
     17 #ifndef LLVM_CODEGEN_MACHINEINSTRBUILDER_H
     18 #define LLVM_CODEGEN_MACHINEINSTRBUILDER_H
     19 
     20 #include "llvm/CodeGen/MachineFunction.h"
     21 #include "llvm/Support/ErrorHandling.h"
     22 
     23 namespace llvm {
     24 
     25 class MCInstrDesc;
     26 class MDNode;
     27 
     28 namespace RegState {
     29   enum {
     30     Define         = 0x2,
     31     Implicit       = 0x4,
     32     Kill           = 0x8,
     33     Dead           = 0x10,
     34     Undef          = 0x20,
     35     EarlyClobber   = 0x40,
     36     Debug          = 0x80,
     37     InternalRead   = 0x100,
     38     DefineNoRead   = Define | Undef,
     39     ImplicitDefine = Implicit | Define,
     40     ImplicitKill   = Implicit | Kill
     41   };
     42 }
     43 
     44 class MachineInstrBuilder {
     45   MachineInstr *MI;
     46 public:
     47   MachineInstrBuilder() : MI(0) {}
     48   explicit MachineInstrBuilder(MachineInstr *mi) : MI(mi) {}
     49 
     50   /// Allow automatic conversion to the machine instruction we are working on.
     51   ///
     52   operator MachineInstr*() const { return MI; }
     53   MachineInstr *operator->() const { return MI; }
     54   operator MachineBasicBlock::iterator() const { return MI; }
     55 
     56   /// addReg - Add a new virtual register operand...
     57   ///
     58   const
     59   MachineInstrBuilder &addReg(unsigned RegNo, unsigned flags = 0,
     60                               unsigned SubReg = 0) const {
     61     assert((flags & 0x1) == 0 &&
     62            "Passing in 'true' to addReg is forbidden! Use enums instead.");
     63     MI->addOperand(MachineOperand::CreateReg(RegNo,
     64                                              flags & RegState::Define,
     65                                              flags & RegState::Implicit,
     66                                              flags & RegState::Kill,
     67                                              flags & RegState::Dead,
     68                                              flags & RegState::Undef,
     69                                              flags & RegState::EarlyClobber,
     70                                              SubReg,
     71                                              flags & RegState::Debug,
     72                                              flags & RegState::InternalRead));
     73     return *this;
     74   }
     75 
     76   /// addImm - Add a new immediate operand.
     77   ///
     78   const MachineInstrBuilder &addImm(int64_t Val) const {
     79     MI->addOperand(MachineOperand::CreateImm(Val));
     80     return *this;
     81   }
     82 
     83   const MachineInstrBuilder &addCImm(const ConstantInt *Val) const {
     84     MI->addOperand(MachineOperand::CreateCImm(Val));
     85     return *this;
     86   }
     87 
     88   const MachineInstrBuilder &addFPImm(const ConstantFP *Val) const {
     89     MI->addOperand(MachineOperand::CreateFPImm(Val));
     90     return *this;
     91   }
     92 
     93   const MachineInstrBuilder &addMBB(MachineBasicBlock *MBB,
     94                                     unsigned char TargetFlags = 0) const {
     95     MI->addOperand(MachineOperand::CreateMBB(MBB, TargetFlags));
     96     return *this;
     97   }
     98 
     99   const MachineInstrBuilder &addFrameIndex(int Idx) const {
    100     MI->addOperand(MachineOperand::CreateFI(Idx));
    101     return *this;
    102   }
    103 
    104   const MachineInstrBuilder &addConstantPoolIndex(unsigned Idx,
    105                                                   int Offset = 0,
    106                                           unsigned char TargetFlags = 0) const {
    107     MI->addOperand(MachineOperand::CreateCPI(Idx, Offset, TargetFlags));
    108     return *this;
    109   }
    110 
    111   const MachineInstrBuilder &addTargetIndex(unsigned Idx, int64_t Offset = 0,
    112                                           unsigned char TargetFlags = 0) const {
    113     MI->addOperand(MachineOperand::CreateTargetIndex(Idx, Offset, TargetFlags));
    114     return *this;
    115   }
    116 
    117   const MachineInstrBuilder &addJumpTableIndex(unsigned Idx,
    118                                           unsigned char TargetFlags = 0) const {
    119     MI->addOperand(MachineOperand::CreateJTI(Idx, TargetFlags));
    120     return *this;
    121   }
    122 
    123   const MachineInstrBuilder &addGlobalAddress(const GlobalValue *GV,
    124                                               int64_t Offset = 0,
    125                                           unsigned char TargetFlags = 0) const {
    126     MI->addOperand(MachineOperand::CreateGA(GV, Offset, TargetFlags));
    127     return *this;
    128   }
    129 
    130   const MachineInstrBuilder &addExternalSymbol(const char *FnName,
    131                                           unsigned char TargetFlags = 0) const {
    132     MI->addOperand(MachineOperand::CreateES(FnName, TargetFlags));
    133     return *this;
    134   }
    135 
    136   const MachineInstrBuilder &addRegMask(const uint32_t *Mask) const {
    137     MI->addOperand(MachineOperand::CreateRegMask(Mask));
    138     return *this;
    139   }
    140 
    141   const MachineInstrBuilder &addMemOperand(MachineMemOperand *MMO) const {
    142     MI->addMemOperand(*MI->getParent()->getParent(), MMO);
    143     return *this;
    144   }
    145 
    146   const MachineInstrBuilder &setMemRefs(MachineInstr::mmo_iterator b,
    147                                         MachineInstr::mmo_iterator e) const {
    148     MI->setMemRefs(b, e);
    149     return *this;
    150   }
    151 
    152 
    153   const MachineInstrBuilder &addOperand(const MachineOperand &MO) const {
    154     MI->addOperand(MO);
    155     return *this;
    156   }
    157 
    158   const MachineInstrBuilder &addMetadata(const MDNode *MD) const {
    159     MI->addOperand(MachineOperand::CreateMetadata(MD));
    160     return *this;
    161   }
    162 
    163   const MachineInstrBuilder &addSym(MCSymbol *Sym) const {
    164     MI->addOperand(MachineOperand::CreateMCSymbol(Sym));
    165     return *this;
    166   }
    167 
    168   const MachineInstrBuilder &setMIFlags(unsigned Flags) const {
    169     MI->setFlags(Flags);
    170     return *this;
    171   }
    172 
    173   const MachineInstrBuilder &setMIFlag(MachineInstr::MIFlag Flag) const {
    174     MI->setFlag(Flag);
    175     return *this;
    176   }
    177 
    178   // Add a displacement from an existing MachineOperand with an added offset.
    179   const MachineInstrBuilder &addDisp(const MachineOperand &Disp,
    180                                      int64_t off) const {
    181     switch (Disp.getType()) {
    182       default:
    183         llvm_unreachable("Unhandled operand type in addDisp()");
    184       case MachineOperand::MO_Immediate:
    185         return addImm(Disp.getImm() + off);
    186       case MachineOperand::MO_GlobalAddress:
    187         return addGlobalAddress(Disp.getGlobal(), Disp.getOffset() + off);
    188     }
    189   }
    190 };
    191 
    192 /// BuildMI - Builder interface.  Specify how to create the initial instruction
    193 /// itself.
    194 ///
    195 inline MachineInstrBuilder BuildMI(MachineFunction &MF,
    196                                    DebugLoc DL,
    197                                    const MCInstrDesc &MCID) {
    198   return MachineInstrBuilder(MF.CreateMachineInstr(MCID, DL));
    199 }
    200 
    201 /// BuildMI - This version of the builder sets up the first operand as a
    202 /// destination virtual register.
    203 ///
    204 inline MachineInstrBuilder BuildMI(MachineFunction &MF,
    205                                    DebugLoc DL,
    206                                    const MCInstrDesc &MCID,
    207                                    unsigned DestReg) {
    208   return MachineInstrBuilder(MF.CreateMachineInstr(MCID, DL))
    209            .addReg(DestReg, RegState::Define);
    210 }
    211 
    212 /// BuildMI - This version of the builder inserts the newly-built
    213 /// instruction before the given position in the given MachineBasicBlock, and
    214 /// sets up the first operand as a destination virtual register.
    215 ///
    216 inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
    217                                    MachineBasicBlock::iterator I,
    218                                    DebugLoc DL,
    219                                    const MCInstrDesc &MCID,
    220                                    unsigned DestReg) {
    221   MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL);
    222   BB.insert(I, MI);
    223   return MachineInstrBuilder(MI).addReg(DestReg, RegState::Define);
    224 }
    225 
    226 inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
    227                                    MachineBasicBlock::instr_iterator I,
    228                                    DebugLoc DL,
    229                                    const MCInstrDesc &MCID,
    230                                    unsigned DestReg) {
    231   MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL);
    232   BB.insert(I, MI);
    233   return MachineInstrBuilder(MI).addReg(DestReg, RegState::Define);
    234 }
    235 
    236 inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
    237                                    MachineInstr *I,
    238                                    DebugLoc DL,
    239                                    const MCInstrDesc &MCID,
    240                                    unsigned DestReg) {
    241   if (I->isInsideBundle()) {
    242     MachineBasicBlock::instr_iterator MII = I;
    243     return BuildMI(BB, MII, DL, MCID, DestReg);
    244   }
    245 
    246   MachineBasicBlock::iterator MII = I;
    247   return BuildMI(BB, MII, DL, MCID, DestReg);
    248 }
    249 
    250 /// BuildMI - This version of the builder inserts the newly-built
    251 /// instruction before the given position in the given MachineBasicBlock, and
    252 /// does NOT take a destination register.
    253 ///
    254 inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
    255                                    MachineBasicBlock::iterator I,
    256                                    DebugLoc DL,
    257                                    const MCInstrDesc &MCID) {
    258   MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL);
    259   BB.insert(I, MI);
    260   return MachineInstrBuilder(MI);
    261 }
    262 
    263 inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
    264                                    MachineBasicBlock::instr_iterator I,
    265                                    DebugLoc DL,
    266                                    const MCInstrDesc &MCID) {
    267   MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL);
    268   BB.insert(I, MI);
    269   return MachineInstrBuilder(MI);
    270 }
    271 
    272 inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
    273                                    MachineInstr *I,
    274                                    DebugLoc DL,
    275                                    const MCInstrDesc &MCID) {
    276   if (I->isInsideBundle()) {
    277     MachineBasicBlock::instr_iterator MII = I;
    278     return BuildMI(BB, MII, DL, MCID);
    279   }
    280 
    281   MachineBasicBlock::iterator MII = I;
    282   return BuildMI(BB, MII, DL, MCID);
    283 }
    284 
    285 /// BuildMI - This version of the builder inserts the newly-built
    286 /// instruction at the end of the given MachineBasicBlock, and does NOT take a
    287 /// destination register.
    288 ///
    289 inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
    290                                    DebugLoc DL,
    291                                    const MCInstrDesc &MCID) {
    292   return BuildMI(*BB, BB->end(), DL, MCID);
    293 }
    294 
    295 /// BuildMI - This version of the builder inserts the newly-built
    296 /// instruction at the end of the given MachineBasicBlock, and sets up the first
    297 /// operand as a destination virtual register.
    298 ///
    299 inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
    300                                    DebugLoc DL,
    301                                    const MCInstrDesc &MCID,
    302                                    unsigned DestReg) {
    303   return BuildMI(*BB, BB->end(), DL, MCID, DestReg);
    304 }
    305 
    306 inline unsigned getDefRegState(bool B) {
    307   return B ? RegState::Define : 0;
    308 }
    309 inline unsigned getImplRegState(bool B) {
    310   return B ? RegState::Implicit : 0;
    311 }
    312 inline unsigned getKillRegState(bool B) {
    313   return B ? RegState::Kill : 0;
    314 }
    315 inline unsigned getDeadRegState(bool B) {
    316   return B ? RegState::Dead : 0;
    317 }
    318 inline unsigned getUndefRegState(bool B) {
    319   return B ? RegState::Undef : 0;
    320 }
    321 inline unsigned getInternalReadRegState(bool B) {
    322   return B ? RegState::InternalRead : 0;
    323 }
    324 
    325 } // End llvm namespace
    326 
    327 #endif
    328