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

Last change on this file since 5493 was 5493, checked in by cameron, 23 months ago

Restore check-ins from the last several days

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