CallArgs.push_back(&A);
CallInst *Call = Builder.CreateCall(ImplAddr, CallArgs);
Call->setTailCall();
+ Call->setAttributes(F.getAttributes());
Builder.CreateRet(Call);
}
set(LLVM_LINK_COMPONENTS
Core
+ OrcJIT
Support
)
add_llvm_unittest(OrcJITTests
+ IndirectionUtilsTest.cpp
LazyEmittingLayerTest.cpp
+ OrcTestCommon.cpp
)
--- /dev/null
+//===- LazyEmittingLayerTest.cpp - Unit tests for the lazy emitting layer -===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "OrcTestCommon.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+TEST(IndirectionUtilsTest, MakeStub) {
+ ModuleBuilder MB(getGlobalContext(), "x86_64-apple-macosx10.10", "");
+ Function *F = MB.createFunctionDecl<void(DummyStruct, DummyStruct)>(MB.getModule(), "");
+ SmallVector<AttributeSet, 4> Attrs;
+ Attrs.push_back(
+ AttributeSet::get(MB.getModule()->getContext(), 1U,
+ AttrBuilder().addAttribute(Attribute::StructRet)));
+ Attrs.push_back(
+ AttributeSet::get(MB.getModule()->getContext(), 2U,
+ AttrBuilder().addAttribute(Attribute::ByVal)));
+ Attrs.push_back(
+ AttributeSet::get(MB.getModule()->getContext(), ~0U,
+ AttrBuilder().addAttribute(Attribute::NoUnwind)));
+ F->setAttributes(AttributeSet::get(MB.getModule()->getContext(), Attrs));
+
+ auto ImplPtr = orc::createImplPointer(*F->getType(), *MB.getModule(), "", nullptr);
+ orc::makeStub(*F, *ImplPtr);
+
+ auto II = F->getEntryBlock().begin();
+ EXPECT_TRUE(isa<LoadInst>(*II)) << "First instruction of stub should be a load.";
+ auto *Call = dyn_cast<CallInst>(std::next(II));
+ EXPECT_TRUE(Call != nullptr) << "Second instruction of stub should be a call.";
+ EXPECT_TRUE(Call->isTailCall()) << "Indirect call from stub should be tail call.";
+ EXPECT_TRUE(Call->hasStructRetAttr())
+ << "makeStub should propagate sret attr on 1st argument.";
+ EXPECT_TRUE(Call->paramHasAttr(2U, Attribute::ByVal))
+ << "makeStub should propagate byval attr on 2nd argument.";
+}
+
+}
--- /dev/null
+//===--------- OrcTestCommon.cpp - Utilities for Orc Unit Tests -----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Common utilities for Orc unit tests.
+//
+//===----------------------------------------------------------------------===//
+
+#include "OrcTestCommon.h"
+
+using namespace llvm;
+
+ModuleBuilder::ModuleBuilder(LLVMContext &Context, StringRef Triple,
+ StringRef Name)
+ : M(new Module(Name, Context)),
+ Builder(Context) {
+ M->setTargetTriple(Triple);
+}
--- /dev/null
+//===------ OrcTestCommon.h - Utilities for Orc Unit Tests ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Common utilities for the Orc unit tests.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_UNITTESTS_EXECUTIONENGINE_ORC_ORCTESTCOMMON_H
+#define LLVM_UNITTESTS_EXECUTIONENGINE_ORC_ORCTESTCOMMON_H
+
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/TypeBuilder.h"
+#include <memory>
+
+namespace llvm {
+
+ class ModuleBuilder {
+ public:
+ ModuleBuilder(LLVMContext &Context, StringRef Triple,
+ StringRef Name);
+
+ template <typename FuncType>
+ Function* createFunctionDecl(Module *M, StringRef Name) {
+ return Function::Create(
+ TypeBuilder<FuncType, false>::get(M->getContext()),
+ GlobalValue::ExternalLinkage, Name, M);
+ }
+
+ Module* getModule() { return M.get(); }
+ const Module* getModule() const { return M.get(); }
+ std::unique_ptr<Module> takeModule() { return std::move(M); }
+
+ private:
+ std::unique_ptr<Module> M;
+ IRBuilder<> Builder;
+ };
+
+ // Dummy struct type.
+ struct DummyStruct {
+ int X[256];
+ };
+
+ // TypeBuilder specialization for DummyStruct.
+ template <bool XCompile>
+ class TypeBuilder<DummyStruct, XCompile> {
+ public:
+ static StructType *get(LLVMContext &Context) {
+ return StructType::get(TypeBuilder<types::i<32>[256], XCompile>::get(Context), NULL);
+ }
+ };
+
+
+} // namespace llvm
+
+#endif