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

Last change on this file since 4388 was 4358, checked in by cameron, 4 years ago

Clean up various minor issues that generate compiler warnings.

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