blob: 079cd11574bd9d10777ed05019786b81ce5508bf [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"
David Blaikie3f833ed2017-11-08 01:01:31 +000018#include "llvm/CodeGen/TargetInstrInfo.h"
David Blaikieb3bde2e2017-11-17 01:07:10 +000019#include "llvm/CodeGen/TargetOpcodes.h"
20#include "llvm/CodeGen/TargetSubtargetInfo.h"
Tim Northover09aac4a2017-01-26 23:39:14 +000021#include "llvm/IR/DebugInfo.h"
Quentin Colombet2ad1f852016-02-11 17:44:59 +000022
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
Adrian Prantlaac78ce2017-08-01 22:37:35 +000086MachineInstrBuilder
87MachineIRBuilder::buildDirectDbgValue(unsigned Reg, const MDNode *Variable,
88 const MDNode *Expr) {
Tim Northover09aac4a2017-01-26 23:39:14 +000089 assert(isa<DILocalVariable>(Variable) && "not a variable");
90 assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
91 assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) &&
92 "Expected inlined-at fields to agree");
Adrian Prantlaac78ce2017-08-01 22:37:35 +000093 return insertInstr(BuildMI(getMF(), DL, getTII().get(TargetOpcode::DBG_VALUE),
94 /*IsIndirect*/ false, Reg, Variable, Expr));
Tim Northover09aac4a2017-01-26 23:39:14 +000095}
96
Adrian Prantld92ac5a2017-07-28 22:46:20 +000097MachineInstrBuilder
98MachineIRBuilder::buildIndirectDbgValue(unsigned Reg, const MDNode *Variable,
99 const MDNode *Expr) {
Tim Northover09aac4a2017-01-26 23:39:14 +0000100 assert(isa<DILocalVariable>(Variable) && "not a variable");
101 assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
102 assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) &&
103 "Expected inlined-at fields to agree");
Adrian Prantlaac78ce2017-08-01 22:37:35 +0000104 return insertInstr(BuildMI(getMF(), DL, getTII().get(TargetOpcode::DBG_VALUE),
105 /*IsIndirect*/ true, Reg, Variable, Expr));
Tim Northover09aac4a2017-01-26 23:39:14 +0000106}
107
108MachineInstrBuilder MachineIRBuilder::buildFIDbgValue(int FI,
109 const MDNode *Variable,
110 const MDNode *Expr) {
111 assert(isa<DILocalVariable>(Variable) && "not a variable");
112 assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
113 assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) &&
114 "Expected inlined-at fields to agree");
115 return buildInstr(TargetOpcode::DBG_VALUE)
116 .addFrameIndex(FI)
117 .addImm(0)
118 .addMetadata(Variable)
119 .addMetadata(Expr);
120}
121
122MachineInstrBuilder MachineIRBuilder::buildConstDbgValue(const Constant &C,
Tim Northover09aac4a2017-01-26 23:39:14 +0000123 const MDNode *Variable,
124 const MDNode *Expr) {
125 assert(isa<DILocalVariable>(Variable) && "not a variable");
126 assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
127 assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) &&
128 "Expected inlined-at fields to agree");
129 auto MIB = buildInstr(TargetOpcode::DBG_VALUE);
130 if (auto *CI = dyn_cast<ConstantInt>(&C)) {
131 if (CI->getBitWidth() > 64)
132 MIB.addCImm(CI);
133 else
134 MIB.addImm(CI->getZExtValue());
Ahmed Bougacha4826bae2017-03-07 20:34:20 +0000135 } else if (auto *CFP = dyn_cast<ConstantFP>(&C)) {
Ahmed Bougachaadce3ee2017-03-07 20:52:57 +0000136 MIB.addFPImm(CFP);
Ahmed Bougacha4826bae2017-03-07 20:34:20 +0000137 } else {
138 // Insert %noreg if we didn't find a usable constant and had to drop it.
139 MIB.addReg(0U);
140 }
Tim Northover09aac4a2017-01-26 23:39:14 +0000141
Adrian Prantld92ac5a2017-07-28 22:46:20 +0000142 return MIB.addImm(0).addMetadata(Variable).addMetadata(Expr);
Tim Northover09aac4a2017-01-26 23:39:14 +0000143}
144
Tim Northover0f140c72016-09-09 11:46:34 +0000145MachineInstrBuilder MachineIRBuilder::buildFrameIndex(unsigned Res, int Idx) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000146 assert(MRI->getType(Res).isPointer() && "invalid operand type");
Tim Northover0f140c72016-09-09 11:46:34 +0000147 return buildInstr(TargetOpcode::G_FRAME_INDEX)
Tim Northovera51575f2016-07-29 17:43:52 +0000148 .addDef(Res)
149 .addFrameIndex(Idx);
Tim Northoverbd505462016-07-22 16:59:52 +0000150}
Tim Northover33b07d62016-07-22 20:03:43 +0000151
Tim Northover032548f2016-09-12 12:10:41 +0000152MachineInstrBuilder MachineIRBuilder::buildGlobalValue(unsigned Res,
153 const GlobalValue *GV) {
154 assert(MRI->getType(Res).isPointer() && "invalid operand type");
155 assert(MRI->getType(Res).getAddressSpace() ==
156 GV->getType()->getAddressSpace() &&
157 "address space mismatch");
158
159 return buildInstr(TargetOpcode::G_GLOBAL_VALUE)
160 .addDef(Res)
161 .addGlobalAddress(GV);
162}
163
Diana Picus05e704f2017-07-05 11:02:31 +0000164MachineInstrBuilder MachineIRBuilder::buildBinaryOp(unsigned Opcode, unsigned Res, unsigned Op0,
Tim Northover0f140c72016-09-09 11:46:34 +0000165 unsigned Op1) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000166 assert((MRI->getType(Res).isScalar() || MRI->getType(Res).isVector()) &&
167 "invalid operand type");
168 assert(MRI->getType(Res) == MRI->getType(Op0) &&
169 MRI->getType(Res) == MRI->getType(Op1) && "type mismatch");
170
Diana Picus05e704f2017-07-05 11:02:31 +0000171 return buildInstr(Opcode)
Tim Northovera51575f2016-07-29 17:43:52 +0000172 .addDef(Res)
173 .addUse(Op0)
174 .addUse(Op1);
Tim Northover33b07d62016-07-22 20:03:43 +0000175}
176
Diana Picus05e704f2017-07-05 11:02:31 +0000177MachineInstrBuilder MachineIRBuilder::buildAdd(unsigned Res, unsigned Op0,
178 unsigned Op1) {
179 return buildBinaryOp(TargetOpcode::G_ADD, Res, Op0, Op1);
180}
181
Tim Northovera7653b32016-09-12 11:20:22 +0000182MachineInstrBuilder MachineIRBuilder::buildGEP(unsigned Res, unsigned Op0,
183 unsigned Op1) {
184 assert(MRI->getType(Res).isPointer() &&
185 MRI->getType(Res) == MRI->getType(Op0) && "type mismatch");
186 assert(MRI->getType(Op1).isScalar() && "invalid offset type");
187
188 return buildInstr(TargetOpcode::G_GEP)
189 .addDef(Res)
190 .addUse(Op0)
191 .addUse(Op1);
192}
193
Daniel Sanders4e523662017-06-13 23:42:32 +0000194Optional<MachineInstrBuilder>
195MachineIRBuilder::materializeGEP(unsigned &Res, unsigned Op0,
196 const LLT &ValueTy, uint64_t Value) {
197 assert(Res == 0 && "Res is a result argument");
198 assert(ValueTy.isScalar() && "invalid offset type");
199
200 if (Value == 0) {
201 Res = Op0;
202 return None;
203 }
204
205 Res = MRI->createGenericVirtualRegister(MRI->getType(Op0));
206 unsigned TmpReg = MRI->createGenericVirtualRegister(ValueTy);
207
208 buildConstant(TmpReg, Value);
209 return buildGEP(Res, Op0, TmpReg);
210}
211
Tim Northoverc2f89562017-02-14 20:56:18 +0000212MachineInstrBuilder MachineIRBuilder::buildPtrMask(unsigned Res, unsigned Op0,
213 uint32_t NumBits) {
214 assert(MRI->getType(Res).isPointer() &&
215 MRI->getType(Res) == MRI->getType(Op0) && "type mismatch");
216
217 return buildInstr(TargetOpcode::G_PTR_MASK)
218 .addDef(Res)
219 .addUse(Op0)
220 .addImm(NumBits);
221}
222
Tim Northover0f140c72016-09-09 11:46:34 +0000223MachineInstrBuilder MachineIRBuilder::buildSub(unsigned Res, unsigned Op0,
224 unsigned Op1) {
Diana Picus05e704f2017-07-05 11:02:31 +0000225 return buildBinaryOp(TargetOpcode::G_SUB, Res, Op0, Op1);
Tim Northovercecee562016-08-26 17:46:13 +0000226}
227
Tim Northover0f140c72016-09-09 11:46:34 +0000228MachineInstrBuilder MachineIRBuilder::buildMul(unsigned Res, unsigned Op0,
229 unsigned Op1) {
Diana Picus05e704f2017-07-05 11:02:31 +0000230 return buildBinaryOp(TargetOpcode::G_MUL, Res, Op0, Op1);
Tim Northovercecee562016-08-26 17:46:13 +0000231}
232
Tim Northoverc3e3f592017-02-03 18:22:45 +0000233MachineInstrBuilder MachineIRBuilder::buildAnd(unsigned Res, unsigned Op0,
234 unsigned Op1) {
Diana Picus05e704f2017-07-05 11:02:31 +0000235 return buildBinaryOp(TargetOpcode::G_AND, Res, Op0, Op1);
Tim Northoverc3e3f592017-02-03 18:22:45 +0000236}
237
Diana Picus3e40b462017-07-05 11:32:12 +0000238MachineInstrBuilder MachineIRBuilder::buildOr(unsigned Res, unsigned Op0,
Diana Picus97a5d9b2017-07-05 11:47:23 +0000239 unsigned Op1) {
Diana Picus3e40b462017-07-05 11:32:12 +0000240 return buildBinaryOp(TargetOpcode::G_OR, Res, Op0, Op1);
241}
Diana Picus05e704f2017-07-05 11:02:31 +0000242
Tim Northovera51575f2016-07-29 17:43:52 +0000243MachineInstrBuilder MachineIRBuilder::buildBr(MachineBasicBlock &Dest) {
Tim Northover0f140c72016-09-09 11:46:34 +0000244 return buildInstr(TargetOpcode::G_BR).addMBB(&Dest);
Tim Northovercc5f7622016-07-26 16:45:26 +0000245}
246
Kristof Beyls65a12c02017-01-30 09:13:18 +0000247MachineInstrBuilder MachineIRBuilder::buildBrIndirect(unsigned Tgt) {
Tim Northoverc9902362017-06-27 22:45:35 +0000248 assert(MRI->getType(Tgt).isPointer() && "invalid branch destination");
Kristof Beyls65a12c02017-01-30 09:13:18 +0000249 return buildInstr(TargetOpcode::G_BRINDIRECT).addUse(Tgt);
250}
251
Tim Northovera51575f2016-07-29 17:43:52 +0000252MachineInstrBuilder MachineIRBuilder::buildCopy(unsigned Res, unsigned Op) {
Tim Northover849fcca2017-06-27 21:41:40 +0000253 assert(MRI->getType(Res) == LLT() || MRI->getType(Op) == LLT() ||
254 MRI->getType(Res) == MRI->getType(Op));
Tim Northovera51575f2016-07-29 17:43:52 +0000255 return buildInstr(TargetOpcode::COPY).addDef(Res).addUse(Op);
Tim Northover756eca32016-07-26 16:45:30 +0000256}
257
Tim Northover9267ac52016-12-05 21:47:07 +0000258MachineInstrBuilder MachineIRBuilder::buildConstant(unsigned Res,
259 const ConstantInt &Val) {
260 LLT Ty = MRI->getType(Res);
Tim Northover1f8b1db2016-09-09 11:46:58 +0000261
Sam McCall03435f52016-12-06 10:14:36 +0000262 assert((Ty.isScalar() || Ty.isPointer()) && "invalid operand type");
Tim Northover9267ac52016-12-05 21:47:07 +0000263
264 const ConstantInt *NewVal = &Val;
265 if (Ty.getSizeInBits() != Val.getBitWidth())
266 NewVal = ConstantInt::get(MF->getFunction()->getContext(),
267 Val.getValue().sextOrTrunc(Ty.getSizeInBits()));
268
269 return buildInstr(TargetOpcode::G_CONSTANT).addDef(Res).addCImm(NewVal);
270}
271
272MachineInstrBuilder MachineIRBuilder::buildConstant(unsigned Res,
273 int64_t Val) {
274 auto IntN = IntegerType::get(MF->getFunction()->getContext(),
275 MRI->getType(Res).getSizeInBits());
276 ConstantInt *CI = ConstantInt::get(IntN, Val, true);
277 return buildConstant(Res, *CI);
Tim Northover9656f142016-08-04 20:54:13 +0000278}
279
Tim Northover0f140c72016-09-09 11:46:34 +0000280MachineInstrBuilder MachineIRBuilder::buildFConstant(unsigned Res,
281 const ConstantFP &Val) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000282 assert(MRI->getType(Res).isScalar() && "invalid operand type");
283
Tim Northover0f140c72016-09-09 11:46:34 +0000284 return buildInstr(TargetOpcode::G_FCONSTANT).addDef(Res).addFPImm(&Val);
Tim Northoverb16734f2016-08-19 20:09:15 +0000285}
286
Tim Northover0f140c72016-09-09 11:46:34 +0000287MachineInstrBuilder MachineIRBuilder::buildBrCond(unsigned Tst,
Tim Northover69c2ba52016-07-29 17:58:00 +0000288 MachineBasicBlock &Dest) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000289 assert(MRI->getType(Tst).isScalar() && "invalid operand type");
290
Tim Northover0f140c72016-09-09 11:46:34 +0000291 return buildInstr(TargetOpcode::G_BRCOND).addUse(Tst).addMBB(&Dest);
Tim Northover69c2ba52016-07-29 17:58:00 +0000292}
293
Tim Northover0f140c72016-09-09 11:46:34 +0000294MachineInstrBuilder MachineIRBuilder::buildLoad(unsigned Res, unsigned Addr,
295 MachineMemOperand &MMO) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000296 assert(MRI->getType(Res).isValid() && "invalid operand type");
297 assert(MRI->getType(Addr).isPointer() && "invalid operand type");
298
Tim Northover0f140c72016-09-09 11:46:34 +0000299 return buildInstr(TargetOpcode::G_LOAD)
Tim Northovera51575f2016-07-29 17:43:52 +0000300 .addDef(Res)
301 .addUse(Addr)
302 .addMemOperand(&MMO);
Tim Northoverad2b7172016-07-26 20:23:26 +0000303}
304
Tim Northover0f140c72016-09-09 11:46:34 +0000305MachineInstrBuilder MachineIRBuilder::buildStore(unsigned Val, unsigned Addr,
306 MachineMemOperand &MMO) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000307 assert(MRI->getType(Val).isValid() && "invalid operand type");
308 assert(MRI->getType(Addr).isPointer() && "invalid operand type");
309
Tim Northover0f140c72016-09-09 11:46:34 +0000310 return buildInstr(TargetOpcode::G_STORE)
Tim Northovera51575f2016-07-29 17:43:52 +0000311 .addUse(Val)
312 .addUse(Addr)
313 .addMemOperand(&MMO);
Tim Northoverad2b7172016-07-26 20:23:26 +0000314}
315
Tim Northover0f140c72016-09-09 11:46:34 +0000316MachineInstrBuilder MachineIRBuilder::buildUAdde(unsigned Res,
317 unsigned CarryOut,
318 unsigned Op0, unsigned Op1,
319 unsigned CarryIn) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000320 assert(MRI->getType(Res).isScalar() && "invalid operand type");
321 assert(MRI->getType(Res) == MRI->getType(Op0) &&
322 MRI->getType(Res) == MRI->getType(Op1) && "type mismatch");
323 assert(MRI->getType(CarryOut).isScalar() && "invalid operand type");
324 assert(MRI->getType(CarryOut) == MRI->getType(CarryIn) && "type mismatch");
325
Tim Northover0f140c72016-09-09 11:46:34 +0000326 return buildInstr(TargetOpcode::G_UADDE)
Tim Northover9656f142016-08-04 20:54:13 +0000327 .addDef(Res)
328 .addDef(CarryOut)
329 .addUse(Op0)
330 .addUse(Op1)
331 .addUse(CarryIn);
332}
333
Tim Northover0f140c72016-09-09 11:46:34 +0000334MachineInstrBuilder MachineIRBuilder::buildAnyExt(unsigned Res, unsigned Op) {
335 validateTruncExt(Res, Op, true);
336 return buildInstr(TargetOpcode::G_ANYEXT).addDef(Res).addUse(Op);
Tim Northover32335812016-08-04 18:35:11 +0000337}
338
Tim Northover0f140c72016-09-09 11:46:34 +0000339MachineInstrBuilder MachineIRBuilder::buildSExt(unsigned Res, unsigned Op) {
340 validateTruncExt(Res, Op, true);
341 return buildInstr(TargetOpcode::G_SEXT).addDef(Res).addUse(Op);
Tim Northover6cd4b232016-08-23 21:01:26 +0000342}
343
Tim Northover0f140c72016-09-09 11:46:34 +0000344MachineInstrBuilder MachineIRBuilder::buildZExt(unsigned Res, unsigned Op) {
345 validateTruncExt(Res, Op, true);
346 return buildInstr(TargetOpcode::G_ZEXT).addDef(Res).addUse(Op);
Tim Northover6cd4b232016-08-23 21:01:26 +0000347}
348
Aditya Nandakumar892979e2017-08-25 04:57:27 +0000349MachineInstrBuilder
350MachineIRBuilder::buildExtOrTrunc(unsigned ExtOpc, unsigned Res, unsigned Op) {
351 assert((TargetOpcode::G_ANYEXT == ExtOpc || TargetOpcode::G_ZEXT == ExtOpc ||
352 TargetOpcode::G_SEXT == ExtOpc) &&
353 "Expecting Extending Opc");
Tim Northoverc9902362017-06-27 22:45:35 +0000354 assert(MRI->getType(Res).isScalar() || MRI->getType(Res).isVector());
355 assert(MRI->getType(Res).isScalar() == MRI->getType(Op).isScalar());
356
Tim Northovera7653b32016-09-12 11:20:22 +0000357 unsigned Opcode = TargetOpcode::COPY;
358 if (MRI->getType(Res).getSizeInBits() > MRI->getType(Op).getSizeInBits())
Aditya Nandakumar892979e2017-08-25 04:57:27 +0000359 Opcode = ExtOpc;
Tim Northovera7653b32016-09-12 11:20:22 +0000360 else if (MRI->getType(Res).getSizeInBits() < MRI->getType(Op).getSizeInBits())
361 Opcode = TargetOpcode::G_TRUNC;
Tim Northoverc9902362017-06-27 22:45:35 +0000362 else
363 assert(MRI->getType(Res) == MRI->getType(Op));
Tim Northovera7653b32016-09-12 11:20:22 +0000364
365 return buildInstr(Opcode).addDef(Res).addUse(Op);
366}
367
Aditya Nandakumar892979e2017-08-25 04:57:27 +0000368MachineInstrBuilder MachineIRBuilder::buildSExtOrTrunc(unsigned Res,
369 unsigned Op) {
370 return buildExtOrTrunc(TargetOpcode::G_SEXT, Res, Op);
371}
372
Tim Northoverc3e3f592017-02-03 18:22:45 +0000373MachineInstrBuilder MachineIRBuilder::buildZExtOrTrunc(unsigned Res,
374 unsigned Op) {
Aditya Nandakumar892979e2017-08-25 04:57:27 +0000375 return buildExtOrTrunc(TargetOpcode::G_ZEXT, Res, Op);
376}
Tim Northoverc9902362017-06-27 22:45:35 +0000377
Aditya Nandakumar892979e2017-08-25 04:57:27 +0000378MachineInstrBuilder MachineIRBuilder::buildAnyExtOrTrunc(unsigned Res,
379 unsigned Op) {
380 return buildExtOrTrunc(TargetOpcode::G_ANYEXT, Res, Op);
Tim Northoverc3e3f592017-02-03 18:22:45 +0000381}
382
Tim Northover95b6d5f2017-03-06 19:04:17 +0000383MachineInstrBuilder MachineIRBuilder::buildCast(unsigned Dst, unsigned Src) {
384 LLT SrcTy = MRI->getType(Src);
385 LLT DstTy = MRI->getType(Dst);
386 if (SrcTy == DstTy)
387 return buildCopy(Dst, Src);
388
389 unsigned Opcode;
390 if (SrcTy.isPointer() && DstTy.isScalar())
391 Opcode = TargetOpcode::G_PTRTOINT;
392 else if (DstTy.isPointer() && SrcTy.isScalar())
393 Opcode = TargetOpcode::G_INTTOPTR;
394 else {
395 assert(!SrcTy.isPointer() && !DstTy.isPointer() && "n G_ADDRCAST yet");
396 Opcode = TargetOpcode::G_BITCAST;
397 }
398
399 return buildInstr(Opcode).addDef(Dst).addUse(Src);
400}
401
Tim Northoverc2c545b2017-03-06 23:50:28 +0000402MachineInstrBuilder MachineIRBuilder::buildExtract(unsigned Res, unsigned Src,
403 uint64_t Index) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000404#ifndef NDEBUG
Tim Northover1f8b1db2016-09-09 11:46:58 +0000405 assert(MRI->getType(Src).isValid() && "invalid operand type");
Tim Northoverc2c545b2017-03-06 23:50:28 +0000406 assert(MRI->getType(Res).isValid() && "invalid operand type");
407 assert(Index + MRI->getType(Res).getSizeInBits() <=
408 MRI->getType(Src).getSizeInBits() &&
409 "extracting off end of register");
Tim Northover1f8b1db2016-09-09 11:46:58 +0000410#endif
411
Tim Northoverc2c545b2017-03-06 23:50:28 +0000412 if (MRI->getType(Res).getSizeInBits() == MRI->getType(Src).getSizeInBits()) {
413 assert(Index == 0 && "insertion past the end of a register");
414 return buildCast(Res, Src);
415 }
Tim Northover33b07d62016-07-22 20:03:43 +0000416
Tim Northoverc2c545b2017-03-06 23:50:28 +0000417 return buildInstr(TargetOpcode::G_EXTRACT)
418 .addDef(Res)
419 .addUse(Src)
420 .addImm(Index);
Tim Northover33b07d62016-07-22 20:03:43 +0000421}
422
Tim Northoverb57bf2a2017-06-23 16:15:37 +0000423void MachineIRBuilder::buildSequence(unsigned Res, ArrayRef<unsigned> Ops,
424 ArrayRef<uint64_t> Indices) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000425#ifndef NDEBUG
Tim Northover0f140c72016-09-09 11:46:34 +0000426 assert(Ops.size() == Indices.size() && "incompatible args");
Tim Northover26b76f22016-08-19 18:32:14 +0000427 assert(!Ops.empty() && "invalid trivial sequence");
Tim Northover991b12b2016-08-30 20:51:25 +0000428 assert(std::is_sorted(Indices.begin(), Indices.end()) &&
429 "sequence offsets must be in ascending order");
Tim Northover91c81732016-08-19 17:17:06 +0000430
Tim Northover1f8b1db2016-09-09 11:46:58 +0000431 assert(MRI->getType(Res).isValid() && "invalid operand type");
432 for (auto Op : Ops)
433 assert(MRI->getType(Op).isValid() && "invalid operand type");
434#endif
435
Tim Northoverb57bf2a2017-06-23 16:15:37 +0000436 LLT ResTy = MRI->getType(Res);
437 LLT OpTy = MRI->getType(Ops[0]);
438 unsigned OpSize = OpTy.getSizeInBits();
439 bool MaybeMerge = true;
Tim Northover91c81732016-08-19 17:17:06 +0000440 for (unsigned i = 0; i < Ops.size(); ++i) {
Tim Northoverb57bf2a2017-06-23 16:15:37 +0000441 if (MRI->getType(Ops[i]) != OpTy || Indices[i] != i * OpSize) {
442 MaybeMerge = false;
443 break;
444 }
Tim Northover91c81732016-08-19 17:17:06 +0000445 }
Tim Northoverb57bf2a2017-06-23 16:15:37 +0000446
447 if (MaybeMerge && Ops.size() * OpSize == ResTy.getSizeInBits()) {
448 buildMerge(Res, Ops);
449 return;
450 }
451
452 unsigned ResIn = MRI->createGenericVirtualRegister(ResTy);
453 buildUndef(ResIn);
454
455 for (unsigned i = 0; i < Ops.size(); ++i) {
456 unsigned ResOut =
457 i + 1 == Ops.size() ? Res : MRI->createGenericVirtualRegister(ResTy);
458 buildInsert(ResOut, ResIn, Ops[i], Indices[i]);
459 ResIn = ResOut;
460 }
Tim Northover33b07d62016-07-22 20:03:43 +0000461}
Tim Northover5fb414d2016-07-29 22:32:36 +0000462
Tim Northover81dafc12017-03-06 18:36:40 +0000463MachineInstrBuilder MachineIRBuilder::buildUndef(unsigned Res) {
Tim Northoverff5e7e12017-06-30 20:27:36 +0000464 return buildInstr(TargetOpcode::G_IMPLICIT_DEF).addDef(Res);
Tim Northover81dafc12017-03-06 18:36:40 +0000465}
466
Tim Northoverbf017292017-03-03 22:46:09 +0000467MachineInstrBuilder MachineIRBuilder::buildMerge(unsigned Res,
468 ArrayRef<unsigned> Ops) {
469
470#ifndef NDEBUG
471 assert(!Ops.empty() && "invalid trivial sequence");
472 LLT Ty = MRI->getType(Ops[0]);
473 for (auto Reg : Ops)
474 assert(MRI->getType(Reg) == Ty && "type mismatch in input list");
475 assert(Ops.size() * MRI->getType(Ops[0]).getSizeInBits() ==
476 MRI->getType(Res).getSizeInBits() &&
477 "input operands do not cover output register");
478#endif
479
Tim Northoverc2d5e6d2017-06-26 20:34:13 +0000480 if (Ops.size() == 1)
Tim Northover849fcca2017-06-27 21:41:40 +0000481 return buildCast(Res, Ops[0]);
Tim Northoverc2d5e6d2017-06-26 20:34:13 +0000482
Tim Northoverbf017292017-03-03 22:46:09 +0000483 MachineInstrBuilder MIB = buildInstr(TargetOpcode::G_MERGE_VALUES);
484 MIB.addDef(Res);
485 for (unsigned i = 0; i < Ops.size(); ++i)
486 MIB.addUse(Ops[i]);
487 return MIB;
488}
489
490MachineInstrBuilder MachineIRBuilder::buildUnmerge(ArrayRef<unsigned> Res,
491 unsigned Op) {
492
493#ifndef NDEBUG
494 assert(!Res.empty() && "invalid trivial sequence");
495 LLT Ty = MRI->getType(Res[0]);
496 for (auto Reg : Res)
497 assert(MRI->getType(Reg) == Ty && "type mismatch in input list");
498 assert(Res.size() * MRI->getType(Res[0]).getSizeInBits() ==
499 MRI->getType(Op).getSizeInBits() &&
500 "input operands do not cover output register");
501#endif
502
503 MachineInstrBuilder MIB = buildInstr(TargetOpcode::G_UNMERGE_VALUES);
504 for (unsigned i = 0; i < Res.size(); ++i)
505 MIB.addDef(Res[i]);
506 MIB.addUse(Op);
507 return MIB;
508}
509
Tim Northover3e6a7af2017-03-03 23:05:47 +0000510MachineInstrBuilder MachineIRBuilder::buildInsert(unsigned Res, unsigned Src,
511 unsigned Op, unsigned Index) {
Tim Northoverc9902362017-06-27 22:45:35 +0000512 assert(Index + MRI->getType(Op).getSizeInBits() <=
513 MRI->getType(Res).getSizeInBits() &&
514 "insertion past the end of a register");
515
Tim Northover95b6d5f2017-03-06 19:04:17 +0000516 if (MRI->getType(Res).getSizeInBits() == MRI->getType(Op).getSizeInBits()) {
Tim Northover95b6d5f2017-03-06 19:04:17 +0000517 return buildCast(Res, Op);
518 }
519
Tim Northover3e6a7af2017-03-03 23:05:47 +0000520 return buildInstr(TargetOpcode::G_INSERT)
521 .addDef(Res)
522 .addUse(Src)
523 .addUse(Op)
524 .addImm(Index);
525}
526
Tim Northover0f140c72016-09-09 11:46:34 +0000527MachineInstrBuilder MachineIRBuilder::buildIntrinsic(Intrinsic::ID ID,
Tim Northover5fb414d2016-07-29 22:32:36 +0000528 unsigned Res,
529 bool HasSideEffects) {
530 auto MIB =
531 buildInstr(HasSideEffects ? TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS
Tim Northover0f140c72016-09-09 11:46:34 +0000532 : TargetOpcode::G_INTRINSIC);
Tim Northover5fb414d2016-07-29 22:32:36 +0000533 if (Res)
534 MIB.addDef(Res);
535 MIB.addIntrinsicID(ID);
536 return MIB;
537}
Tim Northover32335812016-08-04 18:35:11 +0000538
Tim Northover0f140c72016-09-09 11:46:34 +0000539MachineInstrBuilder MachineIRBuilder::buildTrunc(unsigned Res, unsigned Op) {
540 validateTruncExt(Res, Op, false);
541 return buildInstr(TargetOpcode::G_TRUNC).addDef(Res).addUse(Op);
Tim Northover32335812016-08-04 18:35:11 +0000542}
Tim Northoverde3aea0412016-08-17 20:25:25 +0000543
Tim Northover0f140c72016-09-09 11:46:34 +0000544MachineInstrBuilder MachineIRBuilder::buildFPTrunc(unsigned Res, unsigned Op) {
545 validateTruncExt(Res, Op, false);
546 return buildInstr(TargetOpcode::G_FPTRUNC).addDef(Res).addUse(Op);
Tim Northovera11be042016-08-19 22:40:08 +0000547}
548
Tim Northover0f140c72016-09-09 11:46:34 +0000549MachineInstrBuilder MachineIRBuilder::buildICmp(CmpInst::Predicate Pred,
Tim Northoverde3aea0412016-08-17 20:25:25 +0000550 unsigned Res, unsigned Op0,
551 unsigned Op1) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000552#ifndef NDEBUG
Tim Northover1f8b1db2016-09-09 11:46:58 +0000553 assert(MRI->getType(Op0) == MRI->getType(Op0) && "type mismatch");
554 assert(CmpInst::isIntPredicate(Pred) && "invalid predicate");
Tim Northover4cf0a482016-09-15 10:40:38 +0000555 if (MRI->getType(Op0).isScalar() || MRI->getType(Op0).isPointer())
Tim Northover1f8b1db2016-09-09 11:46:58 +0000556 assert(MRI->getType(Res).isScalar() && "type mismatch");
557 else
558 assert(MRI->getType(Res).isVector() &&
559 MRI->getType(Res).getNumElements() ==
560 MRI->getType(Op0).getNumElements() &&
561 "type mismatch");
562#endif
563
Tim Northover0f140c72016-09-09 11:46:34 +0000564 return buildInstr(TargetOpcode::G_ICMP)
Tim Northoverde3aea0412016-08-17 20:25:25 +0000565 .addDef(Res)
566 .addPredicate(Pred)
567 .addUse(Op0)
568 .addUse(Op1);
569}
Tim Northover5a28c362016-08-19 20:09:07 +0000570
Tim Northover0f140c72016-09-09 11:46:34 +0000571MachineInstrBuilder MachineIRBuilder::buildFCmp(CmpInst::Predicate Pred,
Tim Northoverd5c23bc2016-08-19 20:48:16 +0000572 unsigned Res, unsigned Op0,
573 unsigned Op1) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000574#ifndef NDEBUG
575 assert((MRI->getType(Op0).isScalar() || MRI->getType(Op0).isVector()) &&
576 "invalid operand type");
577 assert(MRI->getType(Op0) == MRI->getType(Op1) && "type mismatch");
578 assert(CmpInst::isFPPredicate(Pred) && "invalid predicate");
579 if (MRI->getType(Op0).isScalar())
580 assert(MRI->getType(Res).isScalar() && "type mismatch");
581 else
582 assert(MRI->getType(Res).isVector() &&
583 MRI->getType(Res).getNumElements() ==
584 MRI->getType(Op0).getNumElements() &&
585 "type mismatch");
586#endif
587
Tim Northover0f140c72016-09-09 11:46:34 +0000588 return buildInstr(TargetOpcode::G_FCMP)
Tim Northoverd5c23bc2016-08-19 20:48:16 +0000589 .addDef(Res)
590 .addPredicate(Pred)
591 .addUse(Op0)
592 .addUse(Op1);
593}
594
Tim Northover0f140c72016-09-09 11:46:34 +0000595MachineInstrBuilder MachineIRBuilder::buildSelect(unsigned Res, unsigned Tst,
Tim Northover5a28c362016-08-19 20:09:07 +0000596 unsigned Op0, unsigned Op1) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000597#ifndef NDEBUG
Tim Northoverf50f2f32016-12-06 18:38:34 +0000598 LLT ResTy = MRI->getType(Res);
599 assert((ResTy.isScalar() || ResTy.isVector() || ResTy.isPointer()) &&
Tim Northover1f8b1db2016-09-09 11:46:58 +0000600 "invalid operand type");
Tim Northoverf50f2f32016-12-06 18:38:34 +0000601 assert(ResTy == MRI->getType(Op0) && ResTy == MRI->getType(Op1) &&
602 "type mismatch");
603 if (ResTy.isScalar() || ResTy.isPointer())
Tim Northover1f8b1db2016-09-09 11:46:58 +0000604 assert(MRI->getType(Tst).isScalar() && "type mismatch");
605 else
Ahmed Bougacha38455ea2017-03-07 20:53:03 +0000606 assert((MRI->getType(Tst).isScalar() ||
607 (MRI->getType(Tst).isVector() &&
608 MRI->getType(Tst).getNumElements() ==
609 MRI->getType(Op0).getNumElements())) &&
Tim Northover1f8b1db2016-09-09 11:46:58 +0000610 "type mismatch");
611#endif
612
Tim Northover0f140c72016-09-09 11:46:34 +0000613 return buildInstr(TargetOpcode::G_SELECT)
Tim Northover5a28c362016-08-19 20:09:07 +0000614 .addDef(Res)
615 .addUse(Tst)
616 .addUse(Op0)
617 .addUse(Op1);
618}
Tim Northoverbdf67c92016-08-23 21:01:33 +0000619
Volkan Keles04cb08c2017-03-10 19:08:28 +0000620MachineInstrBuilder MachineIRBuilder::buildInsertVectorElement(unsigned Res,
621 unsigned Val,
622 unsigned Elt,
623 unsigned Idx) {
624#ifndef NDEBUG
625 LLT ResTy = MRI->getType(Res);
626 LLT ValTy = MRI->getType(Val);
627 LLT EltTy = MRI->getType(Elt);
628 LLT IdxTy = MRI->getType(Idx);
629 assert(ResTy.isVector() && ValTy.isVector() && "invalid operand type");
Kristof Beyls0f36e682017-04-19 07:23:57 +0000630 assert(IdxTy.isScalar() && "invalid operand type");
Volkan Keles04cb08c2017-03-10 19:08:28 +0000631 assert(ResTy.getNumElements() == ValTy.getNumElements() && "type mismatch");
632 assert(ResTy.getElementType() == EltTy && "type mismatch");
633#endif
634
635 return buildInstr(TargetOpcode::G_INSERT_VECTOR_ELT)
636 .addDef(Res)
637 .addUse(Val)
638 .addUse(Elt)
639 .addUse(Idx);
640}
641
642MachineInstrBuilder MachineIRBuilder::buildExtractVectorElement(unsigned Res,
643 unsigned Val,
644 unsigned Idx) {
645#ifndef NDEBUG
646 LLT ResTy = MRI->getType(Res);
647 LLT ValTy = MRI->getType(Val);
648 LLT IdxTy = MRI->getType(Idx);
649 assert(ValTy.isVector() && "invalid operand type");
Kristof Beyls0f36e682017-04-19 07:23:57 +0000650 assert((ResTy.isScalar() || ResTy.isPointer()) && "invalid operand type");
651 assert(IdxTy.isScalar() && "invalid operand type");
Volkan Keles04cb08c2017-03-10 19:08:28 +0000652 assert(ValTy.getElementType() == ResTy && "type mismatch");
653#endif
654
655 return buildInstr(TargetOpcode::G_EXTRACT_VECTOR_ELT)
656 .addDef(Res)
657 .addUse(Val)
658 .addUse(Idx);
659}
660
Tim Northover0f140c72016-09-09 11:46:34 +0000661void MachineIRBuilder::validateTruncExt(unsigned Dst, unsigned Src,
662 bool IsExtend) {
Richard Smith418237b2016-08-23 22:14:15 +0000663#ifndef NDEBUG
Tim Northover0f140c72016-09-09 11:46:34 +0000664 LLT SrcTy = MRI->getType(Src);
665 LLT DstTy = MRI->getType(Dst);
Tim Northoverbdf67c92016-08-23 21:01:33 +0000666
667 if (DstTy.isVector()) {
668 assert(SrcTy.isVector() && "mismatched cast between vecot and non-vector");
669 assert(SrcTy.getNumElements() == DstTy.getNumElements() &&
670 "different number of elements in a trunc/ext");
671 } else
672 assert(DstTy.isScalar() && SrcTy.isScalar() && "invalid extend/trunc");
673
674 if (IsExtend)
675 assert(DstTy.getSizeInBits() > SrcTy.getSizeInBits() &&
676 "invalid narrowing extend");
677 else
678 assert(DstTy.getSizeInBits() < SrcTy.getSizeInBits() &&
679 "invalid widening trunc");
Richard Smith418237b2016-08-23 22:14:15 +0000680#endif
Tim Northoverbdf67c92016-08-23 21:01:33 +0000681}