Ignore:
Timestamp:
Jun 1, 2017, 1:00:08 PM (2 years ago)
Author:
nmedfort
Message:

Bug fix for memory check and issues found parsing internal 'files'. Added backtrace option from execinfo.h

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

Legend:

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

    r5486 r5489  
    2424#include <sanitizer/asan_interface.h>
    2525#endif
    26 #ifdef HAVE_LIBUNWIND
     26#ifdef HAS_LIBUNWIND
    2727#define UNW_LOCAL_ONLY
    2828#include <libunwind.h>
     29using unw_word_t = unw_word_t;
     30#elif HAS_EXECINFO
     31#include <execinfo.h>
     32#include <boost/integer.hpp>
     33using unw_word_t = boost::uint_t<sizeof(void *) * CHAR_BIT>::exact;
    2934#else
    3035using unw_word_t = uint64_t;
     
    3237
    3338using namespace llvm;
    34 
    35 void __report_failure(const char * msg, const unw_word_t * trace) {
    36     raw_fd_ostream out(STDERR_FILENO, false);
    37     #ifdef HAVE_LIBUNWIND
    38     if (trace) {
    39         out.changeColor(raw_fd_ostream::WHITE, true);
    40         out << "Compilation Stacktrace:\n";
    41         out.resetColor();
    42         while (*trace) {
    43             const auto pc = *trace++;
    44             out << format_hex(pc, 16) << "   ";
    45             const auto len = codegen::ProgramName.length() + 32;
    46             char cmd[len];
    47             snprintf(cmd, len,"addr2line -fpCe %s %p", codegen::ProgramName.data(), reinterpret_cast<void *>(pc));
    48             FILE * f = popen(cmd, "r");
    49             if (f) {
    50                 char buffer[1024] = {0};
    51                 while(fgets(buffer, sizeof(buffer), f)) {
    52                     out << buffer;
    53                 }
    54                 pclose(f);
    55             }
    56             ++trace;
    57         }
    58     }
    59     #endif
    60     out.changeColor(raw_fd_ostream::WHITE, true);
    61     out << "Assertion `" << msg << "' failed.\n";
    62     out.resetColor();
    63     out.flush();
    64 }
    6539
    6640Value * CBuilder::CreateOpenCall(Value * filename, Value * oflag, Value * mode) {
     
    213187        IRBuilder<> builder(entry);
    214188        std::vector<Value *> args;
    215         args.push_back(getInt32(2));    // fd 2 (stderr)
     189        args.push_back(getInt32(STDERR_FILENO));
    216190        args.push_back(GetString(out.c_str()));
    217191        Value * const name = &*(arg++);
     
    247221        IRBuilder<> builder(entry);
    248222        std::vector<Value *> args;
    249         args.push_back(getInt32(2));    // fd 2 (stderr)
    250         args.push_back(GetString(out.c_str()));
     223        args.push_back(getInt32(STDERR_FILENO));
     224        args.push_back(GetString(out));
    251225        Value * const msg = &*(arg++);
    252226        msg->setName("msg");
     
    667641}
    668642
     643void __report_failure(const char * msg, const unw_word_t * trace, const uint32_t n) {
     644    raw_fd_ostream out(STDERR_FILENO, false);
     645    #if defined(HAS_LIBUNWIND) || defined(HAS_EXECINFO)
     646    if (trace) {
     647        SmallVector<char, 4096> tmp;
     648        raw_svector_ostream trace_string(tmp);
     649        for (uint32_t i = 0; i < n; ++i) {
     650            const auto pc = trace[i];
     651            trace_string << format_hex(pc, 16) << "   ";
     652            const auto len = codegen::ProgramName.length() + 32;
     653            char cmd[len];
     654            snprintf(cmd, len,"addr2line -fpCe %s %p", codegen::ProgramName.data(), reinterpret_cast<void *>(pc));
     655            FILE * f = popen(cmd, "r");
     656            if (f) {
     657                char buffer[1024] = {0};
     658                while(fgets(buffer, sizeof(buffer), f)) {
     659                    trace_string << buffer;
     660                }
     661                pclose(f);
     662            }
     663        }
     664        out.changeColor(raw_fd_ostream::WHITE, true);
     665        out << "Compilation Stacktrace:\n";
     666        out.resetColor();
     667        out << trace_string.str();
     668    }
     669    #endif
     670    out.changeColor(raw_fd_ostream::WHITE, true);
     671    out << "Assertion `" << msg << "' failed.\n";
     672    out.resetColor();
     673    out.flush();
     674}
     675
    669676void CBuilder::CreateAssert(Value * assertion, StringRef failureMessage) {
    670677    if (LLVM_UNLIKELY(codegen::EnableAsserts)) {
     
    677684            IntegerType * const unwWordTy = TypeBuilder<unw_word_t, false>::get(getContext());
    678685            PointerType * const unwWordPtrTy = unwWordTy->getPointerTo();
    679             FunctionType * fty = FunctionType::get(getVoidTy(), { int1Ty, int8PtrTy, unwWordPtrTy }, false);
     686            FunctionType * fty = FunctionType::get(getVoidTy(), { int1Ty, int8PtrTy, unwWordPtrTy, getInt32Ty() }, false);
    680687            function = Function::Create(fty, Function::PrivateLinkage, "assert", m);
    681688            function->setDoesNotThrow();
     
    691698            arg->setName("trace");
    692699            Value * trace = &*arg++;
     700            arg->setName("depth");
     701            Value * depth = &*arg++;
    693702            SetInsertPoint(entry);
    694703            IRBuilder<>::CreateCondBr(assertion, success, failure);
    695704            IRBuilder<>::SetInsertPoint(failure);
    696             IRBuilder<>::CreateCall(LinkFunction("__report_failure", __report_failure), { msg, trace });
     705            IRBuilder<>::CreateCall(LinkFunction("__report_failure", __report_failure), { msg, trace, depth });
    697706            CreateExit(-1);
    698707            IRBuilder<>::CreateBr(success); // necessary to satisfy the LLVM verifier. this is never executed.
     
    704713            assertion = CreateICmpNE(assertion, Constant::getNullValue(assertion->getType()));
    705714        }
    706         IntegerType * const unwWordTy = TypeBuilder<unw_word_t, false>::get(getContext());
    707         PointerType * const unwWordPtrTy = unwWordTy->getPointerTo();
    708         #ifdef HAVE_LIBUNWIND
    709         std::vector<unw_word_t> stack;
     715        SmallVector<unw_word_t, 64> stack;
     716        #ifdef HAS_LIBUNWIND
    710717        unw_context_t context;
    711         unw_cursor_t cursor;
    712718        // Initialize cursor to current frame for local unwinding.
    713719        unw_getcontext(&context);
     720        unw_cursor_t cursor;
    714721        unw_init_local(&cursor, &context);
    715722        // Unwind frames one by one, going up the frame stack.
    716         stack.reserve(64);
    717723        while (unw_step(&cursor) > 0) {
    718724            unw_word_t pc;
    719725            unw_get_reg(&cursor, UNW_REG_IP, &pc);
    720             stack.push_back(pc);
    721726            if (pc == 0) {
    722727                break;
    723728            }
    724         }
    725         GlobalVariable * global = nullptr;
     729            stack.push_back(pc);
     730        }
     731        #elif defined(HAS_EXECINFO)
     732        for (;;) {
     733            const auto n = backtrace(reinterpret_cast<void **>(stack.data()), stack.capacity());
     734            if (LLVM_LIKELY(n < (int)stack.capacity())) {
     735                stack.set_size(n);
     736                break;
     737            }
     738            stack.reserve(n * 2);
     739        }
     740        #endif
     741        IntegerType * const stackTy = TypeBuilder<unw_word_t, false>::get(getContext());
     742        PointerType * const stackPtrTy = stackTy->getPointerTo();
     743        GlobalVariable * ip_trace = nullptr;
    726744        const auto n = stack.size();
    727         IntegerType * const unwTy = TypeBuilder<unw_word_t, false>::get(getContext());
    728745        for (GlobalVariable & gv : m->getGlobalList()) {
    729746            Type * const ty = gv.getValueType();
    730             if (ty->isArrayTy() && ty->getArrayElementType() == unwTy && ty->getArrayNumElements() == n) {
     747            if (ty->isArrayTy() && ty->getArrayElementType() == stackTy && ty->getArrayNumElements() == n) {
    731748                const ConstantDataArray * const array = cast<ConstantDataArray>(gv.getOperand(0));
    732749                bool found = true;
     
    738755                }
    739756                if (LLVM_UNLIKELY(found)) {
    740                     global = &gv;
     757                    ip_trace = &gv;
    741758                    break;
    742759                }
    743760            }
    744761        }
    745         if (LLVM_LIKELY(global == nullptr)) {
     762        if (LLVM_LIKELY(ip_trace == nullptr)) {
    746763            Constant * const initializer = ConstantDataArray::get(getContext(), stack);
    747             global = new GlobalVariable(*m, initializer->getType(), true, GlobalVariable::InternalLinkage, initializer);
    748         }
    749         Value * const trace = CreatePointerCast(global, unwWordPtrTy);
    750         #else
    751         Constant * const trace = ConstantPointerNull::get(unwWordPtrTy);
    752         #endif
    753         IRBuilder<>::CreateCall(function, {assertion, GetString(failureMessage), trace});
     764            ip_trace = new GlobalVariable(*m, initializer->getType(), true, GlobalVariable::InternalLinkage, initializer);
     765        }
     766        Value * const trace = CreatePointerCast(ip_trace, stackPtrTy);
     767        IRBuilder<>::CreateCall(function, {assertion, GetString(failureMessage), trace, getInt32(n)});
    754768    }
    755769}
     
    847861#define CHECK_ADDRESS(Ptr) \
    848862    if (codegen::EnableAsserts) { \
    849         Module * const m = getModule(); \
    850         PointerType * voidPtrTy = getVoidPtrTy(); \
    851         IntegerType * sizeTy = getSizeTy(); \
    852         Function * isPoisoned = m->getFunction("__asan_region_is_poisoned"); \
    853         if (isPoisoned == nullptr) { \
    854             auto isPoisonedTy = FunctionType::get(voidPtrTy, {voidPtrTy, sizeTy}, false); \
    855             isPoisoned = Function::Create(isPoisonedTy, Function::ExternalLinkage, "__asan_region_is_poisoned", m); \
    856         } \
    857         Value * const addr = CreatePointerCast(Ptr, voidPtrTy); \
    858         Constant * const size = ConstantInt::get(sizeTy, Ptr->getType()->getPointerElementType()->getPrimitiveSizeInBits()); \
     863        Function * const isPoisoned = LinkFunction("__asan_region_is_poisoned", __asan_region_is_poisoned); \
     864        auto arg = isPoisoned->arg_begin(); \
     865        Value * const addr = CreatePointerCast(Ptr, arg->getType()); \
     866        Constant * const size = ConstantInt::get((++arg)->getType(), Ptr->getType()->getPointerElementType()->getPrimitiveSizeInBits() / 8); \
    859867        Value * check = CreateCall(isPoisoned, { addr, size }); \
    860         check = CreateICmpEQ(check, ConstantPointerNull::get(voidPtrTy)); \
     868        check = CreateICmpEQ(check, ConstantPointerNull::get(cast<PointerType>(isPoisoned->getReturnType()))); \
    861869        CreateAssert(check, "Valid memory address"); \
    862870    }
     
    891899#endif
    892900
    893 CBuilder::CBuilder(LLVMContext & C, const unsigned GeneralRegisterWidthInBits)
     901CBuilder::CBuilder(LLVMContext & C)
    894902: IRBuilder<>(C)
    895903, mCacheLineAlignment(64)
    896 , mSizeType(getIntNTy(GeneralRegisterWidthInBits))
     904, mSizeType(TypeBuilder<size_t, false>::get(C))
    897905, mFILEtype(nullptr)
    898906, mDriver(nullptr) {
  • icGREP/icgrep-devel/icgrep/IR_Gen/CBuilder.h

    r5486 r5489  
    2727public:
    2828
    29     CBuilder(llvm::LLVMContext & C, const unsigned GeneralRegisterWidthInBits);
     29    CBuilder(llvm::LLVMContext & C);
    3030   
    3131    virtual ~CBuilder() {}
     
    265265    llvm::Module *                  mModule;
    266266    unsigned                        mCacheLineAlignment;
    267     llvm::IntegerType *             mSizeType;
     267    llvm::IntegerType * const       mSizeType;
    268268    llvm::StructType *              mFILEtype;
    269269    Driver *                        mDriver;
  • icGREP/icgrep-devel/icgrep/IR_Gen/idisa_avx_builder.h

    r5464 r5489  
    1414public:
    1515   
    16     IDISA_AVX_Builder(llvm::LLVMContext & C, unsigned archBitWidth, unsigned bitBlockWidth, unsigned stride)
    17     : IDISA_Builder(C, archBitWidth, bitBlockWidth, stride)
    18     , IDISA_SSE2_Builder(C, archBitWidth, bitBlockWidth, stride)
     16    IDISA_AVX_Builder(llvm::LLVMContext & C, unsigned vectorWidth, unsigned stride)
     17    : IDISA_Builder(C, vectorWidth, stride)
     18    , IDISA_SSE2_Builder(C, vectorWidth, stride)
    1919    {
    2020
     
    3232public:
    3333   
    34     IDISA_AVX2_Builder(llvm::LLVMContext & C, unsigned archBitWidth, unsigned bitBlockWidth, unsigned stride)
    35     : IDISA_Builder(C, archBitWidth, bitBlockWidth, stride)
    36     , IDISA_AVX_Builder(C, archBitWidth, bitBlockWidth, stride) {
     34    IDISA_AVX2_Builder(llvm::LLVMContext & C, unsigned vectorWidth, unsigned stride)
     35    : IDISA_Builder(C, vectorWidth, stride)
     36    , IDISA_AVX_Builder(C, vectorWidth, stride) {
    3737
    3838    }
  • icGREP/icgrep-devel/icgrep/IR_Gen/idisa_builder.cpp

    r5488 r5489  
    174174            }
    175175        }
    176         Constant * revVec = ConstantVector::get({Idxs, byte_count});
    177176        return CreateShuffleVector(bitrev8, UndefValue::get(fwVectorType(8)), ConstantVector::get({Idxs, byte_count}));
    178177    }
     
    397396}
    398397
    399 IDISA_Builder::IDISA_Builder(llvm::LLVMContext & C, unsigned archBitWidth, unsigned bitBlockWidth, unsigned stride)
    400 : CBuilder(C, archBitWidth)
    401 , mBitBlockWidth(bitBlockWidth)
     398IDISA_Builder::IDISA_Builder(llvm::LLVMContext & C, unsigned vectorWidth, unsigned stride)
     399: CBuilder(C)
     400, mBitBlockWidth(vectorWidth)
    402401, mStride(stride)
    403 , mBitBlockType(VectorType::get(IntegerType::get(C, 64), bitBlockWidth / 64))
     402, mBitBlockType(VectorType::get(IntegerType::get(C, 64), vectorWidth / 64))
    404403, mZeroInitializer(Constant::getNullValue(mBitBlockType))
    405404, mOneInitializer(Constant::getAllOnesValue(mBitBlockType))
  • icGREP/icgrep-devel/icgrep/IR_Gen/idisa_builder.h

    r5488 r5489  
    2020public:
    2121
    22     IDISA_Builder(llvm::LLVMContext & C, unsigned archBitWidth, unsigned bitBlockWidth, unsigned stride);
     22    IDISA_Builder(llvm::LLVMContext & C, unsigned vectorWidth, unsigned stride);
    2323
    2424    virtual ~IDISA_Builder();
  • icGREP/icgrep-devel/icgrep/IR_Gen/idisa_i64_builder.h

    r5464 r5489  
    1414public:
    1515 
    16     IDISA_I64_Builder(llvm::LLVMContext & C, unsigned archBitWidth, unsigned bitBlockWidth, unsigned stride)
    17     : IDISA_Builder(C, archBitWidth, bitBlockWidth, stride) {
     16    IDISA_I64_Builder(llvm::LLVMContext & C, unsigned bitBlockWidth, unsigned stride)
     17    : IDISA_Builder(C, bitBlockWidth, stride) {
    1818
    1919    }
  • icGREP/icgrep-devel/icgrep/IR_Gen/idisa_nvptx_builder.h

    r5486 r5489  
    1414public:
    1515   
    16     IDISA_NVPTX20_Builder(llvm::LLVMContext & C, unsigned registerWidth, unsigned vectorWidth, unsigned stride)
    17     : IDISA_Builder(C, registerWidth, registerWidth, stride)
    18     , IDISA_I64_Builder(C, registerWidth, registerWidth, stride)
    19     , groupThreads(stride/vectorWidth)
     16    IDISA_NVPTX20_Builder(llvm::LLVMContext & C, unsigned vectorWidth, unsigned stride)
     17    : IDISA_Builder(C, vectorWidth, stride)
     18    , IDISA_I64_Builder(C, vectorWidth, stride)
     19    , groupThreads(stride / vectorWidth)
    2020    , barrierFunc(nullptr)
    2121    , tidFunc(nullptr)
     
    2424    , carry(nullptr)
    2525    , bubble(nullptr) {
    26 
     26        assert ((stride % vectorWidth) == 0);
    2727    }
    2828
  • icGREP/icgrep-devel/icgrep/IR_Gen/idisa_sse_builder.h

    r5464 r5489  
    1515public:
    1616 
    17     IDISA_SSE_Builder(llvm::LLVMContext & C, unsigned archBitWidth, unsigned bitBlockWidth, unsigned stride)
    18     : IDISA_Builder(C, archBitWidth, bitBlockWidth, stride) {
     17    IDISA_SSE_Builder(llvm::LLVMContext & C, unsigned bitBlockWidth, unsigned stride)
     18    : IDISA_Builder(C, bitBlockWidth, stride) {
    1919
    2020    }
     
    2929public:
    3030 
    31     IDISA_SSE2_Builder(llvm::LLVMContext & C, unsigned archBitWidth, unsigned bitBlockWidth, unsigned stride)
    32     : IDISA_Builder(C, archBitWidth, bitBlockWidth, stride)
    33     , IDISA_SSE_Builder(C, archBitWidth, bitBlockWidth, stride) {
     31    IDISA_SSE2_Builder(llvm::LLVMContext & C, unsigned bitBlockWidth, unsigned stride)
     32    : IDISA_Builder(C, bitBlockWidth, stride)
     33    , IDISA_SSE_Builder(C, bitBlockWidth, stride) {
    3434
    3535    }
  • icGREP/icgrep-devel/icgrep/IR_Gen/idisa_target.cpp

    r5464 r5489  
    1919namespace IDISA {
    2020   
    21 KernelBuilder * GetIDISA_Builder(llvm::LLVMContext & C, const std::string & targetTriple) {
    22     unsigned registerWidth = 0;
    23     llvm::Triple T(targetTriple);
    24     if (T.isArch64Bit()) {
    25         registerWidth = 64;
    26     } else if (T.isArch32Bit()) {
    27         registerWidth = 32;
    28     } else if (T.isArch16Bit()) {
    29         registerWidth = 16;
    30     }
     21KernelBuilder * GetIDISA_Builder(llvm::LLVMContext & C) {
    3122    const bool hasAVX2 = AVX2_available();
    3223    if (LLVM_LIKELY(codegen::BlockSize == 0)) {  // No BlockSize override: use processor SIMD width
     
    3526    if (codegen::BlockSize >= 256) {
    3627        if (hasAVX2) {
    37             return new KernelBuilderImpl<IDISA_AVX2_Builder>(C, registerWidth, codegen::BlockSize, codegen::BlockSize);
     28            return new KernelBuilderImpl<IDISA_AVX2_Builder>(C, codegen::BlockSize, codegen::BlockSize);
    3829        }
    3930    } else if (codegen::BlockSize == 64) {
    40         return new KernelBuilderImpl<IDISA_I64_Builder>(C, registerWidth, codegen::BlockSize, codegen::BlockSize);
     31        return new KernelBuilderImpl<IDISA_I64_Builder>(C, codegen::BlockSize, codegen::BlockSize);
    4132    }
    42     return new KernelBuilderImpl<IDISA_SSE2_Builder>(C, registerWidth, codegen::BlockSize, codegen::BlockSize);
     33    return new KernelBuilderImpl<IDISA_SSE2_Builder>(C, codegen::BlockSize, codegen::BlockSize);
    4334}
    4435
    4536KernelBuilder * GetIDISA_GPU_Builder(llvm::LLVMContext & C) {
    46     return new KernelBuilderImpl<IDISA_NVPTX20_Builder>(C, 64, 64, 64*64);
     37    return new KernelBuilderImpl<IDISA_NVPTX20_Builder>(C, 64, 64 * 64);
    4738}
    4839
  • icGREP/icgrep-devel/icgrep/IR_Gen/idisa_target.h

    r5446 r5489  
    1313namespace IDISA {
    1414   
    15 kernel::KernelBuilder * GetIDISA_Builder(llvm::LLVMContext & C, const std::string & targetTriple);
     15kernel::KernelBuilder * GetIDISA_Builder(llvm::LLVMContext & C);
    1616
    1717kernel::KernelBuilder * GetIDISA_GPU_Builder(llvm::LLVMContext & C);
Note: See TracChangeset for help on using the changeset viewer.