blob: 30971e72f7d9abee3498772a506e8187b1150bca [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 Northover33b07d62016-07-22 20:03:43 +000097MachineInstr *MachineIRBuilder::buildExtract(LLT Ty, ArrayRef<unsigned> Results,
98 unsigned Src,
99 ArrayRef<unsigned> Indexes) {
100 assert(Results.size() == Indexes.size() && "inconsistent number of regs");
101
102 MachineInstr *NewMI = buildInstr(TargetOpcode::G_EXTRACT, Ty);
103 auto MIB = MachineInstrBuilder(getMF(), NewMI);
104 for (auto Res : Results)
105 MIB.addReg(Res, RegState::Define);
106
107 MIB.addReg(Src);
108
109 for (auto Idx : Indexes)
110 MIB.addImm(Idx);
111 return NewMI;
112}
113
114MachineInstr *MachineIRBuilder::buildSequence(LLT Ty, unsigned Res,
115 ArrayRef<unsigned> Ops) {
116 MachineInstr *NewMI = buildInstr(TargetOpcode::G_SEQUENCE, Ty);
117 auto MIB = MachineInstrBuilder(getMF(), NewMI);
118 MIB.addReg(Res, RegState::Define);
119 for (auto Op : Ops)
120 MIB.addReg(Op);
121 return NewMI;
122}