Chris Lattner | 2f7c963 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 1 | //===-- Module.cpp - Implement the Module class ------------------*- C++ -*--=// |
| 2 | // |
| 3 | // This file implements the Module class for the VMCore library. |
| 4 | // |
| 5 | //===----------------------------------------------------------------------===// |
| 6 | |
Chris Lattner | 2f7c963 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 7 | #include "llvm/Module.h" |
Chris Lattner | 57698e2 | 2002-03-26 18:01:55 +0000 | [diff] [blame] | 8 | #include "llvm/Function.h" |
Chris Lattner | da97550 | 2001-09-10 07:58:01 +0000 | [diff] [blame] | 9 | #include "llvm/GlobalVariable.h" |
Chris Lattner | 31cf984 | 2001-06-30 04:35:40 +0000 | [diff] [blame] | 10 | #include "llvm/InstrTypes.h" |
| 11 | #include "llvm/ValueHolderImpl.h" |
Chris Lattner | f50b723 | 2001-09-07 16:47:42 +0000 | [diff] [blame] | 12 | #include "llvm/Type.h" |
Chris Lattner | 3462ae3 | 2001-12-03 22:26:30 +0000 | [diff] [blame] | 13 | #include "llvm/ConstantVals.h" |
Chris Lattner | a483b06 | 2002-03-29 03:44:18 +0000 | [diff] [blame] | 14 | #include "llvm/DerivedTypes.h" |
Chris Lattner | 5de2204 | 2001-11-27 00:03:19 +0000 | [diff] [blame] | 15 | #include "Support/STLExtras.h" |
Chris Lattner | 446ad50 | 2001-10-13 06:58:40 +0000 | [diff] [blame] | 16 | #include <map> |
Chris Lattner | 2f7c963 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 17 | |
| 18 | // Instantiate Templates - This ugliness is the price we have to pay |
| 19 | // for having a DefHolderImpl.h file seperate from DefHolder.h! :( |
| 20 | // |
Chris Lattner | da97550 | 2001-09-10 07:58:01 +0000 | [diff] [blame] | 21 | template class ValueHolder<GlobalVariable, Module, Module>; |
Chris Lattner | 57698e2 | 2002-03-26 18:01:55 +0000 | [diff] [blame] | 22 | template class ValueHolder<Function, Module, Module>; |
Chris Lattner | 2f7c963 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 23 | |
Chris Lattner | 446ad50 | 2001-10-13 06:58:40 +0000 | [diff] [blame] | 24 | // Define the GlobalValueRefMap as a struct that wraps a map so that we don't |
| 25 | // have Module.h depend on <map> |
| 26 | // |
Chris Lattner | 7f74a56 | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 27 | struct GlobalValueRefMap : public std::map<GlobalValue*, ConstantPointerRef*>{ |
Chris Lattner | 446ad50 | 2001-10-13 06:58:40 +0000 | [diff] [blame] | 28 | }; |
| 29 | |
| 30 | |
Chris Lattner | 2f7c963 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 31 | Module::Module() |
Chris Lattner | f50b723 | 2001-09-07 16:47:42 +0000 | [diff] [blame] | 32 | : Value(Type::VoidTy, Value::ModuleVal, ""), SymTabValue(this), |
Chris Lattner | 57698e2 | 2002-03-26 18:01:55 +0000 | [diff] [blame] | 33 | GlobalList(this, this), FunctionList(this, this), GVRefMap(0) { |
Chris Lattner | 2f7c963 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 34 | } |
| 35 | |
| 36 | Module::~Module() { |
| 37 | dropAllReferences(); |
Chris Lattner | da97550 | 2001-09-10 07:58:01 +0000 | [diff] [blame] | 38 | GlobalList.delete_all(); |
| 39 | GlobalList.setParent(0); |
Chris Lattner | 57698e2 | 2002-03-26 18:01:55 +0000 | [diff] [blame] | 40 | FunctionList.delete_all(); |
| 41 | FunctionList.setParent(0); |
Chris Lattner | 2f7c963 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 42 | } |
| 43 | |
Chris Lattner | a483b06 | 2002-03-29 03:44:18 +0000 | [diff] [blame] | 44 | // getOrInsertFunction - Look up the specified function in the module symbol |
| 45 | // table. If it does not exist, add a prototype for the function and return |
| 46 | // it. This is nice because it allows most passes to get away with not handling |
| 47 | // the symbol table directly for this common task. |
| 48 | // |
| 49 | Function *Module::getOrInsertFunction(const std::string &Name, |
| 50 | const FunctionType *Ty) { |
| 51 | SymbolTable *SymTab = getSymbolTableSure(); |
| 52 | |
| 53 | // See if we have a definitions for the specified function already... |
| 54 | if (Value *V = SymTab->lookup(PointerType::get(Ty), Name)) { |
| 55 | return cast<Function>(V); // Yup, got it |
| 56 | } else { // Nope, add one |
| 57 | Function *New = new Function(Ty, false, Name); |
| 58 | FunctionList.push_back(New); |
| 59 | return New; // Return the new prototype... |
| 60 | } |
| 61 | } |
| 62 | |
| 63 | // getFunction - Look up the specified function in the module symbol table. |
| 64 | // If it does not exist, return null. |
| 65 | // |
| 66 | Function *Module::getFunction(const std::string &Name, const FunctionType *Ty) { |
| 67 | SymbolTable *SymTab = getSymbolTable(); |
| 68 | if (SymTab == 0) return 0; // No symtab, no symbols... |
| 69 | |
| 70 | return cast_or_null<Function>(SymTab->lookup(PointerType::get(Ty), Name)); |
| 71 | } |
| 72 | |
| 73 | |
Chris Lattner | 2f7c963 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 74 | |
| 75 | // dropAllReferences() - This function causes all the subinstructions to "let |
| 76 | // go" of all references that they are maintaining. This allows one to |
| 77 | // 'delete' a whole class at a time, even though there may be circular |
| 78 | // references... first all references are dropped, and all use counts go to |
| 79 | // zero. Then everything is delete'd for real. Note that no operations are |
| 80 | // valid on an object that has "dropped all references", except operator |
| 81 | // delete. |
| 82 | // |
| 83 | void Module::dropAllReferences() { |
Chris Lattner | 57698e2 | 2002-03-26 18:01:55 +0000 | [diff] [blame] | 84 | for_each(FunctionList.begin(), FunctionList.end(), |
| 85 | std::mem_fun(&Function::dropAllReferences)); |
Chris Lattner | 446ad50 | 2001-10-13 06:58:40 +0000 | [diff] [blame] | 86 | |
| 87 | for_each(GlobalList.begin(), GlobalList.end(), |
| 88 | std::mem_fun(&GlobalVariable::dropAllReferences)); |
| 89 | |
| 90 | // If there are any GlobalVariable references still out there, nuke them now. |
| 91 | // Since all references are hereby dropped, nothing could possibly reference |
| 92 | // them still. |
| 93 | if (GVRefMap) { |
| 94 | for (GlobalValueRefMap::iterator I = GVRefMap->begin(), E = GVRefMap->end(); |
| 95 | I != E; ++I) { |
Chris Lattner | 3462ae3 | 2001-12-03 22:26:30 +0000 | [diff] [blame] | 96 | // Delete the ConstantPointerRef node... |
Chris Lattner | 446ad50 | 2001-10-13 06:58:40 +0000 | [diff] [blame] | 97 | I->second->destroyConstant(); |
| 98 | } |
| 99 | |
| 100 | // Since the table is empty, we can now delete it... |
| 101 | delete GVRefMap; |
| 102 | } |
Chris Lattner | 2f7c963 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 103 | } |
Chris Lattner | 31cf984 | 2001-06-30 04:35:40 +0000 | [diff] [blame] | 104 | |
Chris Lattner | 446ad50 | 2001-10-13 06:58:40 +0000 | [diff] [blame] | 105 | // Accessor for the underlying GlobalValRefMap... |
Chris Lattner | 3462ae3 | 2001-12-03 22:26:30 +0000 | [diff] [blame] | 106 | ConstantPointerRef *Module::getConstantPointerRef(GlobalValue *V){ |
Chris Lattner | 446ad50 | 2001-10-13 06:58:40 +0000 | [diff] [blame] | 107 | // Create ref map lazily on demand... |
| 108 | if (GVRefMap == 0) GVRefMap = new GlobalValueRefMap(); |
| 109 | |
| 110 | GlobalValueRefMap::iterator I = GVRefMap->find(V); |
| 111 | if (I != GVRefMap->end()) return I->second; |
| 112 | |
Chris Lattner | 3462ae3 | 2001-12-03 22:26:30 +0000 | [diff] [blame] | 113 | ConstantPointerRef *Ref = new ConstantPointerRef(V); |
Chris Lattner | 7f74a56 | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 114 | GVRefMap->insert(std::make_pair(V, Ref)); |
Chris Lattner | 446ad50 | 2001-10-13 06:58:40 +0000 | [diff] [blame] | 115 | |
| 116 | return Ref; |
| 117 | } |
| 118 | |
Chris Lattner | 3462ae3 | 2001-12-03 22:26:30 +0000 | [diff] [blame] | 119 | void Module::mutateConstantPointerRef(GlobalValue *OldGV, GlobalValue *NewGV) { |
Chris Lattner | 446ad50 | 2001-10-13 06:58:40 +0000 | [diff] [blame] | 120 | GlobalValueRefMap::iterator I = GVRefMap->find(OldGV); |
| 121 | assert(I != GVRefMap->end() && |
Chris Lattner | 3462ae3 | 2001-12-03 22:26:30 +0000 | [diff] [blame] | 122 | "mutateConstantPointerRef; OldGV not in table!"); |
| 123 | ConstantPointerRef *Ref = I->second; |
Chris Lattner | 446ad50 | 2001-10-13 06:58:40 +0000 | [diff] [blame] | 124 | |
| 125 | // Remove the old entry... |
| 126 | GVRefMap->erase(I); |
| 127 | |
| 128 | // Insert the new entry... |
Chris Lattner | 7f74a56 | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 129 | GVRefMap->insert(std::make_pair(NewGV, Ref)); |
Chris Lattner | 446ad50 | 2001-10-13 06:58:40 +0000 | [diff] [blame] | 130 | } |