Ignore:
Timestamp:
Apr 18, 2017, 12:51:26 PM (2 years ago)
Author:
nmedfort
Message:

Potential bug fix for 32-bit. Modified MRemap to check for Linux OS support. Added MMapAdvise to CBuilder.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/IR_Gen/CBuilder.cpp

    r5403 r5411  
    1717#include <sys/mman.h>
    1818#include <errno.h>
     19#include <llvm/ADT/Triple.h>
    1920
    2021using namespace llvm;
     
    8081void CBuilder::CallPrintInt(const std::string & name, Value * const value) {
    8182    Constant * printRegister = mMod->getFunction("PrintInt");
     83    IntegerType * int64Ty = getInt64Ty();
    8284    if (LLVM_UNLIKELY(printRegister == nullptr)) {
    83         FunctionType *FT = FunctionType::get(getVoidTy(), { PointerType::get(getInt8Ty(), 0), getSizeTy() }, false);
     85        FunctionType *FT = FunctionType::get(getVoidTy(), { getInt8PtrTy(), int64Ty }, false);
    8486        Function * function = Function::Create(FT, Function::InternalLinkage, "PrintInt", mMod);
    8587        auto arg = function->arg_begin();
     
    102104    Value * num = nullptr;
    103105    if (value->getType()->isPointerTy()) {
    104         num = CreatePtrToInt(value, getSizeTy());
     106        num = CreatePtrToInt(value, int64Ty);
    105107    } else {
    106         num = CreateZExtOrBitCast(value, getSizeTy());
     108        num = CreateZExtOrBitCast(value, int64Ty);
    107109    }
    108110    assert (num->getType()->isIntegerTy());
     
    169171}
    170172
    171 #ifdef __APPLE__
    172 #define MAP_ANONYMOUS MAP_ANON
    173 #endif
    174 
    175173Value * CBuilder::CreateAnonymousMMap(Value * size) {
    176174    PointerType * const voidPtrTy = getVoidPtrTy();
     
    179177    size = CreateZExtOrTrunc(size, sizeTy);
    180178    ConstantInt * const prot =  ConstantInt::get(intTy, PROT_READ | PROT_WRITE);
    181     ConstantInt * const flags =  ConstantInt::get(intTy, MAP_PRIVATE | MAP_ANONYMOUS);
     179    ConstantInt * const flags =  ConstantInt::get(intTy, MAP_PRIVATE | MAP_ANON);
    182180    ConstantInt * const fd =  ConstantInt::get(intTy, -1);
    183181    Constant * const offset = ConstantInt::get(sizeTy, 0);
    184     return CreateMMap(Constant::getNullValue(voidPtrTy), size, prot, flags, fd, offset);
     182    return CreateMMap(ConstantPointerNull::getNullValue(voidPtrTy), size, prot, flags, fd, offset);
    185183}
    186184
     
    193191    ConstantInt * const flags =  ConstantInt::get(intTy, MAP_PRIVATE);
    194192    Constant * const offset = ConstantInt::get(sizeTy, 0);
    195     return CreateMMap(Constant::getNullValue(voidPtrTy), size, prot, flags, fd, offset);
     193    return CreateMMap(ConstantPointerNull::getNullValue(voidPtrTy), size, prot, flags, fd, offset);
    196194}
    197195
     
    212210}
    213211
     212/*
     213    MADV_NORMAL
     214        No special treatment. This is the default.
     215    MADV_RANDOM
     216        Expect page references in random order. (Hence, read ahead may be less useful than normally.)
     217    MADV_SEQUENTIAL
     218        Expect page references in sequential order. (Hence, pages in the given range can be aggressively read ahead, and may be freed
     219        soon after they are accessed.)
     220    MADV_WILLNEED
     221        Expect access in the near future. (Hence, it might be a good idea to read some pages ahead.)
     222    MADV_DONTNEED
     223        Do not expect access in the near future. (For the time being, the application is finished with the given range, so the kernel
     224        can free resources associated with it.) Subsequent accesses of pages in this range will succeed, but will result either in
     225        reloading of the memory contents from the underlying mapped file (see mmap(2)) or zero-fill-on-demand pages for mappings
     226        without an underlying file.
     227*/
     228
     229Value * CBuilder::CreateMMapAdvise(Value * addr, Value * length, std::initializer_list<MADV> advice) {
     230    Triple T(mMod->getTargetTriple());
     231    Value * result = nullptr;
     232    if (T.isOSLinux()) {
     233        DataLayout DL(mMod);
     234        IntegerType * const intTy = getIntPtrTy(DL);
     235        IntegerType * const sizeTy = getSizeTy();
     236        PointerType * const voidPtrTy = getVoidPtrTy();
     237        Function * MAdviseFunc = mMod->getFunction("madvise");
     238        if (LLVM_UNLIKELY(MAdviseFunc == nullptr)) {
     239            FunctionType * fty = FunctionType::get(intTy, {voidPtrTy, sizeTy, intTy}, false);
     240            MAdviseFunc = Function::Create(fty, Function::ExternalLinkage, "madvise", mMod);
     241        }
     242        addr = CreatePointerCast(addr, voidPtrTy);
     243        length = CreateZExtOrTrunc(length, sizeTy);
     244        int adviceFlags = 0;
     245        for (const MADV adv : advice) {
     246            switch (adv) {
     247                case MADV::NORMAL: adviceFlags |= MADV_NORMAL; break;
     248                case MADV::RANDOM: adviceFlags |= MADV_RANDOM; break;
     249                case MADV::SEQUENTIAL: adviceFlags |= MADV_SEQUENTIAL; break;
     250                case MADV::DONTNEED: adviceFlags |= MADV_DONTNEED; break;
     251                case MADV::WILLNEED: adviceFlags |= MADV_WILLNEED; break;
     252//                case MADV::REMOVE: adviceFlags |= MADV_REMOVE; break;
     253//                case MADV::DONTFORK: adviceFlags |= MADV_DONTFORK; break;
     254//                case MADV::DOFORK: adviceFlags |= MADV_DOFORK; break;
     255//                case MADV::HWPOISON: adviceFlags |= MADV_HWPOISON; break;
     256//                case MADV::MERGEABLE: adviceFlags |= MADV_MERGEABLE; break;
     257//                case MADV::UNMERGEABLE: adviceFlags |= MADV_UNMERGEABLE; break;
     258//                case MADV::HUGEPAGE: adviceFlags |= MADV_HUGEPAGE; break;
     259//                case MADV::NOHUGEPAGE: adviceFlags |= MADV_NOHUGEPAGE; break;
     260//                case MADV::DONTDUMP: adviceFlags |= MADV_DONTDUMP; break;
     261//                case MADV::DODUMP: adviceFlags |= MADV_DODUMP; break;
     262            }
     263        }
     264        result = CreateCall(MAdviseFunc, {addr, length, ConstantInt::get(intTy, adviceFlags)});
     265        if (codegen::EnableAsserts) {
     266            CreateAssert(CreateICmpEQ(result, ConstantInt::getNullValue(result->getType())), "CreateMMapAdvise: failed");
     267        }
     268    }
     269    return result;
     270}
     271
    214272Value * CBuilder::CheckMMapSuccess(Value * const addr) {
    215273    DataLayout DL(mMod);
    216     IntegerType * const ty = getIntPtrTy(DL);
    217     return CreateICmpNE(CreatePtrToInt(addr, ty), ConstantInt::getAllOnesValue(ty)); // MAP_FAILED = -1
    218 }
    219 
    220 #ifndef __APPLE__
    221 Value * CBuilder::CreateMRemap(Value * addr, Value * oldSize, Value * newSize, const bool mayMove) {
    222     DataLayout DL(mMod);
    223     PointerType * const voidPtrTy = getVoidPtrTy();
    224274    IntegerType * const intTy = getIntPtrTy(DL);
    225     IntegerType * const sizeTy = getSizeTy();
    226     Function * fMRemap = mMod->getFunction("mremap");
    227     if (LLVM_UNLIKELY(fMRemap == nullptr)) {
    228         FunctionType * fty = FunctionType::get(voidPtrTy, {voidPtrTy, sizeTy, sizeTy, intTy}, false);
    229         fMRemap = Function::Create(fty, Function::ExternalLinkage, "mremap", mMod);
    230     }   
    231     addr = CreatePointerCast(addr, voidPtrTy);
    232     oldSize = CreateZExtOrTrunc(oldSize, sizeTy);
    233     newSize = CreateZExtOrTrunc(newSize, sizeTy);
    234     ConstantInt * const flags = ConstantInt::get(intTy, mayMove ? MREMAP_MAYMOVE : 0);
    235     Value * ptr = CreateCall(fMRemap, {addr, oldSize, newSize, flags});
    236     if (codegen::EnableAsserts) {
    237         CreateAssert(CheckMMapSuccess(ptr), "CreateMRemap: mremap failed to allocate memory");
     275    return CreateICmpNE(CreatePtrToInt(addr, intTy), ConstantInt::getAllOnesValue(intTy)); // MAP_FAILED = -1
     276}
     277
     278Value * CBuilder::CreateMRemap(Value * addr, Value * oldSize, Value * newSize) {
     279    Triple T(mMod->getTargetTriple());
     280    Value * ptr = nullptr;
     281    if (T.isOSLinux()) {
     282        DataLayout DL(mMod);
     283        PointerType * const voidPtrTy = getVoidPtrTy();
     284        IntegerType * const sizeTy = getSizeTy();
     285        IntegerType * const intTy = getIntPtrTy(DL);
     286        Function * fMRemap = mMod->getFunction("mremap");
     287        if (LLVM_UNLIKELY(fMRemap == nullptr)) {
     288            FunctionType * fty = FunctionType::get(voidPtrTy, {voidPtrTy, sizeTy, sizeTy, intTy}, false);
     289            fMRemap = Function::Create(fty, Function::ExternalLinkage, "mremap", mMod);
     290        }
     291        addr = CreatePointerCast(addr, voidPtrTy);
     292        oldSize = CreateZExtOrTrunc(oldSize, sizeTy);
     293        newSize = CreateZExtOrTrunc(newSize, sizeTy);
     294        ConstantInt * const flags = ConstantInt::get(intTy, MREMAP_MAYMOVE);
     295        ptr = CreateCall(fMRemap, {addr, oldSize, newSize, flags});
     296        if (codegen::EnableAsserts) {
     297            CreateAssert(CheckMMapSuccess(ptr), "CreateMRemap: mremap failed to allocate memory");
     298        }
     299    } else { // no OS mremap support
     300        ptr = CreateAnonymousMMap(newSize);
     301        CreateMemCpy(ptr, addr, oldSize, getpagesize());
     302        CreateMUnmap(addr, oldSize);
    238303    }
    239304    return ptr;
    240305}
    241 #endif
    242306
    243307Value * CBuilder::CreateMUnmap(Value * addr, Value * size) {
    244     DataLayout DL(mMod);
    245308    IntegerType * const sizeTy = getSizeTy();
    246309    PointerType * const voidPtrTy = getVoidPtrTy();
    247310    Function * fMUnmap = mMod->getFunction("munmap");
    248311    if (LLVM_UNLIKELY(fMUnmap == nullptr)) {
     312        DataLayout DL(mMod);
    249313        IntegerType * const intTy = getIntPtrTy(DL);
    250314        FunctionType * fty = FunctionType::get(intTy, {voidPtrTy, sizeTy}, false);
    251315        fMUnmap = Function::Create(fty, Function::ExternalLinkage, "munmap", mMod);
    252316    }
     317    if (codegen::EnableAsserts) {
     318        Value * const pageOffset = CreateURem(CreatePtrToInt(addr, sizeTy), getSize(getpagesize()));
     319        CreateAssert(CreateICmpEQ(pageOffset, getSize(0)), "CreateMUnmap: addr must be a multiple of the page size");
     320    }
    253321    addr = CreatePointerCast(addr, voidPtrTy);
    254322    size = CreateZExtOrTrunc(size, sizeTy);
    255     return CreateCall(fMUnmap, {addr, size});
     323    CallInst * result = CreateCall(fMUnmap, {addr, size});
     324    if (codegen::EnableAsserts) {
     325        CreateAssert(CreateICmpEQ(result, ConstantInt::getNullValue(result->getType())), "CreateMUnmap: failed");
     326    }
     327    return result;
    256328}
    257329
     
    327399
    328400PointerType * CBuilder::getVoidPtrTy() const {
    329     return TypeBuilder<void *, false>::get(getContext());
     401    return TypeBuilder<void *, true>::get(getContext());
    330402}
    331403
     
    364436Value * CBuilder::CreateFReadCall(Value * ptr, Value * size, Value * nitems, Value * stream) {
    365437    Function * fReadFunc = mMod->getFunction("fread");
     438    PointerType * const voidPtrTy = getVoidPtrTy();
    366439    if (fReadFunc == nullptr) {
    367         FunctionType * fty = FunctionType::get(getSizeTy(), {getVoidPtrTy(), getSizeTy(), getSizeTy(), getFILEptrTy()}, false);
     440        IntegerType * const sizeTy = getSizeTy();
     441        FunctionType * fty = FunctionType::get(sizeTy, {voidPtrTy, sizeTy, sizeTy, getFILEptrTy()}, false);
    368442        fReadFunc = Function::Create(fty, Function::ExternalLinkage, "fread", mMod);
    369443        fReadFunc->setCallingConv(CallingConv::C);
    370444    }
     445    ptr = CreatePointerCast(ptr, voidPtrTy);
    371446    return CreateCall(fReadFunc, {ptr, size, nitems, stream});
    372447}
     
    374449Value * CBuilder::CreateFWriteCall(Value * ptr, Value * size, Value * nitems, Value * stream) {
    375450    Function * fWriteFunc = mMod->getFunction("fwrite");
     451    PointerType * const voidPtrTy = getVoidPtrTy();
    376452    if (fWriteFunc == nullptr) {
    377         FunctionType * fty = FunctionType::get(getSizeTy(), {getVoidPtrTy(), getSizeTy(), getSizeTy(), getFILEptrTy()}, false);
     453        IntegerType * const sizeTy = getSizeTy();
     454        FunctionType * fty = FunctionType::get(sizeTy, {voidPtrTy, sizeTy, sizeTy, getFILEptrTy()}, false);
    378455        fWriteFunc = Function::Create(fty, Function::ExternalLinkage, "fwrite", mMod);
    379456        fWriteFunc->setCallingConv(CallingConv::C);
    380457    }
     458    ptr = CreatePointerCast(ptr, voidPtrTy);
    381459    return CreateCall(fWriteFunc, {ptr, size, nitems, stream});
    382460}
Note: See TracChangeset for help on using the changeset viewer.