blob: 923238955627214f577d289da1646e5c8c80f18b [file] [log] [blame]
Quentin Colombet2ad1f852016-02-11 17:44:59 +00001//===-- 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"
Quentin Colombet8fd67182016-02-11 21:16:56 +000018#include "llvm/Target/TargetOpcodes.h"
Quentin Colombet2ad1f852016-02-11 17:44:59 +000019#include "llvm/Target/TargetSubtargetInfo.h"
20
21using namespace llvm;
22
Quentin Colombet000b5802016-03-11 17:27:51 +000023void MachineIRBuilder::setMF(MachineFunction &MF) {
Quentin Colombet2ad1f852016-02-11 17:44:59 +000024 this->MF = &MF;
25 this->MBB = nullptr;
26 this->TII = MF.getSubtarget().getInstrInfo();
27 this->DL = DebugLoc();
28 this->MI = nullptr;
29}
30
Quentin Colombet91ebd712016-03-11 17:27:47 +000031void MachineIRBuilder::setMBB(MachineBasicBlock &MBB, bool Beginning) {
Quentin Colombet2ad1f852016-02-11 17:44:59 +000032 this->MBB = &MBB;
33 Before = Beginning;
34 assert(&getMF() == MBB.getParent() &&
35 "Basic block is in a different function");
36}
37
38void MachineIRBuilder::setInstr(MachineInstr &MI, bool Before) {
39 assert(MI.getParent() && "Instruction is not part of a basic block");
Quentin Colombet91ebd712016-03-11 17:27:47 +000040 setMBB(*MI.getParent());
Quentin Colombet2ad1f852016-02-11 17:44:59 +000041 this->MI = &MI;
42 this->Before = Before;
43}
44
45MachineBasicBlock::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
Quentin Colombetf9b49342016-03-11 17:27:58 +000056//------------------------------------------------------------------------------
57// Build instruction variants.
58//------------------------------------------------------------------------------
Tim Northovercc5f7622016-07-26 16:45:26 +000059
Tim Northovera51575f2016-07-29 17:43:52 +000060MachineInstrBuilder MachineIRBuilder::buildInstr(unsigned Opcode,
61 ArrayRef<LLT> Tys) {
62 MachineInstrBuilder MIB = BuildMI(getMF(), DL, getTII().get(Opcode));
Tim Northovercc5f7622016-07-26 16:45:26 +000063 if (Tys.size() > 0) {
Quentin Colombet8fd67182016-02-11 21:16:56 +000064 assert(isPreISelGenericOpcode(Opcode) &&
65 "Only generic instruction can have a type");
Tim Northovercc5f7622016-07-26 16:45:26 +000066 for (unsigned i = 0; i < Tys.size(); ++i)
Tim Northovera51575f2016-07-29 17:43:52 +000067 MIB->setType(Tys[i], i);
Quentin Colombet8fd67182016-02-11 21:16:56 +000068 } else
69 assert(!isPreISelGenericOpcode(Opcode) &&
70 "Generic instruction must have a type");
Tim Northovera51575f2016-07-29 17:43:52 +000071 getMBB().insert(getInsertPt(), MIB);
72 return MIB;
Quentin Colombet74d7d2f2016-02-11 18:53:28 +000073}
74
Tim Northovera51575f2016-07-29 17:43:52 +000075MachineInstrBuilder MachineIRBuilder::buildFrameIndex(LLT Ty, unsigned Res,
76 int Idx) {
77 return buildInstr(TargetOpcode::G_FRAME_INDEX, Ty)
78 .addDef(Res)
79 .addFrameIndex(Idx);
Tim Northoverbd505462016-07-22 16:59:52 +000080}
Tim Northover33b07d62016-07-22 20:03:43 +000081
Tim Northovera51575f2016-07-29 17:43:52 +000082MachineInstrBuilder 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);
Tim Northover33b07d62016-07-22 20:03:43 +000088}
89
Tim Northovera51575f2016-07-29 17:43:52 +000090MachineInstrBuilder MachineIRBuilder::buildBr(MachineBasicBlock &Dest) {
91 return buildInstr(TargetOpcode::G_BR, LLT::unsized()).addMBB(&Dest);
Tim Northovercc5f7622016-07-26 16:45:26 +000092}
93
Tim Northovera51575f2016-07-29 17:43:52 +000094MachineInstrBuilder MachineIRBuilder::buildCopy(unsigned Res, unsigned Op) {
95 return buildInstr(TargetOpcode::COPY).addDef(Res).addUse(Op);
Tim Northover756eca32016-07-26 16:45:30 +000096}
97
Tim Northover9656f142016-08-04 20:54:13 +000098MachineInstrBuilder MachineIRBuilder::buildConstant(LLT Ty, unsigned Res,
99 int64_t Val) {
100 return buildInstr(TargetOpcode::G_CONSTANT, Ty).addDef(Res).addImm(Val);
101}
102
Tim Northoverb16734f2016-08-19 20:09:15 +0000103MachineInstrBuilder MachineIRBuilder::buildFConstant(LLT Ty, unsigned Res,
104 const ConstantFP &Val) {
105 return buildInstr(TargetOpcode::G_FCONSTANT, Ty).addDef(Res).addFPImm(&Val);
106}
107
Tim Northover69c2ba52016-07-29 17:58:00 +0000108MachineInstrBuilder MachineIRBuilder::buildBrCond(LLT Ty, unsigned Tst,
109 MachineBasicBlock &Dest) {
110 return buildInstr(TargetOpcode::G_BRCOND, Ty).addUse(Tst).addMBB(&Dest);
111}
112
113
114 MachineInstrBuilder MachineIRBuilder::buildLoad(LLT VTy, LLT PTy, unsigned Res,
Tim Northovera51575f2016-07-29 17:43:52 +0000115 unsigned Addr,
116 MachineMemOperand &MMO) {
117 return buildInstr(TargetOpcode::G_LOAD, {VTy, PTy})
118 .addDef(Res)
119 .addUse(Addr)
120 .addMemOperand(&MMO);
Tim Northoverad2b7172016-07-26 20:23:26 +0000121}
122
Tim Northovera51575f2016-07-29 17:43:52 +0000123MachineInstrBuilder MachineIRBuilder::buildStore(LLT VTy, LLT PTy,
124 unsigned Val, unsigned Addr,
125 MachineMemOperand &MMO) {
126 return buildInstr(TargetOpcode::G_STORE, {VTy, PTy})
127 .addUse(Val)
128 .addUse(Addr)
129 .addMemOperand(&MMO);
Tim Northoverad2b7172016-07-26 20:23:26 +0000130}
131
Tim Northover91c81732016-08-19 17:17:06 +0000132MachineInstrBuilder MachineIRBuilder::buildUAdde(LLT Ty, unsigned Res,
133 unsigned CarryOut,
134 unsigned Op0, unsigned Op1,
135 unsigned CarryIn) {
136 return buildInstr(TargetOpcode::G_UADDE, Ty)
Tim Northover9656f142016-08-04 20:54:13 +0000137 .addDef(Res)
138 .addDef(CarryOut)
139 .addUse(Op0)
140 .addUse(Op1)
141 .addUse(CarryIn);
142}
143
Tim Northover32335812016-08-04 18:35:11 +0000144MachineInstrBuilder MachineIRBuilder::buildAnyExtend(LLT Ty, unsigned Res,
145 unsigned Op) {
146 return buildInstr(TargetOpcode::G_ANYEXTEND, Ty).addDef(Res).addUse(Op);
147}
148
Tim Northover6cd4b232016-08-23 21:01:26 +0000149MachineInstrBuilder MachineIRBuilder::buildSExt(ArrayRef<LLT> Tys, unsigned Res,
150 unsigned Op) {
151 return buildInstr(TargetOpcode::G_SEXT, Tys).addDef(Res).addUse(Op);
152}
153
154MachineInstrBuilder MachineIRBuilder::buildZExt(ArrayRef<LLT> Tys, unsigned Res,
155 unsigned Op) {
156 return buildInstr(TargetOpcode::G_ZEXT, Tys).addDef(Res).addUse(Op);
157}
158
Tim Northover26b76f22016-08-19 18:32:14 +0000159MachineInstrBuilder MachineIRBuilder::buildExtract(ArrayRef<LLT> ResTys,
160 ArrayRef<unsigned> Results,
161 ArrayRef<uint64_t> Indices,
162 LLT SrcTy, unsigned Src) {
163 assert(ResTys.size() == Results.size() && Results.size() == Indices.size() &&
164 "inconsistent number of regs");
165 assert(!Results.empty() && "invalid trivial extract");
Tim Northover33b07d62016-07-22 20:03:43 +0000166
Tim Northover26b76f22016-08-19 18:32:14 +0000167 auto MIB = BuildMI(getMF(), DL, getTII().get(TargetOpcode::G_EXTRACT));
168 for (unsigned i = 0; i < ResTys.size(); ++i)
169 MIB->setType(LLT::scalar(ResTys[i].getSizeInBits()), i);
170 MIB->setType(LLT::scalar(SrcTy.getSizeInBits()), ResTys.size());
171
Tim Northover33b07d62016-07-22 20:03:43 +0000172 for (auto Res : Results)
Tim Northovera51575f2016-07-29 17:43:52 +0000173 MIB.addDef(Res);
Tim Northover33b07d62016-07-22 20:03:43 +0000174
Tim Northovera51575f2016-07-29 17:43:52 +0000175 MIB.addUse(Src);
Tim Northover33b07d62016-07-22 20:03:43 +0000176
Tim Northover26b76f22016-08-19 18:32:14 +0000177 for (auto Idx : Indices)
Tim Northover33b07d62016-07-22 20:03:43 +0000178 MIB.addImm(Idx);
Tim Northover26b76f22016-08-19 18:32:14 +0000179
180 getMBB().insert(getInsertPt(), MIB);
181
Tim Northovera51575f2016-07-29 17:43:52 +0000182 return MIB;
Tim Northover33b07d62016-07-22 20:03:43 +0000183}
184
Tim Northover91c81732016-08-19 17:17:06 +0000185MachineInstrBuilder
Tim Northover26b76f22016-08-19 18:32:14 +0000186MachineIRBuilder::buildSequence(LLT ResTy, unsigned Res,
187 ArrayRef<LLT> OpTys,
Tim Northover91c81732016-08-19 17:17:06 +0000188 ArrayRef<unsigned> Ops,
Tim Northover26b76f22016-08-19 18:32:14 +0000189 ArrayRef<unsigned> Indices) {
190 assert(OpTys.size() == Ops.size() && Ops.size() == Indices.size() &&
191 "incompatible args");
192 assert(!Ops.empty() && "invalid trivial sequence");
Tim Northover91c81732016-08-19 17:17:06 +0000193
Tim Northover26b76f22016-08-19 18:32:14 +0000194 MachineInstrBuilder MIB =
195 buildInstr(TargetOpcode::G_SEQUENCE, LLT::scalar(ResTy.getSizeInBits()));
Tim Northovera51575f2016-07-29 17:43:52 +0000196 MIB.addDef(Res);
Tim Northover91c81732016-08-19 17:17:06 +0000197 for (unsigned i = 0; i < Ops.size(); ++i) {
198 MIB.addUse(Ops[i]);
Tim Northover26b76f22016-08-19 18:32:14 +0000199 MIB.addImm(Indices[i]);
200 MIB->setType(LLT::scalar(OpTys[i].getSizeInBits()), MIB->getNumTypes());
Tim Northover91c81732016-08-19 17:17:06 +0000201 }
Tim Northovera51575f2016-07-29 17:43:52 +0000202 return MIB;
Tim Northover33b07d62016-07-22 20:03:43 +0000203}
Tim Northover5fb414d2016-07-29 22:32:36 +0000204
205MachineInstrBuilder MachineIRBuilder::buildIntrinsic(ArrayRef<LLT> Tys,
206 Intrinsic::ID ID,
207 unsigned Res,
208 bool HasSideEffects) {
209 auto MIB =
210 buildInstr(HasSideEffects ? TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS
211 : TargetOpcode::G_INTRINSIC,
212 Tys);
213 if (Res)
214 MIB.addDef(Res);
215 MIB.addIntrinsicID(ID);
216 return MIB;
217}
Tim Northover32335812016-08-04 18:35:11 +0000218
219MachineInstrBuilder MachineIRBuilder::buildTrunc(LLT Ty, unsigned Res,
220 unsigned Op) {
221 return buildInstr(TargetOpcode::G_TRUNC, Ty).addDef(Res).addUse(Op);
222}
Tim Northoverde3aea0412016-08-17 20:25:25 +0000223
Tim Northovera11be042016-08-19 22:40:08 +0000224MachineInstrBuilder MachineIRBuilder::buildFPTrunc(LLT Ty, unsigned Res,
225 unsigned Op) {
226 return buildInstr(TargetOpcode::G_FPTRUNC, Ty).addDef(Res).addUse(Op);
227}
228
Tim Northoverde3aea0412016-08-17 20:25:25 +0000229MachineInstrBuilder MachineIRBuilder::buildICmp(ArrayRef<LLT> Tys,
230 CmpInst::Predicate Pred,
231 unsigned Res, unsigned Op0,
232 unsigned Op1) {
233 return buildInstr(TargetOpcode::G_ICMP, Tys)
234 .addDef(Res)
235 .addPredicate(Pred)
236 .addUse(Op0)
237 .addUse(Op1);
238}
Tim Northover5a28c362016-08-19 20:09:07 +0000239
Tim Northoverd5c23bc2016-08-19 20:48:16 +0000240MachineInstrBuilder MachineIRBuilder::buildFCmp(ArrayRef<LLT> Tys,
241 CmpInst::Predicate Pred,
242 unsigned Res, unsigned Op0,
243 unsigned Op1) {
244 return buildInstr(TargetOpcode::G_FCMP, Tys)
245 .addDef(Res)
246 .addPredicate(Pred)
247 .addUse(Op0)
248 .addUse(Op1);
249}
250
Tim Northover5a28c362016-08-19 20:09:07 +0000251MachineInstrBuilder MachineIRBuilder::buildSelect(LLT Ty, unsigned Res,
252 unsigned Tst,
253 unsigned Op0, unsigned Op1) {
254 return buildInstr(TargetOpcode::G_SELECT, {Ty, LLT::scalar(1)})
255 .addDef(Res)
256 .addUse(Tst)
257 .addUse(Op0)
258 .addUse(Op1);
259}