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

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

Progress on multi-target UCD compiler.

File size: 20.5 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
[4797]11Zeroes PabloBlock::mZeroes;
[4788]12
[4797]13Ones PabloBlock::mOnes;
[4788]14
[4438]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
[4650]24void PabloBlock::insert(Statement * const statement) {
25    assert (statement);
26    if (LLVM_UNLIKELY(mInsertionPoint == nullptr)) {
27        if (mFirst) {
28            statement->insertBefore(mFirst);
29        }
30        else {
31            statement->removeFromParent();
32            statement->mParent = this;
33            mFirst = mLast = statement;
34        }
35    }
[4761]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
[4657]46Assign * PabloBlock::createAssign(const std::string && prefix, PabloAST * expr)  {
47    return insertAtInsertionPoint(new Assign(expr, makeName(prefix, false)));
[4416]48}
49
[4432]50PabloAST * PabloBlock::createAdvance(PabloAST * expr, PabloAST * shiftAmount) {
51    if (isa<Zeroes>(expr) || cast<Integer>(shiftAmount)->value() == 0) {
[4257]52        return expr;
53    }
[4650]54    return insertAtInsertionPoint(new Advance(expr, shiftAmount, makeName("advance")));
[4213]55}
56
[4438]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    }
[4650]61    return insertAtInsertionPoint(new Advance(expr, shiftAmount, makeName(prefix, false)));
[4438]62}
63
[4699]64PabloAST * PabloBlock::createAdvance(PabloAST * expr, const Integer::Type shiftAmount) {
[4432]65    if (isa<Zeroes>(expr) || shiftAmount == 0) {
66        return expr;
[4438]67    }
[4650]68    return insertAtInsertionPoint(new Advance(expr, getInteger(shiftAmount), makeName("advance")));
[4438]69}
70
[4699]71PabloAST * PabloBlock::createAdvance(PabloAST * expr, const Integer::Type shiftAmount, const std::string prefix) {
[4438]72    if (isa<Zeroes>(expr) || shiftAmount == 0) {
73        return renameNonNamedNode(expr, std::move(prefix));
[4432]74    }   
[4650]75    return insertAtInsertionPoint(new Advance(expr, getInteger(shiftAmount), makeName(prefix, false)));
[4213]76}
77
[4692]78Call * PabloBlock::createCall(PabloAST * prototype, const std::vector<PabloAST *> &) {
[4680]79    assert (prototype);
80    return insertAtInsertionPoint(new Call(prototype));
[4415]81}
82
[4692]83
[4244]84PabloAST * PabloBlock::createNot(PabloAST * expr) {
[4433]85    assert (expr);
[4419]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->getExpr();
94    }
[4650]95    return insertAtInsertionPoint(new Not(expr, makeName("not_")));
[4213]96}
97
[4438]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->getExpr(), std::move(prefix));
108    }
[4650]109    return insertAtInsertionPoint(new Not(expr, makeName(prefix, false)));
[4438]110}
111
[4602]112Var * PabloBlock::createVar(PabloAST * name) {
[4433]113    assert (name);
[4650]114    return new Var(name);
[4415]115}
116
[4717]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
[4718]145PabloAST * PabloBlock::createCount(PabloAST * expr) {
146    assert (expr);
147    return insertAtInsertionPoint(new Count(expr, makeName("count_")));
148}
[4717]149
[4718]150PabloAST * PabloBlock::createCount(PabloAST * expr, const std::string prefix) {
151    assert (expr);
152    return insertAtInsertionPoint(new Count(expr, makeName(prefix, false)));
153}
154
155   
[4214]156/// BINARY CREATE FUNCTIONS
157
[4252]158Next * PabloBlock::createNext(Assign * assign, PabloAST * expr) {
[4433]159    assert (assign && expr);
[4650]160    return insertAtInsertionPoint(new Next(assign, expr));
[4252]161}
162
[4255]163PabloAST * PabloBlock::createMatchStar(PabloAST * marker, PabloAST * charclass) {
[4433]164    assert (marker && charclass);
[4257]165    if (isa<Zeroes>(marker) || isa<Zeroes>(charclass)) {
166        return marker;
167    }
[4650]168    return insertAtInsertionPoint(new MatchStar(marker, charclass, makeName("matchstar")));
[4252]169}
170
[4438]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    }
[4650]176    return insertAtInsertionPoint(new MatchStar(marker, charclass, makeName(prefix, false)));
[4438]177}
178
[4255]179PabloAST * PabloBlock::createScanThru(PabloAST * from, PabloAST * thru) {
[4433]180    assert (from && thru);
[4257]181    if (isa<Zeroes>(from) || isa<Zeroes>(thru)) {
182        return from;
183    }
[4650]184    return insertAtInsertionPoint(new ScanThru(from, thru, makeName("scanthru")));
[4252]185}
186
[4438]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    }
[4650]192    return insertAtInsertionPoint(new ScanThru(from, thru, makeName(prefix, false)));
[4438]193}
194
[4717]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
[4244]227PabloAST * PabloBlock::createAnd(PabloAST * expr1, PabloAST * expr2) {
[4433]228    assert (expr1 && expr2);
[4419]229    if (isa<Zeroes>(expr2) || isa<Ones>(expr1)) {
230        return expr2;
[4736]231    } else if (isa<Zeroes>(expr1) || isa<Ones>(expr2) || equals(expr1, expr2)){
[4419]232        return expr1;
[4736]233    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
[4419]234        if (Not * not2 = dyn_cast<Not>(expr2)) {
235            return createNot(createOr(not1->getExpr(), not2->getExpr()));
[4736]236        } else if (equals(not1->getExpr(), expr2)) {
[4419]237            return createZeroes();
238        }
[4736]239    } else if (Not * not2 = dyn_cast<Not>(expr2)) {
[4419]240        if (equals(expr1, not2->getExpr())) {
241            return createZeroes();
242        }
[4736]243    } else if (Or * or1 = dyn_cast<Or>(expr1)) {
244        if (equals(or1->getExpr1(), expr2) || equals(or1->getExpr2(), expr2)) {
245            return expr2;
246        }
247    } else if (Or * or2 = dyn_cast<Or>(expr2)) {
248        if (equals(or2->getExpr1(), expr1) || equals(or2->getExpr2(), expr1)) {
249            return expr1;
250        }
[4419]251    }
[4692]252    if (isa<Not>(expr1) || expr1 > expr2) {
[4214]253        std::swap(expr1, expr2);
254    }
[4650]255    return insertAtInsertionPoint(new And(expr1, expr2, makeName("and_")));
[4410]256}
257
[4438]258PabloAST * PabloBlock::createAnd(PabloAST * expr1, PabloAST * expr2, const std::string prefix) {
[4433]259    assert (expr1 && expr2);
[4419]260    if (isa<Zeroes>(expr2) || isa<Ones>(expr1)) {
[4438]261        return renameNonNamedNode(expr2, std::move(prefix));
[4736]262    } else if (isa<Zeroes>(expr1) || isa<Ones>(expr2) || equals(expr1, expr2)){
[4438]263        return renameNonNamedNode(expr1, std::move(prefix));
[4736]264    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
[4438]265        if (Not * not2 = dyn_cast<Not>(expr2)) {
266            return createNot(createOr(not1->getExpr(), not2->getExpr()), prefix);
267        }
268        else if (equals(not1->getExpr(), expr2)) {
269            return createZeroes();
270        }
[4736]271    } else if (Not * not2 = dyn_cast<Not>(expr2)) {
[4438]272        if (equals(expr1, not2->getExpr())) {
273            return createZeroes();
274        }
[4736]275    } else if (Or * or1 = dyn_cast<Or>(expr1)) {
276        if (equals(or1->getExpr1(), expr2) || equals(or1->getExpr2(), expr2)) {
277            return expr2;
278        }
279    } else if (Or * or2 = dyn_cast<Or>(expr2)) {
280        if (equals(or2->getExpr1(), expr1) || equals(or2->getExpr2(), expr1)) {
281            return expr1;
282        }
[4438]283    }
[4692]284    if (isa<Not>(expr1) || expr1 > expr2) {
[4438]285        std::swap(expr1, expr2);
286    }
[4650]287    return insertAtInsertionPoint(new And(expr1, expr2, makeName(prefix, false)));
[4438]288}
289
290PabloAST * PabloBlock::createOr(PabloAST * expr1, PabloAST * expr2) {
291    assert (expr1 && expr2);
292    if (isa<Zeroes>(expr1) || isa<Ones>(expr2)){
[4419]293        return expr2;
294    }
[4438]295    if (isa<Zeroes>(expr2) || isa<Ones>(expr1) || equals(expr1, expr2)) {
[4419]296        return expr1;
[4736]297    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
[4419]298        // ¬a√b = ¬¬(¬a√b) = ¬(a ∧ ¬b)
299        return createNot(createAnd(not1->getExpr(), createNot(expr2)));
[4736]300    } else if (Not * not2 = dyn_cast<Not>(expr2)) {
[4419]301        // a√¬b = ¬¬(¬b√a) = ¬(b ∧ ¬a)
302        return createNot(createAnd(not2->getExpr(), createNot(expr1)));
[4736]303    } else if (equals(expr1, expr2)) {
[4419]304        return expr1;
[4736]305    } else if (And * and1 = dyn_cast<And>(expr1)) {
306        if (And * and2 = dyn_cast<And>(expr2)) {
307            PabloAST * const expr1a = and1->getExpr1();
308            PabloAST * const expr1b = and1->getExpr2();
309            PabloAST * const expr2a = and2->getExpr1();
310            PabloAST * const expr2b = and2->getExpr2();
[4419]311            //These optimizations factor out common components that can occur when sets are formed by union
312            //(e.g., union of [a-z] and [A-Z].
313            if (equals(expr1a, expr2a)) {
314                return createAnd(expr1a, createOr(expr1b, expr2b));
[4736]315            } else if (equals(expr1b, expr2b)) {
[4419]316                return createAnd(expr1b, createOr(expr1a, expr2a));
[4736]317            } else if (equals(expr1a, expr2b)) {
[4419]318                return createAnd(expr1a, createOr(expr1b, expr2a));
[4736]319            } else if (equals(expr1b, expr2a)) {
[4419]320                return createAnd(expr1b, createOr(expr1a, expr2b));
321            }
[4736]322        } else if (equals(and1->getExpr1(), expr2) || equals(and1->getExpr2(), expr2)){
323            // (a∧b) √ a = a
324            return expr2;
[4419]325        }
[4736]326    } else if (And * and2 = dyn_cast<And>(expr2)) {
327        if (equals(and2->getExpr1(), expr1) || equals(and2->getExpr2(), expr1)) {
328            return expr1;
329        }
[4419]330    }
[4692]331    if (expr1 > expr2) {
332        std::swap(expr1, expr2);
333    }
[4650]334    return insertAtInsertionPoint(new Or(expr1, expr2, makeName("or_")));
[4410]335}
336
[4438]337PabloAST * PabloBlock::createOr(PabloAST * expr1, PabloAST * expr2, const std::string prefix) {
338    assert (expr1 && expr2);
339    if (isa<Zeroes>(expr1) || isa<Ones>(expr2)){
340        return renameNonNamedNode(expr2, std::move(prefix));
[4797]341    } else if (isa<Zeroes>(expr2) || isa<Ones>(expr1) || equals(expr1, expr2)) {
[4438]342        return renameNonNamedNode(expr1, std::move(prefix));
[4797]343    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
[4438]344        // ¬a√b = ¬¬(¬a√b) = ¬(a ∧ ¬b)
345        return createNot(createAnd(not1->getExpr(), createNot(expr2)), prefix);
[4797]346    } else if (Not * not2 = dyn_cast<Not>(expr2)) {
[4438]347        // a√¬b = ¬¬(¬b√a) = ¬(b ∧ ¬a)
348        return createNot(createAnd(not2->getExpr(), createNot(expr1)), prefix);
[4797]349    } else if (And * and1 = dyn_cast<And>(expr1)) {
[4736]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);
[4797]359            } else if (equals(expr1b, expr2b)) {
[4438]360                return createAnd(expr1b, createOr(expr1a, expr2a), prefix);
[4797]361            } else if (equals(expr1a, expr2b)) {
[4438]362                return createAnd(expr1a, createOr(expr1b, expr2a), prefix);
[4797]363            } else if (equals(expr1b, expr2a)) {
[4438]364                return createAnd(expr1b, createOr(expr1a, expr2b), prefix);
365            }
[4736]366        } else if (equals(and1->getExpr1(), expr2) || equals(and1->getExpr2(), expr2)) {
367            // (a∧b) √ a = a
368            return expr2;
[4438]369        }
[4736]370    } else if (And * and2 = dyn_cast<And>(expr2)) {
371        if (equals(and2->getExpr1(), expr1) || equals(and2->getExpr2(), expr1)) {
372            return expr1;
373        }
[4438]374    }
[4692]375    if (expr1 > expr2) {
376        std::swap(expr1, expr2);
377    }
[4650]378    return insertAtInsertionPoint(new Or(expr1, expr2, makeName(prefix, false)));
[4438]379}
380
[4244]381PabloAST * PabloBlock::createXor(PabloAST * expr1, PabloAST * expr2) {
[4433]382    assert (expr1 && expr2);
[4797]383    if (expr1 == expr2) {
384        return PabloBlock::createZeroes();
385    }
[4419]386    if (isa<Ones>(expr1)) {
387        return createNot(expr2);
[4797]388    } else if (isa<Zeroes>(expr1)){
[4419]389        return expr2;
[4797]390    } else if (isa<Ones>(expr2)) {
[4419]391        return createNot(expr1);
[4797]392    } else if (isa<Zeroes>(expr2)){
[4419]393        return expr1;
[4797]394    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
[4419]395        if (Not * not2 = dyn_cast<Not>(expr2)) {
396            return createXor(not1->getExpr(), not2->getExpr());
397        }
398    }
[4692]399    if (expr1 > expr2) {
400        std::swap(expr1, expr2);
401    }
[4650]402    return insertAtInsertionPoint(new Xor(expr1, expr2, makeName("xor_")));
[4410]403}
404
[4438]405PabloAST * PabloBlock::createXor(PabloAST * expr1, PabloAST * expr2, const std::string prefix) {
406    assert (expr1 && expr2);
[4797]407    if (expr1 == expr2) {
408        return PabloBlock::createZeroes();
409    }
[4438]410    if (isa<Ones>(expr1)) {
411        return createNot(expr2, prefix);
[4797]412    } else if (isa<Zeroes>(expr1)){
[4438]413        return expr2;
[4797]414    } else if (isa<Ones>(expr2)) {
[4438]415        return createNot(expr1, prefix);
[4797]416    } else if (isa<Zeroes>(expr2)){
[4438]417        return expr1;
[4797]418    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
[4438]419        if (Not * not2 = dyn_cast<Not>(expr2)) {
420            return createXor(not1->getExpr(), not2->getExpr(), prefix);
421        }
422    }
[4692]423    if (expr1 > expr2) {
424        std::swap(expr1, expr2);
425    }
[4650]426    return insertAtInsertionPoint(new Xor(expr1, expr2, makeName(prefix, false)));
[4438]427}
428
[4214]429/// TERNARY CREATE FUNCTION
430
[4404]431PabloAST * PabloBlock::createSel(PabloAST * condition, PabloAST * trueExpr, PabloAST * falseExpr) {
[4433]432    assert (condition && trueExpr && falseExpr);
[4419]433    if (isa<Ones>(condition)) {
434        return trueExpr;
[4797]435    } else if (isa<Zeroes>(condition)){
[4419]436        return falseExpr;
[4797]437    } else if (isa<Ones>(trueExpr)) {
[4419]438        return createOr(condition, falseExpr);
[4797]439    } else if (isa<Zeroes>(trueExpr)){
[4419]440        return createAnd(createNot(condition), falseExpr);
[4797]441    } else if (isa<Ones>(falseExpr)) {
[4419]442        return createOr(createNot(condition), trueExpr);
[4797]443    } else if (isa<Zeroes>(falseExpr)){
[4419]444        return createAnd(condition, trueExpr);
[4797]445    } else if (equals(trueExpr, falseExpr)) {
[4419]446        return trueExpr;
[4797]447    } else if (isa<Not>(trueExpr) && equals(cast<Not>(trueExpr)->getExpr(), falseExpr)) {
[4419]448        return createXor(condition, falseExpr);
[4797]449    } else if (isa<Not>(falseExpr) && equals(trueExpr, cast<Not>(falseExpr)->getExpr())){
[4419]450        return createXor(condition, falseExpr);
451    }
[4650]452    return insertAtInsertionPoint(new Sel(condition, trueExpr, falseExpr, makeName("sel")));
[4410]453}
454
[4438]455PabloAST * PabloBlock::createSel(PabloAST * condition, PabloAST * trueExpr, PabloAST * falseExpr, const std::string prefix) {
456    assert (condition && trueExpr && falseExpr);
457
458    if (isa<Zeroes>(condition)){
459        return renameNonNamedNode(falseExpr, std::move(prefix));
460    }
461    else if (isa<Ones>(condition) || equals(trueExpr, falseExpr)) {
462        return renameNonNamedNode(trueExpr, std::move(prefix));
463    }
464    else if (isa<Ones>(trueExpr)) {
465        return createOr(condition, falseExpr, prefix);
466    }
467    else if (isa<Zeroes>(trueExpr)){
468        return createAnd(createNot(condition), falseExpr, prefix);
469    }
470    else if (isa<Ones>(falseExpr)) {
471        return createOr(createNot(condition), trueExpr, prefix);
472    }
473    else if (isa<Zeroes>(falseExpr)){
474        return createAnd(condition, trueExpr, prefix);
475    }
476    else if (isa<Not>(trueExpr) && equals(cast<Not>(trueExpr)->getExpr(), falseExpr)) {
477        return createXor(condition, falseExpr, prefix);
478    }
479    else if (isa<Not>(falseExpr) && equals(trueExpr, cast<Not>(falseExpr)->getExpr())){
480        return createXor(condition, falseExpr, prefix);
481    }
[4650]482    return insertAtInsertionPoint(new Sel(condition, trueExpr, falseExpr, makeName(prefix, false)));
[4438]483}
484
[4524]485If * PabloBlock::createIf(PabloAST * condition, const std::initializer_list<Assign *> definedVars, PabloBlock & body) {
[4433]486    assert (condition);
[4650]487    return insertAtInsertionPoint(new If(condition, definedVars, body));
[4416]488}
[4414]489
[4511]490If * PabloBlock::createIf(PabloAST * condition, const std::vector<Assign *> & definedVars, PabloBlock & body) {
491    assert (condition);
[4650]492    return insertAtInsertionPoint(new If(condition, definedVars, body));
[4511]493}
494
495If * PabloBlock::createIf(PabloAST * condition, std::vector<Assign *> && definedVars, PabloBlock & body) {
496    assert (condition);
[4650]497    return insertAtInsertionPoint(new If(condition, definedVars, body));
[4511]498}
499
[4641]500While * PabloBlock::createWhile(PabloAST * condition, const std::initializer_list<Next *> nextVars, PabloBlock & body) {
[4433]501    assert (condition);
[4650]502    return insertAtInsertionPoint(new While(condition, nextVars, body));
[4416]503}
[4414]504
[4641]505While * PabloBlock::createWhile(PabloAST * condition, const std::vector<Next *> & nextVars, PabloBlock & body) {
506    assert (condition);
[4650]507    return insertAtInsertionPoint(new While(condition, nextVars, body));
[4641]508}
509
510While * PabloBlock::createWhile(PabloAST * condition, std::vector<Next *> && nextVars, PabloBlock & body) {
511    assert (condition);
[4650]512    return insertAtInsertionPoint(new While(condition, nextVars, body));
[4641]513}
514
[4687]515// Assign sequential scope indexes, returning the next unassigned index   
516
517unsigned PabloBlock::enumerateScopes(unsigned baseScopeIndex) {
518    mScopeIndex = baseScopeIndex;
519    unsigned nextScopeIndex = baseScopeIndex + 1;
520    for (Statement * stmt : *this) {
521        if (If * ifStatement = dyn_cast<If>(stmt)) {
522            nextScopeIndex = ifStatement->getBody().enumerateScopes(nextScopeIndex);
523        }
524        else if (While * whileStatement = dyn_cast<While>(stmt)) {
525            nextScopeIndex = whileStatement->getBody().enumerateScopes(nextScopeIndex);
526        }
527    }
528    return nextScopeIndex;
529}   
530           
531   
532       
533   
[4416]534/// CONSTRUCTOR
[4414]535
[4510]536PabloBlock::PabloBlock(SymbolGenerator & symbolGenerator)
[4432]537: PabloAST(PabloAST::ClassTypeId::Block)
[4510]538, mSymbolGenerator(symbolGenerator)
[4521]539, mParent(nullptr)
[4687]540, mScopeIndex(0)
[4416]541{
[4414]542
[4416]543}
[4404]544
[4416]545PabloBlock::PabloBlock(PabloBlock * predecessor)
[4432]546: PabloAST(PabloAST::ClassTypeId::Block)
[4416]547, mSymbolGenerator(predecessor->mSymbolGenerator)
[4687]548, mParent(predecessor)
549, mScopeIndex(0)
550{
[4611]551
[4415]552}
[4404]553
[4432]554PabloBlock::~PabloBlock() {
[4510]555
[4214]556}
[4432]557
558}
Note: See TracBrowser for help on using the repository browser.