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

Last change on this file since 5842 was 5837, checked in by cameron, 19 months ago

Pablo packh/packl and transposition with -enable-pablo-s2p

File size: 12.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 "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    CHECK_SAME_TYPE(var, value);
158    Var * test = nullptr;
159    if (isa<Extract>(var)) {
160        test = cast<Extract>(var)->getArray();
161    } else if (isa<Var>(var)) {
162        test = cast<Var>(var);
163    }
164    if (LLVM_UNLIKELY(test == nullptr || test->isReadOnly())) {
165        std::string tmp;
166        raw_string_ostream out(tmp);
167        out << "cannot assign ";
168        value->print(out);
169        out << " to ";
170        var->print(out);
171        out << ": ";
172        var->print(out);
173        if (test == nullptr) {
174            out << " must be an Extract expression or Var declaration";
175        } else {
176            out << " is read only";
177        }
178        report_fatal_error(out.str());
179    }
180    return insertAtInsertionPoint(new (mAllocator) Assign(var, value, mAllocator));
181}
182
183MatchStar * PabloBlock::createMatchStar(PabloAST * marker, PabloAST * charclass, const String * const name) {
184    CHECK_SAME_TYPE(marker, charclass);
185    return insertAtInsertionPoint(new (mAllocator) MatchStar(marker, charclass, name, mAllocator));
186}
187
188ScanThru * PabloBlock::createScanThru(PabloAST * from, PabloAST * thru, const String * const name) {
189    CHECK_SAME_TYPE(from, thru);
190    return insertAtInsertionPoint(new (mAllocator) ScanThru(from, thru, name, mAllocator));
191}
192
193ScanTo * PabloBlock::createScanTo(PabloAST * from, PabloAST * to, const String * const name) {
194    CHECK_SAME_TYPE(from, to);
195    return insertAtInsertionPoint(new (mAllocator) ScanTo(from, to, name, mAllocator));
196}
197
198AdvanceThenScanThru * PabloBlock::createAdvanceThenScanThru(PabloAST * from, PabloAST * thru, const String * const name) {
199    CHECK_SAME_TYPE(from, thru);
200    return insertAtInsertionPoint(new (mAllocator) AdvanceThenScanThru(from, thru, name, mAllocator));
201}
202
203AdvanceThenScanTo * PabloBlock::createAdvanceThenScanTo(PabloAST * from, PabloAST * to, const String * const name) {
204    CHECK_SAME_TYPE(from, to);
205    return insertAtInsertionPoint(new (mAllocator) AdvanceThenScanTo(from, to, name, mAllocator));
206}
207
208If * PabloBlock::createIf(PabloAST * condition, PabloBlock * body) {
209    assert (condition && body);
210    If * const node = insertAtInsertionPoint(new (mAllocator) If(condition, body, mAllocator));
211    body->setBranch(node);
212    return node;
213}
214
215While * PabloBlock::createWhile(PabloAST * condition, PabloBlock * body) {
216    assert (condition && body);
217    While * const node = insertAtInsertionPoint(new (mAllocator) While(condition, body, mAllocator));
218    body->setBranch(node);
219    return node;
220}
221
222Repeat * PabloBlock::createRepeat(Integer * fieldWidth, PabloAST * value, const String * const name) {
223    assert (fieldWidth && value);
224    Type * const type = VectorType::get(IntegerType::get(value->getType()->getContext(), fieldWidth->value()), 0);
225    return insertAtInsertionPoint(new (mAllocator) Repeat(fieldWidth, value, type, name, mAllocator));
226}
227
228PackH * PabloBlock::createPackH(Integer * fieldWidth, PabloAST * value, const String * const name) {
229    assert (fieldWidth && value);
230    Type * const type = VectorType::get(IntegerType::get(value->getType()->getContext(), fieldWidth->value()/2), 0);
231    return insertAtInsertionPoint(new (mAllocator) PackH(fieldWidth, value, name, type, mAllocator));
232}
233
234PackL * PabloBlock::createPackL(Integer * fieldWidth, PabloAST * value, const String * const name) {
235    assert (fieldWidth && value);
236    Type * const type = VectorType::get(IntegerType::get(value->getType()->getContext(), fieldWidth->value()/2), 0);
237    return insertAtInsertionPoint(new (mAllocator) PackL(fieldWidth, value, name, type, mAllocator));
238}
239
240/// TERNARY CREATE FUNCTIONS
241
242Sel * PabloBlock::createSel(PabloAST * condition, PabloAST * trueExpr, PabloAST * falseExpr, const String * const name) {
243    CHECK_SAME_TYPE(trueExpr, falseExpr);
244    return insertAtInsertionPoint(new (mAllocator) Sel(condition, trueExpr, falseExpr, name, mAllocator));
245}
246
247IndexedAdvance * PabloBlock::createIndexedAdvance(PabloAST * expr, PabloAST * indexStream, Integer * shiftAmount, const String * const name) {
248    return insertAtInsertionPoint(new (mAllocator) IndexedAdvance(expr, indexStream, shiftAmount, name, mAllocator));
249}
250   
251
252/** ------------------------------------------------------------------------------------------------------------- *
253 * @brief createScope
254 ** ------------------------------------------------------------------------------------------------------------- */
255PabloBlock & PabloBlock::createScope() noexcept {
256    return *new (mAllocator) PabloBlock(mParent, mAllocator);
257}
258
259/** ------------------------------------------------------------------------------------------------------------- *
260 * @brief insert
261 ** ------------------------------------------------------------------------------------------------------------- */
262void PabloBlock::insert(Statement * const statement) {
263    assert (statement);
264    if (LLVM_UNLIKELY(mInsertionPoint == nullptr)) {
265        if (mFirst) {
266            statement->insertBefore(mFirst);
267        } else {
268            statement->removeFromParent();
269            statement->mParent = this;
270            mFirst = mLast = statement;
271        }
272    } else if (LLVM_LIKELY(statement != mInsertionPoint)) {
273        statement->insertAfter(mInsertionPoint);
274        mLast = (mLast == mInsertionPoint) ? statement : mLast;
275        assert (statement->mPrev == mInsertionPoint);
276    }
277    mInsertionPoint = statement;
278}
279
280/** ------------------------------------------------------------------------------------------------------------- *
281 * @brief eraseFromParent
282 ** ------------------------------------------------------------------------------------------------------------- */
283void PabloBlock::eraseFromParent(const bool recursively) {
284    Statement * stmt = front();
285    while (stmt) {
286        stmt = stmt->eraseFromParent(recursively);
287    }
288}
289
290/** ------------------------------------------------------------------------------------------------------------- *
291 * @brief getPredecessor
292 ** ------------------------------------------------------------------------------------------------------------- */
293PabloBlock * PabloBlock::getPredecessor() const {
294    return getBranch() ? getBranch()->getParent() : nullptr;
295}
296
297/** ------------------------------------------------------------------------------------------------------------- *
298 * @brief print
299 ** ------------------------------------------------------------------------------------------------------------- */
300void PabloBlock::print(raw_ostream & O, const bool expandNested) const {
301    PabloPrinter::print(this, O, expandNested);
302}
303
304}
Note: See TracBrowser for help on using the repository browser.