2626using namespace llvm ;
2727
2828namespace llvm {
29- void initializeRefNormalizePassPass (PassRegistry &Registry);
30- void initializeRefPrunePassPass (PassRegistry &Registry);
29+ void initializeRefNormalizeLegacyPassPass (PassRegistry &Registry);
30+ void initializeRefPruneLegacyPassPass (PassRegistry &Registry);
3131} // namespace llvm
3232
33+ namespace llvm {
34+ struct OpaqueModulePassManager ;
35+ typedef OpaqueModulePassManager *LLVMModulePassManagerRef;
36+ DEFINE_SIMPLE_CONVERSION_FUNCTIONS (ModulePassManager, LLVMModulePassManagerRef)
37+
38+ struct OpaqueFunctionPassManager ;
39+ typedef OpaqueFunctionPassManager *LLVMFunctionPassManagerRef;
40+ DEFINE_SIMPLE_CONVERSION_FUNCTIONS (FunctionPassManager,
41+ LLVMFunctionPassManagerRef)
42+ } // namespace llvm
43+
44+ namespace {
3345/* *
3446 * Checks if a call instruction is an incref
3547 *
@@ -104,13 +116,9 @@ template <class Tstack> struct raiiStack {
104116 * A FunctionPass to reorder incref/decref instructions such that decrefs occur
105117 * logically after increfs. This is a pre-requisite pass to the pruner passes.
106118 */
107- struct RefNormalizePass : public FunctionPass {
108- static char ID ;
109- RefNormalizePass () : FunctionPass(ID ) {
110- initializeRefNormalizePassPass (*PassRegistry::getPassRegistry ());
111- }
119+ struct RefNormalize {
112120
113- bool runOnFunction (Function &F) override {
121+ bool runOnFunction (Function &F) {
114122 bool mutated = false ;
115123 // For each basic block in F
116124 for (BasicBlock &bb : F) {
@@ -158,7 +166,16 @@ struct RefNormalizePass : public FunctionPass {
158166 }
159167};
160168
161- struct RefPrunePass : public FunctionPass {
169+ typedef enum {
170+ None = 0b0000 ,
171+ PerBasicBlock = 0b0001 ,
172+ Diamond = 0b0010 ,
173+ Fanout = 0b0100 ,
174+ FanoutRaise = 0b1000 ,
175+ All = PerBasicBlock | Diamond | Fanout | FanoutRaise
176+ } Subpasses;
177+
178+ struct RefPrune {
162179 static char ID ;
163180 static size_t stats_per_bb;
164181 static size_t stats_diamond;
@@ -175,25 +192,21 @@ struct RefPrunePass : public FunctionPass {
175192 /* *
176193 * Enum for setting which subpasses to run, there is no interdependence.
177194 */
178- enum Subpasses {
179- None = 0b0000 ,
180- PerBasicBlock = 0b0001 ,
181- Diamond = 0b0010 ,
182- Fanout = 0b0100 ,
183- FanoutRaise = 0b1000 ,
184- All = PerBasicBlock | Diamond | Fanout | FanoutRaise
185- } flags;
186195
187- RefPrunePass (Subpasses flags = Subpasses::All, size_t subgraph_limit = -1 )
188- : FunctionPass(ID ), flags(flags), subgraph_limit(subgraph_limit) {
189- initializeRefPrunePassPass (*PassRegistry::getPassRegistry ());
190- }
196+ Subpasses flags;
197+
198+ DominatorTree &DT ;
199+ PostDominatorTree &PDT ;
200+
201+ RefPrune (DominatorTree &DT , PostDominatorTree &PDT ,
202+ Subpasses flags = Subpasses::All, size_t subgraph_limit = -1 )
203+ : DT (DT ), PDT (PDT ), flags(flags), subgraph_limit(subgraph_limit) {}
191204
192205 bool isSubpassEnabledFor (Subpasses expected) {
193206 return (flags & expected) == expected;
194207 }
195208
196- bool runOnFunction (Function &F) override {
209+ bool runOnFunction (Function &F) {
197210 // state for LLVM function pass mutated IR
198211 bool mutated = false ;
199212
@@ -361,11 +374,6 @@ struct RefPrunePass : public FunctionPass {
361374 */
362375 bool runDiamondPrune (Function &F) {
363376 bool mutated = false ;
364- // gets the dominator tree
365- auto &domtree = getAnalysis<DominatorTreeWrapperPass>().getDomTree ();
366- // gets the post-dominator tree
367- auto &postdomtree =
368- getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree ();
369377
370378 // Find all increfs and decrefs in the Function and store them in
371379 // incref_list and decref_list respectively.
@@ -394,8 +402,8 @@ struct RefPrunePass : public FunctionPass {
394402 continue ;
395403
396404 // incref DOM decref && decref POSTDOM incref
397- if (domtree .dominates (incref, decref) &&
398- postdomtree .dominates (decref, incref)) {
405+ if (DT .dominates (incref, decref) &&
406+ PDT .dominates (decref, incref)) {
399407 // check that the decref cannot be executed multiple times
400408 SmallBBSet tail_nodes;
401409 tail_nodes.insert (decref->getParent ());
@@ -1028,14 +1036,6 @@ struct RefPrunePass : public FunctionPass {
10281036 return NULL ;
10291037 }
10301038
1031- /* *
1032- * getAnalysisUsage() LLVM plumbing for the pass
1033- */
1034- void getAnalysisUsage (AnalysisUsage &Info) const override {
1035- Info.addRequired <DominatorTreeWrapperPass>();
1036- Info.addRequired <PostDominatorTreeWrapperPass>();
1037- }
1038-
10391039 /* *
10401040 * Checks if the first argument to the supplied call_inst is NULL and
10411041 * returns true if so, false otherwise.
@@ -1163,34 +1163,128 @@ struct RefPrunePass : public FunctionPass {
11631163 }
11641164 }
11651165 }
1166- }; // end of struct RefPrunePass
1166+ }; // end of struct RefPrune
1167+
1168+ } // namespace
1169+
1170+ class RefPrunePass : public PassInfoMixin <RefPrunePass> {
1171+
1172+ public:
1173+ Subpasses flags;
1174+ size_t subgraph_limit;
1175+ RefPrunePass (Subpasses flags = Subpasses::All, size_t subgraph_limit = -1 )
1176+ : flags(flags), subgraph_limit(subgraph_limit) {}
1177+
1178+ PreservedAnalyses run (Function &F, FunctionAnalysisManager &AM ) {
1179+ auto &DT = AM .getResult <DominatorTreeAnalysis>(F);
1180+ auto &PDT = AM .getResult <PostDominatorTreeAnalysis>(F);
1181+ if (RefPrune (DT , PDT , flags, subgraph_limit).runOnFunction (F)) {
1182+ return PreservedAnalyses::none ();
1183+ }
1184+
1185+ return PreservedAnalyses::all ();
1186+ }
1187+ };
11671188
1168- char RefNormalizePass::ID = 0 ;
1169- char RefPrunePass::ID = 0 ;
1189+ class RefNormalizePass : public PassInfoMixin <RefNormalizePass> {
11701190
1171- size_t RefPrunePass::stats_per_bb = 0 ;
1172- size_t RefPrunePass::stats_diamond = 0 ;
1173- size_t RefPrunePass::stats_fanout = 0 ;
1174- size_t RefPrunePass::stats_fanout_raise = 0 ;
1191+ public:
1192+ RefNormalizePass () = default ;
11751193
1176- INITIALIZE_PASS (RefNormalizePass, " nrtrefnormalizepass " , " Normalize NRT refops " ,
1177- false , false )
1194+ PreservedAnalyses run (Function &F, FunctionAnalysisManager & AM ) {
1195+ RefNormalize (). runOnFunction (F);
11781196
1179- INITIALIZE_PASS_BEGIN (RefPrunePass, " nrtrefprunepass" , " Prune NRT refops" ,
1180- false , false )
1197+ return PreservedAnalyses::all ();
1198+ }
1199+ };
1200+
1201+ class RefNormalizeLegacyPass : public FunctionPass {
1202+ public:
1203+ static char ID ;
1204+ RefNormalizeLegacyPass () : FunctionPass(ID ) {
1205+ initializeRefNormalizeLegacyPassPass (*PassRegistry::getPassRegistry ());
1206+ }
1207+
1208+ bool runOnFunction (Function &F) override {
1209+ return RefNormalize ().runOnFunction (F);
1210+ };
1211+ };
1212+
1213+ class RefPruneLegacyPass : public FunctionPass {
1214+
1215+ public:
1216+ static char ID ; // Pass identification, replacement for typeid
1217+ // The maximum number of nodes that the fanout pruners will look at.
1218+ size_t subgraph_limit;
1219+ Subpasses flags;
1220+ RefPruneLegacyPass (Subpasses flags = Subpasses::All,
1221+ size_t subgraph_limit = -1 )
1222+ : FunctionPass(ID ), flags(flags), subgraph_limit(subgraph_limit) {
1223+ initializeRefPruneLegacyPassPass (*PassRegistry::getPassRegistry ());
1224+ }
1225+
1226+ bool runOnFunction (Function &F) override {
1227+ auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree ();
1228+
1229+ auto &PDT =
1230+ getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree ();
1231+
1232+ return RefPrune (DT , PDT , flags, subgraph_limit).runOnFunction (F);
1233+ };
1234+
1235+ /* *
1236+ * getAnalysisUsage() LLVM plumbing for the pass
1237+ */
1238+ void getAnalysisUsage (AnalysisUsage &Info) const override {
1239+ Info.addRequired <DominatorTreeWrapperPass>();
1240+ Info.addRequired <PostDominatorTreeWrapperPass>();
1241+ }
1242+ };
1243+
1244+ char RefNormalizeLegacyPass::ID = 0 ;
1245+ char RefPruneLegacyPass::ID = 0 ;
1246+
1247+ size_t RefPrune::stats_per_bb = 0 ;
1248+ size_t RefPrune::stats_diamond = 0 ;
1249+ size_t RefPrune::stats_fanout = 0 ;
1250+ size_t RefPrune::stats_fanout_raise = 0 ;
1251+
1252+ INITIALIZE_PASS (RefNormalizeLegacyPass, " nrtRefNormalize" ,
1253+ " Normalize NRT refops" , false , false )
1254+
1255+ INITIALIZE_PASS_BEGIN (RefPruneLegacyPass, " nrtRefPruneLegacyPass" ,
1256+ " Prune NRT refops" , false , false )
11811257INITIALIZE_PASS_DEPENDENCY (DominatorTreeWrapperPass)
11821258INITIALIZE_PASS_DEPENDENCY (PostDominatorTreeWrapperPass)
11831259
1184- INITIALIZE_PASS_END (RefPrunePass, " refprunepass" , " Prune NRT refops" , false ,
1185- false )
1260+ INITIALIZE_PASS_END (RefPruneLegacyPass, " RefPruneLegacyPass" ,
1261+ " Prune NRT refops" , false , false )
1262+
11861263extern " C" {
11871264
11881265API_EXPORT (void )
1189- LLVMPY_AddRefPrunePass (LLVMPassManagerRef PM , int subpasses,
1190- size_t subgraph_limit) {
1191- unwrap (PM )->add (new RefNormalizePass ());
1266+ LLVMPY_AddLegacyRefPrunePass (LLVMPassManagerRef PM , int subpasses,
1267+ size_t subgraph_limit) {
1268+ unwrap (PM )->add (new RefNormalizeLegacyPass ());
11921269 unwrap (PM )->add (
1193- new RefPrunePass ((RefPrunePass::Subpasses)subpasses, subgraph_limit));
1270+ new RefPruneLegacyPass ((Subpasses)subpasses, subgraph_limit));
1271+ }
1272+
1273+ API_EXPORT (void )
1274+ LLVMPY_AddRefPrunePass_module (LLVMModulePassManagerRef MPM , int subpasses,
1275+ size_t subgraph_limit) {
1276+ llvm::unwrap (MPM )->addPass (
1277+ createModuleToFunctionPassAdaptor (RefNormalizePass ()));
1278+ llvm::unwrap (MPM )->addPass (createModuleToFunctionPassAdaptor (
1279+ RefPrunePass ((Subpasses)subpasses, subgraph_limit)));
1280+ }
1281+
1282+ API_EXPORT (void )
1283+ LLVMPY_AddRefPrunePass_function (LLVMFunctionPassManagerRef FPM , int subpasses,
1284+ size_t subgraph_limit) {
1285+ llvm::unwrap (FPM )->addPass (RefNormalizePass ());
1286+ llvm::unwrap (FPM )->addPass (
1287+ RefPrunePass ((Subpasses)subpasses, subgraph_limit));
11941288}
11951289
11961290/* *
@@ -1207,24 +1301,22 @@ typedef struct PruneStats {
12071301API_EXPORT (void )
12081302LLVMPY_DumpRefPruneStats (PRUNESTATS *buf, bool do_print) {
12091303 /* PRUNESTATS is updated with the statistics about what has been pruned from
1210- * the RefPrunePass static state vars. This isn't threadsafe but neither is
1304+ * the RefPrune static state vars. This isn't threadsafe but neither is
12111305 * the LLVM pass infrastructure so it's all done under a python thread lock.
12121306 *
12131307 * do_print if set will print the stats to stderr.
12141308 */
12151309 if (do_print) {
1216- errs () << " refprune stats "
1217- << " per-BB " << RefPrunePass::stats_per_bb << " "
1218- << " diamond " << RefPrunePass::stats_diamond << " "
1219- << " fanout " << RefPrunePass::stats_fanout << " "
1220- << " fanout+raise " << RefPrunePass::stats_fanout_raise << " "
1221- << " \n " ;
1310+ errs () << " refprune stats " << " per-BB " << RefPrune::stats_per_bb
1311+ << " " << " diamond " << RefPrune::stats_diamond << " "
1312+ << " fanout " << RefPrune::stats_fanout << " " << " fanout+raise "
1313+ << RefPrune::stats_fanout_raise << " " << " \n " ;
12221314 };
12231315
1224- buf->basicblock = RefPrunePass ::stats_per_bb;
1225- buf->diamond = RefPrunePass ::stats_diamond;
1226- buf->fanout = RefPrunePass ::stats_fanout;
1227- buf->fanout_raise = RefPrunePass ::stats_fanout_raise;
1316+ buf->basicblock = RefPrune ::stats_per_bb;
1317+ buf->diamond = RefPrune ::stats_diamond;
1318+ buf->fanout = RefPrune ::stats_fanout;
1319+ buf->fanout_raise = RefPrune ::stats_fanout_raise;
12281320}
12291321
12301322} // extern "C"
0 commit comments