/// Optimize merged modules using various IPO passes
bool LTOCodeGenerator::generateAssemblyCode(raw_ostream& out,
                                            std::string& errMsg)
{
    if ( this->determineTarget(errMsg) ) 
        return true;

    // mark which symbols can not be internalized 
    this->applyScopeRestrictions();

    Module* mergedModule = _linker.getModule();

    // if options were requested, set them
    if ( !_codegenOptions.empty() )
        cl::ParseCommandLineOptions(_codegenOptions.size(), 
                                    const_cast<char **>(&_codegenOptions[0]));

    // Instantiate the pass manager to organize the passes.
    PassManager passes;

    // Start off with a verification pass.
    passes.add(createVerifierPass());

    // Add an appropriate TargetData instance for this module...
    passes.add(new TargetData(*_target->getTargetData()));
    
    createStandardLTOPasses(&passes, /*Internalize=*/ false, !DisableInline,
                            /*VerifyEach=*/ false);

    // Make sure everything is still good.
    passes.add(createVerifierPass());

    FunctionPassManager* codeGenPasses = new FunctionPassManager(mergedModule);

    codeGenPasses->add(new TargetData(*_target->getTargetData()));

    formatted_raw_ostream Out(out);

    if (_target->addPassesToEmitFile(*codeGenPasses, Out,
                                     TargetMachine::CGFT_AssemblyFile,
                                     CodeGenOpt::Aggressive)) {
      errMsg = "target file type not supported";
      return true;
    }

    // Run our queue of passes all at once now, efficiently.
    passes.run(*mergedModule);

    // Run the code generator, and write assembly file
    codeGenPasses->doInitialization();

    for (Module::iterator
           it = mergedModule->begin(), e = mergedModule->end(); it != e; ++it)
      if (!it->isDeclaration())
        codeGenPasses->run(*it);

    codeGenPasses->doFinalization();

    return false; // success
}
示例#2
0
// Unfortunately, the LLVM C API doesn't provide an easy way of iterating over
// all the functions in a module, so we do that manually here. You'll find
// similar code in clang's BackendUtil.cpp file.
extern "C" void
LLVMRustRunFunctionPassManager(LLVMPassManagerRef PM, LLVMModuleRef M) {
    FunctionPassManager *P = unwrap<FunctionPassManager>(PM);
    P->doInitialization();
    for (Module::iterator I = unwrap(M)->begin(),
         E = unwrap(M)->end(); I != E; ++I)
        if (!I->isDeclaration())
            P->run(*I);
    P->doFinalization();
}
  bool JITOptimizations::runOnFunction(Function& F) {
    this->LI        = &getAnalysis<LoopInfo>();
    bool changed = false;

    FPM = new FunctionPassManager(F.getParent());

    // if the user input something we use those passes
    std::vector<const PassInfo *> &customPasses = JPD->getPassList();
    if (customPasses.size() > 0) {
      for (int i=0; i<customPasses.size();i++) {
        const PassInfo *pass = customPasses[i];
        FPM->add(pass->createPass());
      }
    } else {
      // Optimization ordering:
      //  - ADCE
      //  - inline
      //  - DSE <---- THIS causes seg faults when running on sqlite3
      //              test in llvm test-suite
      //  - Instruction Combining
      //  ---- IF LOOPS ----
      //  - LICM
      //  - Loop Simplify
      //  - Loop Strength Reduction
      //  ------------------
      //  - SCCP
      //  - Simplify CFG
      //  - SROA
      FPM->add(createAggressiveDCEPass());
      if (JPD->getThresholdT2() != 0)
        FPM->add(createDynamicInlinerPass(JPD));
      FPM->add(createInstructionCombiningPass());

      // --- Loop optimizations --- //
      if (LI->begin() != LI->end()) {
        FPM->add(createLICMPass());
        FPM->add(createLoopSimplifyPass());
        FPM->add(createLoopStrengthReducePass());
      }
      // -------------------------- //

      FPM->add(createSCCPPass());
      FPM->add(createCFGSimplificationPass());
      FPM->add(createSROAPass(false));
    }

    changed = changed | FPM->doInitialization();
    changed = changed | FPM->run(F);
    changed = changed | FPM->doFinalization();

    delete FPM;
    return changed;
  }
示例#4
0
Function &OptimizeForRuntime(Function &F) {
#ifdef DEBUG
  static PassManagerBuilder Builder = getDebugBuilder();
#else
  static PassManagerBuilder Builder = getBuilder();
#endif
  Module *M = F.getParent();
  opt::GenerateOutput = true;
  polly::opt::PollyParallel = true;

  FunctionPassManager PM = FunctionPassManager(M);

  Builder.populateFunctionPassManager(PM);
  PM.doInitialization();
  PM.run(F);
  PM.doFinalization();

  if (opt::havePapi()) {
    PassManager MPM;
    Builder.populateModulePassManager(MPM);
    MPM.add(polli::createTraceMarkerPass());
    MPM.run(*M);
  }

  if (opt::haveLikwid()) {
    PassManager MPM;
    Builder.populateModulePassManager(MPM);
    MPM.add(polli::createLikwidMarkerPass());
    MPM.run(*M);
  }

  DEBUG(
  StoreModule(*M, M->getModuleIdentifier() + ".after.polly.ll")
  );
  opt::GenerateOutput = false;

  return F;
}
示例#5
0
/// Optimize merged modules using various IPO passes
bool LTOCodeGenerator::generateObjectFile(raw_ostream &out,
                                          std::string &errMsg) {
  if ( this->determineTarget(errMsg) )
    return true;

  Module* mergedModule = _linker.getModule();

  // if options were requested, set them
  if ( !_codegenOptions.empty() )
    cl::ParseCommandLineOptions(_codegenOptions.size(),
                                const_cast<char **>(&_codegenOptions[0]));

  // mark which symbols can not be internalized
  this->applyScopeRestrictions();

  // Instantiate the pass manager to organize the passes.
  PassManager passes;

  // Start off with a verification pass.
  passes.add(createVerifierPass());

  // Add an appropriate TargetData instance for this module...
  passes.add(new TargetData(*_target->getTargetData()));

  // Enabling internalize here would use its AllButMain variant. It
  // keeps only main if it exists and does nothing for libraries. Instead
  // we create the pass ourselves with the symbol list provided by the linker.
  PassManagerBuilder().populateLTOPassManager(passes, /*Internalize=*/false,
                                              !DisableInline,
                                              DisableGVNLoadPRE);

  // Make sure everything is still good.
  passes.add(createVerifierPass());

  FunctionPassManager *codeGenPasses = new FunctionPassManager(mergedModule);

  codeGenPasses->add(new TargetData(*_target->getTargetData()));

  formatted_raw_ostream Out(out);

  if (_target->addPassesToEmitFile(*codeGenPasses, Out,
                                   TargetMachine::CGFT_ObjectFile)) {
    errMsg = "target file type not supported";
    return true;
  }
    bool UsingSAFECode = false;
    // Add the SAFECode optimization/finalization passes.
    // Note that we only run these passes (which require DSA) if we detect
    // that run-time checks have been added to the code.
    for (unsigned index = 0; index < numChecks; ++index) {
      if (mergedModule->getFunction(RuntimeChecks[index].name)) {
        UsingSAFECode = true;
        break;
      }
    }

    if (UsingSAFECode) {
      passes.add(new TargetData(*_target->getTargetData()));
      passes.add(createSAFECodeMSCInfoPass());
      passes.add(createExactCheckOptPass());

      passes.add(new ScalarEvolution());
      passes.add(createLocalArrayBoundsAnalysisPass());
      passes.add(createOptimizeFastMemoryChecksPass());
      passes.add(createOptimizeIdenticalLSChecksPass());
      passes.add(new DominatorTree());
      passes.add(new ScalarEvolution());
      passes.add(createOptimizeImpliedFastLSChecksPass());

      if (mergedModule->getFunction("main")) {
        passes.add(new CompleteChecks());
      }

#ifdef POOLALLOC
      LowerSafecodeIntrinsic::IntrinsicMappingEntry *MapStart, *MapEnd;
      MapStart = RuntimeDebug;
      MapEnd = &RuntimeDebug[sizeof(RuntimeDebug) / sizeof(RuntimeDebug[0])];

      // Add the automatic pool allocation passes
      passes.add(new OptimizeSafeLoadStore());
      passes.add(new PA::AllNodesHeuristic());
      //passes.add(new PoolAllocate());
      passes.add(new PoolAllocateSimple());
      // SAFECode's debug runtime needs to replace some of the poolalloc
      // intrinsics; LowerSafecodeIntrinsic handles the replacement.
      passes.add(new LowerSafecodeIntrinsic(MapStart, MapEnd));
#endif

      // Run our queue of passes all at once now, efficiently.
      passes.run(*mergedModule);

#ifdef POOLALLOC
      if (const char *OutFileName = getenv("PA_BITCODE_FILE")) {
        // Write out the pool allocated bitcode file for debugging purposes.
        std::cerr << "Writing out poolalloc bitcode file to " << OutFileName;
        std::cerr << std::endl;

        std::string error;
        tool_output_file PAFile(OutFileName, error, raw_fd_ostream::F_Binary);

        if (!error.empty()) {
          std::cerr << "Error writing out poolalloc bitcode file: " << error;
          std::cerr << std::endl;
        } else {
          WriteBitcodeToFile(mergedModule, PAFile.os());
          PAFile.os().close();
          PAFile.keep();
        }
      }
#endif
    }

    // Run the code generator, and write assembly file
    codeGenPasses->doInitialization();
  // Run our queue of passes all at once now, efficiently.
  passes.run(*mergedModule);

  // Run the code generator, and write assembly file
  codeGenPasses->doInitialization();

  for (Module::iterator
         it = mergedModule->begin(), e = mergedModule->end(); it != e; ++it)
    if (!it->isDeclaration())
      codeGenPasses->run(*it);

  codeGenPasses->doFinalization();
  delete codeGenPasses;

  return false; // success
}
示例#6
0
/// Optimize merged modules using various IPO passes
bool LTOCodeGenerator::generateAssemblyCode(std::ostream& out, std::string& errMsg)
{
    if (  this->determineTarget(errMsg) ) 
        return true;

    // mark which symbols can not be internalized 
    this->applyScopeRestrictions();

    Module* mergedModule = _linker.getModule();

     // If target supports exception handling then enable it now.
    if ( _target->getTargetAsmInfo()->doesSupportExceptionHandling() )
        llvm::ExceptionHandling = true;

    // set codegen model
    switch( _codeModel ) {
        case LTO_CODEGEN_PIC_MODEL_STATIC:
            _target->setRelocationModel(Reloc::Static);
            break;
        case LTO_CODEGEN_PIC_MODEL_DYNAMIC:
            _target->setRelocationModel(Reloc::PIC_);
            break;
        case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC:
            _target->setRelocationModel(Reloc::DynamicNoPIC);
            break;
    }

    // Instantiate the pass manager to organize the passes.
    PassManager passes;

    // Start off with a verification pass.
    passes.add(createVerifierPass());

    // Add an appropriate TargetData instance for this module...
    passes.add(new TargetData(*_target->getTargetData()));
    
    // Now that we internalized some globals, see if we can hack on them!
    passes.add(createGlobalOptimizerPass());

    // Linking modules together can lead to duplicated global constants, only
    // keep one copy of each constant...
    passes.add(createConstantMergePass());

    // If the -s command line option was specified, strip the symbols out of the
    // resulting program to make it smaller.  -s is a GLD option that we are
    // supporting.
    passes.add(createStripSymbolsPass());
    
    // Propagate constants at call sites into the functions they call.
    passes.add(createIPConstantPropagationPass());

    // Remove unused arguments from functions...
    passes.add(createDeadArgEliminationPass());

    passes.add(createFunctionInliningPass()); // Inline small functions

    passes.add(createPruneEHPass());            // Remove dead EH info

    passes.add(createGlobalDCEPass());          // Remove dead functions

    // If we didn't decide to inline a function, check to see if we can
    // transform it to pass arguments by value instead of by reference.
    passes.add(createArgumentPromotionPass());

    // The IPO passes may leave cruft around.  Clean up after them.
    passes.add(createInstructionCombiningPass());
    passes.add(createJumpThreadingPass());        // Thread jumps.
    passes.add(createScalarReplAggregatesPass()); // Break up allocas

    // Run a few AA driven optimizations here and now, to cleanup the code.
    passes.add(createGlobalsModRefPass());      // IP alias analysis

    passes.add(createLICMPass());               // Hoist loop invariants
    passes.add(createGVNPass());               // Remove common subexprs
    passes.add(createMemCpyOptPass());  // Remove dead memcpy's
    passes.add(createDeadStoreEliminationPass()); // Nuke dead stores

    // Cleanup and simplify the code after the scalar optimizations.
    passes.add(createInstructionCombiningPass());

    passes.add(createJumpThreadingPass());        // Thread jumps.

    // Delete basic blocks, which optimization passes may have killed...
    passes.add(createCFGSimplificationPass());

    // Now that we have optimized the program, discard unreachable functions...
    passes.add(createGlobalDCEPass());

    // Make sure everything is still good.
    passes.add(createVerifierPass());

    FunctionPassManager* codeGenPasses =
            new FunctionPassManager(new ExistingModuleProvider(mergedModule));

    codeGenPasses->add(new TargetData(*_target->getTargetData()));

    MachineCodeEmitter* mce = NULL;

    switch (_target->addPassesToEmitFile(*codeGenPasses, out,
                                      TargetMachine::AssemblyFile, true)) {
        case FileModel::MachOFile:
            mce = AddMachOWriter(*codeGenPasses, out, *_target);
            break;
        case FileModel::ElfFile:
            mce = AddELFWriter(*codeGenPasses, out, *_target);
            break;
        case FileModel::AsmFile:
            break;
        case FileModel::Error:
        case FileModel::None:
            errMsg = "target file type not supported";
            return true;
    }

    if (_target->addPassesToEmitFileFinish(*codeGenPasses, mce, true)) {
        errMsg = "target does not support generation of this file type";
        return true;
    }

    // Run our queue of passes all at once now, efficiently.
    passes.run(*mergedModule);

    // Run the code generator, and write assembly file
    codeGenPasses->doInitialization();
    for (Module::iterator it = mergedModule->begin(),
                e = mergedModule->end(); it != e; ++it) {
        if (!it->isDeclaration())
            codeGenPasses->run(*it);
    }
    codeGenPasses->doFinalization();

    return false; // success
}
示例#7
0
文件: lto.cpp 项目: marnen/rubinius
/// Optimize module M using various IPO passes. Use exportList to 
/// internalize selected symbols. Target platform is selected
/// based on information available to module M. No new target
/// features are selected. 
enum LTOStatus 
LTO::optimize(Module *M, std::ostream &Out,
              std::vector<const char *> &exportList)
{
  // Instantiate the pass manager to organize the passes.
  PassManager Passes;
  
  // Collect Target info
  getTarget(M);

  if (!Target)
    return LTO_NO_TARGET;

  // If target supports exception handling then enable it now.
  if (Target->getTargetAsmInfo()->doesSupportExceptionHandling())
    ExceptionHandling = true;

  // Start off with a verification pass.
  Passes.add(createVerifierPass());
  
  // Add an appropriate TargetData instance for this module...
  Passes.add(new TargetData(*Target->getTargetData()));
  
  // Internalize symbols if export list is nonemty
  if (!exportList.empty())
    Passes.add(createInternalizePass(exportList));

  // Now that we internalized some globals, see if we can hack on them!
  Passes.add(createGlobalOptimizerPass());
  
  // Linking modules together can lead to duplicated global constants, only
  // keep one copy of each constant...
  Passes.add(createConstantMergePass());
  
  // If the -s command line option was specified, strip the symbols out of the
  // resulting program to make it smaller.  -s is a GLD option that we are
  // supporting.
  Passes.add(createStripSymbolsPass());
  
  // Propagate constants at call sites into the functions they call.
  Passes.add(createIPConstantPropagationPass());
  
  // Remove unused arguments from functions...
  Passes.add(createDeadArgEliminationPass());
  
  Passes.add(createFunctionInliningPass()); // Inline small functions
  
  Passes.add(createPruneEHPass());            // Remove dead EH info

  Passes.add(createGlobalDCEPass());          // Remove dead functions

  // If we didn't decide to inline a function, check to see if we can
  // transform it to pass arguments by value instead of by reference.
  Passes.add(createArgumentPromotionPass());

  // The IPO passes may leave cruft around.  Clean up after them.
  Passes.add(createInstructionCombiningPass());
  
  Passes.add(createScalarReplAggregatesPass()); // Break up allocas
  
  // Run a few AA driven optimizations here and now, to cleanup the code.
  Passes.add(createGlobalsModRefPass());      // IP alias analysis
  
  Passes.add(createLICMPass());               // Hoist loop invariants
  Passes.add(createGVNPass());               // Remove common subexprs
  Passed.add(createMemCpyOptPass());  // Remove dead memcpy's
  Passes.add(createDeadStoreEliminationPass()); // Nuke dead stores

  // Cleanup and simplify the code after the scalar optimizations.
  Passes.add(createInstructionCombiningPass());
 
  // Delete basic blocks, which optimization passes may have killed...
  Passes.add(createCFGSimplificationPass());
  
  // Now that we have optimized the program, discard unreachable functions...
  Passes.add(createGlobalDCEPass());
  
  // Make sure everything is still good.
  Passes.add(createVerifierPass());

  FunctionPassManager *CodeGenPasses =
    new FunctionPassManager(new ExistingModuleProvider(M));

  CodeGenPasses->add(new TargetData(*Target->getTargetData()));

  MachineCodeEmitter *MCE = 0;

  switch (Target->addPassesToEmitFile(*CodeGenPasses, Out,
                                      TargetMachine::AssemblyFile, true)) {
  default:
  case FileModel::Error:
    return LTO_WRITE_FAILURE;
  case FileModel::AsmFile:
    break;
  case FileModel::MachOFile:
    MCE = AddMachOWriter(*CodeGenPasses, Out, *Target);
    break;
  case FileModel::ElfFile:
    MCE = AddELFWriter(*CodeGenPasses, Out, *Target);
    break;
  }

  if (Target->addPassesToEmitFileFinish(*CodeGenPasses, MCE, true))
    return LTO_WRITE_FAILURE;

  // Run our queue of passes all at once now, efficiently.
  Passes.run(*M);

  // Run the code generator, if present.
  CodeGenPasses->doInitialization();
  for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) {
    if (!I->isDeclaration())
      CodeGenPasses->run(*I);
  }
  CodeGenPasses->doFinalization();

  return LTO_OPT_SUCCESS;
}
示例#8
0
/// Optimize merged modules using various IPO passes
bool LTOCodeGenerator::generateObjectFile(raw_ostream &out,
                                          std::string &errMsg) {

  // if options were requested, set them
  if (!_codegenOptions.empty())
    cl::ParseCommandLineOptions(_codegenOptions.size(),
                                const_cast<char **>(&_codegenOptions[0]));

  if (this->determineTarget(errMsg))
    return true;

  Module* mergedModule = _linker.getModule();

  // mark which symbols can not be internalized
  this->applyScopeRestrictions();

  // Instantiate the pass manager to organize the passes.
  PassManager passes;

  // Start off with a verification pass.
  passes.add(createVerifierPass());

  // Add an appropriate DataLayout instance for this module...
  passes.add(new DataLayout(*_target->getDataLayout()));
  passes.add(new TargetTransformInfo(_target->getScalarTargetTransformInfo(),
                                     _target->getVectorTargetTransformInfo()));

  // Enabling internalize here would use its AllButMain variant. It
  // keeps only main if it exists and does nothing for libraries. Instead
  // we create the pass ourselves with the symbol list provided by the linker.
  PassManagerBuilder().populateLTOPassManager(passes, /*Internalize=*/false,
                                              !DisableInline,
                                              DisableGVNLoadPRE);

  // Make sure everything is still good.
  passes.add(createVerifierPass());

  FunctionPassManager *codeGenPasses = new FunctionPassManager(mergedModule);

  codeGenPasses->add(new DataLayout(*_target->getDataLayout()));

  formatted_raw_ostream Out(out);

  if (_target->addPassesToEmitFile(*codeGenPasses, Out,
                                   TargetMachine::CGFT_ObjectFile)) {
    errMsg = "target file type not supported";
    return true;
  }

  // Run our queue of passes all at once now, efficiently.
  passes.run(*mergedModule);

  // Run the code generator, and write assembly file
  codeGenPasses->doInitialization();

  for (Module::iterator
         it = mergedModule->begin(), e = mergedModule->end(); it != e; ++it)
    if (!it->isDeclaration())
      codeGenPasses->run(*it);

  codeGenPasses->doFinalization();
  delete codeGenPasses;

  return false; // success
}
/// Optimize merged modules using various IPO passes
bool LTOCodeGenerator::generateAssemblyCode(formatted_raw_ostream& out,
                                            std::string& errMsg)
{
    if ( this->determineTarget(errMsg) ) 
        return true;

    // mark which symbols can not be internalized 
    this->applyScopeRestrictions();

    Module* mergedModule = _linker.getModule();

    // If target supports exception handling then enable it now.
    switch (_target->getTargetAsmInfo()->getExceptionHandlingType()) {
    case ExceptionHandling::Dwarf:
      llvm::DwarfExceptionHandling = true;
      break;
    case ExceptionHandling::SjLj:
      llvm::SjLjExceptionHandling = true;
      break;
    case ExceptionHandling::None:
      break;
    default:
      assert (0 && "Unknown exception handling model!");
    }

    // if options were requested, set them
    if ( !_codegenOptions.empty() )
        cl::ParseCommandLineOptions(_codegenOptions.size(), 
                                                (char**)&_codegenOptions[0]);

    // Instantiate the pass manager to organize the passes.
    PassManager passes;

    // Start off with a verification pass.
    passes.add(createVerifierPass());

    // Add an appropriate TargetData instance for this module...
    passes.add(new TargetData(*_target->getTargetData()));
    
    createStandardLTOPasses(&passes, /*Internalize=*/ false, !DisableInline,
                            /*VerifyEach=*/ false);

    // Make sure everything is still good.
    passes.add(createVerifierPass());

    FunctionPassManager* codeGenPasses =
            new FunctionPassManager(new ExistingModuleProvider(mergedModule));

    codeGenPasses->add(new TargetData(*_target->getTargetData()));

    ObjectCodeEmitter* oce = NULL;

    switch (_target->addPassesToEmitFile(*codeGenPasses, out,
                                         TargetMachine::AssemblyFile,
                                         CodeGenOpt::Aggressive)) {
        case FileModel::MachOFile:
            oce = AddMachOWriter(*codeGenPasses, out, *_target);
            break;
        case FileModel::ElfFile:
            oce = AddELFWriter(*codeGenPasses, out, *_target);
            break;
        case FileModel::AsmFile:
            break;
        case FileModel::Error:
        case FileModel::None:
            errMsg = "target file type not supported";
            return true;
    }

    if (_target->addPassesToEmitFileFinish(*codeGenPasses, oce,
                                           CodeGenOpt::Aggressive)) {
        errMsg = "target does not support generation of this file type";
        return true;
    }

    // Run our queue of passes all at once now, efficiently.
    passes.run(*mergedModule);

    // Run the code generator, and write assembly file
    codeGenPasses->doInitialization();

    for (Module::iterator
           it = mergedModule->begin(), e = mergedModule->end(); it != e; ++it)
      if (!it->isDeclaration())
        codeGenPasses->run(*it);

    codeGenPasses->doFinalization();

    out.flush();

    return false; // success
}