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

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

First attempt to add arguments to Call objects. Currently non-functioning in Pablo_Compiler.

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