source: icGREP/icgrep-devel/icgrep/pablo/pabloAST.h @ 4410

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

Changes to support 3-operand form for all instructions. CSE disabled but partially redundant now.

File size: 10.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 PE_PabloAST_H
8#define PE_PabloAST_H
9
10#include <llvm/Support/Casting.h>
11#include <llvm/Support/Compiler.h>
12#include <llvm/ADT/SetVector.h>
13#include <slab_allocator.h>
14#include <iterator>
15#include <unordered_map>
16
17using namespace llvm;
18
19namespace pablo {
20
21class PabloBlock;
22
23class PMDNode;
24
25class PabloAST {
26    friend class PMDNode;
27    friend class Advance;
28    friend class And;
29    friend class Assign;
30    friend class Call;
31    friend class If;
32    friend class MatchStar;
33    friend class Next;
34    friend class Not;
35    friend class Ones;
36    friend class Or;
37    friend class ScanThru;
38    friend class Sel;
39    friend class String;
40    friend class Var;
41    friend class While;
42    friend class Xor;
43    friend class Zeroes;
44    friend class PabloBlock;
45    friend class SymbolGenerator;
46    typedef std::unordered_map<std::string, PMDNode *> PMDNodeMap;
47public:
48    typedef SlabAllocator<4096> Allocator;
49    enum class ClassTypeId : unsigned {
50        Advance
51        , And
52        , Assign
53        , Call
54        , If
55        , MatchStar
56        , Next
57        , Not
58        , Ones
59        , Or
60        , ScanThru
61        , Sel
62        , String
63        , Var
64        , While
65        , Xor
66        , Zeroes
67    };
68    inline ClassTypeId getClassTypeId() const {
69        return mClassTypeId;
70    }
71
72    void setMetadata(const std::string & name, PMDNode * node);
73
74    PMDNode * getMetadata(const std::string & name);
75
76    inline static void release_memory() {
77        mAllocator.release_memory();
78    }
79
80    void* operator new (std::size_t size) noexcept {
81        return mAllocator.allocate(size);
82    }
83protected:
84    inline PabloAST(const ClassTypeId id)
85    : mClassTypeId(id)
86    , mMetadataMap(nullptr)
87    {
88
89    }
90    inline void addUser(PabloAST * user) {
91        mUsers.insert(user);
92    }
93    inline void removeUser(PabloAST * user) {
94        mUsers.remove(user);
95    }
96    // virtual void removeUsageFromDefs() = 0;
97    static Allocator        mAllocator;
98private:
99    const ClassTypeId       mClassTypeId;
100    SetVector<PabloAST *>   mUsers;
101    PMDNodeMap *            mMetadataMap;
102};
103
104bool equals(const PabloAST * expr1, const PabloAST *expr2);
105
106class StatementList;
107
108class String;
109
110class Statement : public PabloAST {
111    friend class StatementList;
112    friend class If;
113    friend class While;
114    friend class PabloBlock;
115public:
116    static inline bool classof(const PabloAST * e) {
117        switch (e->getClassTypeId()) {
118            case PabloAST::ClassTypeId::String:
119                return false;
120            default:
121                return true;
122        }
123    }
124    static inline bool classof(const Statement *) {
125        return true;
126    }
127    static inline bool classof(const void *) {
128        return false;
129    }
130
131    inline void replaceUsesOfWith(PabloAST * from, PabloAST * to) {
132        if (from == to) {
133            return;
134        }
135        for (unsigned i = 0, operands = getNumOperands(); i != operands; ++i) {
136            if (getOperand(i) == from) {
137                setOperand(i, to);
138            }
139        }
140    }
141
142    virtual PabloAST * getOperand(const unsigned index) const = 0;
143
144    virtual unsigned getNumOperands() const = 0;
145
146    virtual void setOperand(const unsigned index, PabloAST * value) = 0;
147
148    void insertBefore(Statement * const statement);
149    void insertAfter(Statement * const statement);
150    void removeFromParent();
151    void replaceWith(Statement * const statement);
152
153    inline const String * getName() const {
154        return mName;
155    }
156    inline Statement * getNextNode() const {
157        return mNext;
158    }
159    inline Statement * getPrevNode() const {
160        return mPrev;
161    }
162    inline PabloBlock * getParent() const {
163        return mParent;
164    }
165protected:
166    Statement(const ClassTypeId id, const String * name, PabloBlock * parent)
167    : PabloAST(id)
168    , mName(name)
169    , mNext(nullptr)
170    , mPrev(nullptr)
171    , mParent(parent)
172    {
173
174    }
175    virtual ~Statement() = 0;
176protected:
177    const String * mName;
178    Statement * mNext;
179    Statement * mPrev;
180    PabloBlock * mParent;
181};
182
183class StatementList {
184    friend class Statement;
185public:
186    class iterator: public std::iterator<std::forward_iterator_tag, Statement> {
187    public:
188        iterator(): mCurrent(nullptr) {}
189
190        iterator(Statement* base): mCurrent(base) {}
191
192        iterator(const iterator& other): mCurrent(other.mCurrent) {}
193
194        const iterator& operator=(const iterator& other) {
195            mCurrent = other.mCurrent; return other;
196        }
197
198        inline iterator& operator++() {
199            assert (mCurrent);
200            mCurrent = mCurrent->mNext;
201            return *this;
202        }
203
204        iterator  operator++(int) {
205            iterator tmp(*this);
206            ++(*this);
207            return tmp;
208        }
209
210        bool operator==(const iterator& other) const {
211            return  mCurrent == other.mCurrent;
212        }
213
214        bool operator!=(const iterator& other) const {
215            return  mCurrent != other.mCurrent;
216        }
217
218        Statement* operator*() {return mCurrent;}
219        Statement* operator->(){return mCurrent;}
220
221    private:
222        Statement * mCurrent;
223        friend class const_iterator;
224    };
225
226    class const_iterator: public std::iterator<std::forward_iterator_tag, Statement> {
227    public:
228        const_iterator(): mCurrent(nullptr) {}
229        const_iterator(const Statement* base): mCurrent(base) {}
230        const_iterator(const const_iterator& other): mCurrent(other.mCurrent) {}
231        const const_iterator& operator=(const const_iterator& other) {mCurrent = other.mCurrent; return other;}
232
233        inline const_iterator& operator++() {
234            assert (mCurrent);
235            mCurrent = mCurrent->mNext;
236            return *this;
237        }
238
239        const_iterator  operator++(int) {
240            const_iterator tmp(*this);
241            ++(*this);
242            return tmp;
243        }
244
245        bool operator==(const const_iterator & other) const {
246            return  mCurrent == other.mCurrent;
247        }
248        bool operator!=(const const_iterator & other) const {
249            return  mCurrent != other.mCurrent;
250        }
251
252        const Statement* operator*() {return mCurrent;}
253        const Statement* operator->(){return mCurrent;}
254
255    private:
256        const Statement * mCurrent;
257        friend struct iterator;
258    };
259
260    class reverse_iterator: public std::iterator<std::forward_iterator_tag, Statement> {
261    public:
262        reverse_iterator(): mCurrent(nullptr) {}
263
264        reverse_iterator(Statement* base): mCurrent(base) {}
265
266        reverse_iterator(const reverse_iterator& other): mCurrent(other.mCurrent) {}
267
268        const reverse_iterator& operator=(const reverse_iterator& other) {
269            mCurrent = other.mCurrent; return other;
270        }
271
272        inline reverse_iterator& operator++() {
273            assert (mCurrent);
274            mCurrent = mCurrent->mPrev;
275            return *this;
276        }
277
278        reverse_iterator operator++(int) {
279            reverse_iterator tmp(*this);
280            ++(*this);
281            return tmp;
282        }
283
284        bool operator==(const reverse_iterator& other) const {
285            return  mCurrent == other.mCurrent;
286        }
287
288        bool operator!=(const reverse_iterator& other) const {
289            return  mCurrent != other.mCurrent;
290        }
291
292        Statement* operator*() {return mCurrent;}
293        Statement* operator->(){return mCurrent;}
294
295    private:
296        Statement * mCurrent;
297        friend class const_reverse_iterator;
298    };
299
300    class const_reverse_iterator: public std::iterator<std::forward_iterator_tag, Statement> {
301    public:
302        const_reverse_iterator(): mCurrent(nullptr) {}
303        const_reverse_iterator(const Statement* base): mCurrent(base) {}
304        const_reverse_iterator(const const_reverse_iterator& other): mCurrent(other.mCurrent) {}
305        const const_reverse_iterator& operator=(const const_reverse_iterator& other) {mCurrent = other.mCurrent; return other;}
306
307        inline const_reverse_iterator& operator++() {
308            assert (mCurrent);
309            mCurrent = mCurrent->mPrev;
310            return *this;
311        }
312
313        const_reverse_iterator  operator++(int) {
314            const_reverse_iterator tmp(*this);
315            ++(*this);
316            return tmp;
317        }
318
319        bool operator==(const const_reverse_iterator & other) const {
320            return  mCurrent == other.mCurrent;
321        }
322        bool operator!=(const const_reverse_iterator & other) const {
323            return  mCurrent != other.mCurrent;
324        }
325
326        const Statement* operator*() {return mCurrent;}
327        const Statement* operator->(){return mCurrent;}
328
329    private:
330        const Statement * mCurrent;
331        friend struct iterator;
332    };
333
334public:
335
336    StatementList()
337    : mFirst(nullptr)
338    , mLast(nullptr)
339    {
340
341    }
342
343    StatementList(StatementList && other)
344    : mFirst(other.mFirst)
345    , mLast(other.mLast)
346    {
347        other.mFirst = nullptr;
348        other.mLast = nullptr;
349    }
350
351    iterator begin() {
352        return iterator(mFirst);
353    }
354
355    iterator end() {
356        return iterator(nullptr);
357    }
358
359    reverse_iterator rbegin() {
360        return reverse_iterator(mLast);
361    }
362
363    reverse_iterator rend() {
364        return reverse_iterator(nullptr);
365    }
366
367    const_iterator begin() const {
368        return const_iterator(mFirst);
369    }
370
371    const_iterator end() const {
372        return const_iterator(nullptr);
373    }
374
375    const_reverse_iterator rbegin() const {
376        return const_reverse_iterator(mLast);
377    }
378
379    const_reverse_iterator rend() const {
380        return const_reverse_iterator(nullptr);
381    }
382
383    const_iterator cbegin() const {
384        return const_iterator(mFirst);
385    }
386
387    const_iterator cend() const {
388        return const_iterator(nullptr);
389    }
390
391    const_reverse_iterator crbegin() const {
392        return const_reverse_iterator(mLast);
393    }
394
395    const_reverse_iterator crend() const {
396        return const_reverse_iterator(nullptr);
397    }
398
399    Statement * front() const {
400        return mFirst;
401    }
402
403    Statement * back() const {
404        return mLast;
405    }
406
407    void push_back(Statement * const statement);
408
409private:
410    Statement   * mFirst;
411    Statement   * mLast;
412};
413
414}
415
416#endif // PE_PabloAST_H
417
418
419
Note: See TracBrowser for help on using the repository browser.