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

Last change on this file since 5828 was 5828, checked in by nmedfort, 20 months ago

Pablo support for byte comparisions; LineFeed? kernel processes byte streams directly. Some clean up of PabloBuilder? functionality.

File size: 14.1 KB
RevLine 
[3850]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
[5267]7#include "codegenstate.h"
[5245]8#include <pablo/printer_pablos.h>
[5267]9#include <pablo/boolean.h>
10#include <pablo/arithmetic.h>
11#include <pablo/branch.h>
12#include <pablo/pe_advance.h>
[5368]13#include <pablo/pe_count.h>
14#include <pablo/pe_infile.h>
15#include <pablo/pe_integer.h>
[5267]16#include <pablo/pe_lookahead.h>
17#include <pablo/pe_matchstar.h>
[5368]18#include <pablo/pe_ones.h>
[5828]19#include <pablo/pe_pack.h>
20#include <pablo/pe_repeat.h>
[5267]21#include <pablo/pe_scanthru.h>
22#include <pablo/pe_string.h>
[5368]23#include <pablo/pe_var.h>
[5267]24#include <pablo/pe_zeroes.h>
25#include <pablo/ps_assign.h>
26#include <pablo/pablo_kernel.h>
[5446]27#include <IR_Gen/idisa_builder.h>
28#include <llvm/IR/Module.h>
[5270]29#include <llvm/Support/raw_os_ostream.h>
[4213]30
[5267]31using namespace llvm;
[5217]32
[4213]33namespace pablo {
34
[5828]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));
[5368]39}
[5828]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
[5368]47
[4214]48/// UNARY CREATE FUNCTIONS
[5202]49///
[4214]50
[5202]51Count * PabloBlock::createCount(PabloAST * expr) {
[5446]52    IntegerType * const type = getParent()->getSizeTy();
[5230]53    return insertAtInsertionPoint(new (mAllocator) Count(expr, makeName("count"), type, mAllocator));
[4213]54}
55
[5283]56Count * PabloBlock::createCount(PabloAST * const expr, const llvm::StringRef & prefix)  {
[5446]57    IntegerType * const type = getParent()->getSizeTy();
[5230]58    return insertAtInsertionPoint(new (mAllocator) Count(expr, makeName(prefix), type, mAllocator));
[4438]59}
60
[5202]61Not * PabloBlock::createNot(PabloAST * expr, String * name) {
62    assert (expr);
63    if (name == nullptr) {
64        name = makeName("not");
[4438]65    }
[5230]66    return insertAtInsertionPoint(new (mAllocator) Not(expr, name, mAllocator));
[4438]67}
68
[5202]69Var * PabloBlock::createVar(PabloAST * name, Type * type) {
70    if (type == nullptr) {
[5446]71        type = getParent()->getStreamTy();
[4959]72    }
[5202]73    if (LLVM_UNLIKELY(name == nullptr || !isa<String>(name))) {
74        throw std::runtime_error("Var objects must have a String name");
[4959]75    }
[5283]76    return mParent->makeVariable(cast<String>(name), type);
[4959]77}
78
[5202]79InFile * PabloBlock::createInFile(PabloAST * expr, String * name) {
[4433]80    assert (expr);
[5202]81    if (name == nullptr) {
82        name = makeName("inFile");
[4419]83    }
[5230]84    return insertAtInsertionPoint(new (mAllocator) InFile(expr, name, mAllocator));
[4213]85}
86
[5202]87AtEOF * PabloBlock::createAtEOF(PabloAST * expr, String * name) {
[4438]88    assert (expr);
[5202]89    if (name == nullptr) {
90        name = makeName("atEOF");
[4438]91    }
[5230]92    return insertAtInsertionPoint(new (mAllocator) AtEOF(expr, name, mAllocator));
[4438]93}
[5828]94
[5202]95/// BINARY CREATE FUNCTIONS
[5042]96
[5828]97Advance * PabloBlock::createAdvance(PabloAST * expr, Integer * shiftAmount, String * name) {
[5202]98    if (name == nullptr) {
99        name = makeName("advance");
[4257]100    }
[5230]101    return insertAtInsertionPoint(new (mAllocator) Advance(expr, shiftAmount, name, mAllocator));
[4252]102}
103
[5828]104Lookahead * PabloBlock::createLookahead(PabloAST * expr, Integer * shiftAmount, String * name) {
[5202]105    if (name == nullptr) {
106        name = makeName("lookahead");
[4438]107    }
[5230]108    return insertAtInsertionPoint(new (mAllocator) Lookahead(expr, shiftAmount, name, mAllocator));
[4438]109}
110
[5828]111Extract * PabloBlock::createExtract(Var * array, Integer * index) {
[5202]112    assert (array && index);
[5227]113    Type * type = array->getType();
[5230]114    if (LLVM_LIKELY(isa<ArrayType>(type))) {
[5227]115        type = cast<ArrayType>(type)->getArrayElementType();
116    } else {
117        std::string tmp;
118        raw_string_ostream out(tmp);
119        out << "cannot extract element from ";
120        array->print(out);
[5828]121        out << ": ";
122        type->print(out);
123        out << " is not an array type";
[5227]124        throw std::runtime_error(out.str());
[5217]125    }
[5828]126    return new (mAllocator) Extract(array, index, type, mAllocator);
[4252]127}
128
[5202]129And * PabloBlock::createAnd(PabloAST * expr1, PabloAST * expr2, String * name) {
[5217]130    CHECK_SAME_TYPE(expr1, expr2);
[5202]131    if (name == nullptr) {
132        name = makeName("and");
[4438]133    }
[5230]134    return insertAtInsertionPoint(new (mAllocator) And(expr1->getType(), expr1, expr2, name, mAllocator));
[4438]135}
136
[5202]137And * PabloBlock::createAnd(Type * const type, const unsigned reserved, String * name) {
138    if (name == nullptr) {
139        name = makeName("and");
[4886]140    }
[5230]141    return insertAtInsertionPoint(new (mAllocator) And(type, reserved, name, mAllocator));
[4886]142}
143
[5202]144Or * PabloBlock::createOr(PabloAST * expr1, PabloAST * expr2, String * name) {
[5217]145    CHECK_SAME_TYPE(expr1, expr2);
[5202]146    if (name == nullptr) {
147        name = makeName("or");
[4419]148    }
[5230]149    return insertAtInsertionPoint(new (mAllocator) Or(expr1->getType(), expr1, expr2, name, mAllocator));
[4410]150}
151
[5202]152Or * PabloBlock::createOr(Type * const type, const unsigned reserved, String * name) {
153    if (name == nullptr) {
154        name = makeName("or");
[4885]155    }
[5230]156    return insertAtInsertionPoint(new (mAllocator) Or(type, reserved, name, mAllocator));
[4438]157}
158
[5202]159Xor * PabloBlock::createXor(PabloAST * expr1, PabloAST * expr2, String * name) {
[5217]160    CHECK_SAME_TYPE(expr1, expr2);
[5202]161    if (name == nullptr) {
162        name = makeName("xor");
[4885]163    }
[5230]164    return insertAtInsertionPoint(new (mAllocator) Xor(expr1->getType(), expr1, expr2, name, mAllocator));
[4410]165}
166
[5202]167Xor * PabloBlock::createXor(Type * const type, const unsigned reserved, String * name) {
168    if (name == nullptr) {
169        name = makeName("xor");
[4885]170    }
[5230]171    return insertAtInsertionPoint(new (mAllocator) Xor(type, reserved, name, mAllocator));
[4438]172}
173
[5227]174Add * PabloBlock::createAdd(PabloAST * expr1, PabloAST * expr2) {
[5217]175    CHECK_SAME_TYPE(expr1, expr2);
[5230]176    return new (mAllocator) Add(expr1->getType(), expr1, expr2, mAllocator);
[5217]177}
178
[5227]179Subtract * PabloBlock::createSubtract(PabloAST * expr1, PabloAST * expr2) {
[5217]180    CHECK_SAME_TYPE(expr1, expr2);
[5230]181    return new (mAllocator) Subtract(expr1->getType(), expr1, expr2, mAllocator);
[5227]182}
183
184LessThan * PabloBlock::createLessThan(PabloAST * expr1, PabloAST * expr2) {
[5828]185    const Type * const t1 = expr1->getType()->isArrayTy() ? expr1->getType()->getArrayElementType() : expr1->getType();
186    const Type * const t2 = expr2->getType()->isArrayTy() ? expr2->getType()->getArrayElementType() : expr2->getType();
187    CHECK_SAME_TYPE(t1, t2);
188    Type * ty = getParent()->getInt1Ty();
189    if (t1->isVectorTy() || t2->isVectorTy()) {
190        ty = VectorType::get(ty, 0);
191    }
192    return new (mAllocator) LessThan(ty, expr1, expr2, mAllocator);
[5227]193}
194
[5828]195Equals * PabloBlock::createEquals(PabloAST * expr1, PabloAST * expr2) {
196    const Type * const t1 = expr1->getType()->isArrayTy() ? expr1->getType()->getArrayElementType() : expr1->getType();
197    const Type * const t2 = expr2->getType()->isArrayTy() ? expr2->getType()->getArrayElementType() : expr2->getType();
198    CHECK_SAME_TYPE(t1, t2);
199    Type * ty = getParent()->getInt1Ty();
200    if (t1->isVectorTy() || t2->isVectorTy()) {
201        ty = VectorType::get(ty, 0);
[5217]202    }
[5828]203    return new (mAllocator) Equals(ty, expr1, expr2, mAllocator);
[5217]204}
205
[5202]206Assign * PabloBlock::createAssign(PabloAST * const var, PabloAST * const value) {
[5217]207    CHECK_SAME_TYPE(var, value);
[5828]208    Var * test = nullptr;
209    if (isa<Extract>(var)) {
210        test = cast<Extract>(var)->getArray();
211    } else if (isa<Var>(var)) {
212        test = cast<Var>(var);
[5227]213    }
[5828]214    if (LLVM_UNLIKELY(test == nullptr || test->isReadOnly())) {
215        std::string tmp;
216        raw_string_ostream out(tmp);
217        out << "cannot assign ";
218        value->print(out);
219        out << " to ";
220        var->print(out);
221        out << ": ";
222        var->print(out);
223        if (test == nullptr) {
224            out << " must be an Extract expression or Var declaration";
[5227]225        } else {
[5828]226            out << " is read only";
[5227]227        }
[5828]228        report_fatal_error(out.str());
[5227]229    }
[5230]230    return insertAtInsertionPoint(new (mAllocator) Assign(var, value, mAllocator));
[4885]231}
232
[5202]233MatchStar * PabloBlock::createMatchStar(PabloAST * marker, PabloAST * charclass, String * name) {
[5217]234    CHECK_SAME_TYPE(marker, charclass);
[5202]235    if (name == nullptr) {
236        name = makeName("matchstar");
[4419]237    }
[5230]238    return insertAtInsertionPoint(new (mAllocator) MatchStar(marker, charclass, name, mAllocator));
[4410]239}
240
[5202]241ScanThru * PabloBlock::createScanThru(PabloAST * from, PabloAST * thru, String * name) {
[5217]242    CHECK_SAME_TYPE(from, thru);
[5202]243    if (name == nullptr) {
244        name = makeName("scanthru");
[4438]245    }
[5230]246    return insertAtInsertionPoint(new (mAllocator) ScanThru(from, thru, name, mAllocator));
[4438]247}
248
[5329]249ScanTo * PabloBlock::createScanTo(PabloAST * from, PabloAST * to, String * name) {
250    CHECK_SAME_TYPE(from, to);
251    if (name == nullptr) {
252        name = makeName("scanto");
253    }
254    return insertAtInsertionPoint(new (mAllocator) ScanTo(from, to, name, mAllocator));
255}
256
257AdvanceThenScanThru * PabloBlock::createAdvanceThenScanThru(PabloAST * from, PabloAST * thru, String * name) {
258    CHECK_SAME_TYPE(from, thru);
259    if (name == nullptr) {
260        name = makeName("advscanthru");
261    }
262    return insertAtInsertionPoint(new (mAllocator) AdvanceThenScanThru(from, thru, name, mAllocator));
263}
264
265AdvanceThenScanTo * PabloBlock::createAdvanceThenScanTo(PabloAST * from, PabloAST * to, String * name) {
266    CHECK_SAME_TYPE(from, to);
267    if (name == nullptr) {
268        name = makeName("advscanto");
269    }
270    return insertAtInsertionPoint(new (mAllocator) AdvanceThenScanTo(from, to, name, mAllocator));
271}
272
[5202]273If * PabloBlock::createIf(PabloAST * condition, PabloBlock * body) {
[5828]274    assert (condition && body);
[5230]275    If * const node = insertAtInsertionPoint(new (mAllocator) If(condition, body, mAllocator));
[5202]276    body->setBranch(node);
277    return node;
[4886]278}
279
[5202]280While * PabloBlock::createWhile(PabloAST * condition, PabloBlock * body) {
[5828]281    assert (condition && body);
[5230]282    While * const node = insertAtInsertionPoint(new (mAllocator) While(condition, body, mAllocator));
[5202]283    body->setBranch(node);
284    return node;
[4890]285}
286
[5828]287Repeat * PabloBlock::createRepeat(Integer * fieldWidth, PabloAST * value, String * name) {
288    assert (fieldWidth && value);
289    if (name == nullptr) {
290        name = makeName("fill");
291    }
292    Type * const type = VectorType::get(IntegerType::get(value->getType()->getContext(), fieldWidth->value()), 0);
293    return insertAtInsertionPoint(new (mAllocator) Repeat(fieldWidth, value, type, name, mAllocator));
294}
295
296PackH * PabloBlock::createPackH(Integer * fieldWidth, PabloAST * value, String * name) {
297    assert (fieldWidth && value);
298    if (name == nullptr) {
299        name = makeName("packh");
300    }
301    Type * const type = VectorType::get(IntegerType::get(value->getType()->getContext(), fieldWidth->value()), 0);
302    return insertAtInsertionPoint(new (mAllocator) PackH(fieldWidth, value, name, type, mAllocator));
303}
304
305PackL * PabloBlock::createPackL(Integer * fieldWidth, PabloAST * value, String * name) {
306    assert (fieldWidth && value);
307    if (name == nullptr) {
308        name = makeName("packl");
309    }
310    Type * const type = VectorType::get(IntegerType::get(value->getType()->getContext(), fieldWidth->value()), 0);
311    return insertAtInsertionPoint(new (mAllocator) PackL(fieldWidth, value, name, type, mAllocator));
312}
313
[5709]314/// TERNARY CREATE FUNCTIONS
[4214]315
[5202]316Sel * PabloBlock::createSel(PabloAST * condition, PabloAST * trueExpr, PabloAST * falseExpr, String * name) {
[5217]317    CHECK_SAME_TYPE(trueExpr, falseExpr);
[5202]318    if (name == nullptr) {
319        name = makeName("sel");
[4419]320    }
[5230]321    return insertAtInsertionPoint(new (mAllocator) Sel(condition, trueExpr, falseExpr, name, mAllocator));
[4410]322}
323
[5828]324IndexedAdvance * PabloBlock::createIndexedAdvance(PabloAST * expr, PabloAST * indexStream, Integer * shiftAmount, String * name) {
[5709]325    if (name == nullptr) {
326        name = makeName("indexed_advance");
327    }
328    return insertAtInsertionPoint(new (mAllocator) IndexedAdvance(expr, indexStream, shiftAmount, name, mAllocator));
329}
330   
331
[5202]332/** ------------------------------------------------------------------------------------------------------------- *
[5267]333 * @brief Create
334 ** ------------------------------------------------------------------------------------------------------------- */
335PabloBlock * PabloBlock::Create(PabloKernel * const parent) noexcept {
336    Allocator & allocator = parent->mAllocator;
337    return new (allocator) PabloBlock(parent, allocator);
338}
339
340/** ------------------------------------------------------------------------------------------------------------- *
[5202]341 * @brief insert
342 ** ------------------------------------------------------------------------------------------------------------- */
343void PabloBlock::insert(Statement * const statement) {
344    assert (statement);
345    if (LLVM_UNLIKELY(mInsertionPoint == nullptr)) {
346        if (mFirst) {
347            statement->insertBefore(mFirst);
348        } else {
349            statement->removeFromParent();
350            statement->mParent = this;
351            mFirst = mLast = statement;
352        }
353    } else if (LLVM_LIKELY(statement != mInsertionPoint)) {
354        statement->insertAfter(mInsertionPoint);
355        mLast = (mLast == mInsertionPoint) ? statement : mLast;
356        assert (statement->mPrev == mInsertionPoint);
[4438]357    }
[5202]358    mInsertionPoint = statement;
[4438]359}
360
[4870]361/** ------------------------------------------------------------------------------------------------------------- *
362 * @brief eraseFromParent
363 ** ------------------------------------------------------------------------------------------------------------- */
364void PabloBlock::eraseFromParent(const bool recursively) {
365    Statement * stmt = front();
366    while (stmt) {
367        stmt = stmt->eraseFromParent(recursively);
368    }
369}
370
[5245]371/** ------------------------------------------------------------------------------------------------------------- *
[5267]372 * @brief getPredecessor
373 ** ------------------------------------------------------------------------------------------------------------- */
374PabloBlock * PabloBlock::getPredecessor() const {
375    return getBranch() ? getBranch()->getParent() : nullptr;
376}
377
378/** ------------------------------------------------------------------------------------------------------------- *
[5245]379 * @brief print
380 ** ------------------------------------------------------------------------------------------------------------- */
381void PabloBlock::print(raw_ostream & O, const bool expandNested) const {
382    PabloPrinter::print(this, O, expandNested);
[4416]383}
[5245]384
385}
Note: See TracBrowser for help on using the repository browser.