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/pablo/optimizers
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • 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};
Note: See TracChangeset for help on using the changeset viewer.