blob: eb345811f67ab8f6551044c4a67ba4d2a1c90f50 [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"
Quentin Colombet2ad1f852016-02-11 17:44:59 +000018#include "llvm/Target/TargetInstrInfo.h"
Quentin Colombet8fd67182016-02-11 21:16:56 +000019#include "llvm/Target/TargetOpcodes.h"
Quentin Colombet2ad1f852016-02-11 17:44:59 +000020#include "llvm/Target/TargetSubtargetInfo.h"
21
22using namespace llvm;
23
Quentin Colombet000b5802016-03-11 17:27:51 +000024void MachineIRBuilder::setMF(MachineFunction &MF) {
Quentin Colombet2ad1f852016-02-11 17:44:59 +000025 this->MF = &MF;
26 this->MBB = nullptr;
Tim Northover0f140c72016-09-09 11:46:34 +000027 this->MRI = &MF.getRegInfo();
Quentin Colombet2ad1f852016-02-11 17:44:59 +000028 this->TII = MF.getSubtarget().getInstrInfo();
29 this->DL = DebugLoc();
30 this->MI = nullptr;
Tim Northover438c77c2016-08-25 17:37:32 +000031 this->InsertedInstr = nullptr;
Quentin Colombet2ad1f852016-02-11 17:44:59 +000032}
33
Quentin Colombet91ebd712016-03-11 17:27:47 +000034void MachineIRBuilder::setMBB(MachineBasicBlock &MBB, bool Beginning) {
Quentin Colombet2ad1f852016-02-11 17:44:59 +000035 this->MBB = &MBB;
36 Before = Beginning;
37 assert(&getMF() == MBB.getParent() &&
38 "Basic block is in a different function");
39}
40
41void MachineIRBuilder::setInstr(MachineInstr &MI, bool Before) {
42 assert(MI.getParent() && "Instruction is not part of a basic block");
Quentin Colombet91ebd712016-03-11 17:27:47 +000043 setMBB(*MI.getParent());
Quentin Colombet2ad1f852016-02-11 17:44:59 +000044 this->MI = &MI;
45 this->Before = Before;
46}
47
48MachineBasicBlock::iterator MachineIRBuilder::getInsertPt() {
49 if (MI) {
50 if (Before)
51 return MI;
52 if (!MI->getNextNode())
53 return getMBB().end();
54 return MI->getNextNode();
55 }
56 return Before ? getMBB().begin() : getMBB().end();
57}
58
Tim Northover438c77c2016-08-25 17:37:32 +000059void MachineIRBuilder::recordInsertions(
60 std::function<void(MachineInstr *)> Inserted) {
61 InsertedInstr = Inserted;
62}
63
64void MachineIRBuilder::stopRecordingInsertions() {
65 InsertedInstr = nullptr;
66}
67
Quentin Colombetf9b49342016-03-11 17:27:58 +000068//------------------------------------------------------------------------------
69// Build instruction variants.
70//------------------------------------------------------------------------------
Tim Northovercc5f7622016-07-26 16:45:26 +000071
Tim Northover0f140c72016-09-09 11:46:34 +000072MachineInstrBuilder MachineIRBuilder::buildInstr(unsigned Opcode) {
Tim Northovera51575f2016-07-29 17:43:52 +000073 MachineInstrBuilder MIB = BuildMI(getMF(), DL, getTII().get(Opcode));
Tim Northovera51575f2016-07-29 17:43:52 +000074 getMBB().insert(getInsertPt(), MIB);
Tim Northover438c77c2016-08-25 17:37:32 +000075 if (InsertedInstr)
76 InsertedInstr(MIB);
Tim Northovera51575f2016-07-29 17:43:52 +000077 return MIB;
Quentin Colombet74d7d2f2016-02-11 18:53:28 +000078}
79
Tim Northover0f140c72016-09-09 11:46:34 +000080MachineInstrBuilder MachineIRBuilder::buildFrameIndex(unsigned Res, int Idx) {
81 return buildInstr(TargetOpcode::G_FRAME_INDEX)
Tim Northovera51575f2016-07-29 17:43:52 +000082 .addDef(Res)
83 .addFrameIndex(Idx);
Tim Northoverbd505462016-07-22 16:59:52 +000084}
Tim Northover33b07d62016-07-22 20:03:43 +000085
Tim Northover0f140c72016-09-09 11:46:34 +000086MachineInstrBuilder MachineIRBuilder::buildAdd(unsigned Res, unsigned Op0,
87 unsigned Op1) {
88 return buildInstr(TargetOpcode::G_ADD)
Tim Northovera51575f2016-07-29 17:43:52 +000089 .addDef(Res)
90 .addUse(Op0)
91 .addUse(Op1);
Tim Northover33b07d62016-07-22 20:03:43 +000092}
93
Tim Northover0f140c72016-09-09 11:46:34 +000094MachineInstrBuilder MachineIRBuilder::buildSub(unsigned Res, unsigned Op0,
95 unsigned Op1) {
96 return buildInstr(TargetOpcode::G_SUB)
Tim Northovercecee562016-08-26 17:46:13 +000097 .addDef(Res)
98 .addUse(Op0)
99 .addUse(Op1);
100}
101
Tim Northover0f140c72016-09-09 11:46:34 +0000102MachineInstrBuilder MachineIRBuilder::buildMul(unsigned Res, unsigned Op0,
103 unsigned Op1) {
104 return buildInstr(TargetOpcode::G_MUL)
Tim Northovercecee562016-08-26 17:46:13 +0000105 .addDef(Res)
106 .addUse(Op0)
107 .addUse(Op1);
108}
109
Tim Northovera51575f2016-07-29 17:43:52 +0000110MachineInstrBuilder MachineIRBuilder::buildBr(MachineBasicBlock &Dest) {
Tim Northover0f140c72016-09-09 11:46:34 +0000111 return buildInstr(TargetOpcode::G_BR).addMBB(&Dest);
Tim Northovercc5f7622016-07-26 16:45:26 +0000112}
113
Tim Northovera51575f2016-07-29 17:43:52 +0000114MachineInstrBuilder MachineIRBuilder::buildCopy(unsigned Res, unsigned Op) {
115 return buildInstr(TargetOpcode::COPY).addDef(Res).addUse(Op);
Tim Northover756eca32016-07-26 16:45:30 +0000116}
117
Tim Northover0f140c72016-09-09 11:46:34 +0000118MachineInstrBuilder MachineIRBuilder::buildConstant(unsigned Res, int64_t Val) {
119 return buildInstr(TargetOpcode::G_CONSTANT).addDef(Res).addImm(Val);
Tim Northover9656f142016-08-04 20:54:13 +0000120}
121
Tim Northover0f140c72016-09-09 11:46:34 +0000122MachineInstrBuilder MachineIRBuilder::buildFConstant(unsigned Res,
123 const ConstantFP &Val) {
124 return buildInstr(TargetOpcode::G_FCONSTANT).addDef(Res).addFPImm(&Val);
Tim Northoverb16734f2016-08-19 20:09:15 +0000125}
126
Tim Northover0f140c72016-09-09 11:46:34 +0000127MachineInstrBuilder MachineIRBuilder::buildBrCond(unsigned Tst,
Tim Northover69c2ba52016-07-29 17:58:00 +0000128 MachineBasicBlock &Dest) {
Tim Northover0f140c72016-09-09 11:46:34 +0000129 return buildInstr(TargetOpcode::G_BRCOND).addUse(Tst).addMBB(&Dest);
Tim Northover69c2ba52016-07-29 17:58:00 +0000130}
131
Tim Northover0f140c72016-09-09 11:46:34 +0000132MachineInstrBuilder MachineIRBuilder::buildLoad(unsigned Res, unsigned Addr,
133 MachineMemOperand &MMO) {
134 return buildInstr(TargetOpcode::G_LOAD)
Tim Northovera51575f2016-07-29 17:43:52 +0000135 .addDef(Res)
136 .addUse(Addr)
137 .addMemOperand(&MMO);
Tim Northoverad2b7172016-07-26 20:23:26 +0000138}
139
Tim Northover0f140c72016-09-09 11:46:34 +0000140MachineInstrBuilder MachineIRBuilder::buildStore(unsigned Val, unsigned Addr,
141 MachineMemOperand &MMO) {
142 return buildInstr(TargetOpcode::G_STORE)
Tim Northovera51575f2016-07-29 17:43:52 +0000143 .addUse(Val)
144 .addUse(Addr)
145 .addMemOperand(&MMO);
Tim Northoverad2b7172016-07-26 20:23:26 +0000146}
147
Tim Northover0f140c72016-09-09 11:46:34 +0000148MachineInstrBuilder MachineIRBuilder::buildUAdde(unsigned Res,
149 unsigned CarryOut,
150 unsigned Op0, unsigned Op1,
151 unsigned CarryIn) {
152 return buildInstr(TargetOpcode::G_UADDE)
Tim Northover9656f142016-08-04 20:54:13 +0000153 .addDef(Res)
154 .addDef(CarryOut)
155 .addUse(Op0)
156 .addUse(Op1)
157 .addUse(CarryIn);
158}
159
Tim Northover0f140c72016-09-09 11:46:34 +0000160MachineInstrBuilder MachineIRBuilder::buildType(unsigned Res, unsigned Op) {
161 return buildInstr(TargetOpcode::G_TYPE).addDef(Res).addUse(Op);
Tim Northover11a23542016-08-31 21:24:02 +0000162}
163
Tim Northover0f140c72016-09-09 11:46:34 +0000164MachineInstrBuilder MachineIRBuilder::buildAnyExt(unsigned Res, unsigned Op) {
165 validateTruncExt(Res, Op, true);
166 return buildInstr(TargetOpcode::G_ANYEXT).addDef(Res).addUse(Op);
Tim Northover32335812016-08-04 18:35:11 +0000167}
168
Tim Northover0f140c72016-09-09 11:46:34 +0000169MachineInstrBuilder MachineIRBuilder::buildSExt(unsigned Res, unsigned Op) {
170 validateTruncExt(Res, Op, true);
171 return buildInstr(TargetOpcode::G_SEXT).addDef(Res).addUse(Op);
Tim Northover6cd4b232016-08-23 21:01:26 +0000172}
173
Tim Northover0f140c72016-09-09 11:46:34 +0000174MachineInstrBuilder MachineIRBuilder::buildZExt(unsigned Res, unsigned Op) {
175 validateTruncExt(Res, Op, true);
176 return buildInstr(TargetOpcode::G_ZEXT).addDef(Res).addUse(Op);
Tim Northover6cd4b232016-08-23 21:01:26 +0000177}
178
Tim Northover0f140c72016-09-09 11:46:34 +0000179MachineInstrBuilder MachineIRBuilder::buildExtract(ArrayRef<unsigned> Results,
Tim Northover26b76f22016-08-19 18:32:14 +0000180 ArrayRef<uint64_t> Indices,
Tim Northover0f140c72016-09-09 11:46:34 +0000181 unsigned Src) {
182 assert(Results.size() == Indices.size() && "inconsistent number of regs");
Tim Northover26b76f22016-08-19 18:32:14 +0000183 assert(!Results.empty() && "invalid trivial extract");
Tim Northover991b12b2016-08-30 20:51:25 +0000184 assert(std::is_sorted(Indices.begin(), Indices.end()) &&
185 "extract offsets must be in ascending order");
Tim Northover33b07d62016-07-22 20:03:43 +0000186
Tim Northover26b76f22016-08-19 18:32:14 +0000187 auto MIB = BuildMI(getMF(), DL, getTII().get(TargetOpcode::G_EXTRACT));
Tim Northover33b07d62016-07-22 20:03:43 +0000188 for (auto Res : Results)
Tim Northovera51575f2016-07-29 17:43:52 +0000189 MIB.addDef(Res);
Tim Northover33b07d62016-07-22 20:03:43 +0000190
Tim Northovera51575f2016-07-29 17:43:52 +0000191 MIB.addUse(Src);
Tim Northover33b07d62016-07-22 20:03:43 +0000192
Tim Northover26b76f22016-08-19 18:32:14 +0000193 for (auto Idx : Indices)
Tim Northover33b07d62016-07-22 20:03:43 +0000194 MIB.addImm(Idx);
Tim Northover26b76f22016-08-19 18:32:14 +0000195
196 getMBB().insert(getInsertPt(), MIB);
Tim Northover438c77c2016-08-25 17:37:32 +0000197 if (InsertedInstr)
198 InsertedInstr(MIB);
Tim Northover26b76f22016-08-19 18:32:14 +0000199
Tim Northovera51575f2016-07-29 17:43:52 +0000200 return MIB;
Tim Northover33b07d62016-07-22 20:03:43 +0000201}
202
Tim Northover91c81732016-08-19 17:17:06 +0000203MachineInstrBuilder
Tim Northover0f140c72016-09-09 11:46:34 +0000204MachineIRBuilder::buildSequence(unsigned Res,
Tim Northover91c81732016-08-19 17:17:06 +0000205 ArrayRef<unsigned> Ops,
Tim Northover26b76f22016-08-19 18:32:14 +0000206 ArrayRef<unsigned> Indices) {
Tim Northover0f140c72016-09-09 11:46:34 +0000207 assert(Ops.size() == Indices.size() && "incompatible args");
Tim Northover26b76f22016-08-19 18:32:14 +0000208 assert(!Ops.empty() && "invalid trivial sequence");
Tim Northover991b12b2016-08-30 20:51:25 +0000209 assert(std::is_sorted(Indices.begin(), Indices.end()) &&
210 "sequence offsets must be in ascending order");
Tim Northover91c81732016-08-19 17:17:06 +0000211
Tim Northover0f140c72016-09-09 11:46:34 +0000212 MachineInstrBuilder MIB = buildInstr(TargetOpcode::G_SEQUENCE);
Tim Northovera51575f2016-07-29 17:43:52 +0000213 MIB.addDef(Res);
Tim Northover91c81732016-08-19 17:17:06 +0000214 for (unsigned i = 0; i < Ops.size(); ++i) {
215 MIB.addUse(Ops[i]);
Tim Northover26b76f22016-08-19 18:32:14 +0000216 MIB.addImm(Indices[i]);
Tim Northover91c81732016-08-19 17:17:06 +0000217 }
Tim Northovera51575f2016-07-29 17:43:52 +0000218 return MIB;
Tim Northover33b07d62016-07-22 20:03:43 +0000219}
Tim Northover5fb414d2016-07-29 22:32:36 +0000220
Tim Northover0f140c72016-09-09 11:46:34 +0000221MachineInstrBuilder MachineIRBuilder::buildIntrinsic(Intrinsic::ID ID,
Tim Northover5fb414d2016-07-29 22:32:36 +0000222 unsigned Res,
223 bool HasSideEffects) {
224 auto MIB =
225 buildInstr(HasSideEffects ? TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS
Tim Northover0f140c72016-09-09 11:46:34 +0000226 : TargetOpcode::G_INTRINSIC);
Tim Northover5fb414d2016-07-29 22:32:36 +0000227 if (Res)
228 MIB.addDef(Res);
229 MIB.addIntrinsicID(ID);
230 return MIB;
231}
Tim Northover32335812016-08-04 18:35:11 +0000232
Tim Northover0f140c72016-09-09 11:46:34 +0000233MachineInstrBuilder MachineIRBuilder::buildTrunc(unsigned Res, unsigned Op) {
234 validateTruncExt(Res, Op, false);
235 return buildInstr(TargetOpcode::G_TRUNC).addDef(Res).addUse(Op);
Tim Northover32335812016-08-04 18:35:11 +0000236}
Tim Northoverde3aea0412016-08-17 20:25:25 +0000237
Tim Northover0f140c72016-09-09 11:46:34 +0000238MachineInstrBuilder MachineIRBuilder::buildFPTrunc(unsigned Res, unsigned Op) {
239 validateTruncExt(Res, Op, false);
240 return buildInstr(TargetOpcode::G_FPTRUNC).addDef(Res).addUse(Op);
Tim Northovera11be042016-08-19 22:40:08 +0000241}
242
Tim Northover0f140c72016-09-09 11:46:34 +0000243MachineInstrBuilder MachineIRBuilder::buildICmp(CmpInst::Predicate Pred,
Tim Northoverde3aea0412016-08-17 20:25:25 +0000244 unsigned Res, unsigned Op0,
245 unsigned Op1) {
Tim Northover0f140c72016-09-09 11:46:34 +0000246 return buildInstr(TargetOpcode::G_ICMP)
Tim Northoverde3aea0412016-08-17 20:25:25 +0000247 .addDef(Res)
248 .addPredicate(Pred)
249 .addUse(Op0)
250 .addUse(Op1);
251}
Tim Northover5a28c362016-08-19 20:09:07 +0000252
Tim Northover0f140c72016-09-09 11:46:34 +0000253MachineInstrBuilder MachineIRBuilder::buildFCmp(CmpInst::Predicate Pred,
Tim Northoverd5c23bc2016-08-19 20:48:16 +0000254 unsigned Res, unsigned Op0,
255 unsigned Op1) {
Tim Northover0f140c72016-09-09 11:46:34 +0000256 return buildInstr(TargetOpcode::G_FCMP)
Tim Northoverd5c23bc2016-08-19 20:48:16 +0000257 .addDef(Res)
258 .addPredicate(Pred)
259 .addUse(Op0)
260 .addUse(Op1);
261}
262
Tim Northover0f140c72016-09-09 11:46:34 +0000263MachineInstrBuilder MachineIRBuilder::buildSelect(unsigned Res, unsigned Tst,
Tim Northover5a28c362016-08-19 20:09:07 +0000264 unsigned Op0, unsigned Op1) {
Tim Northover0f140c72016-09-09 11:46:34 +0000265 return buildInstr(TargetOpcode::G_SELECT)
Tim Northover5a28c362016-08-19 20:09:07 +0000266 .addDef(Res)
267 .addUse(Tst)
268 .addUse(Op0)
269 .addUse(Op1);
270}
Tim Northoverbdf67c92016-08-23 21:01:33 +0000271
Tim Northover0f140c72016-09-09 11:46:34 +0000272void MachineIRBuilder::validateTruncExt(unsigned Dst, unsigned Src,
273 bool IsExtend) {
Richard Smith418237b2016-08-23 22:14:15 +0000274#ifndef NDEBUG
Tim Northover0f140c72016-09-09 11:46:34 +0000275 LLT SrcTy = MRI->getType(Src);
276 LLT DstTy = MRI->getType(Dst);
Tim Northoverbdf67c92016-08-23 21:01:33 +0000277
278 if (DstTy.isVector()) {
279 assert(SrcTy.isVector() && "mismatched cast between vecot and non-vector");
280 assert(SrcTy.getNumElements() == DstTy.getNumElements() &&
281 "different number of elements in a trunc/ext");
282 } else
283 assert(DstTy.isScalar() && SrcTy.isScalar() && "invalid extend/trunc");
284
285 if (IsExtend)
286 assert(DstTy.getSizeInBits() > SrcTy.getSizeInBits() &&
287 "invalid narrowing extend");
288 else
289 assert(DstTy.getSizeInBits() < SrcTy.getSizeInBits() &&
290 "invalid widening trunc");
Richard Smith418237b2016-08-23 22:14:15 +0000291#endif
Tim Northoverbdf67c92016-08-23 21:01:33 +0000292}