96
96
#include " llvm/IRPrinter/IRPrintingPasses.h"
97
97
#include " llvm/MC/MCAsmInfo.h"
98
98
#include " llvm/MC/MCTargetOptions.h"
99
+ #include " llvm/Passes/PassBuilder.h"
99
100
#include " llvm/Support/CodeGen.h"
100
101
#include " llvm/Support/Debug.h"
101
102
#include " llvm/Support/Error.h"
113
114
#include " llvm/Transforms/Utils/EntryExitInstrumenter.h"
114
115
#include " llvm/Transforms/Utils/LowerInvoke.h"
115
116
#include < cassert>
117
+ #include < tuple>
116
118
#include < type_traits>
117
119
#include < utility>
118
120
@@ -154,8 +156,9 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
154
156
public:
155
157
explicit CodeGenPassBuilder (TargetMachineT &TM,
156
158
const CGPassBuilderOption &Opts,
157
- PassInstrumentationCallbacks *PIC)
158
- : TM(TM), Opt(Opts), PIC(PIC) {
159
+ PassInstrumentationCallbacks *PIC,
160
+ PassBuilder &PB)
161
+ : TM(TM), Opt(Opts), PIC(PIC), PB(PB) {
159
162
// Target could set CGPassBuilderOption::MISchedPostRA to true to achieve
160
163
// substitutePass(&PostRASchedulerID, &PostMachineSchedulerID)
161
164
@@ -291,6 +294,7 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
291
294
TargetMachineT &TM;
292
295
CGPassBuilderOption Opt;
293
296
PassInstrumentationCallbacks *PIC;
297
+ PassBuilder &PB;
294
298
295
299
template <typename TMC> TMC &getTM () const { return static_cast <TMC &>(TM); }
296
300
CodeGenOptLevel getOptLevel () const { return TM.getOptLevel (); }
@@ -498,6 +502,13 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
498
502
// / addMachinePasses helper to create the target-selected or overriden
499
503
// / regalloc pass.
500
504
void addRegAllocPass (AddMachinePass &, bool Optimized) const ;
505
+ // / Read the --regalloc-npm option to add the next pass in line.
506
+ bool addRegAllocPassFromOpt (AddMachinePass &,
507
+ StringRef MatchPassTo = StringRef{}) const ;
508
+ // / Add the next pass in the cli option, or return false if there is no pass
509
+ // / left in the option.
510
+ template <typename RegAllocPassT>
511
+ void addRegAllocPassOrOpt (AddMachinePass &, RegAllocPassT Pass) const ;
501
512
502
513
// / Add core register alloator passes which do the actual register assignment
503
514
// / and rewriting. \returns true if any passes were added.
@@ -594,6 +605,11 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::buildPipeline(
594
605
if (PrintMIR)
595
606
addPass (PrintMIRPass (Out), /* Force=*/ true );
596
607
608
+ if (!Opt.RegAllocPipeline .empty ())
609
+ return make_error<StringError>(
610
+ " Extra passes in regalloc pipeline: " + Opt.RegAllocPipeline ,
611
+ std::make_error_code (std::errc::invalid_argument));
612
+
597
613
return verifyStartStop (*StartStopInfo);
598
614
}
599
615
@@ -1088,6 +1104,49 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::addTargetRegisterAllocator(
1088
1104
addPass (RegAllocFastPass ());
1089
1105
}
1090
1106
1107
+ template <typename Derived, typename TargetMachineT>
1108
+ template <typename RegAllocPassT>
1109
+ void CodeGenPassBuilder<Derived, TargetMachineT>::addRegAllocPassOrOpt(
1110
+ AddMachinePass &addPass, RegAllocPassT Pass) const {
1111
+ if (!addRegAllocPassFromOpt (addPass))
1112
+ addPass (std::move (Pass));
1113
+ }
1114
+
1115
+ template <typename Derived, typename TargetMachineT>
1116
+ bool CodeGenPassBuilder<Derived, TargetMachineT>::addRegAllocPassFromOpt(
1117
+ AddMachinePass &addPass, StringRef MatchPassTo) const {
1118
+ if (!Opt.RegAllocPipeline .empty ()) {
1119
+ StringRef PassOpt;
1120
+ std::tie (PassOpt, Opt.RegAllocPipeline ) = Opt.RegAllocPipeline .split (' ,' );
1121
+ // Reuse the registered parser to parse the pass name.
1122
+ #define MACHINE_FUNCTION_PASS_WITH_PARAMS (NAME, CLASS, CREATE_PASS, PARSER, \
1123
+ PARAMS) \
1124
+ if (PB.checkParametrizedPassName (PassOpt, NAME)) { \
1125
+ auto Params = PB.parsePassParameters (PARSER, PassOpt, NAME, \
1126
+ const_cast <const PassBuilder &>(PB)); \
1127
+ if (!Params) { \
1128
+ auto Err = Params.takeError (); \
1129
+ ExitOnError ()(std::move (Err)); \
1130
+ } \
1131
+ if (!MatchPassTo.empty ()) { \
1132
+ if (MatchPassTo != CLASS) \
1133
+ report_fatal_error (" Expected " + \
1134
+ PIC->getPassNameForClassName (MatchPassTo) + \
1135
+ " in option -regalloc-npm" , \
1136
+ false ); \
1137
+ } \
1138
+ addPass (CREATE_PASS (Params.get ())); \
1139
+ return true ; \
1140
+ }
1141
+ #include " llvm/Passes/MachinePassRegistry.def"
1142
+ if (PassOpt != " default" ) {
1143
+ report_fatal_error (" Unknown register allocator pass: " + PassOpt, false );
1144
+ }
1145
+ }
1146
+ // If user did not give a specific pass, use the default provided.
1147
+ return false ;
1148
+ }
1149
+
1091
1150
// / Find and instantiate the register allocation pass requested by this target
1092
1151
// / at the current optimization level. Different register allocators are
1093
1152
// / defined as separate passes because they may require different analysis.
@@ -1098,22 +1157,13 @@ template <typename Derived, typename TargetMachineT>
1098
1157
void CodeGenPassBuilder<Derived, TargetMachineT>::addRegAllocPass(
1099
1158
AddMachinePass &addPass, bool Optimized) const {
1100
1159
// Use the specified -regalloc-npm={basic|greedy|fast|pbqp}
1101
- if (Opt.RegAlloc > RegAllocType::Default) {
1102
- switch (Opt.RegAlloc ) {
1103
- case RegAllocType::Fast:
1104
- addPass (RegAllocFastPass ());
1105
- break ;
1106
- case RegAllocType::Greedy:
1107
- addPass (RAGreedyPass ());
1108
- break ;
1109
- default :
1110
- report_fatal_error (" register allocator not supported yet" , false );
1111
- }
1112
- return ;
1160
+ StringRef RegAllocPassName;
1161
+ if (!Optimized)
1162
+ RegAllocPassName = RegAllocFastPass::name ();
1163
+
1164
+ if (!addRegAllocPassFromOpt (addPass, RegAllocPassName)) {
1165
+ derived ().addTargetRegisterAllocator (addPass, Optimized);
1113
1166
}
1114
- // -regalloc=default or unspecified, so pick based on the optimization level
1115
- // or ask the target for the regalloc pass.
1116
- derived ().addTargetRegisterAllocator (addPass, Optimized);
1117
1167
}
1118
1168
1119
1169
template <typename Derived, typename TargetMachineT>
0 commit comments