2003-10-10 17:45:12 +00:00
|
|
|
//===-- ExecutionEngine.cpp - Common Implementation shared by EEs ---------===//
|
2005-04-21 22:36:52 +00:00
|
|
|
//
|
2003-10-20 19:43:21 +00:00
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-29 20:36:04 +00:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2005-04-21 22:36:52 +00:00
|
|
|
//
|
2003-10-20 19:43:21 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
2005-04-21 22:36:52 +00:00
|
|
|
//
|
2002-12-24 00:01:05 +00:00
|
|
|
// This file defines the common interface used by the various execution engine
|
|
|
|
// subclasses.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2003-08-05 17:00:32 +00:00
|
|
|
#define DEBUG_TYPE "jit"
|
2002-12-24 00:01:05 +00:00
|
|
|
#include "llvm/Constants.h"
|
2003-10-16 21:18:05 +00:00
|
|
|
#include "llvm/DerivedTypes.h"
|
2002-12-24 00:01:05 +00:00
|
|
|
#include "llvm/Module.h"
|
2003-10-16 21:18:05 +00:00
|
|
|
#include "llvm/ModuleProvider.h"
|
2004-11-29 14:11:29 +00:00
|
|
|
#include "llvm/ADT/Statistic.h"
|
2007-12-14 19:38:31 +00:00
|
|
|
#include "llvm/Config/alloca.h"
|
2003-10-16 21:18:05 +00:00
|
|
|
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
2003-09-05 20:08:15 +00:00
|
|
|
#include "llvm/ExecutionEngine/GenericValue.h"
|
2004-09-01 22:55:40 +00:00
|
|
|
#include "llvm/Support/Debug.h"
|
2006-05-08 22:00:52 +00:00
|
|
|
#include "llvm/Support/MutexGuard.h"
|
2004-11-29 14:11:29 +00:00
|
|
|
#include "llvm/System/DynamicLibrary.h"
|
2007-12-12 23:03:45 +00:00
|
|
|
#include "llvm/System/Host.h"
|
2004-11-29 14:11:29 +00:00
|
|
|
#include "llvm/Target/TargetData.h"
|
2008-02-20 11:08:44 +00:00
|
|
|
#include <cmath>
|
|
|
|
#include <cstring>
|
2003-11-19 21:08:57 +00:00
|
|
|
using namespace llvm;
|
2002-12-24 00:01:05 +00:00
|
|
|
|
2006-12-19 22:43:32 +00:00
|
|
|
STATISTIC(NumInitBytes, "Number of bytes of global vars initialized");
|
|
|
|
STATISTIC(NumGlobals , "Number of global vars initialized");
|
2002-12-24 00:01:05 +00:00
|
|
|
|
2006-03-22 06:07:50 +00:00
|
|
|
ExecutionEngine::EECtorFn ExecutionEngine::JITCtor = 0;
|
|
|
|
ExecutionEngine::EECtorFn ExecutionEngine::InterpCtor = 0;
|
2008-02-13 18:39:37 +00:00
|
|
|
ExecutionEngine::EERegisterFn ExecutionEngine::ExceptionTableRegister = 0;
|
|
|
|
|
2006-03-22 06:07:50 +00:00
|
|
|
|
2007-10-22 02:50:12 +00:00
|
|
|
ExecutionEngine::ExecutionEngine(ModuleProvider *P) : LazyFunctionCreator(0) {
|
2006-11-09 19:31:15 +00:00
|
|
|
LazyCompilationDisabled = false;
|
2008-09-24 16:25:55 +00:00
|
|
|
GVCompilationDisabled = false;
|
2008-06-17 16:49:02 +00:00
|
|
|
SymbolSearchingDisabled = false;
|
2006-08-16 01:24:12 +00:00
|
|
|
Modules.push_back(P);
|
2003-10-16 21:18:05 +00:00
|
|
|
assert(P && "ModuleProvider is null?");
|
|
|
|
}
|
|
|
|
|
2003-09-04 22:57:27 +00:00
|
|
|
ExecutionEngine::~ExecutionEngine() {
|
2007-03-03 18:19:18 +00:00
|
|
|
clearAllGlobalMappings();
|
2006-08-16 01:24:12 +00:00
|
|
|
for (unsigned i = 0, e = Modules.size(); i != e; ++i)
|
|
|
|
delete Modules[i];
|
2003-09-04 22:57:27 +00:00
|
|
|
}
|
|
|
|
|
2008-10-25 15:41:43 +00:00
|
|
|
char* ExecutionEngine::getMemoryForGV(const GlobalVariable* GV) {
|
|
|
|
const Type *ElTy = GV->getType()->getElementType();
|
|
|
|
size_t GVSize = (size_t)getTargetData()->getABITypeSize(ElTy);
|
|
|
|
return new char[GVSize];
|
|
|
|
}
|
|
|
|
|
2007-10-15 19:56:32 +00:00
|
|
|
/// removeModuleProvider - Remove a ModuleProvider from the list of modules.
|
|
|
|
/// Release module from ModuleProvider.
|
|
|
|
Module* ExecutionEngine::removeModuleProvider(ModuleProvider *P,
|
|
|
|
std::string *ErrInfo) {
|
|
|
|
for(SmallVector<ModuleProvider *, 1>::iterator I = Modules.begin(),
|
|
|
|
E = Modules.end(); I != E; ++I) {
|
|
|
|
ModuleProvider *MP = *I;
|
|
|
|
if (MP == P) {
|
|
|
|
Modules.erase(I);
|
2008-05-21 16:34:48 +00:00
|
|
|
clearGlobalMappingsFromModule(MP->getModule());
|
2007-10-15 19:56:32 +00:00
|
|
|
return MP->releaseModule(ErrInfo);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2006-08-16 01:24:12 +00:00
|
|
|
/// FindFunctionNamed - Search all of the active modules to find the one that
|
|
|
|
/// defines FnName. This is very slow operation and shouldn't be used for
|
|
|
|
/// general code.
|
|
|
|
Function *ExecutionEngine::FindFunctionNamed(const char *FnName) {
|
|
|
|
for (unsigned i = 0, e = Modules.size(); i != e; ++i) {
|
2007-02-05 21:19:13 +00:00
|
|
|
if (Function *F = Modules[i]->getModule()->getFunction(FnName))
|
2006-08-16 01:24:12 +00:00
|
|
|
return F;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-05-08 22:00:52 +00:00
|
|
|
/// addGlobalMapping - Tell the execution engine that the specified global is
|
|
|
|
/// at the specified location. This is used internally as functions are JIT'd
|
|
|
|
/// and as global variables are laid out in memory. It can and should also be
|
|
|
|
/// used by clients of the EE that want to have an LLVM global overlay
|
|
|
|
/// existing data in memory.
|
|
|
|
void ExecutionEngine::addGlobalMapping(const GlobalValue *GV, void *Addr) {
|
|
|
|
MutexGuard locked(lock);
|
2008-09-18 07:54:21 +00:00
|
|
|
|
|
|
|
DOUT << "Map " << *GV << " to " << Addr << "\n";
|
2006-05-08 22:00:52 +00:00
|
|
|
void *&CurVal = state.getGlobalAddressMap(locked)[GV];
|
|
|
|
assert((CurVal == 0 || Addr == 0) && "GlobalMapping already established!");
|
|
|
|
CurVal = Addr;
|
|
|
|
|
|
|
|
// If we are using the reverse mapping, add it too
|
|
|
|
if (!state.getGlobalAddressReverseMap(locked).empty()) {
|
|
|
|
const GlobalValue *&V = state.getGlobalAddressReverseMap(locked)[Addr];
|
|
|
|
assert((V == 0 || GV == 0) && "GlobalMapping already established!");
|
|
|
|
V = GV;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// clearAllGlobalMappings - Clear all global mappings and start over again
|
|
|
|
/// use in dynamic compilation scenarios when you want to move globals
|
|
|
|
void ExecutionEngine::clearAllGlobalMappings() {
|
|
|
|
MutexGuard locked(lock);
|
|
|
|
|
|
|
|
state.getGlobalAddressMap(locked).clear();
|
|
|
|
state.getGlobalAddressReverseMap(locked).clear();
|
|
|
|
}
|
|
|
|
|
2008-05-21 16:34:48 +00:00
|
|
|
/// clearGlobalMappingsFromModule - Clear all global mappings that came from a
|
|
|
|
/// particular module, because it has been removed from the JIT.
|
|
|
|
void ExecutionEngine::clearGlobalMappingsFromModule(Module *M) {
|
|
|
|
MutexGuard locked(lock);
|
|
|
|
|
|
|
|
for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; ++FI) {
|
|
|
|
state.getGlobalAddressMap(locked).erase(FI);
|
|
|
|
state.getGlobalAddressReverseMap(locked).erase(FI);
|
|
|
|
}
|
|
|
|
for (Module::global_iterator GI = M->global_begin(), GE = M->global_end();
|
|
|
|
GI != GE; ++GI) {
|
|
|
|
state.getGlobalAddressMap(locked).erase(GI);
|
|
|
|
state.getGlobalAddressReverseMap(locked).erase(GI);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-05-08 22:00:52 +00:00
|
|
|
/// updateGlobalMapping - Replace an existing mapping for GV with a new
|
|
|
|
/// address. This updates both maps as required. If "Addr" is null, the
|
|
|
|
/// entry for the global is removed from the mappings.
|
2008-04-04 04:47:41 +00:00
|
|
|
void *ExecutionEngine::updateGlobalMapping(const GlobalValue *GV, void *Addr) {
|
2006-05-08 22:00:52 +00:00
|
|
|
MutexGuard locked(lock);
|
2008-04-04 04:47:41 +00:00
|
|
|
|
|
|
|
std::map<const GlobalValue*, void *> &Map = state.getGlobalAddressMap(locked);
|
|
|
|
|
2006-05-08 22:00:52 +00:00
|
|
|
// Deleting from the mapping?
|
|
|
|
if (Addr == 0) {
|
2008-04-04 04:47:41 +00:00
|
|
|
std::map<const GlobalValue*, void *>::iterator I = Map.find(GV);
|
|
|
|
void *OldVal;
|
|
|
|
if (I == Map.end())
|
|
|
|
OldVal = 0;
|
|
|
|
else {
|
|
|
|
OldVal = I->second;
|
|
|
|
Map.erase(I);
|
|
|
|
}
|
|
|
|
|
2006-05-08 22:00:52 +00:00
|
|
|
if (!state.getGlobalAddressReverseMap(locked).empty())
|
|
|
|
state.getGlobalAddressReverseMap(locked).erase(Addr);
|
2008-04-04 04:47:41 +00:00
|
|
|
return OldVal;
|
2006-05-08 22:00:52 +00:00
|
|
|
}
|
|
|
|
|
2008-04-04 04:47:41 +00:00
|
|
|
void *&CurVal = Map[GV];
|
|
|
|
void *OldVal = CurVal;
|
|
|
|
|
2006-05-08 22:00:52 +00:00
|
|
|
if (CurVal && !state.getGlobalAddressReverseMap(locked).empty())
|
|
|
|
state.getGlobalAddressReverseMap(locked).erase(CurVal);
|
|
|
|
CurVal = Addr;
|
|
|
|
|
|
|
|
// If we are using the reverse mapping, add it too
|
|
|
|
if (!state.getGlobalAddressReverseMap(locked).empty()) {
|
|
|
|
const GlobalValue *&V = state.getGlobalAddressReverseMap(locked)[Addr];
|
|
|
|
assert((V == 0 || GV == 0) && "GlobalMapping already established!");
|
|
|
|
V = GV;
|
|
|
|
}
|
2008-04-04 04:47:41 +00:00
|
|
|
return OldVal;
|
2006-05-08 22:00:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// getPointerToGlobalIfAvailable - This returns the address of the specified
|
|
|
|
/// global value if it is has already been codegen'd, otherwise it returns null.
|
|
|
|
///
|
|
|
|
void *ExecutionEngine::getPointerToGlobalIfAvailable(const GlobalValue *GV) {
|
|
|
|
MutexGuard locked(lock);
|
|
|
|
|
|
|
|
std::map<const GlobalValue*, void*>::iterator I =
|
|
|
|
state.getGlobalAddressMap(locked).find(GV);
|
|
|
|
return I != state.getGlobalAddressMap(locked).end() ? I->second : 0;
|
|
|
|
}
|
|
|
|
|
2003-12-31 20:21:04 +00:00
|
|
|
/// getGlobalValueAtAddress - Return the LLVM global value object that starts
|
|
|
|
/// at the specified address.
|
|
|
|
///
|
|
|
|
const GlobalValue *ExecutionEngine::getGlobalValueAtAddress(void *Addr) {
|
2005-07-12 15:51:55 +00:00
|
|
|
MutexGuard locked(lock);
|
|
|
|
|
2003-12-31 20:21:04 +00:00
|
|
|
// If we haven't computed the reverse mapping yet, do so first.
|
2005-07-12 15:51:55 +00:00
|
|
|
if (state.getGlobalAddressReverseMap(locked).empty()) {
|
2006-05-08 22:00:52 +00:00
|
|
|
for (std::map<const GlobalValue*, void *>::iterator
|
|
|
|
I = state.getGlobalAddressMap(locked).begin(),
|
|
|
|
E = state.getGlobalAddressMap(locked).end(); I != E; ++I)
|
|
|
|
state.getGlobalAddressReverseMap(locked).insert(std::make_pair(I->second,
|
|
|
|
I->first));
|
2003-12-31 20:21:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
std::map<void *, const GlobalValue*>::iterator I =
|
2005-07-12 15:51:55 +00:00
|
|
|
state.getGlobalAddressReverseMap(locked).find(Addr);
|
|
|
|
return I != state.getGlobalAddressReverseMap(locked).end() ? I->second : 0;
|
2003-12-31 20:21:04 +00:00
|
|
|
}
|
2003-12-26 06:50:30 +00:00
|
|
|
|
|
|
|
// CreateArgv - Turn a vector of strings into a nice argv style array of
|
|
|
|
// pointers to null terminated strings.
|
|
|
|
//
|
|
|
|
static void *CreateArgv(ExecutionEngine *EE,
|
|
|
|
const std::vector<std::string> &InputArgv) {
|
2006-05-03 01:29:57 +00:00
|
|
|
unsigned PtrSize = EE->getTargetData()->getPointerSize();
|
2003-12-26 06:50:30 +00:00
|
|
|
char *Result = new char[(InputArgv.size()+1)*PtrSize];
|
|
|
|
|
2006-11-27 23:54:50 +00:00
|
|
|
DOUT << "ARGV = " << (void*)Result << "\n";
|
2007-12-17 01:12:55 +00:00
|
|
|
const Type *SBytePtr = PointerType::getUnqual(Type::Int8Ty);
|
2003-12-26 06:50:30 +00:00
|
|
|
|
|
|
|
for (unsigned i = 0; i != InputArgv.size(); ++i) {
|
|
|
|
unsigned Size = InputArgv[i].size()+1;
|
|
|
|
char *Dest = new char[Size];
|
2006-11-27 23:54:50 +00:00
|
|
|
DOUT << "ARGV[" << i << "] = " << (void*)Dest << "\n";
|
2005-04-21 22:36:52 +00:00
|
|
|
|
2003-12-26 06:50:30 +00:00
|
|
|
std::copy(InputArgv[i].begin(), InputArgv[i].end(), Dest);
|
|
|
|
Dest[Size-1] = 0;
|
2005-04-21 22:36:52 +00:00
|
|
|
|
2003-12-26 06:50:30 +00:00
|
|
|
// Endian safe: Result[i] = (PointerTy)Dest;
|
|
|
|
EE->StoreValueToMemory(PTOGV(Dest), (GenericValue*)(Result+i*PtrSize),
|
|
|
|
SBytePtr);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Null terminate it
|
|
|
|
EE->StoreValueToMemory(PTOGV(0),
|
|
|
|
(GenericValue*)(Result+InputArgv.size()*PtrSize),
|
|
|
|
SBytePtr);
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
2006-03-08 18:42:46 +00:00
|
|
|
|
|
|
|
/// runStaticConstructorsDestructors - This method is used to execute all of
|
2008-09-30 15:51:21 +00:00
|
|
|
/// the static constructors or destructors for a module, depending on the
|
2006-03-08 18:42:46 +00:00
|
|
|
/// value of isDtors.
|
2008-09-30 15:51:21 +00:00
|
|
|
void ExecutionEngine::runStaticConstructorsDestructors(Module *module, bool isDtors) {
|
2006-03-08 18:42:46 +00:00
|
|
|
const char *Name = isDtors ? "llvm.global_dtors" : "llvm.global_ctors";
|
|
|
|
|
2006-08-16 01:24:12 +00:00
|
|
|
// Execute global ctors/dtors for each module in the program.
|
|
|
|
|
2008-09-30 15:51:21 +00:00
|
|
|
GlobalVariable *GV = module->getNamedGlobal(Name);
|
|
|
|
|
|
|
|
// If this global has internal linkage, or if it has a use, then it must be
|
|
|
|
// an old-style (llvmgcc3) static ctor with __main linked in and in use. If
|
|
|
|
// this is the case, don't execute any of the global ctors, __main will do
|
|
|
|
// it.
|
|
|
|
if (!GV || GV->isDeclaration() || GV->hasInternalLinkage()) return;
|
|
|
|
|
|
|
|
// Should be an array of '{ int, void ()* }' structs. The first value is
|
|
|
|
// the init priority, which we ignore.
|
|
|
|
ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer());
|
|
|
|
if (!InitList) return;
|
|
|
|
for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i)
|
|
|
|
if (ConstantStruct *CS =
|
|
|
|
dyn_cast<ConstantStruct>(InitList->getOperand(i))) {
|
|
|
|
if (CS->getNumOperands() != 2) return; // Not array of 2-element structs.
|
|
|
|
|
|
|
|
Constant *FP = CS->getOperand(1);
|
|
|
|
if (FP->isNullValue())
|
|
|
|
break; // Found a null terminator, exit.
|
|
|
|
|
|
|
|
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP))
|
|
|
|
if (CE->isCast())
|
|
|
|
FP = CE->getOperand(0);
|
|
|
|
if (Function *F = dyn_cast<Function>(FP)) {
|
|
|
|
// Execute the ctor/dtor function!
|
|
|
|
runFunction(F, std::vector<GenericValue>());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// runStaticConstructorsDestructors - This method is used to execute all of
|
|
|
|
/// the static constructors or destructors for a program, depending on the
|
|
|
|
/// value of isDtors.
|
|
|
|
void ExecutionEngine::runStaticConstructorsDestructors(bool isDtors) {
|
|
|
|
// Execute global ctors/dtors for each module in the program.
|
|
|
|
for (unsigned m = 0, e = Modules.size(); m != e; ++m)
|
|
|
|
runStaticConstructorsDestructors(Modules[m]->getModule(), isDtors);
|
2006-03-08 18:42:46 +00:00
|
|
|
}
|
|
|
|
|
2008-08-26 01:38:29 +00:00
|
|
|
#ifndef NDEBUG
|
2007-12-14 19:38:31 +00:00
|
|
|
/// isTargetNullPtr - Return whether the target pointer stored at Loc is null.
|
|
|
|
static bool isTargetNullPtr(ExecutionEngine *EE, void *Loc) {
|
|
|
|
unsigned PtrSize = EE->getTargetData()->getPointerSize();
|
|
|
|
for (unsigned i = 0; i < PtrSize; ++i)
|
|
|
|
if (*(i + (uint8_t*)Loc))
|
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
2008-08-26 01:38:29 +00:00
|
|
|
#endif
|
2007-12-14 19:38:31 +00:00
|
|
|
|
2003-12-26 06:50:30 +00:00
|
|
|
/// runFunctionAsMain - This is a helper function which wraps runFunction to
|
|
|
|
/// handle the common task of starting up main with the specified argc, argv,
|
|
|
|
/// and envp parameters.
|
|
|
|
int ExecutionEngine::runFunctionAsMain(Function *Fn,
|
|
|
|
const std::vector<std::string> &argv,
|
|
|
|
const char * const * envp) {
|
|
|
|
std::vector<GenericValue> GVArgs;
|
|
|
|
GenericValue GVArgc;
|
2007-03-06 03:04:04 +00:00
|
|
|
GVArgc.IntVal = APInt(32, argv.size());
|
2007-06-03 19:17:35 +00:00
|
|
|
|
|
|
|
// Check main() type
|
2004-08-16 01:05:35 +00:00
|
|
|
unsigned NumArgs = Fn->getFunctionType()->getNumParams();
|
2007-06-03 19:17:35 +00:00
|
|
|
const FunctionType *FTy = Fn->getFunctionType();
|
2007-12-17 01:12:55 +00:00
|
|
|
const Type* PPInt8Ty =
|
|
|
|
PointerType::getUnqual(PointerType::getUnqual(Type::Int8Ty));
|
2007-06-03 19:17:35 +00:00
|
|
|
switch (NumArgs) {
|
|
|
|
case 3:
|
|
|
|
if (FTy->getParamType(2) != PPInt8Ty) {
|
|
|
|
cerr << "Invalid type for third argument of main() supplied\n";
|
|
|
|
abort();
|
|
|
|
}
|
2007-06-03 19:20:49 +00:00
|
|
|
// FALLS THROUGH
|
2007-06-03 19:17:35 +00:00
|
|
|
case 2:
|
|
|
|
if (FTy->getParamType(1) != PPInt8Ty) {
|
|
|
|
cerr << "Invalid type for second argument of main() supplied\n";
|
|
|
|
abort();
|
|
|
|
}
|
2007-06-03 19:20:49 +00:00
|
|
|
// FALLS THROUGH
|
2007-06-03 19:17:35 +00:00
|
|
|
case 1:
|
|
|
|
if (FTy->getParamType(0) != Type::Int32Ty) {
|
|
|
|
cerr << "Invalid type for first argument of main() supplied\n";
|
|
|
|
abort();
|
|
|
|
}
|
2007-06-03 19:20:49 +00:00
|
|
|
// FALLS THROUGH
|
2007-06-03 19:17:35 +00:00
|
|
|
case 0:
|
|
|
|
if (FTy->getReturnType() != Type::Int32Ty &&
|
|
|
|
FTy->getReturnType() != Type::VoidTy) {
|
|
|
|
cerr << "Invalid return type of main() supplied\n";
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
cerr << "Invalid number of arguments of main() supplied\n";
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
2004-08-16 01:05:35 +00:00
|
|
|
if (NumArgs) {
|
|
|
|
GVArgs.push_back(GVArgc); // Arg #0 = argc.
|
|
|
|
if (NumArgs > 1) {
|
|
|
|
GVArgs.push_back(PTOGV(CreateArgv(this, argv))); // Arg #1 = argv.
|
2007-12-14 19:38:31 +00:00
|
|
|
assert(!isTargetNullPtr(this, GVTOP(GVArgs[1])) &&
|
2004-08-16 01:05:35 +00:00
|
|
|
"argv[0] was null after CreateArgv");
|
|
|
|
if (NumArgs > 2) {
|
|
|
|
std::vector<std::string> EnvVars;
|
|
|
|
for (unsigned i = 0; envp[i]; ++i)
|
|
|
|
EnvVars.push_back(envp[i]);
|
|
|
|
GVArgs.push_back(PTOGV(CreateArgv(this, EnvVars))); // Arg #2 = envp.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-03-06 03:04:04 +00:00
|
|
|
return runFunction(Fn, GVArgs).IntVal.getZExtValue();
|
2003-12-26 06:50:30 +00:00
|
|
|
}
|
|
|
|
|
2003-10-16 21:18:05 +00:00
|
|
|
/// If possible, create a JIT, unless the caller specifically requests an
|
|
|
|
/// Interpreter or there's an error. If even an Interpreter cannot be created,
|
2005-04-21 22:36:52 +00:00
|
|
|
/// NULL is returned.
|
2003-10-10 17:45:12 +00:00
|
|
|
///
|
2005-04-21 22:36:52 +00:00
|
|
|
ExecutionEngine *ExecutionEngine::create(ModuleProvider *MP,
|
2007-03-03 18:19:18 +00:00
|
|
|
bool ForceInterpreter,
|
2008-08-08 08:11:34 +00:00
|
|
|
std::string *ErrorStr,
|
|
|
|
bool Fast) {
|
2003-09-03 20:34:19 +00:00
|
|
|
ExecutionEngine *EE = 0;
|
|
|
|
|
2008-03-08 02:49:45 +00:00
|
|
|
// Make sure we can resolve symbols in the program as well. The zero arg
|
|
|
|
// to the function tells DynamicLibrary to load the program, not a library.
|
|
|
|
if (sys::DynamicLibrary::LoadLibraryPermanently(0, ErrorStr))
|
|
|
|
return 0;
|
|
|
|
|
2003-12-28 09:44:37 +00:00
|
|
|
// Unless the interpreter was explicitly selected, try making a JIT.
|
2006-03-22 06:07:50 +00:00
|
|
|
if (!ForceInterpreter && JITCtor)
|
2008-08-08 08:11:34 +00:00
|
|
|
EE = JITCtor(MP, ErrorStr, Fast);
|
2003-09-03 20:34:19 +00:00
|
|
|
|
|
|
|
// If we can't make a JIT, make an interpreter instead.
|
2006-03-22 06:07:50 +00:00
|
|
|
if (EE == 0 && InterpCtor)
|
2008-08-08 08:11:34 +00:00
|
|
|
EE = InterpCtor(MP, ErrorStr, Fast);
|
2003-12-28 09:44:37 +00:00
|
|
|
|
2003-09-03 20:34:19 +00:00
|
|
|
return EE;
|
|
|
|
}
|
|
|
|
|
2007-10-21 22:57:11 +00:00
|
|
|
ExecutionEngine *ExecutionEngine::create(Module *M) {
|
|
|
|
return create(new ExistingModuleProvider(M));
|
|
|
|
}
|
|
|
|
|
2003-10-10 17:45:12 +00:00
|
|
|
/// getPointerToGlobal - This returns the address of the specified global
|
|
|
|
/// value. This may involve code generation if it's a function.
|
|
|
|
///
|
2002-12-24 00:01:05 +00:00
|
|
|
void *ExecutionEngine::getPointerToGlobal(const GlobalValue *GV) {
|
2003-08-13 18:16:14 +00:00
|
|
|
if (Function *F = const_cast<Function*>(dyn_cast<Function>(GV)))
|
2002-12-24 00:01:05 +00:00
|
|
|
return getPointerToFunction(F);
|
|
|
|
|
2005-07-12 15:51:55 +00:00
|
|
|
MutexGuard locked(lock);
|
2006-02-07 05:11:57 +00:00
|
|
|
void *p = state.getGlobalAddressMap(locked)[GV];
|
|
|
|
if (p)
|
|
|
|
return p;
|
|
|
|
|
|
|
|
// Global variable might have been added since interpreter started.
|
|
|
|
if (GlobalVariable *GVar =
|
|
|
|
const_cast<GlobalVariable *>(dyn_cast<GlobalVariable>(GV)))
|
|
|
|
EmitGlobalVariable(GVar);
|
|
|
|
else
|
2007-02-14 06:20:04 +00:00
|
|
|
assert(0 && "Global hasn't had an address allocated yet!");
|
2005-07-12 15:51:55 +00:00
|
|
|
return state.getGlobalAddressMap(locked)[GV];
|
2002-12-24 00:01:05 +00:00
|
|
|
}
|
|
|
|
|
2006-11-27 01:05:10 +00:00
|
|
|
/// This function converts a Constant* into a GenericValue. The interesting
|
|
|
|
/// part is if C is a ConstantExpr.
|
2007-08-11 15:57:56 +00:00
|
|
|
/// @brief Get a GenericValue for a Constant*
|
2002-12-24 00:01:05 +00:00
|
|
|
GenericValue ExecutionEngine::getConstantValue(const Constant *C) {
|
2006-11-27 01:05:10 +00:00
|
|
|
// If its undefined, return the garbage.
|
2007-03-06 22:23:15 +00:00
|
|
|
if (isa<UndefValue>(C))
|
|
|
|
return GenericValue();
|
2003-04-23 19:01:49 +00:00
|
|
|
|
2006-11-27 01:05:10 +00:00
|
|
|
// If the value is a ConstantExpr
|
|
|
|
if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
|
2007-03-06 22:23:15 +00:00
|
|
|
Constant *Op0 = CE->getOperand(0);
|
2003-04-23 19:01:49 +00:00
|
|
|
switch (CE->getOpcode()) {
|
|
|
|
case Instruction::GetElementPtr: {
|
2006-11-27 01:05:10 +00:00
|
|
|
// Compute the index
|
2007-03-06 22:23:15 +00:00
|
|
|
GenericValue Result = getConstantValue(Op0);
|
2007-02-10 20:35:22 +00:00
|
|
|
SmallVector<Value*, 8> Indices(CE->op_begin()+1, CE->op_end());
|
2003-04-23 19:01:49 +00:00
|
|
|
uint64_t Offset =
|
2007-03-06 22:23:15 +00:00
|
|
|
TD->getIndexedOffset(Op0->getType(), &Indices[0], Indices.size());
|
2005-04-21 22:36:52 +00:00
|
|
|
|
2007-03-06 03:04:04 +00:00
|
|
|
char* tmp = (char*) Result.PointerVal;
|
|
|
|
Result = PTOGV(tmp + Offset);
|
2003-04-23 19:01:49 +00:00
|
|
|
return Result;
|
|
|
|
}
|
2007-03-06 22:23:15 +00:00
|
|
|
case Instruction::Trunc: {
|
|
|
|
GenericValue GV = getConstantValue(Op0);
|
|
|
|
uint32_t BitWidth = cast<IntegerType>(CE->getType())->getBitWidth();
|
|
|
|
GV.IntVal = GV.IntVal.trunc(BitWidth);
|
2006-11-27 01:05:10 +00:00
|
|
|
return GV;
|
|
|
|
}
|
2007-03-06 22:23:15 +00:00
|
|
|
case Instruction::ZExt: {
|
|
|
|
GenericValue GV = getConstantValue(Op0);
|
|
|
|
uint32_t BitWidth = cast<IntegerType>(CE->getType())->getBitWidth();
|
|
|
|
GV.IntVal = GV.IntVal.zext(BitWidth);
|
|
|
|
return GV;
|
|
|
|
}
|
|
|
|
case Instruction::SExt: {
|
|
|
|
GenericValue GV = getConstantValue(Op0);
|
|
|
|
uint32_t BitWidth = cast<IntegerType>(CE->getType())->getBitWidth();
|
|
|
|
GV.IntVal = GV.IntVal.sext(BitWidth);
|
|
|
|
return GV;
|
|
|
|
}
|
|
|
|
case Instruction::FPTrunc: {
|
2007-09-17 18:44:13 +00:00
|
|
|
// FIXME long double
|
2007-03-06 22:23:15 +00:00
|
|
|
GenericValue GV = getConstantValue(Op0);
|
|
|
|
GV.FloatVal = float(GV.DoubleVal);
|
|
|
|
return GV;
|
|
|
|
}
|
|
|
|
case Instruction::FPExt:{
|
2007-09-17 18:44:13 +00:00
|
|
|
// FIXME long double
|
2007-03-06 22:23:15 +00:00
|
|
|
GenericValue GV = getConstantValue(Op0);
|
|
|
|
GV.DoubleVal = double(GV.FloatVal);
|
|
|
|
return GV;
|
|
|
|
}
|
|
|
|
case Instruction::UIToFP: {
|
|
|
|
GenericValue GV = getConstantValue(Op0);
|
|
|
|
if (CE->getType() == Type::FloatTy)
|
|
|
|
GV.FloatVal = float(GV.IntVal.roundToDouble());
|
2007-09-17 18:44:13 +00:00
|
|
|
else if (CE->getType() == Type::DoubleTy)
|
2007-03-06 22:23:15 +00:00
|
|
|
GV.DoubleVal = GV.IntVal.roundToDouble();
|
2007-09-21 22:09:37 +00:00
|
|
|
else if (CE->getType() == Type::X86_FP80Ty) {
|
2007-09-17 18:44:13 +00:00
|
|
|
const uint64_t zero[] = {0, 0};
|
|
|
|
APFloat apf = APFloat(APInt(80, 2, zero));
|
2008-02-29 01:27:13 +00:00
|
|
|
(void)apf.convertFromAPInt(GV.IntVal,
|
|
|
|
false,
|
|
|
|
APFloat::rmNearestTiesToEven);
|
2008-10-09 18:53:47 +00:00
|
|
|
GV.IntVal = apf.bitcastToAPInt();
|
2007-09-17 18:44:13 +00:00
|
|
|
}
|
2007-03-06 22:23:15 +00:00
|
|
|
return GV;
|
|
|
|
}
|
|
|
|
case Instruction::SIToFP: {
|
|
|
|
GenericValue GV = getConstantValue(Op0);
|
|
|
|
if (CE->getType() == Type::FloatTy)
|
|
|
|
GV.FloatVal = float(GV.IntVal.signedRoundToDouble());
|
2007-09-17 18:44:13 +00:00
|
|
|
else if (CE->getType() == Type::DoubleTy)
|
2007-03-06 22:23:15 +00:00
|
|
|
GV.DoubleVal = GV.IntVal.signedRoundToDouble();
|
2007-09-17 18:44:13 +00:00
|
|
|
else if (CE->getType() == Type::X86_FP80Ty) {
|
|
|
|
const uint64_t zero[] = { 0, 0};
|
|
|
|
APFloat apf = APFloat(APInt(80, 2, zero));
|
2008-02-29 01:27:13 +00:00
|
|
|
(void)apf.convertFromAPInt(GV.IntVal,
|
|
|
|
true,
|
|
|
|
APFloat::rmNearestTiesToEven);
|
2008-10-09 18:53:47 +00:00
|
|
|
GV.IntVal = apf.bitcastToAPInt();
|
2007-09-17 18:44:13 +00:00
|
|
|
}
|
2007-03-06 22:23:15 +00:00
|
|
|
return GV;
|
|
|
|
}
|
|
|
|
case Instruction::FPToUI: // double->APInt conversion handles sign
|
|
|
|
case Instruction::FPToSI: {
|
|
|
|
GenericValue GV = getConstantValue(Op0);
|
|
|
|
uint32_t BitWidth = cast<IntegerType>(CE->getType())->getBitWidth();
|
|
|
|
if (Op0->getType() == Type::FloatTy)
|
|
|
|
GV.IntVal = APIntOps::RoundFloatToAPInt(GV.FloatVal, BitWidth);
|
2007-09-17 18:44:13 +00:00
|
|
|
else if (Op0->getType() == Type::DoubleTy)
|
2007-03-06 22:23:15 +00:00
|
|
|
GV.IntVal = APIntOps::RoundDoubleToAPInt(GV.DoubleVal, BitWidth);
|
2007-09-17 18:44:13 +00:00
|
|
|
else if (Op0->getType() == Type::X86_FP80Ty) {
|
|
|
|
APFloat apf = APFloat(GV.IntVal);
|
|
|
|
uint64_t v;
|
2008-10-09 23:00:39 +00:00
|
|
|
bool ignored;
|
2007-09-17 18:44:13 +00:00
|
|
|
(void)apf.convertToInteger(&v, BitWidth,
|
|
|
|
CE->getOpcode()==Instruction::FPToSI,
|
2008-10-09 23:00:39 +00:00
|
|
|
APFloat::rmTowardZero, &ignored);
|
2007-09-17 18:44:13 +00:00
|
|
|
GV.IntVal = v; // endian?
|
|
|
|
}
|
2007-03-06 22:23:15 +00:00
|
|
|
return GV;
|
|
|
|
}
|
|
|
|
case Instruction::PtrToInt: {
|
|
|
|
GenericValue GV = getConstantValue(Op0);
|
|
|
|
uint32_t PtrWidth = TD->getPointerSizeInBits();
|
|
|
|
GV.IntVal = APInt(PtrWidth, uintptr_t(GV.PointerVal));
|
|
|
|
return GV;
|
2006-11-27 01:05:10 +00:00
|
|
|
}
|
|
|
|
case Instruction::IntToPtr: {
|
2007-03-06 22:23:15 +00:00
|
|
|
GenericValue GV = getConstantValue(Op0);
|
|
|
|
uint32_t PtrWidth = TD->getPointerSizeInBits();
|
|
|
|
if (PtrWidth != GV.IntVal.getBitWidth())
|
|
|
|
GV.IntVal = GV.IntVal.zextOrTrunc(PtrWidth);
|
|
|
|
assert(GV.IntVal.getBitWidth() <= 64 && "Bad pointer width");
|
|
|
|
GV.PointerVal = PointerTy(uintptr_t(GV.IntVal.getZExtValue()));
|
|
|
|
return GV;
|
|
|
|
}
|
|
|
|
case Instruction::BitCast: {
|
|
|
|
GenericValue GV = getConstantValue(Op0);
|
|
|
|
const Type* DestTy = CE->getType();
|
|
|
|
switch (Op0->getType()->getTypeID()) {
|
|
|
|
default: assert(0 && "Invalid bitcast operand");
|
|
|
|
case Type::IntegerTyID:
|
|
|
|
assert(DestTy->isFloatingPoint() && "invalid bitcast");
|
|
|
|
if (DestTy == Type::FloatTy)
|
|
|
|
GV.FloatVal = GV.IntVal.bitsToFloat();
|
|
|
|
else if (DestTy == Type::DoubleTy)
|
|
|
|
GV.DoubleVal = GV.IntVal.bitsToDouble();
|
|
|
|
break;
|
|
|
|
case Type::FloatTyID:
|
|
|
|
assert(DestTy == Type::Int32Ty && "Invalid bitcast");
|
|
|
|
GV.IntVal.floatToBits(GV.FloatVal);
|
|
|
|
break;
|
|
|
|
case Type::DoubleTyID:
|
|
|
|
assert(DestTy == Type::Int64Ty && "Invalid bitcast");
|
|
|
|
GV.IntVal.doubleToBits(GV.DoubleVal);
|
|
|
|
break;
|
|
|
|
case Type::PointerTyID:
|
|
|
|
assert(isa<PointerType>(DestTy) && "Invalid bitcast");
|
|
|
|
break; // getConstantValue(Op0) above already converted it
|
|
|
|
}
|
|
|
|
return GV;
|
2003-04-23 19:01:49 +00:00
|
|
|
}
|
2003-05-14 17:51:49 +00:00
|
|
|
case Instruction::Add:
|
2007-03-06 22:23:15 +00:00
|
|
|
case Instruction::Sub:
|
|
|
|
case Instruction::Mul:
|
|
|
|
case Instruction::UDiv:
|
|
|
|
case Instruction::SDiv:
|
|
|
|
case Instruction::URem:
|
|
|
|
case Instruction::SRem:
|
|
|
|
case Instruction::And:
|
|
|
|
case Instruction::Or:
|
|
|
|
case Instruction::Xor: {
|
|
|
|
GenericValue LHS = getConstantValue(Op0);
|
|
|
|
GenericValue RHS = getConstantValue(CE->getOperand(1));
|
|
|
|
GenericValue GV;
|
2004-07-11 08:01:11 +00:00
|
|
|
switch (CE->getOperand(0)->getType()->getTypeID()) {
|
|
|
|
default: assert(0 && "Bad add type!"); abort();
|
For PR1064:
Implement the arbitrary bit-width integer feature. The feature allows
integers of any bitwidth (up to 64) to be defined instead of just 1, 8,
16, 32, and 64 bit integers.
This change does several things:
1. Introduces a new Derived Type, IntegerType, to represent the number of
bits in an integer. The Type classes SubclassData field is used to
store the number of bits. This allows 2^23 bits in an integer type.
2. Removes the five integer Type::TypeID values for the 1, 8, 16, 32 and
64-bit integers. These are replaced with just IntegerType which is not
a primitive any more.
3. Adjust the rest of LLVM to account for this change.
Note that while this incremental change lays the foundation for arbitrary
bit-width integers, LLVM has not yet been converted to actually deal with
them in any significant way. Most optimization passes, for example, will
still only deal with the byte-width integer types. Future increments
will rectify this situation.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33113 91177308-0d34-0410-b5e6-96231b3b80d8
2007-01-12 07:05:14 +00:00
|
|
|
case Type::IntegerTyID:
|
2007-03-06 22:23:15 +00:00
|
|
|
switch (CE->getOpcode()) {
|
|
|
|
default: assert(0 && "Invalid integer opcode");
|
|
|
|
case Instruction::Add: GV.IntVal = LHS.IntVal + RHS.IntVal; break;
|
|
|
|
case Instruction::Sub: GV.IntVal = LHS.IntVal - RHS.IntVal; break;
|
|
|
|
case Instruction::Mul: GV.IntVal = LHS.IntVal * RHS.IntVal; break;
|
|
|
|
case Instruction::UDiv:GV.IntVal = LHS.IntVal.udiv(RHS.IntVal); break;
|
|
|
|
case Instruction::SDiv:GV.IntVal = LHS.IntVal.sdiv(RHS.IntVal); break;
|
|
|
|
case Instruction::URem:GV.IntVal = LHS.IntVal.urem(RHS.IntVal); break;
|
|
|
|
case Instruction::SRem:GV.IntVal = LHS.IntVal.srem(RHS.IntVal); break;
|
|
|
|
case Instruction::And: GV.IntVal = LHS.IntVal & RHS.IntVal; break;
|
|
|
|
case Instruction::Or: GV.IntVal = LHS.IntVal | RHS.IntVal; break;
|
|
|
|
case Instruction::Xor: GV.IntVal = LHS.IntVal ^ RHS.IntVal; break;
|
|
|
|
}
|
2004-07-11 08:01:11 +00:00
|
|
|
break;
|
|
|
|
case Type::FloatTyID:
|
2007-03-06 22:23:15 +00:00
|
|
|
switch (CE->getOpcode()) {
|
|
|
|
default: assert(0 && "Invalid float opcode"); abort();
|
|
|
|
case Instruction::Add:
|
|
|
|
GV.FloatVal = LHS.FloatVal + RHS.FloatVal; break;
|
|
|
|
case Instruction::Sub:
|
|
|
|
GV.FloatVal = LHS.FloatVal - RHS.FloatVal; break;
|
|
|
|
case Instruction::Mul:
|
|
|
|
GV.FloatVal = LHS.FloatVal * RHS.FloatVal; break;
|
|
|
|
case Instruction::FDiv:
|
|
|
|
GV.FloatVal = LHS.FloatVal / RHS.FloatVal; break;
|
|
|
|
case Instruction::FRem:
|
|
|
|
GV.FloatVal = ::fmodf(LHS.FloatVal,RHS.FloatVal); break;
|
|
|
|
}
|
2004-07-11 08:01:11 +00:00
|
|
|
break;
|
|
|
|
case Type::DoubleTyID:
|
2007-03-06 22:23:15 +00:00
|
|
|
switch (CE->getOpcode()) {
|
|
|
|
default: assert(0 && "Invalid double opcode"); abort();
|
|
|
|
case Instruction::Add:
|
|
|
|
GV.DoubleVal = LHS.DoubleVal + RHS.DoubleVal; break;
|
|
|
|
case Instruction::Sub:
|
|
|
|
GV.DoubleVal = LHS.DoubleVal - RHS.DoubleVal; break;
|
|
|
|
case Instruction::Mul:
|
|
|
|
GV.DoubleVal = LHS.DoubleVal * RHS.DoubleVal; break;
|
|
|
|
case Instruction::FDiv:
|
|
|
|
GV.DoubleVal = LHS.DoubleVal / RHS.DoubleVal; break;
|
|
|
|
case Instruction::FRem:
|
|
|
|
GV.DoubleVal = ::fmod(LHS.DoubleVal,RHS.DoubleVal); break;
|
|
|
|
}
|
2004-07-11 08:01:11 +00:00
|
|
|
break;
|
2007-09-17 18:44:13 +00:00
|
|
|
case Type::X86_FP80TyID:
|
|
|
|
case Type::PPC_FP128TyID:
|
|
|
|
case Type::FP128TyID: {
|
|
|
|
APFloat apfLHS = APFloat(LHS.IntVal);
|
|
|
|
switch (CE->getOpcode()) {
|
|
|
|
default: assert(0 && "Invalid long double opcode"); abort();
|
|
|
|
case Instruction::Add:
|
|
|
|
apfLHS.add(APFloat(RHS.IntVal), APFloat::rmNearestTiesToEven);
|
2008-10-09 18:53:47 +00:00
|
|
|
GV.IntVal = apfLHS.bitcastToAPInt();
|
2007-09-17 18:44:13 +00:00
|
|
|
break;
|
|
|
|
case Instruction::Sub:
|
|
|
|
apfLHS.subtract(APFloat(RHS.IntVal), APFloat::rmNearestTiesToEven);
|
2008-10-09 18:53:47 +00:00
|
|
|
GV.IntVal = apfLHS.bitcastToAPInt();
|
2007-09-17 18:44:13 +00:00
|
|
|
break;
|
|
|
|
case Instruction::Mul:
|
|
|
|
apfLHS.multiply(APFloat(RHS.IntVal), APFloat::rmNearestTiesToEven);
|
2008-10-09 18:53:47 +00:00
|
|
|
GV.IntVal = apfLHS.bitcastToAPInt();
|
2007-09-17 18:44:13 +00:00
|
|
|
break;
|
|
|
|
case Instruction::FDiv:
|
|
|
|
apfLHS.divide(APFloat(RHS.IntVal), APFloat::rmNearestTiesToEven);
|
2008-10-09 18:53:47 +00:00
|
|
|
GV.IntVal = apfLHS.bitcastToAPInt();
|
2007-09-17 18:44:13 +00:00
|
|
|
break;
|
|
|
|
case Instruction::FRem:
|
|
|
|
apfLHS.mod(APFloat(RHS.IntVal), APFloat::rmNearestTiesToEven);
|
2008-10-09 18:53:47 +00:00
|
|
|
GV.IntVal = apfLHS.bitcastToAPInt();
|
2007-09-17 18:44:13 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2004-07-11 08:01:11 +00:00
|
|
|
}
|
2007-03-06 22:23:15 +00:00
|
|
|
return GV;
|
|
|
|
}
|
2003-05-14 17:51:49 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2007-03-06 22:23:15 +00:00
|
|
|
cerr << "ConstantExpr not handled: " << *CE << "\n";
|
2003-05-14 17:51:49 +00:00
|
|
|
abort();
|
|
|
|
}
|
2005-04-21 22:36:52 +00:00
|
|
|
|
2007-03-06 22:23:15 +00:00
|
|
|
GenericValue Result;
|
2004-06-17 18:19:28 +00:00
|
|
|
switch (C->getType()->getTypeID()) {
|
2007-03-06 03:04:04 +00:00
|
|
|
case Type::FloatTyID:
|
2007-09-06 18:13:44 +00:00
|
|
|
Result.FloatVal = cast<ConstantFP>(C)->getValueAPF().convertToFloat();
|
2007-03-06 03:04:04 +00:00
|
|
|
break;
|
|
|
|
case Type::DoubleTyID:
|
2007-09-06 18:13:44 +00:00
|
|
|
Result.DoubleVal = cast<ConstantFP>(C)->getValueAPF().convertToDouble();
|
2007-03-06 03:04:04 +00:00
|
|
|
break;
|
2007-09-17 18:44:13 +00:00
|
|
|
case Type::X86_FP80TyID:
|
|
|
|
case Type::FP128TyID:
|
|
|
|
case Type::PPC_FP128TyID:
|
2008-10-09 18:53:47 +00:00
|
|
|
Result.IntVal = cast <ConstantFP>(C)->getValueAPF().bitcastToAPInt();
|
2007-09-17 18:44:13 +00:00
|
|
|
break;
|
2007-03-06 03:04:04 +00:00
|
|
|
case Type::IntegerTyID:
|
|
|
|
Result.IntVal = cast<ConstantInt>(C)->getValue();
|
For PR1064:
Implement the arbitrary bit-width integer feature. The feature allows
integers of any bitwidth (up to 64) to be defined instead of just 1, 8,
16, 32, and 64 bit integers.
This change does several things:
1. Introduces a new Derived Type, IntegerType, to represent the number of
bits in an integer. The Type classes SubclassData field is used to
store the number of bits. This allows 2^23 bits in an integer type.
2. Removes the five integer Type::TypeID values for the 1, 8, 16, 32 and
64-bit integers. These are replaced with just IntegerType which is not
a primitive any more.
3. Adjust the rest of LLVM to account for this change.
Note that while this incremental change lays the foundation for arbitrary
bit-width integers, LLVM has not yet been converted to actually deal with
them in any significant way. Most optimization passes, for example, will
still only deal with the byte-width integer types. Future increments
will rectify this situation.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33113 91177308-0d34-0410-b5e6-96231b3b80d8
2007-01-12 07:05:14 +00:00
|
|
|
break;
|
2002-12-24 00:01:05 +00:00
|
|
|
case Type::PointerTyID:
|
2004-07-18 00:41:27 +00:00
|
|
|
if (isa<ConstantPointerNull>(C))
|
2002-12-24 00:01:05 +00:00
|
|
|
Result.PointerVal = 0;
|
2004-07-18 00:41:27 +00:00
|
|
|
else if (const Function *F = dyn_cast<Function>(C))
|
|
|
|
Result = PTOGV(getPointerToFunctionOrStub(const_cast<Function*>(F)));
|
|
|
|
else if (const GlobalVariable* GV = dyn_cast<GlobalVariable>(C))
|
|
|
|
Result = PTOGV(getOrEmitGlobalVariable(const_cast<GlobalVariable*>(GV)));
|
|
|
|
else
|
2002-12-24 00:01:05 +00:00
|
|
|
assert(0 && "Unknown constant pointer type!");
|
|
|
|
break;
|
|
|
|
default:
|
2007-03-06 22:23:15 +00:00
|
|
|
cerr << "ERROR: Constant unimplemented for type: " << *C->getType() << "\n";
|
2003-04-23 19:01:49 +00:00
|
|
|
abort();
|
2002-12-24 00:01:05 +00:00
|
|
|
}
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
2007-12-14 19:38:31 +00:00
|
|
|
/// StoreIntToMemory - Fills the StoreBytes bytes of memory starting from Dst
|
|
|
|
/// with the integer held in IntVal.
|
|
|
|
static void StoreIntToMemory(const APInt &IntVal, uint8_t *Dst,
|
|
|
|
unsigned StoreBytes) {
|
|
|
|
assert((IntVal.getBitWidth()+7)/8 >= StoreBytes && "Integer too small!");
|
|
|
|
uint8_t *Src = (uint8_t *)IntVal.getRawData();
|
|
|
|
|
|
|
|
if (sys::littleEndianHost())
|
|
|
|
// Little-endian host - the source is ordered from LSB to MSB. Order the
|
|
|
|
// destination from LSB to MSB: Do a straight copy.
|
|
|
|
memcpy(Dst, Src, StoreBytes);
|
|
|
|
else {
|
|
|
|
// Big-endian host - the source is an array of 64 bit words ordered from
|
|
|
|
// LSW to MSW. Each word is ordered from MSB to LSB. Order the destination
|
|
|
|
// from MSB to LSB: Reverse the word order, but not the bytes in a word.
|
|
|
|
while (StoreBytes > sizeof(uint64_t)) {
|
|
|
|
StoreBytes -= sizeof(uint64_t);
|
|
|
|
// May not be aligned so use memcpy.
|
|
|
|
memcpy(Dst + StoreBytes, Src, sizeof(uint64_t));
|
|
|
|
Src += sizeof(uint64_t);
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(Dst, Src + sizeof(uint64_t) - StoreBytes, StoreBytes);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-04-22 18:53:45 +00:00
|
|
|
/// StoreValueToMemory - Stores the data in Val of type Ty at address Ptr. Ptr
|
|
|
|
/// is the address of the memory at which to store Val, cast to GenericValue *.
|
|
|
|
/// It is not a pointer to a GenericValue containing the address at which to
|
|
|
|
/// store Val.
|
2007-03-06 05:03:16 +00:00
|
|
|
void ExecutionEngine::StoreValueToMemory(const GenericValue &Val, GenericValue *Ptr,
|
2003-10-10 17:45:12 +00:00
|
|
|
const Type *Ty) {
|
2007-12-14 19:38:31 +00:00
|
|
|
const unsigned StoreBytes = getTargetData()->getTypeStoreSize(Ty);
|
2007-12-10 17:43:13 +00:00
|
|
|
|
2007-12-14 19:38:31 +00:00
|
|
|
switch (Ty->getTypeID()) {
|
|
|
|
case Type::IntegerTyID:
|
|
|
|
StoreIntToMemory(Val.IntVal, (uint8_t*)Ptr, StoreBytes);
|
2007-03-06 03:04:04 +00:00
|
|
|
break;
|
|
|
|
case Type::FloatTyID:
|
|
|
|
*((float*)Ptr) = Val.FloatVal;
|
|
|
|
break;
|
|
|
|
case Type::DoubleTyID:
|
|
|
|
*((double*)Ptr) = Val.DoubleVal;
|
|
|
|
break;
|
2007-09-17 18:44:13 +00:00
|
|
|
case Type::X86_FP80TyID: {
|
|
|
|
uint16_t *Dest = (uint16_t*)Ptr;
|
|
|
|
const uint16_t *Src = (uint16_t*)Val.IntVal.getRawData();
|
|
|
|
// This is endian dependent, but it will only work on x86 anyway.
|
|
|
|
Dest[0] = Src[4];
|
|
|
|
Dest[1] = Src[0];
|
|
|
|
Dest[2] = Src[1];
|
|
|
|
Dest[3] = Src[2];
|
|
|
|
Dest[4] = Src[3];
|
|
|
|
break;
|
|
|
|
}
|
2007-12-14 19:38:31 +00:00
|
|
|
case Type::PointerTyID:
|
|
|
|
// Ensure 64 bit target pointers are fully initialized on 32 bit hosts.
|
|
|
|
if (StoreBytes != sizeof(PointerTy))
|
|
|
|
memset(Ptr, 0, StoreBytes);
|
|
|
|
|
2007-03-06 03:04:04 +00:00
|
|
|
*((PointerTy*)Ptr) = Val.PointerVal;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
cerr << "Cannot store value of type " << *Ty << "!\n";
|
2002-12-24 00:01:05 +00:00
|
|
|
}
|
2007-12-14 19:38:31 +00:00
|
|
|
|
|
|
|
if (sys::littleEndianHost() != getTargetData()->isLittleEndian())
|
|
|
|
// Host and target are different endian - reverse the stored bytes.
|
|
|
|
std::reverse((uint8_t*)Ptr, StoreBytes + (uint8_t*)Ptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// LoadIntFromMemory - Loads the integer stored in the LoadBytes bytes starting
|
|
|
|
/// from Src into IntVal, which is assumed to be wide enough and to hold zero.
|
|
|
|
static void LoadIntFromMemory(APInt &IntVal, uint8_t *Src, unsigned LoadBytes) {
|
|
|
|
assert((IntVal.getBitWidth()+7)/8 >= LoadBytes && "Integer too small!");
|
|
|
|
uint8_t *Dst = (uint8_t *)IntVal.getRawData();
|
|
|
|
|
|
|
|
if (sys::littleEndianHost())
|
|
|
|
// Little-endian host - the destination must be ordered from LSB to MSB.
|
|
|
|
// The source is ordered from LSB to MSB: Do a straight copy.
|
|
|
|
memcpy(Dst, Src, LoadBytes);
|
|
|
|
else {
|
|
|
|
// Big-endian - the destination is an array of 64 bit words ordered from
|
|
|
|
// LSW to MSW. Each word must be ordered from MSB to LSB. The source is
|
|
|
|
// ordered from MSB to LSB: Reverse the word order, but not the bytes in
|
|
|
|
// a word.
|
|
|
|
while (LoadBytes > sizeof(uint64_t)) {
|
|
|
|
LoadBytes -= sizeof(uint64_t);
|
|
|
|
// May not be aligned so use memcpy.
|
|
|
|
memcpy(Dst, Src + LoadBytes, sizeof(uint64_t));
|
|
|
|
Dst += sizeof(uint64_t);
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(Dst + sizeof(uint64_t) - LoadBytes, Src, LoadBytes);
|
|
|
|
}
|
2002-12-24 00:01:05 +00:00
|
|
|
}
|
|
|
|
|
2003-10-10 17:45:12 +00:00
|
|
|
/// FIXME: document
|
|
|
|
///
|
2007-12-14 19:38:31 +00:00
|
|
|
void ExecutionEngine::LoadValueFromMemory(GenericValue &Result,
|
2008-03-10 16:38:37 +00:00
|
|
|
GenericValue *Ptr,
|
|
|
|
const Type *Ty) {
|
2007-12-14 19:38:31 +00:00
|
|
|
const unsigned LoadBytes = getTargetData()->getTypeStoreSize(Ty);
|
|
|
|
|
|
|
|
if (sys::littleEndianHost() != getTargetData()->isLittleEndian()) {
|
|
|
|
// Host and target are different endian - reverse copy the stored
|
|
|
|
// bytes into a buffer, and load from that.
|
|
|
|
uint8_t *Src = (uint8_t*)Ptr;
|
|
|
|
uint8_t *Buf = (uint8_t*)alloca(LoadBytes);
|
|
|
|
std::reverse_copy(Src, Src + LoadBytes, Buf);
|
|
|
|
Ptr = (GenericValue*)Buf;
|
|
|
|
}
|
2007-12-10 17:43:13 +00:00
|
|
|
|
2007-12-14 19:38:31 +00:00
|
|
|
switch (Ty->getTypeID()) {
|
|
|
|
case Type::IntegerTyID:
|
2007-12-10 17:43:13 +00:00
|
|
|
// An APInt with all words initially zero.
|
2007-12-14 19:38:31 +00:00
|
|
|
Result.IntVal = APInt(cast<IntegerType>(Ty)->getBitWidth(), 0);
|
|
|
|
LoadIntFromMemory(Result.IntVal, (uint8_t*)Ptr, LoadBytes);
|
2007-03-06 03:04:04 +00:00
|
|
|
break;
|
|
|
|
case Type::FloatTyID:
|
|
|
|
Result.FloatVal = *((float*)Ptr);
|
|
|
|
break;
|
|
|
|
case Type::DoubleTyID:
|
2007-12-14 19:38:31 +00:00
|
|
|
Result.DoubleVal = *((double*)Ptr);
|
2007-03-06 03:04:04 +00:00
|
|
|
break;
|
2007-12-14 19:38:31 +00:00
|
|
|
case Type::PointerTyID:
|
2007-03-06 03:04:04 +00:00
|
|
|
Result.PointerVal = *((PointerTy*)Ptr);
|
|
|
|
break;
|
2007-09-17 18:44:13 +00:00
|
|
|
case Type::X86_FP80TyID: {
|
|
|
|
// This is endian dependent, but it will only work on x86 anyway.
|
2007-12-15 17:37:40 +00:00
|
|
|
// FIXME: Will not trap if loading a signaling NaN.
|
2007-11-28 10:36:19 +00:00
|
|
|
uint16_t *p = (uint16_t*)Ptr;
|
|
|
|
union {
|
|
|
|
uint16_t x[8];
|
|
|
|
uint64_t y[2];
|
|
|
|
};
|
2007-09-17 18:44:13 +00:00
|
|
|
x[0] = p[1];
|
|
|
|
x[1] = p[2];
|
|
|
|
x[2] = p[3];
|
|
|
|
x[3] = p[4];
|
|
|
|
x[4] = p[0];
|
2007-11-28 10:36:19 +00:00
|
|
|
Result.IntVal = APInt(80, 2, y);
|
2007-09-17 18:44:13 +00:00
|
|
|
break;
|
|
|
|
}
|
2007-03-06 03:04:04 +00:00
|
|
|
default:
|
|
|
|
cerr << "Cannot load value of type " << *Ty << "!\n";
|
|
|
|
abort();
|
2003-05-08 16:52:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-12-24 00:01:05 +00:00
|
|
|
// InitializeMemory - Recursive function to apply a Constant value into the
|
|
|
|
// specified memory location...
|
|
|
|
//
|
|
|
|
void ExecutionEngine::InitializeMemory(const Constant *Init, void *Addr) {
|
2008-08-07 01:30:15 +00:00
|
|
|
DOUT << "Initializing " << Addr;
|
|
|
|
DEBUG(Init->dump());
|
2004-10-16 18:19:26 +00:00
|
|
|
if (isa<UndefValue>(Init)) {
|
|
|
|
return;
|
2007-02-15 02:26:10 +00:00
|
|
|
} else if (const ConstantVector *CP = dyn_cast<ConstantVector>(Init)) {
|
2006-01-20 18:18:40 +00:00
|
|
|
unsigned ElementSize =
|
Executive summary: getTypeSize -> getTypeStoreSize / getABITypeSize.
The meaning of getTypeSize was not clear - clarifying it is important
now that we have x86 long double and arbitrary precision integers.
The issue with long double is that it requires 80 bits, and this is
not a multiple of its alignment. This gives a primitive type for
which getTypeSize differed from getABITypeSize. For arbitrary precision
integers it is even worse: there is the minimum number of bits needed to
hold the type (eg: 36 for an i36), the maximum number of bits that will
be overwriten when storing the type (40 bits for i36) and the ABI size
(i.e. the storage size rounded up to a multiple of the alignment; 64 bits
for i36).
This patch removes getTypeSize (not really - it is still there but
deprecated to allow for a gradual transition). Instead there is:
(1) getTypeSizeInBits - a number of bits that suffices to hold all
values of the type. For a primitive type, this is the minimum number
of bits. For an i36 this is 36 bits. For x86 long double it is 80.
This corresponds to gcc's TYPE_PRECISION.
(2) getTypeStoreSizeInBits - the maximum number of bits that is
written when storing the type (or read when reading it). For an
i36 this is 40 bits, for an x86 long double it is 80 bits. This
is the size alias analysis is interested in (getTypeStoreSize
returns the number of bytes). There doesn't seem to be anything
corresponding to this in gcc.
(3) getABITypeSizeInBits - this is getTypeStoreSizeInBits rounded
up to a multiple of the alignment. For an i36 this is 64, for an
x86 long double this is 96 or 128 depending on the OS. This is the
spacing between consecutive elements when you form an array out of
this type (getABITypeSize returns the number of bytes). This is
TYPE_SIZE in gcc.
Since successive elements in a SequentialType (arrays, pointers
and vectors) need to be aligned, the spacing between them will be
given by getABITypeSize. This means that the size of an array
is the length times the getABITypeSize. It also means that GEP
computations need to use getABITypeSize when computing offsets.
Furthermore, if an alloca allocates several elements at once then
these too need to be aligned, so the size of the alloca has to be
the number of elements multiplied by getABITypeSize. Logically
speaking this doesn't have to be the case when allocating just
one element, but it is simpler to also use getABITypeSize in this
case. So alloca's and mallocs should use getABITypeSize. Finally,
since gcc's only notion of size is that given by getABITypeSize, if
you want to output assembler etc the same as gcc then getABITypeSize
is the size you want.
Since a store will overwrite no more than getTypeStoreSize bytes,
and a read will read no more than that many bytes, this is the
notion of size appropriate for alias analysis calculations.
In this patch I have corrected all type size uses except some of
those in ScalarReplAggregates, lib/Codegen, lib/Target (the hard
cases). I will get around to auditing these too at some point,
but I could do with some help.
Finally, I made one change which I think wise but others might
consider pointless and suboptimal: in an unpacked struct the
amount of space allocated for a field is now given by the ABI
size rather than getTypeStoreSize. I did this because every
other place that reserves memory for a type (eg: alloca) now
uses getABITypeSize, and I didn't want to make an exception
for unpacked structs, i.e. I did it to make things more uniform.
This only effects structs containing long doubles and arbitrary
precision integers. If someone wants to pack these types more
tightly they can always use a packed struct.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43620 91177308-0d34-0410-b5e6-96231b3b80d8
2007-11-01 20:53:16 +00:00
|
|
|
getTargetData()->getABITypeSize(CP->getType()->getElementType());
|
2006-01-20 18:18:40 +00:00
|
|
|
for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i)
|
|
|
|
InitializeMemory(CP->getOperand(i), (char*)Addr+i*ElementSize);
|
|
|
|
return;
|
2008-02-15 00:57:28 +00:00
|
|
|
} else if (isa<ConstantAggregateZero>(Init)) {
|
|
|
|
memset(Addr, 0, (size_t)getTargetData()->getABITypeSize(Init->getType()));
|
|
|
|
return;
|
2008-05-20 03:20:09 +00:00
|
|
|
} else if (const ConstantArray *CPA = dyn_cast<ConstantArray>(Init)) {
|
2005-04-21 22:36:52 +00:00
|
|
|
unsigned ElementSize =
|
Executive summary: getTypeSize -> getTypeStoreSize / getABITypeSize.
The meaning of getTypeSize was not clear - clarifying it is important
now that we have x86 long double and arbitrary precision integers.
The issue with long double is that it requires 80 bits, and this is
not a multiple of its alignment. This gives a primitive type for
which getTypeSize differed from getABITypeSize. For arbitrary precision
integers it is even worse: there is the minimum number of bits needed to
hold the type (eg: 36 for an i36), the maximum number of bits that will
be overwriten when storing the type (40 bits for i36) and the ABI size
(i.e. the storage size rounded up to a multiple of the alignment; 64 bits
for i36).
This patch removes getTypeSize (not really - it is still there but
deprecated to allow for a gradual transition). Instead there is:
(1) getTypeSizeInBits - a number of bits that suffices to hold all
values of the type. For a primitive type, this is the minimum number
of bits. For an i36 this is 36 bits. For x86 long double it is 80.
This corresponds to gcc's TYPE_PRECISION.
(2) getTypeStoreSizeInBits - the maximum number of bits that is
written when storing the type (or read when reading it). For an
i36 this is 40 bits, for an x86 long double it is 80 bits. This
is the size alias analysis is interested in (getTypeStoreSize
returns the number of bytes). There doesn't seem to be anything
corresponding to this in gcc.
(3) getABITypeSizeInBits - this is getTypeStoreSizeInBits rounded
up to a multiple of the alignment. For an i36 this is 64, for an
x86 long double this is 96 or 128 depending on the OS. This is the
spacing between consecutive elements when you form an array out of
this type (getABITypeSize returns the number of bytes). This is
TYPE_SIZE in gcc.
Since successive elements in a SequentialType (arrays, pointers
and vectors) need to be aligned, the spacing between them will be
given by getABITypeSize. This means that the size of an array
is the length times the getABITypeSize. It also means that GEP
computations need to use getABITypeSize when computing offsets.
Furthermore, if an alloca allocates several elements at once then
these too need to be aligned, so the size of the alloca has to be
the number of elements multiplied by getABITypeSize. Logically
speaking this doesn't have to be the case when allocating just
one element, but it is simpler to also use getABITypeSize in this
case. So alloca's and mallocs should use getABITypeSize. Finally,
since gcc's only notion of size is that given by getABITypeSize, if
you want to output assembler etc the same as gcc then getABITypeSize
is the size you want.
Since a store will overwrite no more than getTypeStoreSize bytes,
and a read will read no more than that many bytes, this is the
notion of size appropriate for alias analysis calculations.
In this patch I have corrected all type size uses except some of
those in ScalarReplAggregates, lib/Codegen, lib/Target (the hard
cases). I will get around to auditing these too at some point,
but I could do with some help.
Finally, I made one change which I think wise but others might
consider pointless and suboptimal: in an unpacked struct the
amount of space allocated for a field is now given by the ABI
size rather than getTypeStoreSize. I did this because every
other place that reserves memory for a type (eg: alloca) now
uses getABITypeSize, and I didn't want to make an exception
for unpacked structs, i.e. I did it to make things more uniform.
This only effects structs containing long doubles and arbitrary
precision integers. If someone wants to pack these types more
tightly they can always use a packed struct.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43620 91177308-0d34-0410-b5e6-96231b3b80d8
2007-11-01 20:53:16 +00:00
|
|
|
getTargetData()->getABITypeSize(CPA->getType()->getElementType());
|
2004-08-04 08:44:43 +00:00
|
|
|
for (unsigned i = 0, e = CPA->getNumOperands(); i != e; ++i)
|
|
|
|
InitializeMemory(CPA->getOperand(i), (char*)Addr+i*ElementSize);
|
2002-12-24 00:01:05 +00:00
|
|
|
return;
|
2008-05-20 03:20:09 +00:00
|
|
|
} else if (const ConstantStruct *CPS = dyn_cast<ConstantStruct>(Init)) {
|
2002-12-24 00:01:05 +00:00
|
|
|
const StructLayout *SL =
|
2006-05-03 01:29:57 +00:00
|
|
|
getTargetData()->getStructLayout(cast<StructType>(CPS->getType()));
|
2004-08-04 08:44:43 +00:00
|
|
|
for (unsigned i = 0, e = CPS->getNumOperands(); i != e; ++i)
|
2007-02-10 19:55:17 +00:00
|
|
|
InitializeMemory(CPS->getOperand(i), (char*)Addr+SL->getElementOffset(i));
|
2002-12-24 00:01:05 +00:00
|
|
|
return;
|
2008-05-20 03:20:09 +00:00
|
|
|
} else if (Init->getType()->isFirstClassType()) {
|
|
|
|
GenericValue Val = getConstantValue(Init);
|
|
|
|
StoreValueToMemory(Val, (GenericValue*)Addr, Init->getType());
|
|
|
|
return;
|
2002-12-24 00:01:05 +00:00
|
|
|
}
|
|
|
|
|
2008-05-20 03:20:09 +00:00
|
|
|
cerr << "Bad Type: " << *Init->getType() << "\n";
|
|
|
|
assert(0 && "Unknown constant type to initialize memory with!");
|
2002-12-24 00:01:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// EmitGlobals - Emit all of the global variables to memory, storing their
|
|
|
|
/// addresses into GlobalAddress. This must make sure to copy the contents of
|
|
|
|
/// their initializers into the memory.
|
|
|
|
///
|
|
|
|
void ExecutionEngine::emitGlobals() {
|
2005-04-21 22:36:52 +00:00
|
|
|
|
2002-12-24 00:01:05 +00:00
|
|
|
// Loop over all of the global variables in the program, allocating the memory
|
2006-08-16 01:24:12 +00:00
|
|
|
// to hold them. If there is more than one module, do a prepass over globals
|
|
|
|
// to figure out how the different modules should link together.
|
|
|
|
//
|
|
|
|
std::map<std::pair<std::string, const Type*>,
|
|
|
|
const GlobalValue*> LinkedGlobalsMap;
|
|
|
|
|
|
|
|
if (Modules.size() != 1) {
|
|
|
|
for (unsigned m = 0, e = Modules.size(); m != e; ++m) {
|
|
|
|
Module &M = *Modules[m]->getModule();
|
|
|
|
for (Module::const_global_iterator I = M.global_begin(),
|
|
|
|
E = M.global_end(); I != E; ++I) {
|
|
|
|
const GlobalValue *GV = I;
|
2007-01-30 20:08:39 +00:00
|
|
|
if (GV->hasInternalLinkage() || GV->isDeclaration() ||
|
2006-08-16 01:24:12 +00:00
|
|
|
GV->hasAppendingLinkage() || !GV->hasName())
|
|
|
|
continue;// Ignore external globals and globals with internal linkage.
|
|
|
|
|
|
|
|
const GlobalValue *&GVEntry =
|
|
|
|
LinkedGlobalsMap[std::make_pair(GV->getName(), GV->getType())];
|
|
|
|
|
|
|
|
// If this is the first time we've seen this global, it is the canonical
|
|
|
|
// version.
|
|
|
|
if (!GVEntry) {
|
|
|
|
GVEntry = GV;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the existing global is strong, never replace it.
|
2006-09-14 18:23:27 +00:00
|
|
|
if (GVEntry->hasExternalLinkage() ||
|
|
|
|
GVEntry->hasDLLImportLinkage() ||
|
|
|
|
GVEntry->hasDLLExportLinkage())
|
2006-08-16 01:24:12 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
// Otherwise, we know it's linkonce/weak, replace it if this is a strong
|
2008-05-14 20:12:51 +00:00
|
|
|
// symbol. FIXME is this right for common?
|
2006-12-01 00:25:12 +00:00
|
|
|
if (GV->hasExternalLinkage() || GVEntry->hasExternalWeakLinkage())
|
2006-08-16 01:24:12 +00:00
|
|
|
GVEntry = GV;
|
2003-04-23 19:01:49 +00:00
|
|
|
}
|
2002-12-24 00:01:05 +00:00
|
|
|
}
|
2006-08-16 01:24:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<const GlobalValue*> NonCanonicalGlobals;
|
|
|
|
for (unsigned m = 0, e = Modules.size(); m != e; ++m) {
|
|
|
|
Module &M = *Modules[m]->getModule();
|
|
|
|
for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
|
|
|
|
I != E; ++I) {
|
|
|
|
// In the multi-module case, see what this global maps to.
|
|
|
|
if (!LinkedGlobalsMap.empty()) {
|
|
|
|
if (const GlobalValue *GVEntry =
|
|
|
|
LinkedGlobalsMap[std::make_pair(I->getName(), I->getType())]) {
|
|
|
|
// If something else is the canonical global, ignore this one.
|
|
|
|
if (GVEntry != &*I) {
|
|
|
|
NonCanonicalGlobals.push_back(I);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-01-30 20:08:39 +00:00
|
|
|
if (!I->isDeclaration()) {
|
2008-10-25 15:41:43 +00:00
|
|
|
addGlobalMapping(I, getMemoryForGV(I));
|
2006-08-16 01:24:12 +00:00
|
|
|
} else {
|
|
|
|
// External variable reference. Try to use the dynamic loader to
|
|
|
|
// get a pointer to it.
|
|
|
|
if (void *SymAddr =
|
|
|
|
sys::DynamicLibrary::SearchForAddressOfSymbol(I->getName().c_str()))
|
|
|
|
addGlobalMapping(I, SymAddr);
|
|
|
|
else {
|
2006-12-07 01:30:32 +00:00
|
|
|
cerr << "Could not resolve external global address: "
|
|
|
|
<< I->getName() << "\n";
|
2006-08-16 01:24:12 +00:00
|
|
|
abort();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If there are multiple modules, map the non-canonical globals to their
|
|
|
|
// canonical location.
|
|
|
|
if (!NonCanonicalGlobals.empty()) {
|
|
|
|
for (unsigned i = 0, e = NonCanonicalGlobals.size(); i != e; ++i) {
|
|
|
|
const GlobalValue *GV = NonCanonicalGlobals[i];
|
|
|
|
const GlobalValue *CGV =
|
|
|
|
LinkedGlobalsMap[std::make_pair(GV->getName(), GV->getType())];
|
|
|
|
void *Ptr = getPointerToGlobalIfAvailable(CGV);
|
|
|
|
assert(Ptr && "Canonical global wasn't codegen'd!");
|
2008-10-14 10:04:52 +00:00
|
|
|
addGlobalMapping(GV, Ptr);
|
2006-08-16 01:24:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
For PR1064:
Implement the arbitrary bit-width integer feature. The feature allows
integers of any bitwidth (up to 64) to be defined instead of just 1, 8,
16, 32, and 64 bit integers.
This change does several things:
1. Introduces a new Derived Type, IntegerType, to represent the number of
bits in an integer. The Type classes SubclassData field is used to
store the number of bits. This allows 2^23 bits in an integer type.
2. Removes the five integer Type::TypeID values for the 1, 8, 16, 32 and
64-bit integers. These are replaced with just IntegerType which is not
a primitive any more.
3. Adjust the rest of LLVM to account for this change.
Note that while this incremental change lays the foundation for arbitrary
bit-width integers, LLVM has not yet been converted to actually deal with
them in any significant way. Most optimization passes, for example, will
still only deal with the byte-width integer types. Future increments
will rectify this situation.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33113 91177308-0d34-0410-b5e6-96231b3b80d8
2007-01-12 07:05:14 +00:00
|
|
|
// Now that all of the globals are set up in memory, loop through them all
|
|
|
|
// and initialize their contents.
|
2006-08-16 01:24:12 +00:00
|
|
|
for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
|
|
|
|
I != E; ++I) {
|
2007-01-30 20:08:39 +00:00
|
|
|
if (!I->isDeclaration()) {
|
2006-08-16 01:24:12 +00:00
|
|
|
if (!LinkedGlobalsMap.empty()) {
|
|
|
|
if (const GlobalValue *GVEntry =
|
|
|
|
LinkedGlobalsMap[std::make_pair(I->getName(), I->getType())])
|
|
|
|
if (GVEntry != &*I) // Not the canonical variable.
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
EmitGlobalVariable(I);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-12-20 02:45:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// EmitGlobalVariable - This method emits the specified global variable to the
|
|
|
|
// address specified in GlobalAddresses, or allocates new memory if it's not
|
|
|
|
// already in the map.
|
2003-12-20 03:36:47 +00:00
|
|
|
void ExecutionEngine::EmitGlobalVariable(const GlobalVariable *GV) {
|
2003-12-31 20:21:04 +00:00
|
|
|
void *GA = getPointerToGlobalIfAvailable(GV);
|
2006-11-27 23:54:50 +00:00
|
|
|
DOUT << "Global '" << GV->getName() << "' -> " << GA << "\n";
|
2004-02-08 19:33:23 +00:00
|
|
|
|
2003-12-20 02:45:37 +00:00
|
|
|
if (GA == 0) {
|
|
|
|
// If it's not already specified, allocate memory for the global.
|
2008-10-25 15:41:43 +00:00
|
|
|
GA = getMemoryForGV(GV);
|
2003-12-31 20:21:04 +00:00
|
|
|
addGlobalMapping(GV, GA);
|
2003-12-20 02:45:37 +00:00
|
|
|
}
|
2008-10-25 15:41:43 +00:00
|
|
|
|
|
|
|
// Don't initialize if it's thread local, let the client do it.
|
|
|
|
if (!GV->isThreadLocal())
|
|
|
|
InitializeMemory(GV->getInitializer(), GA);
|
|
|
|
|
|
|
|
const Type *ElTy = GV->getType()->getElementType();
|
|
|
|
size_t GVSize = (size_t)getTargetData()->getABITypeSize(ElTy);
|
2005-01-08 20:13:19 +00:00
|
|
|
NumInitBytes += (unsigned)GVSize;
|
2003-12-20 02:45:37 +00:00
|
|
|
++NumGlobals;
|
2002-12-24 00:01:05 +00:00
|
|
|
}
|