Changeset 5353 for icGREP/icgrep-devel


Ignore:
Timestamp:
Mar 1, 2017, 4:17:24 PM (2 years ago)
Author:
nmedfort
Message:

Progress on parenthesis matching example

Location:
icGREP/icgrep-devel/icgrep
Files:
13 edited

Legend:

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

    r5350 r5353  
    5858    if (closeFn == nullptr) {
    5959        IntegerType * int32Ty = getInt32Ty();
    60         closeFn = cast<Function>(mMod->getOrInsertFunction("close",
    61                                                            int32Ty, int32Ty, nullptr));
     60        FunctionType * fty = FunctionType::get(int32Ty, {int32Ty}, true);
     61        closeFn = Function::Create(fty, Function::ExternalLinkage, "close", mMod);
    6262    }
    6363    return CreateCall(closeFn, {fildes});
    6464}
    65 
    66 
    6765
    6866Function * CBuilder::GetPrintf() {
    6967    Function * printf = mMod->getFunction("printf");
    7068    if (printf == nullptr) {
    71         printf = cast<Function>(mMod->getOrInsertFunction("printf"
    72                                 , FunctionType::get(getInt32Ty(), {getInt8PtrTy()}, true)
    73                                 , AttributeSet().addAttribute(getContext(), 1U, Attribute::NoAlias)));
    74 
     69        FunctionType * fty = FunctionType::get(getInt32Ty(), {getInt8PtrTy()}, true);
     70        printf = Function::Create(fty, Function::ExternalLinkage, "printf", mMod);
     71        printf->addAttribute(1, Attribute::NoAlias);
    7572    }
    7673    return printf;
     
    134131    if (malloc == nullptr) {
    135132        PointerType * const voidPtrTy = getVoidPtrTy();
    136         malloc = cast<Function>(m->getOrInsertFunction("malloc", voidPtrTy, intTy, nullptr));
     133        FunctionType * fty = FunctionType::get(voidPtrTy, {intTy}, false);
     134        malloc = Function::Create(fty, Function::ExternalLinkage, "malloc", mMod);
    137135        malloc->setCallingConv(CallingConv::C);
    138136        malloc->setDoesNotAlias(0);
     
    191189    Function * free = m->getFunction("free");
    192190    if (free == nullptr) {
    193         free = cast<Function>(getModule()->getOrInsertFunction("free", getVoidTy(), voidPtrTy, nullptr));
     191        FunctionType * fty = FunctionType::get(getVoidTy(), {voidPtrTy}, false);
     192        free = Function::Create(fty, Function::ExternalLinkage, "free", mMod);
    194193        free->setCallingConv(CallingConv::C);
    195194    }
     
    253252    if (realloc == nullptr) {
    254253        PointerType * const voidPtrTy = getVoidPtrTy();
    255         realloc = cast<Function>(m->getOrInsertFunction("realloc", voidPtrTy, voidPtrTy, intTy, nullptr));
     254        FunctionType * fty = FunctionType::get(voidPtrTy, {voidPtrTy, intTy}, false);
     255        realloc = Function::Create(fty, Function::ExternalLinkage, "realloc", mMod);
    256256        realloc->setCallingConv(CallingConv::C);
    257257        realloc->setDoesNotAlias(1);
     
    293293    Function * fOpenFunc = mMod->getFunction("fopen");
    294294    if (fOpenFunc == nullptr) {
    295         fOpenFunc = cast<Function>(mMod->getOrInsertFunction("fopen", getFILEptrTy(), getInt8Ty()->getPointerTo(), getInt8Ty()->getPointerTo(), nullptr));
     295        FunctionType * fty = FunctionType::get(getFILEptrTy(), {getInt8Ty()->getPointerTo(), getInt8Ty()->getPointerTo()}, false);
     296        fOpenFunc = Function::Create(fty, Function::ExternalLinkage, "fopen", mMod);
    296297        fOpenFunc->setCallingConv(CallingConv::C);
    297298    }
     
    302303    Function * fReadFunc = mMod->getFunction("fread");
    303304    if (fReadFunc == nullptr) {
    304         fReadFunc = cast<Function>(mMod->getOrInsertFunction("fread", getSizeTy(), getVoidPtrTy(), getSizeTy(), getSizeTy(), getFILEptrTy(), nullptr));
     305        FunctionType * fty = FunctionType::get(getSizeTy(), {getVoidPtrTy(), getSizeTy(), getSizeTy(), getFILEptrTy()}, false);
     306        fReadFunc = Function::Create(fty, Function::ExternalLinkage, "fread", mMod);
    305307        fReadFunc->setCallingConv(CallingConv::C);
    306308    }
     
    311313    Function * fWriteFunc = mMod->getFunction("fwrite");
    312314    if (fWriteFunc == nullptr) {
    313         fWriteFunc = cast<Function>(mMod->getOrInsertFunction("fwrite", getSizeTy(), getVoidPtrTy(), getSizeTy(), getSizeTy(), getFILEptrTy(), nullptr));
     315        FunctionType * fty = FunctionType::get(getSizeTy(), {getVoidPtrTy(), getSizeTy(), getSizeTy(), getFILEptrTy()}, false);
     316        fWriteFunc = Function::Create(fty, Function::ExternalLinkage, "fwrite", mMod);
    314317        fWriteFunc->setCallingConv(CallingConv::C);
    315318    }
     
    320323    Function * fCloseFunc = mMod->getFunction("fclose");
    321324    if (fCloseFunc == nullptr) {
    322         fCloseFunc = cast<Function>(mMod->getOrInsertFunction("fclose", getInt32Ty(), getFILEptrTy(), nullptr));
     325        FunctionType * fty = FunctionType::get(getInt32Ty(), {getFILEptrTy()}, false);
     326        fCloseFunc = Function::Create(fty, Function::ExternalLinkage, "fclose", mMod);
    323327        fCloseFunc->setCallingConv(CallingConv::C);
    324328    }
     
    330334    if (pthreadCreateFunc == nullptr) {
    331335        Type * pthreadTy = getSizeTy();
    332         FunctionType * funVoidPtrVoidTy = FunctionType::get(getVoidTy(), getVoidPtrTy(), false);
    333 
    334         pthreadCreateFunc = cast<Function>(mMod->getOrInsertFunction("pthread_create",
    335                                                                      getInt32Ty(),
    336                                                                      pthreadTy->getPointerTo(),
    337                                                                      getVoidPtrTy(),
    338                                                                      static_cast<Type *>(funVoidPtrVoidTy)->getPointerTo(),
    339                                                                      getVoidPtrTy(), nullptr));
     336        FunctionType * funVoidPtrVoidTy = FunctionType::get(getVoidTy(), {getVoidPtrTy()}, false);
     337        FunctionType * fty = FunctionType::get(getInt32Ty(), {pthreadTy->getPointerTo(), getVoidPtrTy(), funVoidPtrVoidTy->getPointerTo(), getVoidPtrTy()}, false);
     338        pthreadCreateFunc = Function::Create(fty, Function::ExternalLinkage, "pthread_create", mMod);
    340339        pthreadCreateFunc->setCallingConv(CallingConv::C);
    341340    }
     
    346345    Function * pthreadExitFunc = mMod->getFunction("pthread_exit");
    347346    if (pthreadExitFunc == nullptr) {
    348         pthreadExitFunc = cast<Function>(mMod->getOrInsertFunction("pthread_exit", getVoidTy(), getVoidPtrTy(), nullptr));
     347        FunctionType * fty = FunctionType::get(getVoidTy(), {getVoidPtrTy()}, false);
     348        pthreadExitFunc = Function::Create(fty, Function::ExternalLinkage, "pthread_exit", mMod);
    349349        pthreadExitFunc->addFnAttr(Attribute::NoReturn);
    350350        pthreadExitFunc->setCallingConv(CallingConv::C);
     
    356356
    357357Value * CBuilder::CreatePThreadJoinCall(Value * thread, Value * value_ptr){
    358     Type * pthreadTy = getSizeTy();
    359     Function * pthreadJoinFunc = cast<Function>(mMod->getOrInsertFunction("pthread_join",
    360                                                                        getInt32Ty(),
    361                                                                        pthreadTy,
    362                                                                        getVoidPtrTy()->getPointerTo(), nullptr));
    363     pthreadJoinFunc->setCallingConv(CallingConv::C);
     358    Function * pthreadJoinFunc = mMod->getFunction("pthread_join");
     359    if (pthreadJoinFunc == nullptr) {
     360        Type * pthreadTy = getSizeTy();
     361        FunctionType * fty = FunctionType::get(getInt32Ty(), {pthreadTy, getVoidPtrTy()->getPointerTo()}, false);
     362        pthreadJoinFunc = Function::Create(fty, Function::ExternalLinkage, "pthread_join", mMod);
     363        pthreadJoinFunc->setCallingConv(CallingConv::C);
     364    }
    364365    return CreateCall(pthreadJoinFunc, {thread, value_ptr});
    365366}
     
    367368void CBuilder::CreateAssert(Value * const assertion, StringRef failureMessage) {
    368369    if (codegen::EnableAsserts) {
    369         Module * const m = getModule();
    370         Function * function = m->getFunction("__assert");
     370        Function * function = mMod->getFunction("__assert");
    371371        if (LLVM_UNLIKELY(function == nullptr)) {
    372372            auto ip = saveIP();
    373             function = cast<Function>(m->getOrInsertFunction("__assert", getVoidTy(), getInt1Ty(), getInt8PtrTy(), getSizeTy(), nullptr));
     373            FunctionType * fty = FunctionType::get(getVoidTy(), { getInt1Ty(), getInt8PtrTy(), getSizeTy() }, false);
     374            function = Function::Create(fty, Function::PrivateLinkage, "__assert", mMod);
    374375            function->setDoesNotThrow();
    375376            function->setDoesNotAlias(2);
     
    405406
    406407void CBuilder::CreateExit(const int exitCode) {
    407     Module * const m = getModule();
    408     Function * exit = m->getFunction("exit");
     408    Function * exit = mMod->getFunction("exit");
    409409    if (LLVM_UNLIKELY(exit == nullptr)) {
    410         exit = cast<Function>(m->getOrInsertFunction("exit", getVoidTy(), getInt32Ty(), nullptr));
     410        FunctionType * fty = FunctionType::get(getVoidTy(), {getInt32Ty()}, false);
     411        exit = Function::Create(fty, Function::ExternalLinkage, "exit", mMod);
    411412        exit->setDoesNotReturn();
    412413        exit->setDoesNotThrow();
  • icGREP/icgrep-devel/icgrep/IR_Gen/CBuilder.h

    r5350 r5353  
    4343
    4444    llvm::CallInst * CreateMemZero(llvm::Value * ptr, llvm::Value * size, const unsigned alignment = 1) {
    45         return CreateMemSet(CreatePointerCast(ptr, getInt8PtrTy()), getInt8(0), size, alignment);
     45        return CreateMemSet(ptr, getInt8(0), size, alignment);
    4646    }
    4747
  • icGREP/icgrep-devel/icgrep/array-test.cpp

    r5337 r5353  
    8888        body.createAssign(pending_lparen, body.createAnd(pscan, lparen));
    8989        // Mark any opening paren without a matching closer as an error.
    90         body.createAssign(accumulated_errors, body.createOr(accumulated_errors, body.createAtEOF(pscan)));
     90        PabloAST * unmatched_lparen = body.createAtEOF(pscan, "unmatched_lparen");
     91        body.createAssign(accumulated_errors, body.createOr(accumulated_errors, unmatched_lparen));
    9192
    9293        body.createAssign(body.createExtract(matches, index), closed);
     
    102103}
    103104
    104 
    105105Function * pipeline(IDISA::IDISA_Builder * iBuilder, const unsigned count) {
    106106
    107     Type * byteStreamTy = iBuilder->getStreamSetTy(1, 2);
     107    Type * byteStreamTy = iBuilder->getStreamSetTy(1, 8);
    108108
    109109    Module * const mod = iBuilder->getModule();
    110    
     110
    111111    Function * const main = cast<Function>(mod->getOrInsertFunction("Main", iBuilder->getVoidTy(), byteStreamTy->getPointerTo(), iBuilder->getSizeTy(), nullptr));
    112112    main->setCallingConv(CallingConv::C);
     
    117117    Value * const fileSize = &*(args++);
    118118    fileSize->setName("fileSize");
     119
     120    const unsigned segmentSize = codegen::SegmentSize;
     121    const unsigned bufferSegments = codegen::BufferSegments;
    119122   
    120     ExternalFileBuffer ByteStream(iBuilder, byteStreamTy);
    121     SingleBlockBuffer BasisBits(iBuilder, iBuilder->getStreamSetTy(8, 1));
    122     ExpandableBuffer matches(iBuilder, iBuilder->getStreamSetTy(count, 1), 2);
    123     SingleBlockBuffer errors(iBuilder, iBuilder->getStreamTy());
    124 
    125     MMapSourceKernel mmapK(iBuilder);
     123    ExternalFileBuffer ByteStream(iBuilder, iBuilder->getStreamSetTy(1, 8));
     124
     125    kernel::MMapSourceKernel mmapK(iBuilder, segmentSize);
    126126    mmapK.generateKernel({}, {&ByteStream});
    127127    mmapK.setInitialArguments({fileSize});
    128    
    129     S2PKernel s2pk(iBuilder);
     128
     129    CircularBuffer BasisBits(iBuilder, iBuilder->getStreamSetTy(8), segmentSize * bufferSegments);
     130
     131    kernel::S2PKernel  s2pk(iBuilder);
    130132    s2pk.generateKernel({&ByteStream}, {&BasisBits});
    131133
     
    136138    generate(&bm);
    137139    pablo_function_passes(&bm);
     140
     141    ExpandableBuffer matches(iBuilder, iBuilder->getStreamSetTy(count), segmentSize * bufferSegments);
     142    SingleBlockBuffer errors(iBuilder, iBuilder->getStreamTy());
    138143
    139144    bm.generateKernel({&BasisBits}, {&matches, &errors});
     
    162167    IDISA::IDISA_Builder * idb = IDISA::GetIDISA_Builder(M);
    163168
    164     llvm::Function * f = pipeline(idb, 4);
     169    llvm::Function * f = pipeline(idb, 3);
    165170
    166171    verifyModule(*M, &dbgs());
     
    175180}
    176181
    177 void run(MatchParens f, const std::string & fileName) {
     182template <typename T>
     183std::ostream & operator<< (std::ostream& out, const std::vector<T>& v) {
     184  if ( !v.empty() ) {
     185    out << '[';
     186    std::copy (v.begin(), v.end(), std::ostream_iterator<T>(out, ", "));
     187    out << "\b\b]";
     188  }
     189  return out;
     190}
     191
     192void check(const char * byteStream, const size_t fileSize) {
     193
     194    std::vector<size_t> unmatched_left;
     195    std::vector<size_t> unmatched_right;
     196    size_t maxDepth = 0;
     197    for (size_t i = 0; i < fileSize; ++i) {
     198        switch (byteStream[i]) {
     199            case '(':
     200                unmatched_left.push_back(i);
     201                maxDepth = std::max<size_t>(maxDepth, unmatched_left.size());
     202                break;
     203            case ')':
     204                if (unmatched_left.empty()) {
     205                    unmatched_right.push_back(i);
     206                } else {
     207                    unmatched_left.pop_back();
     208                }
     209            default:
     210                break;
     211        }
     212    }
     213
     214    std::cerr << "maximum depth:        " << maxDepth << "\n"
     215                 "invalid left parens:  " << unmatched_left << "\n"
     216                 "invalid right parens: " << unmatched_right <<
     217                 std::endl;
     218}
     219
     220
     221void run(MatchParens match, const std::string & fileName) {
    178222    const boost::filesystem::path file(fileName);
    179223    if (exists(file)) {
     
    186230            mappedFile.open(fileName);
    187231            char * fileBuffer = const_cast<char *>(mappedFile.data());
    188             f(fileBuffer, fileSize);
     232            check(fileBuffer, fileSize);
     233            match(fileBuffer, fileSize);
    189234            mappedFile.close();
    190235        }
  • icGREP/icgrep-devel/icgrep/grep_engine.cpp

    r5348 r5353  
    466466    }
    467467#endif
    468     if (CPU_Only){
     468    if (CPU_Only) {
    469469        mainFn = cast<Function>(M->getOrInsertFunction("Main", resultTy, inputType, size_ty, size_ty, nullptr));
    470470        mainFn->setCallingConv(CallingConv::C);
     
    511511    if (CountOnly) {
    512512        icgrepK.generateKernel({&BasisBits}, {});
    513         if (pipelineParallel){
     513        if (pipelineParallel) {
    514514            generatePipelineParallel(iBuilder, {&mmapK, &s2pk, &icgrepK});
    515         } else if (segmentPipelineParallel){
     515        } else if (segmentPipelineParallel) {
    516516            generateSegmentParallelPipeline(iBuilder, {&mmapK, &s2pk, &icgrepK});
    517517        } else {
     
    540540            scanMatchK.setInitialArguments({iBuilder->CreateBitCast(inputStream, int8PtrTy), fileSize, fileIdx});
    541541           
    542             if (pipelineParallel){
    543                 generatePipelineParallel(iBuilder, {&mmapK, &s2pk, &icgrepK, linebreakK, &scanMatchK});
    544             } else if (segmentPipelineParallel){
    545                 generateSegmentParallelPipeline(iBuilder, {&mmapK, &s2pk, &icgrepK, linebreakK, &scanMatchK});
    546             }  else{
    547                 generatePipelineLoop(iBuilder, {&mmapK, &s2pk, &icgrepK, linebreakK, &scanMatchK});
    548             }
     542            if (pipelineParallel) {
     543                generatePipelineParallel(iBuilder, {&mmapK, &s2pk, &icgrepK, linebreakK, &scanMatchK});
     544            } else if (segmentPipelineParallel) {
     545                generateSegmentParallelPipeline(iBuilder, {&mmapK, &s2pk, &icgrepK, linebreakK, &scanMatchK});
     546            } else {
     547                generatePipelineLoop(iBuilder, {&mmapK, &s2pk, &icgrepK, linebreakK, &scanMatchK});
     548            }
    549549        }
    550550        iBuilder->CreateRetVoid();
  • icGREP/icgrep-devel/icgrep/kernels/alignedprint.cpp

    r5340 r5353  
    245245            i->addIncoming(iBuilder->CreateAdd(i, ONE), iBuilder->GetInsertBlock());
    246246            iBuilder->CreateBr(cond);
     247
    247248            // -------------------------------------------------------------------------
    248249            iBuilder->SetInsertPoint(exit);
     
    250251        }
    251252    }
     253
     254
     255
    252256}
    253257
  • icGREP/icgrep-devel/icgrep/kernels/kernel.cpp

    r5351 r5353  
    473473    PHINode * stridesRemaining = iBuilder->CreatePHI(iBuilder->getSizeTy(), 2, "stridesRemaining");
    474474    stridesRemaining->addIncoming(stridesToDo, entryBlock);
     475    // NOTE: stridesRemaining may go to a negative number in the final block if the generateFinalBlockMethod(...)
     476    // calls CreateDoBlockMethodCall(). Do *not* replace the comparator with an unsigned one!
    475477    Value * notDone = iBuilder->CreateICmpSGT(stridesRemaining, iBuilder->getSize(0));
    476478    iBuilder->CreateLikelyCondBr(notDone, mStrideLoopBody, stridesDone);
     
    544546}
    545547
    546 void BlockOrientedKernel::writeDoBlockMethod() {
     548inline void BlockOrientedKernel::writeDoBlockMethod() {
    547549
    548550    Value * const self = mSelf;
     
    603605}
    604606
    605 void BlockOrientedKernel::writeFinalBlockMethod(Value * remainingItems) {
     607inline void BlockOrientedKernel::writeFinalBlockMethod(Value * remainingItems) {
    606608
    607609    Value * const self = mSelf;
     
    639641
    640642//  The default finalBlock method simply dispatches to the doBlock routine.
    641 void BlockOrientedKernel::generateFinalBlockMethod(Value * remainingItems) {
     643void BlockOrientedKernel::generateFinalBlockMethod(Value * /* remainingItems */) {
    642644    CreateDoBlockMethodCall();
    643645}
  • icGREP/icgrep-devel/icgrep/kernels/streamset.cpp

    r5347 r5353  
    2727
    2828void StreamSetBuffer::allocateBuffer() {
    29     mStreamSetBufferPtr = iBuilder->CreateCacheAlignedAlloca(getType(), iBuilder->getSize(mBufferBlocks));
     29    Type * const ty = getType();
     30    ConstantInt * blocks = iBuilder->getSize(mBufferBlocks);
     31    mStreamSetBufferPtr = iBuilder->CreateCacheAlignedAlloca(ty, iBuilder->getSize(mBufferBlocks));
     32    Constant * width = ConstantExpr::getMul(ConstantExpr::getSizeOf(ty), blocks);
     33    iBuilder->CreateMemZero(mStreamSetBufferPtr, width, iBuilder->getCacheAlignment());
    3034}
    3135
    3236Value * StreamSetBuffer::getStreamBlockPtr(Value * self, Value * streamIndex, Value * blockIndex, const bool /* readOnly */) const {
     37    iBuilder->CreateAssert(iBuilder->CreateICmpULT(streamIndex, getStreamSetCount(self)), "StreamSetBuffer: out-of-bounds stream access");
    3338    return iBuilder->CreateGEP(getStreamSetBlockPtr(self, blockIndex), {iBuilder->getInt32(0), streamIndex});
    3439}
    3540
    3641Value * StreamSetBuffer::getStreamPackPtr(Value * self, Value * streamIndex, Value * blockIndex, Value * packIndex, const bool /* readOnly */) const {
     42    iBuilder->CreateAssert(iBuilder->CreateICmpULT(streamIndex, getStreamSetCount(self)), "StreamSetBuffer: out-of-bounds stream access");
    3743    return iBuilder->CreateGEP(getStreamSetBlockPtr(self, blockIndex), {iBuilder->getInt32(0), streamIndex, packIndex});
     44}
     45
     46inline bool StreamSetBuffer::isCapacityGuaranteed(const llvm::Value * const index, const size_t capacity) const {
     47    if (LLVM_UNLIKELY(isa<ConstantInt>(index))) {
     48        if (LLVM_LIKELY(cast<ConstantInt>(index)->getLimitedValue() < capacity)) {
     49            return true;
     50        }
     51    }
     52    return false;
    3853}
    3954
     
    4459    }
    4560    return iBuilder->getSize(count);
     61}
     62
     63inline llvm::Value * StreamSetBuffer::modByBufferBlocks(llvm::Value * const offset) const {
     64    assert (offset->getType()->isIntegerTy());
     65    if (isCapacityGuaranteed(offset, mBufferBlocks)) {
     66        return offset;
     67    } else if (mBufferBlocks == 1) {
     68        return ConstantInt::getNullValue(iBuilder->getSizeTy());
     69    } else if ((mBufferBlocks & (mBufferBlocks - 1)) == 0) { // is power of 2
     70        return iBuilder->CreateAnd(offset, ConstantInt::get(offset->getType(), mBufferBlocks - 1));
     71    } else {
     72        return iBuilder->CreateURem(offset, ConstantInt::get(offset->getType(), mBufferBlocks));
     73    }
    4674}
    4775
     
    115143
    116144Value * CircularBuffer::getStreamSetBlockPtr(Value * self, Value * blockIndex) const {
    117     assert (blockIndex->getType()->isIntegerTy());
    118     Value * offset = nullptr;
    119     if (mBufferBlocks == 1) {
    120         offset = ConstantInt::getNullValue(iBuilder->getSizeTy());
    121     } else if ((mBufferBlocks & (mBufferBlocks - 1)) == 0) { // is power of 2
    122         offset = iBuilder->CreateAnd(blockIndex, ConstantInt::get(blockIndex->getType(), mBufferBlocks - 1));
    123     } else {
    124         offset = iBuilder->CreateURem(blockIndex, ConstantInt::get(blockIndex->getType(), mBufferBlocks));
    125     }
    126     return iBuilder->CreateGEP(self, offset);
    127 }
    128 
     145    return iBuilder->CreateGEP(self, modByBufferBlocks(blockIndex));
     146}
    129147
    130148// CircularCopybackBuffer Buffer
     
    169187
    170188Value * CircularCopybackBuffer::getStreamSetBlockPtr(Value * self, Value * blockIndex) const {
    171     assert (blockIndex->getType()->isIntegerTy());
    172    
    173     Value * offset = nullptr;
    174     if (mBufferBlocks == 1) {
    175         offset = ConstantInt::getNullValue(iBuilder->getSizeTy());
    176     } else if ((mBufferBlocks & (mBufferBlocks - 1)) == 0) { // is power of 2
    177         offset = iBuilder->CreateAnd(blockIndex, ConstantInt::get(blockIndex->getType(), mBufferBlocks - 1));
    178     } else {
    179         offset = iBuilder->CreateURem(blockIndex, ConstantInt::get(blockIndex->getType(), mBufferBlocks));
    180     }
    181     return iBuilder->CreateGEP(self, offset);
    182 }
    183 
    184 
     189    return iBuilder->CreateGEP(self, modByBufferBlocks(blockIndex));
     190}
    185191
    186192// Expandable Buffer
     
    200206}
    201207
    202 inline bool ExpandableBuffer::isGuaranteedCapacity(const llvm::Value * const index) const {
    203     if (LLVM_UNLIKELY(isa<ConstantInt>(index))) {
    204         if (LLVM_LIKELY(cast<ConstantInt>(index)->getLimitedValue() < mInitialCapacity)) {
    205             return true;
    206         }
    207     }
    208     return false;
    209 }
    210 
    211208std::pair<Value *, Value *> ExpandableBuffer::getInternalStreamBuffer(llvm::Value * self, llvm::Value * streamIndex, Value * blockIndex, const bool readOnly) const {
    212 
    213     // MDNode *Weights = MDBuilder(Ctx).createBranchWeights(42, 13);
    214209
    215210    // ENTRY
     
    218213    Value * const streamSetPtr = iBuilder->CreateGEP(self, {iBuilder->getInt32(0), iBuilder->getInt32(1)});
    219214    Value * const streamSet = iBuilder->CreateLoad(streamSetPtr);
     215    blockIndex = modByBufferBlocks(blockIndex);
     216
     217    assert (streamIndex->getType() == capacity->getType());
     218    Value * const cond = iBuilder->CreateICmpULT(streamIndex, capacity);
    220219
    221220    // Are we guaranteed that we can access this stream?
    222     if (isGuaranteedCapacity(streamIndex)) {
    223         return {streamSet, capacity};
    224     } else if (readOnly) {
    225         iBuilder->CreateAssert(iBuilder->CreateICmpULT(streamIndex, capacity), "ExpandableBuffer: out-of-bounds readonly stream access!");
    226         return {streamSet, capacity};
     221    if (readOnly || isCapacityGuaranteed(streamIndex, mInitialCapacity)) {
     222        iBuilder->CreateAssert(cond, "ExpandableBuffer: out-of-bounds stream access");
     223        Value * offset = iBuilder->CreateAdd(iBuilder->CreateMul(blockIndex, capacity), streamIndex);
     224        return {streamSet, offset};
    227225    }
    228226
     
    231229    BasicBlock * const resume = BasicBlock::Create(iBuilder->getContext(), "resume", entry->getParent());
    232230
    233     assert (streamIndex->getType() == capacity->getType());
    234     Value * cond = iBuilder->CreateICmpULT(streamIndex, capacity);
    235     iBuilder->CreateCondBr(cond, resume, expand);
     231    iBuilder->CreateLikelyCondBr(cond, resume, expand);
     232
    236233    // EXPAND
    237234    iBuilder->SetInsertPoint(expand);
    238     /// TODO: this should call a function rather than be inlined into the block. REVISIT once tested.
    239     Constant * vectorWidth = ConstantExpr::getIntegerCast(ConstantExpr::getSizeOf(streamSet->getType()->getPointerElementType()), capacity->getType(), false);
    240     Value * newCapacity = iBuilder->CreateMul(streamIndex, iBuilder->getSize(2));
     235
     236    Type * elementType = getType()->getStructElementType(1)->getPointerElementType();
     237    Constant * const vectorWidth = ConstantExpr::getIntegerCast(ConstantExpr::getSizeOf(elementType), capacity->getType(), false);
     238    Value * newCapacity = iBuilder->CreateMul(iBuilder->CreateAdd(streamIndex, iBuilder->getSize(1)), iBuilder->getSize(2), "newCapacity");
     239
     240    std::string tmp;
     241    raw_string_ostream out(tmp);
     242    out << "__expand";
     243    elementType->print(out);
     244    std::string name = out.str();
     245
     246    Module * const m = iBuilder->getModule();
     247    Function * expandFunction = m->getFunction(name);
     248
     249    if (expandFunction == nullptr) {
     250
     251        const auto ip = iBuilder->saveIP();
     252
     253        FunctionType * fty = FunctionType::get(elementType->getPointerTo(), {elementType->getPointerTo(), iBuilder->getSizeTy(), iBuilder->getSizeTy()}, false);
     254        expandFunction = Function::Create(fty, GlobalValue::PrivateLinkage, name, m);
     255
     256        auto args = expandFunction->arg_begin();
     257        Value * streamSet = &*args++;
     258        Value * capacity = &*args++;
     259        Value * newCapacity = &*args;
     260
     261        BasicBlock * entry = BasicBlock::Create(iBuilder->getContext(), "entry", expandFunction);
     262        iBuilder->SetInsertPoint(entry);
     263
     264        Value * size = iBuilder->CreateMul(newCapacity, iBuilder->getSize(mBufferBlocks));
     265        Value * newStreamSet = iBuilder->CreateAlignedMalloc(elementType, size, iBuilder->getCacheAlignment());
     266        Value * const diffCapacity = iBuilder->CreateMul(iBuilder->CreateSub(newCapacity, capacity), vectorWidth);
     267
     268        const auto alignment = elementType->getPrimitiveSizeInBits() / 8;
     269        for (unsigned i = 0; i < mBufferBlocks; ++i) {
     270            ConstantInt * const offset = iBuilder->getSize(i);
     271            Value * srcOffset = iBuilder->CreateMul(capacity, offset);
     272            Value * srcPtr = iBuilder->CreateGEP(streamSet, srcOffset);
     273            Value * destOffset = iBuilder->CreateMul(newCapacity, offset);
     274            Value * destPtr = iBuilder->CreateGEP(newStreamSet, destOffset);
     275            iBuilder->CreateMemCpy(destPtr, srcPtr, iBuilder->CreateMul(capacity, vectorWidth), alignment);
     276            Value * destZeroOffset = iBuilder->CreateAdd(destOffset, capacity);
     277            Value * destZeroPtr = iBuilder->CreateGEP(newStreamSet, destZeroOffset);
     278            iBuilder->CreateMemZero(destZeroPtr, diffCapacity, alignment);
     279        }
     280
     281        iBuilder->CreateAlignedFree(streamSet);
     282
     283        iBuilder->CreateRet(newStreamSet);
     284
     285        iBuilder->restoreIP(ip);
     286    }
     287
     288    Value * newStreamSet = iBuilder->CreateCall(expandFunction, {streamSet, capacity, newCapacity});
     289    iBuilder->CreateStore(newStreamSet, streamSetPtr);
    241290    iBuilder->CreateStore(newCapacity, capacityPtr);
    242     Type * bufferType = getType()->getStructElementType(1)->getPointerElementType();
    243     Value * size = iBuilder->CreateMul(newCapacity, iBuilder->getSize(mBufferBlocks));
    244     Value * newStreamSet = iBuilder->CreateAlignedMalloc(bufferType, size, iBuilder->getCacheAlignment());
    245     iBuilder->CreateStore(newStreamSet, streamSetPtr);
    246     Value * const diffCapacity = iBuilder->CreateMul(iBuilder->CreateSub(newCapacity, capacity), vectorWidth);
    247     const auto alignment = bufferType->getPrimitiveSizeInBits() / 8;
    248     for (unsigned i = 0; i < mBufferBlocks; ++i) {
    249         ConstantInt * const offset = iBuilder->getSize(i);
    250         Value * srcOffset = iBuilder->CreateMul(capacity, offset);
    251         Value * srcPtr = iBuilder->CreateGEP(streamSet, srcOffset);
    252         Value * destOffset = iBuilder->CreateMul(newCapacity, offset);
    253         Value * destPtr = iBuilder->CreateGEP(newStreamSet, destOffset);
    254         iBuilder->CreateMemCpy(destPtr, srcPtr, iBuilder->CreateMul(capacity, vectorWidth), alignment);
    255         Value * destZeroOffset = iBuilder->CreateAdd(destOffset, capacity);
    256         Value * destZeroPtr = iBuilder->CreateGEP(newStreamSet, destZeroOffset);
    257         iBuilder->CreateMemZero(destZeroPtr, diffCapacity, alignment);
    258     }
    259 
    260     iBuilder->CreateAlignedFree(streamSet);
     291
    261292    iBuilder->CreateBr(resume);
     293
    262294    // RESUME
    263295    iBuilder->SetInsertPoint(resume);
  • icGREP/icgrep-devel/icgrep/kernels/streamset.h

    r5340 r5353  
    6464    // Get the buffer pointer for a given block of the stream.
    6565    virtual llvm::Value * getStreamSetBlockPtr(llvm::Value * self, llvm::Value * blockNo) const = 0;
     66
     67    bool isCapacityGuaranteed(const llvm::Value * const index, const size_t capacity) const;
     68
     69    llvm::Value * modByBufferBlocks(llvm::Value * const offset) const;
    6670
    6771protected:
     
    175179private:
    176180
    177     bool isGuaranteedCapacity(const llvm::Value * const index) const;
    178 
    179181    std::pair<llvm::Value *, llvm::Value *> getInternalStreamBuffer(llvm::Value * self, llvm::Value * streamIndex, llvm::Value * blockIndex, const bool readOnly) const;
    180182
  • icGREP/icgrep-devel/icgrep/pablo/carry_data.h

    r5347 r5353  
    3434    CarryData()
    3535    : summaryType(NoSummary)   
    36     , variableLength(false)
    37     {
     36    , carryCollapsingMode(false) {
    3837
    3938    }
     
    5554    }
    5655
    57     bool hasVariableLength() const {
    58         return variableLength;
     56    bool nonCarryCollapsingMode() const {
     57        return carryCollapsingMode;
    5958    }
    6059
     60    void setNonCarryCollapsingMode(const bool value = true) {
     61        carryCollapsingMode = value;
     62    }
    6163   
    6264protected:
    6365
    6466    SummaryType             summaryType;
    65     bool                    variableLength;
     67    bool                    carryCollapsingMode;
    6668
    6769};
  • icGREP/icgrep-devel/icgrep/pablo/carry_manager.cpp

    r5347 r5353  
    149149    }
    150150
    151     if (LLVM_UNLIKELY(mCarryInfo->hasVariableLength())) {
     151    if (LLVM_UNLIKELY(mCarryInfo->nonCarryCollapsingMode())) {
    152152        // Check whether we need to resize the carry state
    153153        PHINode * index = iBuilder->CreatePHI(iBuilder->getSizeTy(), 2);
     
    183183        iBuilder->SetInsertPoint(cleanUpBlock);
    184184
    185 
    186 
    187185        iBuilder->CreateMemCpy(newArray, array, iBuilder->CreateMul(capacity, carryStateWidth), iBuilder->getCacheAlignment());
    188186        iBuilder->CreateAlignedFree(array);
     
    218216        mCarrySummary.pop_back();
    219217    }
    220     if (LLVM_UNLIKELY(mCarryInfo->hasVariableLength())) {
     218    if (LLVM_UNLIKELY(mCarryInfo->nonCarryCollapsingMode())) {
    221219        assert (!mLoopIndicies.empty());
    222220        PHINode * index = mLoopIndicies.back();
     
    249247Value * CarryManager::generateSummaryTest(Value * condition) {
    250248    if (LLVM_LIKELY(mCarryInfo->hasSummary())) {
    251         ConstantInt * zero = iBuilder->getInt32(0);
    252         std::vector<Value *> indicies;
    253249        // enter the (potentially nested) struct and extract the summary element (always element 0)
    254250        unsigned count = 2;
     
    261257            }
    262258        }
    263         indicies.assign(count, zero);
    264         if (LLVM_UNLIKELY(mCarryInfo->hasImplicitSummary() && mLoopDepth > 0)) {
    265             indicies.push_back(zero);
    266             indicies.push_back(mLoopSelector);
    267         }
    268         Value * ptr = iBuilder->CreateGEP(mCurrentFrame, indicies);
     259        const bool useLoopSelector = mCarryInfo->hasImplicitSummary() && mLoopDepth > 0;
     260        const auto length = count + (useLoopSelector ? 2 : 0);
     261        Value * indicies[length];
     262        std::fill(indicies, indicies + (count + (useLoopSelector ? 1 : 0)), iBuilder->getInt32(0));
     263        if (LLVM_UNLIKELY(useLoopSelector)) {
     264            indicies[count + 1] = mLoopSelector;
     265        }
     266        ArrayRef<Value *> ar(indicies, length);
     267        Value * ptr = iBuilder->CreateGEP(mCurrentFrame, ar);
    269268        // Sanity check: make sure we're accessing a summary value
    270269        assert (ptr->getType()->getPointerElementType()->canLosslesslyBitCastTo(condition->getType()));
     
    334333    mCarryScopeIndex.push_back(++mCarryScopes);
    335334    mCarryInfo = &mCarryMetadata[mCarryScopes];
    336     // Check whether we're still within our struct bounds; if this fails, either the Pablo program changed within
     335    // Check whether we're still within our struct bounds; if this fails, either the Pablo program changed during
    337336    // compilation or a memory corruption has occured.
    338337    assert (mCurrentFrameIndex < mCurrentFrame->getType()->getPointerElementType()->getStructNumElements());
     
    535534 ** ------------------------------------------------------------------------------------------------------------- */
    536535bool CarryManager::inCollapsingCarryMode() const {
    537     return (mCurrentScope->getBranch() && isa<While>(mCurrentScope->getBranch()) && !mCarryInfo->hasVariableLength());
     536    return (mCurrentScope->getBranch() && isa<While>(mCurrentScope->getBranch()) && !mCarryInfo->nonCarryCollapsingMode());
    538537}
    539538
     
    551550
    552551/** ------------------------------------------------------------------------------------------------------------- *
    553  * @brief requiresVariableLengthMode
    554  ** ------------------------------------------------------------------------------------------------------------- */
    555 bool CarryManager::requiresVariableLengthMode(const PabloBlock * const scope) {
     552 * @brief hasIterationSpecificAssignment
     553 ** ------------------------------------------------------------------------------------------------------------- */
     554bool CarryManager::hasIterationSpecificAssignment(const PabloBlock * const scope) {
    556555    if (const Branch * const br = scope->getBranch()) {
    557556        for (const Var * var : br->getEscaped()) {
     
    628627        carryState = StructType::get(iBuilder->getContext());
    629628    } else {
    630         cd.variableLength = loopDepth > 0 && requiresVariableLengthMode(scope);
     629        cd.setNonCarryCollapsingMode(loopDepth > 0 && hasIterationSpecificAssignment(scope));
    631630        if (ifDepth > 0) {
    632631            // A non-collapsing loop requires a unique summary for each iteration. Thus whenever
     
    646645        carryState = StructType::get(iBuilder->getContext(), state);
    647646        // If we in a loop and cannot use collapsing carry mode, convert the struct into a capacity and pointer pair.
    648         if (LLVM_UNLIKELY(cd.hasVariableLength())) {
     647        if (LLVM_UNLIKELY(cd.nonCarryCollapsingMode())) {
    649648            mHasVariableLengthCarryData = true;
    650649            carryState = StructType::get(iBuilder->getSizeTy(), carryState->getPointerTo(), nullptr);
  • icGREP/icgrep-devel/icgrep/pablo/carry_manager.h

    r5347 r5353  
    8484    static unsigned getScopeCount(PabloBlock * const scope, unsigned index = 0);
    8585
    86     static bool requiresVariableLengthMode(const PabloBlock * const scope);
     86    static bool hasIterationSpecificAssignment(const PabloBlock * const scope);
    8787
    8888    llvm::StructType * analyse(PabloBlock * const scope, const unsigned ifDepth = 0, const unsigned whileDepth = 0);
  • icGREP/icgrep-devel/icgrep/pablo/pablo_compiler.cpp

    r5351 r5353  
    211211
    212212    BasicBlock * whileEntryBlock = iBuilder->GetInsertBlock();
    213     BasicBlock * whileBodyBlock = mKernel->CreateBasicBlock("while.body");
    214     BasicBlock * whileEndBlock = mKernel->CreateBasicBlock("while.end");
    215213
    216214    const auto escaped = whileStatement->getEscaped();
     
    238236
    239237    mCarryManager->enterLoopScope(whileBody);
     238
     239    BasicBlock * whileBodyBlock = mKernel->CreateBasicBlock("while.body");
    240240
    241241    iBuilder->CreateBr(whileBodyBlock);
     
    290290    BasicBlock * const whileExitBlock = iBuilder->GetInsertBlock();
    291291
    292     mCarryManager->leaveLoopBody(whileExitBlock);
    293 
    294292    // Terminate the while loop body with a conditional branch back.
    295293    Value * condition = compileExpression(whileStatement->getCondition());
    296294    if (condition->getType() == iBuilder->getBitBlockType()) {
    297         condition = iBuilder->bitblock_any(condition);
    298     }
     295        condition = iBuilder->bitblock_any(mCarryManager->generateSummaryTest(condition));
     296    }
     297
     298    mCarryManager->leaveLoopBody(whileExitBlock);
     299
     300
    299301#ifdef ENABLE_BOUNDED_WHILE
    300302    if (whileStatement->getBound()) {
     
    338340    }
    339341
     342    BasicBlock * whileEndBlock = mKernel->CreateBasicBlock("while.end");
     343
    340344    iBuilder->CreateCondBr(condition, whileBodyBlock, whileEndBlock);
    341 
    342     whileEndBlock->moveAfter(whileExitBlock);
    343345
    344346    iBuilder->SetInsertPoint(whileEndBlock);
  • icGREP/icgrep-devel/icgrep/toolchain.cpp

    r5351 r5353  
    6464int ThreadNum;
    6565bool EnableAsserts;
    66 
    67 
     66#ifndef NDEBUG
     67#define DEFAULT_TO_TRUE_IN_DEBUG_MODE true
     68#else
     69#define DEFAULT_TO_TRUE_IN_DEBUG_MODE false
     70#endif
    6871
    6972static cl::opt<int, true> BlockSizeOption("BlockSize", cl::location(BlockSize), cl::init(0), cl::desc("specify a block size (defaults to widest SIMD register width in bits)."), cl::cat(CodeGenOptions));
     
    7174static cl::opt<int, true> BufferSegmentsOption("buffer-segments", cl::location(BufferSegments), cl::desc("Buffer Segments"), cl::value_desc("positive integer"), cl::init(1));
    7275static cl::opt<int, true> ThreadNumOption("thread-num", cl::location(ThreadNum), cl::desc("Number of threads used for segment pipeline parallel"), cl::value_desc("positive integer"), cl::init(2));
    73 
    74 static cl::opt<bool, true> EnableAssertsOption("ea", cl::location(EnableAsserts), cl::desc("Enable Asserts"), cl::init(
    75 #ifndef NDEBUG
    76 true
    77 #else
    78 false
    79 #endif
    80 ));
     76static cl::opt<bool, true> EnableAssertsOption("ea", cl::location(EnableAsserts), cl::desc("Enable Asserts"), cl::init(DEFAULT_TO_TRUE_IN_DEBUG_MODE));
    8177
    8278const cl::OptionCategory * codegen_flags() {return &CodeGenOptions;}
Note: See TracChangeset for help on using the changeset viewer.