[Alignment][NFC] Support compile time constants
[llvm-core.git] / include / llvm / CodeGen / GlobalISel / IRTranslator.h
blobbdb92aa4689d34d341cc099e37e742e93d4674f0
1 //===- llvm/CodeGen/GlobalISel/IRTranslator.h - IRTranslator ----*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This file declares the IRTranslator pass.
10 /// This pass is responsible for translating LLVM IR into MachineInstr.
11 /// It uses target hooks to lower the ABI but aside from that, the pass
12 /// generated code is generic. This is the default translator used for
13 /// GlobalISel.
14 ///
15 /// \todo Replace the comments with actual doxygen comments.
16 //===----------------------------------------------------------------------===//
18 #ifndef LLVM_CODEGEN_GLOBALISEL_IRTRANSLATOR_H
19 #define LLVM_CODEGEN_GLOBALISEL_IRTRANSLATOR_H
21 #include "llvm/ADT/DenseMap.h"
22 #include "llvm/ADT/SmallVector.h"
23 #include "llvm/CodeGen/GlobalISel/CSEMIRBuilder.h"
24 #include "llvm/CodeGen/GlobalISel/Types.h"
25 #include "llvm/CodeGen/SwiftErrorValueTracking.h"
26 #include "llvm/CodeGen/MachineFunctionPass.h"
27 #include "llvm/CodeGen/SwitchLoweringUtils.h"
28 #include "llvm/IR/Intrinsics.h"
29 #include "llvm/Support/Allocator.h"
30 #include <memory>
31 #include <utility>
33 namespace llvm {
35 class AllocaInst;
36 class BasicBlock;
37 class CallInst;
38 class CallLowering;
39 class Constant;
40 class DataLayout;
41 class FunctionLoweringInfo;
42 class Instruction;
43 class MachineBasicBlock;
44 class MachineFunction;
45 class MachineInstr;
46 class MachineRegisterInfo;
47 class OptimizationRemarkEmitter;
48 class PHINode;
49 class TargetPassConfig;
50 class User;
51 class Value;
53 // Technically the pass should run on an hypothetical MachineModule,
54 // since it should translate Global into some sort of MachineGlobal.
55 // The MachineGlobal should ultimately just be a transfer of ownership of
56 // the interesting bits that are relevant to represent a global value.
57 // That being said, we could investigate what would it cost to just duplicate
58 // the information from the LLVM IR.
59 // The idea is that ultimately we would be able to free up the memory used
60 // by the LLVM IR as soon as the translation is over.
61 class IRTranslator : public MachineFunctionPass {
62 public:
63 static char ID;
65 private:
66 /// Interface used to lower the everything related to calls.
67 const CallLowering *CLI;
69 /// This class contains the mapping between the Values to vreg related data.
70 class ValueToVRegInfo {
71 public:
72 ValueToVRegInfo() = default;
74 using VRegListT = SmallVector<Register, 1>;
75 using OffsetListT = SmallVector<uint64_t, 1>;
77 using const_vreg_iterator =
78 DenseMap<const Value *, VRegListT *>::const_iterator;
79 using const_offset_iterator =
80 DenseMap<const Value *, OffsetListT *>::const_iterator;
82 inline const_vreg_iterator vregs_end() const { return ValToVRegs.end(); }
84 VRegListT *getVRegs(const Value &V) {
85 auto It = ValToVRegs.find(&V);
86 if (It != ValToVRegs.end())
87 return It->second;
89 return insertVRegs(V);
92 OffsetListT *getOffsets(const Value &V) {
93 auto It = TypeToOffsets.find(V.getType());
94 if (It != TypeToOffsets.end())
95 return It->second;
97 return insertOffsets(V);
100 const_vreg_iterator findVRegs(const Value &V) const {
101 return ValToVRegs.find(&V);
104 bool contains(const Value &V) const {
105 return ValToVRegs.find(&V) != ValToVRegs.end();
108 void reset() {
109 ValToVRegs.clear();
110 TypeToOffsets.clear();
111 VRegAlloc.DestroyAll();
112 OffsetAlloc.DestroyAll();
115 private:
116 VRegListT *insertVRegs(const Value &V) {
117 assert(ValToVRegs.find(&V) == ValToVRegs.end() && "Value already exists");
119 // We placement new using our fast allocator since we never try to free
120 // the vectors until translation is finished.
121 auto *VRegList = new (VRegAlloc.Allocate()) VRegListT();
122 ValToVRegs[&V] = VRegList;
123 return VRegList;
126 OffsetListT *insertOffsets(const Value &V) {
127 assert(TypeToOffsets.find(V.getType()) == TypeToOffsets.end() &&
128 "Type already exists");
130 auto *OffsetList = new (OffsetAlloc.Allocate()) OffsetListT();
131 TypeToOffsets[V.getType()] = OffsetList;
132 return OffsetList;
134 SpecificBumpPtrAllocator<VRegListT> VRegAlloc;
135 SpecificBumpPtrAllocator<OffsetListT> OffsetAlloc;
137 // We store pointers to vectors here since references may be invalidated
138 // while we hold them if we stored the vectors directly.
139 DenseMap<const Value *, VRegListT*> ValToVRegs;
140 DenseMap<const Type *, OffsetListT*> TypeToOffsets;
143 /// Mapping of the values of the current LLVM IR function to the related
144 /// virtual registers and offsets.
145 ValueToVRegInfo VMap;
147 // N.b. it's not completely obvious that this will be sufficient for every
148 // LLVM IR construct (with "invoke" being the obvious candidate to mess up our
149 // lives.
150 DenseMap<const BasicBlock *, MachineBasicBlock *> BBToMBB;
152 // One BasicBlock can be translated to multiple MachineBasicBlocks. For such
153 // BasicBlocks translated to multiple MachineBasicBlocks, MachinePreds retains
154 // a mapping between the edges arriving at the BasicBlock to the corresponding
155 // created MachineBasicBlocks. Some BasicBlocks that get translated to a
156 // single MachineBasicBlock may also end up in this Map.
157 using CFGEdge = std::pair<const BasicBlock *, const BasicBlock *>;
158 DenseMap<CFGEdge, SmallVector<MachineBasicBlock *, 1>> MachinePreds;
160 // List of stubbed PHI instructions, for values and basic blocks to be filled
161 // in once all MachineBasicBlocks have been created.
162 SmallVector<std::pair<const PHINode *, SmallVector<MachineInstr *, 1>>, 4>
163 PendingPHIs;
165 /// Record of what frame index has been allocated to specified allocas for
166 /// this function.
167 DenseMap<const AllocaInst *, int> FrameIndices;
169 SwiftErrorValueTracking SwiftError;
171 /// \name Methods for translating form LLVM IR to MachineInstr.
172 /// \see ::translate for general information on the translate methods.
173 /// @{
175 /// Translate \p Inst into its corresponding MachineInstr instruction(s).
176 /// Insert the newly translated instruction(s) right where the CurBuilder
177 /// is set.
179 /// The general algorithm is:
180 /// 1. Look for a virtual register for each operand or
181 /// create one.
182 /// 2 Update the VMap accordingly.
183 /// 2.alt. For constant arguments, if they are compile time constants,
184 /// produce an immediate in the right operand and do not touch
185 /// ValToReg. Actually we will go with a virtual register for each
186 /// constants because it may be expensive to actually materialize the
187 /// constant. Moreover, if the constant spans on several instructions,
188 /// CSE may not catch them.
189 /// => Update ValToVReg and remember that we saw a constant in Constants.
190 /// We will materialize all the constants in finalize.
191 /// Note: we would need to do something so that we can recognize such operand
192 /// as constants.
193 /// 3. Create the generic instruction.
195 /// \return true if the translation succeeded.
196 bool translate(const Instruction &Inst);
198 /// Materialize \p C into virtual-register \p Reg. The generic instructions
199 /// performing this materialization will be inserted into the entry block of
200 /// the function.
202 /// \return true if the materialization succeeded.
203 bool translate(const Constant &C, Register Reg);
205 /// Translate an LLVM bitcast into generic IR. Either a COPY or a G_BITCAST is
206 /// emitted.
207 bool translateBitCast(const User &U, MachineIRBuilder &MIRBuilder);
209 /// Translate an LLVM load instruction into generic IR.
210 bool translateLoad(const User &U, MachineIRBuilder &MIRBuilder);
212 /// Translate an LLVM store instruction into generic IR.
213 bool translateStore(const User &U, MachineIRBuilder &MIRBuilder);
215 /// Translate an LLVM string intrinsic (memcpy, memset, ...).
216 bool translateMemFunc(const CallInst &CI, MachineIRBuilder &MIRBuilder,
217 Intrinsic::ID ID);
219 void getStackGuard(Register DstReg, MachineIRBuilder &MIRBuilder);
221 bool translateOverflowIntrinsic(const CallInst &CI, unsigned Op,
222 MachineIRBuilder &MIRBuilder);
224 /// Helper function for translateSimpleIntrinsic.
225 /// \return The generic opcode for \p IntrinsicID if \p IntrinsicID is a
226 /// simple intrinsic (ceil, fabs, etc.). Otherwise, returns
227 /// Intrinsic::not_intrinsic.
228 unsigned getSimpleIntrinsicOpcode(Intrinsic::ID ID);
230 /// Translates the intrinsics defined in getSimpleIntrinsicOpcode.
231 /// \return true if the translation succeeded.
232 bool translateSimpleIntrinsic(const CallInst &CI, Intrinsic::ID ID,
233 MachineIRBuilder &MIRBuilder);
235 bool translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
236 MachineIRBuilder &MIRBuilder);
238 bool translateInlineAsm(const CallInst &CI, MachineIRBuilder &MIRBuilder);
240 /// Returns true if the value should be split into multiple LLTs.
241 /// If \p Offsets is given then the split type's offsets will be stored in it.
242 /// If \p Offsets is not empty it will be cleared first.
243 bool valueIsSplit(const Value &V,
244 SmallVectorImpl<uint64_t> *Offsets = nullptr);
246 /// Common code for translating normal calls or invokes.
247 bool translateCallSite(const ImmutableCallSite &CS,
248 MachineIRBuilder &MIRBuilder);
250 /// Translate call instruction.
251 /// \pre \p U is a call instruction.
252 bool translateCall(const User &U, MachineIRBuilder &MIRBuilder);
254 bool translateInvoke(const User &U, MachineIRBuilder &MIRBuilder);
256 bool translateCallBr(const User &U, MachineIRBuilder &MIRBuilder);
258 bool translateLandingPad(const User &U, MachineIRBuilder &MIRBuilder);
260 /// Translate one of LLVM's cast instructions into MachineInstrs, with the
261 /// given generic Opcode.
262 bool translateCast(unsigned Opcode, const User &U,
263 MachineIRBuilder &MIRBuilder);
265 /// Translate a phi instruction.
266 bool translatePHI(const User &U, MachineIRBuilder &MIRBuilder);
268 /// Translate a comparison (icmp or fcmp) instruction or constant.
269 bool translateCompare(const User &U, MachineIRBuilder &MIRBuilder);
271 /// Translate an integer compare instruction (or constant).
272 bool translateICmp(const User &U, MachineIRBuilder &MIRBuilder) {
273 return translateCompare(U, MIRBuilder);
276 /// Translate a floating-point compare instruction (or constant).
277 bool translateFCmp(const User &U, MachineIRBuilder &MIRBuilder) {
278 return translateCompare(U, MIRBuilder);
281 /// Add remaining operands onto phis we've translated. Executed after all
282 /// MachineBasicBlocks for the function have been created.
283 void finishPendingPhis();
285 /// Translate \p Inst into a binary operation \p Opcode.
286 /// \pre \p U is a binary operation.
287 bool translateBinaryOp(unsigned Opcode, const User &U,
288 MachineIRBuilder &MIRBuilder);
290 /// Translate branch (br) instruction.
291 /// \pre \p U is a branch instruction.
292 bool translateBr(const User &U, MachineIRBuilder &MIRBuilder);
294 // Begin switch lowering functions.
295 bool emitJumpTableHeader(SwitchCG::JumpTable &JT,
296 SwitchCG::JumpTableHeader &JTH,
297 MachineBasicBlock *HeaderBB);
298 void emitJumpTable(SwitchCG::JumpTable &JT, MachineBasicBlock *MBB);
300 void emitSwitchCase(SwitchCG::CaseBlock &CB, MachineBasicBlock *SwitchBB,
301 MachineIRBuilder &MIB);
303 bool lowerJumpTableWorkItem(SwitchCG::SwitchWorkListItem W,
304 MachineBasicBlock *SwitchMBB,
305 MachineBasicBlock *CurMBB,
306 MachineBasicBlock *DefaultMBB,
307 MachineIRBuilder &MIB,
308 MachineFunction::iterator BBI,
309 BranchProbability UnhandledProbs,
310 SwitchCG::CaseClusterIt I,
311 MachineBasicBlock *Fallthrough,
312 bool FallthroughUnreachable);
314 bool lowerSwitchRangeWorkItem(SwitchCG::CaseClusterIt I,
315 Value *Cond,
316 MachineBasicBlock *Fallthrough,
317 bool FallthroughUnreachable,
318 BranchProbability UnhandledProbs,
319 MachineBasicBlock *CurMBB,
320 MachineIRBuilder &MIB,
321 MachineBasicBlock *SwitchMBB);
323 bool lowerSwitchWorkItem(SwitchCG::SwitchWorkListItem W, Value *Cond,
324 MachineBasicBlock *SwitchMBB,
325 MachineBasicBlock *DefaultMBB,
326 MachineIRBuilder &MIB);
328 bool translateSwitch(const User &U, MachineIRBuilder &MIRBuilder);
329 // End switch lowering section.
331 bool translateIndirectBr(const User &U, MachineIRBuilder &MIRBuilder);
333 bool translateExtractValue(const User &U, MachineIRBuilder &MIRBuilder);
335 bool translateInsertValue(const User &U, MachineIRBuilder &MIRBuilder);
337 bool translateSelect(const User &U, MachineIRBuilder &MIRBuilder);
339 bool translateGetElementPtr(const User &U, MachineIRBuilder &MIRBuilder);
341 bool translateAlloca(const User &U, MachineIRBuilder &MIRBuilder);
343 /// Translate return (ret) instruction.
344 /// The target needs to implement CallLowering::lowerReturn for
345 /// this to succeed.
346 /// \pre \p U is a return instruction.
347 bool translateRet(const User &U, MachineIRBuilder &MIRBuilder);
349 bool translateFSub(const User &U, MachineIRBuilder &MIRBuilder);
351 bool translateFNeg(const User &U, MachineIRBuilder &MIRBuilder);
353 bool translateAdd(const User &U, MachineIRBuilder &MIRBuilder) {
354 return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder);
356 bool translateSub(const User &U, MachineIRBuilder &MIRBuilder) {
357 return translateBinaryOp(TargetOpcode::G_SUB, U, MIRBuilder);
359 bool translateAnd(const User &U, MachineIRBuilder &MIRBuilder) {
360 return translateBinaryOp(TargetOpcode::G_AND, U, MIRBuilder);
362 bool translateMul(const User &U, MachineIRBuilder &MIRBuilder) {
363 return translateBinaryOp(TargetOpcode::G_MUL, U, MIRBuilder);
365 bool translateOr(const User &U, MachineIRBuilder &MIRBuilder) {
366 return translateBinaryOp(TargetOpcode::G_OR, U, MIRBuilder);
368 bool translateXor(const User &U, MachineIRBuilder &MIRBuilder) {
369 return translateBinaryOp(TargetOpcode::G_XOR, U, MIRBuilder);
372 bool translateUDiv(const User &U, MachineIRBuilder &MIRBuilder) {
373 return translateBinaryOp(TargetOpcode::G_UDIV, U, MIRBuilder);
375 bool translateSDiv(const User &U, MachineIRBuilder &MIRBuilder) {
376 return translateBinaryOp(TargetOpcode::G_SDIV, U, MIRBuilder);
378 bool translateURem(const User &U, MachineIRBuilder &MIRBuilder) {
379 return translateBinaryOp(TargetOpcode::G_UREM, U, MIRBuilder);
381 bool translateSRem(const User &U, MachineIRBuilder &MIRBuilder) {
382 return translateBinaryOp(TargetOpcode::G_SREM, U, MIRBuilder);
384 bool translateIntToPtr(const User &U, MachineIRBuilder &MIRBuilder) {
385 return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
387 bool translatePtrToInt(const User &U, MachineIRBuilder &MIRBuilder) {
388 return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
390 bool translateTrunc(const User &U, MachineIRBuilder &MIRBuilder) {
391 return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder);
393 bool translateFPTrunc(const User &U, MachineIRBuilder &MIRBuilder) {
394 return translateCast(TargetOpcode::G_FPTRUNC, U, MIRBuilder);
396 bool translateFPExt(const User &U, MachineIRBuilder &MIRBuilder) {
397 return translateCast(TargetOpcode::G_FPEXT, U, MIRBuilder);
399 bool translateFPToUI(const User &U, MachineIRBuilder &MIRBuilder) {
400 return translateCast(TargetOpcode::G_FPTOUI, U, MIRBuilder);
402 bool translateFPToSI(const User &U, MachineIRBuilder &MIRBuilder) {
403 return translateCast(TargetOpcode::G_FPTOSI, U, MIRBuilder);
405 bool translateUIToFP(const User &U, MachineIRBuilder &MIRBuilder) {
406 return translateCast(TargetOpcode::G_UITOFP, U, MIRBuilder);
408 bool translateSIToFP(const User &U, MachineIRBuilder &MIRBuilder) {
409 return translateCast(TargetOpcode::G_SITOFP, U, MIRBuilder);
411 bool translateUnreachable(const User &U, MachineIRBuilder &MIRBuilder) {
412 return true;
414 bool translateSExt(const User &U, MachineIRBuilder &MIRBuilder) {
415 return translateCast(TargetOpcode::G_SEXT, U, MIRBuilder);
418 bool translateZExt(const User &U, MachineIRBuilder &MIRBuilder) {
419 return translateCast(TargetOpcode::G_ZEXT, U, MIRBuilder);
422 bool translateShl(const User &U, MachineIRBuilder &MIRBuilder) {
423 return translateBinaryOp(TargetOpcode::G_SHL, U, MIRBuilder);
425 bool translateLShr(const User &U, MachineIRBuilder &MIRBuilder) {
426 return translateBinaryOp(TargetOpcode::G_LSHR, U, MIRBuilder);
428 bool translateAShr(const User &U, MachineIRBuilder &MIRBuilder) {
429 return translateBinaryOp(TargetOpcode::G_ASHR, U, MIRBuilder);
432 bool translateFAdd(const User &U, MachineIRBuilder &MIRBuilder) {
433 return translateBinaryOp(TargetOpcode::G_FADD, U, MIRBuilder);
435 bool translateFMul(const User &U, MachineIRBuilder &MIRBuilder) {
436 return translateBinaryOp(TargetOpcode::G_FMUL, U, MIRBuilder);
438 bool translateFDiv(const User &U, MachineIRBuilder &MIRBuilder) {
439 return translateBinaryOp(TargetOpcode::G_FDIV, U, MIRBuilder);
441 bool translateFRem(const User &U, MachineIRBuilder &MIRBuilder) {
442 return translateBinaryOp(TargetOpcode::G_FREM, U, MIRBuilder);
445 bool translateVAArg(const User &U, MachineIRBuilder &MIRBuilder);
447 bool translateInsertElement(const User &U, MachineIRBuilder &MIRBuilder);
449 bool translateExtractElement(const User &U, MachineIRBuilder &MIRBuilder);
451 bool translateShuffleVector(const User &U, MachineIRBuilder &MIRBuilder);
453 bool translateAtomicCmpXchg(const User &U, MachineIRBuilder &MIRBuilder);
454 bool translateAtomicRMW(const User &U, MachineIRBuilder &MIRBuilder);
455 bool translateFence(const User &U, MachineIRBuilder &MIRBuilder);
457 // Stubs to keep the compiler happy while we implement the rest of the
458 // translation.
459 bool translateResume(const User &U, MachineIRBuilder &MIRBuilder) {
460 return false;
462 bool translateCleanupRet(const User &U, MachineIRBuilder &MIRBuilder) {
463 return false;
465 bool translateCatchRet(const User &U, MachineIRBuilder &MIRBuilder) {
466 return false;
468 bool translateCatchSwitch(const User &U, MachineIRBuilder &MIRBuilder) {
469 return false;
471 bool translateAddrSpaceCast(const User &U, MachineIRBuilder &MIRBuilder) {
472 return translateCast(TargetOpcode::G_ADDRSPACE_CAST, U, MIRBuilder);
474 bool translateCleanupPad(const User &U, MachineIRBuilder &MIRBuilder) {
475 return false;
477 bool translateCatchPad(const User &U, MachineIRBuilder &MIRBuilder) {
478 return false;
480 bool translateUserOp1(const User &U, MachineIRBuilder &MIRBuilder) {
481 return false;
483 bool translateUserOp2(const User &U, MachineIRBuilder &MIRBuilder) {
484 return false;
487 /// @}
489 // Builder for machine instruction a la IRBuilder.
490 // I.e., compared to regular MIBuilder, this one also inserts the instruction
491 // in the current block, it can creates block, etc., basically a kind of
492 // IRBuilder, but for Machine IR.
493 // CSEMIRBuilder CurBuilder;
494 std::unique_ptr<MachineIRBuilder> CurBuilder;
496 // Builder set to the entry block (just after ABI lowering instructions). Used
497 // as a convenient location for Constants.
498 // CSEMIRBuilder EntryBuilder;
499 std::unique_ptr<MachineIRBuilder> EntryBuilder;
501 // The MachineFunction currently being translated.
502 MachineFunction *MF;
504 /// MachineRegisterInfo used to create virtual registers.
505 MachineRegisterInfo *MRI = nullptr;
507 const DataLayout *DL;
509 /// Current target configuration. Controls how the pass handles errors.
510 const TargetPassConfig *TPC;
512 /// Current optimization remark emitter. Used to report failures.
513 std::unique_ptr<OptimizationRemarkEmitter> ORE;
515 FunctionLoweringInfo FuncInfo;
517 // True when either the Target Machine specifies no optimizations or the
518 // function has the optnone attribute.
519 bool EnableOpts = false;
521 /// True when the block contains a tail call. This allows the IRTranslator to
522 /// stop translating such blocks early.
523 bool HasTailCall = false;
525 /// Switch analysis and optimization.
526 class GISelSwitchLowering : public SwitchCG::SwitchLowering {
527 public:
528 GISelSwitchLowering(IRTranslator *irt, FunctionLoweringInfo &funcinfo)
529 : SwitchLowering(funcinfo), IRT(irt) {
530 assert(irt && "irt is null!");
533 virtual void addSuccessorWithProb(
534 MachineBasicBlock *Src, MachineBasicBlock *Dst,
535 BranchProbability Prob = BranchProbability::getUnknown()) override {
536 IRT->addSuccessorWithProb(Src, Dst, Prob);
539 virtual ~GISelSwitchLowering() = default;
541 private:
542 IRTranslator *IRT;
545 std::unique_ptr<GISelSwitchLowering> SL;
547 // * Insert all the code needed to materialize the constants
548 // at the proper place. E.g., Entry block or dominator block
549 // of each constant depending on how fancy we want to be.
550 // * Clear the different maps.
551 void finalizeFunction();
553 // Handle emitting jump tables for each basic block.
554 void finalizeBasicBlock();
556 /// Get the VRegs that represent \p Val.
557 /// Non-aggregate types have just one corresponding VReg and the list can be
558 /// used as a single "unsigned". Aggregates get flattened. If such VRegs do
559 /// not exist, they are created.
560 ArrayRef<Register> getOrCreateVRegs(const Value &Val);
562 Register getOrCreateVReg(const Value &Val) {
563 auto Regs = getOrCreateVRegs(Val);
564 if (Regs.empty())
565 return 0;
566 assert(Regs.size() == 1 &&
567 "attempt to get single VReg for aggregate or void");
568 return Regs[0];
571 /// Allocate some vregs and offsets in the VMap. Then populate just the
572 /// offsets while leaving the vregs empty.
573 ValueToVRegInfo::VRegListT &allocateVRegs(const Value &Val);
575 /// Get the frame index that represents \p Val.
576 /// If such VReg does not exist, it is created.
577 int getOrCreateFrameIndex(const AllocaInst &AI);
579 /// Get the alignment of the given memory operation instruction. This will
580 /// either be the explicitly specified value or the ABI-required alignment for
581 /// the type being accessed (according to the Module's DataLayout).
582 unsigned getMemOpAlignment(const Instruction &I);
584 /// Get the MachineBasicBlock that represents \p BB. Specifically, the block
585 /// returned will be the head of the translated block (suitable for branch
586 /// destinations).
587 MachineBasicBlock &getMBB(const BasicBlock &BB);
589 /// Record \p NewPred as a Machine predecessor to `Edge.second`, corresponding
590 /// to `Edge.first` at the IR level. This is used when IRTranslation creates
591 /// multiple MachineBasicBlocks for a given IR block and the CFG is no longer
592 /// represented simply by the IR-level CFG.
593 void addMachineCFGPred(CFGEdge Edge, MachineBasicBlock *NewPred);
595 /// Returns the Machine IR predecessors for the given IR CFG edge. Usually
596 /// this is just the single MachineBasicBlock corresponding to the predecessor
597 /// in the IR. More complex lowering can result in multiple MachineBasicBlocks
598 /// preceding the original though (e.g. switch instructions).
599 SmallVector<MachineBasicBlock *, 1> getMachinePredBBs(CFGEdge Edge) {
600 auto RemappedEdge = MachinePreds.find(Edge);
601 if (RemappedEdge != MachinePreds.end())
602 return RemappedEdge->second;
603 return SmallVector<MachineBasicBlock *, 4>(1, &getMBB(*Edge.first));
606 /// Return branch probability calculated by BranchProbabilityInfo for IR
607 /// blocks.
608 BranchProbability getEdgeProbability(const MachineBasicBlock *Src,
609 const MachineBasicBlock *Dst) const;
611 void addSuccessorWithProb(MachineBasicBlock *Src, MachineBasicBlock *Dst,
612 BranchProbability Prob);
614 public:
615 // Ctor, nothing fancy.
616 IRTranslator();
618 StringRef getPassName() const override { return "IRTranslator"; }
620 void getAnalysisUsage(AnalysisUsage &AU) const override;
622 // Algo:
623 // CallLowering = MF.subtarget.getCallLowering()
624 // F = MF.getParent()
625 // MIRBuilder.reset(MF)
626 // getMBB(F.getEntryBB())
627 // CallLowering->translateArguments(MIRBuilder, F, ValToVReg)
628 // for each bb in F
629 // getMBB(bb)
630 // for each inst in bb
631 // if (!translate(MIRBuilder, inst, ValToVReg, ConstantToSequence))
632 // report_fatal_error("Don't know how to translate input");
633 // finalize()
634 bool runOnMachineFunction(MachineFunction &MF) override;
637 } // end namespace llvm
639 #endif // LLVM_CODEGEN_GLOBALISEL_IRTRANSLATOR_H