aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2002-08-21 22:16:59 +0000
committerChris Lattner <sabre@nondot.org>2002-08-21 22:16:59 +0000
commit0756c11dea6f247fb7667190512e6c0a6e39b868 (patch)
tree48b6fd9ea87cf68828b7c17cddbe7a7e77203bf6 /include
parent03e26ba35b1f3244315e1444fabe0b20bec47bb7 (diff)
downloadexternal_llvm-0756c11dea6f247fb7667190512e6c0a6e39b868.zip
external_llvm-0756c11dea6f247fb7667190512e6c0a6e39b868.tar.gz
external_llvm-0756c11dea6f247fb7667190512e6c0a6e39b868.tar.bz2
- Implement the new AnalysisGroup feature, neccesary for Value#ing and pointer analysis
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3425 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/llvm/PassSupport.h75
1 files changed, 69 insertions, 6 deletions
diff --git a/include/llvm/PassSupport.h b/include/llvm/PassSupport.h
index 6a6e29b..e7bb041 100644
--- a/include/llvm/PassSupport.h
+++ b/include/llvm/PassSupport.h
@@ -16,7 +16,6 @@
// No need to include Pass.h, we are being included by it!
-#include <typeinfo>
class TargetData;
class TargetMachine;
@@ -38,10 +37,11 @@ class PassInfo {
public:
// PassType - Define symbolic constants that can be used to test to see if
// this pass should be listed by analyze or opt. Passes can use none, one or
- // many of these flags or'd together.
+ // many of these flags or'd together. It is not legal to combine the
+ // AnalysisGroup flag with others.
//
enum {
- Analysis = 1, Optimization = 2, LLC = 4
+ Analysis = 1, Optimization = 2, LLC = 4, AnalysisGroup = 8
};
// PassInfo ctor - Do not call this directly, this should only be invoked
@@ -54,6 +54,7 @@ public:
// getPassName - Return the friendly name for the pass, never returns null
const char *getPassName() const { return PassName; }
+ void setPassName(const char *Name) { PassName = Name; }
// getPassArgument - Return the command line option that may be passed to
// 'opt' that will cause this pass to be run. This will return null if there
@@ -77,9 +78,14 @@ public:
Pass *(*getNormalCtor() const)() {
return NormalCtor;
}
+ void setNormalCtor(Pass *(*Ctor)()) {
+ NormalCtor = Ctor;
+ }
// createPass() - Use this
Pass *createPass() const {
+ assert((PassType != AnalysisGroup || NormalCtor) &&
+ "No default implementation found for analysis group!");
assert(NormalCtor &&
"Cannot call createPass on PassInfo without default ctor!");
return NormalCtor();
@@ -117,13 +123,15 @@ struct RegisterPassBase {
// getPassInfo - Get the pass info for the registered class...
const PassInfo *getPassInfo() const { return PIObj; }
- ~RegisterPassBase(); // Intentionally non-virtual...
-
- inline operator PassInfo* () const { return PIObj; }
+ RegisterPassBase() : PIObj(0) {}
+ ~RegisterPassBase() { // Intentionally non-virtual...
+ if (PIObj) unregisterPass(PIObj);
+ }
protected:
PassInfo *PIObj; // The PassInfo object for this pass
void registerPass(PassInfo *);
+ void unregisterPass(PassInfo *);
// setPreservesCFG - Notice that this pass only depends on the CFG, so
// transformations that do not modify the CFG do not invalidate this pass.
@@ -240,6 +248,61 @@ struct RegisterLLC : public RegisterPassBase {
};
+// RegisterAnalysisGroup - Register a Pass as a member of an analysis _group_.
+// Analysis groups are used to define an interface (which need not derive from
+// Pass) that is required by passes to do their job. Analysis Groups differ
+// from normal analyses because any available implementation of the group will
+// be used if it is available.
+//
+// If no analysis implementing the interface is available, a default
+// implementation is created and added. A pass registers itself as the default
+// implementation by specifying 'true' as the third template argument of this
+// class.
+//
+// In addition to registering itself as an analysis group member, a pass must
+// register itself normally as well. Passes may be members of multiple groups
+// and may still be "required" specifically by name.
+//
+// The actual interface may also be registered as well (by not specifying the
+// second template argument). The interface should be registered to associate a
+// nice name with the interface.
+//
+class RegisterAGBase : public RegisterPassBase {
+ PassInfo *InterfaceInfo;
+ const PassInfo *ImplementationInfo;
+ bool isDefaultImplementation;
+protected:
+ RegisterAGBase(const std::type_info &Interface,
+ const std::type_info *Pass = 0,
+ bool isDefault = false);
+ void setGroupName(const char *Name);
+public:
+ ~RegisterAGBase();
+};
+
+
+template<typename Interface, typename DefaultImplementationPass = void,
+ bool Default = false>
+struct RegisterAnalysisGroup : public RegisterAGBase {
+ RegisterAnalysisGroup() : RegisterAGBase(typeid(Interface),
+ &typeid(DefaultImplementationPass),
+ Default) {
+ }
+};
+
+// Define a specialization of RegisterAnalysisGroup that is used to set the name
+// for the analysis group.
+//
+template<typename Interface>
+struct RegisterAnalysisGroup<Interface, void, false> : public RegisterAGBase {
+ RegisterAnalysisGroup(const char *Name)
+ : RegisterAGBase(typeid(Interface)) {
+ setGroupName(Name);
+ }
+};
+
+
+
//===---------------------------------------------------------------------------
// PassRegistrationListener class - This class is meant to be derived from by
// clients that are interested in which passes get registered and unregistered