Changeset 5828


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

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

Location:
icGREP/icgrep-devel/icgrep
Files:
4 deleted
24 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/CMakeLists.txt

    r5825 r5828  
    8585ENDIF()
    8686SET(PABLO_SRC ${PABLO_SRC} pablo/analysis/pabloverifier.cpp)
    87 SET(PABLO_SRC ${PABLO_SRC} pablo/passes/ssapass.cpp)
    8887SET(PABLO_SRC ${PABLO_SRC} pablo/optimizers/pablo_simplifier.cpp pablo/optimizers/codemotionpass.cpp pablo/optimizers/distributivepass.cpp pablo/optimizers/schedulingprepass.cpp)
    8988SET(PABLO_SRC ${PABLO_SRC} pablo/passes/flattenif.cpp)
     
    118117add_executable(wc wc.cpp)
    119118add_executable(editd editd/editd.cpp editd/pattern_compiler.cpp editd/editdscan_kernel.cpp editd/editd_gpu_kernel.cpp editd/editd_cpu_kernel.cpp kernels/streams_merge.cpp kernels/cc_kernel.cpp)
    120 add_executable(array-test array-test.cpp kernels/alignedprint.cpp)
    121119add_executable(lz4d lz4d.cpp lz4FrameDecoder.cpp kernels/cc_kernel.cpp kernels/lz4_index_decoder.cpp kernels/lz4_bytestream_decoder.cpp)
    122120add_executable(core combine/core.cpp combine/regexGen.cpp combine/stringGen.cpp combine/propGen.cpp combine/icgrep-test/icgrep-test.cpp grep_interface.cpp grep_engine.cpp kernels/scanmatchgen.cpp kernels/u8u32_kernel.cpp kernels/delmask_kernel.cpp kernels/cc_kernel.cpp kernels/cc_scan_kernel.cpp kernels/charclasses.cpp kernels/linebreak_kernel.cpp kernels/streams_merge.cpp kernels/grep_kernel.cpp kernels/until_n.cpp)
     
    130128target_link_libraries (wc PabloADT CCADT CodeGen ${REQ_LLVM_LIBRARIES} ${Boost_LIBRARIES} ${CUDA_LIB})
    131129target_link_libraries (editd PabloADT CCADT CodeGen ${REQ_LLVM_LIBRARIES} ${Boost_LIBRARIES} ${CUDA_LIB})
    132 target_link_libraries (array-test PabloADT CodeGen ${REQ_LLVM_LIBRARIES} ${Boost_LIBRARIES} ${CUDA_LIB})
    133130target_link_libraries (lz4d PabloADT CCADT CodeGen ${REQ_LLVM_LIBRARIES} ${Boost_LIBRARIES} ${CUDA_LIB})
    134131target_link_libraries (core RegExpCompiler ${REQ_LLVM_LIBRARIES} ${Boost_LIBRARIES})
  • icGREP/icgrep-devel/icgrep/IR_Gen/CBuilder.cpp

    r5812 r5828  
    678678}
    679679
    680 IntegerType * CBuilder::getIntAddrTy() const {
     680IntegerType * LLVM_READNONE CBuilder::getIntAddrTy() const {
    681681    return TypeBuilder<intptr_t, false>::get(getContext());
    682682}
    683683
    684 PointerType * CBuilder::getVoidPtrTy(const unsigned AddressSpace) const {
     684PointerType * LLVM_READNONE CBuilder::getVoidPtrTy(const unsigned AddressSpace) const {
    685685    return PointerType::get(Type::getVoidTy(getContext()), AddressSpace);
    686686}
     
    701701}
    702702
    703 PointerType * CBuilder::getFILEptrTy() {
     703PointerType * LLVM_READNONE CBuilder::getFILEptrTy() {
    704704    if (mFILEtype == nullptr) {
    705705        mFILEtype = StructType::create(getContext(), "struct._IO_FILE");
     
    10841084    } else { // if assertions are not enabled, make it a compiler assumption.
    10851085
    1086         // INVESTIGATE: while interesting, this does not seem to produce faster code and only provides a trivial reduction
    1087         // of compiled code size in LLVM 3.8 but nearly doubles compilation time. This may have been improved with later
    1088         // versions of LLVM but it's likely that assumptions ought to be hand placed once they're prove to improve performance.
     1086        // INVESTIGATE: while interesting, this does not seem to produce faster code and only provides a trivial
     1087        // reduction of compiled code size in LLVM 3.8 but nearly doubles compilation time. This may have been
     1088        // improved with later versions of LLVM but it's likely that assumptions ought to be hand placed once
     1089        // they're proven to improve performance.
    10891090
    10901091        // IRBuilder<>::CreateAssumption(assertion);
     
    11041105}
    11051106
    1106 BasicBlock * CBuilder::CreateBasicBlock(std::string && name) {
    1107     return BasicBlock::Create(getContext(), name, GetInsertBlock()->getParent());
     1107BasicBlock * CBuilder::CreateBasicBlock(const StringRef name, BasicBlock * insertBefore) {
     1108    return BasicBlock::Create(getContext(), name, GetInsertBlock()->getParent(), insertBefore);
    11081109}
    11091110
     
    11251126}
    11261127
    1127 Value * CBuilder::CreateCountForwardZeroes(Value * value, const bool isZeroUndefined) {
    1128     if (LLVM_UNLIKELY(isZeroUndefined && codegen::DebugOptionIsSet(codegen::EnableAsserts))) {
     1128Value * CBuilder::CreateCountForwardZeroes(Value * value, const bool guaranteedNonZero) {
     1129    if (LLVM_UNLIKELY(guaranteedNonZero && codegen::DebugOptionIsSet(codegen::EnableAsserts))) {
    11291130        CreateAssert(value, "CreateCountForwardZeroes: value cannot be zero!");
    11301131    }
    1131     Value * cttzFunc = Intrinsic::getDeclaration(getModule(), Intrinsic::cttz, value->getType());
    1132     return CreateCall(cttzFunc, {value, getInt1(isZeroUndefined)});
    1133 }
    1134 
    1135 Value * CBuilder::CreateCountReverseZeroes(Value * value, const bool isZeroUndefined) {
    1136     if (LLVM_UNLIKELY(isZeroUndefined && codegen::DebugOptionIsSet(codegen::EnableAsserts))) {
     1132    Value * cttzFunc = Intrinsic::getDeclaration(getModule(), Intrinsic::cttz, value->getType());   
     1133    return CreateCall(cttzFunc, {value, getInt1(guaranteedNonZero)});
     1134}
     1135
     1136Value * CBuilder::CreateCountReverseZeroes(Value * value, const bool guaranteedNonZero) {
     1137    if (LLVM_UNLIKELY(guaranteedNonZero && codegen::DebugOptionIsSet(codegen::EnableAsserts))) {
    11371138        CreateAssert(value, "CreateCountReverseZeroes: value cannot be zero!");
    11381139    }
    11391140    Value * ctlzFunc = Intrinsic::getDeclaration(getModule(), Intrinsic::ctlz, value->getType());
    1140     return CreateCall(ctlzFunc, {value, getInt1(isZeroUndefined)});
     1141    return CreateCall(ctlzFunc, {value, getInt1(guaranteedNonZero)});
    11411142}
    11421143
  • icGREP/icgrep-devel/icgrep/IR_Gen/CBuilder.h

    r5771 r5828  
    222222    }
    223223   
    224     llvm::IntegerType * getIntAddrTy() const;
    225    
    226     llvm::PointerType * getVoidPtrTy(const unsigned AddressSpace = 0) const;
    227    
    228     llvm::PointerType * getFILEptrTy();
     224    llvm::IntegerType * LLVM_READNONE getIntAddrTy() const;
     225   
     226    llvm::PointerType * LLVM_READNONE getVoidPtrTy(const unsigned AddressSpace = 0) const;
     227   
     228    llvm::PointerType * LLVM_READNONE getFILEptrTy();
    229229   
    230230    inline unsigned getCacheAlignment() const {
     
    258258    }
    259259
    260     llvm::BasicBlock * CreateBasicBlock(std::string && name);
     260    llvm::BasicBlock * CreateBasicBlock(const llvm::StringRef name, llvm::BasicBlock * insertBefore = nullptr);
    261261
    262262    virtual bool supportsIndirectBr() const;
     
    264264    llvm::Value * CreatePopcount(llvm::Value * bits);
    265265
    266     llvm::Value * CreateCountForwardZeroes(llvm::Value * value, const bool isZeroUndefined = false);
    267 
    268     llvm::Value * CreateCountReverseZeroes(llvm::Value * value, const bool isZeroUndefined = false);
     266    // TODO: AVX512 offers these as vector instructions
     267    llvm::Value * CreateCountForwardZeroes(llvm::Value * value, const bool guaranteedNonZero = false);
     268    llvm::Value * CreateCountReverseZeroes(llvm::Value * value, const bool guaranteedNonZero = false);
    269269   
    270270    // Useful bit manipulation operations 
  • icGREP/icgrep-devel/icgrep/IR_Gen/idisa_avx_builder.cpp

    r5759 r5828  
    2828            Value * a_as_ps = CreateBitCast(a, bitBlock_f32type);
    2929            return CreateCall(signmask_f32func, a_as_ps);
     30        } else if (fw == 8) {
     31            Value * signmask_f8func = Intrinsic::getDeclaration(getModule(), Intrinsic::x86_avx2_pmovmskb);
     32            Type * bitBlock_i8type = VectorType::get(getInt8Ty(), mBitBlockWidth/8);
     33            Value * a_as_ps = CreateBitCast(a, bitBlock_i8type);
     34            return CreateCall(signmask_f8func, a_as_ps);
    3035        }
    3136    } else if (mBitBlockWidth == 512) {
  • icGREP/icgrep-devel/icgrep/IR_Gen/idisa_builder.cpp

    r5774 r5828  
    7575Value * IDISA_Builder::simd_fill(unsigned fw, Value * a) {
    7676    if (fw < 8) report_fatal_error("Unsupported field width: simd_fill " + std::to_string(fw));
    77    unsigned field_count = mBitBlockWidth/fw;
     77    const unsigned field_count = mBitBlockWidth/fw;
    7878    Type * singleFieldVecTy = VectorType::get(getIntNTy(fw), 1);
    7979    Value * aVec = CreateBitCast(a, singleFieldVecTy);
     
    8282
    8383Value * IDISA_Builder::simd_add(unsigned fw, Value * a, Value * b) {
    84     if (fw == 1) return simd_xor(a, b);
    85     if (fw < 8) {
     84    if (fw == 1) {
     85        return simd_xor(a, b);
     86    } else if (fw < 8) {
    8687        Constant * hi_bit_mask = Constant::getIntegerValue(getIntNTy(mBitBlockWidth),
    8788                                                           APInt::getSplat(mBitBlockWidth, APInt::getHighBitsSet(fw, 1)));
     
    271272}
    272273
    273 Value * IDISA_Builder::simd_cttz(unsigned fw, Value * a) {
    274     if (fw < 8) report_fatal_error("Unsupported field width: cttz " + std::to_string(fw));
    275     Value * cttzFunc = Intrinsic::getDeclaration(getModule(), Intrinsic::cttz, fwVectorType(fw));
    276     return CreateCall(cttzFunc, {fwCast(fw, a), ConstantInt::get(getInt1Ty(), 0)});
    277 }
    278 
    279 Value * IDISA_Builder::simd_popcount(unsigned fw, Value * a) {
    280     if (fw < 8) report_fatal_error("Unsupported field width: popcount " + std::to_string(fw));
    281     Value * ctpopFunc = Intrinsic::getDeclaration(getModule(), Intrinsic::ctpop, fwVectorType(fw));
    282     return CreateCall(ctpopFunc, fwCast(fw, a));
    283 }
    284 
    285274Value * IDISA_Builder::simd_bitreverse(unsigned fw, Value * a) {
    286275    /*  Pure sequential solution too slow!
  • icGREP/icgrep-devel/icgrep/IR_Gen/idisa_builder.h

    r5729 r5828  
    104104    virtual llvm::Value * simd_pdep(unsigned fw, llvm::Value * v, llvm::Value * deposit_mask);
    105105   
    106     virtual llvm::Value * simd_cttz(unsigned fw, llvm::Value * a);
    107     virtual llvm::Value * simd_popcount(unsigned fw, llvm::Value * a);
     106    llvm::Value * simd_popcount(unsigned fw, llvm::Value * a) {
     107        if (LLVM_UNLIKELY(fw < 8)) {
     108            llvm::report_fatal_error("Unsupported field width: popcount " + std::to_string(fw));
     109        }
     110        return CreatePopcount(fwCast(fw, a));
     111    }
     112
    108113    virtual llvm::Value * simd_bitreverse(unsigned fw, llvm::Value * a);
    109114   
     
    134139    virtual llvm::Value * bitblock_mask_from(llvm::Value * pos);
    135140    virtual llvm::Value * bitblock_set_bit(llvm::Value * pos);
    136    
    137141
    138142    virtual void CreateBaseFunctions() {}
  • icGREP/icgrep-devel/icgrep/cc/cc_compiler.cpp

    r5823 r5828  
    230230
    231231   
    232 PabloAST * compileCCfromCodeUnitStream(const CC *cc, PabloAST * codeUnitStream, PabloBuilder & pb) {
     232PabloAST * compileCCfromCodeUnitStream(const CC * cc, PabloAST * codeUnitStream, PabloBuilder & pb) {
    233233    const Alphabet * a = cc->getAlphabet();
    234234    if (!isa<CodeUnitAlphabet>(a)) {
     
    239239    unsigned maxCodeVal = (topBit - 1) | topBit;
    240240    PabloAST * ccStrm = pb.createZeroes();
    241 #ifdef PABLO_ALL
    242241    for (const auto & interval : *cc) {
    243242        unsigned lo = re::lo_codepoint(interval);
    244243        unsigned hi = re::hi_codepoint(interval);
    245244        if (lo == hi) {
    246             PabloAST * testVal = pb.createAll(codeUnitWidth, lo);
    247             ccStrm = pb.createOr(ccStrm, pb.createEqual(codeUnitStream, testVal));
     245            PabloAST * testVal = pb.createRepeat(codeUnitWidth, lo);
     246            ccStrm = pb.createOr(ccStrm, pb.createEquals(codeUnitStream, testVal));
    248247        } else if (lo == 0) {
    249248            if (hi == maxCodeVal) {
     
    251250                ccStrm = pb.createOnes();
    252251            } else {
    253                 PabloAST * testVal = pb.createAll(codeUnitWidth, hi+1);
     252                PabloAST * testVal = pb.createRepeat(codeUnitWidth, hi+1);
    254253                ccStrm = pb.createOr(ccStrm, pb.createLessThan(codeUnitStream, testVal));
    255254            }
    256255        } else if (hi == maxCodeVal) {
    257             PabloAST * testVal = pb.createAll(codeUnitWidth, lo);
    258             ccStrm = pb.createOr(ccStrm, pb.createNot(pb.createLessThan(codeUnitStream, testVal));)
     256            PabloAST * testVal = pb.createRepeat(codeUnitWidth, lo);
     257            ccStrm = pb.createOr(ccStrm, pb.createNot(pb.createLessThan(codeUnitStream, testVal)));
    259258        } else {
    260             PabloAST * testVal_lo = pb.createAll(codeUnitWidth, lo);
    261             PabloAST * testVal_hi = pb.createAll(codeUnitWidth, hi+1);
     259            PabloAST * testVal_lo = pb.createRepeat(codeUnitWidth, lo);
     260            PabloAST * testVal_hi = pb.createRepeat(codeUnitWidth, hi + 1);
    262261            ccStrm = pb.createOr(ccStrm, pb.createAnd(pb.createNot(pb.createLessThan(codeUnitStream, testVal_lo)),
    263262                                                      pb.createLessThan(codeUnitStream, testVal_hi)));
    264263        }
    265264    }
    266 #endif
    267265    return ccStrm;
    268266}
  • icGREP/icgrep-devel/icgrep/kernels/cc_kernel.cpp

    r5823 r5828  
    8989}
    9090
     91inline std::vector<Binding> makeOutputBindings(const std::unique_ptr<kernel::KernelBuilder> & b, const std::vector<CC *> & charClasses) {
     92    std::vector<Binding> bindings;
     93    for (CC * cc : charClasses) {
     94        bindings.emplace_back(Binding(b->getStreamTy(), cc->canonicalName(re::CC_type::ByteClass)));
     95    }
     96    return bindings;
     97}
     98
    9199ParabixCharacterClassKernelBuilder::ParabixCharacterClassKernelBuilder (
    92100        const std::unique_ptr<kernel::KernelBuilder> & b, std::string ccSetName, const std::vector<CC *> & charClasses, unsigned codeUnitSize)
    93 : PabloKernel(b, ccSetName +"_kernel", {Binding{b->getStreamSetTy(codeUnitSize), "basis"}})
     101: PabloKernel(b, ccSetName +"_kernel",
     102// stream inputs
     103{Binding{b->getStreamSetTy(codeUnitSize), "basis"}}
     104// stream outputs
     105, makeOutputBindings(b, charClasses)
     106)
    94107, mCharClasses(charClasses) {
    95     for (CC * cc : mCharClasses) {
    96         addOutput(cc->canonicalName(re::CC_type::ByteClass), b->getStreamTy());
    97     }
     108
    98109}
    99110
  • icGREP/icgrep-devel/icgrep/pablo/analysis/pabloverifier.cpp

    r5782 r5828  
    22#include <pablo/branch.h>
    33#include <pablo/pe_var.h>
    4 #include <pablo/pe_phi.h>
    54#include <pablo/ps_assign.h>
     5#include <pablo/arithmetic.h>
    66#include <pablo/codegenstate.h>
    77#include <pablo/pablo_kernel.h>
     
    7676            }
    7777        } else if (isa<Var>(expr)) {
    78             if (LLVM_UNLIKELY(isa<Branch>(use) || isa<PabloKernel>(use))) {
     78            if (LLVM_UNLIKELY(isa<Branch>(use) || isa<Operator>(use) || isa<PabloKernel>(use))) {
    7979                ++uses;
    8080            } else {
     
    8585                str << " is a user of ";
    8686                PabloPrinter::print(expr, str);
    87                 str << " but can only be a user of a Branch or Kernel.";
     87                str << " but can only be a user of a Branch, Operator or Kernel.";
    8888                throw std::runtime_error(str.str());
     89            }
     90        } else if (const Operator * const user = dyn_cast<Operator>(use)) {
     91            if (user->getLH() == expr) {
     92                ++uses;
     93            }
     94            if (user->getRH() == expr) {
     95                ++uses;
    8996            }
    9097        }
  • icGREP/icgrep-devel/icgrep/pablo/builder.cpp

    r5821 r5828  
    77#include <pablo/pe_matchstar.h>
    88#include <pablo/pe_scanthru.h>
     9#include <pablo/pe_repeat.h>
    910#include <pablo/pe_infile.h>
    1011#include <pablo/pe_count.h>
     
    1516#include <pablo/pe_var.h>
    1617#include <pablo/ps_assign.h>
     18#include <boost/preprocessor/variadic/elem.hpp>
    1719
    1820using namespace llvm;
    1921
    2022namespace pablo {
     23
     24#define GET(I, ...) \
     25    reinterpret_cast<decltype(BOOST_PP_VARIADIC_ELEM(I, __VA_ARGS__))>(arg##I)
    2126
    2227#define MAKE_UNARY(NAME, TYPE, ARGS...) \
    2328struct __##NAME { \
    24     inline PabloAST * operator()(PabloAST * arg) { \
    25         return mPb->NAME(arg); \
     29    inline PabloAST * operator()(void * const arg0) { \
     30        return mPb->NAME(GET(0, ARGS)); \
    2631    } \
    27     inline __##NAME(PabloBlock * pb) : mPb(pb) {} \
     32    inline __##NAME(PabloBlock * const pb) : mPb(pb) {} \
    2833private: \
    29     PabloBlock * mPb; \
     34    PabloBlock * const mPb; \
    3035}; \
    3136__##NAME functor(mPb); \
     
    3439#define MAKE_NAMED_UNARY(NAME, TYPE, PREFIX, ARGS...) \
    3540struct __##NAME { \
    36     inline PabloAST * operator()(PabloAST * arg) { \
    37         return mPb->NAME(arg, mPrefix); \
     41    inline PabloAST * operator()(void * const arg0) { \
     42        return mPb->NAME(GET(0, ARGS), mPrefix); \
    3843    } \
    39     inline __##NAME(PabloBlock * pb, const llvm::StringRef & prefix) : mPb(pb), mPrefix(prefix) {} \
     44    inline __##NAME(PabloBlock * const pb, const llvm::StringRef & prefix) : mPb(pb), mPrefix(prefix) {} \
    4045private: \
    41     PabloBlock * mPb; \
     46    PabloBlock * const mPb; \
    4247    const llvm::StringRef & mPrefix; \
    4348}; \
     
    4752#define MAKE_BINARY(NAME, TYPE, ARGS...) \
    4853struct __##NAME { \
    49     inline PabloAST * operator()(PabloAST * arg1, PabloAST * arg2) { \
    50         return mPb->NAME(arg1, arg2); \
     54    inline PabloAST * operator()(void * const arg0, void * const arg1) { \
     55        return mPb->NAME(GET(0, ARGS), GET(1, ARGS)); \
    5156    } \
    52     inline __##NAME(PabloBlock * pb) : mPb(pb) {} \
     57    inline __##NAME(PabloBlock * const pb) : mPb(pb) {} \
    5358private: \
    54     PabloBlock * mPb; \
     59    PabloBlock * const mPb; \
    5560}; \
    5661__##NAME functor(mPb); \
     
    5964#define MAKE_NAMED_BINARY(NAME, TYPE, PREFIX, ARGS...) \
    6065struct __##NAME { \
    61     inline PabloAST * operator()(PabloAST * arg1, PabloAST * arg2) { \
    62         return mPb->NAME(arg1, arg2, mPrefix); \
     66    inline PabloAST * operator()(void * const arg0, void * const arg1) { \
     67        return mPb->NAME(GET(0, ARGS), GET(1, ARGS), mPrefix); \
    6368    } \
    64     inline __##NAME(PabloBlock * pb, const llvm::StringRef & prefix) : mPb(pb), mPrefix(prefix) {} \
     69    inline __##NAME(PabloBlock * const pb, const llvm::StringRef & prefix) : mPb(pb), mPrefix(prefix) {} \
    6570private: \
    66     PabloBlock * mPb; \
     71    PabloBlock * const mPb; \
    6772    const llvm::StringRef & mPrefix; \
    6873}; \
     
    7277#define MAKE_TERNARY(NAME, TYPE, ARGS...) \
    7378struct __##NAME { \
    74     inline PabloAST * operator()(PabloAST * arg1, PabloAST * arg2, PabloAST * arg3) { \
    75         return mPb->NAME(arg1, arg2, arg3); \
     79    inline PabloAST * operator()(void * const arg0, void * const arg1, void * const arg2) { \
     80        return mPb->NAME(GET(0, ARGS), GET(1, ARGS), GET(2, ARGS)); \
    7681    } \
    77     inline __##NAME(PabloBlock * pb) : mPb(pb) {} \
     82    inline __##NAME(PabloBlock * const pb) : mPb(pb) {} \
    7883private: \
    79     PabloBlock * mPb; \
     84    PabloBlock * const mPb; \
    8085}; \
    8186__##NAME functor(mPb); \
     
    8489#define MAKE_NAMED_TERNARY(NAME, TYPE, PREFIX, ARGS...) \
    8590struct __##NAME { \
    86     inline PabloAST * operator()(PabloAST * arg1, PabloAST * arg2, PabloAST * arg3) { \
    87         return mPb->NAME(arg1, arg2, arg3, mPrefix); \
     91    inline PabloAST * operator()(void * const arg0, void * const arg1, void * const arg2) { \
     92        return mPb->NAME(GET(0, ARGS), GET(1, ARGS), GET(2, ARGS), mPrefix); \
    8893    } \
    89     inline __##NAME(PabloBlock * pb, const llvm::StringRef & prefix) : mPb(pb), mPrefix(prefix) {} \
     94    inline __##NAME(PabloBlock * const pb, const llvm::StringRef & prefix) : mPb(pb), mPrefix(prefix) {} \
    9095private: \
    91     PabloBlock * mPb; \
     96    PabloBlock * const mPb; \
    9297    const llvm::StringRef & mPrefix; \
    9398}; \
     
    95100PabloAST * result = mExprTable.findTernaryOrCall(std::move(functor), TYPE, ARGS)
    96101
    97 #define MAKE_VARIABLE(NAME, TYPE, ARGS...) \
    98 struct __##NAME { \
    99     inline PabloAST * operator()(const std::vector<PabloAST *> & args, PabloAST * prototype) { \
    100         return mPb->NAME(prototype, args); \
    101     } \
    102     inline __##NAME(PabloBlock * pb) : mPb(pb) {} \
    103 private: \
    104     PabloBlock * mPb; \
    105 }; \
    106 __##NAME functor(mPb); \
    107 PabloAST * result = mExprTable.findVariadicOrCall(std::move(functor), TYPE, ARGS)
    108 
    109 template<typename Type>
    110 static inline Type * isBinary(PabloAST * expr) {
    111     if (isa<Type>(expr) && cast<Type>(expr)->getNumOperands() == 2) {
    112         return cast<Type>(expr);
    113     }
    114     return nullptr;
    115 }
    116 
    117102using TypeId = PabloAST::ClassTypeId;
    118103
    119 PabloAST * PabloBuilder::createAdvance(PabloAST * expr, PabloAST * shiftAmount) {
    120     if (isa<Zeroes>(expr) || cast<Integer>(shiftAmount)->value() == 0) {
     104PabloAST * PabloBuilder::createAdvance(PabloAST * expr, not_null<Integer *> shiftAmount) {
     105    if (isa<Zeroes>(expr) || cast<Integer>(shiftAmount.get())->value() == 0) {
    121106        return expr;
    122107    }
    123     MAKE_BINARY(createAdvance, TypeId::Advance, expr, shiftAmount);
    124     return result;
    125 }
    126 
    127 PabloAST * PabloBuilder::createAdvance(PabloAST * expr, PabloAST * shiftAmount, const llvm::StringRef & prefix) {
    128     if (isa<Zeroes>(expr) || cast<Integer>(shiftAmount)->value() == 0) {
     108    MAKE_BINARY(createAdvance, TypeId::Advance, expr, shiftAmount.get());
     109    return result;
     110}
     111
     112PabloAST * PabloBuilder::createAdvance(PabloAST * expr, not_null<Integer *> shiftAmount, const llvm::StringRef & prefix) {
     113    if (isa<Zeroes>(expr) || cast<Integer>(shiftAmount.get())->value() == 0) {
    129114        return expr;
    130115    }
    131     MAKE_NAMED_BINARY(createAdvance, TypeId::Advance, prefix, expr, shiftAmount);
    132     return result;
    133 }
    134 
    135 PabloAST * PabloBuilder::createIndexedAdvance(PabloAST * expr, PabloAST * indexStream, PabloAST * shiftAmount) {
    136     if (isa<Zeroes>(expr) || cast<Integer>(shiftAmount)->value() == 0) {
     116    MAKE_NAMED_BINARY(createAdvance, TypeId::Advance, prefix, expr, shiftAmount.get());
     117    return result;
     118}
     119
     120PabloAST * PabloBuilder::createIndexedAdvance(PabloAST * expr, PabloAST * indexStream, not_null<Integer *> shiftAmount) {
     121    if (isa<Zeroes>(expr) || cast<Integer>(shiftAmount.get())->value() == 0) {
    137122        return expr;
    138123    }
     
    140125        return createAdvance(expr, shiftAmount);
    141126    }
    142     else if (cast<Integer>(shiftAmount)->value() == 1) {
     127    else if (cast<Integer>(shiftAmount.get())->value() == 1) {
    143128        return createAdvanceThenScanTo(createAnd(expr, indexStream), indexStream);
    144129    }
    145     MAKE_TERNARY(createIndexedAdvance, TypeId::IndexedAdvance, expr, indexStream, shiftAmount);
    146     return result;
    147 }
    148 
    149 PabloAST * PabloBuilder::createIndexedAdvance(PabloAST * expr, PabloAST * indexStream, PabloAST * shiftAmount, const llvm::StringRef & prefix) {
    150     if (isa<Zeroes>(expr) || cast<Integer>(shiftAmount)->value() == 0) {
     130    MAKE_TERNARY(createIndexedAdvance, TypeId::IndexedAdvance, expr, indexStream, shiftAmount.get());
     131    return result;
     132}
     133
     134PabloAST * PabloBuilder::createIndexedAdvance(PabloAST * expr, PabloAST * indexStream, not_null<Integer *> shiftAmount, const llvm::StringRef & prefix) {
     135    if (isa<Zeroes>(expr) || cast<Integer>(shiftAmount.get())->value() == 0) {
    151136        return expr;
    152137    }
     
    154139        return createAdvance(expr, shiftAmount, prefix);
    155140    }
    156     else if (cast<Integer>(shiftAmount)->value() == 1) {
     141    else if (cast<Integer>(shiftAmount.get())->value() == 1) {
    157142        return createAdvanceThenScanTo(expr, indexStream, prefix);
    158143    }
    159     MAKE_NAMED_TERNARY(createIndexedAdvance, TypeId::IndexedAdvance, prefix, expr, indexStream, shiftAmount);
     144    MAKE_NAMED_TERNARY(createIndexedAdvance, TypeId::IndexedAdvance, prefix, expr, indexStream, shiftAmount.get());
    160145    return result;
    161146}
    162147   
    163 Extract * PabloBuilder::createExtract(PabloAST * value, not_null<PabloAST *> index) {
    164     MAKE_BINARY(createExtract, TypeId::Extract, value, index);
     148Extract * PabloBuilder::createExtract(Var * array, not_null<Integer *> index) {
     149    MAKE_BINARY(createExtract, TypeId::Extract, array, index.get());
    165150    return cast<Extract>(result);
    166151}
    167152
    168 Extract * PabloBuilder::createExtract(PabloAST * value, not_null<PabloAST *> index, const llvm::StringRef & prefix) {
    169     MAKE_NAMED_BINARY(createExtract, TypeId::Extract, prefix, value, index);
    170     return cast<Extract>(result);
    171 }
    172 
    173 PabloAST * PabloBuilder::createLookahead(PabloAST * expr, PabloAST * shiftAmount) {
    174     if (LLVM_UNLIKELY(isa<Zeroes>(expr) || cast<Integer>(shiftAmount)->value() == 0)) {
     153PabloAST * PabloBuilder::createLookahead(PabloAST * expr, not_null<Integer *> shiftAmount) {
     154    if (LLVM_UNLIKELY(isa<Zeroes>(expr) || cast<Integer>(shiftAmount.get())->value() == 0)) {
    175155        return expr;
    176156    }
    177     MAKE_BINARY(createLookahead, TypeId::Lookahead, expr, shiftAmount);
    178     return result;
    179 }
    180 
    181 PabloAST * PabloBuilder::createLookahead(PabloAST * expr, PabloAST * shiftAmount, const llvm::StringRef & prefix) {
    182     if (LLVM_UNLIKELY(isa<Zeroes>(expr) || cast<Integer>(shiftAmount)->value() == 0)) {
     157    MAKE_BINARY(createLookahead, TypeId::Lookahead, expr, shiftAmount.get());
     158    return result;
     159}
     160
     161PabloAST * PabloBuilder::createLookahead(PabloAST * expr, not_null<Integer *> shiftAmount, const llvm::StringRef & prefix) {
     162    if (LLVM_UNLIKELY(isa<Zeroes>(expr) || cast<Integer>(shiftAmount.get())->value() == 0)) {
    183163        return expr;
    184164    }
    185     MAKE_NAMED_BINARY(createLookahead, TypeId::Lookahead, prefix, expr, shiftAmount);
     165    MAKE_NAMED_BINARY(createLookahead, TypeId::Lookahead, prefix, expr, shiftAmount.get());
    186166    return result;
    187167}
    188168
    189169PabloAST * PabloBuilder::createNot(PabloAST * expr) {
    190     if (isa<Ones>(expr)) {
     170    if (LLVM_UNLIKELY(isa<Ones>(expr))) {
    191171        return createZeroes(expr->getType());
    192172    }
    193     else if (isa<Zeroes>(expr)){
     173    else if (LLVM_UNLIKELY(isa<Zeroes>(expr))){
    194174        return createOnes(expr->getType());
    195175    }
     
    202182
    203183PabloAST * PabloBuilder::createNot(PabloAST * expr, const llvm::StringRef & prefix) {
    204     if (isa<Ones>(expr)) {
     184    if (LLVM_UNLIKELY(isa<Ones>(expr))) {
    205185        return createZeroes(expr->getType());
    206186    }
    207     else if (isa<Zeroes>(expr)){
     187    else if (LLVM_UNLIKELY(isa<Zeroes>(expr))){
    208188        return createOnes(expr->getType());
    209189    }
     
    225205}
    226206
    227 PabloAST * PabloBuilder::createAssign(PabloAST * const variable, PabloAST * const value) {
    228     return mPb->createAssign(variable, value);
     207PabloAST * PabloBuilder::createRepeat(not_null<Integer *> fieldWidth, PabloAST * value) {
     208    MAKE_BINARY(createRepeat, TypeId::Fill, fieldWidth.get(), value);
     209    return result;
     210}
     211
     212PabloAST * PabloBuilder::createRepeat(not_null<Integer *> fieldWidth, PabloAST * value, const llvm::StringRef & prefix) {
     213    MAKE_NAMED_BINARY(createRepeat, TypeId::Fill, prefix, fieldWidth.get(), value);
     214    return result;
    229215}
    230216
     
    244230            return createZeroes(expr1->getType());
    245231        }
    246     } else if (Or * or1 = isBinary<Or>(expr1)) {
     232    } else if (Or * or1 = dyn_cast<Or>(expr1)) {
    247233        if (equals(or1->getOperand(0), expr2) || equals(or1->getOperand(1), expr2)) {
    248234            return expr2;
    249235        }
    250     } else if (Or * or2 = isBinary<Or>(expr2)) {
     236    } else if (Or * or2 = dyn_cast<Or>(expr2)) {
    251237        if (equals(or2->getOperand(0), expr1) || equals(or2->getOperand(1), expr1)) {
    252238            return expr1;
     
    275261            return createZeroes(expr1->getType());
    276262        }
    277     } else if (Or * or1 = isBinary<Or>(expr1)) {
     263    } else if (Or * or1 = dyn_cast<Or>(expr1)) {
    278264        if (equals(or1->getOperand(0), expr2) || equals(or1->getOperand(1), expr2)) {
    279265            return expr2;
    280266        }
    281     } else if (Or * or2 = isBinary<Or>(expr2)) {
     267    } else if (Or * or2 = dyn_cast<Or>(expr2)) {
    282268        if (equals(or2->getOperand(0), expr1) || equals(or2->getOperand(1), expr1)) {
    283269            return expr1;
     
    305291    } else if (equals(expr1, expr2)) {
    306292        return expr1;
    307     } else if (And * and1 = isBinary<And>(expr1)) {
     293    } else if (And * and1 = dyn_cast<And>(expr1)) {
    308294        PabloAST * const expr1a = and1->getOperand(0);
    309295        PabloAST * const expr1b = and1->getOperand(1);
    310         if (And * and2 = isBinary<And>(expr2)) {
     296        if (And * and2 = dyn_cast<And>(expr2)) {
    311297            PabloAST * const expr2a = and2->getOperand(0);
    312298            PabloAST * const expr2b = and2->getOperand(1);
     
    326312            return expr2;
    327313        }
    328     } else if (And * and2 = isBinary<And>(expr2)) {
     314    } else if (And * and2 = dyn_cast<And>(expr2)) {
    329315        if (equals(and2->getOperand(0), expr1) || equals(and2->getOperand(1), expr1)) {
    330316            return expr1;
     
    352338    } else if (equals(expr1, expr2)) {
    353339        return expr1;
    354     } else if (And * and1 = isBinary<And>(expr1)) {
     340    } else if (And * and1 = dyn_cast<And>(expr1)) {
    355341        PabloAST * const expr1a = and1->getOperand(0);
    356342        PabloAST * const expr1b = and1->getOperand(1);
    357         if (And * and2 = isBinary<And>(expr2)) {
     343        if (And * and2 = dyn_cast<And>(expr2)) {
    358344            PabloAST * const expr2a = and2->getOperand(0);
    359345            PabloAST * const expr2b = and2->getOperand(1);
     
    373359            return expr2;
    374360        }
    375     } else if (And * and2 = isBinary<And>(expr2)) {
     361    } else if (And * and2 = dyn_cast<And>(expr2)) {
    376362        if (equals(and2->getOperand(0), expr1) || equals(and2->getOperand(1), expr1)) {
    377363            return expr1;
     
    468454    }
    469455    MAKE_BINARY(createLessThan, TypeId::LessThan, expr1, expr2);
     456    return result;
     457}
     458
     459PabloAST * PabloBuilder::createEquals(PabloAST * expr1, PabloAST * expr2) {
     460    if (isa<Integer>(expr1) && isa<Integer>(expr2)) {
     461        return getInteger(cast<Integer>(expr1)->value() == cast<Integer>(expr2)->value() ? 1 : 0);
     462    }
     463    MAKE_BINARY(createEquals, TypeId::Equals, expr1, expr2);
    470464    return result;
    471465}
  • icGREP/icgrep-devel/icgrep/pablo/builder.hpp

    r5709 r5828  
    1313    template<typename T>
    1414    struct not_null {
    15         inline not_null(T const value) : _value(value) { assert(_value); }
    16         inline not_null(std::nullptr_t) = delete;
    17         inline not_null(unsigned) = delete;
     15        not_null(T const value) : _value(value) { assert(_value); }
     16        not_null(std::nullptr_t) = delete;
     17        not_null(unsigned) = delete;
    1818        operator T() const { return _value; }
    1919        T operator-> () const { return _value; }
     
    5050    using const_iterator = PabloBlock::const_iterator;
    5151
    52     inline static PabloBuilder Create(PabloBlock * block) noexcept {
     52    static PabloBuilder Create(PabloBlock * block) noexcept {
    5353        return PabloBuilder(block);
    5454    }
    5555
    56     inline static PabloBuilder Create(PabloBuilder & builder) noexcept {
     56    static PabloBuilder Create(PabloBuilder & builder) noexcept {
    5757        return PabloBuilder(PabloBlock::Create(builder.getPabloBlock()->getParent()), builder);
    5858    }
    5959
    60     inline Zeroes * createZeroes(llvm::Type * const type = nullptr) {
     60    Zeroes * createZeroes(llvm::Type * const type = nullptr) {
    6161        return mPb->createZeroes(type);
    6262    }
    6363
    64     inline Ones * createOnes(llvm::Type * const type = nullptr) {
     64    Ones * createOnes(llvm::Type * const type = nullptr) {
    6565        return mPb->createOnes(type);
    6666    }
    6767
    68     inline Var * createVar(const llvm::StringRef & name, llvm::Type * const type = nullptr) {
     68    Var * createVar(const llvm::StringRef & name, llvm::Type * const type = nullptr) {
    6969        return createVar(makeName(name), type);
    7070    }
    7171
    72     inline Var * createVar(const llvm::StringRef & name, PabloAST * value) {
    73         Var * var = createVar(name, value->getType());
     72    Var * createVar(const llvm::StringRef & name, PabloAST * value) {
     73        Var * const var = createVar(name, value->getType());
    7474        createAssign(var, value);
    7575        return var;
    7676    }
    7777
    78     inline Var * createVar(String * const name, llvm::Type * const type = nullptr) {
     78    Var * createVar(String * const name, llvm::Type * const type = nullptr) {
    7979        return mPb->createVar(name, type);
    8080    }
    8181
    82     Extract * createExtract(PabloAST * value, not_null<PabloAST *> index);
    83 
    84     inline Extract * createExtract(PabloAST * value, const int64_t index) {
    85         return createExtract(value, getInteger(index));
    86     }
    87 
    88     Extract * createExtract(PabloAST * value, not_null<PabloAST *> index, const llvm::StringRef & prefix);
    89 
    90     inline Extract * createExtract(PabloAST * value, const int64_t index, const llvm::StringRef & prefix) {
    91         return createExtract(value, getInteger(index), prefix);
    92     }
    93 
    94     inline PabloAST * createAdvance(PabloAST * expr, const int64_t shiftAmount) {
     82    Extract * createExtract(Var * const array, not_null<Integer *> index);
     83
     84    Extract * createExtract(Var * const array, const int64_t index) {
     85        return createExtract(array, getInteger(index));
     86    }
     87
     88    Var * createExtract(Var * const array, not_null<Integer *> index, const llvm::StringRef & name) {
     89        return createVar(name, createExtract(array, index));
     90    }
     91
     92    Var * createExtract(Var * const array, const int64_t index, const llvm::StringRef & name) {
     93        return createVar(name, createExtract(array, index));
     94    }
     95
     96    PabloAST * createAdvance(PabloAST * expr, const int64_t shiftAmount) {
     97        if (shiftAmount == 0) {
     98            return expr;
     99        }
    95100        return createAdvance(expr, mPb->getInteger(shiftAmount));
    96101    }
    97102
    98     PabloAST * createAdvance(PabloAST * expr, PabloAST * shiftAmount);
    99 
    100     inline PabloAST * createAdvance(PabloAST * expr, const int64_t shiftAmount, const llvm::StringRef & prefix) {
     103    PabloAST * createAdvance(PabloAST * expr, not_null<Integer *> shiftAmount);
     104
     105    PabloAST * createAdvance(PabloAST * expr, const int64_t shiftAmount, const llvm::StringRef & prefix) {
     106        if (shiftAmount == 0) {
     107            return expr;
     108        }
    101109        return createAdvance(expr, mPb->getInteger(shiftAmount), prefix);
    102110    }
    103111
    104     PabloAST * createAdvance(PabloAST * expr, PabloAST * shiftAmount, const llvm::StringRef & prefix);
    105 
    106     inline PabloAST * createIndexedAdvance(PabloAST * expr, PabloAST * indexStream, const int64_t shiftAmount) {
     112    PabloAST * createAdvance(PabloAST * expr, not_null<Integer *> shiftAmount, const llvm::StringRef & prefix);
     113
     114    PabloAST * createIndexedAdvance(PabloAST * expr, PabloAST * indexStream, const int64_t shiftAmount) {
     115        if (shiftAmount == 0) {
     116            return expr;
     117        }
    107118        return createIndexedAdvance(expr, indexStream, mPb->getInteger(shiftAmount));
    108119    }
    109120   
    110     PabloAST * createIndexedAdvance(PabloAST * expr, PabloAST * indexStream, PabloAST * shiftAmount);
    111    
    112     inline PabloAST * createIndexedAdvance(PabloAST * expr, PabloAST * indexStream, const int64_t shiftAmount, const llvm::StringRef & prefix) {
     121    PabloAST * createIndexedAdvance(PabloAST * expr, PabloAST * indexStream, not_null<Integer *> shiftAmount);
     122   
     123    PabloAST * createIndexedAdvance(PabloAST * expr, PabloAST * indexStream, const int64_t shiftAmount, const llvm::StringRef & prefix) {
     124        if (shiftAmount == 0) {
     125            return expr;
     126        }
    113127        return createIndexedAdvance(expr, indexStream, mPb->getInteger(shiftAmount), prefix);
    114128    }
    115129   
    116     PabloAST * createIndexedAdvance(PabloAST * expr, PabloAST * indexStream, PabloAST * shiftAmount, const llvm::StringRef & prefix);
    117    
    118     inline PabloAST * createLookahead(PabloAST * expr, const int64_t shiftAmount) {
     130    PabloAST * createIndexedAdvance(PabloAST * expr, PabloAST * indexStream, not_null<Integer *> shiftAmount, const llvm::StringRef & prefix);
     131   
     132    PabloAST * createLookahead(PabloAST * expr, const int64_t shiftAmount) {
    119133        if (shiftAmount == 0) {
    120134            return expr;
     
    123137    }
    124138
    125     PabloAST * createLookahead(PabloAST * expr, PabloAST * shiftAmount);
    126 
    127     inline PabloAST * createLookahead(PabloAST * expr, const int64_t shiftAmount, const llvm::StringRef & prefix) {
     139    PabloAST * createLookahead(PabloAST * expr, not_null<Integer *> shiftAmount);
     140
     141    PabloAST * createLookahead(PabloAST * expr, const int64_t shiftAmount, const llvm::StringRef & prefix) {
    128142        if (shiftAmount == 0) {
    129143            return expr;
     
    132146    }
    133147
    134     PabloAST * createLookahead(PabloAST * expr, PabloAST * shiftAmount, const llvm::StringRef & prefix);
    135 
    136     PabloAST * createAssign(PabloAST * const variable, PabloAST * const value);
     148    PabloAST * createLookahead(PabloAST * expr, not_null<Integer *> shiftAmount, const llvm::StringRef & prefix);
     149
     150    Assign * createAssign(PabloAST * const variable, PabloAST * const value){
     151        return mPb->createAssign(variable, value);
     152    }
    137153
    138154    PabloAST * createAnd(PabloAST * expr1, PabloAST * expr2);
     
    144160    PabloAST * createNot(PabloAST * expr, const llvm::StringRef & prefix);
    145161
     162    PabloAST * createRepeat(const int64_t fieldWidth, const int64_t value) {
     163        return createRepeat(mPb->getInteger(fieldWidth), mPb->getInteger(value));
     164    }
     165
     166    PabloAST * createRepeat(const int64_t fieldWidth, PabloAST * value) {
     167        return createRepeat(mPb->getInteger(fieldWidth), value);
     168    }
     169
     170    PabloAST * createRepeat(not_null<Integer *> fieldWidth, PabloAST * value);
     171
     172    PabloAST * createRepeat(const int64_t fieldWidth, PabloAST * value, const llvm::StringRef & prefix) {
     173        return createRepeat(mPb->getInteger(fieldWidth), value, prefix);
     174    }
     175
     176    PabloAST * createRepeat(const int64_t fieldWidth, const int64_t value, const llvm::StringRef & prefix) {
     177        return createRepeat(mPb->getInteger(fieldWidth), mPb->getInteger(value), prefix);
     178    }
     179
     180    PabloAST * createRepeat(not_null<Integer *> fieldWidth, PabloAST * value, const llvm::StringRef & prefix);
     181
    146182    PabloAST * createOr(PabloAST * expr1, PabloAST * expr2);
    147183
     
    194230    PabloAST * createLessThan(PabloAST * expr1, PabloAST * expr2);
    195231
    196     inline If * createIf(PabloAST * condition, PabloBlock * body) {
     232    PabloAST * createEquals(PabloAST * expr1, PabloAST * expr2);
     233
     234    If * createIf(PabloAST * condition, PabloBlock * body) {
    197235        return mPb->createIf(condition, body);
    198236    }
    199237
    200     inline If * createIf(PabloAST * condition, PabloBuilder & builder) {
     238    If * createIf(PabloAST * condition, PabloBuilder & builder) {
    201239        return mPb->createIf(condition, builder.mPb);
    202240    }
    203241
    204     inline While * createWhile(PabloAST * condition, PabloBlock * body) {
     242    While * createWhile(PabloAST * condition, PabloBlock * body) {
    205243        return mPb->createWhile(condition, body);
    206244    }
    207245
    208     inline While * createWhile(PabloAST * condition, PabloBuilder & builder) {
     246    While * createWhile(PabloAST * condition, PabloBuilder & builder) {
    209247        return mPb->createWhile(condition, builder.mPb);
    210248    }
     
    236274    }
    237275
    238     inline Statement * front() const {
     276    Statement * front() const {
    239277        return mPb->front();
    240278    }
    241279
    242     inline Statement * back() const {
     280    Statement * back() const {
    243281        return mPb->back();
    244282    }
    245283
    246     inline Statement * getInsertPoint() const {
     284    Statement * getInsertPoint() const {
    247285        return mPb->getInsertPoint();
    248286    }
    249287
    250     inline PabloBlock * getPabloBlock() const {
     288    PabloBlock * getPabloBlock() const {
    251289        return mPb;
    252290    }
    253291
    254     inline PabloBuilder * getParent() const {
     292    PabloBuilder * getParent() const {
    255293        return mParent;
    256294    }
    257295
    258     inline String * makeName(const llvm::StringRef & prefix) const {
     296    String * makeName(const llvm::StringRef & prefix) const {
    259297        return mPb->makeName(prefix);
    260298    }
    261299
    262     inline Integer * getInteger(const uint64_t value) const {
     300    Integer * getInteger(const uint64_t value) const {
    263301        return mPb->getInteger(value);
    264302    }
    265303
    266     inline void print(llvm::raw_ostream & O, const bool expandNested = true) const {
     304    void print(llvm::raw_ostream & O, const bool expandNested = true) const {
    267305        mPb->print(O, expandNested);
    268306    }
  • icGREP/icgrep-devel/icgrep/pablo/carry_manager.cpp

    r5771 r5828  
    178178        freeDynamicallyAllocatedMemory(idb, idb->getScalarFieldPtr("carries"));
    179179    }
     180}
     181
     182/** ------------------------------------------------------------------------------------------------------------- *
     183 * @brief clearCarryState
     184 ** ------------------------------------------------------------------------------------------------------------- */
     185void CarryManager::clearCarryData(const std::unique_ptr<kernel::KernelBuilder> & idb) {
     186
     187
     188
    180189}
    181190
  • icGREP/icgrep-devel/icgrep/pablo/carry_manager.h

    r5708 r5828  
    4747    CarryManager() noexcept;
    4848
    49     void initializeCarryData(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, PabloKernel * const kernel);
     49    void initializeCarryData(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, PabloKernel * const kernel);   
    5050
    5151    void releaseCarryData(const std::unique_ptr<kernel::KernelBuilder> & idb);
     
    8686         
    8787    llvm::Value * generateSummaryTest(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, llvm::Value * condition);
     88
     89    /* Clear carry state for conditional regions */
     90
     91    void clearCarryData(const std::unique_ptr<kernel::KernelBuilder> & idb);
    8892
    8993protected:
  • icGREP/icgrep-devel/icgrep/pablo/codegenstate.cpp

    r5709 r5828  
    1717#include <pablo/pe_matchstar.h>
    1818#include <pablo/pe_ones.h>
    19 #include <pablo/pe_phi.h>
     19#include <pablo/pe_pack.h>
     20#include <pablo/pe_repeat.h>
    2021#include <pablo/pe_scanthru.h>
    2122#include <pablo/pe_string.h>
     
    2829#include <llvm/Support/raw_os_ostream.h>
    2930
    30 #define CHECK_SAME_TYPE(A, B) \
    31     assert ("DIFFERING CONTEXTS" && (&((A)->getType()->getContext()) == &((B)->getType()->getContext()))); \
    32     assert ("DIFFERING TYPES" && ((A)->getType() == (B)->getType()))
    33 
    3431using namespace llvm;
    3532
    3633namespace pablo {
    3734
    38 
    39 Phi * PabloBlock::createPhi(Type * type) {
    40     return new (mAllocator) Phi(type, mAllocator);
    41 }
     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
    4247
    4348/// UNARY CREATE FUNCTIONS
     
    8792    return insertAtInsertionPoint(new (mAllocator) AtEOF(expr, name, mAllocator));
    8893}
    89    
    90    
     94
    9195/// BINARY CREATE FUNCTIONS
    9296
    93 Advance * PabloBlock::createAdvance(PabloAST * expr, PabloAST * shiftAmount, String * name) {
     97Advance * PabloBlock::createAdvance(PabloAST * expr, Integer * shiftAmount, String * name) {
    9498    if (name == nullptr) {
    9599        name = makeName("advance");
     
    98102}
    99103
    100 Lookahead * PabloBlock::createLookahead(PabloAST * expr, PabloAST * shiftAmount, String * name) {
     104Lookahead * PabloBlock::createLookahead(PabloAST * expr, Integer * shiftAmount, String * name) {
    101105    if (name == nullptr) {
    102106        name = makeName("lookahead");
     
    105109}
    106110
    107 Extract * PabloBlock::createExtract(PabloAST * array, PabloAST * index, String * name) {
     111Extract * PabloBlock::createExtract(Var * array, Integer * index) {
    108112    assert (array && index);
    109     if (name == nullptr) {
    110         std::string tmp;
    111         raw_string_ostream out(tmp);
    112         array->print(out);
    113         out << '[';
    114         index->print(out);
    115         out << ']';
    116         name = makeName(out.str());
    117     }
    118113    Type * type = array->getType();
    119114    if (LLVM_LIKELY(isa<ArrayType>(type))) {
     
    124119        out << "cannot extract element from ";
    125120        array->print(out);
    126         out << " : not a StreamType or ArrayType";
     121        out << ": ";
     122        type->print(out);
     123        out << " is not an array type";
    127124        throw std::runtime_error(out.str());
    128125    }
    129     return insertAtInsertionPoint(new (mAllocator) Extract(array, index, name, type, mAllocator));
     126    return new (mAllocator) Extract(array, index, type, mAllocator);
    130127}
    131128
     
    186183
    187184LessThan * PabloBlock::createLessThan(PabloAST * expr1, PabloAST * expr2) {
    188     CHECK_SAME_TYPE(expr1, expr2);
    189     IntegerType * const int1Ty = getParent()->getInt1Ty();
    190     return new (mAllocator) LessThan(int1Ty, expr1, expr2, mAllocator);
    191 }
    192 
    193 enum class AssignErrorType {
    194     TypeMismatch
    195     , ReadOnlyVar
    196     , NotAVariable
    197 };
    198 
    199 static void reportAssignError(PabloAST * const var, PabloAST * const value, const AssignErrorType type) {
    200     std::string tmp;
    201     raw_string_ostream out(tmp);
    202     out << "Cannot assign ";
    203     value->print(out);
    204     out << " to ";
    205     var->print(out);
    206     out << ": ";
    207     switch (type) {
    208         case AssignErrorType::TypeMismatch:
    209             out << "type mismatch ";
    210             value->getType()->print(out);
    211             out << " vs. ";
    212             var->getType()->print(out);
    213             break;
    214         case AssignErrorType::ReadOnlyVar:
    215             var->print(out);
    216             out << " is read only";
    217             break;
    218         case AssignErrorType::NotAVariable:
    219             var->print(out);
    220             out << " is not a variable";
    221             break;
    222     }
    223     llvm::report_fatal_error(out.str());
     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);
     193}
     194
     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);
     202    }
     203    return new (mAllocator) Equals(ty, expr1, expr2, mAllocator);
    224204}
    225205
    226206Assign * PabloBlock::createAssign(PabloAST * const var, PabloAST * const value) {
    227207    CHECK_SAME_TYPE(var, value);
    228 
    229     if (LLVM_UNLIKELY(var->getType() != value->getType())) {
    230         reportAssignError(var, value, AssignErrorType::TypeMismatch);
    231     }
    232 
    233     PabloAST * test = var;
    234     for (;;) {
    235         if (LLVM_LIKELY(isa<Var>(test))) {
    236             if (LLVM_UNLIKELY(cast<Var>(test)->isReadOnly())) {
    237                 reportAssignError(var, value, AssignErrorType::ReadOnlyVar);
    238             }
    239             break;
    240         } else if (isa<Extract>(test)) {
    241             test = cast<Extract>(test)->getArray();
     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);
     213    }
     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";
    242225        } else {
    243             reportAssignError(var, value, AssignErrorType::NotAVariable);
     226            out << " is read only";
    244227        }
    245     }
    246 
     228        report_fatal_error(out.str());
     229    }
    247230    return insertAtInsertionPoint(new (mAllocator) Assign(var, value, mAllocator));
    248231}
     
    289272
    290273If * PabloBlock::createIf(PabloAST * condition, PabloBlock * body) {
    291     assert (condition);
     274    assert (condition && body);
    292275    If * const node = insertAtInsertionPoint(new (mAllocator) If(condition, body, mAllocator));
    293276    body->setBranch(node);
     
    296279
    297280While * PabloBlock::createWhile(PabloAST * condition, PabloBlock * body) {
    298     assert (condition);
     281    assert (condition && body);
    299282    While * const node = insertAtInsertionPoint(new (mAllocator) While(condition, body, mAllocator));
    300283    body->setBranch(node);
     
    302285}
    303286
     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
    304314/// TERNARY CREATE FUNCTIONS
    305315
     
    312322}
    313323
    314 IndexedAdvance * PabloBlock::createIndexedAdvance(PabloAST * expr, PabloAST * indexStream, PabloAST * shiftAmount, String * name) {
     324IndexedAdvance * PabloBlock::createIndexedAdvance(PabloAST * expr, PabloAST * indexStream, Integer * shiftAmount, String * name) {
    315325    if (name == nullptr) {
    316326        name = makeName("indexed_advance");
  • icGREP/icgrep-devel/icgrep/pablo/codegenstate.h

    r5709 r5828  
    2828namespace pablo { class InFile; }
    2929namespace pablo { class LessThan; }
     30namespace pablo { class Equals; }
    3031namespace pablo { class Lookahead; }
    3132namespace pablo { class MatchStar; }
     
    3435namespace pablo { class Or; }
    3536namespace pablo { class PabloKernel; }
    36 namespace pablo { class Phi; }
     37namespace pablo { class PackH; }
     38namespace pablo { class PackL; }
    3739namespace pablo { class ScanThru; }
    3840namespace pablo { class ScanTo; }
    3941namespace pablo { class Sel; }
     42namespace pablo { class Repeat; }
    4043namespace pablo { class String; }
    4144namespace pablo { class Subtract; }
     
    6871    static PabloBlock * Create(PabloKernel * const parent) noexcept;
    6972
    70     Advance * createAdvance(PabloAST * expr, PabloAST * shiftAmount) {
     73    Advance * createAdvance(PabloAST * expr, Integer * shiftAmount) {
    7174        return createAdvance(expr, shiftAmount, nullptr);
    7275    }
    7376   
    74     Advance * createAdvance(PabloAST * expr, PabloAST * shiftAmount, const llvm::StringRef & prefix) {
     77    Advance * createAdvance(PabloAST * expr, Integer * shiftAmount, const llvm::StringRef & prefix) {
    7578        return createAdvance(expr, shiftAmount, makeName(prefix));
    7679    }
    7780   
    78     Advance * createAdvance(PabloAST * expr, PabloAST * shiftAmount, String * name);
    79    
    80     IndexedAdvance * createIndexedAdvance(PabloAST * expr, PabloAST * indexStream, PabloAST * shiftAmount) {
     81    Advance * createAdvance(PabloAST * expr, Integer * shiftAmount, String * name);
     82   
     83    IndexedAdvance * createIndexedAdvance(PabloAST * expr, PabloAST * indexStream, Integer * shiftAmount) {
    8184        return createIndexedAdvance(expr, indexStream, shiftAmount, nullptr);
    8285    }
    8386   
    84     IndexedAdvance * createIndexedAdvance(PabloAST * expr, PabloAST * indexStream, PabloAST * shiftAmount, const llvm::StringRef & prefix) {
     87    IndexedAdvance * createIndexedAdvance(PabloAST * expr, PabloAST * indexStream, Integer * shiftAmount, const llvm::StringRef & prefix) {
    8588        return createIndexedAdvance(expr, indexStream, shiftAmount, makeName(prefix));
    8689    }
    8790   
    88     IndexedAdvance * createIndexedAdvance(PabloAST * expr, PabloAST * indexStream, PabloAST * shiftAmount, String * name);
    89    
    90     Lookahead * createLookahead(PabloAST * expr, PabloAST * shiftAmount) {
     91    IndexedAdvance * createIndexedAdvance(PabloAST * expr, PabloAST * indexStream, Integer * shiftAmount, String * name);
     92   
     93    Lookahead * createLookahead(PabloAST * expr, Integer * shiftAmount) {
    9194        return createLookahead(expr, shiftAmount, nullptr);
    9295    }
    9396
    94     Lookahead * createLookahead(PabloAST * expr, PabloAST * shiftAmount, const llvm::StringRef & prefix) {
     97    Lookahead * createLookahead(PabloAST * expr, Integer * shiftAmount, const llvm::StringRef & prefix) {
    9598        return createLookahead(expr, shiftAmount, makeName(prefix));
    9699    }
    97100
    98     Lookahead * createLookahead(PabloAST * expr, PabloAST * shiftAmount, String * name);
     101    Lookahead * createLookahead(PabloAST * expr, Integer * shiftAmount, String * name);
    99102
    100103    inline Zeroes * createZeroes(llvm::Type * const type = nullptr) {
     
    148151    AtEOF * createAtEOF(PabloAST * expr, String * name);
    149152
    150     inline Extract * createExtract(PabloAST * array, PabloAST * index) {
    151         return createExtract(array, index, nullptr);
    152     }
    153 
    154     Extract * createExtract(PabloAST * array, PabloAST * index, const llvm::StringRef & prefix) {
    155         return createExtract(array, index, makeName(prefix));
    156     }
    157 
    158     Extract * createExtract(PabloAST * array, const int64_t index) {
    159         return createExtract(array, getInteger(index), nullptr);
    160     }
    161 
    162     Extract * createExtract(PabloAST * array, const int64_t index, const llvm::StringRef & prefix) {
    163         return createExtract(array, getInteger(index), makeName(prefix));
    164     }
    165 
    166     Extract * createExtract(PabloAST * array, PabloAST * index, String * name);
     153    Extract * createExtract(Var * array, Integer * index);
    167154
    168155    Assign * createAssign(PabloAST * const var, PabloAST * const value);
     
    232219    LessThan * createLessThan(PabloAST * expr1, PabloAST * expr2);
    233220
     221    Equals * createEquals(PabloAST * expr1, PabloAST * expr2);
     222
    234223    MatchStar * createMatchStar(PabloAST * marker, PabloAST * charclass) {
    235224        return createMatchStar(marker, charclass, nullptr);
     
    286275    While * createWhile(PabloAST * condition, PabloBlock * body);
    287276
    288     Phi * createPhi(llvm::Type * type);
     277    Repeat * createRepeat(Integer * fieldWidth, PabloAST * value) {
     278        return createRepeat(fieldWidth, value, nullptr);
     279    }
     280
     281    Repeat * createRepeat(Integer * fieldWidth, PabloAST * value, const llvm::StringRef & prefix) {
     282        return createRepeat(fieldWidth, value, makeName(prefix));
     283    }
     284
     285    Repeat * createRepeat(Integer * fieldWidth, PabloAST * value, String * name);
     286
     287    PackH * createPackH(Integer * fieldWidth, PabloAST * value) {
     288        return createPackH(fieldWidth, value, nullptr);
     289    }
     290
     291    PackH * createPackH(Integer * width, PabloAST * value, const llvm::StringRef & prefix) {
     292        return createPackH(width, value, makeName(prefix));
     293    }
     294
     295    PackH * createPackH(Integer * fieldWidth, PabloAST * value, String * name);
     296
     297    PackL * createPackL(Integer * fieldWidth, PabloAST * value) {
     298        return createPackL(fieldWidth, value, nullptr);
     299    }
     300
     301    PackL * createPackL(Integer * fieldWidth, PabloAST * value, const llvm::StringRef & prefix) {
     302        return createPackL(fieldWidth, value, makeName(prefix));
     303    }
     304
     305    PackL * createPackL(Integer * fieldWidth, PabloAST * value, String * name);
    289306
    290307    PabloBlock * getPredecessor() const;
     
    312329    inline Integer * getInteger(const int64_t value) const {
    313330        return mParent->getInteger(value);
     331    }
     332
     333    llvm::LLVMContext & getContext() const {
     334        return mParent->getContext();
    314335    }
    315336
  • icGREP/icgrep-devel/icgrep/pablo/expression_map.hpp

    r5710 r5828  
    1515    friend struct ExpressionTable;
    1616
    17     explicit FixedArgMap(Type * predecessor = nullptr) : mPredecessor(predecessor) { }
     17    explicit FixedArgMap(Type * predecessor = nullptr) noexcept
     18    : mPredecessor(predecessor) {
     19
     20    }
    1821
    1922    explicit FixedArgMap(Type && other) noexcept
     
    2326    }
    2427
    25     FixedArgMap & operator=(Type && other) {
     28    FixedArgMap & operator=(Type && other) noexcept {
    2629        mPredecessor = other.mPredecessor;
    2730        mMap = std::move(other.mMap);
     
    3033
    3134    template <class Functor, typename... Params>
    32     PabloAST * findOrCall(Functor && functor, const PabloAST::ClassTypeId type, Args... args, Params... params) {
    33         Key key = std::make_tuple(type, args...);
     35    PabloAST * findOrCall(Functor && functor, const PabloAST::ClassTypeId typeId, Args... args, Params... params) noexcept {
     36        Key key = std::make_tuple(typeId, args...);
    3437        PabloAST * const f = find(key);
    3538        if (f) {
     
    4144    }
    4245
    43     std::pair<PabloAST *, bool> findOrAdd(PabloAST * object, const PabloAST::ClassTypeId type, Args... args) {
    44         Key key = std::make_tuple(type, args...);
     46    std::pair<PabloAST *, bool> findOrAdd(PabloAST * object, const PabloAST::ClassTypeId typeId, Args... args) noexcept {
     47        Key key = std::make_tuple(typeId, args...);
    4548        PabloAST * const entry = find(key);
    4649        if (entry) {
     
    5154    }
    5255
    53     bool erase(const PabloAST::ClassTypeId type, Args... args) {
     56    bool erase(const PabloAST::ClassTypeId type, Args... args) noexcept {
    5457        Key key = std::make_tuple(type, args...);
    5558        for (Type * obj = this; obj; obj = obj->mPredecessor) {
     
    6366    }
    6467
    65     inline PabloAST * find(const PabloAST::ClassTypeId type, Args... args) const {
     68    inline PabloAST * find(const PabloAST::ClassTypeId type, Args... args) const noexcept {
    6669        return find(std::make_tuple(type, args...));
    6770    }
     
    9396};
    9497
    95 
    96 struct VarArgMap {
    97 
    98     friend struct ExpressionTable;
    99 
    100     using Allocator = SlabAllocator<const PabloAST *>;
    101 
    102     struct Key {
    103 
    104         inline Key(PabloAST::ClassTypeId type, const PabloAST * arg1, const std::vector<PabloAST *> & args, Allocator & allocator)
    105         : mType(type)
    106         , mArgs(1 + args.size())
    107         , mArg(allocator.allocate(mArgs)) {
    108             unsigned i = 1;
    109             mArg[0] = arg1;
    110             for (PabloAST * arg : args) {
    111                 mArg[i++] = arg;
    112             }
    113         }
    114 
    115         inline Key(PabloAST::ClassTypeId type, const Variadic * stmt, Allocator & allocator)
    116         : mType(type)
    117         , mArgs(stmt->getNumOperands())
    118         , mArg(allocator.allocate(mArgs)) {
    119             unsigned i = 0;
    120             for (PabloAST * arg : *stmt) {
    121                 mArg[i++] = arg;
    122             }
    123         }
    124 
    125         inline Key(const Key & key) = default;
    126 
    127         inline Key(Key && key) = default;
    128 
    129         inline bool operator < (const Key & other) const {
    130             if (mType != other.mType) {
    131                 return mType < other.mType;
    132             } else if (mArgs != other.mArgs) {
    133                 return mArgs < other.mArgs;
    134             }
    135             for (unsigned i = 0; i != mArgs; ++i) {
    136                 if (mArg[i] != other.mArg[i]) {
    137                     return mArg[i] < other.mArg[i];
    138                 }
    139             }
    140             return false;
    141         }
    142 
    143         const PabloAST::ClassTypeId   mType;
    144         const unsigned                mArgs;
    145         const PabloAST **             mArg;
    146     };
    147 
    148     using Map = std::map<Key, PabloAST *>;
    149 
    150     explicit VarArgMap(VarArgMap * predecessor = nullptr)
    151     : mPredecessor(predecessor) {
    152 
    153     }
    154 
    155     explicit VarArgMap(VarArgMap && other) noexcept
    156     : mPredecessor(other.mPredecessor)
    157     , mMap(std::move(other.mMap)) {
    158 
    159     }
    160 
    161     VarArgMap & operator=(VarArgMap && other) {
    162         mPredecessor = other.mPredecessor;
    163         mMap = std::move(other.mMap);
    164         return *this;
    165     }
    166 
    167     template <class Functor, typename... Params>
    168     PabloAST * findOrCall(Functor && functor, const PabloAST::ClassTypeId type, const PabloAST * arg1, const std::vector<PabloAST *> & args, Params... params) {
    169         Key key(type, arg1, args, mAllocator);
    170         PabloAST * const f = find(key);
    171         if (f) {
    172             mAllocator.deallocate(key.mArg);
    173             return f;
    174         }
    175         PabloAST * const object = functor(args, std::forward<Params>(params)...);
    176         mMap.insert(std::make_pair(std::move(key), object));
    177         return object;
    178     }
    179 
    180     std::pair<PabloAST *, bool> findOrAdd(Variadic * object, const PabloAST::ClassTypeId type) {
    181         Key key(type, object, mAllocator);
    182         PabloAST * const entry = find(key);
    183         if (entry) {
    184             mAllocator.deallocate(key.mArg);
    185             return std::make_pair(entry, false);
    186         }
    187         mMap.insert(std::make_pair(std::move(key), object));
    188         return std::make_pair(object, true);
    189     }
    190 
    191 private:
    192 
    193     PabloAST * find(const Key & key) const {
    194         // check this map to see if we have it
    195         auto itr = mMap.find(key);
    196         if (itr != mMap.end()) {
    197             return itr->second;
    198         } else { // check any previous maps to see if it exists
    199             auto * pred = mPredecessor;
    200             while (pred) {
    201                 itr = pred->mMap.find(key);
    202                 if (itr == pred->mMap.end()) {
    203                     pred = pred->mPredecessor;
    204                     continue;
    205                 }
    206                 return itr->second;
    207             }
    208         }
    209         return nullptr;
    210     }
    211 
    212 private:
    213     VarArgMap *     mPredecessor;
    214     Map             mMap;
    215     Allocator       mAllocator;
    216 };
    217 
    21898struct ExpressionTable {
    21999
     
    223103            mBinary.mPredecessor = &(predecessor->mBinary);
    224104            mTernary.mPredecessor = &(predecessor->mTernary);
    225             mVariadic.mPredecessor = &(predecessor->mVariadic);
    226105        }
    227106    }
     
    232111    : mUnary(std::move(other.mUnary))
    233112    , mBinary(std::move(other.mBinary))
    234     , mTernary(std::move(other.mTernary))
    235     , mVariadic(std::move(other.mVariadic)) {
     113    , mTernary(std::move(other.mTernary)) {
    236114
    237115    }
    238116
    239     ExpressionTable & operator=(ExpressionTable && other) {
     117    ExpressionTable & operator=(ExpressionTable && other) noexcept {
    240118        mUnary = std::move(other.mUnary);
    241119        mBinary = std::move(other.mBinary);
    242120        mTernary = std::move(other.mTernary);
    243         mVariadic = std::move(other.mVariadic);
    244121        return *this;
    245122    }
    246123
    247124    template <class Functor, typename... Params>
    248     inline PabloAST * findUnaryOrCall(Functor && functor, const PabloAST::ClassTypeId type, PabloAST * expr, Params... params) {
    249         return mUnary.findOrCall(std::move(functor), type,  expr , std::forward<Params>(params)...);
     125    inline PabloAST * findUnaryOrCall(Functor && functor, const PabloAST::ClassTypeId typeId, void * expr, Params... params) noexcept {
     126        return mUnary.findOrCall(std::move(functor), typeId, expr, std::forward<Params>(params)...);
    250127    }
    251128
    252129    template <class Functor, typename... Params>
    253     inline PabloAST * findBinaryOrCall(Functor && functor, const PabloAST::ClassTypeId type, PabloAST * expr1, PabloAST * expr2, Params... params) {
    254         return mBinary.findOrCall(std::move(functor), type, expr1, expr2, std::forward<Params>(params)...);
     130    inline PabloAST * findBinaryOrCall(Functor && functor, const PabloAST::ClassTypeId typeId, void * expr1, void * expr2, Params... params) noexcept {
     131        return mBinary.findOrCall(std::move(functor), typeId, expr1, expr2, std::forward<Params>(params)...);
    255132    }
    256133
    257134    template <class Functor, typename... Params>
    258     inline PabloAST * findTernaryOrCall(Functor && functor, const PabloAST::ClassTypeId type, PabloAST * expr1, PabloAST * expr2, PabloAST * expr3, Params... params) {
    259         return mTernary.findOrCall(std::move(functor), type, expr1, expr2, expr3, std::forward<Params>(params)...);
     135    inline PabloAST * findTernaryOrCall(Functor && functor, const PabloAST::ClassTypeId typeId, void * expr1, void * expr2, void * expr3, Params... params) noexcept {
     136        return mTernary.findOrCall(std::move(functor), typeId, expr1, expr2, expr3, std::forward<Params>(params)...);
    260137    }
    261138
    262     template <class Functor, typename... Params>
    263     inline PabloAST * findVariadicOrCall(Functor && functor, const PabloAST::ClassTypeId type, const PabloAST * arg1, const std::vector<PabloAST *> & args, Params... params) {
    264         return mVariadic.findOrCall(std::move(functor), type, arg1, args, std::forward<Params>(params)...);
    265     }
    266 
    267     std::pair<PabloAST *, bool> findOrAdd(Statement * stmt) {
     139    std::pair<PabloAST *, bool> findOrAdd(Statement * stmt) noexcept {
    268140        switch (stmt->getClassTypeId()) {                     
    269141            case PabloAST::ClassTypeId::Var:
    270142            case PabloAST::ClassTypeId::Not:
    271             case PabloAST::ClassTypeId::Count:
     143            case PabloAST::ClassTypeId::Count:           
    272144                return mUnary.findOrAdd(stmt, stmt->getClassTypeId(), stmt->getOperand(0));
    273145            case PabloAST::ClassTypeId::And:
    274146            case PabloAST::ClassTypeId::Or:
    275147            case PabloAST::ClassTypeId::Xor:
    276                 return mVariadic.findOrAdd(llvm::cast<Variadic>(stmt), stmt->getClassTypeId());
    277148            case PabloAST::ClassTypeId::Advance:
    278149            case PabloAST::ClassTypeId::ScanThru:
     
    280151            case PabloAST::ClassTypeId::Assign:
    281152            case PabloAST::ClassTypeId::Extract:
    282                 return mBinary.findOrAdd(stmt, stmt->getClassTypeId(), stmt->getOperand(0), stmt->getOperand(1));
     153            return mBinary.findOrAdd(stmt, stmt->getClassTypeId(), stmt->getOperand(0), stmt->getOperand(1));
     154            case PabloAST::ClassTypeId::Fill:
     155                return mBinary.findOrAdd(stmt, stmt->getClassTypeId(), stmt->getOperand(0), stmt->getType());
    283156            case PabloAST::ClassTypeId::Sel:
    284157            case PabloAST::ClassTypeId::IndexedAdvance:
     
    289162    }
    290163
    291 
    292164private:
    293     FixedArgMap<PabloAST *>                             mUnary;
    294     FixedArgMap<PabloAST *, PabloAST *>                 mBinary;
    295     FixedArgMap<PabloAST *, PabloAST *, PabloAST *>     mTernary;
    296     VarArgMap                                           mVariadic;
     165    FixedArgMap<void *>                   mUnary;
     166    FixedArgMap<void *, void *>           mBinary;
     167    FixedArgMap<void *, void *, void *>   mTernary;
    297168};
    298169
  • icGREP/icgrep-devel/icgrep/pablo/pabloAST.cpp

    r5706 r5828  
    9191 * @brief replaceAllUsesWith
    9292 ** ------------------------------------------------------------------------------------------------------------- */
    93 void PabloAST::replaceAllUsesWith(PabloAST * const expr) {
     93void PabloAST::replaceAllUsesWith(PabloAST * const expr) noexcept {
    9494    assert (expr);
    9595    if (LLVM_UNLIKELY(this == expr)) {
     
    115115 * @brief addUser
    116116 ** ------------------------------------------------------------------------------------------------------------- */
    117 bool PabloAST::addUser(PabloAST * const user) { assert (user);
     117bool PabloAST::addUser(PabloAST * const user) noexcept {
     118    assert (user);
    118119    const auto p = std::lower_bound(mUsers.begin(), mUsers.end(), user);
    119120    const bool unique = p == mUsers.end() || *p != user;
     
    125126 * @brief removeUser
    126127 ** ------------------------------------------------------------------------------------------------------------- */
    127 bool PabloAST::removeUser(PabloAST * const user) { assert (user);
     128bool PabloAST::removeUser(PabloAST * const user) noexcept {
     129    assert (user);
    128130    const auto p = std::lower_bound(mUsers.begin(), mUsers.end(), user);
    129131    assert (p != mUsers.end() && *p == user);
     
    230232 * @brief removeFromParent
    231233 ** ------------------------------------------------------------------------------------------------------------- */
    232 Statement * Statement::removeFromParent() {
     234Statement * Statement::removeFromParent() noexcept {
    233235    Statement * next = mNext;
    234236    if (LLVM_LIKELY(mParent != nullptr)) {
    235 
    236 
    237 
    238237        if (LLVM_UNLIKELY(mParent->mFirst == this)) {
    239238            mParent->mFirst = mNext;
     
    261260 * @brief eraseFromParent
    262261 ** ------------------------------------------------------------------------------------------------------------- */
    263 Statement * Statement::eraseFromParent(const bool recursively) {
     262Statement * Statement::eraseFromParent(const bool recursively) noexcept {
    264263
    265264    if (LLVM_UNLIKELY(getParent() == nullptr)) {
     
    274273
    275274    Statement * const next = removeFromParent();
    276 
    277275    for (unsigned i = 0; i != mOperands; ++i) {
    278276        PabloAST * const op = mOperand[i]; assert (op);
     
    292290 * @brief replaceWith
    293291 ** ------------------------------------------------------------------------------------------------------------- */
    294 Statement * Statement::replaceWith(PabloAST * const expr, const bool rename, const bool recursively) {
     292Statement * Statement::replaceWith(PabloAST * const expr, const bool rename, const bool recursively) noexcept {
    295293    assert (expr);
    296294    if (LLVM_UNLIKELY(expr == this)) {
     
    319317 * @brief addOperand
    320318 ** ------------------------------------------------------------------------------------------------------------- */
    321 void Variadic::addOperand(PabloAST * const expr) {
     319void Variadic::addOperand(PabloAST * const expr) noexcept {
    322320    if (LLVM_UNLIKELY(mOperands == mCapacity)) {
    323321        mCapacity = std::max<unsigned>(mCapacity * 2, 2);
     
    336334 * @brief removeOperand
    337335 ** ------------------------------------------------------------------------------------------------------------- */
    338 PabloAST * Variadic::removeOperand(const unsigned index) {
     336PabloAST * Variadic::removeOperand(const unsigned index) noexcept {
    339337    assert (index < mOperands);
    340338    PabloAST * const expr = mOperand[index];
  • icGREP/icgrep-devel/icgrep/pablo/pabloAST.h

    r5705 r5828  
    5353        , Add
    5454        , Subtract
    55         // Relational expressions
     55        // Relational operators
    5656        , LessThan
    5757        , LessThanEquals
     
    6666        , Block
    6767        , Kernel
    68         , Phi
     68        , Extract
    6969        /** Statements **/
    7070        // Boolean operations
     
    8989        // Variable assignments
    9090        , Assign
    91         , Extract     
    92         // Scope blocks
     91        // Scope branch statements
    9392        , If
    9493        , While
     94        // Misc. operations
     95        , Fill
     96        , PackH
     97        , PackL
    9598    };
    9699
     
    107110    }
    108111
    109     inline user_iterator user_begin() {
     112    inline user_iterator user_begin() noexcept {
    110113        return mUsers.begin();
    111114    }
    112115
    113     inline user_iterator user_end() {
     116    inline user_iterator user_end() noexcept {
    114117        return mUsers.end();
    115118    }
    116119
    117     inline const_user_iterator user_begin() const {
     120    inline const_user_iterator user_begin() const noexcept {
    118121        return mUsers.cbegin();
    119122    }
    120123
    121     inline const_user_iterator user_end() const {
     124    inline const_user_iterator user_end() const noexcept {
    122125        return mUsers.cend();
    123126    }
    124127
    125     inline Users & users() {
     128    inline Users & users() noexcept {
    126129        return mUsers;
    127130    }
    128131
    129     inline const Users & users() const {
     132    inline const Users & users() const noexcept {
    130133        return mUsers;
    131134    }
    132135
    133     void replaceAllUsesWith(PabloAST * const expr);
    134 
    135     inline Users::size_type getNumUses() const {
     136    void replaceAllUsesWith(PabloAST * const expr) noexcept;
     137
     138    inline Users::size_type getNumUses() const noexcept {
    136139        return mUsers.size();
    137140    }
     
    154157
    155158    }
    156     bool addUser(PabloAST * const user);
    157 
    158     bool removeUser(PabloAST * const user);
     159    bool addUser(PabloAST * const user) noexcept;
     160
     161    bool removeUser(PabloAST * const user) noexcept;
    159162
    160163    virtual ~PabloAST() = default;
     
    209212    void setName(const String * const name) noexcept;
    210213
    211     inline PabloAST * getOperand(const unsigned index) const {
     214    inline PabloAST * getOperand(const unsigned index) const noexcept {
    212215        assert (index < getNumOperands());
    213216        return mOperand[index];
     
    222225    void insertBefore(Statement * const statement);
    223226    void insertAfter(Statement * const statement);
    224     Statement * removeFromParent();
    225     Statement * eraseFromParent(const bool recursively = false);
    226     Statement * replaceWith(PabloAST * const expr, const bool rename = true, const bool recursively = false);
     227    Statement * removeFromParent() noexcept;
     228    Statement * eraseFromParent(const bool recursively = false) noexcept;
     229    Statement * replaceWith(PabloAST * const expr, const bool rename = true, const bool recursively = false) noexcept;
    227230
    228231    inline Statement * getNextNode() const {
     
    404407    using const_iterator = iterator;
    405408
    406     void addOperand(PabloAST * const expr);
    407 
    408     PabloAST * removeOperand(const unsigned index);
    409 
    410     bool deleteOperand(const PabloAST * const expr);
     409    void addOperand(PabloAST * const expr) noexcept;
     410
     411    PabloAST * removeOperand(const unsigned index) noexcept;
     412
     413    bool deleteOperand(const PabloAST * const expr) noexcept;
    411414
    412415    iterator begin() {
     
    713716 * @brief deleteOperand
    714717 ** ------------------------------------------------------------------------------------------------------------- */
    715 inline bool Variadic::deleteOperand(const PabloAST * const expr) {
     718inline bool Variadic::deleteOperand(const PabloAST * const expr) noexcept {
    716719    for (unsigned i = 0; i != getNumOperands(); ++i) {
    717720        if (LLVM_UNLIKELY(getOperand(i) == expr)) {
  • 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
  • icGREP/icgrep-devel/icgrep/pablo/pablo_compiler.h

    r5620 r5828  
    2121namespace pablo { class PabloKernel; }
    2222namespace pablo { class Statement; }
     23namespace pablo { class Var; }
    2324namespace pablo { class While; }
    2425namespace kernel { class KernelBuilder; }
     
    4041protected:
    4142
    42     void initializeKernelData(const std::unique_ptr<kernel::KernelBuilder> & iBuilder);
     43    void initializeKernelData(const std::unique_ptr<kernel::KernelBuilder> & b);
    4344
    44     void compile(const std::unique_ptr<kernel::KernelBuilder> & iBuilder);
     45    void compile(const std::unique_ptr<kernel::KernelBuilder> & b);
    4546
    46     void releaseKernelData(const std::unique_ptr<kernel::KernelBuilder> & iBuilder);
     47    void releaseKernelData(const std::unique_ptr<kernel::KernelBuilder> & b);
     48
     49    void clearCarryData(const std::unique_ptr<kernel::KernelBuilder> & b);
    4750
    4851private:
    4952
    50     void examineBlock(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, const PabloBlock * const block);
     53    void examineBlock(const std::unique_ptr<kernel::KernelBuilder> & b, const PabloBlock * const block);
    5154
    52     void compileBlock(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, const PabloBlock * const block);
     55    void compileBlock(const std::unique_ptr<kernel::KernelBuilder> & b, const PabloBlock * const block);
    5356
    54     void compileStatement(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, const Statement * stmt);
     57    void compileStatement(const std::unique_ptr<kernel::KernelBuilder> & b, const Statement * stmt);
    5558
    56     void compileIf(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, const If * ifStmt);
     59    void compileIf(const std::unique_ptr<kernel::KernelBuilder> & b, const If * ifStmt);
    5760
    58     void compileWhile(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, const While * whileStmt);
     61    void compileWhile(const std::unique_ptr<kernel::KernelBuilder> & b, const While * whileStmt);
    5962
    60     void addBranchCounter(const std::unique_ptr<kernel::KernelBuilder> & iBuilder);
     63    void addBranchCounter(const std::unique_ptr<kernel::KernelBuilder> & b);
    6164
    62     llvm::Value * compileExpression(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, const PabloAST * expr, const bool ensureLoaded = true) const;
     65    llvm::Value * getPointerToVar(const std::unique_ptr<kernel::KernelBuilder> & b, const Var * var, llvm::Value * index1, llvm::Value * index2 = nullptr);
     66
     67    llvm::Value * compileExpression(const std::unique_ptr<kernel::KernelBuilder> & b, const PabloAST * expr, const bool ensureLoaded = true);
    6368
    6469private:
  • icGREP/icgrep-devel/icgrep/pablo/pablo_kernel.cpp

    r5782 r5828  
    2424using namespace llvm;
    2525
    26 inline bool isStreamType(const Type * ty) {
    27     if (ty->isArrayTy()) {
    28         ty = ty->getArrayElementType();
    29     }
    30     if (ty->isVectorTy()) {
    31         return (ty->getVectorNumElements() == 0);
    32     }
    33     return false;
    34 }
    35 
    3626namespace pablo {
    3727
     
    5141
    5242Var * PabloKernel::getOutputScalarVar(const std::string & name) {
    53     const auto f = mScalarOutputNameMap.find(name);
    54     if (LLVM_UNLIKELY(f == mScalarOutputNameMap.end())) {
    55         report_fatal_error("Kernel does not contain scalar: " + name);
    56     }
    57     return f->second;
    58 }
    59 
    60 Var * PabloKernel::addInput(const std::string & name, Type * const type) {
    61     Var * param = new (mAllocator) Var(makeName(name), type, mAllocator, Var::KernelInputParameter);
    62     param->addUser(this);
    63     mInputs.push_back(param);
    64     mVariables.push_back(param);
    65     if (isStreamType(type)) {
    66         mStreamMap.emplace(name, std::make_pair(Port::Input, mStreamSetInputs.size()));
    67         mStreamSetInputs.emplace_back(type, name);       
    68     } else {
    69         mScalarInputs.emplace_back(type, name);
    70         param->setScalar();
    71     }
    72     assert (mStreamSetInputs.size() + mScalarInputs.size() == mInputs.size());
    73     return param;
    74 }
    75 
    76 Var * PabloKernel::addOutput(const std::string & name, Type * const type) {
    77     Var * result = new (mAllocator) Var(makeName(name), type, mAllocator, Var::KernelOutputParameter);
    78     result->addUser(this);
    79     mOutputs.push_back(result);
    80     mVariables.push_back(result);
    81     if (isStreamType(type)) {
    82         mStreamMap.emplace(name, std::make_pair(Port::Output, mStreamSetOutputs.size()));
    83         mStreamSetOutputs.emplace_back(type, name);
    84     } else {
    85         mScalarOutputs.emplace_back(type, name);
    86         mScalarOutputNameMap.emplace(name, result);
    87         result->setScalar();
    88     }
    89     assert (mStreamSetOutputs.size() + mScalarOutputs.size() == mOutputs.size());
    90     return result;
     43    for (Var * out : mScalarOutputVars) {
     44        if (out->getName().equals(name)) {
     45            return out;
     46        }
     47    }
     48    report_fatal_error("Kernel does not contain scalar " + name);
    9149}
    9250
     
    12583}
    12684
    127 void PabloKernel::addInternalKernelProperties(const std::unique_ptr<kernel::KernelBuilder> & iBuilder) {
    128     mSizeTy = iBuilder->getSizeTy();
    129     mStreamTy = iBuilder->getStreamTy();
     85void PabloKernel::addInternalKernelProperties(const std::unique_ptr<kernel::KernelBuilder> & b) {
     86    mSizeTy = b->getSizeTy();
     87    mStreamTy = b->getStreamTy();
     88    mSymbolTable = new SymbolGenerator(b->getContext(), mAllocator);
     89    mEntryBlock = PabloBlock::Create(this);
     90    mContext = &b->getContext();
     91    for (const Binding & ss : mStreamSetInputs) {
     92        Var * param = new (mAllocator) Var(makeName(ss.getName()), ss.getType(), mAllocator, Var::KernelInputParameter);
     93        param->addUser(this);
     94        mInputs.push_back(param);
     95        mVariables.push_back(param);
     96    }
     97    for (const Binding & ss : mStreamSetOutputs) {
     98        Var * result = new (mAllocator) Var(makeName(ss.getName()), ss.getType(), mAllocator, Var::KernelOutputParameter);
     99        result->addUser(this);
     100        mOutputs.push_back(result);
     101        mVariables.push_back(result);
     102    }
     103    for (const Binding & ss : mScalarOutputs) {
     104        Var * result = new (mAllocator) Var(makeName(ss.getName()), ss.getType(), mAllocator, Var::KernelOutputParameter);
     105        result->addUser(this);
     106        mOutputs.push_back(result);
     107        mVariables.push_back(result);
     108        mScalarOutputVars.push_back(result);
     109        result->setScalar();
     110    }
    130111    generatePabloMethod();   
    131112    pablo_function_passes(this);
    132     mPabloCompiler->initializeKernelData(iBuilder);
     113    mPabloCompiler = new PabloCompiler(this);
     114    mPabloCompiler->initializeKernelData(b);
    133115    mSizeTy = nullptr;
    134116    mStreamTy = nullptr;   
     
    142124    mStreamTy = nullptr;
    143125}
     126
     127#if 0
     128void PabloKernel::beginConditionalRegion(const std::unique_ptr<KernelBuilder> & b) {
     129    mPabloCompiler->clearCarryData(b);
     130}
     131#endif
    144132
    145133void PabloKernel::generateFinalBlockMethod(const std::unique_ptr<KernelBuilder> & iBuilder, Value * const remainingBytes) {
     
    221209                      {Binding{b->getBitBlockType(), "EOFbit"}, Binding{b->getBitBlockType(), "EOFmask"}})
    222210, PabloAST(PabloAST::ClassTypeId::Kernel, nullptr, mAllocator)
    223 , mPabloCompiler(new PabloCompiler(this))
    224 , mSymbolTable(new SymbolGenerator(b->getContext(), mAllocator))
    225 , mEntryBlock(PabloBlock::Create(this))
     211, mPabloCompiler(nullptr)
     212, mSymbolTable(nullptr)
     213, mEntryBlock(nullptr)
    226214, mSizeTy(nullptr)
    227 , mStreamTy(nullptr) {
    228     prepareStreamSetNameMap();
    229     for (const Binding & ss : mStreamSetInputs) {
    230         Var * param = new (mAllocator) Var(makeName(ss.getName()), ss.getType(), mAllocator, Var::KernelInputParameter);
    231         param->addUser(this);
    232         mInputs.push_back(param);
    233         mVariables.push_back(param);
    234     }
    235     for (const Binding & ss : mStreamSetOutputs) {
    236         Var * result = new (mAllocator) Var(makeName(ss.getName()), ss.getType(), mAllocator, Var::KernelOutputParameter);
    237         result->addUser(this);
    238         mOutputs.push_back(result);
    239         mVariables.push_back(result);
    240     }
    241     for (const Binding & ss : mScalarOutputs) {
    242         Var * result = new (mAllocator) Var(makeName(ss.getName()), ss.getType(), mAllocator, Var::KernelOutputParameter);
    243         result->addUser(this);
    244         mOutputs.push_back(result);
    245         mVariables.push_back(result);
    246         mScalarOutputNameMap.emplace(ss.getName(), result);
    247         result->setScalar();
    248     }
     215, mStreamTy(nullptr)
     216, mContext(nullptr) {
     217
    249218}
    250219
  • icGREP/icgrep-devel/icgrep/pablo/pablo_kernel.h

    r5706 r5828  
    1212#include <util/slab_allocator.h>
    1313#include <llvm/ADT/StringRef.h>
    14 #include <boost/container/flat_map.hpp>
    1514
    1615namespace llvm { class Type; }
     
    6665
    6766    Var * getInput(const unsigned index) {
     67        assert (index < mInputs.size() && mInputs[index]);
    6868        return mInputs[index];
    6969    }
    7070
    7171    const Var * getInput(const unsigned index) const {
     72        assert (index < mInputs.size() && mInputs[index]);
    7273        return mInputs[index];
    7374    }
    74 
    75     Var * addInput(const std::string & name, llvm::Type * const type);
    7675
    7776    unsigned getNumOfInputs() const {
     
    8483
    8584    Var * getOutput(const unsigned index) {
     85        assert (index < mOutputs.size() && mOutputs[index]);
    8686        return mOutputs[index];
    8787    }
    8888
    8989    const Var * getOutput(const unsigned index) const {
     90        assert (index < mOutputs.size() && mOutputs[index]);
    9091        return mOutputs[index];
    9192    }
    92 
    93     Var * addOutput(const std::string & name, llvm::Type * const type);
    9493
    9594    unsigned getNumOfOutputs() const {
     
    9796    }
    9897
    99     Var * makeVariable(String * name, llvm::Type * const type);
    100 
    10198    Var * getVariable(const unsigned index) {
     99        assert (index < mVariables.size() && mVariables[index]);
    102100        return mVariables[index];
    103101    }
     
    129127    llvm::StructType * getCarryDataTy() const {
    130128        return mCarryDataTy;
     129    }
     130
     131    llvm::LLVMContext & getContext() const {
     132        assert (mContext);
     133        return *mContext;
    131134    }
    132135
     
    156159    }
    157160
     161    Var * makeVariable(String * name, llvm::Type * const type);
     162
    158163    // A custom method for preparing kernel declarations is needed,
    159164    // so that the carry data requirements may be accommodated before
     
    172177    void generateFinalizeMethod(const std::unique_ptr<kernel::KernelBuilder> & iBuilder) final;
    173178
     179    #if 0
     180    void beginConditionalRegion(const std::unique_ptr<KernelBuilder> & b) final;
     181    #endif
     182
    174183private:
    175184
    176185    Allocator                       mAllocator;
    177     PabloCompiler * const           mPabloCompiler;
     186    PabloCompiler *                 mPabloCompiler;
    178187    SymbolGenerator *               mSymbolTable;
    179188    PabloBlock *                    mEntryBlock;
     
    181190    llvm::VectorType *              mStreamTy;
    182191    llvm::StructType *              mCarryDataTy;
     192    llvm::LLVMContext *             mContext;
     193
    183194    std::vector<Var *>              mInputs;
    184195    std::vector<Var *>              mOutputs;
    185196    std::vector<PabloAST *>         mConstants;
    186197    std::vector<Var *>              mVariables;
    187     boost::container::flat_map<std::string, Var *> mScalarOutputNameMap;
     198    std::vector<Var *>              mScalarOutputVars;
    188199};
    189200
  • icGREP/icgrep-devel/icgrep/pablo/pe_var.h

    r5310 r5828  
    9393};
    9494
    95 class Extract : public Statement {
     95class Extract : public PabloAST {
    9696    friend class PabloBlock;
    9797public:
     
    104104    virtual ~Extract(){
    105105    }
    106     inline PabloAST * getArray() const {
    107         return getOperand(0);
     106    inline Var * getArray() const {
     107        return mArray;
    108108    }
    109109    inline PabloAST * getIndex() const {
    110         return getOperand(1);
     110        return mIndex;
    111111    }
    112112protected:
    113     Extract(PabloAST * array, PabloAST * const index, const String * const name, llvm::Type * type, Allocator & allocator)
    114     : Statement(ClassTypeId::Extract, type, {array, index}, name, allocator) {
     113    Extract(Var * array, PabloAST * const index, llvm::Type * type, Allocator & allocator)
     114    : PabloAST(ClassTypeId::Extract, type, allocator)
     115    , mArray(array)
     116    , mIndex(index) {
    115117
    116118    }
     119private:
     120    Var * const mArray;
     121    PabloAST * const mIndex;
    117122};
    118123
  • icGREP/icgrep-devel/icgrep/pablo/printer_pablos.cpp

    r5705 r5828  
    1818#include <pablo/pe_matchstar.h>
    1919#include <pablo/pe_ones.h>
    20 #include <pablo/pe_phi.h>
     20#include <pablo/pe_repeat.h>
    2121#include <pablo/pe_scanthru.h>
    2222#include <pablo/pe_string.h>
     
    2424#include <pablo/pe_zeroes.h>
    2525#include <pablo/ps_assign.h>
     26#include <llvm/IR/Type.h>
    2627#include <llvm/Support/raw_os_ostream.h>
    2728
     
    5859        print(cast<PabloAST>(stmt), out);
    5960
    60         if (const Extract * extract = dyn_cast<Extract>(stmt)) {
    61             out << " = Extract ";
    62             print(extract->getArray(), out);
    63             out << ", ";
    64             print(extract->getIndex(), out);
    65         } else if (const And * andNode = dyn_cast<And>(stmt)) {
     61        if (const And * andNode = dyn_cast<And>(stmt)) {
    6662            out << " = (";
    6763            for (unsigned i = 0; i != andNode->getNumOperands(); ++i) {
     
    144140            print(count->getExpr(), out);
    145141            out << ")";
     142        } else if (const Repeat * splat = dyn_cast<Repeat>(stmt)) {
     143            out << " = pablo.Repeat(";
     144            print(splat->getFieldWidth(), out);
     145            out << ", ";
     146            print(splat->getValue(), out);
     147            out << ")";
    146148        } else if (const InFile * e = dyn_cast<InFile>(stmt)) {
    147149            out << " = pablo.InFile(";
     
    165167    } else if (isa<Ones>(expr)) {
    166168        out << "1";
     169    } else if (const Extract * extract = dyn_cast<Extract>(expr)) {
     170        print(extract->getArray(), out);
     171        out << "[";
     172        print(extract->getIndex(), out);
     173        out << "]";
    167174    } else if (const Var * var = dyn_cast<Var>(expr)) {
    168175        out << var->getName();
    169     } else if (const Phi * const phi = dyn_cast<Phi>(expr)) {
    170         out << "phi(";
    171         for (unsigned i = 0; i != phi->getNumIncomingValues(); ++i) {
    172             if (i) out << ", ";
    173             print(phi->getIncomingValue(i), out);
    174         }
    175         out << ")";
    176176    } else if (const If * ifstmt = dyn_cast<If>(expr)) {
    177177        out << "If ";
Note: See TracChangeset for help on using the changeset viewer.