Ignore:
Timestamp:
Oct 25, 2017, 4:57:58 PM (19 months ago)
Author:
nmedfort
Message:

First stage of MultiBlockKernel? and pipeline restructuring

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

Legend:

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

    r5681 r5706  
    4242using namespace llvm;
    4343
    44 
    45 Value * CBuilder::CreateURem(Value * number, Value * divisor, const Twine &Name) {   
     44inline static bool is_power_2(const uint64_t n) {
     45    return ((n & (n - 1)) == 0) && n;
     46}
     47
     48Value * CBuilder::CreateURem(Value * const number, Value * const divisor, const Twine & Name) {
    4649    if (ConstantInt * c = dyn_cast<ConstantInt>(divisor)) {
    4750        const auto d = c->getZExtValue();
    48         if ((d & (d - 1)) == 0) { // is a power of 2 or 0
    49             if (d > 0) {
    50                 return CreateAnd(number, ConstantInt::get(divisor->getType(), d - 1), Name);
    51             }
    52         }
    53     }
    54     CreateAssert(divisor, "CreateURem divisor cannot be 0!");
     51        assert ("CreateURem divisor cannot be 0!" && d);
     52        if (is_power_2(d)) {
     53            return CreateAnd(number, ConstantInt::get(divisor->getType(), d - 1), Name);
     54        }
     55    } else {
     56        CreateAssert(divisor, "CreateURem divisor cannot be 0!");
     57    }
    5558    return Insert(BinaryOperator::CreateURem(number, divisor), Name);
    5659}
    5760
    58 Value * CBuilder::CreateUDiv(Value * number, Value * divisor, const Twine &Name) {   
     61Value * CBuilder::CreateUDiv(Value * const number, Value * const divisor, const Twine & Name) {
    5962    if (ConstantInt * c = dyn_cast<ConstantInt>(divisor)) {
    6063        const auto d = c->getZExtValue();
    61         if ((d & (d - 1)) == 0) { // is a power of 2 or 0
     64        assert ("CreateUDiv divisor cannot be 0!" && d);
     65        if (is_power_2(d)) {
    6266            if (d > 1) {
    6367                return CreateLShr(number, ConstantInt::get(divisor->getType(), std::log2(d)), Name);
    64             } else if (d == 1) {
     68            } else {
    6569                return number;
    6670            }
     
    7175}
    7276
    73 Value * CBuilder::CreateUDivCeil(Value * number, Value * divisor, const Twine &Name) {   
    74     if (ConstantInt * c = dyn_cast<ConstantInt>(divisor)) {
    75         const auto d = c->getZExtValue();
    76         if ((d & (d - 1)) == 0) { // is a power of 2 or 0
    77             if (d > 1) {
    78                 Value * n = CreateAdd(number, ConstantInt::get(divisor->getType(), d - 1));
    79                 return CreateLShr(n, ConstantInt::get(divisor->getType(), std::log2(d)), Name);
    80             } else if (d == 1) {
    81                 return number;
    82             }
    83         }
     77Value * CBuilder::CreateUDivCeil(Value * const number, Value * const divisor, const Twine & Name) {
     78    assert (number->getType() == divisor->getType());
     79    if (isa<ConstantInt>(divisor)) {
     80        return CreateUDivCeil(number, cast<ConstantInt>(divisor)->getZExtValue(), Name);
    8481    }
    8582    CreateAssert(divisor, "CreateUDivCeil divisor cannot be 0!");
    86     return CreateUDiv(CreateAdd(number, CreateSub(divisor, ConstantInt::get(divisor->getType(), 1))), divisor, Name);
    87 }
    88 
    89 Value * CBuilder::CreateRoundUp(Value * number, Value * divisor, const Twine &Name) {
     83    Constant * const one = ConstantInt::get(divisor->getType(), 1);
     84    return CreateUDiv(CreateAdd(number, CreateSub(divisor, one)), divisor, Name);
     85}
     86
     87Value * CBuilder::CreateUDivCeil(Value * const number, const uint64_t divisor, const Twine & Name) {
     88    assert ("CreateUDivCeil divisor cannot be 0!" && divisor);
     89    Type * const t = number->getType();
     90    Value * const n = CreateAdd(number, ConstantInt::get(t, divisor - 1));
     91    if (is_power_2(divisor)) {
     92        if (divisor > 1) {
     93            return CreateLShr(n, ConstantInt::get(t, std::log2(divisor)), Name);
     94        } else {
     95            return number;
     96        }
     97    }
     98    Constant * const d = ConstantInt::get(t, divisor);
     99    CreateAssert(d, "CreateUDivCeil divisor cannot be 0!");
     100    return CreateUDiv(n, d, Name);
     101}
     102
     103Value * CBuilder::CreateRoundUp(Value * const number, Value * const divisor, const Twine &Name) {
    90104    return CreateMul(CreateUDivCeil(number, divisor), divisor, Name);
    91105}
     
    738752    }
    739753    out.changeColor(raw_fd_ostream::WHITE, true);
    740     out << "Assertion `" << msg << "' failed.\n";
     754    out << msg << "\n";
    741755    out.resetColor();
    742756    out.flush();
     
    10551069
    10561070#ifdef HAS_ADDRESS_SANITIZER
    1057 #define CHECK_ADDRESS_SANITIZER(Ptr, Name) \
     1071Value * checkHeapAddress(CBuilder * const b, Value * const Ptr) {
     1072    Module * const m = b->getModule();
     1073    PointerType * const voidPtrTy = b->getVoidPtrTy();
     1074    IntegerType * const sizeTy = b->getSizeTy();
     1075    Function * isPoisoned = m->getFunction("__asan_region_is_poisoned");
     1076    if (LLVM_UNLIKELY(isPoisoned == nullptr)) {
     1077        isPoisoned = Function::Create(FunctionType::get(voidPtrTy, {voidPtrTy, sizeTy}, false), Function::ExternalLinkage, "__asan_region_is_poisoned", m);
     1078        isPoisoned->setCallingConv(CallingConv::C);
     1079        isPoisoned->setDoesNotAlias(0);
     1080        isPoisoned->setDoesNotAlias(1);
     1081    } \
     1082    Value * const addr = b->CreatePointerCast(Ptr, voidPtrTy);
     1083    ConstantInt * const size = ConstantInt::get(sizeTy, Ptr->getType()->getPointerElementType()->getPrimitiveSizeInBits() / 8);
     1084    Value * check = b->CreateCall(isPoisoned, { addr, size });
     1085    return b->CreateICmpEQ(check, ConstantPointerNull::get(cast<PointerType>(isPoisoned->getReturnType())));
     1086}
     1087#define CHECK_HEAP_ADDRESS(Ptr, Name) \
    10581088if (LLVM_UNLIKELY(hasAddressSanitizer())) { \
    1059     Module * const m = getModule(); \
    1060     PointerType * const voidPtrTy = getVoidPtrTy(); \
    1061     IntegerType * const sizeTy = getSizeTy(); \
    1062     Function * isPoisoned = m->getFunction("__asan_region_is_poisoned"); \
    1063     if (LLVM_UNLIKELY(isPoisoned == nullptr)) { \
    1064         isPoisoned = Function::Create(FunctionType::get(voidPtrTy, {voidPtrTy, sizeTy}, false), Function::ExternalLinkage, "__asan_region_is_poisoned", m); \
    1065         isPoisoned->setCallingConv(CallingConv::C); \
    1066         isPoisoned->setDoesNotAlias(0); \
    1067         isPoisoned->setDoesNotAlias(1); \
     1089    CreateAssert(checkHeapAddress(this, Ptr), Name " was given unallocated memory address"); \
     1090}
     1091#else
     1092#define CHECK_HEAP_ADDRESS(Ptr, Name)
     1093#endif
     1094
     1095static AllocaInst * resolveStackAddress(Value * Ptr) {
     1096    while (isa<GetElementPtrInst>(Ptr)) {
     1097        Ptr = cast<GetElementPtrInst>(Ptr)->getPointerOperand();
     1098    }
     1099    return dyn_cast<AllocaInst>(Ptr);
     1100}
     1101
     1102static Value * checkStackAddress(CBuilder * const b, Value * const Ptr, AllocaInst * const Base) {
     1103    DataLayout DL(b->getModule());
     1104    IntegerType * const intPtrTy = cast<IntegerType>(DL.getIntPtrType(Ptr->getType()));
     1105    Value * sz = ConstantExpr::getSizeOf(Base->getAllocatedType());
     1106    sz = b->CreateZExtOrTrunc(sz, intPtrTy);
     1107    if (dyn_cast_or_null<Constant>(Base->getArraySize()) && !cast<Constant>(Base->getArraySize())->isNullValue()) {
     1108        sz = b->CreateMul(sz, b->CreateZExtOrTrunc(Base->getArraySize(), intPtrTy));
     1109    }
     1110    Value * const p = b->CreatePtrToInt(Ptr, intPtrTy);
     1111    Value * const s = b->CreatePtrToInt(Base, intPtrTy);
     1112    Value * const e = b->CreateAdd(s, sz);
     1113    return b->CreateAnd(b->CreateICmpUGE(p, s), b->CreateICmpULT(p, e));
     1114}
     1115
     1116#define CHECK_ADDRESS(Ptr, Name) \
     1117if (codegen::EnableAsserts) { \
     1118    CreateAssert(Ptr, Name " was given a null address"); \
     1119    if (AllocaInst * Base = resolveStackAddress(Ptr)) { \
     1120        CreateAssert(checkStackAddress(this, Ptr, Base), Name " was given an invalid stack address"); \
     1121    } else { \
     1122        CHECK_HEAP_ADDRESS(Ptr, Name) \
    10681123    } \
    1069     Value * const addr = CreatePointerCast(Ptr, voidPtrTy); \
    1070     ConstantInt * const size = ConstantInt::get(sizeTy, Ptr->getType()->getPointerElementType()->getPrimitiveSizeInBits() / 8); \
    1071     Value * check = CreateCall(isPoisoned, { addr, size }); \
    1072     check = CreateICmpEQ(check, ConstantPointerNull::get(cast<PointerType>(isPoisoned->getReturnType()))); \
    1073     CreateAssert(check, Name ": invalid memory address"); \
    1074 }
    1075 #else
    1076 #define CHECK_ADDRESS_SANITIZER(Ptr, Name)
    1077 #endif
    1078 
    1079 #define CHECK_ADDRESS(Ptr, Name) \
    1080     if (codegen::EnableAsserts) { \
    1081         CreateAssert(Ptr, Name ": null pointer address"); \
    1082         CHECK_ADDRESS_SANITIZER(Ptr, Name) \
    1083     }
    1084 
    1085 LoadInst * CBuilder::CreateLoad(Value *Ptr, const char * Name) {   
     1124}
     1125
     1126LoadInst * CBuilder::CreateLoad(Value *Ptr, const char * Name) {
    10861127    CHECK_ADDRESS(Ptr, "CreateLoad");
    10871128    return IRBuilder<>::CreateLoad(Ptr, Name);
     
    10981139}
    10991140
    1100 LoadInst * CBuilder::CreateLoad(Value *Ptr, bool isVolatile, const Twine & Name) {
     1141LoadInst * CBuilder::CreateLoad(Value *Ptr, bool isVolatile, const Twine & Name) {   
    11011142    CHECK_ADDRESS(Ptr, "CreateLoad");
    11021143    return IRBuilder<>::CreateLoad(Ptr, isVolatile, Name);
     
    11081149    return IRBuilder<>::CreateStore(Val, Ptr, isVolatile);
    11091150}
    1110 
    1111 #undef CHECK_ADDRESS
    11121151
    11131152inline bool CBuilder::hasAddressSanitizer() const {
  • icGREP/icgrep-devel/icgrep/IR_Gen/CBuilder.h

    r5675 r5706  
    5757    llvm::Value * CreateUDivCeil(llvm::Value * number, llvm::Value * divisor, const llvm::Twine &Name = "");
    5858   
     59    llvm::Value * CreateUDivCeil(llvm::Value * number, const uint64_t divisor, const llvm::Twine &Name = "");
     60
    5961    // Round up to a multiple of divisor.
    6062    llvm::Value * CreateRoundUp(llvm::Value * number, llvm::Value * divisor, const llvm::Twine &Name = "");
    6163           
     64    // Get minimum of two unsigned numbers
     65    llvm::Value * CreateUMin(llvm::Value * a, llvm::Value * b) {
     66        assert (a->getType() == b->getType());
     67        return CreateSelect(CreateICmpULT(a, b), a, b);
     68    }
     69
     70    // Get minimum of two signed numbers
     71    llvm::Value * CreateSMin(llvm::Value * a, llvm::Value * b) {
     72        assert (a->getType() == b->getType());
     73        return CreateSelect(CreateICmpSLT(a, b), a, b);
     74    }
     75
     76    // Get maximum of two unsigned numbers
     77    llvm::Value * CreateUMax(llvm::Value * a, llvm::Value * b) {
     78        assert (a->getType() == b->getType());
     79        return CreateSelect(CreateICmpUGT(a, b), a, b);
     80    }
     81
     82    // Get maximum of two signed numbers
     83    llvm::Value * CreateSMax(llvm::Value * a, llvm::Value * b) {
     84        assert (a->getType() == b->getType());
     85        return CreateSelect(CreateICmpSGT(a, b), a, b);
     86    }
     87
    6288    llvm::Value * CreateMalloc(llvm::Value * size);
    6389
Note: See TracChangeset for help on using the changeset viewer.