Ignore:
Timestamp:
Jan 3, 2017, 3:59:33 PM (22 months ago)
Author:
nmedfort
Message:

Work on bracket matching problem

File:
1 edited

Legend:

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

    r5243 r5245  
    7575    DataLayout DL(getModule());
    7676    Type * const intTy = getIntPtrTy(DL);
    77     Type * const voidPtrTy = getVoidPtrTy();
    78     Function * malloc = cast<Function>(getModule()->getOrInsertFunction("malloc", voidPtrTy, intTy, nullptr));
    79     malloc->setDoesNotAlias(0);
    80     const auto width = ConstantExpr::getSizeOf(type);
     77    Constant * const width = ConstantExpr::getSizeOf(type);
     78    if (size->getType() != intTy) {
     79        if (isa<Constant>(size)) {
     80            size = ConstantExpr::getIntegerCast(cast<Constant>(size), intTy, false);
     81        } else {
     82            size = CreateTruncOrBitCast(size, intTy);
     83        }
     84    }
    8185    if (!width->isOneValue()) {
    8286        if (isa<Constant>(size)) {
     
    8690        }
    8791    }
    88     size = CreateTruncOrBitCast(size, intTy);
    89     CallInst * ci = CreateCall(malloc, {size});
     92    Module * const m = getModule();
     93    Function * malloc = m->getFunction("malloc");
     94    if (malloc == nullptr) {
     95        Type * const voidPtrTy = getVoidPtrTy();
     96        malloc = cast<Function>(m->getOrInsertFunction("malloc", voidPtrTy, intTy, nullptr));
     97        malloc->setCallingConv(CallingConv::C);
     98        malloc->setDoesNotAlias(0);
     99    }
     100    CallInst * ci = CreateCall(malloc, size);
    90101    ci->setTailCall();
    91102    ci->setCallingConv(malloc->getCallingConv());
     
    98109    IntegerType * const intTy = getIntPtrTy(DL);
    99110    const auto byteWidth = (intTy->getBitWidth() / 8);
    100     const auto offset = ConstantInt::get(intTy, alignment + byteWidth - 1);
    101     const auto width = ConstantExpr::getSizeOf(type);
     111    Constant * const offset = ConstantInt::get(intTy, alignment + byteWidth - 1);
     112    Constant * const width = ConstantExpr::getSizeOf(type);
    102113    if (!width->isOneValue()) {
    103114        if (isa<Constant>(size)) {
     
    105116        } else {
    106117            size = CreateMul(size, width);
     118        }
     119    }
     120    if (size->getType() != intTy) {
     121        if (isa<Constant>(size)) {
     122            size = ConstantExpr::getIntegerCast(cast<Constant>(size), intTy, false);
     123        } else {
     124            size = CreateTruncOrBitCast(size, intTy);
    107125        }
    108126    }
     
    112130        size = CreateAdd(size, offset);
    113131    }
    114     size = CreateTruncOrBitCast(size, intTy);
    115     Value * unaligned = CreateMalloc(getInt8Ty(), size);
    116     Value * aligned = CreateBitOrPointerCast(unaligned, intTy);
    117     aligned = CreateAnd(CreateAdd(aligned, offset), ConstantExpr::getNot(ConstantInt::get(intTy, alignment - 1)));
    118     Value * ptr = CreateBitOrPointerCast(CreateSub(aligned, ConstantInt::get(intTy, byteWidth)), intTy->getPointerTo());
    119     CreateAlignedStore(CreateBitOrPointerCast(unaligned, intTy), ptr, byteWidth);
    120     return CreateBitOrPointerCast(aligned, type->getPointerTo());
    121 }
    122 
    123 void CBuilder::CreateFree(Value * ptr) {
     132    Value * unaligned = CreatePtrToInt(CreateMalloc(getInt8Ty(), size), intTy);
     133    Value * aligned = CreateAnd(CreateAdd(unaligned, offset), ConstantExpr::getNot(ConstantInt::get(intTy, alignment - 1)));
     134    Value * prefix = CreateIntToPtr(CreateSub(aligned, ConstantInt::get(intTy, byteWidth)), intTy->getPointerTo());
     135    assert (unaligned->getType() == prefix->getType()->getPointerElementType());
     136    CreateAlignedStore(unaligned, prefix, byteWidth);
     137    return CreateIntToPtr(aligned, type->getPointerTo());
     138}
     139
     140void CBuilder::CreateFree(Value * const ptr) {
     141    assert (ptr->getType()->isPointerTy());
     142    Module * const m = getModule();
    124143    PointerType * const voidPtrTy = getVoidPtrTy();
    125     Function * const free = cast<Function>(getModule()->getOrInsertFunction("free", getVoidTy(), voidPtrTy, nullptr));
    126     CallInst * const ci = CreateCall(free, {CreateBitOrPointerCast(ptr, voidPtrTy)});
     144    Function * free = m->getFunction("free");
     145    if (free == nullptr) {
     146        free = cast<Function>(getModule()->getOrInsertFunction("free", getVoidTy(), voidPtrTy, nullptr));
     147        free->setCallingConv(CallingConv::C);
     148    }
     149    CallInst * const ci = CreateCall(free, CreatePointerCast(ptr, voidPtrTy));
    127150    ci->setTailCall();
    128151    ci->setCallingConv(free->getCallingConv());
    129152}
    130153
    131 void CBuilder::CreateAlignedFree(Value * ptr) {
     154void CBuilder::CreateAlignedFree(Value * const ptr, const bool ptrMayBeNull) {
     155    // WARNING: this will cause a segfault if the value of the ptr at runtime is null but ptrMayBeNull was not set
     156    PointerType * type = cast<PointerType>(ptr->getType());
     157    BasicBlock * exit = nullptr;
     158    if (ptrMayBeNull) {
     159        LLVMContext & C = getContext();
     160        BasicBlock * bb = GetInsertBlock();
     161        Function * f = bb->getParent();
     162        exit = BasicBlock::Create(C, "", f, bb);
     163        BasicBlock * entry = BasicBlock::Create(C, "", f, exit);
     164        Value * cond = CreateICmpEQ(ptr, ConstantPointerNull::get(type));
     165        CreateCondBr(cond, exit, entry);
     166        SetInsertPoint(entry);
     167    }
    132168    DataLayout DL(getModule());
    133169    IntegerType * const intTy = getIntPtrTy(DL);
    134170    const auto byteWidth = (intTy->getBitWidth() / 8);
    135     ptr = CreateBitOrPointerCast(ptr, intTy);
    136     ptr = CreateSub(ptr, ConstantInt::get(intTy, byteWidth));
    137     ptr = CreateBitOrPointerCast(ptr, getInt8PtrTy());
    138     CreateFree(CreateAlignedLoad(ptr, byteWidth));
     171    Value * prefix = CreatePtrToInt(ptr, intTy);
     172    prefix = CreateSub(prefix, ConstantInt::get(intTy, byteWidth));
     173    prefix = CreateIntToPtr(prefix, intTy->getPointerTo());
     174    prefix = CreateIntToPtr(CreateAlignedLoad(prefix, byteWidth), type);
     175    CreateFree(prefix);
     176    if (ptrMayBeNull) {
     177        CreateBr(exit);
     178        SetInsertPoint(exit);
     179    }
    139180}
    140181
    141182Value * CBuilder::CreateRealloc(Value * ptr, Value * size) {
    142     assert (ptr->getType()->isPointerTy());
    143     DataLayout DL(getModule());
    144     IntegerType * const intTy = getIntPtrTy(DL);
    145     PointerType * const voidPtrTy = getVoidPtrTy();
    146     Function * realloc = cast<Function>(getModule()->getOrInsertFunction("realloc", voidPtrTy, voidPtrTy, intTy, nullptr));
    147     realloc->setDoesNotAlias(0);
    148     Type * const type = ptr->getType();
    149     // calculate our new size parameter
    150     size = CreateMul(size, ConstantExpr::getSizeOf(type->getPointerElementType()));
    151     size = CreateTruncOrBitCast(size, intTy);
    152     // call realloc with the pointer and adjusted size
     183    DataLayout DL(getModule());
     184    Type * const intTy = getIntPtrTy(DL);
     185    PointerType * type = cast<PointerType>(ptr->getType());
     186    Constant * const width = ConstantExpr::getSizeOf(type->getPointerElementType());
     187    if (size->getType() != intTy) {
     188        if (isa<Constant>(size)) {
     189            size = ConstantExpr::getIntegerCast(cast<Constant>(size), intTy, false);
     190        } else {
     191            size = CreateTruncOrBitCast(size, intTy);
     192        }
     193    }
     194    if (!width->isOneValue()) {
     195        if (isa<Constant>(size)) {
     196            size = ConstantExpr::getMul(cast<Constant>(size), width);
     197        } else {
     198            size = CreateMul(size, width);
     199        }
     200    }
     201    Module * const m = getModule();
     202    Function * realloc = m->getFunction("realloc");
     203    if (realloc == nullptr) {
     204        Type * const voidPtrTy = getVoidPtrTy();
     205        realloc = cast<Function>(m->getOrInsertFunction("realloc", voidPtrTy, voidPtrTy, intTy, nullptr));
     206        realloc->setCallingConv(CallingConv::C);
     207        realloc->setDoesNotAlias(1);
     208    }
    153209    CallInst * ci = CreateCall(realloc, {ptr, size});
    154210    ci->setTailCall();
     
    157213}
    158214
    159 Value * CBuilder::CreateAlignedRealloc(Value * ptr, Value * size, const unsigned alignment) {
    160     assert ((alignment & (alignment - 1)) == 0); // is power of 2
    161     assert (ptr->getType()->isPointerTy());
    162     DataLayout DL(getModule());
    163     IntegerType * const intTy = getIntPtrTy(DL);
    164     PointerType * const bpTy = getInt8PtrTy();
    165     Type * const type = ptr->getType();
    166     // calculate our new size parameter
    167     const auto byteWidth = (intTy->getBitWidth() / 8);
    168     const auto offset = ConstantInt::get(intTy, alignment + byteWidth - 1);
    169     const auto width = ConstantExpr::getSizeOf(type);
    170     if (!width->isOneValue()) {
    171         if (isa<Constant>(size)) {
    172             size = ConstantExpr::getMul(cast<Constant>(size), width);
    173         } else {
    174             size = CreateMul(size, width);
    175         }
    176     }
    177     if (isa<Constant>(size)) {
    178         size = ConstantExpr::getAdd(cast<Constant>(size), offset);
    179     } else {
    180         size = CreateAdd(size, offset);
    181     }
    182     size = CreateTruncOrBitCast(size, intTy);
    183     // calculate the offset containing the unaligned pointer address
    184     ptr = CreateBitOrPointerCast(ptr, bpTy);
    185     ptr = CreateSub(ptr, ConstantInt::get(intTy, byteWidth));
    186     ptr = CreateBitOrPointerCast(ptr, intTy->getPointerTo());
    187     // load the unaligned pointer as an uint8 *
    188     ptr = CreateAlignedLoad(ptr, byteWidth);
    189     ptr = CreateBitOrPointerCast(ptr, bpTy);
    190     // call realloc with the unaligned pointer and adjusted size
    191     Value * unaligned = CreateRealloc(ptr, size);
    192     Value * aligned = CreateBitOrPointerCast(unaligned, intTy);
    193     aligned = CreateAnd(CreateAdd(aligned, offset), ConstantExpr::getNot(ConstantInt::get(intTy, alignment - 1)));
    194     Value * prefix = CreateBitOrPointerCast(CreateSub(aligned, ConstantInt::get(intTy, byteWidth)), intTy->getPointerTo());
    195     CreateAlignedStore(CreateBitOrPointerCast(unaligned, intTy), prefix, byteWidth);
    196     return CreateBitOrPointerCast(aligned, type);
    197 }
    198 
    199215void CBuilder::CreateMemZero(Value * ptr, Value * size, const unsigned alignment) {
    200216    assert (ptr->getType()->isPointerTy() && size->getType()->isIntegerTy());
    201217    Type * const type = ptr->getType();
    202     const auto width = ConstantExpr::getSizeOf(type->getPointerElementType());
     218    Constant * const width = ConstantExpr::getSizeOf(type->getPointerElementType());
    203219    if (isa<Constant>(size)) {
    204220        size = ConstantExpr::getMul(cast<Constant>(size), width);
     
    206222        size = CreateMul(size, width);
    207223    }
    208     CreateMemSet(CreateBitOrPointerCast(ptr, getInt8PtrTy()), getInt8(0), size, alignment);
     224    CreateMemSet(CreatePointerCast(ptr, getInt8PtrTy()), getInt8(0), size, alignment);
    209225}
    210226
     
    233249//
    234250Value * CBuilder::CreatePThreadCreateCall(Value * thread, Value * attr, Function * start_routine, Value * arg) {
    235 
    236     Type * pthreadTy = getSizeTy();
    237     FunctionType * funVoidPtrVoidTy = FunctionType::get(getVoidTy(), getVoidPtrTy(), false);
    238    
    239     Function * pthreadCreateFunc = cast<Function>(mMod->getOrInsertFunction("pthread_create",
    240                                                                          getInt32Ty(),
    241                                                                          pthreadTy->getPointerTo(),
    242                                                                          getVoidPtrTy(),
    243                                                                          static_cast<Type *>(funVoidPtrVoidTy)->getPointerTo(),
    244                                                                          getVoidPtrTy(), nullptr));
    245     pthreadCreateFunc->setCallingConv(llvm::CallingConv::C);
     251    Function * pthreadCreateFunc = mMod->getFunction("pthread_create");
     252    if (pthreadCreateFunc == nullptr) {
     253        Type * pthreadTy = getSizeTy();
     254        FunctionType * funVoidPtrVoidTy = FunctionType::get(getVoidTy(), getVoidPtrTy(), false);
     255
     256        pthreadCreateFunc = cast<Function>(mMod->getOrInsertFunction("pthread_create",
     257                                                                     getInt32Ty(),
     258                                                                     pthreadTy->getPointerTo(),
     259                                                                     getVoidPtrTy(),
     260                                                                     static_cast<Type *>(funVoidPtrVoidTy)->getPointerTo(),
     261                                                                     getVoidPtrTy(), nullptr));
     262        pthreadCreateFunc->setCallingConv(llvm::CallingConv::C);
     263    }
    246264    return CreateCall(pthreadCreateFunc, {thread, attr, start_routine, arg});
    247265}
     
    251269
    252270Value * CBuilder::CreatePThreadExitCall(Value * value_ptr) {
    253     Function * pthreadExitFunc = cast<Function>(mMod->getOrInsertFunction("pthread_exit",
    254                                                                             getVoidTy(),
    255                                                                             getVoidPtrTy(), nullptr));
    256     pthreadExitFunc->addFnAttr(llvm::Attribute::NoReturn);
    257     pthreadExitFunc->setCallingConv(llvm::CallingConv::C);
    258     return CreateCall(pthreadExitFunc, {value_ptr});
     271    Function * pthreadExitFunc = mMod->getFunction("pthread_exit");
     272    if (pthreadExitFunc == nullptr) {
     273        pthreadExitFunc = cast<Function>(mMod->getOrInsertFunction("pthread_exit", getVoidTy(), getVoidPtrTy(), nullptr));
     274        pthreadExitFunc->addFnAttr(llvm::Attribute::NoReturn);
     275        pthreadExitFunc->setCallingConv(llvm::CallingConv::C);
     276    }
    259277    CallInst * exitThread = CreateCall(pthreadExitFunc, {value_ptr});
    260278    exitThread->setDoesNotReturn();
Note: See TracChangeset for help on using the changeset viewer.