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