[DAGCombiner] Expand combining of FP logical ops to sign-setting FP ops
[llvm-core.git] / unittests / ExecutionEngine / Orc / RemoteObjectLayerTest.cpp
blobae408a06f84d71273c58acf060490e95c8a00a0d
1 //===---------------------- RemoteObjectLayerTest.cpp ---------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
10 #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
11 #include "llvm/ExecutionEngine/Orc/NullResolver.h"
12 #include "llvm/ExecutionEngine/Orc/RemoteObjectLayer.h"
13 #include "OrcTestCommon.h"
14 #include "QueueChannel.h"
15 #include "gtest/gtest.h"
17 using namespace llvm;
18 using namespace llvm::orc;
20 namespace {
22 class MockObjectLayer {
23 public:
25 using ObjHandleT = uint64_t;
27 using ObjectPtr = std::unique_ptr<MemoryBuffer>;
29 using LookupFn = std::function<JITSymbol(StringRef, bool)>;
30 using SymbolLookupTable = std::map<ObjHandleT, LookupFn>;
32 using AddObjectFtor =
33 std::function<Expected<ObjHandleT>(ObjectPtr, SymbolLookupTable&)>;
35 class ObjectNotFound : public remote::ResourceNotFound<ObjHandleT> {
36 public:
37 ObjectNotFound(ObjHandleT H) : ResourceNotFound(H, "Object handle") {}
40 MockObjectLayer(AddObjectFtor AddObject)
41 : AddObject(std::move(AddObject)) {}
43 Expected<ObjHandleT> addObject(ObjectPtr Obj,
44 std::shared_ptr<JITSymbolResolver> Resolver) {
45 return AddObject(std::move(Obj), SymTab);
48 Error removeObject(ObjHandleT H) {
49 if (SymTab.count(H))
50 return Error::success();
51 else
52 return make_error<ObjectNotFound>(H);
55 JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
56 for (auto KV : SymTab) {
57 if (auto Sym = KV.second(Name, ExportedSymbolsOnly))
58 return Sym;
59 else if (auto Err = Sym.takeError())
60 return std::move(Err);
62 return JITSymbol(nullptr);
65 JITSymbol findSymbolIn(ObjHandleT H, StringRef Name,
66 bool ExportedSymbolsOnly) {
67 auto LI = SymTab.find(H);
68 if (LI != SymTab.end())
69 return LI->second(Name, ExportedSymbolsOnly);
70 else
71 return make_error<ObjectNotFound>(H);
74 Error emitAndFinalize(ObjHandleT H) {
75 if (SymTab.count(H))
76 return Error::success();
77 else
78 return make_error<ObjectNotFound>(H);
81 private:
82 AddObjectFtor AddObject;
83 SymbolLookupTable SymTab;
86 using RPCEndpoint = rpc::SingleThreadedRPCEndpoint<rpc::RawByteChannel>;
88 MockObjectLayer::ObjectPtr createTestObject() {
89 OrcNativeTarget::initialize();
90 auto TM = std::unique_ptr<TargetMachine>(EngineBuilder().selectTarget());
92 if (!TM)
93 return nullptr;
95 LLVMContext Ctx;
96 ModuleBuilder MB(Ctx, TM->getTargetTriple().str(), "TestModule");
97 MB.getModule()->setDataLayout(TM->createDataLayout());
98 auto *Main = MB.createFunctionDecl<void(int, char**)>("main");
99 Main->getBasicBlockList().push_back(BasicBlock::Create(Ctx));
100 IRBuilder<> B(&Main->back());
101 B.CreateRet(ConstantInt::getSigned(Type::getInt32Ty(Ctx), 42));
103 SimpleCompiler IRCompiler(*TM);
104 return IRCompiler(*MB.getModule());
107 TEST(RemoteObjectLayer, AddObject) {
108 llvm::orc::rpc::registerStringError<rpc::RawByteChannel>();
109 auto TestObject = createTestObject();
110 if (!TestObject)
111 return;
113 auto Channels = createPairedQueueChannels();
115 auto ReportError =
116 [](Error Err) {
117 logAllUnhandledErrors(std::move(Err), llvm::errs(), "");
120 // Copy the bytes out of the test object: the copy will be used to verify
121 // that the original is correctly transmitted over RPC to the mock layer.
122 StringRef ObjBytes = TestObject->getBuffer();
123 std::vector<char> ObjContents(ObjBytes.size());
124 std::copy(ObjBytes.begin(), ObjBytes.end(), ObjContents.begin());
126 RPCEndpoint ClientEP(*Channels.first, true);
127 RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);
129 RPCEndpoint ServerEP(*Channels.second, true);
130 MockObjectLayer BaseLayer(
131 [&ObjContents](MockObjectLayer::ObjectPtr Obj,
132 MockObjectLayer::SymbolLookupTable &SymTab) {
134 // Check that the received object file content matches the original.
135 StringRef RPCObjContents = Obj->getBuffer();
136 EXPECT_EQ(RPCObjContents.size(), ObjContents.size())
137 << "RPC'd object file has incorrect size";
138 EXPECT_TRUE(std::equal(RPCObjContents.begin(), RPCObjContents.end(),
139 ObjContents.begin()))
140 << "RPC'd object file content does not match original content";
142 return 1;
144 RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
145 ServerEP,
146 ReportError);
148 bool Finished = false;
149 ServerEP.addHandler<remote::utils::TerminateSession>(
150 [&]() { Finished = true; }
153 auto ServerThread =
154 std::thread([&]() {
155 while (!Finished)
156 cantFail(ServerEP.handleOne());
159 cantFail(Client.addObject(std::move(TestObject),
160 std::make_shared<NullLegacyResolver>()));
161 cantFail(ClientEP.callB<remote::utils::TerminateSession>());
162 ServerThread.join();
165 TEST(RemoteObjectLayer, AddObjectFailure) {
166 llvm::orc::rpc::registerStringError<rpc::RawByteChannel>();
167 auto TestObject = createTestObject();
168 if (!TestObject)
169 return;
171 auto Channels = createPairedQueueChannels();
173 auto ReportError =
174 [](Error Err) {
175 auto ErrMsg = toString(std::move(Err));
176 EXPECT_EQ(ErrMsg, "AddObjectFailure - Test Message")
177 << "Expected error string to be \"AddObjectFailure - Test Message\"";
180 RPCEndpoint ClientEP(*Channels.first, true);
181 RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);
183 RPCEndpoint ServerEP(*Channels.second, true);
184 MockObjectLayer BaseLayer(
185 [](MockObjectLayer::ObjectPtr Obj,
186 MockObjectLayer::SymbolLookupTable &SymTab)
187 -> Expected<MockObjectLayer::ObjHandleT> {
188 return make_error<StringError>("AddObjectFailure - Test Message",
189 inconvertibleErrorCode());
191 RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
192 ServerEP,
193 ReportError);
195 bool Finished = false;
196 ServerEP.addHandler<remote::utils::TerminateSession>(
197 [&]() { Finished = true; }
200 auto ServerThread =
201 std::thread([&]() {
202 while (!Finished)
203 cantFail(ServerEP.handleOne());
206 auto HandleOrErr = Client.addObject(std::move(TestObject),
207 std::make_shared<NullLegacyResolver>());
209 EXPECT_FALSE(HandleOrErr) << "Expected error from addObject";
211 auto ErrMsg = toString(HandleOrErr.takeError());
212 EXPECT_EQ(ErrMsg, "AddObjectFailure - Test Message")
213 << "Expected error string to be \"AddObjectFailure - Test Message\"";
215 cantFail(ClientEP.callB<remote::utils::TerminateSession>());
216 ServerThread.join();
220 TEST(RemoteObjectLayer, RemoveObject) {
221 llvm::orc::rpc::registerStringError<rpc::RawByteChannel>();
222 auto TestObject = createTestObject();
223 if (!TestObject)
224 return;
226 auto Channels = createPairedQueueChannels();
228 auto ReportError =
229 [](Error Err) {
230 logAllUnhandledErrors(std::move(Err), llvm::errs(), "");
233 RPCEndpoint ClientEP(*Channels.first, true);
234 RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);
236 RPCEndpoint ServerEP(*Channels.second, true);
238 MockObjectLayer BaseLayer(
239 [](MockObjectLayer::ObjectPtr Obj,
240 MockObjectLayer::SymbolLookupTable &SymTab) {
241 SymTab[1] = MockObjectLayer::LookupFn();
242 return 1;
244 RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
245 ServerEP,
246 ReportError);
248 bool Finished = false;
249 ServerEP.addHandler<remote::utils::TerminateSession>(
250 [&]() { Finished = true; }
253 auto ServerThread =
254 std::thread([&]() {
255 while (!Finished)
256 cantFail(ServerEP.handleOne());
259 auto H = cantFail(Client.addObject(std::move(TestObject),
260 std::make_shared<NullLegacyResolver>()));
262 cantFail(Client.removeObject(H));
264 cantFail(ClientEP.callB<remote::utils::TerminateSession>());
265 ServerThread.join();
268 TEST(RemoteObjectLayer, RemoveObjectFailure) {
269 llvm::orc::rpc::registerStringError<rpc::RawByteChannel>();
270 auto TestObject = createTestObject();
271 if (!TestObject)
272 return;
274 auto Channels = createPairedQueueChannels();
276 auto ReportError =
277 [](Error Err) {
278 auto ErrMsg = toString(std::move(Err));
279 EXPECT_EQ(ErrMsg, "Object handle 42 not found")
280 << "Expected error string to be \"Object handle 42 not found\"";
283 RPCEndpoint ClientEP(*Channels.first, true);
284 RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);
286 RPCEndpoint ServerEP(*Channels.second, true);
288 // AddObject lambda does not update symbol table, so removeObject will treat
289 // this as a bad object handle.
290 MockObjectLayer BaseLayer(
291 [](MockObjectLayer::ObjectPtr Obj,
292 MockObjectLayer::SymbolLookupTable &SymTab) {
293 return 42;
295 RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
296 ServerEP,
297 ReportError);
299 bool Finished = false;
300 ServerEP.addHandler<remote::utils::TerminateSession>(
301 [&]() { Finished = true; }
304 auto ServerThread =
305 std::thread([&]() {
306 while (!Finished)
307 cantFail(ServerEP.handleOne());
310 auto H = cantFail(Client.addObject(std::move(TestObject),
311 std::make_shared<NullLegacyResolver>()));
313 auto Err = Client.removeObject(H);
314 EXPECT_TRUE(!!Err) << "Expected error from removeObject";
316 auto ErrMsg = toString(std::move(Err));
317 EXPECT_EQ(ErrMsg, "Object handle 42 not found")
318 << "Expected error string to be \"Object handle 42 not found\"";
320 cantFail(ClientEP.callB<remote::utils::TerminateSession>());
321 ServerThread.join();
324 TEST(RemoteObjectLayer, FindSymbol) {
325 llvm::orc::rpc::registerStringError<rpc::RawByteChannel>();
326 auto TestObject = createTestObject();
327 if (!TestObject)
328 return;
330 auto Channels = createPairedQueueChannels();
332 auto ReportError =
333 [](Error Err) {
334 auto ErrMsg = toString(std::move(Err));
335 EXPECT_EQ(ErrMsg, "Could not find symbol 'badsymbol'")
336 << "Expected error string to be \"Object handle 42 not found\"";
339 RPCEndpoint ClientEP(*Channels.first, true);
340 RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);
342 RPCEndpoint ServerEP(*Channels.second, true);
344 // AddObject lambda does not update symbol table, so removeObject will treat
345 // this as a bad object handle.
346 MockObjectLayer BaseLayer(
347 [](MockObjectLayer::ObjectPtr Obj,
348 MockObjectLayer::SymbolLookupTable &SymTab) {
349 SymTab[42] =
350 [](StringRef Name, bool ExportedSymbolsOnly) -> JITSymbol {
351 if (Name == "foobar")
352 return JITSymbol(0x12348765, JITSymbolFlags::Exported);
353 if (Name == "badsymbol")
354 return make_error<JITSymbolNotFound>(Name);
355 return nullptr;
357 return 42;
359 RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
360 ServerEP,
361 ReportError);
363 bool Finished = false;
364 ServerEP.addHandler<remote::utils::TerminateSession>(
365 [&]() { Finished = true; }
368 auto ServerThread =
369 std::thread([&]() {
370 while (!Finished)
371 cantFail(ServerEP.handleOne());
374 cantFail(Client.addObject(std::move(TestObject),
375 std::make_shared<NullLegacyResolver>()));
377 // Check that we can find and materialize a valid symbol.
378 auto Sym1 = Client.findSymbol("foobar", true);
379 EXPECT_TRUE(!!Sym1) << "Symbol 'foobar' should be findable";
380 EXPECT_EQ(cantFail(Sym1.getAddress()), 0x12348765ULL)
381 << "Symbol 'foobar' does not return the correct address";
384 // Check that we can return a symbol containing an error.
385 auto Sym2 = Client.findSymbol("badsymbol", true);
386 EXPECT_FALSE(!!Sym2) << "Symbol 'badsymbol' should not be findable";
387 auto Err = Sym2.takeError();
388 EXPECT_TRUE(!!Err) << "Sym2 should contain an error value";
389 auto ErrMsg = toString(std::move(Err));
390 EXPECT_EQ(ErrMsg, "Could not find symbol 'badsymbol'")
391 << "Expected symbol-not-found error for Sym2";
395 // Check that we can return a 'null' symbol.
396 auto Sym3 = Client.findSymbol("baz", true);
397 EXPECT_FALSE(!!Sym3) << "Symbol 'baz' should convert to false";
398 auto Err = Sym3.takeError();
399 EXPECT_FALSE(!!Err) << "Symbol 'baz' should not contain an error";
402 cantFail(ClientEP.callB<remote::utils::TerminateSession>());
403 ServerThread.join();
406 TEST(RemoteObjectLayer, FindSymbolIn) {
407 llvm::orc::rpc::registerStringError<rpc::RawByteChannel>();
408 auto TestObject = createTestObject();
409 if (!TestObject)
410 return;
412 auto Channels = createPairedQueueChannels();
414 auto ReportError =
415 [](Error Err) {
416 auto ErrMsg = toString(std::move(Err));
417 EXPECT_EQ(ErrMsg, "Could not find symbol 'barbaz'")
418 << "Expected error string to be \"Object handle 42 not found\"";
421 RPCEndpoint ClientEP(*Channels.first, true);
422 RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);
424 RPCEndpoint ServerEP(*Channels.second, true);
426 // AddObject lambda does not update symbol table, so removeObject will treat
427 // this as a bad object handle.
428 MockObjectLayer BaseLayer(
429 [](MockObjectLayer::ObjectPtr Obj,
430 MockObjectLayer::SymbolLookupTable &SymTab) {
431 SymTab[42] =
432 [](StringRef Name, bool ExportedSymbolsOnly) -> JITSymbol {
433 if (Name == "foobar")
434 return JITSymbol(0x12348765, JITSymbolFlags::Exported);
435 return make_error<JITSymbolNotFound>(Name);
437 // Dummy symbol table entry - this should not be visible to
438 // findSymbolIn.
439 SymTab[43] =
440 [](StringRef Name, bool ExportedSymbolsOnly) -> JITSymbol {
441 if (Name == "barbaz")
442 return JITSymbol(0xdeadbeef, JITSymbolFlags::Exported);
443 return make_error<JITSymbolNotFound>(Name);
446 return 42;
448 RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
449 ServerEP,
450 ReportError);
452 bool Finished = false;
453 ServerEP.addHandler<remote::utils::TerminateSession>(
454 [&]() { Finished = true; }
457 auto ServerThread =
458 std::thread([&]() {
459 while (!Finished)
460 cantFail(ServerEP.handleOne());
463 auto H = cantFail(Client.addObject(std::move(TestObject),
464 std::make_shared<NullLegacyResolver>()));
466 auto Sym1 = Client.findSymbolIn(H, "foobar", true);
468 EXPECT_TRUE(!!Sym1) << "Symbol 'foobar' should be findable";
469 EXPECT_EQ(cantFail(Sym1.getAddress()), 0x12348765ULL)
470 << "Symbol 'foobar' does not return the correct address";
472 auto Sym2 = Client.findSymbolIn(H, "barbaz", true);
473 EXPECT_FALSE(!!Sym2) << "Symbol 'barbaz' should not be findable";
474 auto Err = Sym2.takeError();
475 EXPECT_TRUE(!!Err) << "Sym2 should contain an error value";
476 auto ErrMsg = toString(std::move(Err));
477 EXPECT_EQ(ErrMsg, "Could not find symbol 'barbaz'")
478 << "Expected symbol-not-found error for Sym2";
480 cantFail(ClientEP.callB<remote::utils::TerminateSession>());
481 ServerThread.join();
484 TEST(RemoteObjectLayer, EmitAndFinalize) {
485 llvm::orc::rpc::registerStringError<rpc::RawByteChannel>();
486 auto TestObject = createTestObject();
487 if (!TestObject)
488 return;
490 auto Channels = createPairedQueueChannels();
492 auto ReportError =
493 [](Error Err) {
494 logAllUnhandledErrors(std::move(Err), llvm::errs(), "");
497 RPCEndpoint ClientEP(*Channels.first, true);
498 RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);
500 RPCEndpoint ServerEP(*Channels.second, true);
502 MockObjectLayer BaseLayer(
503 [](MockObjectLayer::ObjectPtr Obj,
504 MockObjectLayer::SymbolLookupTable &SymTab) {
505 SymTab[1] = MockObjectLayer::LookupFn();
506 return 1;
508 RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
509 ServerEP,
510 ReportError);
512 bool Finished = false;
513 ServerEP.addHandler<remote::utils::TerminateSession>(
514 [&]() { Finished = true; }
517 auto ServerThread =
518 std::thread([&]() {
519 while (!Finished)
520 cantFail(ServerEP.handleOne());
523 auto H = cantFail(Client.addObject(std::move(TestObject),
524 std::make_shared<NullLegacyResolver>()));
526 auto Err = Client.emitAndFinalize(H);
527 EXPECT_FALSE(!!Err) << "emitAndFinalize should work";
529 cantFail(ClientEP.callB<remote::utils::TerminateSession>());
530 ServerThread.join();
533 TEST(RemoteObjectLayer, EmitAndFinalizeFailure) {
534 llvm::orc::rpc::registerStringError<rpc::RawByteChannel>();
535 auto TestObject = createTestObject();
536 if (!TestObject)
537 return;
539 auto Channels = createPairedQueueChannels();
541 auto ReportError =
542 [](Error Err) {
543 auto ErrMsg = toString(std::move(Err));
544 EXPECT_EQ(ErrMsg, "Object handle 1 not found")
545 << "Expected bad handle error";
548 RPCEndpoint ClientEP(*Channels.first, true);
549 RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);
551 RPCEndpoint ServerEP(*Channels.second, true);
553 MockObjectLayer BaseLayer(
554 [](MockObjectLayer::ObjectPtr Obj,
555 MockObjectLayer::SymbolLookupTable &SymTab) {
556 return 1;
558 RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
559 ServerEP,
560 ReportError);
562 bool Finished = false;
563 ServerEP.addHandler<remote::utils::TerminateSession>(
564 [&]() { Finished = true; }
567 auto ServerThread =
568 std::thread([&]() {
569 while (!Finished)
570 cantFail(ServerEP.handleOne());
573 auto H = cantFail(Client.addObject(std::move(TestObject),
574 std::make_shared<NullLegacyResolver>()));
576 auto Err = Client.emitAndFinalize(H);
577 EXPECT_TRUE(!!Err) << "emitAndFinalize should work";
579 auto ErrMsg = toString(std::move(Err));
580 EXPECT_EQ(ErrMsg, "Object handle 1 not found")
581 << "emitAndFinalize returned incorrect error";
583 cantFail(ClientEP.callB<remote::utils::TerminateSession>());
584 ServerThread.join();