Brian Gaeke | 8c4174a | 2004-06-03 05:03:37 +0000 | [diff] [blame] | 1 | //===-- InternalGlobalMapper.cpp - Mapping Info for Internal Globals ------===// |
| 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file was developed by the LLVM research group and is distributed under |
| 6 | // the University of Illinois Open Source License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
| 10 | // InternalGlobalMapper is a pass that helps the runtime trace optimizer map |
| 11 | // the names of internal GlobalValues (which may have mangled, |
| 12 | // unreconstructible names in the executable) to pointers. If the name mangler |
| 13 | // is changed at some point in the future to allow its results to be |
| 14 | // reconstructible (for instance, by making the type mangling symbolic instead |
| 15 | // of using a UniqueID) this pass should probably be phased out. |
| 16 | // |
| 17 | //===----------------------------------------------------------------------===// |
| 18 | |
| 19 | #include "llvm/Constants.h" |
| 20 | #include "llvm/Module.h" |
| 21 | #include "llvm/Pass.h" |
Brian Gaeke | 8c4174a | 2004-06-03 05:03:37 +0000 | [diff] [blame] | 22 | #include "llvm/DerivedTypes.h" |
| 23 | using namespace llvm; |
| 24 | |
Brian Gaeke | 8c4174a | 2004-06-03 05:03:37 +0000 | [diff] [blame] | 25 | typedef std::vector<Constant *> GVVectorTy; |
| 26 | |
Chris Lattner | ee8c9ad | 2004-11-30 00:22:59 +0000 | [diff] [blame] | 27 | namespace { |
| 28 | struct InternalGlobalMapper : public ModulePass { |
| 29 | bool runOnModule(Module &M); |
| 30 | }; |
| 31 | } |
Brian Gaeke | 8c4174a | 2004-06-03 05:03:37 +0000 | [diff] [blame] | 32 | |
Chris Lattner | ee8c9ad | 2004-11-30 00:22:59 +0000 | [diff] [blame] | 33 | namespace llvm { |
| 34 | ModulePass *createInternalGlobalMapperPass() { |
| 35 | return new InternalGlobalMapper(); |
| 36 | } |
Brian Gaeke | 8c4174a | 2004-06-03 05:03:37 +0000 | [diff] [blame] | 37 | } |
| 38 | |
| 39 | static void maybeAddInternalValueToVector (GVVectorTy &Vector, GlobalValue &GV){ |
| 40 | // If it's a GlobalValue with internal linkage and a name (i.e. it's going to |
| 41 | // be mangled), then put the GV, casted to sbyte*, in the vector. Otherwise |
| 42 | // add a null. |
| 43 | if (GV.hasInternalLinkage () && GV.hasName ()) |
Chris Lattner | b12914b | 2004-09-20 04:48:05 +0000 | [diff] [blame] | 44 | Vector.push_back(ConstantExpr::getCast(&GV, |
| 45 | PointerType::get(Type::SByteTy))); |
Brian Gaeke | 8c4174a | 2004-06-03 05:03:37 +0000 | [diff] [blame] | 46 | else |
| 47 | Vector.push_back (ConstantPointerNull::get (PointerType::get |
| 48 | (Type::SByteTy))); |
| 49 | } |
| 50 | |
Chris Lattner | b12914b | 2004-09-20 04:48:05 +0000 | [diff] [blame] | 51 | bool InternalGlobalMapper::runOnModule(Module &M) { |
Brian Gaeke | 8c4174a | 2004-06-03 05:03:37 +0000 | [diff] [blame] | 52 | GVVectorTy gvvector; |
| 53 | |
| 54 | // Populate the vector with internal global values and their names. |
Chris Lattner | e4d5c44 | 2005-03-15 04:54:21 +0000 | [diff] [blame] | 55 | for (Module::global_iterator i = M.global_begin (), e = M.global_end (); i != e; ++i) |
Brian Gaeke | 8c4174a | 2004-06-03 05:03:37 +0000 | [diff] [blame] | 56 | maybeAddInternalValueToVector (gvvector, *i); |
Brian Gaeke | 8e6e7c9 | 2004-06-08 20:08:30 +0000 | [diff] [blame] | 57 | // Add an extra global for _llvm_internalGlobals itself (null, |
| 58 | // because it's not internal) |
| 59 | gvvector.push_back (ConstantPointerNull::get |
| 60 | (PointerType::get (Type::SByteTy))); |
Brian Gaeke | 8c4174a | 2004-06-03 05:03:37 +0000 | [diff] [blame] | 61 | for (Module::iterator i = M.begin (), e = M.end (); i != e; ++i) |
| 62 | maybeAddInternalValueToVector (gvvector, *i); |
| 63 | |
| 64 | // Convert the vector to a constant struct of type {Size, [Size x sbyte*]}. |
| 65 | ArrayType *ATy = ArrayType::get (PointerType::get (Type::SByteTy), |
| 66 | gvvector.size ()); |
| 67 | std::vector<const Type *> FieldTypes; |
| 68 | FieldTypes.push_back (Type::UIntTy); |
| 69 | FieldTypes.push_back (ATy); |
| 70 | StructType *STy = StructType::get (FieldTypes); |
| 71 | std::vector<Constant *> FieldValues; |
| 72 | FieldValues.push_back (ConstantUInt::get (Type::UIntTy, gvvector.size ())); |
| 73 | FieldValues.push_back (ConstantArray::get (ATy, gvvector)); |
| 74 | |
| 75 | // Add the constant struct to M as an external global symbol named |
| 76 | // "_llvm_internalGlobals". |
| 77 | new GlobalVariable (STy, true, GlobalValue::ExternalLinkage, |
| 78 | ConstantStruct::get (STy, FieldValues), |
| 79 | "_llvm_internalGlobals", &M); |
| 80 | |
| 81 | return true; // Module was modified. |
| 82 | } |