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

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

Temporary check in.

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