Ignore:
Timestamp:
May 10, 2017, 4:26:11 PM (2 years ago)
Author:
nmedfort
Message:

Large refactoring step. Removed IR generation code from Kernel (formally KernelBuilder?) and moved it into the new KernelBuilder? class.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/toolchain/toolchain.cpp

    r5436 r5440  
    1515#include <llvm/IR/IRPrintingPasses.h>
    1616#include <llvm/InitializePasses.h>                 // for initializeCodeGen
    17 #ifndef NDEBUG
    18 #include <llvm/IR/Verifier.h>
    19 #include <boost/container/flat_set.hpp>
    20 #endif
    2117#include <llvm/PassRegistry.h>                     // for PassRegistry
    2218#include <llvm/Support/CodeGen.h>                  // for Level, Level::None
     
    3430#include <thread>
    3531#include <boost/lockfree/queue.hpp>
     32#ifndef NDEBUG
     33#include <llvm/IR/Verifier.h>
     34#endif
    3635
    3736using namespace llvm;
     
    151150
    152151    builder.setTargetOptions(opts);
    153     builder.setVerifyModules(IN_DEBUG_MODE);
     152    builder.setVerifyModules(false);
    154153    CodeGenOpt::Level optLevel = CodeGenOpt::Level::None;
    155154    switch (codegen::OptLevel) {
     
    204203    assert ("addKernelCall or makeKernelCall was already run on this kernel." && (kb.getModule() == nullptr));
    205204    mPipeline.emplace_back(&kb);
    206     assert (mMainModule);
    207     kb.setBuilder(iBuilder);
    208     kb.createKernelStub(inputs, outputs);
     205    kb.createKernelStub(iBuilder, inputs, outputs);
    209206}
    210207
     
    212209    assert ("addKernelCall or makeKernelCall was already run on this kernel." && (kb->getModule() == nullptr));
    213210    mPipeline.emplace_back(kb);   
    214     kb->setBuilder(iBuilder);
    215     kb->createKernelStub(inputs, outputs);
     211    kb->createKernelStub(iBuilder, inputs, outputs);
    216212}
    217213
     
    219215    #ifndef NDEBUG
    220216    if (LLVM_UNLIKELY(mPipeline.empty())) {
    221         report_fatal_error("Pipeline must contain at least one kernel");
     217        report_fatal_error("Pipeline cannot be empty");
    222218    } else {
    223         boost::container::flat_set<kernel::Kernel *> K(mPipeline.begin(), mPipeline.end());
    224         if (LLVM_UNLIKELY(K.size() != mPipeline.size())) {
    225             report_fatal_error("Kernel definitions can only occur once in the pipeline");
     219        for (auto i = mPipeline.begin(); i != mPipeline.end(); ++i) {
     220            for (auto j = i; ++j != mPipeline.end(); ) {
     221                if (LLVM_UNLIKELY(*i == *j)) {
     222                    report_fatal_error("Kernel instances cannot occur twice in the pipeline");
     223                }
     224            }
    226225        }
    227226    }
    228227    #endif
    229 
    230228    // note: instantiation of all kernels must occur prior to initialization
    231229    for (const auto & k : mPipeline) {
    232         k->addKernelDeclarations();
     230        k->addKernelDeclarations(iBuilder);
    233231    }
    234232    for (const auto & k : mPipeline) {
    235         k->createInstance();
     233        k->createInstance(iBuilder);
    236234    }
    237235    for (const auto & k : mPipeline) {
    238         k->initializeInstance();
     236        k->initializeInstance(iBuilder);
    239237    }
    240238    if (codegen::pipelineParallel) {
     
    247245    }
    248246    for (const auto & k : mPipeline) {
    249         k->setBuilder(iBuilder);
    250         k->finalizeInstance();
     247        k->finalizeInstance(iBuilder);
    251248    }
    252249}
     
    260257
    261258void ParabixDriver::linkAndFinalize() {
    262     Module * m = mMainModule;
    263     #ifndef NDEBUG
     259    Module * module = nullptr;
    264260    try {
    265     #endif
    266     legacy::PassManager PM;
    267     #ifndef NDEBUG
    268     PM.add(createVerifierPass());
    269     #endif
    270     PM.add(createPromoteMemoryToRegisterPass()); //Force the use of mem2reg to promote stack variables.
    271     PM.add(createReassociatePass());             //Reassociate expressions.
    272     PM.add(createGVNPass());                     //Eliminate common subexpressions.
    273     PM.add(createInstructionCombiningPass());    //Simple peephole optimizations and bit-twiddling.
    274     PM.add(createCFGSimplificationPass());
    275 
    276     raw_fd_ostream * IROutputStream = nullptr;
    277     if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::ShowIR))) {
    278         if (codegen::IROutputFilename.empty()) {
    279             IROutputStream = new raw_fd_ostream(STDERR_FILENO, false, false);
    280         } else {
    281             std::error_code error;
    282             IROutputStream = new raw_fd_ostream(codegen::IROutputFilename, error, sys::fs::OpenFlags::F_None);
    283         }
    284         PM.add(createPrintModulePass(*IROutputStream));
    285     }
    286 
    287     #ifndef USE_LLVM_3_6
    288     raw_fd_ostream * ASMOutputStream = nullptr;
    289     if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::ShowASM))) {
    290         if (codegen::ASMOutputFilename.empty()) {
    291             ASMOutputStream = new raw_fd_ostream(STDERR_FILENO, false, false);
    292         } else {
    293             std::error_code error;
    294             ASMOutputStream = new raw_fd_ostream(codegen::ASMOutputFilename, error, sys::fs::OpenFlags::F_None);
    295         }
    296         if (LLVM_UNLIKELY(mTarget->addPassesToEmitFile(PM, *ASMOutputStream, TargetMachine::CGFT_AssemblyFile))) {
    297             report_fatal_error("LLVM error: could not add emit assembly pass");
    298         }
    299     }
    300     #endif
    301 
    302     PM.run(*m);
    303 
    304     for (kernel::Kernel * const k : mPipeline) {
    305         m = k->getModule();
    306         bool uncachedObject = true;
    307         if (mCache && mCache->loadCachedObjectFile(k)) {
    308             uncachedObject = false;
    309         }
    310         if (uncachedObject) {
    311             iBuilder->setModule(m);
    312             k->setBuilder(iBuilder);
    313             k->generateKernel();
    314             PM.run(*m);
    315         }
    316         mEngine->addModule(std::unique_ptr<Module>(m));
    317     }   
    318     mEngine->finalizeObject();
    319 
    320     iBuilder->setModule(mMainModule);
    321 
    322     delete IROutputStream;
    323     #ifndef USE_LLVM_3_6
    324     delete ASMOutputStream;
    325     #endif
    326     #ifndef NDEBUG
    327     } catch (...) { m->dump(); throw; }
    328     #endif
     261
     262        legacy::PassManager PM;
     263        #ifndef NDEBUG
     264        PM.add(createVerifierPass());
     265        #endif
     266        PM.add(createPromoteMemoryToRegisterPass()); //Force the use of mem2reg to promote stack variables.
     267        PM.add(createReassociatePass());             //Reassociate expressions.
     268        PM.add(createGVNPass());                     //Eliminate common subexpressions.
     269        PM.add(createInstructionCombiningPass());    //Simple peephole optimizations and bit-twiddling.
     270        PM.add(createCFGSimplificationPass());
     271
     272        std::unique_ptr<raw_fd_ostream> IROutputStream(nullptr);
     273        if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::ShowIR))) {
     274            if (codegen::IROutputFilename.empty()) {
     275                IROutputStream.reset(new raw_fd_ostream(STDERR_FILENO, false, false));
     276            } else {
     277                std::error_code error;
     278                IROutputStream.reset(new raw_fd_ostream(codegen::IROutputFilename, error, sys::fs::OpenFlags::F_None));
     279            }
     280            PM.add(createPrintModulePass(*IROutputStream));
     281        }
     282
     283        #ifndef USE_LLVM_3_6
     284        std::unique_ptr<raw_fd_ostream> ASMOutputStream(nullptr);
     285        if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::ShowASM))) {
     286            if (codegen::ASMOutputFilename.empty()) {
     287                ASMOutputStream.reset(new raw_fd_ostream(STDERR_FILENO, false, false));
     288            } else {
     289                std::error_code error;
     290                ASMOutputStream.reset(new raw_fd_ostream(codegen::ASMOutputFilename, error, sys::fs::OpenFlags::F_None));
     291            }
     292            if (LLVM_UNLIKELY(mTarget->addPassesToEmitFile(PM, *ASMOutputStream, TargetMachine::CGFT_AssemblyFile))) {
     293                report_fatal_error("LLVM error: could not add emit assembly pass");
     294            }
     295        }
     296        #endif
     297
     298        for (kernel::Kernel * const kernel : mPipeline) {
     299            iBuilder->setKernel(kernel);
     300            module = kernel->getModule();
     301            bool uncachedObject = true;
     302            if (mCache && mCache->loadCachedObjectFile(iBuilder, kernel)) {
     303                uncachedObject = false;
     304            }
     305            if (uncachedObject) {
     306                module->setTargetTriple(mMainModule->getTargetTriple());
     307                kernel->generateKernel(iBuilder);
     308                PM.run(*module);
     309            }
     310            mEngine->addModule(std::unique_ptr<Module>(module));
     311        }
     312
     313        iBuilder->setKernel(nullptr);
     314        module = mMainModule;
     315        PM.run(*module);
     316
     317        mEngine->finalizeObject();
     318
     319    } catch (...) {
     320        module->dump();
     321        throw;
     322    }
    329323}
    330324
Note: See TracChangeset for help on using the changeset viewer.