diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h b/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h --- a/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h +++ b/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h @@ -984,11 +984,20 @@ using GetEdgeKindNameFunction = const char *(*)(Edge::Kind); + using FeatureVector = std::vector; + + LinkGraph(std::string Name, const Triple &TT, FeatureVector Features, + unsigned PointerSize, support::endianness Endianness, + GetEdgeKindNameFunction GetEdgeKindName) + : Name(std::move(Name)), TT(TT), Features(std::move(Features)), + PointerSize(PointerSize), Endianness(Endianness), + GetEdgeKindName(std::move(GetEdgeKindName)) {} + LinkGraph(std::string Name, const Triple &TT, unsigned PointerSize, support::endianness Endianness, GetEdgeKindNameFunction GetEdgeKindName) - : Name(std::move(Name)), TT(TT), PointerSize(PointerSize), - Endianness(Endianness), GetEdgeKindName(std::move(GetEdgeKindName)) {} + : LinkGraph(std::move(Name), TT, FeatureVector(), PointerSize, Endianness, + GetEdgeKindName) {} LinkGraph(const LinkGraph &) = delete; LinkGraph &operator=(const LinkGraph &) = delete; @@ -1002,6 +1011,9 @@ /// Returns the target triple for this Graph. const Triple &getTargetTriple() const { return TT; } + /// Return the subtarget features for this Graph. + const FeatureVector &getFeatures() const { return Features; } + /// Returns the pointer size for use in this graph. unsigned getPointerSize() const { return PointerSize; } @@ -1507,6 +1519,7 @@ std::string Name; Triple TT; + FeatureVector Features; unsigned PointerSize; support::endianness Endianness; GetEdgeKindNameFunction GetEdgeKindName = nullptr; diff --git a/llvm/lib/ExecutionEngine/JITLink/CMakeLists.txt b/llvm/lib/ExecutionEngine/JITLink/CMakeLists.txt --- a/llvm/lib/ExecutionEngine/JITLink/CMakeLists.txt +++ b/llvm/lib/ExecutionEngine/JITLink/CMakeLists.txt @@ -50,6 +50,7 @@ LINK_COMPONENTS BinaryFormat + MC Object Option OrcTargetProcess diff --git a/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.h b/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.h --- a/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.h +++ b/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.h @@ -39,6 +39,7 @@ using COFFSymbolIndex = int32_t; COFFLinkGraphBuilder(const object::COFFObjectFile &Obj, Triple TT, + LinkGraph::FeatureVector Features, LinkGraph::GetEdgeKindNameFunction GetEdgeKindName); LinkGraph &getGraph() const { return *G; } diff --git a/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp b/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp --- a/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp @@ -25,12 +25,12 @@ COFFLinkGraphBuilder::COFFLinkGraphBuilder( const object::COFFObjectFile &Obj, Triple TT, + LinkGraph::FeatureVector Features, LinkGraph::GetEdgeKindNameFunction GetEdgeKindName) - : Obj(Obj), - G(std::make_unique(Obj.getFileName().str(), - createTripleWithCOFFFormat(TT), - getPointerSize(Obj), getEndianness(Obj), - std::move(GetEdgeKindName))) { + : Obj(Obj), G(std::make_unique( + Obj.getFileName().str(), createTripleWithCOFFFormat(TT), + std::move(Features), getPointerSize(Obj), + getEndianness(Obj), std::move(GetEdgeKindName))) { LLVM_DEBUG({ dbgs() << "Created COFFLinkGraphBuilder for \"" << Obj.getFileName() << "\"\n"; diff --git a/llvm/lib/ExecutionEngine/JITLink/COFF_x86_64.cpp b/llvm/lib/ExecutionEngine/JITLink/COFF_x86_64.cpp --- a/llvm/lib/ExecutionEngine/JITLink/COFF_x86_64.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/COFF_x86_64.cpp @@ -181,8 +181,10 @@ } public: - COFFLinkGraphBuilder_x86_64(const object::COFFObjectFile &Obj, const Triple T) - : COFFLinkGraphBuilder(Obj, std::move(T), getCOFFX86RelocationKindName) {} + COFFLinkGraphBuilder_x86_64(const object::COFFObjectFile &Obj, const Triple T, + const LinkGraph::FeatureVector Features) + : COFFLinkGraphBuilder(Obj, std::move(T), std::move(Features), + getCOFFX86RelocationKindName) {} }; class COFFLinkGraphLowering_x86_64 { @@ -314,7 +316,12 @@ if (!COFFObj) return COFFObj.takeError(); - return COFFLinkGraphBuilder_x86_64(**COFFObj, (*COFFObj)->makeTriple()) + auto Features = (*COFFObj)->getFeatures(); + if (!Features) + return Features.takeError(); + + return COFFLinkGraphBuilder_x86_64(**COFFObj, (*COFFObj)->makeTriple(), + Features->getFeatures()) .buildGraph(); } diff --git a/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h b/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h --- a/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h +++ b/llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h @@ -59,7 +59,7 @@ public: ELFLinkGraphBuilder(const object::ELFFile &Obj, Triple TT, - StringRef FileName, + LinkGraph::FeatureVector Features, StringRef FileName, LinkGraph::GetEdgeKindNameFunction GetEdgeKindName); /// Debug sections are included in the graph by default. Use @@ -195,11 +195,11 @@ template ELFLinkGraphBuilder::ELFLinkGraphBuilder( - const ELFFile &Obj, Triple TT, StringRef FileName, - LinkGraph::GetEdgeKindNameFunction GetEdgeKindName) + const ELFFile &Obj, Triple TT, LinkGraph::FeatureVector Features, + StringRef FileName, LinkGraph::GetEdgeKindNameFunction GetEdgeKindName) : ELFLinkGraphBuilderBase(std::make_unique( - FileName.str(), Triple(std::move(TT)), ELFT::Is64Bits ? 8 : 4, - support::endianness(ELFT::TargetEndianness), + FileName.str(), Triple(std::move(TT)), std::move(Features), + ELFT::Is64Bits ? 8 : 4, support::endianness(ELFT::TargetEndianness), std::move(GetEdgeKindName))), Obj(Obj) { LLVM_DEBUG( diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp --- a/llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp @@ -191,9 +191,10 @@ public: ELFLinkGraphBuilder_aarch32(StringRef FileName, const llvm::object::ELFFile &Obj, Triple TT, + LinkGraph::FeatureVector Features, aarch32::ArmConfig ArmCfg) - : ELFLinkGraphBuilder(Obj, std::move(TT), FileName, - getELFAArch32EdgeKindName), + : ELFLinkGraphBuilder(Obj, std::move(TT), std::move(Features), + FileName, getELFAArch32EdgeKindName), ArmCfg(std::move(ArmCfg)) {} }; @@ -217,6 +218,10 @@ if (!ELFObj) return ELFObj.takeError(); + auto Features = (*ELFObj)->getFeatures(); + if (!Features) + return Features.takeError(); + // Find out what exact AArch32 instruction set and features we target. auto TT = (*ELFObj)->makeTriple(); ARM::ArchKind AK = ARM::parseArch(TT.getArchName()); @@ -249,14 +254,16 @@ case Triple::thumb: { auto &ELFFile = cast>(**ELFObj).getELFFile(); return ELFLinkGraphBuilder_aarch32( - (*ELFObj)->getFileName(), ELFFile, TT, ArmCfg) + (*ELFObj)->getFileName(), ELFFile, TT, Features->getFeatures(), + ArmCfg) .buildGraph(); } case Triple::armeb: case Triple::thumbeb: { auto &ELFFile = cast>(**ELFObj).getELFFile(); - return ELFLinkGraphBuilder_aarch32((*ELFObj)->getFileName(), - ELFFile, TT, ArmCfg) + return ELFLinkGraphBuilder_aarch32( + (*ELFObj)->getFileName(), ELFFile, TT, Features->getFeatures(), + ArmCfg) .buildGraph(); } default: diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp --- a/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp @@ -404,9 +404,10 @@ public: ELFLinkGraphBuilder_aarch64(StringRef FileName, - const object::ELFFile &Obj, Triple TT) - : ELFLinkGraphBuilder(Obj, std::move(TT), FileName, - aarch64::getEdgeKindName) {} + const object::ELFFile &Obj, Triple TT, + LinkGraph::FeatureVector Features) + : ELFLinkGraphBuilder(Obj, std::move(TT), std::move(Features), + FileName, aarch64::getEdgeKindName) {} }; // TLS Info Builder. @@ -554,13 +555,17 @@ if (!ELFObj) return ELFObj.takeError(); + auto Features = (*ELFObj)->getFeatures(); + if (!Features) + return Features.takeError(); + assert((*ELFObj)->getArch() == Triple::aarch64 && "Only AArch64 (little endian) is supported for now"); auto &ELFObjFile = cast>(**ELFObj); - return ELFLinkGraphBuilder_aarch64((*ELFObj)->getFileName(), - ELFObjFile.getELFFile(), - (*ELFObj)->makeTriple()) + return ELFLinkGraphBuilder_aarch64( + (*ELFObj)->getFileName(), ELFObjFile.getELFFile(), + (*ELFObj)->makeTriple(), Features->getFeatures()) .buildGraph(); } diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_i386.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_i386.cpp --- a/llvm/lib/ExecutionEngine/JITLink/ELF_i386.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/ELF_i386.cpp @@ -210,9 +210,9 @@ public: ELFLinkGraphBuilder_i386(StringRef FileName, const object::ELFFile &Obj, - Triple TT) - : ELFLinkGraphBuilder(Obj, std::move(TT), FileName, - i386::getEdgeKindName) {} + Triple TT, LinkGraph::FeatureVector Features) + : ELFLinkGraphBuilder(Obj, std::move(TT), std::move(Features), + FileName, i386::getEdgeKindName) {} }; Expected> @@ -226,13 +226,17 @@ if (!ELFObj) return ELFObj.takeError(); + auto Features = (*ELFObj)->getFeatures(); + if (!Features) + return Features.takeError(); + assert((*ELFObj)->getArch() == Triple::x86 && "Only i386 (little endian) is supported for now"); auto &ELFObjFile = cast>(**ELFObj); - return ELFLinkGraphBuilder_i386((*ELFObj)->getFileName(), - ELFObjFile.getELFFile(), - (*ELFObj)->makeTriple()) + return ELFLinkGraphBuilder_i386( + (*ELFObj)->getFileName(), ELFObjFile.getELFFile(), + (*ELFObj)->makeTriple(), Features->getFeatures()) .buildGraph(); } diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_loongarch.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_loongarch.cpp --- a/llvm/lib/ExecutionEngine/JITLink/ELF_loongarch.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/ELF_loongarch.cpp @@ -129,9 +129,10 @@ public: ELFLinkGraphBuilder_loongarch(StringRef FileName, - const object::ELFFile &Obj, Triple TT) - : ELFLinkGraphBuilder(Obj, std::move(TT), FileName, - loongarch::getEdgeKindName) {} + const object::ELFFile &Obj, Triple TT, + LinkGraph::FeatureVector Features) + : ELFLinkGraphBuilder(Obj, std::move(TT), std::move(Features), + FileName, loongarch::getEdgeKindName) {} }; Error buildTables_ELF_loongarch(LinkGraph &G) { @@ -159,11 +160,15 @@ if (!ELFObj) return ELFObj.takeError(); + auto Features = (*ELFObj)->getFeatures(); + if (!Features) + return Features.takeError(); + if ((*ELFObj)->getArch() == Triple::loongarch64) { auto &ELFObjFile = cast>(**ELFObj); return ELFLinkGraphBuilder_loongarch( (*ELFObj)->getFileName(), ELFObjFile.getELFFile(), - (*ELFObj)->makeTriple()) + (*ELFObj)->makeTriple(), Features->getFeatures()) .buildGraph(); } @@ -172,7 +177,7 @@ auto &ELFObjFile = cast>(**ELFObj); return ELFLinkGraphBuilder_loongarch( (*ELFObj)->getFileName(), ELFObjFile.getELFFile(), - (*ELFObj)->makeTriple()) + (*ELFObj)->makeTriple(), Features->getFeatures()) .buildGraph(); } diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp --- a/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp @@ -596,9 +596,10 @@ public: ELFLinkGraphBuilder_riscv(StringRef FileName, - const object::ELFFile &Obj, Triple TT) - : ELFLinkGraphBuilder(Obj, std::move(TT), FileName, - riscv::getEdgeKindName) {} + const object::ELFFile &Obj, Triple TT, + LinkGraph::FeatureVector Features) + : ELFLinkGraphBuilder(Obj, std::move(TT), std::move(Features), + FileName, riscv::getEdgeKindName) {} }; Expected> @@ -612,11 +613,15 @@ if (!ELFObj) return ELFObj.takeError(); + auto Features = (*ELFObj)->getFeatures(); + if (!Features) + return Features.takeError(); + if ((*ELFObj)->getArch() == Triple::riscv64) { auto &ELFObjFile = cast>(**ELFObj); return ELFLinkGraphBuilder_riscv( (*ELFObj)->getFileName(), ELFObjFile.getELFFile(), - (*ELFObj)->makeTriple()) + (*ELFObj)->makeTriple(), Features->getFeatures()) .buildGraph(); } else { assert((*ELFObj)->getArch() == Triple::riscv32 && @@ -624,7 +629,7 @@ auto &ELFObjFile = cast>(**ELFObj); return ELFLinkGraphBuilder_riscv( (*ELFObj)->getFileName(), ELFObjFile.getELFFile(), - (*ELFObj)->makeTriple()) + (*ELFObj)->makeTriple(), Features->getFeatures()) .buildGraph(); } } diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp --- a/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp @@ -227,8 +227,10 @@ public: ELFLinkGraphBuilder_x86_64(StringRef FileName, - const object::ELFFile &Obj) - : ELFLinkGraphBuilder(Obj, Triple("x86_64-unknown-linux"), FileName, + const object::ELFFile &Obj, + LinkGraph::FeatureVector Features) + : ELFLinkGraphBuilder(Obj, Triple("x86_64-unknown-linux"), + std::move(Features), FileName, x86_64::getEdgeKindName) {} }; @@ -329,9 +331,14 @@ if (!ELFObj) return ELFObj.takeError(); + auto Features = (*ELFObj)->getFeatures(); + if (!Features) + return Features.takeError(); + auto &ELFObjFile = cast>(**ELFObj); return ELFLinkGraphBuilder_x86_64((*ELFObj)->getFileName(), - ELFObjFile.getELFFile()) + ELFObjFile.getELFFile(), + Features->getFeatures()) .buildGraph(); } diff --git a/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.h b/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.h --- a/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.h +++ b/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.h @@ -84,6 +84,7 @@ using SectionParserFunction = std::function; MachOLinkGraphBuilder(const object::MachOObjectFile &Obj, Triple TT, + LinkGraph::FeatureVector Features, LinkGraph::GetEdgeKindNameFunction GetEdgeKindName); LinkGraph &getGraph() const { return *G; } diff --git a/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp b/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp --- a/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp @@ -48,11 +48,13 @@ MachOLinkGraphBuilder::MachOLinkGraphBuilder( const object::MachOObjectFile &Obj, Triple TT, + LinkGraph::FeatureVector Features, LinkGraph::GetEdgeKindNameFunction GetEdgeKindName) : Obj(Obj), - G(std::make_unique( - std::string(Obj.getFileName()), std::move(TT), getPointerSize(Obj), - getEndianness(Obj), std::move(GetEdgeKindName))) { + G(std::make_unique(std::string(Obj.getFileName()), + std::move(TT), std::move(Features), + getPointerSize(Obj), getEndianness(Obj), + std::move(GetEdgeKindName))) { auto &MachHeader = Obj.getHeader64(); SubsectionsViaSymbols = MachHeader.flags & MachO::MH_SUBSECTIONS_VIA_SYMBOLS; } diff --git a/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp b/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp --- a/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp @@ -25,9 +25,10 @@ class MachOLinkGraphBuilder_arm64 : public MachOLinkGraphBuilder { public: - MachOLinkGraphBuilder_arm64(const object::MachOObjectFile &Obj) + MachOLinkGraphBuilder_arm64(const object::MachOObjectFile &Obj, + LinkGraph::FeatureVector Features) : MachOLinkGraphBuilder(Obj, Triple("arm64-apple-darwin"), - aarch64::getEdgeKindName), + std::move(Features), aarch64::getEdgeKindName), NumSymbols(Obj.getSymtabLoadCommand().nsyms) {} private: @@ -541,7 +542,13 @@ auto MachOObj = object::ObjectFile::createMachOObjectFile(ObjectBuffer); if (!MachOObj) return MachOObj.takeError(); - return MachOLinkGraphBuilder_arm64(**MachOObj).buildGraph(); + + auto Features = (*MachOObj)->getFeatures(); + if (!Features) + return Features.takeError(); + + return MachOLinkGraphBuilder_arm64(**MachOObj, Features->getFeatures()) + .buildGraph(); } void link_MachO_arm64(std::unique_ptr G, diff --git a/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp b/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp --- a/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp @@ -25,9 +25,10 @@ class MachOLinkGraphBuilder_x86_64 : public MachOLinkGraphBuilder { public: - MachOLinkGraphBuilder_x86_64(const object::MachOObjectFile &Obj) + MachOLinkGraphBuilder_x86_64(const object::MachOObjectFile &Obj, + LinkGraph::FeatureVector Features) : MachOLinkGraphBuilder(Obj, Triple("x86_64-apple-darwin"), - x86_64::getEdgeKindName) {} + std::move(Features), x86_64::getEdgeKindName) {} private: enum MachONormalizedRelocationType : unsigned { @@ -466,7 +467,13 @@ auto MachOObj = object::ObjectFile::createMachOObjectFile(ObjectBuffer); if (!MachOObj) return MachOObj.takeError(); - return MachOLinkGraphBuilder_x86_64(**MachOObj).buildGraph(); + + auto Features = (*MachOObj)->getFeatures(); + if (!Features) + return Features.takeError(); + + return MachOLinkGraphBuilder_x86_64(**MachOObj, Features->getFeatures()) + .buildGraph(); } void link_MachO_x86_64(std::unique_ptr G,