Changeset 4280


Ignore:
Timestamp:
Oct 31, 2014, 6:04:25 PM (5 years ago)
Author:
nmedfort
Message:

More Pablo IR manipulation functionality; finished use analysis optimizer (requires boost). Removed remaining LLVM optimization passes.

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

Legend:

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

    r4275 r4280  
    5151set(Boost_USE_MULTITHREADED OFF)
    5252set(Boost_USE_STATIC_RUNTIME OFF)
    53 # find_package(Boost COMPONENTS system filesystem REQUIRED)
    54 
    55 add_library(PabloADT pablo/pe_and.cpp pablo/pe_not.cpp pablo/pe_or.cpp  pablo/pabloAST.cpp  pablo/pe_sel.cpp  pablo/pe_xor.cpp pablo/codegenstate.cpp  pablo/symbol_generator.cpp pablo/printer_pablos.cpp pablo/pablo_compiler.cpp)
     53find_package(Boost COMPONENTS system filesystem)
     54
     55add_library(PabloADT pablo/pe_and.cpp pablo/pe_not.cpp pablo/pe_or.cpp  pablo/pabloAST.cpp  pablo/pe_sel.cpp  pablo/pe_xor.cpp pablo/codegenstate.cpp  pablo/symbol_generator.cpp pablo/analysis/useanalysis.cpp pablo/printer_pablos.cpp pablo/pablo_compiler.cpp)
    5656add_library(RegExpADT re/re_re.cpp re/re_cc.cpp re/re_parser.cpp re/re_rep.cpp re/parsefailure.cpp re/re_nullable.cpp re/re_simplifier.cpp re/re_compiler.cpp re/printer_re.cpp)
    5757add_library(CCADT cc/cc_namemap.cpp cc/cc_compiler.cpp utf_encoding.cpp utf8_encoder.cpp unicode_categories.h)
     
    106106#Disable RunTime Type Information
    107107IF (MSVC) # using Visual Studio C++
    108   SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR-")
     108  #SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR-")
    109109ELSE() # using Clang, GCC, Intel C++, etc
    110   SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
     110  #SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
    111111ENDIF()
    112112
  • icGREP/icgrep-devel/icgrep/cc/cc_compiler.cpp

    r4270 r4280  
    6666    assert(name);
    6767    Var * var = name->getVar();
    68     if (var == nullptr) {       
     68    if (var == nullptr) {
    6969        if (name->getType() == Name::Type::FixedLength) {
    7070            RE * cc = name->getCC();
     
    8383                throw std::runtime_error("Unexpected CC node given to CC_Compiler: " + Printer_RE::PrintRE(name) + " : " + Printer_RE::PrintRE(cc));
    8484            }
    85             mCG.createAssign(name->getName(), value);
    86         }
    87         var = mCG.createVar(name->getName());
     85            var = mCG.createVar(mCG.createAssign(name->getName(), value));
     86        }
     87        else {
     88            var = mCG.createVar(name->getName());
     89        }
    8890        name->setVar(var);
    8991    }
  • icGREP/icgrep-devel/icgrep/compiler.cpp

    r4276 r4280  
    2222#include <cc/cc_namemap.hpp>
    2323#include <pablo/pablo_compiler.h>
     24#include <pablo/analysis/useanalysis.h>
    2425
    2526//#define DEBUG_PRINT_RE_AST
     
    100101    #ifdef DEBUG_PRINT_PBIX_AST
    101102    //Print to the terminal the AST that was generated by the character class compiler.
    102     std::cerr << "Pablo CC AST:" << std::endl << PabloPrinter::print(main.statements()) << std::endl;
     103    std::cerr << "CC AST:" << std::endl << PabloPrinter::print(main.statements()) << std::endl;
    103104    #endif
    104105
     
    107108    #ifdef DEBUG_PRINT_PBIX_AST
    108109    //Print to the terminal the AST that was generated by the pararallel bit-stream compiler.
    109     std::cerr << "Final Pablo AST:" << PabloPrinter::print(main.statements()) << ")" << std::endl;
     110    std::cerr << "Initial Pablo AST:" << PabloPrinter::print(main.statements()) << ")" << std::endl;
    110111    #endif
    111112
    112113    RE::release_memory();
     114
     115    // Scan through the pablo code and perform DCE and CSE
     116    UseAnalysis::optimize(main);
     117
     118    #ifdef DEBUG_PRINT_PBIX_AST
     119    //Print to the terminal the AST that was generated by the pararallel bit-stream compiler.
     120    std::cerr << "Final Pablo AST:" << PabloPrinter::print(main.statements()) << ")" << std::endl;
     121    #endif
    113122
    114123    PabloCompiler pablo_compiler(basisBits);
  • icGREP/icgrep-devel/icgrep/icgrep-devel.files

    r4272 r4280  
    168168pablo/ps_assign.cpp
    169169pablo/ps_assign.h
    170 pablo/ps_if.cpp
    171170pablo/ps_if.h
    172171pablo/ps_pablos.cpp
     
    226225slab_allocator.h
    227226re/re_re.cpp
     227pablo/ps_if.cpp
  • icGREP/icgrep-devel/icgrep/pablo/analysis/useanalysis.cpp

    r4276 r4280  
    11#include "useanalysis.h"
    22#include <queue>
     3#include <pablo/printer_pablos.h>
     4#include <fstream>
     5
     6using namespace boost;
    37
    48namespace pablo {
    59
    6 void UseAnalysis::optimize(PabloBlock & block) {
     10#ifdef USE_BOOST
     11bool UseAnalysis::optimize(PabloBlock & block) {
    712    UseAnalysis analyzer;
    8     analyzer.gatherUseDefInformation(analyzer.mRoot, block.statements());
    9     analyzer.identifyDeadVariables();
    10 }
    11 
    12 void UseAnalysis::identifyDeadVariables() {
     13    analyzer.gatherUseDefInformation(block.statements());
     14    analyzer.dce();
     15    analyzer.cse(block);
     16    return true;
     17}
     18
     19
     20void UseAnalysis::cse(PabloBlock & block) {
     21
     22    VertexIterator vi, vi_end;
     23    auto mGraphMap = get(vertex_name, mUseDefGraph);
     24    for (std::tie(vi, vi_end) = vertices(mUseDefGraph); vi != vi_end; ++vi) {
     25        const Vertex u = *vi;
     26        if (out_degree(u, mUseDefGraph) > 1) {
     27            PabloAST * expr = mGraphMap[u];
     28            if (isa<Statement>(expr) || isa<Var>(expr)) {
     29                continue;
     30            }
     31            // create the new nodes
     32            Assign * assign = block.createAssign("cse", expr);
     33            Var * var = block.createVar(assign);
     34            const Vertex s = find(assign);
     35            const Vertex v = find(var);
     36            // update the program and graph
     37            OutEdgeIterator ei, ei_end;
     38            for (std::tie(ei, ei_end) = out_edges(u, mUseDefGraph); ei != ei_end; ++ei) {
     39                const Vertex t = target(*ei, mUseDefGraph);
     40                add_edge(v, t, mUseDefGraph);
     41                PabloAST * user = mGraphMap[t];
     42                user->replaceUsesOfWith(expr, var);
     43            }
     44            clear_out_edges(u, mUseDefGraph);
     45            add_edge(u, s, mUseDefGraph);
     46            add_edge(s, v, mUseDefGraph);
     47            Statement * ip = findInsertionPointFor(u, block);
     48            if (ip == nullptr) {
     49                assign->insertBefore(block.statements().front());
     50            }
     51            else {
     52                assign->insertAfter(ip);
     53            }
     54        }
     55    }
     56}
     57
     58inline Statement * UseAnalysis::findInsertionPointFor(const Vertex v, PabloBlock & block) {
     59    // We want to find a predecessor of v that is the last statement in the AST.
     60    auto mGraphMap = get(vertex_name, mUseDefGraph);
     61    PredecessorSet predecessors;
     62    std::queue<Vertex> Q;
     63    InEdgeIterator ei, ei_end;
     64    for (std::tie(ei, ei_end) = in_edges(v, mUseDefGraph); ei != ei_end; ++ei) {
     65        const Vertex u = source(*ei, mUseDefGraph);
     66        PabloAST * n = mGraphMap[u];
     67        if (isa<Statement>(n)) {
     68            predecessors.insert(cast<Statement>(n));
     69        }
     70        else {
     71            Q.push(u);
     72        }
     73    }
     74
     75    while (!Q.empty()) {
     76        const Vertex u = Q.front();
     77        Q.pop();
     78        PabloAST * n = mGraphMap[u];
     79
     80        if (isa<Statement>(n)) {
     81            predecessors.insert(cast<Statement>(n));
     82        }
     83        else {
     84            InEdgeIterator ei, ei_end;
     85            for (std::tie(ei, ei_end) = in_edges(u, mUseDefGraph); ei != ei_end; ++ei) {
     86                Q.push(source(*ei, mUseDefGraph));
     87            }
     88        }
     89    }
     90    if (predecessors.empty()) {
     91        return nullptr;
     92    }
     93    else if (predecessors.size() == 1) {
     94        return *predecessors.begin();
     95    }
     96    return findLastStatement(predecessors, block.statements());
     97}
     98
     99Statement * UseAnalysis::findLastStatement(const PredecessorSet & predecessors, StatementList & statements) {
     100
     101    for (auto ri = statements.rbegin(); ri != statements.rend(); ++ri) {
     102        Statement * stmt = *ri;
     103        if (predecessors.count(stmt)) {
     104            return stmt;
     105        }
     106        else if (isa<If>(stmt)) {
     107            stmt = findLastStatement(predecessors, cast<If>(stmt)->getBody());
     108            if (stmt) {
     109                return stmt;
     110            }
     111        }
     112        else if (isa<While>(stmt)) {
     113            stmt = findLastStatement(predecessors, cast<While>(stmt)->getBody());
     114            if (stmt) {
     115                return stmt;
     116            }
     117        }
     118    }
     119
     120    return nullptr;
     121
     122}
     123
     124
     125void UseAnalysis::dce() {
     126    auto mGraphMap = get(vertex_name, mUseDefGraph);
    13127    std::queue<Vertex> Q;
    14128    // gather up all of the nodes that aren't output assignments and have no users
    15     const auto vMap = get(vertex_name, mUseDefGraph);
    16129    VertexIterator vi, vi_end;
    17130    for (std::tie(vi, vi_end) = vertices(mUseDefGraph); vi != vi_end; ++vi) {
    18131        const Vertex v = *vi;
    19         if (out_degree(v) == 0) {
    20             const PabloAST * n = vMap[v];
    21             if (isa<Assign>(n) && (cast<Assign>(n)->isOutputAssignment())) {
     132        if (out_degree(v, mUseDefGraph) == 0) {
     133            PabloAST * n = mGraphMap[v];
     134            if (!isa<Assign>(n) || (cast<Assign>(n)->isOutputAssignment())) {
    22135                continue;
    23136            }
     
    28141        const Vertex v = Q.front();
    29142        Q.pop();
     143        PabloAST * n = mGraphMap[v];
     144        if (isa<Assign>(n)) {
     145            cast<Assign>(n)->removeFromParent();
     146        }
    30147        InEdgeIterator ei, ei_end;
    31148        for (std::tie(ei, ei_end) = in_edges(v, mUseDefGraph); ei != ei_end; ++ei) {
     
    39156}
    40157
    41 void UseAnalysis::gatherUseDefInformation(const Vertex v, StatementList & statements) {
    42     for (PabloAST * stmt : statements) {
     158void UseAnalysis::gatherUseDefInformation(const StatementList & statements) {
     159    for (const Statement * stmt : statements) {
     160        const Vertex v = find(stmt);
     161        if (const Assign * assign = dyn_cast<Assign>(stmt)) {
     162            gatherUseDefInformation(v, assign->getExpr());
     163        }
     164        if (const Next * next = dyn_cast<Next>(stmt)) {
     165            gatherUseDefInformation(v, next->getExpr());
     166        }
     167        else if (const If * ifStatement = dyn_cast<If>(stmt)) {
     168            gatherUseDefInformation(v, ifStatement->getCondition());
     169            gatherUseDefInformation(v, ifStatement->getBody());
     170        }
     171        else if (const While * whileStatement = dyn_cast<While>(stmt)) {
     172            gatherUseDefInformation(v, whileStatement->getCondition());
     173            gatherUseDefInformation(v, whileStatement->getBody());
     174        }
     175    }
     176}
     177
     178void UseAnalysis::gatherUseDefInformation(const Vertex v, const StatementList & statements) {
     179    for (const Statement * stmt : statements) {
    43180        const Vertex u = find(stmt);
    44181        add_edge(u, v, mUseDefGraph);
     
    46183            gatherUseDefInformation(u, assign->getExpr());
    47184        }
    48         if (const Next * next = dyn_cast<Next>(stmt)) {
     185        else if (const Next * next = dyn_cast<Next>(stmt)) {
     186            add_edge(u, find(next->getInitial()), mUseDefGraph);
    49187            gatherUseDefInformation(u, next->getExpr());
    50188        }
    51         else if (If * ifStatement = dyn_cast<If>(stmt)) {
     189        else if (const If * ifStatement = dyn_cast<If>(stmt)) {
    52190            gatherUseDefInformation(u, ifStatement->getCondition());
    53191            gatherUseDefInformation(u, ifStatement->getBody());
    54192        }
    55         else if (While * whileStatement = dyn_cast<While>(stmt)) {
     193        else if (const While * whileStatement = dyn_cast<While>(stmt)) {
    56194            gatherUseDefInformation(u, whileStatement->getCondition());
    57195            gatherUseDefInformation(u, whileStatement->getBody());
     
    60198}
    61199
    62 void UseAnalysis::gatherUseDefInformation(const Vertex v, PabloAST * expr) {
     200void UseAnalysis::gatherUseDefInformation(const Vertex v, const PabloAST * expr) {
     201    if (isa<Var>(expr) && cast<Var>(expr)->isExternal()) {
     202        return;
     203    }
    63204    const Vertex u = find(expr);
    64205    add_edge(u, v, mUseDefGraph);
    65     if (const And * pablo_and = dyn_cast<const And>(expr)) {
     206    if (const Var * var = dyn_cast<Var>(expr)) {
     207        gatherUseDefInformation(u, var->getVar());
     208    }
     209    else if (const And * pablo_and = dyn_cast<const And>(expr)) {
    66210        gatherUseDefInformation(u, pablo_and->getExpr1());
    67211        gatherUseDefInformation(u, pablo_and->getExpr2());
     
    95239    auto f = mUseDefMap.find(node);
    96240    if (f == mUseDefMap.end()) {
    97         Vertex v = add_vertex(mUseDefGraph, node);
     241        const Vertex v = add_vertex(mUseDefGraph);
    98242        mUseDefMap.insert(std::make_pair(node, v));
     243        get(vertex_name, mUseDefGraph)[v] = const_cast<PabloAST*>(node);
    99244        return v;
    100245    }
    101246    return f->second;
    102247}
    103 
    104 UseAnalysis::UseAnalysis()
    105 : mRoot(add_vertex(mUseDefGraph, nullptr))
    106 {
    107 
    108 }
    109 
    110 }
     248#endif
     249
     250}
  • icGREP/icgrep-devel/icgrep/pablo/analysis/useanalysis.h

    r4270 r4280  
    33
    44#include <pablo/codegenstate.h>
     5
     6#ifdef USE_BOOST
    57#include <boost/graph/adjacency_list.hpp>
    68#include <unordered_map>
     9#include <vector>
     10#include <set>
    711
    812namespace pablo {
     
    1014using namespace boost;
    1115
    12 class UseAnalysis
    13 {
     16class UseAnalysis {
    1417    typedef adjacency_list<hash_setS, vecS, bidirectionalS, property<vertex_name_t, PabloAST*>> UseDefGraph;
    1518    typedef graph_traits<UseDefGraph>::vertex_descriptor Vertex;
    1619    typedef graph_traits<UseDefGraph>::vertex_iterator VertexIterator;
    1720    typedef graph_traits<UseDefGraph>::in_edge_iterator InEdgeIterator;
    18     typedef std::unordered_map<PabloAST*, Vertex> UseDefMap;
     21    typedef graph_traits<UseDefGraph>::out_edge_iterator OutEdgeIterator;
     22    typedef std::unordered_map<const PabloAST*, Vertex> UseDefMap;
     23    typedef std::set<Statement *> PredecessorSet;
    1924public:
    20     static void optimize(PabloBlock & block);
     25    static bool optimize(PabloBlock & block);
    2126private:
    22     void identifyDeadVariables();
    23 
    24     void gatherUseDefInformation(const Vertex parent, StatementList & statements);
    25     void gatherUseDefInformation(const Vertex parent, PabloAST * expr);
     27    void cse(PabloBlock & block);
     28    Statement * findInsertionPointFor(const Vertex v, PabloBlock & block);
     29    Statement * findLastStatement(const PredecessorSet & predecessors, StatementList & statements);
     30    void dce();
     31    void gatherUseDefInformation(const StatementList & statements);
     32    void gatherUseDefInformation(const Vertex parent, const StatementList & statements);
     33    void gatherUseDefInformation(const Vertex parent, const PabloAST * expr);
    2634    Vertex find(const PabloAST * const node);
    27     UseAnalysis();
    2835private:
    2936    UseDefGraph       mUseDefGraph;
    3037    UseDefMap         mUseDefMap;
    31     const Vertex      mRoot;
    3238};
    3339
    3440}
     41#else
     42
     43namespace pablo {
     44class UseAnalysis {
     45public:
     46    static bool optimize(PabloBlock &) {
     47        return false;
     48    }
     49};
     50}
     51
     52#endif
    3553
    3654#endif // USEANALYSIS_H
  • icGREP/icgrep-devel/icgrep/pablo/codegenstate.cpp

    r4264 r4280  
    4242
    4343Next * PabloBlock::createNext(Assign * assign, PabloAST * expr) {
    44     Next * next = mBinary.findOrMake<Next>(PabloAST::ClassTypeId::Next, assign, expr);
     44    Next * next = mBinary.findOrMake<Next>(PabloAST::ClassTypeId::Next, assign, expr, &mStatements);
    4545    mStatements.push_back(next);
    4646    return next;
  • icGREP/icgrep-devel/icgrep/pablo/codegenstate.h

    r4276 r4280  
    7878        // TODO: should this test whether we've somehow created a var for this prior to
    7979        // making the assignment?
    80         Assign * assign = new Assign(mSymbolGenerator.get_ssa(prefix), expr, outputIndex);
     80        Assign * assign = new Assign(mSymbolGenerator.get_ssa(prefix), expr, outputIndex, &mStatements);
    8181        mStatements.push_back(assign);
    8282        return assign;
     
    117117
    118118    inline If * createIf(PabloAST * condition, PabloBlock && body) {
    119         If * statement = new If(condition, std::move(body.mStatements));
     119        If * statement = new If(condition, std::move(body.statements()), &mStatements);
    120120        mStatements.push_back(statement);
    121121        return statement;
     
    123123
    124124    inline While * createWhile(PabloAST * cond, PabloBlock && body) {
    125         While * statement = new While(cond, std::move(body.mStatements));
     125        While * statement = new While(cond, std::move(body.statements()), &mStatements);
    126126        mStatements.push_back(statement);
    127127        return statement;
  • icGREP/icgrep-devel/icgrep/pablo/pabloAST.cpp

    r4276 r4280  
    9292}
    9393
     94Statement::~Statement() {
     95
     96}
     97
    9498void StatementList::push_back(Statement * const statement) {
    9599    if (LLVM_UNLIKELY(mLast == nullptr)) {
  • icGREP/icgrep-devel/icgrep/pablo/pabloAST.h

    r4276 r4280  
    99
    1010#include <llvm/Support/Casting.h>
     11#include <llvm/Support/Compiler.h>
    1112#include <slab_allocator.h>
    1213#include <iterator>
     
    4344        return mClassTypeId;
    4445    }
     46
     47    inline void replaceUsesOfWith(PabloAST * from, PabloAST * to) {
     48        if (from == to) {
     49            return;
     50        }
     51        for (unsigned i = 0, operands = getNumOperands(); i != operands; ++i) {
     52            if (getOperand(i) == from) {
     53                setOperand(i, to);
     54            }
     55        }
     56    }
     57
     58    virtual PabloAST * getOperand(const unsigned index) const = 0;
     59
     60    virtual unsigned getNumOperands() const = 0;
     61
     62    virtual void setOperand(const unsigned index, PabloAST * value) = 0;
     63
    4564    inline static void release_memory() {
    4665        mAllocator.release_memory();
     
    5978bool equals(const PabloAST * expr1, const PabloAST *expr2);
    6079
     80class StatementList;
     81
    6182class Statement : public PabloAST {
    6283    friend class StatementList;
     84    friend class If;
     85    friend class While;
    6386public:
    64     Statement(const ClassTypeId id)
     87    static inline bool classof(const PabloAST * e) {
     88        switch (e->getClassTypeId()) {
     89            case PabloAST::ClassTypeId::Assign:
     90            case PabloAST::ClassTypeId::Next:
     91            case PabloAST::ClassTypeId::If:
     92            case PabloAST::ClassTypeId::While:
     93                return true;
     94            default:
     95                return false;
     96        }
     97    }
     98    static inline bool classof(const Statement *) {
     99        return true;
     100    }
     101    static inline bool classof(const void *) {
     102        return false;
     103    }
     104
     105    inline void insertBefore(Statement * const statement);
     106    inline void insertAfter(Statement * const statement);
     107    inline void removeFromParent();
     108
     109protected:
     110    Statement(const ClassTypeId id, StatementList * parent)
    65111    : PabloAST(id)
    66112    , mNext(nullptr)
    67113    , mPrev(nullptr)
     114    , mParent(parent)
    68115    {
    69116
    70117    }
    71     inline void insertBefore(Statement * const statement) {
    72         assert (statement);
    73         mNext = statement;
    74         mPrev = statement->mPrev;
    75         statement->mPrev = this;
    76     }
    77     inline void insertAfter(Statement * const statement) {
    78         assert (statement);
    79         mPrev = statement;
    80         mNext = statement->mNext;
    81         statement->mNext = this;
    82     }
    83 private:
     118    virtual ~Statement() = 0;
     119protected:
    84120    Statement * mNext;
    85121    Statement * mPrev;
     122    StatementList * mParent;
    86123};
    87124
    88125class StatementList {
    89 
     126    friend class Statement;
     127public:
    90128    class iterator: public std::iterator<std::forward_iterator_tag, Statement> {
    91129    public:
     
    162200    };
    163201
     202    class reverse_iterator: public std::iterator<std::forward_iterator_tag, Statement> {
     203    public:
     204        reverse_iterator(): mCurrent(nullptr) {}
     205
     206        reverse_iterator(Statement* base): mCurrent(base) {}
     207
     208        reverse_iterator(const reverse_iterator& other): mCurrent(other.mCurrent) {}
     209
     210        const reverse_iterator& operator=(const reverse_iterator& other) {
     211            mCurrent = other.mCurrent; return other;
     212        }
     213
     214        inline reverse_iterator& operator++() {
     215            assert (mCurrent);
     216            mCurrent = mCurrent->mPrev;
     217            return *this;
     218        }
     219
     220        reverse_iterator operator++(int) {
     221            reverse_iterator tmp(*this);
     222            ++(*this);
     223            return tmp;
     224        }
     225
     226        bool operator==(const reverse_iterator& other) const {
     227            return  mCurrent == other.mCurrent;
     228        }
     229
     230        bool operator!=(const reverse_iterator& other) const {
     231            return  mCurrent != other.mCurrent;
     232        }
     233
     234        Statement* operator*() {return mCurrent;}
     235        Statement* operator->(){return mCurrent;}
     236
     237    private:
     238        Statement * mCurrent;
     239        friend class const_reverse_iterator;
     240    };
     241
     242    class const_reverse_iterator: public std::iterator<std::forward_iterator_tag, Statement> {
     243    public:
     244        const_reverse_iterator(): mCurrent(nullptr) {}
     245        const_reverse_iterator(const Statement* base): mCurrent(base) {}
     246        const_reverse_iterator(const const_reverse_iterator& other): mCurrent(other.mCurrent) {}
     247        const const_reverse_iterator& operator=(const const_reverse_iterator& other) {mCurrent = other.mCurrent; return other;}
     248
     249        inline const_reverse_iterator& operator++() {
     250            assert (mCurrent);
     251            mCurrent = mCurrent->mPrev;
     252            return *this;
     253        }
     254
     255        const_reverse_iterator  operator++(int) {
     256            const_reverse_iterator tmp(*this);
     257            ++(*this);
     258            return tmp;
     259        }
     260
     261        bool operator==(const const_reverse_iterator & other) const {
     262            return  mCurrent == other.mCurrent;
     263        }
     264        bool operator!=(const const_reverse_iterator & other) const {
     265            return  mCurrent != other.mCurrent;
     266        }
     267
     268        const Statement* operator*() {return mCurrent;}
     269        const Statement* operator->(){return mCurrent;}
     270
     271    private:
     272        const Statement * mCurrent;
     273        friend class iterator;
     274    };
     275
    164276public:
    165277
     
    187299    }
    188300
     301    reverse_iterator rbegin() {
     302        return reverse_iterator(mLast);
     303    }
     304
     305    reverse_iterator rend() {
     306        return reverse_iterator(nullptr);
     307    }
     308
    189309    const_iterator begin() const {
    190310        return const_iterator(mFirst);
     
    195315    }
    196316
     317    const_reverse_iterator rbegin() const {
     318        return const_reverse_iterator(mLast);
     319    }
     320
     321    const_reverse_iterator rend() const {
     322        return const_reverse_iterator(nullptr);
     323    }
     324
    197325    const_iterator cbegin() const {
    198326        return const_iterator(mFirst);
     
    201329    const_iterator cend() const {
    202330        return const_iterator(nullptr);
     331    }
     332
     333    const_reverse_iterator crbegin() const {
     334        return const_reverse_iterator(mLast);
     335    }
     336
     337    const_reverse_iterator crend() const {
     338        return const_reverse_iterator(nullptr);
     339    }
     340
     341    Statement * front() const {
     342        return mFirst;
     343    }
     344
     345    Statement * back() const {
     346        return mLast;
    203347    }
    204348
     
    210354};
    211355
     356inline void Statement::insertBefore(Statement * const statement) {
     357    assert (statement);
     358    assert (statement != this);
     359    assert (statement->mParent);
     360    removeFromParent();
     361    mParent = statement->mParent;
     362    if (LLVM_UNLIKELY(mParent->mFirst == statement)) {
     363        mParent->mFirst = this;
     364    }
     365    mNext = statement;
     366    mPrev = statement->mPrev;
     367    statement->mPrev = this;
     368    if (LLVM_LIKELY(mPrev != nullptr)) {
     369        mPrev->mNext = this;
     370    }
    212371}
     372inline void Statement::insertAfter(Statement * const statement) {
     373    assert (statement);
     374    assert (statement != this);
     375    assert (statement->mParent);
     376    removeFromParent();
     377    mParent = statement->mParent;
     378    if (LLVM_UNLIKELY(mParent->mLast == statement)) {
     379        mParent->mLast = this;
     380    }
     381    mPrev = statement;
     382    mNext = statement->mNext;
     383    statement->mNext = this;
     384    if (LLVM_LIKELY(mNext != nullptr)) {
     385        mNext->mPrev = this;
     386    }
     387}
     388inline void Statement::removeFromParent() {
     389    if (LLVM_LIKELY(mParent != nullptr)) {
     390        if (LLVM_UNLIKELY(mParent->mFirst == this)) {
     391            mParent->mFirst = mNext;
     392        }
     393        if (LLVM_UNLIKELY(mParent->mLast == this)) {
     394            mParent->mLast = mPrev;
     395        }
     396        if (LLVM_LIKELY(mPrev != nullptr)) {
     397            mPrev->mNext = mNext;
     398        }
     399        if (LLVM_LIKELY(mNext != nullptr)) {
     400            mNext->mPrev = mPrev;
     401        }
     402    }
     403    mPrev = nullptr;
     404    mNext = nullptr;
     405    mParent = nullptr;
     406}
     407
     408}
    213409
    214410#endif // PE_PabloAST_H
  • icGREP/icgrep-devel/icgrep/pablo/pablo_compiler.cpp

    r4276 r4280  
    4646#include <llvm/Support/MathExtras.h>
    4747#include <llvm/Support/Casting.h>
     48#include <llvm/Support/Compiler.h>
    4849#include <llvm/Support/Debug.h>
    4950#include <llvm/Support/TargetSelect.h>
     
    5859
    5960//#define DUMP_GENERATED_IR
    60 //#define DUMP_OPTIMIZED_IR
    6161
    6262extern "C" {
     
    231231
    232232    //Un-comment this line in order to display the IR that has been generated by this module.
    233     #ifdef DUMP_GENERATED_IR
     233    #if defined(DUMP_GENERATED_IR)
    234234    mMod->dump();
    235235    #endif
     
    254254    fpm.add(new DataLayout(*mExecutionEngine->getDataLayout()));
    255255#endif
    256 
    257     fpm.add(createCorrelatedValuePropagationPass());
    258     fpm.add(createEarlyCSEPass());
    259     fpm.add(createInstructionCombiningPass());    //Simple peephole optimizations and bit-twiddling.
    260     fpm.add(createReassociatePass());             //Reassociate expressions.
    261     fpm.add(createGVNPass());                     //Eliminate common subexpressions.   
    262 
    263256    fpm.doInitialization();
    264 
    265257    fpm.run(*mFunction);
    266258
    267 #ifdef DUMP_OPTIMIZED_IR
    268     mMod->dump();
    269 #endif
    270259    mExecutionEngine->finalizeObject();
    271260
     
    520509        #undef CHECK_GENERAL_CODE_CATEGORY
    521510        Value * unicodeCategory = mMod->getOrInsertFunction("__get_category_" + callee->str(), mBitBlockType, mBasisBitsInputPtr, NULL);
    522         if (unicodeCategory == nullptr) {
     511        if (LLVM_UNLIKELY(unicodeCategory == nullptr)) {
    523512            throw std::runtime_error("Could not create static method call for unicode category \"" + callee->str() + "\"");
    524513        }
     
    543532        Value* expr = compileExpression(assign->getExpr());
    544533        mMarkerMap[assign->getName()] = expr;
    545         if (unlikely(assign->isOutputAssignment())) {
     534        if (LLVM_UNLIKELY(assign->isOutputAssignment())) {
    546535            SetOutputValue(expr, assign->getOutputIndex());
    547536        }
     
    717706        if (mi == mMarkerMap.end()) {
    718707            auto ci = mCalleeMap.find(call->getCallee());
    719             if (ci == mCalleeMap.end()) {
     708            if (LLVM_UNLIKELY(ci == mCalleeMap.end())) {
    720709                throw std::runtime_error("Unexpected error locating static function for \"" + call->getCallee()->str() + "\"");
    721710            }
     
    727716    {
    728717        auto f = mMarkerMap.find(var->getName());
    729         assert (f != mMarkerMap.end());
     718        if (LLVM_UNLIKELY(f == mMarkerMap.end())) {
     719            throw std::runtime_error(PabloPrinter::print(var) + " used before creation.");
     720        }
    730721        retVal = f->second;
    731722    }
  • icGREP/icgrep-devel/icgrep/pablo/pe_advance.h

    r4272 r4280  
    2323    virtual ~Advance() {
    2424    }
     25    virtual PabloAST * getOperand(const unsigned index) const {
     26        assert (index == 0);
     27        return mExpr;
     28    }
     29    virtual void setOperand(const unsigned index, PabloAST * value) {
     30        assert (index == 0);
     31        mExpr = value;
     32    }
     33    virtual unsigned getNumOperands() const {
     34        return 1;
     35    }
    2536    inline PabloAST * getExpr() const {
    2637        return mExpr;
     
    4051    }
    4152private:
    42     PabloAST * const mExpr;
     53    PabloAST * mExpr;
    4354        int const mShiftAmount;
    4455};
  • icGREP/icgrep-devel/icgrep/pablo/pe_and.h

    r4272 r4280  
    99
    1010#include <pablo/pabloAST.h>
     11#include <array>
    1112
    1213namespace pablo {
     
    2627    virtual ~And() {
    2728    }
     29    virtual PabloAST * getOperand(const unsigned index) const {
     30        assert (index < 2);
     31        return mExprs[index];
     32    }
     33    virtual unsigned getNumOperands() const {
     34        return 2;
     35    }
     36    virtual void setOperand(const unsigned index, PabloAST * value) {
     37        assert (index < 2);
     38        mExprs[index] = value;
     39    }
    2840    PabloAST * getExpr1() const {
    29         return mExpr1;
     41        return mExprs[0];
    3042    }
    3143    PabloAST * getExpr2() const {
    32         return mExpr2;
     44        return mExprs[1];
    3345    }
    3446protected:
     
    3850    And(PabloAST * expr1, PabloAST * expr2)
    3951    : PabloAST(ClassTypeId::And)
    40     , mExpr1(expr1)
    41     , mExpr2(expr2)
     52    , mExprs({expr1, expr2})
    4253    {
    4354
    4455    }
    4556private:
    46     PabloAST * const mExpr1;
    47     PabloAST * const mExpr2;
     57    std::array<PabloAST*, 2> mExprs;
    4858};
    4959
  • icGREP/icgrep-devel/icgrep/pablo/pe_call.h

    r4272 r4280  
    1919    virtual ~Call() {
    2020    }
     21    virtual PabloAST * getOperand(const unsigned index) const {
     22        assert (index == 0);
     23        return mCallee;
     24    }
     25    virtual unsigned getNumOperands() const {
     26        return 1;
     27    }
     28    virtual void setOperand(const unsigned index, PabloAST * value) {
     29        assert (index == 0);
     30        assert (isa<String>(value));
     31        mCallee = cast<String>(value);
     32    }
    2133    inline const String * getCallee() const {
    2234        return mCallee;
     
    2638        return mAllocator.allocate(size);
    2739    }
    28     Call(const PabloAST * callee)
     40    Call(PabloAST * callee)
    2941    : PabloAST(ClassTypeId::Call)
    3042    , mCallee(cast<String>(callee)) {
     
    3244    }
    3345private:
    34     const String * const mCallee;
     46    String * mCallee;
    3547};
    3648}
  • icGREP/icgrep-devel/icgrep/pablo/pe_matchstar.h

    r4253 r4280  
    99
    1010#include "pabloAST.h"
     11#include <array>
    1112
    1213namespace pablo {
     
    2324    virtual ~MatchStar() {
    2425    }
     26    virtual PabloAST * getOperand(const unsigned index) const {
     27        assert (index < 2);
     28        return mExprs[index];
     29    }
     30    virtual unsigned getNumOperands() const {
     31        return 2;
     32    }
     33    virtual void setOperand(const unsigned index, PabloAST * value) {
     34        assert (index < 2);
     35        mExprs[index] = value;
     36    }
    2537    inline PabloAST * getMarker() const {
    26         return mMarker;
     38        return mExprs[0];
    2739    }
    2840    inline PabloAST * getCharClass() const  {
    29         return mCC;
     41        return mExprs[1];
    3042    }
    3143protected:
    3244    MatchStar(PabloAST * marker, PabloAST * cc)
    3345    : PabloAST(ClassTypeId::MatchStar)
    34     , mMarker(marker)
    35     , mCC(cc)
     46    , mExprs({marker, cc})
    3647    {
    3748
    3849    }
    3950private:
    40     PabloAST * const mMarker;
    41     PabloAST * const mCC;
     51    std::array<PabloAST*, 2> mExprs;
    4252};
    4353
  • icGREP/icgrep-devel/icgrep/pablo/pe_next.h

    r4276 r4280  
    44#include <pablo/pabloAST.h>
    55#include <pablo/ps_assign.h>
     6#include <array>
    67
    78namespace pablo {
     
    1819        return false;
    1920    }
     21    virtual PabloAST * getOperand(const unsigned index) const {
     22        assert (index < 2);
     23        return mExprs[index];
     24    }
     25    virtual unsigned getNumOperands() const {
     26        return 2;
     27    }
     28    virtual void setOperand(const unsigned index, PabloAST * value) {
     29        assert (index < 2);
     30        assert (index == 0 || isa<Assign>(value));
     31        mExprs[index] = value;
     32    }
    2033    inline const Assign * getInitial() const {
    21         return mInitial;
     34        return cast<const Assign>(mExprs[0]);
    2235    }
    2336    inline const String * getName() const {
    24         return mInitial->getName();
     37        return getInitial()->getName();
    2538    }
    2639    inline PabloAST * getExpr() const {
    27         return mExpr;
     40        return mExprs[1];
    2841    }
    2942protected:
     
    3144        return mAllocator.allocate(size);
    3245    }
    33     Next(const PabloAST * initial, PabloAST * expr)
    34     : Statement(ClassTypeId::Next)
    35     , mInitial(cast<Assign>(initial))
    36     , mExpr(expr)
     46    Next(PabloAST * initial, PabloAST * expr, StatementList * parent)
     47    : Statement(ClassTypeId::Next, parent)
     48    , mExprs({cast<Assign>(initial), expr})
    3749    {
    3850
    3951    }
    4052private:
    41     const Assign * const      mInitial;
    42     PabloAST * const          mExpr;
     53    std::array<PabloAST*, 2>  mExprs;
    4354};
    4455
  • icGREP/icgrep-devel/icgrep/pablo/pe_not.h

    r4272 r4280  
    2424        return false;
    2525    }
     26    virtual PabloAST * getOperand(const unsigned index) const {
     27        assert (index == 0);
     28        return mExpr;
     29    }
     30    virtual unsigned getNumOperands() const {
     31        return 1;
     32    }
     33    virtual void setOperand(const unsigned index, PabloAST * value) {
     34        assert (index == 0);
     35        mExpr = value;
     36    }
    2637    virtual ~Not() {
    2738    }
     
    3950    }
    4051private:
    41     PabloAST * const mExpr;
     52    PabloAST * mExpr;
    4253};
    4354
  • icGREP/icgrep-devel/icgrep/pablo/pe_ones.h

    r4272 r4280  
    2222    }
    2323    virtual ~Ones() {
    24 
     24    }
     25    virtual PabloAST * getOperand(const unsigned) const {
     26        assert (false);
     27        return nullptr;
     28    }
     29    virtual unsigned getNumOperands() const {
     30        return 0;
     31    }
     32    virtual void setOperand(const unsigned, PabloAST *) {
     33        assert (false);
    2534    }
    2635    inline bool operator==(const Ones & other) const {
  • icGREP/icgrep-devel/icgrep/pablo/pe_or.h

    r4272 r4280  
    99
    1010#include <pablo/pabloAST.h>
     11#include <array>
    1112
    1213namespace pablo {
     
    2627    virtual ~Or() {
    2728    }
    28     inline PabloAST * getExpr1() const {
    29         return mExpr1;
     29    virtual PabloAST * getOperand(const unsigned index) const {
     30        assert (index < 2);
     31        return mExprs[index];
    3032    }
    31     inline PabloAST* getExpr2() const {
    32         return mExpr2;
     33    virtual unsigned getNumOperands() const {
     34        return 2;
     35    }
     36    virtual void setOperand(const unsigned index, PabloAST * value) {
     37        assert (index < 2);
     38        mExprs[index] = value;
     39    }
     40    PabloAST * getExpr1() const {
     41        return mExprs[0];
     42    }
     43    PabloAST * getExpr2() const {
     44        return mExprs[1];
    3345    }
    3446protected:
     
    3850    Or(PabloAST * expr1, PabloAST * expr2)
    3951    : PabloAST(ClassTypeId::Or)
    40     , mExpr1(expr1)
    41     , mExpr2(expr2)
     52    , mExprs({expr1, expr2})
    4253    {
    4354
    4455    }
    4556private:
    46     PabloAST * const mExpr1;
    47     PabloAST * const mExpr2;
     57    std::array<PabloAST*, 2> mExprs;
    4858};
    4959
  • icGREP/icgrep-devel/icgrep/pablo/pe_scanthru.h

    r4244 r4280  
    99
    1010#include <pablo/pabloAST.h>
     11#include <array>
    1112
    1213namespace pablo {
     
    2122        return false;
    2223    }
     24    virtual ~ScanThru() {
     25    }
     26    virtual PabloAST * getOperand(const unsigned index) const {
     27        assert (index < 2);
     28        return mExprs[index];
     29    }
     30    virtual unsigned getNumOperands() const {
     31        return 2;
     32    }
     33    virtual void setOperand(const unsigned index, PabloAST * value) {
     34        assert (index < 2);
     35        mExprs[index] = value;
     36    }
     37    PabloAST * getScanFrom() const {
     38        return mExprs[0];
     39    }
     40    PabloAST * getScanThru() const {
     41        return mExprs[1];
     42    }
    2343    ScanThru(PabloAST * from, PabloAST * thru)
    2444    : PabloAST(ClassTypeId::ScanThru)
    25     , mScanFrom(from)
    26     , mScanThru(thru)
     45    , mExprs({from, thru})
    2746    {
    2847
    2948    }
    30     virtual ~ScanThru() {
    31     }
    32     PabloAST * getScanFrom() const {
    33         return mScanFrom;
    34     }
    35     PabloAST * getScanThru() const {
    36         return mScanThru;
    37     }
    3849private:
    39     PabloAST * const mScanFrom;
    40     PabloAST * const mScanThru;
     50    std::array<PabloAST*, 2> mExprs;
    4151};
    4252
  • icGREP/icgrep-devel/icgrep/pablo/pe_sel.h

    r4272 r4280  
    99
    1010#include <pablo/pabloAST.h>
     11#include <array>
    1112
    1213namespace pablo {
     
    2627    virtual ~Sel() {
    2728    }
     29    virtual PabloAST * getOperand(const unsigned index) const {
     30        assert (index < 3);
     31        return mExprs[index];
     32    }
     33    virtual unsigned getNumOperands() const {
     34        return 3;
     35    }
     36    virtual void setOperand(const unsigned index, PabloAST * value) {
     37        assert (index < 3);
     38        mExprs[index] = value;
     39    }
    2840    inline PabloAST * getCondition() const {
    29         return mIf_expr;
     41        return mExprs[0];
    3042    }
    3143    inline PabloAST * getTrueExpr() const {
    32         return mT_expr;
     44        return mExprs[1];
    3345    }
    3446    inline PabloAST * getFalseExpr() const {
    35         return mF_expr;
     47        return mExprs[2];
    3648    }
    3749protected:
     
    4153    Sel(PabloAST* if_expr, PabloAST* t_expr, PabloAST* f_expr)
    4254    : PabloAST(ClassTypeId::Sel)
    43     , mIf_expr(if_expr)
    44     , mT_expr(t_expr)
    45     , mF_expr(f_expr)
     55    , mExprs({if_expr, t_expr, f_expr})
    4656    {
    4757
    4858    }
    4959private:
    50     PabloAST * const mIf_expr;
    51     PabloAST * const mT_expr;
    52     PabloAST * const mF_expr;
     60    std::array<PabloAST*, 3> mExprs;
    5361};
    5462
  • icGREP/icgrep-devel/icgrep/pablo/pe_string.h

    r4272 r4280  
    1818    virtual ~String(){
    1919
     20    }
     21    virtual PabloAST * getOperand(const unsigned) const {
     22        assert (false);
     23        return nullptr;
     24    }
     25    virtual unsigned getNumOperands() const {
     26        return 0;
     27    }
     28    virtual void setOperand(const unsigned, PabloAST *) {
     29        assert (false);
    2030    }
    2131    inline const std::string & str() const {
  • icGREP/icgrep-devel/icgrep/pablo/pe_var.h

    r4272 r4280  
    3232    virtual ~Var(){
    3333    }
     34    virtual PabloAST * getOperand(const unsigned index) const {
     35        assert (index == 0);
     36        return mVar;
     37    }
     38    virtual unsigned getNumOperands() const {
     39        return 1;
     40    }
     41    virtual void setOperand(const unsigned index, PabloAST * value) {
     42        assert (index == 0);
     43        mVar = value;
     44        mName = getNameOf(value);
     45    }
    3446    inline const String * getName() const {
    3547        return mName;
     48    }
     49    inline PabloAST * getVar() {
     50        return mVar;
    3651    }
    3752    inline const PabloAST * getVar() const {
     
    4863        return mAllocator.allocate(size);
    4964    }
    50     Var(const PabloAST * var)
     65    Var(PabloAST * var)
    5166    : PabloAST(ClassTypeId::Var)
    5267    , mVar(var)
     
    6984    }
    7085private:
    71     const PabloAST * const  mVar;
    72     const String * const    mName;
     86    PabloAST *         mVar;
     87    const String *     mName;
    7388};
    7489
  • icGREP/icgrep-devel/icgrep/pablo/pe_xor.h

    r4272 r4280  
    99
    1010#include <pablo/pabloAST.h>
     11#include <array>
    1112
    1213namespace pablo {
     
    2627    virtual ~Xor() {
    2728    }
    28     inline PabloAST * getExpr1() const {
    29         return mExpr1;
     29    virtual PabloAST * getOperand(const unsigned index) const {
     30        assert (index < 2);
     31        return mExprs[index];
    3032    }
    31     inline PabloAST * getExpr2() const {
    32         return mExpr2;
     33    virtual unsigned getNumOperands() const {
     34        return 2;
     35    }
     36    virtual void setOperand(const unsigned index, PabloAST * value) {
     37        assert (index < 2);
     38        mExprs[index] = value;
     39    }
     40    PabloAST * getExpr1() const {
     41        return mExprs[0];
     42    }
     43    PabloAST * getExpr2() const {
     44        return mExprs[1];
    3345    }
    3446protected:
     
    3850    Xor(PabloAST * expr1, PabloAST * expr2)
    3951    : PabloAST(ClassTypeId::Xor)
    40     , mExpr1(expr1)
    41     , mExpr2(expr2)
     52    , mExprs({expr1, expr2})
    4253    {
    4354
    4455    }
    4556private:
    46     PabloAST * const mExpr1;
    47     PabloAST * const mExpr2;
     57    std::array<PabloAST*, 2> mExprs;
    4858};
    4959
  • icGREP/icgrep-devel/icgrep/pablo/pe_zeroes.h

    r4272 r4280  
    2424
    2525    }
     26    virtual PabloAST * getOperand(const unsigned) const {
     27        assert (false);
     28        return nullptr;
     29    }
     30    virtual unsigned getNumOperands() const {
     31        return 0;
     32    }
     33    virtual void setOperand(const unsigned, PabloAST *) {
     34        assert (false);
     35    }
    2636    inline bool operator==(const Zeroes & other) const {
    2737        return true;
  • icGREP/icgrep-devel/icgrep/pablo/printer_pablos.cpp

    r4276 r4280  
    6161}
    6262
    63 std::string PabloPrinter::print(const Statement * stmt)
    64 {
    65     if (const Assign * an = dyn_cast<const Assign>(stmt)) {
     63std::string PabloPrinter::print(const Statement * stmt) {
     64    if (stmt == nullptr) {
     65        return "<null>";
     66    }
     67    else if (const Assign * an = dyn_cast<const Assign>(stmt)) {
    6668        std::string result = "Assign('" + an->getName()->str() + "'," + print(an->getExpr());
    6769        if (an->isOutputAssignment()) {
     
    8385
    8486std::string PabloPrinter::print(const PabloAST *expr) {
    85     if (isa<const Zeroes>(expr)) {
     87    if (expr == nullptr) {
     88        return "<null>";
     89    }
     90    else if (isa<const Zeroes>(expr)) {
    8691        return "Zeroes";
    8792    }
     
    116121        return "ScanThru(" + print(sthru->getScanFrom()) + ", " + print(sthru->getScanThru()) + ")";
    117122    }
     123    else if (isa<Statement>(expr)) {
     124        return print(cast<Statement>(expr));
     125    }
    118126    return "???";
    119127}
  • icGREP/icgrep-devel/icgrep/pablo/ps_assign.h

    r4276 r4280  
    99
    1010#include <pablo/pe_string.h>
     11#include <array>
    1112
    1213namespace pablo {
     
    2425    virtual ~Assign() {
    2526    }
     27    virtual PabloAST * getOperand(const unsigned index) const {
     28        assert (index < 2);
     29        return mExprs[index];
     30    }
     31    virtual unsigned getNumOperands() const {
     32        return 2;
     33    }
     34    virtual void setOperand(const unsigned index, PabloAST * value) {
     35        assert (index < 2);
     36        mExprs[index] = value;
     37    }
    2638    inline const String * getName() const {
    27         return mName;
     39        return cast<String>(mExprs[0]);
    2840    }
    2941    inline PabloAST * getExpr() const {
    30         return mExpr;
     42        return mExprs[1];
    3143    }
    3244    inline bool isOutputAssignment() const {
     
    4052        return mAllocator.allocate(size);
    4153    }
    42     Assign(PabloAST * name, PabloAST * expr, const int outputIndex)
    43     : Statement(ClassTypeId::Assign)
    44     , mName(cast<String>(name))
    45     , mExpr(expr)
     54    Assign(PabloAST * name, PabloAST * expr, const int outputIndex, StatementList * parent)
     55    : Statement(ClassTypeId::Assign, parent)
     56    , mExprs({name, expr})
    4657    , mOutputIndex(outputIndex)
    4758    {
     
    4960    }
    5061private:
    51     String * const          mName;
    52     PabloAST * const        mExpr;
    53     const int               mOutputIndex;
     62    std::array<PabloAST *,2>    mExprs;
     63    const int                   mOutputIndex;
    5464};
    5565
  • icGREP/icgrep-devel/icgrep/pablo/ps_if.h

    r4276 r4280  
    2323    virtual ~If() {
    2424    }
     25    virtual PabloAST * getOperand(const unsigned index) const {
     26        assert (index == 0);
     27        return mExpr;
     28    }
     29    virtual unsigned getNumOperands() const {
     30        return 1;
     31    }
     32    virtual void setOperand(const unsigned index, PabloAST * value) {
     33        assert (index == 0);
     34        mExpr = value;
     35    }
    2536    inline PabloAST * getCondition() const {
    2637        return mExpr;
     
    4253        return mAllocator.allocate(size);
    4354    }
    44     If(PabloAST * expr, StatementList && body)
    45     : Statement(ClassTypeId::If)
     55    If(PabloAST * expr, StatementList && body, StatementList * parent)
     56    : Statement(ClassTypeId::If, parent)
    4657    , mExpr(expr)
    4758    , mBody(std::move(body))
    4859    , mCarryCount(0)
    4960    {
    50 
     61        for (Statement * s : mBody) {
     62            s->mParent = &mBody;
     63        }
    5164    }
    5265private:
    53     PabloAST * const    mExpr;
     66    PabloAST *          mExpr;
    5467    StatementList       mBody;
    5568    unsigned            mCarryCount;
  • icGREP/icgrep-devel/icgrep/pablo/ps_while.h

    r4276 r4280  
    2323    virtual ~While() {
    2424    }
     25    virtual PabloAST * getOperand(const unsigned index) const {
     26        assert (index == 0);
     27        return mExpr;
     28    }
     29    virtual unsigned getNumOperands() const {
     30        return 1;
     31    }
     32    virtual void setOperand(const unsigned index, PabloAST * value) {
     33        assert (index == 0);
     34        mExpr = value;
     35    }
    2536    inline PabloAST * getCondition() const {
    2637        return mExpr;
     
    4253        return mAllocator.allocate(size);
    4354    }
    44     While(PabloAST * expr, StatementList && body)
    45     : Statement(ClassTypeId::While)
     55    While(PabloAST * expr, StatementList && body, StatementList * parent)
     56    : Statement(ClassTypeId::While, parent)
    4657    , mExpr(expr)
    4758    , mBody(std::move(body))
    4859    , mCarryCount(0)
    4960    {
    50 
     61        for (Statement * s : mBody) {
     62            s->mParent = &mBody;
     63        }
    5164    }
    5265private:
    53     PabloAST * const    mExpr;
     66    PabloAST *          mExpr;
    5467    StatementList       mBody;
    5568    unsigned            mCarryCount;
  • icGREP/icgrep-devel/icgrep/re/re_compiler.cpp

    r4268 r4280  
    4646    const std::string nonfinal = "nonfinal";
    4747
    48     if (hasUnicode(re)) {
    49         //Set the 'internal.initial' bit stream for the utf-8 multi-byte encoding.       
    50         PabloAST * u8single = mNameMap["UTF8-SingleByte"]->getVar();
    51         PabloAST * u8pfx2 = mNameMap["UTF8-Prefix2"]->getVar();
    52         PabloAST * u8pfx3 = mNameMap["UTF8-Prefix3"]->getVar();
    53         PabloAST * u8pfx4 = mNameMap["UTF8-Prefix4"]->getVar();
    54         PabloAST * u8pfx = pb.createOr(pb.createOr(u8pfx2, u8pfx3), u8pfx4);
    55         mInitial = pb.createVar(pb.createAssign(initial, pb.createOr(u8pfx, u8single)));
    56         #ifdef USE_IF_FOR_NONFINAL
    57         mNonFinal = pb.createVar(pb.createAssign(gs_nonfinal, pb.createZeroes()));
    58         #endif
    59         PabloAST * u8scope32 = pb.createAdvance(u8pfx3, 1);
    60         PabloAST * u8scope42 = pb.createAdvance(u8pfx4, 1);
    61         PabloAST * u8scope43 = pb.createAdvance(u8scope42, 1);
    62         #ifdef USE_IF_FOR_NONFINAL
    63         PabloBlock it(pb);
    64         it.createAssign(gs_nonfinal, it.createOr(it.createOr(u8pfx, u8scope32), it.createOr(u8scope42, u8scope43)));
    65         pb.createIf(u8pfx, std::move(it));
    66         #else       
    67         mNonFinal = pb.createVar(pb.createAssign(nonfinal, pb.createOr(pb.createOr(u8pfx, u8scope32), pb.createOr(u8scope42, u8scope43))));
    68         #endif
    69     }
    70     else {
    71         mInitial = pb.createZeroes();
    72         mNonFinal = pb.createZeroes();
    73     }
     48    //Set the 'internal.initial' bit stream for the utf-8 multi-byte encoding.
     49    PabloAST * u8single = mNameMap["UTF8-SingleByte"]->getVar();
     50    PabloAST * u8pfx2 = mNameMap["UTF8-Prefix2"]->getVar();
     51    PabloAST * u8pfx3 = mNameMap["UTF8-Prefix3"]->getVar();
     52    PabloAST * u8pfx4 = mNameMap["UTF8-Prefix4"]->getVar();
     53    PabloAST * u8pfx = pb.createOr(pb.createOr(u8pfx2, u8pfx3), u8pfx4);
     54    mInitial = pb.createVar(pb.createAssign(initial, pb.createOr(u8pfx, u8single)));
     55    #ifdef USE_IF_FOR_NONFINAL
     56    mNonFinal = pb.createVar(pb.createAssign(gs_nonfinal, pb.createZeroes()));
     57    #endif
     58    PabloAST * u8scope32 = pb.createAdvance(u8pfx3, 1);
     59    PabloAST * u8scope42 = pb.createAdvance(u8pfx4, 1);
     60    PabloAST * u8scope43 = pb.createAdvance(u8scope42, 1);
     61    #ifdef USE_IF_FOR_NONFINAL
     62    PabloBlock it(pb);
     63    it.createAssign(gs_nonfinal, it.createOr(it.createOr(u8pfx, u8scope32), it.createOr(u8scope42, u8scope43)));
     64    pb.createIf(u8pfx, std::move(it));
     65    #else
     66    mNonFinal = pb.createVar(pb.createAssign(nonfinal, pb.createOr(pb.createOr(u8pfx, u8scope32), pb.createOr(u8scope42, u8scope43))));
     67    #endif
    7468
    7569    PabloAST * result = process(re, pb.createAssign("start", pb.createOnes()), pb);
     
    127121    }
    128122    else {
    129         cc = pb.createVar(name->getName());
     123        cc = name->getVar();
    130124    }
    131125    return pb.createAssign("m", pb.createAdvance(pb.createAnd(cc, markerVar), 1));
     
    205199               
    206200inline bool RE_Compiler::isFixedLength(RE * regexp) {
    207     return isa<Name>(regexp) && ((cast<Name>(regexp) -> getType()) == Name::Type::FixedLength);
     201    return isa<Name>(regexp) && ((cast<Name>(regexp)->getType()) == Name::Type::FixedLength);
    208202}
    209203
    210204inline Assign * RE_Compiler::processLowerBound(RE * repeated, int lb, Assign * marker, PabloBlock & pb) {
    211205        if (isFixedLength(repeated)) {
    212                 Name * rep_name = cast<Name>(repeated);
    213                 Assign * cc_lb = consecutive(pb.createAssign("repeated", pb.createAdvance(pb.createVar(rep_name->getName()), 1)), 1, lb, pb);
     206        Name * name = cast<Name>(repeated);
     207        Assign * cc_lb = consecutive(pb.createAssign("repeated", pb.createAdvance(name->getVar(), 1)), 1, lb, pb);
    214208                return pb.createAssign("lowerbound", pb.createAnd(pb.createAdvance(pb.createVar(marker), lb), pb.createVar(cc_lb)));
    215209        }
     
    228222                Assign * nonMatch = pb.createAssign("nonmatch", pb.createNot(pb.createVar(marker)));
    229223                PabloAST * upperLimitMask = pb.createNot(pb.createVar(consecutive(nonMatch, 1, ub + 1, pb)));
    230                 PabloAST * rep_class_var = pb.createVar(cast<Name>(repeated) -> getName());
    231                         return pb.createAssign("bounded", pb.createAnd(pb.createMatchStar(pb.createVar(marker), rep_class_var), upperLimitMask));
     224        PabloAST * rep_class_var = cast<Name>(repeated)->getVar();
     225        return pb.createAssign("bounded", pb.createAnd(pb.createMatchStar(pb.createVar(marker), rep_class_var), upperLimitMask));
    232226        }
    233227        // Fall through to general case.
     
    244238
    245239    if (isa<Name>(repeated)) {
    246         Name * rep_name = cast<Name>(repeated);
     240        Name * name = cast<Name>(repeated);
    247241
    248242        PabloAST * cc;
    249         if (rep_name->getType() == Name::Type::UnicodeCategory) {
    250             cc = pb.createCall(rep_name->getName());
     243        if (name->getType() == Name::Type::UnicodeCategory) {
     244            cc = pb.createCall(name->getName());
    251245        }
    252246        else {
    253             cc = pb.createVar(rep_name->getName());
     247            cc = name->getVar();
    254248        }
    255249
    256250        unbounded = pb.createVar(marker);
    257         if (rep_name->getType() == Name::Type::FixedLength) {
     251        if (name->getType() == Name::Type::FixedLength) {
    258252            unbounded = pb.createMatchStar(unbounded, cc);
    259253        }
     
    289283}
    290284
    291 bool RE_Compiler::hasUnicode(const RE * re) {
    292     bool found = false;
    293     if (re == nullptr) {
    294         throw std::runtime_error("Unexpected Null Value passed to RE Compiler!");
    295     }
    296     else if (isa<Any>(re)) {
    297         found = true;
    298     }
    299     else if (isa<Diff>(re)) {
    300         found = true;
    301     }
    302     else if (const Name * name = dyn_cast<const Name>(re)) {
    303         if ((name->getType() == Name::Type::UnicodeCategory) || (name->getType() == Name::Type::Unicode)) {
    304             found = true;
    305         }
    306     }
    307     else if (const Seq * re_seq = dyn_cast<const Seq>(re)) {
    308         for (auto i = re_seq->cbegin(); i != re_seq->cend(); ++i) {
    309             if (hasUnicode(*i)) {
    310                 found = true;
    311                 break;
    312             }
    313         }
    314     }
    315     else if (const Alt * re_alt = dyn_cast<const Alt>(re)) {
    316         for (auto i = re_alt->cbegin(); i != re_alt->cend(); ++i) {
    317             if (hasUnicode(*i)) {
    318                 found = true;
    319                 break;
    320             }
    321         }
    322     }
    323     else if (const Rep * rep = dyn_cast<const Rep>(re)) {
    324         found = hasUnicode(rep->getRE());
    325     }
    326     return found;
    327 }
    328 
    329285} // end of namespace re
  • icGREP/icgrep-devel/icgrep/re/re_compiler.h

    r4266 r4280  
    4646    pablo::Assign * process(Diff * diff, pablo::Assign * marker, pablo::PabloBlock & cg);
    4747    pablo::Assign * consecutive(pablo::Assign * repeated,  int repeated_lgth, int repeat_count, pablo::PabloBlock & pb);
    48     bool isFixedLength(RE * regexp);
     48    static bool isFixedLength(RE * regexp);
    4949    pablo::Assign * processLowerBound(RE * repeated,  int lb, pablo::Assign * marker, pablo::PabloBlock & pb);
    5050    pablo::Assign * processUnboundedRep(RE * repeated, pablo::Assign * marker, pablo::PabloBlock & pb);
    5151    pablo::Assign * processBoundedRep(RE * repeated, int ub, pablo::Assign * marker, pablo::PabloBlock & pb);
    52 
    53 
    54     static bool hasUnicode(const RE *re);
    5552
    5653    pablo::PabloBlock &                             mCG;
Note: See TracChangeset for help on using the changeset viewer.