mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 20:23:11 +01:00
1fef885677
llvm-svn: 21425
83 lines
3.2 KiB
C++
83 lines
3.2 KiB
C++
//===-- InternalGlobalMapper.cpp - Mapping Info for Internal Globals ------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file was developed by the LLVM research group and is distributed under
|
|
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// InternalGlobalMapper is a pass that helps the runtime trace optimizer map
|
|
// the names of internal GlobalValues (which may have mangled,
|
|
// unreconstructible names in the executable) to pointers. If the name mangler
|
|
// is changed at some point in the future to allow its results to be
|
|
// reconstructible (for instance, by making the type mangling symbolic instead
|
|
// of using a UniqueID) this pass should probably be phased out.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/Constants.h"
|
|
#include "llvm/Module.h"
|
|
#include "llvm/Pass.h"
|
|
#include "llvm/DerivedTypes.h"
|
|
using namespace llvm;
|
|
|
|
typedef std::vector<Constant *> GVVectorTy;
|
|
|
|
namespace {
|
|
struct InternalGlobalMapper : public ModulePass {
|
|
bool runOnModule(Module &M);
|
|
};
|
|
}
|
|
|
|
namespace llvm {
|
|
ModulePass *createInternalGlobalMapperPass() {
|
|
return new InternalGlobalMapper();
|
|
}
|
|
}
|
|
|
|
static void maybeAddInternalValueToVector (GVVectorTy &Vector, GlobalValue &GV){
|
|
// If it's a GlobalValue with internal linkage and a name (i.e. it's going to
|
|
// be mangled), then put the GV, casted to sbyte*, in the vector. Otherwise
|
|
// add a null.
|
|
if (GV.hasInternalLinkage () && GV.hasName ())
|
|
Vector.push_back(ConstantExpr::getCast(&GV,
|
|
PointerType::get(Type::SByteTy)));
|
|
else
|
|
Vector.push_back (ConstantPointerNull::get (PointerType::get
|
|
(Type::SByteTy)));
|
|
}
|
|
|
|
bool InternalGlobalMapper::runOnModule(Module &M) {
|
|
GVVectorTy gvvector;
|
|
|
|
// Populate the vector with internal global values and their names.
|
|
for (Module::global_iterator i = M.global_begin (), e = M.global_end (); i != e; ++i)
|
|
maybeAddInternalValueToVector (gvvector, *i);
|
|
// Add an extra global for _llvm_internalGlobals itself (null,
|
|
// because it's not internal)
|
|
gvvector.push_back (ConstantPointerNull::get
|
|
(PointerType::get (Type::SByteTy)));
|
|
for (Module::iterator i = M.begin (), e = M.end (); i != e; ++i)
|
|
maybeAddInternalValueToVector (gvvector, *i);
|
|
|
|
// Convert the vector to a constant struct of type {Size, [Size x sbyte*]}.
|
|
ArrayType *ATy = ArrayType::get (PointerType::get (Type::SByteTy),
|
|
gvvector.size ());
|
|
std::vector<const Type *> FieldTypes;
|
|
FieldTypes.push_back (Type::UIntTy);
|
|
FieldTypes.push_back (ATy);
|
|
StructType *STy = StructType::get (FieldTypes);
|
|
std::vector<Constant *> FieldValues;
|
|
FieldValues.push_back (ConstantUInt::get (Type::UIntTy, gvvector.size ()));
|
|
FieldValues.push_back (ConstantArray::get (ATy, gvvector));
|
|
|
|
// Add the constant struct to M as an external global symbol named
|
|
// "_llvm_internalGlobals".
|
|
new GlobalVariable (STy, true, GlobalValue::ExternalLinkage,
|
|
ConstantStruct::get (STy, FieldValues),
|
|
"_llvm_internalGlobals", &M);
|
|
|
|
return true; // Module was modified.
|
|
}
|