blob: 280c836f338c47a3c85a0aa5b8e61566c7f1a778 [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"
Brian Gaeke8c4174a2004-06-03 05:03:37 +000022#include "llvm/DerivedTypes.h"
23using namespace llvm;
24
Brian Gaeke8c4174a2004-06-03 05:03:37 +000025typedef std::vector<Constant *> GVVectorTy;
26
Chris Lattneree8c9ad2004-11-30 00:22:59 +000027namespace {
28 struct InternalGlobalMapper : public ModulePass {
29 bool runOnModule(Module &M);
30 };
31}
Brian Gaeke8c4174a2004-06-03 05:03:37 +000032
Chris Lattneree8c9ad2004-11-30 00:22:59 +000033namespace llvm {
34 ModulePass *createInternalGlobalMapperPass() {
35 return new InternalGlobalMapper();
36 }
Brian Gaeke8c4174a2004-06-03 05:03:37 +000037}
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 ())
Chris Lattnerb12914b2004-09-20 04:48:05 +000044 Vector.push_back(ConstantExpr::getCast(&GV,
45 PointerType::get(Type::SByteTy)));
Brian Gaeke8c4174a2004-06-03 05:03:37 +000046 else
47 Vector.push_back (ConstantPointerNull::get (PointerType::get
48 (Type::SByteTy)));
49}
50
Chris Lattnerb12914b2004-09-20 04:48:05 +000051bool InternalGlobalMapper::runOnModule(Module &M) {
Brian Gaeke8c4174a2004-06-03 05:03:37 +000052 GVVectorTy gvvector;
53
54 // Populate the vector with internal global values and their names.
Chris Lattnere4d5c442005-03-15 04:54:21 +000055 for (Module::global_iterator i = M.global_begin (), e = M.global_end (); i != e; ++i)
Brian Gaeke8c4174a2004-06-03 05:03:37 +000056 maybeAddInternalValueToVector (gvvector, *i);
Brian Gaeke8e6e7c92004-06-08 20:08:30 +000057 // 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 Gaeke8c4174a2004-06-03 05:03:37 +000061 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}