1188ede28SSunho Kim #include "llvm/ExecutionEngine/Orc/ReOptimizeLayer.h" 2188ede28SSunho Kim #include "OrcTestCommon.h" 3188ede28SSunho Kim #include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h" 4*dc11c060SLang Hames #include "llvm/ExecutionEngine/Orc/AbsoluteSymbols.h" 5188ede28SSunho Kim #include "llvm/ExecutionEngine/Orc/CompileUtils.h" 6188ede28SSunho Kim #include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h" 7188ede28SSunho Kim #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" 8188ede28SSunho Kim #include "llvm/ExecutionEngine/Orc/IRPartitionLayer.h" 9188ede28SSunho Kim #include "llvm/ExecutionEngine/Orc/IRTransformLayer.h" 10188ede28SSunho Kim #include "llvm/ExecutionEngine/Orc/JITLinkRedirectableSymbolManager.h" 11188ede28SSunho Kim #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h" 12188ede28SSunho Kim #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" 13188ede28SSunho Kim #include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h" 14188ede28SSunho Kim #include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h" 15188ede28SSunho Kim #include "llvm/IR/IRBuilder.h" 16188ede28SSunho Kim #include "llvm/Support/CodeGen.h" 17188ede28SSunho Kim #include "llvm/TargetParser/Host.h" 18188ede28SSunho Kim #include "llvm/Testing/Support/Error.h" 19188ede28SSunho Kim #include "gtest/gtest.h" 20188ede28SSunho Kim 21188ede28SSunho Kim using namespace llvm; 22188ede28SSunho Kim using namespace llvm::orc; 23188ede28SSunho Kim using namespace llvm::jitlink; 24188ede28SSunho Kim 25188ede28SSunho Kim class ReOptimizeLayerTest : public testing::Test { 26188ede28SSunho Kim public: 27188ede28SSunho Kim ~ReOptimizeLayerTest() { 28188ede28SSunho Kim if (ES) 29188ede28SSunho Kim if (auto Err = ES->endSession()) 30188ede28SSunho Kim ES->reportError(std::move(Err)); 31188ede28SSunho Kim } 32188ede28SSunho Kim 33188ede28SSunho Kim protected: 34188ede28SSunho Kim void SetUp() override { 35188ede28SSunho Kim auto JTMB = JITTargetMachineBuilder::detectHost(); 36188ede28SSunho Kim // Bail out if we can not detect the host. 37188ede28SSunho Kim if (!JTMB) { 38188ede28SSunho Kim consumeError(JTMB.takeError()); 39188ede28SSunho Kim GTEST_SKIP(); 40188ede28SSunho Kim } 41188ede28SSunho Kim 42e5f7e73dSSunho Kim // COFF-ARM64 is not supported yet 43e5f7e73dSSunho Kim auto Triple = JTMB->getTargetTriple(); 44e5f7e73dSSunho Kim if (Triple.isOSBinFormatCOFF() && Triple.isAArch64()) 45e5f7e73dSSunho Kim GTEST_SKIP(); 46e5f7e73dSSunho Kim 479b7be3ebSTom Stellard // SystemZ is not supported yet. 489b7be3ebSTom Stellard if (Triple.isSystemZ()) 499b7be3ebSTom Stellard GTEST_SKIP(); 509b7be3ebSTom Stellard 51beb7fb9dSTom Stellard // 32-bit X86 is not supported yet. 52beb7fb9dSTom Stellard if (Triple.isX86() && Triple.isArch32Bit()) 53beb7fb9dSTom Stellard GTEST_SKIP(); 54beb7fb9dSTom Stellard 5539aae575SSunho Kim if (Triple.isPPC()) 5639aae575SSunho Kim GTEST_SKIP(); 5739aae575SSunho Kim 58188ede28SSunho Kim auto EPC = SelfExecutorProcessControl::Create(); 59188ede28SSunho Kim if (!EPC) { 60188ede28SSunho Kim consumeError(EPC.takeError()); 61188ede28SSunho Kim GTEST_SKIP(); 62188ede28SSunho Kim } 637fea5c03SSunho Kim 647fea5c03SSunho Kim auto DLOrErr = JTMB->getDefaultDataLayoutForTarget(); 657fea5c03SSunho Kim if (!DLOrErr) { 667fea5c03SSunho Kim consumeError(DLOrErr.takeError()); 677fea5c03SSunho Kim GTEST_SKIP(); 687fea5c03SSunho Kim } 69188ede28SSunho Kim ES = std::make_unique<ExecutionSession>(std::move(*EPC)); 70188ede28SSunho Kim JD = &ES->createBareJITDylib("main"); 71188ede28SSunho Kim ObjLinkingLayer = std::make_unique<ObjectLinkingLayer>( 72188ede28SSunho Kim *ES, std::make_unique<InProcessMemoryManager>(16384)); 737fea5c03SSunho Kim DL = std::make_unique<DataLayout>(std::move(*DLOrErr)); 74188ede28SSunho Kim 75188ede28SSunho Kim auto TM = JTMB->createTargetMachine(); 76188ede28SSunho Kim if (!TM) { 77188ede28SSunho Kim consumeError(TM.takeError()); 78188ede28SSunho Kim GTEST_SKIP(); 79188ede28SSunho Kim } 80188ede28SSunho Kim auto CompileFunction = 81188ede28SSunho Kim std::make_unique<TMOwningSimpleCompiler>(std::move(*TM)); 82188ede28SSunho Kim CompileLayer = std::make_unique<IRCompileLayer>(*ES, *ObjLinkingLayer, 83188ede28SSunho Kim std::move(CompileFunction)); 84188ede28SSunho Kim } 85188ede28SSunho Kim 86188ede28SSunho Kim Error addIRModule(ResourceTrackerSP RT, ThreadSafeModule TSM) { 87188ede28SSunho Kim assert(TSM && "Can not add null module"); 88188ede28SSunho Kim 89188ede28SSunho Kim TSM.withModuleDo([&](Module &M) { M.setDataLayout(*DL); }); 90188ede28SSunho Kim 91188ede28SSunho Kim return ROLayer->add(std::move(RT), std::move(TSM)); 92188ede28SSunho Kim } 93188ede28SSunho Kim 94188ede28SSunho Kim JITDylib *JD{nullptr}; 95188ede28SSunho Kim std::unique_ptr<ExecutionSession> ES; 96188ede28SSunho Kim std::unique_ptr<ObjectLinkingLayer> ObjLinkingLayer; 97188ede28SSunho Kim std::unique_ptr<IRCompileLayer> CompileLayer; 98188ede28SSunho Kim std::unique_ptr<ReOptimizeLayer> ROLayer; 99188ede28SSunho Kim std::unique_ptr<DataLayout> DL; 100188ede28SSunho Kim }; 101188ede28SSunho Kim 102188ede28SSunho Kim static Function *createRetFunction(Module *M, StringRef Name, 103188ede28SSunho Kim uint32_t ReturnCode) { 104188ede28SSunho Kim Function *Result = Function::Create( 105188ede28SSunho Kim FunctionType::get(Type::getInt32Ty(M->getContext()), {}, false), 106188ede28SSunho Kim GlobalValue::ExternalLinkage, Name, M); 107188ede28SSunho Kim 108188ede28SSunho Kim BasicBlock *BB = BasicBlock::Create(M->getContext(), Name, Result); 109188ede28SSunho Kim IRBuilder<> Builder(M->getContext()); 110188ede28SSunho Kim Builder.SetInsertPoint(BB); 111188ede28SSunho Kim 112188ede28SSunho Kim Value *RetValue = ConstantInt::get(M->getContext(), APInt(32, ReturnCode)); 113188ede28SSunho Kim Builder.CreateRet(RetValue); 114188ede28SSunho Kim return Result; 115188ede28SSunho Kim } 116188ede28SSunho Kim 117188ede28SSunho Kim TEST_F(ReOptimizeLayerTest, BasicReOptimization) { 118188ede28SSunho Kim MangleAndInterner Mangle(*ES, *DL); 119188ede28SSunho Kim 120188ede28SSunho Kim auto &EPC = ES->getExecutorProcessControl(); 121188ede28SSunho Kim EXPECT_THAT_ERROR(JD->define(absoluteSymbols( 122188ede28SSunho Kim {{Mangle("__orc_rt_jit_dispatch"), 123188ede28SSunho Kim {EPC.getJITDispatchInfo().JITDispatchFunction, 124188ede28SSunho Kim JITSymbolFlags::Exported}}, 125188ede28SSunho Kim {Mangle("__orc_rt_jit_dispatch_ctx"), 126188ede28SSunho Kim {EPC.getJITDispatchInfo().JITDispatchContext, 127188ede28SSunho Kim JITSymbolFlags::Exported}}, 128188ede28SSunho Kim {Mangle("__orc_rt_reoptimize_tag"), 129188ede28SSunho Kim {ExecutorAddr(), JITSymbolFlags::Exported}}})), 130188ede28SSunho Kim Succeeded()); 131188ede28SSunho Kim 132529c0913SLang Hames auto RM = JITLinkRedirectableSymbolManager::Create(*ObjLinkingLayer); 133188ede28SSunho Kim EXPECT_THAT_ERROR(RM.takeError(), Succeeded()); 134188ede28SSunho Kim 135188ede28SSunho Kim ROLayer = std::make_unique<ReOptimizeLayer>(*ES, *DL, *CompileLayer, **RM); 136188ede28SSunho Kim ROLayer->setReoptimizeFunc( 137188ede28SSunho Kim [&](ReOptimizeLayer &Parent, 138188ede28SSunho Kim ReOptimizeLayer::ReOptMaterializationUnitID MUID, unsigned CurVerison, 139188ede28SSunho Kim ResourceTrackerSP OldRT, ThreadSafeModule &TSM) { 140188ede28SSunho Kim TSM.withModuleDo([&](Module &M) { 141188ede28SSunho Kim for (auto &F : M) { 142188ede28SSunho Kim if (F.isDeclaration()) 143188ede28SSunho Kim continue; 144188ede28SSunho Kim for (auto &B : F) { 145188ede28SSunho Kim for (auto &I : B) { 146188ede28SSunho Kim if (ReturnInst *Ret = dyn_cast<ReturnInst>(&I)) { 147188ede28SSunho Kim Value *RetValue = 148188ede28SSunho Kim ConstantInt::get(M.getContext(), APInt(32, 53)); 149188ede28SSunho Kim Ret->setOperand(0, RetValue); 150188ede28SSunho Kim } 151188ede28SSunho Kim } 152188ede28SSunho Kim } 153188ede28SSunho Kim } 154188ede28SSunho Kim }); 155188ede28SSunho Kim return Error::success(); 156188ede28SSunho Kim }); 157188ede28SSunho Kim EXPECT_THAT_ERROR(ROLayer->reigsterRuntimeFunctions(*JD), Succeeded()); 158188ede28SSunho Kim 159188ede28SSunho Kim ThreadSafeContext Ctx(std::make_unique<LLVMContext>()); 160188ede28SSunho Kim auto M = std::make_unique<Module>("<main>", *Ctx.getContext()); 161188ede28SSunho Kim M->setTargetTriple(sys::getProcessTriple()); 162188ede28SSunho Kim 163188ede28SSunho Kim (void)createRetFunction(M.get(), "main", 42); 164188ede28SSunho Kim 165188ede28SSunho Kim EXPECT_THAT_ERROR(addIRModule(JD->getDefaultResourceTracker(), 166188ede28SSunho Kim ThreadSafeModule(std::move(M), std::move(Ctx))), 167188ede28SSunho Kim Succeeded()); 168188ede28SSunho Kim 169188ede28SSunho Kim auto Result = cantFail(ES->lookup({JD}, Mangle("main"))); 170188ede28SSunho Kim auto FuncPtr = Result.getAddress().toPtr<int (*)()>(); 171188ede28SSunho Kim for (size_t I = 0; I <= ReOptimizeLayer::CallCountThreshold; I++) 172188ede28SSunho Kim EXPECT_EQ(FuncPtr(), 42); 173188ede28SSunho Kim EXPECT_EQ(FuncPtr(), 53); 174188ede28SSunho Kim } 175