Changeset 5391 for icGREP/icgrep-devel


Ignore:
Timestamp:
Apr 4, 2017, 12:09:16 PM (2 years ago)
Author:
cameron
Message:

ParabixDriver/ObjectCache? separate compilation and linking: initial check-in with wc

Location:
icGREP/icgrep-devel/icgrep
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/kernels/interface.h

    r5390 r5391  
    145145
    146146    KernelInterface(IDISA::IDISA_Builder * builder,
    147                     std::string && kernelName,
     147                    std::string kernelName,
    148148                    std::vector<Binding> && stream_inputs,
    149149                    std::vector<Binding> && stream_outputs,
  • icGREP/icgrep-devel/icgrep/kernels/kernel.cpp

    r5390 r5391  
    120120}
    121121
     122std::unique_ptr<Module> KernelBuilder::createKernelStub() {
     123    return make_unique<Module>(getName() + "_" + iBuilder->getBuilderUniqueName(), iBuilder->getContext());
     124}
     125
     126void KernelBuilder::setCallParameters(const std::vector<StreamSetBuffer *> & inputs, const std::vector<StreamSetBuffer *> & outputs) {
     127    mStreamSetInputBuffers.assign(inputs.begin(), inputs.end());
     128    for (unsigned i = 0; i < mStreamSetInputBuffers.size(); ++i) {
     129        if (LLVM_UNLIKELY(mStreamSetInputBuffers[i] == nullptr)) {
     130            report_fatal_error(getName() + ": input stream set " + std::to_string(i)
     131                               + " cannot be null when calling generateKernel()");
     132        }
     133    }
     134    if (LLVM_UNLIKELY(mStreamSetInputs.size() != mStreamSetInputBuffers.size())) {
     135        report_fatal_error(getName() + ": expected " + std::to_string(mStreamSetInputs.size()) +
     136                           " input stream sets but generateKernel() was given "
     137                           + std::to_string(mStreamSetInputBuffers.size()));
     138    }
     139   
     140    mStreamSetOutputBuffers.assign(outputs.begin(), outputs.end());
     141    for (unsigned i = 0; i < mStreamSetOutputBuffers.size(); ++i) {
     142        if (LLVM_UNLIKELY(mStreamSetOutputBuffers[i] == nullptr)) {
     143            report_fatal_error(getName() + ": output stream set " + std::to_string(i)
     144                               + " cannot be null when calling generateKernel()");
     145        }
     146    }
     147    if (LLVM_UNLIKELY(mStreamSetOutputs.size() != mStreamSetOutputBuffers.size())) {
     148        report_fatal_error(getName() + ": expected " + std::to_string(mStreamSetOutputs.size())
     149                           + " output stream sets but generateKernel() was given "
     150                           + std::to_string(mStreamSetOutputBuffers.size()));
     151    }
     152    prepareKernel(); // possibly overridden by the KernelBuilder subtype
     153   
     154}   
     155
    122156std::unique_ptr<Module> KernelBuilder::createKernelModule(const std::vector<StreamSetBuffer *> & inputs, const std::vector<StreamSetBuffer *> & outputs) {
    123157    auto saveModule = iBuilder->getModule();
    124158    auto savePoint = iBuilder->saveIP();
    125     auto module = make_unique<Module>(getName() + "_" + iBuilder->getBitBlockTypeName(), iBuilder->getContext());
     159    auto module = createKernelStub();
    126160    iBuilder->setModule(module.get());
    127161    generateKernel(inputs, outputs);
     
    132166
    133167void KernelBuilder::generateKernel(const std::vector<StreamSetBuffer *> & inputs, const std::vector<StreamSetBuffer *> & outputs) {
    134 
    135     mStreamSetInputBuffers.assign(inputs.begin(), inputs.end());
    136     for (unsigned i = 0; i < mStreamSetInputBuffers.size(); ++i) {
    137         if (LLVM_UNLIKELY(mStreamSetInputBuffers[i] == nullptr)) {
    138             report_fatal_error(getName() + ": input stream set " + std::to_string(i)
    139                                + " cannot be null when calling generateKernel()");
    140         }
    141     }
    142     if (LLVM_UNLIKELY(mStreamSetInputs.size() != mStreamSetInputBuffers.size())) {
    143         report_fatal_error(getName() + ": expected " + std::to_string(mStreamSetInputs.size()) +
    144                            " input stream sets but generateKernel() was given "
    145                            + std::to_string(mStreamSetInputBuffers.size()));
    146     }
    147 
    148     mStreamSetOutputBuffers.assign(outputs.begin(), outputs.end());
    149     for (unsigned i = 0; i < mStreamSetOutputBuffers.size(); ++i) {
    150         if (LLVM_UNLIKELY(mStreamSetOutputBuffers[i] == nullptr)) {
    151             report_fatal_error(getName() + ": output stream set " + std::to_string(i)
    152                                + " cannot be null when calling generateKernel()");
    153         }
    154     }
    155     if (LLVM_UNLIKELY(mStreamSetOutputs.size() != mStreamSetOutputBuffers.size())) {
    156         report_fatal_error(getName() + ": expected " + std::to_string(mStreamSetOutputs.size())
    157                            + " output stream sets but generateKernel() was given "
    158                            + std::to_string(mStreamSetOutputBuffers.size()));
    159     }
    160 
    161 
     168    setCallParameters(inputs, outputs);
     169    generateKernel();
     170}
     171
     172void KernelBuilder::generateKernel() {
    162173    auto savePoint = iBuilder->saveIP();
    163     prepareKernel(); // possibly overridden by the KernelBuilder subtype
    164174    addKernelDeclarations(iBuilder->getModule());
    165175    callGenerateInitMethod();
  • icGREP/icgrep-devel/icgrep/kernels/kernel.h

    r5390 r5391  
    2828public:
    2929   
     30    // Create a module stub for the kernel, populated only with its Module ID.     
     31    //
     32    std::unique_ptr<llvm::Module> createKernelStub();
     33   
    3034    // Create a module for the kernel, including the kernel state type declaration and
    3135    // the full implementation of all required methods.     
     
    3337    std::unique_ptr<llvm::Module> createKernelModule(const std::vector<parabix::StreamSetBuffer *> & inputs, const std::vector<parabix::StreamSetBuffer *> & outputs);
    3438   
     39    void setCallParameters(const std::vector<parabix::StreamSetBuffer *> & inputs, const std::vector<parabix::StreamSetBuffer *> & outputs);
     40
    3541    // Generate the Kernel to the current module (iBuilder->getModule()).
     42    void generateKernel();
    3643    void generateKernel(const std::vector<parabix::StreamSetBuffer *> & inputs, const std::vector<parabix::StreamSetBuffer *> & outputs);
    3744   
  • icGREP/icgrep-devel/icgrep/kernels/mmap_kernel.cpp

    r5377 r5391  
    5050
    5151MMapSourceKernel::MMapSourceKernel(IDISA::IDISA_Builder * iBuilder, unsigned blocksPerSegment, unsigned codeUnitWidth)
    52 : SegmentOrientedKernel(iBuilder, "mmap_source",
     52: SegmentOrientedKernel(iBuilder, "Parabix:mmap_source",
    5353    {},
    5454    {Binding{iBuilder->getStreamSetTy(1, codeUnitWidth), "sourceBuffer"}},
  • icGREP/icgrep-devel/icgrep/kernels/s2p_kernel.cpp

    r5377 r5391  
    162162
    163163S2PKernel::S2PKernel(IDISA::IDISA_Builder * builder)
    164 : BlockOrientedKernel(builder, "s2p", {Binding{builder->getStreamSetTy(1, 8), "byteStream"}}, {Binding{builder->getStreamSetTy(8, 1), "basisBits"}}, {}, {}, {}) {
     164: BlockOrientedKernel(builder, "Parabix:s2p",
     165    {Binding{builder->getStreamSetTy(1, 8), "byteStream"}}, {Binding{builder->getStreamSetTy(8, 1), "basisBits"}}, {}, {}, {}) {
    165166    setNoTerminateAttribute(true);
    166167}
  • icGREP/icgrep-devel/icgrep/kernels/scanmatchgen.cpp

    r5389 r5391  
    222222
    223223ScanMatchKernel::ScanMatchKernel(IDISA::IDISA_Builder * iBuilder, GrepType grepType, const unsigned codeUnitWidth)
    224 : BlockOrientedKernel(iBuilder, "scanMatch" + std::to_string(codeUnitWidth),
     224: BlockOrientedKernel(iBuilder, "Parabix:scanMatch" + std::to_string(codeUnitWidth),
    225225    {Binding{iBuilder->getStreamSetTy(1, 8), "InputStream"}, Binding{iBuilder->getStreamSetTy(1, 1), "matchResult"}, Binding{iBuilder->getStreamSetTy(1, 1), "lineBreak"}},
    226226    {},
  • icGREP/icgrep-devel/icgrep/object_cache.cpp

    r5267 r5391  
    66#include <llvm/Support/Path.h>
    77#include <llvm/IR/Module.h>
     8
     9
    810#ifdef OBJECT_CACHE_DEBUG
    911#include <iostream>
     
    2022// file exists.
    2123//
    22 ICGrepObjectCache::ICGrepObjectCache(const std::string &dir): CacheDir(dir) {}
     24ParabixObjectCache::ParabixObjectCache(const std::string &dir): CacheDir(dir) {}
    2325
    24 ICGrepObjectCache::ICGrepObjectCache() {
     26ParabixObjectCache::ParabixObjectCache() {
    2527    // $HOME/.cache/icgrep
    2628    // TODO use path::user_cache_directory once we have llvm >= 3.7.
    2729    sys::path::home_directory(CacheDir);
    28     sys::path::append(CacheDir, ".cache", "icgrep");
     30    std::string Version = PARABIX_VERSION;
     31    std::string Date = __DATE__;
     32    std::string Time = __TIME__;
     33    std::string DateStamp = Date.substr(7) + Date.substr(0,3) + (Date[4] == ' ' ? Date.substr(5,1) : Date.substr(4,2));
     34    std::string CacheSubDir = "Parabix" + Version + "_" + DateStamp + "@" + Time;
     35    sys::path::append(CacheDir, ".cache", CacheSubDir);
    2936}
    3037
    31 ICGrepObjectCache::~ICGrepObjectCache() {}
     38ParabixObjectCache::~ParabixObjectCache() {}
    3239
    33 void ICGrepObjectCache::notifyObjectCompiled(const Module *M, MemoryBufferRef Obj) {
     40void ParabixObjectCache::notifyObjectCompiled(const Module *M, MemoryBufferRef Obj) {
    3441    const std::string &ModuleID = M->getModuleIdentifier();
     42   
    3543    Path CacheName(CacheDir);
    36     if (!getCacheFilename(ModuleID, CacheName))
    37         return;
     44    if (!getCacheFilename(ModuleID, CacheName)) return;
    3845    if (!CacheDir.empty())      // Re-creating an existing directory is fine.
    3946        sys::fs::create_directories(Twine(CacheDir));
     
    4754}
    4855
    49 std::unique_ptr<MemoryBuffer> ICGrepObjectCache::getObject(const Module* M) {
     56
     57bool ParabixObjectCache::loadCachedObjectFile(const Module* M) {
     58    const std::string ModuleID = M->getModuleIdentifier();
     59    auto f = cachedObjectMap.find(ModuleID);
     60    if (f != cachedObjectMap.end()) {
     61        return true;
     62    }
     63    Path CachedObjectName(CacheDir);
     64    if (!getCacheFilename(ModuleID, CachedObjectName)) return false;
     65    ErrorOr<std::unique_ptr<MemoryBuffer>> KernelObjectBuffer = MemoryBuffer::getFile(CachedObjectName.c_str(), -1, false);
     66    if (!KernelObjectBuffer) return false;
     67    // Make a copy so that the JIT engine can freely modify it.
     68    cachedObjectMap.emplace(ModuleID, std::move(KernelObjectBuffer.get()));
     69    return true;
     70}
     71
     72
     73std::unique_ptr<MemoryBuffer> ParabixObjectCache::getObject(const Module* M) {
    5074    const std::string &ModuleID = M->getModuleIdentifier();
    51     Path CacheName(CacheDir);
    52     if (!getCacheFilename(ModuleID, CacheName))
     75    auto f = cachedObjectMap.find(ModuleID);
     76    if (f == cachedObjectMap.end()) {
    5377        return nullptr;
    54     // Load the object from the cache filename
    55     ErrorOr<std::unique_ptr<MemoryBuffer>> IRObjectBuffer =
    56         MemoryBuffer::getFile(CacheName.c_str(), -1, false);
    57     // If the file isn't there, that's OK.
    58     if (!IRObjectBuffer)
    59         return nullptr;
     78    }
    6079#ifdef OBJECT_CACHE_DEBUG
    6180    std::cerr << "Found cached object." << std::endl;
    6281#endif
    63     // MCJIT will want to write into this buffer, and we don't want that
    64     // because the file has probably just been mmapped.  Instead we make
    65     // a copy.  The filed-based buffer will be released when it goes
    66     // out of scope.
    67     return MemoryBuffer::getMemBufferCopy(IRObjectBuffer.get()->getBuffer());
     82    // Return a copy of the buffer, for MCJIT to modify, if necessary.
     83    return MemoryBuffer::getMemBufferCopy(f->second.get()->getBuffer());
    6884}
    6985
    70 bool ICGrepObjectCache::getCacheFilename(const std::string &ModID, Path &CacheName) {
     86bool ParabixObjectCache::getCacheFilename(const std::string &ModID, Path &CacheName) {
    7187#ifdef OBJECT_CACHE_DEBUG
    7288    std::cerr << "ModuleID: " << ModID << std::endl;
    7389#endif
    74     const std::string Prefix("grepcode:");
     90    const std::string Prefix("Parabix:");
    7591    size_t PrefixLength = Prefix.length();
    7692    if (ModID.substr(0, PrefixLength) != Prefix)
  • icGREP/icgrep-devel/icgrep/object_cache.h

    r5267 r5391  
     1/*
     2 *  Copyright (c) 2017 International Characters.
     3 *  This software is licensed to the public under the Open Software License 3.0.
     4 *  icgrep is a trademark of International Characters.
     5 */
     6
    17#ifndef OBJECT_CACHE_H
    28#define OBJECT_CACHE_H
     
    612#include <llvm/Support/MemoryBuffer.h>
    713#include <string>
     14#include <map>
     15
    816namespace llvm { class Module; }
    917
    10 class ICGrepObjectCache : public llvm::ObjectCache {
     18// The ParabixObjectCache is a two-level cache compatible with the requirements
     19// of the LLVM ExecutionEngine as well as the Parabix Kernel builder infrastructure.
     20//
     21// The ParabixObjectCache allows the ParabixDriver to look up cached modules based on a
     22// module stub that contains only the necessary Module ID and signature (loadCachedObjectFile).
     23// If found, the module object file is immediately loaded into the cachedObjectMap,
     24// and later made available to the ExecutionEngine as needed.  Otherwise, false is
     25// return to signal that a cached File is not found.  The ParabixDriver can then
     26// apply the necessary kernel builder to build the full module IR before passing
     27// it to the ExecutionEngine.
     28//
     29
     30class ParabixObjectCache : public llvm::ObjectCache {
    1131    public:
    12         ICGrepObjectCache(const std::string &dir);
    13         ICGrepObjectCache();
    14         virtual ~ICGrepObjectCache();
     32        ParabixObjectCache(const std::string &dir);
     33        ParabixObjectCache();
     34        virtual ~ParabixObjectCache();
    1535
    1636        void notifyObjectCompiled(const llvm::Module *M, llvm::MemoryBufferRef Obj) override;
     37        bool loadCachedObjectFile(const llvm::Module* M);
    1738        std::unique_ptr<llvm::MemoryBuffer> getObject(const llvm::Module* M) override;
    18 
     39   
    1940    private:
    20         using Path = llvm::SmallString<256>;
     41        std::map<std::string, std::unique_ptr<llvm::MemoryBuffer>> cachedObjectMap;
     42        using Path = llvm::SmallString<128>;
    2143        Path CacheDir;
    2244
  • icGREP/icgrep-devel/icgrep/toolchain.cpp

    r5377 r5391  
    2424#include <object_cache.h>
    2525#include <kernels/pipeline.h>
     26#include <kernels/interface.h>
     27#include <kernels/kernel.h>
    2628#ifdef CUDA_ENABLED
    2729#include <IR_Gen/llvm2ptx.h>
     
    249251
    250252void ApplyObjectCache(ExecutionEngine * e) {
    251     ICGrepObjectCache * cache = nullptr;
     253    ParabixObjectCache * cache = nullptr;
    252254    if (codegen::EnableObjectCache) {
    253255        if (codegen::ObjectCacheDir.empty())
    254256            // Default is $HOME/.cache/icgrep
    255             cache = new ICGrepObjectCache();
     257            cache = new ParabixObjectCache();
    256258        else
    257             cache = new ICGrepObjectCache(codegen::ObjectCacheDir);
     259            cache = new ParabixObjectCache(codegen::ObjectCacheDir);
    258260        e->setObjectCache(cache);
    259261    }
     
    272274
    273275
     276ParabixDriver::ParabixDriver(IDISA::IDISA_Builder * iBuilder) : iBuilder(iBuilder) {
     277    mMainModule = iBuilder->getModule();
     278    if (codegen::EnableObjectCache) {
     279        if (codegen::ObjectCacheDir.empty()) {
     280            mCache = llvm::make_unique<ParabixObjectCache>();
     281        }
     282        else {
     283            mCache = llvm::make_unique<ParabixObjectCache>(codegen::ObjectCacheDir);
     284        }
     285    }
     286}
     287
     288void ParabixDriver::JITcompileMain () {
     289
     290    // Use the pass manager to optimize the function.
     291    #ifndef NDEBUG
     292    try {
     293    #endif
     294    legacy::PassManager PM;
     295    #ifndef NDEBUG
     296    PM.add(createVerifierPass());
     297    #endif
     298    PM.add(createReassociatePass());             //Reassociate expressions.
     299    PM.add(createGVNPass());                     //Eliminate common subexpressions.
     300    PM.add(createInstructionCombiningPass());    //Simple peephole optimizations and bit-twiddling.
     301    PM.add(createCFGSimplificationPass());   
     302    PM.run(*mMainModule);
     303    #ifndef NDEBUG
     304    } catch (...) { mMainModule->dump(); throw; }
     305    #endif
     306    InitializeNativeTarget();
     307    InitializeNativeTargetAsmPrinter();
     308    InitializeNativeTargetAsmParser();
     309
     310    PassRegistry * Registry = PassRegistry::getPassRegistry();
     311    initializeCore(*Registry);
     312    initializeCodeGen(*Registry);
     313    initializeLowerIntrinsicsPass(*Registry);
     314
     315    std::string errMessage;
     316    EngineBuilder builder{std::unique_ptr<Module>(mMainModule)};
     317    builder.setErrorStr(&errMessage);
     318    TargetOptions opts = InitTargetOptionsFromCodeGenFlags();
     319    opts.MCOptions.AsmVerbose = codegen::AsmVerbose;
     320
     321    builder.setTargetOptions(opts);
     322    builder.setVerifyModules(true);
     323    CodeGenOpt::Level optLevel = CodeGenOpt::Level::None;
     324    switch (codegen::OptLevel) {
     325        case '0': optLevel = CodeGenOpt::None; break;
     326        case '1': optLevel = CodeGenOpt::Less; break;
     327        case '2': optLevel = CodeGenOpt::Default; break;
     328        case '3': optLevel = CodeGenOpt::Aggressive; break;
     329        default: errs() << codegen::OptLevel << " is an invalid optimization level.\n";
     330    }
     331    builder.setOptLevel(optLevel);
     332
     333    setAllFeatures(builder);
     334
     335    if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::ShowIR))) {
     336        if (codegen::IROutputFilename.empty()) {
     337            mMainModule->dump();
     338        } else {
     339            std::error_code error;
     340            raw_fd_ostream out(codegen::IROutputFilename, error, sys::fs::OpenFlags::F_None);
     341            mMainModule->print(out, nullptr);
     342        }
     343    }
     344#if LLVM_VERSION_MINOR > 6
     345    if (codegen::DebugOptionIsSet(codegen::ShowASM)) {
     346        WriteAssembly(builder.selectTarget(), mMainModule);
     347    }
     348#endif
     349    ExecutionEngine * engine = builder.create();
     350    if (engine == nullptr) {
     351        throw std::runtime_error("Could not create ExecutionEngine: " + errMessage);
     352    }
     353    if (mCache) {
     354        engine->setObjectCache(mCache.get());
     355    }
     356    mEngine = engine;
     357}
     358
     359void ParabixDriver::addKernelCall(kernel::KernelBuilder & kb, const std::vector<parabix::StreamSetBuffer *> & inputs, const std::vector<parabix::StreamSetBuffer *> & outputs) {
     360    mKernelList.push_back(&kb);
     361    kb.setCallParameters(inputs, outputs);
     362}
     363
     364
     365void ParabixDriver::generatePipelineIR() {
     366    for (auto kb : mKernelList) {
     367        kb->addKernelDeclarations(mMainModule);
     368    }
     369    if (codegen::pipelineParallel) {
     370        generateParallelPipeline(iBuilder, mKernelList);
     371    } else if (codegen::segmentPipelineParallel) {
     372        generateSegmentParallelPipeline(iBuilder, mKernelList);
     373    } else {
     374        codegen::ThreadNum = 1;
     375        generatePipelineLoop(iBuilder, mKernelList);
     376    }
     377}
     378
     379void ParabixDriver::linkAndFinalize() {
     380    for (auto kb : mKernelList) {
     381        std::unique_ptr<Module> km = kb->createKernelStub();
     382        if (!(mCache && mCache->loadCachedObjectFile(km.get()))) {
     383            Module * saveM = iBuilder->getModule();
     384            iBuilder->setModule(km.get());
     385            kb->generateKernel();
     386            iBuilder->setModule(saveM);
     387        }
     388        mEngine->addModule(std::move(km));
     389    }
     390    mEngine->finalizeObject();
     391}
     392
     393void * ParabixDriver::getPointerToMain() {
     394    return mEngine->getPointerToNamedFunction("Main");
     395}
     396
  • icGREP/icgrep-devel/icgrep/toolchain.h

    r5373 r5391  
    11/*
    2  *  Copyright (c) 2015 International Characters.
     2 *  Copyright (c) 2017 International Characters.
    33 *  This software is licensed to the public under the Open Software License 3.0.
    44 *  icgrep is a trademark of International Characters.
     
    99#include <string>
    1010#include <IR_Gen/idisa_builder.h>
     11#include <object_cache.h>
    1112
    1213namespace llvm { class ExecutionEngine; }
     
    1516namespace IDISA { class IDISA_Builder; }
    1617namespace kernel { class KernelBuilder; }
     18namespace parabix { class StreamSetBuffer; }
    1719
    1820namespace codegen {
     
    5860void generatePipeline(IDISA::IDISA_Builder * iBuilder, const std::vector<kernel::KernelBuilder *> & kernels);
    5961
     62
     63class ParabixDriver {
     64public:
     65    ParabixDriver(IDISA::IDISA_Builder * iBuilder);
     66   
     67    IDISA::IDISA_Builder * getIDISA_Builder() {return iBuilder;}
     68   
     69    void JITcompileMain ();
     70   
     71    void addKernelCall(kernel::KernelBuilder & kb, const std::vector<parabix::StreamSetBuffer *> & inputs, const std::vector<parabix::StreamSetBuffer *> & outputs);
     72   
     73    void generatePipelineIR();
     74   
     75    void linkAndFinalize();
     76   
     77    void * getPointerToMain();
     78
     79   
     80private:
     81    llvm::Module * mMainModule;
     82    IDISA::IDISA_Builder * iBuilder;
     83    std::unique_ptr<ParabixObjectCache> mCache;
     84    //std::unique_ptr<llvm::ExecutionEngine> mEngine;
     85    llvm::ExecutionEngine * mEngine;
     86    std::vector<kernel::KernelBuilder *> mKernelList;
     87};
    6088#endif
  • icGREP/icgrep-devel/icgrep/wc.cpp

    r5377 r5391  
    123123}
    124124
    125 Function * pipeline(Module * m, IDISA::IDISA_Builder * iBuilder) {
     125
     126
     127
     128typedef void (*wcFunctionType)(char * byte_data, size_t filesize, size_t fileIdx);
     129
     130void wcPipelineGen(ParabixDriver & pxDriver) {
     131
     132    IDISA::IDISA_Builder * iBuilder = pxDriver.getIDISA_Builder();
     133    Module * m = iBuilder->getModule();
     134   
    126135    Type * mBitBlockType = iBuilder->getBitBlockType();
    127136    Constant * record_counts_routine;
     
    145154
    146155    SingleBlockBuffer BasisBits(iBuilder, iBuilder->getStreamSetTy(8, 1));
    147    
     156    iBuilder->SetInsertPoint(BasicBlock::Create(m->getContext(), "entry", main,0));
     157
    148158    MMapSourceKernel mmapK(iBuilder);
    149     std::unique_ptr<Module> mmapM = mmapK.createKernelModule({}, {&ByteStream});
    150159    mmapK.setInitialArguments({fileSize});
    151    
     160    pxDriver.addKernelCall(mmapK, {}, {&ByteStream});
     161
    152162    S2PKernel  s2pk(iBuilder);
    153     std::unique_ptr<Module> s2pM = s2pk.createKernelModule({&ByteStream}, {&BasisBits});
     163    pxDriver.addKernelCall(s2pk, {&ByteStream}, {&BasisBits});
    154164   
    155165    PabloKernel wck(iBuilder, "wc",
     
    161171    wc_gen(&wck);
    162172    pablo_function_passes(&wck);
    163    
    164     std::unique_ptr<Module> wcM = wck.createKernelModule({&BasisBits}, {});
    165    
    166     mmapK.addKernelDeclarations(m);
    167     s2pk.addKernelDeclarations(m);
    168     wck.addKernelDeclarations(m);
    169    
    170     iBuilder->SetInsertPoint(BasicBlock::Create(m->getContext(), "entry", main,0));
     173    pxDriver.addKernelCall(wck, {&BasisBits}, {});
    171174
    172175    ByteStream.setStreamSetBuffer(inputStream);
    173176    BasisBits.allocateBuffer();
    174    
    175     generatePipeline(iBuilder, {&mmapK, &s2pk, &wck});
     177
     178    pxDriver.generatePipelineIR();
    176179   
    177180    Value * lineCount = wck.createGetAccumulatorCall(wck.getInstance(), "lineCount");
     
    183186    iBuilder->CreateRetVoid();
    184187   
    185     Linker L(*m);
    186     L.linkInModule(std::move(mmapM));
    187     L.linkInModule(std::move(s2pM));
    188     L.linkInModule(std::move(wcM));
    189    
    190     return main;
    191 }
    192 
    193 
    194 typedef void (*wcFunctionType)(char * byte_data, size_t filesize, size_t fileIdx);
    195 
    196 static ExecutionEngine * wcEngine = nullptr;
     188    pxDriver.JITcompileMain();
     189    pxDriver.linkAndFinalize();
     190}
     191
    197192
    198193wcFunctionType wcCodeGen(void) {
    199194    Module * M = new Module("wc", getGlobalContext());
    200195    IDISA::IDISA_Builder * idb = IDISA::GetIDISA_Builder(M);
    201 
    202     llvm::Function * main_IR = pipeline(M, idb);
    203 
    204     wcEngine = JIT_to_ExecutionEngine(M);
    205    
    206     wcEngine->finalizeObject();
    207 
     196    ParabixDriver pxDriver(idb);
     197   
     198    wcPipelineGen(pxDriver);
     199
     200    wcFunctionType main = reinterpret_cast<wcFunctionType>(pxDriver.getPointerToMain());
    208201    delete idb;
    209     return reinterpret_cast<wcFunctionType>(wcEngine->getPointerToFunction(main_IR));
     202    return main;
    210203}
    211204
Note: See TracChangeset for help on using the changeset viewer.