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

Last change on this file was 6215, checked in by cameron, 5 months ago

pablo.terminateAt

File size: 12.3 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 "codegenstate.h"
8#include <pablo/printer_pablos.h>
9#include <pablo/boolean.h>
10#include <pablo/arithmetic.h>
11#include <pablo/branch.h>
12#include <pablo/pe_advance.h>
13#include <pablo/pe_count.h>
14#include <pablo/pe_infile.h>
15#include <pablo/pe_integer.h>
16#include <pablo/pe_lookahead.h>
17#include <pablo/pe_matchstar.h>
18#include <pablo/pe_ones.h>
19#include <pablo/pe_pack.h>
20#include <pablo/pe_repeat.h>
21#include <pablo/pe_scanthru.h>
22#include <pablo/pe_string.h>
23#include <pablo/pe_var.h>
24#include <pablo/pe_zeroes.h>
25#include <pablo/ps_assign.h>
26#include <pablo/ps_terminate.h>
27#include <pablo/pablo_kernel.h>
28#include <IR_Gen/idisa_builder.h>
29#include <llvm/IR/Module.h>
30#include <llvm/Support/raw_os_ostream.h>
31
32using namespace llvm;
33
34namespace pablo {
35
36#ifndef NDEBUG
37inline void __checkSameType(const Type * const A, const Type * const B) {
38    assert ("DIFFERING CONTEXTS" && (&(A->getContext()) == &(B->getContext())));
39    assert ("DIFFERING TYPES" && (A == B));
40}
41inline void __checkSameType(const PabloAST * const A, const PabloAST * const B) {
42    __checkSameType(A->getType(), B->getType());
43}
44#define CHECK_SAME_TYPE(A, B) __checkSameType(A, B)
45#else
46#define CHECK_SAME_TYPE(A, B)
47#endif
48
49/// UNARY CREATE FUNCTIONS
50///
51
52Count * PabloBlock::createCount(PabloAST * const expr, const String * const name)  {
53    IntegerType * const type = getParent()->getSizeTy();
54    return insertAtInsertionPoint(new (mAllocator) Count(expr, name, type, mAllocator));
55}
56
57Not * PabloBlock::createNot(PabloAST * expr, const String * const name) {
58    assert (expr);
59    return insertAtInsertionPoint(new (mAllocator) Not(expr, name, mAllocator));
60}
61
62Var * PabloBlock::createVar(const String * const name, Type * type) {
63    if (type == nullptr) {
64        type = getParent()->getStreamTy();
65    }
66    if (LLVM_UNLIKELY(name == nullptr)) {
67        throw std::runtime_error("Var objects must have a String name");
68    }
69    return mParent->makeVariable(name, type);
70}
71
72InFile * PabloBlock::createInFile(PabloAST * expr, const String * const name) {
73    assert (expr);
74    return insertAtInsertionPoint(new (mAllocator) InFile(expr, name, mAllocator));
75}
76
77AtEOF * PabloBlock::createAtEOF(PabloAST * expr, const String * const name) {
78    assert (expr);
79    return insertAtInsertionPoint(new (mAllocator) AtEOF(expr, name, mAllocator));
80}
81
82TerminateAt * PabloBlock::createTerminateAt(PabloAST * strm, Integer *  code, const String * const name) {
83    assert (strm); assert(code);
84    return insertAtInsertionPoint(new (mAllocator) TerminateAt(strm, code, name, mAllocator));
85}
86
87/// BINARY CREATE FUNCTIONS
88
89Advance * PabloBlock::createAdvance(PabloAST * expr, Integer * shiftAmount, const String * const name) {
90    return insertAtInsertionPoint(new (mAllocator) Advance(expr, shiftAmount, name, mAllocator));
91}
92
93Lookahead * PabloBlock::createLookahead(PabloAST * expr, Integer * shiftAmount, const String * const name) {
94    return insertAtInsertionPoint(new (mAllocator) Lookahead(expr, shiftAmount, name, mAllocator));
95}
96
97Extract * PabloBlock::createExtract(Var * array, Integer * index) {
98    assert (array && index);
99    Type * type = array->getType();
100    if (LLVM_LIKELY(isa<ArrayType>(type))) {
101        type = cast<ArrayType>(type)->getArrayElementType();
102    } else {
103        std::string tmp;
104        raw_string_ostream out(tmp);
105        out << "cannot extract element from ";
106        array->print(out);
107        out << ": ";
108        type->print(out);
109        out << " is not an array type";
110        throw std::runtime_error(out.str());
111    }
112    return new (mAllocator) Extract(array, index, type, mAllocator);
113}
114
115And * PabloBlock::createAnd(PabloAST * expr1, PabloAST * expr2, const String * const name) {
116    CHECK_SAME_TYPE(expr1, expr2);
117    return insertAtInsertionPoint(new (mAllocator) And(expr1->getType(), expr1, expr2, name, mAllocator));
118}
119
120Or * PabloBlock::createOr(PabloAST * expr1, PabloAST * expr2, const String * const name) {
121    CHECK_SAME_TYPE(expr1, expr2);
122    return insertAtInsertionPoint(new (mAllocator) Or(expr1->getType(), expr1, expr2, name, mAllocator));
123}
124
125Xor * PabloBlock::createXor(PabloAST * expr1, PabloAST * expr2, const String * const name) {
126    CHECK_SAME_TYPE(expr1, expr2);
127    return insertAtInsertionPoint(new (mAllocator) Xor(expr1->getType(), expr1, expr2, name, mAllocator));
128}
129
130Add * PabloBlock::createAdd(PabloAST * expr1, PabloAST * expr2) {
131    CHECK_SAME_TYPE(expr1, expr2);
132    return new (mAllocator) Add(expr1->getType(), expr1, expr2, mAllocator);
133}
134
135Subtract * PabloBlock::createSubtract(PabloAST * expr1, PabloAST * expr2) {
136    CHECK_SAME_TYPE(expr1, expr2);
137    return new (mAllocator) Subtract(expr1->getType(), expr1, expr2, mAllocator);
138}
139
140LessThan * PabloBlock::createLessThan(PabloAST * expr1, PabloAST * expr2) {
141    const Type * const t1 = expr1->getType()->isArrayTy() ? expr1->getType()->getArrayElementType() : expr1->getType();
142    const Type * const t2 = expr2->getType()->isArrayTy() ? expr2->getType()->getArrayElementType() : expr2->getType();
143    CHECK_SAME_TYPE(t1, t2);
144    Type * ty = getParent()->getInt1Ty();
145    if (t1->isVectorTy() || t2->isVectorTy()) {
146        ty = VectorType::get(ty, 0);
147    }
148    return new (mAllocator) LessThan(ty, expr1, expr2, mAllocator);
149}
150
151Equals * PabloBlock::createEquals(PabloAST * expr1, PabloAST * expr2) {
152    const Type * const t1 = expr1->getType()->isArrayTy() ? expr1->getType()->getArrayElementType() : expr1->getType();
153    const Type * const t2 = expr2->getType()->isArrayTy() ? expr2->getType()->getArrayElementType() : expr2->getType();
154    CHECK_SAME_TYPE(t1, t2);
155    Type * ty = getParent()->getInt1Ty();
156    if (t1->isVectorTy() || t2->isVectorTy()) {
157        ty = VectorType::get(ty, 0);
158    }
159    return new (mAllocator) Equals(ty, expr1, expr2, mAllocator);
160}
161
162Assign * PabloBlock::createAssign(PabloAST * const var, PabloAST * const value) {
163    Var * test = nullptr;
164    if (isa<Extract>(var)) {
165        test = cast<Extract>(var)->getArray();
166    } else if (isa<Var>(var)) {
167        test = cast<Var>(var);
168    }
169    if (LLVM_UNLIKELY(test == nullptr || test->isReadOnly())) {
170        std::string tmp;
171        raw_string_ostream out(tmp);
172        out << "cannot assign ";
173        value->print(out);
174        out << " to ";
175        var->print(out);
176        out << ": ";
177        var->print(out);
178        if (test == nullptr) {
179            out << " must be an Extract expression or Var declaration";
180        } else {
181            out << " is read only";
182        }
183        report_fatal_error(out.str());
184    }
185    return insertAtInsertionPoint(new (mAllocator) Assign(var, value, mAllocator));
186}
187
188MatchStar * PabloBlock::createMatchStar(PabloAST * marker, PabloAST * charclass, const String * const name) {
189    CHECK_SAME_TYPE(marker, charclass);
190    return insertAtInsertionPoint(new (mAllocator) MatchStar(marker, charclass, name, mAllocator));
191}
192
193ScanThru * PabloBlock::createScanThru(PabloAST * from, PabloAST * thru, const String * const name) {
194    CHECK_SAME_TYPE(from, thru);
195    return insertAtInsertionPoint(new (mAllocator) ScanThru(from, thru, name, mAllocator));
196}
197
198ScanTo * PabloBlock::createScanTo(PabloAST * from, PabloAST * to, const String * const name) {
199    CHECK_SAME_TYPE(from, to);
200    return insertAtInsertionPoint(new (mAllocator) ScanTo(from, to, name, mAllocator));
201}
202
203AdvanceThenScanThru * PabloBlock::createAdvanceThenScanThru(PabloAST * from, PabloAST * thru, const String * const name) {
204    CHECK_SAME_TYPE(from, thru);
205    return insertAtInsertionPoint(new (mAllocator) AdvanceThenScanThru(from, thru, name, mAllocator));
206}
207
208AdvanceThenScanTo * PabloBlock::createAdvanceThenScanTo(PabloAST * from, PabloAST * to, const String * const name) {
209    CHECK_SAME_TYPE(from, to);
210    return insertAtInsertionPoint(new (mAllocator) AdvanceThenScanTo(from, to, name, mAllocator));
211}
212
213If * PabloBlock::createIf(PabloAST * condition, PabloBlock * body) {
214    assert (condition && body);
215    If * const node = insertAtInsertionPoint(new (mAllocator) If(condition, body, mAllocator));
216    body->setBranch(node);
217    return node;
218}
219
220While * PabloBlock::createWhile(PabloAST * condition, PabloBlock * body) {
221    assert (condition && body);
222    While * const node = insertAtInsertionPoint(new (mAllocator) While(condition, body, mAllocator));
223    body->setBranch(node);
224    return node;
225}
226
227Repeat * PabloBlock::createRepeat(Integer * fieldWidth, PabloAST * value, const String * const name) {
228    assert (fieldWidth && value);
229    Type * const type = VectorType::get(IntegerType::get(value->getType()->getContext(), fieldWidth->value()), 0);
230    return insertAtInsertionPoint(new (mAllocator) Repeat(fieldWidth, value, type, name, mAllocator));
231}
232
233PackH * PabloBlock::createPackH(Integer * fieldWidth, PabloAST * value, const String * const name) {
234    assert (fieldWidth && value);
235    Type * const type = VectorType::get(IntegerType::get(value->getType()->getContext(), fieldWidth->value()/2), 0);
236    return insertAtInsertionPoint(new (mAllocator) PackH(fieldWidth, value, name, type, mAllocator));
237}
238
239PackL * PabloBlock::createPackL(Integer * fieldWidth, PabloAST * value, const String * const name) {
240    assert (fieldWidth && value);
241    Type * const type = VectorType::get(IntegerType::get(value->getType()->getContext(), fieldWidth->value()/2), 0);
242    return insertAtInsertionPoint(new (mAllocator) PackL(fieldWidth, value, name, type, mAllocator));
243}
244
245/// TERNARY CREATE FUNCTIONS
246
247Sel * PabloBlock::createSel(PabloAST * condition, PabloAST * trueExpr, PabloAST * falseExpr, const String * const name) {
248    CHECK_SAME_TYPE(trueExpr, falseExpr);
249    return insertAtInsertionPoint(new (mAllocator) Sel(condition, trueExpr, falseExpr, name, mAllocator));
250}
251
252IndexedAdvance * PabloBlock::createIndexedAdvance(PabloAST * expr, PabloAST * indexStream, Integer * shiftAmount, const String * const name) {
253    return insertAtInsertionPoint(new (mAllocator) IndexedAdvance(expr, indexStream, shiftAmount, name, mAllocator));
254}
255   
256
257/** ------------------------------------------------------------------------------------------------------------- *
258 * @brief createScope
259 ** ------------------------------------------------------------------------------------------------------------- */
260PabloBlock * PabloBlock::createScope() noexcept {
261    return new (mAllocator) PabloBlock(mParent, mAllocator);
262}
263
264/** ------------------------------------------------------------------------------------------------------------- *
265 * @brief insert
266 ** ------------------------------------------------------------------------------------------------------------- */
267void PabloBlock::insert(Statement * const statement) {
268    assert (statement);
269    if (LLVM_UNLIKELY(mInsertionPoint == nullptr)) {
270        if (mFirst) {
271            statement->insertBefore(mFirst);
272        } else {
273            statement->removeFromParent();
274            statement->mParent = this;
275            mFirst = mLast = statement;
276        }
277    } else if (LLVM_LIKELY(statement != mInsertionPoint)) {
278        statement->insertAfter(mInsertionPoint);
279        mLast = (mLast == mInsertionPoint) ? statement : mLast;
280        assert (statement->mPrev == mInsertionPoint);
281    }
282    mInsertionPoint = statement;
283}
284
285/** ------------------------------------------------------------------------------------------------------------- *
286 * @brief eraseFromParent
287 ** ------------------------------------------------------------------------------------------------------------- */
288void PabloBlock::eraseFromParent(const bool recursively) {
289    Statement * stmt = front();
290    while (stmt) {
291        stmt = stmt->eraseFromParent(recursively);
292    }
293}
294
295/** ------------------------------------------------------------------------------------------------------------- *
296 * @brief getPredecessor
297 ** ------------------------------------------------------------------------------------------------------------- */
298PabloBlock * PabloBlock::getPredecessor() const {
299    return getBranch() ? getBranch()->getParent() : nullptr;
300}
301
302/** ------------------------------------------------------------------------------------------------------------- *
303 * @brief print
304 ** ------------------------------------------------------------------------------------------------------------- */
305void PabloBlock::print(raw_ostream & O, const bool expandNested) const {
306    PabloPrinter::print(this, O, expandNested);
307}
308
309}
Note: See TracBrowser for help on using the repository browser.