Esempio n. 1
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
}
Esempio n. 2
0
File: llc.cpp Progetto: bholt/llvm
static int compileModule(char **argv, LLVMContext &Context) {
  // Load the module to be compiled...
  SMDiagnostic Err;
  OwningPtr<Module> M;
  Module *mod = 0;
  Triple TheTriple;

  bool SkipModule = MCPU == "help" ||
                    (!MAttrs.empty() && MAttrs.front() == "help");

  // If user just wants to list available options, skip module loading
  if (!SkipModule) {
    M.reset(ParseIRFile(InputFilename, Err, Context));
    mod = M.get();
    if (mod == 0) {
      Err.print(argv[0], errs());
      return 1;
    }

    // If we are supposed to override the target triple, do so now.
    if (!TargetTriple.empty())
      mod->setTargetTriple(Triple::normalize(TargetTriple));
    TheTriple = Triple(mod->getTargetTriple());
  } else {
    TheTriple = Triple(Triple::normalize(TargetTriple));
  }

  if (TheTriple.getTriple().empty())
    TheTriple.setTriple(sys::getDefaultTargetTriple());

  // Get the target specific parser.
  std::string Error;
  const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple,
                                                         Error);
  if (!TheTarget) {
    errs() << argv[0] << ": " << Error;
    return 1;
  }

  // Package up features to be passed to target/subtarget
  std::string FeaturesStr;
  if (MAttrs.size()) {
    SubtargetFeatures Features;
    for (unsigned i = 0; i != MAttrs.size(); ++i)
      Features.AddFeature(MAttrs[i]);
    FeaturesStr = Features.getString();
  }

  CodeGenOpt::Level OLvl = CodeGenOpt::Default;
  switch (OptLevel) {
  default:
    errs() << argv[0] << ": invalid optimization level.\n";
    return 1;
  case ' ': break;
  case '0': OLvl = CodeGenOpt::None; break;
  case '1': OLvl = CodeGenOpt::Less; break;
  case '2': OLvl = CodeGenOpt::Default; break;
  case '3': OLvl = CodeGenOpt::Aggressive; break;
  }

  TargetOptions Options;
  Options.LessPreciseFPMADOption = EnableFPMAD;
  Options.NoFramePointerElim = DisableFPElim;
  Options.AllowFPOpFusion = FuseFPOps;
  Options.UnsafeFPMath = EnableUnsafeFPMath;
  Options.NoInfsFPMath = EnableNoInfsFPMath;
  Options.NoNaNsFPMath = EnableNoNaNsFPMath;
  Options.HonorSignDependentRoundingFPMathOption =
      EnableHonorSignDependentRoundingFPMath;
  Options.UseSoftFloat = GenerateSoftFloatCalls;
  if (FloatABIForCalls != FloatABI::Default)
    Options.FloatABIType = FloatABIForCalls;
  Options.NoZerosInBSS = DontPlaceZerosInBSS;
  Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt;
  Options.DisableTailCalls = DisableTailCalls;
  Options.StackAlignmentOverride = OverrideStackAlignment;
  Options.TrapFuncName = TrapFuncName;
  Options.PositionIndependentExecutable = EnablePIE;
  Options.EnableSegmentedStacks = SegmentedStacks;
  Options.UseInitArray = UseInitArray;

  OwningPtr<TargetMachine>
    target(TheTarget->createTargetMachine(TheTriple.getTriple(),
                                          MCPU, FeaturesStr, Options,
                                          RelocModel, CMModel, OLvl));
  assert(target.get() && "Could not allocate target machine!");
  assert(mod && "Should have exited after outputting help!");
  TargetMachine &Target = *target.get();

  if (DisableDotLoc)
    Target.setMCUseLoc(false);

  if (DisableCFI)
    Target.setMCUseCFI(false);

  if (EnableDwarfDirectory)
    Target.setMCUseDwarfDirectory(true);

  if (GenerateSoftFloatCalls)
    FloatABIForCalls = FloatABI::Soft;

  // Disable .loc support for older OS X versions.
  if (TheTriple.isMacOSX() &&
      TheTriple.isMacOSXVersionLT(10, 6))
    Target.setMCUseLoc(false);

  // Figure out where we are going to send the output.
  OwningPtr<tool_output_file> Out
    (GetOutputStream(TheTarget->getName(), TheTriple.getOS(), argv[0]));
  if (!Out) return 1;

  // Build up all of the passes that we want to do to the module.
  PassManager PM;

  // Add an appropriate TargetLibraryInfo pass for the module's triple.
  TargetLibraryInfo *TLI = new TargetLibraryInfo(TheTriple);
  if (DisableSimplifyLibCalls)
    TLI->disableAllFunctions();
  PM.add(TLI);

  // Add the target data from the target machine, if it exists, or the module.
  if (const DataLayout *TD = Target.getDataLayout())
    PM.add(new DataLayout(*TD));
  else
    PM.add(new DataLayout(mod));

  // Override default to generate verbose assembly.
  Target.setAsmVerbosityDefault(true);

  if (RelaxAll) {
    if (FileType != TargetMachine::CGFT_ObjectFile)
      errs() << argv[0]
             << ": warning: ignoring -mc-relax-all because filetype != obj";
    else
      Target.setMCRelaxAll(true);
  }

  {
    formatted_raw_ostream FOS(Out->os());

    AnalysisID StartAfterID = 0;
    AnalysisID StopAfterID = 0;
    const PassRegistry *PR = PassRegistry::getPassRegistry();
    if (!StartAfter.empty()) {
      const PassInfo *PI = PR->getPassInfo(StartAfter);
      if (!PI) {
        errs() << argv[0] << ": start-after pass is not registered.\n";
        return 1;
      }
      StartAfterID = PI->getTypeInfo();
    }
    if (!StopAfter.empty()) {
      const PassInfo *PI = PR->getPassInfo(StopAfter);
      if (!PI) {
        errs() << argv[0] << ": stop-after pass is not registered.\n";
        return 1;
      }
      StopAfterID = PI->getTypeInfo();
    }

    // Ask the target to add backend passes as necessary.
    if (Target.addPassesToEmitFile(PM, FOS, FileType, NoVerify,
                                   StartAfterID, StopAfterID)) {
      errs() << argv[0] << ": target does not support generation of this"
             << " file type!\n";
      return 1;
    }

    // Before executing passes, print the final values of the LLVM options.
    cl::PrintOptionValues();

    PM.run(*mod);
  }

  // Declare success.
  Out->keep();

  return 0;
}
Esempio n. 3
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();

  // Initialize passes
  PassRegistry &Registry = *PassRegistry::getPassRegistry();
  initializeCore(Registry);
  initializeScalarOpts(Registry);
  initializeIPO(Registry);
  initializeAnalysis(Registry);
  initializeIPA(Registry);
  initializeTransformUtils(Registry);
  initializeInstCombine(Registry);
  initializeInstrumentation(Registry);
  initializeTarget(Registry);

  cl::ParseCommandLineOptions(argc, argv,
    "llvm .bc -> .bc modular optimizer and analysis printer\n");

  if (AnalyzeOnly && NoOutput) {
    errs() << argv[0] << ": analyze mode conflicts with no-output mode.\n";
    return 1;
  }

  // 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...
  OwningPtr<tool_output_file> Out;
  if (NoOutput) {
    if (!OutputFilename.empty())
      errs() << "WARNING: The -o (output filename) option is ignored when\n"
                "the --disable-output option is used.\n";
  } else {
    // Default to standard output.
    if (OutputFilename.empty())
      OutputFilename = "-";

    std::string ErrorInfo;
    Out.reset(new tool_output_file(OutputFilename.c_str(), ErrorInfo,
                                   raw_fd_ostream::F_Binary));
    if (!ErrorInfo.empty()) {
      errs() << ErrorInfo << '\n';
      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->os(), !Quiet))
      NoOutput = true;

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

  // Add an appropriate TargetLibraryInfo pass for the module's triple.
  TargetLibraryInfo *TLI = new TargetLibraryInfo(Triple(M->getTargetTriple()));

  // The -disable-simplify-libcalls flag actually disables all builtin optzns.
  if (DisableSimplifyLibCalls)
    TLI->disableAllFunctions();
  Passes.add(TLI);

  // 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);

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

  if (PrintBreakpoints) {
    // Default to standard output.
    if (!Out) {
      if (OutputFilename.empty())
        OutputFilename = "-";

      std::string ErrorInfo;
      Out.reset(new tool_output_file(OutputFilename.c_str(), ErrorInfo,
                                     raw_fd_ostream::F_Binary));
      if (!ErrorInfo.empty()) {
        errs() << ErrorInfo << '\n';
        return 1;
      }
    }
    Passes.add(new BreakpointPrinter(Out->os()));
    NoOutput = true;
  }

  // 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, Out->os()));
          break;
        case PT_Region:
          Passes.add(new RegionPassPrinter(PassInf, Out->os()));
          break;
        case PT_Loop:
          Passes.add(new LoopPassPrinter(PassInf, Out->os()));
          break;
        case PT_Function:
          Passes.add(new FunctionPassPrinter(PassInf, Out->os()));
          break;
        case PT_CallGraphSCC:
          Passes.add(new CallGraphSCCPassPrinter(PassInf, Out->os()));
          break;
        default:
          Passes.add(new ModulePassPrinter(PassInf, Out->os()));
          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 F = M->begin(), E = M->end(); F != E; ++F)
      FPasses->run(*F);
    FPasses->doFinalization();
  }

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

  // Write bitcode or assembly to the output as the last step...
  if (!NoOutput && !AnalyzeOnly) {
    if (OutputAssembly)
      Passes.add(createPrintModulePass(&Out->os()));
    else
      Passes.add(createBitcodeWriterPass(Out->os()));
  }

  // Before executing passes, print the final values of the LLVM options.
  cl::PrintOptionValues();

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

  // Declare success.
  if (!NoOutput || PrintBreakpoints)
    Out->keep();

  return 0;
}
Esempio n. 4
0
int main(int argc, char **argv) {
  // Print a stack trace if we signal out.
  sys::PrintStackTraceOnErrorSignal();
  PrettyStackTraceProgram X(argc, argv);

  LLVMContext &Context = getGlobalContext();
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
  
  cl::ParseCommandLineOptions(argc, argv, "llvm profile dump decoder\n");

  // Read in the bitcode file...
  std::string ErrorMessage;
  error_code ec;
  Module *M = 0;
  if(DiffMode) {
     ProfileInfoLoader PIL1(argv[0], BitcodeFile);
     ProfileInfoLoader PIL2(argv[0], ProfileDataFile);
     
     ProfileInfoCompare Compare(PIL1,PIL2);
     Compare.run();
     return 0;
  }
  if(Merge != MERGE_NONE) {
     /** argument alignment: 
      *  BitcodeFile ProfileDataFile MergeFile 
      *  output.out  input1.out      other-input.out 
      **/

     // Add the ProfileDataFile arg to MergeFile, it blongs to the MergeFile
     MergeFile.push_back(std::string(ProfileDataFile.getValue()));
     if(MergeFile.size()==0){
        errs()<<"No merge file!";
        return 0;
     }

     //Initialize the ProfileInfoMerge class using one of merge files
     ProfileInfoLoader AHS(argv[0], MergeFile.back());
     ProfileInfoMerge MergeClass(std::string(argv[0]), BitcodeFile, AHS);

     for (std::vector<std::string>::iterator merIt = MergeFile.begin(),
                                             END = MergeFile.end() - 1;
          merIt != END; ++merIt) {
        //errs()<<*merIt<<"\n";
       ProfileInfoLoader THS(argv[0], *merIt);
       MergeClass.addProfileInfo(THS);
     }
     if (Merge == MERGE_SUM) {
       MergeClass.writeTotalFile();
     } else if (Merge == MERGE_AVG) {
       /** avg = sum/N **/
       MergeClass.writeTotalFile(
           std::bind2nd(std::divides<unsigned>(), MergeFile.size()));
     }
     return 0;
  }
#if LLVM_VERSION_MAJOR==3 && LLVM_VERSION_MINOR==4
  OwningPtr<MemoryBuffer> Buffer;
  if (!(ec = MemoryBuffer::getFileOrSTDIN(BitcodeFile, Buffer.get()))) {
     M = ParseBitcodeFile(Buffer.get(), Context, &ErrorMessage);
  } else
     ErrorMessage = ec.message();

#else

  auto Buffer = MemoryBuffer::getFileOrSTDIN(BitcodeFile);
  if (!(ec = Buffer.getError())){
     auto R = parseBitcodeFile(&**Buffer, Context);
     if(R.getError()){
        M = NULL;
        ErrorMessage = R.getError().message();
     }else
        M = R.get();
  } else
     ErrorMessage = ec.message();
#endif
  if (M == 0) {
     errs() << argv[0] << ": " << BitcodeFile << ": "
        << ErrorMessage << "\n";
     return 1;
  }

  // Run the printer pass.
  PassManager PassMgr;
  PassMgr.add(createProfileLoaderPass(ProfileDataFile));

  if(CommMode) {
     PassMgr.add(new ProfileInfoComm());
     PassMgr.run(*M);
     return 0;
  }
  if(Convert){
     Require3rdArg("no output file");
     ProfileInfoWriter PIW(argv[0], MergeFile.front());
     PassMgr.add(new ProfileInfoConverter(PIW));
  }else if(Timing.size() != 0){
     Require3rdArg("no timing source file");
     PassMgr.add(new ProfileTimingPrint(std::move(Timing.getValue()), MergeFile));
  }else{
     // Read the profiling information. This is redundant since we load it again
     // using the standard profile info provider pass, but for now this gives us
     // access to additional information not exposed via the ProfileInfo
     // interface.
     ProfileInfoLoader PIL(argv[0], ProfileDataFile);
     PassMgr.add(new ProfileInfoPrinterPass(PIL));
  }
  PassMgr.run(*M);

  return 0;
}
Esempio n. 5
0
void LTOCodeGenerator::applyScopeRestrictions() {
  if (_scopeRestrictionsDone) return;
  Module *mergedModule = _linker.getModule();

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

  // mark which symbols can not be internalized
  MCContext Context(*_target->getMCAsmInfo(), *_target->getRegisterInfo(),NULL);
  Mangler mangler(Context, *_target->getDataLayout());
  std::vector<const char*> mustPreserveList;
  SmallPtrSet<GlobalValue*, 8> asmUsed;

  for (Module::iterator f = mergedModule->begin(),
         e = mergedModule->end(); f != e; ++f)
    applyRestriction(*f, mustPreserveList, asmUsed, mangler);
  for (Module::global_iterator v = mergedModule->global_begin(),
         e = mergedModule->global_end(); v !=  e; ++v)
    applyRestriction(*v, mustPreserveList, asmUsed, mangler);
  for (Module::alias_iterator a = mergedModule->alias_begin(),
         e = mergedModule->alias_end(); a != e; ++a)
    applyRestriction(*a, mustPreserveList, asmUsed, mangler);

  GlobalVariable *LLVMCompilerUsed =
    mergedModule->getGlobalVariable("llvm.compiler.used");
  findUsedValues(LLVMCompilerUsed, asmUsed);
  if (LLVMCompilerUsed)
    LLVMCompilerUsed->eraseFromParent();

  if (!asmUsed.empty()) {
    llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(_context);
    std::vector<Constant*> asmUsed2;
    for (SmallPtrSet<GlobalValue*, 16>::const_iterator i = asmUsed.begin(),
           e = asmUsed.end(); i !=e; ++i) {
      GlobalValue *GV = *i;
      Constant *c = ConstantExpr::getBitCast(GV, i8PTy);
      asmUsed2.push_back(c);
    }

    llvm::ArrayType *ATy = llvm::ArrayType::get(i8PTy, asmUsed2.size());
    LLVMCompilerUsed =
      new llvm::GlobalVariable(*mergedModule, ATy, false,
                               llvm::GlobalValue::AppendingLinkage,
                               llvm::ConstantArray::get(ATy, asmUsed2),
                               "llvm.compiler.used");

    LLVMCompilerUsed->setSection("llvm.metadata");
  }

  // Add prerequisite passes needed by SAFECode
  PassManagerBuilder().populateLTOPassManager(passes, /*Internalize=*/ false,
                                              !DisableInline);

  passes.add(createInternalizePass(mustPreserveList));

  // apply scope restrictions
  passes.run(*mergedModule);

  _scopeRestrictionsDone = true;
}
Esempio n. 6
0
/// Optimize merged modules using various IPO passes
bool LTOCodeGenerator::generateObjectFile(raw_ostream &out,
        bool DisableOpt,
        bool DisableInline,
        bool DisableGVNLoadPRE,
        std::string &errMsg) {
    if (!this->determineTarget(errMsg))
        return false;

    Module *mergedModule = IRLinker.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());
    passes.add(createDebugInfoVerifierPass());

    // Add an appropriate DataLayout instance for this module...
    mergedModule->setDataLayout(TargetMach->getDataLayout());
    passes.add(new DataLayoutPass(mergedModule));

    // Add appropriate TargetLibraryInfo for this module.
    passes.add(new TargetLibraryInfo(Triple(TargetMach->getTargetTriple())));

    TargetMach->addAnalysisPasses(passes);

    // 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.
    if (!DisableOpt)
        PassManagerBuilder().populateLTOPassManager(passes,
                /*Internalize=*/false,
                !DisableInline,
                DisableGVNLoadPRE);

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

    PassManager codeGenPasses;

    codeGenPasses.add(new DataLayoutPass(mergedModule));

    formatted_raw_ostream Out(out);

    // If the bitcode files contain ARC code and were compiled with optimization,
    // the ObjCARCContractPass must be run, so do it unconditionally here.
    codeGenPasses.add(createObjCARCContractPass());

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

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

    // Run the code generator, and write assembly file
    codeGenPasses.run(*mergedModule);

    return true;
}
Esempio n. 7
0
// main - Entry point for the llc compiler.
//
int main(int argc, char **argv) {
  sys::PrintStackTraceOnErrorSignal();
  PrettyStackTraceProgram X(argc, argv);

  // Enable debug stream buffering.
  EnableDebugBuffering = true;

  LLVMContext &Context = getGlobalContext();
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.

  // Initialize targets first, so that --version shows registered targets.
  InitializeAllTargets();
  InitializeAllTargetMCs();
  InitializeAllAsmPrinters();
  InitializeAllAsmParsers();

  // Register the target printer for --version.
  cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);

  cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n");

  // Load the module to be compiled...
  SMDiagnostic Err;
  std::auto_ptr<Module> M;

  M.reset(ParseIRFile(InputFilename, Err, Context));
  if (M.get() == 0) {
    Err.print(argv[0], errs());
    return 1;
  }
  Module &mod = *M.get();

  // If we are supposed to override the target triple, do so now.
  if (!TargetTriple.empty())
    mod.setTargetTriple(Triple::normalize(TargetTriple));

  Triple TheTriple(mod.getTargetTriple());
  if (TheTriple.getTriple().empty())
    TheTriple.setTriple(sys::getDefaultTargetTriple());

  // Allocate target machine.  First, check whether the user has explicitly
  // specified an architecture to compile for. If so we have to look it up by
  // name, because it might be a backend that has no mapping to a target triple.
  const Target *TheTarget = 0;
  if (!MArch.empty()) {
    for (TargetRegistry::iterator it = TargetRegistry::begin(),
           ie = TargetRegistry::end(); it != ie; ++it) {
      if (MArch == it->getName()) {
        TheTarget = &*it;
        break;
      }
    }

    if (!TheTarget) {
      errs() << argv[0] << ": error: invalid target '" << MArch << "'.\n";
      return 1;
    }

    // Adjust the triple to match (if known), otherwise stick with the
    // module/host triple.
    Triple::ArchType Type = Triple::getArchTypeForLLVMName(MArch);
    if (Type != Triple::UnknownArch)
      TheTriple.setArch(Type);
  } else {
    std::string Err;
    TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), Err);
    if (TheTarget == 0) {
      errs() << argv[0] << ": error auto-selecting target for module '"
             << Err << "'.  Please use the -march option to explicitly "
             << "pick a target.\n";
      return 1;
    }
  }

  // Package up features to be passed to target/subtarget
  std::string FeaturesStr;
  if (MAttrs.size()) {
    SubtargetFeatures Features;
    for (unsigned i = 0; i != MAttrs.size(); ++i)
      Features.AddFeature(MAttrs[i]);
    FeaturesStr = Features.getString();
  }

  std::auto_ptr<TargetMachine>
    target(TheTarget->createTargetMachine(TheTriple.getTriple(),
                                          MCPU, FeaturesStr,
                                          RelocModel, CMModel));
  assert(target.get() && "Could not allocate target machine!");
  TargetMachine &Target = *target.get();

  if (DisableDotLoc)
    Target.setMCUseLoc(false);

  if (DisableCFI)
    Target.setMCUseCFI(false);

  if (EnableDwarfDirectory)
    Target.setMCUseDwarfDirectory(true);

  // Disable .loc support for older OS X versions.
  if (TheTriple.isMacOSX() &&
      TheTriple.isMacOSXVersionLT(10, 6))
    Target.setMCUseLoc(false);

  // Figure out where we are going to send the output...
  OwningPtr<tool_output_file> Out
    (GetOutputStream(TheTarget->getName(), TheTriple.getOS(), argv[0]));
  if (!Out) return 1;

  CodeGenOpt::Level OLvl = CodeGenOpt::Default;
  switch (OptLevel) {
  default:
    errs() << argv[0] << ": invalid optimization level.\n";
    return 1;
  case ' ': break;
  case '0': OLvl = CodeGenOpt::None; break;
  case '1': OLvl = CodeGenOpt::Less; break;
  case '2': OLvl = CodeGenOpt::Default; break;
  case '3': OLvl = CodeGenOpt::Aggressive; break;
  }

  // Build up all of the passes that we want to do to the module.
  PassManager PM;

  // Add the target data from the target machine, if it exists, or the module.
  if (const TargetData *TD = Target.getTargetData())
    PM.add(new TargetData(*TD));
  else
    PM.add(new TargetData(&mod));

  // Override default to generate verbose assembly.
  Target.setAsmVerbosityDefault(true);

  if (RelaxAll) {
    if (FileType != TargetMachine::CGFT_ObjectFile)
      errs() << argv[0]
             << ": warning: ignoring -mc-relax-all because filetype != obj";
    else
      Target.setMCRelaxAll(true);
  }

  {
    formatted_raw_ostream FOS(Out->os());

    // Ask the target to add backend passes as necessary.
    if (Target.addPassesToEmitFile(PM, FOS, FileType, OLvl, NoVerify)) {
      errs() << argv[0] << ": target does not support generation of this"
             << " file type!\n";
      return 1;
    }

    // Before executing passes, print the final values of the LLVM options.
    cl::PrintOptionValues();

    PM.run(mod);
  }

  // Declare success.
  Out->keep();

  return 0;
}
Esempio n. 8
0
static int compileModule(char **argv, LLVMContext &Context) {
  // Load the module to be compiled...
  SMDiagnostic Err;
  std::unique_ptr<Module> M;
  Triple TheTriple;

  bool SkipModule = MCPU == "help" ||
                    (!MAttrs.empty() && MAttrs.front() == "help");

  // If user asked for the 'native' CPU, autodetect here. If autodection fails,
  // this will set the CPU to an empty string which tells the target to
  // pick a basic default.
  if (MCPU == "native")
    MCPU = sys::getHostCPUName();

  // If user just wants to list available options, skip module loading
  if (!SkipModule) {
    M = parseIRFile(InputFilename, Err, Context);
    if (!M) {
      Err.print(argv[0], errs());
      return 1;
    }

    // If we are supposed to override the target triple, do so now.
    if (!TargetTriple.empty())
      M->setTargetTriple(Triple::normalize(TargetTriple));
    TheTriple = Triple(M->getTargetTriple());
  } else {
    TheTriple = Triple(Triple::normalize(TargetTriple));
  }

  if (TheTriple.getTriple().empty())
    TheTriple.setTriple(sys::getDefaultTargetTriple());

  // Get the target specific parser.
  std::string Error;
  const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple,
                                                         Error);
  if (!TheTarget) {
    errs() << argv[0] << ": " << Error;
    return 1;
  }

  // Package up features to be passed to target/subtarget
  std::string FeaturesStr;
  if (MAttrs.size()) {
    SubtargetFeatures Features;
    for (unsigned i = 0; i != MAttrs.size(); ++i)
      Features.AddFeature(MAttrs[i]);
    FeaturesStr = Features.getString();
  }

  CodeGenOpt::Level OLvl = CodeGenOpt::Default;
  switch (OptLevel) {
  default:
    errs() << argv[0] << ": invalid optimization level.\n";
    return 1;
  case ' ': break;
  case '0': OLvl = CodeGenOpt::None; break;
  case '1': OLvl = CodeGenOpt::Less; break;
  case '2': OLvl = CodeGenOpt::Default; break;
  case '3': OLvl = CodeGenOpt::Aggressive; break;
  }

  TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
  Options.DisableIntegratedAS = NoIntegratedAssembler;
  Options.MCOptions.ShowMCEncoding = ShowMCEncoding;
  Options.MCOptions.MCUseDwarfDirectory = EnableDwarfDirectory;
  Options.MCOptions.AsmVerbose = AsmVerbose;

  std::unique_ptr<TargetMachine> Target(
      TheTarget->createTargetMachine(TheTriple.getTriple(), MCPU, FeaturesStr,
                                     Options, RelocModel, CMModel, OLvl));
  assert(Target && "Could not allocate target machine!");

  // If we don't have a module then just exit now. We do this down
  // here since the CPU/Feature help is underneath the target machine
  // creation.
  if (SkipModule)
    return 0;

  assert(M && "Should have exited if we didn't have a module!");

  if (GenerateSoftFloatCalls)
    FloatABIForCalls = FloatABI::Soft;

  // Figure out where we are going to send the output.
  std::unique_ptr<tool_output_file> Out =
      GetOutputStream(TheTarget->getName(), TheTriple.getOS(), argv[0]);
  if (!Out) return 1;

  // Build up all of the passes that we want to do to the module.
  PassManager PM;

  // Add an appropriate TargetLibraryInfo pass for the module's triple.
  TargetLibraryInfo *TLI = new TargetLibraryInfo(TheTriple);
  if (DisableSimplifyLibCalls)
    TLI->disableAllFunctions();
  PM.add(TLI);

  // Add the target data from the target machine, if it exists, or the module.
  if (const DataLayout *DL = Target->getSubtargetImpl()->getDataLayout())
    M->setDataLayout(DL);
  PM.add(new DataLayoutPass());

  if (RelaxAll.getNumOccurrences() > 0 &&
      FileType != TargetMachine::CGFT_ObjectFile)
    errs() << argv[0]
             << ": warning: ignoring -mc-relax-all because filetype != obj";

  {
    formatted_raw_ostream FOS(Out->os());

    AnalysisID StartAfterID = nullptr;
    AnalysisID StopAfterID = nullptr;
    const PassRegistry *PR = PassRegistry::getPassRegistry();
    if (!StartAfter.empty()) {
      const PassInfo *PI = PR->getPassInfo(StartAfter);
      if (!PI) {
        errs() << argv[0] << ": start-after pass is not registered.\n";
        return 1;
      }
      StartAfterID = PI->getTypeInfo();
    }
    if (!StopAfter.empty()) {
      const PassInfo *PI = PR->getPassInfo(StopAfter);
      if (!PI) {
        errs() << argv[0] << ": stop-after pass is not registered.\n";
        return 1;
      }
      StopAfterID = PI->getTypeInfo();
    }

    // Ask the target to add backend passes as necessary.
    if (Target->addPassesToEmitFile(PM, FOS, FileType, NoVerify,
                                    StartAfterID, StopAfterID)) {
      errs() << argv[0] << ": target does not support generation of this"
             << " file type!\n";
      return 1;
    }

    // Before executing passes, print the final values of the LLVM options.
    cl::PrintOptionValues();

    PM.run(*M);
  }

  // Declare success.
  Out->keep();

  return 0;
}
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;
}
Esempio n. 10
0
void* MCJITHelper::dynamicInlinerForOpenOSR(Function* F1, Instruction* OSRSrc, void* extra, void* profDataAddr) {
    DynamicInlinerInfo* inlineInfo = (DynamicInlinerInfo*) extra;
    MCJITHelper* TheHelper = inlineInfo->TheHelper;
    bool verbose = TheHelper->verbose;

    assert(OSRSrc->getParent()->getParent() == F1 && "MCJIT messed up the objects");

    if (verbose) {
        std::cerr << "Value for F1 is " << F1 << std::endl;
        std::cerr << "Value for OSRSrc is " << OSRSrc << std::endl;
        std::cerr << "Value for extra is " << extra << std::endl;
        std::cerr << "Value for profDataAddr is " << profDataAddr << std::endl;
    }

    std::pair<Function*, StateMap*> identityPair = StateMap::generateIdentityMapping(F1);

    Function* F2 = identityPair.first;
    StateMap* M = identityPair.second;

    Value* valToInlineInF2 = M->getCorrespondingOneToOneValue(inlineInfo->valToInline);

    Instruction* OSRSrcInF2 = cast<Instruction>(M->getCorrespondingOneToOneValue(OSRSrc));
    assert (OSRSrcInF2 != nullptr && "TODO cannot find corresponding OSRSrc in temporary F2");
    if (OSRLibrary::removeOSRPoint(*OSRSrcInF2) && verbose) {
        std::cerr << "OSR point removed after cloning F1" << std::endl;
    }

    Instruction* LPad = M->getLandingPad(OSRSrc);

    StateMap* M_F2toOSRContFun;
    LivenessAnalysis LA(F1);
    std::vector<Value*>* valuesToPass = OSRLibrary::getLiveValsVecAtInstr(OSRSrc, LA);
    std::string OSRDestFunName = (F2->getName().str()).append("OSRCont");
    Function* OSRContFun = OSRLibrary::genContinuationFunc(TheHelper->Context,
            *F1, *F2, *OSRSrc, *LPad, *valuesToPass, *M, &OSRDestFunName, verbose, &M_F2toOSRContFun);

    Value* valToInline = M_F2toOSRContFun->getCorrespondingOneToOneValue(valToInlineInF2);
    assert (valToInline != nullptr && "broken state map for continuation function");

    delete valuesToPass;
    delete F2;
    delete M;
    delete M_F2toOSRContFun;

    // create a module for generated code
    std::string modForJITName = "OpenOSRDynInline";
    modForJITName.append(OSRDestFunName);
    std::unique_ptr<Module> modForJIT = llvm::make_unique<Module>(modForJITName, TheHelper->Context);
    Module* modForJIT_ptr = modForJIT.get();

    // determine which function is called
    uint64_t calledFun = (uint64_t)profDataAddr;

    std::cerr << "Address of invoked function: " << calledFun << std::endl;
    Function* funToInline = nullptr;
    for (AddrSymPair &pair: TheHelper->CompiledFunAddrTable) {
        if (pair.first == calledFun) {
            std::string &FunName = pair.second;
            funToInline = TheHelper->getFunction(FunName);
            break;
        }
    }

    Function* myFunToInline = nullptr;
    if (funToInline == nullptr) {
        std::cerr << "Sorry, I could not determine which function was called!" << std::endl;
    } else {
        std::cerr << "Function being inlined: " << funToInline->getName().str() << std::endl;
        ValueToValueMapTy VMap;
        myFunToInline = CloneFunction(funToInline, VMap, false, nullptr);
        myFunToInline->addFnAttr(Attribute::AlwaysInline);
        myFunToInline->setLinkage(Function::LinkageTypes::PrivateLinkage);
        modForJIT_ptr->getFunctionList().push_back(myFunToInline);
        OSRLibrary::fixUsesOfFunctionsAndGlobals(funToInline, myFunToInline);
        for (Value::use_iterator UI = valToInline->use_begin(),
                UE = valToInline->use_end(); UI != UE; ) {
            Use &U = *(UI++);
            if (CallInst* CI = dyn_cast<CallInst>(U.getUser())) {
                if (CI->getParent()->getParent() != OSRContFun) continue;
                if (verbose) {
                    raw_os_ostream errStream(std::cerr);
                    std::cerr << "Updating instruction ";
                    CI->print(errStream);
                    std::cerr << std::endl;
                }
                U.set(myFunToInline);
            }
        }
    }

    modForJIT_ptr->getFunctionList().push_back(OSRContFun);
    verifyFunction(*OSRContFun, &outs());

    // remove dead code & inline when possible
    FunctionPassManager FPM(modForJIT_ptr);
    FPM.add(createCFGSimplificationPass());
    FPM.doInitialization();
    FPM.run(*OSRContFun);

    if (funToInline != nullptr) {
        PassManager PM;
        PM.add(llvm::createAlwaysInlinerPass());
        PM.run(*modForJIT_ptr);
    }

    // compile code
    TheHelper->addModule(std::move(modForJIT));
    return (void*)TheHelper->JIT->getFunctionAddress(OSRDestFunName);
}
Esempio n. 11
0
// TODO: factor this into a C++ core function, and a thin OCaml C wrapper
CAMLprim value compile_module_to_string(LLVMModuleRef modref) {
#ifndef __arm__
    Module &mod = *llvm::unwrap(modref);
    LLVMContext &ctx = mod.getContext();
    
    // TODO: streamline this - don't initialize anything but PTX
    LLVMInitializeNVPTXTargetInfo();
    LLVMInitializeNVPTXTarget();
    LLVMInitializeNVPTXTargetMC();
    LLVMInitializeNVPTXAsmPrinter();

    // DISABLED - hooked in here to force PrintBeforeAll option - seems to be the only way?
    /*char* argv[] = { "llc", "-print-before-all" };*/
    /*int argc = sizeof(argv)/sizeof(char*);*/
    /*cl::ParseCommandLineOptions(argc, argv, "Halide PTX internal compiler\n");*/

    // Set up TargetTriple
    mod.setTargetTriple(Triple::normalize("nvptx64--"));
    Triple TheTriple(mod.getTargetTriple());
    
    // Allocate target machine
    const std::string MArch = "nvptx64";
    const std::string MCPU = "sm_20";
    const Target* TheTarget = 0;
    
    std::string errStr;
    TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), errStr);
    assert(TheTarget);

    TargetOptions Options;
    Options.LessPreciseFPMADOption = true;
    Options.PrintMachineCode = false;
    Options.NoFramePointerElim = false;
    Options.NoFramePointerElimNonLeaf = false;
    //Options.NoExcessFPPrecision = false;
    Options.AllowFPOpFusion = FPOpFusion::Fast;
    Options.UnsafeFPMath = true;
    Options.NoInfsFPMath = false;
    Options.NoNaNsFPMath = false;
    Options.HonorSignDependentRoundingFPMathOption = false;
    Options.UseSoftFloat = false;
    /* if (FloatABIForCalls != FloatABI::Default) */
        /* Options.FloatABIType = FloatABIForCalls; */
    Options.NoZerosInBSS = false;
    Options.JITExceptionHandling = false;
    Options.JITEmitDebugInfo = false;
    Options.JITEmitDebugInfoToDisk = false;
    Options.GuaranteedTailCallOpt = false;
    Options.StackAlignmentOverride = 0;
    Options.RealignStack = true;
    // Options.DisableJumpTables = false;
    Options.TrapFuncName = "";
    Options.EnableSegmentedStacks = false;

    CodeGenOpt::Level OLvl = CodeGenOpt::Default;

    const std::string FeaturesStr = "";
    std::auto_ptr<TargetMachine>
        target(TheTarget->createTargetMachine(TheTriple.getTriple(),
                                              MCPU, FeaturesStr, Options,
                                              llvm::Reloc::Default,
                                              llvm::CodeModel::Default,
                                              OLvl));
    assert(target.get() && "Could not allocate target machine!");
    TargetMachine &Target = *target.get();

    // Set up passes
    PassManager PM;
    // Add the target data from the target machine
    PM.add(new TargetData(*Target.getTargetData()));

    // Inlining functions is essential to PTX
    PM.add(createAlwaysInlinerPass());

    // Override default to generate verbose assembly.
    Target.setAsmVerbosityDefault(true);

    // Output string stream
    std::string outstr;
    raw_string_ostream outs(outstr);
    formatted_raw_ostream ostream(outs);

    // Ask the target to add backend passes as necessary.
    bool fail = Target.addPassesToEmitFile(PM, ostream,
                                           TargetMachine::CGFT_AssemblyFile,
                                           true);
    assert(!fail);

    PM.run(mod);

    ostream.flush();
    std::string& out = outs.str();
    return copy_string(out.c_str());
#else
    return caml_copy_string("NOT IMPLEMENTED ON ARM: compile_module_to_string");
#endif //disable on ARM
}
Esempio n. 12
0
File: tc.cpp Progetto: brills/pfpa
// main - Entry point for the sc compiler.
//
int main(int argc, char **argv) {

  cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n");
  sys::PrintStackTraceOnErrorSignal();

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

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

  // Build up all of the passes that we want to do to the module...
  PassManager Passes;

  Passes.add(new TargetData(M.get()));

  // Currently deactiviated
  Passes.add(new TypeChecks());
  if(EnableTypeSafetyOpts)
    Passes.add(new TypeChecksOpt());

  // Verify the final result
  Passes.add(createVerifierPass());

  // Figure out where we are going to send the output...
  raw_fd_ostream *Out = 0;
  std::string error;
  if (OutputFilename != "") {
    if (OutputFilename != "-") {
      // Specified an output filename?
      if (!Force && std::ifstream(OutputFilename.c_str())) {
        // If force is not specified, make sure not to overwrite a file!
        std::cerr << argv[0] << ": error opening '" << OutputFilename
          << "': file exists!\n"
          << "Use -f command line argument to force output\n";
        return 1;
      }
      Out = new raw_fd_ostream (OutputFilename.c_str(), error);

      // Make sure that the Out file gets unlinked from the disk if we get a
      // SIGINT
      sys::RemoveFileOnSignal(sys::Path(OutputFilename));
    } else {
      Out = new raw_stdout_ostream();
    }
  } else {
    if (InputFilename == "-") {
      OutputFilename = "-";
      Out = new raw_stdout_ostream();
    } else {
      OutputFilename = GetFileNameRoot(InputFilename);

      OutputFilename += ".abc.bc";
    }

    if (!Force && std::ifstream(OutputFilename.c_str())) {
      // If force is not specified, make sure not to overwrite a file!
      std::cerr << argv[0] << ": error opening '" << OutputFilename
        << "': file exists!\n"
        << "Use -f command line argument to force output\n";
      return 1;
    }

    Out = new raw_fd_ostream(OutputFilename.c_str(), error);
    if (error.length()) {
      std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
      delete Out;
      return 1;
    }

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

  // Add the writing of the output file to the list of passes
  Passes.add (createBitcodeWriterPass(*Out));

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

  // Delete the ostream
  delete Out;

  return 0;
}
Esempio n. 13
0
int main(int argc, char* argv[])
{
   if(argc < 2)
   {
      cerr << "Usage: " << argv[0] << " bf_file" << endl;
      return -1;
   }
   ifstream sourceFile(argv[1]);
   string line, source;
   while(getline(sourceFile, line)) source += line;

   // Setup a module and engine for JIT-ing
   std::string error;
   InitializeNativeTarget();

   Module* module = new Module("bfcode", getGlobalContext());

   InitializeNativeTarget();
   LLVMLinkInJIT();
   ExecutionEngine *engine = EngineBuilder(module)
      .setErrorStr(&error)
      .setOptLevel(CodeGenOpt::Aggressive)
      .create();
   if(!engine)
   {
      cout << "No engine created: " << error << endl;
      return -1;
   }

   module->setDataLayout(engine->getTargetData()->getStringRepresentation());

   // Compile the BF to IR
   cout << "Parsing… " << flush;
   Function* func = makeFunc(module, source.c_str());
   cout << "done" << endl;

   {
       ofstream dst("out.ll");
       raw_os_ostream rawdst(dst);
       rawdst << *module;
   }

   // Run optimization passes
   cout << "Optimizing… " << flush;

   PassManagerBuilder PMBuilder;

   FunctionPassManager pm(module);
   PMBuilder.populateFunctionPassManager(pm);
   pm.add(new TargetData(*(engine->getTargetData())));
   pm.add(createVerifierPass());

   // Eliminate simple loops such as [>>++<<-]
   pm.add(createInstructionCombiningPass()); // Cleanup for scalarrepl.
   pm.add(createLICMPass());                 // Hoist loop invariants
   pm.add(createPromoteMemoryToRegisterPass());
   pm.add(createIndVarSimplifyPass());       // Canonicalize indvars
   pm.add(createLoopDeletionPass());         // Delete dead loops
   pm.add(createConstantPropagationPass());  // Propagate constants
   pm.add(new CondProp);                     // Propagate conditionals

   // Simplify code
   for(int repeat=0; repeat < 3; repeat++)
   {
      pm.add(createPromoteMemoryToRegisterPass());
      pm.add(createGVNPass());                  // Remove redundancies
      pm.add(createSCCPPass());                 // Constant prop with SCCP
      pm.add(createLoopDeletionPass());
      pm.add(createLoopUnrollPass());
      pm.add(createCFGSimplificationPass());    // Merge & remove BBs
      pm.add(createInstructionCombiningPass());
      pm.add(createConstantPropagationPass());  // Propagate constants
      pm.add(createAggressiveDCEPass());        // Delete dead instructions
      pm.add(createCFGSimplificationPass());    // Merge & remove BBs
      pm.add(createDeadStoreEliminationPass()); // Delete dead stores
      pm.add(createMemCpyOptPass());            // Combine multiple stores into memset's
      //pm.add(new PutCharAggregatePass);
   }

   pm.add(createPromoteMemoryToRegisterPass());

   // Process
   foreach (Function& f, *module)
       if (!f.isDeclaration)
           pm.run(f);

   PassManager pmm;

   PMBuilder.populateModulePassManager(pmm);
   pmm.add(createConstantMergePass());
   pmm.add(createGlobalOptimizerPass());
   pmm.add(createGlobalDCEPass());
   pmm.add(createIPConstantPropagationPass());
   pmm.run(*module);

   foreach (Function& f, *module)
       if (!f.isDeclaration)
           pm.run(f);
   pmm.run(*module);

   cout << "done" << endl;

   {
       ofstream dst("optout.ll");
       raw_os_ostream rawdst(dst);
       rawdst << *module;
   }

   // Compile …
   cout << "Compiling…" << flush;
   int (*bf)() = (int (*)())engine->getPointerToFunction(func);
   cout << " done" << endl;

   // … and run!
   return bf();
}
Esempio n. 14
0
//===----------------------------------------------------------------------===//
// main for dppgen
//
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();

  PassRegistry &Registry = *PassRegistry::getPassRegistry();
  initializeInstructionGraphPass(Registry);
  INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
  INITIALIZE_PASS_DEPENDENCY(PostDominatorTree)
  INITIALIZE_PASS_DEPENDENCY(LoopInfo)


  cl::ParseCommandLineOptions(argc, argv,
    "llvm .bc -> .cpp generate processing pipeline with decoupled memory access\n");


  SMDiagnostic Err;

  // Load the input module...
  errs()<<"before parsing\n";
  std::unique_ptr<Module> M = parseIRFile(InputFilename, Err, Context);
  errs()<<"after parsing\n";
  //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...
  std::unique_ptr<tool_output_file> Out;
  if (NoOutput) {
    if (!OutputFilename.empty())
      errs() << "WARNING: The -o (output filename) option is ignored when\n"
                "the --disable-output option is used.\n";
  } else {
    // Default to standard output.
    if (OutputFilename.empty())
      OutputFilename = "-";

    std::error_code EC;
    Out.reset(new tool_output_file(OutputFilename, EC, sys::fs::F_None));
    if (EC) {
      errs() << EC.message() << '\n';
      return 1;
    }


  }



  // a separate stream
  std::unique_ptr<tool_output_file>  fdesOut;
  std::unique_ptr<tool_output_file> OutC;
  // do the samething for FIFO description
  if (NoOutput) {
    if (!OutputFIFOFilename.empty())
      errs() << "WARNING: The -fdes (fifo des filename) option is ignored when\n"
                "the --disable-output option is used.\n";
    if(!OutputCFileName.empty())
      errs() << "WARNING: The -ocfile (synthesiziable c filename) option is ignored when\n"
                  "the --disable-output option is used.\n";

  } else {
    // Default to standard output.
    if (OutputFIFOFilename.empty())
      OutputFIFOFilename = "-";

    std::error_code EC;
    fdesOut.reset(new tool_output_file(OutputFIFOFilename, EC, sys::fs::F_None));
    if (EC) {
      errs() << EC.message() << '\n';
      return 1;
    }


    if(!OutputCFileName.empty())
    {
        std::error_code EC_c;
        OutC.reset(new tool_output_file(OutputCFileName, EC_c, sys::fs::F_None));
        if (EC_c) {
          errs() << EC_c.message() << '\n';
          return 1;
        }
    }



  }




  PassManager Passes;
  // we will need two passes
  // the first pass is to generate multiple function from a single function
  // the second pass is to generate the synthesizable C version for each generated function

  Passes.add(llvm::createDecoupleInsSccPass(!NoControlFlowDup));

  Passes.add(llvm::createDecoupleMemAccessPass(Burst));

  Passes.add(createPrintModulePass(Out->os()));
  if(!OutputCFileName.empty())
  {
    errs()<<"added cprint pass\n";
    Passes.add(llvm::createGenSynthCPass(OutC->os(),GenerateCPUMode));
  }

  //PartitionGen* pg = new PartitionGen(Out->os(),fdesOut->os(),NoControlFlowDup,GenerateCPUMode);

  //Passes.add(pg );
  // 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.
    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);
    }
  }*/

  // Before executing passes, print the final values of the LLVM options.
  cl::PrintOptionValues();

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




  // Declare success.
  if (!NoOutput )
  {
    Out->keep();
    if (!OutputFIFOFilename.empty())
        fdesOut->keep();
    if(!OutputCFileName.empty())
        OutC->keep();
  }
  return 0;
}
Esempio n. 15
0
//////////////////////////////////////////////////////////////////////////////////////////
// This function runs optimization passes based on command line arguments.
// Returns true if any optimization passes were invoked.
bool ldc_optimize_module(llvm::Module* m)
{
    // Create a PassManager to hold and optimize the collection of
    // per-module passes we are about to build.
    PassManager mpm;

    // Add an appropriate TargetLibraryInfo pass for the module's triple.
    TargetLibraryInfo *tli = new TargetLibraryInfo(Triple(m->getTargetTriple()));

    // The -disable-simplify-libcalls flag actually disables all builtin optzns.
    if (disableSimplifyLibCalls)
        tli->disableAllFunctions();
    mpm.add(tli);

    // Add an appropriate TargetData instance for this module.
#if LDC_LLVM_VER >= 302
    mpm.add(new DataLayout(m));
#else
    mpm.add(new TargetData(m));
#endif

    // Also set up a manager for the per-function passes.
    FunctionPassManager fpm(m);
#if LDC_LLVM_VER >= 302
    fpm.add(new DataLayout(m));
#else
    fpm.add(new TargetData(m));
#endif

    // If the -strip-debug command line option was specified, add it before
    // anything else.
    if (stripDebug)
        mpm.add(createStripSymbolsPass(true));

    bool defaultsAdded = false;
    // Create a new optimization pass for each one specified on the command line
    for (unsigned i = 0; i < passList.size(); ++i) {
        if (optimizeLevel && optimizeLevel.getPosition() < passList.getPosition(i)) {
            addOptimizationPasses(mpm, fpm, optLevel(), sizeLevel());
            defaultsAdded = true;
        }

        const PassInfo *passInf = passList[i];
        Pass *pass = 0;
        if (passInf->getNormalCtor())
            pass = passInf->getNormalCtor()();
        else {
            const char* arg = passInf->getPassArgument(); // may return null
            if (arg)
                error("Can't create pass '-%s' (%s)", arg, pass->getPassName());
            else
                error("Can't create pass (%s)", pass->getPassName());
            llvm_unreachable("pass creation failed");
        }
        if (pass) {
            addPass(mpm, pass);
        }
    }

    // Add the default passes for the specified optimization level.
    if (!defaultsAdded)
        addOptimizationPasses(mpm, fpm, optLevel(), sizeLevel());

    // Run per-function passes.
    fpm.doInitialization();
    for (llvm::Module::iterator F = m->begin(), E = m->end(); F != E; ++F)
        fpm.run(*F);
    fpm.doFinalization();

    // Run per-module passes.
    mpm.run(*m);

    // Verify the resulting module.
    verifyModule(m);

    // Report that we run some passes.
    return true;
}
Esempio n. 16
0
int main(int argc, char **argv) {
  // Print a stack trace if we signal out.
  sys::PrintStackTraceOnErrorSignal();
  PrettyStackTraceProgram X(argc, argv);

  LLVMContext &Context = getGlobalContext();
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
  cl::ParseCommandLineOptions(argc, argv, "llvm extractor\n");

  // Use lazy loading, since we only care about selected global values.
  SMDiagnostic Err;
  std::unique_ptr<Module> M = getLazyIRFileModule(InputFilename, Err, Context);

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

  // Use SetVector to avoid duplicates.
  SetVector<GlobalValue *> GVs;

  // Figure out which aliases we should extract.
  for (size_t i = 0, e = ExtractAliases.size(); i != e; ++i) {
    GlobalAlias *GA = M->getNamedAlias(ExtractAliases[i]);
    if (!GA) {
      errs() << argv[0] << ": program doesn't contain alias named '"
             << ExtractAliases[i] << "'!\n";
      return 1;
    }
    GVs.insert(GA);
  }

  // Extract aliases via regular expression matching.
  for (size_t i = 0, e = ExtractRegExpAliases.size(); i != e; ++i) {
    std::string Error;
    Regex RegEx(ExtractRegExpAliases[i]);
    if (!RegEx.isValid(Error)) {
      errs() << argv[0] << ": '" << ExtractRegExpAliases[i] << "' "
        "invalid regex: " << Error;
    }
    bool match = false;
    for (Module::alias_iterator GA = M->alias_begin(), E = M->alias_end();
         GA != E; GA++) {
      if (RegEx.match(GA->getName())) {
        GVs.insert(&*GA);
        match = true;
      }
    }
    if (!match) {
      errs() << argv[0] << ": program doesn't contain global named '"
             << ExtractRegExpAliases[i] << "'!\n";
      return 1;
    }
  }

  // Figure out which globals we should extract.
  for (size_t i = 0, e = ExtractGlobals.size(); i != e; ++i) {
    GlobalValue *GV = M->getNamedGlobal(ExtractGlobals[i]);
    if (!GV) {
      errs() << argv[0] << ": program doesn't contain global named '"
             << ExtractGlobals[i] << "'!\n";
      return 1;
    }
    GVs.insert(GV);
  }

  // Extract globals via regular expression matching.
  for (size_t i = 0, e = ExtractRegExpGlobals.size(); i != e; ++i) {
    std::string Error;
    Regex RegEx(ExtractRegExpGlobals[i]);
    if (!RegEx.isValid(Error)) {
      errs() << argv[0] << ": '" << ExtractRegExpGlobals[i] << "' "
        "invalid regex: " << Error;
    }
    bool match = false;
    for (auto &GV : M->globals()) {
      if (RegEx.match(GV.getName())) {
        GVs.insert(&GV);
        match = true;
      }
    }
    if (!match) {
      errs() << argv[0] << ": program doesn't contain global named '"
             << ExtractRegExpGlobals[i] << "'!\n";
      return 1;
    }
  }

  // Figure out which functions we should extract.
  for (size_t i = 0, e = ExtractFuncs.size(); i != e; ++i) {
    GlobalValue *GV = M->getFunction(ExtractFuncs[i]);
    if (!GV) {
      errs() << argv[0] << ": program doesn't contain function named '"
             << ExtractFuncs[i] << "'!\n";
      return 1;
    }
    GVs.insert(GV);
  }
  // Extract functions via regular expression matching.
  for (size_t i = 0, e = ExtractRegExpFuncs.size(); i != e; ++i) {
    std::string Error;
    StringRef RegExStr = ExtractRegExpFuncs[i];
    Regex RegEx(RegExStr);
    if (!RegEx.isValid(Error)) {
      errs() << argv[0] << ": '" << ExtractRegExpFuncs[i] << "' "
        "invalid regex: " << Error;
    }
    bool match = false;
    for (Module::iterator F = M->begin(), E = M->end(); F != E;
         F++) {
      if (RegEx.match(F->getName())) {
        GVs.insert(&*F);
        match = true;
      }
    }
    if (!match) {
      errs() << argv[0] << ": program doesn't contain global named '"
             << ExtractRegExpFuncs[i] << "'!\n";
      return 1;
    }
  }

  // Materialize requisite global values.
  if (!DeleteFn)
    for (size_t i = 0, e = GVs.size(); i != e; ++i) {
      GlobalValue *GV = GVs[i];
      if (GV->isMaterializable()) {
        std::string ErrInfo;
        if (GV->Materialize(&ErrInfo)) {
          errs() << argv[0] << ": error reading input: " << ErrInfo << "\n";
          return 1;
        }
      }
    }
  else {
    // Deleting. Materialize every GV that's *not* in GVs.
    SmallPtrSet<GlobalValue *, 8> GVSet(GVs.begin(), GVs.end());
    for (auto &G : M->globals()) {
      if (!GVSet.count(&G) && G.isMaterializable()) {
        std::string ErrInfo;
        if (G.Materialize(&ErrInfo)) {
          errs() << argv[0] << ": error reading input: " << ErrInfo << "\n";
          return 1;
        }
      }
    }
    for (auto &F : *M) {
      if (!GVSet.count(&F) && F.isMaterializable()) {
        std::string ErrInfo;
        if (F.Materialize(&ErrInfo)) {
          errs() << argv[0] << ": error reading input: " << ErrInfo << "\n";
          return 1;
        }
      }
    }
  }

  // In addition to deleting all other functions, we also want to spiff it
  // up a little bit.  Do this now.
  PassManager Passes;
  Passes.add(new DataLayoutPass(M.get())); // Use correct DataLayout

  std::vector<GlobalValue*> Gvs(GVs.begin(), GVs.end());

  Passes.add(createGVExtractionPass(Gvs, DeleteFn));
  if (!DeleteFn)
    Passes.add(createGlobalDCEPass());           // Delete unreachable globals
  Passes.add(createStripDeadDebugInfoPass());    // Remove dead debug info
  Passes.add(createStripDeadPrototypesPass());   // Remove dead func decls

  std::error_code EC;
  tool_output_file Out(OutputFilename, EC, sys::fs::F_None);
  if (EC) {
    errs() << EC.message() << '\n';
    return 1;
  }

  if (OutputAssembly)
    Passes.add(createPrintModulePass(Out.os()));
  else if (Force || !CheckBitcodeOutputToConsole(Out.os(), true))
    Passes.add(createBitcodeWriterPass(Out.os()));

  Passes.run(*M.get());

  // Declare success.
  Out.keep();

  return 0;
}
Esempio n. 17
0
void LTOCodeGenerator::applyScopeRestrictions() {
  if (ScopeRestrictionsDone || !shouldInternalize())
    return;
  Module *mergedModule = Linker.getModule();

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

  // mark which symbols can not be internalized
  Mangler Mangler(TargetMach->getDataLayout());
  std::vector<const char*> MustPreserveList;
  SmallPtrSet<GlobalValue*, 8> AsmUsed;
  std::vector<StringRef> Libcalls;
  TargetLibraryInfo TLI(Triple(TargetMach->getTargetTriple()));
  accumulateAndSortLibcalls(Libcalls, TLI, TargetMach->getTargetLowering());

  for (Module::iterator f = mergedModule->begin(),
         e = mergedModule->end(); f != e; ++f)
    applyRestriction(*f, Libcalls, MustPreserveList, AsmUsed, Mangler);
  for (Module::global_iterator v = mergedModule->global_begin(),
         e = mergedModule->global_end(); v !=  e; ++v)
    applyRestriction(*v, Libcalls, MustPreserveList, AsmUsed, Mangler);
  for (Module::alias_iterator a = mergedModule->alias_begin(),
         e = mergedModule->alias_end(); a != e; ++a)
    applyRestriction(*a, Libcalls, MustPreserveList, AsmUsed, Mangler);

  GlobalVariable *LLVMCompilerUsed =
    mergedModule->getGlobalVariable("llvm.compiler.used");
  findUsedValues(LLVMCompilerUsed, AsmUsed);
  if (LLVMCompilerUsed)
    LLVMCompilerUsed->eraseFromParent();

  if (!AsmUsed.empty()) {
    llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(Context);
    std::vector<Constant*> asmUsed2;
    for (SmallPtrSet<GlobalValue*, 16>::const_iterator i = AsmUsed.begin(),
           e = AsmUsed.end(); i !=e; ++i) {
      GlobalValue *GV = *i;
      Constant *c = ConstantExpr::getBitCast(GV, i8PTy);
      asmUsed2.push_back(c);
    }

    llvm::ArrayType *ATy = llvm::ArrayType::get(i8PTy, asmUsed2.size());
    LLVMCompilerUsed =
      new llvm::GlobalVariable(*mergedModule, ATy, false,
                               llvm::GlobalValue::AppendingLinkage,
                               llvm::ConstantArray::get(ATy, asmUsed2),
                               "llvm.compiler.used");

    LLVMCompilerUsed->setSection("llvm.metadata");
  }

  passes.add(
      createInternalizePass(MustPreserveList, shouldOnlyInternalizeHidden()));

  // apply scope restrictions
  passes.run(*mergedModule);

  ScopeRestrictionsDone = true;
}
Esempio n. 18
0
//////////////////////////////////////////////////////////////////////////////////////////
// This function runs optimization passes based on command line arguments.
// Returns true if any optimization passes were invoked.
bool ldc_optimize_module(llvm::Module *M)
{
    // Create a PassManager to hold and optimize the collection of
    // per-module passes we are about to build.
#if LDC_LLVM_VER >= 307
    legacy::
#endif
    PassManager mpm;

#if LDC_LLVM_VER >= 307
    // Add an appropriate TargetLibraryInfo pass for the module's triple.
    TargetLibraryInfoImpl *tlii = new TargetLibraryInfoImpl(Triple(M->getTargetTriple()));

    // The -disable-simplify-libcalls flag actually disables all builtin optzns.
    if (disableSimplifyLibCalls)
      tlii->disableAllFunctions();

    mpm.add(new TargetLibraryInfoWrapperPass(*tlii));
#else
    // Add an appropriate TargetLibraryInfo pass for the module's triple.
    TargetLibraryInfo *tli = new TargetLibraryInfo(Triple(M->getTargetTriple()));

    // The -disable-simplify-libcalls flag actually disables all builtin optzns.
    if (disableSimplifyLibCalls)
      tli->disableAllFunctions();

    mpm.add(tli);
#endif

    // Add an appropriate DataLayout instance for this module.
#if LDC_LLVM_VER >= 307
    // The DataLayout is already set at the module (in module.cpp,
    // method Module::genLLVMModule())
    // FIXME: Introduce new command line switch default-data-layout to
    // override the module data layout
#elif LDC_LLVM_VER == 306
    mpm.add(new DataLayoutPass());
#elif LDC_LLVM_VER == 305
    const DataLayout *DL = M->getDataLayout();
    assert(DL && "DataLayout not set at module");
    mpm.add(new DataLayoutPass(*DL));
#elif LDC_LLVM_VER >= 302
    mpm.add(new DataLayout(M));
#else
    mpm.add(new TargetData(M));
#endif

#if LDC_LLVM_VER >= 307
    // Add internal analysis passes from the target machine.
    mpm.add(createTargetTransformInfoWrapperPass(gTargetMachine->getTargetIRAnalysis()));
#elif LDC_LLVM_VER >= 305
    // Add internal analysis passes from the target machine.
    gTargetMachine->addAnalysisPasses(mpm);
#endif

    // Also set up a manager for the per-function passes.
#if LDC_LLVM_VER >= 307
    legacy::
#endif
    FunctionPassManager fpm(M);

#if LDC_LLVM_VER >= 307
    // Add internal analysis passes from the target machine.
    fpm.add(createTargetTransformInfoWrapperPass(gTargetMachine->getTargetIRAnalysis()));
#elif LDC_LLVM_VER >= 306
    fpm.add(new DataLayoutPass());
    gTargetMachine->addAnalysisPasses(fpm);
#elif LDC_LLVM_VER == 305
    fpm.add(new DataLayoutPass(M));
    gTargetMachine->addAnalysisPasses(fpm);
#elif LDC_LLVM_VER >= 302
    fpm.add(new DataLayout(M));
#else
    fpm.add(new TargetData(M));
#endif

    // If the -strip-debug command line option was specified, add it before
    // anything else.
    if (stripDebug)
        mpm.add(createStripSymbolsPass(true));

    bool defaultsAdded = false;
    // Create a new optimization pass for each one specified on the command line
    for (unsigned i = 0; i < passList.size(); ++i) {
        if (optimizeLevel && optimizeLevel.getPosition() < passList.getPosition(i)) {
            addOptimizationPasses(mpm, fpm, optLevel(), sizeLevel());
            defaultsAdded = true;
        }

        const PassInfo *passInf = passList[i];
        Pass *pass = 0;
        if (passInf->getNormalCtor())
            pass = passInf->getNormalCtor()();
        else {
            const char* arg = passInf->getPassArgument(); // may return null
            if (arg)
                error(Loc(), "Can't create pass '-%s' (%s)", arg, pass->getPassName());
            else
                error(Loc(), "Can't create pass (%s)", pass->getPassName());
            llvm_unreachable("pass creation failed");
        }
        if (pass) {
            addPass(mpm, pass);
        }
    }

    // Add the default passes for the specified optimization level.
    if (!defaultsAdded)
        addOptimizationPasses(mpm, fpm, optLevel(), sizeLevel());

    // Run per-function passes.
    fpm.doInitialization();
    for (llvm::Module::iterator F = M->begin(), E = M->end(); F != E; ++F)
        fpm.run(*F);
    fpm.doFinalization();

    // Run per-module passes.
    mpm.run(*M);

    // Verify the resulting module.
    verifyModule(M);

    // Report that we run some passes.
    return true;
}
Esempio n. 19
0
//===----------------------------------------------------------------------===//
// main for dppgen
//
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();

  PassRegistry &Registry = *PassRegistry::getPassRegistry();
  initializeInstructionGraphPass(Registry);
  INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
  INITIALIZE_PASS_DEPENDENCY(PostDominatorTree)
  INITIALIZE_PASS_DEPENDENCY(LoopInfo)

  cl::ParseCommandLineOptions(argc, argv,
    "llvm .bc -> .cpp generate decoupled processing pipeline\n");


  SMDiagnostic Err;

  // Load the input module...
  std::unique_ptr<Module> M = parseIRFile(InputFilename, Err, Context);
  //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...
  std::unique_ptr<tool_output_file> Out;
  if (NoOutput) {
    if (!OutputFilename.empty())
      errs() << "WARNING: The -o (output filename) option is ignored when\n"
                "the --disable-output option is used.\n";
  } else {
    // Default to standard output.
    if (OutputFilename.empty())
      OutputFilename = "-";

    std::error_code EC;
    Out.reset(new tool_output_file(OutputFilename, EC, sys::fs::F_None));
    if (EC) {
      errs() << EC.message() << '\n';
      return 1;
    }


  }
  PassManager Passes;
  // we will need two passes
  // the first pass is to generate multiple function from a single function
  // the second pass is to generate the synthesizable C version for each generated function


  Passes.add(llvm::createGenSynthCPass(Out->os(),GenerateCPUMode));


  // Before executing passes, print the final values of the LLVM options.
  cl::PrintOptionValues();

  // Now that we have all of the passes ready, run them.
  Passes.run(*M.get());
  // Declare success.
  if (!NoOutput )
  {
    Out->keep();
  }
  return 0;
}
Esempio n. 20
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;
}
Esempio n. 21
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();

  InitializeAllTargets();
  InitializeAllTargetMCs();
  InitializeAllAsmPrinters();

  // Initialize passes
  PassRegistry &Registry = *PassRegistry::getPassRegistry();
  initializeCore(Registry);
  initializeScalarOpts(Registry);
  initializeObjCARCOpts(Registry);
  initializeVectorization(Registry);
  initializeIPO(Registry);
  initializeAnalysis(Registry);
  initializeIPA(Registry);
  initializeTransformUtils(Registry);
  initializeInstCombine(Registry);
  initializeInstrumentation(Registry);
  initializeTarget(Registry);
  initializeCheerpOpts(Registry);
  // For codegen passes, only passes that do IR to IR transformation are
  // supported.
  initializeCodeGenPreparePass(Registry);
  initializeAtomicExpandPass(Registry);
  initializeRewriteSymbolsPass(Registry);

#ifdef LINK_POLLY_INTO_TOOLS
  polly::initializePollyPasses(Registry);
#endif

  cl::ParseCommandLineOptions(argc, argv,
    "llvm .bc -> .bc modular optimizer and analysis printer\n");

  if (AnalyzeOnly && NoOutput) {
    errs() << argv[0] << ": analyze mode conflicts with no-output mode.\n";
    return 1;
  }

  SMDiagnostic Err;

  // Load the input module...
  std::unique_ptr<Module> M = parseIRFile(InputFilename, Err, Context);

  if (!M) {
    Err.print(argv[0], errs());
    return 1;
  }

  // If we are supposed to override the target triple, do so now.
  if (!TargetTriple.empty())
    M->setTargetTriple(Triple::normalize(TargetTriple));

  // Figure out what stream we are supposed to write to...
  std::unique_ptr<tool_output_file> Out;
  if (NoOutput) {
    if (!OutputFilename.empty())
      errs() << "WARNING: The -o (output filename) option is ignored when\n"
                "the --disable-output option is used.\n";
  } else {
    // Default to standard output.
    if (OutputFilename.empty())
      OutputFilename = "-";

    std::error_code EC;
    Out.reset(new tool_output_file(OutputFilename, EC, sys::fs::F_None));
    if (EC) {
      errs() << EC.message() << '\n';
      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->os(), !Quiet))
      NoOutput = true;

  if (PassPipeline.getNumOccurrences() > 0) {
    OutputKind OK = OK_NoOutput;
    if (!NoOutput)
      OK = OutputAssembly ? OK_OutputAssembly : OK_OutputBitcode;

    VerifierKind VK = VK_VerifyInAndOut;
    if (NoVerify)
      VK = VK_NoVerifier;
    else if (VerifyEach)
      VK = VK_VerifyEachPass;

    // The user has asked to use the new pass manager and provided a pipeline
    // string. Hand off the rest of the functionality to the new code for that
    // layer.
    return runPassPipeline(argv[0], Context, *M, Out.get(), PassPipeline,
                           OK, VK)
               ? 0
               : 1;
  }

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

  // Add an appropriate TargetLibraryInfo pass for the module's triple.
  TargetLibraryInfo *TLI = new TargetLibraryInfo(Triple(M->getTargetTriple()));

  // The -disable-simplify-libcalls flag actually disables all builtin optzns.
  if (DisableSimplifyLibCalls)
    TLI->disableAllFunctions();
  Passes.add(TLI);

  // Add an appropriate DataLayout instance for this module.
  const DataLayout *DL = M->getDataLayout();
  if (!DL && !DefaultDataLayout.empty()) {
    M->setDataLayout(DefaultDataLayout);
    DL = M->getDataLayout();
  }

  if (DL)
    Passes.add(new DataLayoutPass());

  Triple ModuleTriple(M->getTargetTriple());
  TargetMachine *Machine = nullptr;
  if (ModuleTriple.getArch())
    Machine = GetTargetMachine(Triple(ModuleTriple));
  std::unique_ptr<TargetMachine> TM(Machine);

  // Add internal analysis passes from the target machine.
  if (TM)
    TM->addAnalysisPasses(Passes);

  std::unique_ptr<FunctionPassManager> FPasses;
  if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) {
    FPasses.reset(new FunctionPassManager(M.get()));
    if (DL)
      FPasses->add(new DataLayoutPass());
    if (TM)
      TM->addAnalysisPasses(*FPasses);

  }

  if (PrintBreakpoints) {
    // Default to standard output.
    if (!Out) {
      if (OutputFilename.empty())
        OutputFilename = "-";

      std::error_code EC;
      Out = llvm::make_unique<tool_output_file>(OutputFilename, EC,
                                                sys::fs::F_None);
      if (EC) {
        errs() << EC.message() << '\n';
        return 1;
      }
    }
    Passes.add(createBreakpointPrinter(Out->os()));
    NoOutput = true;
  }

  // If the -strip-debug command line option was specified, add it.
  if (StripDebug)
    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) {
    if (StandardLinkOpts &&
        StandardLinkOpts.getPosition() < PassList.getPosition(i)) {
      AddStandardLinkPasses(Passes);
      StandardLinkOpts = false;
    }

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

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

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

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

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

    const PassInfo *PassInf = PassList[i];
    Pass *P = nullptr;
    if (PassInf->getTargetMachineCtor())
      P = PassInf->getTargetMachineCtor()(TM.get());
    else 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(createBasicBlockPassPrinter(PassInf, Out->os(), Quiet));
          break;
        case PT_Region:
          Passes.add(createRegionPassPrinter(PassInf, Out->os(), Quiet));
          break;
        case PT_Loop:
          Passes.add(createLoopPassPrinter(PassInf, Out->os(), Quiet));
          break;
        case PT_Function:
          Passes.add(createFunctionPassPrinter(PassInf, Out->os(), Quiet));
          break;
        case PT_CallGraphSCC:
          Passes.add(createCallGraphPassPrinter(PassInf, Out->os(), Quiet));
          break;
        default:
          Passes.add(createModulePassPrinter(PassInf, Out->os(), Quiet));
          break;
        }
      }
    }

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

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

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

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

  if (OptLevelOs)
    AddOptimizationPasses(Passes, *FPasses, 2, 1);

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

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

  if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) {
    FPasses->doInitialization();
    for (Function &F : *M)
      FPasses->run(F);
    FPasses->doFinalization();
  }

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

  // Write bitcode or assembly to the output as the last step...
  if (!NoOutput && !AnalyzeOnly) {
    if (OutputAssembly)
      Passes.add(createPrintModulePass(Out->os()));
    else
      Passes.add(createBitcodeWriterPass(Out->os()));
  }

  // Before executing passes, print the final values of the LLVM options.
  cl::PrintOptionValues();

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

  // Declare success.
  if (!NoOutput || PrintBreakpoints)
    Out->keep();

  return 0;
}
Esempio n. 22
0
/**
 * Compile an LLVM module to machine code.
 *
 * @param bytes This function allocates memory for the byte stream, it is the
 * caller's responsibility to free it.
 */
extern "C" unsigned
radeon_llvm_compile(LLVMModuleRef M, unsigned char ** bytes,
                 unsigned * byte_count, const char * gpu_family,
                 unsigned dump) {

   Triple AMDGPUTriple(sys::getDefaultTargetTriple());

#ifdef EXTERNAL_LLVM
   /* XXX: Can we just initialize the AMDGPU target here? */
   InitializeAllTargets();
   InitializeAllTargetMCs();
#else
   LLVMInitializeAMDGPUTargetInfo();
   LLVMInitializeAMDGPUTarget();
   LLVMInitializeAMDGPUTargetMC();
#endif
   std::string err;
   const Target * AMDGPUTarget = TargetRegistry::lookupTarget("r600", err);
   if(!AMDGPUTarget) {
      fprintf(stderr, "Can't find target: %s\n", err.c_str());
      return 1;
   }
   
   Triple::ArchType Arch = Triple::getArchTypeForLLVMName("r600");
   if (Arch == Triple::UnknownArch) {
      fprintf(stderr, "Unknown Arch\n");
   }
   AMDGPUTriple.setArch(Arch);

   Module * mod = unwrap(M);
   std::string FS;
   TargetOptions TO;

   if (dump) {
      mod->dump();
      FS += "+DumpCode";
   }

   std::auto_ptr<TargetMachine> tm(AMDGPUTarget->createTargetMachine(
                     AMDGPUTriple.getTriple(), gpu_family, FS,
                     TO, Reloc::Default, CodeModel::Default,
                     CodeGenOpt::Default
                     ));
   TargetMachine &AMDGPUTargetMachine = *tm.get();
   PassManager PM;
   PM.add(new TargetData(*AMDGPUTargetMachine.getTargetData()));
   PM.add(createPromoteMemoryToRegisterPass());
   AMDGPUTargetMachine.setAsmVerbosityDefault(true);

   std::string CodeString;
   raw_string_ostream oStream(CodeString);
   formatted_raw_ostream out(oStream);

   /* Optional extra paramater true / false to disable verify */
   if (AMDGPUTargetMachine.addPassesToEmitFile(PM, out, TargetMachine::CGFT_AssemblyFile,
                                               true)){
      fprintf(stderr, "AddingPasses failed.\n");
      return 1;
   }
   PM.run(*mod);

   out.flush();
   std::string &data = oStream.str();

   *bytes = (unsigned char*)malloc(data.length() * sizeof(unsigned char));
   memcpy(*bytes, data.c_str(), data.length() * sizeof(unsigned char));
   *byte_count = data.length();

   return 0;
}
Esempio n. 23
0
////////////////////////////////////////////////////////////////////////////////
// This function runs optimization passes based on command line arguments.
// Returns true if any optimization passes were invoked.
bool ldc_optimize_module(llvm::Module *M) {
// Create a PassManager to hold and optimize the collection of
// per-module passes we are about to build.
#if LDC_LLVM_VER >= 307
  legacy::
#endif
      PassManager mpm;

#if LDC_LLVM_VER >= 307
  // Add an appropriate TargetLibraryInfo pass for the module's triple.
  TargetLibraryInfoImpl *tlii =
      new TargetLibraryInfoImpl(Triple(M->getTargetTriple()));

  // The -disable-simplify-libcalls flag actually disables all builtin optzns.
  if (disableSimplifyLibCalls)
    tlii->disableAllFunctions();

  mpm.add(new TargetLibraryInfoWrapperPass(*tlii));
#else
  // Add an appropriate TargetLibraryInfo pass for the module's triple.
  TargetLibraryInfo *tli = new TargetLibraryInfo(Triple(M->getTargetTriple()));

  // The -disable-simplify-libcalls flag actually disables all builtin optzns.
  if (disableSimplifyLibCalls) {
    tli->disableAllFunctions();
  }

  mpm.add(tli);
#endif

// Add an appropriate DataLayout instance for this module.
#if LDC_LLVM_VER >= 307
// The DataLayout is already set at the module (in module.cpp,
// method Module::genLLVMModule())
// FIXME: Introduce new command line switch default-data-layout to
// override the module data layout
#elif LDC_LLVM_VER == 306
  mpm.add(new DataLayoutPass());
#else
                                    const DataLayout *DL = M->getDataLayout();
                                    assert(DL &&
                                           "DataLayout not set at module");
                                    mpm.add(new DataLayoutPass(*DL));
#endif

#if LDC_LLVM_VER >= 307
  // Add internal analysis passes from the target machine.
  mpm.add(createTargetTransformInfoWrapperPass(
      gTargetMachine->getTargetIRAnalysis()));
#else
  // Add internal analysis passes from the target machine.
  gTargetMachine->addAnalysisPasses(mpm);
#endif

// Also set up a manager for the per-function passes.
#if LDC_LLVM_VER >= 307
  legacy::
#endif
      FunctionPassManager fpm(M);

#if LDC_LLVM_VER >= 307
  // Add internal analysis passes from the target machine.
  fpm.add(createTargetTransformInfoWrapperPass(
      gTargetMachine->getTargetIRAnalysis()));
#elif LDC_LLVM_VER >= 306
  fpm.add(new DataLayoutPass());
  gTargetMachine->addAnalysisPasses(fpm);
#else
                                    fpm.add(new DataLayoutPass(M));
                                    gTargetMachine->addAnalysisPasses(fpm);
#endif

  // If the -strip-debug command line option was specified, add it before
  // anything else.
  if (stripDebug) {
    mpm.add(createStripSymbolsPass(true));
  }

  addOptimizationPasses(mpm, fpm, optLevel(), sizeLevel());

  // Run per-function passes.
  fpm.doInitialization();
  for (auto &F : *M) {
    fpm.run(F);
  }
  fpm.doFinalization();

  // Run per-module passes.
  mpm.run(*M);

  // Verify the resulting module.
  verifyModule(M);

  // Report that we run some passes.
  return true;
}
Esempio n. 24
0
int
main (int argc, char ** argv)
{
  cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n");

  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
  LLVMContext &Context = getGlobalContext();

  OwningPtr<tool_output_file> Out;  
  std::string ErrorInfo;
  Out.reset(new tool_output_file(OutputFilename.c_str(), ErrorInfo,
				 sys::fs::F_Binary));

  SMDiagnostic Err;

  std::auto_ptr<Module> M;
  M.reset(ParseIRFile(InputFilename, Err, Context));

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

  if (PreOpt) 
  {
    PassManager Passes;
    Passes.add(createVerifierPass());
    Passes.add(createPromoteMemoryToRegisterPass());
    Passes.add(createDeadInstEliminationPass());
    Passes.run(*M.get());
  }

  if (CSE) {
#ifdef UseC
    LLVMCommonSubexpressionElimination(wrap(M.get()));
#else
    LLVMCommonSubexpressionElimination_Cpp(M.get());
#endif
  }


 if (DumpSummary)
   {
      char filename[1024]; 
      sprintf(filename,"%s.stats",OutputFilename.c_str());
#ifdef UseC
      Summarize(wrap(M.get()),"preGCM",filename);
#else
      Summarize_Cpp(M.get(),"preGCM",filename);
#endif
   }

 if (!NoLICM) {
#ifdef UseC
    LoopInvariantCodeMotion_C(wrap(M.get()));
#else
    LoopInvariantCodeMotion_Cpp(M.get());
#endif

    if (Twice) {
#ifdef UseC
    LoopInvariantCodeMotion_C(wrap(M.get()));
#else
    LoopInvariantCodeMotion_Cpp(M.get());
#endif
    }

  }


 if (DumpSummary)
   {
      char filename[1024]; 
      sprintf(filename,"%s.stats",OutputFilename.c_str());
#ifdef UseC
      Summarize(wrap(M.get()),"postGCM",filename);
#else
      Summarize_Cpp(M.get(),"postGCM",filename);
#endif
   }

  if (PostOpt)
   {
     PassManager Passes;
     Passes.add(createDeadCodeEliminationPass());
     Passes.add(createCFGSimplificationPass()); 
     Passes.run(*M.get());
   }
   
   WriteBitcodeToFile(M.get(),Out->os());
   Out->keep();
   
   return 0;
}
Esempio n. 25
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 DataLayout instance for this module...
  passes.add(new DataLayout(*_target->getDataLayout()));
  _target->addAnalysisPasses(passes);

  // 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.
  if (!DisableOpt) {
    PassManagerBuilder().populateLTOPassManager(passes,
                                              /*Internalize=*/false,
                                              !DisableInline,
                                              DisableGVNLoadPRE);
  }

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

  PassManager codeGenPasses;

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

  formatted_raw_ostream Out(out);

  // If the bitcode files contain ARC code and were compiled with optimization,
  // the ObjCARCContractPass must be run, so do it unconditionally here.
  codeGenPasses.add(createObjCARCContractPass());

  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;
      }
    }
 
    // Do a check for some other SAFECode run-time checks.
    if (mergedModule->getFunction("poolcheck_freeui") ||
        mergedModule->getFunction("poolcheck_freeui_debug") ||
        mergedModule->getFunction("poolcheck_free") ||
        mergedModule->getFunction("poolcheck_free_debug")) {
      UsingSAFECode = true;
    }

    if (UsingSAFECode) {
      passes.add(new DataLayout(*_target->getDataLayout()));
      passes.add(createSAFECodeMSCInfoPass());
#if 0
      passes.add(createExactCheckOptPass());
#endif

      passes.add(new DominatorTree());
      passes.add(new ScalarEvolution());
      passes.add(createOptimizeImpliedFastLSChecksPass());

      if (mergedModule->getFunction("main")) {
        passes.add(new CompleteChecks());
      }
    
#ifdef HAVE_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 HAVE_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.run(*mergedModule);

  return false; // success
}
Esempio n. 26
0
int compile(list<string> args, list<string> kgen_args,
            string merge, list<string> merge_args,
            string input, string output, int arch,
            string host_compiler, string fileprefix)
{
    //
    // The LLVM compiler to emit IR.
    //
    const char* llvm_compiler = "kernelgen-gfortran";

    //
    // Interpret kernelgen compile options.
    //
    for (list<string>::iterator iarg = kgen_args.begin(),
            iearg = kgen_args.end(); iarg != iearg; iarg++)
    {
        const char* arg = (*iarg).c_str();
        if (!strncmp(arg, "-Wk,--llvm-compiler=", 20))
            llvm_compiler = arg + 20;
    }

    //
    // Generate temporary output file.
    // Check if output file is specified in the command line.
    // Replace or add output to the temporary file.
    //
    cfiledesc tmp_output = cfiledesc::mktemp(fileprefix);
    bool output_specified = false;
    for (list<string>::iterator iarg = args.begin(),
            iearg = args.end(); iarg != iearg; iarg++)
    {
        const char* arg = (*iarg).c_str();
        if (!strcmp(arg, "-o"))
        {
            iarg++;
            *iarg = tmp_output.getFilename();
            output_specified = true;
            break;
        }
    }
    if (!output_specified)
    {
        args.push_back("-o");
        args.push_back(tmp_output.getFilename());
    }

    //
    // 1) Compile source code using regular host compiler.
    //
    {
        if (verbose)
        {
            cout << host_compiler;
            for (list<string>::iterator iarg = args.begin(),
                    iearg = args.end(); iarg != iearg; iarg++)
                cout << " " << *iarg;
            cout << endl;
        }
        int status = execute(host_compiler, args, "", NULL, NULL);
        if (status) return status;
    }

    //
    // 2) Emit LLVM IR.
    //
    string out = "";
    {
        list<string> emit_ir_args;
        for (list<string>::iterator iarg = args.begin(),
                iearg = args.end(); iarg != iearg; iarg++)
        {
            const char* arg = (*iarg).c_str();
            if (!strcmp(arg, "-c") || !strcmp(arg, "-o"))
            {
                iarg++;
                continue;
            }
            if (!strcmp(arg, "-g"))
            {
                continue;
            }
            emit_ir_args.push_back(*iarg);
        }
        emit_ir_args.push_back("-fplugin=/opt/kernelgen/lib/dragonegg.so");
        emit_ir_args.push_back("-fplugin-arg-dragonegg-emit-ir");
        emit_ir_args.push_back("-S");
        emit_ir_args.push_back(input);
        emit_ir_args.push_back("-o");
        emit_ir_args.push_back("-");
        if (verbose)
        {
            cout << llvm_compiler;
            for (list<string>::iterator iarg = emit_ir_args.begin(),
                    iearg = emit_ir_args.end(); iarg != iearg; iarg++)
                cout << " " << *iarg;
            cout << endl;
        }
        int status = execute(llvm_compiler, emit_ir_args, "", &out, NULL);
        if (status) return status;
    }

    //
    // 3) Record existing module functions.
    //
    LLVMContext &context = getGlobalContext();
    SMDiagnostic diag;
    MemoryBuffer* buffer1 = MemoryBuffer::getMemBuffer(out);
    auto_ptr<Module> m1;
    m1.reset(ParseIR(buffer1, diag, context));

    //m1.get()->dump();

    //
    // 4) Inline calls and extract loops into new functions.
    //
    MemoryBuffer* buffer2 = MemoryBuffer::getMemBuffer(out);
    auto_ptr<Module> m2;
    m2.reset(ParseIR(buffer2, diag, context));
    {
        PassManager manager;
        manager.add(createInstructionCombiningPass());
        manager.run(*m2.get());
    }
    std::vector<CallInst *> LoopFuctionCalls;
    {
        PassManager manager;
        manager.add(createBranchedLoopExtractorPass(LoopFuctionCalls));
        manager.run(*m2.get());
    }

    //m2.get()->dump();

    //
    // 5) Replace call to loop functions with call to launcher.
    // Append "always inline" attribute to all other functions.
    //
    Type* int32Ty = Type::getInt32Ty(context);
    Function* launch = Function::Create(
                           TypeBuilder<types::i<32>(types::i<8>*, types::i<64>, types::i<32>*), true>::get(context),
                           GlobalValue::ExternalLinkage, "kernelgen_launch", m2.get());
    for (Module::iterator f1 = m2.get()->begin(), fe1 = m2.get()->end(); f1 != fe1; f1++)
    {
        Function* func = f1;
        if (func->isDeclaration()) continue;

        // Search for the current function in original module
        // functions list.
        // If function is not in list of original module, then
        // it is generated by the loop extractor.
        // Append "always inline" attribute to all other functions.
        if (m1.get()->getFunction(func->getName()))
        {
            const AttrListPtr attr = func->getAttributes();
            const AttrListPtr attr_new = attr.addAttr(~0U, Attribute::AlwaysInline);
            func->setAttributes(attr_new);
            continue;
        }

        // Each such function must be extracted to the
        // standalone module and packed into resulting
        // object file data section.
        if (verbose)
            cout << "Preparing loop function " << func->getName().data() <<
                 " ..." << endl;

        // Reset to default visibility.
        func->setVisibility(GlobalValue::DefaultVisibility);

        // Reset to default linkage.
        func->setLinkage(GlobalValue::ExternalLinkage);

        // Replace call to this function in module with call to launcher.
        bool found = false;
        for (Module::iterator f2 = m2->begin(), fe2 = m2->end(); (f2 != fe2) && !found; f2++)
            for (Function::iterator bb = f2->begin(); (bb != f2->end()) && !found; bb++)
                for (BasicBlock::iterator i = bb->begin(); i != bb->end(); i++)
                {
                    // Check if instruction in focus is a call.
                    CallInst* call = dyn_cast<CallInst>(cast<Value>(i));
                    if (!call) continue;

                    // Check if function is called (needs -instcombine pass).
                    Function* callee = call->getCalledFunction();
                    if (!callee) continue;
                    if (callee->isDeclaration()) continue;
                    if (callee->getName() != func->getName()) continue;

                    // Create a constant array holding original called
                    // function name.
                    Constant* name = ConstantArray::get(
                                         context, callee->getName(), true);

                    // Create and initialize the memory buffer for name.
                    ArrayType* nameTy = cast<ArrayType>(name->getType());
                    AllocaInst* nameAlloc = new AllocaInst(nameTy, "", call);
                    StoreInst* nameInit = new StoreInst(name, nameAlloc, "", call);
                    Value* Idx[2];
                    Idx[0] = Constant::getNullValue(Type::getInt32Ty(context));
                    Idx[1] = ConstantInt::get(Type::getInt32Ty(context), 0);
                    GetElementPtrInst* namePtr = GetElementPtrInst::Create(nameAlloc, Idx, "", call);

                    // Add pointer to the original function string name.
                    SmallVector<Value*, 16> call_args;
                    call_args.push_back(namePtr);

                    // Add size of the aggregated arguments structure.
                    {
                        BitCastInst* BC = new BitCastInst(
                            call->getArgOperand(0), Type::getInt64PtrTy(context),
                            "", call);

                        LoadInst* LI = new LoadInst(BC, "", call);
                        call_args.push_back(LI);
                    }

                    // Add original aggregated structure argument.
                    call_args.push_back(call->getArgOperand(0));

                    // Create new function call with new call arguments
                    // and copy old call properties.
                    CallInst* newcall = CallInst::Create(launch, call_args, "", call);
                    //newcall->takeName(call);
                    newcall->setCallingConv(call->getCallingConv());
                    newcall->setAttributes(call->getAttributes());
                    newcall->setDebugLoc(call->getDebugLoc());

                    // Replace old call with new one.
                    call->replaceAllUsesWith(newcall);
                    call->eraseFromParent();

                    found = true;
                    break;
                }
    }

    //m2.get()->dump();

    //
    // 6) Apply optimization passes to the resulting common
    // module.
    //
    {
        PassManager manager;
        manager.add(createLowerSetJmpPass());
        PassManagerBuilder builder;
        builder.Inliner = createFunctionInliningPass();
        builder.OptLevel = 3;
        builder.DisableSimplifyLibCalls = true;
        builder.populateModulePassManager(manager);
        manager.run(*m2.get());
    }

    //m2.get()->dump();

    //
    // 7) Embed the resulting module into object file.
    //
    {
        string ir_string;
        raw_string_ostream ir(ir_string);
        ir << (*m2.get());
        celf e(tmp_output.getFilename(), output);
        e.getSection(".data")->addSymbol(
            "__kernelgen_" + string(input),
            ir_string.c_str(), ir_string.size() + 1);
    }

    return 0;
}
Esempio n. 27
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...
  raw_ostream *Out = 0;
  bool DeleteStream = false;
  if (!NoOutput && !AnalyzeOnly) {
    if (OutputFilename == "-") {
      // Print to stdout.
      Out = &outs();
      // If we're printing a bitcode file, switch stdout to binary mode.
      // FIXME: This switches outs() globally, not just for the bitcode output.
      if (!OutputAssembly)
        sys::Program::ChangeStdoutToBinary(); 
    } else {
      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;
        }
        DeleteStream = true;
      }
    }
  }

  // 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);

  OwningPtr<PassManager> FPasses;
  if (OptLevelO1 || OptLevelO2 || OptLevelO3) {
    FPasses.reset(new PassManager());
    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->run(*M.get());

  // 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 (DeleteStream)
    delete Out;
  return 0;
}
Esempio n. 28
0
void jl_dump_native(const char *bc_fname, const char *obj_fname, const char *sysimg_data, size_t sysimg_len)
{
    assert(imaging_mode);
    // We don't want to use MCJIT's target machine because
    // it uses the large code model and we may potentially
    // want less optimizations there.
    Triple TheTriple = Triple(jl_TargetMachine->getTargetTriple());
    // make sure to emit the native object format, even if FORCE_ELF was set in codegen
#if defined(_OS_WINDOWS_)
#ifdef LLVM35
    TheTriple.setObjectFormat(Triple::COFF);
#else
    TheTriple.setEnvironment(Triple::UnknownEnvironment);
#endif
#elif defined(_OS_DARWIN_)
#ifdef LLVM35
    TheTriple.setObjectFormat(Triple::MachO);
#else
    TheTriple.setEnvironment(Triple::MachO);
#endif
#endif
#ifdef LLVM35
    std::unique_ptr<TargetMachine>
#else
    OwningPtr<TargetMachine>
#endif
    TM(jl_TargetMachine->getTarget().createTargetMachine(
        TheTriple.getTriple(),
        jl_TargetMachine->getTargetCPU(),
        jl_TargetMachine->getTargetFeatureString(),
        jl_TargetMachine->Options,
#if defined(_OS_LINUX_) || defined(_OS_FREEBSD_)
        Reloc::PIC_,
#elif defined(LLVM39)
        Optional<Reloc::Model>(),
#else
        Reloc::Default,
#endif
        CodeModel::Default,
        CodeGenOpt::Aggressive // -O3 TODO: respect command -O0 flag?
        ));

#ifdef LLVM37
    legacy::PassManager PM;
#else
    PassManager PM;
#endif
#ifndef LLVM37
    PM.add(new TargetLibraryInfo(Triple(TM->getTargetTriple())));
#else
    PM.add(new TargetLibraryInfoWrapperPass(Triple(TM->getTargetTriple())));
#endif


    // set up optimization passes
#ifdef LLVM37
    // No DataLayout pass needed anymore.
#elif defined(LLVM36)
    PM.add(new DataLayoutPass());
#elif defined(LLVM35)
    PM.add(new DataLayoutPass(*jl_ExecutionEngine->getDataLayout()));
#else
    PM.add(new DataLayout(*jl_ExecutionEngine->getDataLayout()));
#endif

    addOptimizationPasses(&PM);

    std::unique_ptr<raw_fd_ostream> bc_OS;
    std::unique_ptr<raw_fd_ostream> obj_OS;
#ifdef LLVM37 // 3.7 simplified formatted output; just use the raw stream alone
    std::unique_ptr<raw_fd_ostream> &bc_FOS = bc_OS;
    std::unique_ptr<raw_fd_ostream> &obj_FOS = obj_OS;
#else
    std::unique_ptr<formatted_raw_ostream> bc_FOS;
    std::unique_ptr<formatted_raw_ostream> obj_FOS;
#endif

    if (bc_fname) {
#if defined(LLVM35)
        // call output handler directly to avoid special case handling of `-` filename
        int FD;
        std::error_code EC = sys::fs::openFileForWrite(bc_fname, FD, sys::fs::F_None);
        bc_OS.reset(new raw_fd_ostream(FD, true));
        std::string err;
        if (EC)
            err = "ERROR: failed to open --output-bc file '" + std::string(bc_fname) + "': " + EC.message();
#else
        std::string err;
        bc_OS.reset(new raw_fd_ostream(bc_fname, err, raw_fd_ostream::F_Binary));
#endif
        if (!err.empty())
            jl_safe_printf("%s\n", err.c_str());
        else {
#ifndef LLVM37
            bc_FOS.reset(new formatted_raw_ostream(*bc_OS.get()));
#endif
            PM.add(createBitcodeWriterPass(*bc_FOS.get()));     // Unroll small loops
        }
    }

    if (obj_fname) {
#if defined(LLVM35)
        // call output handler directly to avoid special case handling of `-` filename
        int FD;
        std::error_code EC = sys::fs::openFileForWrite(obj_fname, FD, sys::fs::F_None);
        obj_OS.reset(new raw_fd_ostream(FD, true));
        std::string err;
        if (EC)
            err = "ERROR: failed to open --output-o file '" + std::string(obj_fname) + "': " + EC.message();
#else
        std::string err;
        obj_OS.reset(new raw_fd_ostream(obj_fname, err, raw_fd_ostream::F_Binary));
#endif
        if (!err.empty())
            jl_safe_printf("%s\n", err.c_str());
        else {
#ifndef LLVM37
            obj_FOS.reset(new formatted_raw_ostream(*obj_OS.get()));
#endif
            if (TM->addPassesToEmitFile(PM, *obj_FOS.get(), TargetMachine::CGFT_ObjectFile, false)) {
                jl_safe_printf("ERROR: target does not support generation of object files\n");
            }
        }
    }

    ValueToValueMapTy VMap;
#if defined(USE_MCJIT) || defined(USE_ORCJIT)
    // now copy the module (if using the old JIT), since PM.run may modify it
    Module *clone = shadow_output;
#else
    Module *clone = CloneModule(shadow_output, VMap);
#endif

#ifdef LLVM37
    // Reset the target triple to make sure it matches the new target machine
    clone->setTargetTriple(TM->getTargetTriple().str());
#ifdef LLVM38
    clone->setDataLayout(TM->createDataLayout());
#else
    clone->setDataLayout(TM->getDataLayout()->getStringRepresentation());
#endif
#endif

    // add metadata information
    jl_gen_llvm_globaldata(clone, VMap, sysimg_data, sysimg_len);

    // do the actual work
    PM.run(*clone);
#if !defined(USE_MCJIT) && !defined(USE_ORCJIT)
    delete clone;
#endif
    imaging_mode = false;
}
Esempio n. 29
0
/// lintModule - Check a module for errors, printing messages on stderr.
///
void llvm::lintModule(const Module &M) {
    PassManager PM;
    Lint *V = new Lint();
    PM.add(V);
    PM.run(const_cast<Module&>(M));
}
Esempio n. 30
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
}