1 //===-- 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"
18 #include "llvm/Target/TargetOpcodes.h"
19 #include "llvm/Target/TargetSubtargetInfo.h"
20 
21 using namespace llvm;
22 
23 void MachineIRBuilder::setMF(MachineFunction &MF) {
24   this->MF = &MF;
25   this->MBB = nullptr;
26   this->TII = MF.getSubtarget().getInstrInfo();
27   this->DL = DebugLoc();
28   this->MI = nullptr;
29 }
30 
31 void MachineIRBuilder::setMBB(MachineBasicBlock &MBB, bool Beginning) {
32   this->MBB = &MBB;
33   Before = Beginning;
34   assert(&getMF() == MBB.getParent() &&
35          "Basic block is in a different function");
36 }
37 
38 void MachineIRBuilder::setInstr(MachineInstr &MI, bool Before) {
39   assert(MI.getParent() && "Instruction is not part of a basic block");
40   setMBB(*MI.getParent());
41   this->MI = &MI;
42   this->Before = Before;
43 }
44 
45 MachineBasicBlock::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 
56 //------------------------------------------------------------------------------
57 // Build instruction variants.
58 //------------------------------------------------------------------------------
59 MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, LLT Ty) {
60   MachineInstr *NewMI = BuildMI(getMF(), DL, getTII().get(Opcode));
61   if (Ty.isValid()) {
62     assert(isPreISelGenericOpcode(Opcode) &&
63            "Only generic instruction can have a type");
64     NewMI->setType(Ty);
65   } else
66     assert(!isPreISelGenericOpcode(Opcode) &&
67            "Generic instruction must have a type");
68   getMBB().insert(getInsertPt(), NewMI);
69   return NewMI;
70 }
71 
72 MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, unsigned Res,
73                                            unsigned Op0, unsigned Op1) {
74   return buildInstr(Opcode, LLT{}, Res, Op0, Op1);
75 }
76 
77 MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, LLT Ty,
78                                            unsigned Res, unsigned Op0,
79                                            unsigned Op1) {
80   MachineInstr *NewMI = buildInstr(Opcode, Ty);
81   MachineInstrBuilder(getMF(), NewMI)
82       .addReg(Res, RegState::Define)
83       .addReg(Op0)
84       .addReg(Op1);
85   return NewMI;
86 }
87 
88 MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, ArrayRef<LLT> Tys,
89                                            unsigned Res, unsigned Op0) {
90   MachineInstr *NewMI = buildInstr(Opcode, Tys[0]);
91   for (unsigned i = 1; i < Tys.size(); ++i)
92     NewMI->setType(Tys[i], i);
93 
94   MachineInstrBuilder(getMF(), NewMI)
95       .addReg(Res, RegState::Define)
96       .addReg(Op0);
97   return NewMI;
98 }
99 
100 MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, unsigned Res,
101                                            unsigned Op0) {
102   MachineInstr *NewMI = buildInstr(Opcode, LLT{});
103   MachineInstrBuilder(getMF(), NewMI).addReg(Res, RegState::Define).addReg(Op0);
104   return NewMI;
105 }
106 
107 MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode) {
108   return buildInstr(Opcode, LLT{});
109 }
110 
111 MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, LLT Ty,
112                                            MachineBasicBlock &BB) {
113   MachineInstr *NewMI = buildInstr(Opcode, Ty);
114   MachineInstrBuilder(getMF(), NewMI).addMBB(&BB);
115   return NewMI;
116 }
117 
118 MachineInstr *MachineIRBuilder::buildFrameIndex(LLT Ty, unsigned Res, int Idx) {
119   MachineInstr *NewMI = buildInstr(TargetOpcode::G_FRAME_INDEX, Ty);
120   auto MIB = MachineInstrBuilder(getMF(), NewMI);
121   MIB.addReg(Res, RegState::Define);
122   MIB.addImm(Idx);
123   return NewMI;
124 }
125 
126 MachineInstr *MachineIRBuilder::buildAdd(LLT Ty, unsigned Res, unsigned Op0,
127                                          unsigned Op1) {
128   return buildInstr(TargetOpcode::G_ADD, Ty, Res, Op0, Op1);
129 }
130 
131 MachineInstr *MachineIRBuilder::buildExtract(LLT Ty, ArrayRef<unsigned> Results,
132                                              unsigned Src,
133                                              ArrayRef<unsigned> Indexes) {
134   assert(Results.size() == Indexes.size() && "inconsistent number of regs");
135 
136   MachineInstr *NewMI = buildInstr(TargetOpcode::G_EXTRACT, Ty);
137   auto MIB = MachineInstrBuilder(getMF(), NewMI);
138   for (auto Res : Results)
139     MIB.addReg(Res, RegState::Define);
140 
141   MIB.addReg(Src);
142 
143   for (auto Idx : Indexes)
144     MIB.addImm(Idx);
145   return NewMI;
146 }
147 
148 MachineInstr *MachineIRBuilder::buildSequence(LLT Ty, unsigned Res,
149                                               ArrayRef<unsigned> Ops) {
150   MachineInstr *NewMI = buildInstr(TargetOpcode::G_SEQUENCE, Ty);
151   auto MIB = MachineInstrBuilder(getMF(), NewMI);
152   MIB.addReg(Res, RegState::Define);
153   for (auto Op : Ops)
154     MIB.addReg(Op);
155   return NewMI;
156 }
157