llvm.org GIT mirror llvm / 21c4458
[PM] Sink the reference vs. value decision for IR units out of the templated interface. So far, every single IR unit I can come up with has address-identity. That is, when two units of IR are both active in LLVM, their addresses will be distinct of the IR is distinct. This is clearly true for Modules, Functions, BasicBlocks, and Instructions. It turns out that the only practical way to make the CGSCC stuff work the way we want is to make it true for SCCs as well. I expect this pattern to continue. When first designing the pass manager code, I kept this dimension of freedom in the type parameters, essentially allowing for a wrapper-type whose address did not form identity. But that really no longer makes sense and is making the code more complex or subtle for no gain. If we ever have an actual use case for this, we can figure out what makes sense then and there. It will be better because then we will have the actual example in hand. While the simplifications afforded in this patch are fairly small (mostly sinking the '&' out of many type parameters onto a few interfaces), it would have become much more pronounced with subsequent changes. I have a sequence of changes that will completely remove the code duplication that currently exists between all of the pass managers and analysis managers. =] Should make things much cleaner and avoid bug fixing N times for the N pass managers. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225723 91177308-0d34-0410-b5e6-96231b3b80d8 Chandler Carruth 5 years ago
4 changed file(s) with 43 addition(s) and 43 deletion(s). Raw diff Collapse all Expand all
5050
5151 private:
5252 // Pull in the concept type and model template specialized for SCCs.
53 typedef detail::PassConcept &, CGSCCAnalysisManager>
53 typedef detail::PassConcept, CGSCCAnalysisManager>
5454 CGSCCPassConcept;
5555 template
5656 struct CGSCCPassModel
57 : detail::PassModel &, CGSCCAnalysisManager, PassT> {
57 : detail::PassModel, CGSCCAnalysisManager, PassT> {
5858 CGSCCPassModel(PassT Pass)
59 : detail::PassModel &, CGSCCAnalysisManager, PassT>(
59 : detail::PassModel, CGSCCAnalysisManager, PassT>(
6060 std::move(Pass)) {}
6161 };
6262
6969 /// \brief A function analysis manager to coordinate and cache analyses run over
7070 /// a module.
7171 class CGSCCAnalysisManager : public detail::AnalysisManagerBase<
72 CGSCCAnalysisManager, LazyCallGraph::SCC &> {
72 CGSCCAnalysisManager, LazyCallGraph::SCC> {
7373 friend class detail::AnalysisManagerBase
74 LazyCallGraph::SCC &>;
74 LazyCallGraph::SCC>;
7575 typedef detail::AnalysisManagerBase
76 LazyCallGraph::SCC &> BaseT;
76 LazyCallGraph::SCC> BaseT;
7777 typedef BaseT::ResultConceptT ResultConceptT;
7878 typedef BaseT::PassConceptT PassConceptT;
7979
128128 /// half of a bijection and provides storage for the actual result concept.
129129 typedef std::list<
130130 std::pair
131 LazyCallGraph::SCC &>>>> CGSCCAnalysisResultListT;
131 LazyCallGraph::SCC>>>> CGSCCAnalysisResultListT;
132132
133133 /// \brief Map type from function pointer to our custom list type.
134134 typedef DenseMap
202202
203203 private:
204204 // Pull in the concept type and model template specialized for modules.
205 typedef detail::PassConcept &, ModuleAnalysisManager>
205 typedef detail::PassConcept, ModuleAnalysisManager>
206206 ModulePassConcept;
207207 template
208208 struct ModulePassModel
209 : detail::PassModel &, ModuleAnalysisManager, PassT> {
209 : detail::PassModel, ModuleAnalysisManager, PassT> {
210210 ModulePassModel(PassT Pass)
211 : detail::PassModel &, ModuleAnalysisManager, PassT>(
211 : detail::PassModel, ModuleAnalysisManager, PassT>(
212212 std::move(Pass)) {}
213213 };
214214
267267
268268 private:
269269 // Pull in the concept type and model template specialized for functions.
270 typedef detail::PassConcept &, FunctionAnalysisManager>
270 typedef detail::PassConcept, FunctionAnalysisManager>
271271 FunctionPassConcept;
272272 template
273273 struct FunctionPassModel
274 : detail::PassModel &, FunctionAnalysisManager, PassT> {
274 : detail::PassModel, FunctionAnalysisManager, PassT> {
275275 FunctionPassModel(PassT Pass)
276 : detail::PassModel &, FunctionAnalysisManager, PassT>(
276 : detail::PassModel, FunctionAnalysisManager, PassT>(
277277 std::move(Pass)) {}
278278 };
279279
329329 ///
330330 /// If there is not a valid cached result in the manager already, this will
331331 /// re-run the analysis to produce a valid result.
332 template typename PassT::Result &getResult(IRUnitT IR) {
332 template typename PassT::Result &getResult(IRUnitT &IR) {
333333 assert(AnalysisPasses.count(PassT::ID()) &&
334334 "This analysis pass was not registered prior to being queried");
335335
346346 ///
347347 /// \returns null if there is no cached result.
348348 template
349 typename PassT::Result *getCachedResult(IRUnitT IR) const {
349 typename PassT::Result *getCachedResult(IRUnitT &IR) const {
350350 assert(AnalysisPasses.count(PassT::ID()) &&
351351 "This analysis pass was not registered prior to being queried");
352352
375375 /// \brief Invalidate a specific analysis pass for an IR module.
376376 ///
377377 /// Note that the analysis result can disregard invalidation.
378 template void invalidate(IRUnitT IR) {
378 template void invalidate(IRUnitT &IR) {
379379 assert(AnalysisPasses.count(PassT::ID()) &&
380380 "This analysis pass was not registered prior to being invalidated");
381381 derived_this()->invalidateImpl(PassT::ID(), IR);
388388 /// We accept the PreservedAnalyses set by value and update it with each
389389 /// analyis pass which has been successfully invalidated and thus can be
390390 /// preserved going forward. The updated set is returned.
391 PreservedAnalyses invalidate(IRUnitT IR, PreservedAnalyses PA) {
391 PreservedAnalyses invalidate(IRUnitT &IR, PreservedAnalyses PA) {
392392 return derived_this()->invalidateImpl(IR, std::move(PA));
393393 }
394394
422422 /// \brief A module analysis pass manager with lazy running and caching of
423423 /// results.
424424 class ModuleAnalysisManager
425 : public detail::AnalysisManagerBase {
426 friend class detail::AnalysisManagerBase;
427 typedef detail::AnalysisManagerBase BaseT;
425 : public detail::AnalysisManagerBase {
426 friend class detail::AnalysisManagerBase;
427 typedef detail::AnalysisManagerBase BaseT;
428428 typedef BaseT::ResultConceptT ResultConceptT;
429429 typedef BaseT::PassConceptT PassConceptT;
430430
461461 /// \brief Map type from module analysis pass ID to pass result concept
462462 /// pointer.
463463 typedef DenseMap
464 std::unique_ptr &>>>
464 std::unique_ptr>>>
465465 ModuleAnalysisResultMapT;
466466
467467 /// \brief Cache of computed module analysis results for this module.
471471 /// \brief A function analysis manager to coordinate and cache analyses run over
472472 /// a module.
473473 class FunctionAnalysisManager
474 : public detail::AnalysisManagerBase {
475 friend class detail::AnalysisManagerBase;
476 typedef detail::AnalysisManagerBase
474 : public detail::AnalysisManagerBase {
475 friend class detail::AnalysisManagerBase;
476 typedef detail::AnalysisManagerBase
477477 BaseT;
478478 typedef BaseT::ResultConceptT ResultConceptT;
479479 typedef BaseT::PassConceptT PassConceptT;
528528 /// erases. Provides both the pass ID and concept pointer such that it is
529529 /// half of a bijection and provides storage for the actual result concept.
530530 typedef std::list
531 void *, std::unique_ptr &>>>>
531 void *, std::unique_ptr>>>>
532532 FunctionAnalysisResultListT;
533533
534534 /// \brief Map type from function pointer to our custom list type.
787787 /// provided they satisfy the basic API requirements. When this pass is
788788 /// created, these methods can be instantiated to satisfy whatever the
789789 /// context requires.
790 template
791 PreservedAnalyses run(T &&Arg, AnalysisManagerT *AM) {
790 template
791 PreservedAnalyses run(IRUnitT &Arg, AnalysisManagerT *AM) {
792792 if (AM)
793 (void)AM->template getResult(std::forward(Arg));
793 (void)AM->template getResult(Arg);
794794
795795 return PreservedAnalyses::all();
796796 }
810810 /// provided they satisfy the basic API requirements. When this pass is
811811 /// created, these methods can be instantiated to satisfy whatever the
812812 /// context requires.
813 template
814 PreservedAnalyses run(T &&Arg, AnalysisManagerT *AM) {
813 template
814 PreservedAnalyses run(IRUnitT &Arg, AnalysisManagerT *AM) {
815815 if (AM)
816816 // We have to directly invalidate the analysis result as we can't
817817 // enumerate all other analyses and use the preserved set to control it.
818 (void)AM->template invalidate(std::forward(Arg));
818 (void)AM->template invalidate(Arg);
819819
820820 return PreservedAnalyses::all();
821821 }
3939 /// Note that actual pass object can omit the analysis manager argument if
4040 /// desired. Also that the analysis manager may be null if there is no
4141 /// analysis manager in the pass pipeline.
42 virtual PreservedAnalyses run(IRUnitT IR, AnalysisManagerT *AM) = 0;
42 virtual PreservedAnalyses run(IRUnitT &IR, AnalysisManagerT *AM) = 0;
4343
4444 /// \brief Polymorphic method to access the name of a pass.
4545 virtual StringRef name() = 0;
5555 char a, b;
5656 };
5757
58 template , AnalysisManagerT *)>
58 template &, AnalysisManagerT *)>
5959 struct Checker;
6060
6161 template static SmallType f(Checker *);
9696 return *this;
9797 }
9898
99 PreservedAnalysesT run(IRUnitT IR, AnalysisManagerT *AM) override {
99 PreservedAnalysesT run(IRUnitT &IR, AnalysisManagerT *AM) override {
100100 return Pass.run(IR, AM);
101101 }
102102 StringRef name() override { return PassT::name(); }
123123 return *this;
124124 }
125125
126 PreservedAnalysesT run(IRUnitT IR, AnalysisManagerT *AM) override {
126 PreservedAnalysesT run(IRUnitT &IR, AnalysisManagerT *AM) override {
127127 return Pass.run(IR);
128128 }
129129 StringRef name() override { return PassT::name(); }
147147 /// took care to update or preserve the analysis result in some way.
148148 ///
149149 /// \returns true if the result is indeed invalid (the default).
150 virtual bool invalidate(IRUnitT IR, const PreservedAnalyses &PA) = 0;
150 virtual bool invalidate(IRUnitT &IR, const PreservedAnalyses &PA) = 0;
151151 };
152152
153153 /// \brief SFINAE metafunction for computing whether \c ResultT provides an
158158 char a, b;
159159 };
160160
161 template , const PreservedAnalyses &)>
161 template &, const PreservedAnalyses &)>
162162 struct Checker;
163163
164164 template static SmallType f(Checker *);
206206 // FIXME: We should actually use two different concepts for analysis results
207207 // rather than two different models, and avoid the indirect function call for
208208 // ones that use the trivial behavior.
209 bool invalidate(IRUnitT, const PreservedAnalysesT &PA) override {
209 bool invalidate(IRUnitT &, const PreservedAnalysesT &PA) override {
210210 return !PA.preserved(PassT::ID());
211211 }
212212
235235 }
236236
237237 /// \brief The model delegates to the \c ResultT method.
238 bool invalidate(IRUnitT IR, const PreservedAnalysesT &PA) override {
238 bool invalidate(IRUnitT &IR, const PreservedAnalysesT &PA) override {
239239 return Result.invalidate(IR, PA);
240240 }
241241
254254 /// \returns A unique_ptr to the analysis result object to be queried by
255255 /// users.
256256 virtual std::unique_ptr>
257 run(IRUnitT IR, AnalysisManagerT *AM) = 0;
257 run(IRUnitT &IR, AnalysisManagerT *AM) = 0;
258258
259259 /// \brief Polymorphic method to access the name of a pass.
260260 virtual StringRef name() = 0;
297297 ///
298298 /// The return is wrapped in an \c AnalysisResultModel.
299299 std::unique_ptr>
300 run(IRUnitT IR, AnalysisManagerT *AM) override {
300 run(IRUnitT &IR, AnalysisManagerT *AM) override {
301301 return make_unique(Pass.run(IR, AM));
302302 }
303303
336336 ///
337337 /// The return is wrapped in an \c AnalysisResultModel.
338338 std::unique_ptr>
339 run(IRUnitT IR, AnalysisManagerT *) override {
339 run(IRUnitT &IR, AnalysisManagerT *) override {
340340 return make_unique(Pass.run(IR));
341341 }
342342
5656 ModuleAnalysisResultMapT::iterator RI;
5757 bool Inserted;
5858 std::tie(RI, Inserted) = ModuleAnalysisResults.insert(std::make_pair(
59 PassID, std::unique_ptr &>>()));
59 PassID, std::unique_ptr>>()));
6060
6161 // If we don't have a cached result for this module, look up the pass and run
6262 // it to produce a result, which we then add to the cache.