blob: 8630ef842b4a8e92c7f4cf2ac1c36158d048bc30 [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"
Tim Northover0f140c72016-09-09 11:46:34 +000017#include "llvm/CodeGen/MachineRegisterInfo.h"
Tim Northover09aac4a2017-01-26 23:39:14 +000018#include "llvm/IR/DebugInfo.h"
Quentin Colombet2ad1f852016-02-11 17:44:59 +000019#include "llvm/Target/TargetInstrInfo.h"
Quentin Colombet8fd67182016-02-11 21:16:56 +000020#include "llvm/Target/TargetOpcodes.h"
Quentin Colombet2ad1f852016-02-11 17:44:59 +000021#include "llvm/Target/TargetSubtargetInfo.h"
22
23using namespace llvm;
24
Quentin Colombet000b5802016-03-11 17:27:51 +000025void MachineIRBuilder::setMF(MachineFunction &MF) {
Quentin Colombet2ad1f852016-02-11 17:44:59 +000026 this->MF = &MF;
27 this->MBB = nullptr;
Tim Northover0f140c72016-09-09 11:46:34 +000028 this->MRI = &MF.getRegInfo();
Quentin Colombet2ad1f852016-02-11 17:44:59 +000029 this->TII = MF.getSubtarget().getInstrInfo();
30 this->DL = DebugLoc();
Tim Northover05cc4852016-12-07 21:05:38 +000031 this->II = MachineBasicBlock::iterator();
Tim Northover438c77c2016-08-25 17:37:32 +000032 this->InsertedInstr = nullptr;
Quentin Colombet2ad1f852016-02-11 17:44:59 +000033}
34
Tim Northover05cc4852016-12-07 21:05:38 +000035void MachineIRBuilder::setMBB(MachineBasicBlock &MBB) {
Quentin Colombet2ad1f852016-02-11 17:44:59 +000036 this->MBB = &MBB;
Tim Northover05cc4852016-12-07 21:05:38 +000037 this->II = MBB.end();
Quentin Colombet2ad1f852016-02-11 17:44:59 +000038 assert(&getMF() == MBB.getParent() &&
39 "Basic block is in a different function");
40}
41
Tim Northover05cc4852016-12-07 21:05:38 +000042void MachineIRBuilder::setInstr(MachineInstr &MI) {
Quentin Colombet2ad1f852016-02-11 17:44:59 +000043 assert(MI.getParent() && "Instruction is not part of a basic block");
Quentin Colombet91ebd712016-03-11 17:27:47 +000044 setMBB(*MI.getParent());
Tim Northover05cc4852016-12-07 21:05:38 +000045 this->II = MI.getIterator();
Quentin Colombet2ad1f852016-02-11 17:44:59 +000046}
47
Tim Northover05cc4852016-12-07 21:05:38 +000048void MachineIRBuilder::setInsertPt(MachineBasicBlock &MBB,
49 MachineBasicBlock::iterator II) {
50 assert(MBB.getParent() == &getMF() &&
51 "Basic block is in a different function");
52 this->MBB = &MBB;
53 this->II = II;
Quentin Colombet2ad1f852016-02-11 17:44:59 +000054}
55
Tim Northover438c77c2016-08-25 17:37:32 +000056void MachineIRBuilder::recordInsertions(
57 std::function<void(MachineInstr *)> Inserted) {
Benjamin Kramer061f4a52017-01-13 14:39:03 +000058 InsertedInstr = std::move(Inserted);
Tim Northover438c77c2016-08-25 17:37:32 +000059}
60
61void MachineIRBuilder::stopRecordingInsertions() {
62 InsertedInstr = nullptr;
63}
64
Quentin Colombetf9b49342016-03-11 17:27:58 +000065//------------------------------------------------------------------------------
66// Build instruction variants.
67//------------------------------------------------------------------------------
Tim Northovercc5f7622016-07-26 16:45:26 +000068
Tim Northover0f140c72016-09-09 11:46:34 +000069MachineInstrBuilder MachineIRBuilder::buildInstr(unsigned Opcode) {
Tim Northovera5e38fa2016-09-22 13:49:25 +000070 return insertInstr(buildInstrNoInsert(Opcode));
71}
72
73MachineInstrBuilder MachineIRBuilder::buildInstrNoInsert(unsigned Opcode) {
Tim Northovera51575f2016-07-29 17:43:52 +000074 MachineInstrBuilder MIB = BuildMI(getMF(), DL, getTII().get(Opcode));
Tim Northovera5e38fa2016-09-22 13:49:25 +000075 return MIB;
76}
77
78
79MachineInstrBuilder MachineIRBuilder::insertInstr(MachineInstrBuilder MIB) {
Tim Northovera51575f2016-07-29 17:43:52 +000080 getMBB().insert(getInsertPt(), MIB);
Tim Northover438c77c2016-08-25 17:37:32 +000081 if (InsertedInstr)
82 InsertedInstr(MIB);
Tim Northovera51575f2016-07-29 17:43:52 +000083 return MIB;
Quentin Colombet74d7d2f2016-02-11 18:53:28 +000084}
85
Tim Northover09aac4a2017-01-26 23:39:14 +000086MachineInstrBuilder MachineIRBuilder::buildDirectDbgValue(
87 unsigned Reg, const MDNode *Variable, const MDNode *Expr) {
88 assert(isa<DILocalVariable>(Variable) && "not a variable");
89 assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
90 assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) &&
91 "Expected inlined-at fields to agree");
92 return buildInstr(TargetOpcode::DBG_VALUE)
93 .addReg(Reg, RegState::Debug)
94 .addReg(0, RegState::Debug)
95 .addMetadata(Variable)
96 .addMetadata(Expr);
97}
98
99MachineInstrBuilder MachineIRBuilder::buildIndirectDbgValue(
100 unsigned Reg, unsigned Offset, const MDNode *Variable, const MDNode *Expr) {
101 assert(isa<DILocalVariable>(Variable) && "not a variable");
102 assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
103 assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) &&
104 "Expected inlined-at fields to agree");
105 return buildInstr(TargetOpcode::DBG_VALUE)
106 .addReg(Reg, RegState::Debug)
107 .addImm(Offset)
108 .addMetadata(Variable)
109 .addMetadata(Expr);
110}
111
112MachineInstrBuilder MachineIRBuilder::buildFIDbgValue(int FI,
113 const MDNode *Variable,
114 const MDNode *Expr) {
115 assert(isa<DILocalVariable>(Variable) && "not a variable");
116 assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
117 assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) &&
118 "Expected inlined-at fields to agree");
119 return buildInstr(TargetOpcode::DBG_VALUE)
120 .addFrameIndex(FI)
121 .addImm(0)
122 .addMetadata(Variable)
123 .addMetadata(Expr);
124}
125
126MachineInstrBuilder MachineIRBuilder::buildConstDbgValue(const Constant &C,
127 unsigned Offset,
128 const MDNode *Variable,
129 const MDNode *Expr) {
130 assert(isa<DILocalVariable>(Variable) && "not a variable");
131 assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
132 assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) &&
133 "Expected inlined-at fields to agree");
134 auto MIB = buildInstr(TargetOpcode::DBG_VALUE);
135 if (auto *CI = dyn_cast<ConstantInt>(&C)) {
136 if (CI->getBitWidth() > 64)
137 MIB.addCImm(CI);
138 else
139 MIB.addImm(CI->getZExtValue());
Ahmed Bougacha4826bae2017-03-07 20:34:20 +0000140 } else if (auto *CFP = dyn_cast<ConstantFP>(&C)) {
141 assert(isa<ConstantFP>(C) && "Unexpected constant dbg value");
Tim Northover09aac4a2017-01-26 23:39:14 +0000142 MIB.addFPImm(&cast<ConstantFP>(C));
Ahmed Bougacha4826bae2017-03-07 20:34:20 +0000143 } else {
144 // Insert %noreg if we didn't find a usable constant and had to drop it.
145 MIB.addReg(0U);
146 }
Tim Northover09aac4a2017-01-26 23:39:14 +0000147
148 return MIB.addImm(Offset).addMetadata(Variable).addMetadata(Expr);
149}
150
Tim Northover0f140c72016-09-09 11:46:34 +0000151MachineInstrBuilder MachineIRBuilder::buildFrameIndex(unsigned Res, int Idx) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000152 assert(MRI->getType(Res).isPointer() && "invalid operand type");
Tim Northover0f140c72016-09-09 11:46:34 +0000153 return buildInstr(TargetOpcode::G_FRAME_INDEX)
Tim Northovera51575f2016-07-29 17:43:52 +0000154 .addDef(Res)
155 .addFrameIndex(Idx);
Tim Northoverbd505462016-07-22 16:59:52 +0000156}
Tim Northover33b07d62016-07-22 20:03:43 +0000157
Tim Northover032548f2016-09-12 12:10:41 +0000158MachineInstrBuilder MachineIRBuilder::buildGlobalValue(unsigned Res,
159 const GlobalValue *GV) {
160 assert(MRI->getType(Res).isPointer() && "invalid operand type");
161 assert(MRI->getType(Res).getAddressSpace() ==
162 GV->getType()->getAddressSpace() &&
163 "address space mismatch");
164
165 return buildInstr(TargetOpcode::G_GLOBAL_VALUE)
166 .addDef(Res)
167 .addGlobalAddress(GV);
168}
169
Tim Northover0f140c72016-09-09 11:46:34 +0000170MachineInstrBuilder MachineIRBuilder::buildAdd(unsigned Res, unsigned Op0,
171 unsigned Op1) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000172 assert((MRI->getType(Res).isScalar() || MRI->getType(Res).isVector()) &&
173 "invalid operand type");
174 assert(MRI->getType(Res) == MRI->getType(Op0) &&
175 MRI->getType(Res) == MRI->getType(Op1) && "type mismatch");
176
Tim Northover0f140c72016-09-09 11:46:34 +0000177 return buildInstr(TargetOpcode::G_ADD)
Tim Northovera51575f2016-07-29 17:43:52 +0000178 .addDef(Res)
179 .addUse(Op0)
180 .addUse(Op1);
Tim Northover33b07d62016-07-22 20:03:43 +0000181}
182
Tim Northovera7653b32016-09-12 11:20:22 +0000183MachineInstrBuilder MachineIRBuilder::buildGEP(unsigned Res, unsigned Op0,
184 unsigned Op1) {
185 assert(MRI->getType(Res).isPointer() &&
186 MRI->getType(Res) == MRI->getType(Op0) && "type mismatch");
187 assert(MRI->getType(Op1).isScalar() && "invalid offset type");
188
189 return buildInstr(TargetOpcode::G_GEP)
190 .addDef(Res)
191 .addUse(Op0)
192 .addUse(Op1);
193}
194
Tim Northoverc2f89562017-02-14 20:56:18 +0000195MachineInstrBuilder MachineIRBuilder::buildPtrMask(unsigned Res, unsigned Op0,
196 uint32_t NumBits) {
197 assert(MRI->getType(Res).isPointer() &&
198 MRI->getType(Res) == MRI->getType(Op0) && "type mismatch");
199
200 return buildInstr(TargetOpcode::G_PTR_MASK)
201 .addDef(Res)
202 .addUse(Op0)
203 .addImm(NumBits);
204}
205
Tim Northover0f140c72016-09-09 11:46:34 +0000206MachineInstrBuilder MachineIRBuilder::buildSub(unsigned Res, unsigned Op0,
207 unsigned Op1) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000208 assert((MRI->getType(Res).isScalar() || MRI->getType(Res).isVector()) &&
209 "invalid operand type");
210 assert(MRI->getType(Res) == MRI->getType(Op0) &&
211 MRI->getType(Res) == MRI->getType(Op1) && "type mismatch");
212
Tim Northover0f140c72016-09-09 11:46:34 +0000213 return buildInstr(TargetOpcode::G_SUB)
Tim Northovercecee562016-08-26 17:46:13 +0000214 .addDef(Res)
215 .addUse(Op0)
216 .addUse(Op1);
217}
218
Tim Northover0f140c72016-09-09 11:46:34 +0000219MachineInstrBuilder MachineIRBuilder::buildMul(unsigned Res, unsigned Op0,
220 unsigned Op1) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000221 assert((MRI->getType(Res).isScalar() || MRI->getType(Res).isVector()) &&
222 "invalid operand type");
223 assert(MRI->getType(Res) == MRI->getType(Op0) &&
224 MRI->getType(Res) == MRI->getType(Op1) && "type mismatch");
225
Tim Northover0f140c72016-09-09 11:46:34 +0000226 return buildInstr(TargetOpcode::G_MUL)
Tim Northovercecee562016-08-26 17:46:13 +0000227 .addDef(Res)
228 .addUse(Op0)
229 .addUse(Op1);
230}
231
Tim Northoverc3e3f592017-02-03 18:22:45 +0000232MachineInstrBuilder MachineIRBuilder::buildAnd(unsigned Res, unsigned Op0,
233 unsigned Op1) {
234 assert((MRI->getType(Res).isScalar() || MRI->getType(Res).isVector()) &&
235 "invalid operand type");
236 assert(MRI->getType(Res) == MRI->getType(Op0) &&
237 MRI->getType(Res) == MRI->getType(Op1) && "type mismatch");
238
239 return buildInstr(TargetOpcode::G_AND)
240 .addDef(Res)
241 .addUse(Op0)
242 .addUse(Op1);
243}
244
Tim Northovera51575f2016-07-29 17:43:52 +0000245MachineInstrBuilder MachineIRBuilder::buildBr(MachineBasicBlock &Dest) {
Tim Northover0f140c72016-09-09 11:46:34 +0000246 return buildInstr(TargetOpcode::G_BR).addMBB(&Dest);
Tim Northovercc5f7622016-07-26 16:45:26 +0000247}
248
Kristof Beyls65a12c02017-01-30 09:13:18 +0000249MachineInstrBuilder MachineIRBuilder::buildBrIndirect(unsigned Tgt) {
250 return buildInstr(TargetOpcode::G_BRINDIRECT).addUse(Tgt);
251}
252
Tim Northovera51575f2016-07-29 17:43:52 +0000253MachineInstrBuilder MachineIRBuilder::buildCopy(unsigned Res, unsigned Op) {
254 return buildInstr(TargetOpcode::COPY).addDef(Res).addUse(Op);
Tim Northover756eca32016-07-26 16:45:30 +0000255}
256
Tim Northover9267ac52016-12-05 21:47:07 +0000257MachineInstrBuilder MachineIRBuilder::buildConstant(unsigned Res,
258 const ConstantInt &Val) {
259 LLT Ty = MRI->getType(Res);
Tim Northover1f8b1db2016-09-09 11:46:58 +0000260
Sam McCall03435f52016-12-06 10:14:36 +0000261 assert((Ty.isScalar() || Ty.isPointer()) && "invalid operand type");
Tim Northover9267ac52016-12-05 21:47:07 +0000262
263 const ConstantInt *NewVal = &Val;
264 if (Ty.getSizeInBits() != Val.getBitWidth())
265 NewVal = ConstantInt::get(MF->getFunction()->getContext(),
266 Val.getValue().sextOrTrunc(Ty.getSizeInBits()));
267
268 return buildInstr(TargetOpcode::G_CONSTANT).addDef(Res).addCImm(NewVal);
269}
270
271MachineInstrBuilder MachineIRBuilder::buildConstant(unsigned Res,
272 int64_t Val) {
273 auto IntN = IntegerType::get(MF->getFunction()->getContext(),
274 MRI->getType(Res).getSizeInBits());
275 ConstantInt *CI = ConstantInt::get(IntN, Val, true);
276 return buildConstant(Res, *CI);
Tim Northover9656f142016-08-04 20:54:13 +0000277}
278
Tim Northover0f140c72016-09-09 11:46:34 +0000279MachineInstrBuilder MachineIRBuilder::buildFConstant(unsigned Res,
280 const ConstantFP &Val) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000281 assert(MRI->getType(Res).isScalar() && "invalid operand type");
282
Tim Northover0f140c72016-09-09 11:46:34 +0000283 return buildInstr(TargetOpcode::G_FCONSTANT).addDef(Res).addFPImm(&Val);
Tim Northoverb16734f2016-08-19 20:09:15 +0000284}
285
Tim Northover0f140c72016-09-09 11:46:34 +0000286MachineInstrBuilder MachineIRBuilder::buildBrCond(unsigned Tst,
Tim Northover69c2ba52016-07-29 17:58:00 +0000287 MachineBasicBlock &Dest) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000288 assert(MRI->getType(Tst).isScalar() && "invalid operand type");
289
Tim Northover0f140c72016-09-09 11:46:34 +0000290 return buildInstr(TargetOpcode::G_BRCOND).addUse(Tst).addMBB(&Dest);
Tim Northover69c2ba52016-07-29 17:58:00 +0000291}
292
Tim Northover0f140c72016-09-09 11:46:34 +0000293MachineInstrBuilder MachineIRBuilder::buildLoad(unsigned Res, unsigned Addr,
294 MachineMemOperand &MMO) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000295 assert(MRI->getType(Res).isValid() && "invalid operand type");
296 assert(MRI->getType(Addr).isPointer() && "invalid operand type");
297
Tim Northover0f140c72016-09-09 11:46:34 +0000298 return buildInstr(TargetOpcode::G_LOAD)
Tim Northovera51575f2016-07-29 17:43:52 +0000299 .addDef(Res)
300 .addUse(Addr)
301 .addMemOperand(&MMO);
Tim Northoverad2b7172016-07-26 20:23:26 +0000302}
303
Tim Northover0f140c72016-09-09 11:46:34 +0000304MachineInstrBuilder MachineIRBuilder::buildStore(unsigned Val, unsigned Addr,
305 MachineMemOperand &MMO) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000306 assert(MRI->getType(Val).isValid() && "invalid operand type");
307 assert(MRI->getType(Addr).isPointer() && "invalid operand type");
308
Tim Northover0f140c72016-09-09 11:46:34 +0000309 return buildInstr(TargetOpcode::G_STORE)
Tim Northovera51575f2016-07-29 17:43:52 +0000310 .addUse(Val)
311 .addUse(Addr)
312 .addMemOperand(&MMO);
Tim Northoverad2b7172016-07-26 20:23:26 +0000313}
314
Tim Northover0f140c72016-09-09 11:46:34 +0000315MachineInstrBuilder MachineIRBuilder::buildUAdde(unsigned Res,
316 unsigned CarryOut,
317 unsigned Op0, unsigned Op1,
318 unsigned CarryIn) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000319 assert(MRI->getType(Res).isScalar() && "invalid operand type");
320 assert(MRI->getType(Res) == MRI->getType(Op0) &&
321 MRI->getType(Res) == MRI->getType(Op1) && "type mismatch");
322 assert(MRI->getType(CarryOut).isScalar() && "invalid operand type");
323 assert(MRI->getType(CarryOut) == MRI->getType(CarryIn) && "type mismatch");
324
Tim Northover0f140c72016-09-09 11:46:34 +0000325 return buildInstr(TargetOpcode::G_UADDE)
Tim Northover9656f142016-08-04 20:54:13 +0000326 .addDef(Res)
327 .addDef(CarryOut)
328 .addUse(Op0)
329 .addUse(Op1)
330 .addUse(CarryIn);
331}
332
Tim Northover0f140c72016-09-09 11:46:34 +0000333MachineInstrBuilder MachineIRBuilder::buildAnyExt(unsigned Res, unsigned Op) {
334 validateTruncExt(Res, Op, true);
335 return buildInstr(TargetOpcode::G_ANYEXT).addDef(Res).addUse(Op);
Tim Northover32335812016-08-04 18:35:11 +0000336}
337
Tim Northover0f140c72016-09-09 11:46:34 +0000338MachineInstrBuilder MachineIRBuilder::buildSExt(unsigned Res, unsigned Op) {
339 validateTruncExt(Res, Op, true);
340 return buildInstr(TargetOpcode::G_SEXT).addDef(Res).addUse(Op);
Tim Northover6cd4b232016-08-23 21:01:26 +0000341}
342
Tim Northover0f140c72016-09-09 11:46:34 +0000343MachineInstrBuilder MachineIRBuilder::buildZExt(unsigned Res, unsigned Op) {
344 validateTruncExt(Res, Op, true);
345 return buildInstr(TargetOpcode::G_ZEXT).addDef(Res).addUse(Op);
Tim Northover6cd4b232016-08-23 21:01:26 +0000346}
347
Tim Northovera7653b32016-09-12 11:20:22 +0000348MachineInstrBuilder MachineIRBuilder::buildSExtOrTrunc(unsigned Res,
349 unsigned Op) {
350 unsigned Opcode = TargetOpcode::COPY;
351 if (MRI->getType(Res).getSizeInBits() > MRI->getType(Op).getSizeInBits())
352 Opcode = TargetOpcode::G_SEXT;
353 else if (MRI->getType(Res).getSizeInBits() < MRI->getType(Op).getSizeInBits())
354 Opcode = TargetOpcode::G_TRUNC;
355
356 return buildInstr(Opcode).addDef(Res).addUse(Op);
357}
358
Tim Northoverc3e3f592017-02-03 18:22:45 +0000359MachineInstrBuilder MachineIRBuilder::buildZExtOrTrunc(unsigned Res,
360 unsigned Op) {
361 unsigned Opcode = TargetOpcode::COPY;
362 if (MRI->getType(Res).getSizeInBits() > MRI->getType(Op).getSizeInBits())
363 Opcode = TargetOpcode::G_ZEXT;
364 else if (MRI->getType(Res).getSizeInBits() < MRI->getType(Op).getSizeInBits())
365 Opcode = TargetOpcode::G_TRUNC;
366
367 return buildInstr(Opcode).addDef(Res).addUse(Op);
368}
369
Tim Northover95b6d5f2017-03-06 19:04:17 +0000370
371MachineInstrBuilder MachineIRBuilder::buildCast(unsigned Dst, unsigned Src) {
372 LLT SrcTy = MRI->getType(Src);
373 LLT DstTy = MRI->getType(Dst);
374 if (SrcTy == DstTy)
375 return buildCopy(Dst, Src);
376
377 unsigned Opcode;
378 if (SrcTy.isPointer() && DstTy.isScalar())
379 Opcode = TargetOpcode::G_PTRTOINT;
380 else if (DstTy.isPointer() && SrcTy.isScalar())
381 Opcode = TargetOpcode::G_INTTOPTR;
382 else {
383 assert(!SrcTy.isPointer() && !DstTy.isPointer() && "n G_ADDRCAST yet");
384 Opcode = TargetOpcode::G_BITCAST;
385 }
386
387 return buildInstr(Opcode).addDef(Dst).addUse(Src);
388}
389
Tim Northoverc2c545b2017-03-06 23:50:28 +0000390MachineInstrBuilder MachineIRBuilder::buildExtract(unsigned Res, unsigned Src,
391 uint64_t Index) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000392#ifndef NDEBUG
Tim Northover1f8b1db2016-09-09 11:46:58 +0000393 assert(MRI->getType(Src).isValid() && "invalid operand type");
Tim Northoverc2c545b2017-03-06 23:50:28 +0000394 assert(MRI->getType(Res).isValid() && "invalid operand type");
395 assert(Index + MRI->getType(Res).getSizeInBits() <=
396 MRI->getType(Src).getSizeInBits() &&
397 "extracting off end of register");
Tim Northover1f8b1db2016-09-09 11:46:58 +0000398#endif
399
Tim Northoverc2c545b2017-03-06 23:50:28 +0000400 if (MRI->getType(Res).getSizeInBits() == MRI->getType(Src).getSizeInBits()) {
401 assert(Index == 0 && "insertion past the end of a register");
402 return buildCast(Res, Src);
403 }
Tim Northover33b07d62016-07-22 20:03:43 +0000404
Tim Northoverc2c545b2017-03-06 23:50:28 +0000405 return buildInstr(TargetOpcode::G_EXTRACT)
406 .addDef(Res)
407 .addUse(Src)
408 .addImm(Index);
Tim Northover33b07d62016-07-22 20:03:43 +0000409}
410
Tim Northover91c81732016-08-19 17:17:06 +0000411MachineInstrBuilder
Tim Northover0f140c72016-09-09 11:46:34 +0000412MachineIRBuilder::buildSequence(unsigned Res,
Tim Northover91c81732016-08-19 17:17:06 +0000413 ArrayRef<unsigned> Ops,
Tim Northoverb18ea162016-09-20 15:20:36 +0000414 ArrayRef<uint64_t> Indices) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000415#ifndef NDEBUG
Tim Northover0f140c72016-09-09 11:46:34 +0000416 assert(Ops.size() == Indices.size() && "incompatible args");
Tim Northover26b76f22016-08-19 18:32:14 +0000417 assert(!Ops.empty() && "invalid trivial sequence");
Tim Northover991b12b2016-08-30 20:51:25 +0000418 assert(std::is_sorted(Indices.begin(), Indices.end()) &&
419 "sequence offsets must be in ascending order");
Tim Northover91c81732016-08-19 17:17:06 +0000420
Tim Northover1f8b1db2016-09-09 11:46:58 +0000421 assert(MRI->getType(Res).isValid() && "invalid operand type");
422 for (auto Op : Ops)
423 assert(MRI->getType(Op).isValid() && "invalid operand type");
424#endif
425
Tim Northover0f140c72016-09-09 11:46:34 +0000426 MachineInstrBuilder MIB = buildInstr(TargetOpcode::G_SEQUENCE);
Tim Northovera51575f2016-07-29 17:43:52 +0000427 MIB.addDef(Res);
Tim Northover91c81732016-08-19 17:17:06 +0000428 for (unsigned i = 0; i < Ops.size(); ++i) {
429 MIB.addUse(Ops[i]);
Tim Northover26b76f22016-08-19 18:32:14 +0000430 MIB.addImm(Indices[i]);
Tim Northover91c81732016-08-19 17:17:06 +0000431 }
Tim Northovera51575f2016-07-29 17:43:52 +0000432 return MIB;
Tim Northover33b07d62016-07-22 20:03:43 +0000433}
Tim Northover5fb414d2016-07-29 22:32:36 +0000434
Tim Northover81dafc12017-03-06 18:36:40 +0000435MachineInstrBuilder MachineIRBuilder::buildUndef(unsigned Res) {
436 return buildInstr(TargetOpcode::IMPLICIT_DEF).addDef(Res);
437}
438
Tim Northoverbf017292017-03-03 22:46:09 +0000439MachineInstrBuilder MachineIRBuilder::buildMerge(unsigned Res,
440 ArrayRef<unsigned> Ops) {
441
442#ifndef NDEBUG
443 assert(!Ops.empty() && "invalid trivial sequence");
444 LLT Ty = MRI->getType(Ops[0]);
445 for (auto Reg : Ops)
446 assert(MRI->getType(Reg) == Ty && "type mismatch in input list");
447 assert(Ops.size() * MRI->getType(Ops[0]).getSizeInBits() ==
448 MRI->getType(Res).getSizeInBits() &&
449 "input operands do not cover output register");
450#endif
451
452 MachineInstrBuilder MIB = buildInstr(TargetOpcode::G_MERGE_VALUES);
453 MIB.addDef(Res);
454 for (unsigned i = 0; i < Ops.size(); ++i)
455 MIB.addUse(Ops[i]);
456 return MIB;
457}
458
459MachineInstrBuilder MachineIRBuilder::buildUnmerge(ArrayRef<unsigned> Res,
460 unsigned Op) {
461
462#ifndef NDEBUG
463 assert(!Res.empty() && "invalid trivial sequence");
464 LLT Ty = MRI->getType(Res[0]);
465 for (auto Reg : Res)
466 assert(MRI->getType(Reg) == Ty && "type mismatch in input list");
467 assert(Res.size() * MRI->getType(Res[0]).getSizeInBits() ==
468 MRI->getType(Op).getSizeInBits() &&
469 "input operands do not cover output register");
470#endif
471
472 MachineInstrBuilder MIB = buildInstr(TargetOpcode::G_UNMERGE_VALUES);
473 for (unsigned i = 0; i < Res.size(); ++i)
474 MIB.addDef(Res[i]);
475 MIB.addUse(Op);
476 return MIB;
477}
478
Tim Northover3e6a7af2017-03-03 23:05:47 +0000479MachineInstrBuilder MachineIRBuilder::buildInsert(unsigned Res, unsigned Src,
480 unsigned Op, unsigned Index) {
Tim Northover95b6d5f2017-03-06 19:04:17 +0000481 if (MRI->getType(Res).getSizeInBits() == MRI->getType(Op).getSizeInBits()) {
482 assert(Index == 0 && "insertion past the end of a register");
483 return buildCast(Res, Op);
484 }
485
Tim Northover3e6a7af2017-03-03 23:05:47 +0000486 return buildInstr(TargetOpcode::G_INSERT)
487 .addDef(Res)
488 .addUse(Src)
489 .addUse(Op)
490 .addImm(Index);
491}
492
Tim Northover0f140c72016-09-09 11:46:34 +0000493MachineInstrBuilder MachineIRBuilder::buildIntrinsic(Intrinsic::ID ID,
Tim Northover5fb414d2016-07-29 22:32:36 +0000494 unsigned Res,
495 bool HasSideEffects) {
496 auto MIB =
497 buildInstr(HasSideEffects ? TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS
Tim Northover0f140c72016-09-09 11:46:34 +0000498 : TargetOpcode::G_INTRINSIC);
Tim Northover5fb414d2016-07-29 22:32:36 +0000499 if (Res)
500 MIB.addDef(Res);
501 MIB.addIntrinsicID(ID);
502 return MIB;
503}
Tim Northover32335812016-08-04 18:35:11 +0000504
Tim Northover0f140c72016-09-09 11:46:34 +0000505MachineInstrBuilder MachineIRBuilder::buildTrunc(unsigned Res, unsigned Op) {
506 validateTruncExt(Res, Op, false);
507 return buildInstr(TargetOpcode::G_TRUNC).addDef(Res).addUse(Op);
Tim Northover32335812016-08-04 18:35:11 +0000508}
Tim Northoverde3aea0412016-08-17 20:25:25 +0000509
Tim Northover0f140c72016-09-09 11:46:34 +0000510MachineInstrBuilder MachineIRBuilder::buildFPTrunc(unsigned Res, unsigned Op) {
511 validateTruncExt(Res, Op, false);
512 return buildInstr(TargetOpcode::G_FPTRUNC).addDef(Res).addUse(Op);
Tim Northovera11be042016-08-19 22:40:08 +0000513}
514
Tim Northover0f140c72016-09-09 11:46:34 +0000515MachineInstrBuilder MachineIRBuilder::buildICmp(CmpInst::Predicate Pred,
Tim Northoverde3aea0412016-08-17 20:25:25 +0000516 unsigned Res, unsigned Op0,
517 unsigned Op1) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000518#ifndef NDEBUG
Tim Northover1f8b1db2016-09-09 11:46:58 +0000519 assert(MRI->getType(Op0) == MRI->getType(Op0) && "type mismatch");
520 assert(CmpInst::isIntPredicate(Pred) && "invalid predicate");
Tim Northover4cf0a482016-09-15 10:40:38 +0000521 if (MRI->getType(Op0).isScalar() || MRI->getType(Op0).isPointer())
Tim Northover1f8b1db2016-09-09 11:46:58 +0000522 assert(MRI->getType(Res).isScalar() && "type mismatch");
523 else
524 assert(MRI->getType(Res).isVector() &&
525 MRI->getType(Res).getNumElements() ==
526 MRI->getType(Op0).getNumElements() &&
527 "type mismatch");
528#endif
529
Tim Northover0f140c72016-09-09 11:46:34 +0000530 return buildInstr(TargetOpcode::G_ICMP)
Tim Northoverde3aea0412016-08-17 20:25:25 +0000531 .addDef(Res)
532 .addPredicate(Pred)
533 .addUse(Op0)
534 .addUse(Op1);
535}
Tim Northover5a28c362016-08-19 20:09:07 +0000536
Tim Northover0f140c72016-09-09 11:46:34 +0000537MachineInstrBuilder MachineIRBuilder::buildFCmp(CmpInst::Predicate Pred,
Tim Northoverd5c23bc2016-08-19 20:48:16 +0000538 unsigned Res, unsigned Op0,
539 unsigned Op1) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000540#ifndef NDEBUG
541 assert((MRI->getType(Op0).isScalar() || MRI->getType(Op0).isVector()) &&
542 "invalid operand type");
543 assert(MRI->getType(Op0) == MRI->getType(Op1) && "type mismatch");
544 assert(CmpInst::isFPPredicate(Pred) && "invalid predicate");
545 if (MRI->getType(Op0).isScalar())
546 assert(MRI->getType(Res).isScalar() && "type mismatch");
547 else
548 assert(MRI->getType(Res).isVector() &&
549 MRI->getType(Res).getNumElements() ==
550 MRI->getType(Op0).getNumElements() &&
551 "type mismatch");
552#endif
553
Tim Northover0f140c72016-09-09 11:46:34 +0000554 return buildInstr(TargetOpcode::G_FCMP)
Tim Northoverd5c23bc2016-08-19 20:48:16 +0000555 .addDef(Res)
556 .addPredicate(Pred)
557 .addUse(Op0)
558 .addUse(Op1);
559}
560
Tim Northover0f140c72016-09-09 11:46:34 +0000561MachineInstrBuilder MachineIRBuilder::buildSelect(unsigned Res, unsigned Tst,
Tim Northover5a28c362016-08-19 20:09:07 +0000562 unsigned Op0, unsigned Op1) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000563#ifndef NDEBUG
Tim Northoverf50f2f32016-12-06 18:38:34 +0000564 LLT ResTy = MRI->getType(Res);
565 assert((ResTy.isScalar() || ResTy.isVector() || ResTy.isPointer()) &&
Tim Northover1f8b1db2016-09-09 11:46:58 +0000566 "invalid operand type");
Tim Northoverf50f2f32016-12-06 18:38:34 +0000567 assert(ResTy == MRI->getType(Op0) && ResTy == MRI->getType(Op1) &&
568 "type mismatch");
569 if (ResTy.isScalar() || ResTy.isPointer())
Tim Northover1f8b1db2016-09-09 11:46:58 +0000570 assert(MRI->getType(Tst).isScalar() && "type mismatch");
571 else
572 assert(MRI->getType(Tst).isVector() &&
573 MRI->getType(Tst).getNumElements() ==
574 MRI->getType(Op0).getNumElements() &&
575 "type mismatch");
576#endif
577
Tim Northover0f140c72016-09-09 11:46:34 +0000578 return buildInstr(TargetOpcode::G_SELECT)
Tim Northover5a28c362016-08-19 20:09:07 +0000579 .addDef(Res)
580 .addUse(Tst)
581 .addUse(Op0)
582 .addUse(Op1);
583}
Tim Northoverbdf67c92016-08-23 21:01:33 +0000584
Tim Northover0f140c72016-09-09 11:46:34 +0000585void MachineIRBuilder::validateTruncExt(unsigned Dst, unsigned Src,
586 bool IsExtend) {
Richard Smith418237b2016-08-23 22:14:15 +0000587#ifndef NDEBUG
Tim Northover0f140c72016-09-09 11:46:34 +0000588 LLT SrcTy = MRI->getType(Src);
589 LLT DstTy = MRI->getType(Dst);
Tim Northoverbdf67c92016-08-23 21:01:33 +0000590
591 if (DstTy.isVector()) {
592 assert(SrcTy.isVector() && "mismatched cast between vecot and non-vector");
593 assert(SrcTy.getNumElements() == DstTy.getNumElements() &&
594 "different number of elements in a trunc/ext");
595 } else
596 assert(DstTy.isScalar() && SrcTy.isScalar() && "invalid extend/trunc");
597
598 if (IsExtend)
599 assert(DstTy.getSizeInBits() > SrcTy.getSizeInBits() &&
600 "invalid narrowing extend");
601 else
602 assert(DstTy.getSizeInBits() < SrcTy.getSizeInBits() &&
603 "invalid widening trunc");
Richard Smith418237b2016-08-23 22:14:15 +0000604#endif
Tim Northoverbdf67c92016-08-23 21:01:33 +0000605}