Path: blob/main/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/Layer.cpp
35266 views
//===-------------------- Layer.cpp - Layer interfaces --------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "llvm/ExecutionEngine/Orc/Layer.h"910#include "llvm/ExecutionEngine/Orc/DebugUtils.h"11#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"12#include "llvm/ExecutionEngine/Orc/ObjectFileInterface.h"13#include "llvm/IR/Constants.h"14#include "llvm/Support/Debug.h"1516#define DEBUG_TYPE "orc"1718namespace llvm {19namespace orc {2021IRLayer::~IRLayer() = default;2223Error IRLayer::add(ResourceTrackerSP RT, ThreadSafeModule TSM) {24assert(RT && "RT can not be null");25auto &JD = RT->getJITDylib();26return JD.define(std::make_unique<BasicIRLayerMaterializationUnit>(27*this, *getManglingOptions(), std::move(TSM)),28std::move(RT));29}3031IRMaterializationUnit::IRMaterializationUnit(32ExecutionSession &ES, const IRSymbolMapper::ManglingOptions &MO,33ThreadSafeModule TSM)34: MaterializationUnit(Interface()), TSM(std::move(TSM)) {3536assert(this->TSM && "Module must not be null");3738MangleAndInterner Mangle(ES, this->TSM.getModuleUnlocked()->getDataLayout());39this->TSM.withModuleDo([&](Module &M) {40for (auto &G : M.global_values()) {41// Skip globals that don't generate symbols.4243if (!G.hasName() || G.isDeclaration() || G.hasLocalLinkage() ||44G.hasAvailableExternallyLinkage() || G.hasAppendingLinkage())45continue;4647// thread locals generate different symbols depending on whether or not48// emulated TLS is enabled.49if (G.isThreadLocal() && MO.EmulatedTLS) {50auto &GV = cast<GlobalVariable>(G);5152auto Flags = JITSymbolFlags::fromGlobalValue(GV);5354auto EmuTLSV = Mangle(("__emutls_v." + GV.getName()).str());55SymbolFlags[EmuTLSV] = Flags;56SymbolToDefinition[EmuTLSV] = &GV;5758// If this GV has a non-zero initializer we'll need to emit an59// __emutls.t symbol too.60if (GV.hasInitializer()) {61const auto *InitVal = GV.getInitializer();6263// Skip zero-initializers.64if (isa<ConstantAggregateZero>(InitVal))65continue;66const auto *InitIntValue = dyn_cast<ConstantInt>(InitVal);67if (InitIntValue && InitIntValue->isZero())68continue;6970auto EmuTLST = Mangle(("__emutls_t." + GV.getName()).str());71SymbolFlags[EmuTLST] = Flags;72}73continue;74}7576// Otherwise we just need a normal linker mangling.77auto MangledName = Mangle(G.getName());78SymbolFlags[MangledName] = JITSymbolFlags::fromGlobalValue(G);79if (G.getComdat() &&80G.getComdat()->getSelectionKind() != Comdat::NoDeduplicate)81SymbolFlags[MangledName] |= JITSymbolFlags::Weak;82SymbolToDefinition[MangledName] = &G;83}8485// If we need an init symbol for this module then create one.86if (!getStaticInitGVs(M).empty()) {87size_t Counter = 0;8889do {90std::string InitSymbolName;91raw_string_ostream(InitSymbolName)92<< "$." << M.getModuleIdentifier() << ".__inits." << Counter++;93InitSymbol = ES.intern(InitSymbolName);94} while (SymbolFlags.count(InitSymbol));9596SymbolFlags[InitSymbol] = JITSymbolFlags::MaterializationSideEffectsOnly;97}98});99}100101IRMaterializationUnit::IRMaterializationUnit(102ThreadSafeModule TSM, Interface I,103SymbolNameToDefinitionMap SymbolToDefinition)104: MaterializationUnit(std::move(I)), TSM(std::move(TSM)),105SymbolToDefinition(std::move(SymbolToDefinition)) {}106107StringRef IRMaterializationUnit::getName() const {108if (TSM)109return TSM.withModuleDo(110[](const Module &M) -> StringRef { return M.getModuleIdentifier(); });111return "<null module>";112}113114void IRMaterializationUnit::discard(const JITDylib &JD,115const SymbolStringPtr &Name) {116LLVM_DEBUG(JD.getExecutionSession().runSessionLocked([&]() {117dbgs() << "In " << JD.getName() << " discarding " << *Name << " from MU@"118<< this << " (" << getName() << ")\n";119}););120121auto I = SymbolToDefinition.find(Name);122assert(I != SymbolToDefinition.end() &&123"Symbol not provided by this MU, or previously discarded");124assert(!I->second->isDeclaration() &&125"Discard should only apply to definitions");126I->second->setLinkage(GlobalValue::AvailableExternallyLinkage);127// According to the IR verifier, "Declaration[s] may not be in a Comdat!"128// Remove it, if this is a GlobalObject.129if (auto *GO = dyn_cast<GlobalObject>(I->second))130GO->setComdat(nullptr);131SymbolToDefinition.erase(I);132}133134BasicIRLayerMaterializationUnit::BasicIRLayerMaterializationUnit(135IRLayer &L, const IRSymbolMapper::ManglingOptions &MO, ThreadSafeModule TSM)136: IRMaterializationUnit(L.getExecutionSession(), MO, std::move(TSM)), L(L) {137}138139void BasicIRLayerMaterializationUnit::materialize(140std::unique_ptr<MaterializationResponsibility> R) {141142// Throw away the SymbolToDefinition map: it's not usable after we hand143// off the module.144SymbolToDefinition.clear();145146// If cloneToNewContextOnEmit is set, clone the module now.147if (L.getCloneToNewContextOnEmit())148TSM = cloneToNewContext(TSM);149150#ifndef NDEBUG151auto &ES = R->getTargetJITDylib().getExecutionSession();152auto &N = R->getTargetJITDylib().getName();153#endif // NDEBUG154155LLVM_DEBUG(ES.runSessionLocked(156[&]() { dbgs() << "Emitting, for " << N << ", " << *this << "\n"; }););157L.emit(std::move(R), std::move(TSM));158LLVM_DEBUG(ES.runSessionLocked([&]() {159dbgs() << "Finished emitting, for " << N << ", " << *this << "\n";160}););161}162163char ObjectLayer::ID;164165ObjectLayer::ObjectLayer(ExecutionSession &ES) : ES(ES) {}166167ObjectLayer::~ObjectLayer() = default;168169Error ObjectLayer::add(ResourceTrackerSP RT, std::unique_ptr<MemoryBuffer> O,170MaterializationUnit::Interface I) {171assert(RT && "RT can not be null");172auto &JD = RT->getJITDylib();173return JD.define(std::make_unique<BasicObjectLayerMaterializationUnit>(174*this, std::move(O), std::move(I)),175std::move(RT));176}177178Error ObjectLayer::add(ResourceTrackerSP RT, std::unique_ptr<MemoryBuffer> O) {179auto I = getObjectFileInterface(getExecutionSession(), O->getMemBufferRef());180if (!I)181return I.takeError();182return add(std::move(RT), std::move(O), std::move(*I));183}184185Error ObjectLayer::add(JITDylib &JD, std::unique_ptr<MemoryBuffer> O) {186auto I = getObjectFileInterface(getExecutionSession(), O->getMemBufferRef());187if (!I)188return I.takeError();189return add(JD, std::move(O), std::move(*I));190}191192Expected<std::unique_ptr<BasicObjectLayerMaterializationUnit>>193BasicObjectLayerMaterializationUnit::Create(ObjectLayer &L,194std::unique_ptr<MemoryBuffer> O) {195196auto ObjInterface =197getObjectFileInterface(L.getExecutionSession(), O->getMemBufferRef());198199if (!ObjInterface)200return ObjInterface.takeError();201202return std::make_unique<BasicObjectLayerMaterializationUnit>(203L, std::move(O), std::move(*ObjInterface));204}205206BasicObjectLayerMaterializationUnit::BasicObjectLayerMaterializationUnit(207ObjectLayer &L, std::unique_ptr<MemoryBuffer> O, Interface I)208: MaterializationUnit(std::move(I)), L(L), O(std::move(O)) {}209210StringRef BasicObjectLayerMaterializationUnit::getName() const {211if (O)212return O->getBufferIdentifier();213return "<null object>";214}215216void BasicObjectLayerMaterializationUnit::materialize(217std::unique_ptr<MaterializationResponsibility> R) {218L.emit(std::move(R), std::move(O));219}220221void BasicObjectLayerMaterializationUnit::discard(const JITDylib &JD,222const SymbolStringPtr &Name) {223// This is a no-op for object files: Having removed 'Name' from SymbolFlags224// the symbol will be dead-stripped by the JIT linker.225}226227} // End namespace orc.228} // End namespace llvm.229230231