Ignore:
Timestamp:
Mar 16, 2017, 4:57:11 PM (2 years ago)
Author:
nmedfort
Message:

Continued work on non-carry-collapsing mode support.

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

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/array-test.cpp

    r5364 r5366  
    4545static cl::list<std::string> inputFiles(cl::Positional, cl::desc("<input file ...>"), cl::OneOrMore);
    4646
     47//void generate(PabloKernel * kernel) {
     48
     49//    PabloBuilder pb(kernel->getEntryBlock());
     50
     51//    Var * input = kernel->getInputStreamVar("input");
     52
     53//    PabloAST * basis[8];
     54//    for (int i = 0; i < 8; ++i) {
     55//        basis[i] = pb.createExtract(input, i);
     56//    }
     57
     58//    PabloAST * temp1 = pb.createOr(basis[0], basis[1], "temp1");
     59//    PabloAST * temp2 = pb.createAnd(basis[2], pb.createNot(basis[3]), "temp2");
     60//    PabloAST * temp3 = pb.createAnd(temp2, pb.createNot(temp1), "temp3");
     61//    PabloAST * temp4 = pb.createAnd(basis[4], pb.createNot(basis[5]), "temp4");
     62//    PabloAST * temp5 = pb.createOr(basis[6], basis[7], "temp5");
     63//    PabloAST * temp6 = pb.createAnd(temp4, pb.createNot(temp5), "temp6");
     64//    PabloAST * lparen = pb.createAnd(temp3, temp6, "lparens");
     65//    PabloAST * temp7 = pb.createAnd(basis[7], pb.createNot(basis[6]), "temp7");
     66//    PabloAST * temp8 = pb.createAnd(temp4, temp7, "temp8");
     67//    PabloAST * rparen = pb.createAnd(temp3, temp8, "rparens");
     68//    PabloAST * parens = pb.createOr(lparen, rparen, "parens");
     69
     70
     71//    Var * const pending_lparen = pb.createVar("pending_lparen", lparen);
     72//    Var * const all_closed = pb.createVar("all_closed", pb.createZeroes());
     73//    Var * const accumulated_errors = pb.createVar("accumulated_errors", pb.createZeroes());
     74//    Var * const in_play = pb.createVar("in_play", parens);
     75//    Var * const index = pb.createVar("i", pb.getInteger(0));
     76
     77//    Var * matches = kernel->getOutputStreamVar("matches");
     78
     79//    PabloBuilder body = PabloBuilder::Create(pb);
     80//    PabloBuilder ifPScan = PabloBuilder::Create(body);
     81
     82//    pb.createWhile(pending_lparen, body);
     83
     84//        PabloAST * adv_pending_lparen = body.createAdvance(pending_lparen, 1);
     85
     86//        Var * closed_rparen = body.createVar("closed_rparen", pb.createZeroes());
     87
     88//        body.createIf(adv_pending_lparen, ifPScan); // <-- inefficient but tests whether we're probably calculating the summary later
     89
     90//            PabloAST * pscan = ifPScan.createScanTo(adv_pending_lparen, in_play, "pscan");
     91
     92//            ifPScan.createAssign(pending_lparen, ifPScan.createAnd(pscan, lparen));
     93
     94//            ifPScan.createAssign(closed_rparen, ifPScan.createAnd(pscan, rparen));
     95
     96//            ifPScan.createAssign(all_closed, ifPScan.createOr(all_closed, closed_rparen));
     97
     98//            // Mark any opening paren without a matching closer as an error.
     99//            PabloAST * unmatched_lparen = ifPScan.createAtEOF(pscan, "unmatched_lparen");
     100//            ifPScan.createAssign(accumulated_errors, ifPScan.createOr(accumulated_errors, unmatched_lparen));
     101
     102//            PabloAST * pending_rparen = ifPScan.createAnd(rparen, ifPScan.createNot(all_closed, "open_rparen"), "pending_rparen");
     103
     104//            ifPScan.createAssign(in_play, ifPScan.createOr(pending_lparen, pending_rparen));
     105
     106//        body.createAssign(body.createExtract(matches, index), closed_rparen);
     107
     108//        body.createAssign(index, body.createAdd(index, body.getInteger(1)));
     109
     110//    // Mark any closing paren that was not actually used to close an opener as an error.
     111//    PabloAST * const unmatched_rparen = pb.createAnd(rparen, pb.createNot(all_closed), "unmatched_rparen");
     112//    pb.createAssign(kernel->getOutputStreamVar("errors"), pb.createOr(accumulated_errors, unmatched_rparen));
     113
     114//}
     115
    47116void generate(PabloKernel * kernel) {
    48117
     
    78147
    79148    PabloBuilder body = PabloBuilder::Create(pb);
     149    PabloBuilder ifPScan = PabloBuilder::Create(body);
    80150
    81151    pb.createWhile(pending_lparen, body);
     
    83153        PabloAST * pscan = body.createAdvanceThenScanTo(pending_lparen, in_play, "pscan");
    84154
    85         PabloAST * closed = body.createAnd(pscan, rparen, "closed_rparen");
    86         body.createAssign(all_closed, body.createOr(all_closed, closed));
     155        Var * closed_rparen = body.createVar("closed_rparen", pb.createZeroes());
    87156
    88157        body.createAssign(pending_lparen, body.createAnd(pscan, lparen));
    89         // Mark any opening paren without a matching closer as an error.
    90         PabloAST * unmatched_lparen = body.createAtEOF(pscan, "unmatched_lparen");
    91         body.createAssign(accumulated_errors, body.createOr(accumulated_errors, unmatched_lparen));
    92 
    93         body.createAssign(body.createExtract(matches, index), closed);
    94 
    95         PabloAST * pending_rparen = body.createAnd(rparen, body.createNot(all_closed, "open_rparen"), "pending_rparen");
    96         body.createAssign(in_play, body.createOr(pending_lparen, pending_rparen));
     158
     159        body.createIf(pscan, ifPScan);
     160
     161            ifPScan.createAssign(closed_rparen, ifPScan.createAnd(pscan, rparen));
     162
     163            ifPScan.createAssign(all_closed, ifPScan.createOr(all_closed, closed_rparen));
     164
     165            // Mark any opening paren without a matching closer as an error.
     166            PabloAST * unmatched_lparen = ifPScan.createAtEOF(pscan, "unmatched_lparen");
     167            ifPScan.createAssign(accumulated_errors, ifPScan.createOr(accumulated_errors, unmatched_lparen));
     168
     169            PabloAST * pending_rparen = ifPScan.createAnd(rparen, ifPScan.createNot(all_closed, "open_rparen"), "pending_rparen");
     170
     171            ifPScan.createAssign(in_play, ifPScan.createOr(pending_lparen, pending_rparen));
     172
     173            ifPScan.createAssign(ifPScan.createExtract(matches, index), closed_rparen);
     174
    97175        body.createAssign(index, body.createAdd(index, body.getInteger(1)));
    98176
     
    102180
    103181}
     182
     183//void generate(PabloKernel * kernel) {
     184
     185//    PabloBuilder pb(kernel->getEntryBlock());
     186
     187//    Var * input = kernel->getInputStreamVar("input");
     188
     189//    PabloAST * basis[8];
     190//    for (int i = 0; i < 8; ++i) {
     191//        basis[i] = pb.createExtract(input, i);
     192//    }
     193
     194//    PabloAST * temp1 = pb.createOr(basis[0], basis[1], "temp1");
     195//    PabloAST * temp2 = pb.createAnd(basis[2], pb.createNot(basis[3]), "temp2");
     196//    PabloAST * temp3 = pb.createAnd(temp2, pb.createNot(temp1), "temp3");
     197//    PabloAST * temp4 = pb.createAnd(basis[4], pb.createNot(basis[5]), "temp4");
     198//    PabloAST * temp5 = pb.createOr(basis[6], basis[7], "temp5");
     199//    PabloAST * temp6 = pb.createAnd(temp4, pb.createNot(temp5), "temp6");
     200//    PabloAST * lparen = pb.createAnd(temp3, temp6, "lparens");
     201//    PabloAST * temp7 = pb.createAnd(basis[7], pb.createNot(basis[6]), "temp7");
     202//    PabloAST * temp8 = pb.createAnd(temp4, temp7, "temp8");
     203//    PabloAST * rparen = pb.createAnd(temp3, temp8, "rparens");
     204//    PabloAST * parens = pb.createOr(lparen, rparen, "parens");
     205
     206
     207//    Var * const pending_lparen = pb.createVar("pending_lparen", lparen);
     208//    Var * const all_closed = pb.createVar("all_closed", pb.createZeroes());
     209//    Var * const accumulated_errors = pb.createVar("accumulated_errors", pb.createZeroes());
     210//    Var * const in_play = pb.createVar("in_play", parens);
     211//    Var * const index = pb.createVar("i", pb.getInteger(0));
     212
     213//    Var * matches = kernel->getOutputStreamVar("matches");
     214
     215//    PabloBuilder body = PabloBuilder::Create(pb);
     216
     217//    pb.createWhile(pending_lparen, body);
     218
     219//        PabloAST * pscan = body.createAdvanceThenScanTo(pending_lparen, in_play, "pscan");
     220
     221//        PabloAST * closed_rparen = body.createAnd(pscan, rparen, "closed_rparen");
     222//        body.createAssign(all_closed, body.createOr(all_closed, closed_rparen));
     223
     224//        body.createAssign(pending_lparen, body.createAnd(pscan, lparen));
     225//        // Mark any opening paren without a matching closer as an error.
     226//        PabloAST * unmatched_lparen = body.createAtEOF(pscan, "unmatched_lparen");
     227//        body.createAssign(accumulated_errors, body.createOr(accumulated_errors, unmatched_lparen));
     228
     229//        body.createAssign(body.createExtract(matches, index), closed_rparen);
     230
     231//        PabloAST * pending_rparen = body.createAnd(rparen, body.createNot(all_closed, "open_rparen"), "pending_rparen");
     232//        body.createAssign(in_play, body.createOr(pending_lparen, pending_rparen));
     233//        body.createAssign(index, body.createAdd(index, body.getInteger(1)));
     234
     235//    // Mark any closing paren that was not actually used to close an opener as an error.
     236//    PabloAST * const unmatched_rparen = pb.createAnd(rparen, pb.createNot(all_closed), "unmatched_rparen");
     237//    pb.createAssign(kernel->getOutputStreamVar("errors"), pb.createOr(accumulated_errors, unmatched_rparen));
     238
     239//}
    104240
    105241Function * pipeline(IDISA::IDISA_Builder * iBuilder, const unsigned count) {
  • icGREP/icgrep-devel/icgrep/icgrep-devel.files

    r5347 r5366  
    4444kernels/kernel.cpp
    4545kernels/kernel.h
     46kernels/linebreak_kernel.cpp
     47kernels/linebreak_kernel.h
    4648kernels/match_count.cpp
    4749kernels/match_count.h
     
    6870kernels/swizzle.cpp
    6971kernels/swizzle.h
    70 kernels/unicode_linebreak_kernel.cpp
    71 kernels/unicode_linebreak_kernel.h
    7272pablo/analysis/pabloverifier.cpp
    7373pablo/analysis/pabloverifier.hpp
  • icGREP/icgrep-devel/icgrep/kernels/linebreak_kernel.cpp

    r5358 r5366  
    1313#include <pablo/builder.hpp>
    1414#include <llvm/IR/Module.h>
     15
     16#include <llvm/Support/raw_ostream.h>
    1517
    1618using namespace cc;
  • icGREP/icgrep-devel/icgrep/kernels/pipeline.cpp

    r5364 r5366  
    241241    AllocaInst * const pthreads = iBuilder->CreateAlloca(pthreadsTy);
    242242    std::vector<Value *> pthreadsPtrs;
    243     for (unsigned i = 0; i < codegen::ThreadNum; i++) {
     243    for (int i = 0; i < codegen::ThreadNum; i++) {
    244244        pthreadsPtrs.push_back(iBuilder->CreateGEP(pthreads, {iBuilder->getInt32(0), iBuilder->getInt32(i)}));
    245245    }
     
    264264    std::vector<Function *> thread_functions;
    265265    const auto ip = iBuilder->saveIP();
    266     for (unsigned i = 0; i < codegen::ThreadNum; i++) {
     266    for (int i = 0; i < codegen::ThreadNum; i++) {
    267267        thread_functions.push_back(generateSegmentParallelPipelineThreadFunction("thread"+std::to_string(i), iBuilder, kernels, sharedStructType, producerTable, i));
    268268    }
    269269    iBuilder->restoreIP(ip);
    270270   
    271     for (unsigned i = 0; i < codegen::ThreadNum; i++) {
     271    for (int i = 0; i < codegen::ThreadNum; i++) {
    272272        iBuilder->CreatePThreadCreateCall(pthreadsPtrs[i], nullVal, thread_functions[i], iBuilder->CreateBitCast(sharedStruct, int8PtrTy));
    273273    }
    274274   
    275275    std::vector<Value *> threadIDs;
    276     for (unsigned i = 0; i < codegen::ThreadNum; i++) {
     276    for (int i = 0; i < codegen::ThreadNum; i++) {
    277277        threadIDs.push_back(iBuilder->CreateLoad(pthreadsPtrs[i]));
    278278    }
    279279   
    280     for (unsigned i = 0; i < codegen::ThreadNum; i++) {
     280    for (int i = 0; i < codegen::ThreadNum; i++) {
    281281        iBuilder->CreatePThreadJoinCall(threadIDs[i], status);
    282282    }
  • icGREP/icgrep-devel/icgrep/pablo/carry_data.h

    r5361 r5366  
    77#ifndef CARRY_DATA_H
    88#define CARRY_DATA_H
    9 
    10 /*
    11  * Carry Data system.
    12  *
    13  * Each PabloBlock (Main, If, While) has a contiguous data area for carry information.
    14  * The data area may be at a fixed or variable base offset from the base of the
    15  * main function carry data area.
    16  * The data area for each block consists of contiguous space for the local carries and
    17  * advances of the block plus the areas of any ifs/whiles nested within the block.
    18 
    19 */
    209
    2110namespace pablo {
     
    3019        , BorrowedSummary
    3120        , ExplicitSummary
    32         , CountingSummary
    3321    };
    3422
    3523    CarryData()
    36     : mSummaryType(NoSummary) {
     24    : mSummaryType(NoSummary)
     25    , mInNonCollapsingCarryMode(false) {
    3726
    3827    }
     
    5443    }
    5544
    56     bool hasCountingSummary() const {
    57         return (mSummaryType == CountingSummary);
     45    bool nonCarryCollapsingMode() const {
     46        return mInNonCollapsingCarryMode;
    5847    }
    5948
     
    6150        mSummaryType = value;
    6251    }
     52
     53    void setNonCollapsingCarryMode(const bool value = true) {
     54        mInNonCollapsingCarryMode = value;
     55    }
    6356   
    6457private:
    6558
    66     SummaryType             mSummaryType;
     59    SummaryType     mSummaryType;
     60    bool            mInNonCollapsingCarryMode;
    6761
    6862};
  • icGREP/icgrep-devel/icgrep/pablo/carry_manager.cpp

    r5361 r5366  
    1616#include <pablo/pe_matchstar.h>
    1717#include <pablo/pe_var.h>
    18 #include <llvm/Support/raw_ostream.h>
     18// #include <llvm/Support/raw_ostream.h>
    1919using namespace llvm;
    2020
     
    7979    mCarryMetadata.resize(getScopeCount(kernel->getEntryBlock()));
    8080
    81     mKernel->addScalar(analyse(kernel->getEntryBlock()), "carries");
     81    Type * ty = analyse(kernel->getEntryBlock());
     82
     83    ty->dump();
     84
     85    mKernel->addScalar(ty, "carries");
    8286
    8387    if (mHasLoop) {
     
    103107    mCarryScopeIndex.push_back(0);
    104108
    105 
    106     assert (mCarryFrame.empty());
    107 
    108     assert (mCarryInSummary.empty());
    109     mCarryInSummary.push_back(Constant::getNullValue(mCarryPackType));
     109    assert (mCarryFrameStack.empty());
    110110
    111111    assert (mCarryOutSummary.empty());
     
    114114    if (mHasLoop) {
    115115        mLoopSelector = mKernel->getScalarField("selector");
     116        mNextLoopSelector = iBuilder->CreateXor(mLoopSelector, ConstantInt::get(mLoopSelector->getType(), 1));
    116117    }
    117118}
     
    122123void CarryManager::finalizeCodeGen() {
    123124    if (mHasLoop) {
    124         mKernel->setScalarField("selector", iBuilder->CreateXor(mLoopSelector, iBuilder->getInt32(1)));
     125        mKernel->setScalarField("selector", mNextLoopSelector);
    125126    }
    126127    if (mHasLongAdvance) {
     
    129130        mKernel->setScalarField("CarryBlockIndex", idx);
    130131    }
    131     assert (mCarryFrame.empty());
    132 
    133     assert (mCarryInSummary.size() == 1);
    134     mCarryInSummary.clear();
     132    assert (mCarryFrameStack.empty());
    135133
    136134    assert (mCarryOutSummary.size() == 1);
     
    146144void CarryManager::enterLoopScope(const PabloBlock * const scope) {
    147145    assert (scope);
     146    assert (mHasLoop);
    148147    ++mLoopDepth;
    149148    enterScope(scope);
     
    154153 ** ------------------------------------------------------------------------------------------------------------- */
    155154void CarryManager::enterLoopBody(BasicBlock * const entryBlock) {
    156 
    157     assert (mHasLoop);
    158 
    159155    if (mCarryInfo->hasSummary()) {
    160156        PHINode * phiCarryOutSummary = iBuilder->CreatePHI(mCarryPackType, 2, "summary");
     
    164160        // so that we can properly OR it into the outgoing summary value.
    165161        mCarryOutSummary.back() = phiCarryOutSummary;
    166         Value * carryOut = phiCarryOutSummary;
    167         // In non-carry-collapsing mode, the carry out summary of this block iteration *MUST* match the carry in of the
    168         // subsequent block iteration. Otherwise the subsequent block iteration may become trapped in an infinite loop.
    169         // To ensure this, we effectively "zero-initialize" the carry-out coming into this loop but OR in carry-out
    170         // of the outer scope for the phi value the end of the loop body. This avoids us needing to maintain a carry-in
    171         // summary for all outer scopes whenever only a nested scope requires this mode.
    172         if (LLVM_UNLIKELY(mCarryInfo->hasCountingSummary())) {
    173             carryOut = Constant::getNullValue(mCarryPackType);
    174         }
    175         mCarryOutSummary.push_back(carryOut);
    176     }
    177 
    178     if (LLVM_UNLIKELY(mCarryInfo->hasCountingSummary())) {
     162        mCarryOutSummary.push_back(phiCarryOutSummary);
     163    }
     164    if (LLVM_UNLIKELY(mCarryInfo->nonCarryCollapsingMode())) {
     165
     166        assert (mCarryInfo->hasSummary());
    179167
    180168        // Check whether we need to resize the carry state
     
    182170        mLoopIndicies.push_back(index);
    183171        index->addIncoming(iBuilder->getSize(0), entryBlock);
    184 
    185         mCarryInSummary.push_back(Constant::getNullValue(mCarryPackType));
    186172
    187173        Value * capacityPtr = iBuilder->CreateGEP(mCurrentFrame, {iBuilder->getInt32(0), iBuilder->getInt32(0)});
     
    279265        phiArrayPtr->addIncoming(newArray, reallocExisting);
    280266
    281         // note: the 3 here is only to pass the assertion later. It refers to the number of elements in the carry data struct.
    282         mCarryFrame.emplace_back(mCurrentFrame, 3);
     267        // NOTE: the 3 here is only to pass the assertion later. It refers to the number of elements in the carry data struct.
     268        mCarryFrameStack.emplace_back(mCurrentFrame, 3);
    283269        mCurrentFrame = iBuilder->CreateGEP(phiArrayPtr, index);
    284270    }
     
    290276void CarryManager::leaveLoopBody(BasicBlock * /* exitBlock */) {
    291277
    292     if (LLVM_UNLIKELY(mCarryInfo->hasCountingSummary())) {
    293 
    294         std::tie(mCurrentFrame, mCurrentFrameIndex) = mCarryFrame.back();
    295         mCarryFrame.pop_back();
    296         assert (!mCarryInSummary.empty());
    297         Value * carryInAccumulator = mCarryInSummary.back();
     278    if (LLVM_UNLIKELY(mCarryInfo->nonCarryCollapsingMode())) {
     279
     280        assert (mCarryInfo->hasSummary());
     281
     282        ConstantInt * const summaryIndex = iBuilder->getInt32(mCurrentFrame->getType()->getPointerElementType()->getStructNumElements() - 1);
     283
     284        Value * carryInAccumulator = readCarryInSummary(summaryIndex);
    298285        Value * carryOutAccumulator = mCarryOutSummary.back();
     286
     287        if (mCarryInfo->hasExplicitSummary()) {
     288            writeCarryOutSummary(carryOutAccumulator, summaryIndex);
     289        }
     290
     291        std::tie(mCurrentFrame, mCurrentFrameIndex) = mCarryFrameStack.back();
     292        mCarryFrameStack.pop_back();
    299293
    300294        // In non-carry-collapsing mode, we cannot rely on the fact that performing a single iteration of this
     
    355349
    356350        // loop condition
    357         Value * n = iBuilder->CreateAdd(i, ONE);
    358         i->addIncoming(n, update);
     351        i->addIncoming(iBuilder->CreateAdd(i, ONE), update);
    359352        iBuilder->CreateCondBr(iBuilder->CreateICmpNE(iBuilder->CreateShl(ONE, i), capacity), update, resume);
    360353
    361354        iBuilder->SetInsertPoint(resume);
    362 
    363         IntegerType * ty = IntegerType::get(iBuilder->getContext(), iBuilder->getBitBlockWidth());
    364         iBuilder->CreateAssert(iBuilder->CreateICmpEQ(iBuilder->CreateBitCast(finalBorrow, ty), Constant::getNullValue(ty)), "borrow != 0");
    365         iBuilder->CreateAssert(iBuilder->CreateICmpEQ(iBuilder->CreateBitCast(finalCarry, ty), Constant::getNullValue(ty)), "carry != 0");
    366355
    367356        assert (!mLoopIndicies.empty());
     
    369358        index->addIncoming(iBuilder->CreateAdd(index, iBuilder->getSize(1)), resume);
    370359        mLoopIndicies.pop_back();
    371         mCarryInSummary.back() = finalCarryInSummary;
     360
     361        mNextSummaryTest = finalCarryInSummary;
    372362    }
    373363    if (mCarryInfo->hasSummary()) {
     
    376366        mCarryOutSummary.pop_back();
    377367        PHINode * phiCarryOut = cast<PHINode>(mCarryOutSummary.back());
    378         if (LLVM_UNLIKELY(mCarryInfo->hasCountingSummary())) {
    379             carryOut = iBuilder->CreateOr(phiCarryOut, carryOut);
    380         }
    381368        phiCarryOut->addIncoming(carryOut, iBuilder->GetInsertBlock());
     369        mCarryOutSummary.back() = carryOut;
    382370    }
    383371}
     
    398386    ++mIfDepth;
    399387    enterScope(scope);
     388    // We start with zero-initialized carry in order and later OR in the current carry summary so that upon
     389    // processing the subsequent block iteration, we branch into this If scope iff a carry was generated by
     390    // a statement within the If scope and not by a dominating statement in the outer scope.
    400391    mCarryOutSummary.push_back(Constant::getNullValue(mCarryPackType));
     392    if (LLVM_LIKELY(mCarryInfo->hasSummary())) {
     393        assert (mCurrentFrameIndex == 0);
     394        mNextSummaryTest = readCarryInSummary(iBuilder->getInt32(0));
     395        if (mCarryInfo->hasExplicitSummary()) {
     396            mCurrentFrameIndex = 1;
     397        }
     398    }
    401399}
    402400
     
    406404Value * CarryManager::generateSummaryTest(Value * condition) {
    407405    if (LLVM_LIKELY(mCarryInfo->hasSummary())) {
    408         Value * summary = nullptr;
    409         if (LLVM_UNLIKELY(mCarryInfo->hasCountingSummary())) {
    410             summary = mCarryInSummary.back();
    411             mCarryInSummary.pop_back();
    412         } else {
    413             // enter the (potentially nested) struct and extract the summary element (always element 0)
    414             unsigned count = 2;
    415             if (LLVM_UNLIKELY(mCarryInfo->hasBorrowedSummary())) {
    416                 Type * frameTy = mCurrentFrame->getType()->getPointerElementType();
    417                 count = 1;
    418                 while (frameTy->isStructTy()) {
    419                     ++count;
    420                     frameTy = frameTy->getStructElementType(0);
    421                 }
    422             }
    423             const bool useLoopSelector = mCarryInfo->hasImplicitSummary() && mLoopDepth > 0;
    424             const auto length = count + (useLoopSelector ? 1 : 0);
    425             Value * indicies[length];
    426             std::fill(indicies, indicies + count, iBuilder->getInt32(0));
    427             if (LLVM_UNLIKELY(useLoopSelector)) {
    428                 indicies[count] = mLoopSelector;
    429             }
    430             ArrayRef<Value *> ar(indicies, length);
    431             Value * ptr = iBuilder->CreateGEP(mCurrentFrame, ar);
    432             // Sanity check: make sure we're accessing a summary value
    433             assert (ptr->getType()->getPointerElementType()->canLosslesslyBitCastTo(condition->getType()));
    434             summary = iBuilder->CreateBlockAlignedLoad(ptr);
    435         }
    436         condition = iBuilder->simd_or(condition, summary);
    437     }
     406        assert ("summary test was not generated" && mNextSummaryTest);
     407        condition = iBuilder->simd_or(condition, mNextSummaryTest);
     408        mNextSummaryTest = nullptr;
     409    }
     410    assert ("summary test was not consumed" && (mNextSummaryTest == nullptr));
    438411    return condition;
    439412}
     
    442415 * @brief enterIfBody
    443416 ** ------------------------------------------------------------------------------------------------------------- */
    444 void CarryManager::enterIfBody(BasicBlock * const entryBlock) { assert (entryBlock);
    445 
     417void CarryManager::enterIfBody(BasicBlock * const entryBlock) {
     418    assert (entryBlock);
    446419}
    447420
     
    449422 * @brief leaveIfBody
    450423 ** ------------------------------------------------------------------------------------------------------------- */
    451 void CarryManager::leaveIfBody(BasicBlock * const exitBlock) { assert (exitBlock);
     424void CarryManager::leaveIfBody(BasicBlock * const exitBlock) {
     425    assert (exitBlock);
    452426    const auto n = mCarryOutSummary.size();
    453     if (LLVM_LIKELY(mCarryInfo->hasExplicitSummary())) {
    454         assert (!mCarryOutSummary.empty());
    455         Value * ptr = iBuilder->CreateGEP(mCurrentFrame, {iBuilder->getInt32(0), iBuilder->getInt32(0)});
    456         Value * const value = iBuilder->CreateBitCast(mCarryOutSummary.back(), mBitBlockType);
    457         iBuilder->CreateBlockAlignedStore(value, ptr);
    458     }
    459     if (n > 1) {
     427    if (LLVM_LIKELY(mCarryInfo->hasSummary())) {
     428        if (LLVM_LIKELY(mCarryInfo->hasExplicitSummary())) {
     429            writeCarryOutSummary(mCarryOutSummary[n - 1], iBuilder->getInt32(0));
     430        }
     431    }
     432    if (n > 2) {
    460433        mCarryOutSummary[n - 1] = iBuilder->CreateOr(mCarryOutSummary[n - 1], mCarryOutSummary[n - 2], "summary");
    461434    }
     
    467440void CarryManager::leaveIfScope(BasicBlock * const entryBlock, BasicBlock * const exitBlock) {
    468441    assert (mIfDepth > 0);
    469     if (mCarryInfo->hasSummary()) {
     442    if (LLVM_LIKELY(mCarryInfo->hasSummary())) {
    470443        const auto n = mCarryOutSummary.size(); assert (n > 0);
    471         if (n > 1) {
     444        if (n > 2) {
    472445            // When leaving a nested If scope with a summary value, phi out the summary to ensure the
    473446            // appropriate summary is stored in the outer scope.
     
    481454                mCarryOutSummary[n - 2] = phi;
    482455            }
    483         }       
     456        }
    484457    }
    485458    --mIfDepth;
     
    494467    assert (scope);
    495468    // Store the state of the current frame and update the scope state
    496     mCarryFrame.emplace_back(mCurrentFrame, mCurrentFrameIndex + 1);
     469    mCarryFrameStack.emplace_back(mCurrentFrame, mCurrentFrameIndex + 1);
    497470    mCurrentScope = scope;
    498471    mCarryScopeIndex.push_back(++mCarryScopes);
     
    504477    // Verify we're pointing to a carry frame struct
    505478    assert(mCurrentFrame->getType()->getPointerElementType()->isStructTy());
    506     // We always use the 0-th slot for the summary value, even when it's implicit
    507     mCurrentFrameIndex = mCarryInfo->hasExplicitSummary() ? 1 : 0;
     479    mCurrentFrameIndex = 0;
    508480}
    509481
     
    516488    assert (mCurrentFrameIndex == mCurrentFrame->getType()->getPointerElementType()->getStructNumElements());
    517489    // Sanity test: are there remaining carry frames?
    518     assert (!mCarryFrame.empty());
    519 
    520     std::tie(mCurrentFrame, mCurrentFrameIndex) = mCarryFrame.back();
     490    assert (!mCarryFrameStack.empty());
     491
     492    std::tie(mCurrentFrame, mCurrentFrameIndex) = mCarryFrameStack.back();
    521493
    522494    assert(mCurrentFrame->getType()->getPointerElementType()->isStructTy());
    523495
    524     mCarryFrame.pop_back();
     496    mCarryFrameStack.pop_back();
    525497    mCarryScopeIndex.pop_back();
    526498    assert (!mCarryScopeIndex.empty());
     
    561533        return result;
    562534    } else {
    563         return longAdvanceCarryInCarryOut(shiftAmount, value);
     535        return longAdvanceCarryInCarryOut(value, shiftAmount);
    564536    }
    565537}
     
    568540 * @brief longAdvanceCarryInCarryOut
    569541 ** ------------------------------------------------------------------------------------------------------------- */
    570 Value * CarryManager::longAdvanceCarryInCarryOut(const unsigned shiftAmount, Value * value) {
     542Value * CarryManager::longAdvanceCarryInCarryOut(Value * const value, const unsigned shiftAmount) {
    571543
    572544    assert (shiftAmount > mBitBlockWidth);
     
    574546
    575547    Type * const streamVectorTy = iBuilder->getIntNTy(mBitBlockWidth);
    576     value = iBuilder->CreateBitCast(value, mBitBlockType);
    577548    Value * buffer = iBuilder->CreateGEP(mCurrentFrame, {iBuilder->getInt32(0), iBuilder->getInt32(mCurrentFrameIndex++), iBuilder->getInt32(0)});
    578549
     
    592563            if (LLVM_LIKELY(i == limit)) {
    593564                stream = iBuilder->CreateAnd(stream, iBuilder->bitblock_mask_from(iBuilder->getInt32(entries % mBitBlockWidth)));
    594                 addToSummary(stream);
     565                addToCarryOutSummary(stream);
    595566                iBuilder->CreateBlockAlignedStore(stream, ptr);               
    596567                buffer = iBuilder->CreateGEP(buffer, iBuilder->getInt32(1));
    597568                break;
    598569            }
    599             addToSummary(stream);
     570            addToCarryOutSummary(stream);
    600571            iBuilder->CreateBlockAlignedStore(stream, ptr);
    601572            carry = iBuilder->CreateLShr(prior, mBitBlockWidth - 1);
     
    612583    Value * carryIn = iBuilder->CreateBlockAlignedLoad(iBuilder->CreateGEP(buffer, loadIndex0));
    613584    assert (carryIn->getType() == mBitBlockType);
    614     // in non-carry collapsing mode, we need to accumulate the carry in value in order to properly subtract it from the
    615     // carry in state in order to deduce whether we still have pending iterations even if the loop condition fails.
    616     if (LLVM_UNLIKELY(mCarryInfo->hasCountingSummary())) {
    617         mCarryInSummary.back() = iBuilder->CreateOr(mCarryInSummary.back(), carryIn);
    618     }
    619     // If the long advance is an exact multiple of mBitBlockWidth, we simply return the oldest
     585
     586    // If the long advance is an exact multiple of BitBlockWidth, we simply return the oldest
    620587    // block in the long advance carry data area. 
    621588    if (blockShift == 0) {
     
    638605Value * CarryManager::getNextCarryIn() {
    639606    assert (mCurrentFrameIndex < mCurrentFrame->getType()->getPointerElementType()->getStructNumElements());
    640     Value * carryInPtr = iBuilder->CreateGEP(mCurrentFrame, {iBuilder->getInt32(0), iBuilder->getInt32(mCurrentFrameIndex++)});
    641     mCarryPackPtr = carryInPtr;
    642     if (mLoopDepth > 0) {
    643         carryInPtr = iBuilder->CreateGEP(carryInPtr, {iBuilder->getInt32(0), mLoopSelector});       
    644     }   
     607    Value * carryInPtr = nullptr;
     608    if (mLoopDepth == 0) {
     609        carryInPtr = iBuilder->CreateGEP(mCurrentFrame, {iBuilder->getInt32(0), iBuilder->getInt32(mCurrentFrameIndex)});
     610    } else {
     611        carryInPtr = iBuilder->CreateGEP(mCurrentFrame, {iBuilder->getInt32(0), iBuilder->getInt32(mCurrentFrameIndex), mLoopSelector});
     612    }
    645613    assert (carryInPtr->getType()->getPointerElementType() == mCarryPackType);
    646614    Value * const carryIn = iBuilder->CreateBlockAlignedLoad(carryInPtr);
    647     // in non-carry collapsing mode, we need to accumulate the carry in value in order to properly subtract it from the
    648     // carry in state in order to deduce whether we still have pending iterations even if the loop condition fails.
    649     if (LLVM_UNLIKELY(mCarryInfo->hasCountingSummary())) {
    650         mCarryInSummary.back() = iBuilder->CreateOr(mCarryInSummary.back(), carryIn);
    651     }
    652615    if (mLoopDepth > 0) {
    653616        iBuilder->CreateBlockAlignedStore(Constant::getNullValue(mCarryPackType), carryInPtr);
     
    657620
    658621/** ------------------------------------------------------------------------------------------------------------- *
     622 * @brief collapsingCarryMode
     623 ** ------------------------------------------------------------------------------------------------------------- */
     624inline bool CarryManager::inCarryCollapsingMode() const {
     625    return (dyn_cast_or_null<While>(mCurrentScope->getBranch()) && !mCarryInfo->nonCarryCollapsingMode());
     626}
     627
     628/** ------------------------------------------------------------------------------------------------------------- *
    659629 * @brief setNextCarryOut
    660630 ** ------------------------------------------------------------------------------------------------------------- */
    661631void CarryManager::setNextCarryOut(Value * carryOut) {
    662     if (mCarryInfo->hasExplicitSummary() || mCarryInfo->hasCountingSummary()) {
    663         addToSummary(carryOut);
    664     }
    665     Value * carryOutPtr = mCarryPackPtr;
    666     if (mLoopDepth > 0) {
    667         Value * selector = iBuilder->CreateXor(mLoopSelector, ConstantInt::get(mLoopSelector->getType(), 1));
    668         carryOutPtr = iBuilder->CreateGEP(mCarryPackPtr, {iBuilder->getInt32(0), selector});
    669     }
     632    assert (mCurrentFrameIndex < mCurrentFrame->getType()->getPointerElementType()->getStructNumElements());
    670633    carryOut = iBuilder->CreateBitCast(carryOut, mCarryPackType);
    671     if (inCollapsingCarryMode()) {
     634    if (mCarryInfo->hasExplicitSummary()) {
     635        addToCarryOutSummary(carryOut);
     636    }
     637    Value * carryOutPtr = nullptr;
     638    if (mLoopDepth == 0) {
     639        carryOutPtr = iBuilder->CreateGEP(mCurrentFrame, {iBuilder->getInt32(0), iBuilder->getInt32(mCurrentFrameIndex)});
     640    } else {
     641        carryOutPtr = iBuilder->CreateGEP(mCurrentFrame, {iBuilder->getInt32(0), iBuilder->getInt32(mCurrentFrameIndex), mNextLoopSelector});
     642    }
     643    ++mCurrentFrameIndex;
     644    if (inCarryCollapsingMode()) {
    672645        Value * accum = iBuilder->CreateBlockAlignedLoad(carryOutPtr);
    673646        carryOut = iBuilder->CreateOr(carryOut, accum);
     
    675648    assert (carryOutPtr->getType()->getPointerElementType() == mCarryPackType);
    676649    iBuilder->CreateBlockAlignedStore(carryOut, carryOutPtr);
    677 }
    678 
    679 /** ------------------------------------------------------------------------------------------------------------- *
    680  * @brief addToSummary
    681  ** ------------------------------------------------------------------------------------------------------------- */
    682 void CarryManager::addToSummary(Value * value) { assert (value);
    683     assert (!mCarryOutSummary.empty());
    684     Value * const summary = mCarryOutSummary.back(); assert (summary);
    685     if (LLVM_UNLIKELY(summary == value)) {
    686         return;  //Nothing to add.
    687     }
    688     value = iBuilder->CreateBitCast(value, mCarryPackType);
    689     if (LLVM_UNLIKELY(isa<Constant>(value))) {
    690         if (LLVM_UNLIKELY(cast<Constant>(value)->isZeroValue())) {
    691             return;
    692         } else if (LLVM_UNLIKELY(cast<Constant>(value)->isAllOnesValue())) {
    693             mCarryOutSummary.back() = value;
    694             return;
    695         }
    696     } else if (LLVM_UNLIKELY(isa<Constant>(summary))) {
    697         if (LLVM_UNLIKELY(cast<Constant>(summary)->isZeroValue())) {
    698             mCarryOutSummary.back() = value;
    699             return;
    700         } else if (LLVM_UNLIKELY(cast<Constant>(summary)->isAllOnesValue())) {
    701             return;
    702         }
    703     }   
    704     mCarryOutSummary.back() = iBuilder->CreateOr(summary, value);
    705 }
    706 
    707 /** ------------------------------------------------------------------------------------------------------------- *
    708  * @brief collapsingCarryMode
    709  ** ------------------------------------------------------------------------------------------------------------- */
    710 bool CarryManager::inCollapsingCarryMode() const {
    711     return (mCurrentScope->getBranch() && isa<While>(mCurrentScope->getBranch()) && !mCarryInfo->hasCountingSummary());
     650
     651}
     652
     653/** ------------------------------------------------------------------------------------------------------------- *
     654 * @brief readCarryInSummary
     655 ** ------------------------------------------------------------------------------------------------------------- */
     656Value * CarryManager::readCarryInSummary(ConstantInt * index) const {
     657    assert (mCarryInfo->hasSummary());
     658    unsigned count = 2;
     659    if (LLVM_UNLIKELY(mCarryInfo->hasBorrowedSummary())) {
     660        Type * frameTy = mCurrentFrame->getType()->getPointerElementType();
     661        count = 1;
     662        while (frameTy->isStructTy()) {
     663            ++count;
     664            frameTy = frameTy->getStructElementType(0);
     665        }
     666    }
     667    const unsigned length = (mLoopDepth == 0) ? count : (count + 1);
     668    Value * indicies[length];
     669    std::fill(indicies, indicies + count - 1, iBuilder->getInt32(0));
     670    indicies[count - 1] = index;
     671    if (mLoopDepth > 0) {
     672        indicies[count] = mLoopSelector;
     673    }
     674    ArrayRef<Value *> ar(indicies, length);
     675    Value * const ptr = iBuilder->CreateGEP(mCurrentFrame, ar);
     676    Value * const summary = iBuilder->CreateBlockAlignedLoad(ptr);
     677    if (mLoopDepth > 0) {
     678        iBuilder->CreateBlockAlignedStore(Constant::getNullValue(mCarryPackType), ptr);
     679    }
     680    return summary;
     681}
     682
     683/** ------------------------------------------------------------------------------------------------------------- *
     684 * @brief writeCarryOutSummary
     685 ** ------------------------------------------------------------------------------------------------------------- */
     686inline void CarryManager::writeCarryOutSummary(Value * const summary, ConstantInt * index) const {
     687    Value * ptr = nullptr;
     688    assert (mCarryInfo->hasExplicitSummary());
     689    if (mLoopDepth > 0) {
     690        ptr = iBuilder->CreateGEP(mCurrentFrame, {iBuilder->getInt32(0), index, mNextLoopSelector});
     691    } else {
     692        ptr = iBuilder->CreateGEP(mCurrentFrame, {iBuilder->getInt32(0), index});
     693    }
     694    iBuilder->CreateBlockAlignedStore(summary, ptr);
     695}
     696
     697
     698/** ------------------------------------------------------------------------------------------------------------- *
     699 * @brief addToCarryOutSummary
     700 ** ------------------------------------------------------------------------------------------------------------- */
     701inline void CarryManager::addToCarryOutSummary(Value * const value) {
     702    assert ("cannot add null summary value!" && value);
     703    assert ("summary stack is empty!" && !mCarryOutSummary.empty());
     704    mCarryOutSummary.back() = iBuilder->CreateOr(value, mCarryOutSummary.back());
    712705}
    713706
     
    728721 ** ------------------------------------------------------------------------------------------------------------- */
    729722bool CarryManager::hasIterationSpecificAssignment(const PabloBlock * const scope) {
    730     if (const Branch * const br = scope->getBranch()) {
     723    if (const While * const br = dyn_cast_or_null<While>(scope->getBranch())) {
    731724        for (const Var * var : br->getEscaped()) {
    732725            for (const PabloAST * user : var->users()) {
     
    756749 * @brief analyse
    757750 ** ------------------------------------------------------------------------------------------------------------- */
    758 StructType * CarryManager::analyse(PabloBlock * const scope, const unsigned ifDepth, const unsigned loopDepth) {
     751StructType * CarryManager::analyse(PabloBlock * const scope, const unsigned ifDepth, const unsigned loopDepth, const bool isNestedWithinNonCarryCollapsingLoop) {
    759752
    760753    assert (scope != mKernel->getEntryBlock() || mCarryScopes == 0);
     
    762755    assert (mCarryPackType);
    763756
    764     CarryData & cd = mCarryMetadata[mCarryScopes++];
    765 
     757    const unsigned carryScopeIndex = mCarryScopes++;
     758    const bool nonCarryCollapsingMode = hasIterationSpecificAssignment(scope);
     759    Type * const carryPackType = (loopDepth == 0) ? mCarryPackType : ArrayType::get(mCarryPackType, 2);
     760    bool hasLongAdvances = false;
    766761    std::vector<Type *> state;
    767762
    768     Type * const carryPackType = (loopDepth == 0) ? mCarryPackType : ArrayType::get(mCarryPackType, 2);
    769 
    770     bool hasLongAdvances = false;
    771763    for (Statement * stmt : *scope) {
    772764        if (LLVM_UNLIKELY(isa<Advance>(stmt))) {
    773765            const auto amount = cast<Advance>(stmt)->getAmount();
    774             if (LLVM_LIKELY(amount <= mBitBlockWidth)) {
    775                 state.push_back(carryPackType);
    776             } else {
     766            Type * type = carryPackType;
     767            if (LLVM_UNLIKELY(amount > mBitBlockWidth)) {
    777768                const auto blocks = ceil_udiv(amount, mBitBlockWidth); assert (blocks > 1);
    778                 Type * type = ArrayType::get(mBitBlockType, nearest_pow2(blocks));
     769                type = ArrayType::get(mBitBlockType, nearest_pow2(blocks));
    779770                if (LLVM_UNLIKELY(ifDepth > 0)) {
    780771                    Type * carryType = ArrayType::get(mBitBlockType, ceil_udiv(amount, std::pow(mBitBlockWidth, 2)));
     
    783774                }
    784775                mHasLongAdvance = true;
    785                 state.push_back(type);
    786776            }
     777            state.push_back(type);
    787778        } else if (LLVM_UNLIKELY(isNonAdvanceCarryGeneratingStatement(stmt))) {
    788779            state.push_back(carryPackType);
    789780        } else if (LLVM_UNLIKELY(isa<If>(stmt))) {
    790             state.push_back(analyse(cast<If>(stmt)->getBody(), ifDepth + 1, loopDepth));
     781            state.push_back(analyse(cast<If>(stmt)->getBody(), ifDepth + 1, loopDepth, nonCarryCollapsingMode | isNestedWithinNonCarryCollapsingLoop));
    791782        } else if (LLVM_UNLIKELY(isa<While>(stmt))) {
    792783            mHasLoop = true;
    793             state.push_back(analyse(cast<While>(stmt)->getBody(), ifDepth, loopDepth + 1));
    794         }
    795     }
    796 
     784            state.push_back(analyse(cast<While>(stmt)->getBody(), ifDepth, loopDepth + 1, nonCarryCollapsingMode | isNestedWithinNonCarryCollapsingLoop));
     785        }
     786    }
     787    // Build the carry state struct and add the summary pack if needed.
     788    CarryData & cd = mCarryMetadata[carryScopeIndex];
    797789    StructType * carryState = nullptr;
    798     // Add the summary pack if needed.
    799790    CarryData::SummaryType summaryType = CarryData::NoSummary;
    800791    if (LLVM_UNLIKELY(state.empty())) {
    801792        carryState = StructType::get(iBuilder->getContext());
    802793    } else {
    803         const bool nonCarryCollapsingMode = loopDepth > 0 && hasIterationSpecificAssignment(scope);
    804         if (LLVM_UNLIKELY(nonCarryCollapsingMode)) {
    805             summaryType = CarryData::CountingSummary;
    806         } else if (ifDepth > 0) {
    807             // A non-collapsing loop requires a unique summary for each iteration. Thus whenever we have a non-collapsing While
    808             // within an If scope with an implicit summary, the If scope requires an explicit summary.
    809             if (isa<If>(scope->getBranch())) {
    810                 if (LLVM_LIKELY(hasLongAdvances || state.size() > 1)) {
    811                     summaryType = CarryData::ExplicitSummary;
    812                     state.insert(state.begin(), mCarryPackType);
    813                 } else {
    814                     summaryType = CarryData::ImplicitSummary;
    815                     if (state[0]->isStructTy()) {
    816                         summaryType = CarryData::BorrowedSummary;
    817                     }
     794        //if (ifDepth > 0 || (nonCarryCollapsingMode | isNestedWithinNonCarryCollapsingLoop)) {
     795        if (dyn_cast_or_null<If>(scope->getBranch()) || nonCarryCollapsingMode || isNestedWithinNonCarryCollapsingLoop) {
     796            if (LLVM_LIKELY(state.size() > 1 || hasLongAdvances)) {
     797                summaryType = CarryData::ExplicitSummary;
     798                // NOTE: summaries are stored differently depending whether we're entering an If or While branch. With an If branch, they
     799                // preceed the carry state data and with a While loop they succeed it. This is to help cache prefectching performance.
     800                state.insert(isa<If>(scope->getBranch()) ? state.begin() : state.end(), carryPackType);
     801            } else {
     802                summaryType = CarryData::ImplicitSummary;
     803                if (state[0]->isStructTy()) {
     804                    summaryType = CarryData::BorrowedSummary;
    818805                }
    819             }
     806            }           
    820807        }
    821808        carryState = StructType::get(iBuilder->getContext(), state);
     
    825812            carryState = StructType::get(iBuilder->getSizeTy(), carryState->getPointerTo(), mCarryPackType->getPointerTo(), nullptr);
    826813        }
     814        cd.setNonCollapsingCarryMode(nonCarryCollapsingMode);
    827815    }
    828816    cd.setSummaryType(summaryType);
    829 
    830817    return carryState;
    831818}
     
    845832, mCarryInfo(nullptr)
    846833, mCarryPackType(mBitBlockType)
    847 , mCarryPackPtr(nullptr)
     834, mNextSummaryTest(nullptr)
    848835, mIfDepth(0)
    849836, mHasLongAdvance(false)
     
    851838, mLoopDepth(0)
    852839, mLoopSelector(nullptr)
     840, mNextLoopSelector(nullptr)
    853841, mCarryScopes(0) {
    854842
  • icGREP/icgrep-devel/icgrep/pablo/carry_manager.h

    r5361 r5366  
    1212namespace IDISA { class IDISA_Builder; }
    1313namespace llvm { class BasicBlock; }
     14namespace llvm { class ConstantInt; }
    1415namespace llvm { class Function; }
    1516namespace llvm { class PHINode; }
     
    7980         
    8081    llvm::Value * generateSummaryTest(llvm::Value * condition);
    81    
     82
    8283protected:
    8384
     
    8687    static bool hasIterationSpecificAssignment(const PabloBlock * const scope);
    8788
    88     llvm::StructType * analyse(PabloBlock * const scope, const unsigned ifDepth = 0, const unsigned whileDepth = 0);
     89    llvm::StructType * analyse(PabloBlock * const scope, const unsigned ifDepth = 0, const unsigned whileDepth = 0, const bool isNestedWithinNonCarryCollapsingLoop = false);
    8990
    9091    /* Entering and leaving scopes. */
     
    9596    llvm::Value * getNextCarryIn();
    9697    void setNextCarryOut(llvm::Value * const carryOut);
    97     llvm::Value * longAdvanceCarryInCarryOut(const unsigned shiftAmount, llvm::Value * const value);
     98    llvm::Value * longAdvanceCarryInCarryOut(llvm::Value * const value, const unsigned shiftAmount);
     99    llvm::Value * readCarryInSummary(llvm::ConstantInt *index) const;
     100    bool inCarryCollapsingMode() const;
     101    void writeCarryOutSummary(llvm::Value * const summary, llvm::ConstantInt * index) const;
    98102
    99103    /* Summary handling routines */
    100     void addToSummary(llvm::Value * const value);
    101 
    102     bool inCollapsingCarryMode() const;
     104    void addToCarryOutSummary(llvm::Value * const value);
    103105
    104106private:
     
    117119
    118120    llvm::Type *                                    mCarryPackType;
    119     llvm::Value *                                   mCarryPackPtr;
     121    llvm::Value *                                   mNextSummaryTest;
    120122
    121123    unsigned                                        mIfDepth;
     
    126128    unsigned                                        mLoopDepth;
    127129    llvm::Value *                                   mLoopSelector;
     130    llvm::Value *                                   mNextLoopSelector;
    128131    std::vector<llvm::PHINode *>                    mLoopIndicies;
    129132
    130133    std::vector<CarryData>                          mCarryMetadata;
    131134
    132     std::vector<std::pair<llvm::Value *, unsigned>> mCarryFrame;
     135    std::vector<std::pair<llvm::Value *, unsigned>> mCarryFrameStack;
    133136
    134137    unsigned                                        mCarryScopes;
    135138    std::vector<unsigned>                           mCarryScopeIndex;
    136139
    137     std::vector<llvm::Value *>                      mCarryInSummary;
     140//    std::vector<llvm::Value *>                      mCarryInSummary;
    138141    std::vector<llvm::Value *>                      mCarryOutSummary;
    139142};
  • icGREP/icgrep-devel/icgrep/pablo/optimizers/pablo_simplifier.cpp

    r5329 r5366  
    560560            Branch * const br = cast<Branch>(stmt);
    561561            deadCodeElimination(br->getBody());
     562            if (LLVM_UNLIKELY(br->getEscaped().empty())) {
     563                stmt = stmt->eraseFromParent(true);
     564                continue;
     565            }
    562566        } else if (LLVM_UNLIKELY(isa<Assign>(stmt))) {
    563567            // An Assign statement is locally dead whenever its variable is not read
Note: See TracChangeset for help on using the changeset viewer.