1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "llvm/Passes/RunCodeGen.h"
10#include "PassesOptions.h"
11#include "llvm/Analysis/CGSCCPassManager.h"
12#include "llvm/Analysis/LoopAnalysisManager.h"
13#include "llvm/Analysis/RuntimeLibcallInfo.h"
14#include "llvm/Analysis/TargetLibraryInfo.h"
15#include "llvm/Analysis/TargetTransformInfo.h"
16#include "llvm/CodeGen/MachineFunctionAnalysisManager.h"
17#include "llvm/CodeGen/MachineModuleInfo.h"
18#include "llvm/IR/LegacyPassManager.h"
19#include "llvm/IR/PassManager.h"
20#include "llvm/Passes/PassBuilder.h"
21#include "llvm/Support/CodeGen.h"
22#include "llvm/Support/Error.h"
23#include "llvm/Support/ToolOutputFile.h"
24#include "llvm/Support/raw_ostream.h"
25#include "llvm/Target/CGPassBuilderOption.h"
26
27using namespace llvm;
28
29static Error runCodeGenPipelineLegacy(TargetMachine &TM, Module &M,
30 raw_pwrite_stream &OS,
31 std::unique_ptr<ToolOutputFile> &DwoOS,
32 CodeGenFileType CGFT, bool DisableVerify,
33 bool DisableSimplifyLibCalls) {
34 legacy::PassManager CodeGenPasses;
35 CodeGenPasses.add(
36 P: createTargetTransformInfoWrapperPass(TIRA: TM.getTargetIRAnalysis()));
37 // Add LibraryInfo.
38 TargetLibraryInfoImpl TLII(TM.getTargetTriple(), TM.Options.VecLib);
39 if (DisableSimplifyLibCalls)
40 TLII.disableAllFunctions();
41 CodeGenPasses.add(P: new TargetLibraryInfoWrapperPass(TLII));
42
43 const TargetOptions &Options = TM.Options;
44 CodeGenPasses.add(
45 P: new RuntimeLibraryInfoWrapper(Options.MCOptions.ABIName, Options.VecLib));
46
47 if (TM.addPassesToEmitFile(CodeGenPasses, OS, DwoOS ? &DwoOS->os() : nullptr,
48 CGFT, DisableVerify))
49 return createStringError(Fmt: "Failed to construct CodeGen pipeline");
50 CodeGenPasses.run(M);
51
52 return Error::success();
53}
54
55static Error runCodeGenPipelineNewPM(TargetMachine &TM, Module &M,
56 raw_pwrite_stream &OS,
57 std::unique_ptr<ToolOutputFile> &DwoOS,
58 CodeGenFileType CGFT, bool DisableVerify,
59 IntrusiveRefCntPtr<vfs::FileSystem> VFS) {
60 ModulePassManager MPM;
61 MachineFunctionAnalysisManager MFAM;
62 LoopAnalysisManager LAM;
63 FunctionAnalysisManager FAM;
64 CGSCCAnalysisManager CGAM;
65 ModuleAnalysisManager MAM;
66 CGPassBuilderOption Opt = getCGPassBuilderOption();
67 Opt.DisableVerify = DisableVerify;
68 MachineModuleInfo MMI(&TM);
69 PassInstrumentationCallbacks PIC;
70 PipelineTuningOptions PTOptions;
71 TargetMachine *TMPointer = &TM;
72 PassBuilder PB(TMPointer, PTOptions, std::nullopt, &PIC, VFS);
73 PB.registerModuleAnalyses(MAM);
74 PB.registerCGSCCAnalyses(CGAM);
75 PB.registerFunctionAnalyses(FAM);
76 PB.registerLoopAnalyses(LAM);
77 PB.registerMachineFunctionAnalyses(MFAM);
78 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM, MFAM: &MFAM);
79
80 MAM.registerPass(PassBuilder: [&] { return MachineModuleAnalysis(MMI); });
81
82 Error BuildPipelineError =
83 TM.buildCodeGenPipeline(MPM, MAM, Out&: OS, DwoOut: DwoOS ? &DwoOS->os() : nullptr,
84 FileType: CGFT, Opt, Ctx&: MMI.getContext(), PIC: &PIC);
85 if (BuildPipelineError)
86 return BuildPipelineError;
87
88 MPM.run(IR&: M, AM&: MAM);
89 return Error::success();
90}
91
92Error llvm::runCodeGenPipeline(TargetMachine &TM, Module &M,
93 raw_pwrite_stream &OS,
94 std::unique_ptr<ToolOutputFile> &DwoOS,
95 CodeGenFileType CGFT, bool DisableVerify,
96 bool DisableSimplifyLibCalls,
97 IntrusiveRefCntPtr<vfs::FileSystem> VFS) {
98 if (valueOr(X: PassesOptions::Global.force_new_pm_codegen,
99 Default: TM.shouldDefaultToNewPM())) {
100 return runCodeGenPipelineNewPM(TM, M, OS, DwoOS, CGFT, DisableVerify, VFS);
101 }
102
103 return runCodeGenPipelineLegacy(TM, M, OS, DwoOS, CGFT, DisableVerify,
104 DisableSimplifyLibCalls);
105}
106