]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
MFV r310796, r310797:
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / CodeGen / GlobalISel / IRTranslator.cpp
1 //===-- llvm/CodeGen/GlobalISel/IRTranslator.cpp - IRTranslator --*- 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 IRTranslator class.
11 //===----------------------------------------------------------------------===//
12
13 #include "llvm/CodeGen/GlobalISel/IRTranslator.h"
14
15 #include "llvm/ADT/SmallVector.h"
16 #include "llvm/CodeGen/GlobalISel/CallLowering.h"
17 #include "llvm/CodeGen/MachineFunction.h"
18 #include "llvm/CodeGen/MachineRegisterInfo.h"
19 #include "llvm/IR/Constant.h"
20 #include "llvm/IR/Function.h"
21 #include "llvm/IR/Type.h"
22 #include "llvm/IR/Value.h"
23 #include "llvm/Target/TargetLowering.h"
24
25 #define DEBUG_TYPE "irtranslator"
26
27 using namespace llvm;
28
29 char IRTranslator::ID = 0;
30 INITIALIZE_PASS(IRTranslator, "irtranslator", "IRTranslator LLVM IR -> MI",
31                 false, false);
32
33 IRTranslator::IRTranslator() : MachineFunctionPass(ID), MRI(nullptr) {
34   initializeIRTranslatorPass(*PassRegistry::getPassRegistry());
35 }
36
37 unsigned IRTranslator::getOrCreateVReg(const Value &Val) {
38   unsigned &ValReg = ValToVReg[&Val];
39   // Check if this is the first time we see Val.
40   if (!ValReg) {
41     // Fill ValRegsSequence with the sequence of registers
42     // we need to concat together to produce the value.
43     assert(Val.getType()->isSized() &&
44            "Don't know how to create an empty vreg");
45     assert(!Val.getType()->isAggregateType() && "Not yet implemented");
46     unsigned Size = Val.getType()->getPrimitiveSizeInBits();
47     unsigned VReg = MRI->createGenericVirtualRegister(Size);
48     ValReg = VReg;
49     assert(!isa<Constant>(Val) && "Not yet implemented");
50   }
51   return ValReg;
52 }
53
54 MachineBasicBlock &IRTranslator::getOrCreateBB(const BasicBlock &BB) {
55   MachineBasicBlock *&MBB = BBToMBB[&BB];
56   if (!MBB) {
57     MachineFunction &MF = MIRBuilder.getMF();
58     MBB = MF.CreateMachineBasicBlock();
59     MF.push_back(MBB);
60   }
61   return *MBB;
62 }
63
64 bool IRTranslator::translateBinaryOp(unsigned Opcode, const Instruction &Inst) {
65   // Get or create a virtual register for each value.
66   // Unless the value is a Constant => loadimm cst?
67   // or inline constant each time?
68   // Creation of a virtual register needs to have a size.
69   unsigned Op0 = getOrCreateVReg(*Inst.getOperand(0));
70   unsigned Op1 = getOrCreateVReg(*Inst.getOperand(1));
71   unsigned Res = getOrCreateVReg(Inst);
72   MIRBuilder.buildInstr(Opcode, Inst.getType(), Res, Op0, Op1);
73   return true;
74 }
75
76 bool IRTranslator::translateReturn(const Instruction &Inst) {
77   assert(isa<ReturnInst>(Inst) && "Return expected");
78   const Value *Ret = cast<ReturnInst>(Inst).getReturnValue();
79   // The target may mess up with the insertion point, but
80   // this is not important as a return is the last instruction
81   // of the block anyway.
82   return CLI->lowerReturn(MIRBuilder, Ret, !Ret ? 0 : getOrCreateVReg(*Ret));
83 }
84
85 bool IRTranslator::translateBr(const Instruction &Inst) {
86   assert(isa<BranchInst>(Inst) && "Branch expected");
87   const BranchInst &BrInst = *cast<BranchInst>(&Inst);
88   if (BrInst.isUnconditional()) {
89     const BasicBlock &BrTgt = *cast<BasicBlock>(BrInst.getOperand(0));
90     MachineBasicBlock &TgtBB = getOrCreateBB(BrTgt);
91     MIRBuilder.buildInstr(TargetOpcode::G_BR, BrTgt.getType(), TgtBB);
92   } else {
93     assert(0 && "Not yet implemented");
94   }
95   // Link successors.
96   MachineBasicBlock &CurBB = MIRBuilder.getMBB();
97   for (const BasicBlock *Succ : BrInst.successors())
98     CurBB.addSuccessor(&getOrCreateBB(*Succ));
99   return true;
100 }
101
102 bool IRTranslator::translate(const Instruction &Inst) {
103   MIRBuilder.setDebugLoc(Inst.getDebugLoc());
104   switch(Inst.getOpcode()) {
105   case Instruction::Add:
106     return translateBinaryOp(TargetOpcode::G_ADD, Inst);
107   case Instruction::Or:
108     return translateBinaryOp(TargetOpcode::G_OR, Inst);
109   case Instruction::Br:
110     return translateBr(Inst);
111   case Instruction::Ret:
112     return translateReturn(Inst);
113
114   default:
115     llvm_unreachable("Opcode not supported");
116   }
117 }
118
119
120 void IRTranslator::finalize() {
121   // Release the memory used by the different maps we
122   // needed during the translation.
123   ValToVReg.clear();
124   Constants.clear();
125 }
126
127 bool IRTranslator::runOnMachineFunction(MachineFunction &MF) {
128   const Function &F = *MF.getFunction();
129   if (F.empty())
130     return false;
131   CLI = MF.getSubtarget().getCallLowering();
132   MIRBuilder.setMF(MF);
133   MRI = &MF.getRegInfo();
134   // Setup the arguments.
135   MachineBasicBlock &MBB = getOrCreateBB(F.front());
136   MIRBuilder.setMBB(MBB);
137   SmallVector<unsigned, 8> VRegArgs;
138   for (const Argument &Arg: F.args())
139     VRegArgs.push_back(getOrCreateVReg(Arg));
140   bool Succeeded =
141       CLI->lowerFormalArguments(MIRBuilder, F.getArgumentList(), VRegArgs);
142   if (!Succeeded)
143     report_fatal_error("Unable to lower arguments");
144
145   for (const BasicBlock &BB: F) {
146     MachineBasicBlock &MBB = getOrCreateBB(BB);
147     // Set the insertion point of all the following translations to
148     // the end of this basic block.
149     MIRBuilder.setMBB(MBB);
150     for (const Instruction &Inst: BB) {
151       bool Succeeded = translate(Inst);
152       if (!Succeeded) {
153         DEBUG(dbgs() << "Cannot translate: " << Inst << '\n');
154         report_fatal_error("Unable to translate instruction");
155       }
156     }
157   }
158
159   // Now that the MachineFrameInfo has been configured, no further changes to
160   // the reserved registers are possible.
161   MRI->freezeReservedRegs(MF);
162
163   return false;
164 }