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 
60 MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, ArrayRef<LLT> Tys) {
61   MachineInstr *NewMI = BuildMI(getMF(), DL, getTII().get(Opcode));
62   if (Tys.size() > 0) {
63     assert(isPreISelGenericOpcode(Opcode) &&
64            "Only generic instruction can have a type");
65     for (unsigned i = 0; i < Tys.size(); ++i)
66       NewMI->setType(Tys[i], i);
67   } else
68     assert(!isPreISelGenericOpcode(Opcode) &&
69            "Generic instruction must have a type");
70   getMBB().insert(getInsertPt(), NewMI);
71   return NewMI;
72 }
73 
74 MachineInstr *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);
78   MIB.addFrameIndex(Idx);
79   return NewMI;
80 }
81 
82 MachineInstr *MachineIRBuilder::buildAdd(LLT Ty, unsigned Res, unsigned Op0,
83                                          unsigned Op1) {
84   return buildInstr(TargetOpcode::G_ADD, Ty, Res, Op0, Op1);
85 }
86 
87 MachineInstr *MachineIRBuilder::buildBr(MachineBasicBlock &Dest) {
88   MachineInstr *NewMI = buildInstr(TargetOpcode::G_BR, LLT::unsized());
89   MachineInstrBuilder(getMF(), NewMI).addMBB(&Dest);
90   return NewMI;
91 }
92 
93 MachineInstr *MachineIRBuilder::buildCopy(unsigned Res, unsigned Op) {
94   return buildInstr(TargetOpcode::COPY, Res, Op);
95 }
96 
97 MachineInstr *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 
105 MachineInstr *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 
114 MachineInstr *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 
131 MachineInstr *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 }
140