blob: 8df87fd0006c7fe5db4a3ca87197ecd8fe4e14f2 [file] [log] [blame]
Brian Gaeke8c4174a2004-06-03 05:03:37 +00001//===-- 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"
24using namespace llvm;
25
26namespace llvm {
27
28typedef std::vector<Constant *> GVVectorTy;
29
30class InternalGlobalMapper : public Pass {
31public:
32 bool run (Module &M);
33};
34
35Pass *llvm::createInternalGlobalMapperPass () {
36 return new InternalGlobalMapper ();
37}
38
39static 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
51bool 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