1 //===-- llvm/CodeGen/GlobalISel/MachineIRBuilder.cpp - MIBuilder--*- 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 /// \file 10 /// This file implements the MachineIRBuidler class. 11 //===----------------------------------------------------------------------===// 12 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" 13 14 #include "llvm/CodeGen/MachineFunction.h" 15 #include "llvm/CodeGen/MachineInstr.h" 16 #include "llvm/CodeGen/MachineInstrBuilder.h" 17 #include "llvm/Target/TargetInstrInfo.h" 18 #include "llvm/Target/TargetOpcodes.h" 19 #include "llvm/Target/TargetSubtargetInfo.h" 20 21 using namespace llvm; 22 23 void MachineIRBuilder::setMF(MachineFunction &MF) { 24 this->MF = &MF; 25 this->MBB = nullptr; 26 this->TII = MF.getSubtarget().getInstrInfo(); 27 this->DL = DebugLoc(); 28 this->MI = nullptr; 29 } 30 31 void MachineIRBuilder::setMBB(MachineBasicBlock &MBB, bool Beginning) { 32 this->MBB = &MBB; 33 Before = Beginning; 34 assert(&getMF() == MBB.getParent() && 35 "Basic block is in a different function"); 36 } 37 38 void MachineIRBuilder::setInstr(MachineInstr &MI, bool Before) { 39 assert(MI.getParent() && "Instruction is not part of a basic block"); 40 setMBB(*MI.getParent()); 41 this->MI = &MI; 42 this->Before = Before; 43 } 44 45 MachineBasicBlock::iterator MachineIRBuilder::getInsertPt() { 46 if (MI) { 47 if (Before) 48 return MI; 49 if (!MI->getNextNode()) 50 return getMBB().end(); 51 return MI->getNextNode(); 52 } 53 return Before ? getMBB().begin() : getMBB().end(); 54 } 55 56 //------------------------------------------------------------------------------ 57 // Build instruction variants. 58 //------------------------------------------------------------------------------ 59 60 MachineInstrBuilder MachineIRBuilder::buildInstr(unsigned Opcode, 61 ArrayRef<LLT> Tys) { 62 MachineInstrBuilder MIB = BuildMI(getMF(), DL, getTII().get(Opcode)); 63 if (Tys.size() > 0) { 64 assert(isPreISelGenericOpcode(Opcode) && 65 "Only generic instruction can have a type"); 66 for (unsigned i = 0; i < Tys.size(); ++i) 67 MIB->setType(Tys[i], i); 68 } else 69 assert(!isPreISelGenericOpcode(Opcode) && 70 "Generic instruction must have a type"); 71 getMBB().insert(getInsertPt(), MIB); 72 return MIB; 73 } 74 75 MachineInstrBuilder MachineIRBuilder::buildFrameIndex(LLT Ty, unsigned Res, 76 int Idx) { 77 return buildInstr(TargetOpcode::G_FRAME_INDEX, Ty) 78 .addDef(Res) 79 .addFrameIndex(Idx); 80 } 81 82 MachineInstrBuilder MachineIRBuilder::buildAdd(LLT Ty, unsigned Res, 83 unsigned Op0, unsigned Op1) { 84 return buildInstr(TargetOpcode::G_ADD, Ty) 85 .addDef(Res) 86 .addUse(Op0) 87 .addUse(Op1); 88 } 89 90 MachineInstrBuilder MachineIRBuilder::buildBr(MachineBasicBlock &Dest) { 91 return buildInstr(TargetOpcode::G_BR, LLT::unsized()).addMBB(&Dest); 92 } 93 94 MachineInstrBuilder MachineIRBuilder::buildCopy(unsigned Res, unsigned Op) { 95 return buildInstr(TargetOpcode::COPY).addDef(Res).addUse(Op); 96 } 97 98 MachineInstrBuilder MachineIRBuilder::buildConstant(LLT Ty, unsigned Res, 99 int64_t Val) { 100 return buildInstr(TargetOpcode::G_CONSTANT, Ty).addDef(Res).addImm(Val); 101 } 102 103 MachineInstrBuilder MachineIRBuilder::buildBrCond(LLT Ty, unsigned Tst, 104 MachineBasicBlock &Dest) { 105 return buildInstr(TargetOpcode::G_BRCOND, Ty).addUse(Tst).addMBB(&Dest); 106 } 107 108 109 MachineInstrBuilder MachineIRBuilder::buildLoad(LLT VTy, LLT PTy, unsigned Res, 110 unsigned Addr, 111 MachineMemOperand &MMO) { 112 return buildInstr(TargetOpcode::G_LOAD, {VTy, PTy}) 113 .addDef(Res) 114 .addUse(Addr) 115 .addMemOperand(&MMO); 116 } 117 118 MachineInstrBuilder MachineIRBuilder::buildStore(LLT VTy, LLT PTy, 119 unsigned Val, unsigned Addr, 120 MachineMemOperand &MMO) { 121 return buildInstr(TargetOpcode::G_STORE, {VTy, PTy}) 122 .addUse(Val) 123 .addUse(Addr) 124 .addMemOperand(&MMO); 125 } 126 127 MachineInstrBuilder MachineIRBuilder::buildAdde(LLT Ty, unsigned Res, 128 unsigned CarryOut, unsigned Op0, 129 unsigned Op1, 130 unsigned CarryIn) { 131 return buildInstr(TargetOpcode::G_ADDE, Ty) 132 .addDef(Res) 133 .addDef(CarryOut) 134 .addUse(Op0) 135 .addUse(Op1) 136 .addUse(CarryIn); 137 } 138 139 MachineInstrBuilder MachineIRBuilder::buildAnyExtend(LLT Ty, unsigned Res, 140 unsigned Op) { 141 return buildInstr(TargetOpcode::G_ANYEXTEND, Ty).addDef(Res).addUse(Op); 142 } 143 144 MachineInstrBuilder 145 MachineIRBuilder::buildExtract(LLT Ty, ArrayRef<unsigned> Results, unsigned Src, 146 ArrayRef<unsigned> Indexes) { 147 assert(Results.size() == Indexes.size() && "inconsistent number of regs"); 148 149 MachineInstrBuilder MIB = buildInstr(TargetOpcode::G_EXTRACT, Ty); 150 for (auto Res : Results) 151 MIB.addDef(Res); 152 153 MIB.addUse(Src); 154 155 for (auto Idx : Indexes) 156 MIB.addImm(Idx); 157 return MIB; 158 } 159 160 MachineInstrBuilder MachineIRBuilder::buildSequence(LLT Ty, unsigned Res, 161 ArrayRef<unsigned> Ops) { 162 MachineInstrBuilder MIB = buildInstr(TargetOpcode::G_SEQUENCE, Ty); 163 MIB.addDef(Res); 164 for (auto Op : Ops) 165 MIB.addUse(Op); 166 return MIB; 167 } 168 169 MachineInstrBuilder MachineIRBuilder::buildIntrinsic(ArrayRef<LLT> Tys, 170 Intrinsic::ID ID, 171 unsigned Res, 172 bool HasSideEffects) { 173 auto MIB = 174 buildInstr(HasSideEffects ? TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS 175 : TargetOpcode::G_INTRINSIC, 176 Tys); 177 if (Res) 178 MIB.addDef(Res); 179 MIB.addIntrinsicID(ID); 180 return MIB; 181 } 182 183 MachineInstrBuilder MachineIRBuilder::buildTrunc(LLT Ty, unsigned Res, 184 unsigned Op) { 185 return buildInstr(TargetOpcode::G_TRUNC, Ty).addDef(Res).addUse(Op); 186 } 187