blob: 50136c4b1b3a10163aee04c22061c4df1666d478 [file] [log] [blame]
Than McIntosh9cff07b2017-05-18 14:24:02 -04001//===-- go-llvm-cabi-irbuilders.h - IR builder helper classes -------------===//
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//
10// Assorted helper classes for IR building.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVMGOFRONTEND_GO_LLVM_IRBUILDER_H
15#define LLVMGOFRONTEND_GO_LLVM_IRBUILDER_H
16
17#include "go-llvm-bexpression.h"
18
19#include "llvm/IR/IRBuilder.h"
20
21class NameGen;
22
23// Generic "no insert" builder
24typedef llvm::IRBuilder<> LIRBuilder;
25
Than McIntoshbcbffd72017-06-02 09:17:23 -040026// Insertion helper for Bexpressions; inserts any instructions
27// created by IRBuilder into the specified Bexpression's inst list.
28
Than McIntosh9cff07b2017-05-18 14:24:02 -040029class BexprInserter {
30 public:
31 BexprInserter() : expr_(nullptr) { }
32 void setDest(Bexpression *expr) { assert(!expr_); expr_ = expr; }
33
34 void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name,
35 llvm::BasicBlock *BB,
36 llvm::BasicBlock::iterator InsertPt) const {
37 assert(expr_);
38 expr_->appendInstruction(I);
39 I->setName(Name);
40 }
41
42 private:
43 mutable Bexpression *expr_;
44};
45
46// Builder that appends to a specified Bexpression
47
48class BexprLIRBuilder :
49 public llvm::IRBuilder<llvm::ConstantFolder, BexprInserter> {
50 typedef llvm::IRBuilder<llvm::ConstantFolder, BexprInserter> IRBuilderBase;
51 public:
52 BexprLIRBuilder(llvm::LLVMContext &context, Bexpression *expr) :
53 IRBuilderBase(context, llvm::ConstantFolder()) {
54 setDest(expr);
55 }
56};
57
Than McIntoshbcbffd72017-06-02 09:17:23 -040058// Similar to the above, but adds to a Binstructions object.
59
Than McIntosh9cff07b2017-05-18 14:24:02 -040060class BinstructionsInserter {
61 public:
62 BinstructionsInserter() : insns_(nullptr) { }
63 void setDest(Binstructions *insns) { assert(!insns_); insns_ = insns; }
64
65 void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name,
66 llvm::BasicBlock *BB,
67 llvm::BasicBlock::iterator InsertPt) const {
68 assert(insns_);
69 insns_->appendInstruction(I);
70 I->setName(Name);
71 }
72
73 private:
74 mutable Binstructions *insns_;
75};
76
77// Builder that appends to a specified Binstructions object
78
79class BinstructionsLIRBuilder :
80 public llvm::IRBuilder<llvm::ConstantFolder, BinstructionsInserter> {
81 typedef llvm::IRBuilder<llvm::ConstantFolder,
82 BinstructionsInserter> IRBuilderBase;
83 public:
84 BinstructionsLIRBuilder(llvm::LLVMContext &context, Binstructions *insns) :
85 IRBuilderBase(context, llvm::ConstantFolder()) {
86 setDest(insns);
87 }
88};
89
Than McIntoshbcbffd72017-06-02 09:17:23 -040090// Some of the methods in the LLVM IRBuilder class (ex: CreateMemCpy)
91// assume that you are appending to an existing basic block (which is
92// typically not what we want to do in many cases in the bridge code).
93// Furthermore it is required that the block in question be already
94// parented within an llvm::Function (the IRBuilder code relies on
95// being able to call getParent() to trace back up to the enclosing
96// context).
Than McIntosh9cff07b2017-05-18 14:24:02 -040097//
Than McIntoshbcbffd72017-06-02 09:17:23 -040098// This builder works around this issue by creating a dummy basic
99// block to capture any instructions generated, then when the builder
100// is destroyed it detaches the instructions from the block so that
101// they can be returned in a list. A dummy function has to be passed in
102// as well in order to host the dummy BB, however the dummy block will
103// be detached in the destructor.
Than McIntosh9cff07b2017-05-18 14:24:02 -0400104
105class BlockLIRBuilder : public LIRBuilder {
106 public:
Than McIntoshbcbffd72017-06-02 09:17:23 -0400107 BlockLIRBuilder(llvm::Function *dummyFcn, NameGen *namegen);
108 ~BlockLIRBuilder();
Than McIntosh9cff07b2017-05-18 14:24:02 -0400109
110 // Return the instructions generated by this builder. Note that
111 // this detaches them from the dummy block we emitted them into,
112 // hence is not intended to be invoked more than once.
113 std::vector<llvm::Instruction*> instructions();
114
115 private:
116 std::unique_ptr<llvm::BasicBlock> dummyBlock_;
117 NameGen *namegen_;
118};
119
120#endif // LLVMGOFRONTEND_GO_LLVM_IRBUILDER_H