source: icGREP/icgrep-devel/icgrep/IR_Gen/CBuilder.cpp @ 5755

Last change on this file since 5755 was 5755, checked in by nmedfort, 17 months ago

Bug fixes and simplified MultiBlockKernel? logic

File size: 56.6 KB
RevLine 
[5239]1/*
2 *  Copyright (c) 2016 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 *  icgrep is a trademark of International Characters.
5 */
6
7#include "CBuilder.h"
[5260]8#include <llvm/IR/Module.h>
[5239]9#include <llvm/IR/Constants.h>
10#include <llvm/IR/Intrinsics.h>
11#include <llvm/IR/TypeBuilder.h>
[5350]12#include <llvm/IR/MDBuilder.h>
[5402]13#include <llvm/Support/raw_ostream.h>
[5486]14#include <llvm/Support/Format.h>
[5425]15#include <toolchain/toolchain.h>
[5464]16#include <toolchain/driver.h>
[5486]17#include <set>
18#include <thread>
[5464]19#include <stdlib.h>
[5386]20#include <sys/mman.h>
[5464]21#include <unistd.h>
[5486]22#include <stdio.h>
[5498]23
24#if defined(__i386__)
25typedef uint32_t unw_word_t;
26#else
27typedef uint64_t unw_word_t;
28#endif
[5493]29#if defined(HAS_MACH_VM_TYPES)
30#include <mach/vm_types.h>
31extern void _thread_stack_pcs(vm_address_t *buffer, unsigned max, unsigned *nb, unsigned skip);
32static_assert(sizeof(vm_address_t) == sizeof(uintptr_t), "");
33#elif defined(HAS_LIBUNWIND)
[5486]34#define UNW_LOCAL_ONLY
35#include <libunwind.h>
[5493]36static_assert(sizeof(unw_word_t) <= sizeof(uintptr_t), "");
37#elif defined(HAS_EXECINFO)
[5489]38#include <execinfo.h>
[5493]39static_assert(sizeof(void *) == sizeof(uintptr_t), "");
[5486]40#endif
[5361]41
[5733]42
43#if LLVM_VERSION_INTEGER < LLVM_5_0_0
44#define setReturnDoesNotAlias() setDoesNotAlias(0)
45#endif
46
47
[5260]48using namespace llvm;
[5243]49
[5706]50inline static bool is_power_2(const uint64_t n) {
51    return ((n & (n - 1)) == 0) && n;
52}
[5541]53
[5755]54#ifdef HAS_ADDRESS_SANITIZER
55Value * checkHeapAddress(CBuilder * const b, Value * const Ptr, Value * const Size) {
56    Module * const m = b->getModule();
57    PointerType * const voidPtrTy = b->getVoidPtrTy();
58    IntegerType * const sizeTy = b->getSizeTy();
59    Function * isPoisoned = m->getFunction("__asan_region_is_poisoned");
60    if (LLVM_UNLIKELY(isPoisoned == nullptr)) {
61        isPoisoned = Function::Create(FunctionType::get(voidPtrTy, {voidPtrTy, sizeTy}, false), Function::ExternalLinkage, "__asan_region_is_poisoned", m);
62        isPoisoned->setCallingConv(CallingConv::C);
63        isPoisoned->setReturnDoesNotAlias();
64        #if LLVM_VERSION_INTEGER < LLVM_5_0_0
65        isPoisoned->setDoesNotAlias(1);
66        #endif
67    }
68    Value * const addr = b->CreatePointerCast(Ptr, voidPtrTy);
69    Value * check = b->CreateCall(isPoisoned, { addr, b->CreateTrunc(Size, sizeTy) });
70    return b->CreateICmpEQ(check, ConstantPointerNull::get(cast<PointerType>(isPoisoned->getReturnType())));
71}
72#define CHECK_HEAP_ADDRESS(Ptr, Size, Name) \
73if (LLVM_UNLIKELY(hasAddressSanitizer())) { \
74    CreateAssert(checkHeapAddress(this, Ptr, Size), Name " was given unallocated memory address"); \
75}
76#else
77#define CHECK_HEAP_ADDRESS(Ptr, Size, Name)
78#endif
79
80static AllocaInst * resolveStackAddress(Value * Ptr) {
81    for (;;) {
82        if (GetElementPtrInst * gep = dyn_cast<GetElementPtrInst>(Ptr)) {
83            Ptr = gep->getPointerOperand();
84        } else if (CastInst * ci = dyn_cast<CastInst>(Ptr)) {
85            Ptr = ci->getOperand(0);
86        } else {
87            return dyn_cast<AllocaInst>(Ptr);
88        }
89    }
90}
91
92static Value * checkStackAddress(CBuilder * const b, Value * const Ptr, Value * const Size, AllocaInst * const Base) {
93    DataLayout DL(b->getModule());
94    IntegerType * const intPtrTy = cast<IntegerType>(DL.getIntPtrType(Ptr->getType()));
95    Value * sz = ConstantExpr::getTrunc(ConstantExpr::getSizeOf(Base->getAllocatedType()), intPtrTy);
96    if (dyn_cast_or_null<Constant>(Base->getArraySize()) && !cast<Constant>(Base->getArraySize())->isNullValue()) {
97        sz = b->CreateMul(sz, b->CreateZExtOrTrunc(Base->getArraySize(), intPtrTy));
98    }
99    Value * const p = b->CreatePtrToInt(Ptr, intPtrTy);
100    Value * const s = b->CreatePtrToInt(Base, intPtrTy);
101    Value * const e = b->CreateAdd(s, b->CreateSub(sz, b->CreateZExtOrTrunc(Size, intPtrTy)));
102    return b->CreateAnd(b->CreateICmpUGE(p, s), b->CreateICmpULE(p, e));
103}
104
105#define CHECK_ADDRESS(Ptr, Size, Name) \
106    CreateAssert(Ptr, Name " was given a null address"); \
107    if (AllocaInst * Base = resolveStackAddress(Ptr)) { \
108        CreateAssert(checkStackAddress(this, Ptr, Size, Base), Name " was given an invalid stack address"); \
109    } else { \
110        CHECK_HEAP_ADDRESS(Ptr, Size, Name) \
111    }
112
[5706]113Value * CBuilder::CreateURem(Value * const number, Value * const divisor, const Twine & Name) {
[5541]114    if (ConstantInt * c = dyn_cast<ConstantInt>(divisor)) {
[5622]115        const auto d = c->getZExtValue();
[5706]116        assert ("CreateURem divisor cannot be 0!" && d);
117        if (is_power_2(d)) {
118            return CreateAnd(number, ConstantInt::get(divisor->getType(), d - 1), Name);
[5541]119        }
120    }
[5755]121    CreateAssert(divisor, "CreateURem divisor cannot be 0!");
[5541]122    return Insert(BinaryOperator::CreateURem(number, divisor), Name);
123}
124
[5706]125Value * CBuilder::CreateUDiv(Value * const number, Value * const divisor, const Twine & Name) {
[5541]126    if (ConstantInt * c = dyn_cast<ConstantInt>(divisor)) {
[5622]127        const auto d = c->getZExtValue();
[5706]128        assert ("CreateUDiv divisor cannot be 0!" && d);
129        if (is_power_2(d)) {
[5622]130            if (d > 1) {
131                return CreateLShr(number, ConstantInt::get(divisor->getType(), std::log2(d)), Name);
[5706]132            } else {
[5622]133                return number;
134            }
[5541]135        }
136    }
[5622]137    CreateAssert(divisor, "CreateUDiv divisor cannot be 0!");
[5541]138    return Insert(BinaryOperator::CreateUDiv(number, divisor), Name);
139}
140
[5706]141Value * CBuilder::CreateUDivCeil(Value * const number, Value * const divisor, const Twine & Name) {
142    assert (number->getType() == divisor->getType());
[5755]143    Type * const t = number->getType();
144    Value * const n = CreateAdd(number, CreateSub(divisor, ConstantInt::get(t, 1)));
[5706]145    if (isa<ConstantInt>(divisor)) {
[5755]146        const auto d = cast<ConstantInt>(divisor)->getZExtValue();
147        if (is_power_2(d)) {
148            if (d > 1) {
149                return CreateLShr(n, ConstantInt::get(t, std::log2(d)), Name);
150            } else {
151                return number;
152            }
153        }
[5541]154    }
[5622]155    CreateAssert(divisor, "CreateUDivCeil divisor cannot be 0!");
[5755]156    return CreateUDiv(n, divisor, Name);
[5541]157}
158
[5706]159Value * CBuilder::CreateRoundUp(Value * const number, Value * const divisor, const Twine &Name) {
[5543]160    return CreateMul(CreateUDivCeil(number, divisor), divisor, Name);
161}
[5541]162
[5350]163Value * CBuilder::CreateOpenCall(Value * filename, Value * oflag, Value * mode) {
[5440]164    Module * const m = getModule();
165    Function * openFn = m->getFunction("open");
[5308]166    if (openFn == nullptr) {
[5755]167        IntegerType * const int32Ty = getInt32Ty();
168        PointerType * const int8PtrTy = getInt8PtrTy();
[5440]169        openFn = cast<Function>(m->getOrInsertFunction("open",
[5308]170                                                         int32Ty, int8PtrTy, int32Ty, int32Ty, nullptr));
171    }
172    return CreateCall(openFn, {filename, oflag, mode});
173}
174
[5243]175// ssize_t write(int fildes, const void *buf, size_t nbyte);
[5418]176Value * CBuilder::CreateWriteCall(Value * fileDescriptor, Value * buf, Value * nbyte) {
[5755]177    PointerType * const voidPtrTy = getVoidPtrTy();
[5440]178    Module * const m = getModule();
179    Function * write = m->getFunction("write");
[5243]180    if (write == nullptr) {
[5755]181        IntegerType * const sizeTy = getSizeTy();
182        IntegerType * const int32Ty = getInt32Ty();
[5440]183        write = cast<Function>(m->getOrInsertFunction("write",
[5733]184#if LLVM_VERSION_INTEGER < LLVM_5_0_0
[5755]185        AttributeSet().addAttribute(getContext(), 2U, Attribute::NoAlias),
[5733]186#else
[5755]187        AttributeList().addAttribute(getContext(), 2U, Attribute::NoAlias),
[5733]188#endif
[5755]189        sizeTy, int32Ty, voidPtrTy, sizeTy, nullptr));
[5243]190    }
[5429]191    buf = CreatePointerCast(buf, voidPtrTy);
[5755]192    if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::EnableAsserts))) {
193        CHECK_ADDRESS(buf, nbyte, "CreateWriteCall");
194    }
[5418]195    return CreateCall(write, {fileDescriptor, buf, nbyte});
[5243]196}
197
[5425]198Value * CBuilder::CreateReadCall(Value * fileDescriptor, Value * buf, Value * nbyte) {
[5755]199    PointerType * const voidPtrTy = getVoidPtrTy();
[5440]200    Module * const m = getModule();
201    Function * readFn = m->getFunction("read");
[5281]202    if (readFn == nullptr) {
[5755]203        IntegerType * const sizeTy = getSizeTy();
204        IntegerType * const int32Ty = getInt32Ty();
[5440]205        readFn = cast<Function>(m->getOrInsertFunction("read",
[5733]206#if LLVM_VERSION_INTEGER < LLVM_5_0_0
[5755]207        AttributeSet().addAttribute(getContext(), 2U, Attribute::NoAlias),
[5733]208#else
[5755]209        AttributeList().addAttribute(getContext(), 2U, Attribute::NoAlias),
[5733]210#endif
[5755]211        sizeTy, int32Ty, voidPtrTy, sizeTy, nullptr));
[5281]212    }
[5429]213    buf = CreatePointerCast(buf, voidPtrTy);
[5755]214    if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::EnableAsserts))) {
215        CHECK_ADDRESS(buf, nbyte, "CreateReadCall");
216    }
[5425]217    return CreateCall(readFn, {fileDescriptor, buf, nbyte});
[5281]218}
219
[5418]220Value * CBuilder::CreateCloseCall(Value * fileDescriptor) {
[5440]221    Module * const m = getModule();
222    Function * closeFn = m->getFunction("close");
[5308]223    if (closeFn == nullptr) {
224        IntegerType * int32Ty = getInt32Ty();
[5353]225        FunctionType * fty = FunctionType::get(int32Ty, {int32Ty}, true);
[5440]226        closeFn = Function::Create(fty, Function::ExternalLinkage, "close", m);
[5308]227    }
[5425]228    return CreateCall(closeFn, fileDescriptor);
[5308]229}
230
[5415]231Value * CBuilder::CreateUnlinkCall(Value * path) {
[5440]232    Module * const m = getModule();
233    Function * unlinkFunc = m->getFunction("unlink");
[5415]234    if (unlinkFunc == nullptr) {
235        FunctionType * fty = FunctionType::get(getInt32Ty(), {getInt8PtrTy()}, false);
[5440]236        unlinkFunc = Function::Create(fty, Function::ExternalLinkage, "unlink", m);
[5415]237        unlinkFunc->setCallingConv(CallingConv::C);
238    }
[5425]239    return CreateCall(unlinkFunc, path);
[5415]240}
241
242Value * CBuilder::CreateMkstempCall(Value * ftemplate) {
[5440]243    Module * const m = getModule();
244    Function * mkstempFn = m->getFunction("mkstemp");
[5415]245    if (mkstempFn == nullptr) {
[5440]246        mkstempFn = cast<Function>(m->getOrInsertFunction("mkstemp", getInt32Ty(), getInt8PtrTy(), nullptr));
[5415]247    }
[5425]248    return CreateCall(mkstempFn, ftemplate);
[5415]249}
250
251Value * CBuilder::CreateStrlenCall(Value * str) {
[5440]252    Module * const m = getModule();
253    Function * strlenFn = m->getFunction("strlen");
[5415]254    if (strlenFn == nullptr) {
[5440]255        strlenFn = cast<Function>(m->getOrInsertFunction("strlen", getSizeTy(), getInt8PtrTy(), nullptr));
[5415]256    }
[5425]257    return CreateCall(strlenFn, str);
[5415]258}
259
[5239]260Function * CBuilder::GetPrintf() {
[5440]261    Module * const m = getModule();
262    Function * printf = m->getFunction("printf");
[5239]263    if (printf == nullptr) {
[5353]264        FunctionType * fty = FunctionType::get(getInt32Ty(), {getInt8PtrTy()}, true);
[5440]265        printf = Function::Create(fty, Function::ExternalLinkage, "printf", m);
[5353]266        printf->addAttribute(1, Attribute::NoAlias);
[5239]267    }
268    return printf;
269}
270
[5422]271Function * CBuilder::GetDprintf() {
[5440]272    Module * const m = getModule();
273    Function * dprintf = m->getFunction("dprintf");
[5422]274    if (dprintf == nullptr) {
275        FunctionType * fty = FunctionType::get(getInt32Ty(), {getInt32Ty(), getInt8PtrTy()}, true);
[5440]276        dprintf = Function::Create(fty, Function::ExternalLinkage, "dprintf", m);
[5422]277    }
278    return dprintf;
279}
280
[5239]281void CBuilder::CallPrintInt(const std::string & name, Value * const value) {
[5440]282    Module * const m = getModule();
283    Constant * printRegister = m->getFunction("PrintInt");
[5411]284    IntegerType * int64Ty = getInt64Ty();
[5239]285    if (LLVM_UNLIKELY(printRegister == nullptr)) {
[5411]286        FunctionType *FT = FunctionType::get(getVoidTy(), { getInt8PtrTy(), int64Ty }, false);
[5633]287        Function * function = Function::Create(FT, Function::InternalLinkage, "PrintInt", m);
[5239]288        auto arg = function->arg_begin();
289        std::string out = "%-40s = %" PRIx64 "\n";
[5425]290        BasicBlock * entry = BasicBlock::Create(getContext(), "entry", function);
[5239]291        IRBuilder<> builder(entry);
292        std::vector<Value *> args;
[5398]293        args.push_back(GetString(out.c_str()));
[5239]294        Value * const name = &*(arg++);
295        name->setName("name");
296        args.push_back(name);
297        Value * value = &*arg;
298        value->setName("value");
299        args.push_back(value);
300        builder.CreateCall(GetPrintf(), args);
301        builder.CreateRetVoid();
302
303        printRegister = function;
304    }
305    Value * num = nullptr;
306    if (value->getType()->isPointerTy()) {
[5411]307        num = CreatePtrToInt(value, int64Ty);
[5239]308    } else {
[5411]309        num = CreateZExtOrBitCast(value, int64Ty);
[5239]310    }
311    assert (num->getType()->isIntegerTy());
[5398]312    CreateCall(printRegister, {GetString(name.c_str()), num});
[5239]313}
314
[5422]315void CBuilder::CallPrintIntToStderr(const std::string & name, Value * const value) {
[5440]316    Module * const m = getModule();
317    Constant * printRegister = m->getFunction("PrintIntToStderr");
[5422]318    if (LLVM_UNLIKELY(printRegister == nullptr)) {
319        FunctionType *FT = FunctionType::get(getVoidTy(), { PointerType::get(getInt8Ty(), 0), getSizeTy() }, false);
[5440]320        Function * function = Function::Create(FT, Function::InternalLinkage, "PrintIntToStderr", m);
[5422]321        auto arg = function->arg_begin();
322        std::string out = "%-40s = %" PRIx64 "\n";
[5425]323        BasicBlock * entry = BasicBlock::Create(getContext(), "entry", function);
[5422]324        IRBuilder<> builder(entry);
325        std::vector<Value *> args;
[5489]326        args.push_back(getInt32(STDERR_FILENO));
[5422]327        args.push_back(GetString(out.c_str()));
328        Value * const name = &*(arg++);
329        name->setName("name");
330        args.push_back(name);
331        Value * value = &*arg;
332        value->setName("value");
333        args.push_back(value);
334        builder.CreateCall(GetDprintf(), args);
335        builder.CreateRetVoid();
336
337        printRegister = function;
338    }
339    Value * num = nullptr;
340    if (value->getType()->isPointerTy()) {
341        num = CreatePtrToInt(value, getSizeTy());
342    } else {
343        num = CreateZExtOrBitCast(value, getSizeTy());
344    }
345    assert (num->getType()->isIntegerTy());
346    CreateCall(printRegister, {GetString(name.c_str()), num});
347}
348
349void CBuilder::CallPrintMsgToStderr(const std::string & message) {
[5440]350    Module * const m = getModule();
351    Constant * printMsg = m->getFunction("PrintMsgToStderr");
[5422]352    if (LLVM_UNLIKELY(printMsg == nullptr)) {
353        FunctionType *FT = FunctionType::get(getVoidTy(), { PointerType::get(getInt8Ty(), 0) }, false);
[5440]354        Function * function = Function::Create(FT, Function::InternalLinkage, "PrintMsgToStderr", m);
[5422]355        auto arg = function->arg_begin();
356        std::string out = "%s\n";
[5425]357        BasicBlock * entry = BasicBlock::Create(getContext(), "entry", function);
[5422]358        IRBuilder<> builder(entry);
359        std::vector<Value *> args;
[5489]360        args.push_back(getInt32(STDERR_FILENO));
361        args.push_back(GetString(out));
[5422]362        Value * const msg = &*(arg++);
363        msg->setName("msg");
364        args.push_back(msg);
365        builder.CreateCall(GetDprintf(), args);
366        builder.CreateRetVoid();
367
368        printMsg = function;
369    }
370    CreateCall(printMsg, {GetString(message.c_str())});
371}
372
[5361]373Value * CBuilder::CreateMalloc(Value * size) {
374    Module * const m = getModule();
[5464]375    IntegerType * const sizeTy = getSizeTy();   
[5467]376    Function * f = m->getFunction("malloc");
377    if (f == nullptr) {
[5464]378        PointerType * const voidPtrTy = getVoidPtrTy();
379        FunctionType * fty = FunctionType::get(voidPtrTy, {sizeTy}, false);
[5467]380        f = Function::Create(fty, Function::ExternalLinkage, "malloc", m);
381        f->setCallingConv(CallingConv::C);
[5733]382        f->setReturnDoesNotAlias();
[5245]383    }
[5464]384    size = CreateZExtOrTrunc(size, sizeTy);
[5467]385    CallInst * const ptr = CreateCall(f, size);
[5464]386    CreateAssert(ptr, "CreateMalloc: returned null pointer");
[5347]387    return ptr;
[5239]388}
389
[5361]390Value * CBuilder::CreateAlignedMalloc(Value * size, const unsigned alignment) {
[5755]391    if (LLVM_UNLIKELY(!is_power_2(alignment))) {
[5361]392        report_fatal_error("CreateAlignedMalloc: alignment must be a power of 2");
393    }
[5440]394    Module * const m = getModule();
[5467]395    IntegerType * const sizeTy = getSizeTy();
396    PointerType * const voidPtrTy = getVoidPtrTy();
[5755]397    ConstantInt * const align = ConstantInt::get(sizeTy, alignment);
398    ConstantInt * const alignMask = ConstantInt::get(sizeTy, alignment - 1);
[5464]399    size = CreateZExtOrTrunc(size, sizeTy);
[5755]400    Value * const offset = CreateAnd(size, alignMask);
401    size = CreateSelect(CreateIsNull(offset), size, CreateAdd(size, CreateXor(offset, alignMask)));
402    CreateAssertZero(CreateURem(size, align), "CreateAlignedMalloc: size must be an integral multiple of alignment.");
[5493]403    Value * ptr = nullptr;
404    if (hasAlignedAlloc()) {
405        Function * f = m->getFunction("aligned_alloc");
406        if (LLVM_UNLIKELY(f == nullptr)) {
407            FunctionType * const fty = FunctionType::get(voidPtrTy, {sizeTy, sizeTy}, false);
408            f = Function::Create(fty, Function::ExternalLinkage, "aligned_alloc", m);
409            f->setCallingConv(CallingConv::C);
[5733]410            f->setReturnDoesNotAlias();
[5493]411        }
412        ptr = CreateCall(f, {align, size});
413    } else if (hasPosixMemalign()) {
414        Function * f = m->getFunction("posix_memalign");
415        if (LLVM_UNLIKELY(f == nullptr)) {
416            FunctionType * const fty = FunctionType::get(getInt32Ty(), {voidPtrTy->getPointerTo(), sizeTy, sizeTy}, false);
417            f = Function::Create(fty, Function::ExternalLinkage, "posix_memalign", m);
418            f->setCallingConv(CallingConv::C);
[5733]419            f->setReturnDoesNotAlias();
[5755]420            #if LLVM_VERSION_INTEGER < LLVM_5_0_0
[5493]421            f->setDoesNotAlias(1);
[5755]422            #endif
[5493]423        }
[5500]424        Value * handle = CreateAlloca(voidPtrTy);
425        CallInst * success = CreateCall(f, {handle, align, size});
[5721]426        if (codegen::DebugOptionIsSet(codegen::EnableAsserts)) {
[5493]427            CreateAssertZero(success, "CreateAlignedMalloc: posix_memalign reported bad allocation");
428        }
[5500]429        ptr = CreateLoad(handle);
[5493]430    } else {
431        report_fatal_error("stdlib.h does not contain either aligned_alloc or posix_memalign");
[5467]432    }
[5464]433    CreateAssert(ptr, "CreateAlignedMalloc: returned null pointer.");
434    return ptr;
[5239]435}
436
[5493]437inline bool CBuilder::hasAlignedAlloc() const {
438    return mDriver && mDriver->hasExternalFunction("aligned_alloc");
439}
440
441
442inline bool CBuilder::hasPosixMemalign() const {
443    return mDriver && mDriver->hasExternalFunction("posix_memalign");
444}
445
446Value * CBuilder::CreateRealloc(Value * const ptr, Value * const size) {
[5474]447    Module * const m = getModule();
448    IntegerType * const sizeTy = getSizeTy();
449    PointerType * const voidPtrTy = getVoidPtrTy();
450    Function * f = m->getFunction("realloc");
451    if (f == nullptr) {
452        FunctionType * fty = FunctionType::get(voidPtrTy, {voidPtrTy, sizeTy}, false);
453        f = Function::Create(fty, Function::ExternalLinkage, "realloc", m);
454        f->setCallingConv(CallingConv::C);
[5733]455        f->setReturnDoesNotAlias();
456#if LLVM_VERSION_INTEGER < LLVM_5_0_0
[5474]457        f->setDoesNotAlias(1);
[5733]458#endif
[5474]459    }
[5493]460    CallInst * const ci = CreateCall(f, {CreatePointerCast(ptr, voidPtrTy), CreateZExtOrTrunc(size, sizeTy)});
[5474]461    return CreatePointerCast(ci, ptr->getType());
462}
463
[5493]464void CBuilder::CreateFree(Value * const ptr) {
[5474]465    assert (ptr->getType()->isPointerTy());
466    Module * const m = getModule();
467    Type * const voidPtrTy =  getVoidPtrTy();
468    Function * f = m->getFunction("free");
469    if (f == nullptr) {
470        FunctionType * fty = FunctionType::get(getVoidTy(), {voidPtrTy}, false);
471        f = Function::Create(fty, Function::ExternalLinkage, "free", m);
472        f->setCallingConv(CallingConv::C);
473    }
[5493]474    CreateCall(f, CreatePointerCast(ptr, voidPtrTy));
[5474]475}
476
[5386]477Value * CBuilder::CreateAnonymousMMap(Value * size) {
478    PointerType * const voidPtrTy = getVoidPtrTy();
[5389]479    IntegerType * const intTy = getInt32Ty();
[5386]480    IntegerType * const sizeTy = getSizeTy();
[5387]481    size = CreateZExtOrTrunc(size, sizeTy);
[5386]482    ConstantInt * const prot =  ConstantInt::get(intTy, PROT_READ | PROT_WRITE);
[5411]483    ConstantInt * const flags =  ConstantInt::get(intTy, MAP_PRIVATE | MAP_ANON);
[5386]484    ConstantInt * const fd =  ConstantInt::get(intTy, -1);
[5389]485    Constant * const offset = ConstantInt::get(sizeTy, 0);
[5411]486    return CreateMMap(ConstantPointerNull::getNullValue(voidPtrTy), size, prot, flags, fd, offset);
[5386]487}
488
[5418]489Value * CBuilder::CreateFileSourceMMap(Value * fd, Value * size) {
[5386]490    PointerType * const voidPtrTy = getVoidPtrTy();
[5389]491    IntegerType * const intTy = getInt32Ty();
[5418]492    fd = CreateZExtOrTrunc(fd, intTy);
[5386]493    IntegerType * const sizeTy = getSizeTy();
[5389]494    size = CreateZExtOrTrunc(size, sizeTy);
495    ConstantInt * const prot =  ConstantInt::get(intTy, PROT_READ);
496    ConstantInt * const flags =  ConstantInt::get(intTy, MAP_PRIVATE);
[5421]497    Constant * const offset = ConstantInt::get(sizeTy, 0);       
[5411]498    return CreateMMap(ConstantPointerNull::getNullValue(voidPtrTy), size, prot, flags, fd, offset);
[5389]499}
500
501Value * CBuilder::CreateMMap(Value * const addr, Value * size, Value * const prot, Value * const flags, Value * const fd, Value * const offset) {
[5440]502    Module * const m = getModule();
503    Function * fMMap = m->getFunction("mmap");
[5386]504    if (LLVM_UNLIKELY(fMMap == nullptr)) {
[5389]505        PointerType * const voidPtrTy = getVoidPtrTy();
506        IntegerType * const intTy = getInt32Ty();
507        IntegerType * const sizeTy = getSizeTy();
508        FunctionType * fty = FunctionType::get(voidPtrTy, {voidPtrTy, sizeTy, intTy, intTy, intTy, sizeTy}, false);
[5440]509        fMMap = Function::Create(fty, Function::ExternalLinkage, "mmap", m);
[5386]510    }
[5389]511    Value * ptr = CreateCall(fMMap, {addr, size, prot, flags, fd, offset});
[5755]512    if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::EnableAsserts))) {
[5486]513        DataLayout DL(m);
514        IntegerType * const intTy = getIntPtrTy(DL);
515        Value * success = CreateICmpNE(CreatePtrToInt(addr, intTy), ConstantInt::getAllOnesValue(intTy)); // MAP_FAILED = -1
516        CreateAssert(success, "CreateMMap: mmap failed to allocate memory");
[5398]517    }
[5386]518    return ptr;
519}
520
[5419]521/**
522 * @brief CBuilder::CreateMAdvise
523 * @param addr
524 * @param length
525 * @param advice
526 *
[5420]527 * Note: this funcition can fail if a kernel resource was temporarily unavailable. Test if this is more than a simple hint and handle accordingly.
[5419]528 *
529 *  ADVICE_NORMAL
530 *      No special treatment. This is the default.
531 *  ADVICE_RANDOM
532 *      Expect page references in random order. (Hence, read ahead may be less useful than normally.)
533 *  ADVICE_SEQUENTIAL
534 *      Expect page references in sequential order. (Hence, pages in the given range can be aggressively read ahead, and may be freed
535 *      soon after they are accessed.)
536 *  ADVICE_WILLNEED
537 *      Expect access in the near future. (Hence, it might be a good idea to read some pages ahead.)
538 *  ADVICE_DONTNEED
539 *      Do not expect access in the near future. (For the time being, the application is finished with the given range, so the kernel
540 *      can free resources associated with it.) Subsequent accesses of pages in this range will succeed, but will result either in
541 *      reloading of the memory contents from the underlying mapped file (see mmap(2)) or zero-fill-on-demand pages for mappings
542 *      without an underlying file.
543 *
[5421]544 * @return Value indicating success (0) or failure (-1).
[5419]545 */
546Value * CBuilder::CreateMAdvise(Value * addr, Value * length, Advice advice) {
[5425]547    Triple T(mTriple);
[5411]548    Value * result = nullptr;
[5419]549    if (T.isOSLinux() || T.isOSDarwin()) {
[5440]550        Module * const m = getModule();
[5420]551        IntegerType * const intTy = getInt32Ty();
[5411]552        IntegerType * const sizeTy = getSizeTy();
553        PointerType * const voidPtrTy = getVoidPtrTy();
[5440]554        Function * MAdviseFunc = m->getFunction("madvise");
[5411]555        if (LLVM_UNLIKELY(MAdviseFunc == nullptr)) {
556            FunctionType * fty = FunctionType::get(intTy, {voidPtrTy, sizeTy, intTy}, false);
[5440]557            MAdviseFunc = Function::Create(fty, Function::ExternalLinkage, "madvise", m);
[5411]558        }
559        addr = CreatePointerCast(addr, voidPtrTy);
560        length = CreateZExtOrTrunc(length, sizeTy);
[5419]561        int madv_flag = 0;
562        switch (advice) {
563            case Advice::ADVICE_NORMAL:
564                madv_flag = MADV_NORMAL; break;
565            case Advice::ADVICE_RANDOM:
566                madv_flag = MADV_RANDOM; break;
567            case Advice::ADVICE_SEQUENTIAL:
568                madv_flag = MADV_SEQUENTIAL; break;
569            case Advice::ADVICE_WILLNEED:
570                madv_flag = MADV_WILLNEED; break;
571            case Advice::ADVICE_DONTNEED:
572                madv_flag = MADV_DONTNEED; break;
[5411]573        }
[5419]574        result = CreateCall(MAdviseFunc, {addr, length, ConstantInt::get(intTy, madv_flag)});
[5411]575    }
576    return result;
577}
578
[5412]579#ifndef MREMAP_MAYMOVE
580#define MREMAP_MAYMOVE  1
581#endif
582
[5411]583Value * CBuilder::CreateMRemap(Value * addr, Value * oldSize, Value * newSize) {
[5425]584    Triple T(mTriple);
[5411]585    Value * ptr = nullptr;
586    if (T.isOSLinux()) {
[5440]587        Module * const m = getModule();
588        DataLayout DL(m);
[5411]589        PointerType * const voidPtrTy = getVoidPtrTy();
590        IntegerType * const sizeTy = getSizeTy();
591        IntegerType * const intTy = getIntPtrTy(DL);
[5440]592        Function * fMRemap = m->getFunction("mremap");
[5411]593        if (LLVM_UNLIKELY(fMRemap == nullptr)) {
594            FunctionType * fty = FunctionType::get(voidPtrTy, {voidPtrTy, sizeTy, sizeTy, intTy}, false);
[5440]595            fMRemap = Function::Create(fty, Function::ExternalLinkage, "mremap", m);
[5411]596        }
597        addr = CreatePointerCast(addr, voidPtrTy);
598        oldSize = CreateZExtOrTrunc(oldSize, sizeTy);
599        newSize = CreateZExtOrTrunc(newSize, sizeTy);
600        ConstantInt * const flags = ConstantInt::get(intTy, MREMAP_MAYMOVE);
601        ptr = CreateCall(fMRemap, {addr, oldSize, newSize, flags});
[5755]602        if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::EnableAsserts))) {
[5486]603            Value * success = CreateICmpNE(CreatePtrToInt(addr, intTy), ConstantInt::getAllOnesValue(intTy)); // MAP_FAILED = -1
604            CreateAssert(success, "CreateMRemap: mremap failed to allocate memory");
[5411]605        }
606    } else { // no OS mremap support
607        ptr = CreateAnonymousMMap(newSize);
608        CreateMemCpy(ptr, addr, oldSize, getpagesize());
609        CreateMUnmap(addr, oldSize);
[5398]610    }
[5386]611    return ptr;
612}
613
[5420]614Value * CBuilder::CreateMUnmap(Value * addr, Value * len) {
[5386]615    IntegerType * const sizeTy = getSizeTy();
[5387]616    PointerType * const voidPtrTy = getVoidPtrTy();
[5440]617    Module * const m = getModule();
618    Function * munmapFunc = m->getFunction("munmap");
[5420]619    if (LLVM_UNLIKELY(munmapFunc == nullptr)) {
620        FunctionType * const fty = FunctionType::get(sizeTy, {voidPtrTy, sizeTy}, false);
[5440]621        munmapFunc = Function::Create(fty, Function::ExternalLinkage, "munmap", m);
[5386]622    }
[5420]623    len = CreateZExtOrTrunc(len, sizeTy);
[5755]624    if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::EnableAsserts))) {
[5454]625        DataLayout DL(getModule());
626        IntegerType * const intPtrTy = getIntPtrTy(DL);
[5420]627        CreateAssert(len, "CreateMUnmap: length cannot be 0");
[5454]628        Value * const addrValue = CreatePtrToInt(addr, intPtrTy);
629        Value * const pageOffset = CreateURem(addrValue, ConstantInt::get(intPtrTy, getpagesize()));
[5493]630        CreateAssertZero(pageOffset, "CreateMUnmap: addr must be a multiple of the page size");
[5454]631        Value * const boundCheck = CreateICmpULT(addrValue, CreateSub(ConstantInt::getAllOnesValue(intPtrTy), CreateZExtOrTrunc(len, intPtrTy)));
[5420]632        CreateAssert(boundCheck, "CreateMUnmap: addresses in [addr, addr+len) are outside the valid address space range");
[5411]633    }
[5387]634    addr = CreatePointerCast(addr, voidPtrTy);
[5420]635    return CreateCall(munmapFunc, {addr, len});
[5386]636}
637
[5755]638Value * CBuilder::CreateMProtect(Value * addr, Value * size, const int protect) {
639    if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::EnableAsserts))) {
640        // mprotect() changes the access protections for the calling process's
641        // memory pages containing any part of the address range in the interval
642        // [addr, addr+len-1].  addr must be aligned to a page boundary.
643
644        // mprotect(): POSIX.1-2001, POSIX.1-2008, SVr4.  POSIX says that the
645        // behavior of mprotect() is unspecified if it is applied to a region of
646        // memory that was not obtained via mmap(2).
647
648        // On Linux, it is always permissible to call mprotect() on any address
649        // in a process's address space (except for the kernel vsyscall area).
650        // In particular, it can be used to change existing code mappings to be
651        // writable.
652
653//        Triple T(mTriple);
654//        if (!T.isOSLinux()) {
655//            DataLayout DL(getModule());
656//            IntegerType * const intPtrTy = getIntPtrTy(DL);
657//            Value * a = CreatePtrToInt(addr, intPtrTy);
658//            Constant * const pageSize = ConstantInt::get(intPtrTy, getpagesize());
659//            CreateAssertZero(CreateURem(a, pageSize), "CreateMProtect: addr must be aligned to page boundary on non-Linux architectures");
660//        }
661    }
662
663    IntegerType * const sizeTy = getSizeTy();
664    PointerType * const voidPtrTy = getVoidPtrTy();
665    IntegerType * const int32Ty = getInt32Ty();
666
667    Module * const m = getModule();
668    Function * mprotectFunc = m->getFunction("mprotect");
669    if (LLVM_UNLIKELY(mprotectFunc == nullptr)) {
670        FunctionType * const fty = FunctionType::get(sizeTy, {voidPtrTy, sizeTy, int32Ty}, false);
671        mprotectFunc = Function::Create(fty, Function::ExternalLinkage, "mprotect", m);
672    }
673    addr = CreatePointerCast(addr, voidPtrTy);
674    size = CreateZExtOrTrunc(size, sizeTy);
675    return CreateCall(mprotectFunc, {addr, size, ConstantInt::get(int32Ty, (int)protect)});
676
677}
678
[5675]679IntegerType * CBuilder::getIntAddrTy() const {
[5681]680    return TypeBuilder<intptr_t, false>::get(getContext());
[5675]681}
682
[5755]683PointerType * CBuilder::getVoidPtrTy(const unsigned AddressSpace) const {
684    return PointerType::get(Type::getVoidTy(getContext()), AddressSpace);
[5239]685}
686
687LoadInst * CBuilder::CreateAtomicLoadAcquire(Value * ptr) {
[5320]688    const auto alignment = ptr->getType()->getPointerElementType()->getPrimitiveSizeInBits() / 8;
[5239]689    LoadInst * inst = CreateAlignedLoad(ptr, alignment);
690    inst->setOrdering(AtomicOrdering::Acquire);
691    return inst;
692   
693}
[5361]694
[5239]695StoreInst * CBuilder::CreateAtomicStoreRelease(Value * val, Value * ptr) {
[5320]696    const auto alignment = ptr->getType()->getPointerElementType()->getPrimitiveSizeInBits() / 8;
[5239]697    StoreInst * inst = CreateAlignedStore(val, ptr, alignment);
698    inst->setOrdering(AtomicOrdering::Release);
699    return inst;
700}
[5242]701
[5280]702PointerType * CBuilder::getFILEptrTy() {
703    if (mFILEtype == nullptr) {
704        mFILEtype = StructType::create(getContext(), "struct._IO_FILE");
705    }
706    return mFILEtype->getPointerTo();
707}
708
709Value * CBuilder::CreateFOpenCall(Value * filename, Value * mode) {
[5440]710    Module * const m = getModule();
711    Function * fOpenFunc = m->getFunction("fopen");
[5280]712    if (fOpenFunc == nullptr) {
[5353]713        FunctionType * fty = FunctionType::get(getFILEptrTy(), {getInt8Ty()->getPointerTo(), getInt8Ty()->getPointerTo()}, false);
[5440]714        fOpenFunc = Function::Create(fty, Function::ExternalLinkage, "fopen", m);
[5350]715        fOpenFunc->setCallingConv(CallingConv::C);
[5280]716    }
717    return CreateCall(fOpenFunc, {filename, mode});
718}
719
[5281]720Value * CBuilder::CreateFReadCall(Value * ptr, Value * size, Value * nitems, Value * stream) {
[5440]721    Module * const m = getModule();
722    Function * fReadFunc = m->getFunction("fread");
[5411]723    PointerType * const voidPtrTy = getVoidPtrTy();
[5281]724    if (fReadFunc == nullptr) {
[5411]725        IntegerType * const sizeTy = getSizeTy();
726        FunctionType * fty = FunctionType::get(sizeTy, {voidPtrTy, sizeTy, sizeTy, getFILEptrTy()}, false);
[5440]727        fReadFunc = Function::Create(fty, Function::ExternalLinkage, "fread", m);
[5350]728        fReadFunc->setCallingConv(CallingConv::C);
[5281]729    }
[5411]730    ptr = CreatePointerCast(ptr, voidPtrTy);
[5755]731    if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::EnableAsserts))) {
732        CHECK_ADDRESS(ptr, CreateMul(size, nitems), "CreateFReadCall");
733    }
[5281]734    return CreateCall(fReadFunc, {ptr, size, nitems, stream});
735}
736
[5280]737Value * CBuilder::CreateFWriteCall(Value * ptr, Value * size, Value * nitems, Value * stream) {
[5440]738    Module * const m = getModule();
739    Function * fWriteFunc = m->getFunction("fwrite");
[5411]740    PointerType * const voidPtrTy = getVoidPtrTy();
[5280]741    if (fWriteFunc == nullptr) {
[5411]742        IntegerType * const sizeTy = getSizeTy();
743        FunctionType * fty = FunctionType::get(sizeTy, {voidPtrTy, sizeTy, sizeTy, getFILEptrTy()}, false);
[5440]744        fWriteFunc = Function::Create(fty, Function::ExternalLinkage, "fwrite", m);
[5350]745        fWriteFunc->setCallingConv(CallingConv::C);
[5280]746    }
[5411]747    ptr = CreatePointerCast(ptr, voidPtrTy);
[5755]748    if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::EnableAsserts))) {
749        CHECK_ADDRESS(ptr, CreateMul(size, nitems), "CreateFReadCall");
750    }
[5280]751    return CreateCall(fWriteFunc, {ptr, size, nitems, stream});
752}
753
754Value * CBuilder::CreateFCloseCall(Value * stream) {
[5440]755    Module * const m = getModule();
756    Function * fCloseFunc = m->getFunction("fclose");
[5280]757    if (fCloseFunc == nullptr) {
[5353]758        FunctionType * fty = FunctionType::get(getInt32Ty(), {getFILEptrTy()}, false);
[5440]759        fCloseFunc = Function::Create(fty, Function::ExternalLinkage, "fclose", m);
[5350]760        fCloseFunc->setCallingConv(CallingConv::C);
[5280]761    }
762    return CreateCall(fCloseFunc, {stream});
763}
764
[5415]765Value * CBuilder::CreateRenameCall(Value * oldName, Value * newName) {
[5440]766    Module * const m = getModule();
767    Function * renameFunc = m->getFunction("rename");
[5415]768    if (renameFunc == nullptr) {
769        FunctionType * fty = FunctionType::get(getInt32Ty(), {getInt8PtrTy(), getInt8PtrTy()}, false);
[5440]770        renameFunc = Function::Create(fty, Function::ExternalLinkage, "rename", m);
[5415]771        renameFunc->setCallingConv(CallingConv::C);
772    }
773    return CreateCall(renameFunc, {oldName, newName});
774}
775
776Value * CBuilder::CreateRemoveCall(Value * path) {
[5440]777    Module * const m = getModule();
778    Function * removeFunc = m->getFunction("remove");
[5415]779    if (removeFunc == nullptr) {
780        FunctionType * fty = FunctionType::get(getInt32Ty(), {getInt8PtrTy()}, false);
[5440]781        removeFunc = Function::Create(fty, Function::ExternalLinkage, "remove", m);
[5415]782        removeFunc->setCallingConv(CallingConv::C);
783    }
784    return CreateCall(removeFunc, {path});
785}
786
[5242]787Value * CBuilder::CreatePThreadCreateCall(Value * thread, Value * attr, Function * start_routine, Value * arg) {
[5440]788    Module * const m = getModule();
[5403]789    Type * const voidPtrTy = getVoidPtrTy();
[5440]790    Function * pthreadCreateFunc = m->getFunction("pthread_create");
[5245]791    if (pthreadCreateFunc == nullptr) {
792        Type * pthreadTy = getSizeTy();
[5633]793        FunctionType * funVoidPtrVoidTy = FunctionType::get(getVoidTy(), {voidPtrTy}, false);
[5403]794        FunctionType * fty = FunctionType::get(getInt32Ty(), {pthreadTy->getPointerTo(), voidPtrTy, funVoidPtrVoidTy->getPointerTo(), voidPtrTy}, false);
[5440]795        pthreadCreateFunc = Function::Create(fty, Function::ExternalLinkage, "pthread_create", m);
[5350]796        pthreadCreateFunc->setCallingConv(CallingConv::C);
[5245]797    }
[5403]798    return CreateCall(pthreadCreateFunc, {thread, attr, start_routine, CreatePointerCast(arg, voidPtrTy)});
[5242]799}
800
[5486]801Value * CBuilder::CreatePThreadYield() {
802    Module * const m = getModule();
803    Function * f = m->getFunction("pthread_yield");
804    if (f == nullptr) {
805        FunctionType * fty = FunctionType::get(getInt32Ty(), false);
806        f = Function::Create(fty, Function::ExternalLinkage, "pthread_yield", m);
807        f->setCallingConv(CallingConv::C);
808    }
809    return CreateCall(f);
810}
811
[5242]812Value * CBuilder::CreatePThreadExitCall(Value * value_ptr) {
[5440]813    Module * const m = getModule();
814    Function * pthreadExitFunc = m->getFunction("pthread_exit");
[5245]815    if (pthreadExitFunc == nullptr) {
[5353]816        FunctionType * fty = FunctionType::get(getVoidTy(), {getVoidPtrTy()}, false);
[5440]817        pthreadExitFunc = Function::Create(fty, Function::ExternalLinkage, "pthread_exit", m);
[5350]818        pthreadExitFunc->addFnAttr(Attribute::NoReturn);
819        pthreadExitFunc->setCallingConv(CallingConv::C);
[5245]820    }
[5242]821    CallInst * exitThread = CreateCall(pthreadExitFunc, {value_ptr});
822    exitThread->setDoesNotReturn();
823    return exitThread;
824}
825
826Value * CBuilder::CreatePThreadJoinCall(Value * thread, Value * value_ptr){
[5440]827    Module * const m = getModule();
828    Function * pthreadJoinFunc = m->getFunction("pthread_join");
[5353]829    if (pthreadJoinFunc == nullptr) {
[5486]830        FunctionType * fty = FunctionType::get(getInt32Ty(), {getSizeTy(), getVoidPtrTy()->getPointerTo()}, false);
[5440]831        pthreadJoinFunc = Function::Create(fty, Function::ExternalLinkage, "pthread_join", m);
[5353]832        pthreadJoinFunc->setCallingConv(CallingConv::C);
833    }
[5242]834    return CreateCall(pthreadJoinFunc, {thread, value_ptr});
835}
[5260]836
[5493]837void __report_failure(const char * msg, const uintptr_t * trace, const uint32_t n) {
[5489]838    raw_fd_ostream out(STDERR_FILENO, false);
839    if (trace) {
840        SmallVector<char, 4096> tmp;
841        raw_svector_ostream trace_string(tmp);
842        for (uint32_t i = 0; i < n; ++i) {
843            const auto pc = trace[i];
844            trace_string << format_hex(pc, 16) << "   ";
845            const auto len = codegen::ProgramName.length() + 32;
846            char cmd[len];
847            snprintf(cmd, len,"addr2line -fpCe %s %p", codegen::ProgramName.data(), reinterpret_cast<void *>(pc));
848            FILE * f = popen(cmd, "r");
849            if (f) {
850                char buffer[1024] = {0};
851                while(fgets(buffer, sizeof(buffer), f)) {
852                    trace_string << buffer;
853                }
854                pclose(f);
855            }
856        }
857        out.changeColor(raw_fd_ostream::WHITE, true);
858        out << "Compilation Stacktrace:\n";
859        out.resetColor();
860        out << trace_string.str();
861    }
862    out.changeColor(raw_fd_ostream::WHITE, true);
[5706]863    out << msg << "\n";
[5489]864    out.resetColor();
865    out.flush();
[5493]866
[5489]867}
868
[5493]869#if defined(HAS_MACH_VM_TYPES)
870
871/*
872 * Copyright (c) 1999, 2007 Apple Inc. All rights reserved.
873 *
874 * @APPLE_LICENSE_HEADER_START@
875 *
876 * This file contains Original Code and/or Modifications of Original Code
877 * as defined in and that are subject to the Apple Public Source License
878 * Version 2.0 (the 'License'). You may not use this file except in
879 * compliance with the License. Please obtain a copy of the License at
880 * http://www.opensource.apple.com/apsl/ and read it before using this
881 * file.
882 *
883 * The Original Code and all software distributed under the License are
884 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
885 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
886 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
887 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
888 * Please see the License for the specific language governing rights and
889 * limitations under the License.
890 *
891 * @APPLE_LICENSE_HEADER_END@
892 */
893
894#include <pthread.h>
895#include <mach/mach.h>
896#include <mach/vm_statistics.h>
897#include <stdlib.h>
898
899#if defined(__i386__) || defined(__x86_64__)
900#define FP_LINK_OFFSET 1
901#elif defined(__ppc__) || defined(__ppc64__)
902#define FP_LINK_OFFSET 2
903#else
904#error  ********** Unimplemented architecture
905#endif
906
907#define INSTACK(a)      ((uintptr_t)(a) >= stackbot && (uintptr_t)(a) <= stacktop)
908#if defined(__ppc__) || defined(__ppc64__) || defined(__x86_64__)
909#define ISALIGNED(a)    ((((uintptr_t)(a)) & 0xf) == 0)
910#elif defined(__i386__)
911#define ISALIGNED(a)    ((((uintptr_t)(a)) & 0xf) == 8)
912#endif
913
914__private_extern__  __attribute__((noinline))
915void
916_thread_stack_pcs(vm_address_t *buffer, unsigned max, unsigned *nb, unsigned skip)
917{
918    void *frame, *next;
919    pthread_t self = pthread_self();
920    uintptr_t stacktop = (uintptr_t)(pthread_get_stackaddr_np(self));
921    uintptr_t stackbot = stacktop - (uintptr_t)(pthread_get_stacksize_np(self));
922   
923    *nb = 0;
924   
925    /* make sure return address is never out of bounds */
926    stacktop -= (FP_LINK_OFFSET + 1) * sizeof(void *);
927   
928    /*
929     * The original implementation called the first_frame_address() function,
930     * which returned the stack frame pointer.  The problem was that in ppc,
931     * it was a leaf function, so no new stack frame was set up with
932     * optimization turned on (while a new stack frame was set up without
933     * optimization).  We now inline the code to get the stack frame pointer,
934     * so we are consistent about the stack frame.
935     */
936#if defined(__i386__) || defined(__x86_64__)
937    frame = __builtin_frame_address(0);
938#elif defined(__ppc__) || defined(__ppc64__)
939    /* __builtin_frame_address IS BROKEN IN BEAKER: RADAR #2340421 */
940    __asm__ volatile("mr %0, r1" : "=r" (frame));
941#endif
942    if(!INSTACK(frame) || !ISALIGNED(frame))
943        return;
944#if defined(__ppc__) || defined(__ppc64__)
945    /* back up the stack pointer up over the current stack frame */
946    next = *(void **)frame;
947    if(!INSTACK(next) || !ISALIGNED(next) || next <= frame)
948        return;
949    frame = next;
950#endif
951    while (skip--) {
952        next = *(void **)frame;
953        if(!INSTACK(next) || !ISALIGNED(next) || next <= frame)
954            return;
955        frame = next;
956    }
957    while (max--) {
958        buffer[*nb] = *(vm_address_t *)(((void **)frame) + FP_LINK_OFFSET);
959        (*nb)++;
960        next = *(void **)frame;
961        if(!INSTACK(next) || !ISALIGNED(next) || next <= frame)
962            return;
963        frame = next;
964    }
965}
966#endif
967
968void CBuilder::__CreateAssert(Value * const assertion, StringRef failureMessage) {
[5721]969    if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::EnableAsserts))) {
[5440]970        Module * const m = getModule();
[5493]971        if (LLVM_UNLIKELY(isa<ConstantInt>(assertion))) {
972            if (LLVM_UNLIKELY(cast<ConstantInt>(assertion)->isZero())) {
973                report_fatal_error(failureMessage);
974            } else {
975                return;
976            }
977        }
978        Type * const stackTy = TypeBuilder<uintptr_t, false>::get(getContext());
979        PointerType * const stackPtrTy = stackTy->getPointerTo();
980        PointerType * const int8PtrTy = getInt8PtrTy();
[5486]981        Function * function = m->getFunction("assert");
[5347]982        if (LLVM_UNLIKELY(function == nullptr)) {
983            auto ip = saveIP();
[5493]984            IntegerType * const int1Ty = getInt1Ty();
985            FunctionType * fty = FunctionType::get(getVoidTy(), { int1Ty, int8PtrTy, stackPtrTy, getInt32Ty() }, false);
[5486]986            function = Function::Create(fty, Function::PrivateLinkage, "assert", m);
[5347]987            function->setDoesNotThrow();
[5733]988#if LLVM_VERSION_INTEGER < LLVM_5_0_0
[5347]989            function->setDoesNotAlias(2);
[5733]990#endif
[5347]991            BasicBlock * const entry = BasicBlock::Create(getContext(), "", function);
992            BasicBlock * const failure = BasicBlock::Create(getContext(), "", function);
993            BasicBlock * const success = BasicBlock::Create(getContext(), "", function);
994            auto arg = function->arg_begin();
995            arg->setName("assertion");
[5486]996            Value * assertion = &*arg++;
[5347]997            arg->setName("msg");
998            Value * msg = &*arg++;
[5486]999            arg->setName("trace");
1000            Value * trace = &*arg++;
[5489]1001            arg->setName("depth");
1002            Value * depth = &*arg++;
[5347]1003            SetInsertPoint(entry);
[5486]1004            IRBuilder<>::CreateCondBr(assertion, success, failure);
1005            IRBuilder<>::SetInsertPoint(failure);
[5489]1006            IRBuilder<>::CreateCall(LinkFunction("__report_failure", __report_failure), { msg, trace, depth });
[5347]1007            CreateExit(-1);
[5486]1008            IRBuilder<>::CreateBr(success); // necessary to satisfy the LLVM verifier. this is never executed.
[5347]1009            SetInsertPoint(success);
[5486]1010            IRBuilder<>::CreateRetVoid();
[5347]1011            restoreIP(ip);
[5340]1012        }
[5493]1013
[5498]1014        SmallVector<unw_word_t, 64> stack;
[5493]1015        #if defined(HAS_MACH_VM_TYPES)
1016        for (;;) {
1017            unsigned int n;
1018            _thread_stack_pcs(reinterpret_cast<vm_address_t *>(stack.data()), stack.capacity(), &n, 1);
1019            if (LLVM_UNLIKELY(n < stack.capacity() || stack[n - 1] == 0)) {
1020                while (n >= 1 && stack[n - 1] == 0) {
1021                    n -= 1;
1022                }
1023                stack.set_size(n);
1024                break;
1025            }
1026            stack.reserve(n * 2);
[5486]1027        }
[5493]1028        #elif defined(HAS_LIBUNWIND)
[5486]1029        unw_context_t context;
1030        // Initialize cursor to current frame for local unwinding.
1031        unw_getcontext(&context);
[5489]1032        unw_cursor_t cursor;
[5486]1033        unw_init_local(&cursor, &context);
1034        // Unwind frames one by one, going up the frame stack.
1035        while (unw_step(&cursor) > 0) {
1036            unw_word_t pc;
1037            unw_get_reg(&cursor, UNW_REG_IP, &pc);
1038            if (pc == 0) {
1039                break;
1040            }
[5502]1041            stack.push_back(pc);
[5486]1042        }
[5489]1043        #elif defined(HAS_EXECINFO)
1044        for (;;) {
1045            const auto n = backtrace(reinterpret_cast<void **>(stack.data()), stack.capacity());
1046            if (LLVM_LIKELY(n < (int)stack.capacity())) {
1047                stack.set_size(n);
1048                break;
1049            }
1050            stack.reserve(n * 2);
1051        }
1052        #endif
[5493]1053        Value * trace = nullptr;
1054        ConstantInt * depth = nullptr;
1055        if (stack.empty()) {
1056            trace = ConstantPointerNull::get(stackPtrTy);
1057            depth = getInt32(0);
1058        } else {
1059            const auto n = stack.size() - 1;
1060            for (GlobalVariable & gv : m->getGlobalList()) {
1061                Type * const ty = gv.getValueType();
1062                if (ty->isArrayTy() && ty->getArrayElementType() == stackTy && ty->getArrayNumElements() == n) {
1063                    const ConstantDataArray * const array = cast<ConstantDataArray>(gv.getOperand(0));
1064                    bool found = true;
1065                    for (size_t i = 0; i < n; ++i) {
1066                        if (LLVM_LIKELY(array->getElementAsInteger(i) != stack[i + 1])) {
1067                            found = false;
1068                            break;
1069                        }
1070                    }
1071                    if (LLVM_UNLIKELY(found)) {
1072                        trace = &gv;
[5486]1073                        break;
1074                    }
1075                }
1076            }
[5493]1077            if (LLVM_LIKELY(trace == nullptr)) {
[5498]1078                Constant * const initializer = ConstantDataArray::get(getContext(), ArrayRef<unw_word_t>(stack.data() + 1, n));
[5493]1079                trace = new GlobalVariable(*m, initializer->getType(), true, GlobalVariable::InternalLinkage, initializer);
1080            }
1081            trace = CreatePointerCast(trace, stackPtrTy);
1082            depth = getInt32(n);
[5486]1083        }
[5493]1084        IRBuilder<>::CreateCall(function, {assertion, GetString(failureMessage), trace, depth});
[5755]1085    } else { // if assertions are not enabled, make it a compiler assumption.
1086        IRBuilder<>::CreateAssumption(assertion);
[5340]1087    }
1088}
1089
[5347]1090void CBuilder::CreateExit(const int exitCode) {
[5440]1091    Module * const m = getModule();
1092    Function * exit = m->getFunction("exit");
[5347]1093    if (LLVM_UNLIKELY(exit == nullptr)) {
[5353]1094        FunctionType * fty = FunctionType::get(getVoidTy(), {getInt32Ty()}, false);
[5440]1095        exit = Function::Create(fty, Function::ExternalLinkage, "exit", m);
[5347]1096        exit->setDoesNotReturn();
1097        exit->setDoesNotThrow();
1098    }
1099    CreateCall(exit, getInt32(exitCode));
1100}
1101
[5486]1102BasicBlock * CBuilder::CreateBasicBlock(std::string && name) {
[5440]1103    return BasicBlock::Create(getContext(), name, GetInsertBlock()->getParent());
1104}
1105
[5746]1106bool CBuilder::supportsIndirectBr() const {
1107    return !codegen::DebugOptionIsSet(codegen::DisableIndirectBranch);
1108}
1109
[5350]1110BranchInst * CBuilder::CreateLikelyCondBr(Value * Cond, BasicBlock * True, BasicBlock * False, const int probability) {
1111    MDBuilder mdb(getContext());
1112    if (probability < 0 || probability > 100) {
1113        report_fatal_error("branch weight probability must be in [0,100]");
1114    }
1115    return CreateCondBr(Cond, True, False, mdb.createBranchWeights(probability, 100 - probability));
1116}
1117
[5398]1118Value * CBuilder::CreatePopcount(Value * bits) {
[5440]1119    Value * ctpopFunc = Intrinsic::getDeclaration(getModule(), Intrinsic::ctpop, bits->getType());
[5398]1120    return CreateCall(ctpopFunc, bits);
1121}
1122
[5624]1123Value * CBuilder::CreateCountForwardZeroes(Value * value, const bool isZeroUndefined) {
[5755]1124    if (LLVM_UNLIKELY(isZeroUndefined && codegen::DebugOptionIsSet(codegen::EnableAsserts))) {
[5624]1125        CreateAssert(value, "CreateCountForwardZeroes: value cannot be zero!");
1126    }
[5440]1127    Value * cttzFunc = Intrinsic::getDeclaration(getModule(), Intrinsic::cttz, value->getType());
[5624]1128    return CreateCall(cttzFunc, {value, getInt1(isZeroUndefined)});
[5398]1129}
1130
[5624]1131Value * CBuilder::CreateCountReverseZeroes(Value * value, const bool isZeroUndefined) {
[5755]1132    if (LLVM_UNLIKELY(isZeroUndefined && codegen::DebugOptionIsSet(codegen::EnableAsserts))) {
[5624]1133        CreateAssert(value, "CreateCountReverseZeroes: value cannot be zero!");
1134    }
[5440]1135    Value * ctlzFunc = Intrinsic::getDeclaration(getModule(), Intrinsic::ctlz, value->getType());
[5624]1136    return CreateCall(ctlzFunc, {value, getInt1(isZeroUndefined)});
[5398]1137}
1138
[5427]1139Value * CBuilder::CreateResetLowestBit(Value * bits) {
1140    return CreateAnd(bits, CreateSub(bits, ConstantInt::get(bits->getType(), 1)));
1141}
1142
1143Value * CBuilder::CreateIsolateLowestBit(Value * bits) {
1144    return CreateAnd(bits, CreateNeg(bits));
1145}
1146
1147Value * CBuilder::CreateMaskToLowestBitInclusive(Value * bits) {
1148    return CreateXor(bits, CreateSub(bits, ConstantInt::get(bits->getType(), 1)));
1149}
1150
1151Value * CBuilder::CreateMaskToLowestBitExclusive(Value * bits) {
1152    return CreateAnd(CreateSub(bits, ConstantInt::get(bits->getType(), 1)), CreateNot(bits));
1153}
1154
[5486]1155Value * CBuilder::CreateExtractBitField(Value * bits, Value * start, Value * length) {
[5427]1156    Constant * One = ConstantInt::get(bits->getType(), 1);
1157    return CreateAnd(CreateLShr(bits, start), CreateSub(CreateShl(One, length), One));
1158}
1159
[5374]1160Value * CBuilder::CreateCeilLog2(Value * value) {
[5361]1161    IntegerType * ty = cast<IntegerType>(value->getType());
[5425]1162    Value * m = CreateCountReverseZeroes(CreateSub(value, ConstantInt::get(ty, 1)));
[5493]1163    return CreateSub(ConstantInt::get(m->getType(), ty->getBitWidth()), m);
[5361]1164}
1165
[5398]1166Value * CBuilder::GetString(StringRef Str) {
[5440]1167    Module * const m = getModule();
1168    Value * ptr = m->getGlobalVariable(Str, true);
[5398]1169    if (ptr == nullptr) {
1170        ptr = CreateGlobalString(Str, Str);
1171    }
1172    Value * zero = getInt32(0);
1173    return CreateInBoundsGEP(ptr, { zero, zero });
1174}
1175
[5424]1176Value * CBuilder::CreateReadCycleCounter() {
[5440]1177    Module * const m = getModule();
1178    Value * cycleCountFunc = Intrinsic::getDeclaration(m, Intrinsic::readcyclecounter);
[5424]1179    return CreateCall(cycleCountFunc, std::vector<Value *>({}));
1180}
1181
[5486]1182Function * CBuilder::LinkFunction(StringRef name, FunctionType * type, void * functionPtr) const {
[5425]1183    assert (mDriver);
[5464]1184    return mDriver->addLinkFunction(getModule(), name, type, functionPtr);
[5425]1185}
[5424]1186
[5755]1187LoadInst * CBuilder::CreateLoad(Value *Ptr, const char * Name) {
1188    if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::EnableAsserts))) {
1189        CHECK_ADDRESS(Ptr, ConstantExpr::getSizeOf(Ptr->getType()->getPointerElementType()), "CreateLoad");
[5486]1190    }
1191    return IRBuilder<>::CreateLoad(Ptr, Name);
1192}
1193
1194LoadInst * CBuilder::CreateLoad(Value * Ptr, const Twine & Name) {
[5755]1195    if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::EnableAsserts))) {
1196        CHECK_ADDRESS(Ptr, ConstantExpr::getSizeOf(Ptr->getType()->getPointerElementType()), "CreateLoad");
1197    }
[5486]1198    return IRBuilder<>::CreateLoad(Ptr, Name);
1199}
1200
[5755]1201LoadInst * CBuilder::CreateLoad(Type * Ty, Value *Ptr, const Twine & Name) {
1202    if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::EnableAsserts))) {
1203        CHECK_ADDRESS(Ptr, ConstantExpr::getSizeOf(Ty), "CreateLoad");
1204    }
[5486]1205    return IRBuilder<>::CreateLoad(Ty, Ptr, Name);
1206}
1207
[5755]1208LoadInst * CBuilder::CreateLoad(Value * Ptr, bool isVolatile, const Twine & Name) {
1209    if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::EnableAsserts))) {
1210        CHECK_ADDRESS(Ptr, ConstantExpr::getSizeOf(Ptr->getType()->getPointerElementType()), "CreateLoad");
1211    }
[5486]1212    return IRBuilder<>::CreateLoad(Ptr, isVolatile, Name);
1213}
1214
1215StoreInst * CBuilder::CreateStore(Value * Val, Value * Ptr, bool isVolatile) {
[5755]1216    assert (Val->getType() == Ptr->getType()->getPointerElementType());
1217    if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::EnableAsserts))) {
1218        CHECK_ADDRESS(Ptr, ConstantExpr::getSizeOf(Val->getType()), "CreateStore");
1219    }
[5486]1220    return IRBuilder<>::CreateStore(Val, Ptr, isVolatile);
1221}
1222
[5493]1223inline bool CBuilder::hasAddressSanitizer() const {
[5755]1224    return mDriver && mDriver->hasExternalFunction("__asan_region_is_poisoned");
[5493]1225}
1226
1227LoadInst * CBuilder::CreateAlignedLoad(Value * Ptr, unsigned Align, const char * Name) {
[5755]1228    if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::EnableAsserts))) {
[5493]1229        DataLayout DL(getModule());
1230        IntegerType * const intPtrTy = cast<IntegerType>(DL.getIntPtrType(Ptr->getType()));
1231        Value * alignmentOffset = CreateURem(CreatePtrToInt(Ptr, intPtrTy), ConstantInt::get(intPtrTy, Align));
1232        CreateAssertZero(alignmentOffset, "CreateAlignedLoad: pointer is misaligned");
1233    }
1234    LoadInst * LI = CreateLoad(Ptr, Name);
1235    LI->setAlignment(Align);
1236    return LI;
1237}
1238
1239LoadInst * CBuilder::CreateAlignedLoad(Value * Ptr, unsigned Align, const Twine & Name) {
[5755]1240    if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::EnableAsserts))) {
[5493]1241        DataLayout DL(getModule());
1242        IntegerType * const intPtrTy = cast<IntegerType>(DL.getIntPtrType(Ptr->getType()));
1243        Value * alignmentOffset = CreateURem(CreatePtrToInt(Ptr, intPtrTy), ConstantInt::get(intPtrTy, Align));
1244        CreateAssertZero(alignmentOffset, "CreateAlignedLoad: pointer is misaligned");
1245    }
1246    LoadInst * LI = CreateLoad(Ptr, Name);
1247    LI->setAlignment(Align);
1248    return LI;
1249}
1250
1251LoadInst * CBuilder::CreateAlignedLoad(Value * Ptr, unsigned Align, bool isVolatile, const Twine & Name) {
[5755]1252    if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::EnableAsserts))) {
[5493]1253        DataLayout DL(getModule());
1254        IntegerType * const intPtrTy = cast<IntegerType>(DL.getIntPtrType(Ptr->getType()));
1255        Value * alignmentOffset = CreateURem(CreatePtrToInt(Ptr, intPtrTy), ConstantInt::get(intPtrTy, Align));
1256        CreateAssertZero(alignmentOffset, "CreateAlignedLoad: pointer is misaligned");
1257    }
1258    LoadInst * LI = CreateLoad(Ptr, isVolatile, Name);
1259    LI->setAlignment(Align);
1260    return LI;
1261}
1262
1263StoreInst * CBuilder::CreateAlignedStore(Value * Val, Value * Ptr, unsigned Align, bool isVolatile) {
[5755]1264    if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::EnableAsserts))) {
[5493]1265        DataLayout DL(getModule());
1266        IntegerType * const intPtrTy = cast<IntegerType>(DL.getIntPtrType(Ptr->getType()));
1267        Value * alignmentOffset = CreateURem(CreatePtrToInt(Ptr, intPtrTy), ConstantInt::get(intPtrTy, Align));
1268        CreateAssertZero(alignmentOffset, "CreateAlignedStore: pointer is misaligned");
1269    }
1270    StoreInst *SI = CreateStore(Val, Ptr, isVolatile);
1271    SI->setAlignment(Align);
1272    return SI;
1273}
1274
[5630]1275CallInst * CBuilder::CreateMemMove(Value * Dst, Value * Src, Value *Size, unsigned Align, bool isVolatile,
1276                                   MDNode *TBAATag, MDNode *ScopeTag, MDNode *NoAliasTag) {
[5755]1277    if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::EnableAsserts))) {
1278        CHECK_ADDRESS(Src, Size, "CreateMemMove: Src");
1279        CHECK_ADDRESS(Dst, Size, "CreateMemMove: Dst");
[5630]1280        // If the call to this intrinisic has an alignment value that is not 0 or 1, then the caller
1281        // guarantees that both the source and destination pointers are aligned to that boundary.
[5622]1282        if (Align > 1) {
[5755]1283            DataLayout DL(getModule());
1284            IntegerType * const intPtrTy = DL.getIntPtrType(getContext());
1285            Value * intSrc = CreatePtrToInt(Src, intPtrTy);
1286            Value * intDst = CreatePtrToInt(Dst, intPtrTy);
[5622]1287            ConstantInt * align = ConstantInt::get(intPtrTy, Align);
[5755]1288            CreateAssertZero(CreateURem(intSrc, align), "CreateMemMove: Src pointer is misaligned");
[5622]1289            CreateAssertZero(CreateURem(intDst, align), "CreateMemMove: Dst pointer is misaligned");
[5755]1290
[5622]1291        }
1292    }
1293    return IRBuilder<>::CreateMemMove(Dst, Src, Size, Align, isVolatile, TBAATag, ScopeTag, NoAliasTag);
1294}
1295
[5633]1296CallInst * CBuilder::CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align, bool isVolatile,
1297                                  MDNode *TBAATag, MDNode *TBAAStructTag, MDNode *ScopeTag, MDNode *NoAliasTag) {
[5755]1298    if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::EnableAsserts))) {
1299        CHECK_ADDRESS(Src, Size, "CreateMemCpy: Src");
1300        CHECK_ADDRESS(Dst, Size, "CreateMemCpy: Dst");
[5630]1301        DataLayout DL(getModule());
1302        IntegerType * const intPtrTy = DL.getIntPtrType(getContext());
[5755]1303        Value * intSrc = CreatePtrToInt(Src, intPtrTy);
[5630]1304        Value * intDst = CreatePtrToInt(Dst, intPtrTy);
1305        // If the call to this intrinisic has an alignment value that is not 0 or 1, then the caller
1306        // guarantees that both the source and destination pointers are aligned to that boundary.
1307        if (Align > 1) {
1308            ConstantInt * align = ConstantInt::get(intPtrTy, Align);
[5755]1309            CreateAssertZero(CreateURem(intSrc, align), "CreateMemCpy: Src pointer is misaligned");
[5630]1310            CreateAssertZero(CreateURem(intDst, align), "CreateMemCpy: Dst pointer is misaligned");
1311        }
[5755]1312        Value * intSize = CreateZExtOrTrunc(Size, intPtrTy);
[5630]1313        Value * nonOverlapping = CreateOr(CreateICmpULT(CreateAdd(intSrc, intSize), intDst),
1314                                          CreateICmpULT(CreateAdd(intDst, intSize), intSrc));
1315        CreateAssert(nonOverlapping, "CreateMemCpy: overlapping ranges is undefined");
1316    }
1317    return IRBuilder<>::CreateMemCpy(Dst, Src, Size, Align, isVolatile, TBAATag, TBAAStructTag, ScopeTag, NoAliasTag);
1318}
1319
[5755]1320llvm::CallInst * CBuilder::CreateMemSet(llvm::Value * Ptr, llvm::Value * Val, llvm::Value * Size, unsigned Align,
1321                       bool isVolatile, llvm::MDNode * TBAATag, llvm::MDNode * ScopeTag, llvm::MDNode * NoAliasTag) {
1322    if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::EnableAsserts))) {
1323        CHECK_ADDRESS(Ptr, Size, "CreateMemSet");
1324    }
1325    return IRBuilder<>::CreateMemSet(Ptr, Val, Size, Align, isVolatile, TBAATag, ScopeTag, NoAliasTag);
1326}
1327
[5489]1328CBuilder::CBuilder(LLVMContext & C)
[5436]1329: IRBuilder<>(C)
[5435]1330, mCacheLineAlignment(64)
[5489]1331, mSizeType(TypeBuilder<size_t, false>::get(C))
[5350]1332, mFILEtype(nullptr)
[5425]1333, mDriver(nullptr) {
1334
[5260]1335}
Note: See TracBrowser for help on using the repository browser.