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

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

Minor changes towards maintaining UseDef? information.

File size: 10.3 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        , MatchStar
43        , Next
44        , Not
45        , Ones
46        , Or
47        , ScanThru
48        , Sel
49        , String
50        , Var
51        , While
52        , Xor
53        , Zeroes
54    };
55    inline ClassTypeId getClassTypeId() const {
56        return mClassTypeId;
57    }
58
59    void setMetadata(const std::string & name, PMDNode * node);
60
61    PMDNode * getMetadata(const std::string & name);
62
63    inline static void release_memory() {
64        mAllocator.release_memory();
65    }
66
67    void* operator new (std::size_t size) noexcept {
68        return mAllocator.allocate(size);
69    }
70protected:
71    inline PabloAST(const ClassTypeId id)
72    : mClassTypeId(id)
73    , mMetadataMap(nullptr)
74    {
75
76    }
77    inline void addUser(PabloAST * user) {
78        mUsers.insert(user);
79    }
80    inline void removeUser(PabloAST * user) {
81        mUsers.remove(user);
82    }
83    static Allocator        mAllocator;
84private:
85    const ClassTypeId       mClassTypeId;
86    SetVector<PabloAST *>   mUsers;
87    PMDNodeMap *            mMetadataMap;
88};
89
90bool equals(const PabloAST * expr1, const PabloAST *expr2);
91
92class StatementList;
93
94class String;
95
96class Statement : public PabloAST {
97    friend class StatementList;
98    friend class If;
99    friend class While;
100    friend class PabloBlock;
101public:
102    static inline bool classof(const PabloAST * e) {
103        switch (e->getClassTypeId()) {
104            case PabloAST::ClassTypeId::String:
105                return false;
106            default:
107                return true;
108        }
109    }
110    static inline bool classof(const Statement *) {
111        return true;
112    }
113    static inline bool classof(const void *) {
114        return false;
115    }
116
117    inline void replaceUsesOfWith(PabloAST * from, PabloAST * to) {
118        if (LLVM_UNLIKELY(from == to)) {
119            return;
120        }
121        for (unsigned i = 0, operands = getNumOperands(); i != operands; ++i) {
122            if (getOperand(i) == from) {
123                setOperand(i, to);
124            }
125        }
126    }
127
128    PabloAST * getOperand(const unsigned index) const {
129        assert (index < getNumOperands());
130        return mOperand[index];
131    }
132
133    unsigned getNumOperands() const {
134        return mOperand.size();
135    }
136
137    void setOperand(const unsigned index, PabloAST * value) {
138        assert (index < getNumOperands());
139        mOperand[index] = value;
140    }
141
142    void insertBefore(Statement * const statement);
143    void insertAfter(Statement * const statement);
144    void removeFromParent();
145    void replaceWith(Statement * const statement);
146
147    inline const String * getName() const {
148        return mName;
149    }
150    inline Statement * getNextNode() const {
151        return mNext;
152    }
153    inline Statement * getPrevNode() const {
154        return mPrev;
155    }
156    inline PabloBlock * getParent() const {
157        return mParent;
158    }
159protected:
160    Statement(const ClassTypeId id, std::vector<PabloAST *> && operands, const String * name, PabloBlock * parent)
161    : PabloAST(id)
162    , mName(name)
163    , mNext(nullptr)
164    , mPrev(nullptr)
165    , mParent(parent)
166    , mOperand(std::move(operands))
167    {
168        for (PabloAST * op : mOperand) {
169            op->addUser(this);
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    : mFirst(nullptr)
337    , mLast(nullptr)
338    {
339
340    }
341
342    StatementList(StatementList && other)
343    : mFirst(other.mFirst)
344    , mLast(other.mLast)
345    {
346        other.mFirst = nullptr;
347        other.mLast = nullptr;
348    }
349
350    iterator begin() {
351        return iterator(mFirst);
352    }
353
354    iterator end() {
355        return iterator(nullptr);
356    }
357
358    reverse_iterator rbegin() {
359        return reverse_iterator(mLast);
360    }
361
362    reverse_iterator rend() {
363        return reverse_iterator(nullptr);
364    }
365
366    const_iterator begin() const {
367        return const_iterator(mFirst);
368    }
369
370    const_iterator end() const {
371        return const_iterator(nullptr);
372    }
373
374    const_reverse_iterator rbegin() const {
375        return const_reverse_iterator(mLast);
376    }
377
378    const_reverse_iterator rend() const {
379        return const_reverse_iterator(nullptr);
380    }
381
382    const_iterator cbegin() const {
383        return const_iterator(mFirst);
384    }
385
386    const_iterator cend() const {
387        return const_iterator(nullptr);
388    }
389
390    const_reverse_iterator crbegin() const {
391        return const_reverse_iterator(mLast);
392    }
393
394    const_reverse_iterator crend() const {
395        return const_reverse_iterator(nullptr);
396    }
397
398    Statement * front() const {
399        return mFirst;
400    }
401
402    Statement * back() const {
403        return mLast;
404    }
405
406    void push_back(Statement * const statement);
407
408private:
409    Statement   * mFirst;
410    Statement   * mLast;
411};
412
413}
414
415#endif // PE_PabloAST_H
416
417
418
Note: See TracBrowser for help on using the repository browser.