Ejemplo n.º 1
0
/// 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
}
Ejemplo n.º 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;
  }
Ejemplo n.º 4
0
ExecutionEngine *MCJITHelper::compileModule(Module *M) {
  if (M == OpenModule)
    closeCurrentModule();

  std::string ErrStr;
  ExecutionEngine *NewEngine = EngineBuilder(M)
                                            .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(M);

  // 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 = M->end();
  for (it = M->begin(); it != end; ++it) {
    // Run the FPM on this function
    FPM->run(*it);
  }

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

  // Store this engine
  EngineMap[M] = NewEngine;
  NewEngine->finalizeObject();

  return NewEngine;
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
0
//===----------------------------------------------------------------------===//
// 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;
}
Ejemplo n.º 8
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
}
Ejemplo n.º 9
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
}
Ejemplo n.º 10
0
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;
}
Ejemplo n.º 11
0
/// 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;
}
static int compileInternal(const char *input, int optimize, int optsize,
                           const char *argv0,
                           raw_fd_ostream *fd, CompilerInstance &Clang)
{
  std::string ErrMsg;
  LLVMContext &Context = getGlobalContext();
  std::auto_ptr<Module> M;

  MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(input, &ErrMsg);
  if (!Buffer) {
    errs() << "Could not open temp input file '" << input << "'\n";
    return 2;
  }
  M.reset(ParseBitcodeFile(Buffer, Context, &ErrMsg));
  delete Buffer;
  if (M.get() == 0) {
    errs() << "Cannot parse temp input file '" << input << "'" << ErrMsg << "\n";
    return 2;
  }

  // FIXME: Remove TargetData!
  //XXX  M->setTargetTriple("");
  //XXX  M->setDataLayout("");

  // TODO: let clang handle these
  PassManager Passes;
  FunctionPassManager *FPasses = NULL;
  if (optimize) {
    FPasses = new FunctionPassManager(M.get());
//    FPasses->add(new TargetData(M.get()));//XXX
    createStandardFunctionPasses(FPasses, optimize);
  }
//  Passes.add(new TargetData(M.get()));//XXX
  unsigned threshold = optsize ? 75 : optimize > 2 ? 275 : 225;
  createStandardModulePasses(&Passes, optimize,
                             optsize,
                             true,
                             optimize > 1 && !optsize,
                             false,
                             false,
                             optimize > 1 ?
                             createFunctionInliningPass(threshold) :
                             createAlwaysInlinerPass());
  if (optimize) {
    FPasses->doInitialization();
    for (Module::iterator I = M.get()->begin(), E = M.get()->end();
         I != E; ++I)
      FPasses->run(*I);
    Passes.add(createVerifierPass());
    Passes.run(*M.get());
  }

  std::string Err2;
  //TODO: directly construct our target
  const Target *TheTarget =
    TargetRegistry::lookupTarget("clambc-generic-generic", Err2);
  if (TheTarget == 0) {
    errs() << argv0 << ": error auto-selecting target for module '"
      << Err2 << "'.  Please use the -march option to explicitly "
      << "pick a target.\n";
    return 1;
  }
  std::auto_ptr<TargetMachine> 
    Target(TheTarget->createTargetMachine("clambc-generic-generic", ""));
  //TODO: send it to the -o specified on cmdline
  // Figure out where we are going to send the output...
  formatted_raw_ostream *Out2 =
    new formatted_raw_ostream(*fd, formatted_raw_ostream::DELETE_STREAM);
  if (Out2 == 0) return 2;

  CodeGenOpt::Level OLvl = CodeGenOpt::Default;
  switch (optimize) {
  case 0: OLvl = CodeGenOpt::None; break;
  case 3: OLvl = CodeGenOpt::Aggressive; break;
  default: break;
  }

  PassManager PM;
  PM.add(new TargetData(M.get()));//XXX
  if (Target->addPassesToEmitWholeFile(PM, *Out2, TargetMachine::CGFT_AssemblyFile, OLvl)) {
      errs() << argv0<< ": target does not support generation of this"
             << " file type!\n";
      if (Out2 != &fouts()) delete Out2;
      // And the Out file is empty and useless, so remove it now.
//      sys::Path(OutputFilename).eraseFromDisk();
      return 2;
  }
  PM.run(*M.get());
  delete Out2;
  return 0;
}
Ejemplo n.º 13
0
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;
}
Ejemplo n.º 14
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;
}
Ejemplo n.º 15
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
}
Ejemplo n.º 16
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->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
}