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

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

Merged PabloFunction? and PabloKernel? classes. Updated projects where necessary.

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