blob: be4cafc575bfaf3623914ab7986e7d5d77afe175 [file] [log] [blame]
Quentin Colombet2ad1f852016-02-11 17:44:59 +00001//===-- llvm/CodeGen/GlobalISel/MachineIRBuilder.cpp - MIBuilder--*- C++ -*-==//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9/// \file
10/// This file implements the MachineIRBuidler class.
11//===----------------------------------------------------------------------===//
12#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
13
14#include "llvm/CodeGen/MachineFunction.h"
15#include "llvm/CodeGen/MachineInstr.h"
16#include "llvm/CodeGen/MachineInstrBuilder.h"
17#include "llvm/Target/TargetInstrInfo.h"
Quentin Colombet8fd67182016-02-11 21:16:56 +000018#include "llvm/Target/TargetOpcodes.h"
Quentin Colombet2ad1f852016-02-11 17:44:59 +000019#include "llvm/Target/TargetSubtargetInfo.h"
20
21using namespace llvm;
22
Quentin Colombet000b5802016-03-11 17:27:51 +000023void MachineIRBuilder::setMF(MachineFunction &MF) {
Quentin Colombet2ad1f852016-02-11 17:44:59 +000024 this->MF = &MF;
25 this->MBB = nullptr;
26 this->TII = MF.getSubtarget().getInstrInfo();
27 this->DL = DebugLoc();
28 this->MI = nullptr;
29}
30
Quentin Colombet91ebd712016-03-11 17:27:47 +000031void MachineIRBuilder::setMBB(MachineBasicBlock &MBB, bool Beginning) {
Quentin Colombet2ad1f852016-02-11 17:44:59 +000032 this->MBB = &MBB;
33 Before = Beginning;
34 assert(&getMF() == MBB.getParent() &&
35 "Basic block is in a different function");
36}
37
38void MachineIRBuilder::setInstr(MachineInstr &MI, bool Before) {
39 assert(MI.getParent() && "Instruction is not part of a basic block");
Quentin Colombet91ebd712016-03-11 17:27:47 +000040 setMBB(*MI.getParent());
Quentin Colombet2ad1f852016-02-11 17:44:59 +000041 this->MI = &MI;
42 this->Before = Before;
43}
44
45MachineBasicBlock::iterator MachineIRBuilder::getInsertPt() {
46 if (MI) {
47 if (Before)
48 return MI;
49 if (!MI->getNextNode())
50 return getMBB().end();
51 return MI->getNextNode();
52 }
53 return Before ? getMBB().begin() : getMBB().end();
54}
55
Quentin Colombetf9b49342016-03-11 17:27:58 +000056//------------------------------------------------------------------------------
57// Build instruction variants.
58//------------------------------------------------------------------------------
Tim Northovercc5f7622016-07-26 16:45:26 +000059
60MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, ArrayRef<LLT> Tys) {
Quentin Colombetf9b49342016-03-11 17:27:58 +000061 MachineInstr *NewMI = BuildMI(getMF(), DL, getTII().get(Opcode));
Tim Northovercc5f7622016-07-26 16:45:26 +000062 if (Tys.size() > 0) {
Quentin Colombet8fd67182016-02-11 21:16:56 +000063 assert(isPreISelGenericOpcode(Opcode) &&
64 "Only generic instruction can have a type");
Tim Northovercc5f7622016-07-26 16:45:26 +000065 for (unsigned i = 0; i < Tys.size(); ++i)
66 NewMI->setType(Tys[i], i);
Quentin Colombet8fd67182016-02-11 21:16:56 +000067 } else
68 assert(!isPreISelGenericOpcode(Opcode) &&
69 "Generic instruction must have a type");
Quentin Colombet74d7d2f2016-02-11 18:53:28 +000070 getMBB().insert(getInsertPt(), NewMI);
71 return NewMI;
72}
73
Tim Northoverbd505462016-07-22 16:59:52 +000074MachineInstr *MachineIRBuilder::buildFrameIndex(LLT Ty, unsigned Res, int Idx) {
75 MachineInstr *NewMI = buildInstr(TargetOpcode::G_FRAME_INDEX, Ty);
76 auto MIB = MachineInstrBuilder(getMF(), NewMI);
77 MIB.addReg(Res, RegState::Define);
Tim Northoverab395cb2016-07-26 17:42:40 +000078 MIB.addFrameIndex(Idx);
Tim Northoverbd505462016-07-22 16:59:52 +000079 return NewMI;
80}
Tim Northover33b07d62016-07-22 20:03:43 +000081
82MachineInstr *MachineIRBuilder::buildAdd(LLT Ty, unsigned Res, unsigned Op0,
83 unsigned Op1) {
84 return buildInstr(TargetOpcode::G_ADD, Ty, Res, Op0, Op1);
85}
86
Tim Northovercc5f7622016-07-26 16:45:26 +000087MachineInstr *MachineIRBuilder::buildBr(MachineBasicBlock &Dest) {
88 MachineInstr *NewMI = buildInstr(TargetOpcode::G_BR, LLT::unsized());
89 MachineInstrBuilder(getMF(), NewMI).addMBB(&Dest);
90 return NewMI;
91}
92
Tim Northover756eca32016-07-26 16:45:30 +000093MachineInstr *MachineIRBuilder::buildCopy(unsigned Res, unsigned Op) {
94 return buildInstr(TargetOpcode::COPY, Res, Op);
95}
96
Tim Northoverad2b7172016-07-26 20:23:26 +000097MachineInstr *MachineIRBuilder::buildLoad(LLT VTy, LLT PTy, unsigned Res,
98 unsigned Addr,
99 MachineMemOperand &MMO) {
100 MachineInstr *NewMI = buildInstr(TargetOpcode::G_LOAD, {VTy, PTy}, Res, Addr);
101 NewMI->addMemOperand(getMF(), &MMO);
102 return NewMI;
103}
104
105MachineInstr *MachineIRBuilder::buildStore(LLT VTy, LLT PTy, unsigned Val,
106 unsigned Addr,
107 MachineMemOperand &MMO) {
108 MachineInstr *NewMI = buildInstr(TargetOpcode::G_STORE, {VTy, PTy});
109 NewMI->addMemOperand(getMF(), &MMO);
110 MachineInstrBuilder(getMF(), NewMI).addReg(Val).addReg(Addr);
111 return NewMI;
112}
113
Tim Northover33b07d62016-07-22 20:03:43 +0000114MachineInstr *MachineIRBuilder::buildExtract(LLT Ty, ArrayRef<unsigned> Results,
115 unsigned Src,
116 ArrayRef<unsigned> Indexes) {
117 assert(Results.size() == Indexes.size() && "inconsistent number of regs");
118
119 MachineInstr *NewMI = buildInstr(TargetOpcode::G_EXTRACT, Ty);
120 auto MIB = MachineInstrBuilder(getMF(), NewMI);
121 for (auto Res : Results)
122 MIB.addReg(Res, RegState::Define);
123
124 MIB.addReg(Src);
125
126 for (auto Idx : Indexes)
127 MIB.addImm(Idx);
128 return NewMI;
129}
130
131MachineInstr *MachineIRBuilder::buildSequence(LLT Ty, unsigned Res,
132 ArrayRef<unsigned> Ops) {
133 MachineInstr *NewMI = buildInstr(TargetOpcode::G_SEQUENCE, Ty);
134 auto MIB = MachineInstrBuilder(getMF(), NewMI);
135 MIB.addReg(Res, RegState::Define);
136 for (auto Op : Ops)
137 MIB.addReg(Op);
138 return NewMI;
139}