aboutsummaryrefslogtreecommitdiffstats
path: root/unittests
diff options
context:
space:
mode:
authorJeffrey Yasskin <jyasskin@google.com>2009-12-22 23:47:23 +0000
committerJeffrey Yasskin <jyasskin@google.com>2009-12-22 23:47:23 +0000
commitc5818fb83750259f23f70e91ee9fb9b11d67160d (patch)
tree1d3b225a256beb93ab8489dc6ec22413296cbc9e /unittests
parent3dbcb55b40e3916d538fb6e21ba1662dc82c8fa6 (diff)
downloadexternal_llvm-c5818fb83750259f23f70e91ee9fb9b11d67160d.zip
external_llvm-c5818fb83750259f23f70e91ee9fb9b11d67160d.tar.gz
external_llvm-c5818fb83750259f23f70e91ee9fb9b11d67160d.tar.bz2
Partially revert r91626. Materializing extra functions to determine whether
they're available_externally broke VMKit, which was relying on the fact that functions would only be materialized when they were first called. We'll have to wait for http://llvm.org/PR5737 to really fix this. I also added a test for one of the F->isDeclaration() calls which wasn't covered by anything else in the test suite. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@91943 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'unittests')
-rw-r--r--unittests/ExecutionEngine/JIT/JITTest.cpp102
-rw-r--r--unittests/ExecutionEngine/JIT/Makefile2
2 files changed, 97 insertions, 7 deletions
diff --git a/unittests/ExecutionEngine/JIT/JITTest.cpp b/unittests/ExecutionEngine/JIT/JITTest.cpp
index c6c26c7..de30dda 100644
--- a/unittests/ExecutionEngine/JIT/JITTest.cpp
+++ b/unittests/ExecutionEngine/JIT/JITTest.cpp
@@ -12,6 +12,7 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Assembly/Parser.h"
#include "llvm/BasicBlock.h"
+#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/Constant.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
@@ -24,6 +25,7 @@
#include "llvm/Module.h"
#include "llvm/ModuleProvider.h"
#include "llvm/Support/IRBuilder.h"
+#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TypeBuilder.h"
#include "llvm/Target/TargetSelect.h"
@@ -177,6 +179,17 @@ public:
}
};
+bool LoadAssemblyInto(Module *M, const char *assembly) {
+ SMDiagnostic Error;
+ bool success =
+ NULL != ParseAssemblyString(assembly, M, Error, M->getContext());
+ std::string errMsg;
+ raw_string_ostream os(errMsg);
+ Error.Print("", os);
+ EXPECT_TRUE(success) << os.str();
+ return success;
+}
+
class JITTest : public testing::Test {
protected:
virtual void SetUp() {
@@ -192,12 +205,7 @@ class JITTest : public testing::Test {
}
void LoadAssembly(const char *assembly) {
- SMDiagnostic Error;
- bool success = NULL != ParseAssemblyString(assembly, M, Error, Context);
- std::string errMsg;
- raw_string_ostream os(errMsg);
- Error.Print("", os);
- ASSERT_TRUE(success) << os.str();
+ LoadAssemblyInto(M, assembly);
}
LLVMContext Context;
@@ -619,6 +627,88 @@ TEST_F(JITTest, AvailableExternallyFunctionIsntCompiled) {
<< " not 7 from the IR version.";
}
+// Converts the LLVM assembly to bitcode and returns it in a std::string. An
+// empty string indicates an error.
+std::string AssembleToBitcode(LLVMContext &Context, const char *Assembly) {
+ Module TempModule("TempModule", Context);
+ if (!LoadAssemblyInto(&TempModule, Assembly)) {
+ return "";
+ }
+
+ std::string Result;
+ raw_string_ostream OS(Result);
+ WriteBitcodeToFile(&TempModule, OS);
+ OS.flush();
+ return Result;
+}
+
+// Returns a newly-created ExecutionEngine that reads the bitcode in 'Bitcode'
+// lazily. The associated ModuleProvider (owned by the ExecutionEngine) is
+// returned in MP. Both will be NULL on an error. Bitcode must live at least
+// as long as the ExecutionEngine.
+ExecutionEngine *getJITFromBitcode(
+ LLVMContext &Context, const std::string &Bitcode, ModuleProvider *&MP) {
+ // c_str() is null-terminated like MemoryBuffer::getMemBuffer requires.
+ MemoryBuffer *BitcodeBuffer =
+ MemoryBuffer::getMemBuffer(Bitcode.c_str(),
+ Bitcode.c_str() + Bitcode.size(),
+ "Bitcode for test");
+ std::string errMsg;
+ MP = getBitcodeModuleProvider(BitcodeBuffer, Context, &errMsg);
+ if (MP == NULL) {
+ ADD_FAILURE() << errMsg;
+ delete BitcodeBuffer;
+ return NULL;
+ }
+ ExecutionEngine *TheJIT = EngineBuilder(MP)
+ .setEngineKind(EngineKind::JIT)
+ .setErrorStr(&errMsg)
+ .create();
+ if (TheJIT == NULL) {
+ ADD_FAILURE() << errMsg;
+ delete MP;
+ MP = NULL;
+ return NULL;
+ }
+ return TheJIT;
+}
+
+TEST(LazyLoadedJITTest, EagerCompiledRecursionThroughGhost) {
+ LLVMContext Context;
+ const std::string Bitcode =
+ AssembleToBitcode(Context,
+ "define i32 @recur1(i32 %a) { "
+ " %zero = icmp eq i32 %a, 0 "
+ " br i1 %zero, label %done, label %notdone "
+ "done: "
+ " ret i32 3 "
+ "notdone: "
+ " %am1 = sub i32 %a, 1 "
+ " %result = call i32 @recur2(i32 %am1) "
+ " ret i32 %result "
+ "} "
+ " "
+ "define i32 @recur2(i32 %b) { "
+ " %result = call i32 @recur1(i32 %b) "
+ " ret i32 %result "
+ "} ");
+ ASSERT_FALSE(Bitcode.empty()) << "Assembling failed";
+ ModuleProvider *MP;
+ OwningPtr<ExecutionEngine> TheJIT(getJITFromBitcode(Context, Bitcode, MP));
+ ASSERT_TRUE(TheJIT.get()) << "Failed to create JIT.";
+ TheJIT->DisableLazyCompilation(true);
+
+ Module *M = MP->getModule();
+ Function *recur1IR = M->getFunction("recur1");
+ Function *recur2IR = M->getFunction("recur2");
+ EXPECT_TRUE(recur1IR->hasNotBeenReadFromBitcode());
+ EXPECT_TRUE(recur2IR->hasNotBeenReadFromBitcode());
+
+ int32_t (*recur1)(int32_t) = reinterpret_cast<int32_t(*)(int32_t)>(
+ (intptr_t)TheJIT->getPointerToFunction(recur1IR));
+ EXPECT_EQ(3, recur1(4));
+}
+
// This code is copied from JITEventListenerTest, but it only runs once for all
// the tests in this directory. Everything seems fine, but that's strange
// behavior.
diff --git a/unittests/ExecutionEngine/JIT/Makefile b/unittests/ExecutionEngine/JIT/Makefile
index 8de390b..f5abe75 100644
--- a/unittests/ExecutionEngine/JIT/Makefile
+++ b/unittests/ExecutionEngine/JIT/Makefile
@@ -9,7 +9,7 @@
LEVEL = ../../..
TESTNAME = JIT
-LINK_COMPONENTS := asmparser core support jit native
+LINK_COMPONENTS := asmparser bitreader bitwriter core jit native support
include $(LEVEL)/Makefile.config
include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest