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

Last change on this file since 4433 was 4433, checked in by nmedfort, 5 years ago

Possible fix for segfault issue. CC seems to be generating the same charclass multiple times.

File size: 7.7 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
[4214]11/// UNARY CREATE FUNCTIONS
12
[4416]13Assign * PabloBlock::createAssign(const std::string prefix, PabloAST * expr, const int outputIndex)  {
[4433]14    return insertAtInsertionPoint(new Assign(expr, outputIndex, makeName(prefix, false), this));
[4416]15}
16
[4432]17PabloAST * PabloBlock::createAdvance(PabloAST * expr, PabloAST * shiftAmount) {
18    if (isa<Zeroes>(expr) || cast<Integer>(shiftAmount)->value() == 0) {
[4257]19        return expr;
20    }
[4416]21    return insertAtInsertionPoint(new Advance(expr, shiftAmount, mSymbolGenerator, this));
[4213]22}
23
[4432]24PabloAST * PabloBlock::createAdvance(PabloAST * expr, const int shiftAmount) {
25    if (isa<Zeroes>(expr) || shiftAmount == 0) {
26        return expr;
27    }   
28    return insertAtInsertionPoint(new Advance(expr, mSymbolGenerator->getInteger(shiftAmount), mSymbolGenerator, this));
[4213]29}
30
[4415]31Call * PabloBlock::createCall(String * name) {
[4433]32    assert (name);
[4416]33    return insertAtInsertionPoint(new Call(name, this));
[4415]34}
35
[4244]36PabloAST * PabloBlock::createNot(PabloAST * expr) {
[4433]37    assert (expr);
[4419]38    if (isa<Ones>(expr)) {
39        return createZeroes();
40    }
41    else if (isa<Zeroes>(expr)){
42        return createOnes();
43    }
44    else if (Not * not1 = dyn_cast<Not>(expr)) {
45        return not1->getExpr();
46    }
[4416]47    return insertAtInsertionPoint(new Not(expr, this));
[4213]48}
49
[4415]50Var * PabloBlock::createVar(String * name) {
[4433]51    assert (name);
[4416]52    return insertAtInsertionPoint(new Var(name, this));
[4415]53}
54
[4214]55/// BINARY CREATE FUNCTIONS
56
[4252]57Next * PabloBlock::createNext(Assign * assign, PabloAST * expr) {
[4433]58    assert (assign && expr);
[4416]59    return insertAtInsertionPoint(new Next(assign, expr, this));
[4252]60}
61
[4255]62PabloAST * PabloBlock::createMatchStar(PabloAST * marker, PabloAST * charclass) {
[4433]63    assert (marker && charclass);
[4257]64    if (isa<Zeroes>(marker) || isa<Zeroes>(charclass)) {
65        return marker;
66    }
[4416]67    return insertAtInsertionPoint(new MatchStar(marker, charclass, mSymbolGenerator, this));
[4252]68}
69
[4255]70PabloAST * PabloBlock::createScanThru(PabloAST * from, PabloAST * thru) {
[4433]71    assert (from && thru);
[4257]72    if (isa<Zeroes>(from) || isa<Zeroes>(thru)) {
73        return from;
74    }
[4416]75    return insertAtInsertionPoint(new ScanThru(from, thru, mSymbolGenerator, this));
[4252]76}
77
[4244]78PabloAST * PabloBlock::createAnd(PabloAST * expr1, PabloAST * expr2) {
[4433]79    assert (expr1 && expr2);
[4419]80    if (isa<Zeroes>(expr2) || isa<Ones>(expr1)) {
81        return expr2;
82    }
83    else if (isa<Zeroes>(expr1) || isa<Ones>(expr2)){
84        return expr1;
85    }
86    else if (equals(expr1, expr2)) {
87        return expr1;
88    }
89    else if (Not * not1 = dyn_cast<Not>(expr1)) {
90        if (Not * not2 = dyn_cast<Not>(expr2)) {
91            return createNot(createOr(not1->getExpr(), not2->getExpr()));
92        }
93        else if (equals(not1->getExpr(), expr2)) {
94            return createZeroes();
95        }
96    }
97    else if (Not * not2 = dyn_cast<Not>(expr2)) {
98        if (equals(expr1, not2->getExpr())) {
99            return createZeroes();
100        }
101    }
102    if (isa<Not>(expr1)) {
[4214]103        std::swap(expr1, expr2);
104    }
[4416]105    return insertAtInsertionPoint(new And(expr1, expr2, this));
[4410]106}
107
[4419]108
[4244]109PabloAST * PabloBlock::createOr(PabloAST * expr1, PabloAST * expr2) {
[4433]110    assert (expr1 && expr2);
[4419]111    if (isa<Zeroes>(expr2) || isa<Ones>(expr1)) {
112        return expr1;
[4214]113    }
[4419]114    else if (isa<Zeroes>(expr1) || isa<Ones>(expr2)){
115        return expr2;
116    }
117    else if (equals(expr1, expr2)) {
118        return expr1;
119    }
120    else if (Not * not1 = dyn_cast<Not>(expr1)) {
121        // ¬a√b = ¬¬(¬a√b) = ¬(a ∧ ¬b)
122        return createNot(createAnd(not1->getExpr(), createNot(expr2)));
123    }
124    else if (Not * not2 = dyn_cast<Not>(expr2)) {
125        // a√¬b = ¬¬(¬b√a) = ¬(b ∧ ¬a)
126        return createNot(createAnd(not2->getExpr(), createNot(expr1)));
127    }
128    else if (equals(expr1, expr2)) {
129        return expr1;
130    }
131    else if (And * and_expr1 = dyn_cast<And>(expr1)) {
132        if (And * and_expr2 = dyn_cast<And>(expr2)) {
133            PabloAST * const expr1a = and_expr1->getExpr1();
134            PabloAST * const expr1b = and_expr1->getExpr2();
135            PabloAST * const expr2a = and_expr2->getExpr1();
136            PabloAST * const expr2b = and_expr2->getExpr2();
137            //These optimizations factor out common components that can occur when sets are formed by union
138            //(e.g., union of [a-z] and [A-Z].
139            if (equals(expr1a, expr2a)) {
140                return createAnd(expr1a, createOr(expr1b, expr2b));
141            }
142            else if (equals(expr1b, expr2b)) {
143                return createAnd(expr1b, createOr(expr1a, expr2a));
144            }
145            else if (equals(expr1a, expr2b)) {
146                return createAnd(expr1a, createOr(expr1b, expr2a));
147            }
148            else if (equals(expr1b, expr2a)) {
149                return createAnd(expr1b, createOr(expr1a, expr2b));
150            }
151        }
152    }
[4416]153    return insertAtInsertionPoint(new Or(expr1, expr2, this));
[4410]154}
155
[4244]156PabloAST * PabloBlock::createXor(PabloAST * expr1, PabloAST * expr2) {
[4433]157    assert (expr1 && expr2);
[4419]158    if (isa<Ones>(expr1)) {
159        return createNot(expr2);
[4214]160    }
[4419]161    else if (isa<Zeroes>(expr1)){
162        return expr2;
163    }
164    else if (isa<Ones>(expr2)) {
165        return createNot(expr1);
166    }
167    else if (isa<Zeroes>(expr2)){
168        return expr1;
169    }
170    else if (Not * not1 = dyn_cast<Not>(expr1)) {
171        if (Not * not2 = dyn_cast<Not>(expr2)) {
172            return createXor(not1->getExpr(), not2->getExpr());
173        }
174    }
[4416]175    return insertAtInsertionPoint(new Xor(expr1, expr2,  this));
[4410]176}
177
[4214]178/// TERNARY CREATE FUNCTION
179
[4404]180PabloAST * PabloBlock::createSel(PabloAST * condition, PabloAST * trueExpr, PabloAST * falseExpr) {
[4433]181    assert (condition && trueExpr && falseExpr);
[4214]182
[4419]183    if (isa<Ones>(condition)) {
184        return trueExpr;
185    }
186    else if (isa<Zeroes>(condition)){
187        return falseExpr;
188    }
189    else if (isa<Ones>(trueExpr)) {
190        return createOr(condition, falseExpr);
191    }
192    else if (isa<Zeroes>(trueExpr)){
193        return createAnd(createNot(condition), falseExpr);
194    }
195    else if (isa<Ones>(falseExpr)) {
196        return createOr(createNot(condition), trueExpr);
197    }
198    else if (isa<Zeroes>(falseExpr)){
199        return createAnd(condition, trueExpr);
200    }
201    else if (equals(trueExpr, falseExpr)) {
202        return trueExpr;
203    }
204    else if (isa<Not>(trueExpr) && equals(cast<Not>(trueExpr)->getExpr(), falseExpr)) {
205        return createXor(condition, falseExpr);
206    }
207    else if (isa<Not>(falseExpr) && equals(trueExpr, cast<Not>(falseExpr)->getExpr())){
208        return createXor(condition, falseExpr);
209    }
[4416]210    return insertAtInsertionPoint(new Sel(condition, trueExpr, falseExpr, this));
[4410]211}
212
[4416]213If * PabloBlock::createIf(PabloAST * condition, std::vector<Assign *> && definedVars, PabloBlock & body) {
[4433]214    assert (condition);
[4416]215    return insertAtInsertionPoint(new If(condition, std::move(definedVars), body, this));
216}
[4414]217
[4433]218While * PabloBlock::createWhile(PabloAST * condition, PabloBlock & body) {
219    assert (condition);
220    return insertAtInsertionPoint(new While(condition, body, this));
[4416]221}
[4414]222
[4416]223/// CONSTRUCTOR
[4414]224
[4416]225PabloBlock::PabloBlock()
[4432]226: PabloAST(PabloAST::ClassTypeId::Block)
227, mZeroes(new Zeroes())
[4416]228, mOnes(new Ones())
229, mSymbolGenerator(new SymbolGenerator())
[4432]230, mPredecessor(nullptr)
[4416]231{
[4414]232
[4416]233}
[4404]234
[4416]235PabloBlock::PabloBlock(PabloBlock * predecessor)
[4432]236: PabloAST(PabloAST::ClassTypeId::Block)
237, mZeroes(predecessor->mZeroes) // inherit the original "Zeroes" variable for simplicity
[4416]238, mOnes(predecessor->mOnes) // inherit the original "Ones" variable for simplicity
239, mSymbolGenerator(predecessor->mSymbolGenerator)
[4432]240, mPredecessor(predecessor)
[4416]241{
[4404]242
[4415]243}
[4404]244
[4432]245PabloBlock::~PabloBlock() {
246    if (mPredecessor == nullptr) {
247        delete mSymbolGenerator;
248    }   
[4214]249}
[4432]250
251}
Note: See TracBrowser for help on using the repository browser.