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

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

Couple minor bug fixes.

File size: 7.7 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
11/// UNARY CREATE FUNCTIONS
12
13Assign * PabloBlock::createAssign(const std::string prefix, PabloAST * expr, const int outputIndex)  {
14    return insertAtInsertionPoint(new Assign(expr, outputIndex, makeName(prefix, false), this));
15}
16
17PabloAST * PabloBlock::createAdvance(PabloAST * expr, PabloAST * shiftAmount) {
18    if (isa<Zeroes>(expr) || cast<Integer>(shiftAmount)->value() == 0) {
19        return expr;
20    }
21    return insertAtInsertionPoint(new Advance(expr, shiftAmount, mSymbolGenerator, this));
22}
23
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));
29}
30
31Call * PabloBlock::createCall(String * name) {
32    assert (name);
33    return insertAtInsertionPoint(new Call(name, this));
34}
35
36PabloAST * PabloBlock::createNot(PabloAST * expr) {
37    assert (expr);
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    }
47    return insertAtInsertionPoint(new Not(expr, this));
48}
49
50Var * PabloBlock::createVar(String * name) {
51    assert (name);
52    return new Var(name, this);
53}
54
55/// BINARY CREATE FUNCTIONS
56
57Next * PabloBlock::createNext(Assign * assign, PabloAST * expr) {
58    assert (assign && expr);
59    return insertAtInsertionPoint(new Next(assign, expr, this));
60}
61
62PabloAST * PabloBlock::createMatchStar(PabloAST * marker, PabloAST * charclass) {
63    assert (marker && charclass);
64    if (isa<Zeroes>(marker) || isa<Zeroes>(charclass)) {
65        return marker;
66    }
67    return insertAtInsertionPoint(new MatchStar(marker, charclass, mSymbolGenerator, this));
68}
69
70PabloAST * PabloBlock::createScanThru(PabloAST * from, PabloAST * thru) {
71    assert (from && thru);
72    if (isa<Zeroes>(from) || isa<Zeroes>(thru)) {
73        return from;
74    }
75    return insertAtInsertionPoint(new ScanThru(from, thru, mSymbolGenerator, this));
76}
77
78PabloAST * PabloBlock::createAnd(PabloAST * expr1, PabloAST * expr2) {
79    assert (expr1 && expr2);
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)) {
103        std::swap(expr1, expr2);
104    }
105    return insertAtInsertionPoint(new And(expr1, expr2, this));
106}
107
108
109PabloAST * PabloBlock::createOr(PabloAST * expr1, PabloAST * expr2) {
110    assert (expr1 && expr2);
111    if (isa<Zeroes>(expr2) || isa<Ones>(expr1)) {
112        return expr1;
113    }
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    }
153    return insertAtInsertionPoint(new Or(expr1, expr2, this));
154}
155
156PabloAST * PabloBlock::createXor(PabloAST * expr1, PabloAST * expr2) {
157    assert (expr1 && expr2);
158    if (isa<Ones>(expr1)) {
159        return createNot(expr2);
160    }
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    }
175    return insertAtInsertionPoint(new Xor(expr1, expr2,  this));
176}
177
178/// TERNARY CREATE FUNCTION
179
180PabloAST * PabloBlock::createSel(PabloAST * condition, PabloAST * trueExpr, PabloAST * falseExpr) {
181    assert (condition && trueExpr && falseExpr);
182
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    }
210    return insertAtInsertionPoint(new Sel(condition, trueExpr, falseExpr, this));
211}
212
213If * PabloBlock::createIf(PabloAST * condition, std::vector<Assign *> && definedVars, PabloBlock & body) {
214    assert (condition);
215    return insertAtInsertionPoint(new If(condition, std::move(definedVars), body, this));
216}
217
218While * PabloBlock::createWhile(PabloAST * condition, PabloBlock & body) {
219    assert (condition);
220    return insertAtInsertionPoint(new While(condition, body, this));
221}
222
223/// CONSTRUCTOR
224
225PabloBlock::PabloBlock()
226: PabloAST(PabloAST::ClassTypeId::Block)
227, mZeroes(new Zeroes())
228, mOnes(new Ones())
229, mSymbolGenerator(new SymbolGenerator())
230, mPredecessor(nullptr)
231{
232
233}
234
235PabloBlock::PabloBlock(PabloBlock * predecessor)
236: PabloAST(PabloAST::ClassTypeId::Block)
237, mZeroes(predecessor->mZeroes) // inherit the original "Zeroes" variable for simplicity
238, mOnes(predecessor->mOnes) // inherit the original "Ones" variable for simplicity
239, mSymbolGenerator(predecessor->mSymbolGenerator)
240, mPredecessor(predecessor)
241{
242
243}
244
245PabloBlock::~PabloBlock() {
246    if (mPredecessor == nullptr) {
247        delete mSymbolGenerator;
248    }   
249}
250
251}
Note: See TracBrowser for help on using the repository browser.