source: icGREP/icgrep-devel/icgrep/pablo/codegenstate.cpp @ 4899

Last change on this file since 4899 was 4896, checked in by nmedfort, 3 years ago

Work on coalescing algorithm + minor changes.

File size: 21.8 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#include <pablo/codegenstate.h>
8#include <iostream>
9#include <pablo/printer_pablos.h>
10
11namespace pablo {
12
13Zeroes PabloBlock::mZeroes;
14
15Ones PabloBlock::mOnes;
16
17inline PabloAST * PabloBlock::renameNonNamedNode(PabloAST * expr, const std::string && prefix) {
18    if (Statement * stmt = dyn_cast<Statement>(expr)) {
19        if (stmt->getName()->isGenerated()) {
20            stmt->setName(makeName(prefix, false));
21        }
22    }
23    return expr;
24}
25
26void PabloBlock::insert(Statement * const statement) {
27    assert (statement);
28    if (LLVM_UNLIKELY(mInsertionPoint == nullptr)) {
29        if (mFirst) {
30            statement->insertBefore(mFirst);
31        } else {
32            statement->removeFromParent();
33            statement->mParent = this;
34            mFirst = mLast = statement;
35        }
36    } else if (LLVM_LIKELY(statement != mInsertionPoint)) {
37        statement->insertAfter(mInsertionPoint);
38        mLast = (mLast == mInsertionPoint) ? statement : mLast;
39        assert (statement->mPrev == mInsertionPoint);
40    }
41    mInsertionPoint = statement;
42}
43
44/// UNARY CREATE FUNCTIONS
45
46Assign * PabloBlock::createAssign(const std::string && prefix, PabloAST * expr)  {
47    return insertAtInsertionPoint(new Assign(expr, makeName(prefix, false)));
48}
49
50PabloAST * PabloBlock::createAdvance(PabloAST * expr, PabloAST * shiftAmount) {
51    if (isa<Zeroes>(expr) || cast<Integer>(shiftAmount)->value() == 0) {
52        return expr;
53    }
54    return insertAtInsertionPoint(new Advance(expr, shiftAmount, makeName("advance")));
55}
56
57PabloAST * PabloBlock::createAdvance(PabloAST * expr, PabloAST * shiftAmount, const std::string prefix) {
58    if (isa<Zeroes>(expr) || cast<Integer>(shiftAmount)->value() == 0) {
59        return expr;
60    }
61    return insertAtInsertionPoint(new Advance(expr, shiftAmount, makeName(prefix, false)));
62}
63
64PabloAST * PabloBlock::createAdvance(PabloAST * expr, const Integer::Type shiftAmount) {
65    if (isa<Zeroes>(expr) || shiftAmount == 0) {
66        return expr;
67    }
68    return insertAtInsertionPoint(new Advance(expr, getInteger(shiftAmount), makeName("advance")));
69}
70
71PabloAST * PabloBlock::createAdvance(PabloAST * expr, const Integer::Type shiftAmount, const std::string prefix) {
72    if (isa<Zeroes>(expr) || shiftAmount == 0) {
73        return renameNonNamedNode(expr, std::move(prefix));
74    }   
75    return insertAtInsertionPoint(new Advance(expr, getInteger(shiftAmount), makeName(prefix, false)));
76}
77
78Call * PabloBlock::createCall(PabloAST * prototype, const std::vector<PabloAST *> &) {
79    assert (prototype);
80    return insertAtInsertionPoint(new Call(prototype));
81}
82
83
84PabloAST * PabloBlock::createNot(PabloAST * expr) {
85    assert (expr);
86    if (isa<Ones>(expr)) {
87        return createZeroes();
88    }
89    else if (isa<Zeroes>(expr)){
90        return createOnes();
91    }
92    else if (Not * not1 = dyn_cast<Not>(expr)) {
93        return not1->getOperand(0);
94    }
95    return insertAtInsertionPoint(new Not(expr, makeName("not_")));
96}
97
98PabloAST * PabloBlock::createNot(PabloAST * expr, const std::string prefix) {
99    assert (expr);
100    if (isa<Ones>(expr)) {
101        return createZeroes();
102    }
103    else if (isa<Zeroes>(expr)){
104        return createOnes();
105    }
106    else if (Not * not1 = dyn_cast<Not>(expr)) {       
107        return renameNonNamedNode(not1->getOperand(0), std::move(prefix));
108    }
109    return insertAtInsertionPoint(new Not(expr, makeName(prefix, false)));
110}
111
112Var * PabloBlock::createVar(PabloAST * name) {
113    assert (name);
114    return new Var(name);
115}
116
117PabloAST * PabloBlock::createMod64Advance(PabloAST * expr, PabloAST * shiftAmount) {
118    if (isa<Zeroes>(expr) || cast<Integer>(shiftAmount)->value() == 0) {
119        return expr;
120    }
121    return insertAtInsertionPoint(new Mod64Advance(expr, shiftAmount, makeName("advance")));
122}
123
124PabloAST * PabloBlock::createMod64Advance(PabloAST * expr, PabloAST * shiftAmount, const std::string prefix) {
125    if (isa<Zeroes>(expr) || cast<Integer>(shiftAmount)->value() == 0) {
126        return expr;
127    }
128    return insertAtInsertionPoint(new Mod64Advance(expr, shiftAmount, makeName(prefix, false)));
129}
130
131PabloAST * PabloBlock::createMod64Advance(PabloAST * expr, const Integer::Type shiftAmount) {
132    if (isa<Zeroes>(expr) || shiftAmount == 0) {
133        return expr;
134    }
135    return insertAtInsertionPoint(new Mod64Advance(expr, getInteger(shiftAmount), makeName("advance")));
136}
137
138PabloAST * PabloBlock::createMod64Advance(PabloAST * expr, const Integer::Type shiftAmount, const std::string prefix) {
139    if (isa<Zeroes>(expr) || shiftAmount == 0) {
140        return renameNonNamedNode(expr, std::move(prefix));
141    }   
142    return insertAtInsertionPoint(new Mod64Advance(expr, getInteger(shiftAmount), makeName(prefix, false)));
143}
144
145PabloAST * PabloBlock::createCount(PabloAST * expr) {
146    assert (expr);
147    return insertAtInsertionPoint(new Count(expr, makeName("count_")));
148}
149
150PabloAST * PabloBlock::createCount(PabloAST * expr, const std::string prefix) {
151    assert (expr);
152    return insertAtInsertionPoint(new Count(expr, makeName(prefix, false)));
153}
154
155   
156/// BINARY CREATE FUNCTIONS
157
158Next * PabloBlock::createNext(Assign * assign, PabloAST * expr) {
159    assert (assign && expr);
160    return insertAtInsertionPoint(new Next(assign, expr));
161}
162
163PabloAST * PabloBlock::createMatchStar(PabloAST * marker, PabloAST * charclass) {
164    assert (marker && charclass);
165    if (isa<Zeroes>(marker) || isa<Zeroes>(charclass)) {
166        return marker;
167    }
168    return insertAtInsertionPoint(new MatchStar(marker, charclass, makeName("matchstar")));
169}
170
171PabloAST * PabloBlock::createMatchStar(PabloAST * marker, PabloAST * charclass, const std::string prefix) {
172    assert (marker && charclass);
173    if (isa<Zeroes>(marker) || isa<Zeroes>(charclass)) {
174        return renameNonNamedNode(marker, std::move(prefix));
175    }
176    return insertAtInsertionPoint(new MatchStar(marker, charclass, makeName(prefix, false)));
177}
178
179PabloAST * PabloBlock::createScanThru(PabloAST * from, PabloAST * thru) {
180    assert (from && thru);
181    if (isa<Zeroes>(from) || isa<Zeroes>(thru)) {
182        return from;
183    }
184    return insertAtInsertionPoint(new ScanThru(from, thru, makeName("scanthru")));
185}
186
187PabloAST * PabloBlock::createScanThru(PabloAST * from, PabloAST * thru, const std::string prefix) {
188    assert (from && thru);
189    if (isa<Zeroes>(from) || isa<Zeroes>(thru)) {       
190        return renameNonNamedNode(from, std::move(prefix));
191    }
192    return insertAtInsertionPoint(new ScanThru(from, thru, makeName(prefix, false)));
193}
194
195PabloAST * PabloBlock::createMod64MatchStar(PabloAST * marker, PabloAST * charclass) {
196    assert (marker && charclass);
197    if (isa<Zeroes>(marker) || isa<Zeroes>(charclass)) {
198        return marker;
199    }
200    return insertAtInsertionPoint(new Mod64MatchStar(marker, charclass, makeName("matchstar")));
201}
202
203PabloAST * PabloBlock::createMod64MatchStar(PabloAST * marker, PabloAST * charclass, const std::string prefix) {
204    assert (marker && charclass);
205    if (isa<Zeroes>(marker) || isa<Zeroes>(charclass)) {
206        return renameNonNamedNode(marker, std::move(prefix));
207    }
208    return insertAtInsertionPoint(new Mod64MatchStar(marker, charclass, makeName(prefix, false)));
209}
210
211PabloAST * PabloBlock::createMod64ScanThru(PabloAST * from, PabloAST * thru) {
212    assert (from && thru);
213    if (isa<Zeroes>(from) || isa<Zeroes>(thru)) {
214        return from;
215    }
216    return insertAtInsertionPoint(new Mod64ScanThru(from, thru, makeName("scanthru")));
217}
218
219PabloAST * PabloBlock::createMod64ScanThru(PabloAST * from, PabloAST * thru, const std::string prefix) {
220    assert (from && thru);
221    if (isa<Zeroes>(from) || isa<Zeroes>(thru)) {       
222        return renameNonNamedNode(from, std::move(prefix));
223    }
224    return insertAtInsertionPoint(new Mod64ScanThru(from, thru, makeName(prefix, false)));
225}
226
227template<typename Type>
228static inline Type * isBinary(PabloAST * expr) {
229    if (isa<Type>(expr) && cast<Type>(expr)->getNumOperands() == 2) {
230        return cast<Type>(expr);
231    }
232    return nullptr;
233}
234
235PabloAST * PabloBlock::createAnd(PabloAST * expr1, PabloAST * expr2) {
236    assert (expr1 && expr2);
237    if (isa<Zeroes>(expr2) || isa<Ones>(expr1)) {
238        return expr2;
239    } else if (isa<Zeroes>(expr1) || isa<Ones>(expr2) || equals(expr1, expr2)){
240        return expr1;
241    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
242        if (Not * not2 = dyn_cast<Not>(expr2)) {
243            return createNot(createOr(not1->getOperand(0), not2->getOperand(0)));
244        } else if (equals(not1->getOperand(0), expr2)) {
245            return createZeroes();
246        }
247    } else if (Not * not2 = dyn_cast<Not>(expr2)) {
248        if (equals(expr1, not2->getOperand(0))) {
249            return createZeroes();
250        }
251    } else if (Or * or1 = isBinary<Or>(expr1)) {
252        if (equals(or1->getOperand(0), expr2) || equals(or1->getOperand(1), expr2)) {
253            return expr2;
254        }
255    } else if (Or * or2 = isBinary<Or>(expr2)) {
256        if (equals(or2->getOperand(0), expr1) || equals(or2->getOperand(1), expr1)) {
257            return expr1;
258        }
259    }
260    return insertAtInsertionPoint(new And(expr1, expr2, makeName("and_")));
261}
262
263PabloAST * PabloBlock::createAnd(PabloAST * expr1, PabloAST * expr2, const std::string prefix) {
264    assert (expr1 && expr2);
265    if (isa<Zeroes>(expr2) || isa<Ones>(expr1)) {
266        return renameNonNamedNode(expr2, std::move(prefix));
267    }
268    else if (isa<Zeroes>(expr1) || isa<Ones>(expr2) || equals(expr1, expr2)){
269        return renameNonNamedNode(expr1, std::move(prefix));
270    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
271        if (Not * not2 = dyn_cast<Not>(expr2)) {
272            return createNot(createOr(not1->getOperand(0), not2->getOperand(0)), prefix);
273        }
274        else if (equals(not1->getOperand(0), expr2)) {
275            return createZeroes();
276        }
277    } else if (Not * not2 = dyn_cast<Not>(expr2)) {
278        if (equals(expr1, not2->getOperand(0))) {
279            return createZeroes();
280        }
281    } else if (Or * or1 = isBinary<Or>(expr1)) {
282        if (equals(or1->getOperand(0), expr2) || equals(or1->getOperand(1), expr2)) {
283            return expr2;
284        }
285    } else if (Or * or2 = isBinary<Or>(expr2)) {
286        if (equals(or2->getOperand(0), expr1) || equals(or2->getOperand(1), expr1)) {
287            return expr1;
288        }
289    }
290    return insertAtInsertionPoint(new And(expr1, expr2, makeName(prefix, false)));
291}
292
293And * PabloBlock::createAnd(const unsigned reserved) {
294    return insertAtInsertionPoint(new And(reserved, makeName("and_")));
295}
296
297And * PabloBlock::createAnd(const unsigned reserved, const std::string prefix) {
298    return insertAtInsertionPoint(new And(reserved, makeName(prefix, false)));
299}
300
301PabloAST * PabloBlock::createOr(PabloAST * expr1, PabloAST * expr2) {
302    assert (expr1 && expr2);
303    if (isa<Zeroes>(expr1) || isa<Ones>(expr2)){
304        return expr2;
305    }
306    if (isa<Zeroes>(expr2) || isa<Ones>(expr1) || equals(expr1, expr2)) {
307        return expr1;
308    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
309        // ¬a√b = ¬¬(¬a √ b) = ¬(a ∧ ¬b)
310        return createNot(createAnd(not1->getOperand(0), createNot(expr2)));
311    } else if (Not * not2 = dyn_cast<Not>(expr2)) {
312        // a√¬b = ¬¬(¬b √ a) = ¬(b ∧ ¬a)
313        return createNot(createAnd(not2->getOperand(0), createNot(expr1)));
314    } else if (equals(expr1, expr2)) {
315        return expr1;
316    } else if (And * and1 = isBinary<And>(expr1)) {
317        if (And * and2 = isBinary<And>(expr2)) {
318            PabloAST * const expr1a = and1->getOperand(0);
319            PabloAST * const expr1b = and1->getOperand(1);
320            PabloAST * const expr2a = and2->getOperand(0);
321            PabloAST * const expr2b = and2->getOperand(1);
322            //These optimizations factor out common components that can occur when sets are formed by union
323            //(e.g., union of [a-z] and [A-Z].
324            if (equals(expr1a, expr2a)) {
325                return createAnd(expr1a, createOr(expr1b, expr2b));
326            } else if (equals(expr1b, expr2b)) {
327                return createAnd(expr1b, createOr(expr1a, expr2a));
328            } else if (equals(expr1a, expr2b)) {
329                return createAnd(expr1a, createOr(expr1b, expr2a));
330            } else if (equals(expr1b, expr2a)) {
331                return createAnd(expr1b, createOr(expr1a, expr2b));
332            }
333        } else if (equals(and1->getOperand(0), expr2) || equals(and1->getOperand(1), expr2)) {
334            // (a ∧ b) √ a = a
335            return expr2;
336        }
337    } else if (And * and2 = isBinary<And>(expr2)) {
338        if (equals(and2->getOperand(0), expr1) || equals(and2->getOperand(1), expr1)) {
339            return expr1;
340        }
341    }
342    return insertAtInsertionPoint(new Or(expr1, expr2, makeName("or_")));
343}
344
345PabloAST * PabloBlock::createOr(PabloAST * expr1, PabloAST * expr2, const std::string prefix) {
346    assert (expr1 && expr2);
347    if (isa<Zeroes>(expr1) || isa<Ones>(expr2)){
348        return renameNonNamedNode(expr2, std::move(prefix));
349    }
350    else if (isa<Zeroes>(expr2) || isa<Ones>(expr1) || equals(expr1, expr2)) {
351        return renameNonNamedNode(expr1, std::move(prefix));
352    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
353        // ¬a√b = ¬¬(¬a√b) = ¬(a ∧ ¬b)
354        return createNot(createAnd(not1->getOperand(0), createNot(expr2)), prefix);
355    } else if (Not * not2 = dyn_cast<Not>(expr2)) {
356        // a√¬b = ¬¬(¬b√a) = ¬(b ∧ ¬a)
357        return createNot(createAnd(not2->getOperand(0), createNot(expr1)), prefix);
358    } else if (And * and1 = isBinary<And>(expr1)) {
359        if (And * and2 = isBinary<And>(expr2)) {
360            PabloAST * const expr1a = and1->getOperand(0);
361            PabloAST * const expr1b = and1->getOperand(1);
362            PabloAST * const expr2a = and2->getOperand(0);
363            PabloAST * const expr2b = and2->getOperand(1);
364            //These optimizations factor out common components that can occur when sets are formed by union
365            //(e.g., union of [a-z] and [A-Z].
366            if (equals(expr1a, expr2a)) {
367                return createAnd(expr1a, createOr(expr1b, expr2b), prefix);
368            } else if (equals(expr1b, expr2b)) {
369                return createAnd(expr1b, createOr(expr1a, expr2a), prefix);
370            } else if (equals(expr1a, expr2b)) {
371                return createAnd(expr1a, createOr(expr1b, expr2a), prefix);
372            } else if (equals(expr1b, expr2a)) {
373                return createAnd(expr1b, createOr(expr1a, expr2b), prefix);
374            }
375        } else if (equals(and1->getOperand(0), expr2) || equals(and1->getOperand(1), expr2)) {
376            // (a∧b) √ a = a
377            return expr2;
378        }
379    } else if (And * and2 = isBinary<And>(expr2)) {
380        if (equals(and2->getOperand(0), expr1) || equals(and2->getOperand(1), expr1)) {
381            return expr1;
382        }
383    }
384    return insertAtInsertionPoint(new Or(expr1, expr2, makeName(prefix, false)));
385}
386
387Or * PabloBlock::createOr(const unsigned reserved) {
388    return insertAtInsertionPoint(new Or(reserved, makeName("or_")));
389}
390
391Or * PabloBlock::createOr(const unsigned reserved, const std::string prefix) {
392    return insertAtInsertionPoint(new Or(reserved, makeName(prefix, false)));
393}
394
395PabloAST * PabloBlock::createXor(PabloAST * expr1, PabloAST * expr2) {
396    assert (expr1 && expr2);
397    if (expr1 == expr2) {
398        return PabloBlock::createZeroes();
399    }
400    if (isa<Ones>(expr1)) {
401        return createNot(expr2);
402    } else if (isa<Zeroes>(expr1)){
403        return expr2;
404    } else if (isa<Ones>(expr2)) {
405        return createNot(expr1);
406    } else if (isa<Zeroes>(expr2)){
407        return expr1;
408    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
409        if (Not * not2 = dyn_cast<Not>(expr2)) {
410            return createXor(not1->getOperand(0), not2->getOperand(0));
411        }
412    }
413    return insertAtInsertionPoint(new Xor(expr1, expr2, makeName("xor_")));
414}
415
416PabloAST * PabloBlock::createXor(PabloAST * expr1, PabloAST * expr2, const std::string prefix) {
417    assert (expr1 && expr2);
418    if (expr1 == expr2) {
419        return PabloBlock::createZeroes();
420    }
421    if (isa<Ones>(expr1)) {
422        return createNot(expr2, prefix);
423    } else if (isa<Zeroes>(expr1)){
424        return expr2;
425    } else if (isa<Ones>(expr2)) {
426        return createNot(expr1, prefix);
427    } else if (isa<Zeroes>(expr2)){
428        return expr1;
429    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
430        if (Not * not2 = dyn_cast<Not>(expr2)) {
431            return createXor(not1->getOperand(0), not2->getOperand(0), prefix);
432        }
433    }
434    return insertAtInsertionPoint(new Xor(expr1, expr2, makeName(prefix, false)));
435}
436
437Xor * PabloBlock::createXor(const unsigned reserved) {
438    return insertAtInsertionPoint(new Xor(reserved, makeName("xor_")));
439}
440
441Xor * PabloBlock::createXor(const unsigned reserved, const std::string prefix) {
442    return insertAtInsertionPoint(new Xor(reserved, makeName(prefix, false)));
443}
444
445/// TERNARY CREATE FUNCTION
446
447PabloAST * PabloBlock::createSel(PabloAST * condition, PabloAST * trueExpr, PabloAST * falseExpr) {
448    assert (condition && trueExpr && falseExpr);
449    if (isa<Ones>(condition)) {
450        return trueExpr;
451    } else if (isa<Zeroes>(condition)){
452        return falseExpr;
453    } else if (isa<Ones>(trueExpr)) {
454        return createOr(condition, falseExpr);
455    } else if (isa<Zeroes>(trueExpr)){
456        return createAnd(createNot(condition), falseExpr);
457    } else if (isa<Ones>(falseExpr)) {
458        return createOr(createNot(condition), trueExpr);
459    } else if (isa<Zeroes>(falseExpr)){
460        return createAnd(condition, trueExpr);
461    } else if (equals(trueExpr, falseExpr)) {
462        return trueExpr;
463    } else if (isa<Not>(trueExpr) && equals(cast<Not>(trueExpr)->getOperand(0), falseExpr)) {
464        return createXor(condition, falseExpr);
465    } else if (isa<Not>(falseExpr) && equals(trueExpr, cast<Not>(falseExpr)->getOperand(0))){
466        return createXor(condition, trueExpr);
467    }
468    return insertAtInsertionPoint(new Sel(condition, trueExpr, falseExpr, makeName("sel")));
469}
470
471PabloAST * PabloBlock::createSel(PabloAST * condition, PabloAST * trueExpr, PabloAST * falseExpr, const std::string prefix) {
472    assert (condition && trueExpr && falseExpr);
473    if (isa<Zeroes>(condition)){
474        return renameNonNamedNode(falseExpr, std::move(prefix));
475    }
476    else if (isa<Ones>(condition) || equals(trueExpr, falseExpr)) {
477        return renameNonNamedNode(trueExpr, std::move(prefix));
478    }
479    else if (isa<Ones>(trueExpr)) {
480        return createOr(condition, falseExpr, prefix);
481    }
482    else if (isa<Zeroes>(trueExpr)){
483        return createAnd(createNot(condition), falseExpr, prefix);
484    }
485    else if (isa<Ones>(falseExpr)) {
486        return createOr(createNot(condition), trueExpr, prefix);
487    }
488    else if (isa<Zeroes>(falseExpr)){
489        return createAnd(condition, trueExpr, prefix);
490    }
491    else if (isa<Not>(trueExpr) && equals(cast<Not>(trueExpr)->getOperand(0), falseExpr)) {
492        return createXor(condition, falseExpr, prefix);
493    }
494    else if (isa<Not>(falseExpr) && equals(trueExpr, cast<Not>(falseExpr)->getOperand(0))){
495        return createXor(condition, trueExpr, prefix);
496    }
497    return insertAtInsertionPoint(new Sel(condition, trueExpr, falseExpr, makeName(prefix, false)));
498}
499
500If * PabloBlock::createIf(PabloAST * condition, const std::initializer_list<Assign *> definedVars, PabloBlock * body) {
501    assert (condition);
502    return insertAtInsertionPoint(new If(condition, definedVars, body));
503}
504
505If * PabloBlock::createIf(PabloAST * condition, const std::vector<Assign *> & definedVars, PabloBlock * body) {
506    assert (condition);
507    return insertAtInsertionPoint(new If(condition, definedVars, body));
508}
509
510If * PabloBlock::createIf(PabloAST * condition, std::vector<Assign *> && definedVars, PabloBlock * body) {
511    assert (condition);
512    return insertAtInsertionPoint(new If(condition, definedVars, body));
513}
514
515While * PabloBlock::createWhile(PabloAST * condition, const std::initializer_list<Next *> nextVars, PabloBlock * body) {
516    assert (condition);
517    return insertAtInsertionPoint(new While(condition, nextVars, body));
518}
519
520While * PabloBlock::createWhile(PabloAST * condition, const std::vector<Next *> & nextVars, PabloBlock * body) {
521    assert (condition);
522    return insertAtInsertionPoint(new While(condition, nextVars, body));
523}
524
525While * PabloBlock::createWhile(PabloAST * condition, std::vector<Next *> && nextVars, PabloBlock * body) {
526    assert (condition);
527    return insertAtInsertionPoint(new While(condition, nextVars, body));
528}
529
530/** ------------------------------------------------------------------------------------------------------------- *
531 * @brief eraseFromParent
532 ** ------------------------------------------------------------------------------------------------------------- */
533void PabloBlock::eraseFromParent(const bool recursively) {
534    Statement * stmt = front();
535    // Note: by erasing the scope block, any Assign/Next nodes will be replaced with Zero and removed from
536    // the If/While node
537    while (stmt) {
538        stmt = stmt->eraseFromParent(recursively);
539    }
540    mAllocator.deallocate(reinterpret_cast<Allocator::pointer>(this));
541}
542
543
544// Assign sequential scope indexes, returning the next unassigned index   
545
546unsigned PabloBlock::enumerateScopes(unsigned baseScopeIndex) {
547    mScopeIndex = baseScopeIndex;
548    unsigned nextScopeIndex = baseScopeIndex + 1;
549    for (Statement * stmt : *this) {
550        if (If * ifStatement = dyn_cast<If>(stmt)) {
551            nextScopeIndex = ifStatement->getBody()->enumerateScopes(nextScopeIndex);
552        }
553        else if (While * whileStatement = dyn_cast<While>(stmt)) {
554            nextScopeIndex = whileStatement->getBody()->enumerateScopes(nextScopeIndex);
555        }
556    }
557    return nextScopeIndex;
558}   
559   
560/// CONSTRUCTOR
561
562PabloBlock::PabloBlock(SymbolGenerator * symbolGenerator) noexcept
563: PabloAST(PabloAST::ClassTypeId::Block)
564, mSymbolGenerator(symbolGenerator)
565, mParent(nullptr)
566, mBranch(nullptr)
567, mScopeIndex(0)
568{
569
570}
571
572PabloBlock::~PabloBlock() {
573
574}
575
576}
Note: See TracBrowser for help on using the repository browser.