Ignore:
Timestamp:
May 22, 2017, 12:14:19 PM (2 years ago)
Author:
nmedfort
Message:

Restructuring work for the Driver classes. Start of work to eliminate the memory leaks with the ExecutionEngine?. Replaced custom AlignedMalloc? with backend call to std::aligned_malloc. Salvaged some work on DistributionPass? for reevaluation.

Location:
icGREP/icgrep-devel/icgrep/IR_Gen
Files:
1 added
1 deleted
13 edited

Legend:

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

    r5454 r5464  
    1313#include <llvm/Support/raw_ostream.h>
    1414#include <toolchain/toolchain.h>
     15#include <toolchain/driver.h>
     16#include <stdlib.h>
    1517#include <sys/mman.h>
     18#include <unistd.h>
    1619
    1720using namespace llvm;
     
    218221Value * CBuilder::CreateMalloc(Value * size) {
    219222    Module * const m = getModule();
    220     DataLayout DL(m);
    221     IntegerType * const intTy = getIntPtrTy(DL);
    222     if (size->getType() != intTy) {
    223         if (isa<Constant>(size)) {
    224             size = ConstantExpr::getIntegerCast(cast<Constant>(size), intTy, false);
    225         } else {
    226             size = CreateZExtOrTrunc(size, intTy);
    227         }
    228     }   
    229     PointerType * const voidPtrTy = getVoidPtrTy();
     223    IntegerType * const sizeTy = getSizeTy();   
    230224    Function * malloc = m->getFunction("malloc");
    231225    if (malloc == nullptr) {
    232         FunctionType * fty = FunctionType::get(voidPtrTy, {intTy}, false);
     226//        malloc = LinkFunction("malloc", &std::malloc);
     227        PointerType * const voidPtrTy = getVoidPtrTy();
     228        FunctionType * fty = FunctionType::get(voidPtrTy, {sizeTy}, false);
    233229        malloc = Function::Create(fty, Function::ExternalLinkage, "malloc", m);
    234230        malloc->setCallingConv(CallingConv::C);
    235231        malloc->setDoesNotAlias(0);
    236232    }
    237     assert (size->getType() == intTy);
    238     CallInst * ci = CreateCall(malloc, size); assert (ci);
    239     ci->setTailCall();
    240     ci->setCallingConv(malloc->getCallingConv());
    241     Value * ptr = CreatePointerCast(ci, voidPtrTy); assert (ptr);
    242     CreateAssert(ptr, "FATAL ERROR: out of memory");
     233    size = CreateZExtOrTrunc(size, sizeTy);
     234    CallInst * const ptr = CreateCall(malloc, size);
     235    ptr->setTailCall();
     236    CreateAssert(ptr, "CreateMalloc: returned null pointer");
    243237    return ptr;
    244238}
     
    249243    }
    250244    Module * const m = getModule();
    251     DataLayout DL(m);
    252     IntegerType * const intTy = getIntPtrTy(DL);
    253     Function * aligned_malloc = m->getFunction("aligned_malloc" + std::to_string(alignment));
     245    Function * aligned_malloc = m->getFunction("aligned_alloc");
     246    IntegerType * const sizeTy = getSizeTy();
    254247    if (LLVM_UNLIKELY(aligned_malloc == nullptr)) {
    255         const auto ip = saveIP();
    256248        PointerType * const voidPtrTy = getVoidPtrTy();
    257         FunctionType * fty = FunctionType::get(voidPtrTy, {intTy}, false);
    258         aligned_malloc = Function::Create(fty, Function::InternalLinkage, "aligned_malloc" + std::to_string(alignment), m);
     249        FunctionType * const fty = FunctionType::get(voidPtrTy, {sizeTy, sizeTy}, false);
     250        aligned_malloc = Function::Create(fty, Function::ExternalLinkage, "aligned_alloc", m);
    259251        aligned_malloc->setCallingConv(CallingConv::C);
    260252        aligned_malloc->setDoesNotAlias(0);
    261         aligned_malloc->addFnAttr(Attribute::AlwaysInline);
    262         Value * size = &*aligned_malloc->arg_begin();
    263         SetInsertPoint(BasicBlock::Create(getContext(), "entry", aligned_malloc));
    264         const auto byteWidth = (intTy->getBitWidth() / 8);
    265         Constant * const offset = ConstantInt::get(intTy, alignment + byteWidth - 1);
    266         size = CreateAdd(size, offset);
    267         Value * unaligned = CreatePtrToInt(CreateMalloc(size), intTy);
    268         Value * aligned = CreateAnd(CreateAdd(unaligned, offset), ConstantExpr::getNot(ConstantInt::get(intTy, alignment - 1)));
    269         Value * prefix = CreateIntToPtr(CreateSub(aligned, ConstantInt::get(intTy, byteWidth)), intTy->getPointerTo());
    270         assert (unaligned->getType() == prefix->getType()->getPointerElementType());
    271         CreateAlignedStore(unaligned, prefix, byteWidth);
    272         CreateRet(CreateIntToPtr(aligned, voidPtrTy));
    273         restoreIP(ip);
    274     }
    275     return CreateCall(aligned_malloc, {CreateZExtOrTrunc(size, intTy)});
     253
     254        // aligned_malloc = LinkFunction("aligned_alloc", &aligned_alloc);
     255    }
     256
     257    size = CreateZExtOrTrunc(size, sizeTy);
     258    ConstantInt * const align = ConstantInt::get(sizeTy, alignment);
     259    if (codegen::EnableAsserts) {
     260        CreateAssert(CreateICmpEQ(CreateURem(size, align), ConstantInt::get(sizeTy, 0)),
     261                     "CreateAlignedMalloc: size must be an integral multiple of alignment.");
     262    }
     263    Value * const ptr = CreateCall(aligned_malloc, {align, size});
     264    CreateAssert(ptr, "CreateAlignedMalloc: returned null pointer.");
     265    return ptr;
    276266}
    277267
     
    440430}
    441431
    442 void CBuilder::CreateFree(Value * const ptr) {
     432void CBuilder::CreateFree(Value * ptr) {
    443433    assert (ptr->getType()->isPointerTy());
    444434    Module * const m = getModule();
     435    Type * const voidPtrTy =  getVoidPtrTy();
     436    Function * f = m->getFunction("free");
     437    if (f == nullptr) {
     438        FunctionType * fty = FunctionType::get(getVoidTy(), {voidPtrTy}, false);
     439        f = Function::Create(fty, Function::ExternalLinkage, "free", m);
     440        f->setCallingConv(CallingConv::C);
     441        // f = LinkFunction("free", &std::free);
     442    }
     443    ptr = CreatePointerCast(ptr, voidPtrTy);
     444    CreateCall(f, ptr)->setTailCall();
     445}
     446
     447Value * CBuilder::CreateRealloc(Value * const ptr, Value * size) {
     448    Module * const m = getModule();
     449    IntegerType * const sizeTy = getSizeTy();
    445450    PointerType * const voidPtrTy = getVoidPtrTy();
    446     Function * free = m->getFunction("free");
    447     if (free == nullptr) {
    448         FunctionType * fty = FunctionType::get(getVoidTy(), {voidPtrTy}, false);
    449         Module * const m = getModule();
    450         free = Function::Create(fty, Function::ExternalLinkage, "free", m);
    451         free->setCallingConv(CallingConv::C);
    452     }
    453     CallInst * const ci = CreateCall(free, CreatePointerCast(ptr, voidPtrTy));
     451    Function * f = m->getFunction("realloc");
     452    if (f == nullptr) {
     453        FunctionType * fty = FunctionType::get(voidPtrTy, {voidPtrTy, sizeTy}, false);
     454        f = Function::Create(fty, Function::ExternalLinkage, "realloc", m);
     455        f->setCallingConv(CallingConv::C);
     456        f->setDoesNotAlias(0);
     457        f->setDoesNotAlias(1);
     458        // f = LinkFunction("realloc", &realloc);
     459    }
     460    Value * const addr = CreatePointerCast(ptr, voidPtrTy);
     461    size = CreateZExtOrTrunc(size, sizeTy);
     462    CallInst * const ci = CreateCall(f, {addr, size});
    454463    ci->setTailCall();
    455     ci->setCallingConv(free->getCallingConv());
    456 }
    457 
    458 void CBuilder::CreateAlignedFree(Value * const ptr, const bool testForNullAddress) {
    459     // WARNING: this will segfault if the value of the ptr at runtime is null but testForNullAddress was not set
    460     PointerType * type = cast<PointerType>(ptr->getType());
    461     BasicBlock * exit = nullptr;
    462     if (testForNullAddress) {
    463         LLVMContext & C = getContext();
    464         BasicBlock * bb = GetInsertBlock();
    465         Function * f = bb->getParent();
    466         exit = BasicBlock::Create(C, "", f, bb);
    467         BasicBlock * entry = BasicBlock::Create(C, "", f, exit);
    468         Value * cond = CreateICmpEQ(ptr, ConstantPointerNull::get(type));
    469         CreateCondBr(cond, exit, entry);
    470         SetInsertPoint(entry);
    471     }
    472     DataLayout DL(getModule());
    473     IntegerType * const intTy = getIntPtrTy(DL);
    474     const auto byteWidth = (intTy->getBitWidth() / 8);
    475     Value * prefix = CreatePtrToInt(ptr, intTy);
    476     prefix = CreateSub(prefix, ConstantInt::get(intTy, byteWidth));
    477     prefix = CreateIntToPtr(prefix, intTy->getPointerTo());
    478     prefix = CreateIntToPtr(CreateAlignedLoad(prefix, byteWidth), type);
    479     CreateFree(prefix);
    480     if (testForNullAddress) {
    481         CreateBr(exit);
    482         SetInsertPoint(exit);
    483     }
    484 }
    485 
    486 Value * CBuilder::CreateRealloc(Value * ptr, Value * size) {
    487     Module * const m = getModule();
    488     DataLayout DL(m);
    489     IntegerType * const intTy = getIntPtrTy(DL);
    490     PointerType * type = cast<PointerType>(ptr->getType());
    491     if (size->getType() != intTy) {
    492         if (isa<Constant>(size)) {
    493             size = ConstantExpr::getIntegerCast(cast<Constant>(size), intTy, false);
    494         } else {
    495             size = CreateZExtOrTrunc(size, intTy);
    496         }
    497     }
    498     Function * realloc = m->getFunction("realloc");
    499     if (realloc == nullptr) {
    500         PointerType * const voidPtrTy = getVoidPtrTy();
    501         FunctionType * fty = FunctionType::get(voidPtrTy, {voidPtrTy, intTy}, false);       
    502         realloc = Function::Create(fty, Function::ExternalLinkage, "realloc", m);
    503         realloc->setCallingConv(CallingConv::C);
    504         realloc->setDoesNotAlias(1);
    505     }
    506     assert (size->getType() == intTy);
    507     CallInst * ci = CreateCall(realloc, {ptr, size});
    508     ci->setTailCall();
    509     ci->setCallingConv(realloc->getCallingConv());
    510     return CreateBitOrPointerCast(ci, type);
     464    return CreatePointerCast(ci, ptr->getType());
    511465}
    512466
    513467PointerType * CBuilder::getVoidPtrTy() const {
    514     return TypeBuilder<void *, true>::get(getContext());
     468    return TypeBuilder<void *, false>::get(getContext());
    515469}
    516470
     
    776730Function * CBuilder::LinkFunction(llvm::StringRef name, FunctionType * type, void * functionPtr) const {
    777731    assert (mDriver);
    778     return mDriver->LinkFunction(getModule(), name, type, functionPtr);
     732    return mDriver->addLinkFunction(getModule(), name, type, functionPtr);
    779733}
    780734
  • icGREP/icgrep-devel/icgrep/IR_Gen/CBuilder.h

    r5440 r5464  
    2222namespace llvm { class Value; }
    2323
    24 class ParabixDriver;
     24class Driver;
    2525
    2626class CBuilder : public llvm::IRBuilder<> {
    27     friend class ParabixDriver;
    2827public:
    2928
     
    5453   
    5554    void CreateFree(llvm::Value * const ptr);
    56    
    57     void CreateAlignedFree(llvm::Value * const ptr, const bool testForNullAddress = false);
    58    
     55
    5956    llvm::Value * CreateRealloc(llvm::Value * ptr, llvm::Value * size);
    6057
     
    6764        instr->setAlignment(getCacheAlignment());
    6865        return instr;
     66    }
     67
     68    llvm::Value * CreateCacheAlignedMalloc(llvm::Value * size) {
     69        return CreateAlignedMalloc(size, getCacheAlignment());
    6970    }
    7071
     
    188189
    189190    virtual bool supportsIndirectBr() const {
    190         return true;
     191        return false;
    191192    }
    192193
     
    215216    llvm::Function * LinkFunction(llvm::StringRef name, ExternalFunctionType * functionPtr) const;
    216217
     218    void setDriver(Driver * const driver) {
     219        mDriver = driver;
     220    }
     221
    217222protected:
    218223
    219224    llvm::Function * LinkFunction(llvm::StringRef name, llvm::FunctionType * type, void * functionPtr) const;
    220 
    221     void setDriver(ParabixDriver * driver) {
    222         mDriver = driver;
    223     }
    224225
    225226protected:
     
    229230    llvm::IntegerType *             mSizeType;
    230231    llvm::StructType *              mFILEtype;
    231     ParabixDriver *                 mDriver;
     232    Driver *                        mDriver;
    232233    llvm::LLVMContext               mContext;
    233234    const std::string               mTriple;
  • icGREP/icgrep-devel/icgrep/IR_Gen/idisa_avx_builder.cpp

    r5440 r5464  
    66
    77#include "idisa_avx_builder.h"
     8
     9using namespace llvm;
    810
    911namespace IDISA {
  • icGREP/icgrep-devel/icgrep/IR_Gen/idisa_avx_builder.h

    r5436 r5464  
    88
    99#include <IR_Gen/idisa_sse_builder.h>
    10 
    11 using namespace llvm;
    1210
    1311namespace IDISA {
     
    2523    virtual std::string getBuilderUniqueName() override;
    2624
    27     Value * hsimd_signmask(unsigned fw, Value * a) override;
     25    llvm::Value * hsimd_signmask(unsigned fw, llvm::Value * a) override;
    2826
    2927    ~IDISA_AVX_Builder() {}
     
    4139
    4240    virtual std::string getBuilderUniqueName() override;
    43     Value * hsimd_packh(unsigned fw, Value * a, Value * b) override;
    44     Value * hsimd_packl(unsigned fw, Value * a, Value * b) override;
    45     Value * esimd_mergeh(unsigned fw, Value * a, Value * b) override;
    46     Value * esimd_mergel(unsigned fw, Value * a, Value * b) override;
    47     Value * hsimd_packh_in_lanes(unsigned lanes, unsigned fw, Value * a, Value * b) override;
    48     Value * hsimd_packl_in_lanes(unsigned lanes, unsigned fw, Value * a, Value * b) override;
    49     std::pair<Value *, Value *> bitblock_add_with_carry(Value * a, Value * b, Value * carryin) override;
     41    llvm::Value * hsimd_packh(unsigned fw, llvm::Value * a, llvm::Value * b) override;
     42    llvm::Value * hsimd_packl(unsigned fw, llvm::Value * a, llvm::Value * b) override;
     43    llvm::Value * esimd_mergeh(unsigned fw, llvm::Value * a, llvm::Value * b) override;
     44    llvm::Value * esimd_mergel(unsigned fw, llvm::Value * a, llvm::Value * b) override;
     45    llvm::Value * hsimd_packh_in_lanes(unsigned lanes, unsigned fw, llvm::Value * a, llvm::Value * b) override;
     46    llvm::Value * hsimd_packl_in_lanes(unsigned lanes, unsigned fw, llvm::Value * a, llvm::Value * b) override;
     47    std::pair<llvm::Value *, llvm::Value *> bitblock_add_with_carry(llvm::Value * a, llvm::Value * b, llvm::Value * carryin) override;
    5048
    5149    ~IDISA_AVX2_Builder() {}
  • icGREP/icgrep-devel/icgrep/IR_Gen/idisa_builder.h

    r5458 r5464  
    108108    virtual llvm::Value * bitblock_set_bit(llvm::Value * pos);
    109109
    110     virtual void CreateBaseFunctions(){};
     110    virtual void CreateBaseFunctions() {}
    111111   
    112112    llvm::Value * simd_and(llvm::Value * a, llvm::Value * b);
  • icGREP/icgrep-devel/icgrep/IR_Gen/idisa_i64_builder.cpp

    r5374 r5464  
    66
    77#include "idisa_i64_builder.h"
     8
     9using namespace llvm;
    810
    911namespace IDISA {
  • icGREP/icgrep-devel/icgrep/IR_Gen/idisa_i64_builder.h

    r5436 r5464  
    88 */
    99#include <IR_Gen/idisa_builder.h>
    10 
    11 using namespace llvm;
    1210
    1311namespace IDISA {
     
    2321    virtual std::string getBuilderUniqueName() override;
    2422
    25     Value * hsimd_packh(unsigned fw, Value * a, Value * b) override;
    26     Value * hsimd_packl(unsigned fw, Value * a, Value * b) override;
     23    llvm::Value * hsimd_packh(unsigned fw, llvm::Value * a, llvm::Value * b) override;
     24    llvm::Value * hsimd_packl(unsigned fw, llvm::Value * a, llvm::Value * b) override;
    2725    ~IDISA_I64_Builder() {}
    2826
  • icGREP/icgrep-devel/icgrep/IR_Gen/idisa_nvptx_builder.cpp

    r5440 r5464  
    88#include <llvm/IR/InlineAsm.h>
    99#include <llvm/IR/Module.h>
     10
     11using namespace llvm;
    1012
    1113namespace IDISA {
     
    276278}
    277279
    278    
    279 }
     280void IDISA_NVPTX20_Builder::CreateBaseFunctions() {
     281    CreateGlobals();
     282    CreateBuiltinFunctions();
     283    CreateLongAdvanceFunc();
     284    CreateLongAddFunc();
     285    CreateBallotFunc();
     286}
     287
     288   
     289}
  • icGREP/icgrep-devel/icgrep/IR_Gen/idisa_nvptx_builder.h

    r5458 r5464  
    88
    99#include <IR_Gen/idisa_i64_builder.h>
    10 
    11 using namespace llvm;
    1210
    1311namespace IDISA {
     
    2422
    2523    ~IDISA_NVPTX20_Builder() {}
     24
    2625    virtual std::string getBuilderUniqueName() override;
     26
    2727    int getGroupThreads();
    2828
    29     void CreateBaseFunctions() override {
    30         CreateGlobals();
    31         CreateBuiltinFunctions();
    32         CreateLongAdvanceFunc();
    33         CreateLongAddFunc();
    34         CreateBallotFunc();
    35     };
     29    void CreateBaseFunctions() override;
    3630   
    37     Value * bitblock_any(Value * a) override;
    38     std::pair<Value *, Value *> bitblock_add_with_carry(Value * a, Value * b, Value * carryin) override;
    39     virtual std::pair<Value *, Value *> bitblock_advance(Value * a, Value * shiftin, unsigned shift) override;
    40     Value * bitblock_mask_from(Value * pos) override;
    41     Value * bitblock_set_bit(Value * pos) override;
     31    llvm::Value * bitblock_any(llvm::Value * a) override;
     32    std::pair<llvm::Value *, llvm::Value *> bitblock_add_with_carry(llvm::Value * a, llvm::Value * b, llvm::Value * carryin) override;
     33    virtual std::pair<llvm::Value *, llvm::Value *> bitblock_advance(llvm::Value * a, llvm::Value * shiftin, unsigned shift) override;
     34    llvm::Value * bitblock_mask_from(llvm::Value * pos) override;
     35    llvm::Value * bitblock_set_bit(llvm::Value * pos) override;
    4236
    43     Value * getEOFMask(Value * remainingBytes);
     37    llvm::Value * getEOFMask(llvm::Value * remainingBytes);
    4438
    45     Value * Advance(const unsigned index, const unsigned shiftAmount, Value * const value);
    46     Value * LongAdd(Value * const valA, Value * const valB, Value * carryIn);
     39    llvm::Value * Advance(const unsigned index, const unsigned shiftAmount, llvm::Value * const value);
     40    llvm::Value * LongAdd(llvm::Value * const valA, llvm::Value * const valB, llvm::Value * carryIn);
    4741
    48     LoadInst * CreateAtomicLoadAcquire(Value * ptr) override;
    49     StoreInst * CreateAtomicStoreRelease(Value * val, Value * ptr) override;
     42    llvm::LoadInst * CreateAtomicLoadAcquire(llvm::Value * ptr) override;
     43    llvm::StoreInst * CreateAtomicStoreRelease(llvm::Value * val, llvm::Value * ptr) override;
    5044
    5145    bool supportsIndirectBr() const final {
     
    5448
    5549private:
     50
    5651    void CreateGlobals();
    5752    void CreateBuiltinFunctions();
     
    6055    void CreateBallotFunc();
    6156
    62     int                                 groupThreads;
    63     Function *                          barrierFunc;
    64     Function *                          tidFunc;
    65     Function *                          mLongAdvanceFunc;
    66     Function *                          mLongAddFunc;
    67     GlobalVariable*                     carry;
    68     GlobalVariable*                     bubble;
     57private:
     58    int                         groupThreads;
     59    llvm::Function *            barrierFunc;
     60    llvm::Function *            tidFunc;
     61    llvm::Function *            mLongAdvanceFunc;
     62    llvm::Function *            mLongAddFunc;
     63    llvm::GlobalVariable*       carry;
     64    llvm::GlobalVariable*       bubble;
    6965};
    7066
     
    7470    IDISA_NVPTX35_Builder(Module * m, int groupSize) : IDISA_NVPTX30_Builder(m, groupSize) {}
    7571   
    76     std::pair<Value *, Value *> bitblock_advance(Value * a, Value * shiftin, unsigned shift) override;
     72    std::pair<llvm::Value *, llvm::Value *> bitblock_advance(llvm::Value * a, llvm::Value * shiftin, unsigned shift) override;
    7773
    7874    ~IDISA_NVPTX35_Builder() {};
  • icGREP/icgrep-devel/icgrep/IR_Gen/idisa_sse_builder.cpp

    r5440 r5464  
    66
    77#include "idisa_sse_builder.h"
     8
     9using namespace llvm;
    810
    911namespace IDISA {
  • icGREP/icgrep-devel/icgrep/IR_Gen/idisa_sse_builder.h

    r5436 r5464  
    99
    1010#include <IR_Gen/idisa_builder.h>
    11 
    12 using namespace llvm;
    1311
    1412namespace IDISA {
     
    2321
    2422    virtual std::string getBuilderUniqueName() override;
    25     Value * hsimd_signmask(unsigned fw, Value * a) override;
     23    llvm::Value * hsimd_signmask(unsigned fw, llvm::Value * a) override;
    2624    ~IDISA_SSE_Builder() {}
    2725
     
    3836
    3937    virtual std::string getBuilderUniqueName() override;
    40     Value * hsimd_signmask(unsigned fw, Value * a) override;
    41     Value * hsimd_packh(unsigned fw, Value * a, Value * b) override;
    42     Value * hsimd_packl(unsigned fw, Value * a, Value * b) override;
    43     std::pair<Value *, Value *> bitblock_advance(Value * a, Value * shiftin, unsigned shift) final;
     38    llvm::Value * hsimd_signmask(unsigned fw, llvm::Value * a) override;
     39    llvm::Value * hsimd_packh(unsigned fw, llvm::Value * a, llvm::Value * b) override;
     40    llvm::Value * hsimd_packl(unsigned fw, llvm::Value * a, llvm::Value * b) override;
     41    std::pair<llvm::Value *, llvm::Value *> bitblock_advance(llvm::Value * a, llvm::Value * shiftin, unsigned shift) final;
    4442
    4543    ~IDISA_SSE2_Builder() {}
  • icGREP/icgrep-devel/icgrep/IR_Gen/idisa_target.cpp

    r5458 r5464  
    2121KernelBuilder * GetIDISA_Builder(llvm::LLVMContext & C, const std::string & targetTriple) {
    2222    unsigned registerWidth = 0;
    23     Triple T(targetTriple);
     23    llvm::Triple T(targetTriple);
    2424    if (T.isArch64Bit()) {
    2525        registerWidth = 64;
  • icGREP/icgrep-devel/icgrep/IR_Gen/tracegen.h

    r5398 r5464  
    88#include "idisa_builder.h"
    99#include <string>
    10 #include <llvm/IR/Module.h>
    11 #include <llvm/IR/Constants.h>
    12 #include <llvm/IR/Intrinsics.h>
    13 #include <llvm/IR/Function.h>
    14 
    15 
    1610
    1711class TraceTool {
     
    3428};
    3529
    36 using namespace llvm;
    37 
    38 TraceTool::TraceTool(IDISA::IDISA_Builder * b, unsigned log2TraceBufSize) :
    39     iBuilder(b),
    40     mLog2TraceBufSize(log2TraceBufSize),
    41     mTraceVarCount(0) {
    42 
    43     Type * entryType = StructType::get(iBuilder->getInt8Ty()->getPointerTo(), iBuilder->getSizeTy(), nullptr);
    44     Type * bufferType = ArrayType::get(entryType, 1 << mLog2TraceBufSize);
    45     mTraceBufferPtr = iBuilder->CreateAlloca(bufferType);
    46     mTraceIndexPtr = iBuilder->CreateAlloca(iBuilder->getInt32Ty());
    47     iBuilder->CreateStore(ConstantInt::getNullValue(iBuilder->getInt32Ty()), mTraceIndexPtr);
    48     mTraceIndexMask = ConstantInt::get(iBuilder->getInt32Ty(), (1 << mLog2TraceBufSize) - 1);
    49 }
    50 
    51 unsigned TraceTool::newTraceVar(std::string traceName) {
    52     std::string formatString = traceName + " = %" PRIx64 "\n";
    53     mTraceFormatString.push_back(iBuilder->GetString(formatString.c_str()));
    54     return mTraceVarCount++;
    55 }
    56 
    57 void TraceTool::addTraceEntry(unsigned traceVar, llvm::Value * traceVal) {
    58    
    59     Value * traceIndex = iBuilder->CreateLoad(mTraceIndexPtr);
    60     Value * entryVarPtr = iBuilder->CreateGEP(mTraceBufferPtr, {iBuilder->getInt32(0), traceIndex, iBuilder->getInt32(0)});
    61     iBuilder->CreateStore(mTraceFormatString[traceVar], entryVarPtr);
    62     Value * entryValPtr = iBuilder->CreateGEP(mTraceBufferPtr, {iBuilder->getInt32(0), traceIndex, iBuilder->getInt32(1)});
    63     iBuilder->CreateStore(iBuilder->CreateZExt(traceVal, iBuilder->getSizeTy()), entryValPtr);
    64     iBuilder->CreateStore(iBuilder->CreateAnd(mTraceIndexMask, iBuilder->CreateAdd(traceIndex, iBuilder->getInt32(1))), mTraceIndexPtr);
    65 }
    66 
    67 void TraceTool::createDumpTrace() {
    68     Constant * traceBufSize = ConstantInt::get(iBuilder->getInt32Ty(), 1<<mLog2TraceBufSize);
    69     Function * printF = iBuilder->GetPrintf();
    70     BasicBlock * DumpEntryBlock = iBuilder->GetInsertBlock();
    71     Function * currentFn = DumpEntryBlock->getParent();
    72     BasicBlock * DumpTraceLoop = BasicBlock::Create(iBuilder->getContext(), "DumpTraceLoop", currentFn, 0);
    73     BasicBlock * DumpTraceExit = BasicBlock::Create(iBuilder->getContext(), "DumpTraceExit", currentFn, 0);
    74    
    75     Value * lastTraceIndex = iBuilder->CreateLoad(mTraceIndexPtr);
    76     Value * truncated = iBuilder->CreateICmpUGT(lastTraceIndex, traceBufSize);
    77     Value * firstDumpIndex = iBuilder->CreateSelect(truncated, iBuilder->CreateSub(lastTraceIndex, traceBufSize), ConstantInt::getNullValue(iBuilder->getInt32Ty()));
    78    
    79     iBuilder->CreateBr(DumpTraceLoop);
    80     iBuilder->SetInsertPoint(DumpTraceLoop);
    81     PHINode * loopIndex = iBuilder->CreatePHI(iBuilder->getInt32Ty(), 2);
    82     loopIndex->addIncoming(firstDumpIndex, DumpEntryBlock);
    83    
    84     Value * entryVarPtr = iBuilder->CreateGEP(mTraceBufferPtr, {iBuilder->getInt32(0), loopIndex, iBuilder->getInt32(0)});
    85     Value * formatString = iBuilder->CreateLoad(entryVarPtr);
    86     Value * entryValPtr = iBuilder->CreateGEP(mTraceBufferPtr, {iBuilder->getInt32(0), loopIndex, iBuilder->getInt32(1)});
    87     Value * entryVal = iBuilder->CreateLoad(entryValPtr);
    88     iBuilder->CreateCall(printF, {formatString, entryVal});
    89    
    90     Value * nextIndex = iBuilder->CreateAnd(iBuilder->CreateAdd(loopIndex, iBuilder->getInt32(1)), mTraceIndexMask);
    91     loopIndex->addIncoming(nextIndex, DumpTraceLoop);
    92     Value * atLastTraceIndex = iBuilder->CreateICmpEQ(nextIndex, lastTraceIndex);
    93     iBuilder->CreateCondBr(atLastTraceIndex, DumpTraceExit, DumpTraceLoop);
    94     iBuilder->SetInsertPoint(DumpTraceExit);
    95 }
    96 
    9730#endif
Note: See TracChangeset for help on using the changeset viewer.