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