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

Last change on this file since 5486 was 5486, checked in by nmedfort, 2 years ago

Initial attempt to improve debugging capabilities with compilation stack traces on error.

File size: 10.5 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, const unsigned GeneralRegisterWidthInBits);
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 *             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.