blob: ae1550d0d3d3cfc9b655caf142266d2bc3e21578 [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());
140 } else
141 MIB.addFPImm(&cast<ConstantFP>(C));
142
143 return MIB.addImm(Offset).addMetadata(Variable).addMetadata(Expr);
144}
145
Tim Northover0f140c72016-09-09 11:46:34 +0000146MachineInstrBuilder MachineIRBuilder::buildFrameIndex(unsigned Res, int Idx) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000147 assert(MRI->getType(Res).isPointer() && "invalid operand type");
Tim Northover0f140c72016-09-09 11:46:34 +0000148 return buildInstr(TargetOpcode::G_FRAME_INDEX)
Tim Northovera51575f2016-07-29 17:43:52 +0000149 .addDef(Res)
150 .addFrameIndex(Idx);
Tim Northoverbd505462016-07-22 16:59:52 +0000151}
Tim Northover33b07d62016-07-22 20:03:43 +0000152
Tim Northover032548f2016-09-12 12:10:41 +0000153MachineInstrBuilder MachineIRBuilder::buildGlobalValue(unsigned Res,
154 const GlobalValue *GV) {
155 assert(MRI->getType(Res).isPointer() && "invalid operand type");
156 assert(MRI->getType(Res).getAddressSpace() ==
157 GV->getType()->getAddressSpace() &&
158 "address space mismatch");
159
160 return buildInstr(TargetOpcode::G_GLOBAL_VALUE)
161 .addDef(Res)
162 .addGlobalAddress(GV);
163}
164
Tim Northover0f140c72016-09-09 11:46:34 +0000165MachineInstrBuilder MachineIRBuilder::buildAdd(unsigned Res, unsigned Op0,
166 unsigned Op1) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000167 assert((MRI->getType(Res).isScalar() || MRI->getType(Res).isVector()) &&
168 "invalid operand type");
169 assert(MRI->getType(Res) == MRI->getType(Op0) &&
170 MRI->getType(Res) == MRI->getType(Op1) && "type mismatch");
171
Tim Northover0f140c72016-09-09 11:46:34 +0000172 return buildInstr(TargetOpcode::G_ADD)
Tim Northovera51575f2016-07-29 17:43:52 +0000173 .addDef(Res)
174 .addUse(Op0)
175 .addUse(Op1);
Tim Northover33b07d62016-07-22 20:03:43 +0000176}
177
Tim Northovera7653b32016-09-12 11:20:22 +0000178MachineInstrBuilder MachineIRBuilder::buildGEP(unsigned Res, unsigned Op0,
179 unsigned Op1) {
180 assert(MRI->getType(Res).isPointer() &&
181 MRI->getType(Res) == MRI->getType(Op0) && "type mismatch");
182 assert(MRI->getType(Op1).isScalar() && "invalid offset type");
183
184 return buildInstr(TargetOpcode::G_GEP)
185 .addDef(Res)
186 .addUse(Op0)
187 .addUse(Op1);
188}
189
Tim Northover0f140c72016-09-09 11:46:34 +0000190MachineInstrBuilder MachineIRBuilder::buildSub(unsigned Res, unsigned Op0,
191 unsigned Op1) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000192 assert((MRI->getType(Res).isScalar() || MRI->getType(Res).isVector()) &&
193 "invalid operand type");
194 assert(MRI->getType(Res) == MRI->getType(Op0) &&
195 MRI->getType(Res) == MRI->getType(Op1) && "type mismatch");
196
Tim Northover0f140c72016-09-09 11:46:34 +0000197 return buildInstr(TargetOpcode::G_SUB)
Tim Northovercecee562016-08-26 17:46:13 +0000198 .addDef(Res)
199 .addUse(Op0)
200 .addUse(Op1);
201}
202
Tim Northover0f140c72016-09-09 11:46:34 +0000203MachineInstrBuilder MachineIRBuilder::buildMul(unsigned Res, unsigned Op0,
204 unsigned Op1) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000205 assert((MRI->getType(Res).isScalar() || MRI->getType(Res).isVector()) &&
206 "invalid operand type");
207 assert(MRI->getType(Res) == MRI->getType(Op0) &&
208 MRI->getType(Res) == MRI->getType(Op1) && "type mismatch");
209
Tim Northover0f140c72016-09-09 11:46:34 +0000210 return buildInstr(TargetOpcode::G_MUL)
Tim Northovercecee562016-08-26 17:46:13 +0000211 .addDef(Res)
212 .addUse(Op0)
213 .addUse(Op1);
214}
215
Tim Northovera51575f2016-07-29 17:43:52 +0000216MachineInstrBuilder MachineIRBuilder::buildBr(MachineBasicBlock &Dest) {
Tim Northover0f140c72016-09-09 11:46:34 +0000217 return buildInstr(TargetOpcode::G_BR).addMBB(&Dest);
Tim Northovercc5f7622016-07-26 16:45:26 +0000218}
219
Tim Northovera51575f2016-07-29 17:43:52 +0000220MachineInstrBuilder MachineIRBuilder::buildCopy(unsigned Res, unsigned Op) {
221 return buildInstr(TargetOpcode::COPY).addDef(Res).addUse(Op);
Tim Northover756eca32016-07-26 16:45:30 +0000222}
223
Tim Northover9267ac52016-12-05 21:47:07 +0000224MachineInstrBuilder MachineIRBuilder::buildConstant(unsigned Res,
225 const ConstantInt &Val) {
226 LLT Ty = MRI->getType(Res);
Tim Northover1f8b1db2016-09-09 11:46:58 +0000227
Sam McCall03435f52016-12-06 10:14:36 +0000228 assert((Ty.isScalar() || Ty.isPointer()) && "invalid operand type");
Tim Northover9267ac52016-12-05 21:47:07 +0000229
230 const ConstantInt *NewVal = &Val;
231 if (Ty.getSizeInBits() != Val.getBitWidth())
232 NewVal = ConstantInt::get(MF->getFunction()->getContext(),
233 Val.getValue().sextOrTrunc(Ty.getSizeInBits()));
234
235 return buildInstr(TargetOpcode::G_CONSTANT).addDef(Res).addCImm(NewVal);
236}
237
238MachineInstrBuilder MachineIRBuilder::buildConstant(unsigned Res,
239 int64_t Val) {
240 auto IntN = IntegerType::get(MF->getFunction()->getContext(),
241 MRI->getType(Res).getSizeInBits());
242 ConstantInt *CI = ConstantInt::get(IntN, Val, true);
243 return buildConstant(Res, *CI);
Tim Northover9656f142016-08-04 20:54:13 +0000244}
245
Tim Northover0f140c72016-09-09 11:46:34 +0000246MachineInstrBuilder MachineIRBuilder::buildFConstant(unsigned Res,
247 const ConstantFP &Val) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000248 assert(MRI->getType(Res).isScalar() && "invalid operand type");
249
Tim Northover0f140c72016-09-09 11:46:34 +0000250 return buildInstr(TargetOpcode::G_FCONSTANT).addDef(Res).addFPImm(&Val);
Tim Northoverb16734f2016-08-19 20:09:15 +0000251}
252
Tim Northover0f140c72016-09-09 11:46:34 +0000253MachineInstrBuilder MachineIRBuilder::buildBrCond(unsigned Tst,
Tim Northover69c2ba52016-07-29 17:58:00 +0000254 MachineBasicBlock &Dest) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000255 assert(MRI->getType(Tst).isScalar() && "invalid operand type");
256
Tim Northover0f140c72016-09-09 11:46:34 +0000257 return buildInstr(TargetOpcode::G_BRCOND).addUse(Tst).addMBB(&Dest);
Tim Northover69c2ba52016-07-29 17:58:00 +0000258}
259
Tim Northover0f140c72016-09-09 11:46:34 +0000260MachineInstrBuilder MachineIRBuilder::buildLoad(unsigned Res, unsigned Addr,
261 MachineMemOperand &MMO) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000262 assert(MRI->getType(Res).isValid() && "invalid operand type");
263 assert(MRI->getType(Addr).isPointer() && "invalid operand type");
264
Tim Northover0f140c72016-09-09 11:46:34 +0000265 return buildInstr(TargetOpcode::G_LOAD)
Tim Northovera51575f2016-07-29 17:43:52 +0000266 .addDef(Res)
267 .addUse(Addr)
268 .addMemOperand(&MMO);
Tim Northoverad2b7172016-07-26 20:23:26 +0000269}
270
Tim Northover0f140c72016-09-09 11:46:34 +0000271MachineInstrBuilder MachineIRBuilder::buildStore(unsigned Val, unsigned Addr,
272 MachineMemOperand &MMO) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000273 assert(MRI->getType(Val).isValid() && "invalid operand type");
274 assert(MRI->getType(Addr).isPointer() && "invalid operand type");
275
Tim Northover0f140c72016-09-09 11:46:34 +0000276 return buildInstr(TargetOpcode::G_STORE)
Tim Northovera51575f2016-07-29 17:43:52 +0000277 .addUse(Val)
278 .addUse(Addr)
279 .addMemOperand(&MMO);
Tim Northoverad2b7172016-07-26 20:23:26 +0000280}
281
Tim Northover0f140c72016-09-09 11:46:34 +0000282MachineInstrBuilder MachineIRBuilder::buildUAdde(unsigned Res,
283 unsigned CarryOut,
284 unsigned Op0, unsigned Op1,
285 unsigned CarryIn) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000286 assert(MRI->getType(Res).isScalar() && "invalid operand type");
287 assert(MRI->getType(Res) == MRI->getType(Op0) &&
288 MRI->getType(Res) == MRI->getType(Op1) && "type mismatch");
289 assert(MRI->getType(CarryOut).isScalar() && "invalid operand type");
290 assert(MRI->getType(CarryOut) == MRI->getType(CarryIn) && "type mismatch");
291
Tim Northover0f140c72016-09-09 11:46:34 +0000292 return buildInstr(TargetOpcode::G_UADDE)
Tim Northover9656f142016-08-04 20:54:13 +0000293 .addDef(Res)
294 .addDef(CarryOut)
295 .addUse(Op0)
296 .addUse(Op1)
297 .addUse(CarryIn);
298}
299
Tim Northover0f140c72016-09-09 11:46:34 +0000300MachineInstrBuilder MachineIRBuilder::buildAnyExt(unsigned Res, unsigned Op) {
301 validateTruncExt(Res, Op, true);
302 return buildInstr(TargetOpcode::G_ANYEXT).addDef(Res).addUse(Op);
Tim Northover32335812016-08-04 18:35:11 +0000303}
304
Tim Northover0f140c72016-09-09 11:46:34 +0000305MachineInstrBuilder MachineIRBuilder::buildSExt(unsigned Res, unsigned Op) {
306 validateTruncExt(Res, Op, true);
307 return buildInstr(TargetOpcode::G_SEXT).addDef(Res).addUse(Op);
Tim Northover6cd4b232016-08-23 21:01:26 +0000308}
309
Tim Northover0f140c72016-09-09 11:46:34 +0000310MachineInstrBuilder MachineIRBuilder::buildZExt(unsigned Res, unsigned Op) {
311 validateTruncExt(Res, Op, true);
312 return buildInstr(TargetOpcode::G_ZEXT).addDef(Res).addUse(Op);
Tim Northover6cd4b232016-08-23 21:01:26 +0000313}
314
Tim Northovera7653b32016-09-12 11:20:22 +0000315MachineInstrBuilder MachineIRBuilder::buildSExtOrTrunc(unsigned Res,
316 unsigned Op) {
317 unsigned Opcode = TargetOpcode::COPY;
318 if (MRI->getType(Res).getSizeInBits() > MRI->getType(Op).getSizeInBits())
319 Opcode = TargetOpcode::G_SEXT;
320 else if (MRI->getType(Res).getSizeInBits() < MRI->getType(Op).getSizeInBits())
321 Opcode = TargetOpcode::G_TRUNC;
322
323 return buildInstr(Opcode).addDef(Res).addUse(Op);
324}
325
Tim Northover0f140c72016-09-09 11:46:34 +0000326MachineInstrBuilder MachineIRBuilder::buildExtract(ArrayRef<unsigned> Results,
Tim Northover26b76f22016-08-19 18:32:14 +0000327 ArrayRef<uint64_t> Indices,
Tim Northover0f140c72016-09-09 11:46:34 +0000328 unsigned Src) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000329#ifndef NDEBUG
Tim Northover0f140c72016-09-09 11:46:34 +0000330 assert(Results.size() == Indices.size() && "inconsistent number of regs");
Tim Northover26b76f22016-08-19 18:32:14 +0000331 assert(!Results.empty() && "invalid trivial extract");
Tim Northover991b12b2016-08-30 20:51:25 +0000332 assert(std::is_sorted(Indices.begin(), Indices.end()) &&
333 "extract offsets must be in ascending order");
Tim Northover33b07d62016-07-22 20:03:43 +0000334
Tim Northover1f8b1db2016-09-09 11:46:58 +0000335 assert(MRI->getType(Src).isValid() && "invalid operand type");
336 for (auto Res : Results)
337 assert(MRI->getType(Res).isValid() && "invalid operand type");
338#endif
339
Tim Northover26b76f22016-08-19 18:32:14 +0000340 auto MIB = BuildMI(getMF(), DL, getTII().get(TargetOpcode::G_EXTRACT));
Tim Northover33b07d62016-07-22 20:03:43 +0000341 for (auto Res : Results)
Tim Northovera51575f2016-07-29 17:43:52 +0000342 MIB.addDef(Res);
Tim Northover33b07d62016-07-22 20:03:43 +0000343
Tim Northovera51575f2016-07-29 17:43:52 +0000344 MIB.addUse(Src);
Tim Northover33b07d62016-07-22 20:03:43 +0000345
Tim Northover26b76f22016-08-19 18:32:14 +0000346 for (auto Idx : Indices)
Tim Northover33b07d62016-07-22 20:03:43 +0000347 MIB.addImm(Idx);
Tim Northover26b76f22016-08-19 18:32:14 +0000348
349 getMBB().insert(getInsertPt(), MIB);
Tim Northover438c77c2016-08-25 17:37:32 +0000350 if (InsertedInstr)
351 InsertedInstr(MIB);
Tim Northover26b76f22016-08-19 18:32:14 +0000352
Tim Northovera51575f2016-07-29 17:43:52 +0000353 return MIB;
Tim Northover33b07d62016-07-22 20:03:43 +0000354}
355
Tim Northover91c81732016-08-19 17:17:06 +0000356MachineInstrBuilder
Tim Northover0f140c72016-09-09 11:46:34 +0000357MachineIRBuilder::buildSequence(unsigned Res,
Tim Northover91c81732016-08-19 17:17:06 +0000358 ArrayRef<unsigned> Ops,
Tim Northoverb18ea162016-09-20 15:20:36 +0000359 ArrayRef<uint64_t> Indices) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000360#ifndef NDEBUG
Tim Northover0f140c72016-09-09 11:46:34 +0000361 assert(Ops.size() == Indices.size() && "incompatible args");
Tim Northover26b76f22016-08-19 18:32:14 +0000362 assert(!Ops.empty() && "invalid trivial sequence");
Tim Northover991b12b2016-08-30 20:51:25 +0000363 assert(std::is_sorted(Indices.begin(), Indices.end()) &&
364 "sequence offsets must be in ascending order");
Tim Northover91c81732016-08-19 17:17:06 +0000365
Tim Northover1f8b1db2016-09-09 11:46:58 +0000366 assert(MRI->getType(Res).isValid() && "invalid operand type");
367 for (auto Op : Ops)
368 assert(MRI->getType(Op).isValid() && "invalid operand type");
369#endif
370
Tim Northover0f140c72016-09-09 11:46:34 +0000371 MachineInstrBuilder MIB = buildInstr(TargetOpcode::G_SEQUENCE);
Tim Northovera51575f2016-07-29 17:43:52 +0000372 MIB.addDef(Res);
Tim Northover91c81732016-08-19 17:17:06 +0000373 for (unsigned i = 0; i < Ops.size(); ++i) {
374 MIB.addUse(Ops[i]);
Tim Northover26b76f22016-08-19 18:32:14 +0000375 MIB.addImm(Indices[i]);
Tim Northover91c81732016-08-19 17:17:06 +0000376 }
Tim Northovera51575f2016-07-29 17:43:52 +0000377 return MIB;
Tim Northover33b07d62016-07-22 20:03:43 +0000378}
Tim Northover5fb414d2016-07-29 22:32:36 +0000379
Tim Northover0f140c72016-09-09 11:46:34 +0000380MachineInstrBuilder MachineIRBuilder::buildIntrinsic(Intrinsic::ID ID,
Tim Northover5fb414d2016-07-29 22:32:36 +0000381 unsigned Res,
382 bool HasSideEffects) {
383 auto MIB =
384 buildInstr(HasSideEffects ? TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS
Tim Northover0f140c72016-09-09 11:46:34 +0000385 : TargetOpcode::G_INTRINSIC);
Tim Northover5fb414d2016-07-29 22:32:36 +0000386 if (Res)
387 MIB.addDef(Res);
388 MIB.addIntrinsicID(ID);
389 return MIB;
390}
Tim Northover32335812016-08-04 18:35:11 +0000391
Tim Northover0f140c72016-09-09 11:46:34 +0000392MachineInstrBuilder MachineIRBuilder::buildTrunc(unsigned Res, unsigned Op) {
393 validateTruncExt(Res, Op, false);
394 return buildInstr(TargetOpcode::G_TRUNC).addDef(Res).addUse(Op);
Tim Northover32335812016-08-04 18:35:11 +0000395}
Tim Northoverde3aea0412016-08-17 20:25:25 +0000396
Tim Northover0f140c72016-09-09 11:46:34 +0000397MachineInstrBuilder MachineIRBuilder::buildFPTrunc(unsigned Res, unsigned Op) {
398 validateTruncExt(Res, Op, false);
399 return buildInstr(TargetOpcode::G_FPTRUNC).addDef(Res).addUse(Op);
Tim Northovera11be042016-08-19 22:40:08 +0000400}
401
Tim Northover0f140c72016-09-09 11:46:34 +0000402MachineInstrBuilder MachineIRBuilder::buildICmp(CmpInst::Predicate Pred,
Tim Northoverde3aea0412016-08-17 20:25:25 +0000403 unsigned Res, unsigned Op0,
404 unsigned Op1) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000405#ifndef NDEBUG
Tim Northover1f8b1db2016-09-09 11:46:58 +0000406 assert(MRI->getType(Op0) == MRI->getType(Op0) && "type mismatch");
407 assert(CmpInst::isIntPredicate(Pred) && "invalid predicate");
Tim Northover4cf0a482016-09-15 10:40:38 +0000408 if (MRI->getType(Op0).isScalar() || MRI->getType(Op0).isPointer())
Tim Northover1f8b1db2016-09-09 11:46:58 +0000409 assert(MRI->getType(Res).isScalar() && "type mismatch");
410 else
411 assert(MRI->getType(Res).isVector() &&
412 MRI->getType(Res).getNumElements() ==
413 MRI->getType(Op0).getNumElements() &&
414 "type mismatch");
415#endif
416
Tim Northover0f140c72016-09-09 11:46:34 +0000417 return buildInstr(TargetOpcode::G_ICMP)
Tim Northoverde3aea0412016-08-17 20:25:25 +0000418 .addDef(Res)
419 .addPredicate(Pred)
420 .addUse(Op0)
421 .addUse(Op1);
422}
Tim Northover5a28c362016-08-19 20:09:07 +0000423
Tim Northover0f140c72016-09-09 11:46:34 +0000424MachineInstrBuilder MachineIRBuilder::buildFCmp(CmpInst::Predicate Pred,
Tim Northoverd5c23bc2016-08-19 20:48:16 +0000425 unsigned Res, unsigned Op0,
426 unsigned Op1) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000427#ifndef NDEBUG
428 assert((MRI->getType(Op0).isScalar() || MRI->getType(Op0).isVector()) &&
429 "invalid operand type");
430 assert(MRI->getType(Op0) == MRI->getType(Op1) && "type mismatch");
431 assert(CmpInst::isFPPredicate(Pred) && "invalid predicate");
432 if (MRI->getType(Op0).isScalar())
433 assert(MRI->getType(Res).isScalar() && "type mismatch");
434 else
435 assert(MRI->getType(Res).isVector() &&
436 MRI->getType(Res).getNumElements() ==
437 MRI->getType(Op0).getNumElements() &&
438 "type mismatch");
439#endif
440
Tim Northover0f140c72016-09-09 11:46:34 +0000441 return buildInstr(TargetOpcode::G_FCMP)
Tim Northoverd5c23bc2016-08-19 20:48:16 +0000442 .addDef(Res)
443 .addPredicate(Pred)
444 .addUse(Op0)
445 .addUse(Op1);
446}
447
Tim Northover0f140c72016-09-09 11:46:34 +0000448MachineInstrBuilder MachineIRBuilder::buildSelect(unsigned Res, unsigned Tst,
Tim Northover5a28c362016-08-19 20:09:07 +0000449 unsigned Op0, unsigned Op1) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000450#ifndef NDEBUG
Tim Northoverf50f2f32016-12-06 18:38:34 +0000451 LLT ResTy = MRI->getType(Res);
452 assert((ResTy.isScalar() || ResTy.isVector() || ResTy.isPointer()) &&
Tim Northover1f8b1db2016-09-09 11:46:58 +0000453 "invalid operand type");
Tim Northoverf50f2f32016-12-06 18:38:34 +0000454 assert(ResTy == MRI->getType(Op0) && ResTy == MRI->getType(Op1) &&
455 "type mismatch");
456 if (ResTy.isScalar() || ResTy.isPointer())
Tim Northover1f8b1db2016-09-09 11:46:58 +0000457 assert(MRI->getType(Tst).isScalar() && "type mismatch");
458 else
459 assert(MRI->getType(Tst).isVector() &&
460 MRI->getType(Tst).getNumElements() ==
461 MRI->getType(Op0).getNumElements() &&
462 "type mismatch");
463#endif
464
Tim Northover0f140c72016-09-09 11:46:34 +0000465 return buildInstr(TargetOpcode::G_SELECT)
Tim Northover5a28c362016-08-19 20:09:07 +0000466 .addDef(Res)
467 .addUse(Tst)
468 .addUse(Op0)
469 .addUse(Op1);
470}
Tim Northoverbdf67c92016-08-23 21:01:33 +0000471
Tim Northover0f140c72016-09-09 11:46:34 +0000472void MachineIRBuilder::validateTruncExt(unsigned Dst, unsigned Src,
473 bool IsExtend) {
Richard Smith418237b2016-08-23 22:14:15 +0000474#ifndef NDEBUG
Tim Northover0f140c72016-09-09 11:46:34 +0000475 LLT SrcTy = MRI->getType(Src);
476 LLT DstTy = MRI->getType(Dst);
Tim Northoverbdf67c92016-08-23 21:01:33 +0000477
478 if (DstTy.isVector()) {
479 assert(SrcTy.isVector() && "mismatched cast between vecot and non-vector");
480 assert(SrcTy.getNumElements() == DstTy.getNumElements() &&
481 "different number of elements in a trunc/ext");
482 } else
483 assert(DstTy.isScalar() && SrcTy.isScalar() && "invalid extend/trunc");
484
485 if (IsExtend)
486 assert(DstTy.getSizeInBits() > SrcTy.getSizeInBits() &&
487 "invalid narrowing extend");
488 else
489 assert(DstTy.getSizeInBits() < SrcTy.getSizeInBits() &&
490 "invalid widening trunc");
Richard Smith418237b2016-08-23 22:14:15 +0000491#endif
Tim Northoverbdf67c92016-08-23 21:01:33 +0000492}