Ignore:
Timestamp:
Feb 25, 2017, 12:50:29 PM (2 years ago)
Author:
nmedfort
Message:

Added enable asserts (-ea) command line flag + restructured BlockOrientedKernels? to allow for inlined code.

Location:
icGREP/icgrep-devel/icgrep/IR_Gen
Files:
2 edited

Legend:

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

    r5340 r5347  
    1111#include <llvm/IR/TypeBuilder.h>
    1212#include <fcntl.h>
     13#include <toolchain.h>
    1314
    1415using namespace llvm;
     
    2425    return CreateCall(openFn, {filename, oflag, mode});
    2526}
    26 
    27 
    2827
    2928// ssize_t write(int fildes, const void *buf, size_t nbyte);
     
    142141    ci->setTailCall();
    143142    ci->setCallingConv(malloc->getCallingConv());
    144     return CreateBitOrPointerCast(ci, type->getPointerTo());
     143    Value * ptr = CreateBitOrPointerCast(ci, type->getPointerTo());
     144    CreateAssert(ptr, "FATAL ERROR: out of memory");
     145    return ptr;
    145146}
    146147
     
    363364}
    364365
    365 void CBuilder::CreateAssert(llvm::Value * const toCheck, llvm::StringRef failureMessage) {
    366     #ifndef NDEBUG
    367     Module * m = getModule();
    368     Function * assertion = m->getFunction("__assert");
    369     if (LLVM_UNLIKELY(assertion == nullptr)) {
    370         auto ip = saveIP();
    371         assertion = cast<Function>(m->getOrInsertFunction("__assert", getVoidTy(), getInt1Ty(), getInt8PtrTy(), getSizeTy(), nullptr));
    372         BasicBlock * entry = BasicBlock::Create(getContext(), "", assertion);
    373         BasicBlock * failure = BasicBlock::Create(getContext(), "", assertion);
    374         BasicBlock * success = BasicBlock::Create(getContext(), "", assertion);
    375         auto arg = assertion->arg_begin();
    376         arg->setName("e");
    377         Value * e = &*arg++;
    378         arg->setName("msg");
    379         Value * msg = &*arg++;
    380         arg->setName("sz");
    381         Value * sz = &*arg;
    382         SetInsertPoint(entry);
    383         CreateCondBr(e, failure, success);
    384         SetInsertPoint(failure);
    385         CreateWriteCall(getInt32(2), msg, sz);
    386         Function * exit = m->getFunction("exit");
    387         if (LLVM_UNLIKELY(exit == nullptr)) {
    388             exit = cast<Function>(m->getOrInsertFunction("exit", getVoidTy(), getInt32Ty(), nullptr));
    389             exit->setDoesNotReturn();
    390             exit->setDoesNotThrow();
    391         }
    392         CreateCall(exit, getInt32(-1));
    393         CreateBr(success); // we're forced to have this to satisfy the LLVM verifier. this is not actually executed.
    394         SetInsertPoint(success);
    395         CreateRetVoid();
    396         restoreIP(ip);
    397     }
    398     CreateCall(assertion, {CreateICmpEQ(toCheck, Constant::getNullValue(toCheck->getType())), CreateGlobalStringPtr(failureMessage), getSize(failureMessage.size())});
    399     #endif
     366void CBuilder::CreateAssert(llvm::Value * const assertion, llvm::StringRef failureMessage) {
     367    if (codegen::EnableAsserts) {
     368        Module * const m = getModule();
     369        Function * function = m->getFunction("__assert");
     370        if (LLVM_UNLIKELY(function == nullptr)) {
     371            auto ip = saveIP();
     372            function = cast<Function>(m->getOrInsertFunction("__assert", getVoidTy(), getInt1Ty(), getInt8PtrTy(), getSizeTy(), nullptr));
     373            function->setDoesNotThrow();
     374            function->setDoesNotAlias(2);
     375            BasicBlock * const entry = BasicBlock::Create(getContext(), "", function);
     376            BasicBlock * const failure = BasicBlock::Create(getContext(), "", function);
     377            BasicBlock * const success = BasicBlock::Create(getContext(), "", function);
     378            auto arg = function->arg_begin();
     379            arg->setName("assertion");
     380            Value * e = &*arg++;
     381            arg->setName("msg");
     382            Value * msg = &*arg++;
     383            arg->setName("sz");
     384            Value * sz = &*arg;
     385            SetInsertPoint(entry);
     386            CreateCondBr(e, failure, success);
     387            SetInsertPoint(failure);
     388            Value * len = CreateAdd(sz, getSize(21));
     389            ConstantInt * _11 = getSize(11);
     390            Value * bytes = CreateMalloc(getInt8Ty(), len);
     391            CreateMemCpy(bytes, CreateGlobalStringPtr("Assertion `"), _11, 1);
     392            CreateMemCpy(CreateGEP(bytes, _11), msg, sz, 1);
     393            CreateMemCpy(CreateGEP(bytes, CreateAdd(sz, _11)), CreateGlobalStringPtr("' failed.\n"), getSize(10), 1);
     394            CreateWriteCall(getInt32(2), bytes, len);
     395            CreateExit(-1);
     396            CreateBr(success); // necessary to satisfy the LLVM verifier. this is not actually executed.
     397            SetInsertPoint(success);
     398            CreateRetVoid();
     399            restoreIP(ip);
     400        }
     401        CreateCall(function, {CreateICmpEQ(assertion, Constant::getNullValue(assertion->getType())), CreateGlobalStringPtr(failureMessage), getSize(failureMessage.size())});
     402    }
     403}
     404
     405void CBuilder::CreateExit(const int exitCode) {
     406    Module * const m = getModule();
     407    Function * exit = m->getFunction("exit");
     408    if (LLVM_UNLIKELY(exit == nullptr)) {
     409        exit = cast<Function>(m->getOrInsertFunction("exit", getVoidTy(), getInt32Ty(), nullptr));
     410        exit->setDoesNotReturn();
     411        exit->setDoesNotThrow();
     412    }
     413    CreateCall(exit, getInt32(exitCode));
    400414}
    401415
  • icGREP/icgrep-devel/icgrep/IR_Gen/CBuilder.h

    r5340 r5347  
    109109    virtual llvm::StoreInst *  CreateAtomicStoreRelease(llvm::Value * val, llvm::Value * ptr);
    110110   
    111     // Warning! this class must be compiled in debug mode or the check will be ignored.
    112     void CreateAssert(llvm::Value * toCheck, llvm::StringRef failureMessage);
     111    void CreateAssert(llvm::Value * assertion, llvm::StringRef failureMessage);
     112
     113    void CreateExit(const int exitCode);
    113114
    114115protected:
Note: See TracChangeset for help on using the changeset viewer.