Implement DCE of global values
[oota-llvm.git] / include / llvm / SymbolTable.h
1 //===-- llvm/SymbolTable.h - Implement a type planned symtab ------*- C++ -*-=//
2 //
3 // This file implements a symbol table that has planed broken up by type.  
4 // Identical types may have overlapping symbol names as long as they are 
5 // distinct.
6 //
7 // Note that this implements a chained symbol table.  If a name being 'lookup'd
8 // isn't found in the current symbol table, then the parent symbol table is 
9 // searched.
10 //
11 // This chaining behavior does NOT affect iterators though: only the lookup 
12 // method
13 //
14 //===----------------------------------------------------------------------===//
15
16 #ifndef LLVM_SYMBOL_TABLE_H
17 #define LLVM_SYMBOL_TABLE_H
18
19 #include "llvm/Value.h"
20 #include <map>
21
22 #ifndef NDEBUG             // Only for assertions
23 #include "llvm/Type.h"
24 #include "llvm/ConstPoolVals.h"
25 #endif
26
27 class Type;
28
29 class SymbolTable : public AbstractTypeUser,
30                     public map<const Type *, map<const string, Value *> > {
31 public:
32   typedef map<const string, Value *> VarMap;
33   typedef map<const Type *, VarMap> super;
34 private:
35
36   SymbolTable *ParentSymTab;
37
38   friend class SymTabValue;
39   inline void setParentSymTab(SymbolTable *P) { ParentSymTab = P; }
40
41 public:
42   typedef VarMap::iterator type_iterator;
43   typedef VarMap::const_iterator type_const_iterator;
44
45   inline SymbolTable(SymbolTable *P = 0) {
46     ParentSymTab = P;
47     InternallyInconsistent = false;
48   }
49   ~SymbolTable();
50
51   SymbolTable *getParentSymTab() { return ParentSymTab; }
52
53   // lookup - Returns null on failure...
54   Value *lookup(const Type *Ty, const string &name);
55
56   // insert - Add named definition to the symbol table...
57   inline void insert(Value *N) {
58     assert(N->hasName() && "Value must be named to go into symbol table!");
59     insertEntry(N->getName(), N->getType(), N);
60   }
61
62   // insert - Insert a constant or type into the symbol table with the specified
63   // name...  There can be a many to one mapping between names and
64   // (constant/type)s.
65   //
66   inline void insert(const string &Name, Value *V) {
67     assert((isa<Type>(V) || isa<ConstPoolVal>(V)) &&
68            "Can only insert types and constants here!");
69     insertEntry(Name, V->getType(), V);
70   }
71
72   void remove(Value *N);
73   Value *type_remove(const type_iterator &It) {
74     return removeEntry(find(It->second->getType()), It);
75   }
76
77   // getUniqueName - Given a base name, return a string that is either equal to
78   // it (or derived from it) that does not already occur in the symbol table for
79   // the specified type.
80   //
81   string getUniqueName(const Type *Ty, const string &BaseName);
82
83   inline unsigned type_size(const Type *TypeID) const {
84     return find(TypeID)->second.size();
85   }
86
87   // Note that type_begin / type_end only work if you know that an element of 
88   // TypeID is already in the symbol table!!!
89   //
90   inline type_iterator type_begin(const Type *TypeID) { 
91     return find(TypeID)->second.begin(); 
92   }
93   inline type_const_iterator type_begin(const Type *TypeID) const {
94     return find(TypeID)->second.begin(); 
95   }
96
97   inline type_iterator type_end(const Type *TypeID) { 
98     return find(TypeID)->second.end(); 
99   }
100   inline type_const_iterator type_end(const Type *TypeID) const { 
101     return find(TypeID)->second.end(); 
102   }
103
104   void dump() const;  // Debug method, print out symbol table
105
106 private:
107   // InternallyInconsistent - There are times when the symbol table is
108   // internally inconsistent with the rest of the program.  In this one case, a
109   // value exists with a Name, and it's not in the symbol table.  When we call
110   // V->setName(""), it tries to remove itself from the symbol table and dies.
111   // We know this is happening, and so if the flag InternallyInconsistent is
112   // set, removal from the symbol table is a noop.
113   //
114   bool InternallyInconsistent;
115
116   inline super::value_type operator[](const Type *Ty) {
117     assert(0 && "Should not use this operator to access symbol table!");
118     return super::value_type();
119   }
120
121   // insertEntry - Insert a value into the symbol table with the specified
122   // name...
123   //
124   void insertEntry(const string &Name, const Type *Ty, Value *V);
125
126   // removeEntry - Remove a value from the symbol table...
127   //
128   Value *removeEntry(iterator Plane, type_iterator Entry);
129
130   // This function is called when one of the types in the type plane are refined
131   virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
132 };
133
134 #endif