fix some GCC 4 warnings
[oota-llvm.git] / lib / Target / SparcV9 / InternalGlobalMapper.cpp
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/DerivedTypes.h"
23 using namespace llvm;
24
25 typedef std::vector<Constant *> GVVectorTy;
26
27 namespace {
28   struct InternalGlobalMapper : public ModulePass {
29     bool runOnModule(Module &M);
30   };
31 }
32
33 namespace llvm {
34   ModulePass *createInternalGlobalMapperPass() {
35     return new InternalGlobalMapper();
36   }
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(&GV,
45                                            PointerType::get(Type::SByteTy)));
46   else
47     Vector.push_back (ConstantPointerNull::get (PointerType::get
48                                                 (Type::SByteTy)));
49 }
50
51 bool InternalGlobalMapper::runOnModule(Module &M) {
52   GVVectorTy gvvector;
53
54   // Populate the vector with internal global values and their names.
55   for (Module::global_iterator i = M.global_begin (), e = M.global_end (); i != e; ++i)
56     maybeAddInternalValueToVector (gvvector, *i);
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)));
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 }