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

Last change on this file since 4602 was 4602, checked in by nmedfort, 4 years ago

Fixed PabloBuilder? and intergrated it into CC Compiler.

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