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

Last change on this file since 5202 was 5202, checked in by nmedfort, 2 years ago

Initial work on adding types to PabloAST and mutable Var objects.

File size: 7.9 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#include <pablo/printer_pablos.h>
9
10namespace pablo {
11
12/// UNARY CREATE FUNCTIONS
13///
14
15Call * PabloBlock::createCall(PabloAST * prototype, const std::vector<PabloAST *> &) {
16    assert (prototype);
17    return insertAtInsertionPoint(new Call(prototype));
18}
19
20Count * PabloBlock::createCount(PabloAST * expr) {
21    return insertAtInsertionPoint(new Count(expr, makeName("count")));
22}
23
24Count * PabloBlock::createCount(PabloAST * const expr, const std::string & prefix)  {
25    return insertAtInsertionPoint(new Count(expr, makeName(prefix)));
26}
27
28Not * PabloBlock::createNot(PabloAST * expr, String * name) {
29    assert (expr);
30    if (name == nullptr) {
31        name = makeName("not");
32    }
33    return insertAtInsertionPoint(new Not(expr, name));
34}
35
36Var * PabloBlock::createVar(PabloAST * name, Type * type) {
37    if (type == nullptr) {
38        type = getStreamTy();
39    }
40    if (LLVM_UNLIKELY(name == nullptr || !isa<String>(name))) {
41        throw std::runtime_error("Var objects must have a String name");
42    }
43    return mParent->makeVariable(name, type);
44}
45
46InFile * PabloBlock::createInFile(PabloAST * expr, String * name) {
47    assert (expr);
48    if (name == nullptr) {
49        name = makeName("inFile");
50    }
51    return insertAtInsertionPoint(new InFile(expr, name));
52}
53
54AtEOF * PabloBlock::createAtEOF(PabloAST * expr, String * name) {
55    assert (expr);
56    if (name == nullptr) {
57        name = makeName("atEOF");
58    }
59    return insertAtInsertionPoint(new AtEOF(expr, name));
60}
61   
62   
63/// BINARY CREATE FUNCTIONS
64
65Advance * PabloBlock::createAdvance(PabloAST * expr, PabloAST * shiftAmount, String * name) {
66    if (name == nullptr) {
67        name = makeName("advance");
68    }
69    return insertAtInsertionPoint(new Advance(expr, shiftAmount, name));
70}
71
72Lookahead * PabloBlock::createLookahead(PabloAST * expr, PabloAST * shiftAmount, String * name) {
73    if (name == nullptr) {
74        name = makeName("lookahead");
75    }
76    return insertAtInsertionPoint(new Lookahead(expr, shiftAmount, name));
77}
78
79Extract * PabloBlock::createExtract(PabloAST * array, PabloAST * index, String * name) {
80    assert (array && index);
81    if (LLVM_LIKELY(isa<ArrayType>(array->getType()))) {
82        if (name == nullptr) {
83            std::string tmp;
84            raw_string_ostream out(tmp);
85            PabloPrinter::print(array, out);
86            PabloPrinter::print(index, out);
87            name = makeName(out.str());
88        }
89        return insertAtInsertionPoint(new Extract(array, index, name));
90    }
91    std::string tmp;
92    raw_string_ostream out(tmp);
93    out << "cannot extract element from ";
94    array->print(out);
95    out << ": type is not a valid ArrayType";
96    throw std::runtime_error(out.str());
97}
98
99And * PabloBlock::createAnd(PabloAST * expr1, PabloAST * expr2, String * name) {
100    if (name == nullptr) {
101        name = makeName("and");
102    }
103    return insertAtInsertionPoint(new And(expr1->getType(), expr1, expr2, name));
104}
105
106And * PabloBlock::createAnd(Type * const type, const unsigned reserved, String * name) {
107    if (name == nullptr) {
108        name = makeName("and");
109    }
110    return insertAtInsertionPoint(new And(type, reserved, name));
111}
112
113Or * PabloBlock::createOr(PabloAST * expr1, PabloAST * expr2, String * name) {
114    if (name == nullptr) {
115        name = makeName("or");
116    }
117    return insertAtInsertionPoint(new Or(expr1->getType(), expr1, expr2, name));
118}
119
120Or * PabloBlock::createOr(Type * const type, const unsigned reserved, String * name) {
121    if (name == nullptr) {
122        name = makeName("or");
123    }
124    return insertAtInsertionPoint(new Or(type, reserved, name));
125}
126
127Xor * PabloBlock::createXor(PabloAST * expr1, PabloAST * expr2, String * name) {
128    if (name == nullptr) {
129        name = makeName("xor");
130    }
131    return insertAtInsertionPoint(new Xor(expr1->getType(), expr1, expr2, name));
132}
133
134Xor * PabloBlock::createXor(Type * const type, const unsigned reserved, String * name) {
135    if (name == nullptr) {
136        name = makeName("xor");
137    }
138    return insertAtInsertionPoint(new Xor(type, reserved, name));
139}
140
141Assign * PabloBlock::createAssign(PabloAST * const var, PabloAST * const value) {
142    return insertAtInsertionPoint(new Assign(var, value));
143}
144
145MatchStar * PabloBlock::createMatchStar(PabloAST * marker, PabloAST * charclass, String * name) {
146    if (name == nullptr) {
147        name = makeName("matchstar");
148    }
149    return insertAtInsertionPoint(new MatchStar(marker, charclass, name));
150}
151
152ScanThru * PabloBlock::createScanThru(PabloAST * from, PabloAST * thru, String * name) {
153    if (name == nullptr) {
154        name = makeName("scanthru");
155    }
156    return insertAtInsertionPoint(new ScanThru(from, thru, name));
157}
158
159If * PabloBlock::createIf(PabloAST * condition, PabloBlock * body) {
160    assert (condition);
161    If * const node = insertAtInsertionPoint(new If(condition, body));
162    body->setBranch(node);
163    return node;
164}
165
166While * PabloBlock::createWhile(PabloAST * condition, PabloBlock * body) {
167    assert (condition);
168    While * const node = insertAtInsertionPoint(new While(condition, body));
169    body->setBranch(node);
170    return node;
171}
172
173/// TERNARY CREATE FUNCTION
174
175Sel * PabloBlock::createSel(PabloAST * condition, PabloAST * trueExpr, PabloAST * falseExpr, String * name) {
176    if (name == nullptr) {
177        name = makeName("sel");
178    }
179    return insertAtInsertionPoint(new Sel(condition, trueExpr, falseExpr, name));
180}
181
182/** ------------------------------------------------------------------------------------------------------------- *
183 * @brief insert
184 ** ------------------------------------------------------------------------------------------------------------- */
185void PabloBlock::insert(Statement * const statement) {
186    assert (statement);
187    if (LLVM_UNLIKELY(mInsertionPoint == nullptr)) {
188        if (mFirst) {
189            statement->insertBefore(mFirst);
190        } else {
191            statement->removeFromParent();
192            statement->mParent = this;
193            mFirst = mLast = statement;
194        }
195    } else if (LLVM_LIKELY(statement != mInsertionPoint)) {
196        statement->insertAfter(mInsertionPoint);
197        mLast = (mLast == mInsertionPoint) ? statement : mLast;
198        assert (statement->mPrev == mInsertionPoint);
199    }
200    mInsertionPoint = statement;
201}
202
203/** ------------------------------------------------------------------------------------------------------------- *
204 * @brief eraseFromParent
205 ** ------------------------------------------------------------------------------------------------------------- */
206void PabloBlock::eraseFromParent(const bool recursively) {
207    Statement * stmt = front();
208    while (stmt) {
209        stmt = stmt->eraseFromParent(recursively);
210    }
211    mAllocator.deallocate(reinterpret_cast<Allocator::pointer>(this));
212}
213
214/** ------------------------------------------------------------------------------------------------------------- *
215 * @brief enumerateScopes
216 *
217 * Assign sequential scope indexes, returning the next unassigned index
218 ** ------------------------------------------------------------------------------------------------------------- */
219unsigned PabloBlock::enumerateScopes(unsigned baseScopeIndex) {
220    mScopeIndex = baseScopeIndex;
221    unsigned nextScopeIndex = baseScopeIndex + 1;
222    for (Statement * stmt : *this) {
223        if (If * ifStatement = dyn_cast<If>(stmt)) {
224            nextScopeIndex = ifStatement->getBody()->enumerateScopes(nextScopeIndex);
225        }
226        else if (While * whileStatement = dyn_cast<While>(stmt)) {
227            nextScopeIndex = whileStatement->getBody()->enumerateScopes(nextScopeIndex);
228        }
229    }
230    return nextScopeIndex;
231}   
232   
233/// CONSTRUCTOR
234
235PabloBlock::PabloBlock(PabloFunction * const parent) noexcept
236: PabloAST(PabloAST::ClassTypeId::Block, nullptr, nullptr)
237, mParent(parent)
238, mBranch(nullptr)
239, mScopeIndex(0)
240{
241
242}
243
244PabloBlock::~PabloBlock() {
245
246}
247
248}
Note: See TracBrowser for help on using the repository browser.