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

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

Work on better scheduling in reassociation pass.

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