- if (options::generate_bc_file != options::BC_NO) {
- std::string path;
- if (options::generate_bc_file == options::BC_ONLY)
- path = output_name;
- else if (!options::bc_path.empty())
- path = options::bc_path;
- else
- path = output_name + ".bc";
- std::string Error;
- if (!CodeGen->writeMergedModules(path.c_str(), Error))
- (*message)(LDPL_FATAL, "Failed to write the output file.");
- if (options::generate_bc_file == options::BC_ONLY) {
- delete CodeGen;
- exit(0);
- }
+ return Obj.takeModule();
+}
+
+static void runLTOPasses(Module &M, TargetMachine &TM) {
+ M.setDataLayout(TM.createDataLayout());
+
+ legacy::PassManager passes;
+ passes.add(createTargetTransformInfoWrapperPass(TM.getTargetIRAnalysis()));
+
+ PassManagerBuilder PMB;
+ PMB.LibraryInfo = new TargetLibraryInfoImpl(Triple(TM.getTargetTriple()));
+ PMB.Inliner = createFunctionInliningPass();
+ PMB.VerifyInput = true;
+ PMB.VerifyOutput = true;
+ PMB.LoopVectorize = true;
+ PMB.SLPVectorize = true;
+ PMB.OptLevel = options::OptLevel;
+ PMB.populateLTOPassManager(passes);
+ passes.run(M);
+}
+
+static void saveBCFile(StringRef Path, Module &M) {
+ std::error_code EC;
+ raw_fd_ostream OS(Path, EC, sys::fs::OpenFlags::F_None);
+ if (EC)
+ message(LDPL_FATAL, "Failed to write the output file.");
+ WriteBitcodeToFile(&M, OS, /* ShouldPreserveUseListOrder */ true);
+}
+
+static void codegen(std::unique_ptr<Module> M) {
+ const std::string &TripleStr = M->getTargetTriple();
+ Triple TheTriple(TripleStr);
+
+ std::string ErrMsg;
+ const Target *TheTarget = TargetRegistry::lookupTarget(TripleStr, ErrMsg);
+ if (!TheTarget)
+ message(LDPL_FATAL, "Target not found: %s", ErrMsg.c_str());
+
+ if (unsigned NumOpts = options::extra.size())
+ cl::ParseCommandLineOptions(NumOpts, &options::extra[0]);
+
+ SubtargetFeatures Features;
+ Features.getDefaultSubtargetFeatures(TheTriple);
+ for (const std::string &A : MAttrs)
+ Features.AddFeature(A);
+
+ TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
+ CodeGenOpt::Level CGOptLevel;
+ switch (options::OptLevel) {
+ case 0:
+ CGOptLevel = CodeGenOpt::None;
+ break;
+ case 1:
+ CGOptLevel = CodeGenOpt::Less;
+ break;
+ case 2:
+ CGOptLevel = CodeGenOpt::Default;
+ break;
+ case 3:
+ CGOptLevel = CodeGenOpt::Aggressive;
+ break;