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

Last change on this file since 5836 was 5836, checked in by nmedfort, 18 months ago

Added PabloBlock/Builder? createScope() methods + minor code changes.

File size: 12.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
[5836]51Count * PabloBlock::createCount(PabloAST * const expr, const String * const name)  {
[5446]52    IntegerType * const type = getParent()->getSizeTy();
[5836]53    return insertAtInsertionPoint(new (mAllocator) Count(expr, name, type, mAllocator));
[4213]54}
55
[5836]56Not * PabloBlock::createNot(PabloAST * expr, const String * const name) {
[5202]57    assert (expr);
[5230]58    return insertAtInsertionPoint(new (mAllocator) Not(expr, name, mAllocator));
[4438]59}
60
[5836]61Var * PabloBlock::createVar(const String * const name, Type * type) {
[5202]62    if (type == nullptr) {
[5446]63        type = getParent()->getStreamTy();
[4959]64    }
[5834]65    if (LLVM_UNLIKELY(name == nullptr)) {
[5202]66        throw std::runtime_error("Var objects must have a String name");
[4959]67    }
[5836]68    return mParent->makeVariable(name, type);
[4959]69}
70
[5836]71InFile * PabloBlock::createInFile(PabloAST * expr, const String * const name) {
[4433]72    assert (expr);
[5230]73    return insertAtInsertionPoint(new (mAllocator) InFile(expr, name, mAllocator));
[4213]74}
75
[5836]76AtEOF * PabloBlock::createAtEOF(PabloAST * expr, const String * const name) {
[4438]77    assert (expr);
[5230]78    return insertAtInsertionPoint(new (mAllocator) AtEOF(expr, name, mAllocator));
[4438]79}
[5828]80
[5202]81/// BINARY CREATE FUNCTIONS
[5042]82
[5836]83Advance * PabloBlock::createAdvance(PabloAST * expr, Integer * shiftAmount, const String * const name) {
[5230]84    return insertAtInsertionPoint(new (mAllocator) Advance(expr, shiftAmount, name, mAllocator));
[4252]85}
86
[5836]87Lookahead * PabloBlock::createLookahead(PabloAST * expr, Integer * shiftAmount, const String * const name) {
[5230]88    return insertAtInsertionPoint(new (mAllocator) Lookahead(expr, shiftAmount, name, mAllocator));
[4438]89}
90
[5828]91Extract * PabloBlock::createExtract(Var * array, Integer * index) {
[5202]92    assert (array && index);
[5227]93    Type * type = array->getType();
[5230]94    if (LLVM_LIKELY(isa<ArrayType>(type))) {
[5227]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);
[5828]101        out << ": ";
102        type->print(out);
103        out << " is not an array type";
[5227]104        throw std::runtime_error(out.str());
[5217]105    }
[5828]106    return new (mAllocator) Extract(array, index, type, mAllocator);
[4252]107}
108
[5836]109And * PabloBlock::createAnd(PabloAST * expr1, PabloAST * expr2, const String * const name) {
[5217]110    CHECK_SAME_TYPE(expr1, expr2);
[5230]111    return insertAtInsertionPoint(new (mAllocator) And(expr1->getType(), expr1, expr2, name, mAllocator));
[4438]112}
113
[5836]114Or * PabloBlock::createOr(PabloAST * expr1, PabloAST * expr2, const String * const name) {
[5217]115    CHECK_SAME_TYPE(expr1, expr2);
[5230]116    return insertAtInsertionPoint(new (mAllocator) Or(expr1->getType(), expr1, expr2, name, mAllocator));
[4410]117}
118
[5836]119Xor * PabloBlock::createXor(PabloAST * expr1, PabloAST * expr2, const String * const name) {
[5217]120    CHECK_SAME_TYPE(expr1, expr2);
[5230]121    return insertAtInsertionPoint(new (mAllocator) Xor(expr1->getType(), expr1, expr2, name, mAllocator));
[4410]122}
123
[5227]124Add * PabloBlock::createAdd(PabloAST * expr1, PabloAST * expr2) {
[5217]125    CHECK_SAME_TYPE(expr1, expr2);
[5230]126    return new (mAllocator) Add(expr1->getType(), expr1, expr2, mAllocator);
[5217]127}
128
[5227]129Subtract * PabloBlock::createSubtract(PabloAST * expr1, PabloAST * expr2) {
[5217]130    CHECK_SAME_TYPE(expr1, expr2);
[5230]131    return new (mAllocator) Subtract(expr1->getType(), expr1, expr2, mAllocator);
[5227]132}
133
134LessThan * PabloBlock::createLessThan(PabloAST * expr1, PabloAST * expr2) {
[5828]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);
[5227]143}
144
[5828]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);
[5217]152    }
[5828]153    return new (mAllocator) Equals(ty, expr1, expr2, mAllocator);
[5217]154}
155
[5202]156Assign * PabloBlock::createAssign(PabloAST * const var, PabloAST * const value) {
[5217]157    CHECK_SAME_TYPE(var, value);
[5828]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);
[5227]163    }
[5828]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";
[5227]175        } else {
[5828]176            out << " is read only";
[5227]177        }
[5828]178        report_fatal_error(out.str());
[5227]179    }
[5230]180    return insertAtInsertionPoint(new (mAllocator) Assign(var, value, mAllocator));
[4885]181}
182
[5836]183MatchStar * PabloBlock::createMatchStar(PabloAST * marker, PabloAST * charclass, const String * const name) {
[5217]184    CHECK_SAME_TYPE(marker, charclass);
[5230]185    return insertAtInsertionPoint(new (mAllocator) MatchStar(marker, charclass, name, mAllocator));
[4410]186}
187
[5836]188ScanThru * PabloBlock::createScanThru(PabloAST * from, PabloAST * thru, const String * const name) {
[5217]189    CHECK_SAME_TYPE(from, thru);
[5230]190    return insertAtInsertionPoint(new (mAllocator) ScanThru(from, thru, name, mAllocator));
[4438]191}
192
[5836]193ScanTo * PabloBlock::createScanTo(PabloAST * from, PabloAST * to, const String * const name) {
[5329]194    CHECK_SAME_TYPE(from, to);
195    return insertAtInsertionPoint(new (mAllocator) ScanTo(from, to, name, mAllocator));
196}
197
[5836]198AdvanceThenScanThru * PabloBlock::createAdvanceThenScanThru(PabloAST * from, PabloAST * thru, const String * const name) {
[5329]199    CHECK_SAME_TYPE(from, thru);
200    return insertAtInsertionPoint(new (mAllocator) AdvanceThenScanThru(from, thru, name, mAllocator));
201}
202
[5836]203AdvanceThenScanTo * PabloBlock::createAdvanceThenScanTo(PabloAST * from, PabloAST * to, const String * const name) {
[5329]204    CHECK_SAME_TYPE(from, to);
205    return insertAtInsertionPoint(new (mAllocator) AdvanceThenScanTo(from, to, name, mAllocator));
206}
207
[5202]208If * PabloBlock::createIf(PabloAST * condition, PabloBlock * body) {
[5828]209    assert (condition && body);
[5230]210    If * const node = insertAtInsertionPoint(new (mAllocator) If(condition, body, mAllocator));
[5202]211    body->setBranch(node);
212    return node;
[4886]213}
214
[5202]215While * PabloBlock::createWhile(PabloAST * condition, PabloBlock * body) {
[5828]216    assert (condition && body);
[5230]217    While * const node = insertAtInsertionPoint(new (mAllocator) While(condition, body, mAllocator));
[5202]218    body->setBranch(node);
219    return node;
[4890]220}
221
[5836]222Repeat * PabloBlock::createRepeat(Integer * fieldWidth, PabloAST * value, const String * const name) {
[5828]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
[5836]228PackH * PabloBlock::createPackH(Integer * fieldWidth, PabloAST * value, const String * const name) {
[5828]229    assert (fieldWidth && value);
230    Type * const type = VectorType::get(IntegerType::get(value->getType()->getContext(), fieldWidth->value()), 0);
231    return insertAtInsertionPoint(new (mAllocator) PackH(fieldWidth, value, name, type, mAllocator));
232}
233
[5836]234PackL * PabloBlock::createPackL(Integer * fieldWidth, PabloAST * value, const String * const name) {
[5828]235    assert (fieldWidth && value);
236    Type * const type = VectorType::get(IntegerType::get(value->getType()->getContext(), fieldWidth->value()), 0);
237    return insertAtInsertionPoint(new (mAllocator) PackL(fieldWidth, value, name, type, mAllocator));
238}
239
[5709]240/// TERNARY CREATE FUNCTIONS
[4214]241
[5836]242Sel * PabloBlock::createSel(PabloAST * condition, PabloAST * trueExpr, PabloAST * falseExpr, const String * const name) {
[5217]243    CHECK_SAME_TYPE(trueExpr, falseExpr);
[5230]244    return insertAtInsertionPoint(new (mAllocator) Sel(condition, trueExpr, falseExpr, name, mAllocator));
[4410]245}
246
[5836]247IndexedAdvance * PabloBlock::createIndexedAdvance(PabloAST * expr, PabloAST * indexStream, Integer * shiftAmount, const String * const name) {
[5709]248    return insertAtInsertionPoint(new (mAllocator) IndexedAdvance(expr, indexStream, shiftAmount, name, mAllocator));
249}
250   
251
[5202]252/** ------------------------------------------------------------------------------------------------------------- *
[5836]253 * @brief createScope
[5267]254 ** ------------------------------------------------------------------------------------------------------------- */
[5836]255PabloBlock & PabloBlock::createScope() noexcept {
256    return *new (mAllocator) PabloBlock(mParent, mAllocator);
[5267]257}
258
259/** ------------------------------------------------------------------------------------------------------------- *
[5202]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);
[4438]276    }
[5202]277    mInsertionPoint = statement;
[4438]278}
279
[4870]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
[5245]290/** ------------------------------------------------------------------------------------------------------------- *
[5267]291 * @brief getPredecessor
292 ** ------------------------------------------------------------------------------------------------------------- */
293PabloBlock * PabloBlock::getPredecessor() const {
294    return getBranch() ? getBranch()->getParent() : nullptr;
295}
296
297/** ------------------------------------------------------------------------------------------------------------- *
[5245]298 * @brief print
299 ** ------------------------------------------------------------------------------------------------------------- */
300void PabloBlock::print(raw_ostream & O, const bool expandNested) const {
301    PabloPrinter::print(this, O, expandNested);
[4416]302}
[5245]303
304}
Note: See TracBrowser for help on using the repository browser.