示例#1
0
void PassManagerBuilder::populateFunctionPassManager(FunctionPassManager &FPM) {
  addExtensionsToPM(EP_EarlyAsPossible, FPM);

  // Add LibraryInfo if we have some.
  if (LibraryInfo) FPM.add(new TargetLibraryInfo(*LibraryInfo));

  if (OptLevel == 0) return;

  addInitialAliasAnalysisPasses(FPM);

  FPM.add(createCFGSimplificationPass());
  if (UseNewSROA)
    FPM.add(createSROAPass());
  else
    FPM.add(createScalarReplAggregatesPass());
  FPM.add(createEarlyCSEPass());
  FPM.add(createLowerExpectIntrinsicPass());
}
示例#2
0
文件: opt.cpp 项目: CartBlanche/llvm
/// AddOptimizationPasses - This routine adds optimization passes
/// based on selected optimization level, OptLevel. This routine
/// duplicates llvm-gcc behaviour.
///
/// OptLevel - Optimization Level
static void AddOptimizationPasses(PassManagerBase &MPM,FunctionPassManager &FPM,
                                  unsigned OptLevel) {
  FPM.add(createVerifierPass());                  // Verify that input is correct

  PassManagerBuilder Builder;
  Builder.OptLevel = OptLevel;

  if (DisableInline) {
    // No inlining pass
  } else if (OptLevel > 1) {
    unsigned Threshold = 225;
    if (OptLevel > 2)
      Threshold = 275;
    Builder.Inliner = createFunctionInliningPass(Threshold);
  } else {
    Builder.Inliner = createAlwaysInlinerPass();
  }
  Builder.DisableUnitAtATime = !UnitAtATime;
  Builder.DisableUnrollLoops = OptLevel == 0;
  Builder.DisableSimplifyLibCalls = DisableSimplifyLibCalls;
  
  Builder.populateFunctionPassManager(FPM);
  Builder.populateModulePassManager(MPM);
}
示例#3
0
FunctionPassManager* Builder::getStandardOptimizer() {
    FunctionPassManager* optimizer = new FunctionPassManager(this->_mod);

    // Set up the optimizer pipeline.  Start with registering info about how the
    // target lays out data structures.
    if (this->_jit) {
        optimizer->add(new DataLayoutPass(*this->_jit->getDataLayout()));
    }
    // Provide basic AliasAnalysis support for GVN.
    optimizer->add(createBasicAliasAnalysisPass());
    // Do simple "peephole" optimizations and bit-twiddling optzns.
    optimizer->add(createInstructionCombiningPass());
    // Reassociate expressions.
    optimizer->add(createReassociatePass());
    // Eliminate Common SubExpressions.
    optimizer->add(createGVNPass());
    // Simplify the control flow graph (deleting unreachable blocks, etc).
    optimizer->add(createCFGSimplificationPass());

    optimizer->doInitialization();
    return optimizer;
}
示例#4
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
}
示例#5
0
MonoEERef
mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee)
{
  std::string Error;
  MonoEE *mono_ee;

  init_llvm ();

  mono_ee = new MonoEE ();

  MonoJITMemoryManager *mono_mm = new MonoJITMemoryManager ();
  mono_mm->alloc_cb = alloc_cb;
  mono_mm->dlsym_cb = dlsym_cb;
  mono_mm->exception_cb = exception_cb;
  mono_ee->mm = mono_mm;

  /*
   * The Default code model doesn't seem to work on amd64,
   * test_0_fields_with_big_offsets (among others) crashes, because LLVM tries to call
   * memset using a normal pcrel code which is in 32bit memory, while memset isn't.
   */

  TargetOptions opts;
  opts.JITExceptionHandling = 1;

  StringRef cpu_name = sys::getHostCPUName ();

  // EngineBuilder no longer has a copy assignment operator (?)
  std::unique_ptr<Module> Owner(unwrap(MP));
  EngineBuilder b (std::move(Owner));
  ExecutionEngine *EE = b.setJITMemoryManager (mono_mm).setTargetOptions (opts).setAllocateGVsWithCode (true).setMCPU (cpu_name).create ();

  g_assert (EE);
  mono_ee->EE = EE;

  MonoJITEventListener *listener = new MonoJITEventListener (emitted_cb);
  EE->RegisterJITEventListener (listener);
  mono_ee->listener = listener;

  FunctionPassManager *fpm = new FunctionPassManager (unwrap (MP));
  mono_ee->fpm = fpm;

  fpm->add(new DataLayoutPass(*EE->getDataLayout()));

  if (PassList.size() > 0) {
	  /* Use the passes specified by the env variable */
	  /* Only the passes in force_pass_linking () can be used */
	  for (unsigned i = 0; i < PassList.size(); ++i) {
		  const PassInfo *PassInf = PassList[i];
		  Pass *P = 0;

		  if (PassInf->getNormalCtor())
			  P = PassInf->getNormalCtor()();
		  fpm->add (P);
	  }
  } else {
	  /* Use the same passes used by 'opt' by default, without the ipo passes */
	  const char *opts = "-simplifycfg -domtree -domfrontier -scalarrepl -instcombine -simplifycfg -domtree -domfrontier -scalarrepl -instcombine -simplifycfg -instcombine -simplifycfg -reassociate -domtree -loops -loop-simplify -domfrontier -loop-simplify -lcssa -loop-rotate -licm -lcssa -loop-unswitch -instcombine -scalar-evolution -loop-simplify -lcssa -iv-users -indvars -loop-deletion -loop-simplify -lcssa -loop-unroll -instcombine -memdep -gvn -memdep -memcpyopt -sccp -instcombine -domtree -memdep -dse -adce -gvn -simplifycfg";
	  char **args;
	  int i;

	  args = g_strsplit (opts, " ", 1000);
	  for (i = 0; args [i]; i++)
		  ;
	  llvm::cl::ParseCommandLineOptions (i, args, "");
	  g_strfreev (args);

	  for (unsigned i = 0; i < PassList.size(); ++i) {
		  const PassInfo *PassInf = PassList[i];
		  Pass *P = 0;

		  if (PassInf->getNormalCtor())
			  P = PassInf->getNormalCtor()();
		  g_assert (P->getPassKind () == llvm::PT_Function || P->getPassKind () == llvm::PT_Loop);
		  fpm->add (P);
	  }

	  /*
	  fpm->add(createInstructionCombiningPass());
	  fpm->add(createReassociatePass());
	  fpm->add(createGVNPass());
	  fpm->add(createCFGSimplificationPass());
	  */
  }

  *ee = wrap (EE);

  return mono_ee;
}
示例#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
/// 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->getMCAsmInfo()->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(mergedModule);

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

    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
}
示例#8
0
文件: optimizer.cpp 项目: Axure/ldc
static void addOptimizationPasses(PassManagerBase &mpm, FunctionPassManager &fpm,
#endif
                                  unsigned optLevel, unsigned sizeLevel) {
    fpm.add(createVerifierPass());                  // Verify that input is correct

    PassManagerBuilder builder;
    builder.OptLevel = optLevel;
    builder.SizeLevel = sizeLevel;

    if (willInline()) {
        unsigned threshold = 225;
        if (sizeLevel == 1)      // -Os
            threshold = 75;
        else if (sizeLevel == 2) // -Oz
            threshold = 25;
        if (optLevel > 2)
            threshold = 275;
        builder.Inliner = createFunctionInliningPass(threshold);
    } else {
        builder.Inliner = createAlwaysInlinerPass();
    }
#if LDC_LLVM_VER < 304
    builder.DisableSimplifyLibCalls = disableSimplifyLibCalls;
#endif
    builder.DisableUnitAtATime = !unitAtATime;
    builder.DisableUnrollLoops = optLevel == 0;

#if LDC_LLVM_VER >= 304
    builder.DisableUnrollLoops = (disableLoopUnrolling.getNumOccurrences() > 0) ?
                                  disableLoopUnrolling : optLevel == 0;

    // This is final, unless there is a #pragma vectorize enable
    if (disableLoopVectorization)
        builder.LoopVectorize = false;
    // If option wasn't forced via cmd line (-vectorize-loops, -loop-vectorize)
    else if (!builder.LoopVectorize)
      builder.LoopVectorize = optLevel > 1 && sizeLevel < 2;

    // When #pragma vectorize is on for SLP, do the same as above
    builder.SLPVectorize =
        disableSLPVectorization ? false : optLevel > 1 && sizeLevel < 2;
#else
    /* builder.Vectorize is set in ctor from command line switch */
#endif

#if LDC_LLVM_VER >= 303
    if (opts::sanitize == opts::AddressSanitizer) {
        builder.addExtension(PassManagerBuilder::EP_OptimizerLast,
                             addAddressSanitizerPasses);
        builder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
                             addAddressSanitizerPasses);
    }

    if (opts::sanitize == opts::MemorySanitizer) {
        builder.addExtension(PassManagerBuilder::EP_OptimizerLast,
                             addMemorySanitizerPass);
        builder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
                             addMemorySanitizerPass);
    }

    if (opts::sanitize == opts::ThreadSanitizer) {
        builder.addExtension(PassManagerBuilder::EP_OptimizerLast,
                             addThreadSanitizerPass);
        builder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
                             addThreadSanitizerPass);
    }
#endif

    if (!disableLangSpecificPasses) {
        if (!disableSimplifyDruntimeCalls)
            builder.addExtension(PassManagerBuilder::EP_LoopOptimizerEnd, addSimplifyDRuntimeCallsPass);

        if (!disableGCToStack)
            builder.addExtension(PassManagerBuilder::EP_LoopOptimizerEnd, addGarbageCollect2StackPass);
    }

    // EP_OptimizerLast does not exist in LLVM 3.0, add it manually below.
    builder.addExtension(PassManagerBuilder::EP_OptimizerLast, addStripExternalsPass);

    builder.populateFunctionPassManager(fpm);
    builder.populateModulePassManager(mpm);
}
示例#9
0
//===----------------------------------------------------------------------===//
// main for opt
//
int main(int argc, char **argv) {
    llvm_shutdown_obj X;  // Call llvm_shutdown() on exit.
    try {
        cl::ParseCommandLineOptions(argc, argv,
                                    "llvm .bc -> .bc modular optimizer and analysis printer\n");
        sys::PrintStackTraceOnErrorSignal();

        // Allocate a full target machine description only if necessary.
        // FIXME: The choice of target should be controllable on the command line.
        std::auto_ptr<TargetMachine> target;

        std::string ErrorMessage;

        // Load the input module...
        std::auto_ptr<Module> M;
        if (MemoryBuffer *Buffer
                = MemoryBuffer::getFileOrSTDIN(InputFilename, &ErrorMessage)) {
            M.reset(ParseBitcodeFile(Buffer, &ErrorMessage));
            delete Buffer;
        }

        if (M.get() == 0) {
            cerr << argv[0] << ": ";
            if (ErrorMessage.size())
                cerr << ErrorMessage << "\n";
            else
                cerr << "bitcode didn't read correctly.\n";
            return 1;
        }

        // Figure out what stream we are supposed to write to...
        // FIXME: cout is not binary!
        std::ostream *Out = &std::cout;  // Default to printing to stdout...
        if (OutputFilename != "-") {
            if (!Force && std::ifstream(OutputFilename.c_str())) {
                // If force is not specified, make sure not to overwrite a file!
                cerr << argv[0] << ": error opening '" << OutputFilename
                     << "': file exists!\n"
                     << "Use -f command line argument to force output\n";
                return 1;
            }
            std::ios::openmode io_mode = std::ios::out | std::ios::trunc |
                                         std::ios::binary;
            Out = new std::ofstream(OutputFilename.c_str(), io_mode);

            if (!Out->good()) {
                cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
                return 1;
            }

            // Make sure that the Output file gets unlinked from the disk if we get a
            // SIGINT
            sys::RemoveFileOnSignal(sys::Path(OutputFilename));
        }

        // If the output is set to be emitted to standard out, and standard out is a
        // console, print out a warning message and refuse to do it.  We don't
        // impress anyone by spewing tons of binary goo to a terminal.
        if (!Force && !NoOutput && CheckBitcodeOutputToConsole(Out,!Quiet)) {
            NoOutput = true;
        }

        // Create a PassManager to hold and optimize the collection of passes we are
        // about to build...
        //
        PassManager Passes;

        // Add an appropriate TargetData instance for this module...
        Passes.add(new TargetData(M.get()));

        FunctionPassManager *FPasses = NULL;
        if (OptLevelO1 || OptLevelO2 || OptLevelO3) {
            FPasses = new FunctionPassManager(new ExistingModuleProvider(M.get()));
            FPasses->add(new TargetData(M.get()));
        }

        // If the -strip-debug command line option was specified, add it.  If
        // -std-compile-opts was also specified, it will handle StripDebug.
        if (StripDebug && !StandardCompileOpts)
            addPass(Passes, createStripSymbolsPass(true));

        // Create a new optimization pass for each one specified on the command line
        for (unsigned i = 0; i < PassList.size(); ++i) {
            // Check to see if -std-compile-opts was specified before this option.  If
            // so, handle it.
            if (StandardCompileOpts &&
                    StandardCompileOpts.getPosition() < PassList.getPosition(i)) {
                AddStandardCompilePasses(Passes);
                StandardCompileOpts = false;
            }

            if (OptLevelO1 && OptLevelO1.getPosition() < PassList.getPosition(i)) {
                AddOptimizationPasses(Passes, *FPasses, 1);
                OptLevelO1 = false;
            }

            if (OptLevelO2 && OptLevelO2.getPosition() < PassList.getPosition(i)) {
                AddOptimizationPasses(Passes, *FPasses, 2);
                OptLevelO2 = false;
            }

            if (OptLevelO3 && OptLevelO3.getPosition() < PassList.getPosition(i)) {
                AddOptimizationPasses(Passes, *FPasses, 3);
                OptLevelO3 = false;
            }

            const PassInfo *PassInf = PassList[i];
            Pass *P = 0;
            if (PassInf->getNormalCtor())
                P = PassInf->getNormalCtor()();
            else
                cerr << argv[0] << ": cannot create pass: "******"\n";
            if (P) {
                bool isBBPass = dynamic_cast<BasicBlockPass*>(P) != 0;
                bool isLPass = !isBBPass && dynamic_cast<LoopPass*>(P) != 0;
                bool isFPass = !isLPass && dynamic_cast<FunctionPass*>(P) != 0;
                bool isCGSCCPass = !isFPass && dynamic_cast<CallGraphSCCPass*>(P) != 0;

                addPass(Passes, P);

                if (AnalyzeOnly) {
                    if (isBBPass)
                        Passes.add(new BasicBlockPassPrinter(PassInf));
                    else if (isLPass)
                        Passes.add(new LoopPassPrinter(PassInf));
                    else if (isFPass)
                        Passes.add(new FunctionPassPrinter(PassInf));
                    else if (isCGSCCPass)
                        Passes.add(new CallGraphSCCPassPrinter(PassInf));
                    else
                        Passes.add(new ModulePassPrinter(PassInf));
                }
            }

            if (PrintEachXForm)
                Passes.add(createPrintModulePass(&errs()));
        }

        // If -std-compile-opts was specified at the end of the pass list, add them.
        if (StandardCompileOpts) {
            AddStandardCompilePasses(Passes);
            StandardCompileOpts = false;
        }

        if (OptLevelO1) {
            AddOptimizationPasses(Passes, *FPasses, 1);
        }

        if (OptLevelO2) {
            AddOptimizationPasses(Passes, *FPasses, 2);
        }

        if (OptLevelO3) {
            AddOptimizationPasses(Passes, *FPasses, 3);
        }

        if (OptLevelO1 || OptLevelO2 || OptLevelO3) {
            for (Module::iterator I = M.get()->begin(), E = M.get()->end();
                    I != E; ++I)
                FPasses->run(*I);
        }

        // Check that the module is well formed on completion of optimization
        if (!NoVerify && !VerifyEach)
            Passes.add(createVerifierPass());

        // Write bitcode out to disk or cout as the last step...
        if (!NoOutput && !AnalyzeOnly)
            Passes.add(CreateBitcodeWriterPass(*Out));

        // Now that we have all of the passes ready, run them.
        Passes.run(*M.get());

        // Delete the ofstream.
        if (Out != &std::cout)
            delete Out;
        return 0;

    } catch (const std::string& msg) {
        cerr << argv[0] << ": " << msg << "\n";
    } catch (...) {
        cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
    }
    llvm_shutdown();
    return 1;
}
示例#10
0
文件: toy.cpp 项目: shepmaster/llvm
ExecutionEngine *MCJITHelper::compileModule(Module *M) {
    assert(EngineMap.find(M) == EngineMap.end());

    if (M == CurrentModule)
        closeCurrentModule();

    std::string ErrStr;
    ExecutionEngine *EE = EngineBuilder(M)
                          .setErrorStr(&ErrStr)
                          .setMCJITMemoryManager(new HelpingMemoryManager(this))
                          .create();
    if (!EE) {
        fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
        exit(1);
    }

    if (UseObjectCache)
        EE->setObjectCache(&OurObjectCache);
    // Get the ModuleID so we can identify IR input files
    const std::string ModuleID = M->getModuleIdentifier();

    // If we've flagged this as an IR file, it doesn't need function passes run.
    if (0 != ModuleID.compare(0, 3, "IR:")) {
        FunctionPassManager *FPM = 0;

        // Create a FPM for this module
        FPM = new FunctionPassManager(M);

        // Set up the optimizer pipeline.  Start with registering info about how the
        // target lays out data structures.
        FPM->add(new DataLayout(*EE->getDataLayout()));
        // Provide basic AliasAnalysis support for GVN.
        FPM->add(createBasicAliasAnalysisPass());
        // Promote allocas to registers.
        FPM->add(createPromoteMemoryToRegisterPass());
        // Do simple "peephole" optimizations and bit-twiddling optzns.
        FPM->add(createInstructionCombiningPass());
        // Reassociate expressions.
        FPM->add(createReassociatePass());
        // Eliminate Common SubExpressions.
        FPM->add(createGVNPass());
        // Simplify the control flow graph (deleting unreachable blocks, etc).
        FPM->add(createCFGSimplificationPass());

        FPM->doInitialization();

        // For each function in the module
        Module::iterator it;
        Module::iterator end = M->end();
        for (it = M->begin(); it != end; ++it) {
            // Run the FPM on this function
            FPM->run(*it);
        }

        delete FPM;
    }

    EE->finalizeObject();

    // Store this engine
    EngineMap[M] = EE;

    return EE;
}
示例#11
0
void EmitAssemblyHelper::CreatePasses(TargetMachine *TM) {
  unsigned OptLevel = CodeGenOpts.OptimizationLevel;
  CodeGenOptions::InliningMethod Inlining = CodeGenOpts.getInlining();

  // Handle disabling of LLVM optimization, where we want to preserve the
  // internal module before any optimization.
  if (CodeGenOpts.DisableLLVMOpts) {
    OptLevel = 0;
    Inlining = CodeGenOpts.NoInlining;
  }

  PassManagerBuilderWrapper PMBuilder(CodeGenOpts, LangOpts);
  PMBuilder.OptLevel = OptLevel;
  PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize;
  PMBuilder.BBVectorize = CodeGenOpts.VectorizeBB;
  PMBuilder.SLPVectorize = CodeGenOpts.VectorizeSLP;
  PMBuilder.LoopVectorize = CodeGenOpts.VectorizeLoop;

  PMBuilder.DisableUnitAtATime = !CodeGenOpts.UnitAtATime;
  PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops;

  // In ObjC ARC mode, add the main ARC optimization passes.
  if (LangOpts.ObjCAutoRefCount) {
    PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
                           addObjCARCExpandPass);
    PMBuilder.addExtension(PassManagerBuilder::EP_ModuleOptimizerEarly,
                           addObjCARCAPElimPass);
    PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate,
                           addObjCARCOptPass);
  }

  if (LangOpts.Sanitize.Bounds) {
    PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate,
                           addBoundsCheckingPass);
    PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
                           addBoundsCheckingPass);
  }

  if (LangOpts.Sanitize.Address) {
    PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
                           addAddressSanitizerPasses);
    PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
                           addAddressSanitizerPasses);
  }

  if (LangOpts.Sanitize.Memory) {
    PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
                           addMemorySanitizerPass);
    PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
                           addMemorySanitizerPass);
  }

  if (LangOpts.Sanitize.Thread) {
    PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
                           addThreadSanitizerPass);
    PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
                           addThreadSanitizerPass);
  }

  // This should depend on duetto, non on byte addressable
  if (!TM->getDataLayout()->isByteAddressable())
    PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
                           addDuettoNativeRewriterPass);

  // Figure out TargetLibraryInfo.
  Triple TargetTriple(TheModule->getTargetTriple());
  PMBuilder.LibraryInfo = new TargetLibraryInfo(TargetTriple);
  if (!CodeGenOpts.SimplifyLibCalls)
    PMBuilder.LibraryInfo->disableAllFunctions();
  
  switch (Inlining) {
  case CodeGenOptions::NoInlining: break;
  case CodeGenOptions::NormalInlining: {
    // FIXME: Derive these constants in a principled fashion.
    unsigned Threshold = 225;
    if (CodeGenOpts.OptimizeSize == 1)      // -Os
      Threshold = 75;
    else if (CodeGenOpts.OptimizeSize == 2) // -Oz
      Threshold = 25;
    else if (OptLevel > 2)
      Threshold = 275;
    PMBuilder.Inliner = createFunctionInliningPass(Threshold);
    break;
  }
  case CodeGenOptions::OnlyAlwaysInlining:
    // Respect always_inline.
    if (OptLevel == 0)
      // Do not insert lifetime intrinsics at -O0.
      PMBuilder.Inliner = createAlwaysInlinerPass(false);
    else
      PMBuilder.Inliner = createAlwaysInlinerPass();
    break;
  }

  // Set up the per-function pass manager.
  FunctionPassManager *FPM = getPerFunctionPasses(TM);
  if (CodeGenOpts.VerifyModule)
    FPM->add(createVerifierPass());
  PMBuilder.populateFunctionPassManager(*FPM);

  // Set up the per-module pass manager.
  PassManager *MPM = getPerModulePasses(TM);

  if (!CodeGenOpts.DisableGCov &&
      (CodeGenOpts.EmitGcovArcs || CodeGenOpts.EmitGcovNotes)) {
    // Not using 'GCOVOptions::getDefault' allows us to avoid exiting if
    // LLVM's -default-gcov-version flag is set to something invalid.
    GCOVOptions Options;
    Options.EmitNotes = CodeGenOpts.EmitGcovNotes;
    Options.EmitData = CodeGenOpts.EmitGcovArcs;
    memcpy(Options.Version, CodeGenOpts.CoverageVersion, 4);
    Options.UseCfgChecksum = CodeGenOpts.CoverageExtraChecksum;
    Options.NoRedZone = CodeGenOpts.DisableRedZone;
    Options.FunctionNamesInData =
        !CodeGenOpts.CoverageNoFunctionNamesInData;
    MPM->add(createGCOVProfilerPass(Options));
    if (CodeGenOpts.getDebugInfo() == CodeGenOptions::NoDebugInfo)
      MPM->add(createStripSymbolsPass(true));
  }

  PMBuilder.populateModulePassManager(*MPM);
}
示例#12
0
文件: BackendUtil.cpp 项目: jrk/clang
void EmitAssemblyHelper::CreatePasses() {
  unsigned OptLevel = CodeGenOpts.OptimizationLevel;
  CodeGenOptions::InliningMethod Inlining = CodeGenOpts.Inlining;

  // Handle disabling of LLVM optimization, where we want to preserve the
  // internal module before any optimization.
  if (CodeGenOpts.DisableLLVMOpts) {
    OptLevel = 0;
    Inlining = CodeGenOpts.NoInlining;
  }
  
  PassManagerBuilder PMBuilder;
  PMBuilder.OptLevel = OptLevel;
  PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize;

  PMBuilder.DisableSimplifyLibCalls = !CodeGenOpts.SimplifyLibCalls;
  PMBuilder.DisableUnitAtATime = !CodeGenOpts.UnitAtATime;
  PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops;

  // In ObjC ARC mode, add the main ARC optimization passes.
  if (LangOpts.ObjCAutoRefCount) {
    PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
                           addObjCARCExpandPass);
    PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate,
                           addObjCARCOptPass);
  }

  if (LangOpts.AddressSanitizer) {
    PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate,
                           addAddressSanitizerPass);
    PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
                           addAddressSanitizerPass);
  }
  
  // Figure out TargetLibraryInfo.
  Triple TargetTriple(TheModule->getTargetTriple());
  PMBuilder.LibraryInfo = new TargetLibraryInfo(TargetTriple);
  if (!CodeGenOpts.SimplifyLibCalls)
    PMBuilder.LibraryInfo->disableAllFunctions();
  
  switch (Inlining) {
  case CodeGenOptions::NoInlining: break;
  case CodeGenOptions::NormalInlining: {
    // FIXME: Derive these constants in a principled fashion.
    unsigned Threshold = 225;
    if (CodeGenOpts.OptimizeSize == 1)      // -Os
      Threshold = 75;
    else if (CodeGenOpts.OptimizeSize == 2) // -Oz
      Threshold = 25;
    else if (OptLevel > 2)
      Threshold = 275;
    PMBuilder.Inliner = createFunctionInliningPass(Threshold);
    break;
  }
  case CodeGenOptions::OnlyAlwaysInlining:
    // Respect always_inline.
    PMBuilder.Inliner = createAlwaysInlinerPass();
    break;
  }

 
  // Set up the per-function pass manager.
  FunctionPassManager *FPM = getPerFunctionPasses();
  if (CodeGenOpts.VerifyModule)
    FPM->add(createVerifierPass());
  PMBuilder.populateFunctionPassManager(*FPM);

  // Set up the per-module pass manager.
  PassManager *MPM = getPerModulePasses();

  if (CodeGenOpts.EmitGcovArcs || CodeGenOpts.EmitGcovNotes) {
    MPM->add(createGCOVProfilerPass(CodeGenOpts.EmitGcovNotes,
                                    CodeGenOpts.EmitGcovArcs,
                                    TargetTriple.isMacOSX()));

    if (!CodeGenOpts.DebugInfo)
      MPM->add(createStripSymbolsPass(true));
  }
  
  
  PMBuilder.populateModulePassManager(*MPM);
}
示例#13
0
文件: toy.cpp 项目: 0x00evil/llvm
void *MCJITHelper::getPointerToFunction(Function* F) {
  // See if an existing instance of MCJIT has this function.
  EngineVector::iterator begin = Engines.begin();
  EngineVector::iterator end = Engines.end();
  EngineVector::iterator it;
  for (it = begin; it != end; ++it) {
    void *P = (*it)->getPointerToFunction(F);
    if (P)
      return P;
  }

  // If we didn't find the function, see if we can generate it.
  if (OpenModule) {
    std::string ErrStr;
    ExecutionEngine *NewEngine = EngineBuilder(OpenModule)
                                              .setErrorStr(&ErrStr)
                                              .setMCJITMemoryManager(new HelpingMemoryManager(this))
                                              .create();
    if (!NewEngine) {
      fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
      exit(1);
    }

    // Create a function pass manager for this engine
    FunctionPassManager *FPM = new FunctionPassManager(OpenModule);

    // Set up the optimizer pipeline.  Start with registering info about how the
    // target lays out data structures.
    FPM->add(new DataLayout(*NewEngine->getDataLayout()));
    // Provide basic AliasAnalysis support for GVN.
    FPM->add(createBasicAliasAnalysisPass());
    // Promote allocas to registers.
    FPM->add(createPromoteMemoryToRegisterPass());
    // Do simple "peephole" optimizations and bit-twiddling optzns.
    FPM->add(createInstructionCombiningPass());
    // Reassociate expressions.
    FPM->add(createReassociatePass());
    // Eliminate Common SubExpressions.
    FPM->add(createGVNPass());
    // Simplify the control flow graph (deleting unreachable blocks, etc).
    FPM->add(createCFGSimplificationPass());
    FPM->doInitialization();

    // For each function in the module
    Module::iterator it;
    Module::iterator end = OpenModule->end();
    for (it = OpenModule->begin(); it != end; ++it) {
      // Run the FPM on this function
      FPM->run(*it);
    }

    // We don't need this anymore
    delete FPM;

    OpenModule = NULL;
    Engines.push_back(NewEngine);
    NewEngine->finalizeObject();
    return NewEngine->getPointerToFunction(F);
  }
  return NULL;
}
示例#14
0
文件: BackendPass.cpp 项目: 8l/cling
  void BackendPass::CreatePasses(const clang::LangOptions& LangOpts,
                                 const clang::CodeGenOptions& CodeGenOpts) {
    // See clang/lib/CodeGen/BackendUtil.cpp EmitAssemblyHelper::CreatePasses()
    unsigned OptLevel = CodeGenOpts.OptimizationLevel;
    CodeGenOptions::InliningMethod Inlining = CodeGenOpts.getInlining();

    // Handle disabling of LLVM optimization, where we want to preserve the
    // internal module before any optimization.
    if (CodeGenOpts.DisableLLVMOpts) {
      OptLevel = 0;
      Inlining = CodeGenOpts.NoInlining;
    }

    PassManagerBuilderWithOpts PMBuilder(LangOpts, CodeGenOpts);
    PMBuilder.OptLevel = OptLevel;
    PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize;
    PMBuilder.BBVectorize = CodeGenOpts.VectorizeBB;
    PMBuilder.SLPVectorize = CodeGenOpts.VectorizeSLP;
    PMBuilder.LoopVectorize = CodeGenOpts.VectorizeLoop;

    PMBuilder.DisableUnitAtATime = !CodeGenOpts.UnitAtATime;
    PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops;
    PMBuilder.RerollLoops = CodeGenOpts.RerollLoops;

#if 0
    if (!CodeGenOpts.SampleProfileFile.empty())
      PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
                             addSampleProfileLoaderPass);
#endif

    // In ObjC ARC mode, add the main ARC optimization passes.
    if (LangOpts.ObjCAutoRefCount) {
      PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
                             addObjCARCExpandPass);
      PMBuilder.addExtension(PassManagerBuilder::EP_ModuleOptimizerEarly,
                             addObjCARCAPElimPass);
      PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate,
                             addObjCARCOptPass);
    }

    if (LangOpts.Sanitize.LocalBounds) {
      PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate,
                             addBoundsCheckingPass);
      PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
                             addBoundsCheckingPass);
    }

    if (LangOpts.Sanitize.Address) {
      PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
                             addAddressSanitizerPasses);
      PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
                             addAddressSanitizerPasses);
    }

    if (LangOpts.Sanitize.Memory) {
      PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
                             addMemorySanitizerPass);
      PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
                             addMemorySanitizerPass);
    }

    if (LangOpts.Sanitize.Thread) {
      PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
                             addThreadSanitizerPass);
      PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
                             addThreadSanitizerPass);
    }

    if (LangOpts.Sanitize.DataFlow) {
      PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
                             addDataFlowSanitizerPass);
      PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
                             addDataFlowSanitizerPass);
    }

    // Figure out TargetLibraryInfo.
    Triple TargetTriple(m_Module->getTargetTriple());
    PMBuilder.LibraryInfo = new TargetLibraryInfo(TargetTriple);
    if (!CodeGenOpts.SimplifyLibCalls)
      PMBuilder.LibraryInfo->disableAllFunctions();

    switch (Inlining) {
    case CodeGenOptions::NoInlining: break;
    case CodeGenOptions::NormalInlining: {
      // FIXME: Derive these constants in a principled fashion.
      unsigned Threshold = 225;
      if (CodeGenOpts.OptimizeSize == 1)      // -Os
        Threshold = 75;
      else if (CodeGenOpts.OptimizeSize == 2) // -Oz
        Threshold = 25;
      else if (OptLevel > 2)
        Threshold = 275;
      // Creates a SimpleInliner that requests InsertLifetime.
      PMBuilder.Inliner
        = new InlinerKeepDeadFunc(createFunctionInliningPass(Threshold));
      break;
    }
    case CodeGenOptions::OnlyAlwaysInlining:
      // Respect always_inline.
      if (OptLevel == 0)
        // Do not insert lifetime intrinsics at -O0.
        PMBuilder.Inliner
          = new InlinerKeepDeadFunc(createAlwaysInlinerPass(false));
      else
        PMBuilder.Inliner
          = new InlinerKeepDeadFunc(createAlwaysInlinerPass());
      break;
    }

    // Set up the per-function pass manager.
    FunctionPassManager *FPM = getPerFunctionPasses();
    if (CodeGenOpts.VerifyModule)
      FPM->add(createVerifierPass());
    PMBuilder.populateFunctionPassManager(*FPM);

    // The Inliner is a module pass; register it.
    PMBuilder.populateModulePassManager(*getPerModulePasses());
  }
示例#15
0
int main(int argc, char **argv){
    cl::ParseCommandLineOptions(argc, argv, "llvm_trace_test\n");

    char directory[250];
    strncpy(directory, LogDir.c_str(), 250);
    int len = strlen(directory);
    if (len > 230){
        printf("Directory name too long\n");
        exit(1);
    }

    LLVMContext &Context = getGlobalContext();

    // Load the bitcode...
    SMDiagnostic Err;
    Module *Mod = ParseIRFile(strncat(directory, "/llvm-mod.bc", 12), Err,
        Context);
    if (!Mod) {
        Err.print(argv[0], errs());
        exit(1);
    }

    // Load dynamic log
    directory[len] = '\0';
    dlog = fopen(strncat(directory, "/llvm-memlog.log", 16), "r");
    if (!dlog){
        printf("Could not find log of dynamic values in specified directory\n");
        exit(1);
    }

    // Load function log
    directory[len] = '\0';
    flog = fopen(strncat(directory, "/llvm-functions.log", 19), "r");
    if (!flog){
        printf("Could not find log of LLVM functions in specified directory\n");
        exit(1);
    }

    // Initialize test function pass
    FunctionPassManager *FPasses = new FunctionPassManager(Mod);
    FunctionPass *fp = static_cast<FunctionPass*>(createTestFunctionPass());
    FPasses->add(fp);
    FPasses->doInitialization();

    char funcline[500];
    Function *F;

    // Check trace
    while (true){
        strncpy(funcline, "\0", 1);
        char *s = fgets(funcline, sizeof(funcline), flog);

        if (feof(flog)){
            break; // Done processing trace
        }

        // System call information - ignore for test
        if (!strncmp(funcline, "taint", 5)){
            continue;
        }

        funcline[strlen(funcline)-1] = '\0'; // remove newline
        F = Mod->getFunction(funcline);
        if (F == NULL){
            fprintf(stderr, "Error: unknown function, %s\n", funcline);
            exit(1);
        }

        //printf("%s\n", F->getName().str().c_str());
        FPasses->run(*F); // Call runOnFunction()
    }
    fclose(flog);
    fclose(dlog);
    printf("Trace and dynamic log are aligned.\n");
    return 0;
}
static void createOptimizationPasses() {
  // Create and set up the per-function pass manager.
  // FIXME: Move the code generator to be function-at-a-time.
  PerFunctionPasses =
    new FunctionPassManager(new ExistingModuleProvider(TheModule));
  PerFunctionPasses->add(new TargetData(*TheTarget->getTargetData()));

  // In -O0 if checking is disabled, we don't even have per-function passes.
  bool HasPerFunctionPasses = false;
#ifdef ENABLE_CHECKING
  PerFunctionPasses->add(createVerifierPass());
  HasPerFunctionPasses = true;
#endif

  if (optimize > 0 && !DisableLLVMOptimizations) {
    HasPerFunctionPasses = true;
    PerFunctionPasses->add(createCFGSimplificationPass());
    if (optimize == 1)
      PerFunctionPasses->add(createPromoteMemoryToRegisterPass());
    else
      PerFunctionPasses->add(createScalarReplAggregatesPass());
    PerFunctionPasses->add(createInstructionCombiningPass());
    //    PerFunctionPasses->add(createCFGSimplificationPass());
  }

  // FIXME: AT -O0/O1, we should stream out functions at a time.
  PerModulePasses = new PassManager();
  PerModulePasses->add(new TargetData(*TheTarget->getTargetData()));
  bool HasPerModulePasses = false;

  if (optimize > 0 && !DisableLLVMOptimizations) {
    HasPerModulePasses = true;
    PassManager *PM = PerModulePasses;
    if (flag_unit_at_a_time)
      PM->add(createRaiseAllocationsPass());      // call %malloc -> malloc inst
    PM->add(createCFGSimplificationPass());       // Clean up disgusting code
    PM->add(createPromoteMemoryToRegisterPass()); // Kill useless allocas
    if (flag_unit_at_a_time) {
      PM->add(createGlobalOptimizerPass());       // Optimize out global vars
      PM->add(createGlobalDCEPass());             // Remove unused fns and globs
      PM->add(createIPConstantPropagationPass()); // IP Constant Propagation
      PM->add(createDeadArgEliminationPass());    // Dead argument elimination
    }
    PM->add(createInstructionCombiningPass());    // Clean up after IPCP & DAE
    // DISABLE PREDSIMPLIFY UNTIL PR967 is fixed.
    //PM->add(createPredicateSimplifierPass());   // Canonicalize registers
    PM->add(createCFGSimplificationPass());       // Clean up after IPCP & DAE
    if (flag_unit_at_a_time)
      PM->add(createPruneEHPass());               // Remove dead EH info

    if (optimize > 1) {
      if (flag_inline_trees > 1)                // respect -fno-inline-functions
        PM->add(createFunctionInliningPass());  // Inline small functions
      if (flag_unit_at_a_time && !lang_hooks.flag_no_builtin())
        PM->add(createSimplifyLibCallsPass());  // Library Call Optimizations

      if (optimize > 2)
    	PM->add(createArgumentPromotionPass()); // Scalarize uninlined fn args
    }
    
    PM->add(createTailDuplicationPass());       // Simplify cfg by copying code
    PM->add(createInstructionCombiningPass());  // Cleanup for scalarrepl.
    PM->add(createCFGSimplificationPass());     // Merge & remove BBs
    PM->add(createScalarReplAggregatesPass());  // Break up aggregate allocas
    PM->add(createInstructionCombiningPass());  // Combine silly seq's
    PM->add(createCondPropagationPass());       // Propagate conditionals
    PM->add(createTailCallEliminationPass());   // Eliminate tail calls
    PM->add(createCFGSimplificationPass());     // Merge & remove BBs
    PM->add(createReassociatePass());           // Reassociate expressions
    PM->add(createLoopRotatePass());            // Rotate Loop
    PM->add(createLICMPass());                  // Hoist loop invariants
    PM->add(createLoopUnswitchPass(optimize_size ? true : false));
    PM->add(createInstructionCombiningPass());  // Clean up after LICM/reassoc
    PM->add(createIndVarSimplifyPass());        // Canonicalize indvars
    if (flag_unroll_loops)
      PM->add(createLoopUnrollPass());          // Unroll small loops
    PM->add(createInstructionCombiningPass());  // Clean up after the unroller
    PM->add(createLoadValueNumberingPass());    // GVN for load instructions
    PM->add(createGCSEPass());                  // Remove common subexprs
    PM->add(createSCCPPass());                  // Constant prop with SCCP
    
    // Run instcombine after redundancy elimination to exploit opportunities
    // opened up by them.
    PM->add(createInstructionCombiningPass());
    PM->add(createCondPropagationPass());       // Propagate conditionals
    PM->add(createDeadStoreEliminationPass());  // Delete dead stores
    PM->add(createAggressiveDCEPass());         // SSA based 'Aggressive DCE'
    PM->add(createCFGSimplificationPass());     // Merge & remove BBs
    
    if (optimize > 1 && flag_unit_at_a_time)
      PM->add(createConstantMergePass());       // Merge dup global constants 
    PM->add(createStripDeadPrototypesPass());   // Get rid of dead prototypes
  }
  
  if (emit_llvm_bc) {
    // Emit an LLVM .bc file to the output.  This is used when passed
    // -emit-llvm -c to the GCC driver.
    PerModulePasses->add(CreateBitcodeWriterPass(*AsmOutStream));

    // Disable emission of .ident into the output file... which is completely
    // wrong for llvm/.bc emission cases.
    flag_no_ident = 1;
    HasPerModulePasses = true;
  } else if (emit_llvm) {
    // Emit an LLVM .ll file to the output.  This is used when passed 
    // -emit-llvm -S to the GCC driver.
    PerModulePasses->add(new PrintModulePass(AsmOutFile));
    
    // Disable emission of .ident into the output file... which is completely
    // wrong for llvm/.bc emission cases.
    flag_no_ident = 1;
    HasPerModulePasses = true;
  } else {
    FunctionPassManager *PM;
    
    // If there are passes we have to run on the entire module, we do codegen
    // as a separate "pass" after that happens.
    // FIXME: This is disabled right now until bugs can be worked out.  Reenable
    // this for fast -O0 compiles!
    if (HasPerModulePasses || 1) {
      CodeGenPasses = PM =
        new FunctionPassManager(new ExistingModuleProvider(TheModule));
      PM->add(new TargetData(*TheTarget->getTargetData()));
    } else {
      // If there are no module-level passes that have to be run, we codegen as
      // each function is parsed.
      PM = PerFunctionPasses;
      HasPerFunctionPasses = true;
    }

    // Normal mode, emit a .s file by running the code generator.
    switch (TheTarget->addPassesToEmitFile(*PM, *AsmOutStream,
                                           TargetMachine::AssemblyFile,
                                           /*FAST*/optimize == 0)) {
    default:
    case FileModel::Error:
      cerr << "Error interfacing to target machine!\n";
      exit(1);
    case FileModel::AsmFile:
      break;
    }

    if (TheTarget->addPassesToEmitFileFinish(*PM, 0, /*Fast*/optimize == 0)) {
      cerr << "Error interfacing to target machine!\n";
      exit(1);
    }
  }
  
  if (HasPerFunctionPasses) {
    PerFunctionPasses->doInitialization();
  } else {
    delete PerFunctionPasses;
    PerFunctionPasses = 0;
  }
  if (!HasPerModulePasses) {
    delete PerModulePasses;
    PerModulePasses = 0;
  }
}
示例#17
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
}
示例#18
0
void EmitAssemblyHelper::CreatePasses() {
    unsigned OptLevel = CodeGenOpts.OptimizationLevel;
    CodeGenOptions::InliningMethod Inlining = CodeGenOpts.getInlining();

    // Handle disabling of LLVM optimization, where we want to preserve the
    // internal module before any optimization.
    if (CodeGenOpts.DisableLLVMOpts) {
        OptLevel = 0;
        Inlining = CodeGenOpts.NoInlining;
    }

    PassManagerBuilderWrapper PMBuilder(CodeGenOpts, LangOpts);
    PMBuilder.OptLevel = OptLevel;
    PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize;
    PMBuilder.BBVectorize = CodeGenOpts.VectorizeBB;
    PMBuilder.SLPVectorize = CodeGenOpts.VectorizeSLP;
    PMBuilder.LoopVectorize = CodeGenOpts.VectorizeLoop;

    PMBuilder.DisableTailCalls = CodeGenOpts.DisableTailCalls;
    PMBuilder.DisableUnitAtATime = !CodeGenOpts.UnitAtATime;
    PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops;
    PMBuilder.MergeFunctions = CodeGenOpts.MergeFunctions;
    PMBuilder.RerollLoops = CodeGenOpts.RerollLoops;

    PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
                           addAddDiscriminatorsPass);

    if (!CodeGenOpts.SampleProfileFile.empty())
        PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
                               addSampleProfileLoaderPass);

    // In ObjC ARC mode, add the main ARC optimization passes.
    if (LangOpts.ObjCAutoRefCount) {
        PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
                               addObjCARCExpandPass);
        PMBuilder.addExtension(PassManagerBuilder::EP_ModuleOptimizerEarly,
                               addObjCARCAPElimPass);
        PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate,
                               addObjCARCOptPass);
    }


    if (!CodeGenOpts.FsSemanticConfFile.empty())
        PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
                               addFsSemanticPass);

    if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds)) {
        PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate,
                               addBoundsCheckingPass);
        PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
                               addBoundsCheckingPass);
    }

    if (CodeGenOpts.SanitizeCoverage) {
        PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
                               addSanitizerCoveragePass);
        PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
                               addSanitizerCoveragePass);
    }

    if (LangOpts.Sanitize.has(SanitizerKind::Address)) {
        PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
                               addAddressSanitizerPasses);
        PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
                               addAddressSanitizerPasses);
    }

    if (LangOpts.Sanitize.has(SanitizerKind::Memory)) {
        PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
                               addMemorySanitizerPass);
        PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
                               addMemorySanitizerPass);
    }

    if (LangOpts.Sanitize.has(SanitizerKind::Thread)) {
        PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
                               addThreadSanitizerPass);
        PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
                               addThreadSanitizerPass);
    }

    if (LangOpts.Sanitize.has(SanitizerKind::DataFlow)) {
        PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
                               addDataFlowSanitizerPass);
        PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
                               addDataFlowSanitizerPass);
    }

    // Figure out TargetLibraryInfo.
    Triple TargetTriple(TheModule->getTargetTriple());
    PMBuilder.LibraryInfo = createTLI(TargetTriple, CodeGenOpts);

    switch (Inlining) {
    case CodeGenOptions::NoInlining:
        break;
    case CodeGenOptions::NormalInlining: {
        PMBuilder.Inliner =
            createFunctionInliningPass(OptLevel, CodeGenOpts.OptimizeSize);
        break;
    }
    case CodeGenOptions::OnlyAlwaysInlining:
        // Respect always_inline.
        if (OptLevel == 0)
            // Do not insert lifetime intrinsics at -O0.
            PMBuilder.Inliner = createAlwaysInlinerPass(false);
        else
            PMBuilder.Inliner = createAlwaysInlinerPass();
        break;
    }

    // Set up the per-function pass manager.
    FunctionPassManager *FPM = getPerFunctionPasses();
    if (CodeGenOpts.VerifyModule)
        FPM->add(createVerifierPass());
    PMBuilder.populateFunctionPassManager(*FPM);

    // Set up the per-module pass manager.
    PassManager *MPM = getPerModulePasses();
    if (CodeGenOpts.VerifyModule)
        MPM->add(createDebugInfoVerifierPass());

    if (!CodeGenOpts.DisableGCov &&
            (CodeGenOpts.EmitGcovArcs || CodeGenOpts.EmitGcovNotes)) {
        // Not using 'GCOVOptions::getDefault' allows us to avoid exiting if
        // LLVM's -default-gcov-version flag is set to something invalid.
        GCOVOptions Options;
        Options.EmitNotes = CodeGenOpts.EmitGcovNotes;
        Options.EmitData = CodeGenOpts.EmitGcovArcs;
        memcpy(Options.Version, CodeGenOpts.CoverageVersion, 4);
        Options.UseCfgChecksum = CodeGenOpts.CoverageExtraChecksum;
        Options.NoRedZone = CodeGenOpts.DisableRedZone;
        Options.FunctionNamesInData =
            !CodeGenOpts.CoverageNoFunctionNamesInData;
        MPM->add(createGCOVProfilerPass(Options));
        if (CodeGenOpts.getDebugInfo() == CodeGenOptions::NoDebugInfo)
            MPM->add(createStripSymbolsPass(true));
    }

    PMBuilder.populateModulePassManager(*MPM);
}
示例#19
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;
}
//===----------------------------------------------------------------------===//
// main for opt
//
int main(int argc, char **argv) {
  sys::PrintStackTraceOnErrorSignal();
  llvm::PrettyStackTraceProgram X(argc, argv);
  
  // Enable debug stream buffering.
  EnableDebugBuffering = true;

  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
  LLVMContext &Context = getGlobalContext();
  
  cl::ParseCommandLineOptions(argc, argv,
    "llvm .bc -> .bc modular optimizer and analysis printer\n");

  // Allocate a full target machine description only if necessary.
  // FIXME: The choice of target should be controllable on the command line.
  std::auto_ptr<TargetMachine> target;

  SMDiagnostic Err;

  // Load the input module...
  std::auto_ptr<Module> M;
  M.reset(ParseIRFile(InputFilename, Err, Context));

  if (M.get() == 0) {
    Err.Print(argv[0], errs());
    return 1;
  }

  // Figure out what stream we are supposed to write to...
  // FIXME: outs() is not binary!
  raw_ostream *Out = &outs();  // Default to printing to stdout...
  if (OutputFilename != "-") {
    if (NoOutput || AnalyzeOnly) {
      errs() << "WARNING: The -o (output filename) option is ignored when\n"
                "the --disable-output or --analyze options are used.\n";
    } else {
      // Make sure that the Output file gets unlinked from the disk if we get a
      // SIGINT
      sys::RemoveFileOnSignal(sys::Path(OutputFilename));

      std::string ErrorInfo;
      Out = new raw_fd_ostream(OutputFilename.c_str(), ErrorInfo,
                               raw_fd_ostream::F_Binary);
      if (!ErrorInfo.empty()) {
        errs() << ErrorInfo << '\n';
        delete Out;
        return 1;
      }
    }
  }

  // If the output is set to be emitted to standard out, and standard out is a
  // console, print out a warning message and refuse to do it.  We don't
  // impress anyone by spewing tons of binary goo to a terminal.
  if (!Force && !NoOutput && !AnalyzeOnly && !OutputAssembly)
    if (CheckBitcodeOutputToConsole(*Out, !Quiet))
      NoOutput = true;

  // Create a PassManager to hold and optimize the collection of passes we are
  // about to build...
  //
  PassManager Passes;

  // Add an appropriate TargetData instance for this module...
  TargetData *TD = 0;
  const std::string &ModuleDataLayout = M.get()->getDataLayout();
  if (!ModuleDataLayout.empty())
    TD = new TargetData(ModuleDataLayout);
  else if (!DefaultDataLayout.empty())
    TD = new TargetData(DefaultDataLayout);

  if (TD)
    Passes.add(TD);

  FunctionPassManager *FPasses = NULL;
  if (OptLevelO1 || OptLevelO2 || OptLevelO3) {
    FPasses = new FunctionPassManager(M.get());
    if (TD)
      FPasses->add(new TargetData(*TD));
  }

  // If the -strip-debug command line option was specified, add it.  If
  // -std-compile-opts was also specified, it will handle StripDebug.
  if (StripDebug && !StandardCompileOpts)
    addPass(Passes, createStripSymbolsPass(true));

  // Create a new optimization pass for each one specified on the command line
  for (unsigned i = 0; i < PassList.size(); ++i) {
    // Check to see if -std-compile-opts was specified before this option.  If
    // so, handle it.
    if (StandardCompileOpts &&
        StandardCompileOpts.getPosition() < PassList.getPosition(i)) {
      AddStandardCompilePasses(Passes);
      StandardCompileOpts = false;
    }

    if (StandardLinkOpts &&
        StandardLinkOpts.getPosition() < PassList.getPosition(i)) {
      AddStandardLinkPasses(Passes);
      StandardLinkOpts = false;
    }

    if (OptLevelO1 && OptLevelO1.getPosition() < PassList.getPosition(i)) {
      AddOptimizationPasses(Passes, *FPasses, 1);
      OptLevelO1 = false;
    }

    if (OptLevelO2 && OptLevelO2.getPosition() < PassList.getPosition(i)) {
      AddOptimizationPasses(Passes, *FPasses, 2);
      OptLevelO2 = false;
    }

    if (OptLevelO3 && OptLevelO3.getPosition() < PassList.getPosition(i)) {
      AddOptimizationPasses(Passes, *FPasses, 3);
      OptLevelO3 = false;
    }

    const PassInfo *PassInf = PassList[i];
    Pass *P = 0;
    if (PassInf->getNormalCtor())
      P = PassInf->getNormalCtor()();
    else
      errs() << argv[0] << ": cannot create pass: "******"\n";
    if (P) {
      PassKind Kind = P->getPassKind();
      addPass(Passes, P);

      if (AnalyzeOnly) {
        switch (Kind) {
        case PT_BasicBlock:
          Passes.add(new BasicBlockPassPrinter(PassInf));
          break;
        case PT_Loop:
          Passes.add(new LoopPassPrinter(PassInf));
          break;
        case PT_Function:
          Passes.add(new FunctionPassPrinter(PassInf));
          break;
        case PT_CallGraphSCC:
          Passes.add(new CallGraphSCCPassPrinter(PassInf));
          break;
        default:
          Passes.add(new ModulePassPrinter(PassInf));
          break;
        }
      }
    }

    if (PrintEachXForm)
      Passes.add(createPrintModulePass(&errs()));
  }

  // If -std-compile-opts was specified at the end of the pass list, add them.
  if (StandardCompileOpts) {
    AddStandardCompilePasses(Passes);
    StandardCompileOpts = false;
  }

  if (StandardLinkOpts) {
    AddStandardLinkPasses(Passes);
    StandardLinkOpts = false;
  }

  if (OptLevelO1)
    AddOptimizationPasses(Passes, *FPasses, 1);

  if (OptLevelO2)
    AddOptimizationPasses(Passes, *FPasses, 2);

  if (OptLevelO3)
    AddOptimizationPasses(Passes, *FPasses, 3);

  if (OptLevelO1 || OptLevelO2 || OptLevelO3) {
    FPasses->doInitialization();
    for (Module::iterator I = M.get()->begin(), E = M.get()->end();
         I != E; ++I)
      FPasses->run(*I);
  }

  // Check that the module is well formed on completion of optimization
  if (!NoVerify && !VerifyEach)
    Passes.add(createVerifierPass());

  // Write bitcode or assembly out to disk or outs() as the last step...
  if (!NoOutput && !AnalyzeOnly) {
    if (OutputAssembly)
      Passes.add(createPrintModulePass(Out));
    else
      Passes.add(createBitcodeWriterPass(*Out));
  }

  // Now that we have all of the passes ready, run them.
  Passes.run(*M.get());

  // Delete the raw_fd_ostream.
  if (Out != &outs())
    delete Out;
  return 0;
}
示例#21
0
void EmitAssemblyHelper::CreatePasses() {
  unsigned OptLevel = CodeGenOpts.OptimizationLevel;
  CodeGenOptions::InliningMethod Inlining = CodeGenOpts.Inlining;

  // Handle disabling of LLVM optimization, where we want to preserve the
  // internal module before any optimization.
  if (CodeGenOpts.DisableLLVMOpts) {
    OptLevel = 0;
    Inlining = CodeGenOpts.NoInlining;
  }
  
  PassManagerBuilder PMBuilder;
  PMBuilder.OptLevel = OptLevel;
  PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize;

  PMBuilder.DisableSimplifyLibCalls = !CodeGenOpts.SimplifyLibCalls;
  PMBuilder.DisableUnitAtATime = !CodeGenOpts.UnitAtATime;
  PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops;

  // In ObjC ARC mode, add the main ARC optimization passes.
  if (LangOpts.ObjCAutoRefCount) {
    PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
                           addObjCARCExpandPass);
    PMBuilder.addExtension(PassManagerBuilder::EP_ModuleOptimizerEarly,
                           addObjCARCAPElimPass);
    PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate,
                           addObjCARCOptPass);
  }

  if (CodeGenOpts.BoundsChecking > 0) {
    BoundsChecking = CodeGenOpts.BoundsChecking;
    PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate,
                           addBoundsCheckingPass);
    PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
                           addBoundsCheckingPass);
  }

  if (LangOpts.AddressSanitizer) {
    PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate,
                           addAddressSanitizerPass);
    PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
                           addAddressSanitizerPass);
  }

  if (LangOpts.ThreadSanitizer) {
    PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
                           addThreadSanitizerPass);
    PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
                           addThreadSanitizerPass);
  }

  // Figure out TargetLibraryInfo.
  Triple TargetTriple(TheModule->getTargetTriple());
  PMBuilder.LibraryInfo = new TargetLibraryInfo(TargetTriple);
  if (!CodeGenOpts.SimplifyLibCalls)
    PMBuilder.LibraryInfo->disableAllFunctions();
  
  switch (Inlining) {
  case CodeGenOptions::NoInlining: break;
  case CodeGenOptions::NormalInlining: {
    // FIXME: Derive these constants in a principled fashion.
    unsigned Threshold = 225;
    if (CodeGenOpts.OptimizeSize == 1)      // -Os
      Threshold = 75;
    else if (CodeGenOpts.OptimizeSize == 2) // -Oz
      Threshold = 25;
    else if (OptLevel > 2)
      Threshold = 275;
    PMBuilder.Inliner = createFunctionInliningPass(Threshold);
    break;
  }
  case CodeGenOptions::OnlyAlwaysInlining:
    // Respect always_inline.
    if (OptLevel == 0)
      // Do not insert lifetime intrinsics at -O0.
      PMBuilder.Inliner = createAlwaysInlinerPass(false);
    else
      PMBuilder.Inliner = createAlwaysInlinerPass();
    break;
  }

 
  // Set up the per-function pass manager.
  FunctionPassManager *FPM = getPerFunctionPasses();
  if (CodeGenOpts.VerifyModule)
    FPM->add(createVerifierPass());
  PMBuilder.populateFunctionPassManager(*FPM);

  // Set up the per-module pass manager.
  PassManager *MPM = getPerModulePasses();

  if (CodeGenOpts.EmitGcovArcs || CodeGenOpts.EmitGcovNotes) {
    MPM->add(createGCOVProfilerPass(CodeGenOpts.EmitGcovNotes,
                                    CodeGenOpts.EmitGcovArcs,
                                    TargetTriple.isMacOSX()));

    if (CodeGenOpts.DebugInfo == CodeGenOptions::NoDebugInfo)
      MPM->add(createStripSymbolsPass(true));
  }

  // Add the memory safety passes for control-flow integrity
  if (CodeGenOpts.MemSafety) {
    // Make sure everything that can be in an LLVM register is.
    MPM->add (createPromoteMemoryToRegisterPass());
    MPM->add (createUnifyFunctionExitNodesPass());
    MPM->add (new CFIChecks());
  }
  
  PMBuilder.populateModulePassManager(*MPM);

  if (CodeGenOpts.SoftBound) {
    // Make sure SoftBound+CETS is run after optimization with atleast mem2reg run 
    MPM->add(new DominatorTree());
    MPM->add(new DominanceFrontier());
    MPM->add(new LoopInfo());
    MPM->add(new InitializeSoftBound());
    MPM->add(new SoftBoundCETSPass());
  }

  // Add the memory safety passes
  if (CodeGenOpts.MemSafety) {
    MPM->add (createCommonMSCInfoPass());
    MPM->add (createSAFECodeMSCInfoPass());

    // C standard library / format string function transforms
    if (!CodeGenOpts.BaggyBounds) {
      MPM->add (new StringTransform());
      MPM->add (new FormatStringTransform());
      MPM->add (new RegisterVarargCallSites());
      MPM->add (new LoggingFunctions());
    }

    MPM->add (new InitAllocas());
    MPM->add (createRegisterGlobalsPass(/*RegUncertain=*/true,
                                        /*MakeInternal=*/false));
    MPM->add (createRemoveUnsuitableGlobalRegistrationsPass());
    MPM->add (new RegisterMainArgs());
    MPM->add (createInstrumentFreeCallsPass());
    MPM->add (new RegisterCustomizedAllocation());
    MPM->add (new LoopInfo ());
    MPM->add (new DominatorTree ());
    MPM->add (createRegisterStackPoolsPass(/*RegByval=*/true));
    MPM->add (createUnregisterStackPoolsPass());
    MPM->add (createSpecializeCMSCallsPass());
    MPM->add (new RegisterRuntimeInitializer(CodeGenOpts.MemSafetyLogFile.c_str()));
    MPM->add (new DebugInstrument());

    MPM->add (createInstrumentMemoryAccessesPass());
    MPM->add (createInstrumentGEPsPass());
    MPM->add (createSpecializeCMSCallsPass());

    MPM->add (new ScalarEvolution());
    MPM->add (new ArrayBoundsCheckLocal());
    MPM->add (createOptimizeGEPChecksPass());

    MPM->add (createExactCheckOptPass());

    MPM->add (new ScalarEvolution());
    MPM->add (createLocalArrayBoundsAnalysisPass());
    MPM->add (createOptimizeFastMemoryChecksPass());
    MPM->add (createOptimizeIdenticalLSChecksPass());
    MPM->add (new DominatorTree());
    MPM->add (new ScalarEvolution());
    MPM->add (createOptimizeImpliedFastLSChecksPass());

    MPM->add (new OptimizeChecks());
    MPM->add (createOptimizeMemoryRegistrationsPass(/*AllowFastChecks=*/true));
    if (CodeGenOpts.MemSafeTerminate) {
      MPM->add (llvm::createSCTerminatePass ());
    }
  }

  if (CodeGenOpts.BaggyBounds) {
    MPM->add (new InsertBaggyBoundsChecks());
  }

  //
  // Rerun the LLVM optimizations again.
  //
  PMBuilder.populateModulePassManager(*MPM);

  // For SAFECode, do the debug instrumentation and OOB rewriting after
  // all optimization is done.
  if (CodeGenOpts.MemSafety) {
    MPM->add (new DebugInstrument());
    MPM->add (new RewriteOOB());
  }
}