Changeset 4870 for icGREP


Ignore:
Timestamp:
Nov 14, 2015, 5:38:36 PM (4 years ago)
Author:
nmedfort
Message:

Bug fix for Multiplexing. Added ability to set the body of a If/While? node after creation.

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

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/pablo/analysis/pabloverifier.cpp

    r4866 r4870  
    3737}
    3838
    39 void verifyUseDefInformation(const PabloBlock & block, const ScopeSet & validScopes) {
    40     for (const Statement * stmt : block) {
    41 
     39void verifyUseDefInformation(const PabloBlock * block, const ScopeSet & validScopes) {
     40    for (const Statement * stmt : *block) {
    4241        for (const PabloAST * use : stmt->users()) {
    4342            if (LLVM_LIKELY(isa<Statement>(use))) {
     
    4746                    std::string tmp;
    4847                    raw_string_ostream str(tmp);
    49                     PabloPrinter::print(user, "PabloVerifier: use-def error: ", str);
     48                    str << "PabloVerifier: use-def error: ";
     49                    PabloPrinter::print(user, str);
    5050                    str << " is a user of ";
    5151                    PabloPrinter::print(stmt, str);
     
    100100                std::string tmp;
    101101                raw_string_ostream str(tmp);
    102                 PabloPrinter::print(stmt, "PabloVerifier: def-use error: ", str);
     102                str << "PabloVerifier: def-use error: ";
     103                PabloPrinter::print(stmt, str);
    103104                str << " is not a user of ";
    104105                PabloPrinter::print(def, str);
     
    112113}
    113114
    114 void gatherValidScopes(const PabloBlock & block, ScopeSet & validScopes) {
    115     validScopes.insert(&block);
    116     for (const Statement * stmt : block) {
     115void gatherValidScopes(const PabloBlock * block, ScopeSet & validScopes) {
     116    validScopes.insert(block);
     117    for (const Statement * stmt : *block) {
    117118        if (LLVM_UNLIKELY(isa<If>(stmt) || isa<While>(stmt))) {
    118119            gatherValidScopes(isa<If>(stmt) ? cast<If>(stmt)->getBody() : cast<While>(stmt)->getBody(), validScopes);
     
    130131 * @brief unreachable
    131132 ** ------------------------------------------------------------------------------------------------------------- */
    132 bool unreachable(const Statement * stmt, const PabloBlock & block) {
     133bool unreachable(const Statement * stmt, const PabloBlock * const block) {
    133134    PabloBlock * parent = stmt->getParent();
    134135    while (parent)  {
    135         if (parent == &block) {
     136        if (parent == block) {
    136137            return false;
    137138        }
     
    144145 * @brief verifyProgramStructure
    145146 ** ------------------------------------------------------------------------------------------------------------- */
    146 void verifyProgramStructure(const PabloBlock & block) {
     147void verifyProgramStructure(const PabloBlock * block) {
    147148    const Statement * prev = nullptr;
    148     for (const Statement * stmt : block) {
     149    for (const Statement * stmt : *block) {
    149150        if (LLVM_UNLIKELY(stmt->getPrevNode() != prev)) {
    150151            std::string tmp;
    151152            raw_string_ostream str(tmp);
    152             PabloPrinter::print(stmt, "PabloVerifier: structure error: ", str);
     153            str << "PabloVerifier: structure error: ";
     154            PabloPrinter::print(stmt, str);
    153155            str << " succeeds ";
    154156            PabloPrinter::print(prev, str);
     
    158160        }
    159161        prev = stmt;
    160         if (LLVM_UNLIKELY(stmt->getParent() != &block)) {
     162        if (LLVM_UNLIKELY(stmt->getParent() != block)) {
    161163            std::string tmp;
    162164            raw_string_ostream str(tmp);
    163             PabloPrinter::print(stmt, "PabloVerifier: structure error: ", str);
     165            str << "PabloVerifier: structure error: ";
     166            PabloPrinter::print(stmt, str);
    164167            str << " is not contained in its reported scope block";
    165168            throw std::runtime_error(str.str());
    166169        }
    167170        if (LLVM_UNLIKELY(isa<If>(stmt) || isa<While>(stmt))) {
    168             const PabloBlock & nested = isa<If>(stmt) ? cast<If>(stmt)->getBody() : cast<While>(stmt)->getBody();
    169             if (LLVM_UNLIKELY(nested.getParent() != &block)) {
     171            const PabloBlock * nested = isa<If>(stmt) ? cast<If>(stmt)->getBody() : cast<While>(stmt)->getBody();
     172            if (LLVM_UNLIKELY(nested->getParent() != block)) {
    170173                std::string tmp;
    171174                raw_string_ostream str(tmp);
     
    280283}
    281284
    282 void isTopologicallyOrdered(const PabloBlock & block, const OrderingVerifier & parent) {
     285void isTopologicallyOrdered(const PabloBlock * block, const OrderingVerifier & parent) {
    283286    OrderingVerifier ov(parent);
    284     for (const Statement * stmt : block) {
     287    for (const Statement * stmt : *block) {
    285288        if (LLVM_UNLIKELY(isa<While>(stmt))) {
    286289            isTopologicallyOrdered(cast<While>(stmt)->getBody(), ov);
     
    306309                str << "function is not topologically ordered! ";
    307310                PabloPrinter::print(stmt->getOperand(i), str);
    308                 PabloPrinter::print(stmt, " was used before definition by ", str);
     311                str << " was used before definition by ";
     312                PabloPrinter::print(stmt, str);
    309313                throw std::runtime_error(str.str());
    310314            }
     
    335339    } catch(std::runtime_error err) {
    336340        raw_os_ostream out(std::cerr);
    337         PabloPrinter::print(function.getEntryBlock().statements(), out);
     341        PabloPrinter::print(function, out);
    338342        out.flush();
    339343        if (location.empty()) {
  • icGREP/icgrep-devel/icgrep/pablo/builder.hpp

    r4788 r4870  
    1010public:
    1111
    12     explicit PabloBuilder(PabloBlock & block) : mPb(&block), mParent(nullptr), mExprTable(nullptr) {}
    13 
    14     explicit PabloBuilder(PabloBlock & block, PabloBuilder & parent) : mPb(&block), mParent(&parent), mExprTable(&(parent.mExprTable)) {}
     12    explicit PabloBuilder(PabloBlock * block) : mPb(block), mParent(nullptr), mExprTable(nullptr) {}
     13
     14    explicit PabloBuilder(PabloBlock * block, PabloBuilder & parent) : mPb(block), mParent(&parent), mExprTable(&(parent.mExprTable)) {}
    1515
    1616    PabloBuilder(PabloBuilder && builder) : mPb(builder.mPb), mParent(builder.mParent), mExprTable(std::move(builder.mExprTable)) {}
     
    3131    using const_iterator = PabloBlock::const_iterator;
    3232
    33     inline static PabloBuilder Create(PabloBuilder & parent) noexcept {
    34         return std::move(PabloBuilder(PabloBlock::Create(*(parent.mPb)), parent));
     33    inline static PabloBuilder Create(PabloBlock * block) noexcept {
     34        return std::move(PabloBuilder(block));
     35    }
     36
     37    inline static PabloBuilder Create(PabloBuilder & builder) noexcept {
     38        return std::move(PabloBuilder(new PabloBlock(builder.mPb->mSymbolGenerator), builder));
    3539    }
    3640
     
    150154    /// CreateIf Wrappers
    151155
    152     inline If * createIf(PabloAST * condition, std::initializer_list<Assign *> definedVars, PabloBlock & body) {
     156    inline If * createIf(PabloAST * condition, std::initializer_list<Assign *> definedVars, PabloBlock * body) {
    153157        return mPb->createIf(condition, std::move(definedVars), body);
    154158    }
    155159
    156     inline If * createIf(PabloAST * condition, const std::vector<Assign *> & definedVars, PabloBlock & body) {
     160    inline If * createIf(PabloAST * condition, const std::vector<Assign *> & definedVars, PabloBlock * body) {
    157161        return mPb->createIf(condition, definedVars, body);
    158162    }
    159163
    160     inline If * createIf(PabloAST * condition, std::vector<Assign *> && definedVars, PabloBlock & body) {
     164    inline If * createIf(PabloAST * condition, std::vector<Assign *> && definedVars, PabloBlock * body) {
    161165        return mPb->createIf(condition, std::move(definedVars), body);
    162166    }
    163167
    164168    inline If * createIf(PabloAST * condition, std::initializer_list<Assign *> definedVars, PabloBuilder & builder) {
    165         return mPb->createIf(condition, std::move(definedVars), *builder.mPb);
     169        return mPb->createIf(condition, std::move(definedVars), builder.mPb);
    166170    }
    167171
    168172    inline If * createIf(PabloAST * condition, const std::vector<Assign *> & definedVars, PabloBuilder & builder) {
    169         return mPb->createIf(condition, definedVars, *builder.mPb);
     173        return mPb->createIf(condition, definedVars, builder.mPb);
    170174    }
    171175
    172176    inline If * createIf(PabloAST * condition, std::vector<Assign *> && definedVars, PabloBuilder & builder) {
    173         return mPb->createIf(condition, std::move(definedVars), *builder.mPb);
     177        return mPb->createIf(condition, std::move(definedVars), builder.mPb);
    174178    }
    175179
    176180    /// CreateWhile Wrappers
    177181
    178     inline While * createWhile(PabloAST * condition, const std::initializer_list<Next *> nextVars, PabloBlock & body) {
     182    inline While * createWhile(PabloAST * condition, const std::initializer_list<Next *> nextVars, PabloBlock * body) {
    179183        return mPb->createWhile(condition, nextVars, body);
    180184    }
    181185
    182     inline While * createWhile(PabloAST * condition, const std::vector<Next *> & nextVars, PabloBlock & body) {
     186    inline While * createWhile(PabloAST * condition, const std::vector<Next *> & nextVars, PabloBlock * body) {
    183187        return mPb->createWhile(condition, nextVars, body);
    184188    }
    185189
    186     inline While * createWhile(PabloAST * condition, std::vector<Next *> && nextVars, PabloBlock & body) {
     190    inline While * createWhile(PabloAST * condition, std::vector<Next *> && nextVars, PabloBlock * body) {
    187191        return mPb->createWhile(condition, std::move(nextVars), body);
    188192    }
    189193
    190194    inline While * createWhile(PabloAST * condition, const std::initializer_list<Next *> nextVars, PabloBuilder & builder) {
    191         return mPb->createWhile(condition, nextVars, *builder.mPb);
     195        return mPb->createWhile(condition, std::move(nextVars), builder.mPb);
    192196    }
    193197
    194198    inline While * createWhile(PabloAST * condition, const std::vector<Next *> & nextVars, PabloBuilder & builder) {
    195         return mPb->createWhile(condition, nextVars, *builder.mPb);
     199        return mPb->createWhile(condition, nextVars, builder.mPb);
    196200    }
    197201
    198202    inline While * createWhile(PabloAST * condition, std::vector<Next *> && nextVars, PabloBuilder & builder) {
    199         return mPb->createWhile(condition, std::move(nextVars), *builder.mPb);
     203        return mPb->createWhile(condition, std::move(nextVars), builder.mPb);
    200204    }
    201205
  • icGREP/icgrep-devel/icgrep/pablo/carry_manager.cpp

    r4845 r4870  
    3333        for (Statement * stmt : *pb) {
    3434            if (If * ifStatement = dyn_cast<If>(stmt)) {
    35                 count += doScopeCount(&ifStatement->getBody());
     35                count += doScopeCount(ifStatement->getBody());
    3636            }
    3737            else if (While * whileStatement = dyn_cast<While>(stmt)) {
    38                 count += doScopeCount(&whileStatement->getBody());
     38                count += doScopeCount(whileStatement->getBody());
    3939            }
    4040        }
     
    151151        }
    152152        else if (If * ifStatement = dyn_cast<If>(stmt)) {
    153             const unsigned ifCarryDataBits = enumerate(&ifStatement->getBody(), ifDepth+1, whileDepth);
    154             PabloBlockCarryData * nestedBlockData = mCarryInfoVector[ifStatement->getBody().getScopeIndex()];
     153            const unsigned ifCarryDataBits = enumerate(ifStatement->getBody(), ifDepth+1, whileDepth);
     154            PabloBlockCarryData * nestedBlockData = mCarryInfoVector[ifStatement->getBody()->getScopeIndex()];
    155155            if (mITEMS_PER_PACK == mPACK_SIZE) {  // PACKING
    156156                if (cd->roomInFinalPack(nestedOffset) < ifCarryDataBits) {
     
    168168        }
    169169        else if (While * whileStatement = dyn_cast<While>(stmt)) {
    170             const unsigned whileCarryDataBits = enumerate(&whileStatement->getBody(), ifDepth, whileDepth+1);
    171             PabloBlockCarryData * nestedBlockData = mCarryInfoVector[whileStatement->getBody().getScopeIndex()];
     170            const unsigned whileCarryDataBits = enumerate(whileStatement->getBody(), ifDepth, whileDepth+1);
     171            PabloBlockCarryData * nestedBlockData = mCarryInfoVector[whileStatement->getBody()->getScopeIndex()];
    172172            //if (whileStatement->isMultiCarry()) whileCarryDataBits *= whileStatement->getMaxIterations();
    173173            if (mITEMS_PER_PACK == mPACK_SIZE) {  // PACKING
     
    625625        for (Statement * stmt : *mCurrentScope) {
    626626            if (If * innerIf = dyn_cast<If>(stmt)) {
    627                 PabloBlock * inner_blk = & innerIf->getBody();
     627                PabloBlock * inner_blk = innerIf->getBody();
    628628                enterScope(inner_blk);
    629629                if (blockHasCarries()) {
     
    633633            }
    634634            else if (While * innerWhile = dyn_cast<While>(stmt)) {
    635                 PabloBlock * inner_blk = & innerWhile->getBody();
     635                PabloBlock * inner_blk = innerWhile->getBody();
    636636                enterScope(inner_blk);
    637637                if (blockHasCarries()) {
  • icGREP/icgrep-devel/icgrep/pablo/codegenstate.cpp

    r4868 r4870  
    66
    77#include <pablo/codegenstate.h>
     8#include <iostream>
     9#include <pablo/printer_pablos.h>
    810
    911namespace pablo {
     
    482484}
    483485
    484 If * PabloBlock::createIf(PabloAST * condition, const std::initializer_list<Assign *> definedVars, PabloBlock & body) {
     486If * PabloBlock::createIf(PabloAST * condition, const std::initializer_list<Assign *> definedVars, PabloBlock * body) {
    485487    assert (condition);
    486488    return insertAtInsertionPoint(new If(condition, definedVars, body));
    487489}
    488490
    489 If * PabloBlock::createIf(PabloAST * condition, const std::vector<Assign *> & definedVars, PabloBlock & body) {
     491If * PabloBlock::createIf(PabloAST * condition, const std::vector<Assign *> & definedVars, PabloBlock * body) {
    490492    assert (condition);
    491493    return insertAtInsertionPoint(new If(condition, definedVars, body));
    492494}
    493495
    494 If * PabloBlock::createIf(PabloAST * condition, std::vector<Assign *> && definedVars, PabloBlock & body) {
     496If * PabloBlock::createIf(PabloAST * condition, std::vector<Assign *> && definedVars, PabloBlock * body) {
    495497    assert (condition);
    496498    return insertAtInsertionPoint(new If(condition, definedVars, body));
    497499}
    498500
    499 While * PabloBlock::createWhile(PabloAST * condition, const std::initializer_list<Next *> nextVars, PabloBlock & body) {
     501While * PabloBlock::createWhile(PabloAST * condition, const std::initializer_list<Next *> nextVars, PabloBlock * body) {
    500502    assert (condition);
    501503    return insertAtInsertionPoint(new While(condition, nextVars, body));
    502504}
    503505
    504 While * PabloBlock::createWhile(PabloAST * condition, const std::vector<Next *> & nextVars, PabloBlock & body) {
     506While * PabloBlock::createWhile(PabloAST * condition, const std::vector<Next *> & nextVars, PabloBlock * body) {
    505507    assert (condition);
    506508    return insertAtInsertionPoint(new While(condition, nextVars, body));
    507509}
    508510
    509 While * PabloBlock::createWhile(PabloAST * condition, std::vector<Next *> && nextVars, PabloBlock & body) {
     511While * PabloBlock::createWhile(PabloAST * condition, std::vector<Next *> && nextVars, PabloBlock * body) {
    510512    assert (condition);
    511513    return insertAtInsertionPoint(new While(condition, nextVars, body));
    512514}
     515
     516/** ------------------------------------------------------------------------------------------------------------- *
     517 * @brief eraseFromParent
     518 ** ------------------------------------------------------------------------------------------------------------- */
     519void PabloBlock::eraseFromParent(const bool recursively) {
     520    Statement * stmt = front();
     521    // Note: by erasing the scope block, any Assign/Next nodes will be replaced with Zero and removed from
     522    // the If/While node
     523    while (stmt) {
     524        stmt = stmt->eraseFromParent(recursively);
     525    }
     526    mAllocator.deallocate(reinterpret_cast<Allocator::pointer>(this));
     527}
     528
    513529
    514530// Assign sequential scope indexes, returning the next unassigned index   
     
    519535    for (Statement * stmt : *this) {
    520536        if (If * ifStatement = dyn_cast<If>(stmt)) {
    521             nextScopeIndex = ifStatement->getBody().enumerateScopes(nextScopeIndex);
     537            nextScopeIndex = ifStatement->getBody()->enumerateScopes(nextScopeIndex);
    522538        }
    523539        else if (While * whileStatement = dyn_cast<While>(stmt)) {
    524             nextScopeIndex = whileStatement->getBody().enumerateScopes(nextScopeIndex);
     540            nextScopeIndex = whileStatement->getBody()->enumerateScopes(nextScopeIndex);
    525541        }
    526542    }
     
    530546/// CONSTRUCTOR
    531547
    532 PabloBlock::PabloBlock(SymbolGenerator * symbolGenerator)
     548PabloBlock::PabloBlock(SymbolGenerator * symbolGenerator) noexcept
    533549: PabloAST(PabloAST::ClassTypeId::Block)
    534550, mSymbolGenerator(symbolGenerator)
     
    539555}
    540556
    541 PabloBlock::PabloBlock(PabloBlock * predecessor)
    542 : PabloAST(PabloAST::ClassTypeId::Block)
    543 , mSymbolGenerator(predecessor->mSymbolGenerator)
    544 , mParent(predecessor)
    545 , mScopeIndex(0)
    546 {
    547 
    548 }
    549 
    550557PabloBlock::~PabloBlock() {
    551558
  • icGREP/icgrep-devel/icgrep/pablo/codegenstate.h

    r4860 r4870  
    5353    }
    5454
    55     inline static PabloBlock & Create(SymbolGenerator * symbolGenerator) {
    56         assert (symbolGenerator);
    57         return *(new PabloBlock(symbolGenerator));
    58     }
    59 
    60     inline static PabloBlock & Create(PabloBlock & parent) {
    61         return *(new PabloBlock(&parent));
     55    inline static PabloBlock * Create(PabloFunction & function) noexcept {
     56        return new PabloBlock(function.mSymbolTable);
    6257    }
    6358
     
    136131    PabloAST * createCount(PabloAST * expr, const std::string prefix);
    137132   
    138     If * createIf(PabloAST * condition, const std::initializer_list<Assign *> definedVars, PabloBlock & body);
    139 
    140     If * createIf(PabloAST * condition, const std::vector<Assign *> & definedVars, PabloBlock & body);
    141 
    142     If * createIf(PabloAST * condition, std::vector<Assign *> && definedVars, PabloBlock & body);
    143 
    144     While * createWhile(PabloAST * condition, const std::initializer_list<Next *> nextVars, PabloBlock & body);
    145 
    146     While * createWhile(PabloAST * condition, const std::vector<Next *> & nextVars, PabloBlock & body);
    147 
    148     While * createWhile(PabloAST * condition, std::vector<Next *> && nextVars, PabloBlock & body);
     133    If * createIf(PabloAST * condition, const std::initializer_list<Assign *> definedVars, PabloBlock * body);
     134
     135    If * createIf(PabloAST * condition, const std::vector<Assign *> & definedVars, PabloBlock * body);
     136
     137    If * createIf(PabloAST * condition, std::vector<Assign *> && definedVars, PabloBlock * body);
     138
     139    While * createWhile(PabloAST * condition, const std::initializer_list<Next *> nextVars, PabloBlock * body);
     140
     141    While * createWhile(PabloAST * condition, const std::vector<Next *> & nextVars, PabloBlock * body);
     142
     143    While * createWhile(PabloAST * condition, std::vector<Next *> && nextVars, PabloBlock * body);
    149144
    150145    PabloAST * createMod64Advance(PabloAST * expr, const Integer::Type shiftAmount);
     
    189184    }
    190185   
     186    void setParent(PabloBlock * parent) {
     187        mParent = parent;
     188        // Add test to assert this block is in the same function.
     189    }
     190
    191191    void insert(Statement * const statement);
    192192
     
    197197    }
    198198   
     199    void eraseFromParent(const bool recursively = false);
     200
    199201    virtual ~PabloBlock();
    200202
    201203protected:
    202204
    203     explicit PabloBlock(SymbolGenerator * symbolGenerator);
    204 
    205     explicit PabloBlock(PabloBlock * predecessor);
     205    explicit PabloBlock(SymbolGenerator * symbolGenerator) noexcept;
    206206
    207207    PabloAST * renameNonNamedNode(PabloAST * expr, const std::string && prefix);
     
    211211        if (isa<Statement>(expr)) {
    212212            if (LLVM_UNLIKELY(isa<If>(expr) || isa<While>(expr))) {
    213                 PabloBlock & body = isa<If>(expr) ? cast<If>(expr)->getBody() : cast<While>(expr)->getBody();
    214                 this->addUser(&body);
     213                PabloBlock * const body = isa<If>(expr) ? cast<If>(expr)->getBody() : cast<While>(expr)->getBody();
     214                body->setParent(this);
     215                addUser(body);
    215216            }
    216217            insert(cast<Statement>(expr));
     
    228229    static Zeroes                                       mZeroes;
    229230    static Ones                                         mOnes;
    230     SymbolGenerator *                                   mSymbolGenerator;
     231    SymbolGenerator *                                   mSymbolGenerator; // TODO: need a better way of passing a symbol generator around
    231232    PabloBlock *                                        mParent;
    232233    unsigned                                            mScopeIndex;
  • icGREP/icgrep-devel/icgrep/pablo/function.cpp

    r4860 r4870  
    1717: Prototype(ClassTypeId::Function, std::move(name), numOfParameters, numOfResults, nullptr)
    1818, mSymbolTable(new SymbolGenerator())
    19 , mEntryBlock(PabloBlock::Create(mSymbolTable))
     19, mEntryBlock(PabloBlock::Create(*this))
    2020, mParameters(reinterpret_cast<Var **>(mAllocator.allocate(sizeof(Var *) * numOfParameters)))
    2121, mResults(reinterpret_cast<Assign **>(mAllocator.allocate(sizeof(Assign *) * numOfResults))) {
  • icGREP/icgrep-devel/icgrep/pablo/function.h

    r4860 r4870  
    8282    }
    8383
    84     PabloBlock & getEntryBlock() {
     84    PabloBlock * getEntryBlock() {
    8585        return mEntryBlock;
    8686    }
    8787
    88     const PabloBlock & getEntryBlock() const {
     88    const PabloBlock * getEntryBlock() const {
    8989        return mEntryBlock;
     90    }
     91
     92    PabloBlock * setEntryBlock(PabloBlock * entryBlock) {
     93        assert (entryBlock);
     94        std::swap(mEntryBlock, entryBlock);
     95        return entryBlock;
    9096    }
    9197
     
    150156private:
    151157    SymbolGenerator *   mSymbolTable;
    152     PabloBlock &        mEntryBlock;   
     158    PabloBlock *        mEntryBlock;
    153159    Var ** const        mParameters;
    154160    Assign ** const     mResults;
  • icGREP/icgrep-devel/icgrep/pablo/optimizers/booleanreassociationpass.cpp

    r4868 r4870  
    1010#include <algorithm>
    1111#include <numeric> // std::iota
    12 
    1312#ifndef NDEBUG
    1413#include <queue>
     14#endif
     15
    1516#include <pablo/printer_pablos.h>
     17#include <llvm/Support/raw_os_ostream.h>
    1618#include <iostream>
    17 #include <llvm/Support/raw_os_ostream.h>
    18 #include <boost/graph/strong_components.hpp>
    19 #endif
    20 
    2119
    2220using namespace boost;
     
    8684}
    8785
    88 static inline bool inCurrentBlock(const Statement * stmt, const PabloBlock & block) {
    89     return stmt->getParent() == &block;
    90 }
    91 
    92 static inline bool inCurrentBlock(const PabloAST * expr, const PabloBlock & block) {
     86static inline bool inCurrentBlock(const Statement * stmt, const PabloBlock * const block) {
     87    return stmt->getParent() == block;
     88}
     89
     90static inline bool inCurrentBlock(const PabloAST * expr, const PabloBlock * const block) {
    9391    return expr ? isa<Statement>(expr) && inCurrentBlock(cast<Statement>(expr), block) : true;
    9492}
     
    167165bool BooleanReassociationPass::optimize(PabloFunction & function) {
    168166    BooleanReassociationPass brp;
    169     brp.resolveScopes(function);
    170     brp.processScopes(function);   
     167    // brp.resolveScopes(function);
     168    PabloVerifier::verify(function, "pre-reassociation");
     169    brp.processScopes(function);
    171170    #ifndef NDEBUG
    172171    PabloVerifier::verify(function, "post-reassociation");
     
    179178 * @brief resolveScopes
    180179 ** ------------------------------------------------------------------------------------------------------------- */
    181 inline void BooleanReassociationPass::resolveScopes(PabloFunction &function) {
    182     mResolvedScopes.emplace(&function.getEntryBlock(), nullptr);
     180inline void BooleanReassociationPass::resolveScopes(PabloFunction & function) {
     181    mResolvedScopes.emplace(function.getEntryBlock(), nullptr);
    183182    resolveScopes(function.getEntryBlock());
    184183}
     
    187186 * @brief resolveScopes
    188187 ** ------------------------------------------------------------------------------------------------------------- */
    189 void BooleanReassociationPass::resolveScopes(PabloBlock & block) {
    190     for (Statement * stmt : block) {
     188void BooleanReassociationPass::resolveScopes(PabloBlock * const block) {
     189    for (Statement * stmt : *block) {
    191190        if (isa<If>(stmt) || isa<While>(stmt)) {
    192             PabloBlock & nested = isa<If>(stmt) ? cast<If>(stmt)->getBody() : cast<While>(stmt)->getBody();
    193             mResolvedScopes.emplace(&nested, stmt);
     191            PabloBlock * const nested = isa<If>(stmt) ? cast<If>(stmt)->getBody() : cast<While>(stmt)->getBody();
     192            mResolvedScopes.emplace(nested, stmt);
    194193            resolveScopes(nested);
    195194        }
     
    201200 ** ------------------------------------------------------------------------------------------------------------- */
    202201inline void BooleanReassociationPass::processScopes(PabloFunction & function) {
    203     processScopes(function, function.getEntryBlock());
     202    function.setEntryBlock(processScopes(function, function.getEntryBlock()))->eraseFromParent();
    204203}
    205204
     
    207206 * @brief processScopes
    208207 ** ------------------------------------------------------------------------------------------------------------- */
    209 void BooleanReassociationPass::processScopes(PabloFunction & function, PabloBlock & block) {
    210     for (Statement * stmt : block) {
    211         if (isa<If>(stmt)) {
    212             processScopes(function, cast<If>(stmt)->getBody());
    213         } else if (isa<While>(stmt)) {
    214             processScopes(function, cast<While>(stmt)->getBody());
    215         }
    216     }
    217     processScope(function, block);
     208PabloBlock * BooleanReassociationPass::processScopes(PabloFunction & f, PabloBlock * const block) {
     209    for (Statement * stmt : *block) {
     210        if (If * ifNode = dyn_cast<If>(stmt)) {
     211            PabloBlock * rewrittenBlock = processScopes(f, ifNode->getBody());
     212            mResolvedScopes.emplace(rewrittenBlock, stmt);
     213            PabloBlock * priorBlock = ifNode->setBody(rewrittenBlock);
     214            // mResolvedScopes.erase(priorBlock);
     215            priorBlock->eraseFromParent();
     216            PabloVerifier::verify(f, "post-if");
     217        } else if (While * whileNode = dyn_cast<While>(stmt)) {
     218            PabloBlock * rewrittenBlock = processScopes(f, whileNode->getBody());
     219            mResolvedScopes.emplace(rewrittenBlock, stmt);
     220            PabloBlock * priorBlock = whileNode->setBody(rewrittenBlock);
     221            // mResolvedScopes.erase(priorBlock);
     222            priorBlock->eraseFromParent();
     223            PabloVerifier::verify(f, "post-while");
     224        }
     225    }   
     226    return processScope(f, block);
    218227}
    219228
     
    235244 * @brief writeTree
    236245 ** ------------------------------------------------------------------------------------------------------------- */
    237 inline PabloAST * writeTree(PabloBlock & block, const TypeId typeId, circular_buffer<PabloAST *> & Q) {
     246inline PabloAST * writeTree(PabloBlock * block, const TypeId typeId, circular_buffer<PabloAST *> & Q) {
    238247    while (Q.size() > 1) {
    239248        PabloAST * e1 = Q.front(); Q.pop_front();
     
    242251        switch (typeId) {
    243252            case TypeId::And:
    244                 expr = block.createAnd(e1, e2); break;
     253                expr = block->createAnd(e1, e2); break;
    245254            case TypeId::Or:
    246                 expr = block.createOr(e1, e2); break;
     255                expr = block->createOr(e1, e2); break;
    247256            case TypeId::Xor:
    248                 expr = block.createXor(e1, e2); break;
     257                expr = block->createXor(e1, e2); break;
    249258            default: break;
    250259        }
    251260        Q.push_back(expr);
    252     }   
     261    }
    253262    return Q.front();
    254263}
     
    257266 * @brief isReachableAtEntryPoint
    258267 ** ------------------------------------------------------------------------------------------------------------- */
    259 bool isReachableAtEntryPoint(const PabloAST * const expr, const PabloBlock & block) {
     268bool isReachableAtEntryPoint(const PabloAST * const expr, const PabloBlock * const block) {
    260269    // if expr is not a statement, it's always reachable
    261270    if (isa<Statement>(expr)) {
    262271        const PabloBlock * parent = cast<Statement>(expr)->getParent();
    263272        // if expr is in the current block, it's not reachable at the entry point of this block
    264         if (parent == &block) {
     273        if (parent == block) {
    265274            return false;
    266275        }
    267         const PabloBlock * current = block.getParent();
     276        const PabloBlock * current = block->getParent();
    268277        // If expr is an Assign or Next node, it must escape its block (presuming the Simplifier has eliminated any
    269278        // unnecessary Assign or Next nodes.) We'll want to test whether the parent of its block is an ancestor of
     
    291300 * @brief createTree
    292301 ** ------------------------------------------------------------------------------------------------------------- */
    293 PabloAST * BooleanReassociationPass::createTree(PabloBlock & block, const Vertex u, Graph & G) {
     302PabloAST * BooleanReassociationPass::createTree(const PabloBlock * const block, PabloBlock * const newScope, const Vertex u, Graph & G) {
    294303
    295304    flat_set<PabloAST *> internalVars;
     
    315324
    316325    const TypeId typeId = getType(G[u]);
    317     Statement * stmt = block.front();
     326    Statement * stmt = newScope->front();
    318327    if (Q.size() > 1) {
    319         block.setInsertPoint(nullptr);
    320         writeTree(block, typeId, Q);
     328        newScope->setInsertPoint(nullptr);
     329        writeTree(newScope, typeId, Q);
    321330        assert (Q.size() == 1);
    322331    }
     
    325334
    326335        if (distance > 3 && Q.size() > 1) { // write out the current Q
    327             writeTree(block, typeId, Q);
     336            writeTree(newScope, typeId, Q);
    328337            assert (Q.size() == 1);
    329338        }
     
    352361
    353362        if (found) {
    354             block.setInsertPoint(stmt);
     363            newScope->setInsertPoint(stmt);
    355364            distance = 0;
    356365        }
     
    359368    assert (internalVars.empty());
    360369
    361     block.setInsertPoint(block.back());
    362 
    363     writeTree(block, typeId, Q);
     370    newScope->setInsertPoint(newScope->back());
     371
     372    writeTree(newScope, typeId, Q);
    364373    assert (Q.size() == 1);
    365374    PabloAST * const result = Q.front();
     
    373382 * @brief processScope
    374383 ** ------------------------------------------------------------------------------------------------------------- */
    375 inline void BooleanReassociationPass::processScope(PabloFunction &, PabloBlock & block) {
     384inline PabloBlock * BooleanReassociationPass::processScope(PabloFunction & f, PabloBlock * const block) {
    376385    Graph G;
    377     Map M;
    378     summarizeAST(block, G, M);
    379     redistributeAST(block, G, M);
    380     rewriteAST(block, G);
     386    summarizeAST(block, G);
     387    redistributeAST(G);
     388    return rewriteAST(f, block, G);
    381389}
    382390
     
    384392 * @brief rewriteAST
    385393 ** ------------------------------------------------------------------------------------------------------------- */
    386 void BooleanReassociationPass::rewriteAST(PabloBlock & block, Graph & G) {
     394PabloBlock * BooleanReassociationPass::rewriteAST(PabloFunction & f, PabloBlock * const block, Graph & G) {
    387395
    388396    using ReadyPair = std::pair<unsigned, Vertex>;
     
    431439    for (const Vertex u : make_iterator_range(vertices(G))) {
    432440        if (in_degree(u, G) == 0 && out_degree(u, G) != 0) {
    433 
    434441            readySet.emplace_back(ordering[u], u);
    435442        }
     
    444451    std::sort(readySet.begin(), readySet.end(), readyComparator);
    445452
    446     // Store the original AST then clear the block
    447     std::vector<Statement *> originalAST(block.begin(), block.end());
    448     block.clear();
    449453    flat_set<Vertex> tested;
     454
     455    PabloBlock * const newScope = PabloBlock::Create(f);
    450456
    451457    // Rewrite the AST using the bottom-up ordering
     
    466472                    const auto w = target(ej, G);
    467473                    PabloAST * expr = getValue(G[w]);
    468                     if (expr == nullptr || (isa<Statement>(expr) && cast<Statement>(expr)->getParent() == nullptr)) {
     474                    if (expr == nullptr || (isa<Statement>(expr) && cast<Statement>(expr)->getParent() != newScope)) {
    469475                        if (++remaining > 1) {
    470476                            break;
     
    483489        Vertex u; unsigned weight;
    484490        std::tie(weight, u) = *chosen;
    485         readySet.erase(chosen);               
     491        readySet.erase(chosen);
    486492        PabloAST * expr = getValue(G[u]);
    487493
     
    490496        if (LLVM_LIKELY(isMutable(G[u]))) {
    491497            if (isAssociative(G[u])) {
    492                 expr = createTree(block, u, G);
     498                expr = createTree(block, newScope, u, G);
    493499            }
    494500            assert (expr);
     
    501507            }
    502508            // Make sure that optimization doesn't reduce this to an already written statement
    503             if (LLVM_LIKELY(isa<Statement>(expr) && cast<Statement>(expr)->getParent() == nullptr)) {
    504                 block.insert(cast<Statement>(expr));
     509            if (LLVM_LIKELY(isa<Statement>(expr) && cast<Statement>(expr)->getParent() != newScope)) {
     510                newScope->insert(cast<Statement>(expr));
    505511            }
    506512        }
     
    521527                }
    522528                if (ready) {
    523 
    524529                    auto entry = std::make_pair(ordering[v], v);
    525530                    auto position = std::lower_bound(readySet.begin(), readySet.end(), entry, readyComparator);
     
    532537    }
    533538
    534     for (Statement * stmt : originalAST) {
    535         if (stmt->getParent() == nullptr) {
    536             stmt->eraseFromParent();
    537         }
    538     }
     539    return newScope;
    539540}
    540541
     
    545546 * are "flattened" (i.e., allowed to have any number of inputs.)
    546547 ** ------------------------------------------------------------------------------------------------------------- */
    547 void BooleanReassociationPass::summarizeAST(PabloBlock & block, Graph & G, Map & M) const {
     548void BooleanReassociationPass::summarizeAST(PabloBlock * const block, Graph & G) const {
     549    Map M;
    548550    // Compute the base def-use graph ...
    549     for (Statement * stmt : block) {
     551    for (Statement * stmt : *block) {
    550552        const Vertex u = getSummaryVertex(stmt, G, M, block);
    551553        for (unsigned i = 0; i != stmt->getNumOperands(); ++i) {
     
    587589    }
    588590    std::vector<Vertex> mapping(num_vertices(G));
    589     summarizeGraph(block, G, mapping, M);
     591    summarizeGraph(G, mapping);
    590592}
    591593
     
    593595 * @brief resolveNestedUsages
    594596 ** ------------------------------------------------------------------------------------------------------------- */
    595 void BooleanReassociationPass::resolveNestedUsages(const Vertex u, PabloAST * expr, PabloBlock & block, Graph & G, Map & M, const Statement * const ignoreIfThis) const {
     597void BooleanReassociationPass::resolveNestedUsages(const Vertex u, PabloAST * expr, PabloBlock * const block, Graph & G, Map & M, const Statement * const ignoreIfThis) const {
    596598    for (PabloAST * user : expr->users()) {
    597599        assert (user);
     
    599601            PabloBlock * parent = cast<Statement>(user)->getParent();
    600602            assert (parent);
    601             if (LLVM_UNLIKELY(parent != &block)) {
     603            if (LLVM_UNLIKELY(parent != block)) {
    602604                for (;;) {
    603605                    if (LLVM_UNLIKELY(parent == nullptr)) {
    604606                        assert (isa<Assign>(expr) || isa<Next>(expr));
    605607                        break;
    606                     } else if (parent->getParent() == &block) {
     608                    } else if (parent->getParent() == block) {
    607609                        const auto f = mResolvedScopes.find(parent);
    608610                        if (LLVM_UNLIKELY(f == mResolvedScopes.end())) {
     
    631633 * @brief summarizeGraph
    632634 ** ------------------------------------------------------------------------------------------------------------- */
    633 inline void BooleanReassociationPass::summarizeGraph(const PabloBlock &, Graph & G, std::vector<Vertex> & mapping, Map &) {
     635inline void BooleanReassociationPass::summarizeGraph(Graph & G, std::vector<Vertex> & mapping) {
    634636    std::vector<Vertex> reverse_topological_ordering;
    635637    reverse_topological_ordering.reserve(num_vertices(G));
     
    637639    topological_sort(G, std::back_inserter(reverse_topological_ordering));
    638640    assert(mapping.size() >= num_vertices(G));
    639     for (const Vertex u : reverse_topological_ordering) {       
     641    for (const Vertex u : reverse_topological_ordering) {
    640642        if (in_degree(u, G) == 0 && out_degree(u, G) == 0) {
    641643            continue;
     
    656658                    }
    657659                    mapping[u] = v;
    658                     clear_vertex(u, G);                   
     660                    clear_vertex(u, G);
    659661                    getType(G[u]) = TypeId::Var;
    660662                    getValue(G[u]) = nullptr;
     
    684686            continue;
    685687        }
    686     }   
     688    }
    687689}
    688690
     
    752754    for (auto Bi = B.begin(); Bi != B.end(); ++Bi) {
    753755        VertexSet Ai(A);
    754         for (const Vertex u : *Bi) {                                   
     756        for (const Vertex u : *Bi) {
    755757            VertexSet Aj;
    756758            Aj.reserve(out_degree(u, G));
     
    945947 * Apply the distribution law to reduce computations whenever possible.
    946948 ** ------------------------------------------------------------------------------------------------------------- */
    947 void BooleanReassociationPass::redistributeAST(const PabloBlock & block, Graph & G, Map & M) const {
     949void BooleanReassociationPass::redistributeAST(Graph & G) const {
    948950
    949951    std::vector<Vertex> mapping(num_vertices(G) + 16);
     
    993995                }
    994996                add_edge(nullptr, u, x, G);
    995             }           
     997            }
    996998
    997999            for (const Vertex s : sources) {
     
    10091011            }
    10101012
    1011             summarizeGraph(block, G, mapping, M);
     1013            summarizeGraph(G, mapping);
    10121014        }
    10131015    }
     
    10241026 * @brief getVertex
    10251027 ** ------------------------------------------------------------------------------------------------------------- */
    1026 Vertex BooleanReassociationPass::getSummaryVertex(PabloAST * expr, Graph & G, Map & M, const PabloBlock & block) {
     1028Vertex BooleanReassociationPass::getSummaryVertex(PabloAST * expr, Graph & G, Map & M, const PabloBlock * const block) {
    10271029    const auto f = M.find(expr);
    10281030    if (f != M.end()) {
  • icGREP/icgrep-devel/icgrep/pablo/optimizers/booleanreassociationpass.h

    r4868 r4870  
    1919    inline BooleanReassociationPass() {}
    2020    void resolveScopes(PabloFunction & function);
    21     void resolveScopes(PabloBlock &block);
     21    void resolveScopes(PabloBlock * const block);
    2222    void processScopes(PabloFunction & function);
    23     void processScopes(PabloFunction & function, PabloBlock & block);
    24     void processScope(PabloFunction &, PabloBlock & block);
    25     void summarizeAST(PabloBlock & block, Graph & G, Map & M) const;
    26     static void summarizeGraph(const PabloBlock & block, Graph & G, std::vector<Vertex> & mapping, Map &M);
    27     void resolveNestedUsages(const Vertex u, PabloAST * expr, PabloBlock & block, Graph & G, Map & M, const Statement * const ignoreIfThis = nullptr) const;
    28     void redistributeAST(const PabloBlock & block, Graph & G, Map & M) const;
    29     void rewriteAST(PabloBlock & block, Graph & G);
    30     static PabloAST * createTree(PabloBlock & block, const Vertex u, Graph & G);
    31     static Vertex getSummaryVertex(PabloAST * expr, Graph & G, Map & M, const PabloBlock & block);
     23    PabloBlock * processScopes(PabloFunction & f, PabloBlock * const block);
     24    PabloBlock * processScope(PabloFunction & f, PabloBlock * const block);
     25    void summarizeAST(PabloBlock * const block, Graph & G) const;
     26    static void summarizeGraph(Graph & G, std::vector<Vertex> & mapping);
     27    void resolveNestedUsages(const Vertex u, PabloAST * expr, PabloBlock * const block, Graph & G, Map & M, const Statement * const ignoreIfThis = nullptr) const;
     28    void redistributeAST(Graph & G) const;
     29    PabloBlock * rewriteAST(PabloFunction & f, PabloBlock * const block, Graph & G);
     30    static PabloAST * createTree(const PabloBlock * const block, PabloBlock * const newScope, const Vertex u, Graph & G);
     31    static Vertex getSummaryVertex(PabloAST * expr, Graph & G, Map & M, const PabloBlock * const block);
    3232    static Vertex addSummaryVertex(const PabloAST::ClassTypeId typeId, Graph & G);
    3333private:
  • icGREP/icgrep-devel/icgrep/pablo/optimizers/codemotionpass.cpp

    r4860 r4870  
    3333 * @brief process
    3434 ** ------------------------------------------------------------------------------------------------------------- */
    35 void CodeMotionPass::process(PabloBlock & block) {
     35void CodeMotionPass::process(PabloBlock * const block) {
    3636    sink(block);
    37     for (Statement * stmt : block) {
     37    for (Statement * stmt : *block) {
    3838        if (isa<If>(stmt)) {
    3939            process(cast<If>(stmt)->getBody());
     
    5757 * @brief calculateDepthToCurrentBlock
    5858 ** ------------------------------------------------------------------------------------------------------------- */
    59 inline static unsigned calculateDepthToCurrentBlock(const PabloBlock * scope, const PabloBlock & root) {
     59inline static unsigned calculateDepthToCurrentBlock(const PabloBlock * scope, const PabloBlock * const root) {
    6060    unsigned depth = 0;
    61     while (scope != &root) {
     61    while (scope != root) {
    6262        ++depth;
    6363        assert (scope);
     
    7171 ** ------------------------------------------------------------------------------------------------------------- */
    7272template <class ScopeSet>
    73 inline bool findScopeUsages(Statement * stmt, ScopeSet & scopeSet, const PabloBlock & block) {
     73inline bool findScopeUsages(Statement * stmt, ScopeSet & scopeSet, const PabloBlock * const block, const PabloBlock * const ignored = nullptr) {
    7474    for (PabloAST * use : stmt->users()) {
    7575        assert (isa<Statement>(use));
    7676        PabloBlock * const parent = cast<Statement>(use)->getParent();
    77         if (LLVM_LIKELY(parent == &block)) {
     77        if (LLVM_LIKELY(parent == block)) {
    7878            return false;
    7979        }
    80         scopeSet.insert(parent);
     80        if (parent != ignored) {
     81            scopeSet.insert(parent);
     82        }
    8183    }
    8284    return true;
     
    8486
    8587/** ------------------------------------------------------------------------------------------------------------- *
    86  * @brief findScopeUsages
    87  ** ------------------------------------------------------------------------------------------------------------- */
    88 template <class ScopeSet>
    89 inline bool findScopeUsages(Statement * stmt, ScopeSet & scopeSet, const PabloBlock & block, const PabloBlock & ignored) {
    90     for (PabloAST * use : stmt->users()) {
    91         assert (isa<Statement>(use));
    92         PabloBlock * const parent = cast<Statement>(use)->getParent();
    93         if (LLVM_LIKELY(parent == &block)) {
    94             return false;
    95         }
    96         if (parent != &ignored) {
    97             scopeSet.insert(parent);
    98         }
    99     }
    100     return true;
    101 }
    102 
    103 /** ------------------------------------------------------------------------------------------------------------- *
    10488 * @brief isAcceptableTarget
    10589 ** ------------------------------------------------------------------------------------------------------------- */
    106 inline bool CodeMotionPass::isAcceptableTarget(Statement * stmt, ScopeSet & scopeSet, const PabloBlock & block) {
     90inline bool CodeMotionPass::isAcceptableTarget(Statement * stmt, ScopeSet & scopeSet, const PabloBlock * const block) {
    10791    // Scan through this statement's users to see if they're all in a nested scope. If so,
    10892    // find the least common ancestor of the scope blocks. If it is not the current scope,
     
    129113 * @brief sink
    130114 ** ------------------------------------------------------------------------------------------------------------- */
    131 void CodeMotionPass::sink(PabloBlock & block) {
     115void CodeMotionPass::sink(PabloBlock * const block) {
    132116    ScopeSet scopes;
    133     Statement * stmt = block.back(); // note: reverse AST traversal
     117    Statement * stmt = block->back(); // note: reverse AST traversal
    134118    while (stmt) {
    135119        Statement * prevNode = stmt->getPrevNode();
     
    163147                assert (scope1 && scope2);
    164148                // But if the LCA is the current block, we can't sink the statement.
    165                 if (scope1 == &block) {
     149                if (scope1 == block) {
    166150                    goto abort;
    167151                }
     
    169153            }
    170154            assert (scopes.size() == 1);
    171             assert (isa<If>(stmt) ? &(cast<If>(stmt)->getBody()) != scopes.front() : true);
    172             assert (isa<While>(stmt) ? &(cast<While>(stmt)->getBody()) != scopes.front() : true);
     155            assert (isa<If>(stmt) ? (cast<If>(stmt)->getBody() != scopes.front()) : true);
     156            assert (isa<While>(stmt) ? (cast<While>(stmt)->getBody() != scopes.front()) : true);
    173157            stmt->insertBefore(scopes.front()->front());
    174158        }
     
    188172    }
    189173    Statement * outerNode = loop->getPrevNode();
    190     Statement * stmt = loop->getBody().front();
     174    Statement * stmt = loop->getBody()->front();
    191175    while (stmt) {
    192176        if (isa<If>(stmt)) {
  • icGREP/icgrep-devel/icgrep/pablo/optimizers/codemotionpass.h

    r4854 r4870  
    3030    static bool optimize(PabloFunction & function);
    3131protected:
    32     static void process(PabloBlock & block);
    33     static bool isAcceptableTarget(Statement *stmt, ScopeSet & scopeSet, const PabloBlock & block);
    34     static void sink(PabloBlock & block);   
     32    static void process(PabloBlock * const block);
     33    static bool isAcceptableTarget(Statement *stmt, ScopeSet & scopeSet, const PabloBlock * const block);
     34    static void sink(PabloBlock * const block);
    3535    static void hoistLoopInvariants(While * loop);
    3636};
  • icGREP/icgrep-devel/icgrep/pablo/optimizers/pablo_automultiplexing.cpp

    r4868 r4870  
    5656                " (" << (((double)num_edges(G)) / ((double)(num_vertices(G) * (num_vertices(G) - 1) / 2))) << ')')
    5757
    58 unsigned __count_advances(const PabloBlock & entry) {
     58unsigned __count_advances(const PabloBlock * const entry) {
    5959
    6060    std::stack<const Statement *> scope;
     
    6262
    6363    // Scan through and collect all the advances, calls, scanthrus and matchstars ...
    64     for (const Statement * stmt = entry.front(); ; ) {
     64    for (const Statement * stmt = entry->front(); ; ) {
    6565        while ( stmt ) {
    6666            if (isa<Advance>(stmt)) {
     
    7070                // Set the next statement to be the first statement of the inner scope and push the
    7171                // next statement of the current statement into the scope stack.
    72                 const PabloBlock & nested = isa<If>(stmt) ? cast<If>(stmt)->getBody() : cast<While>(stmt)->getBody();
     72                const PabloBlock * const nested = isa<If>(stmt) ? cast<If>(stmt)->getBody() : cast<While>(stmt)->getBody();
    7373                scope.push(stmt->getNextNode());
    74                 stmt = nested.front();
     74                stmt = nested->front();
    7575                assert (stmt);
    7676                continue;
     
    108108    RNG rng(seed);
    109109
     110
     111    raw_os_ostream out(std::cerr);
     112
     113//    out << seed << ',';
     114
    110115    LOG("Seed:                    " << seed);
    111116
    112117    AutoMultiplexing am(limit, maxSelections);
    113118    RECORD_TIMESTAMP(start_initialize);
    114     const unsigned advances = am.initialize(function);
     119    const unsigned advances = am.initialize(function, out);
    115120    RECORD_TIMESTAMP(end_initialize);
    116121
     
    126131    am.characterize(function.getEntryBlock());
    127132    RECORD_TIMESTAMP(end_characterize);
     133
     134    out << bdd_getnodenum() << ',' << bdd_getallocnum() << '\n';
    128135
    129136    LOG("Characterize:            " << (end_characterize - start_characterize));
     
    147154        RECORD_TIMESTAMP(end_select_multiplex_sets);
    148155        LOG("SelectMultiplexSets:     " << (end_select_multiplex_sets - start_select_multiplex_sets));
     156
     157//        raw_os_ostream out(std::cerr);
     158//        PabloPrinter::print(function.getEntryBlock().statements(), out);
     159//        out.flush();
    149160
    150161        RECORD_TIMESTAMP(start_subset_constraints);
     
    173184 * the proper variable ordering.
    174185 ** ------------------------------------------------------------------------------------------------------------- */
    175 unsigned AutoMultiplexing::initialize(PabloFunction & function) {
     186unsigned AutoMultiplexing::initialize(PabloFunction & function, raw_ostream & out) {
    176187
    177188    flat_map<const PabloAST *, unsigned> map;   
     
    181192    // Scan through and collect all the advances, calls, scanthrus and matchstars ...
    182193    unsigned statements = 0, advances = 0;
    183     unsigned maxDepth = 0;
    184     mResolvedScopes.emplace(&function.getEntryBlock(), nullptr);
    185     for (Statement * stmt = function.getEntryBlock().front(); ; ) {
     194    mResolvedScopes.emplace(function.getEntryBlock(), nullptr);
     195    for (Statement * stmt = function.getEntryBlock()->front(); ; ) {
    186196        while ( stmt ) {
    187197            ++statements;
     
    189199                // Set the next statement to be the first statement of the inner scope and push the
    190200                // next statement of the current statement into the scope stack.
    191                 const PabloBlock & nested = isa<If>(stmt) ? cast<If>(stmt)->getBody() : cast<While>(stmt)->getBody();
    192                 mResolvedScopes.emplace(&nested, stmt);
     201                const PabloBlock * const nested = isa<If>(stmt) ? cast<If>(stmt)->getBody() : cast<While>(stmt)->getBody();
     202                mResolvedScopes.emplace(nested, stmt);
    193203                scope.push(stmt->getNextNode());
    194                 stmt = nested.front();
    195                 maxDepth = std::max<unsigned>(maxDepth, scope.size());
     204                stmt = nested->front();
    196205                assert (stmt);
    197206                continue;
     
    220229    }
    221230
     231    out << statements << ',' << variableCount << ',' << advances << ',';
     232
    222233    // If there are fewer than three Advances in this program, just abort. We cannot reduce it.
    223234    if (advances < 3) {
     
    241252    unsigned m = 0;
    242253
    243     for (const Statement * stmt = function.getEntryBlock().front();;) {
     254    for (const Statement * stmt = function.getEntryBlock()->front();;) {
    244255        while ( stmt ) {
    245256
     
    264275                // Set the next statement to be the first statement of the inner scope
    265276                // and push the next statement of the current statement into the stack.
    266                 const PabloBlock & nested = isa<If>(stmt) ? cast<If>(stmt)->getBody() : cast<While>(stmt)->getBody();
     277                const PabloBlock * const nested = isa<If>(stmt) ? cast<If>(stmt)->getBody() : cast<While>(stmt)->getBody();
    267278                scope.push(stmt->getNextNode());
    268                 stmt = nested.front();
     279                stmt = nested->front();
    269280                assert (stmt);
    270281                continue;
     
    321332 * Scan through the program and iteratively compute the BDDs for each statement.
    322333 ** ------------------------------------------------------------------------------------------------------------- */
    323 void AutoMultiplexing::characterize(PabloBlock & block) {
    324     for (Statement * stmt : block) {
    325         if (LLVM_UNLIKELY(isa<If>(stmt) || isa<While>(stmt))) {
    326             characterize(isa<If>(stmt) ? cast<If>(stmt)->getBody() : cast<While>(stmt)->getBody());
     334void AutoMultiplexing::characterize(PabloBlock * const block) {
     335    for (Statement * stmt : *block) {
     336        if (LLVM_UNLIKELY(isa<If>(stmt))) {
     337            characterize(cast<If>(stmt)->getBody());
     338        } else if (LLVM_UNLIKELY(isa<While>(stmt))) {
     339            const auto & variants = cast<While>(stmt)->getVariants();
     340            std::vector<BDD> assignments(variants.size());
     341            for (unsigned i = 0; i != variants.size(); ++i) {
     342                assignments[i] = get(variants[i]->getInitial());
     343            }
     344            characterize(cast<While>(stmt)->getBody());
     345            for (unsigned i = 0; i != variants.size(); ++i) {
     346                BDD & var = get(variants[i]->getInitial());
     347                var = bdd_addref(bdd_or(var, assignments[i]));
     348            }
    327349        } else {
    328350            mCharacterizationMap.insert(std::make_pair(stmt, characterize(stmt)));
     
    343365            continue;
    344366        }
    345         auto f = mCharacterizationMap.find(op);
    346         if (LLVM_UNLIKELY(f == mCharacterizationMap.end())) {
    347             std::string tmp;
    348             llvm::raw_string_ostream msg(tmp);
    349             msg << "AutoMultiplexing: Uncharacterized operand " << std::to_string(i);
    350             PabloPrinter::print(stmt, " of ", msg);
    351             throw std::runtime_error(msg.str());
    352         }
    353         input[i] = f->second;
     367        input[i] = get(op);
    354368    }
    355369
     
    394408inline BDD AutoMultiplexing::characterize(Advance * const adv, const BDD Ik) {
    395409
    396     assert (Ik != bdd_zero());
    397 
    398410    bdd_addref(Ik);
    399411
     
    406418        if (unconstrained[i]) continue;
    407419
     420        // If these advances are "shifting" their values by the same amount ...
    408421        const Advance * const ithAdv = std::get<0>(mAdvanceAttributes[i]);
    409         // If these advances are "shifting" their values by the same amount ...
    410422        if (adv->getOperand(1) == ithAdv->getOperand(1)) {
    411             BDD Ii = std::get<1>(mAdvanceAttributes[i]);
    412             const BDD IiIk = bdd_and(Ik, Ii);
    413             bdd_addref(IiIk);
     423            const BDD Ii = get(ithAdv->getOperand(0));
     424            const BDD IiIk = bdd_addref(bdd_and(Ii, Ik));
    414425            // Is there any satisfying truth assignment? If not, these streams are mutually exclusive.
    415426            if (bdd_satone(IiIk) == bdd_zero()) {
     
    418429.
    419430                for (auto e : make_iterator_range(in_edges(i, mSubsetGraph))) {
    420                      unconstrained[source(e, mSubsetGraph)] = true;
     431                    unconstrained[source(e, mSubsetGraph)] = true;
     432                }
     433                unconstrained[i] = true;
     434            } else if (Ii == IiIk) {
     435                // If Ii = Ii ∩ Ik then Ii ⊂ Ik. Record this in the subset graph with the arc (i, k).
     436                // Note: the AST will be modified to make these mutually exclusive if Ai and Ak end up in
     437                // the same multiplexing set.
     438                add_edge(i, k, mSubsetGraph);
     439                // If Ai ⊂ Ak and Aj ⊂ Ai, Aj ⊂ Ak.
     440                for (auto e : make_iterator_range(in_edges(i, mSubsetGraph))) {
     441                    const auto j = source(e, mSubsetGraph);
     442                    add_edge(j, k, mSubsetGraph);
     443                    unconstrained[j] = true;
    421444                }
    422445                unconstrained[i] = true;
    423446            } else if (Ik == IiIk) {
    424447                // If Ik = Ii ∩ Ik then Ik ⊂ Ii. Record this in the subset graph with the arc (k, i).
    425                 // The AST will be modified to make these mutually exclusive if Ai and Ak end up in
    426                 // the same multiplexing set.
    427448                add_edge(k, i, mSubsetGraph);
    428449                // If Ak ⊂ Ai and Ai ⊂ Aj, Ak ⊂ Aj.
     
    433454                }
    434455                unconstrained[i] = true;
    435             } else if (Ii == IiIk) {
    436                 // If Ii = Ii ∩ Ik then Ii ⊂ Ik. Record this in the subset graph with the arc (i, k).
    437                 add_edge(i, k, mSubsetGraph);
    438                 // If Ai ⊂ Ak and Aj ⊂ Ai, Aj ⊂ Ak.
    439                 for (auto e : make_iterator_range(in_edges(i, mSubsetGraph))) {
    440                     const auto j = source(e, mSubsetGraph);
    441                     add_edge(j, k, mSubsetGraph);
    442                     unconstrained[j] = true;
    443                 }
    444                 unconstrained[i] = true;
    445456            }
    446457            bdd_delref(IiIk);
     
    454465    for (unsigned i = 0; i != k; ++i) {
    455466        const Advance * const ithAdv = std::get<0>(mAdvanceAttributes[i]);
    456         auto f = mCharacterizationMap.find(ithAdv);
    457         assert (f != mCharacterizationMap.end());
    458         BDD & Ci = f->second;
    459         const BDD Vi = std::get<2>(mAdvanceAttributes[i]);
     467        BDD & Ci = get(ithAdv);
     468        const BDD Vi = std::get<1>(mAdvanceAttributes[i]);
    460469        if (unconstrained[i]) {
    461             Ck = bdd_and(Ck, bdd_not(Vi));
    462             bdd_addref(Ck);
    463             Ci = bdd_and(Ci, bdd_not(Vk));
    464             bdd_addref(Ci);
     470            Ck = bdd_addref(bdd_imp(Ck, bdd_addref(bdd_not(Vi))));
     471            Ci = bdd_addref(bdd_imp(Ci, bdd_addref(bdd_not(Vk))));
    465472            // If these Advances are mutually exclusive, in the same scope, and transitively independent,
    466473            // we safely multiplex them.
     
    468475                continue;
    469476            }
    470         } else { // TODO: investigate how to determine when it's safe to avoid computing these
    471             Ck = bdd_imp(Ck, Vi);
    472             bdd_addref(Ck);
    473             Ci = bdd_imp(Ci, Vk);
    474             bdd_addref(Ci);
    475477        }
    476478        add_edge(i, k, mConstraintGraph);
    477479    }
    478480
    479     mAdvanceAttributes.emplace_back(adv, Ik, Vk);
     481    bdd_delref(Ik);
     482
     483    mAdvanceAttributes.emplace_back(adv, Vk);
    480484
    481485    return Ck;
     
    755759        const auto v = target(*ei, mSubsetGraph);
    756760        if (in_degree(u, mMultiplexSetGraph) != 0 && in_degree(v, mMultiplexSetGraph) != 0) {
     761            assert (in_degree(u, mMultiplexSetGraph) == 1);
    757762            const auto su = source(*(in_edges(u, mMultiplexSetGraph).first), mMultiplexSetGraph);
     763            assert (in_degree(v, mMultiplexSetGraph) == 1);
    758764            const auto sv = source(*(in_edges(v, mMultiplexSetGraph).first), mMultiplexSetGraph);
    759765            if (su == sv) {
     
    769775        // we perform the minimum number of AST modifications for the given multiplexing sets.
    770776
    771         transitiveReductionOfSubsetGraph();
     777        doTransitiveReductionOfSubsetGraph();
    772778
    773779        // Afterwards modify the AST to ensure that multiplexing algorithm can ignore any subset constraints
     
    819825            Advance * const adv = input[0];
    820826            PabloBlock * const block = adv->getParent(); assert (block);
    821             PabloBuilder builder(*block);
     827            PabloBuilder builder(block);
    822828            block->setInsertPoint(block->back());
    823829
     
    903909    std::unordered_set<const PabloAST *> encountered;
    904910    std::stack<Statement *> scope;
    905     for (Statement * stmt = function.getEntryBlock().front(); ; ) { restart:
     911    for (Statement * stmt = function.getEntryBlock()->front(); ; ) { restart:
    906912        while ( stmt ) {
    907913            for (unsigned i = 0; i != stmt->getNumOperands(); ++i) {
     
    924930                // Set the next statement to be the first statement of the inner scope and push the
    925931                // next statement of the current statement into the scope stack.
    926                 const PabloBlock & nested = isa<If>(stmt) ? cast<If>(stmt)->getBody() : cast<While>(stmt)->getBody();
     932                const PabloBlock * const nested = isa<If>(stmt) ? cast<If>(stmt)->getBody() : cast<While>(stmt)->getBody();
    927933                scope.push(stmt->getNextNode());
    928                 stmt = nested.front();
     934                stmt = nested->front();
    929935                continue;
    930936            }
     
    941947
    942948/** ------------------------------------------------------------------------------------------------------------- *
    943  * @brief transitiveReductionOfSubsetGraph
    944  ** ------------------------------------------------------------------------------------------------------------- */
    945 void AutoMultiplexing::transitiveReductionOfSubsetGraph() {
     949 * @brief doTransitiveReductionOfSubsetGraph
     950 ** ------------------------------------------------------------------------------------------------------------- */
     951void AutoMultiplexing::doTransitiveReductionOfSubsetGraph() {
    946952    std::vector<SubsetGraph::vertex_descriptor> Q;
    947953    for (auto u : make_iterator_range(vertices(mSubsetGraph))) {
     
    971977}
    972978
     979/** ------------------------------------------------------------------------------------------------------------- *
     980 * @brief get
     981 ** ------------------------------------------------------------------------------------------------------------- */
     982inline BDD & AutoMultiplexing::get(const PabloAST * const expr) {
     983    auto f = mCharacterizationMap.find(expr);
     984    assert (f != mCharacterizationMap.end());
     985    return f->second;
     986}
     987
    973988} // end of namespace pablo
  • icGREP/icgrep-devel/icgrep/pablo/optimizers/pablo_automultiplexing.hpp

    r4868 r4870  
    2929    using MultiplexSetGraph = boost::adjacency_list<boost::hash_setS, boost::vecS, boost::bidirectionalS>;
    3030    using SubsetGraph = boost::adjacency_list<boost::hash_setS, boost::vecS, boost::bidirectionalS>;
    31     using AdvanceAttributes = std::vector<std::tuple<Advance *, BDD, BDD>>; // the Advance pointer, input BDD, the base BDD variable
     31    using AdvanceAttributes = std::vector<std::pair<Advance *, BDD>>; // the Advance pointer and its respective base BDD variable
    3232    using VertexVector = std::vector<ConstraintVertex>;
    3333    using ScopeMap = boost::container::flat_map<const PabloBlock *, Statement *>;
     
    3636    static bool optimize(PabloFunction & function, const unsigned limit = std::numeric_limits<unsigned>::max(), const unsigned maxSelections = 100);
    3737protected:
    38     unsigned initialize(PabloFunction & function);
    39     void characterize(PabloBlock & block);
     38    unsigned initialize(PabloFunction & function, raw_ostream & out);
     39    void characterize(PabloBlock * const block);
    4040    BDD characterize(Statement * const stmt);
    4141    BDD characterize(Advance * const adv, const BDD Ik);
     
    4444    void addCandidateSet(const VertexVector & S, RNG & rng);
    4545    void selectMultiplexSets(RNG &);
    46     void transitiveReductionOfSubsetGraph() ;
     46    void doTransitiveReductionOfSubsetGraph() ;
    4747    void applySubsetConstraints();
    4848    void multiplexSelectedIndependentSets(PabloFunction & function);
    4949    static void topologicalSort(PabloFunction & function);
     50    BDD & get(const PabloAST * const expr);
     51
    5052
    5153    inline AutoMultiplexing(const unsigned limit, const unsigned maxSelections)
     
    5860
    5961private:
    60     unsigned                    mLimit;
     62    const unsigned              mLimit;
    6163    const unsigned              mMaxSelections;
    6264    unsigned                    mVariables;
  • icGREP/icgrep-devel/icgrep/pablo/optimizers/pablo_bddminimization.cpp

    r4868 r4870  
    4242    unsigned variableCount = function.getNumOfParameters(); // number of statements that cannot always be categorized without generating a new variable
    4343    unsigned statementCount = 0;
    44     for (const Statement * stmt = function.getEntryBlock().front(); ; ) {
     44    for (const Statement * stmt = function.getEntryBlock()->front(); ; ) {
    4545        while ( stmt ) {
    4646            if (LLVM_UNLIKELY(isa<If>(stmt) || isa<While>(stmt))) {
    4747                // Set the next statement to be the first statement of the inner scope and push the
    4848                // next statement of the current statement into the scope stack.
    49                 const PabloBlock & nested = isa<If>(stmt) ? cast<If>(stmt)->getBody() : cast<While>(stmt)->getBody();
     49                const PabloBlock * const nested = isa<If>(stmt) ? cast<If>(stmt)->getBody() : cast<While>(stmt)->getBody();
    5050                scope.push(stmt->getNextNode());
    51                 stmt = nested.front();
     51                stmt = nested->front();
    5252                assert (stmt);
    5353                continue;
     
    9494void BDDMinimizationPass::eliminateLogicallyEquivalentStatements(PabloFunction & function) {
    9595    SubsitutionMap baseMap;
    96     baseMap.insert(bdd_zero(), function.getEntryBlock().createZeroes());
    97     baseMap.insert(bdd_one(), function.getEntryBlock().createOnes());
     96    baseMap.insert(bdd_zero(), PabloBlock::createZeroes());
     97    baseMap.insert(bdd_one(), PabloBlock::createOnes());
    9898    eliminateLogicallyEquivalentStatements(function.getEntryBlock(), baseMap);
    9999}
     
    102102 * @brief eliminateLogicallyEquivalentStatements
    103103 ** ------------------------------------------------------------------------------------------------------------- */
    104 void BDDMinimizationPass::eliminateLogicallyEquivalentStatements(PabloBlock & block, SubsitutionMap & parent) {
     104void BDDMinimizationPass::eliminateLogicallyEquivalentStatements(PabloBlock * const block, SubsitutionMap & parent) {
    105105    SubsitutionMap map(&parent);
    106     Statement * stmt = block.front();
     106    Statement * stmt = block->front();
    107107    while (stmt) {
    108108        if (LLVM_UNLIKELY(isa<If>(stmt))) {
     
    164164            std::string tmp;
    165165            llvm::raw_string_ostream msg(tmp);
    166             msg << "BDDMinimizationPass: uncharacterized operand " << std::to_string(i);
    167             PabloPrinter::print(stmt, " of ", msg);
     166            msg << "BDDMinimizationPass: uncharacterized operand " << std::to_string(i) << " of ";
     167            PabloPrinter::print(stmt, msg);
    168168            throw std::runtime_error(msg.str());
    169169        }
  • icGREP/icgrep-devel/icgrep/pablo/optimizers/pablo_bddminimization.h

    r4868 r4870  
    4242    void initialize(PabloFunction & function);
    4343    void eliminateLogicallyEquivalentStatements(PabloFunction & function);
    44     void eliminateLogicallyEquivalentStatements(PabloBlock & block, SubsitutionMap & parent);
     44    void eliminateLogicallyEquivalentStatements(PabloBlock * const block, SubsitutionMap & parent);
    4545    void eliminateLogicallyEquivalentStatements(Statement * const stmt, SubsitutionMap & map);
    4646    std::pair<BDD, bool> characterize(Statement * const stmt);
  • icGREP/icgrep-devel/icgrep/pablo/optimizers/pablo_simplifier.cpp

    r4868 r4870  
    3838 * @brief canTriviallyFold
    3939 ** ------------------------------------------------------------------------------------------------------------- */
    40 inline static PabloAST * canTriviallyFold(Statement * stmt, PabloBlock & block) {
     40inline static PabloAST * canTriviallyFold(Statement * stmt, PabloBlock * block) {
    4141    for (unsigned i = 0; i != stmt->getNumOperands(); ++i) {
    4242        if (LLVM_UNLIKELY(isa<Zeroes>(stmt->getOperand(i)))) {
     
    4444                case PabloAST::ClassTypeId::And:
    4545                case PabloAST::ClassTypeId::Advance:
    46                     return block.createZeroes();
     46                    return block->createZeroes();
    4747                case PabloAST::ClassTypeId::Xor:
    4848                case PabloAST::ClassTypeId::Or:
    4949                    return stmt->getOperand(1 - i);
    5050                case PabloAST::ClassTypeId::Not:
    51                     return block.createOnes();
     51                    return block->createOnes();
    5252                case PabloAST::ClassTypeId::Sel:
    53                     block.setInsertPoint(stmt->getPrevNode());
     53                    block->setInsertPoint(stmt->getPrevNode());
    5454                    switch (i) {
    5555                        case 0: return stmt->getOperand(2);
    56                         case 1: return block.createAnd(block.createNot(stmt->getOperand(0)), stmt->getOperand(2));
    57                         case 2: return block.createAnd(stmt->getOperand(0), stmt->getOperand(1));
     56                        case 1: return block->createAnd(block->createNot(stmt->getOperand(0)), stmt->getOperand(2));
     57                        case 2: return block->createAnd(stmt->getOperand(0), stmt->getOperand(1));
    5858                    }
    5959                case PabloAST::ClassTypeId::ScanThru:
     
    6363            }
    6464        } else if (LLVM_UNLIKELY(isa<Ones>(stmt->getOperand(i)))) {
    65             block.setInsertPoint(stmt->getPrevNode());
     65            block->setInsertPoint(stmt->getPrevNode());
    6666            switch (stmt->getClassTypeId()) {
    6767                case PabloAST::ClassTypeId::And:
    6868                    return stmt->getOperand(1 - i);
    6969                case PabloAST::ClassTypeId::Or:
    70                     return block.createOnes();
     70                    return block->createOnes();
    7171                case PabloAST::ClassTypeId::Xor:
    72                     return block.createNot(stmt->getOperand(1 - i));
     72                    return block->createNot(stmt->getOperand(1 - i));
    7373                case PabloAST::ClassTypeId::Not:
    74                     return block.createZeroes();
     74                    return block->createZeroes();
    7575                case PabloAST::ClassTypeId::Sel:
    76                     block.setInsertPoint(stmt->getPrevNode());
     76                    block->setInsertPoint(stmt->getPrevNode());
    7777                    switch (i) {
    7878                        case 0: return stmt->getOperand(1);
    79                         case 1: return block.createOr(stmt->getOperand(0), stmt->getOperand(2));
    80                         case 2: return block.createOr(block.createNot(stmt->getOperand(0)), stmt->getOperand(1));
     79                        case 1: return block->createOr(stmt->getOperand(0), stmt->getOperand(2));
     80                        case 2: return block->createOr(block->createNot(stmt->getOperand(0)), stmt->getOperand(1));
    8181                    }
    8282                case PabloAST::ClassTypeId::ScanThru:
    8383                    if (i == 1) {
    84                         return block.createZeroes();
     84                        return block->createZeroes();
    8585                    }
    8686                    break;
    8787                case PabloAST::ClassTypeId::MatchStar:
    8888                    if (i == 0) {
    89                         return block.createOnes();
     89                        return block->createOnes();
    9090                    }
    9191                    break;
     
    175175 *
    176176 * If this inner block is composed of only Boolean logic and Assign statements and there are fewer than 3
    177  * statements, just add the statements in the inner block to the current block.
    178  ** ------------------------------------------------------------------------------------------------------------- */
    179 inline bool discardNestedIfBlock(const PabloBlock & pb) {
     177 * statements, just add the statements in the inner block to the current block->
     178 ** ------------------------------------------------------------------------------------------------------------- */
     179inline bool discardNestedIfBlock(const PabloBlock * const block) {
    180180    unsigned computations = 0;
    181     for (const Statement * stmt : pb) {
     181    for (const Statement * stmt : *block) {
    182182        switch (stmt->getClassTypeId()) {
    183183            case PabloAST::ClassTypeId::And:
     
    222222 * as replacements. Let the DCE remove the unnecessary statements with the finalized Def-Use information.
    223223 ** ------------------------------------------------------------------------------------------------------------- */
    224 void Simplifier::eliminateRedundantCode(PabloBlock & block, ExpressionTable * predecessor) {
     224void Simplifier::eliminateRedundantCode(PabloBlock * const block, ExpressionTable * predecessor) {
    225225    ExpressionTable encountered(predecessor);
    226     Statement * stmt = block.front();
     226    Statement * stmt = block->front();
    227227
    228228    while (stmt) {
     
    273273            // condition will meet or exceed the cost of executing the body.
    274274            if (LLVM_UNLIKELY(discardNestedIfBlock(ifNode->getBody()))) {
    275                 Statement * nested = ifNode->getBody().front();
     275                Statement * nested = ifNode->getBody()->front();
    276276                while (nested) {
    277277                    Statement * next = nested->removeFromParent();
     
    319319 * @brief deadCodeElimination
    320320 ** ------------------------------------------------------------------------------------------------------------- */
    321 void Simplifier::deadCodeElimination(PabloBlock & block) {
    322     Statement * stmt = block.front();
     321void Simplifier::deadCodeElimination(PabloBlock * const block) {
     322    Statement * stmt = block->front();
    323323    while (stmt) {
    324324        if (isa<If>(stmt)) {
     
    337337 * @brief eliminateRedundantEquations
    338338 ** ------------------------------------------------------------------------------------------------------------- */
    339 void Simplifier::eliminateRedundantEquations(PabloBlock & block) {
    340     Statement * stmt = block.front();
     339void Simplifier::eliminateRedundantEquations(PabloBlock * const block) {
     340    Statement * stmt = block->front();
    341341    while (stmt) {
    342342        if (isa<If>(stmt)) {
     
    351351                if (LLVM_UNLIKELY(op->getNumUses() == 1)) {
    352352                    adv->setOperand(0, op->getOperand(0));
    353                     adv->setOperand(1, block.getInteger(adv->getAdvanceAmount() + op->getAdvanceAmount()));
     353                    adv->setOperand(1, block->getInteger(adv->getAdvanceAmount() + op->getAdvanceAmount()));
    354354                    op->eraseFromParent(false);
    355355                }
     
    361361                Advance * op = cast<Advance>(stmt->getOperand(0));
    362362                if (LLVM_UNLIKELY(op->getNumUses() == 1)) {
    363                     block.setInsertPoint(scanThru->getPrevNode());
    364                     PabloAST * expr = block.createAdvance(op->getOperand(0), op->getAdvanceAmount() - 1);
     363                    block->setInsertPoint(scanThru->getPrevNode());
     364                    PabloAST * expr = block->createAdvance(op->getOperand(0), op->getAdvanceAmount() - 1);
    365365                    scanThru->setOperand(0, expr);
    366                     scanThru->setOperand(1, block.createOr(scanThru->getOperand(1), expr));
     366                    scanThru->setOperand(1, block->createOr(scanThru->getOperand(1), expr));
    367367                    op->eraseFromParent(false);
    368368                }
     
    371371        stmt = stmt->getNextNode();
    372372    }
    373     block.setInsertPoint(block.back());
    374 }
    375 
    376 }
     373    block->setInsertPoint(block->back());
     374}
     375
     376}
  • icGREP/icgrep-devel/icgrep/pablo/optimizers/pablo_simplifier.hpp

    r4829 r4870  
    1212public:
    1313    static bool optimize(PabloFunction & function);
    14     static void deadCodeElimination(PabloBlock & block);
     14    static void deadCodeElimination(PabloBlock * const block);
    1515protected:
    1616    Simplifier() = default;
    1717private:
    18     static void eliminateRedundantCode(PabloBlock & block, ExpressionTable * predecessor = nullptr);
    19     static void eliminateRedundantEquations(PabloBlock & block);
     18    static void eliminateRedundantCode(PabloBlock * const block, ExpressionTable * predecessor = nullptr);
     19    static void eliminateRedundantEquations(PabloBlock * const block);
    2020    static bool isSuperfluous(const Assign * const assign);
    2121};
  • icGREP/icgrep-devel/icgrep/pablo/pabloAST.cpp

    r4868 r4870  
    210210    }
    211211    if (LLVM_UNLIKELY(isa<If>(this) || isa<While>(this))) {
    212         PabloBlock & body = isa<If>(this) ? cast<If>(this)->getBody() : cast<While>(this)->getBody();
    213         mParent->addUser(&body);
     212        PabloBlock * body = isa<If>(this) ? cast<If>(this)->getBody() : cast<While>(this)->getBody();
     213        body->setParent(mParent);
     214        mParent->addUser(body);
    214215    }
    215216}
     
    240241    }
    241242    if (LLVM_UNLIKELY(isa<If>(this) || isa<While>(this))) {
    242         PabloBlock & body = isa<If>(this) ? cast<If>(this)->getBody() : cast<While>(this)->getBody();
    243         mParent->addUser(&body);
     243        PabloBlock * body = isa<If>(this) ? cast<If>(this)->getBody() : cast<While>(this)->getBody();
     244        body->setParent(mParent);
     245        mParent->addUser(body);
    244246    }
    245247}
     
    267269        }
    268270        if (LLVM_UNLIKELY(isa<If>(this) || isa<While>(this))) {
    269             PabloBlock & body = isa<If>(this) ? cast<If>(this)->getBody() : cast<While>(this)->getBody();
    270             mParent->removeUser(&body);
     271            PabloBlock * body = isa<If>(this) ? cast<If>(this)->getBody() : cast<While>(this)->getBody();
     272            body->setParent(nullptr);
     273            mParent->removeUser(body);
    271274        }
    272275    }
     
    289292    // body or we'll lose track of them.
    290293    if (LLVM_UNLIKELY(isa<If>(this) || isa<While>(this))) {
    291         PabloBlock & body = isa<If>(this) ? cast<If>(this)->getBody() : cast<While>(this)->getBody();
    292         Statement * stmt = body.front();
    293         // Note: by erasing the body, any Assign/Next nodes will be replaced with Zero.
    294         while (stmt) {
    295             stmt = stmt->eraseFromParent(recursively);
    296         }
     294        PabloBlock * const body = isa<If>(this) ? cast<If>(this)->getBody() : cast<While>(this)->getBody();
     295        body->eraseFromParent(recursively);
    297296    } else if (LLVM_UNLIKELY(isa<Assign>(this))) {
    298297        for (PabloAST * use : mUsers) {
     
    347346        }
    348347        if (LLVM_UNLIKELY(redundantBranch != nullptr)) {
     348            // By eliminating this redundant branch, we may inadvertantly delete the scope block this statement
     349            // resides within. Check and return null if so.
     350            const PabloBlock * const body = isa<If>(redundantBranch) ? cast<If>(redundantBranch)->getBody() : cast<While>(redundantBranch)->getBody();
     351            const bool eliminatedScope = (body == getParent());
    349352            redundantBranch->eraseFromParent(true);
    350         }
    351     }
    352 
     353            if (eliminatedScope) {
     354                return nullptr;
     355            }
     356        }
     357    }
    353358    Statement * const next = removeFromParent();
    354359    mAllocator.deallocate(reinterpret_cast<Allocator::pointer>(this));
     
    384389    }
    385390    return false;
    386 }
    387 
    388 /** ------------------------------------------------------------------------------------------------------------- *
    389  * @brief clear
    390  ** ------------------------------------------------------------------------------------------------------------- */
    391 void StatementList::clear() {
    392     Statement * stmt = front();
    393     while (stmt) {
    394         Statement * next = stmt->mNext;
    395         if (LLVM_UNLIKELY(isa<If>(stmt) || isa<While>(stmt))) {
    396             PabloBlock & body = isa<If>(stmt) ? cast<If>(stmt)->getBody() : cast<While>(stmt)->getBody();
    397             stmt->mParent->removeUser(&body);
    398         }
    399         stmt->mPrev = nullptr;
    400         stmt->mNext = nullptr;
    401         stmt->mParent = nullptr;
    402         stmt = next;
    403     }
    404     mInsertionPoint = nullptr;
    405     mFirst = nullptr;
    406     mLast = nullptr;
    407391}
    408392
  • icGREP/icgrep-devel/icgrep/pablo/pabloAST.h

    r4860 r4870  
    487487    }
    488488
    489     void clear();
    490 
    491489    inline void setInsertPoint(Statement * const statement) {
    492490        assert (statement == nullptr || contains(statement));
  • icGREP/icgrep-devel/icgrep/pablo/pablo_compiler.cpp

    r4843 r4870  
    9393
    9494 
    95     PabloBlock & mainScope = function->getEntryBlock();
    96 
    97     mainScope.enumerateScopes(0);
     95    PabloBlock * const mainScope = function->getEntryBlock();
     96
     97    mainScope->enumerateScopes(0);
    9898   
    9999    Examine(*function);
     
    124124    //Generate the IR instructions for the function.
    125125   
    126     mCarryManager->initialize(mMod, &mainScope);
     126    mCarryManager->initialize(mMod, mainScope);
    127127   
    128128    compileBlock(mainScope);
     
    191191
    192192
    193 void PabloCompiler::Examine(PabloBlock & block) {
    194     for (Statement * stmt : block) {
     193void PabloCompiler::Examine(PabloBlock * block) {
     194    for (Statement * stmt : *block) {
    195195        if (If * ifStatement = dyn_cast<If>(stmt)) {
    196196            Examine(ifStatement->getBody());
     
    204204}
    205205
    206 void PabloCompiler::compileBlock(PabloBlock & block) {
    207     mPabloBlock = & block;
    208     for (const Statement * statement : block) {
     206void PabloCompiler::compileBlock(PabloBlock * block) {
     207    mPabloBlock = block;
     208    for (const Statement * statement : *block) {
    209209        compileStatement(statement);
    210210    }
    211     mPabloBlock = block.getParent();
     211    mPabloBlock = block->getParent();
    212212}
    213213
     
    235235    BasicBlock * ifEndBlock = BasicBlock::Create(mMod->getContext(), "if.end", mFunction, 0);
    236236   
    237     PabloBlock & ifBody = ifStatement -> getBody();
     237    PabloBlock * ifBody = ifStatement->getBody();
    238238   
    239239    Value * if_test_value = compileExpression(ifStatement->getCondition());
    240240   
    241     mCarryManager->enterScope(&ifBody);
     241    mCarryManager->enterScope(ifBody);
    242242    mBuilder->CreateCondBr(mCarryManager->generateBitBlockOrSummaryTest(if_test_value), ifBodyBlock, ifEndBlock);
    243243   
     
    271271void PabloCompiler::compileWhile(const While * whileStatement) {
    272272
    273     PabloBlock & whileBody = whileStatement -> getBody();
     273    PabloBlock * const whileBody = whileStatement->getBody();
    274274   
    275275    BasicBlock * whileEntryBlock = mBuilder->GetInsertBlock();
     
    277277    BasicBlock * whileEndBlock = BasicBlock::Create(mMod->getContext(), "while.end", mFunction, 0);
    278278
    279     mCarryManager->enterScope(&whileBody);
     279    mCarryManager->enterScope(whileBody);
    280280    mCarryManager->ensureCarriesLoadedRecursive();
    281281
  • icGREP/icgrep-devel/icgrep/pablo/pablo_compiler.h

    r4843 r4870  
    8282    void GenerateFunction(PabloFunction & function);
    8383    void Examine(PabloFunction & function);
    84     void Examine(PabloBlock & block);
     84    void Examine(PabloBlock * block);
    8585
    8686    void SetOutputValue(Value * marker, const unsigned index);
    8787
    88     void compileBlock(PabloBlock & block);
     88    void compileBlock(PabloBlock * block);
    8989    void compileStatement(const Statement * stmt);
    9090    void compileIf(const If * ifStmt);
  • icGREP/icgrep-devel/icgrep/pablo/printer_pablos.cpp

    r4797 r4870  
    55 */
    66
    7 #include <pablo/printer_pablos.h>
     7#include "printer_pablos.h"
     8#include <pablo/codegenstate.h>
     9#include <llvm/Support/raw_os_ostream.h>
    810#include <iostream>
    9 #include <ostream>
    10 #include <llvm/Support/raw_os_ostream.h>
    1111
    12 //Regular Expressions
    13 #include <re/re_re.h>
    14 #include <re/re_cc.h>
    15 #include <re/re_start.h>
    16 #include <re/re_end.h>
    17 #include <re/re_seq.h>
    18 #include <re/re_name.h>
    19 
    20 //Pablo Expressions
    21 #include <pablo/pabloAST.h>
    22 #include <pablo/pe_advance.h>
    23 #include <pablo/pe_and.h>
    24 #include <pablo/pe_call.h>
    25 #include <pablo/pe_matchstar.h>
    26 #include <pablo/pe_not.h>
    27 #include <pablo/pe_or.h>
    28 #include <pablo/pe_scanthru.h>
    29 #include <pablo/pe_sel.h>
    30 #include <pablo/pe_var.h>
    31 #include <pablo/pe_xor.h>
    32 #include <pablo/ps_assign.h>
    33 #include <pablo/ps_if.h>
    34 #include <pablo/ps_while.h>
    35 #include <pablo/pe_zeroes.h>
    36 #include <pablo/pe_ones.h>
    37 #include <pablo/codegenstate.h>
    38 
    39 using namespace re;
    4012using namespace pablo;
    4113
    42 void PabloPrinter::print(const PabloBlock & block, llvm::raw_ostream & strm)
    43 {
    44     print(block.statements(), "  ", strm);
     14const unsigned BlockIndenting = 2;
     15
     16void PabloPrinter::print(const pablo::PabloFunction & function, llvm::raw_ostream & out) {
     17    print(function.getEntryBlock(), out, true);
    4518}
    4619
    47 void PabloPrinter::print(const StatementList & stmts, llvm::raw_ostream & strm) {
    48     print(stmts, "  ", strm);
     20inline void print_vars(const pablo::If::DefinedVars & vars, llvm::raw_ostream & out, const unsigned indent) {
     21    for (const Assign * def : vars) {
     22        out.indent(indent);
     23        out << def->getName() << " = 0\n";
     24    }
    4925}
    5026
    51 void PabloPrinter::print(const StatementList & stmts, std::string indent, llvm::raw_ostream & strm) {
    52     for (const Statement * stmt : stmts) {
    53         print(stmt, indent, strm);
     27void PabloPrinter::print(const Statement * stmt, llvm::raw_ostream & out, const bool expandNested, const unsigned indent) {
     28    out.indent(indent);
     29    if (stmt == nullptr) {
     30        out << "<null-stmt>";
     31    } else if (const Assign * an = dyn_cast<const Assign>(stmt)) {
     32        out << an->getName() << " = ";
     33        print(an->getExpression(), out);
     34    } else if (const Next * next = dyn_cast<const Next>(stmt)) {
     35        out << "Next(" << next->getName() << ") = ";
     36        print(next->getExpr(), out);
     37    } else if (const If * ifstmt = dyn_cast<const If>(stmt)) {
     38        out << "if ";
     39        print(ifstmt->getCondition(), out);
     40        if (expandNested) {
     41            out << ":\n";
     42            print(ifstmt->getBody(), out, true, indent + BlockIndenting);
     43            out.indent(indent);
     44            out << "else:\n";
     45            print_vars(ifstmt->getDefined(), out, indent + BlockIndenting);
     46        }
     47    } else if (const While * whileNode = dyn_cast<const While>(stmt)) {
     48        out << "while ";
     49        print(whileNode->getCondition(), out);
     50        if (expandNested) {
     51            out << ":\n";
     52            print(whileNode->getBody(), out, true, indent + BlockIndenting);
     53        }
     54    } else if (const Call * call = dyn_cast<const Call>(stmt)) {
     55        out << " = " << call->getCallee() << "()";
     56    } else if (const And * pablo_and = dyn_cast<const And>(stmt)) {
     57        out << pablo_and->getName() << " = (";
     58        print(pablo_and->getExpr1(), out);
     59        out << " & ";
     60        print(pablo_and->getExpr2(), out);
     61        out << ")";
     62    } else if (const Or * pablo_or = dyn_cast<const Or>(stmt)) {
     63        out << pablo_or->getName() << " = (";
     64        print(pablo_or->getExpr1(), out);
     65        out << " | ";
     66        print(pablo_or->getExpr2(), out);
     67        out << ")";
     68    } else if (const Xor * pablo_xor = dyn_cast<const Xor>(stmt)) {
     69        out << pablo_xor->getName() << " = (";
     70        print(pablo_xor->getExpr1(), out);
     71        out << " ^ ";
     72        print(pablo_xor->getExpr2(), out);
     73        out << ")";
     74    } else if (const Sel * pablo_sel = dyn_cast<const Sel>(stmt)) {
     75        out << pablo_sel->getName() << " = (";
     76        print(pablo_sel->getCondition(), out);
     77        out << " ? ";
     78        print(pablo_sel->getTrueExpr(), out);
     79        out << " : ";
     80        print(pablo_sel->getFalseExpr(), out);
     81        out << ")";
     82    } else if (const Not * pablo_not = dyn_cast<const Not>(stmt)) {
     83        out << pablo_not->getName() << " = (~";
     84        print(pablo_not->getExpr(), out);
     85        out << ")";
     86    } else if (const Advance * adv = dyn_cast<const Advance>(stmt)) {
     87        out << adv->getName() << " = pablo.Advance(";
     88        print(adv->getExpr(), out);
     89        out << ", " << std::to_string(adv->getAdvanceAmount()) << ")";
     90    } else if (const MatchStar * mstar = dyn_cast<const MatchStar>(stmt)) {
     91        out << mstar->getName() << " = pablo.MatchStar(";
     92        print(mstar->getMarker(), out);
     93        out << ", ";
     94        print(mstar->getCharClass(), out);
     95        out << ")";
     96    } else if (const ScanThru * sthru = dyn_cast<const ScanThru>(stmt)) {
     97        out << sthru->getName() << " = pablo.ScanThru(";
     98        print(sthru->getScanFrom(), out);
     99        out << ", ";
     100        print(sthru->getScanThru(), out);
     101        out << ")";
     102    } else if (const Mod64Advance * adv = dyn_cast<const Mod64Advance>(stmt)) {
     103        out << adv->getName() << " = pablo.Mod64Advance(";
     104        print(adv->getExpr(), out);
     105        out << ", " << std::to_string(adv->getAdvanceAmount()) << ")";
     106    } else if (const Mod64MatchStar * mstar = dyn_cast<const Mod64MatchStar>(stmt)) {
     107        out << mstar->getName() << " = pablo.Mod64MatchStar(";
     108        print(mstar->getMarker(), out);
     109        out << ", ";
     110        print(mstar->getCharClass(), out);
     111        out << ")";
     112    } else if (const Mod64ScanThru * sthru = dyn_cast<const Mod64ScanThru>(stmt)) {
     113        out << sthru->getName() << " = pablo.Mod64ScanThru(";
     114        print(sthru->getScanFrom(), out);
     115        out << ", ";
     116        print(sthru->getScanThru(), out);
     117        out << ")";
     118    } else if (const Count * count = dyn_cast<const Count>(stmt)) {
     119        out << count->getName() << " = pablo.Count(";
     120        print(count->getExpr(), out);
     121        out << ")";
     122    } else {
     123        out << "???";
     124    }
     125}
     126
     127void PabloPrinter::print(const PabloAST * expr, llvm::raw_ostream & out) {
     128    if (expr == nullptr) {
     129        out << "<null-expr>";
     130    } else if (isa<const Zeroes>(expr)) {
     131        out << "0";
     132    } else if (isa<const Ones>(expr)) {
     133        out << "1";
     134    } else if (const Var * var = dyn_cast<const Var>(expr)) {
     135        out  << var->getName();
     136    } else if (const Next * next = dyn_cast<const Next>(expr)) {
     137        out << "Next(" << next->getName() << ")";
     138    } else if (const If * ifstmt = dyn_cast<If>(expr)) {
     139        out << "If ";
     140        print(ifstmt->getCondition(), out);
     141    } else if (const While * whl = dyn_cast<While>(expr)) {
     142        out << "While ";
     143        print(whl->getCondition(), out);
     144    } else if (const Statement * stmt = dyn_cast<Statement>(expr)) {
     145        out << stmt->getName();
     146    } else if (isa<Integer>(expr)) {
     147        out << cast<Integer>(expr)->value();
     148    } else {
     149        out << "???";
     150    }
     151}
     152
     153void PabloPrinter::print(const PabloBlock * block, llvm::raw_ostream & strm, const bool expandNested, const unsigned indent) {
     154    for (const Statement * stmt : *block) {
     155        print(stmt, strm, expandNested, indent);
    54156        strm << "\n";
    55157    }
    56158}
    57159
    58 void PabloPrinter::print_vars(const DefinedVars & vars, std::string indent, llvm::raw_ostream & strm) {
    59     for (const PabloAST * v : vars) {
    60         strm << indent << dyn_cast<Assign>(v)->getName() << " = 0" << "\n";
    61     }
    62 }
    63160
    64 void PabloPrinter::print(const Statement * stmt, std::string indent, llvm::raw_ostream & strm) {
    65     strm << indent;
    66     if (stmt == nullptr) {
    67         strm << "<null-stmt>";
    68     }
    69     else if (const Assign * an = dyn_cast<const Assign>(stmt)) {
    70         strm << an->getName() << " = ";
    71         print(an->getExpression(), strm);
    72     }
    73     else if (const Next * next = dyn_cast<const Next>(stmt)) {       
    74         strm << "Next(" << next->getName() << ") = ";
    75         print(next->getExpr(), strm);
    76     }
    77     else if (const If * ifstmt = dyn_cast<const If>(stmt)) {
    78         strm << "if ";
    79         print(ifstmt->getCondition(), strm);
    80         strm << ":" << "\n";
    81         print(ifstmt->getBody(), indent + "  ", strm);
    82         strm << indent << "else:" << "\n";
    83         print_vars(ifstmt->getDefined(), indent + "  ", strm);
    84     }
    85     else if (const While * whl = dyn_cast<const While>(stmt)) {
    86         strm << "while ";
    87         print(whl->getCondition(), strm);
    88         strm << ":" << "\n";
    89         print(whl->getBody(), indent + "  ", strm);
    90     }
    91     else if (const Call * call = dyn_cast<const Call>(stmt)) {
    92         strm << " = " << call->getCallee() << "()";
    93     }
    94     else if (const And * pablo_and = dyn_cast<const And>(stmt)) {
    95         print(pablo_and, strm);
    96         strm << " = (";
    97         print(pablo_and->getExpr1(), strm);
    98         strm << " & ";
    99         print(pablo_and->getExpr2(), strm);
    100         strm << ")";
    101     }
    102     else if (const Or * pablo_or = dyn_cast<const Or>(stmt)) {
    103         print(pablo_or, strm);
    104         strm << " = (";
    105         print(pablo_or->getExpr1(), strm);
    106         strm << " | ";
    107         print(pablo_or->getExpr2(), strm);
    108         strm << ")";
    109     }
    110     else if (const Xor * pablo_xor = dyn_cast<const Xor>(stmt)) {
    111         print(pablo_xor, strm);
    112         strm << " = (";
    113         print(pablo_xor->getExpr1(), strm);
    114         strm << " ^ ";
    115         print(pablo_xor->getExpr2(), strm);
    116         strm << ")";
    117     }
    118     else if (const Sel * pablo_sel = dyn_cast<const Sel>(stmt)) {
    119         print(pablo_sel, strm);
    120         strm << " = (";
    121         print(pablo_sel->getCondition(), strm);
    122         strm << " ? ";
    123         print(pablo_sel->getTrueExpr(), strm);
    124         strm << " : ";
    125         print(pablo_sel->getFalseExpr(), strm);
    126         strm << ")";
    127     }
    128     else if (const Not * pablo_not = dyn_cast<const Not>(stmt)) {
    129         print(pablo_not, strm);
    130         strm << " = (~";
    131         print(pablo_not->getExpr(), strm);
    132         strm << ")";
    133     }
    134     else if (const Advance * adv = dyn_cast<const Advance>(stmt)) {
    135         print(adv, strm);
    136         strm << " = pablo.Advance(";
    137         print(adv->getExpr(), strm);
    138         strm << ", " << std::to_string(adv->getAdvanceAmount()) << ")";
    139     }
    140     else if (const MatchStar * mstar = dyn_cast<const MatchStar>(stmt)) {
    141         print(mstar, strm);
    142         strm << " = pablo.MatchStar(";
    143         print(mstar->getMarker(), strm);
    144         strm << ", ";
    145         print(mstar->getCharClass(), strm);
    146         strm << ")";
    147     }
    148     else if (const ScanThru * sthru = dyn_cast<const ScanThru>(stmt)) {
    149         print(sthru, strm);
    150         strm << " = pablo.ScanThru(";
    151         print(sthru->getScanFrom(), strm);
    152         strm << ", ";
    153         print(sthru->getScanThru(), strm);
    154         strm << ")";
    155     }
    156     else if (const Mod64Advance * adv = dyn_cast<const Mod64Advance>(stmt)) {
    157         print(adv, strm);
    158         strm << " = pablo.Mod64Advance(";
    159         print(adv->getExpr(), strm);
    160         strm << ", " << std::to_string(adv->getAdvanceAmount()) << ")";
    161     }
    162     else if (const Mod64MatchStar * mstar = dyn_cast<const Mod64MatchStar>(stmt)) {
    163         print(mstar, strm);
    164         strm << " = pablo.Mod64MatchStar(";
    165         print(mstar->getMarker(), strm);
    166         strm << ", ";
    167         print(mstar->getCharClass(), strm);
    168         strm << ")";
    169     }
    170     else if (const Mod64ScanThru * sthru = dyn_cast<const Mod64ScanThru>(stmt)) {
    171         print(sthru, strm);
    172         strm << " = pablo.Mod64ScanThru(";
    173         print(sthru->getScanFrom(), strm);
    174         strm << ", ";
    175         print(sthru->getScanThru(), strm);
    176         strm << ")";
    177     }
    178     else if (const Count * pablo_not = dyn_cast<const Count>(stmt)) {
    179         print(pablo_not, strm);
    180         strm << " = pablo.Count(";
    181         print(pablo_not->getExpr(), strm);
    182         strm << ")";
    183     }
    184     else {
    185         strm << "???";
    186     }
    187 }
    188 
    189 void PabloPrinter::print(const PabloAST * expr, llvm::raw_ostream & strm) {
    190     if (expr == nullptr) {
    191         strm << "<null-expr>";
    192     } else if (isa<const Zeroes>(expr)) {
    193         strm << "0";
    194     } else if (isa<const Ones>(expr)) {
    195         strm << "1";
    196     } else if (const Var * var = dyn_cast<const Var>(expr)) {
    197         assert (var->getName());
    198         strm  << var->getName();
    199     } else if (const Next * next = dyn_cast<const Next>(expr)) {
    200         assert (next->getName());
    201         strm << "Next(" << next->getName() << ")";
    202     } else if (const If * ifstmt = dyn_cast<If>(expr)) {
    203         strm << "if ";
    204         print(ifstmt->getCondition(), strm);
    205     } else if (const While * whl = dyn_cast<While>(expr)) {
    206         strm << "while ";
    207         print(whl->getCondition(), strm);
    208     } else if (const Statement * stmt = dyn_cast<Statement>(expr)) {
    209         assert (stmt->getName());
    210         strm << stmt->getName();
    211     } else if (isa<Integer>(expr)) {
    212         strm << cast<Integer>(expr)->value();
    213     } else {
    214         strm << "???";
    215     }
    216 }
    217 
    218 
  • icGREP/icgrep-devel/icgrep/pablo/printer_pablos.h

    r4788 r4870  
    88#define SHOW_H
    99
    10 #include <pablo/pabloAST.h>
    11 #include <pablo/ps_if.h>
    12 #include <string>
     10namespace llvm { class raw_ostream; }
    1311
    14 namespace pablo { class PabloBlock; }
     12namespace pablo {
    1513
    16 namespace llvm { class raw_ostream; }
     14class PabloFunction;
     15class PabloBlock;
     16class Statement;
     17class PabloAST;
    1718
    1819class PabloPrinter {
    1920public:
    20     using DefinedVars = pablo::If::DefinedVars;
    21     static void print(const pablo::PabloBlock & block, llvm::raw_ostream & strm);
    22     static void print(const pablo::StatementList & stmts, llvm::raw_ostream & strm);
    23     static void print(const pablo::StatementList & stmts, std::string indent, llvm::raw_ostream & strm);
    24     static void print_vars(const DefinedVars & vars, std::string indent, llvm::raw_ostream & strm);
    25     static void print(const pablo::PabloAST * expr, llvm::raw_ostream & strm);
    26     static void print(const pablo::Statement *stmt, std::string indent, llvm::raw_ostream & strm);
     21    static void print(const pablo::PabloFunction & function, llvm::raw_ostream & out);
     22    static void print(const pablo::PabloAST * expr, llvm::raw_ostream & out);
     23    static void print(const pablo::PabloBlock * block, llvm::raw_ostream & strm, const bool expandNested = false, const unsigned indent = 0);
     24    static void print(const pablo::Statement * stmt, llvm::raw_ostream & out, const bool expandNested = false, const unsigned indent = 0);
    2725};
    2826
     27}
     28
    2929#endif // SHOW_H
  • icGREP/icgrep-devel/icgrep/pablo/ps_if.cpp

    r4868 r4870  
    55namespace pablo {
    66
    7 If::If(PabloAST * expr, const std::initializer_list<Assign *> definedVars, PabloBlock & body)
     7If::If(PabloAST * expr, const std::initializer_list<Assign *> definedVars, PabloBlock * body)
    88: Statement(ClassTypeId::If, {expr}, nullptr)
    99, mBody(body)
     
    2727}
    2828
    29 If::If(PabloAST * expr, const std::vector<Assign *> & definedVars, PabloBlock & body)
     29If::If(PabloAST * expr, const std::vector<Assign *> & definedVars, PabloBlock * body)
    3030: Statement(ClassTypeId::If, {expr}, nullptr)
    3131, mBody(body)
     
    5656}
    5757
     58PabloBlock * If::setBody(PabloBlock * body) {
     59    body->setParent(mBody->getParent());
     60    std::swap(mBody, body);
     61    body->setParent(nullptr);
     62    return body;
    5863}
     64
     65}
  • icGREP/icgrep-devel/icgrep/pablo/ps_if.h

    r4868 r4870  
    3535        return getOperand(0);
    3636    }
    37     inline PabloBlock & getBody() {
     37    inline PabloBlock * getBody() {
    3838        return mBody;
    3939    }
    40     inline  PabloBlock & getBody() const {
     40    inline  PabloBlock * getBody() const {
    4141        return mBody;
    4242    }
     43    PabloBlock * setBody(PabloBlock * body);
    4344    inline const DefinedVars & getDefined() const {
    4445        return mDefined;
     
    5051    DefinedVars::iterator removeDefined(Assign * def);
    5152protected:
    52     If(PabloAST * expr, const std::initializer_list<Assign *> definedVars, PabloBlock & body);
    53     If(PabloAST * expr, const std::vector<Assign *> & definedVars, PabloBlock & body);
     53    If(PabloAST * expr, const std::initializer_list<Assign *> definedVars, PabloBlock * body);
     54    If(PabloAST * expr, const std::vector<Assign *> & definedVars, PabloBlock * body);
    5455private:
    55     PabloBlock &    mBody;
     56    PabloBlock *    mBody;
    5657    DefinedVars     mDefined;
    5758};
  • icGREP/icgrep-devel/icgrep/pablo/ps_while.cpp

    r4860 r4870  
    44namespace pablo {
    55
    6 While::While(PabloAST * expr, const std::initializer_list<Next *> nextVars, PabloBlock & body)
     6While::While(PabloAST * expr, const std::initializer_list<Next *> nextVars, PabloBlock * body)
    77: Statement(ClassTypeId::While, {expr}, nullptr)
    88, mBody(body)
     
    1414}
    1515
    16 While::While(PabloAST * expr, const std::vector<Next *> & nextVars, PabloBlock & body)
     16While::While(PabloAST * expr, const std::vector<Next *> & nextVars, PabloBlock * body)
    1717: Statement(ClassTypeId::While, {expr}, nullptr)
    1818, mBody(body)
     
    2424}
    2525
     26PabloBlock * While::setBody(PabloBlock * body) {
     27    body->setParent(mBody->getParent());
     28    std::swap(mBody, body);
     29    body->setParent(nullptr);
     30    return body;
    2631}
     32
     33}
  • icGREP/icgrep-devel/icgrep/pablo/ps_while.h

    r4854 r4870  
    3838        return mNext;
    3939    }
    40     inline PabloBlock & getBody() {
     40    inline PabloBlock * getBody() {
    4141        return mBody;
    4242    }
    43     inline PabloBlock & getBody() const {
     43    inline PabloBlock * getBody() const {
    4444        return mBody;
    4545    }
     46    PabloBlock * setBody(PabloBlock * body);
    4647protected:
    47     While(PabloAST * expr, const std::initializer_list<Next *> nextVars, PabloBlock &body);
    48     While(PabloAST * expr, const std::vector<Next *> & nextVars, PabloBlock &body);
     48    While(PabloAST * expr, const std::initializer_list<Next *> nextVars, PabloBlock * body);
     49    While(PabloAST * expr, const std::vector<Next *> & nextVars, PabloBlock * body);
    4950
    5051private:
    51     PabloBlock &    mBody;
     52    PabloBlock *    mBody;
    5253    Variants        mNext;
    5354};
  • icGREP/icgrep-devel/icgrep/re/re_compiler.cpp

    r4852 r4870  
    792792, mStarDepth(0)
    793793, mLoopVariants()
    794 , mPB(*ccCompiler.getBuilder().getPabloBlock(), ccCompiler.getBuilder())
     794, mPB(ccCompiler.getBuilder().getPabloBlock(), ccCompiler.getBuilder())
    795795, mFunction(function)
    796796{
  • icGREP/icgrep-devel/icgrep/toolchain.cpp

    r4868 r4870  
    4949#include "do_grep.h"
    5050
     51using namespace pablo;
     52
    5153static cl::OptionCategory cRegexOutputOptions("Regex Dump Options",
    5254                                              "These options control printing of intermediate regular expression structures.");
     
    116118}
    117119   
    118 pablo::PabloFunction * re2pablo_compiler(const Encoding encoding, re::RE * re_ast) {   
    119     pablo::PabloFunction * function = pablo::PabloFunction::Create("process_block", 8, 2);   
     120PabloFunction * re2pablo_compiler(const Encoding encoding, re::RE * re_ast) {
     121    PabloFunction * function = PabloFunction::Create("process_block", 8, 2);
    120122    cc::CC_Compiler cc_compiler(*function, encoding);
    121123    re::RE_Compiler re_compiler(*function, cc_compiler);
     
    128130        llvm::raw_os_ostream cerr(std::cerr);
    129131        cerr << "Initial Pablo AST:\n";
    130         PabloPrinter::print(function->getEntryBlock().statements(), cerr);
     132        PabloPrinter::print(function, cerr);
    131133    }
    132134#ifndef NDEBUG
    133     pablo::PabloVerifier::verify(*function, "creation");
     135    PabloVerifier::verify(*function, "creation");
    134136#endif
    135137    return function;
    136138}
    137139
    138 void pablo_function_passes(pablo::PabloFunction * function) {
     140void pablo_function_passes(PabloFunction * function) {
    139141    // Scan through the pablo code and perform DCE and CSE
    140142    if (!DisablePabloCSE) {
    141         pablo::Simplifier::optimize(*function);
     143        Simplifier::optimize(*function);
    142144    }
    143145    if (PabloSinkingPass) {
    144         pablo::CodeMotionPass::optimize(*function);
     146        CodeMotionPass::optimize(*function);
    145147    }
    146148#ifdef ENABLE_MULTIPLEXING   
    147149    if (EnableMultiplexing) {
    148         pablo::BDDMinimizationPass::optimize(*function);
    149         pablo::AutoMultiplexing::optimize(*function, MultiplexingSetLimit, MultiplexingSelectionLimit);
     150        BDDMinimizationPass::optimize(*function);
     151        AutoMultiplexing::optimize(*function, MultiplexingSetLimit, MultiplexingSelectionLimit);
    150152    }
    151153    if (EnableReassociation) {
    152         pablo::BooleanReassociationPass::optimize(*function);
     154        BooleanReassociationPass::optimize(*function);
    153155    }
    154156#endif
     
    157159        llvm::raw_os_ostream cerr(std::cerr);
    158160        cerr << "Final Pablo AST:\n";
    159         PabloPrinter::print(function->getEntryBlock().statements(), cerr);
    160     }
    161 }
    162 
    163 
     161        PabloPrinter::print(function, cerr);
     162    }
     163}
    164164
    165165ExecutionEngine * JIT_to_ExecutionEngine (llvm::Function * f) {
Note: See TracChangeset for help on using the changeset viewer.