1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===- llvm/PassSupport.h - Pass Support code -------------------*- C++ -*-===//
2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//                     The LLVM Compiler Infrastructure
4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source
6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details.
7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===//
9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file defines stuff that is used to define and "use" Passes.  This file
11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// is automatically #included by Pass.h, so:
12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//           NO .CPP FILES SHOULD INCLUDE THIS FILE DIRECTLY
14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Instead, #include Pass.h.
16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file defines Pass registration code and classes used for it.
18894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===//
20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#ifndef LLVM_PASS_SUPPORT_H
22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#define LLVM_PASS_SUPPORT_H
23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "Pass.h"
25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/PassRegistry.h"
2619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/InitializePasses.h"
2719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/Atomic.h"
2819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include <vector>
29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumannamespace llvm {
31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
32894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===---------------------------------------------------------------------------
33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// PassInfo class - An instance of this class exists for every pass known by
34894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// the system, and can be obtained from a live Pass by calling its
35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// getPassInfo() method.  These objects are set up by the RegisterPass<>
36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// template, defined below.
37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///
38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass PassInfo {
39894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic:
40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  typedef Pass* (*NormalCtor_t)();
41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanprivate:
43894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  const char      *const PassName;     // Nice name for Pass
44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  const char      *const PassArgument; // Command Line argument to run this pass
45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  const void *PassID;
46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  const bool IsCFGOnlyPass;            // Pass only looks at the CFG.
47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  const bool IsAnalysis;               // True if an analysis pass.
48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  const bool IsAnalysisGroup;          // True if an analysis group.
49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  std::vector<const PassInfo*> ItfImpl;// Interfaces implemented by this pass
50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  NormalCtor_t NormalCtor;
52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
53894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic:
54894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// PassInfo ctor - Do not call this directly, this should only be invoked
55894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// through RegisterPass.
56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  PassInfo(const char *name, const char *arg, const void *pi,
57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman           NormalCtor_t normal, bool isCFGOnly, bool is_analysis)
58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    : PassName(name), PassArgument(arg), PassID(pi),
59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      IsCFGOnlyPass(isCFGOnly),
6019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      IsAnalysis(is_analysis), IsAnalysisGroup(false), NormalCtor(normal) { }
61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// PassInfo ctor - Do not call this directly, this should only be invoked
62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// through RegisterPass. This version is for use by analysis groups; it
63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// does not auto-register the pass.
64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  PassInfo(const char *name, const void *pi)
65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    : PassName(name), PassArgument(""), PassID(pi),
66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman      IsCFGOnlyPass(false),
6719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      IsAnalysis(false), IsAnalysisGroup(true), NormalCtor(0) { }
68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// getPassName - Return the friendly name for the pass, never returns null
70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  ///
71894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  const char *getPassName() const { return PassName; }
72894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// getPassArgument - Return the command line option that may be passed to
74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// 'opt' that will cause this pass to be run.  This will return null if there
75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// is no argument.
76894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  ///
77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  const char *getPassArgument() const { return PassArgument; }
78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
79894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// getTypeInfo - Return the id object for the pass...
80894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// TODO : Rename
81894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  const void *getTypeInfo() const { return PassID; }
82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// Return true if this PassID implements the specified ID pointer.
84894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool isPassID(const void *IDPtr) const {
85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return PassID == IDPtr;
86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
87894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
88894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// isAnalysisGroup - Return true if this is an analysis group, not a normal
89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// pass.
90894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  ///
91894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool isAnalysisGroup() const { return IsAnalysisGroup; }
92894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool isAnalysis() const { return IsAnalysis; }
93894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
94894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// isCFGOnlyPass - return true if this pass only looks at the CFG for the
95894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// function.
96894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  bool isCFGOnlyPass() const { return IsCFGOnlyPass; }
97894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
98894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// getNormalCtor - Return a pointer to a function, that when called, creates
99894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// an instance of the pass and returns it.  This pointer may be null if there
100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// is no default constructor for the pass.
101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  ///
102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  NormalCtor_t getNormalCtor() const {
103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return NormalCtor;
104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  void setNormalCtor(NormalCtor_t Ctor) {
106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    NormalCtor = Ctor;
107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// createPass() - Use this method to create an instance of this pass.
110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  Pass *createPass() const;
111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// addInterfaceImplemented - This method is called when this pass is
113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// registered as a member of an analysis group with the RegisterAnalysisGroup
114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// template.
115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  ///
116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  void addInterfaceImplemented(const PassInfo *ItfPI) {
117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    ItfImpl.push_back(ItfPI);
118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// getInterfacesImplemented - Return a list of all of the analysis group
121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// interfaces implemented by this pass.
122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  ///
123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  const std::vector<const PassInfo*> &getInterfacesImplemented() const {
124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return ItfImpl;
125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanprivate:
128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  void operator=(const PassInfo &); // do not implement
129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  PassInfo(const PassInfo &);       // do not implement
130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman};
131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
13219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#define CALL_ONCE_INITIALIZATION(function) \
13319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  static volatile sys::cas_flag initialized = 0; \
13419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  sys::cas_flag old_val = sys::CompareAndSwap(&initialized, 1, 0); \
13519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (old_val == 0) { \
13619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    function(Registry); \
13719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    sys::MemoryFence(); \
13819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    initialized = 2; \
13919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else { \
14019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    sys::cas_flag tmp = initialized; \
14119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    sys::MemoryFence(); \
14219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    while (tmp != 2) { \
14319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      tmp = initialized; \
14419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      sys::MemoryFence(); \
14519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    } \
14619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
14719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#define INITIALIZE_PASS(passName, arg, name, cfg, analysis) \
14919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  static void* initialize##passName##PassOnce(PassRegistry &Registry) { \
15019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    PassInfo *PI = new PassInfo(name, arg, & passName ::ID, \
15119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      PassInfo::NormalCtor_t(callDefaultCtor< passName >), cfg, analysis); \
15219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Registry.registerPass(*PI, true); \
15319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return PI; \
15419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } \
15519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
15619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \
15719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
15819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
15919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis) \
16019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  static void* initialize##passName##PassOnce(PassRegistry &Registry) {
16119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
16219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#define INITIALIZE_PASS_DEPENDENCY(depName) \
16319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    initialize##depName##Pass(Registry);
16419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#define INITIALIZE_AG_DEPENDENCY(depName) \
16519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    initialize##depName##AnalysisGroup(Registry);
16619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
16719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis) \
16819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    PassInfo *PI = new PassInfo(name, arg, & passName ::ID, \
16919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      PassInfo::NormalCtor_t(callDefaultCtor< passName >), cfg, analysis); \
17019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Registry.registerPass(*PI, true); \
17119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return PI; \
17219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } \
17319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
17419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \
17519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<typename PassName>
178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanPass *callDefaultCtor() { return new PassName(); }
179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===---------------------------------------------------------------------------
181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// RegisterPass<t> template - This template class is used to notify the system
182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// that a Pass is available for use, and registers it into the internal
183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// database maintained by the PassManager.  Unless this template is used, opt,
184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// for example will not be able to see the pass and attempts to create the pass
185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// will fail. This template is used in the follow manner (at global scope, in
186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// your .cpp file):
187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///
188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// static RegisterPass<YourPassClassName> tmp("passopt", "My Pass Name");
189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///
190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// This statement will cause your pass to be created by calling the default
191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// constructor exposed by the pass.  If you have a different constructor that
192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// must be called, create a global constructor function (which takes the
193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// arguments you need and returns a Pass*) and register your pass like this:
194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///
195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// static RegisterPass<PassClassName> tmp("passopt", "My Name");
196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///
197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<typename passName>
198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstruct RegisterPass : public PassInfo {
199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Register Pass using default constructor...
201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  RegisterPass(const char *PassArg, const char *Name, bool CFGOnly = false,
202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman               bool is_analysis = false)
203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    : PassInfo(Name, PassArg, &passName::ID,
204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman               PassInfo::NormalCtor_t(callDefaultCtor<passName>),
205894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman               CFGOnly, is_analysis) {
20619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    PassRegistry::getPassRegistry()->registerPass(*this);
207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
208894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman};
209894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
210894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// RegisterAnalysisGroup - Register a Pass as a member of an analysis _group_.
212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// Analysis groups are used to define an interface (which need not derive from
213894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// Pass) that is required by passes to do their job.  Analysis Groups differ
214894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// from normal analyses because any available implementation of the group will
215894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// be used if it is available.
216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///
217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// If no analysis implementing the interface is available, a default
218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// implementation is created and added.  A pass registers itself as the default
219894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// implementation by specifying 'true' as the second template argument of this
220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// class.
221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///
222894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// In addition to registering itself as an analysis group member, a pass must
223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// register itself normally as well.  Passes may be members of multiple groups
224894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// and may still be "required" specifically by name.
225894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///
226894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// The actual interface may also be registered as well (by not specifying the
227894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// second template argument).  The interface should be registered to associate
228894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// a nice name with the interface.
229894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///
230894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass RegisterAGBase : public PassInfo {
23119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanpublic:
232894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  RegisterAGBase(const char *Name,
233894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                 const void *InterfaceID,
234894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                 const void *PassID = 0,
235894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                 bool isDefault = false);
236894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman};
237894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
238894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<typename Interface, bool Default = false>
239894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstruct RegisterAnalysisGroup : public RegisterAGBase {
240894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  explicit RegisterAnalysisGroup(PassInfo &RPB)
241894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    : RegisterAGBase(RPB.getPassName(),
242894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                     &Interface::ID, RPB.getTypeInfo(),
243894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                     Default) {
244894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
245894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
246894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  explicit RegisterAnalysisGroup(const char *Name)
247894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    : RegisterAGBase(Name, &Interface::ID) {
248894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
249894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman};
250894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
25119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#define INITIALIZE_ANALYSIS_GROUP(agName, name, defaultPass) \
25219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  static void* initialize##agName##AnalysisGroupOnce(PassRegistry &Registry) { \
25319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    initialize##defaultPass##Pass(Registry); \
25419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    PassInfo *AI = new PassInfo(name, & agName :: ID); \
25519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Registry.registerAnalysisGroup(& agName ::ID, 0, *AI, false, true); \
25619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return AI; \
25719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } \
25819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  void llvm::initialize##agName##AnalysisGroup(PassRegistry &Registry) { \
25919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    CALL_ONCE_INITIALIZATION(initialize##agName##AnalysisGroupOnce) \
26019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
26119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
26219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
263894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#define INITIALIZE_AG_PASS(passName, agName, arg, name, cfg, analysis, def) \
26419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  static void* initialize##passName##PassOnce(PassRegistry &Registry) { \
26519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!def) initialize##agName##AnalysisGroup(Registry); \
26619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    PassInfo *PI = new PassInfo(name, arg, & passName ::ID, \
26719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      PassInfo::NormalCtor_t(callDefaultCtor< passName >), cfg, analysis); \
26819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Registry.registerPass(*PI, true); \
26919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    \
27019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    PassInfo *AI = new PassInfo(name, & agName :: ID); \
27119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Registry.registerAnalysisGroup(& agName ::ID, & passName ::ID, \
27219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                   *AI, def, true); \
27319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return AI; \
27419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } \
27519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
27619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \
27719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
27819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
27919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
28019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#define INITIALIZE_AG_PASS_BEGIN(passName, agName, arg, n, cfg, analysis, def) \
28119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  static void* initialize##passName##PassOnce(PassRegistry &Registry) { \
28219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!def) initialize##agName##AnalysisGroup(Registry);
28319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
28419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#define INITIALIZE_AG_PASS_END(passName, agName, arg, n, cfg, analysis, def) \
28519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    PassInfo *PI = new PassInfo(n, arg, & passName ::ID, \
28619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      PassInfo::NormalCtor_t(callDefaultCtor< passName >), cfg, analysis); \
28719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Registry.registerPass(*PI, true); \
28819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    \
28919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    PassInfo *AI = new PassInfo(n, & agName :: ID); \
29019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Registry.registerAnalysisGroup(& agName ::ID, & passName ::ID, \
29119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                   *AI, def, true); \
29219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return AI; \
29319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } \
29419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
29519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \
29619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
297894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
298894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===---------------------------------------------------------------------------
299894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// PassRegistrationListener class - This class is meant to be derived from by
300894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// clients that are interested in which passes get registered and unregistered
301894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// at runtime (which can be because of the RegisterPass constructors being run
302894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// as the program starts up, or may be because a shared object just got
303894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// loaded).  Deriving from the PassRegistationListener class automatically
304894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// registers your object to receive callbacks indicating when passes are loaded
305894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// and removed.
306894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///
307894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstruct PassRegistrationListener {
308894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
309894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// PassRegistrationListener ctor - Add the current object to the list of
310894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// PassRegistrationListeners...
311894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  PassRegistrationListener();
312894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
313894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// dtor - Remove object from list of listeners...
314894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  ///
315894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  virtual ~PassRegistrationListener();
316894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
317894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// Callback functions - These functions are invoked whenever a pass is loaded
318894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// or removed from the current executable.
319894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  ///
320894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  virtual void passRegistered(const PassInfo *) {}
321894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
322894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// enumeratePasses - Iterate over the registered passes, calling the
323894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// passEnumerate callback on each PassInfo object.
324894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  ///
325894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  void enumeratePasses();
326894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
327894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// passEnumerate - Callback function invoked when someone calls
328894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  /// enumeratePasses on this PassRegistrationListener object.
329894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  ///
330894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  virtual void passEnumerate(const PassInfo *) {}
331894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman};
332894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
333894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
334894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} // End llvm namespace
335894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
336894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif
337