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 "llvm/Analysis/CGSCCPassManager.h"
11#include "llvm/Analysis/LoopAnalysisManager.h"
12#include "llvm/Analysis/RuntimeLibcallInfo.h"
13#include "llvm/Analysis/TargetLibraryInfo.h"
14#include "llvm/Analysis/TargetTransformInfo.h"
15#include "llvm/CodeGen/MachineFunctionAnalysisManager.h"
16#include "llvm/CodeGen/MachineModuleInfo.h"
17#include "llvm/IR/LegacyPassManager.h"
18#include "llvm/IR/PassManager.h"
19#include "llvm/Passes/PassBuilder.h"
20#include "llvm/Support/CodeGen.h"
21#include "llvm/Support/Error.h"
22#include "llvm/Support/ToolOutputFile.h"
23#include "llvm/Support/raw_ostream.h"
24#include "llvm/Target/CGPassBuilderOption.h"
25
26using namespace llvm;
27
28static cl::opt<cl::boolOrDefault>
29 ForceNewPM("force-new-pm-codegen",
30 cl::desc("Whether to force the NewPM on/off. Not setting the "
31 "option will default to what the target prefers."),
32 cl::init(Val: cl::boolOrDefault::BOU_UNSET));
33
34static Error
35runCodeGenPipelineLegacy(TargetMachine &TM, Module &M, raw_pwrite_stream &OS,
36 std::unique_ptr<ToolOutputFile> &DwoOS,
37 CodeGenFileType CGFT, bool PrintPipelinePasses,
38 bool DisableVerify, bool DisableSimplifyLibCalls) {
39 legacy::PassManager CodeGenPasses;
40 CodeGenPasses.add(
41 P: createTargetTransformInfoWrapperPass(TIRA: TM.getTargetIRAnalysis()));
42 // Add LibraryInfo.
43 TargetLibraryInfoImpl TLII(TM.getTargetTriple(), TM.Options.VecLib);
44 if (DisableSimplifyLibCalls)
45 TLII.disableAllFunctions();
46 CodeGenPasses.add(P: new TargetLibraryInfoWrapperPass(TLII));
47
48 const TargetOptions &Options = TM.Options;
49 CodeGenPasses.add(
50 P: new RuntimeLibraryInfoWrapper(Options.MCOptions.ABIName, Options.VecLib));
51
52 if (TM.addPassesToEmitFile(CodeGenPasses, OS, DwoOS ? &DwoOS->os() : nullptr,
53 CGFT, DisableVerify))
54 return createStringError(Fmt: "Failed to construct CodeGen pipeline");
55 CodeGenPasses.run(M);
56
57 return Error::success();
58}
59
60static Error runCodeGenPipelineNewPM(TargetMachine &TM, Module &M,
61 raw_pwrite_stream &OS,
62 std::unique_ptr<ToolOutputFile> &DwoOS,
63 CodeGenFileType CGFT, bool DisableVerify,
64 IntrusiveRefCntPtr<vfs::FileSystem> VFS) {
65 ModulePassManager MPM;
66 MachineFunctionAnalysisManager MFAM;
67 LoopAnalysisManager LAM;
68 FunctionAnalysisManager FAM;
69 CGSCCAnalysisManager CGAM;
70 ModuleAnalysisManager MAM;
71 CGPassBuilderOption Opt = getCGPassBuilderOption();
72 Opt.DisableVerify = DisableVerify;
73 MachineModuleInfo MMI(&TM);
74 PassInstrumentationCallbacks PIC;
75 PipelineTuningOptions PTOptions;
76 TargetMachine *TMPointer = &TM;
77 PassBuilder PB(TMPointer, PTOptions, std::nullopt, &PIC, VFS);
78 PB.registerModuleAnalyses(MAM);
79 PB.registerCGSCCAnalyses(CGAM);
80 PB.registerFunctionAnalyses(FAM);
81 PB.registerLoopAnalyses(LAM);
82 PB.registerMachineFunctionAnalyses(MFAM);
83 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM, MFAM: &MFAM);
84
85 MAM.registerPass(PassBuilder: [&] { return MachineModuleAnalysis(MMI); });
86
87 Error BuildPipelineError =
88 TM.buildCodeGenPipeline(MPM, MAM, Out&: OS, DwoOut: DwoOS ? &DwoOS->os() : nullptr,
89 FileType: CGFT, Opt, Ctx&: MMI.getContext(), PIC: &PIC);
90 if (BuildPipelineError)
91 return BuildPipelineError;
92
93 MPM.run(IR&: M, AM&: MAM);
94 return Error::success();
95}
96
97Error llvm::runCodeGenPipeline(TargetMachine &TM, Module &M,
98 raw_pwrite_stream &OS,
99 std::unique_ptr<ToolOutputFile> &DwoOS,
100 CodeGenFileType CGFT, bool PrintPipelinePasses,
101 bool DisableVerify, bool DisableSimplifyLibCalls,
102 IntrusiveRefCntPtr<vfs::FileSystem> VFS) {
103 if (ForceNewPM == cl::boolOrDefault::BOU_TRUE ||
104 (TM.shouldDefaultToNewPM() &&
105 ForceNewPM != cl::boolOrDefault::BOU_FALSE)) {
106 return runCodeGenPipelineNewPM(TM, M, OS, DwoOS, CGFT, DisableVerify, VFS);
107 }
108
109 return runCodeGenPipelineLegacy(TM, M, OS, DwoOS, CGFT, PrintPipelinePasses,
110 DisableVerify, DisableSimplifyLibCalls);
111}
112