mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-25 16:24:23 +00:00
[MCJIT] Add a FindGlobalVariableNamed utility
Summary: This adds FindGlobalVariableNamed to ExecutionEngine (plus implementation in MCJIT), which is an analog of FindFunctionNamed for GlobalVariables. Reviewers: lhames Reviewed By: lhames Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D10421 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240202 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -197,11 +197,16 @@ public:
|
|||||||
/// M is found.
|
/// M is found.
|
||||||
virtual bool removeModule(Module *M);
|
virtual bool removeModule(Module *M);
|
||||||
|
|
||||||
/// FindFunctionNamed - Search all of the active modules to find the one that
|
/// FindFunctionNamed - Search all of the active modules to find the function that
|
||||||
/// defines FnName. This is very slow operation and shouldn't be used for
|
/// defines FnName. This is very slow operation and shouldn't be used for
|
||||||
/// general code.
|
/// general code.
|
||||||
virtual Function *FindFunctionNamed(const char *FnName);
|
virtual Function *FindFunctionNamed(const char *FnName);
|
||||||
|
|
||||||
|
/// FindGlobalVariableNamed - Search all of the active modules to find the global variable
|
||||||
|
/// that defines Name. This is very slow operation and shouldn't be used for
|
||||||
|
/// general code.
|
||||||
|
virtual GlobalVariable *FindGlobalVariableNamed(const char *Name, bool AllowInternal = false);
|
||||||
|
|
||||||
/// runFunction - Execute the specified function with the specified arguments,
|
/// runFunction - Execute the specified function with the specified arguments,
|
||||||
/// and return the result.
|
/// and return the result.
|
||||||
virtual GenericValue runFunction(Function *F,
|
virtual GenericValue runFunction(Function *F,
|
||||||
|
@ -153,6 +153,14 @@ Function *ExecutionEngine::FindFunctionNamed(const char *FnName) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GlobalVariable *ExecutionEngine::FindGlobalVariableNamed(const char *Name, bool AllowInternal) {
|
||||||
|
for (unsigned i = 0, e = Modules.size(); i != e; ++i) {
|
||||||
|
GlobalVariable *GV = Modules[i]->getGlobalVariable(Name,AllowInternal);
|
||||||
|
if (GV && !GV->isDeclaration())
|
||||||
|
return GV;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t ExecutionEngineState::RemoveMapping(StringRef Name) {
|
uint64_t ExecutionEngineState::RemoveMapping(StringRef Name) {
|
||||||
GlobalAddressMapTy::iterator I = GlobalAddressMap.find(Name);
|
GlobalAddressMapTy::iterator I = GlobalAddressMap.find(Name);
|
||||||
|
@ -429,6 +429,19 @@ Function *MCJIT::FindFunctionNamedInModulePtrSet(const char *FnName,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GlobalVariable *MCJIT::FindGlobalVariableNamedInModulePtrSet(const char *Name,
|
||||||
|
bool AllowInternal,
|
||||||
|
ModulePtrSet::iterator I,
|
||||||
|
ModulePtrSet::iterator E) {
|
||||||
|
for (; I != E; ++I) {
|
||||||
|
GlobalVariable *GV = (*I)->getGlobalVariable(Name, AllowInternal);
|
||||||
|
if (GV && !GV->isDeclaration())
|
||||||
|
return GV;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Function *MCJIT::FindFunctionNamed(const char *FnName) {
|
Function *MCJIT::FindFunctionNamed(const char *FnName) {
|
||||||
Function *F = FindFunctionNamedInModulePtrSet(
|
Function *F = FindFunctionNamedInModulePtrSet(
|
||||||
FnName, OwnedModules.begin_added(), OwnedModules.end_added());
|
FnName, OwnedModules.begin_added(), OwnedModules.end_added());
|
||||||
@ -441,6 +454,18 @@ Function *MCJIT::FindFunctionNamed(const char *FnName) {
|
|||||||
return F;
|
return F;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GlobalVariable *MCJIT::FindGlobalVariableNamed(const char *Name, bool AllowInternal) {
|
||||||
|
GlobalVariable *GV = FindGlobalVariableNamedInModulePtrSet(
|
||||||
|
Name, AllowInternal, OwnedModules.begin_added(), OwnedModules.end_added());
|
||||||
|
if (!GV)
|
||||||
|
GV = FindGlobalVariableNamedInModulePtrSet(Name, AllowInternal, OwnedModules.begin_loaded(),
|
||||||
|
OwnedModules.end_loaded());
|
||||||
|
if (!GV)
|
||||||
|
GV = FindGlobalVariableNamedInModulePtrSet(Name, AllowInternal, OwnedModules.begin_finalized(),
|
||||||
|
OwnedModules.end_finalized());
|
||||||
|
return GV;
|
||||||
|
}
|
||||||
|
|
||||||
GenericValue MCJIT::runFunction(Function *F, ArrayRef<GenericValue> ArgValues) {
|
GenericValue MCJIT::runFunction(Function *F, ArrayRef<GenericValue> ArgValues) {
|
||||||
assert(F && "Function *F was null at entry to run()");
|
assert(F && "Function *F was null at entry to run()");
|
||||||
|
|
||||||
|
@ -200,6 +200,11 @@ class MCJIT : public ExecutionEngine {
|
|||||||
ModulePtrSet::iterator I,
|
ModulePtrSet::iterator I,
|
||||||
ModulePtrSet::iterator E);
|
ModulePtrSet::iterator E);
|
||||||
|
|
||||||
|
GlobalVariable *FindGlobalVariableNamedInModulePtrSet(const char *Name,
|
||||||
|
bool AllowInternal,
|
||||||
|
ModulePtrSet::iterator I,
|
||||||
|
ModulePtrSet::iterator E);
|
||||||
|
|
||||||
void runStaticConstructorsDestructorsInModulePtrSet(bool isDtors,
|
void runStaticConstructorsDestructorsInModulePtrSet(bool isDtors,
|
||||||
ModulePtrSet::iterator I,
|
ModulePtrSet::iterator I,
|
||||||
ModulePtrSet::iterator E);
|
ModulePtrSet::iterator E);
|
||||||
@ -215,10 +220,15 @@ public:
|
|||||||
void addArchive(object::OwningBinary<object::Archive> O) override;
|
void addArchive(object::OwningBinary<object::Archive> O) override;
|
||||||
bool removeModule(Module *M) override;
|
bool removeModule(Module *M) override;
|
||||||
|
|
||||||
/// FindFunctionNamed - Search all of the active modules to find the one that
|
/// FindFunctionNamed - Search all of the active modules to find the function that
|
||||||
/// defines FnName. This is very slow operation and shouldn't be used for
|
/// defines FnName. This is very slow operation and shouldn't be used for
|
||||||
/// general code.
|
/// general code.
|
||||||
Function *FindFunctionNamed(const char *FnName) override;
|
virtual Function *FindFunctionNamed(const char *FnName) override;
|
||||||
|
|
||||||
|
/// FindGlobalVariableNamed - Search all of the active modules to find the global variable
|
||||||
|
/// that defines Name. This is very slow operation and shouldn't be used for
|
||||||
|
/// general code.
|
||||||
|
virtual GlobalVariable *FindGlobalVariableNamed(const char *Name, bool AllowInternal = false) override;
|
||||||
|
|
||||||
/// Sets the object manager that MCJIT should use to avoid compilation.
|
/// Sets the object manager that MCJIT should use to avoid compilation.
|
||||||
void setObjectCache(ObjectCache *manager) override;
|
void setObjectCache(ObjectCache *manager) override;
|
||||||
|
@ -194,14 +194,15 @@ TEST_F(MCJITMultipleModuleTest, two_module_consecutive_call_case) {
|
|||||||
|
|
||||||
|
|
||||||
// Module A { Global Variable GVA, Function FA loads GVA },
|
// Module A { Global Variable GVA, Function FA loads GVA },
|
||||||
// Module B { Global Variable GVB, Function FB loads GVB },
|
// Module B { Global Variable GVB, Internal Global GVC, Function FB loads GVB },
|
||||||
// execute FB then FA
|
// execute FB then FA, also check that the global variables are properly accesible
|
||||||
|
// through the ExecutionEngine APIs
|
||||||
TEST_F(MCJITMultipleModuleTest, two_module_global_variables_case) {
|
TEST_F(MCJITMultipleModuleTest, two_module_global_variables_case) {
|
||||||
SKIP_UNSUPPORTED_PLATFORM;
|
SKIP_UNSUPPORTED_PLATFORM;
|
||||||
|
|
||||||
std::unique_ptr<Module> A, B;
|
std::unique_ptr<Module> A, B;
|
||||||
Function *FA, *FB;
|
Function *FA, *FB;
|
||||||
GlobalVariable *GVA, *GVB;
|
GlobalVariable *GVA, *GVB, *GVC;
|
||||||
A.reset(createEmptyModule("A"));
|
A.reset(createEmptyModule("A"));
|
||||||
B.reset(createEmptyModule("B"));
|
B.reset(createEmptyModule("B"));
|
||||||
|
|
||||||
@ -213,9 +214,17 @@ TEST_F(MCJITMultipleModuleTest, two_module_global_variables_case) {
|
|||||||
FB = startFunction<int32_t(void)>(B.get(), "FB");
|
FB = startFunction<int32_t(void)>(B.get(), "FB");
|
||||||
endFunctionWithRet(FB, Builder.CreateLoad(GVB));
|
endFunctionWithRet(FB, Builder.CreateLoad(GVB));
|
||||||
|
|
||||||
|
GVC = insertGlobalInt32(B.get(), "GVC", initialNum);
|
||||||
|
GVC->setLinkage(GlobalValue::InternalLinkage);
|
||||||
|
|
||||||
createJIT(std::move(A));
|
createJIT(std::move(A));
|
||||||
TheJIT->addModule(std::move(B));
|
TheJIT->addModule(std::move(B));
|
||||||
|
|
||||||
|
EXPECT_EQ(GVA, TheJIT->FindGlobalVariableNamed("GVA"));
|
||||||
|
EXPECT_EQ(GVB, TheJIT->FindGlobalVariableNamed("GVB"));
|
||||||
|
EXPECT_EQ(GVC, TheJIT->FindGlobalVariableNamed("GVC",true));
|
||||||
|
EXPECT_EQ(NULL, TheJIT->FindGlobalVariableNamed("GVC"));
|
||||||
|
|
||||||
uint64_t FBPtr = TheJIT->getFunctionAddress(FB->getName().str());
|
uint64_t FBPtr = TheJIT->getFunctionAddress(FB->getName().str());
|
||||||
TheJIT->finalizeObject();
|
TheJIT->finalizeObject();
|
||||||
EXPECT_TRUE(0 != FBPtr);
|
EXPECT_TRUE(0 != FBPtr);
|
||||||
|
Reference in New Issue
Block a user