source: icGREP/icgrep-devel/icgrep/IR_Gen/CBuilder.h @ 5489

Last change on this file since 5489 was 5489, checked in by nmedfort, 22 months ago

Bug fix for memory check and issues found parsing internal 'files'. Added backtrace option from execinfo.h

File size: 10.4 KB
Line 
1/*
2 *  Copyright (c) 2016 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 */
5#ifndef CBUILDER_H
6#define CBUILDER_H
7
8#include <IR_Gen/FunctionTypeBuilder.h>
9#include <llvm/IR/IRBuilder.h>
10#include <llvm/IR/Constants.h>
11#include <llvm/ADT/Triple.h>
12#ifndef NDEBUG
13#include <llvm/IR/Function.h>
14#endif
15
16namespace kernels { class KernelBuilder; }
17namespace llvm { class Function; }
18namespace llvm { class IntegerType; }
19namespace llvm { class Module; }
20namespace llvm { class PointerType; }
21namespace llvm { class Type; }
22namespace llvm { class Value; }
23
24class Driver;
25
26class CBuilder : public llvm::IRBuilder<> {
27public:
28
29    CBuilder(llvm::LLVMContext & C);
30   
31    virtual ~CBuilder() {}
32
33    llvm::Module * getModule() const {
34        #ifndef NDEBUG
35        llvm::BasicBlock * const bb = GetInsertBlock();
36        if (bb) {
37            llvm::Function * const f = bb->getParent();
38            assert ("CBuilder has an insert point that is not contained within a Function" && f);
39            assert ("CBuilder module differs from insertion point module" && (mModule == f->getParent()));
40        }
41        #endif
42        return mModule;
43    }
44
45    void setModule(llvm::Module * module) {
46        mModule = module;
47        ClearInsertionPoint();
48    }
49
50    llvm::Value * CreateMalloc(llvm::Value * size);
51
52    llvm::Value * CreateAlignedMalloc(llvm::Value * size, const unsigned alignment);
53   
54    void CreateFree(llvm::Value * const ptr);
55
56    llvm::Value * CreateRealloc(llvm::Value * ptr, llvm::Value * size);
57
58    llvm::CallInst * CreateMemZero(llvm::Value * ptr, llvm::Value * size, const unsigned alignment = 1) {
59        return CreateMemSet(ptr, getInt8(0), size, alignment);
60    }
61
62    llvm::AllocaInst * CreateCacheAlignedAlloca(llvm::Type * Ty, llvm::Value * ArraySize = nullptr) {
63        llvm::AllocaInst * instr = CreateAlloca(Ty, ArraySize);
64        instr->setAlignment(getCacheAlignment());
65        return instr;
66    }
67
68    llvm::Value * CreateCacheAlignedMalloc(llvm::Value * size) {
69        return CreateAlignedMalloc(size, getCacheAlignment());
70    }
71
72    // stdio.h functions
73    //
74    //  Create a call to:  FILE * fopen(const char *filename, const char *mode);
75    llvm::Value * CreateFOpenCall(llvm::Value * filename, llvm::Value * mode);
76    //  Create a call to:  size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream);
77    llvm::Value * CreateFReadCall(llvm::Value * ptr, llvm::Value * size, llvm::Value * nitems, llvm::Value * stream);
78    //  Create a call to:  size_t fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream));
79    llvm::Value * CreateFWriteCall(llvm::Value * ptr, llvm::Value * size, llvm::Value * nitems, llvm::Value * stream);
80    //  Create a call to:  int fclose ( FILE * stream );
81    llvm::Value * CreateFCloseCall(llvm::Value * stream);
82    //  Create a call to:  int remove(const char *path);
83    llvm::Value * CreateRemoveCall(llvm::Value * path);
84   
85    //  Create a call to:  int rename(const char *old, const char *new);
86    llvm::Value * CreateRenameCall(llvm::Value * oldName, llvm::Value * newName);
87   
88    llvm::Function * GetPrintf();
89
90    llvm::Function * GetDprintf();
91
92    //  Create calls to unistd.h functions.
93    //
94    //  Create a call to:  int open(const char *filename, int oflag, ...);
95    llvm::Value * CreateOpenCall(llvm::Value * filename, llvm::Value * oflag, llvm::Value * mode);
96    //  Create a call to:  ssize_t write(int fildes, const void *buf, size_t nbyte);
97    llvm::Value * CreateWriteCall(llvm::Value * fileDescriptor, llvm::Value * buf, llvm::Value * nbyte);
98    //  Create a call to:  ssize_t read(int fildes, void *buf, size_t nbyte);
99    llvm::Value * CreateReadCall(llvm::Value * fileDescriptor, llvm::Value * buf, llvm::Value * nbyte);
100    //  Create a call to:  int close(int filedes);
101    llvm::Value * CreateCloseCall(llvm::Value * fileDescriptor);
102    //  Create a call to:  int unlink(const char *path);
103    llvm::Value * CreateUnlinkCall(llvm::Value * path);
104
105    llvm::Value * CreateFileSize(llvm::Value * fileDescriptor);
106
107    //  Create calls to stdlib.h functions.
108    //
109    //  Create a call to:  int mkstemp (char *template);
110    llvm::Value * CreateMkstempCall(llvm::Value * ftemplate);
111   
112    //  Create a call to:  size_t strlen(const char *str);
113    llvm::Value * CreateStrlenCall(llvm::Value * str);
114   
115    llvm::Value * CreateAnonymousMMap(llvm::Value * size);
116
117    llvm::Value * CreateFileSourceMMap(llvm::Value * fd, llvm::Value * size);
118
119    enum Advice {
120        ADVICE_NORMAL
121        , ADVICE_RANDOM
122        , ADVICE_SEQUENTIAL
123        , ADVICE_WILLNEED
124        , ADVICE_DONTNEED
125    };
126
127    llvm::Value * CreateMAdvise(llvm::Value * addr, llvm::Value * length, Advice advice);
128
129    llvm::Value * CreateMMap(llvm::Value * const addr, llvm::Value * size, llvm::Value * const prot, llvm::Value * const flags, llvm::Value * const fd, llvm::Value * const offset);
130
131    llvm::Value * CreateMRemap(llvm::Value * addr, llvm::Value * oldSize, llvm::Value * newSize);
132
133    llvm::Value * CreateMUnmap(llvm::Value * addr, llvm::Value * size);
134
135    //  Posix thread (pthread.h) functions.
136    //
137    //  Create a call to:  int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
138    //                    void *(*start_routine)(void*), void *arg);
139    llvm::Value * CreatePThreadCreateCall(llvm::Value * thread, llvm::Value * attr, llvm::Function * start_routine, llvm::Value * arg);
140
141    //  Create a call to:  int pthread_yield(void);
142    llvm::Value * CreatePThreadYield();
143   
144    //  Create a call to:  void pthread_exit(void *value_ptr);
145    llvm::Value * CreatePThreadExitCall(llvm::Value * value_ptr);
146   
147    //  Create a call to:  int pthread_join(pthread_t thread, void **value_ptr);
148    llvm::Value * CreatePThreadJoinCall(llvm::Value * thread, llvm::Value * value_ptr);
149   
150    void CallPrintInt(const std::string & name, llvm::Value * const value);
151   
152    void CallPrintIntToStderr(const std::string & name, llvm::Value * const value);
153   
154    llvm::Value * GetString(llvm::StringRef Str);
155   
156    void CallPrintMsgToStderr(const std::string & message);
157
158    inline llvm::IntegerType * getSizeTy() const {
159        assert (mSizeType);
160        return mSizeType;
161    }
162   
163    inline llvm::ConstantInt * getSize(const size_t value) {
164        return llvm::ConstantInt::get(getSizeTy(), value);
165    }
166   
167    llvm::PointerType * getVoidPtrTy() const;
168
169    llvm::PointerType * getFILEptrTy();
170   
171    inline unsigned getCacheAlignment() const {
172        return mCacheLineAlignment;
173    }
174   
175    virtual llvm::LoadInst* CreateAtomicLoadAcquire(llvm::Value * ptr);
176
177    virtual llvm::StoreInst *  CreateAtomicStoreRelease(llvm::Value * val, llvm::Value * ptr);
178
179    void CreateAssert(llvm::Value * assertion, llvm::StringRef failureMessage);
180
181    void CreateExit(const int exitCode);
182
183    llvm::BranchInst * CreateLikelyCondBr(llvm::Value * Cond, llvm::BasicBlock * True, llvm::BasicBlock * False, const int probability = 90);
184
185    llvm::BranchInst * CreateUnlikelyCondBr(llvm::Value * Cond, llvm::BasicBlock * True, llvm::BasicBlock * False, const int probability = 90) {
186        return CreateLikelyCondBr(Cond, True, False, 100 - probability);
187    }
188
189    llvm::BasicBlock * CreateBasicBlock(std::string && name);
190
191    virtual bool supportsIndirectBr() const {
192        return true;
193    }
194
195    llvm::Value * CreatePopcount(llvm::Value * bits);
196
197    llvm::Value * CreateCountForwardZeroes(llvm::Value * value);
198
199    llvm::Value * CreateCountReverseZeroes(llvm::Value * value);
200   
201    // Useful bit manipulation operations 
202    llvm::Value * CreateResetLowestBit(llvm::Value * bits);   
203   
204    llvm::Value * CreateIsolateLowestBit(llvm::Value * bits);
205   
206    llvm::Value * CreateMaskToLowestBitInclusive(llvm::Value * bits);
207   
208    llvm::Value * CreateMaskToLowestBitExclusive(llvm::Value * bits);
209   
210    llvm::Value * CreateExtractBitField(llvm::Value * bits, llvm::Value * start, llvm::Value * length);
211   
212    llvm::Value * CreateCeilLog2(llvm::Value * value);
213   
214    llvm::Value * CreateReadCycleCounter();
215
216    template <typename ExternalFunctionType>
217    llvm::Function * LinkFunction(llvm::StringRef name, ExternalFunctionType * functionPtr) const;
218
219    #ifdef HAS_ADDRESS_SANITIZER
220    virtual llvm::LoadInst * CreateLoad(llvm::Value *Ptr, const char *Name);
221
222    virtual llvm::LoadInst * CreateLoad(llvm::Value *Ptr, const llvm::Twine &Name = "");
223
224    virtual llvm::LoadInst * CreateLoad(llvm::Type *Ty, llvm::Value *Ptr, const llvm::Twine &Name = "");
225
226    virtual llvm::LoadInst * CreateLoad(llvm::Value *Ptr, bool isVolatile, const llvm::Twine &Name = "");
227
228    virtual llvm::StoreInst * CreateStore(llvm::Value *Val, llvm::Value *Ptr, bool isVolatile = false);
229
230    llvm::LoadInst * CreateAlignedLoad(llvm::Value *Ptr, unsigned Align, const char *Name) {
231        llvm::LoadInst * LI = CreateLoad(Ptr, Name);
232        LI->setAlignment(Align);
233        return LI;
234    }
235
236    llvm::LoadInst * CreateAlignedLoad(llvm::Value *Ptr, unsigned Align, const llvm::Twine &Name = "") {
237        llvm::LoadInst * LI = CreateLoad(Ptr, Name);
238        LI->setAlignment(Align);
239        return LI;
240    }
241
242    llvm::LoadInst * CreateAlignedLoad(llvm::Value *Ptr, unsigned Align, bool isVolatile, const llvm::Twine &Name = "") {
243        llvm::LoadInst * LI = CreateLoad(Ptr, isVolatile, Name);
244        LI->setAlignment(Align);
245        return LI;
246    }
247
248    llvm::StoreInst * CreateAlignedStore(llvm::Value *Val, llvm::Value *Ptr, unsigned Align, bool isVolatile = false) {
249        llvm::StoreInst *SI = CreateStore(Val, Ptr, isVolatile);
250        SI->setAlignment(Align);
251        return SI;
252    }
253    #endif
254
255    void setDriver(Driver * const driver) {
256        mDriver = driver;
257    }
258
259protected:
260
261    llvm::Function * LinkFunction(llvm::StringRef name, llvm::FunctionType * type, void * functionPtr) const;
262
263protected:
264
265    llvm::Module *                  mModule;
266    unsigned                        mCacheLineAlignment;
267    llvm::IntegerType * const       mSizeType;
268    llvm::StructType *              mFILEtype;
269    Driver *                        mDriver;
270    llvm::LLVMContext               mContext;
271    const std::string               mTriple;
272};
273
274template <typename ExternalFunctionType>
275llvm::Function *CBuilder::LinkFunction(llvm::StringRef name, ExternalFunctionType * functionPtr) const {
276    llvm::FunctionType * const type = FunctionTypeBuilder<ExternalFunctionType>::get(getContext());
277    assert ("FunctionTypeBuilder did not resolve a function type." && type);
278    return LinkFunction(name, type, reinterpret_cast<void *>(functionPtr));
279}
280
281#endif
Note: See TracBrowser for help on using the repository browser.