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" |
| 22 | #include "llvm/Type.h" |
| 23 | #include "llvm/DerivedTypes.h" |
| 24 | using namespace llvm; |
| 25 | |
| 26 | namespace llvm { |
| 27 | |
| 28 | typedef std::vector<Constant *> GVVectorTy; |
| 29 | |
| 30 | class InternalGlobalMapper : public Pass { |
| 31 | public: |
| 32 | bool run (Module &M); |
| 33 | }; |
| 34 | |
| 35 | Pass *llvm::createInternalGlobalMapperPass () { |
| 36 | return new InternalGlobalMapper (); |
| 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 ()) |
| 44 | Vector.push_back (ConstantExpr::getCast |
| 45 | (ConstantPointerRef::get (&GV), PointerType::get (Type::SByteTy))); |
| 46 | else |
| 47 | Vector.push_back (ConstantPointerNull::get (PointerType::get |
| 48 | (Type::SByteTy))); |
| 49 | } |
| 50 | |
| 51 | bool InternalGlobalMapper::run (Module &M) { |
| 52 | GVVectorTy gvvector; |
| 53 | |
| 54 | // Populate the vector with internal global values and their names. |
| 55 | for (Module::giterator i = M.gbegin (), e = M.gend (); i != e; ++i) |
| 56 | maybeAddInternalValueToVector (gvvector, *i); |
| 57 | for (Module::iterator i = M.begin (), e = M.end (); i != e; ++i) |
| 58 | maybeAddInternalValueToVector (gvvector, *i); |
| 59 | |
| 60 | // Convert the vector to a constant struct of type {Size, [Size x sbyte*]}. |
| 61 | ArrayType *ATy = ArrayType::get (PointerType::get (Type::SByteTy), |
| 62 | gvvector.size ()); |
| 63 | std::vector<const Type *> FieldTypes; |
| 64 | FieldTypes.push_back (Type::UIntTy); |
| 65 | FieldTypes.push_back (ATy); |
| 66 | StructType *STy = StructType::get (FieldTypes); |
| 67 | std::vector<Constant *> FieldValues; |
| 68 | FieldValues.push_back (ConstantUInt::get (Type::UIntTy, gvvector.size ())); |
| 69 | FieldValues.push_back (ConstantArray::get (ATy, gvvector)); |
| 70 | |
| 71 | // Add the constant struct to M as an external global symbol named |
| 72 | // "_llvm_internalGlobals". |
| 73 | new GlobalVariable (STy, true, GlobalValue::ExternalLinkage, |
| 74 | ConstantStruct::get (STy, FieldValues), |
| 75 | "_llvm_internalGlobals", &M); |
| 76 | |
| 77 | return true; // Module was modified. |
| 78 | } |
| 79 | |
| 80 | } // end namespace llvm |