source: icGREP/icgrep-devel/icgrep/pablo/codegenstate.h @ 4215

Last change on this file since 4215 was 4215, checked in by nmedfort, 5 years ago

Removed string based CC lookup in CC Compiler.

File size: 5.2 KB
Line 
1/*
2 *  Copyright (c) 2014 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 *  icgrep is a trademark of International Characters.
5 */
6
7#ifndef PS_PABLOS_H
8#define PS_PABLOS_H
9
10#include <pablo/pe_pabloe.h>
11#include <pablo/pe_string.h>
12#include <pablo/pe_advance.h>
13#include <pablo/pe_all.h>
14#include <pablo/pe_and.h>
15#include <pablo/pe_call.h>
16#include <pablo/pe_charclass.h>
17#include <pablo/pe_matchstar.h>
18#include <pablo/pe_not.h>
19#include <pablo/pe_or.h>
20#include <pablo/pe_pabloe.h>
21#include <pablo/pe_scanthru.h>
22#include <pablo/pe_sel.h>
23#include <pablo/pe_var.h>
24#include <pablo/pe_xor.h>
25#include <pablo/ps_assign.h>
26#include <pablo/ps_if.h>
27#include <pablo/ps_while.h>
28#include <pablo/symbol_generator.h>
29#include <unordered_map>
30#include <vector>
31#include <string>
32#include <array>
33#include <tuple>
34
35namespace pablo {
36
37struct CodeGenState {
38
39    CodeGenState(SymbolGenerator & symgen)
40    : mSymbolGenerator(symgen)
41    , mAll{{new All(0), new All(1)}}
42    , mUnary(nullptr, this)
43    , mBinary(nullptr, this)
44    , mTernary(nullptr, this)
45    {
46
47    }
48
49    CodeGenState(CodeGenState & cg)
50    : mSymbolGenerator(cg.mSymbolGenerator)
51    , mAll(cg.mAll)    // inherit the original "All" variables for simplicity
52    , mUnary(&(cg.mUnary), this)
53    , mBinary(&(cg.mBinary), this)
54    , mTernary(&(cg.mTernary), this)
55    {
56
57    }
58
59    Advance * createAdvance(PabloE * expr);
60
61    inline All * createAll(const bool value) const {
62        return mAll[value];
63    }
64
65    Assign * createAssign(const std::string name, PabloE * expr);
66
67    Call * createCall(const std::string name);
68
69    Var * createVar(const std::string name);
70
71    Var * createVar(Assign * assign);
72
73    inline PabloE * createVarIfAssign(PabloE * const input) {
74        return isa<Assign>(input) ? createVar(cast<Assign>(input)) : input;
75    }
76
77    CharClass * createCharClass(const std::string name);
78
79    PabloE * createAnd(PabloE * expr1, PabloE * expr2);
80
81    PabloE * createNot(PabloE * expr);
82
83    PabloE * createOr(PabloE * expr1, PabloE * expr2);
84
85    PabloE * createXor(PabloE * expr1, PabloE * expr2);
86
87    MatchStar * createMatchStar(PabloE * expr1, PabloE * expr2);
88
89    ScanThru * createScanThru(PabloE * from, PabloE * thru);
90
91    PabloE * createSel(PabloE * condition, PabloE * trueExpr, PabloE * falseExpr);
92
93    inline If * createIf(PabloE * condition, ExpressionList statements) {
94        return new If(condition, std::move(statements));
95    }
96
97    inline While * createWhile(PabloE * cond, ExpressionList statements) {
98        return new While(cond, std::move(statements));
99    }
100
101    template<typename... Args>
102    struct ExpressionMap {
103        typedef ExpressionMap<Args...> MapType;
104        typedef std::tuple<PabloE::ClassTypeId, Args...> Key;
105
106        inline ExpressionMap(MapType * predecessor, CodeGenState * parent)
107        : mPredecessor(predecessor)
108        , mCodeGenState(*parent)
109        {
110
111        }
112
113        template <class Type>
114        inline Type * findOrMake(const PabloE::ClassTypeId type, Args... args) {
115            auto key = std::make_tuple(type, args...);
116            PabloE * f = find(key);
117            if (f) {
118                return cast<Type>(f);
119            }
120            Type * expr = new Type(args...);
121            mMap.insert(std::make_pair(std::move(key), expr));
122            return expr;
123        }
124
125        template <class Functor>
126        inline PabloE * findOrCall(const PabloE::ClassTypeId type, Args... args) {
127            auto key = std::make_tuple(type, args...);
128            PabloE * f = find(key);
129            if (f) {
130                return f;
131            }
132            Functor mf(mCodeGenState);
133            PabloE * expr = mf(args...);
134            mMap.insert(std::make_pair(std::move(key), expr));
135            return expr;
136        }
137
138    private:
139
140        inline PabloE * find(const Key & key) const {
141            // check this map to see if we have it
142            auto itr = mMap.find(key);
143            if (itr != mMap.end()) {
144                return itr->second;
145            }
146            // check any previous maps to see if it exists
147            auto * pred = mPredecessor;
148            while (pred) {
149                itr = pred->mMap.find(key);
150                if (itr == pred->mMap.end()) {
151                    pred = pred->mPredecessor;
152                    continue;
153                }
154                return itr->second;
155            }
156            return nullptr;
157        }
158
159    private:
160        MapType * const         mPredecessor;
161        CodeGenState &          mCodeGenState;
162        std::map<Key, PabloE *> mMap;
163    };
164
165    inline void push_back(PabloE * expr) {
166        mExpressions.push_back(expr);
167    }
168
169    inline std::string ssa(std::string prefix) { // Static Single-Assignment
170        return mSymbolGenerator.ssa(prefix);
171    }
172
173    inline const ExpressionList & expressions() const {
174        return mExpressions;
175    }
176
177private:   
178    SymbolGenerator &                               mSymbolGenerator;
179    const std::array<All *, 2>                      mAll;
180    ExpressionMap<PabloE *>                         mUnary;
181    ExpressionMap<PabloE *, PabloE *>               mBinary;
182    ExpressionMap<PabloE *, PabloE *, PabloE *>     mTernary;
183    ExpressionList                                  mExpressions;
184};
185
186}
187
188#endif // PS_PABLOS_H
Note: See TracBrowser for help on using the repository browser.