diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.h b/llvm/tools/llvm-jitlink/llvm-jitlink.h --- a/llvm/tools/llvm-jitlink/llvm-jitlink.h +++ b/llvm/tools/llvm-jitlink/llvm-jitlink.h @@ -19,6 +19,7 @@ #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" #include "llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h" #include "llvm/ExecutionEngine/RuntimeDyldChecker.h" +#include "llvm/MC/SubtargetFeature.h" #include "llvm/Support/Error.h" #include "llvm/Support/Regex.h" #include "llvm/Support/raw_ostream.h" @@ -36,10 +37,12 @@ orc::JITDylib *MainJD = nullptr; orc::ObjectLinkingLayer ObjLayer; orc::JITDylibSearchOrder JDSearchOrder; + SubtargetFeatures Features; ~Session(); - static Expected> Create(Triple TT); + static Expected> Create(Triple TT, + SubtargetFeatures Features); void dumpSessionInfo(raw_ostream &OS); void modifyPassConfig(const Triple &FTT, jitlink::PassConfiguration &PassConfig); diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp --- a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp +++ b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp @@ -893,7 +893,8 @@ } }; -Expected> Session::Create(Triple TT) { +Expected> Session::Create(Triple TT, + SubtargetFeatures Features) { std::unique_ptr EPC; if (OutOfProcessExecutor.getNumOccurrences()) { @@ -923,6 +924,7 @@ std::unique_ptr S(new Session(std::move(EPC), Err)); if (Err) return std::move(Err); + S->Features = std::move(Features); return std::move(S); } @@ -1223,8 +1225,8 @@ } // end namespace llvm -static Triple getFirstFileTriple() { - static Triple FirstTT = []() { +static std::pair getFirstFileTripleAndFeatures() { + static std::pair FirstTTAndFeatures = []() { assert(!InputFiles.empty() && "InputFiles can not be empty"); for (auto InputFile : InputFiles) { auto ObjBuffer = ExitOnErr(getFile(InputFile)); @@ -1241,16 +1243,19 @@ TT.setObjectFormat(Triple::COFF); TT.setOS(Triple::OSType::Win32); } - return TT; + SubtargetFeatures Features; + if (auto ObjFeatures = Obj->getFeatures()) + Features = std::move(*ObjFeatures); + return std::make_pair(TT, Features); } default: break; } } - return Triple(); + return std::make_pair(Triple(), SubtargetFeatures()); }(); - return FirstTT; + return FirstTTAndFeatures; } static Error sanitizeArguments(const Triple &TT, const char *ArgV0) { @@ -1808,7 +1813,9 @@ }; } // anonymous namespace -static TargetInfo getTargetInfo(const Triple &TT) { +static TargetInfo +getTargetInfo(const Triple &TT, + const SubtargetFeatures &TF = SubtargetFeatures()) { auto TripleName = TT.str(); std::string ErrorStr; const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, ErrorStr); @@ -1818,7 +1825,7 @@ inconvertibleErrorCode())); std::unique_ptr STI( - TheTarget->createMCSubtargetInfo(TripleName, "", "")); + TheTarget->createMCSubtargetInfo(TripleName, "", TF.getString())); if (!STI) ExitOnErr( make_error("Unable to create subtarget for " + TripleName, @@ -1879,7 +1886,7 @@ LLVM_DEBUG(dbgs() << "Running checks...\n"); - auto TI = getTargetInfo(S.ES.getTargetTriple()); + auto TI = getTargetInfo(S.ES.getTargetTriple(), S.Features); auto IsSymbolValid = [&S](StringRef Symbol) { return S.isSymbolRegistered(Symbol); @@ -2026,9 +2033,10 @@ std::unique_ptr Timers = ShowTimes ? std::make_unique() : nullptr; - ExitOnErr(sanitizeArguments(getFirstFileTriple(), argv[0])); + auto [TT, Features] = getFirstFileTripleAndFeatures(); + ExitOnErr(sanitizeArguments(TT, argv[0])); - auto S = ExitOnErr(Session::Create(getFirstFileTriple())); + auto S = ExitOnErr(Session::Create(std::move(TT), std::move(Features))); { TimeRegion TR(Timers ? &Timers->LoadObjectsTimer : nullptr);