LLVM API Documentation

InternalGlobalMapper.cpp

Go to the documentation of this file.
00001 //===-- InternalGlobalMapper.cpp - Mapping Info for Internal Globals ------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file was developed by the LLVM research group and is distributed under
00006 // the University of Illinois Open Source License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // InternalGlobalMapper is a pass that helps the runtime trace optimizer map
00011 // the names of internal GlobalValues (which may have mangled,
00012 // unreconstructible names in the executable) to pointers. If the name mangler
00013 // is changed at some point in the future to allow its results to be
00014 // reconstructible (for instance, by making the type mangling symbolic instead
00015 // of using a UniqueID) this pass should probably be phased out.
00016 //
00017 //===----------------------------------------------------------------------===//
00018 
00019 #include "llvm/Constants.h"
00020 #include "llvm/Module.h"
00021 #include "llvm/Pass.h"
00022 #include "llvm/DerivedTypes.h"
00023 using namespace llvm;
00024 
00025 typedef std::vector<Constant *> GVVectorTy;
00026 
00027 namespace {
00028   struct InternalGlobalMapper : public ModulePass {
00029     bool runOnModule(Module &M);
00030   };
00031 }
00032 
00033 namespace llvm {
00034   ModulePass *createInternalGlobalMapperPass() {
00035     return new InternalGlobalMapper();
00036   }
00037 }
00038 
00039 static void maybeAddInternalValueToVector (GVVectorTy &Vector, GlobalValue &GV){
00040   // If it's a GlobalValue with internal linkage and a name (i.e. it's going to
00041   // be mangled), then put the GV, casted to sbyte*, in the vector. Otherwise
00042   // add a null.
00043   if (GV.hasInternalLinkage () && GV.hasName ())
00044     Vector.push_back(ConstantExpr::getCast(&GV,
00045                                            PointerType::get(Type::SByteTy)));
00046   else
00047     Vector.push_back (ConstantPointerNull::get (PointerType::get
00048                                                 (Type::SByteTy)));
00049 }
00050 
00051 bool InternalGlobalMapper::runOnModule(Module &M) {
00052   GVVectorTy gvvector;
00053 
00054   // Populate the vector with internal global values and their names.
00055   for (Module::global_iterator i = M.global_begin (), e = M.global_end (); i != e; ++i)
00056     maybeAddInternalValueToVector (gvvector, *i);
00057   // Add an extra global for _llvm_internalGlobals itself (null,
00058   // because it's not internal)
00059   gvvector.push_back (ConstantPointerNull::get
00060     (PointerType::get (Type::SByteTy)));
00061   for (Module::iterator i = M.begin (), e = M.end (); i != e; ++i)
00062     maybeAddInternalValueToVector (gvvector, *i);
00063 
00064   // Convert the vector to a constant struct of type {Size, [Size x sbyte*]}.
00065   ArrayType *ATy = ArrayType::get (PointerType::get (Type::SByteTy),
00066                                   gvvector.size ());
00067   std::vector<const Type *> FieldTypes;
00068   FieldTypes.push_back (Type::UIntTy);
00069   FieldTypes.push_back (ATy);
00070   StructType *STy = StructType::get (FieldTypes);
00071   std::vector<Constant *> FieldValues;
00072   FieldValues.push_back (ConstantUInt::get (Type::UIntTy, gvvector.size ()));
00073   FieldValues.push_back (ConstantArray::get (ATy, gvvector));
00074 
00075   // Add the constant struct to M as an external global symbol named
00076   // "_llvm_internalGlobals".
00077   new GlobalVariable (STy, true, GlobalValue::ExternalLinkage,
00078                       ConstantStruct::get (STy, FieldValues),
00079                       "_llvm_internalGlobals", &M);
00080 
00081   return true; // Module was modified.
00082 }