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

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

Remove mod64 junk

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