source: icGREP/icgrep-devel/icgrep/pablo/expression_map.hpp @ 5829

Last change on this file since 5829 was 5828, checked in by nmedfort, 22 months ago

Pablo support for byte comparisions; LineFeed? kernel processes byte streams directly. Some clean up of PabloBuilder? functionality.

File size: 6.1 KB
Line 
1#ifndef EXPRESSION_MAP_HPP
2#define EXPRESSION_MAP_HPP
3
4#include <pablo/pabloAST.h>
5#include <util/slab_allocator.h>
6#include <map>
7
8namespace pablo {
9
10template<typename... Args>
11struct FixedArgMap {
12    enum {N = sizeof...(Args)};
13    typedef FixedArgMap<Args...> Type;
14    typedef std::tuple<PabloAST::ClassTypeId, Args...> Key;
15    friend struct ExpressionTable;
16
17    explicit FixedArgMap(Type * predecessor = nullptr) noexcept
18    : mPredecessor(predecessor) {
19
20    }
21
22    explicit FixedArgMap(Type && other) noexcept
23    : mPredecessor(other.mPredecessor)
24    , mMap(std::move(other.mMap)) {
25
26    }
27
28    FixedArgMap & operator=(Type && other) noexcept {
29        mPredecessor = other.mPredecessor;
30        mMap = std::move(other.mMap);
31        return *this;
32    }
33
34    template <class Functor, typename... Params>
35    PabloAST * findOrCall(Functor && functor, const PabloAST::ClassTypeId typeId, Args... args, Params... params) noexcept {
36        Key key = std::make_tuple(typeId, args...);
37        PabloAST * const f = find(key);
38        if (f) {
39            return f;
40        }
41        PabloAST * const object = functor(std::forward<Args>(args)..., std::forward<Params>(params)...);
42        mMap.insert(std::make_pair(std::move(key), object));
43        return object;
44    }
45
46    std::pair<PabloAST *, bool> findOrAdd(PabloAST * object, const PabloAST::ClassTypeId typeId, Args... args) noexcept {
47        Key key = std::make_tuple(typeId, args...);
48        PabloAST * const entry = find(key);
49        if (entry) {
50            return std::make_pair(entry, false);
51        }
52        mMap.insert(std::make_pair(std::move(key), object));
53        return std::make_pair(object, true);
54    }
55
56    bool erase(const PabloAST::ClassTypeId type, Args... args) noexcept {
57        Key key = std::make_tuple(type, args...);
58        for (Type * obj = this; obj; obj = obj->mPredecessor) {
59            auto itr = obj->mMap.find(key);
60            if (itr != mMap.end()) {
61                obj->mMap.erase(itr);
62                return true;
63            }
64        }
65        return false;
66    }
67
68    inline PabloAST * find(const PabloAST::ClassTypeId type, Args... args) const noexcept {
69        return find(std::make_tuple(type, args...));
70    }
71
72private:
73
74    PabloAST * find(const Key & key) const {
75        // check this map to see if we have it
76        auto itr = mMap.find(key);
77        if (itr != mMap.end()) {
78            return itr->second;
79        } else { // check any previous maps to see if it exists
80            auto * pred = mPredecessor;
81            while (pred) {
82                itr = pred->mMap.find(key);
83                if (itr == pred->mMap.end()) {
84                    pred = pred->mPredecessor;
85                    continue;
86                }
87                return itr->second;
88            }
89        }
90        return nullptr;
91    }
92
93private:
94    Type *                      mPredecessor;
95    std::map<Key, PabloAST *>   mMap;
96};
97
98struct ExpressionTable {
99
100    explicit ExpressionTable(ExpressionTable * predecessor = nullptr) noexcept {
101        if (predecessor) {
102            mUnary.mPredecessor = &(predecessor->mUnary);
103            mBinary.mPredecessor = &(predecessor->mBinary);
104            mTernary.mPredecessor = &(predecessor->mTernary);
105        }
106    }
107
108    explicit ExpressionTable(ExpressionTable & other) = delete;
109
110    explicit ExpressionTable(ExpressionTable && other) noexcept
111    : mUnary(std::move(other.mUnary))
112    , mBinary(std::move(other.mBinary))
113    , mTernary(std::move(other.mTernary)) {
114
115    }
116
117    ExpressionTable & operator=(ExpressionTable && other) noexcept {
118        mUnary = std::move(other.mUnary);
119        mBinary = std::move(other.mBinary);
120        mTernary = std::move(other.mTernary);
121        return *this;
122    }
123
124    template <class Functor, typename... Params>
125    inline PabloAST * findUnaryOrCall(Functor && functor, const PabloAST::ClassTypeId typeId, void * expr, Params... params) noexcept {
126        return mUnary.findOrCall(std::move(functor), typeId, expr, std::forward<Params>(params)...);
127    }
128
129    template <class Functor, typename... Params>
130    inline PabloAST * findBinaryOrCall(Functor && functor, const PabloAST::ClassTypeId typeId, void * expr1, void * expr2, Params... params) noexcept {
131        return mBinary.findOrCall(std::move(functor), typeId, expr1, expr2, std::forward<Params>(params)...);
132    }
133
134    template <class Functor, typename... Params>
135    inline PabloAST * findTernaryOrCall(Functor && functor, const PabloAST::ClassTypeId typeId, void * expr1, void * expr2, void * expr3, Params... params) noexcept {
136        return mTernary.findOrCall(std::move(functor), typeId, expr1, expr2, expr3, std::forward<Params>(params)...);
137    }
138
139    std::pair<PabloAST *, bool> findOrAdd(Statement * stmt) noexcept {
140        switch (stmt->getClassTypeId()) {                     
141            case PabloAST::ClassTypeId::Var:
142            case PabloAST::ClassTypeId::Not:
143            case PabloAST::ClassTypeId::Count:           
144                return mUnary.findOrAdd(stmt, stmt->getClassTypeId(), stmt->getOperand(0));
145            case PabloAST::ClassTypeId::And:
146            case PabloAST::ClassTypeId::Or:
147            case PabloAST::ClassTypeId::Xor:
148            case PabloAST::ClassTypeId::Advance:
149            case PabloAST::ClassTypeId::ScanThru:
150            case PabloAST::ClassTypeId::MatchStar:
151            case PabloAST::ClassTypeId::Assign:
152            case PabloAST::ClassTypeId::Extract:
153            return mBinary.findOrAdd(stmt, stmt->getClassTypeId(), stmt->getOperand(0), stmt->getOperand(1));
154            case PabloAST::ClassTypeId::Fill:
155                return mBinary.findOrAdd(stmt, stmt->getClassTypeId(), stmt->getOperand(0), stmt->getType());
156            case PabloAST::ClassTypeId::Sel:
157            case PabloAST::ClassTypeId::IndexedAdvance:
158                return mTernary.findOrAdd(stmt, stmt->getClassTypeId(), stmt->getOperand(0), stmt->getOperand(1), stmt->getOperand(2));
159            default:
160                return std::make_pair(stmt, true);
161        }
162    }
163
164private:
165    FixedArgMap<void *>                   mUnary;
166    FixedArgMap<void *, void *>           mBinary;
167    FixedArgMap<void *, void *, void *>   mTernary;
168};
169
170}
171
172#endif // EXPRESSION_MAP_HPP
Note: See TracBrowser for help on using the repository browser.