annotate llvm/lib/CodeGen/TargetPassConfig.cpp @ 152:e8a9b4f4d755

pull from 146
author anatofuz
date Wed, 11 Mar 2020 18:29:16 +0900
parents 1d019706d866
children f935e5e0dbe7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 //===- TargetPassConfig.cpp - Target independent code generation passes ---===//
anatofuz
parents:
diff changeset
2 //
anatofuz
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
anatofuz
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
anatofuz
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
anatofuz
parents:
diff changeset
6 //
anatofuz
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
8 //
anatofuz
parents:
diff changeset
9 // This file defines interfaces to access the target independent code
anatofuz
parents:
diff changeset
10 // generation passes provided by the LLVM backend.
anatofuz
parents:
diff changeset
11 //
anatofuz
parents:
diff changeset
12 //===---------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
13
anatofuz
parents:
diff changeset
14 #include "llvm/CodeGen/TargetPassConfig.h"
anatofuz
parents:
diff changeset
15 #include "llvm/ADT/DenseMap.h"
anatofuz
parents:
diff changeset
16 #include "llvm/ADT/SmallVector.h"
anatofuz
parents:
diff changeset
17 #include "llvm/ADT/StringRef.h"
anatofuz
parents:
diff changeset
18 #include "llvm/Analysis/BasicAliasAnalysis.h"
anatofuz
parents:
diff changeset
19 #include "llvm/Analysis/CFLAndersAliasAnalysis.h"
anatofuz
parents:
diff changeset
20 #include "llvm/Analysis/CFLSteensAliasAnalysis.h"
anatofuz
parents:
diff changeset
21 #include "llvm/Analysis/CallGraphSCCPass.h"
anatofuz
parents:
diff changeset
22 #include "llvm/Analysis/ScopedNoAliasAA.h"
anatofuz
parents:
diff changeset
23 #include "llvm/Analysis/TargetTransformInfo.h"
anatofuz
parents:
diff changeset
24 #include "llvm/Analysis/TypeBasedAliasAnalysis.h"
anatofuz
parents:
diff changeset
25 #include "llvm/CodeGen/CSEConfigBase.h"
anatofuz
parents:
diff changeset
26 #include "llvm/CodeGen/MachineFunctionPass.h"
anatofuz
parents:
diff changeset
27 #include "llvm/CodeGen/MachinePassRegistry.h"
anatofuz
parents:
diff changeset
28 #include "llvm/CodeGen/Passes.h"
anatofuz
parents:
diff changeset
29 #include "llvm/CodeGen/RegAllocRegistry.h"
anatofuz
parents:
diff changeset
30 #include "llvm/IR/IRPrintingPasses.h"
anatofuz
parents:
diff changeset
31 #include "llvm/IR/LegacyPassManager.h"
anatofuz
parents:
diff changeset
32 #include "llvm/IR/Verifier.h"
anatofuz
parents:
diff changeset
33 #include "llvm/InitializePasses.h"
anatofuz
parents:
diff changeset
34 #include "llvm/MC/MCAsmInfo.h"
anatofuz
parents:
diff changeset
35 #include "llvm/MC/MCTargetOptions.h"
anatofuz
parents:
diff changeset
36 #include "llvm/Pass.h"
anatofuz
parents:
diff changeset
37 #include "llvm/Support/CodeGen.h"
anatofuz
parents:
diff changeset
38 #include "llvm/Support/CommandLine.h"
anatofuz
parents:
diff changeset
39 #include "llvm/Support/Compiler.h"
anatofuz
parents:
diff changeset
40 #include "llvm/Support/Debug.h"
anatofuz
parents:
diff changeset
41 #include "llvm/Support/ErrorHandling.h"
anatofuz
parents:
diff changeset
42 #include "llvm/Support/SaveAndRestore.h"
anatofuz
parents:
diff changeset
43 #include "llvm/Support/Threading.h"
anatofuz
parents:
diff changeset
44 #include "llvm/Target/TargetMachine.h"
anatofuz
parents:
diff changeset
45 #include "llvm/Transforms/Scalar.h"
anatofuz
parents:
diff changeset
46 #include "llvm/Transforms/Utils.h"
anatofuz
parents:
diff changeset
47 #include "llvm/Transforms/Utils/SymbolRewriter.h"
anatofuz
parents:
diff changeset
48 #include <cassert>
anatofuz
parents:
diff changeset
49 #include <string>
anatofuz
parents:
diff changeset
50
anatofuz
parents:
diff changeset
51 using namespace llvm;
anatofuz
parents:
diff changeset
52
anatofuz
parents:
diff changeset
53 static cl::opt<bool>
anatofuz
parents:
diff changeset
54 EnableIPRA("enable-ipra", cl::init(false), cl::Hidden,
anatofuz
parents:
diff changeset
55 cl::desc("Enable interprocedural register allocation "
anatofuz
parents:
diff changeset
56 "to reduce load/store at procedure calls."));
anatofuz
parents:
diff changeset
57 static cl::opt<bool> DisablePostRASched("disable-post-ra", cl::Hidden,
anatofuz
parents:
diff changeset
58 cl::desc("Disable Post Regalloc Scheduler"));
anatofuz
parents:
diff changeset
59 static cl::opt<bool> DisableBranchFold("disable-branch-fold", cl::Hidden,
anatofuz
parents:
diff changeset
60 cl::desc("Disable branch folding"));
anatofuz
parents:
diff changeset
61 static cl::opt<bool> DisableTailDuplicate("disable-tail-duplicate", cl::Hidden,
anatofuz
parents:
diff changeset
62 cl::desc("Disable tail duplication"));
anatofuz
parents:
diff changeset
63 static cl::opt<bool> DisableEarlyTailDup("disable-early-taildup", cl::Hidden,
anatofuz
parents:
diff changeset
64 cl::desc("Disable pre-register allocation tail duplication"));
anatofuz
parents:
diff changeset
65 static cl::opt<bool> DisableBlockPlacement("disable-block-placement",
anatofuz
parents:
diff changeset
66 cl::Hidden, cl::desc("Disable probability-driven block placement"));
anatofuz
parents:
diff changeset
67 static cl::opt<bool> EnableBlockPlacementStats("enable-block-placement-stats",
anatofuz
parents:
diff changeset
68 cl::Hidden, cl::desc("Collect probability-driven block placement stats"));
anatofuz
parents:
diff changeset
69 static cl::opt<bool> DisableSSC("disable-ssc", cl::Hidden,
anatofuz
parents:
diff changeset
70 cl::desc("Disable Stack Slot Coloring"));
anatofuz
parents:
diff changeset
71 static cl::opt<bool> DisableMachineDCE("disable-machine-dce", cl::Hidden,
anatofuz
parents:
diff changeset
72 cl::desc("Disable Machine Dead Code Elimination"));
anatofuz
parents:
diff changeset
73 static cl::opt<bool> DisableEarlyIfConversion("disable-early-ifcvt", cl::Hidden,
anatofuz
parents:
diff changeset
74 cl::desc("Disable Early If-conversion"));
anatofuz
parents:
diff changeset
75 static cl::opt<bool> DisableMachineLICM("disable-machine-licm", cl::Hidden,
anatofuz
parents:
diff changeset
76 cl::desc("Disable Machine LICM"));
anatofuz
parents:
diff changeset
77 static cl::opt<bool> DisableMachineCSE("disable-machine-cse", cl::Hidden,
anatofuz
parents:
diff changeset
78 cl::desc("Disable Machine Common Subexpression Elimination"));
anatofuz
parents:
diff changeset
79 static cl::opt<cl::boolOrDefault> OptimizeRegAlloc(
anatofuz
parents:
diff changeset
80 "optimize-regalloc", cl::Hidden,
anatofuz
parents:
diff changeset
81 cl::desc("Enable optimized register allocation compilation path."));
anatofuz
parents:
diff changeset
82 static cl::opt<bool> DisablePostRAMachineLICM("disable-postra-machine-licm",
anatofuz
parents:
diff changeset
83 cl::Hidden,
anatofuz
parents:
diff changeset
84 cl::desc("Disable Machine LICM"));
anatofuz
parents:
diff changeset
85 static cl::opt<bool> DisableMachineSink("disable-machine-sink", cl::Hidden,
anatofuz
parents:
diff changeset
86 cl::desc("Disable Machine Sinking"));
anatofuz
parents:
diff changeset
87 static cl::opt<bool> DisablePostRAMachineSink("disable-postra-machine-sink",
anatofuz
parents:
diff changeset
88 cl::Hidden,
anatofuz
parents:
diff changeset
89 cl::desc("Disable PostRA Machine Sinking"));
anatofuz
parents:
diff changeset
90 static cl::opt<bool> DisableLSR("disable-lsr", cl::Hidden,
anatofuz
parents:
diff changeset
91 cl::desc("Disable Loop Strength Reduction Pass"));
anatofuz
parents:
diff changeset
92 static cl::opt<bool> DisableConstantHoisting("disable-constant-hoisting",
anatofuz
parents:
diff changeset
93 cl::Hidden, cl::desc("Disable ConstantHoisting"));
anatofuz
parents:
diff changeset
94 static cl::opt<bool> DisableCGP("disable-cgp", cl::Hidden,
anatofuz
parents:
diff changeset
95 cl::desc("Disable Codegen Prepare"));
anatofuz
parents:
diff changeset
96 static cl::opt<bool> DisableCopyProp("disable-copyprop", cl::Hidden,
anatofuz
parents:
diff changeset
97 cl::desc("Disable Copy Propagation pass"));
anatofuz
parents:
diff changeset
98 static cl::opt<bool> DisablePartialLibcallInlining("disable-partial-libcall-inlining",
anatofuz
parents:
diff changeset
99 cl::Hidden, cl::desc("Disable Partial Libcall Inlining"));
anatofuz
parents:
diff changeset
100 static cl::opt<bool> EnableImplicitNullChecks(
anatofuz
parents:
diff changeset
101 "enable-implicit-null-checks",
anatofuz
parents:
diff changeset
102 cl::desc("Fold null checks into faulting memory operations"),
anatofuz
parents:
diff changeset
103 cl::init(false), cl::Hidden);
anatofuz
parents:
diff changeset
104 static cl::opt<bool> DisableMergeICmps("disable-mergeicmps",
anatofuz
parents:
diff changeset
105 cl::desc("Disable MergeICmps Pass"),
anatofuz
parents:
diff changeset
106 cl::init(false), cl::Hidden);
anatofuz
parents:
diff changeset
107 static cl::opt<bool> PrintLSR("print-lsr-output", cl::Hidden,
anatofuz
parents:
diff changeset
108 cl::desc("Print LLVM IR produced by the loop-reduce pass"));
anatofuz
parents:
diff changeset
109 static cl::opt<bool> PrintISelInput("print-isel-input", cl::Hidden,
anatofuz
parents:
diff changeset
110 cl::desc("Print LLVM IR input to isel pass"));
anatofuz
parents:
diff changeset
111 static cl::opt<bool> PrintGCInfo("print-gc", cl::Hidden,
anatofuz
parents:
diff changeset
112 cl::desc("Dump garbage collector data"));
anatofuz
parents:
diff changeset
113 static cl::opt<cl::boolOrDefault>
anatofuz
parents:
diff changeset
114 VerifyMachineCode("verify-machineinstrs", cl::Hidden,
anatofuz
parents:
diff changeset
115 cl::desc("Verify generated machine code"),
anatofuz
parents:
diff changeset
116 cl::ZeroOrMore);
anatofuz
parents:
diff changeset
117 enum RunOutliner { AlwaysOutline, NeverOutline, TargetDefault };
anatofuz
parents:
diff changeset
118 // Enable or disable the MachineOutliner.
anatofuz
parents:
diff changeset
119 static cl::opt<RunOutliner> EnableMachineOutliner(
anatofuz
parents:
diff changeset
120 "enable-machine-outliner", cl::desc("Enable the machine outliner"),
anatofuz
parents:
diff changeset
121 cl::Hidden, cl::ValueOptional, cl::init(TargetDefault),
anatofuz
parents:
diff changeset
122 cl::values(clEnumValN(AlwaysOutline, "always",
anatofuz
parents:
diff changeset
123 "Run on all functions guaranteed to be beneficial"),
anatofuz
parents:
diff changeset
124 clEnumValN(NeverOutline, "never", "Disable all outlining"),
anatofuz
parents:
diff changeset
125 // Sentinel value for unspecified option.
anatofuz
parents:
diff changeset
126 clEnumValN(AlwaysOutline, "", "")));
anatofuz
parents:
diff changeset
127 // Enable or disable FastISel. Both options are needed, because
anatofuz
parents:
diff changeset
128 // FastISel is enabled by default with -fast, and we wish to be
anatofuz
parents:
diff changeset
129 // able to enable or disable fast-isel independently from -O0.
anatofuz
parents:
diff changeset
130 static cl::opt<cl::boolOrDefault>
anatofuz
parents:
diff changeset
131 EnableFastISelOption("fast-isel", cl::Hidden,
anatofuz
parents:
diff changeset
132 cl::desc("Enable the \"fast\" instruction selector"));
anatofuz
parents:
diff changeset
133
anatofuz
parents:
diff changeset
134 static cl::opt<cl::boolOrDefault> EnableGlobalISelOption(
anatofuz
parents:
diff changeset
135 "global-isel", cl::Hidden,
anatofuz
parents:
diff changeset
136 cl::desc("Enable the \"global\" instruction selector"));
anatofuz
parents:
diff changeset
137
anatofuz
parents:
diff changeset
138 static cl::opt<std::string> PrintMachineInstrs(
anatofuz
parents:
diff changeset
139 "print-machineinstrs", cl::ValueOptional, cl::desc("Print machine instrs"),
anatofuz
parents:
diff changeset
140 cl::value_desc("pass-name"), cl::init("option-unspecified"), cl::Hidden);
anatofuz
parents:
diff changeset
141
anatofuz
parents:
diff changeset
142 static cl::opt<GlobalISelAbortMode> EnableGlobalISelAbort(
anatofuz
parents:
diff changeset
143 "global-isel-abort", cl::Hidden,
anatofuz
parents:
diff changeset
144 cl::desc("Enable abort calls when \"global\" instruction selection "
anatofuz
parents:
diff changeset
145 "fails to lower/select an instruction"),
anatofuz
parents:
diff changeset
146 cl::values(
anatofuz
parents:
diff changeset
147 clEnumValN(GlobalISelAbortMode::Disable, "0", "Disable the abort"),
anatofuz
parents:
diff changeset
148 clEnumValN(GlobalISelAbortMode::Enable, "1", "Enable the abort"),
anatofuz
parents:
diff changeset
149 clEnumValN(GlobalISelAbortMode::DisableWithDiag, "2",
anatofuz
parents:
diff changeset
150 "Disable the abort but emit a diagnostic on failure")));
anatofuz
parents:
diff changeset
151
anatofuz
parents:
diff changeset
152 // Temporary option to allow experimenting with MachineScheduler as a post-RA
anatofuz
parents:
diff changeset
153 // scheduler. Targets can "properly" enable this with
anatofuz
parents:
diff changeset
154 // substitutePass(&PostRASchedulerID, &PostMachineSchedulerID).
anatofuz
parents:
diff changeset
155 // Targets can return true in targetSchedulesPostRAScheduling() and
anatofuz
parents:
diff changeset
156 // insert a PostRA scheduling pass wherever it wants.
anatofuz
parents:
diff changeset
157 static cl::opt<bool> MISchedPostRA(
anatofuz
parents:
diff changeset
158 "misched-postra", cl::Hidden,
anatofuz
parents:
diff changeset
159 cl::desc(
anatofuz
parents:
diff changeset
160 "Run MachineScheduler post regalloc (independent of preRA sched)"));
anatofuz
parents:
diff changeset
161
anatofuz
parents:
diff changeset
162 // Experimental option to run live interval analysis early.
anatofuz
parents:
diff changeset
163 static cl::opt<bool> EarlyLiveIntervals("early-live-intervals", cl::Hidden,
anatofuz
parents:
diff changeset
164 cl::desc("Run live interval analysis earlier in the pipeline"));
anatofuz
parents:
diff changeset
165
anatofuz
parents:
diff changeset
166 // Experimental option to use CFL-AA in codegen
anatofuz
parents:
diff changeset
167 enum class CFLAAType { None, Steensgaard, Andersen, Both };
anatofuz
parents:
diff changeset
168 static cl::opt<CFLAAType> UseCFLAA(
anatofuz
parents:
diff changeset
169 "use-cfl-aa-in-codegen", cl::init(CFLAAType::None), cl::Hidden,
anatofuz
parents:
diff changeset
170 cl::desc("Enable the new, experimental CFL alias analysis in CodeGen"),
anatofuz
parents:
diff changeset
171 cl::values(clEnumValN(CFLAAType::None, "none", "Disable CFL-AA"),
anatofuz
parents:
diff changeset
172 clEnumValN(CFLAAType::Steensgaard, "steens",
anatofuz
parents:
diff changeset
173 "Enable unification-based CFL-AA"),
anatofuz
parents:
diff changeset
174 clEnumValN(CFLAAType::Andersen, "anders",
anatofuz
parents:
diff changeset
175 "Enable inclusion-based CFL-AA"),
anatofuz
parents:
diff changeset
176 clEnumValN(CFLAAType::Both, "both",
anatofuz
parents:
diff changeset
177 "Enable both variants of CFL-AA")));
anatofuz
parents:
diff changeset
178
anatofuz
parents:
diff changeset
179 /// Option names for limiting the codegen pipeline.
anatofuz
parents:
diff changeset
180 /// Those are used in error reporting and we didn't want
anatofuz
parents:
diff changeset
181 /// to duplicate their names all over the place.
anatofuz
parents:
diff changeset
182 static const char StartAfterOptName[] = "start-after";
anatofuz
parents:
diff changeset
183 static const char StartBeforeOptName[] = "start-before";
anatofuz
parents:
diff changeset
184 static const char StopAfterOptName[] = "stop-after";
anatofuz
parents:
diff changeset
185 static const char StopBeforeOptName[] = "stop-before";
anatofuz
parents:
diff changeset
186
anatofuz
parents:
diff changeset
187 static cl::opt<std::string>
anatofuz
parents:
diff changeset
188 StartAfterOpt(StringRef(StartAfterOptName),
anatofuz
parents:
diff changeset
189 cl::desc("Resume compilation after a specific pass"),
anatofuz
parents:
diff changeset
190 cl::value_desc("pass-name"), cl::init(""), cl::Hidden);
anatofuz
parents:
diff changeset
191
anatofuz
parents:
diff changeset
192 static cl::opt<std::string>
anatofuz
parents:
diff changeset
193 StartBeforeOpt(StringRef(StartBeforeOptName),
anatofuz
parents:
diff changeset
194 cl::desc("Resume compilation before a specific pass"),
anatofuz
parents:
diff changeset
195 cl::value_desc("pass-name"), cl::init(""), cl::Hidden);
anatofuz
parents:
diff changeset
196
anatofuz
parents:
diff changeset
197 static cl::opt<std::string>
anatofuz
parents:
diff changeset
198 StopAfterOpt(StringRef(StopAfterOptName),
anatofuz
parents:
diff changeset
199 cl::desc("Stop compilation after a specific pass"),
anatofuz
parents:
diff changeset
200 cl::value_desc("pass-name"), cl::init(""), cl::Hidden);
anatofuz
parents:
diff changeset
201
anatofuz
parents:
diff changeset
202 static cl::opt<std::string>
anatofuz
parents:
diff changeset
203 StopBeforeOpt(StringRef(StopBeforeOptName),
anatofuz
parents:
diff changeset
204 cl::desc("Stop compilation before a specific pass"),
anatofuz
parents:
diff changeset
205 cl::value_desc("pass-name"), cl::init(""), cl::Hidden);
anatofuz
parents:
diff changeset
206
anatofuz
parents:
diff changeset
207 /// Allow standard passes to be disabled by command line options. This supports
anatofuz
parents:
diff changeset
208 /// simple binary flags that either suppress the pass or do nothing.
anatofuz
parents:
diff changeset
209 /// i.e. -disable-mypass=false has no effect.
anatofuz
parents:
diff changeset
210 /// These should be converted to boolOrDefault in order to use applyOverride.
anatofuz
parents:
diff changeset
211 static IdentifyingPassPtr applyDisable(IdentifyingPassPtr PassID,
anatofuz
parents:
diff changeset
212 bool Override) {
anatofuz
parents:
diff changeset
213 if (Override)
anatofuz
parents:
diff changeset
214 return IdentifyingPassPtr();
anatofuz
parents:
diff changeset
215 return PassID;
anatofuz
parents:
diff changeset
216 }
anatofuz
parents:
diff changeset
217
anatofuz
parents:
diff changeset
218 /// Allow standard passes to be disabled by the command line, regardless of who
anatofuz
parents:
diff changeset
219 /// is adding the pass.
anatofuz
parents:
diff changeset
220 ///
anatofuz
parents:
diff changeset
221 /// StandardID is the pass identified in the standard pass pipeline and provided
anatofuz
parents:
diff changeset
222 /// to addPass(). It may be a target-specific ID in the case that the target
anatofuz
parents:
diff changeset
223 /// directly adds its own pass, but in that case we harmlessly fall through.
anatofuz
parents:
diff changeset
224 ///
anatofuz
parents:
diff changeset
225 /// TargetID is the pass that the target has configured to override StandardID.
anatofuz
parents:
diff changeset
226 ///
anatofuz
parents:
diff changeset
227 /// StandardID may be a pseudo ID. In that case TargetID is the name of the real
anatofuz
parents:
diff changeset
228 /// pass to run. This allows multiple options to control a single pass depending
anatofuz
parents:
diff changeset
229 /// on where in the pipeline that pass is added.
anatofuz
parents:
diff changeset
230 static IdentifyingPassPtr overridePass(AnalysisID StandardID,
anatofuz
parents:
diff changeset
231 IdentifyingPassPtr TargetID) {
anatofuz
parents:
diff changeset
232 if (StandardID == &PostRASchedulerID)
anatofuz
parents:
diff changeset
233 return applyDisable(TargetID, DisablePostRASched);
anatofuz
parents:
diff changeset
234
anatofuz
parents:
diff changeset
235 if (StandardID == &BranchFolderPassID)
anatofuz
parents:
diff changeset
236 return applyDisable(TargetID, DisableBranchFold);
anatofuz
parents:
diff changeset
237
anatofuz
parents:
diff changeset
238 if (StandardID == &TailDuplicateID)
anatofuz
parents:
diff changeset
239 return applyDisable(TargetID, DisableTailDuplicate);
anatofuz
parents:
diff changeset
240
anatofuz
parents:
diff changeset
241 if (StandardID == &EarlyTailDuplicateID)
anatofuz
parents:
diff changeset
242 return applyDisable(TargetID, DisableEarlyTailDup);
anatofuz
parents:
diff changeset
243
anatofuz
parents:
diff changeset
244 if (StandardID == &MachineBlockPlacementID)
anatofuz
parents:
diff changeset
245 return applyDisable(TargetID, DisableBlockPlacement);
anatofuz
parents:
diff changeset
246
anatofuz
parents:
diff changeset
247 if (StandardID == &StackSlotColoringID)
anatofuz
parents:
diff changeset
248 return applyDisable(TargetID, DisableSSC);
anatofuz
parents:
diff changeset
249
anatofuz
parents:
diff changeset
250 if (StandardID == &DeadMachineInstructionElimID)
anatofuz
parents:
diff changeset
251 return applyDisable(TargetID, DisableMachineDCE);
anatofuz
parents:
diff changeset
252
anatofuz
parents:
diff changeset
253 if (StandardID == &EarlyIfConverterID)
anatofuz
parents:
diff changeset
254 return applyDisable(TargetID, DisableEarlyIfConversion);
anatofuz
parents:
diff changeset
255
anatofuz
parents:
diff changeset
256 if (StandardID == &EarlyMachineLICMID)
anatofuz
parents:
diff changeset
257 return applyDisable(TargetID, DisableMachineLICM);
anatofuz
parents:
diff changeset
258
anatofuz
parents:
diff changeset
259 if (StandardID == &MachineCSEID)
anatofuz
parents:
diff changeset
260 return applyDisable(TargetID, DisableMachineCSE);
anatofuz
parents:
diff changeset
261
anatofuz
parents:
diff changeset
262 if (StandardID == &MachineLICMID)
anatofuz
parents:
diff changeset
263 return applyDisable(TargetID, DisablePostRAMachineLICM);
anatofuz
parents:
diff changeset
264
anatofuz
parents:
diff changeset
265 if (StandardID == &MachineSinkingID)
anatofuz
parents:
diff changeset
266 return applyDisable(TargetID, DisableMachineSink);
anatofuz
parents:
diff changeset
267
anatofuz
parents:
diff changeset
268 if (StandardID == &PostRAMachineSinkingID)
anatofuz
parents:
diff changeset
269 return applyDisable(TargetID, DisablePostRAMachineSink);
anatofuz
parents:
diff changeset
270
anatofuz
parents:
diff changeset
271 if (StandardID == &MachineCopyPropagationID)
anatofuz
parents:
diff changeset
272 return applyDisable(TargetID, DisableCopyProp);
anatofuz
parents:
diff changeset
273
anatofuz
parents:
diff changeset
274 return TargetID;
anatofuz
parents:
diff changeset
275 }
anatofuz
parents:
diff changeset
276
anatofuz
parents:
diff changeset
277 //===---------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
278 /// TargetPassConfig
anatofuz
parents:
diff changeset
279 //===---------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
280
anatofuz
parents:
diff changeset
281 INITIALIZE_PASS(TargetPassConfig, "targetpassconfig",
anatofuz
parents:
diff changeset
282 "Target Pass Configuration", false, false)
anatofuz
parents:
diff changeset
283 char TargetPassConfig::ID = 0;
anatofuz
parents:
diff changeset
284
anatofuz
parents:
diff changeset
285 namespace {
anatofuz
parents:
diff changeset
286
anatofuz
parents:
diff changeset
287 struct InsertedPass {
anatofuz
parents:
diff changeset
288 AnalysisID TargetPassID;
anatofuz
parents:
diff changeset
289 IdentifyingPassPtr InsertedPassID;
anatofuz
parents:
diff changeset
290 bool VerifyAfter;
anatofuz
parents:
diff changeset
291 bool PrintAfter;
anatofuz
parents:
diff changeset
292
anatofuz
parents:
diff changeset
293 InsertedPass(AnalysisID TargetPassID, IdentifyingPassPtr InsertedPassID,
anatofuz
parents:
diff changeset
294 bool VerifyAfter, bool PrintAfter)
anatofuz
parents:
diff changeset
295 : TargetPassID(TargetPassID), InsertedPassID(InsertedPassID),
anatofuz
parents:
diff changeset
296 VerifyAfter(VerifyAfter), PrintAfter(PrintAfter) {}
anatofuz
parents:
diff changeset
297
anatofuz
parents:
diff changeset
298 Pass *getInsertedPass() const {
anatofuz
parents:
diff changeset
299 assert(InsertedPassID.isValid() && "Illegal Pass ID!");
anatofuz
parents:
diff changeset
300 if (InsertedPassID.isInstance())
anatofuz
parents:
diff changeset
301 return InsertedPassID.getInstance();
anatofuz
parents:
diff changeset
302 Pass *NP = Pass::createPass(InsertedPassID.getID());
anatofuz
parents:
diff changeset
303 assert(NP && "Pass ID not registered");
anatofuz
parents:
diff changeset
304 return NP;
anatofuz
parents:
diff changeset
305 }
anatofuz
parents:
diff changeset
306 };
anatofuz
parents:
diff changeset
307
anatofuz
parents:
diff changeset
308 } // end anonymous namespace
anatofuz
parents:
diff changeset
309
anatofuz
parents:
diff changeset
310 namespace llvm {
anatofuz
parents:
diff changeset
311
anatofuz
parents:
diff changeset
312 class PassConfigImpl {
anatofuz
parents:
diff changeset
313 public:
anatofuz
parents:
diff changeset
314 // List of passes explicitly substituted by this target. Normally this is
anatofuz
parents:
diff changeset
315 // empty, but it is a convenient way to suppress or replace specific passes
anatofuz
parents:
diff changeset
316 // that are part of a standard pass pipeline without overridding the entire
anatofuz
parents:
diff changeset
317 // pipeline. This mechanism allows target options to inherit a standard pass's
anatofuz
parents:
diff changeset
318 // user interface. For example, a target may disable a standard pass by
anatofuz
parents:
diff changeset
319 // default by substituting a pass ID of zero, and the user may still enable
anatofuz
parents:
diff changeset
320 // that standard pass with an explicit command line option.
anatofuz
parents:
diff changeset
321 DenseMap<AnalysisID,IdentifyingPassPtr> TargetPasses;
anatofuz
parents:
diff changeset
322
anatofuz
parents:
diff changeset
323 /// Store the pairs of <AnalysisID, AnalysisID> of which the second pass
anatofuz
parents:
diff changeset
324 /// is inserted after each instance of the first one.
anatofuz
parents:
diff changeset
325 SmallVector<InsertedPass, 4> InsertedPasses;
anatofuz
parents:
diff changeset
326 };
anatofuz
parents:
diff changeset
327
anatofuz
parents:
diff changeset
328 } // end namespace llvm
anatofuz
parents:
diff changeset
329
anatofuz
parents:
diff changeset
330 // Out of line virtual method.
anatofuz
parents:
diff changeset
331 TargetPassConfig::~TargetPassConfig() {
anatofuz
parents:
diff changeset
332 delete Impl;
anatofuz
parents:
diff changeset
333 }
anatofuz
parents:
diff changeset
334
anatofuz
parents:
diff changeset
335 static const PassInfo *getPassInfo(StringRef PassName) {
anatofuz
parents:
diff changeset
336 if (PassName.empty())
anatofuz
parents:
diff changeset
337 return nullptr;
anatofuz
parents:
diff changeset
338
anatofuz
parents:
diff changeset
339 const PassRegistry &PR = *PassRegistry::getPassRegistry();
anatofuz
parents:
diff changeset
340 const PassInfo *PI = PR.getPassInfo(PassName);
anatofuz
parents:
diff changeset
341 if (!PI)
anatofuz
parents:
diff changeset
342 report_fatal_error(Twine('\"') + Twine(PassName) +
anatofuz
parents:
diff changeset
343 Twine("\" pass is not registered."));
anatofuz
parents:
diff changeset
344 return PI;
anatofuz
parents:
diff changeset
345 }
anatofuz
parents:
diff changeset
346
anatofuz
parents:
diff changeset
347 static AnalysisID getPassIDFromName(StringRef PassName) {
anatofuz
parents:
diff changeset
348 const PassInfo *PI = getPassInfo(PassName);
anatofuz
parents:
diff changeset
349 return PI ? PI->getTypeInfo() : nullptr;
anatofuz
parents:
diff changeset
350 }
anatofuz
parents:
diff changeset
351
anatofuz
parents:
diff changeset
352 static std::pair<StringRef, unsigned>
anatofuz
parents:
diff changeset
353 getPassNameAndInstanceNum(StringRef PassName) {
anatofuz
parents:
diff changeset
354 StringRef Name, InstanceNumStr;
anatofuz
parents:
diff changeset
355 std::tie(Name, InstanceNumStr) = PassName.split(',');
anatofuz
parents:
diff changeset
356
anatofuz
parents:
diff changeset
357 unsigned InstanceNum = 0;
anatofuz
parents:
diff changeset
358 if (!InstanceNumStr.empty() && InstanceNumStr.getAsInteger(10, InstanceNum))
anatofuz
parents:
diff changeset
359 report_fatal_error("invalid pass instance specifier " + PassName);
anatofuz
parents:
diff changeset
360
anatofuz
parents:
diff changeset
361 return std::make_pair(Name, InstanceNum);
anatofuz
parents:
diff changeset
362 }
anatofuz
parents:
diff changeset
363
anatofuz
parents:
diff changeset
364 void TargetPassConfig::setStartStopPasses() {
anatofuz
parents:
diff changeset
365 StringRef StartBeforeName;
anatofuz
parents:
diff changeset
366 std::tie(StartBeforeName, StartBeforeInstanceNum) =
anatofuz
parents:
diff changeset
367 getPassNameAndInstanceNum(StartBeforeOpt);
anatofuz
parents:
diff changeset
368
anatofuz
parents:
diff changeset
369 StringRef StartAfterName;
anatofuz
parents:
diff changeset
370 std::tie(StartAfterName, StartAfterInstanceNum) =
anatofuz
parents:
diff changeset
371 getPassNameAndInstanceNum(StartAfterOpt);
anatofuz
parents:
diff changeset
372
anatofuz
parents:
diff changeset
373 StringRef StopBeforeName;
anatofuz
parents:
diff changeset
374 std::tie(StopBeforeName, StopBeforeInstanceNum)
anatofuz
parents:
diff changeset
375 = getPassNameAndInstanceNum(StopBeforeOpt);
anatofuz
parents:
diff changeset
376
anatofuz
parents:
diff changeset
377 StringRef StopAfterName;
anatofuz
parents:
diff changeset
378 std::tie(StopAfterName, StopAfterInstanceNum)
anatofuz
parents:
diff changeset
379 = getPassNameAndInstanceNum(StopAfterOpt);
anatofuz
parents:
diff changeset
380
anatofuz
parents:
diff changeset
381 StartBefore = getPassIDFromName(StartBeforeName);
anatofuz
parents:
diff changeset
382 StartAfter = getPassIDFromName(StartAfterName);
anatofuz
parents:
diff changeset
383 StopBefore = getPassIDFromName(StopBeforeName);
anatofuz
parents:
diff changeset
384 StopAfter = getPassIDFromName(StopAfterName);
anatofuz
parents:
diff changeset
385 if (StartBefore && StartAfter)
anatofuz
parents:
diff changeset
386 report_fatal_error(Twine(StartBeforeOptName) + Twine(" and ") +
anatofuz
parents:
diff changeset
387 Twine(StartAfterOptName) + Twine(" specified!"));
anatofuz
parents:
diff changeset
388 if (StopBefore && StopAfter)
anatofuz
parents:
diff changeset
389 report_fatal_error(Twine(StopBeforeOptName) + Twine(" and ") +
anatofuz
parents:
diff changeset
390 Twine(StopAfterOptName) + Twine(" specified!"));
anatofuz
parents:
diff changeset
391 Started = (StartAfter == nullptr) && (StartBefore == nullptr);
anatofuz
parents:
diff changeset
392 }
anatofuz
parents:
diff changeset
393
anatofuz
parents:
diff changeset
394 // Out of line constructor provides default values for pass options and
anatofuz
parents:
diff changeset
395 // registers all common codegen passes.
anatofuz
parents:
diff changeset
396 TargetPassConfig::TargetPassConfig(LLVMTargetMachine &TM, PassManagerBase &pm)
anatofuz
parents:
diff changeset
397 : ImmutablePass(ID), PM(&pm), TM(&TM) {
anatofuz
parents:
diff changeset
398 Impl = new PassConfigImpl();
anatofuz
parents:
diff changeset
399
anatofuz
parents:
diff changeset
400 // Register all target independent codegen passes to activate their PassIDs,
anatofuz
parents:
diff changeset
401 // including this pass itself.
anatofuz
parents:
diff changeset
402 initializeCodeGen(*PassRegistry::getPassRegistry());
anatofuz
parents:
diff changeset
403
anatofuz
parents:
diff changeset
404 // Also register alias analysis passes required by codegen passes.
anatofuz
parents:
diff changeset
405 initializeBasicAAWrapperPassPass(*PassRegistry::getPassRegistry());
anatofuz
parents:
diff changeset
406 initializeAAResultsWrapperPassPass(*PassRegistry::getPassRegistry());
anatofuz
parents:
diff changeset
407
anatofuz
parents:
diff changeset
408 if (StringRef(PrintMachineInstrs.getValue()).equals(""))
anatofuz
parents:
diff changeset
409 TM.Options.PrintMachineCode = true;
anatofuz
parents:
diff changeset
410
anatofuz
parents:
diff changeset
411 if (EnableIPRA.getNumOccurrences())
anatofuz
parents:
diff changeset
412 TM.Options.EnableIPRA = EnableIPRA;
anatofuz
parents:
diff changeset
413 else {
anatofuz
parents:
diff changeset
414 // If not explicitly specified, use target default.
anatofuz
parents:
diff changeset
415 TM.Options.EnableIPRA |= TM.useIPRA();
anatofuz
parents:
diff changeset
416 }
anatofuz
parents:
diff changeset
417
anatofuz
parents:
diff changeset
418 if (TM.Options.EnableIPRA)
anatofuz
parents:
diff changeset
419 setRequiresCodeGenSCCOrder();
anatofuz
parents:
diff changeset
420
anatofuz
parents:
diff changeset
421 if (EnableGlobalISelAbort.getNumOccurrences())
anatofuz
parents:
diff changeset
422 TM.Options.GlobalISelAbort = EnableGlobalISelAbort;
anatofuz
parents:
diff changeset
423
anatofuz
parents:
diff changeset
424 setStartStopPasses();
anatofuz
parents:
diff changeset
425 }
anatofuz
parents:
diff changeset
426
anatofuz
parents:
diff changeset
427 CodeGenOpt::Level TargetPassConfig::getOptLevel() const {
anatofuz
parents:
diff changeset
428 return TM->getOptLevel();
anatofuz
parents:
diff changeset
429 }
anatofuz
parents:
diff changeset
430
152
e8a9b4f4d755 pull from 146
anatofuz
parents: 150
diff changeset
431 #ifndef noCbC
e8a9b4f4d755 pull from 146
anatofuz
parents: 150
diff changeset
432 unsigned TargetPassConfig::hasCodeSegment() {
e8a9b4f4d755 pull from 146
anatofuz
parents: 150
diff changeset
433 return TM->Options.HasCodeSegment;
e8a9b4f4d755 pull from 146
anatofuz
parents: 150
diff changeset
434 }
e8a9b4f4d755 pull from 146
anatofuz
parents: 150
diff changeset
435 #endif
e8a9b4f4d755 pull from 146
anatofuz
parents: 150
diff changeset
436
150
anatofuz
parents:
diff changeset
437 /// Insert InsertedPassID pass after TargetPassID.
anatofuz
parents:
diff changeset
438 void TargetPassConfig::insertPass(AnalysisID TargetPassID,
anatofuz
parents:
diff changeset
439 IdentifyingPassPtr InsertedPassID,
anatofuz
parents:
diff changeset
440 bool VerifyAfter, bool PrintAfter) {
anatofuz
parents:
diff changeset
441 assert(((!InsertedPassID.isInstance() &&
anatofuz
parents:
diff changeset
442 TargetPassID != InsertedPassID.getID()) ||
anatofuz
parents:
diff changeset
443 (InsertedPassID.isInstance() &&
anatofuz
parents:
diff changeset
444 TargetPassID != InsertedPassID.getInstance()->getPassID())) &&
anatofuz
parents:
diff changeset
445 "Insert a pass after itself!");
anatofuz
parents:
diff changeset
446 Impl->InsertedPasses.emplace_back(TargetPassID, InsertedPassID, VerifyAfter,
anatofuz
parents:
diff changeset
447 PrintAfter);
anatofuz
parents:
diff changeset
448 }
anatofuz
parents:
diff changeset
449
anatofuz
parents:
diff changeset
450 /// createPassConfig - Create a pass configuration object to be used by
anatofuz
parents:
diff changeset
451 /// addPassToEmitX methods for generating a pipeline of CodeGen passes.
anatofuz
parents:
diff changeset
452 ///
anatofuz
parents:
diff changeset
453 /// Targets may override this to extend TargetPassConfig.
anatofuz
parents:
diff changeset
454 TargetPassConfig *LLVMTargetMachine::createPassConfig(PassManagerBase &PM) {
anatofuz
parents:
diff changeset
455 return new TargetPassConfig(*this, PM);
anatofuz
parents:
diff changeset
456 }
anatofuz
parents:
diff changeset
457
anatofuz
parents:
diff changeset
458 TargetPassConfig::TargetPassConfig()
anatofuz
parents:
diff changeset
459 : ImmutablePass(ID) {
anatofuz
parents:
diff changeset
460 report_fatal_error("Trying to construct TargetPassConfig without a target "
anatofuz
parents:
diff changeset
461 "machine. Scheduling a CodeGen pass without a target "
anatofuz
parents:
diff changeset
462 "triple set?");
anatofuz
parents:
diff changeset
463 }
anatofuz
parents:
diff changeset
464
anatofuz
parents:
diff changeset
465 bool TargetPassConfig::willCompleteCodeGenPipeline() {
anatofuz
parents:
diff changeset
466 return StopBeforeOpt.empty() && StopAfterOpt.empty();
anatofuz
parents:
diff changeset
467 }
anatofuz
parents:
diff changeset
468
anatofuz
parents:
diff changeset
469 bool TargetPassConfig::hasLimitedCodeGenPipeline() {
anatofuz
parents:
diff changeset
470 return !StartBeforeOpt.empty() || !StartAfterOpt.empty() ||
anatofuz
parents:
diff changeset
471 !willCompleteCodeGenPipeline();
anatofuz
parents:
diff changeset
472 }
anatofuz
parents:
diff changeset
473
anatofuz
parents:
diff changeset
474 std::string
anatofuz
parents:
diff changeset
475 TargetPassConfig::getLimitedCodeGenPipelineReason(const char *Separator) const {
anatofuz
parents:
diff changeset
476 if (!hasLimitedCodeGenPipeline())
anatofuz
parents:
diff changeset
477 return std::string();
anatofuz
parents:
diff changeset
478 std::string Res;
anatofuz
parents:
diff changeset
479 static cl::opt<std::string> *PassNames[] = {&StartAfterOpt, &StartBeforeOpt,
anatofuz
parents:
diff changeset
480 &StopAfterOpt, &StopBeforeOpt};
anatofuz
parents:
diff changeset
481 static const char *OptNames[] = {StartAfterOptName, StartBeforeOptName,
anatofuz
parents:
diff changeset
482 StopAfterOptName, StopBeforeOptName};
anatofuz
parents:
diff changeset
483 bool IsFirst = true;
anatofuz
parents:
diff changeset
484 for (int Idx = 0; Idx < 4; ++Idx)
anatofuz
parents:
diff changeset
485 if (!PassNames[Idx]->empty()) {
anatofuz
parents:
diff changeset
486 if (!IsFirst)
anatofuz
parents:
diff changeset
487 Res += Separator;
anatofuz
parents:
diff changeset
488 IsFirst = false;
anatofuz
parents:
diff changeset
489 Res += OptNames[Idx];
anatofuz
parents:
diff changeset
490 }
anatofuz
parents:
diff changeset
491 return Res;
anatofuz
parents:
diff changeset
492 }
anatofuz
parents:
diff changeset
493
anatofuz
parents:
diff changeset
494 // Helper to verify the analysis is really immutable.
anatofuz
parents:
diff changeset
495 void TargetPassConfig::setOpt(bool &Opt, bool Val) {
anatofuz
parents:
diff changeset
496 assert(!Initialized && "PassConfig is immutable");
anatofuz
parents:
diff changeset
497 Opt = Val;
anatofuz
parents:
diff changeset
498 }
anatofuz
parents:
diff changeset
499
anatofuz
parents:
diff changeset
500 void TargetPassConfig::substitutePass(AnalysisID StandardID,
anatofuz
parents:
diff changeset
501 IdentifyingPassPtr TargetID) {
anatofuz
parents:
diff changeset
502 Impl->TargetPasses[StandardID] = TargetID;
anatofuz
parents:
diff changeset
503 }
anatofuz
parents:
diff changeset
504
anatofuz
parents:
diff changeset
505 IdentifyingPassPtr TargetPassConfig::getPassSubstitution(AnalysisID ID) const {
anatofuz
parents:
diff changeset
506 DenseMap<AnalysisID, IdentifyingPassPtr>::const_iterator
anatofuz
parents:
diff changeset
507 I = Impl->TargetPasses.find(ID);
anatofuz
parents:
diff changeset
508 if (I == Impl->TargetPasses.end())
anatofuz
parents:
diff changeset
509 return ID;
anatofuz
parents:
diff changeset
510 return I->second;
anatofuz
parents:
diff changeset
511 }
anatofuz
parents:
diff changeset
512
anatofuz
parents:
diff changeset
513 bool TargetPassConfig::isPassSubstitutedOrOverridden(AnalysisID ID) const {
anatofuz
parents:
diff changeset
514 IdentifyingPassPtr TargetID = getPassSubstitution(ID);
anatofuz
parents:
diff changeset
515 IdentifyingPassPtr FinalPtr = overridePass(ID, TargetID);
anatofuz
parents:
diff changeset
516 return !FinalPtr.isValid() || FinalPtr.isInstance() ||
anatofuz
parents:
diff changeset
517 FinalPtr.getID() != ID;
anatofuz
parents:
diff changeset
518 }
anatofuz
parents:
diff changeset
519
anatofuz
parents:
diff changeset
520 /// Add a pass to the PassManager if that pass is supposed to be run. If the
anatofuz
parents:
diff changeset
521 /// Started/Stopped flags indicate either that the compilation should start at
anatofuz
parents:
diff changeset
522 /// a later pass or that it should stop after an earlier pass, then do not add
anatofuz
parents:
diff changeset
523 /// the pass. Finally, compare the current pass against the StartAfter
anatofuz
parents:
diff changeset
524 /// and StopAfter options and change the Started/Stopped flags accordingly.
anatofuz
parents:
diff changeset
525 void TargetPassConfig::addPass(Pass *P, bool verifyAfter, bool printAfter) {
anatofuz
parents:
diff changeset
526 assert(!Initialized && "PassConfig is immutable");
anatofuz
parents:
diff changeset
527
anatofuz
parents:
diff changeset
528 // Cache the Pass ID here in case the pass manager finds this pass is
anatofuz
parents:
diff changeset
529 // redundant with ones already scheduled / available, and deletes it.
anatofuz
parents:
diff changeset
530 // Fundamentally, once we add the pass to the manager, we no longer own it
anatofuz
parents:
diff changeset
531 // and shouldn't reference it.
anatofuz
parents:
diff changeset
532 AnalysisID PassID = P->getPassID();
anatofuz
parents:
diff changeset
533
anatofuz
parents:
diff changeset
534 if (StartBefore == PassID && StartBeforeCount++ == StartBeforeInstanceNum)
anatofuz
parents:
diff changeset
535 Started = true;
anatofuz
parents:
diff changeset
536 if (StopBefore == PassID && StopBeforeCount++ == StopBeforeInstanceNum)
anatofuz
parents:
diff changeset
537 Stopped = true;
anatofuz
parents:
diff changeset
538 if (Started && !Stopped) {
anatofuz
parents:
diff changeset
539 std::string Banner;
anatofuz
parents:
diff changeset
540 // Construct banner message before PM->add() as that may delete the pass.
anatofuz
parents:
diff changeset
541 if (AddingMachinePasses && (printAfter || verifyAfter))
anatofuz
parents:
diff changeset
542 Banner = std::string("After ") + std::string(P->getPassName());
anatofuz
parents:
diff changeset
543 PM->add(P);
anatofuz
parents:
diff changeset
544 if (AddingMachinePasses) {
anatofuz
parents:
diff changeset
545 if (printAfter)
anatofuz
parents:
diff changeset
546 addPrintPass(Banner);
anatofuz
parents:
diff changeset
547 if (verifyAfter)
anatofuz
parents:
diff changeset
548 addVerifyPass(Banner);
anatofuz
parents:
diff changeset
549 }
anatofuz
parents:
diff changeset
550
anatofuz
parents:
diff changeset
551 // Add the passes after the pass P if there is any.
anatofuz
parents:
diff changeset
552 for (auto IP : Impl->InsertedPasses) {
anatofuz
parents:
diff changeset
553 if (IP.TargetPassID == PassID)
anatofuz
parents:
diff changeset
554 addPass(IP.getInsertedPass(), IP.VerifyAfter, IP.PrintAfter);
anatofuz
parents:
diff changeset
555 }
anatofuz
parents:
diff changeset
556 } else {
anatofuz
parents:
diff changeset
557 delete P;
anatofuz
parents:
diff changeset
558 }
anatofuz
parents:
diff changeset
559
anatofuz
parents:
diff changeset
560 if (StopAfter == PassID && StopAfterCount++ == StopAfterInstanceNum)
anatofuz
parents:
diff changeset
561 Stopped = true;
anatofuz
parents:
diff changeset
562
anatofuz
parents:
diff changeset
563 if (StartAfter == PassID && StartAfterCount++ == StartAfterInstanceNum)
anatofuz
parents:
diff changeset
564 Started = true;
anatofuz
parents:
diff changeset
565 if (Stopped && !Started)
anatofuz
parents:
diff changeset
566 report_fatal_error("Cannot stop compilation after pass that is not run");
anatofuz
parents:
diff changeset
567 }
anatofuz
parents:
diff changeset
568
anatofuz
parents:
diff changeset
569 /// Add a CodeGen pass at this point in the pipeline after checking for target
anatofuz
parents:
diff changeset
570 /// and command line overrides.
anatofuz
parents:
diff changeset
571 ///
anatofuz
parents:
diff changeset
572 /// addPass cannot return a pointer to the pass instance because is internal the
anatofuz
parents:
diff changeset
573 /// PassManager and the instance we create here may already be freed.
anatofuz
parents:
diff changeset
574 AnalysisID TargetPassConfig::addPass(AnalysisID PassID, bool verifyAfter,
anatofuz
parents:
diff changeset
575 bool printAfter) {
anatofuz
parents:
diff changeset
576 IdentifyingPassPtr TargetID = getPassSubstitution(PassID);
anatofuz
parents:
diff changeset
577 IdentifyingPassPtr FinalPtr = overridePass(PassID, TargetID);
anatofuz
parents:
diff changeset
578 if (!FinalPtr.isValid())
anatofuz
parents:
diff changeset
579 return nullptr;
anatofuz
parents:
diff changeset
580
anatofuz
parents:
diff changeset
581 Pass *P;
anatofuz
parents:
diff changeset
582 if (FinalPtr.isInstance())
anatofuz
parents:
diff changeset
583 P = FinalPtr.getInstance();
anatofuz
parents:
diff changeset
584 else {
anatofuz
parents:
diff changeset
585 P = Pass::createPass(FinalPtr.getID());
anatofuz
parents:
diff changeset
586 if (!P)
anatofuz
parents:
diff changeset
587 llvm_unreachable("Pass ID not registered");
anatofuz
parents:
diff changeset
588 }
anatofuz
parents:
diff changeset
589 AnalysisID FinalID = P->getPassID();
anatofuz
parents:
diff changeset
590 addPass(P, verifyAfter, printAfter); // Ends the lifetime of P.
anatofuz
parents:
diff changeset
591
anatofuz
parents:
diff changeset
592 return FinalID;
anatofuz
parents:
diff changeset
593 }
anatofuz
parents:
diff changeset
594
anatofuz
parents:
diff changeset
595 void TargetPassConfig::printAndVerify(const std::string &Banner) {
anatofuz
parents:
diff changeset
596 addPrintPass(Banner);
anatofuz
parents:
diff changeset
597 addVerifyPass(Banner);
anatofuz
parents:
diff changeset
598 }
anatofuz
parents:
diff changeset
599
anatofuz
parents:
diff changeset
600 void TargetPassConfig::addPrintPass(const std::string &Banner) {
anatofuz
parents:
diff changeset
601 if (TM->shouldPrintMachineCode())
anatofuz
parents:
diff changeset
602 PM->add(createMachineFunctionPrinterPass(dbgs(), Banner));
anatofuz
parents:
diff changeset
603 }
anatofuz
parents:
diff changeset
604
anatofuz
parents:
diff changeset
605 void TargetPassConfig::addVerifyPass(const std::string &Banner) {
anatofuz
parents:
diff changeset
606 bool Verify = VerifyMachineCode == cl::BOU_TRUE;
anatofuz
parents:
diff changeset
607 #ifdef EXPENSIVE_CHECKS
anatofuz
parents:
diff changeset
608 if (VerifyMachineCode == cl::BOU_UNSET)
anatofuz
parents:
diff changeset
609 Verify = TM->isMachineVerifierClean();
anatofuz
parents:
diff changeset
610 #endif
anatofuz
parents:
diff changeset
611 if (Verify)
anatofuz
parents:
diff changeset
612 PM->add(createMachineVerifierPass(Banner));
anatofuz
parents:
diff changeset
613 }
anatofuz
parents:
diff changeset
614
anatofuz
parents:
diff changeset
615 /// Add common target configurable passes that perform LLVM IR to IR transforms
anatofuz
parents:
diff changeset
616 /// following machine independent optimization.
anatofuz
parents:
diff changeset
617 void TargetPassConfig::addIRPasses() {
anatofuz
parents:
diff changeset
618 switch (UseCFLAA) {
anatofuz
parents:
diff changeset
619 case CFLAAType::Steensgaard:
anatofuz
parents:
diff changeset
620 addPass(createCFLSteensAAWrapperPass());
anatofuz
parents:
diff changeset
621 break;
anatofuz
parents:
diff changeset
622 case CFLAAType::Andersen:
anatofuz
parents:
diff changeset
623 addPass(createCFLAndersAAWrapperPass());
anatofuz
parents:
diff changeset
624 break;
anatofuz
parents:
diff changeset
625 case CFLAAType::Both:
anatofuz
parents:
diff changeset
626 addPass(createCFLAndersAAWrapperPass());
anatofuz
parents:
diff changeset
627 addPass(createCFLSteensAAWrapperPass());
anatofuz
parents:
diff changeset
628 break;
anatofuz
parents:
diff changeset
629 default:
anatofuz
parents:
diff changeset
630 break;
anatofuz
parents:
diff changeset
631 }
anatofuz
parents:
diff changeset
632
anatofuz
parents:
diff changeset
633 // Basic AliasAnalysis support.
anatofuz
parents:
diff changeset
634 // Add TypeBasedAliasAnalysis before BasicAliasAnalysis so that
anatofuz
parents:
diff changeset
635 // BasicAliasAnalysis wins if they disagree. This is intended to help
anatofuz
parents:
diff changeset
636 // support "obvious" type-punning idioms.
anatofuz
parents:
diff changeset
637 addPass(createTypeBasedAAWrapperPass());
anatofuz
parents:
diff changeset
638 addPass(createScopedNoAliasAAWrapperPass());
anatofuz
parents:
diff changeset
639 addPass(createBasicAAWrapperPass());
anatofuz
parents:
diff changeset
640
anatofuz
parents:
diff changeset
641 // Before running any passes, run the verifier to determine if the input
anatofuz
parents:
diff changeset
642 // coming from the front-end and/or optimizer is valid.
anatofuz
parents:
diff changeset
643 if (!DisableVerify)
anatofuz
parents:
diff changeset
644 addPass(createVerifierPass());
anatofuz
parents:
diff changeset
645
anatofuz
parents:
diff changeset
646 // Run loop strength reduction before anything else.
anatofuz
parents:
diff changeset
647 if (getOptLevel() != CodeGenOpt::None && !DisableLSR) {
anatofuz
parents:
diff changeset
648 addPass(createLoopStrengthReducePass());
anatofuz
parents:
diff changeset
649 if (PrintLSR)
anatofuz
parents:
diff changeset
650 addPass(createPrintFunctionPass(dbgs(), "\n\n*** Code after LSR ***\n"));
anatofuz
parents:
diff changeset
651 }
anatofuz
parents:
diff changeset
652
anatofuz
parents:
diff changeset
653 if (getOptLevel() != CodeGenOpt::None) {
anatofuz
parents:
diff changeset
654 // The MergeICmpsPass tries to create memcmp calls by grouping sequences of
anatofuz
parents:
diff changeset
655 // loads and compares. ExpandMemCmpPass then tries to expand those calls
anatofuz
parents:
diff changeset
656 // into optimally-sized loads and compares. The transforms are enabled by a
anatofuz
parents:
diff changeset
657 // target lowering hook.
anatofuz
parents:
diff changeset
658 if (!DisableMergeICmps)
anatofuz
parents:
diff changeset
659 addPass(createMergeICmpsLegacyPass());
anatofuz
parents:
diff changeset
660 addPass(createExpandMemCmpPass());
anatofuz
parents:
diff changeset
661 }
anatofuz
parents:
diff changeset
662
anatofuz
parents:
diff changeset
663 // Run GC lowering passes for builtin collectors
anatofuz
parents:
diff changeset
664 // TODO: add a pass insertion point here
anatofuz
parents:
diff changeset
665 addPass(createGCLoweringPass());
anatofuz
parents:
diff changeset
666 addPass(createShadowStackGCLoweringPass());
anatofuz
parents:
diff changeset
667 addPass(createLowerConstantIntrinsicsPass());
anatofuz
parents:
diff changeset
668
anatofuz
parents:
diff changeset
669 // Make sure that no unreachable blocks are instruction selected.
anatofuz
parents:
diff changeset
670 addPass(createUnreachableBlockEliminationPass());
anatofuz
parents:
diff changeset
671
anatofuz
parents:
diff changeset
672 // Prepare expensive constants for SelectionDAG.
anatofuz
parents:
diff changeset
673 if (getOptLevel() != CodeGenOpt::None && !DisableConstantHoisting)
anatofuz
parents:
diff changeset
674 addPass(createConstantHoistingPass());
anatofuz
parents:
diff changeset
675
anatofuz
parents:
diff changeset
676 if (getOptLevel() != CodeGenOpt::None && !DisablePartialLibcallInlining)
anatofuz
parents:
diff changeset
677 addPass(createPartiallyInlineLibCallsPass());
anatofuz
parents:
diff changeset
678
anatofuz
parents:
diff changeset
679 // Instrument function entry and exit, e.g. with calls to mcount().
anatofuz
parents:
diff changeset
680 addPass(createPostInlineEntryExitInstrumenterPass());
anatofuz
parents:
diff changeset
681
anatofuz
parents:
diff changeset
682 // Add scalarization of target's unsupported masked memory intrinsics pass.
anatofuz
parents:
diff changeset
683 // the unsupported intrinsic will be replaced with a chain of basic blocks,
anatofuz
parents:
diff changeset
684 // that stores/loads element one-by-one if the appropriate mask bit is set.
anatofuz
parents:
diff changeset
685 addPass(createScalarizeMaskedMemIntrinPass());
anatofuz
parents:
diff changeset
686
anatofuz
parents:
diff changeset
687 // Expand reduction intrinsics into shuffle sequences if the target wants to.
anatofuz
parents:
diff changeset
688 addPass(createExpandReductionsPass());
anatofuz
parents:
diff changeset
689 }
anatofuz
parents:
diff changeset
690
anatofuz
parents:
diff changeset
691 /// Turn exception handling constructs into something the code generators can
anatofuz
parents:
diff changeset
692 /// handle.
anatofuz
parents:
diff changeset
693 void TargetPassConfig::addPassesToHandleExceptions() {
anatofuz
parents:
diff changeset
694 const MCAsmInfo *MCAI = TM->getMCAsmInfo();
anatofuz
parents:
diff changeset
695 assert(MCAI && "No MCAsmInfo");
anatofuz
parents:
diff changeset
696 switch (MCAI->getExceptionHandlingType()) {
anatofuz
parents:
diff changeset
697 case ExceptionHandling::SjLj:
anatofuz
parents:
diff changeset
698 // SjLj piggy-backs on dwarf for this bit. The cleanups done apply to both
anatofuz
parents:
diff changeset
699 // Dwarf EH prepare needs to be run after SjLj prepare. Otherwise,
anatofuz
parents:
diff changeset
700 // catch info can get misplaced when a selector ends up more than one block
anatofuz
parents:
diff changeset
701 // removed from the parent invoke(s). This could happen when a landing
anatofuz
parents:
diff changeset
702 // pad is shared by multiple invokes and is also a target of a normal
anatofuz
parents:
diff changeset
703 // edge from elsewhere.
anatofuz
parents:
diff changeset
704 addPass(createSjLjEHPreparePass());
anatofuz
parents:
diff changeset
705 LLVM_FALLTHROUGH;
anatofuz
parents:
diff changeset
706 case ExceptionHandling::DwarfCFI:
anatofuz
parents:
diff changeset
707 case ExceptionHandling::ARM:
anatofuz
parents:
diff changeset
708 addPass(createDwarfEHPass());
anatofuz
parents:
diff changeset
709 break;
anatofuz
parents:
diff changeset
710 case ExceptionHandling::WinEH:
anatofuz
parents:
diff changeset
711 // We support using both GCC-style and MSVC-style exceptions on Windows, so
anatofuz
parents:
diff changeset
712 // add both preparation passes. Each pass will only actually run if it
anatofuz
parents:
diff changeset
713 // recognizes the personality function.
anatofuz
parents:
diff changeset
714 addPass(createWinEHPass());
anatofuz
parents:
diff changeset
715 addPass(createDwarfEHPass());
anatofuz
parents:
diff changeset
716 break;
anatofuz
parents:
diff changeset
717 case ExceptionHandling::Wasm:
anatofuz
parents:
diff changeset
718 // Wasm EH uses Windows EH instructions, but it does not need to demote PHIs
anatofuz
parents:
diff changeset
719 // on catchpads and cleanuppads because it does not outline them into
anatofuz
parents:
diff changeset
720 // funclets. Catchswitch blocks are not lowered in SelectionDAG, so we
anatofuz
parents:
diff changeset
721 // should remove PHIs there.
anatofuz
parents:
diff changeset
722 addPass(createWinEHPass(/*DemoteCatchSwitchPHIOnly=*/false));
anatofuz
parents:
diff changeset
723 addPass(createWasmEHPass());
anatofuz
parents:
diff changeset
724 break;
anatofuz
parents:
diff changeset
725 case ExceptionHandling::None:
anatofuz
parents:
diff changeset
726 addPass(createLowerInvokePass());
anatofuz
parents:
diff changeset
727
anatofuz
parents:
diff changeset
728 // The lower invoke pass may create unreachable code. Remove it.
anatofuz
parents:
diff changeset
729 addPass(createUnreachableBlockEliminationPass());
anatofuz
parents:
diff changeset
730 break;
anatofuz
parents:
diff changeset
731 }
anatofuz
parents:
diff changeset
732 }
anatofuz
parents:
diff changeset
733
anatofuz
parents:
diff changeset
734 /// Add pass to prepare the LLVM IR for code generation. This should be done
anatofuz
parents:
diff changeset
735 /// before exception handling preparation passes.
anatofuz
parents:
diff changeset
736 void TargetPassConfig::addCodeGenPrepare() {
152
e8a9b4f4d755 pull from 146
anatofuz
parents: 150
diff changeset
737 #ifdef noCbC
150
anatofuz
parents:
diff changeset
738 if (getOptLevel() != CodeGenOpt::None && !DisableCGP)
152
e8a9b4f4d755 pull from 146
anatofuz
parents: 150
diff changeset
739 #endif
150
anatofuz
parents:
diff changeset
740 addPass(createCodeGenPreparePass());
anatofuz
parents:
diff changeset
741 addPass(createRewriteSymbolsPass());
anatofuz
parents:
diff changeset
742 }
anatofuz
parents:
diff changeset
743
anatofuz
parents:
diff changeset
744 /// Add common passes that perform LLVM IR to IR transforms in preparation for
anatofuz
parents:
diff changeset
745 /// instruction selection.
anatofuz
parents:
diff changeset
746 void TargetPassConfig::addISelPrepare() {
anatofuz
parents:
diff changeset
747 addPreISel();
anatofuz
parents:
diff changeset
748
anatofuz
parents:
diff changeset
749 // Force codegen to run according to the callgraph.
anatofuz
parents:
diff changeset
750 if (requiresCodeGenSCCOrder())
anatofuz
parents:
diff changeset
751 addPass(new DummyCGSCCPass);
anatofuz
parents:
diff changeset
752
anatofuz
parents:
diff changeset
753 // Add both the safe stack and the stack protection passes: each of them will
anatofuz
parents:
diff changeset
754 // only protect functions that have corresponding attributes.
anatofuz
parents:
diff changeset
755 addPass(createSafeStackPass());
anatofuz
parents:
diff changeset
756 addPass(createStackProtectorPass());
anatofuz
parents:
diff changeset
757
anatofuz
parents:
diff changeset
758 if (PrintISelInput)
anatofuz
parents:
diff changeset
759 addPass(createPrintFunctionPass(
anatofuz
parents:
diff changeset
760 dbgs(), "\n\n*** Final LLVM Code input to ISel ***\n"));
anatofuz
parents:
diff changeset
761
anatofuz
parents:
diff changeset
762 // All passes which modify the LLVM IR are now complete; run the verifier
anatofuz
parents:
diff changeset
763 // to ensure that the IR is valid.
anatofuz
parents:
diff changeset
764 if (!DisableVerify)
anatofuz
parents:
diff changeset
765 addPass(createVerifierPass());
anatofuz
parents:
diff changeset
766 }
anatofuz
parents:
diff changeset
767
anatofuz
parents:
diff changeset
768 bool TargetPassConfig::addCoreISelPasses() {
anatofuz
parents:
diff changeset
769 // Enable FastISel with -fast-isel, but allow that to be overridden.
anatofuz
parents:
diff changeset
770 TM->setO0WantsFastISel(EnableFastISelOption != cl::BOU_FALSE);
anatofuz
parents:
diff changeset
771
anatofuz
parents:
diff changeset
772 // Determine an instruction selector.
anatofuz
parents:
diff changeset
773 enum class SelectorType { SelectionDAG, FastISel, GlobalISel };
anatofuz
parents:
diff changeset
774 SelectorType Selector;
anatofuz
parents:
diff changeset
775
anatofuz
parents:
diff changeset
776 if (EnableFastISelOption == cl::BOU_TRUE)
anatofuz
parents:
diff changeset
777 Selector = SelectorType::FastISel;
anatofuz
parents:
diff changeset
778 else if (EnableGlobalISelOption == cl::BOU_TRUE ||
anatofuz
parents:
diff changeset
779 (TM->Options.EnableGlobalISel &&
anatofuz
parents:
diff changeset
780 EnableGlobalISelOption != cl::BOU_FALSE))
anatofuz
parents:
diff changeset
781 Selector = SelectorType::GlobalISel;
anatofuz
parents:
diff changeset
782 else if (TM->getOptLevel() == CodeGenOpt::None && TM->getO0WantsFastISel())
anatofuz
parents:
diff changeset
783 Selector = SelectorType::FastISel;
anatofuz
parents:
diff changeset
784 else
anatofuz
parents:
diff changeset
785 Selector = SelectorType::SelectionDAG;
anatofuz
parents:
diff changeset
786
anatofuz
parents:
diff changeset
787 // Set consistently TM->Options.EnableFastISel and EnableGlobalISel.
anatofuz
parents:
diff changeset
788 if (Selector == SelectorType::FastISel) {
anatofuz
parents:
diff changeset
789 TM->setFastISel(true);
anatofuz
parents:
diff changeset
790 TM->setGlobalISel(false);
anatofuz
parents:
diff changeset
791 } else if (Selector == SelectorType::GlobalISel) {
anatofuz
parents:
diff changeset
792 TM->setFastISel(false);
anatofuz
parents:
diff changeset
793 TM->setGlobalISel(true);
anatofuz
parents:
diff changeset
794 }
anatofuz
parents:
diff changeset
795
anatofuz
parents:
diff changeset
796 // Add instruction selector passes.
anatofuz
parents:
diff changeset
797 if (Selector == SelectorType::GlobalISel) {
anatofuz
parents:
diff changeset
798 SaveAndRestore<bool> SavedAddingMachinePasses(AddingMachinePasses, true);
anatofuz
parents:
diff changeset
799 if (addIRTranslator())
anatofuz
parents:
diff changeset
800 return true;
anatofuz
parents:
diff changeset
801
anatofuz
parents:
diff changeset
802 addPreLegalizeMachineIR();
anatofuz
parents:
diff changeset
803
anatofuz
parents:
diff changeset
804 if (addLegalizeMachineIR())
anatofuz
parents:
diff changeset
805 return true;
anatofuz
parents:
diff changeset
806
anatofuz
parents:
diff changeset
807 // Before running the register bank selector, ask the target if it
anatofuz
parents:
diff changeset
808 // wants to run some passes.
anatofuz
parents:
diff changeset
809 addPreRegBankSelect();
anatofuz
parents:
diff changeset
810
anatofuz
parents:
diff changeset
811 if (addRegBankSelect())
anatofuz
parents:
diff changeset
812 return true;
anatofuz
parents:
diff changeset
813
anatofuz
parents:
diff changeset
814 addPreGlobalInstructionSelect();
anatofuz
parents:
diff changeset
815
anatofuz
parents:
diff changeset
816 if (addGlobalInstructionSelect())
anatofuz
parents:
diff changeset
817 return true;
anatofuz
parents:
diff changeset
818
anatofuz
parents:
diff changeset
819 // Pass to reset the MachineFunction if the ISel failed.
anatofuz
parents:
diff changeset
820 addPass(createResetMachineFunctionPass(
anatofuz
parents:
diff changeset
821 reportDiagnosticWhenGlobalISelFallback(), isGlobalISelAbortEnabled()));
anatofuz
parents:
diff changeset
822
anatofuz
parents:
diff changeset
823 // Provide a fallback path when we do not want to abort on
anatofuz
parents:
diff changeset
824 // not-yet-supported input.
anatofuz
parents:
diff changeset
825 if (!isGlobalISelAbortEnabled() && addInstSelector())
anatofuz
parents:
diff changeset
826 return true;
anatofuz
parents:
diff changeset
827
anatofuz
parents:
diff changeset
828 } else if (addInstSelector())
anatofuz
parents:
diff changeset
829 return true;
anatofuz
parents:
diff changeset
830
anatofuz
parents:
diff changeset
831 // Expand pseudo-instructions emitted by ISel. Don't run the verifier before
anatofuz
parents:
diff changeset
832 // FinalizeISel.
anatofuz
parents:
diff changeset
833 addPass(&FinalizeISelID);
anatofuz
parents:
diff changeset
834
anatofuz
parents:
diff changeset
835 // Print the instruction selected machine code...
anatofuz
parents:
diff changeset
836 printAndVerify("After Instruction Selection");
anatofuz
parents:
diff changeset
837
anatofuz
parents:
diff changeset
838 return false;
anatofuz
parents:
diff changeset
839 }
anatofuz
parents:
diff changeset
840
anatofuz
parents:
diff changeset
841 bool TargetPassConfig::addISelPasses() {
anatofuz
parents:
diff changeset
842 if (TM->useEmulatedTLS())
anatofuz
parents:
diff changeset
843 addPass(createLowerEmuTLSPass());
anatofuz
parents:
diff changeset
844
anatofuz
parents:
diff changeset
845 addPass(createPreISelIntrinsicLoweringPass());
anatofuz
parents:
diff changeset
846 addPass(createTargetTransformInfoWrapperPass(TM->getTargetIRAnalysis()));
anatofuz
parents:
diff changeset
847 addIRPasses();
anatofuz
parents:
diff changeset
848 addCodeGenPrepare();
anatofuz
parents:
diff changeset
849 addPassesToHandleExceptions();
anatofuz
parents:
diff changeset
850 addISelPrepare();
anatofuz
parents:
diff changeset
851
anatofuz
parents:
diff changeset
852 return addCoreISelPasses();
anatofuz
parents:
diff changeset
853 }
anatofuz
parents:
diff changeset
854
anatofuz
parents:
diff changeset
855 /// -regalloc=... command line option.
anatofuz
parents:
diff changeset
856 static FunctionPass *useDefaultRegisterAllocator() { return nullptr; }
anatofuz
parents:
diff changeset
857 static cl::opt<RegisterRegAlloc::FunctionPassCtor, false,
anatofuz
parents:
diff changeset
858 RegisterPassParser<RegisterRegAlloc>>
anatofuz
parents:
diff changeset
859 RegAlloc("regalloc", cl::Hidden, cl::init(&useDefaultRegisterAllocator),
anatofuz
parents:
diff changeset
860 cl::desc("Register allocator to use"));
anatofuz
parents:
diff changeset
861
anatofuz
parents:
diff changeset
862 /// Add the complete set of target-independent postISel code generator passes.
anatofuz
parents:
diff changeset
863 ///
anatofuz
parents:
diff changeset
864 /// This can be read as the standard order of major LLVM CodeGen stages. Stages
anatofuz
parents:
diff changeset
865 /// with nontrivial configuration or multiple passes are broken out below in
anatofuz
parents:
diff changeset
866 /// add%Stage routines.
anatofuz
parents:
diff changeset
867 ///
anatofuz
parents:
diff changeset
868 /// Any TargetPassConfig::addXX routine may be overriden by the Target. The
anatofuz
parents:
diff changeset
869 /// addPre/Post methods with empty header implementations allow injecting
anatofuz
parents:
diff changeset
870 /// target-specific fixups just before or after major stages. Additionally,
anatofuz
parents:
diff changeset
871 /// targets have the flexibility to change pass order within a stage by
anatofuz
parents:
diff changeset
872 /// overriding default implementation of add%Stage routines below. Each
anatofuz
parents:
diff changeset
873 /// technique has maintainability tradeoffs because alternate pass orders are
anatofuz
parents:
diff changeset
874 /// not well supported. addPre/Post works better if the target pass is easily
anatofuz
parents:
diff changeset
875 /// tied to a common pass. But if it has subtle dependencies on multiple passes,
anatofuz
parents:
diff changeset
876 /// the target should override the stage instead.
anatofuz
parents:
diff changeset
877 ///
anatofuz
parents:
diff changeset
878 /// TODO: We could use a single addPre/Post(ID) hook to allow pass injection
anatofuz
parents:
diff changeset
879 /// before/after any target-independent pass. But it's currently overkill.
anatofuz
parents:
diff changeset
880 void TargetPassConfig::addMachinePasses() {
anatofuz
parents:
diff changeset
881 AddingMachinePasses = true;
anatofuz
parents:
diff changeset
882
anatofuz
parents:
diff changeset
883 // Insert a machine instr printer pass after the specified pass.
anatofuz
parents:
diff changeset
884 StringRef PrintMachineInstrsPassName = PrintMachineInstrs.getValue();
anatofuz
parents:
diff changeset
885 if (!PrintMachineInstrsPassName.equals("") &&
anatofuz
parents:
diff changeset
886 !PrintMachineInstrsPassName.equals("option-unspecified")) {
anatofuz
parents:
diff changeset
887 if (const PassInfo *TPI = getPassInfo(PrintMachineInstrsPassName)) {
anatofuz
parents:
diff changeset
888 const PassRegistry *PR = PassRegistry::getPassRegistry();
anatofuz
parents:
diff changeset
889 const PassInfo *IPI = PR->getPassInfo(StringRef("machineinstr-printer"));
anatofuz
parents:
diff changeset
890 assert(IPI && "failed to get \"machineinstr-printer\" PassInfo!");
anatofuz
parents:
diff changeset
891 const char *TID = (const char *)(TPI->getTypeInfo());
anatofuz
parents:
diff changeset
892 const char *IID = (const char *)(IPI->getTypeInfo());
anatofuz
parents:
diff changeset
893 insertPass(TID, IID);
anatofuz
parents:
diff changeset
894 }
anatofuz
parents:
diff changeset
895 }
anatofuz
parents:
diff changeset
896
anatofuz
parents:
diff changeset
897 // Add passes that optimize machine instructions in SSA form.
anatofuz
parents:
diff changeset
898 if (getOptLevel() != CodeGenOpt::None) {
anatofuz
parents:
diff changeset
899 addMachineSSAOptimization();
anatofuz
parents:
diff changeset
900 } else {
anatofuz
parents:
diff changeset
901 // If the target requests it, assign local variables to stack slots relative
anatofuz
parents:
diff changeset
902 // to one another and simplify frame index references where possible.
anatofuz
parents:
diff changeset
903 addPass(&LocalStackSlotAllocationID, false);
anatofuz
parents:
diff changeset
904 }
anatofuz
parents:
diff changeset
905
anatofuz
parents:
diff changeset
906 if (TM->Options.EnableIPRA)
anatofuz
parents:
diff changeset
907 addPass(createRegUsageInfoPropPass());
anatofuz
parents:
diff changeset
908
anatofuz
parents:
diff changeset
909 // Run pre-ra passes.
anatofuz
parents:
diff changeset
910 addPreRegAlloc();
anatofuz
parents:
diff changeset
911
anatofuz
parents:
diff changeset
912 // Run register allocation and passes that are tightly coupled with it,
anatofuz
parents:
diff changeset
913 // including phi elimination and scheduling.
anatofuz
parents:
diff changeset
914 if (getOptimizeRegAlloc())
anatofuz
parents:
diff changeset
915 addOptimizedRegAlloc();
anatofuz
parents:
diff changeset
916 else
anatofuz
parents:
diff changeset
917 addFastRegAlloc();
anatofuz
parents:
diff changeset
918
anatofuz
parents:
diff changeset
919 // Run post-ra passes.
anatofuz
parents:
diff changeset
920 addPostRegAlloc();
anatofuz
parents:
diff changeset
921
anatofuz
parents:
diff changeset
922 // Insert prolog/epilog code. Eliminate abstract frame index references...
anatofuz
parents:
diff changeset
923 if (getOptLevel() != CodeGenOpt::None) {
anatofuz
parents:
diff changeset
924 addPass(&PostRAMachineSinkingID);
anatofuz
parents:
diff changeset
925 addPass(&ShrinkWrapID);
anatofuz
parents:
diff changeset
926 }
anatofuz
parents:
diff changeset
927
anatofuz
parents:
diff changeset
928 // Prolog/Epilog inserter needs a TargetMachine to instantiate. But only
anatofuz
parents:
diff changeset
929 // do so if it hasn't been disabled, substituted, or overridden.
anatofuz
parents:
diff changeset
930 if (!isPassSubstitutedOrOverridden(&PrologEpilogCodeInserterID))
anatofuz
parents:
diff changeset
931 addPass(createPrologEpilogInserterPass());
anatofuz
parents:
diff changeset
932
anatofuz
parents:
diff changeset
933 /// Add passes that optimize machine instructions after register allocation.
anatofuz
parents:
diff changeset
934 if (getOptLevel() != CodeGenOpt::None)
anatofuz
parents:
diff changeset
935 addMachineLateOptimization();
anatofuz
parents:
diff changeset
936
anatofuz
parents:
diff changeset
937 // Expand pseudo instructions before second scheduling pass.
anatofuz
parents:
diff changeset
938 addPass(&ExpandPostRAPseudosID);
anatofuz
parents:
diff changeset
939
anatofuz
parents:
diff changeset
940 // Run pre-sched2 passes.
anatofuz
parents:
diff changeset
941 addPreSched2();
anatofuz
parents:
diff changeset
942
anatofuz
parents:
diff changeset
943 if (EnableImplicitNullChecks)
anatofuz
parents:
diff changeset
944 addPass(&ImplicitNullChecksID);
anatofuz
parents:
diff changeset
945
anatofuz
parents:
diff changeset
946 // Second pass scheduler.
anatofuz
parents:
diff changeset
947 // Let Target optionally insert this pass by itself at some other
anatofuz
parents:
diff changeset
948 // point.
anatofuz
parents:
diff changeset
949 if (getOptLevel() != CodeGenOpt::None &&
anatofuz
parents:
diff changeset
950 !TM->targetSchedulesPostRAScheduling()) {
anatofuz
parents:
diff changeset
951 if (MISchedPostRA)
anatofuz
parents:
diff changeset
952 addPass(&PostMachineSchedulerID);
anatofuz
parents:
diff changeset
953 else
anatofuz
parents:
diff changeset
954 addPass(&PostRASchedulerID);
anatofuz
parents:
diff changeset
955 }
anatofuz
parents:
diff changeset
956
anatofuz
parents:
diff changeset
957 // GC
anatofuz
parents:
diff changeset
958 if (addGCPasses()) {
anatofuz
parents:
diff changeset
959 if (PrintGCInfo)
anatofuz
parents:
diff changeset
960 addPass(createGCInfoPrinter(dbgs()), false, false);
anatofuz
parents:
diff changeset
961 }
anatofuz
parents:
diff changeset
962
anatofuz
parents:
diff changeset
963 // Basic block placement.
anatofuz
parents:
diff changeset
964 if (getOptLevel() != CodeGenOpt::None)
anatofuz
parents:
diff changeset
965 addBlockPlacement();
anatofuz
parents:
diff changeset
966
anatofuz
parents:
diff changeset
967 // Insert before XRay Instrumentation.
anatofuz
parents:
diff changeset
968 addPass(&FEntryInserterID, false);
anatofuz
parents:
diff changeset
969
anatofuz
parents:
diff changeset
970 addPass(&XRayInstrumentationID, false);
anatofuz
parents:
diff changeset
971 addPass(&PatchableFunctionID, false);
anatofuz
parents:
diff changeset
972
anatofuz
parents:
diff changeset
973 addPreEmitPass();
anatofuz
parents:
diff changeset
974
anatofuz
parents:
diff changeset
975 if (TM->Options.EnableIPRA)
anatofuz
parents:
diff changeset
976 // Collect register usage information and produce a register mask of
anatofuz
parents:
diff changeset
977 // clobbered registers, to be used to optimize call sites.
anatofuz
parents:
diff changeset
978 addPass(createRegUsageInfoCollector());
anatofuz
parents:
diff changeset
979
anatofuz
parents:
diff changeset
980 addPass(&FuncletLayoutID, false);
anatofuz
parents:
diff changeset
981
anatofuz
parents:
diff changeset
982 addPass(&StackMapLivenessID, false);
anatofuz
parents:
diff changeset
983 addPass(&LiveDebugValuesID, false);
anatofuz
parents:
diff changeset
984
anatofuz
parents:
diff changeset
985 if (TM->Options.EnableMachineOutliner && getOptLevel() != CodeGenOpt::None &&
anatofuz
parents:
diff changeset
986 EnableMachineOutliner != NeverOutline) {
anatofuz
parents:
diff changeset
987 bool RunOnAllFunctions = (EnableMachineOutliner == AlwaysOutline);
anatofuz
parents:
diff changeset
988 bool AddOutliner = RunOnAllFunctions ||
anatofuz
parents:
diff changeset
989 TM->Options.SupportsDefaultOutlining;
anatofuz
parents:
diff changeset
990 if (AddOutliner)
anatofuz
parents:
diff changeset
991 addPass(createMachineOutlinerPass(RunOnAllFunctions));
anatofuz
parents:
diff changeset
992 }
anatofuz
parents:
diff changeset
993
anatofuz
parents:
diff changeset
994 // Add passes that directly emit MI after all other MI passes.
anatofuz
parents:
diff changeset
995 addPreEmitPass2();
anatofuz
parents:
diff changeset
996
anatofuz
parents:
diff changeset
997 AddingMachinePasses = false;
anatofuz
parents:
diff changeset
998 }
anatofuz
parents:
diff changeset
999
anatofuz
parents:
diff changeset
1000 /// Add passes that optimize machine instructions in SSA form.
anatofuz
parents:
diff changeset
1001 void TargetPassConfig::addMachineSSAOptimization() {
anatofuz
parents:
diff changeset
1002 // Pre-ra tail duplication.
anatofuz
parents:
diff changeset
1003 addPass(&EarlyTailDuplicateID);
anatofuz
parents:
diff changeset
1004
anatofuz
parents:
diff changeset
1005 // Optimize PHIs before DCE: removing dead PHI cycles may make more
anatofuz
parents:
diff changeset
1006 // instructions dead.
anatofuz
parents:
diff changeset
1007 addPass(&OptimizePHIsID, false);
anatofuz
parents:
diff changeset
1008
anatofuz
parents:
diff changeset
1009 // This pass merges large allocas. StackSlotColoring is a different pass
anatofuz
parents:
diff changeset
1010 // which merges spill slots.
anatofuz
parents:
diff changeset
1011 addPass(&StackColoringID, false);
anatofuz
parents:
diff changeset
1012
anatofuz
parents:
diff changeset
1013 // If the target requests it, assign local variables to stack slots relative
anatofuz
parents:
diff changeset
1014 // to one another and simplify frame index references where possible.
anatofuz
parents:
diff changeset
1015 addPass(&LocalStackSlotAllocationID, false);
anatofuz
parents:
diff changeset
1016
anatofuz
parents:
diff changeset
1017 // With optimization, dead code should already be eliminated. However
anatofuz
parents:
diff changeset
1018 // there is one known exception: lowered code for arguments that are only
anatofuz
parents:
diff changeset
1019 // used by tail calls, where the tail calls reuse the incoming stack
anatofuz
parents:
diff changeset
1020 // arguments directly (see t11 in test/CodeGen/X86/sibcall.ll).
anatofuz
parents:
diff changeset
1021 addPass(&DeadMachineInstructionElimID);
anatofuz
parents:
diff changeset
1022
anatofuz
parents:
diff changeset
1023 // Allow targets to insert passes that improve instruction level parallelism,
anatofuz
parents:
diff changeset
1024 // like if-conversion. Such passes will typically need dominator trees and
anatofuz
parents:
diff changeset
1025 // loop info, just like LICM and CSE below.
anatofuz
parents:
diff changeset
1026 addILPOpts();
anatofuz
parents:
diff changeset
1027
anatofuz
parents:
diff changeset
1028 addPass(&EarlyMachineLICMID, false);
anatofuz
parents:
diff changeset
1029 addPass(&MachineCSEID, false);
anatofuz
parents:
diff changeset
1030
anatofuz
parents:
diff changeset
1031 addPass(&MachineSinkingID);
anatofuz
parents:
diff changeset
1032
anatofuz
parents:
diff changeset
1033 addPass(&PeepholeOptimizerID);
anatofuz
parents:
diff changeset
1034 // Clean-up the dead code that may have been generated by peephole
anatofuz
parents:
diff changeset
1035 // rewriting.
anatofuz
parents:
diff changeset
1036 addPass(&DeadMachineInstructionElimID);
anatofuz
parents:
diff changeset
1037 }
anatofuz
parents:
diff changeset
1038
anatofuz
parents:
diff changeset
1039 //===---------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
1040 /// Register Allocation Pass Configuration
anatofuz
parents:
diff changeset
1041 //===---------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
1042
anatofuz
parents:
diff changeset
1043 bool TargetPassConfig::getOptimizeRegAlloc() const {
anatofuz
parents:
diff changeset
1044 switch (OptimizeRegAlloc) {
anatofuz
parents:
diff changeset
1045 case cl::BOU_UNSET: return getOptLevel() != CodeGenOpt::None;
anatofuz
parents:
diff changeset
1046 case cl::BOU_TRUE: return true;
anatofuz
parents:
diff changeset
1047 case cl::BOU_FALSE: return false;
anatofuz
parents:
diff changeset
1048 }
anatofuz
parents:
diff changeset
1049 llvm_unreachable("Invalid optimize-regalloc state");
anatofuz
parents:
diff changeset
1050 }
anatofuz
parents:
diff changeset
1051
anatofuz
parents:
diff changeset
1052 /// A dummy default pass factory indicates whether the register allocator is
anatofuz
parents:
diff changeset
1053 /// overridden on the command line.
anatofuz
parents:
diff changeset
1054 static llvm::once_flag InitializeDefaultRegisterAllocatorFlag;
anatofuz
parents:
diff changeset
1055
anatofuz
parents:
diff changeset
1056 static RegisterRegAlloc
anatofuz
parents:
diff changeset
1057 defaultRegAlloc("default",
anatofuz
parents:
diff changeset
1058 "pick register allocator based on -O option",
anatofuz
parents:
diff changeset
1059 useDefaultRegisterAllocator);
anatofuz
parents:
diff changeset
1060
anatofuz
parents:
diff changeset
1061 static void initializeDefaultRegisterAllocatorOnce() {
anatofuz
parents:
diff changeset
1062 if (!RegisterRegAlloc::getDefault())
anatofuz
parents:
diff changeset
1063 RegisterRegAlloc::setDefault(RegAlloc);
anatofuz
parents:
diff changeset
1064 }
anatofuz
parents:
diff changeset
1065
anatofuz
parents:
diff changeset
1066 /// Instantiate the default register allocator pass for this target for either
anatofuz
parents:
diff changeset
1067 /// the optimized or unoptimized allocation path. This will be added to the pass
anatofuz
parents:
diff changeset
1068 /// manager by addFastRegAlloc in the unoptimized case or addOptimizedRegAlloc
anatofuz
parents:
diff changeset
1069 /// in the optimized case.
anatofuz
parents:
diff changeset
1070 ///
anatofuz
parents:
diff changeset
1071 /// A target that uses the standard regalloc pass order for fast or optimized
anatofuz
parents:
diff changeset
1072 /// allocation may still override this for per-target regalloc
anatofuz
parents:
diff changeset
1073 /// selection. But -regalloc=... always takes precedence.
anatofuz
parents:
diff changeset
1074 FunctionPass *TargetPassConfig::createTargetRegisterAllocator(bool Optimized) {
anatofuz
parents:
diff changeset
1075 if (Optimized)
anatofuz
parents:
diff changeset
1076 return createGreedyRegisterAllocator();
anatofuz
parents:
diff changeset
1077 else
anatofuz
parents:
diff changeset
1078 return createFastRegisterAllocator();
anatofuz
parents:
diff changeset
1079 }
anatofuz
parents:
diff changeset
1080
anatofuz
parents:
diff changeset
1081 /// Find and instantiate the register allocation pass requested by this target
anatofuz
parents:
diff changeset
1082 /// at the current optimization level. Different register allocators are
anatofuz
parents:
diff changeset
1083 /// defined as separate passes because they may require different analysis.
anatofuz
parents:
diff changeset
1084 ///
anatofuz
parents:
diff changeset
1085 /// This helper ensures that the regalloc= option is always available,
anatofuz
parents:
diff changeset
1086 /// even for targets that override the default allocator.
anatofuz
parents:
diff changeset
1087 ///
anatofuz
parents:
diff changeset
1088 /// FIXME: When MachinePassRegistry register pass IDs instead of function ptrs,
anatofuz
parents:
diff changeset
1089 /// this can be folded into addPass.
anatofuz
parents:
diff changeset
1090 FunctionPass *TargetPassConfig::createRegAllocPass(bool Optimized) {
anatofuz
parents:
diff changeset
1091 // Initialize the global default.
anatofuz
parents:
diff changeset
1092 llvm::call_once(InitializeDefaultRegisterAllocatorFlag,
anatofuz
parents:
diff changeset
1093 initializeDefaultRegisterAllocatorOnce);
anatofuz
parents:
diff changeset
1094
anatofuz
parents:
diff changeset
1095 RegisterRegAlloc::FunctionPassCtor Ctor = RegisterRegAlloc::getDefault();
anatofuz
parents:
diff changeset
1096 if (Ctor != useDefaultRegisterAllocator)
anatofuz
parents:
diff changeset
1097 return Ctor();
anatofuz
parents:
diff changeset
1098
anatofuz
parents:
diff changeset
1099 // With no -regalloc= override, ask the target for a regalloc pass.
anatofuz
parents:
diff changeset
1100 return createTargetRegisterAllocator(Optimized);
anatofuz
parents:
diff changeset
1101 }
anatofuz
parents:
diff changeset
1102
anatofuz
parents:
diff changeset
1103 bool TargetPassConfig::addRegAssignmentFast() {
anatofuz
parents:
diff changeset
1104 if (RegAlloc != &useDefaultRegisterAllocator &&
anatofuz
parents:
diff changeset
1105 RegAlloc != &createFastRegisterAllocator)
anatofuz
parents:
diff changeset
1106 report_fatal_error("Must use fast (default) register allocator for unoptimized regalloc.");
anatofuz
parents:
diff changeset
1107
anatofuz
parents:
diff changeset
1108 addPass(createRegAllocPass(false));
anatofuz
parents:
diff changeset
1109 return true;
anatofuz
parents:
diff changeset
1110 }
anatofuz
parents:
diff changeset
1111
anatofuz
parents:
diff changeset
1112 bool TargetPassConfig::addRegAssignmentOptimized() {
anatofuz
parents:
diff changeset
1113 // Add the selected register allocation pass.
anatofuz
parents:
diff changeset
1114 addPass(createRegAllocPass(true));
anatofuz
parents:
diff changeset
1115
anatofuz
parents:
diff changeset
1116 // Allow targets to change the register assignments before rewriting.
anatofuz
parents:
diff changeset
1117 addPreRewrite();
anatofuz
parents:
diff changeset
1118
anatofuz
parents:
diff changeset
1119 // Finally rewrite virtual registers.
anatofuz
parents:
diff changeset
1120 addPass(&VirtRegRewriterID);
anatofuz
parents:
diff changeset
1121 // Perform stack slot coloring and post-ra machine LICM.
anatofuz
parents:
diff changeset
1122 //
anatofuz
parents:
diff changeset
1123 // FIXME: Re-enable coloring with register when it's capable of adding
anatofuz
parents:
diff changeset
1124 // kill markers.
anatofuz
parents:
diff changeset
1125 addPass(&StackSlotColoringID);
anatofuz
parents:
diff changeset
1126
anatofuz
parents:
diff changeset
1127 return true;
anatofuz
parents:
diff changeset
1128 }
anatofuz
parents:
diff changeset
1129
anatofuz
parents:
diff changeset
1130 /// Return true if the default global register allocator is in use and
anatofuz
parents:
diff changeset
1131 /// has not be overriden on the command line with '-regalloc=...'
anatofuz
parents:
diff changeset
1132 bool TargetPassConfig::usingDefaultRegAlloc() const {
anatofuz
parents:
diff changeset
1133 return RegAlloc.getNumOccurrences() == 0;
anatofuz
parents:
diff changeset
1134 }
anatofuz
parents:
diff changeset
1135
anatofuz
parents:
diff changeset
1136 /// Add the minimum set of target-independent passes that are required for
anatofuz
parents:
diff changeset
1137 /// register allocation. No coalescing or scheduling.
anatofuz
parents:
diff changeset
1138 void TargetPassConfig::addFastRegAlloc() {
anatofuz
parents:
diff changeset
1139 addPass(&PHIEliminationID, false);
anatofuz
parents:
diff changeset
1140 addPass(&TwoAddressInstructionPassID, false);
anatofuz
parents:
diff changeset
1141
anatofuz
parents:
diff changeset
1142 addRegAssignmentFast();
anatofuz
parents:
diff changeset
1143 }
anatofuz
parents:
diff changeset
1144
anatofuz
parents:
diff changeset
1145 /// Add standard target-independent passes that are tightly coupled with
anatofuz
parents:
diff changeset
1146 /// optimized register allocation, including coalescing, machine instruction
anatofuz
parents:
diff changeset
1147 /// scheduling, and register allocation itself.
anatofuz
parents:
diff changeset
1148 void TargetPassConfig::addOptimizedRegAlloc() {
anatofuz
parents:
diff changeset
1149 addPass(&DetectDeadLanesID, false);
anatofuz
parents:
diff changeset
1150
anatofuz
parents:
diff changeset
1151 addPass(&ProcessImplicitDefsID, false);
anatofuz
parents:
diff changeset
1152
anatofuz
parents:
diff changeset
1153 // LiveVariables currently requires pure SSA form.
anatofuz
parents:
diff changeset
1154 //
anatofuz
parents:
diff changeset
1155 // FIXME: Once TwoAddressInstruction pass no longer uses kill flags,
anatofuz
parents:
diff changeset
1156 // LiveVariables can be removed completely, and LiveIntervals can be directly
anatofuz
parents:
diff changeset
1157 // computed. (We still either need to regenerate kill flags after regalloc, or
anatofuz
parents:
diff changeset
1158 // preferably fix the scavenger to not depend on them).
anatofuz
parents:
diff changeset
1159 addPass(&LiveVariablesID, false);
anatofuz
parents:
diff changeset
1160
anatofuz
parents:
diff changeset
1161 // Edge splitting is smarter with machine loop info.
anatofuz
parents:
diff changeset
1162 addPass(&MachineLoopInfoID, false);
anatofuz
parents:
diff changeset
1163 addPass(&PHIEliminationID, false);
anatofuz
parents:
diff changeset
1164
anatofuz
parents:
diff changeset
1165 // Eventually, we want to run LiveIntervals before PHI elimination.
anatofuz
parents:
diff changeset
1166 if (EarlyLiveIntervals)
anatofuz
parents:
diff changeset
1167 addPass(&LiveIntervalsID, false);
anatofuz
parents:
diff changeset
1168
anatofuz
parents:
diff changeset
1169 addPass(&TwoAddressInstructionPassID, false);
anatofuz
parents:
diff changeset
1170 addPass(&RegisterCoalescerID);
anatofuz
parents:
diff changeset
1171
anatofuz
parents:
diff changeset
1172 // The machine scheduler may accidentally create disconnected components
anatofuz
parents:
diff changeset
1173 // when moving subregister definitions around, avoid this by splitting them to
anatofuz
parents:
diff changeset
1174 // separate vregs before. Splitting can also improve reg. allocation quality.
anatofuz
parents:
diff changeset
1175 addPass(&RenameIndependentSubregsID);
anatofuz
parents:
diff changeset
1176
anatofuz
parents:
diff changeset
1177 // PreRA instruction scheduling.
anatofuz
parents:
diff changeset
1178 addPass(&MachineSchedulerID);
anatofuz
parents:
diff changeset
1179
anatofuz
parents:
diff changeset
1180 if (addRegAssignmentOptimized()) {
anatofuz
parents:
diff changeset
1181 // Allow targets to expand pseudo instructions depending on the choice of
anatofuz
parents:
diff changeset
1182 // registers before MachineCopyPropagation.
anatofuz
parents:
diff changeset
1183 addPostRewrite();
anatofuz
parents:
diff changeset
1184
anatofuz
parents:
diff changeset
1185 // Copy propagate to forward register uses and try to eliminate COPYs that
anatofuz
parents:
diff changeset
1186 // were not coalesced.
anatofuz
parents:
diff changeset
1187 addPass(&MachineCopyPropagationID);
anatofuz
parents:
diff changeset
1188
anatofuz
parents:
diff changeset
1189 // Run post-ra machine LICM to hoist reloads / remats.
anatofuz
parents:
diff changeset
1190 //
anatofuz
parents:
diff changeset
1191 // FIXME: can this move into MachineLateOptimization?
anatofuz
parents:
diff changeset
1192 addPass(&MachineLICMID);
anatofuz
parents:
diff changeset
1193 }
anatofuz
parents:
diff changeset
1194 }
anatofuz
parents:
diff changeset
1195
anatofuz
parents:
diff changeset
1196 //===---------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
1197 /// Post RegAlloc Pass Configuration
anatofuz
parents:
diff changeset
1198 //===---------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
1199
anatofuz
parents:
diff changeset
1200 /// Add passes that optimize machine instructions after register allocation.
anatofuz
parents:
diff changeset
1201 void TargetPassConfig::addMachineLateOptimization() {
anatofuz
parents:
diff changeset
1202 // Branch folding must be run after regalloc and prolog/epilog insertion.
anatofuz
parents:
diff changeset
1203 addPass(&BranchFolderPassID);
anatofuz
parents:
diff changeset
1204
anatofuz
parents:
diff changeset
1205 // Tail duplication.
anatofuz
parents:
diff changeset
1206 // Note that duplicating tail just increases code size and degrades
anatofuz
parents:
diff changeset
1207 // performance for targets that require Structured Control Flow.
anatofuz
parents:
diff changeset
1208 // In addition it can also make CFG irreducible. Thus we disable it.
anatofuz
parents:
diff changeset
1209 if (!TM->requiresStructuredCFG())
anatofuz
parents:
diff changeset
1210 addPass(&TailDuplicateID);
anatofuz
parents:
diff changeset
1211
anatofuz
parents:
diff changeset
1212 // Copy propagation.
anatofuz
parents:
diff changeset
1213 addPass(&MachineCopyPropagationID);
anatofuz
parents:
diff changeset
1214 }
anatofuz
parents:
diff changeset
1215
anatofuz
parents:
diff changeset
1216 /// Add standard GC passes.
anatofuz
parents:
diff changeset
1217 bool TargetPassConfig::addGCPasses() {
anatofuz
parents:
diff changeset
1218 addPass(&GCMachineCodeAnalysisID, false);
anatofuz
parents:
diff changeset
1219 return true;
anatofuz
parents:
diff changeset
1220 }
anatofuz
parents:
diff changeset
1221
anatofuz
parents:
diff changeset
1222 /// Add standard basic block placement passes.
anatofuz
parents:
diff changeset
1223 void TargetPassConfig::addBlockPlacement() {
anatofuz
parents:
diff changeset
1224 if (addPass(&MachineBlockPlacementID)) {
anatofuz
parents:
diff changeset
1225 // Run a separate pass to collect block placement statistics.
anatofuz
parents:
diff changeset
1226 if (EnableBlockPlacementStats)
anatofuz
parents:
diff changeset
1227 addPass(&MachineBlockPlacementStatsID);
anatofuz
parents:
diff changeset
1228 }
anatofuz
parents:
diff changeset
1229 }
anatofuz
parents:
diff changeset
1230
anatofuz
parents:
diff changeset
1231 //===---------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
1232 /// GlobalISel Configuration
anatofuz
parents:
diff changeset
1233 //===---------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
1234 bool TargetPassConfig::isGlobalISelAbortEnabled() const {
anatofuz
parents:
diff changeset
1235 return TM->Options.GlobalISelAbort == GlobalISelAbortMode::Enable;
anatofuz
parents:
diff changeset
1236 }
anatofuz
parents:
diff changeset
1237
anatofuz
parents:
diff changeset
1238 bool TargetPassConfig::reportDiagnosticWhenGlobalISelFallback() const {
anatofuz
parents:
diff changeset
1239 return TM->Options.GlobalISelAbort == GlobalISelAbortMode::DisableWithDiag;
anatofuz
parents:
diff changeset
1240 }
anatofuz
parents:
diff changeset
1241
anatofuz
parents:
diff changeset
1242 bool TargetPassConfig::isGISelCSEEnabled() const {
anatofuz
parents:
diff changeset
1243 return true;
anatofuz
parents:
diff changeset
1244 }
anatofuz
parents:
diff changeset
1245
anatofuz
parents:
diff changeset
1246 std::unique_ptr<CSEConfigBase> TargetPassConfig::getCSEConfig() const {
anatofuz
parents:
diff changeset
1247 return std::make_unique<CSEConfigBase>();
anatofuz
parents:
diff changeset
1248 }