Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / unittests / ExecutionEngine / Orc / ObjectLinkingLayerTest.cpp
blob91659240c9d6dc118e156fc55f658bcb4b564f96
1 //===-------- ObjectLinkingLayerTest.cpp - ObjectLinkingLayer tests -------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
10 #include "llvm/ExecutionEngine/JITLink/JITLink.h"
11 #include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
12 #include "llvm/ExecutionEngine/JITLink/x86_64.h"
13 #include "llvm/Testing/Support/Error.h"
14 #include "gtest/gtest.h"
16 using namespace llvm;
17 using namespace llvm::jitlink;
18 using namespace llvm::orc;
20 namespace {
22 const char BlockContentBytes[] = {0x01, 0x02, 0x03, 0x04,
23 0x05, 0x06, 0x07, 0x08};
25 ArrayRef<char> BlockContent(BlockContentBytes);
27 class ObjectLinkingLayerTest : public testing::Test {
28 public:
29 ~ObjectLinkingLayerTest() {
30 if (auto Err = ES.endSession())
31 ES.reportError(std::move(Err));
34 protected:
35 ExecutionSession ES{std::make_unique<UnsupportedExecutorProcessControl>()};
36 JITDylib &JD = ES.createBareJITDylib("main");
37 ObjectLinkingLayer ObjLinkingLayer{
38 ES, std::make_unique<InProcessMemoryManager>(4096)};
41 TEST_F(ObjectLinkingLayerTest, AddLinkGraph) {
42 auto G = std::make_unique<LinkGraph>("foo", Triple("x86_64-apple-darwin"), 8,
43 llvm::endianness::little,
44 x86_64::getEdgeKindName);
46 auto &Sec1 = G->createSection("__data", MemProt::Read | MemProt::Write);
47 auto &B1 = G->createContentBlock(Sec1, BlockContent,
48 orc::ExecutorAddr(0x1000), 8, 0);
49 G->addDefinedSymbol(B1, 4, "_X", 4, Linkage::Strong, Scope::Default, false,
50 false);
51 G->addDefinedSymbol(B1, 4, "_Y", 4, Linkage::Weak, Scope::Default, false,
52 false);
53 G->addDefinedSymbol(B1, 4, "_Z", 4, Linkage::Strong, Scope::Hidden, false,
54 false);
55 G->addDefinedSymbol(B1, 4, "_W", 4, Linkage::Strong, Scope::Default, true,
56 false);
58 EXPECT_THAT_ERROR(ObjLinkingLayer.add(JD, std::move(G)), Succeeded());
60 EXPECT_THAT_EXPECTED(ES.lookup(&JD, "_X"), Succeeded());
63 TEST_F(ObjectLinkingLayerTest, ClaimLateDefinedWeakSymbols) {
64 // Check that claiming weak symbols works as expected.
66 // To do this we'll need a custom plugin to inject some new symbols during
67 // the link.
68 class TestPlugin : public ObjectLinkingLayer::Plugin {
69 public:
70 void modifyPassConfig(MaterializationResponsibility &MR,
71 jitlink::LinkGraph &G,
72 jitlink::PassConfiguration &Config) override {
73 Config.PrePrunePasses.insert(
74 Config.PrePrunePasses.begin(), [](LinkGraph &G) {
75 auto *DataSec = G.findSectionByName("__data");
76 auto &DataBlock = G.createContentBlock(
77 *DataSec, BlockContent, orc::ExecutorAddr(0x2000), 8, 0);
78 G.addDefinedSymbol(DataBlock, 4, "_x", 4, Linkage::Weak,
79 Scope::Default, false, false);
81 auto &TextSec =
82 G.createSection("__text", MemProt::Read | MemProt::Write);
83 auto &FuncBlock = G.createContentBlock(
84 TextSec, BlockContent, orc::ExecutorAddr(0x3000), 8, 0);
85 G.addDefinedSymbol(FuncBlock, 4, "_f", 4, Linkage::Weak,
86 Scope::Default, true, false);
88 return Error::success();
89 });
92 Error notifyFailed(MaterializationResponsibility &MR) override {
93 llvm_unreachable("unexpected error");
96 Error notifyRemovingResources(JITDylib &JD, ResourceKey K) override {
97 return Error::success();
99 void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey,
100 ResourceKey SrcKey) override {
101 llvm_unreachable("unexpected resource transfer");
105 ObjLinkingLayer.addPlugin(std::make_unique<TestPlugin>());
107 auto G = std::make_unique<LinkGraph>("foo", Triple("x86_64-apple-darwin"), 8,
108 llvm::endianness::little,
109 x86_64::getEdgeKindName);
111 auto &DataSec = G->createSection("__data", MemProt::Read | MemProt::Write);
112 auto &DataBlock = G->createContentBlock(DataSec, BlockContent,
113 orc::ExecutorAddr(0x1000), 8, 0);
114 G->addDefinedSymbol(DataBlock, 4, "_anchor", 4, Linkage::Weak, Scope::Default,
115 false, true);
117 EXPECT_THAT_ERROR(ObjLinkingLayer.add(JD, std::move(G)), Succeeded());
119 EXPECT_THAT_EXPECTED(ES.lookup(&JD, "_anchor"), Succeeded());
122 TEST_F(ObjectLinkingLayerTest, HandleErrorDuringPostAllocationPass) {
123 // We want to confirm that Errors in post allocation passes correctly
124 // abandon the in-flight allocation and report an error.
125 class TestPlugin : public ObjectLinkingLayer::Plugin {
126 public:
127 ~TestPlugin() { EXPECT_TRUE(ErrorReported); }
129 void modifyPassConfig(MaterializationResponsibility &MR,
130 jitlink::LinkGraph &G,
131 jitlink::PassConfiguration &Config) override {
132 Config.PostAllocationPasses.insert(
133 Config.PostAllocationPasses.begin(), [](LinkGraph &G) {
134 return make_error<StringError>("Kaboom", inconvertibleErrorCode());
138 Error notifyFailed(MaterializationResponsibility &MR) override {
139 ErrorReported = true;
140 return Error::success();
143 Error notifyRemovingResources(JITDylib &JD, ResourceKey K) override {
144 return Error::success();
146 void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey,
147 ResourceKey SrcKey) override {
148 llvm_unreachable("unexpected resource transfer");
151 private:
152 bool ErrorReported = false;
155 // We expect this test to generate errors. Consume them so that we don't
156 // add noise to the test logs.
157 ES.setErrorReporter(consumeError);
159 ObjLinkingLayer.addPlugin(std::make_unique<TestPlugin>());
161 auto G = std::make_unique<LinkGraph>("foo", Triple("x86_64-apple-darwin"), 8,
162 llvm::endianness::little,
163 x86_64::getEdgeKindName);
165 auto &DataSec = G->createSection("__data", MemProt::Read | MemProt::Write);
166 auto &DataBlock = G->createContentBlock(DataSec, BlockContent,
167 orc::ExecutorAddr(0x1000), 8, 0);
168 G->addDefinedSymbol(DataBlock, 4, "_anchor", 4, Linkage::Weak, Scope::Default,
169 false, true);
171 EXPECT_THAT_ERROR(ObjLinkingLayer.add(JD, std::move(G)), Succeeded());
173 EXPECT_THAT_EXPECTED(ES.lookup(&JD, "_anchor"), Failed());
176 } // end anonymous namespace