mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-30 16:17:05 +00:00 
			
		
		
		
	git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21425 91177308-0d34-0410-b5e6-96231b3b80d8
		
			
				
	
	
		
			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.
 | |
| }
 |