10b57cec5SDimitry Andric //===- llvm/PassInfo.h - Pass Info class ------------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file defines and implements the PassInfo class.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #ifndef LLVM_PASSINFO_H
140b57cec5SDimitry Andric #define LLVM_PASSINFO_H
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
170b57cec5SDimitry Andric #include <cassert>
180b57cec5SDimitry Andric #include <vector>
190b57cec5SDimitry Andric 
200b57cec5SDimitry Andric namespace llvm {
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric class Pass;
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric //===---------------------------------------------------------------------------
250b57cec5SDimitry Andric /// PassInfo class - An instance of this class exists for every pass known by
260b57cec5SDimitry Andric /// the system, and can be obtained from a live Pass by calling its
270b57cec5SDimitry Andric /// getPassInfo() method.  These objects are set up by the RegisterPass<>
280b57cec5SDimitry Andric /// template.
290b57cec5SDimitry Andric ///
300b57cec5SDimitry Andric class PassInfo {
310b57cec5SDimitry Andric public:
320b57cec5SDimitry Andric   using NormalCtor_t = Pass* (*)();
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric private:
350b57cec5SDimitry Andric   StringRef PassName;     // Nice name for Pass
360b57cec5SDimitry Andric   StringRef PassArgument; // Command Line argument to run this pass
370b57cec5SDimitry Andric   const void *PassID;
380b57cec5SDimitry Andric   const bool IsCFGOnlyPass = false;      // Pass only looks at the CFG.
390b57cec5SDimitry Andric   const bool IsAnalysis;                 // True if an analysis pass.
400b57cec5SDimitry Andric   const bool IsAnalysisGroup;            // True if an analysis group.
410b57cec5SDimitry Andric   std::vector<const PassInfo *> ItfImpl; // Interfaces implemented by this pass
420b57cec5SDimitry Andric   NormalCtor_t NormalCtor = nullptr;
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric public:
450b57cec5SDimitry Andric   /// PassInfo ctor - Do not call this directly, this should only be invoked
460b57cec5SDimitry Andric   /// through RegisterPass.
PassInfo(StringRef name,StringRef arg,const void * pi,NormalCtor_t normal,bool isCFGOnly,bool is_analysis)470b57cec5SDimitry Andric   PassInfo(StringRef name, StringRef arg, const void *pi, NormalCtor_t normal,
480b57cec5SDimitry Andric            bool isCFGOnly, bool is_analysis)
490b57cec5SDimitry Andric       : PassName(name), PassArgument(arg), PassID(pi), IsCFGOnlyPass(isCFGOnly),
500b57cec5SDimitry Andric         IsAnalysis(is_analysis), IsAnalysisGroup(false), NormalCtor(normal) {}
510b57cec5SDimitry Andric 
520b57cec5SDimitry Andric   /// PassInfo ctor - Do not call this directly, this should only be invoked
530b57cec5SDimitry Andric   /// through RegisterPass. This version is for use by analysis groups; it
540b57cec5SDimitry Andric   /// does not auto-register the pass.
PassInfo(StringRef name,const void * pi)550b57cec5SDimitry Andric   PassInfo(StringRef name, const void *pi)
560b57cec5SDimitry Andric       : PassName(name), PassID(pi), IsAnalysis(false), IsAnalysisGroup(true) {}
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric   PassInfo(const PassInfo &) = delete;
590b57cec5SDimitry Andric   PassInfo &operator=(const PassInfo &) = delete;
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric   /// getPassName - Return the friendly name for the pass, never returns null
getPassName()620b57cec5SDimitry Andric   StringRef getPassName() const { return PassName; }
630b57cec5SDimitry Andric 
640b57cec5SDimitry Andric   /// getPassArgument - Return the command line option that may be passed to
650b57cec5SDimitry Andric   /// 'opt' that will cause this pass to be run.  This will return null if there
660b57cec5SDimitry Andric   /// is no argument.
getPassArgument()670b57cec5SDimitry Andric   StringRef getPassArgument() const { return PassArgument; }
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric   /// getTypeInfo - Return the id object for the pass...
700b57cec5SDimitry Andric   /// TODO : Rename
getTypeInfo()710b57cec5SDimitry Andric   const void *getTypeInfo() const { return PassID; }
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric   /// Return true if this PassID implements the specified ID pointer.
isPassID(const void * IDPtr)740b57cec5SDimitry Andric   bool isPassID(const void *IDPtr) const { return PassID == IDPtr; }
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric   /// isAnalysisGroup - Return true if this is an analysis group, not a normal
770b57cec5SDimitry Andric   /// pass.
isAnalysisGroup()780b57cec5SDimitry Andric   bool isAnalysisGroup() const { return IsAnalysisGroup; }
isAnalysis()790b57cec5SDimitry Andric   bool isAnalysis() const { return IsAnalysis; }
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric   /// isCFGOnlyPass - return true if this pass only looks at the CFG for the
820b57cec5SDimitry Andric   /// function.
isCFGOnlyPass()830b57cec5SDimitry Andric   bool isCFGOnlyPass() const { return IsCFGOnlyPass; }
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric   /// getNormalCtor - Return a pointer to a function, that when called, creates
860b57cec5SDimitry Andric   /// an instance of the pass and returns it.  This pointer may be null if there
870b57cec5SDimitry Andric   /// is no default constructor for the pass.
getNormalCtor()880b57cec5SDimitry Andric   NormalCtor_t getNormalCtor() const {
890b57cec5SDimitry Andric     return NormalCtor;
900b57cec5SDimitry Andric   }
setNormalCtor(NormalCtor_t Ctor)910b57cec5SDimitry Andric   void setNormalCtor(NormalCtor_t Ctor) {
920b57cec5SDimitry Andric     NormalCtor = Ctor;
930b57cec5SDimitry Andric   }
940b57cec5SDimitry Andric 
950b57cec5SDimitry Andric   /// createPass() - Use this method to create an instance of this pass.
createPass()960b57cec5SDimitry Andric   Pass *createPass() const {
970b57cec5SDimitry Andric     assert((!isAnalysisGroup() || NormalCtor) &&
980b57cec5SDimitry Andric            "No default implementation found for analysis group!");
990b57cec5SDimitry Andric     assert(NormalCtor &&
1000b57cec5SDimitry Andric            "Cannot call createPass on PassInfo without default ctor!");
1010b57cec5SDimitry Andric     return NormalCtor();
1020b57cec5SDimitry Andric   }
1030b57cec5SDimitry Andric 
1040b57cec5SDimitry Andric   /// addInterfaceImplemented - This method is called when this pass is
1050b57cec5SDimitry Andric   /// registered as a member of an analysis group with the RegisterAnalysisGroup
1060b57cec5SDimitry Andric   /// template.
addInterfaceImplemented(const PassInfo * ItfPI)1070b57cec5SDimitry Andric   void addInterfaceImplemented(const PassInfo *ItfPI) {
1080b57cec5SDimitry Andric     ItfImpl.push_back(ItfPI);
1090b57cec5SDimitry Andric   }
1100b57cec5SDimitry Andric 
1110b57cec5SDimitry Andric   /// getInterfacesImplemented - Return a list of all of the analysis group
1120b57cec5SDimitry Andric   /// interfaces implemented by this pass.
getInterfacesImplemented()1130b57cec5SDimitry Andric   const std::vector<const PassInfo*> &getInterfacesImplemented() const {
1140b57cec5SDimitry Andric     return ItfImpl;
1150b57cec5SDimitry Andric   }
1160b57cec5SDimitry Andric };
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric } // end namespace llvm
1190b57cec5SDimitry Andric 
1200b57cec5SDimitry Andric #endif // LLVM_PASSINFO_H
121