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

Last change on this file since 6189 was 6189, checked in by nmedfort, 11 months ago

Bug fixes for 32-bit

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