blob: c9499ca7e6fb44a14e0450f1c249b61221924d29 [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 Northoverbdf67c92016-08-23 21:01:33 +0000144MachineInstrBuilder MachineIRBuilder::buildAnyExt(ArrayRef<LLT> Tys,
145 unsigned Res, unsigned Op) {
146 validateTruncExt(Tys, true);
147 return buildInstr(TargetOpcode::G_ANYEXT, Tys).addDef(Res).addUse(Op);
Tim Northover32335812016-08-04 18:35:11 +0000148}
149
Tim Northover6cd4b232016-08-23 21:01:26 +0000150MachineInstrBuilder MachineIRBuilder::buildSExt(ArrayRef<LLT> Tys, unsigned Res,
151 unsigned Op) {
Tim Northoverbdf67c92016-08-23 21:01:33 +0000152 validateTruncExt(Tys, true);
Tim Northover6cd4b232016-08-23 21:01:26 +0000153 return buildInstr(TargetOpcode::G_SEXT, Tys).addDef(Res).addUse(Op);
154}
155
156MachineInstrBuilder MachineIRBuilder::buildZExt(ArrayRef<LLT> Tys, unsigned Res,
157 unsigned Op) {
Tim Northoverbdf67c92016-08-23 21:01:33 +0000158 validateTruncExt(Tys, true);
Tim Northover6cd4b232016-08-23 21:01:26 +0000159 return buildInstr(TargetOpcode::G_ZEXT, Tys).addDef(Res).addUse(Op);
160}
161
Tim Northover26b76f22016-08-19 18:32:14 +0000162MachineInstrBuilder MachineIRBuilder::buildExtract(ArrayRef<LLT> ResTys,
163 ArrayRef<unsigned> Results,
164 ArrayRef<uint64_t> Indices,
165 LLT SrcTy, unsigned Src) {
166 assert(ResTys.size() == Results.size() && Results.size() == Indices.size() &&
167 "inconsistent number of regs");
168 assert(!Results.empty() && "invalid trivial extract");
Tim Northover33b07d62016-07-22 20:03:43 +0000169
Tim Northover26b76f22016-08-19 18:32:14 +0000170 auto MIB = BuildMI(getMF(), DL, getTII().get(TargetOpcode::G_EXTRACT));
171 for (unsigned i = 0; i < ResTys.size(); ++i)
172 MIB->setType(LLT::scalar(ResTys[i].getSizeInBits()), i);
173 MIB->setType(LLT::scalar(SrcTy.getSizeInBits()), ResTys.size());
174
Tim Northover33b07d62016-07-22 20:03:43 +0000175 for (auto Res : Results)
Tim Northovera51575f2016-07-29 17:43:52 +0000176 MIB.addDef(Res);
Tim Northover33b07d62016-07-22 20:03:43 +0000177
Tim Northovera51575f2016-07-29 17:43:52 +0000178 MIB.addUse(Src);
Tim Northover33b07d62016-07-22 20:03:43 +0000179
Tim Northover26b76f22016-08-19 18:32:14 +0000180 for (auto Idx : Indices)
Tim Northover33b07d62016-07-22 20:03:43 +0000181 MIB.addImm(Idx);
Tim Northover26b76f22016-08-19 18:32:14 +0000182
183 getMBB().insert(getInsertPt(), MIB);
184
Tim Northovera51575f2016-07-29 17:43:52 +0000185 return MIB;
Tim Northover33b07d62016-07-22 20:03:43 +0000186}
187
Tim Northover91c81732016-08-19 17:17:06 +0000188MachineInstrBuilder
Tim Northover26b76f22016-08-19 18:32:14 +0000189MachineIRBuilder::buildSequence(LLT ResTy, unsigned Res,
190 ArrayRef<LLT> OpTys,
Tim Northover91c81732016-08-19 17:17:06 +0000191 ArrayRef<unsigned> Ops,
Tim Northover26b76f22016-08-19 18:32:14 +0000192 ArrayRef<unsigned> Indices) {
193 assert(OpTys.size() == Ops.size() && Ops.size() == Indices.size() &&
194 "incompatible args");
195 assert(!Ops.empty() && "invalid trivial sequence");
Tim Northover91c81732016-08-19 17:17:06 +0000196
Tim Northover26b76f22016-08-19 18:32:14 +0000197 MachineInstrBuilder MIB =
198 buildInstr(TargetOpcode::G_SEQUENCE, LLT::scalar(ResTy.getSizeInBits()));
Tim Northovera51575f2016-07-29 17:43:52 +0000199 MIB.addDef(Res);
Tim Northover91c81732016-08-19 17:17:06 +0000200 for (unsigned i = 0; i < Ops.size(); ++i) {
201 MIB.addUse(Ops[i]);
Tim Northover26b76f22016-08-19 18:32:14 +0000202 MIB.addImm(Indices[i]);
203 MIB->setType(LLT::scalar(OpTys[i].getSizeInBits()), MIB->getNumTypes());
Tim Northover91c81732016-08-19 17:17:06 +0000204 }
Tim Northovera51575f2016-07-29 17:43:52 +0000205 return MIB;
Tim Northover33b07d62016-07-22 20:03:43 +0000206}
Tim Northover5fb414d2016-07-29 22:32:36 +0000207
208MachineInstrBuilder MachineIRBuilder::buildIntrinsic(ArrayRef<LLT> Tys,
209 Intrinsic::ID ID,
210 unsigned Res,
211 bool HasSideEffects) {
212 auto MIB =
213 buildInstr(HasSideEffects ? TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS
214 : TargetOpcode::G_INTRINSIC,
215 Tys);
216 if (Res)
217 MIB.addDef(Res);
218 MIB.addIntrinsicID(ID);
219 return MIB;
220}
Tim Northover32335812016-08-04 18:35:11 +0000221
Tim Northoverbdf67c92016-08-23 21:01:33 +0000222MachineInstrBuilder MachineIRBuilder::buildTrunc(ArrayRef<LLT> Tys,
223 unsigned Res, unsigned Op) {
224 validateTruncExt(Tys, false);
225 return buildInstr(TargetOpcode::G_TRUNC, Tys).addDef(Res).addUse(Op);
Tim Northover32335812016-08-04 18:35:11 +0000226}
Tim Northoverde3aea0412016-08-17 20:25:25 +0000227
Tim Northoverbdf67c92016-08-23 21:01:33 +0000228MachineInstrBuilder MachineIRBuilder::buildFPTrunc(ArrayRef<LLT> Tys,
229 unsigned Res, unsigned Op) {
230 validateTruncExt(Tys, false);
231 return buildInstr(TargetOpcode::G_FPTRUNC, Tys).addDef(Res).addUse(Op);
Tim Northovera11be042016-08-19 22:40:08 +0000232}
233
Tim Northoverde3aea0412016-08-17 20:25:25 +0000234MachineInstrBuilder MachineIRBuilder::buildICmp(ArrayRef<LLT> Tys,
235 CmpInst::Predicate Pred,
236 unsigned Res, unsigned Op0,
237 unsigned Op1) {
238 return buildInstr(TargetOpcode::G_ICMP, Tys)
239 .addDef(Res)
240 .addPredicate(Pred)
241 .addUse(Op0)
242 .addUse(Op1);
243}
Tim Northover5a28c362016-08-19 20:09:07 +0000244
Tim Northoverd5c23bc2016-08-19 20:48:16 +0000245MachineInstrBuilder MachineIRBuilder::buildFCmp(ArrayRef<LLT> Tys,
246 CmpInst::Predicate Pred,
247 unsigned Res, unsigned Op0,
248 unsigned Op1) {
249 return buildInstr(TargetOpcode::G_FCMP, Tys)
250 .addDef(Res)
251 .addPredicate(Pred)
252 .addUse(Op0)
253 .addUse(Op1);
254}
255
Tim Northover5a28c362016-08-19 20:09:07 +0000256MachineInstrBuilder MachineIRBuilder::buildSelect(LLT Ty, unsigned Res,
257 unsigned Tst,
258 unsigned Op0, unsigned Op1) {
259 return buildInstr(TargetOpcode::G_SELECT, {Ty, LLT::scalar(1)})
260 .addDef(Res)
261 .addUse(Tst)
262 .addUse(Op0)
263 .addUse(Op1);
264}
Tim Northoverbdf67c92016-08-23 21:01:33 +0000265
266void MachineIRBuilder::validateTruncExt(ArrayRef<LLT> Tys, bool IsExtend) {
267 assert(Tys.size() == 2 && "cast should have a source and a dest type");
268 LLT DstTy{Tys[0]}, SrcTy{Tys[1]};
269
270 if (DstTy.isVector()) {
271 assert(SrcTy.isVector() && "mismatched cast between vecot and non-vector");
272 assert(SrcTy.getNumElements() == DstTy.getNumElements() &&
273 "different number of elements in a trunc/ext");
274 } else
275 assert(DstTy.isScalar() && SrcTy.isScalar() && "invalid extend/trunc");
276
277 if (IsExtend)
278 assert(DstTy.getSizeInBits() > SrcTy.getSizeInBits() &&
279 "invalid narrowing extend");
280 else
281 assert(DstTy.getSizeInBits() < SrcTy.getSizeInBits() &&
282 "invalid widening trunc");
283}