Changeset 5646 for icGREP


Ignore:
Timestamp:
Sep 21, 2017, 3:10:34 PM (17 months ago)
Author:
nmedfort
Message:

Minor clean up. Bug fix for object cache when the same cached kernel is used twice in a single run. Improvement to RE Minimizer.

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

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/CMakeLists.txt

    r5630 r5646  
    158158  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR-")
    159159ELSE() # using Clang, GCC, Intel C++, etc
    160   SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
     160  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti") 
    161161ENDIF()
    162162
  • icGREP/icgrep-devel/icgrep/UCD/unicode_set.cpp

    r5634 r5646  
    648648 ** ------------------------------------------------------------------------------------------------------------- */
    649649bool UnicodeSet::intersects(const UnicodeSet & other) const {
    650     std::vector<run_t> runs;
    651     std::vector<bitquad_t> quads;
    652650    const auto e1 = quad_end();
    653651    const auto e2 = other.quad_end();
  • icGREP/icgrep-devel/icgrep/cc/cc_compiler.cpp

    r5620 r5646  
    2020namespace cc {
    2121
    22 //    CC_Compiler::CC_Compiler(PabloKernel * kernel, const unsigned encodingBits, const std::string prefix)
    23 //    : mBuilder(kernel->getEntryBlock())
    24 //    , mEncodingBits(encodingBits)
    25 //    , mBasisBit(encodingBits) {
    26        
    27 //        // TODO: basisBits should be defined prior and only retrieved here.
    28 //        Var * const basisBits = kernel->addInput(prefix, kernel->getStreamSetTy(encodingBits));
    29 //        for (unsigned i = 0; i != mEncodingBits; i++) {
    30 //            mBasisBit[i] = mBuilder.createExtract(basisBits, mBuilder.getInteger(i)); assert (mBasisBit[i]);
    31 //        }
    32 //        mEncodingMask = (static_cast<unsigned>(1) << encodingBits) - static_cast<unsigned>(1);
    33 //    }
    34    
    35    
    3622CC_Compiler::CC_Compiler(pablo::PabloKernel * kernel, pablo::Var * basisBits)
    3723: mBuilder(kernel->getEntryBlock())
  • icGREP/icgrep-devel/icgrep/grep_engine.cpp

    r5631 r5646  
    326326    const auto n = REs.size();
    327327   
    328     std::vector<std::vector<UCD::UnicodeSet>> charclasses;
     328    std::vector<std::vector<UCD::UnicodeSet>> charclasses(n);
    329329
    330330    for (unsigned i = 0; i < n; i++) {
    331         REs[i] = resolveNames(REs[i]);
     331        REs[i] = re::resolveNames(REs[i]);
    332332        std::vector<UCD::UnicodeSet> UnicodeSets = re::collect_UnicodeSets(REs[i]);
    333333        std::vector<std::vector<unsigned>> exclusiveSetIDs;
    334         std::vector<UCD::UnicodeSet> multiplexedCCs;
    335         doMultiplexCCs(UnicodeSets, exclusiveSetIDs, multiplexedCCs);
     334        doMultiplexCCs(UnicodeSets, exclusiveSetIDs, charclasses[i]);
    336335        REs[i] = multiplex(REs[i], UnicodeSets, exclusiveSetIDs);
    337         charclasses.push_back(multiplexedCCs);
    338336    }
    339337
     
    346344        grepDriver->makeKernelCall(ccK, {BasisBits}, {CharClasses});
    347345        StreamSetBuffer * MatchResults = grepDriver->addBuffer(make_unique<CircularBuffer>(idb, idb->getStreamSetTy(1, 1), segmentSize * bufferSegments));
    348         kernel::Kernel * icgrepK = grepDriver->addKernelInstance(make_unique<kernel::ICGrepKernel>(idb, REs[i], true, numOfCharacterClasses));
     346        kernel::Kernel * icgrepK = grepDriver->addKernelInstance(make_unique<kernel::ICGrepKernel>(idb, REs[i], numOfCharacterClasses));
    349347        grepDriver->makeKernelCall(icgrepK, {CharClasses, LineBreakStream, RequiredStreams}, {MatchResults});
    350348        MatchResultsBufs[i] = MatchResults;
  • icGREP/icgrep-devel/icgrep/icgrep-devel.files

    r5630 r5646  
    295295re/re_minimizer.cpp
    296296re/re_memoizer.cpp
     297hashtag-counting.cpp
  • icGREP/icgrep-devel/icgrep/kernels/grep_kernel.cpp

    r5585 r5646  
    177177
    178178
    179 ICGrepKernel::ICGrepKernel(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, RE * const re, bool cc, unsigned cc_size)
     179ICGrepKernel::ICGrepKernel(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, RE * const re, unsigned numOfCharacterClasses)
    180180: RegularExpressionOptimizer(re)
    181181, PabloKernel(iBuilder,
    182182              "ic" + sha1sum(mSignature),
    183               {Binding{iBuilder->getStreamSetTy(cc ? cc_size : 8), "basis"}, Binding{iBuilder->getStreamSetTy(1, 1), "linebreak"}, Binding{iBuilder->getStreamSetTy(4, 1), "required"}},
     183              {Binding{iBuilder->getStreamSetTy(numOfCharacterClasses), "basis"},
     184               Binding{iBuilder->getStreamSetTy(1, 1), "linebreak"},
     185               Binding{iBuilder->getStreamSetTy(4, 1), "required"}},
     186
    184187              {Binding{iBuilder->getStreamSetTy(1, 1), "matches"}}) {
    185188
     
    191194
    192195void ICGrepKernel::generatePabloMethod() {
    193     re2pablo_compiler(this, mRE);
     196    PabloAST * const match_post = re2pablo_compiler(this, mRE);
     197    PabloBlock * const pb = getEntryBlock();
     198    Var * const output = getOutputStreamVar("matches");
     199    pb->createAssign(pb->createExtract(output, pb->getInteger(0)), match_post);
    194200}
    195201
  • icGREP/icgrep-devel/icgrep/kernels/grep_kernel.h

    r5585 r5646  
    4242class ICGrepKernel : public RegularExpressionOptimizer, public pablo::PabloKernel {
    4343public:
    44     ICGrepKernel(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, re::RE * const re_ast, bool cc = false, unsigned cc_size = 0);
     44    ICGrepKernel(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, re::RE * const re_ast, const unsigned numOfCharacterClasses = 8);
    4545    std::string makeSignature(const std::unique_ptr<kernel::KernelBuilder> & iBuilder) override;
    4646    bool isCachable() const override { return true; }
  • icGREP/icgrep-devel/icgrep/kernels/interface.cpp

    r5611 r5646  
    8585}
    8686
    87 unsigned ProcessingRate::calculateMaxReferenceItems(unsigned outputItems, bool doFinal) const {
     87unsigned ProcessingRate::calculateMaxReferenceItems(const unsigned outputItems, const bool doFinal) const {
    8888    if (mKind == ProcessingRate::ProcessingRateKind::FixedRatio || mKind == ProcessingRate::ProcessingRateKind::MaxRatio) {
    8989        if (mRatioNumerator == mRatioDenominator) {
     
    9696    }
    9797    if (mKind == ProcessingRate::ProcessingRateKind::Add1) {
    98         return doFinal ? outputItems - 1 : outputItems;
     98        return outputItems - (doFinal ? 1 : 0);
    9999    }
    100100    report_fatal_error("Inverse processing rate calculation attempted for unknown rate.");
  • icGREP/icgrep-devel/icgrep/kernels/interface.h

    r5620 r5646  
    106106    }
    107107
     108    unsigned getNumOfStreamInputs() const {
     109        return mStreamSetInputs.size();
     110    }
     111
    108112    const std::vector<Binding> & getStreamOutputs() const {
    109113        return mStreamSetOutputs;
     114    }
     115
     116    unsigned getNumOfStreamOutputs() const {
     117        return mStreamSetOutputs.size();
    110118    }
    111119
     
    155163    }
    156164
    157     unsigned getLookAhead() const {
    158         return mLookAheadPositions;
    159     }
    160 
    161     void setLookAhead(const unsigned lookAheadPositions) {
    162         mLookAheadPositions = lookAheadPositions;
     165    unsigned getLookAhead(const unsigned i) const {
     166        assert (i < mStreamSetInputLookahead.size());
     167        return mStreamSetInputLookahead[i];
     168    }
     169
     170    void setLookAhead(const unsigned i, const unsigned lookAheadPositions) {
     171        assert (i < mStreamSetInputLookahead.size());
     172        mStreamSetInputLookahead[i] = lookAheadPositions;
    163173    }
    164174
     
    180190    , mModule(nullptr)
    181191    , mKernelStateType(nullptr)
    182     , mLookAheadPositions(0)
    183192    , mKernelName(kernelName)
    184193    , mStreamSetInputs(stream_inputs)
     194    , mStreamSetInputLookahead(mStreamSetInputs.size(), 0)
    185195    , mStreamSetOutputs(stream_outputs)
    186196    , mScalarInputs(scalar_inputs)
     
    195205    llvm::Module *                          mModule;
    196206    llvm::StructType *                      mKernelStateType;
    197     unsigned                                mLookAheadPositions;
    198207    const std::string                       mKernelName;
    199208    std::vector<llvm::Value *>              mInitialArguments;
    200209    std::vector<Binding>                    mStreamSetInputs;
     210    std::vector<unsigned>                   mStreamSetInputLookahead;
    201211    std::vector<Binding>                    mStreamSetOutputs;
    202212    std::vector<Binding>                    mScalarInputs;
  • icGREP/icgrep-devel/icgrep/kernels/kernel.cpp

    r5641 r5646  
    137137    assert ("KernelBuilder does not have a valid IDISA Builder" && idb);
    138138    if (LLVM_UNLIKELY(mKernelStateType != nullptr)) {
    139         report_fatal_error("Cannot prepare kernel after kernel state finalized");
     139        report_fatal_error(getName() + ": cannot prepare kernel after kernel state finalized");
    140140    }
    141141    const auto blockSize = idb->getBitBlockWidth();
     
    144144        mStride = blockSize;
    145145    }
    146     const auto requiredBlocks = codegen::SegmentSize + ((blockSize + mLookAheadPositions - 1) / blockSize);
    147 
    148146    IntegerType * const sizeTy = idb->getSizeTy();
    149147
     148    assert (mStreamSetInputs.size() == mStreamSetInputBuffers.size());
     149//    assert (mStreamSetInputs.size() == mStreamSetInputLookahead.size());
     150
    150151    for (unsigned i = 0; i < mStreamSetInputs.size(); i++) {
    151         if ((mStreamSetInputBuffers[i]->getBufferBlocks() != 0) && (mStreamSetInputBuffers[i]->getBufferBlocks() < requiredBlocks)) {
    152             //report_fatal_error(getName() + ": " + mStreamSetInputs[i].name + " requires buffer size " + std::to_string(requiredBlocks));
    153         }
     152//        const auto requiredBlocks = codegen::SegmentSize + ((mStreamSetInputLookahead[i] + blockSize - 1) / blockSize);
     153//        if ((mStreamSetInputBuffers[i]->getBufferBlocks() != 0) && (mStreamSetInputBuffers[i]->getBufferBlocks() < requiredBlocks)) {
     154//            report_fatal_error(getName() + ": " + mStreamSetInputs[i].name + " requires buffer size " + std::to_string(requiredBlocks));
     155//        }
    154156        mScalarInputs.emplace_back(mStreamSetInputBuffers[i]->getStreamSetHandle()->getType(), mStreamSetInputs[i].name + BUFFER_PTR_SUFFIX);
    155157        if ((i == 0) || !mStreamSetInputs[i].rate.isExact()) {
     
    157159        }
    158160    }
     161
     162    assert (mStreamSetOutputs.size() == mStreamSetOutputBuffers.size());
    159163
    160164    for (unsigned i = 0; i < mStreamSetOutputs.size(); i++) {
     
    201205    if (LLVM_LIKELY(mKernelStateType == nullptr)) {
    202206        mKernelStateType = StructType::create(idb->getContext(), mKernelFields, getName());
     207        assert (mKernelStateType);
    203208    }
    204209    processingRateAnalysis();
     
    209214    assert ("KernelBuilder does not have a valid IDISA Builder" && idb);
    210215    if (LLVM_UNLIKELY(mKernelStateType != nullptr)) {
    211         report_fatal_error("Cannot prepare kernel after kernel state finalized");
     216        report_fatal_error(getName() + ": cannot prepare kernel after kernel state finalized");
    212217    }
    213218    assert (getModule());
     
    217222        mStride = blockSize;
    218223    }
    219     const auto requiredBlocks = codegen::SegmentSize + ((blockSize + mLookAheadPositions - 1) / blockSize);
    220 
    221224    IntegerType * const sizeTy = idb->getSizeTy();
     225
     226    assert (mStreamSetInputs.size() == mStreamSetInputBuffers.size());
     227//    assert (mStreamSetInputs.size() == mStreamSetInputLookahead.size());
     228
    222229    for (unsigned i = 0; i < mStreamSetInputs.size(); i++) {
    223         if ((mStreamSetInputBuffers[i]->getBufferBlocks() != 0) && (mStreamSetInputBuffers[i]->getBufferBlocks() < requiredBlocks)) {
    224             //report_fatal_error(getName() + ": " + mStreamSetInputs[i].name + " requires buffer size " + std::to_string(requiredBlocks));
    225         }
     230//        const auto requiredBlocks = codegen::SegmentSize + ((mStreamSetInputLookahead[i] + blockSize - 1) / blockSize);
     231//        if ((mStreamSetInputBuffers[i]->getBufferBlocks() != 0) && (mStreamSetInputBuffers[i]->getBufferBlocks() < requiredBlocks)) {
     232//            report_fatal_error(getName() + ": " + mStreamSetInputs[i].name + " requires buffer size " + std::to_string(requiredBlocks));
     233//        }
    226234        mScalarInputs.emplace_back(mStreamSetInputBuffers[i]->getStreamSetHandle()->getType(), mStreamSetInputs[i].name + BUFFER_PTR_SUFFIX);
    227235        if ((i == 0) || !mStreamSetInputs[i].rate.isExact()) {
     
    229237        }
    230238    }
     239
     240    assert (mStreamSetOutputs.size() == mStreamSetOutputBuffers.size());
    231241
    232242    for (unsigned i = 0; i < mStreamSetOutputs.size(); i++) {
     
    248258        addScalar(binding.type, binding.name);
    249259    }
    250 
    251260    Type * const consumerSetTy = StructType::get(sizeTy, sizeTy->getPointerTo()->getPointerTo(), nullptr)->getPointerTo();
    252261    for (unsigned i = 0; i < mStreamSetOutputs.size(); i++) {
    253262        addScalar(consumerSetTy, mStreamSetOutputs[i].name + CONSUMER_SUFFIX);
    254263    }
    255 
    256264    addScalar(sizeTy, LOGICAL_SEGMENT_NO_SCALAR);
    257265    addScalar(idb->getInt1Ty(), TERMINATION_SIGNAL);
    258 
    259266    for (unsigned i = 0; i < mStreamSetOutputs.size(); i++) {
    260267        addScalar(sizeTy, mStreamSetOutputs[i].name + CONSUMED_ITEM_COUNT_SUFFIX);
    261268    }
    262 
    263269    // We compile in a 64-bit CPU cycle counter into every kernel.   It will remain unused
    264270    // in normal execution, but when codegen::EnableCycleCounter is specified, pipelines
    265271    // will be able to add instrumentation to cached modules without recompilation.
    266272    addScalar(idb->getInt64Ty(), CYCLECOUNT_SCALAR);
     273
    267274    mKernelStateType = getModule()->getTypeByName(getName());
    268     assert (mKernelStateType);
     275    if (LLVM_UNLIKELY(mKernelStateType == nullptr)) {
     276        report_fatal_error("Kernel " + getName() + " definition could not be found in the cache object");
     277    }
    269278    processingRateAnalysis();
    270279}
     
    12621271    //kb->GetInsertBlock()->dump();
    12631272    for (unsigned i = 0; i < outputSetCount; i++) {
    1264         requiredOutputBufferSpace[i] = nullptr;
    1265         auto & rate = kernel->getStreamOutput(i).rate;
     1273        const auto & rate = kernel->getStreamOutput(i).rate;
    12661274        if (rate.isUnknownRate()) continue;  // No calculations possible.
    12671275        Kernel::Port port; unsigned ssIdx;
    12681276        std::tie(port, ssIdx) = kernel->getStreamPort(rate.referenceStreamSet());
     1277        Value * base = nullptr;
    12691278        if (port == Kernel::Port::Output) {
    1270             requiredOutputBufferSpace[i] = rate.CreateRatioCalculation(kb.get(), requiredOutputBufferSpace[ssIdx], doFinal);
    1271         }
    1272         else {
    1273             requiredOutputBufferSpace[i] = rate.CreateRatioCalculation(kb.get(), newlyAvailInputItems[ssIdx], doFinal);
    1274         }
     1279            base = requiredOutputBufferSpace[ssIdx]; assert (base);
     1280        } else {
     1281            base = newlyAvailInputItems[ssIdx]; assert (base);
     1282        }
     1283        requiredOutputBufferSpace[i] = rate.CreateRatioCalculation(kb.get(), base, doFinal);
    12751284        if (auto db = dyn_cast<DynamicBuffer>(outputs[i])) {
    12761285            Value * handle = db->getStreamSetHandle();
  • icGREP/icgrep-devel/icgrep/kernels/kernel_builder.cpp

    r5637 r5646  
    132132    Kernel::Port port; unsigned index;
    133133    std::tie(port, index) = mKernel->getStreamPort(name);
     134    const StreamSetBuffer * buf = nullptr;
    134135    if (port == Kernel::Port::Input) {
    135         const StreamSetBuffer * const buf = mKernel->getInputStreamSetBuffer(name);
    136         return buf->getLinearlyAccessibleItems(this, getStreamSetBufferPtr(name), fromPosition);
    137     }
    138     else {
    139         const StreamSetBuffer * const buf = mKernel->getOutputStreamSetBuffer(name);
    140         return buf->getLinearlyAccessibleItems(this, getStreamSetBufferPtr(name), fromPosition);
    141     }
     136        buf = mKernel->getInputStreamSetBuffer(name);
     137        const auto lookAhead = mKernel->getLookAhead(index);
     138        if (LLVM_UNLIKELY(lookAhead != 0)) {
     139            fromPosition = CreateAdd(ConstantInt::get(fromPosition->getType(), lookAhead), fromPosition);
     140        }
     141    } else {
     142        buf = mKernel->getOutputStreamSetBuffer(name);
     143    }
     144    return buf->getLinearlyAccessibleItems(this, getStreamSetBufferPtr(name), fromPosition);
    142145}
    143146
     
    145148    Kernel::Port port; unsigned index;
    146149    std::tie(port, index) = mKernel->getStreamPort(name);
     150    const StreamSetBuffer * buf = nullptr;
    147151    if (port == Kernel::Port::Input) {
    148         const StreamSetBuffer * const buf = mKernel->getInputStreamSetBuffer(name);
    149         return buf->getLinearlyAccessibleBlocks(this, getStreamSetBufferPtr(name), fromBlock);
    150     } else {
    151         const StreamSetBuffer * const buf = mKernel->getOutputStreamSetBuffer(name);
    152         return buf->getLinearlyAccessibleBlocks(this, getStreamSetBufferPtr(name), fromBlock);
    153     }
     152        buf = mKernel->getInputStreamSetBuffer(name);
     153        const auto lookAhead = mKernel->getLookAhead(index);
     154        if (LLVM_UNLIKELY(lookAhead != 0)) {
     155            const auto blocksAhead = (lookAhead + getBitBlockWidth() - 1) / getBitBlockWidth();
     156            fromBlock = CreateAdd(ConstantInt::get(fromBlock->getType(), blocksAhead), fromBlock);
     157        }
     158    } else {
     159        buf = mKernel->getOutputStreamSetBuffer(name);
     160    }
     161    return buf->getLinearlyAccessibleBlocks(this, getStreamSetBufferPtr(name), fromBlock);
    154162}
    155163
  • icGREP/icgrep-devel/icgrep/kernels/streamset.cpp

    r5641 r5646  
    140140}
    141141
    142 Value * StreamSetBuffer::getLinearlyAccessibleItems(IDISA::IDISA_Builder * const iBuilder, Value * self, Value * fromPosition, bool reverse) const {
     142Value * StreamSetBuffer::getLinearlyAccessibleItems(IDISA::IDISA_Builder * const iBuilder, Value * self, Value * fromPosition, bool reverse, const unsigned lookAhead) const {
    143143    Constant * bufSize = iBuilder->getSize(mBufferBlocks * iBuilder->getStride());
    144144    Value * bufRem = iBuilder->CreateURem(fromPosition, bufSize);
     
    149149}
    150150
    151 Value * StreamSetBuffer::getLinearlyAccessibleBlocks(IDISA::IDISA_Builder * const iBuilder, Value * self, Value * fromBlock, bool reverse) const {
     151Value * StreamSetBuffer::getLinearlyAccessibleBlocks(IDISA::IDISA_Builder * const iBuilder, Value * self, Value * fromBlock, bool reverse, const unsigned lookAhead) const {
    152152    Constant * bufBlocks = iBuilder->getSize(mBufferBlocks);
    153153    Value * bufRem = iBuilder->CreateURem(fromBlock, bufBlocks);
     
    264264}
    265265
    266 Value * SourceBuffer::getLinearlyAccessibleItems(IDISA::IDISA_Builder * const iBuilder, Value * self, Value * fromPosition, bool reverse) const {
     266Value * SourceBuffer::getLinearlyAccessibleItems(IDISA::IDISA_Builder * const iBuilder, Value * self, Value * fromPosition, bool reverse, const unsigned lookAhead) const {
    267267    if (reverse) report_fatal_error("SourceBuffer cannot be accessed in reverse");
    268268    return iBuilder->CreateSub(getCapacity(iBuilder, self), fromPosition);
    269269}
    270270
    271 Value * SourceBuffer::getLinearlyAccessibleBlocks(IDISA::IDISA_Builder * const iBuilder, Value * self, Value * fromBlock, bool reverse) const {
     271Value * SourceBuffer::getLinearlyAccessibleBlocks(IDISA::IDISA_Builder * const iBuilder, Value * self, Value * fromBlock, bool reverse, const unsigned lookAhead) const {
    272272    if (reverse) report_fatal_error("SourceBuffer cannot be accessed in reverse");
    273273    return iBuilder->CreateSub(iBuilder->CreateUDiv(getCapacity(iBuilder, self), iBuilder->getSize(iBuilder->getBitBlockWidth())), fromBlock);
     
    301301}
    302302
    303 Value * ExternalBuffer::getLinearlyAccessibleItems(IDISA::IDISA_Builder * const, Value *, Value *, bool reverse) const {
     303Value * ExternalBuffer::getLinearlyAccessibleItems(IDISA::IDISA_Builder * const, Value *, Value *, bool, const unsigned) const {
    304304    report_fatal_error("External buffers: getLinearlyAccessibleItems is not supported.");
    305305}
     
    591591}
    592592
    593 Value * ExpandableBuffer::getLinearlyAccessibleItems(IDISA::IDISA_Builder * const iBuilder, Value * self, Value *, bool reverse) const {
     593Value * ExpandableBuffer::getLinearlyAccessibleItems(IDISA::IDISA_Builder * const, Value *, Value *, bool, const unsigned) const {
    594594    report_fatal_error("Expandable buffers: getLinearlyAccessibleItems is not supported.");
    595595}
     
    682682
    683683
    684 Value * DynamicBuffer::getLinearlyAccessibleItems(IDISA::IDISA_Builder * const b, Value * handle, Value * fromPosition, bool reverse) const {
     684Value * DynamicBuffer::getLinearlyAccessibleItems(IDISA::IDISA_Builder * const b, Value * handle, Value * fromPosition, bool reverse, const unsigned lookAhead) const {
    685685    Constant * blockSize = b->getSize(b->getBitBlockWidth());
    686686    Value * const bufBlocks = b->CreateLoad(b->CreateGEP(handle, {b->getInt32(0), b->getInt32(int(Field::WorkingBlocks))}));
     
    690690        return b->CreateSelect(b->CreateICmpEQ(bufRem, b->getSize(0)), bufSize, bufRem);
    691691    }
    692     else return b->CreateSub(bufSize, bufRem, "linearItems");
     692    return b->CreateSub(bufSize, bufRem, "linearItems");
    693693}
    694694
     
    699699}
    700700
    701 Value * DynamicBuffer::getLinearlyAccessibleBlocks(IDISA::IDISA_Builder * const b, Value * handle, Value * fromBlock, bool reverse) const {
     701Value * DynamicBuffer::getLinearlyAccessibleBlocks(IDISA::IDISA_Builder * const b, Value * handle, Value * fromBlock, bool reverse, const unsigned lookAhead) const {
    702702    Value * const bufBlocks = b->CreateLoad(b->CreateGEP(handle, {b->getInt32(0), b->getInt32(int(Field::WorkingBlocks))}));
    703703    Value * bufRem = b->CreateURem(fromBlock, bufBlocks);
     
    705705        return b->CreateSelect(b->CreateICmpEQ(bufRem, b->getSize(0)), bufBlocks, bufRem);
    706706    }
    707     else return b->CreateSub(bufBlocks, bufRem, "linearBlocks");
     707    return b->CreateSub(bufBlocks, bufRem, "linearBlocks");
    708708}
    709709
  • icGREP/icgrep-devel/icgrep/kernels/streamset.h

    r5641 r5646  
    8383   
    8484    // The number of items that cam be linearly accessed from a given logical stream position.
    85     virtual llvm::Value * getLinearlyAccessibleItems(IDISA::IDISA_Builder * const iBuilder, llvm::Value * self, llvm::Value * fromPosition, bool reverse = false) const;
    86    
    87     virtual llvm::Value * getLinearlyAccessibleBlocks(IDISA::IDISA_Builder * const iBuilder, llvm::Value * self, llvm::Value * fromBlock, bool reverse = false) const;
     85    virtual llvm::Value * getLinearlyAccessibleItems(IDISA::IDISA_Builder * const iBuilder, llvm::Value * self, llvm::Value * fromPosition, bool reverse = false, const unsigned lookAhead = 0) const;
     86   
     87    virtual llvm::Value * getLinearlyAccessibleBlocks(IDISA::IDISA_Builder * const iBuilder, llvm::Value * self, llvm::Value * fromBlock, bool reverse = false, const unsigned lookAhead = 0) const;
    8888   
    8989    void createBlockCopy(IDISA::IDISA_Builder * const iBuilder, llvm::Value * targetBlockPtr, llvm::Value * sourceBlockPtr, llvm::Value * blocksToCopy) const;
     
    163163    llvm::Value * getCapacity(IDISA::IDISA_Builder * const iBuilder, llvm::Value * self) const override;
    164164   
    165     llvm::Value * getLinearlyAccessibleItems(IDISA::IDISA_Builder * const iBuilder, llvm::Value * self, llvm::Value * fromPosition, bool reverse = false) const override;
    166    
    167     llvm::Value * getLinearlyAccessibleBlocks(IDISA::IDISA_Builder * const iBuilder, llvm::Value * self, llvm::Value * fromBlock, bool reverse = false) const override;
     165    llvm::Value * getLinearlyAccessibleItems(IDISA::IDISA_Builder * const iBuilder, llvm::Value * self, llvm::Value * fromPosition, bool reverse = false, const unsigned lookAhead = 0) const override;
     166   
     167    llvm::Value * getLinearlyAccessibleBlocks(IDISA::IDISA_Builder * const iBuilder, llvm::Value * self, llvm::Value * fromBlock, bool reverse = false, const unsigned lookAhead = 0) const override;
    168168
    169169    llvm::Type * getStreamSetBlockType() const override;
     
    191191    ExternalBuffer(const std::unique_ptr<kernel::KernelBuilder> & b, llvm::Type * type, llvm::Value * addr, unsigned AddressSpace = 0);
    192192
    193     llvm::Value * getLinearlyAccessibleItems(IDISA::IDISA_Builder * const iBuilder, llvm::Value * self, llvm::Value * fromPosition, bool reverse = false) const override;
     193    llvm::Value * getLinearlyAccessibleItems(IDISA::IDISA_Builder * const iBuilder, llvm::Value * self, llvm::Value * fromPosition, bool reverse = false, const unsigned lookAhead = 0) const override;
    194194
    195195    void allocateBuffer(const std::unique_ptr<kernel::KernelBuilder> & iBuilder) override;
     
    291291    llvm::Value * getStreamPackPtr(IDISA::IDISA_Builder * const iBuilder, llvm::Value * self, llvm::Value * streamIndex, llvm::Value * blockIndex, llvm::Value * packIndex, const bool readOnly) const override;
    292292
    293     llvm::Value * getLinearlyAccessibleItems(IDISA::IDISA_Builder * const iBuilder, llvm::Value * self, llvm::Value * fromPosition, bool reverse = false) const override;
     293    llvm::Value * getLinearlyAccessibleItems(IDISA::IDISA_Builder * const iBuilder, llvm::Value * self, llvm::Value * fromPosition, bool reverse = false, const unsigned lookAhead = 0) const override;
    294294
    295295    llvm::Value * getStreamSetCount(IDISA::IDISA_Builder * const iBuilder, llvm::Value * self) const override;
     
    322322    DynamicBuffer(const std::unique_ptr<kernel::KernelBuilder> & b, llvm::Type * type, size_t initialCapacity, size_t overflowBlocks = 0, unsigned swizzleFactor = 1, unsigned addrSpace = 0);
    323323   
    324     llvm::Value * getLinearlyAccessibleItems(IDISA::IDISA_Builder * const b, llvm::Value * handle, llvm::Value * fromPosition, bool reverse = false) const override;
    325    
    326     llvm::Value * getLinearlyAccessibleBlocks(IDISA::IDISA_Builder * const iBuilder, llvm::Value * self, llvm::Value * fromBlock, bool reverse = false) const override;
     324    llvm::Value * getLinearlyAccessibleItems(IDISA::IDISA_Builder * const b, llvm::Value * handle, llvm::Value * fromPosition, bool reverse = false, const unsigned lookAhead = 0) const override;
     325   
     326    llvm::Value * getLinearlyAccessibleBlocks(IDISA::IDISA_Builder * const iBuilder, llvm::Value * self, llvm::Value * fromBlock, bool reverse = false, const unsigned lookAhead = 0) const override;
    327327
    328328    llvm::Value * getLinearlyWritableItems(IDISA::IDISA_Builder * const iBuilder, llvm::Value * self, llvm::Value * fromPosition, bool reverse = false) const override;
  • icGREP/icgrep-devel/icgrep/pablo/optimizers/pablo_simplifier.cpp

    r5620 r5646  
    1010#include <pablo/ps_assign.h>
    1111#include <pablo/pe_advance.h>
     12#include <pablo/pe_lookahead.h>
    1213#include <pablo/pe_scanthru.h>
    1314#include <pablo/pe_matchstar.h>
     
    269270            return block->createZeroes(stmt->getType()); // ¬1 ⇔ 0
    270271        }
    271     } else if (LLVM_UNLIKELY(isa<Add>(stmt) || isa<Subtract>(stmt))) {
    272        if (LLVM_UNLIKELY(isa<Integer>(stmt->getOperand(0)) && isa<Integer>(stmt->getOperand(1)))) {
    273            const Integer * const int0 = cast<Integer>(stmt->getOperand(0));
    274            const Integer * const int1 = cast<Integer>(stmt->getOperand(1));
    275            Integer::IntTy result = 0;
    276            if (isa<Add>(stmt)) {
    277                result = int0->value() + int1->value();
    278            } else {
    279                result = int0->value() - int1->value();
    280            }
    281            return block->getInteger(result);
    282        }
    283     } else if (LLVM_UNLIKELY(isa<Variadic>(stmt))) {
    284 
     272    } else if (isa<Variadic>(stmt)) {
    285273        std::sort(cast<Variadic>(stmt)->begin(), cast<Variadic>(stmt)->end());
    286 
    287274        for (unsigned i = 1; i < stmt->getNumOperands(); ) {
    288275            if (LLVM_UNLIKELY(stmt->getOperand(i - 1) == stmt->getOperand(i))) {
     
    306293            ++i;
    307294        }
    308 
    309295        if (LLVM_UNLIKELY(stmt->getNumOperands() < 2)) {
    310296            if (LLVM_LIKELY(stmt->getNumOperands() == 1)) {
     
    314300            }
    315301        }
    316 
    317302        if (LLVM_UNLIKELY(isa<Xor>(stmt))) {
    318303            bool negated = false;
     
    337322            if (LLVM_UNLIKELY(negated)) {
    338323                block->setInsertPoint(stmt);
    339                 expr = block->createNot(expr ? expr : stmt);
     324                expr = triviallyFold(block->createNot(expr ? expr : stmt), block);
    340325            }
    341326            return expr;
     
    358343            }
    359344        }
    360     } else {
    361         for (unsigned i = 0; i != stmt->getNumOperands(); ++i) {
    362             if (LLVM_UNLIKELY(isa<Zeroes>(stmt->getOperand(i)))) {
    363                 switch (stmt->getClassTypeId()) {
    364                     case TypeId::Sel:
    365                         block->setInsertPoint(stmt->getPrevNode());
    366                         switch (i) {
    367                             case 0: return stmt->getOperand(2);
    368                             case 1: return block->createAnd(block->createNot(stmt->getOperand(0)), stmt->getOperand(2));
    369                             case 2: return block->createAnd(stmt->getOperand(0), stmt->getOperand(1));
    370                         }
    371                     case TypeId::Advance:
    372                     case TypeId::ScanThru:
    373                     case TypeId::MatchStar:
    374                         return stmt->getOperand(0);
    375                     default: break;
    376                 }
    377             } else if (LLVM_UNLIKELY(isa<Ones>(stmt->getOperand(i)))) {
    378                 switch (stmt->getClassTypeId()) {
    379                     case TypeId::Sel:
    380                         block->setInsertPoint(stmt->getPrevNode());
    381                         switch (i) {
    382                             case 0: return stmt->getOperand(1);
    383                             case 1: return block->createOr(stmt->getOperand(0), stmt->getOperand(2));
    384                             case 2: return block->createOr(block->createNot(stmt->getOperand(0)), stmt->getOperand(1));
    385                         }
    386                     case TypeId::ScanThru:
    387                         if (LLVM_UNLIKELY(i == 1)) {
    388                             return block->createZeroes(stmt->getType());
    389                         }
    390                         break;
    391                     case TypeId::MatchStar:
    392                         if (LLVM_UNLIKELY(i == 0)) {
    393                             return block->createOnes(stmt->getType());
    394                         }
    395                         break;
    396                     default: break;
    397                 }
    398             }
    399         }       
     345    } else if (isa<Advance>(stmt)) {
     346        Advance * const adv = cast<Advance>(stmt);
     347        if (LLVM_UNLIKELY(isa<Zeroes>(adv->getExpression()) || adv->getAmount() == 0)) {
     348            return adv->getExpression();
     349        }
     350    } else if (isa<ScanThru>(stmt)) {
     351        ScanThru * const st = cast<ScanThru>(stmt);
     352        if (LLVM_UNLIKELY(isa<Zeroes>(st->getScanFrom()) || isa<Zeroes>(st->getScanThru()))) {
     353            return st->getScanFrom();
     354        } else if (LLVM_UNLIKELY(isa<Ones>(st->getScanThru()))) {
     355            block->setInsertPoint(stmt->getPrevNode());
     356            return block->createZeroes(stmt->getType());
     357        }
     358    } else if (isa<MatchStar>(stmt)) {
     359        MatchStar * const mstar = cast<MatchStar>(stmt);
     360        if (LLVM_UNLIKELY(isa<Zeroes>(mstar->getMarker()) || isa<Zeroes>(mstar->getCharClass()))) {
     361            return mstar->getMarker();
     362        } else if (LLVM_UNLIKELY(isa<Ones>(mstar->getMarker()))) {
     363            block->setInsertPoint(stmt->getPrevNode());
     364            return block->createOnes(stmt->getType());
     365        }
     366    } else if (isa<Lookahead>(stmt)) {
     367        Lookahead * const la = cast<Lookahead>(stmt);
     368        if (LLVM_UNLIKELY(isa<Zeroes>(la->getExpression()) || la->getAmount() == 0)) {
     369            return la->getExpression();
     370        }
     371    } else if (LLVM_UNLIKELY(isa<Sel>(stmt))) {
     372        Sel * const sel = cast<Sel>(stmt);
     373        if (LLVM_UNLIKELY(isa<Zeroes>(sel->getCondition()))) {
     374            return sel->getFalseExpr();
     375        }
     376        if (LLVM_UNLIKELY(isa<Ones>(sel->getCondition()))) {
     377            return sel->getTrueExpr();
     378        }
     379        if (LLVM_UNLIKELY(isa<Zeroes>(sel->getTrueExpr()))) {
     380            block->setInsertPoint(stmt->getPrevNode());
     381            PabloAST * const negCond = triviallyFold(block->createNot(sel->getCondition()), block);
     382            return triviallyFold(block->createAnd(sel->getFalseExpr(), negCond), block);
     383        }
     384        if (LLVM_UNLIKELY(isa<Ones>(sel->getTrueExpr()))) {
     385            block->setInsertPoint(stmt->getPrevNode());
     386            return triviallyFold(block->createOr(sel->getCondition(), sel->getFalseExpr()), block);
     387        }
     388        if (LLVM_UNLIKELY(isa<Zeroes>(sel->getFalseExpr()))) {
     389            block->setInsertPoint(stmt->getPrevNode());
     390            return triviallyFold(block->createAnd(sel->getCondition(), sel->getTrueExpr()), block);
     391        }
     392        if (LLVM_UNLIKELY(isa<Ones>(sel->getFalseExpr()))) {
     393            block->setInsertPoint(stmt->getPrevNode());
     394            PabloAST * const negCond = triviallyFold(block->createNot(sel->getCondition()), block);
     395            return triviallyFold(block->createOr(sel->getTrueExpr(), negCond), block);
     396        }
     397    } else if (LLVM_UNLIKELY(isa<Add>(stmt) || isa<Subtract>(stmt))) {
     398       if (LLVM_UNLIKELY(isa<Integer>(stmt->getOperand(0)) && isa<Integer>(stmt->getOperand(1)))) {
     399           const Integer * const int0 = cast<Integer>(stmt->getOperand(0));
     400           const Integer * const int1 = cast<Integer>(stmt->getOperand(1));
     401           Integer::IntTy result = 0;
     402           if (isa<Add>(stmt)) {
     403               result = int0->value() + int1->value();
     404           } else {
     405               result = int0->value() - int1->value();
     406           }
     407           return block->getInteger(result);
     408       }
    400409    }
    401410    return nullptr;
  • icGREP/icgrep-devel/icgrep/pablo/pablo_compiler.cpp

    r5629 r5646  
    8181        if (LLVM_UNLIKELY(isa<Lookahead>(stmt))) {
    8282            const Lookahead * const la = cast<Lookahead>(stmt);
    83             //assert ((isa<Var>(la->getExpr()) || isa<Extract>(la->getExpr())));
    84             if (LLVM_LIKELY(la->getAmount() > mKernel->getLookAhead())) {
    85                 mKernel->setLookAhead(la->getAmount());
     83            PabloAST * input = la->getExpression();
     84            if (LLVM_UNLIKELY(isa<Extract>(input))) {
     85                input = cast<Extract>(input)->getArray();
     86            }
     87            bool notFound = true;
     88            if (LLVM_LIKELY(isa<Var>(input))) {
     89                for (unsigned i = 0; i < mKernel->getNumOfInputs(); ++i) {
     90                    if (input == mKernel->getInput(i)) {
     91                        if (LLVM_LIKELY(mKernel->getLookAhead(i) < la->getAmount())) {
     92                            mKernel->setLookAhead(i, la->getAmount());
     93                        }
     94                        notFound = false;
     95                        break;
     96                    }
     97                }
     98            }
     99            if (LLVM_UNLIKELY(notFound)) {
     100                report_fatal_error("Lookahead " + stmt->getName() + " can only be performed on an input streamset");
    86101            }
    87102        } else if (LLVM_UNLIKELY(isa<Branch>(stmt))) {
     
    542557        } else if (const Lookahead * l = dyn_cast<Lookahead>(stmt)) {
    543558            Var * var = nullptr;
    544             PabloAST * stream = l->getExpr();
     559            PabloAST * stream = l->getExpression();
    545560            Value * index = iBuilder->getInt32(0);
    546561            if (LLVM_UNLIKELY(isa<Extract>(stream))) {
    547                 var = dyn_cast<Var>(cast<Extract>(stream)->getArray());
    548                 index = compileExpression(iBuilder, cast<Extract>(stream)->getIndex());
    549                 if (!var->isKernelParameter() || var->isReadNone()) {
    550                     std::string tmp;
    551                     raw_string_ostream out(tmp);
    552                     out << "Lookahead operation cannot be applied to ";
    553                     stmt->print(out);
    554                     out << " - not an input stream";
    555                     report_fatal_error(out.str());
    556                 }
    557             }
    558             if (LLVM_LIKELY(isa<Var>(stream))) {
    559                 var = cast<Var>(stream);
    560                 if (!var->isKernelParameter() || var->isReadNone()) {
    561                     std::string tmp;
    562                     raw_string_ostream out(tmp);
    563                     out << "Lookahead operation cannot be applied to ";
    564                     stmt->print(out);
    565                     out << ": ";
    566                     var->print(out);
    567                     out << " is not an input stream";
    568                     report_fatal_error(out.str());
    569                 }
     562                var = cast<Var>(cast<Extract>(stream)->getArray());
    570563            }
    571564            const auto bit_shift = (l->getAmount() % iBuilder->getBitBlockWidth());
  • icGREP/icgrep-devel/icgrep/pablo/pe_lookahead.h

    r5454 r5646  
    2424    virtual ~Lookahead() {
    2525    }
    26     inline PabloAST * getExpr() const {
     26    inline PabloAST * getExpression() const {
    2727        return getOperand(0);
    2828    }
  • icGREP/icgrep-devel/icgrep/pablo/printer_pablos.cpp

    r5371 r5646  
    102102        } else if (const Lookahead * adv = dyn_cast<Lookahead>(stmt)) {
    103103            out << " = pablo.Lookahead(";
    104             print(adv->getExpr(), out);
     104            print(adv->getExpression(), out);
    105105            out << ", " << std::to_string(adv->getAmount()) << ")";
    106106        } else if (const MatchStar * mstar = dyn_cast<MatchStar>(stmt)) {
  • icGREP/icgrep-devel/icgrep/re/re_compiler.cpp

    r5638 r5646  
    5555}
    5656
    57 void RE_Compiler::compileUnicodeNames(RE *& re) {
    58     re = resolveUnicodeProperties(re);
    59 }
    60 
    61 void RE_Compiler::compile(RE * re) {
    62     MarkerType match_results = compile(re, mPB);
    63     PabloAST * match_post = markerVar(AdvanceMarker(match_results, MarkerPosition::FinalPostPositionUnit, mPB));
    64     Var * const output = mKernel->getOutputStreamVar("matches");
    65    
    66     mPB.createAssign(mPB.createExtract(output, mPB.getInteger(0)), match_post);
     57RE * RE_Compiler::compileUnicodeNames(RE * re) {
     58    return resolveUnicodeProperties(re);
     59}
     60
     61PabloAST * RE_Compiler::compile(RE * re) {
     62    return markerVar(AdvanceMarker(compile(re, mPB), MarkerPosition::FinalPostPositionUnit, mPB));
    6763}
    6864   
     
    9591        pablo_follow = pb.createOr(pablo_follow, follow);
    9692    }
    97     PabloAST * result = pb.createAnd(pb.createMatchStar(pb.createAdvance(pablo_first, 1), pb.createOr(pablo_follow, mNonFinal)), pb.createAdvance(pablo_final, 1));
     93    PabloAST * result = pb.createAnd(pb.createMatchStar(pb.createAdvance(pablo_first, 1),
     94                                                        pb.createOr(pablo_follow, mNonFinal)),
     95                                     pb.createAdvance(pablo_final, 1));
    9896    return makeMarker(MarkerPosition::FinalPostPositionUnit, result);
    9997}
     
    110108        } else if (isa<Intersect>(re)) {
    111109            return compileIntersect(cast<Intersect>(re), marker, pb);
    112         }
    113         UnsupportedRE("RE Compiler for local language failed to process " + Printer_RE::PrintRE(re));
     110        } else {
     111            UnsupportedRE("RE Compiler for local language failed to process " + Printer_RE::PrintRE(re));
     112        }
    114113    } else {
    115114        if (isa<Name>(re)) {
     
    136135            // CCs may be passed through the toolchain directly to the compiler.
    137136            return compileCC(cast<CC>(re), marker, pb);
    138         }
    139         UnsupportedRE("RE Compiler failed to process " + Printer_RE::PrintRE(re));
     137        } else {
     138            UnsupportedRE("RE Compiler failed to process " + Printer_RE::PrintRE(re));
     139        }
    140140    }
    141141}
  • icGREP/icgrep-devel/icgrep/re/re_compiler.h

    r5617 r5646  
    6262
    6363    RE_Compiler(pablo::PabloKernel * kernel, cc::CC_Compiler & ccCompiler, bool local = false);
    64     void compileUnicodeNames(RE *& re);
    65     void compile(RE * re);
     64    LLVM_ATTRIBUTE_UNUSED_RESULT RE * compileUnicodeNames(RE * re);
     65    LLVM_ATTRIBUTE_UNUSED_RESULT pablo::PabloAST * compile(RE * re);
    6666
    6767    static LLVM_ATTRIBUTE_NORETURN void UnsupportedRE(std::string errmsg);
  • icGREP/icgrep-devel/icgrep/re/re_minimizer.cpp

    r5630 r5646  
    1212#include <boost/container/flat_map.hpp>
    1313
     14#include <llvm/Support/raw_ostream.h>
     15#include <re/printer_re.h>
     16
    1417using namespace llvm;
    1518
    1619namespace re {
    1720
    18 using AlternationSet = boost::container::flat_set<RE *, MemoizerComparator>;
    19 
     21using Set = boost::container::flat_set<RE *>;
    2022using Map = boost::container::flat_map<RE *, RE *>;
    2123
    22 struct PassContainer {
    23 
    24     RE * minimize(RE * const original) {
    25         const auto f = mMapping.find(original);
    26         if (LLVM_UNLIKELY(f != mMapping.end())) {
     24struct PassContainer : private Memoizer {
     25
     26    RE * minimize(RE * original) {
     27        const auto f = mMap.find(original);
     28        if (LLVM_UNLIKELY(f != mMap.end())) {
    2729            return f->second;
    2830        }
    2931        RE * re = original;
    30         if (Alt * alt = dyn_cast<Alt>(re)) {
    31             AlternationSet list;
     32repeat: if (Alt * alt = dyn_cast<Alt>(re)) {
     33            Set list;
    3234            list.reserve(alt->size());
     35            RE * namedCC = nullptr;
     36            bool repeat = false;
    3337            for (RE * item : *alt) {
    3438                item = minimize(item);
    3539                if (LLVM_UNLIKELY(isa<Vector>(item) && cast<Vector>(item)->empty())) {
    3640                    continue;
     41                } else if (LLVM_UNLIKELY(isa<Alt>(item))) {
     42                    repeat = true;
     43                } else { // if we have an alternation containing multiple CCs, combine them
     44                    CC * const cc = extractCC(item);
     45                    if (cc) {
     46                        namedCC = namedCC ? makeCC(extractCC(namedCC), cc) : item;
     47                        continue;
     48                    }
    3749                }
    3850                list.insert(item);
    3951            }
    40             // When compiling Pablo code, CSE can identify common prefixes but cannot
    41             // identify common suffixes. Prioritize this optimization accordingly.
     52            // Combine and/or insert any named CC object into the alternation
     53            if (namedCC) {
     54                if (LLVM_UNLIKELY(isa<CC>(namedCC))) {
     55                    namedCC = memoize(cast<CC>(namedCC));
     56                }
     57                list.insert(cast<Name>(namedCC));
     58            }
     59            // Pablo CSE may identify common prefixes but cannot identify common suffixes.
    4260            extractCommonSuffixes(list);
    4361            extractCommonPrefixes(list);
    4462            re = makeAlt(list.begin(), list.end());
     63            if (LLVM_UNLIKELY(repeat)) {
     64                goto repeat;
     65            }
    4566        } else if (Seq * seq = dyn_cast<Seq>(re)) {
    4667            std::vector<RE *> list;
    4768            list.reserve(seq->size());
     69            bool repeat = false;
    4870            for (RE * item : *seq) {
    4971                item = minimize(item);
    5072                if (LLVM_UNLIKELY(isa<Vector>(item) && cast<Vector>(item)->empty())) {
    5173                    continue;
     74                } else if (LLVM_UNLIKELY(isa<Seq>(item))) {
     75                    repeat = true;
    5276                }
    5377                list.push_back(item);
    5478            }
     79            for (unsigned i = 1, run = 0; i < list.size(); ) {
     80                if (LLVM_UNLIKELY(list[i - 1] == list[i])) {
     81                    ++run;
     82                } else if (LLVM_UNLIKELY(run != 0)) {
     83                    // If we have a run of the same RE, make a bounded repetition for it
     84                    const auto j = i - run; assert (j > 0);
     85                    list[j - 1] = memoize(makeRep(list[j - 1], run + 1, run + 1));
     86                    list.erase(list.begin() + j, list.begin() + i);
     87                    i = j;
     88                    run = 0;
     89                    continue;
     90                } else if (LLVM_UNLIKELY(isa<Rep>(list[i - 1]) && isa<Rep>(list[i]))){
     91                    // If we have adjacent repetitions of the same RE, we can merge them
     92                    Rep * const r1 = cast<Rep>(list[i - 1]);
     93                    Rep * const r2 = cast<Rep>(list[i]);
     94                    if (LLVM_UNLIKELY(r1->getRE() == r2->getRE())) {
     95                        list[i - 1] = memoize(combineRep(r1, r2));
     96                        list.erase(list.begin() + i);
     97                        continue;
     98                    }
     99                }
     100                ++i;
     101            }
    55102            re = makeSeq(list.begin(), list.end());
     103            if (LLVM_UNLIKELY(repeat)) {
     104                goto repeat;
     105            }
    56106        } else if (Assertion * a = dyn_cast<Assertion>(re)) {
    57             minimize(a->getAsserted());
     107            re = makeAssertion(minimize(a->getAsserted()), a->getKind(), a->getSense());
    58108        } else if (Rep * rep = dyn_cast<Rep>(re)) {
    59             minimize(rep->getRE());
     109            re = makeRep(minimize(rep->getRE()), rep->getLB(), rep->getUB());
    60110        } else if (Diff * diff = dyn_cast<Diff>(re)) {
    61             minimize(diff->getLH());
    62             minimize(diff->getRH());
    63         } else if (Intersect * e = dyn_cast<Intersect>(re)) {
    64             minimize(e->getLH());
    65             minimize(e->getRH());
     111            re = makeDiff(minimize(diff->getLH()), minimize(diff->getRH()));
     112        } else if (Intersect * ix = dyn_cast<Intersect>(re)) {
     113            re = makeIntersect(minimize(ix->getLH()), minimize(ix->getRH()));
    66114        } else if (Name * n = dyn_cast<Name>(re)) {
    67             assert (n->getDefinition());
    68             if (!isa<CC>(n->getDefinition())) {
    69                 n->setDefinition(minimize(n->getDefinition()));
    70             }
    71         }
    72         mMapping.emplace(original, re);
     115            RE * const def = n->getDefinition(); assert (def);
     116            if (LLVM_UNLIKELY(!isa<CC>(def))) {
     117                n->setDefinition(minimize(def));
     118            }
     119        }
     120        re = memoize(re);
     121        mMap.emplace(original, re);
     122        if (LLVM_LIKELY(original != re)) {
     123            mMap.emplace(re, re);
     124        }
    73125        return re;
    74126    }
    75127
    76     void extractCommonPrefixes(AlternationSet & source) {
    77         if (LLVM_UNLIKELY(source.size() < 2)) {
     128protected:
     129
     130    void extractCommonPrefixes(Set & source) {
     131        std::vector<RE *> combine;
     132restart:if (LLVM_UNLIKELY(source.size() < 2)) {
    78133            return;
    79134        }
    80135        for (auto i = source.begin(); i != source.end(); ++i) {
    81             assert (mCombine.empty());
    82             assert (*i);
    83             if (Seq * seq_i = dyn_cast<Seq>(*i)) {
    84                 assert (seq_i);
    85                 RE * const head = seq_i->front();
    86                 assert (head);
    87                 for (auto j = i + 1; j != source.end(); ) {
    88                     if (Seq * seq_j = dyn_cast<Seq>(*j)) {
    89                         if (LLVM_UNLIKELY(head == seq_j->front())) {
    90                             mCombine.push_back(seq_j);
    91                             j = source.erase(j);
     136            assert (combine.empty());           
     137            RE * const head = getHead(*i);
     138            for (auto j = i + 1; j != source.end(); ) {
     139                if (LLVM_UNLIKELY(head == getHead(*j))) {
     140                    combine.push_back(*j);
     141                    j = source.erase(j);
     142                    continue;
     143                }
     144                ++j;
     145            }
     146
     147            if (LLVM_UNLIKELY(!combine.empty())) {
     148                combine.push_back(*i);
     149                source.erase(i);
     150                Set tailSet;
     151                tailSet.reserve(combine.size());
     152                bool isOptional = false;
     153                for (RE * const re : combine) {
     154                    if (LLVM_LIKELY(isa<Seq>(re))) {
     155                        Seq * const seq = cast<Seq>(re);
     156                        if (LLVM_LIKELY(seq->size() > 1)) {
     157                            tailSet.insert(minimize(makeSeq(seq->begin() + 1, seq->end())));
     158                            continue;
     159                        }
     160                    } else if (LLVM_UNLIKELY(isa<Rep>(re))) {
     161                        Rep * const rep = cast<Rep>(re);
     162                        if (head != rep) {
     163                            assert (head == rep->getRE());
     164                            assert (rep->getLB() > 0);
     165                            const auto lb = rep->getLB() - 1;
     166                            const auto ub = rep->getUB() == Rep::UNBOUNDED_REP ? Rep::UNBOUNDED_REP : rep->getUB() - 1;
     167                            tailSet.insert(minimize(makeRep(rep->getRE(), lb, ub)));
    92168                            continue;
    93169                        }
    94170                    }
    95                     ++j;
    96                 }
    97                 if (LLVM_UNLIKELY(!mCombine.empty())) {
    98                     AlternationSet tailSet;
    99                     tailSet.reserve(mCombine.size() + 1);
    100                     for (Seq * seq_j : mCombine) {
    101                         if (LLVM_LIKELY(seq_j->size() > 1)) {
    102                             tailSet.insert(makeSeq(seq_j->begin() + 1, seq_j->end()));
     171                    isOptional = true;
     172                }
     173                combine.clear();
     174                extractCommonPrefixes(tailSet);
     175                RE * tail = makeAlt(tailSet.begin(), tailSet.end());
     176                if (LLVM_UNLIKELY(isOptional)) {
     177                    tail = makeRep(tail, 0, 1);
     178                }
     179                source.insert(minimize(makeSeq({ head, tail })));
     180                goto restart;
     181            }
     182        }
     183    }
     184
     185    void extractCommonSuffixes(Set & source) {
     186        std::vector<RE *> combine;
     187restart:if (LLVM_UNLIKELY(source.size() < 2)) {
     188            return;
     189        }
     190        for (auto i = source.begin(); i != source.end(); ++i) {
     191            assert (combine.empty());
     192            assert (*i);
     193            RE * const tail = getTail(*i);
     194            for (auto j = i + 1; j != source.end(); ) {
     195                if (LLVM_UNLIKELY(tail == getTail(*j))) {
     196                    combine.push_back(*j);
     197                    j = source.erase(j);
     198                    continue;
     199                }
     200                ++j;
     201            }
     202            if (LLVM_UNLIKELY(!combine.empty())) {
     203                combine.push_back(*i);
     204                source.erase(i);
     205                Set headSet;
     206                headSet.reserve(combine.size());
     207                bool isOptional = false;
     208                for (RE * const re : combine) {
     209                    if (LLVM_LIKELY(isa<Seq>(re))) {
     210                        Seq * const seq = cast<Seq>(re);
     211                        if (LLVM_LIKELY(seq->size() > 1)) {
     212                            headSet.insert(minimize(makeSeq(seq->begin(), seq->end() - 1)));
     213                            continue;
    103214                        }
    104                     }
    105                     mCombine.clear();
    106                     if (LLVM_LIKELY(seq_i->size() > 1)) {
    107                         tailSet.insert(makeSeq(seq_i->begin() + 1, seq_i->end()));
    108                     }
    109                     extractCommonPrefixes(tailSet);
    110                     source.erase(i);
    111                     RE * const tail = makeAlt(tailSet.begin(), tailSet.end());
    112                     source.insert(makeSeq({ head, tail }));
    113                     extractCommonPrefixes(source);
    114                     break;
    115                 }
    116             }
    117         }
    118     }
    119 
    120     void extractCommonSuffixes(AlternationSet & source) {
    121         if (LLVM_UNLIKELY(source.size() < 2)) {
    122             return;
    123         }
    124         for (auto i = source.begin(); i != source.end(); ++i) {
    125             assert (mCombine.empty());
    126             assert (*i);
    127             if (Seq * seq_i = dyn_cast<Seq>(*i)) {
    128                 assert (seq_i);
    129                 assert (!seq_i->empty());
    130                 RE * const tail = seq_i->back();
    131                 for (auto j = i + 1; j != source.end(); ) {
    132                     if (Seq * seq_j = dyn_cast<Seq>(*j)) {
    133                         if (LLVM_UNLIKELY(tail == seq_j->back())) {
    134                             mCombine.push_back(seq_j);
    135                             j = source.erase(j);
     215                    } else if (LLVM_UNLIKELY(isa<Rep>(re))) {
     216                        Rep * const rep = cast<Rep>(re);
     217                        if (tail != rep) {
     218                            assert (tail == rep->getRE());
     219                            assert (rep->getUB() != 0);
     220                            assert (rep->getLB() > 0);
     221                            const auto lb = rep->getLB() - 1;
     222                            const auto ub = (rep->getUB() == Rep::UNBOUNDED_REP) ? Rep::UNBOUNDED_REP : rep->getUB() - 1;
     223                            headSet.insert(minimize(makeRep(rep->getRE(), lb, ub)));
    136224                            continue;
    137225                        }
    138226                    }
    139                     ++j;
    140                 }
    141                 if (LLVM_UNLIKELY(!mCombine.empty())) {
    142                     AlternationSet headSet;
    143                     headSet.reserve(mCombine.size() + 1);
    144                     for (Seq * seq_j : mCombine) {
    145                         if (LLVM_LIKELY(seq_j->size() > 1)) {
    146                             headSet.insert(makeSeq(seq_j->begin(), seq_j->end() - 1));
    147                         }
    148                     }
    149                     mCombine.clear();
    150                     if (LLVM_LIKELY(seq_i->size() > 1)) {
    151                         headSet.insert(makeSeq(seq_i->begin(), seq_i->end() - 1));
    152                     }
    153                     extractCommonSuffixes(headSet);
    154                     extractCommonPrefixes(headSet);
    155                     source.erase(i);
    156                     RE * head = makeAlt(headSet.begin(), headSet.end());
    157                     source.insert(makeSeq({ head, tail }));
    158                     extractCommonSuffixes(source);
    159                     break;
    160                 }
    161             }
    162         }
     227                    isOptional = true;
     228                }
     229                combine.clear();
     230                extractCommonSuffixes(headSet);
     231                extractCommonPrefixes(headSet);
     232                RE * head = makeAlt(headSet.begin(), headSet.end());
     233                if (LLVM_UNLIKELY(isOptional)) {
     234                    head = makeRep(head, 0, 1);
     235                }
     236                source.insert(minimize(makeSeq({ head, tail })));
     237                goto restart;
     238            }
     239        }
     240    }
     241
     242    static CC * extractCC(RE * const re) {
     243        if (LLVM_UNLIKELY(isa<CC>(re))) {
     244            return cast<CC>(re);
     245        } else if (isa<Name>(re)) {
     246            RE * const def = cast<Name>(re)->getDefinition();
     247            if (LLVM_LIKELY(isa<CC>(def))) {
     248                return cast<CC>(def);
     249            }
     250        }
     251        return nullptr;
     252    }
     253
     254    static RE * combineRep(Rep * const r1, Rep * const r2) {
     255        assert (r1->getRE() == r2->getRE());
     256        assert (r1->getLB() != Rep::UNBOUNDED_REP);
     257        assert (r2->getLB() != Rep::UNBOUNDED_REP);
     258        const int lb = r1->getLB() + r2->getLB();
     259        int ub = Rep::UNBOUNDED_REP;
     260        if ((r1->getUB() != Rep::UNBOUNDED_REP) && (r2->getUB() != Rep::UNBOUNDED_REP)) {
     261            ub = r1->getUB() + r2->getUB();
     262        }
     263        return makeRep(r1->getRE(), lb, ub);
     264    }
     265
     266    static RE * getHead(RE * re) {
     267        assert (re);
     268        if (isa<Seq>(re)) {
     269            re = cast<Seq>(re)->front(); assert (re);
     270        } else if (isa<Rep>(re)) {
     271            Rep * const rep = cast<Rep>(re);
     272            assert (rep->getLB() != Rep::UNBOUNDED_REP);
     273            if (rep->getLB() > 0) {
     274                re = rep->getRE(); assert (re);
     275            }
     276        }
     277        return re;
     278    }
     279
     280    static RE * getTail(RE * re) {
     281        assert (re);
     282        if (isa<Seq>(re)) {
     283            re = cast<Seq>(re)->back();
     284            assert (re);
     285        } else if (isa<Rep>(re)) {
     286            Rep * const rep = cast<Rep>(re);
     287            assert (rep->getLB() != Rep::UNBOUNDED_REP);
     288            assert (rep->getUB() == Rep::UNBOUNDED_REP || rep->getUB() >= rep->getLB());
     289            if (rep->getLB() > 0) {
     290                re = rep->getRE(); assert (re);
     291            }
     292        }
     293        return re;
    163294    }
    164295
    165296private:
    166297
    167     std::vector<Seq *>  mCombine;
    168     Map                 mMapping;
     298    Map mMap;
    169299};
    170300
  • icGREP/icgrep-devel/icgrep/re/re_name_resolve.cpp

    r5631 r5646  
    3030
    3131struct NameResolver {
    32     RE * resolve(RE * re) {
     32    RE * resolve(RE * re) LLVM_ATTRIBUTE_UNUSED_RESULT {
    3333        if (Name * name = dyn_cast<Name>(re)) {
    3434            auto f = mMemoizer.find(name);
     
    5656            std::stringstream name;
    5757            for (auto ai = alt->begin(); ai != alt->end(); ) {
    58                 RE * re = resolve(*ai);
    59                 if (CC * cc = extractCC(re)) {
     58                RE * item = resolve(*ai);
     59                if (CC * cc = extractCC(item)) {
    6060                    if (unionCC == nullptr) {
    6161                        unionCC = cc;
     
    6464                        name << '+';
    6565                    }
    66                     if (LLVM_LIKELY(isa<Name>(re))) {
    67                         Name * n = cast<Name>(re);
     66                    if (LLVM_LIKELY(isa<Name>(item))) {
     67                        Name * n = cast<Name>(item);
    6868                        if (n->hasNamespace()) {
    6969                            name << n->getNamespace() << ':';
    7070                        }
    7171                        name << n->getName();
    72                     } else if (isa<CC>(re)) {
    73                         name << cast<CC>(re)->canonicalName(UnicodeClass);
     72                    } else if (isa<CC>(item)) {
     73                        name << cast<CC>(item)->canonicalName(UnicodeClass);
    7474                    }
    7575                    ai = alt->erase(ai);
    7676                } else {
    77                     *ai++ = re;
     77                    *ai++ = item;
    7878                }
    7979            }
     
    108108    }
    109109
    110     NameResolver() {
    111 
    112     }
    113 
    114110private:
    115111    Memoizer                mMemoizer;
    116112};
    117113   
    118 RE * resolveNames(RE *& re) {
     114RE * resolveNames(RE * re) {
    119115    NameResolver nameResolver;
    120116    return nameResolver.resolve(re);   
  • icGREP/icgrep-devel/icgrep/re/re_name_resolve.h

    r5565 r5646  
    99    class Name;
    1010
    11     RE * resolveNames(RE * &re);
     11    RE * resolveNames(RE * re) LLVM_ATTRIBUTE_UNUSED_RESULT;
    1212
    1313}
  • icGREP/icgrep-devel/icgrep/re/re_nullable.h

    r5509 r5646  
    11#ifndef RE_NULLABLE_H
    22#define RE_NULLABLE_H
     3
     4#include <llvm/Support/Compiler.h>
    35
    46namespace re { class RE; }
     
    911class RE_Nullable {
    1012public:
    11     static RE * removeNullablePrefix(RE * re);
    12     static RE * removeNullableSuffix(RE * re);
    13     static RE * removeNullableAssertion(RE * re);
    14     static RE * removeNullableAfterAssertion(RE * re);
     13    static RE * removeNullablePrefix(RE * re) LLVM_ATTRIBUTE_UNUSED_RESULT;
     14    static RE * removeNullableSuffix(RE * re) LLVM_ATTRIBUTE_UNUSED_RESULT;
     15    static RE * removeNullableAssertion(RE * re) LLVM_ATTRIBUTE_UNUSED_RESULT;
     16    static RE * removeNullableAfterAssertion(RE * re) LLVM_ATTRIBUTE_UNUSED_RESULT;
    1517    static bool isNullable(const RE * re);
    1618    static bool hasNullablePrefix(const RE * re);
  • icGREP/icgrep-devel/icgrep/re/re_parser.h

    r5558 r5646  
    4040    static LLVM_ATTRIBUTE_NORETURN void ParseFailure(std::string errmsg);
    4141
    42     static RE * parse(const std::string &input_string, ModeFlagSet initialFlags, RE_Syntax syntax = RE_Syntax::PCRE, bool ByteMode = false);
     42    static RE * parse(const std::string &input_string, ModeFlagSet initialFlags, RE_Syntax syntax = RE_Syntax::PCRE, bool ByteMode = false) LLVM_ATTRIBUTE_UNUSED_RESULT;
    4343
    4444protected:
  • icGREP/icgrep-devel/icgrep/re/re_rep.cpp

    r5515 r5646  
    1111#include "re_nullable.h"
    1212#include <llvm/Support/Casting.h>
     13#include <llvm/Support/ErrorHandling.h>
    1314
    1415using namespace llvm;
     
    2627   
    2728RE * makeRep(RE * re, int lb, const int ub) {
     29    if (LLVM_UNLIKELY(lb == Rep::UNBOUNDED_REP)) {
     30        report_fatal_error("repetition lower bound must be finite!");
     31    }
     32    if (LLVM_UNLIKELY(ub != Rep::UNBOUNDED_REP && ub < lb)) {
     33        report_fatal_error("lower bound cannot exceed upper bound");
     34    }
    2835    if (RE_Nullable::isNullable(re)) {
    2936        if (ub == 1) {
     
    3138        }
    3239        lb = 0;
    33     }
     40    }   
    3441    if (Rep * rep = dyn_cast<Rep>(re)) {
    3542        int l = rep->getLB();
  • icGREP/icgrep-devel/icgrep/re/re_simplifier.h

    r4841 r5646  
    11#ifndef RE_SIMPLIFIER_H
    22#define RE_SIMPLIFIER_H
     3
     4#include <llvm/Support/Compiler.h>
    35
    46namespace re {
     
    810class RE_Simplifier {
    911public:
    10     static RE * simplify(RE * re);
     12    static RE * simplify(RE * re) LLVM_ATTRIBUTE_UNUSED_RESULT;
    1113};
    1214
  • icGREP/icgrep-devel/icgrep/re/re_star_normal.cpp

    r5493 r5646  
    5656
    5757RE * RE_Star_Normal::helper(RE * re) {
    58 
    5958    if (Alt * alt = dyn_cast<Alt>(re)) {
    6059        std::vector<RE *> list;
     
    6564        re = makeAlt(list.begin(), list.end());
    6665    } else if (Seq * seq = dyn_cast<Seq>(re)) {
    67         RE * re_first = *(seq->begin());
    68         std::vector<RE *> list;
    69         list.reserve(seq->size());
    70         for (auto i = seq->begin() + 1; i != seq->end(); i++) {
    71             list.push_back(*i);
    72         }
    73         RE * re_follow = makeSeq(list.begin(), list.end());
    74         if (!isNullable(re_first) && !isNullable(re_follow)) {
     66        RE * const re_first = *(seq->begin());
     67        RE * const re_follow = makeSeq(seq->begin() + 1, seq->end());
     68        const auto isFirstNullable = isNullable(re_first);
     69        const auto isFollowNullable = isNullable(re_follow);
     70        if (LLVM_LIKELY(!isFirstNullable && !isFollowNullable)) {
    7571            re = makeSeq({star_normal(re_first), star_normal(re_follow)});
    76         } else if (!isNullable(re_first) && isNullable(re_follow)) {
     72        } else if (!isFirstNullable && isFollowNullable) {
    7773            re = makeSeq({helper(re_first), star_normal(re_follow)});
    78         } else if (isNullable(re_first) && !isNullable(re_follow)) {
     74        } else if (isFirstNullable && !isFollowNullable) {
    7975            re = makeSeq({star_normal(re_first), helper(re_follow)});
    8076        } else {
     
    8480        re = makeAssertion(helper(a->getAsserted()), a->getKind(), a->getSense());
    8581    } else if (Rep * rep = dyn_cast<Rep>(re)) {
     82        RE * const expr = helper(rep->getRE());
    8683        if (rep->getLB() == 0 && rep->getUB() == Rep::UNBOUNDED_REP) {
    87             re = helper(rep->getRE());
     84            re = expr;
    8885        } else {
    89             RE * expr = helper(rep->getRE());
    9086            re = makeRep(expr, rep->getLB(), rep->getUB());
    9187        }
  • icGREP/icgrep-devel/icgrep/re/re_toolchain.cpp

    r5630 r5646  
    1616#include <re/printer_re.h>
    1717#include <re/re_analysis.h>
    18 #include <iostream>
    1918#include <llvm/Support/raw_ostream.h>
    2019
     
    5857
    5958
    60 RE * regular_expression_passes(RE * re_ast)  {
     59RE * regular_expression_passes(RE * re)  {
     60
    6161    if (PrintOptions.isSet(ShowAllREs) || PrintOptions.isSet(ShowREs)) {
    62         std::cerr << "Parser:" << std::endl << Printer_RE::PrintRE(re_ast) << std::endl;
     62        errs() << "Parser:\n" << Printer_RE::PrintRE(re) << '\n';
    6363    }
    6464
    6565    //Optimization passes to simplify the AST.
    66     re_ast = RE_Nullable::removeNullablePrefix(re_ast);
     66    re = RE_Nullable::removeNullablePrefix(re);
    6767    if (PrintOptions.isSet(ShowAllREs) || PrintOptions.isSet(ShowStrippedREs)) {
    68         std::cerr << "RemoveNullablePrefix:" << std::endl << Printer_RE::PrintRE(re_ast) << std::endl;
     68        errs() << "RemoveNullablePrefix:\n" << Printer_RE::PrintRE(re) << '\n';
    6969    }
    70     re_ast = RE_Nullable::removeNullableSuffix(re_ast);
     70    re = RE_Nullable::removeNullableSuffix(re);
    7171    if (PrintOptions.isSet(ShowAllREs) || PrintOptions.isSet(ShowStrippedREs)) {
    72         std::cerr << "RemoveNullableSuffix:" << std::endl << Printer_RE::PrintRE(re_ast) << std::endl;
     72        errs() << "RemoveNullableSuffix:\n" << Printer_RE::PrintRE(re) << '\n';
    7373    }
    74     re_ast = RE_Nullable::removeNullableAssertion(re_ast);
     74    re = RE_Nullable::removeNullableAssertion(re);
    7575    if (PrintOptions.isSet(ShowAllREs) || PrintOptions.isSet(ShowStrippedREs)) {
    76         std::cerr << "RemoveNullableAssertion:" << std::endl << Printer_RE::PrintRE(re_ast) << std::endl;
     76        errs() << "RemoveNullableAssertion:\n" << Printer_RE::PrintRE(re) << '\n';
    7777    }
    78     //re_ast = RE_Nullable::removeNullableAfterAssertion(re_ast);
     78    //re = RE_Nullable::removeNullableAfterAssertion(re);
    7979    //if (PrintOptions.isSet(ShowAllREs) || PrintOptions.isSet(ShowStrippedREs)) {
    80     //    std::cerr << "RemoveNullableAfterAssertion" << std::endl << Printer_RE::PrintRE(re_ast) << std::endl;
     80    //    errs() << "RemoveNullableAfterAssertion\n" << Printer_RE::PrintRE(re) << '\n';
    8181    //}
    82    
    83     // re_ast = RE_Minimizer::minimize(re_ast);
    8482
    85     re_ast = RE_Simplifier::simplify(re_ast);
     83    re = RE_Simplifier::simplify(re);
    8684
    8785    if (PrintOptions.isSet(ShowAllREs) || PrintOptions.isSet(ShowSimplifiedREs)) {
    8886        //Print to the terminal the AST that was generated by the simplifier.
    89         std::cerr << "Simplifier:" << std::endl << Printer_RE::PrintRE(re_ast) << std::endl;
     87        errs() << "Simplifier:\n" << Printer_RE::PrintRE(re) << '\n';
    9088    }
     89   
     90//    re = RE_Minimizer::minimize(re);
    9191
    92     re_ast = RE_Star_Normal::star_normal(re_ast);
     92//    if (PrintOptions.isSet(ShowAllREs) || PrintOptions.isSet(ShowSimplifiedREs)) {
     93//        //Print to the terminal the AST that was generated by the simplifier.
     94//        errs() << "Minimizer:\n" << Printer_RE::PrintRE(re) << '\n';
     95//    }
     96
     97    re = RE_Star_Normal::star_normal(re);
    9398
    9499    if (PrintOptions.isSet(ShowAllREs) || PrintOptions.isSet(ShowSimplifiedREs)) {
    95100        //Print to the terminal the AST that was transformed to the star normal form.
    96         std::cerr << "Star_Normal_Form:" << std::endl << Printer_RE::PrintRE(re_ast) << std::endl;
    97     }   
     101        errs() << "Star_Normal_Form:\n" << Printer_RE::PrintRE(re) << '\n';
     102    }
    98103
    99     return re_ast;
     104    return re;
    100105}
    101106   
    102 void re2pablo_compiler(PabloKernel * kernel, RE * re_ast) {
     107PabloAST * re2pablo_compiler(PabloKernel * kernel, RE * re_ast) {
    103108    Var * const basis = kernel->getInputStreamVar("basis");
    104     bool local = RE_Local::isLocalLanguage(re_ast) && isTypeForLocal(re_ast);
     109    const bool local = RE_Local::isLocalLanguage(re_ast) && isTypeForLocal(re_ast);
    105110    cc::CC_Compiler cc_compiler(kernel, basis);
    106111    RE_Compiler re_compiler(kernel, cc_compiler, local);
    107     re_compiler.compileUnicodeNames(re_ast);
    108     re_compiler.compile(re_ast);
     112    re_ast = re_compiler.compileUnicodeNames(re_ast);
     113    return re_compiler.compile(re_ast);
    109114}
    110115
  • icGREP/icgrep-devel/icgrep/re/re_toolchain.h

    r5473 r5646  
    77#ifndef RE_TOOLCHAIN_H
    88#define RE_TOOLCHAIN_H
    9 
     9#include <llvm/Support/Compiler.h>
    1010namespace llvm { namespace cl { class OptionCategory; } }
    11 namespace pablo { class PabloKernel; }
     11namespace pablo { class PabloKernel; class PabloAST; }
    1212namespace re { class RE; }
    1313
     
    2929const llvm::cl::OptionCategory * re_toolchain_flags();
    3030
    31 RE * regular_expression_passes(RE * re_ast);
     31RE * regular_expression_passes(RE * re_ast) LLVM_ATTRIBUTE_UNUSED_RESULT;
    3232
    33 void re2pablo_compiler(pablo::PabloKernel * kernel, RE * re_ast);
     33pablo::PabloAST * re2pablo_compiler(pablo::PabloKernel * kernel, RE * re_ast) LLVM_ATTRIBUTE_UNUSED_RESULT;
    3434   
    3535}
  • icGREP/icgrep-devel/icgrep/toolchain/NVPTXDriver.cpp

    r5630 r5646  
    5858
    5959void NVPTXDriver::generatePipelineIR() {
    60     #ifndef NDEBUG
    61     if (LLVM_UNLIKELY(mPipeline.empty())) {
    62         report_fatal_error("Pipeline cannot be empty");
    63     } else {
    64         for (auto i = mPipeline.begin(); i != mPipeline.end(); ++i) {
    65             for (auto j = i; ++j != mPipeline.end(); ) {
    66                 if (LLVM_UNLIKELY(*i == *j)) {
    67                     report_fatal_error("Kernel instances cannot occur twice in the pipeline");
    68                 }
    69             }
    70         }
    71     }
    72     #endif
    73 
    7460    // note: instantiation of all kernels must occur prior to initialization
    7561    for (const auto & k : mPipeline) {
  • icGREP/icgrep-devel/icgrep/toolchain/cpudriver.cpp

    r5630 r5646  
    2020#include <kernels/kernel.h>
    2121#include <llvm/IR/Verifier.h>
     22
    2223#ifndef NDEBUG
    2324#define IN_DEBUG_MODE true
     
    99100
    100101void ParabixDriver::generatePipelineIR() {
    101 
    102     if (LLVM_UNLIKELY(mPipeline.empty())) {
    103         report_fatal_error("Pipeline cannot be empty");
    104     } else {
    105         for (auto i = mPipeline.begin(); i != mPipeline.end(); ++i) {
    106             for (auto j = i; ++j != mPipeline.end(); ) {
    107                 if (LLVM_UNLIKELY(*i == *j)) {
    108                     report_fatal_error("Kernel " + (*i)->getName() + " occurs twice in the pipeline");
    109                 }
    110             }
    111         }
    112     }
    113102
    114103    for (Kernel * const kernel : mUncachedKernel) {
  • icGREP/icgrep-devel/icgrep/toolchain/driver.cpp

    r5620 r5646  
    2929}
    3030
    31 kernel::Kernel * Driver::addKernelInstance(std::unique_ptr<kernel::Kernel> kb) {
     31kernel::Kernel * Driver::addKernelInstance(std::unique_ptr<Kernel> kb) {
    3232    mOwnedKernels.emplace_back(std::move(kb));
    3333    return mOwnedKernels.back().get();
     
    3535
    3636void Driver::deallocateBuffers() {
    37     for (auto &b : mOwnedBuffers) {
     37    for (const auto & b : mOwnedBuffers) {
    3838        b->releaseBuffer(iBuilder);
    3939    }
  • icGREP/icgrep-devel/icgrep/toolchain/object_cache.cpp

    r5630 r5646  
    8484            Module * const m = f->second.first; assert (m);
    8585            kernel->setModule(m);
     86            kernel->prepareCachedKernel(idb);
    8687            return true;
    8788        }
  • icGREP/icgrep-devel/icgrep/wc.cpp

    r5597 r5646  
    1111#include <llvm/IR/Function.h>
    1212#include <llvm/IR/Module.h>
    13 // #include <llvm/ExecutionEngine/ExecutionEngine.h>
    14 // #include <llvm/Linker/Linker.h>
    1513#include <llvm/Support/CommandLine.h>
    1614#include <llvm/Support/raw_ostream.h>
Note: See TracChangeset for help on using the changeset viewer.