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

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

Initial stages of a simple boolean equation reassociation pass.

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