Ignore:
Timestamp:
Jan 13, 2018, 11:57:43 AM (12 months ago)
Author:
nmedfort
Message:

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/pablo/pablo_compiler.cpp

    r5782 r5828  
    2222#include <pablo/pe_zeroes.h>
    2323#include <pablo/pe_ones.h>
     24#include <pablo/pe_repeat.h>
     25#include <pablo/pe_pack.h>
    2426#include <pablo/pe_var.h>
    2527#include <pablo/ps_assign.h>
     
    4850}
    4951
    50 void PabloCompiler::initializeKernelData(const std::unique_ptr<kernel::KernelBuilder> & iBuilder) {
    51     assert ("PabloCompiler does not have a IDISA iBuilder" && iBuilder);
     52void PabloCompiler::initializeKernelData(const std::unique_ptr<kernel::KernelBuilder> & b) {
    5253    mBranchCount = 0;
    53     examineBlock(iBuilder, mKernel->getEntryBlock());
    54     mCarryManager->initializeCarryData(iBuilder, mKernel);
     54    examineBlock(b, mKernel->getEntryBlock());
     55    mCarryManager->initializeCarryData(b, mKernel);
    5556    if (CompileOptionIsSet(PabloCompilationFlags::EnableProfiling)) {
    5657        const auto count = (mBranchCount * 2) + 1;
     
    6061}
    6162
    62 void PabloCompiler::releaseKernelData(const std::unique_ptr<kernel::KernelBuilder> & iBuilder) {
    63     assert ("PabloCompiler does not have a IDISA iBuilder" && iBuilder);
    64     mCarryManager->releaseCarryData(iBuilder);
    65 }
    66 
    67 void PabloCompiler::compile(const std::unique_ptr<kernel::KernelBuilder> & iBuilder) {
    68     assert ("PabloCompiler does not have a IDISA iBuilder" && iBuilder);
    69     mCarryManager->initializeCodeGen(iBuilder);
     63void PabloCompiler::releaseKernelData(const std::unique_ptr<kernel::KernelBuilder> & b) {
     64    mCarryManager->releaseCarryData(b);
     65}
     66
     67void PabloCompiler::clearCarryData(const std::unique_ptr<kernel::KernelBuilder> & b) {
     68    mCarryManager->clearCarryData(b);
     69}
     70
     71void PabloCompiler::compile(const std::unique_ptr<kernel::KernelBuilder> & b) {
     72    mCarryManager->initializeCodeGen(b);
    7073    PabloBlock * const entryBlock = mKernel->getEntryBlock(); assert (entryBlock);
    71     mMarker.emplace(entryBlock->createZeroes(), iBuilder->allZeroes());
    72     mMarker.emplace(entryBlock->createOnes(), iBuilder->allOnes());
     74    mMarker.emplace(entryBlock->createZeroes(), b->allZeroes());
     75    mMarker.emplace(entryBlock->createOnes(), b->allOnes());
    7376    mBranchCount = 0;
    74     addBranchCounter(iBuilder);
    75     compileBlock(iBuilder, entryBlock);
    76     mCarryManager->finalizeCodeGen(iBuilder);
    77 }
    78 
    79 void PabloCompiler::examineBlock(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, const PabloBlock * const block) {
     77    addBranchCounter(b);
     78    compileBlock(b, entryBlock);
     79    mCarryManager->finalizeCodeGen(b);
     80}
     81
     82void PabloCompiler::examineBlock(const std::unique_ptr<kernel::KernelBuilder> & b, const PabloBlock * const block) {
    8083    for (const Statement * stmt : *block) {
    8184        if (LLVM_UNLIKELY(isa<Lookahead>(stmt))) {
     
    107110        } else if (LLVM_UNLIKELY(isa<Branch>(stmt))) {
    108111            ++mBranchCount;
    109             examineBlock(iBuilder, cast<Branch>(stmt)->getBody());
     112            examineBlock(b, cast<Branch>(stmt)->getBody());
    110113        } else if (LLVM_UNLIKELY(isa<Count>(stmt))) {
    111             mAccumulator.insert(std::make_pair(stmt, iBuilder->getInt32(mKernel->addUnnamedScalar(stmt->getType()))));
     114            mAccumulator.insert(std::make_pair(stmt, b->getInt32(mKernel->addUnnamedScalar(stmt->getType()))));
    112115        }
    113116    }   
    114117}
    115118
    116 void PabloCompiler::addBranchCounter(const std::unique_ptr<kernel::KernelBuilder> & iBuilder) {
     119void PabloCompiler::addBranchCounter(const std::unique_ptr<kernel::KernelBuilder> & b) {
    117120    if (CompileOptionIsSet(PabloCompilationFlags::EnableProfiling)) {       
    118         Value * ptr = iBuilder->getScalarFieldPtr("profile");
     121        Value * ptr = b->getScalarFieldPtr("profile");
    119122        assert (mBasicBlock.size() < ptr->getType()->getPointerElementType()->getArrayNumElements());
    120         ptr = iBuilder->CreateGEP(ptr, {iBuilder->getInt32(0), iBuilder->getInt32(mBasicBlock.size())});
     123        ptr = b->CreateGEP(ptr, {b->getInt32(0), b->getInt32(mBasicBlock.size())});
    121124        const auto alignment = getPointerElementAlignment(ptr);
    122         Value * value = iBuilder->CreateAlignedLoad(ptr, alignment, false, "branchCounter");
    123         value = iBuilder->CreateAdd(value, ConstantInt::get(cast<IntegerType>(value->getType()), 1));
    124         iBuilder->CreateAlignedStore(value, ptr, alignment);
    125         mBasicBlock.push_back(iBuilder->GetInsertBlock());
    126     }
    127 }
    128 
    129 inline void PabloCompiler::compileBlock(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, const PabloBlock * const block) {
     125        Value * value = b->CreateAlignedLoad(ptr, alignment, false, "branchCounter");
     126        value = b->CreateAdd(value, ConstantInt::get(cast<IntegerType>(value->getType()), 1));
     127        b->CreateAlignedStore(value, ptr, alignment);
     128        mBasicBlock.push_back(b->GetInsertBlock());
     129    }
     130}
     131
     132inline void PabloCompiler::compileBlock(const std::unique_ptr<kernel::KernelBuilder> & b, const PabloBlock * const block) {
    130133    for (const Statement * statement : *block) {
    131         compileStatement(iBuilder, statement);
    132     }
    133 }
    134 
    135 void PabloCompiler::compileIf(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, const If * const ifStatement) {
     134        compileStatement(b, statement);
     135    }
     136}
     137
     138void PabloCompiler::compileIf(const std::unique_ptr<kernel::KernelBuilder> & b, const If * const ifStatement) {
    136139    //
    137140    //  The If-ElseZero stmt:
     
    152155    //
    153156
    154     BasicBlock * const ifEntryBlock = iBuilder->GetInsertBlock();
     157    BasicBlock * const ifEntryBlock = b->GetInsertBlock();
    155158    ++mBranchCount;
    156     BasicBlock * const ifBodyBlock = iBuilder->CreateBasicBlock("if.body_" + std::to_string(mBranchCount));
    157     BasicBlock * const ifEndBlock = iBuilder->CreateBasicBlock("if.end_" + std::to_string(mBranchCount));
     159    BasicBlock * const ifBodyBlock = b->CreateBasicBlock("if.body_" + std::to_string(mBranchCount));
     160    BasicBlock * const ifEndBlock = b->CreateBasicBlock("if.end_" + std::to_string(mBranchCount));
    158161   
    159162    std::vector<std::pair<const Var *, Value *>> incoming;
     
    163166            Value * marker = nullptr;
    164167            if (var->isScalar()) {
    165                 marker = iBuilder->getScalarFieldPtr(var->getName());
     168                marker = b->getScalarFieldPtr(var->getName());
    166169            } else if (var->isReadOnly()) {
    167                 marker = iBuilder->getInputStreamBlockPtr(var->getName(), iBuilder->getInt32(0));
     170                marker = b->getInputStreamBlockPtr(var->getName(), b->getInt32(0));
    168171            } else if (var->isReadNone()) {
    169                 marker = iBuilder->getOutputStreamBlockPtr(var->getName(), iBuilder->getInt32(0));
     172                marker = b->getOutputStreamBlockPtr(var->getName(), b->getInt32(0));
    170173            }
    171174            mMarker[var] = marker;
     
    186189    const PabloBlock * ifBody = ifStatement->getBody();
    187190   
    188     mCarryManager->enterIfScope(iBuilder, ifBody);
    189 
    190     Value * condition = compileExpression(iBuilder, ifStatement->getCondition());
    191     if (condition->getType() == iBuilder->getBitBlockType()) {
    192         condition = iBuilder->bitblock_any(mCarryManager->generateSummaryTest(iBuilder, condition));
     191    mCarryManager->enterIfScope(b, ifBody);
     192
     193    Value * condition = compileExpression(b, ifStatement->getCondition());
     194    if (condition->getType() == b->getBitBlockType()) {
     195        condition = b->bitblock_any(mCarryManager->generateSummaryTest(b, condition));
    193196    }
    194197   
    195     iBuilder->CreateCondBr(condition, ifBodyBlock, ifEndBlock);
     198    b->CreateCondBr(condition, ifBodyBlock, ifEndBlock);
    196199   
    197200    // Entry processing is complete, now handle the body of the if.
    198     iBuilder->SetInsertPoint(ifBodyBlock);
    199 
    200     mCarryManager->enterIfBody(iBuilder, ifEntryBlock);
    201 
    202     addBranchCounter(iBuilder);
    203 
    204     compileBlock(iBuilder, ifBody);
    205 
    206     mCarryManager->leaveIfBody(iBuilder, iBuilder->GetInsertBlock());
    207 
    208     BasicBlock * ifExitBlock = iBuilder->GetInsertBlock();
    209 
    210     iBuilder->CreateBr(ifEndBlock);
     201    b->SetInsertPoint(ifBodyBlock);
     202
     203    mCarryManager->enterIfBody(b, ifEntryBlock);
     204
     205    addBranchCounter(b);
     206
     207    compileBlock(b, ifBody);
     208
     209    mCarryManager->leaveIfBody(b, b->GetInsertBlock());
     210
     211    BasicBlock * ifExitBlock = b->GetInsertBlock();
     212
     213    b->CreateBr(ifEndBlock);
    211214
    212215    ifEndBlock->moveAfter(ifExitBlock);
    213216
    214217    //End Block
    215     iBuilder->SetInsertPoint(ifEndBlock);
    216 
    217     mCarryManager->leaveIfScope(iBuilder, ifEntryBlock, ifExitBlock);
     218    b->SetInsertPoint(ifEndBlock);
     219
     220    mCarryManager->leaveIfScope(b, ifEntryBlock, ifExitBlock);
    218221
    219222    for (const auto i : incoming) {
     
    250253        }
    251254
    252         PHINode * phi = iBuilder->CreatePHI(incoming->getType(), 2, var->getName());
     255        PHINode * phi = b->CreatePHI(incoming->getType(), 2, var->getName());
    253256        phi->addIncoming(incoming, ifEntryBlock);
    254257        phi->addIncoming(outgoing, ifExitBlock);
     
    256259    }
    257260
    258     addBranchCounter(iBuilder);
    259 }
    260 
    261 void PabloCompiler::compileWhile(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, const While * const whileStatement) {
     261    addBranchCounter(b);
     262}
     263
     264void PabloCompiler::compileWhile(const std::unique_ptr<kernel::KernelBuilder> & b, const While * const whileStatement) {
    262265
    263266    const PabloBlock * const whileBody = whileStatement->getBody();
    264267
    265     BasicBlock * whileEntryBlock = iBuilder->GetInsertBlock();
     268    BasicBlock * whileEntryBlock = b->GetInsertBlock();
    266269
    267270    const auto escaped = whileStatement->getEscaped();
     
    278281            Value * marker = nullptr;
    279282            if (var->isScalar()) {
    280                 marker = iBuilder->getScalarFieldPtr(var->getName());
     283                marker = b->getScalarFieldPtr(var->getName());
    281284            } else if (var->isReadOnly()) {
    282                 marker = iBuilder->getInputStreamBlockPtr(var->getName(), iBuilder->getInt32(0));
     285                marker = b->getInputStreamBlockPtr(var->getName(), b->getInt32(0));
    283286            } else if (var->isReadNone()) {
    284                 marker = iBuilder->getOutputStreamBlockPtr(var->getName(), iBuilder->getInt32(0));
     287                marker = b->getOutputStreamBlockPtr(var->getName(), b->getInt32(0));
    285288            }
    286289            mMarker[var] = marker;
     
    288291    }
    289292
    290     mCarryManager->enterLoopScope(iBuilder, whileBody);
    291 
    292     BasicBlock * whileBodyBlock = iBuilder->CreateBasicBlock("while.body_" + std::to_string(mBranchCount));
    293     BasicBlock * whileEndBlock = iBuilder->CreateBasicBlock("while.end_" + std::to_string(mBranchCount));
     293    mCarryManager->enterLoopScope(b, whileBody);
     294
     295    BasicBlock * whileBodyBlock = b->CreateBasicBlock("while.body_" + std::to_string(mBranchCount));
     296    BasicBlock * whileEndBlock = b->CreateBasicBlock("while.end_" + std::to_string(mBranchCount));
    294297    ++mBranchCount;
    295298
    296     iBuilder->CreateBr(whileBodyBlock);
    297 
    298     iBuilder->SetInsertPoint(whileBodyBlock);
     299    b->CreateBr(whileBodyBlock);
     300
     301    b->SetInsertPoint(whileBodyBlock);
    299302
    300303    //
     
    322325        }
    323326        Value * entryValue = f->second;
    324         PHINode * phi = iBuilder->CreatePHI(entryValue->getType(), 2, var->getName());
     327        PHINode * phi = b->CreatePHI(entryValue->getType(), 2, var->getName());
    325328        phi->addIncoming(entryValue, whileEntryBlock);
    326329        f->second = phi;
     
    330333#ifdef ENABLE_BOUNDED_WHILE
    331334    if (whileStatement->getBound()) {
    332         bound_phi = iBuilder->CreatePHI(iBuilder->getSizeTy(), 2, "while_bound");
    333         bound_phi->addIncoming(iBuilder->getSize(whileStatement->getBound()), whileEntryBlock);
     335        bound_phi = b->CreatePHI(b->getSizeTy(), 2, "while_bound");
     336        bound_phi->addIncoming(b->getSize(whileStatement->getBound()), whileEntryBlock);
    334337    }
    335338#endif
    336339
    337     mCarryManager->enterLoopBody(iBuilder, whileEntryBlock);
    338 
    339     addBranchCounter(iBuilder);
    340 
    341     compileBlock(iBuilder, whileBody);
     340    mCarryManager->enterLoopBody(b, whileEntryBlock);
     341
     342    addBranchCounter(b);
     343
     344    compileBlock(b, whileBody);
    342345
    343346    // After the whileBody has been compiled, we may be in a different basic block.
    344347
    345     mCarryManager->leaveLoopBody(iBuilder, iBuilder->GetInsertBlock());
     348    mCarryManager->leaveLoopBody(b, b->GetInsertBlock());
    346349
    347350
    348351#ifdef ENABLE_BOUNDED_WHILE
    349352    if (whileStatement->getBound()) {
    350         Value * new_bound = iBuilder->CreateSub(bound_phi, iBuilder->getSize(1));
     353        Value * new_bound = b->CreateSub(bound_phi, b->getSize(1));
    351354        bound_phi->addIncoming(new_bound, whileExitBlock);
    352         condition = iBuilder->CreateAnd(condition, iBuilder->CreateICmpUGT(new_bound, ConstantInt::getNullValue(iBuilder->getSizeTy())));
     355        condition = b->CreateAnd(condition, b->CreateICmpUGT(new_bound, ConstantInt::getNullValue(b->getSizeTy())));
    353356    }
    354357#endif
    355358
    356     BasicBlock * const whileExitBlock = iBuilder->GetInsertBlock();
     359    BasicBlock * const whileExitBlock = b->GetInsertBlock();
    357360
    358361    // and for any variant nodes in the loop body
     
    390393
    391394    // Terminate the while loop body with a conditional branch back.
    392     Value * condition = compileExpression(iBuilder, whileStatement->getCondition());
    393     if (condition->getType() == iBuilder->getBitBlockType()) {
    394         condition = iBuilder->bitblock_any(mCarryManager->generateSummaryTest(iBuilder, condition));
    395     }
    396 
    397     iBuilder->CreateCondBr(condition, whileBodyBlock, whileEndBlock);
     395    Value * condition = compileExpression(b, whileStatement->getCondition());
     396    if (condition->getType() == b->getBitBlockType()) {
     397        condition = b->bitblock_any(mCarryManager->generateSummaryTest(b, condition));
     398    }
     399
     400    b->CreateCondBr(condition, whileBodyBlock, whileEndBlock);
    398401
    399402    whileEndBlock->moveAfter(whileExitBlock);
    400403
    401     iBuilder->SetInsertPoint(whileEndBlock);
    402 
    403     mCarryManager->leaveLoopScope(iBuilder, whileEntryBlock, whileExitBlock);
    404 
    405     addBranchCounter(iBuilder);
    406 }
    407 
    408 void PabloCompiler::compileStatement(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, const Statement * const stmt) {
     404    b->SetInsertPoint(whileEndBlock);
     405
     406    mCarryManager->leaveLoopScope(b, whileEntryBlock, whileExitBlock);
     407
     408    addBranchCounter(b);
     409}
     410
     411void PabloCompiler::compileStatement(const std::unique_ptr<kernel::KernelBuilder> & b, const Statement * const stmt) {
    409412
    410413    if (LLVM_UNLIKELY(isa<If>(stmt))) {
    411         compileIf(iBuilder, cast<If>(stmt));
     414        compileIf(b, cast<If>(stmt));
    412415    } else if (LLVM_UNLIKELY(isa<While>(stmt))) {
    413         compileWhile(iBuilder, cast<While>(stmt));
     416        compileWhile(b, cast<While>(stmt));
    414417    } else {
    415418        const PabloAST * expr = stmt;
    416419        Value * value = nullptr;
    417         if (LLVM_UNLIKELY(isa<Assign>(stmt))) {
    418             value = compileExpression(iBuilder, cast<Assign>(stmt)->getValue());
    419             expr = cast<Assign>(stmt)->getVariable();
    420             Value * ptr = nullptr;
    421             if (LLVM_LIKELY(isa<Var>(expr))) {
    422                 const Var * var = cast<Var>(expr);
    423                 if (LLVM_UNLIKELY(var->isReadOnly())) {
    424                     std::string tmp;
    425                     raw_string_ostream out(tmp);
    426                     out << mKernel->getName();
    427                     out << " cannot assign value to ";
    428                     var->print(out);
    429                     out << ": ";
    430                     var->print(out);
    431                     out << " is read only";
    432                     report_fatal_error(out.str());
    433                 }
    434                 if (var->isKernelParameter()) {
    435                     if (var->isScalar()) {
    436                         ptr = iBuilder->getScalarFieldPtr(var->getName());
    437                     } else {
    438                         ptr = iBuilder->getOutputStreamBlockPtr(var->getName(), iBuilder->getInt32(0));
    439                     }
    440                 }
    441             } else if (isa<Extract>(expr)) {
    442                 const auto f = mMarker.find(expr);
    443                 if (LLVM_UNLIKELY(f == mMarker.end())) {
    444                     std::string tmp;
    445                     raw_string_ostream out(tmp);
    446                     out << mKernel->getName();
    447                     out << " cannot assign value to ";
    448                     expr->print(out);
    449                     out << ": ";
    450                     expr->print(out);
    451                     out << " does not dominate ";
    452                     stmt->print(out);
    453                     report_fatal_error(out.str());
    454                 }
    455                 ptr = f->second;
    456                 assert (ptr);
    457             }
    458             if (ptr) {
    459                 iBuilder->CreateAlignedStore(value, ptr, getAlignment(value));
    460                 value = ptr;
    461             }
    462         } else if (const Extract * extract = dyn_cast<Extract>(stmt)) {
    463             Value * index = compileExpression(iBuilder, extract->getIndex());
    464             Var * const array = dyn_cast<Var>(extract->getArray());
    465             if (LLVM_LIKELY(array && array->isKernelParameter())) {
    466                 if (array->isReadOnly()) {
    467                     value = iBuilder->getInputStreamBlockPtr(array->getName(), index);
    468                     value = iBuilder->CreateLoad(value);
    469                 } else if (array->isReadNone()) {
    470                     value = iBuilder->getOutputStreamBlockPtr(array->getName(), index);
    471                 } else {
    472                     std::string tmp;
    473                     raw_string_ostream out(tmp);
    474                     out << mKernel->getName();
    475                     out << " stream ";
    476                     expr->print(out);
    477                     out << " cannot be read or written to";
    478                     report_fatal_error(out.str());
    479                 }
    480             } else {
    481                 Value * ptr = compileExpression(iBuilder, extract->getArray(), false);
    482                 value = iBuilder->CreateGEP(ptr, {ConstantInt::getNullValue(index->getType()), index}, "extract");
    483             }
    484         } else if (isa<And>(stmt)) {
    485             value = compileExpression(iBuilder, stmt->getOperand(0));
     420        if (isa<And>(stmt)) {
     421            value = compileExpression(b, stmt->getOperand(0));
    486422            for (unsigned i = 1; i < stmt->getNumOperands(); ++i) {
    487                 value = iBuilder->simd_and(value, compileExpression(iBuilder, stmt->getOperand(1)));
     423                value = b->simd_and(value, compileExpression(b, stmt->getOperand(1)));
    488424            }
    489425        } else if (isa<Or>(stmt)) {
    490             value = compileExpression(iBuilder, stmt->getOperand(0));
     426            value = compileExpression(b, stmt->getOperand(0));
    491427            for (unsigned i = 1; i < stmt->getNumOperands(); ++i) {
    492                 value = iBuilder->simd_or(value, compileExpression(iBuilder, stmt->getOperand(1)));
     428                value = b->simd_or(value, compileExpression(b, stmt->getOperand(1)));
    493429            }
    494430        } else if (isa<Xor>(stmt)) {
    495             value = compileExpression(iBuilder, stmt->getOperand(0));
     431            value = compileExpression(b, stmt->getOperand(0));
    496432            for (unsigned i = 1; i < stmt->getNumOperands(); ++i) {
    497                 value = iBuilder->simd_xor(value, compileExpression(iBuilder, stmt->getOperand(1)));
     433                value = b->simd_xor(value, compileExpression(b, stmt->getOperand(1)));
    498434            }
    499435        } else if (const Sel * sel = dyn_cast<Sel>(stmt)) {
    500             Value* ifMask = compileExpression(iBuilder, sel->getCondition());
    501             Value* ifTrue = iBuilder->simd_and(ifMask, compileExpression(iBuilder, sel->getTrueExpr()));
    502             Value* ifFalse = iBuilder->simd_and(iBuilder->simd_not(ifMask), compileExpression(iBuilder, sel->getFalseExpr()));
    503             value = iBuilder->simd_or(ifTrue, ifFalse);
     436            Value* ifMask = compileExpression(b, sel->getCondition());
     437            Value* ifTrue = b->simd_and(ifMask, compileExpression(b, sel->getTrueExpr()));
     438            Value* ifFalse = b->simd_and(b->simd_not(ifMask), compileExpression(b, sel->getFalseExpr()));
     439            value = b->simd_or(ifTrue, ifFalse);
    504440        } else if (isa<Not>(stmt)) {
    505             value = iBuilder->simd_not(compileExpression(iBuilder, stmt->getOperand(0)));
     441            value = b->simd_not(compileExpression(b, stmt->getOperand(0)));
    506442        } else if (isa<Advance>(stmt)) {
    507443            const Advance * const adv = cast<Advance>(stmt);
    508444            // If our expr is an Extract op on a mutable Var then we need to pass the index value to the carry
    509445            // manager so that it properly selects the correct carry bit.
    510             value = mCarryManager->advanceCarryInCarryOut(iBuilder, adv, compileExpression(iBuilder, adv->getExpression()));
     446            value = mCarryManager->advanceCarryInCarryOut(b, adv, compileExpression(b, adv->getExpression()));
    511447        } else if (isa<IndexedAdvance>(stmt)) {
    512448            const IndexedAdvance * const adv = cast<IndexedAdvance>(stmt);
    513             Value * strm = compileExpression(iBuilder, adv->getExpression());
    514             Value * index_strm = compileExpression(iBuilder, adv->getIndex());
     449            Value * strm = compileExpression(b, adv->getExpression());
     450            Value * index_strm = compileExpression(b, adv->getIndex());
    515451            // If our expr is an Extract op on a mutable Var then we need to pass the index value to the carry
    516452            // manager so that it properly selects the correct carry bit.
    517             value = mCarryManager->indexedAdvanceCarryInCarryOut(iBuilder, adv, strm, index_strm);
     453            value = mCarryManager->indexedAdvanceCarryInCarryOut(b, adv, strm, index_strm);
    518454        } else if (const MatchStar * mstar = dyn_cast<MatchStar>(stmt)) {
    519             Value * const marker = compileExpression(iBuilder, mstar->getMarker());
    520             Value * const cc = compileExpression(iBuilder, mstar->getCharClass());
    521             Value * const marker_and_cc = iBuilder->simd_and(marker, cc);
    522             Value * const sum = mCarryManager->addCarryInCarryOut(iBuilder, mstar, marker_and_cc, cc);
    523             value = iBuilder->simd_or(iBuilder->simd_xor(sum, cc), marker);
     455            Value * const marker = compileExpression(b, mstar->getMarker());
     456            Value * const cc = compileExpression(b, mstar->getCharClass());
     457            Value * const marker_and_cc = b->simd_and(marker, cc);
     458            Value * const sum = mCarryManager->addCarryInCarryOut(b, mstar, marker_and_cc, cc);
     459            value = b->simd_or(b->simd_xor(sum, cc), marker);
    524460        } else if (const ScanThru * sthru = dyn_cast<ScanThru>(stmt)) {
    525             Value * const from = compileExpression(iBuilder, sthru->getScanFrom());
    526             Value * const thru = compileExpression(iBuilder, sthru->getScanThru());
    527             Value * const sum = mCarryManager->addCarryInCarryOut(iBuilder, sthru, from, thru);
    528             value = iBuilder->simd_and(sum, iBuilder->simd_not(thru));
     461            Value * const from = compileExpression(b, sthru->getScanFrom());
     462            Value * const thru = compileExpression(b, sthru->getScanThru());
     463            Value * const sum = mCarryManager->addCarryInCarryOut(b, sthru, from, thru);
     464            value = b->simd_and(sum, b->simd_not(thru));
    529465        } else if (const ScanTo * sthru = dyn_cast<ScanTo>(stmt)) {
    530             Value * const marker_expr = compileExpression(iBuilder, sthru->getScanFrom());
    531             Value * const to = iBuilder->simd_xor(compileExpression(iBuilder, sthru->getScanTo()), iBuilder->getScalarField("EOFmask"));
    532             Value * const sum = mCarryManager->addCarryInCarryOut(iBuilder, sthru, marker_expr, iBuilder->simd_not(to));
    533             value = iBuilder->simd_and(sum, to);
     466            Value * const marker_expr = compileExpression(b, sthru->getScanFrom());
     467            Value * const to = b->simd_xor(compileExpression(b, sthru->getScanTo()), b->getScalarField("EOFmask"));
     468            Value * const sum = mCarryManager->addCarryInCarryOut(b, sthru, marker_expr, b->simd_not(to));
     469            value = b->simd_and(sum, to);
    534470        } else if (const AdvanceThenScanThru * sthru = dyn_cast<AdvanceThenScanThru>(stmt)) {
    535             Value * const from = compileExpression(iBuilder, sthru->getScanFrom());
    536             Value * const thru = compileExpression(iBuilder, sthru->getScanThru());
    537             Value * const sum = mCarryManager->addCarryInCarryOut(iBuilder, sthru, from, iBuilder->simd_or(from, thru));
    538             value = iBuilder->simd_and(sum, iBuilder->simd_not(thru));
     471            Value * const from = compileExpression(b, sthru->getScanFrom());
     472            Value * const thru = compileExpression(b, sthru->getScanThru());
     473            Value * const sum = mCarryManager->addCarryInCarryOut(b, sthru, from, b->simd_or(from, thru));
     474            value = b->simd_and(sum, b->simd_not(thru));
    539475        } else if (const AdvanceThenScanTo * sthru = dyn_cast<AdvanceThenScanTo>(stmt)) {
    540             Value * const from = compileExpression(iBuilder, sthru->getScanFrom());
    541             Value * const to = iBuilder->simd_xor(compileExpression(iBuilder, sthru->getScanTo()), iBuilder->getScalarField("EOFmask"));
    542             Value * const sum = mCarryManager->addCarryInCarryOut(iBuilder, sthru, from, iBuilder->simd_or(from, iBuilder->simd_not(to)));
    543             value = iBuilder->simd_and(sum, to);
     476            Value * const from = compileExpression(b, sthru->getScanFrom());
     477            Value * const to = b->simd_xor(compileExpression(b, sthru->getScanTo()), b->getScalarField("EOFmask"));
     478            Value * const sum = mCarryManager->addCarryInCarryOut(b, sthru, from, b->simd_or(from, b->simd_not(to)));
     479            value = b->simd_and(sum, to);
     480        } else if (LLVM_UNLIKELY(isa<Assign>(stmt))) {
     481            expr = cast<Assign>(stmt)->getVariable();
     482            value = compileExpression(b, cast<Assign>(stmt)->getValue());
     483            if (isa<Extract>(expr) || (isa<Var>(expr) && cast<Var>(expr)->isKernelParameter())) {
     484                Value * const ptr = compileExpression(b, expr, false);
     485                b->CreateAlignedStore(value, ptr, getAlignment(value));
     486                value = ptr;
     487            }
    544488        } else if (const InFile * e = dyn_cast<InFile>(stmt)) {
    545             Value * EOFmask = iBuilder->getScalarField("EOFmask");
    546             value = iBuilder->simd_and(compileExpression(iBuilder, e->getExpr()), iBuilder->simd_not(EOFmask));
     489            Value * EOFmask = b->getScalarField("EOFmask");
     490            value = b->simd_and(compileExpression(b, e->getExpr()), b->simd_not(EOFmask));
    547491        } else if (const AtEOF * e = dyn_cast<AtEOF>(stmt)) {
    548             Value * EOFbit = iBuilder->getScalarField("EOFbit");
    549             value = iBuilder->simd_and(compileExpression(iBuilder, e->getExpr()), EOFbit);
     492            Value * EOFbit = b->getScalarField("EOFbit");
     493            value = b->simd_and(compileExpression(b, e->getExpr()), EOFbit);
    550494        } else if (const Count * c = dyn_cast<Count>(stmt)) {
    551             Value * EOFbit = iBuilder->getScalarField("EOFbit");
    552             Value * EOFmask = iBuilder->getScalarField("EOFmask");
    553             Value * const to_count = iBuilder->simd_and(iBuilder->simd_or(iBuilder->simd_not(EOFmask), EOFbit), compileExpression(iBuilder, c->getExpr()));
    554             const unsigned counterSize = iBuilder->getSizeTy()->getBitWidth();
     495            Value * EOFbit = b->getScalarField("EOFbit");
     496            Value * EOFmask = b->getScalarField("EOFmask");
     497            Value * const to_count = b->simd_and(b->simd_or(b->simd_not(EOFmask), EOFbit), compileExpression(b, c->getExpr()));
     498            const unsigned counterSize = b->getSizeTy()->getBitWidth();
    555499            const auto f = mAccumulator.find(c);
    556500            if (LLVM_UNLIKELY(f == mAccumulator.end())) {
    557501                report_fatal_error("Unknown accumulator: " + c->getName().str());
    558502            }
    559             Value * ptr = iBuilder->getScalarFieldPtr(f->second);
     503            Value * ptr = b->getScalarFieldPtr(f->second);
    560504            const auto alignment = getPointerElementAlignment(ptr);
    561             Value * countSoFar = iBuilder->CreateAlignedLoad(ptr, alignment, c->getName() + "_accumulator");
    562             auto fields = (iBuilder->getBitBlockWidth() / counterSize);
    563             Value * fieldCounts = iBuilder->simd_popcount(counterSize, to_count);
     505            Value * countSoFar = b->CreateAlignedLoad(ptr, alignment, c->getName() + "_accumulator");
     506            auto fields = (b->getBitBlockWidth() / counterSize);
     507            Value * fieldCounts = b->simd_popcount(counterSize, to_count);
    564508            while (fields > 1) {
    565509                fields = fields/2;
    566                 fieldCounts = iBuilder->CreateAdd(fieldCounts, iBuilder->mvmd_srli(counterSize, fieldCounts, fields));
    567             }
    568             value = iBuilder->CreateAdd(iBuilder->mvmd_extract(counterSize, fieldCounts, 0), countSoFar, "countSoFar");
    569             iBuilder->CreateAlignedStore(value, ptr, alignment);
     510                fieldCounts = b->CreateAdd(fieldCounts, b->mvmd_srli(counterSize, fieldCounts, fields));
     511            }
     512            value = b->CreateAdd(b->mvmd_extract(counterSize, fieldCounts, 0), countSoFar, "countSoFar");
     513            b->CreateAlignedStore(value, ptr, alignment);
    570514        } else if (const Lookahead * l = dyn_cast<Lookahead>(stmt)) {
    571515            PabloAST * stream = l->getExpression();
    572516            Value * index = nullptr;
    573517            if (LLVM_UNLIKELY(isa<Extract>(stream))) {               
    574                 index = compileExpression(iBuilder, cast<Extract>(stream)->getIndex(), true);
     518                index = compileExpression(b, cast<Extract>(stream)->getIndex(), true);
    575519                stream = cast<Extract>(stream)->getArray();
    576520            } else {
    577                 index = iBuilder->getInt32(0);
    578             }
    579             const auto bit_shift = (l->getAmount() % iBuilder->getBitBlockWidth());
    580             const auto block_shift = (l->getAmount() / iBuilder->getBitBlockWidth());
    581             Value * ptr = iBuilder->getInputStreamBlockPtr(cast<Var>(stream)->getName(), index, iBuilder->getSize(block_shift));
    582             Value * lookAhead = iBuilder->CreateBlockAlignedLoad(ptr);
     521                index = b->getInt32(0);
     522            }
     523            const auto bit_shift = (l->getAmount() % b->getBitBlockWidth());
     524            const auto block_shift = (l->getAmount() / b->getBitBlockWidth());
     525            Value * ptr = b->getInputStreamBlockPtr(cast<Var>(stream)->getName(), index, b->getSize(block_shift));
     526            Value * lookAhead = b->CreateBlockAlignedLoad(ptr);
    583527            if (bit_shift == 0) {  // Simple case with no intra-block shifting.
    584528                value = lookAhead;
    585529            } else { // Need to form shift result from two adjacent blocks.
    586                 Value * ptr = iBuilder->getInputStreamBlockPtr(cast<Var>(stream)->getName(), index, iBuilder->getSize(block_shift + 1));
    587                 Value * lookAhead1 = iBuilder->CreateBlockAlignedLoad(ptr);
     530                Value * ptr = b->getInputStreamBlockPtr(cast<Var>(stream)->getName(), index, b->getSize(block_shift + 1));
     531                Value * lookAhead1 = b->CreateBlockAlignedLoad(ptr);
    588532                if (LLVM_UNLIKELY((bit_shift % 8) == 0)) { // Use a single whole-byte shift, if possible.
    589                     value = iBuilder->mvmd_dslli(8, lookAhead1, lookAhead, (bit_shift / 8));
     533                    value = b->mvmd_dslli(8, lookAhead1, lookAhead, (bit_shift / 8));
    590534                } else {
    591                     Type  * const streamType = iBuilder->getIntNTy(iBuilder->getBitBlockWidth());
    592                     Value * b1 = iBuilder->CreateBitCast(lookAhead1, streamType);
    593                     Value * b0 = iBuilder->CreateBitCast(lookAhead, streamType);
    594                     Value * result = iBuilder->CreateOr(iBuilder->CreateShl(b1, iBuilder->getBitBlockWidth() - bit_shift), iBuilder->CreateLShr(b0, bit_shift));
    595                     value = iBuilder->CreateBitCast(result, iBuilder->getBitBlockType());
     535                    Type  * const streamType = b->getIntNTy(b->getBitBlockWidth());
     536                    Value * b1 = b->CreateBitCast(lookAhead1, streamType);
     537                    Value * b0 = b->CreateBitCast(lookAhead, streamType);
     538                    Value * result = b->CreateOr(b->CreateShl(b1, b->getBitBlockWidth() - bit_shift), b->CreateLShr(b0, bit_shift));
     539                    value = b->CreateBitCast(result, b->getBitBlockType());
    596540                }
    597541            }
    598 
     542        } else if (const Repeat * const s = dyn_cast<Repeat>(stmt)) {
     543            value = compileExpression(b, s->getValue());
     544            Type * const ty = s->getType();
     545            if (LLVM_LIKELY(ty->isVectorTy())) {
     546                const auto fw = s->getFieldWidth()->value();
     547                value = b->CreateZExtOrTrunc(value, b->getIntNTy(fw));
     548                value = b->simd_fill(fw, value);
     549            } else {
     550                value = b->CreateZExtOrTrunc(value, ty);
     551            }
     552        #if 0
     553        } else if (const PackH * const p = dyn_cast<PackH>(stmt)) {
     554            const auto sourceWidth = p->getValue()->getType()->getVectorElementType()->getIntegerBitWidth();
     555            const auto packedWidth = p->getFieldWidth()->value();
     556            Value * const base = compileExpression(b, p->getValue(), false);
     557            const auto packs = sourceWidth / 2;
     558            if (LLVM_LIKELY(packs > 1)) {
     559                value = b->CreateAlloca(b->getBitBlockType(), b->getInt32(packs));
     560            }
     561            Constant * const ZERO = b->getInt32(0);
     562            for (unsigned i = 0; i < packs; ++i) {
     563                Value * A = b->CreateLoad(b->CreateGEP(base, {ZERO, b->getInt32(i * 2)}));
     564                Value * B = b->CreateLoad(b->CreateGEP(base, {ZERO, b->getInt32(i * 2 + 1)}));
     565                Value * P = b->hsimd_packh(packedWidth, A, B);
     566                if (LLVM_UNLIKELY(packs == 1)) {
     567                    value = P;
     568                    break;
     569                }
     570                b->CreateStore(P, b->CreateGEP(value, b->getInt32(i)));
     571            }
     572        } else if (const PackL * const p = dyn_cast<PackL>(stmt)) {
     573            const auto sourceWidth = p->getValue()->getType()->getVectorElementType()->getIntegerBitWidth();
     574            const auto packedWidth = p->getFieldWidth()->value();
     575            Value * const base = compileExpression(b, p->getValue(), false);
     576            const auto count = sourceWidth / 2;
     577            if (LLVM_LIKELY(count > 1)) {
     578                value = b->CreateAlloca(b->getBitBlockType(), b->getInt32(count));
     579            }
     580            Constant * const ZERO = b->getInt32(0);
     581            for (unsigned i = 0; i < count; ++i) {
     582                Value * A = b->CreateLoad(b->CreateGEP(base, {ZERO, b->getInt32(i * 2)}));
     583                Value * B = b->CreateLoad(b->CreateGEP(base, {ZERO, b->getInt32(i * 2 + 1)}));
     584                Value * P = b->hsimd_packl(packedWidth, A, B);
     585                if (LLVM_UNLIKELY(count == 1)) {
     586                    value = P;
     587                    break;
     588                }
     589                b->CreateStore(P, b->CreateGEP(value, b->getInt32(i)));
     590            }
     591        #endif
    599592        } else {
    600593            std::string tmp;
     
    605598            report_fatal_error(out.str());
    606599        }
    607 
     600        assert (expr);
     601        assert (value);
    608602        mMarker[expr] = value;
    609603        if (DebugOptionIsSet(DumpTrace)) {
    610             const String & name = isa<Var>(expr) ? cast<Var>(expr)->getName() : cast<Statement>(expr)->getName();
     604            std::string tmp;
     605            raw_string_ostream name(tmp);
     606            expr->print(name);
    611607            if (value->getType()->isVectorTy()) {
    612                 iBuilder->CallPrintRegister(name.str(), value);
     608                b->CallPrintRegister(name.str(), value);
    613609            } else if (value->getType()->isIntegerTy()) {
    614                 iBuilder->CallPrintInt(name.str(), value);
    615             }
    616         }
    617     }
    618 }
    619 
    620 Value * PabloCompiler::compileExpression(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, const PabloAST * expr, const bool ensureLoaded) const {
    621     if (LLVM_UNLIKELY(isa<Ones>(expr))) {
    622         return iBuilder->allOnes();
    623     } else if (LLVM_UNLIKELY(isa<Zeroes>(expr))) {
    624         return iBuilder->allZeroes();
    625     } else if (LLVM_UNLIKELY(isa<Integer>(expr))) {
    626         return ConstantInt::get(cast<Integer>(expr)->getType(), cast<Integer>(expr)->value());
    627     } else if (LLVM_UNLIKELY(isa<Operator>(expr))) {
    628         const Operator * op = cast<Operator>(expr);
    629         Value * lh = compileExpression(iBuilder, op->getLH());
    630         Value * rh = compileExpression(iBuilder, op->getRH());
    631         if (LLVM_UNLIKELY(lh->getType() != rh->getType())) {
     610                b->CallPrintInt(name.str(), value);
     611            }
     612        }
     613    }
     614}
     615
     616unsigned getIntegerBitWidth(const Type * ty) {
     617    if (ty->isArrayTy()) {
     618        assert (ty->getArrayNumElements() == 1);
     619        ty = ty->getArrayElementType();
     620    }
     621    if (ty->isVectorTy()) {
     622        assert (ty->getVectorNumElements() == 0);
     623        ty = ty->getVectorElementType();
     624    }
     625    return ty->getIntegerBitWidth();
     626}
     627
     628Value * PabloCompiler::compileExpression(const std::unique_ptr<kernel::KernelBuilder> & b, const PabloAST * const expr, const bool ensureLoaded) {
     629    const auto f = mMarker.find(expr);   
     630    Value * value = nullptr;
     631    if (LLVM_LIKELY(f != mMarker.end())) {
     632        value = f->second;
     633    } else {
     634        if (isa<Integer>(expr)) {
     635            value = ConstantInt::get(cast<Integer>(expr)->getType(), cast<Integer>(expr)->value());
     636        } else if (isa<Zeroes>(expr)) {
     637            value = b->allZeroes();
     638        } else if (LLVM_UNLIKELY(isa<Ones>(expr))) {
     639            value = b->allOnes();
     640        } else if (isa<Extract>(expr)) {
     641            const Extract * const extract = cast<Extract>(expr);
     642            const Var * const var = cast<Var>(extract->getArray());
     643            Value * const index = compileExpression(b, extract->getIndex());
     644            value = getPointerToVar(b, var, index);
     645        } else if (LLVM_UNLIKELY(isa<Var>(expr))) {
     646            const Var * const var = cast<Var>(expr);
     647            if (LLVM_LIKELY(var->isKernelParameter() && var->isScalar())) {
     648                value = b->getScalarFieldPtr(var->getName());
     649            } else { // use before def error
     650                std::string tmp;
     651                raw_string_ostream out(tmp);
     652                out << "PabloCompiler: ";
     653                expr->print(out);
     654                out << " is not a scalar value or was used before definition";
     655                report_fatal_error(out.str());
     656            }
     657        } else if (LLVM_UNLIKELY(isa<Operator>(expr))) {
     658            const Operator * const op = cast<Operator>(expr);
     659            const PabloAST * lh = op->getLH();
     660            const PabloAST * rh = op->getRH();
     661            if ((isa<Var>(lh) || isa<Extract>(lh)) || (isa<Var>(rh) || isa<Extract>(rh))) {
     662                const unsigned n = std::min(getIntegerBitWidth(lh->getType()), getIntegerBitWidth(rh->getType()));
     663                const unsigned m = b->getBitBlockWidth() / n;
     664                IntegerType * const fw = b->getIntNTy(m);
     665                VectorType * const vTy = VectorType::get(b->getIntNTy(n), m);
     666
     667                Value * baseLhv = nullptr;
     668                Value * lhvStreamIndex = nullptr;
     669                if (isa<Var>(lh)) {
     670                    lhvStreamIndex = b->getInt32(0);
     671                } else if (isa<Extract>(lh)) {
     672                    lhvStreamIndex = compileExpression(b, cast<Extract>(lh)->getIndex());
     673                } else {
     674                    baseLhv = compileExpression(b, lh, false);
     675                }
     676
     677                Value * baseRhv = nullptr;
     678                Value * rhvStreamIndex = nullptr;
     679                if (isa<Var>(rh)) {
     680                    rhvStreamIndex = b->getInt32(0);
     681                } else if (isa<Extract>(lh)) {
     682                    rhvStreamIndex = compileExpression(b, cast<Extract>(rh)->getIndex());
     683                } else {
     684                    baseRhv = compileExpression(b, rh, false);
     685                }
     686
     687                const TypeId typeId = op->getClassTypeId();
     688
     689                if (LLVM_UNLIKELY(typeId == TypeId::Add || typeId == TypeId::Subtract)) {
     690
     691
     692
     693                    value = b->CreateAlloca(vTy, b->getInt32(n));
     694
     695                    for (unsigned i = 0; i < n; ++i) {
     696                        llvm::Constant * const index = b->getInt32(i);
     697                        Value * lhv = nullptr;
     698                        if (baseLhv) {
     699                            lhv = baseLhv;
     700                        } else {
     701                            lhv = getPointerToVar(b, cast<Var>(lh), lhvStreamIndex, index);
     702                            lhv = b->CreateAlignedLoad(lhv, getAlignment(lhv));
     703                        }
     704                        lhv = b->CreateBitCast(lhv, vTy);
     705
     706                        Value * rhv = nullptr;
     707                        if (baseRhv) {
     708                            rhv = baseRhv;
     709                        } else {
     710                            rhv = getPointerToVar(b, cast<Var>(rh), rhvStreamIndex, index);
     711                            rhv = b->CreateAlignedLoad(rhv, getAlignment(rhv));
     712                        }
     713                        rhv = b->CreateBitCast(rhv, vTy);
     714
     715                        Value * result = nullptr;
     716                        if (typeId == TypeId::Add) {
     717                            result = b->CreateAdd(lhv, rhv);
     718                        } else {
     719                            result = b->CreateSub(lhv, rhv);
     720                        }
     721                        b->CreateAlignedStore(result, b->CreateGEP(value, {b->getInt32(0), b->getInt32(i)}), getAlignment(result));
     722                    }
     723
     724
     725
     726                } else {
     727
     728                    value = UndefValue::get(VectorType::get(fw, n));
     729
     730                    for (unsigned i = 0; i < n; ++i) {
     731                        llvm::Constant * const index = b->getInt32(i);
     732                        Value * lhv = nullptr;
     733                        if (baseLhv) {
     734                            lhv = baseLhv;
     735                        } else {
     736                            lhv = getPointerToVar(b, cast<Var>(lh), lhvStreamIndex, index);
     737                            lhv = b->CreateAlignedLoad(lhv, getAlignment(lhv));
     738                        }
     739                        lhv = b->CreateBitCast(lhv, vTy);
     740
     741                        Value * rhv = nullptr;
     742                        if (baseRhv) {
     743                            rhv = baseRhv;
     744                        } else {
     745                            rhv = getPointerToVar(b, cast<Var>(rh), rhvStreamIndex, index);
     746                            rhv = b->CreateAlignedLoad(rhv, getAlignment(rhv));
     747                        }
     748                        rhv = b->CreateBitCast(rhv, vTy);
     749
     750                        Value * comp = nullptr;
     751                        switch (typeId) {
     752                            case TypeId::GreaterThanEquals:
     753                            case TypeId::LessThan:
     754                                comp = b->simd_ult(n, lhv, rhv);
     755                                break;
     756                            case TypeId::Equals:
     757                            case TypeId::NotEquals:
     758                                comp = b->simd_eq(n, lhv, rhv);
     759                                break;
     760                            case TypeId::LessThanEquals:
     761                            case TypeId::GreaterThan:
     762                                comp = b->simd_ugt(n, lhv, rhv);
     763                                break;
     764                            default: llvm_unreachable("invalid vector operator id");
     765                        }
     766                        Value * const mask = b->CreateBitCast(b->hsimd_signmask(n, comp), fw);
     767                        value = b->mvmd_insert(m, value, mask, i);
     768                    }
     769
     770                    value = b->CreateBitCast(value, b->getBitBlockType());
     771                    switch (typeId) {
     772                        case TypeId::GreaterThanEquals:
     773                        case TypeId::LessThanEquals:
     774                        case TypeId::NotEquals:
     775                            value = b->simd_not(value);
     776                        default: break;
     777                    }
     778                }
     779
     780            } else {
     781                Value * const lhv = compileExpression(b, lh);
     782                Value * const rhv = compileExpression(b, rh);
     783                switch (op->getClassTypeId()) {
     784                    case TypeId::Add:
     785                        value = b->CreateAdd(lhv, rhv); break;
     786                    case TypeId::Subtract:
     787                        value = b->CreateSub(lhv, rhv); break;
     788                    case TypeId::LessThan:
     789                        value = b->CreateICmpSLT(lhv, rhv); break;
     790                    case TypeId::LessThanEquals:
     791                        value = b->CreateICmpSLE(lhv, rhv); break;
     792                    case TypeId::Equals:
     793                        value = b->CreateICmpEQ(lhv, rhv); break;
     794                    case TypeId::GreaterThanEquals:
     795                        value = b->CreateICmpSGE(lhv, rhv); break;
     796                    case TypeId::GreaterThan:
     797                        value = b->CreateICmpSGT(lhv, rhv); break;
     798                    case TypeId::NotEquals:
     799                        value = b->CreateICmpNE(lhv, rhv); break;
     800                    default: llvm_unreachable("invalid scalar operator id");
     801                }
     802            }
     803        } else { // use before def error
    632804            std::string tmp;
    633805            raw_string_ostream out(tmp);
    634             out << "Operator creation error: left hand type of ";
     806            out << "PabloCompiler: ";
    635807            expr->print(out);
    636             out << " (";
    637             lh->getType()->print(out);
    638             out << ") differs from right hand type (";
    639             rh->getType()->print(out);
    640             out << ")";
     808            out << " was used before definition";
    641809            report_fatal_error(out.str());
    642810        }
    643         switch (op->getClassTypeId()) {
    644             case TypeId::Add:
    645                 return iBuilder->CreateAdd(lh, rh);
    646             case TypeId::Subtract:
    647                 return iBuilder->CreateSub(lh, rh);
    648             case TypeId::LessThan:
    649                 return iBuilder->CreateICmpSLT(lh, rh);
    650             case TypeId::LessThanEquals:
    651                 return iBuilder->CreateICmpSLE(lh, rh);
    652             case TypeId::Equals:
    653                 return iBuilder->CreateICmpEQ(lh, rh);
    654             case TypeId::GreaterThanEquals:
    655                 return iBuilder->CreateICmpSGE(lh, rh);
    656             case TypeId::GreaterThan:
    657                 return iBuilder->CreateICmpSGT(lh, rh);
    658             case TypeId::NotEquals:
    659                 return iBuilder->CreateICmpNE(lh, rh);
    660             default: break;
    661         }
    662         std::string tmp;
    663         raw_string_ostream out(tmp);
    664         out << "PabloCompiler: ";
    665         expr->print(out);
    666         out << " is not a valid Operator";
    667         report_fatal_error(out.str());
    668     }
    669     const auto f = mMarker.find(expr);
    670     if (LLVM_UNLIKELY(f == mMarker.end())) {
    671         std::string tmp;
    672         raw_string_ostream out(tmp);
    673         out << "PabloCompiler: ";
    674         expr->print(out);
    675         out << " was used before definition!";
    676         report_fatal_error(out.str());
    677     }
    678     Value * value = f->second;
    679     if (LLVM_UNLIKELY(isa<GetElementPtrInst>(value) && ensureLoaded)) {
    680         value = iBuilder->CreateAlignedLoad(value, getPointerElementAlignment(value));
     811        assert (value);
     812        // mMarker.insert({expr, value});
     813    }
     814    if (LLVM_UNLIKELY(value->getType()->isPointerTy() && ensureLoaded)) {
     815        value = b->CreateAlignedLoad(value, getPointerElementAlignment(value));
    681816    }
    682817    return value;
     818}
     819
     820Value * PabloCompiler::getPointerToVar(const std::unique_ptr<kernel::KernelBuilder> & b, const Var * var, Value * index1, Value * index2)  {
     821    assert (var && index1 && (index2 == nullptr || index1->getType() == index2->getType()));
     822    if (LLVM_LIKELY(var->isKernelParameter())) {
     823        if (LLVM_UNLIKELY(var->isScalar())) {
     824            std::string tmp;
     825            raw_string_ostream out(tmp);
     826            out << mKernel->getName();
     827            out << ": cannot index scalar value ";
     828            var->print(out);
     829            report_fatal_error(out.str());
     830        } else if (var->isReadOnly()) {
     831            if (index2) {
     832                return b->getInputStreamPackPtr(var->getName(), index1, index2);
     833            } else {
     834                return b->getInputStreamBlockPtr(var->getName(), index1);
     835            }
     836        } else if (var->isReadNone()) {
     837            if (index2) {
     838                return b->getOutputStreamPackPtr(var->getName(), index1, index2);
     839            } else {
     840                return b->getOutputStreamBlockPtr(var->getName(), index1);
     841            }
     842        } else {
     843            std::string tmp;
     844            raw_string_ostream out(tmp);
     845            out << mKernel->getName();
     846            out << ": stream ";
     847            var->print(out);
     848            out << " cannot be read from or written to";
     849            report_fatal_error(out.str());
     850        }
     851    } else {
     852        Value * const ptr = compileExpression(b, var, false);
     853        std::vector<Value *> offsets;
     854        offsets.push_back(ConstantInt::getNullValue(index1->getType()));
     855        offsets.push_back(index1);
     856        if (index2) offsets.push_back(index2);
     857        return b->CreateGEP(ptr, offsets);
     858    }
    683859}
    684860
Note: See TracChangeset for help on using the changeset viewer.