+ for (auto *GV : Drop)
+ drop(*GV);
+
+ 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();
+ // Unconditionally verify input since it is not verified before this
+ // point and has unknown origin.
+ PMB.VerifyInput = true;
+ PMB.VerifyOutput = !options::DisableVerify;
+ 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;
+ }
+ std::unique_ptr<TargetMachine> TM(TheTarget->createTargetMachine(
+ TripleStr, options::mcpu, Features.getString(), Options, RelocationModel,
+ CodeModel::Default, CGOptLevel));
+
+ runLTOPasses(*M, *TM);
+
+ if (options::TheOutputType == options::OT_SAVE_TEMPS)
+ saveBCFile(output_name + ".opt.bc", *M);
+
+ SmallString<128> Filename;
+ if (!options::obj_path.empty())
+ Filename = options::obj_path;
+ else if (options::TheOutputType == options::OT_SAVE_TEMPS)
+ Filename = output_name + ".o";
+
+ std::vector<SmallString<128>> Filenames(options::Parallelism);
+ bool TempOutFile = Filename.empty();