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

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

More work on usedef info.

File size: 10.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 PMDNode;
24
25class PabloAST {
26    friend class PMDNode;
27    friend class Statement;
28    friend class Var;
29    friend class If;
30    friend class While;
31    friend class PabloBlock;
32    friend class SymbolGenerator;
33    typedef std::unordered_map<std::string, PMDNode *> PMDNodeMap;
34public:
35    typedef SlabAllocator<4096> 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    };
56    inline ClassTypeId getClassTypeId() const {
57        return mClassTypeId;
58    }
59
60    void setMetadata(const std::string & name, PMDNode * node);
61
62    PMDNode * getMetadata(const std::string & name);
63
64    inline static void release_memory() {
65        mAllocator.release_memory();
66    }
67
68    void* operator new (std::size_t size) noexcept {
69        return mAllocator.allocate(size);
70    }
71protected:
72    inline PabloAST(const ClassTypeId id)
73    : mClassTypeId(id)
74    , mMetadataMap(nullptr)
75    {
76
77    }
78    inline void addUser(PabloAST * user) {
79        mUsers.insert(user);
80    }
81    inline void removeUser(PabloAST * user) {
82        mUsers.remove(user);
83    }
84    static Allocator        mAllocator;
85private:
86    const ClassTypeId       mClassTypeId;
87    SetVector<PabloAST *>   mUsers;
88    PMDNodeMap *            mMetadataMap;
89};
90
91bool equals(const PabloAST * expr1, const PabloAST *expr2);
92
93class StatementList;
94
95class String;
96
97class Statement : public PabloAST {
98    friend class StatementList;
99    friend class If;
100    friend class While;
101    friend class PabloBlock;
102public:
103    static inline bool classof(const PabloAST * e) {
104        switch (e->getClassTypeId()) {
105            case PabloAST::ClassTypeId::String:
106                return false;
107            default:
108                return true;
109        }
110    }
111    static inline bool classof(const Statement *) {
112        return true;
113    }
114    static inline bool classof(const void *) {
115        return false;
116    }
117
118    inline PabloAST * replaceUsesOfWith(PabloAST * from, PabloAST * to) {
119        if (from == to) {
120            return this;
121        }
122        for (unsigned i = 0; i != getNumOperands(); ++i) {
123            if (getOperand(i) == from) {
124                return setOperand(i, to);
125            }
126        }
127        return this;
128    }
129
130    PabloAST * getOperand(const unsigned index) const {
131        assert (index < getNumOperands());
132        return mOperand[index];
133    }
134
135    PabloAST * setOperand(const unsigned index, PabloAST * value);
136
137    unsigned getNumOperands() const {
138        return mOperand.size();
139    }
140
141    void insertBefore(Statement * const statement);
142    void insertAfter(Statement * const statement);
143    void removeFromParent();
144    void replaceWith(Statement * const statement);
145
146    inline const String * getName() const {
147        return mName;
148    }
149    inline Statement * getNextNode() const {
150        return mNext;
151    }
152    inline Statement * getPrevNode() const {
153        return mPrev;
154    }
155    inline PabloBlock * getParent() const {
156        return mParent;
157    }
158protected:
159    Statement(const ClassTypeId id, std::vector<PabloAST *> && operands, const String * name, PabloBlock * parent)
160    : PabloAST(id)
161    , mName(name)
162    , mNext(nullptr)
163    , mPrev(nullptr)
164    , mParent(parent)
165    , mOperand(std::move(operands))
166    {
167        for (PabloAST * op : mOperand) {
168            op->addUser(this);
169        }
170    }
171
172    virtual ~Statement() = 0;
173protected:
174    const String *              mName;
175    Statement *                 mNext;
176    Statement *                 mPrev;
177    PabloBlock *                mParent;
178    std::vector<PabloAST *>     mOperand;
179
180};
181
182class StatementList {
183    friend class Statement;
184public:
185    class iterator: public std::iterator<std::forward_iterator_tag, Statement> {
186    public:
187        iterator(): mCurrent(nullptr) {}
188
189        iterator(Statement* base): mCurrent(base) {}
190
191        iterator(const iterator& other): mCurrent(other.mCurrent) {}
192
193        const iterator& operator=(const iterator& other) {
194            mCurrent = other.mCurrent; return other;
195        }
196
197        inline iterator& operator++() {
198            assert (mCurrent);
199            mCurrent = mCurrent->mNext;
200            return *this;
201        }
202
203        iterator  operator++(int) {
204            iterator tmp(*this);
205            ++(*this);
206            return tmp;
207        }
208
209        bool operator==(const iterator& other) const {
210            return  mCurrent == other.mCurrent;
211        }
212
213        bool operator!=(const iterator& other) const {
214            return  mCurrent != other.mCurrent;
215        }
216
217        Statement* operator*() {return mCurrent;}
218        Statement* operator->(){return mCurrent;}
219
220    private:
221        Statement * mCurrent;
222        friend class const_iterator;
223    };
224
225    class const_iterator: public std::iterator<std::forward_iterator_tag, Statement> {
226    public:
227        const_iterator(): mCurrent(nullptr) {}
228        const_iterator(const Statement* base): mCurrent(base) {}
229        const_iterator(const const_iterator& other): mCurrent(other.mCurrent) {}
230        const const_iterator& operator=(const const_iterator& other) {mCurrent = other.mCurrent; return other;}
231
232        inline const_iterator& operator++() {
233            assert (mCurrent);
234            mCurrent = mCurrent->mNext;
235            return *this;
236        }
237
238        const_iterator  operator++(int) {
239            const_iterator tmp(*this);
240            ++(*this);
241            return tmp;
242        }
243
244        bool operator==(const const_iterator & other) const {
245            return  mCurrent == other.mCurrent;
246        }
247        bool operator!=(const const_iterator & other) const {
248            return  mCurrent != other.mCurrent;
249        }
250
251        const Statement* operator*() {return mCurrent;}
252        const Statement* operator->(){return mCurrent;}
253
254    private:
255        const Statement * mCurrent;
256        friend struct iterator;
257    };
258
259    class reverse_iterator: public std::iterator<std::forward_iterator_tag, Statement> {
260    public:
261        reverse_iterator(): mCurrent(nullptr) {}
262
263        reverse_iterator(Statement* base): mCurrent(base) {}
264
265        reverse_iterator(const reverse_iterator& other): mCurrent(other.mCurrent) {}
266
267        const reverse_iterator& operator=(const reverse_iterator& other) {
268            mCurrent = other.mCurrent; return other;
269        }
270
271        inline reverse_iterator& operator++() {
272            assert (mCurrent);
273            mCurrent = mCurrent->mPrev;
274            return *this;
275        }
276
277        reverse_iterator operator++(int) {
278            reverse_iterator tmp(*this);
279            ++(*this);
280            return tmp;
281        }
282
283        bool operator==(const reverse_iterator& other) const {
284            return  mCurrent == other.mCurrent;
285        }
286
287        bool operator!=(const reverse_iterator& other) const {
288            return  mCurrent != other.mCurrent;
289        }
290
291        Statement* operator*() {return mCurrent;}
292        Statement* operator->(){return mCurrent;}
293
294    private:
295        Statement * mCurrent;
296        friend class const_reverse_iterator;
297    };
298
299    class const_reverse_iterator: public std::iterator<std::forward_iterator_tag, Statement> {
300    public:
301        const_reverse_iterator(): mCurrent(nullptr) {}
302        const_reverse_iterator(const Statement* base): mCurrent(base) {}
303        const_reverse_iterator(const const_reverse_iterator& other): mCurrent(other.mCurrent) {}
304        const const_reverse_iterator& operator=(const const_reverse_iterator& other) {mCurrent = other.mCurrent; return other;}
305
306        inline const_reverse_iterator& operator++() {
307            assert (mCurrent);
308            mCurrent = mCurrent->mPrev;
309            return *this;
310        }
311
312        const_reverse_iterator  operator++(int) {
313            const_reverse_iterator tmp(*this);
314            ++(*this);
315            return tmp;
316        }
317
318        bool operator==(const const_reverse_iterator & other) const {
319            return  mCurrent == other.mCurrent;
320        }
321        bool operator!=(const const_reverse_iterator & other) const {
322            return  mCurrent != other.mCurrent;
323        }
324
325        const Statement* operator*() {return mCurrent;}
326        const Statement* operator->(){return mCurrent;}
327
328    private:
329        const Statement * mCurrent;
330        friend struct iterator;
331    };
332
333public:
334
335    StatementList()
336    : mInsertionPoint(nullptr)
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 setInsertPoint(Statement * const statement);
408
409    void setInsertPoint(StatementList * const list);
410
411    Statement * getInsertPoint() const {
412        return mInsertionPoint;
413    }
414
415    void insert(Statement * const statement);
416
417    void insertAfterLastOperand(Statement * const statement);
418
419private:
420
421    Statement   * mInsertionPoint;
422    Statement   * mFirst;
423    Statement   * mLast;   
424};
425
426}
427
428#endif // PE_PabloAST_H
429
430
431
Note: See TracBrowser for help on using the repository browser.