diff options
Diffstat (limited to 'llvm/lib')
60 files changed, 268 insertions, 1742 deletions
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp index 9e78ec9..8ea1326 100644 --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -4030,7 +4030,6 @@ bool PhiNodeSetIterator::operator!=(const PhiNodeSetIterator &RHS) const { /// if it is simplified. class SimplificationTracker { DenseMap<Value *, Value *> Storage; - const SimplifyQuery &SQ; // Tracks newly created Phi nodes. The elements are iterated by insertion // order. PhiNodeSet AllPhiNodes; @@ -4038,8 +4037,6 @@ class SimplificationTracker { SmallPtrSet<SelectInst *, 32> AllSelectNodes; public: - SimplificationTracker(const SimplifyQuery &sq) : SQ(sq) {} - Value *Get(Value *V) { do { auto SV = Storage.find(V); @@ -4049,30 +4046,6 @@ public: } while (true); } - Value *Simplify(Value *Val) { - SmallVector<Value *, 32> WorkList; - SmallPtrSet<Value *, 32> Visited; - WorkList.push_back(Val); - while (!WorkList.empty()) { - auto *P = WorkList.pop_back_val(); - if (!Visited.insert(P).second) - continue; - if (auto *PI = dyn_cast<Instruction>(P)) - if (Value *V = simplifyInstruction(cast<Instruction>(PI), SQ)) { - for (auto *U : PI->users()) - WorkList.push_back(cast<Value>(U)); - Put(PI, V); - PI->replaceAllUsesWith(V); - if (auto *PHI = dyn_cast<PHINode>(PI)) - AllPhiNodes.erase(PHI); - if (auto *Select = dyn_cast<SelectInst>(PI)) - AllSelectNodes.erase(Select); - PI->eraseFromParent(); - } - } - return Get(Val); - } - void Put(Value *From, Value *To) { Storage.insert({From, To}); } void ReplacePhi(PHINode *From, PHINode *To) { @@ -4133,8 +4106,7 @@ private: /// Common Type for all different fields in addressing modes. Type *CommonType = nullptr; - /// SimplifyQuery for simplifyInstruction utility. - const SimplifyQuery &SQ; + const DataLayout &DL; /// Original Address. Value *Original; @@ -4143,8 +4115,8 @@ private: Value *CommonValue = nullptr; public: - AddressingModeCombiner(const SimplifyQuery &_SQ, Value *OriginalValue) - : SQ(_SQ), Original(OriginalValue) {} + AddressingModeCombiner(const DataLayout &DL, Value *OriginalValue) + : DL(DL), Original(OriginalValue) {} ~AddressingModeCombiner() { eraseCommonValueIfDead(); } @@ -4256,7 +4228,7 @@ private: // Keep track of keys where the value is null. We will need to replace it // with constant null when we know the common type. SmallVector<Value *, 2> NullValue; - Type *IntPtrTy = SQ.DL.getIntPtrType(AddrModes[0].OriginalValue->getType()); + Type *IntPtrTy = DL.getIntPtrType(AddrModes[0].OriginalValue->getType()); for (auto &AM : AddrModes) { Value *DV = AM.GetFieldAsValue(DifferentField, IntPtrTy); if (DV) { @@ -4306,7 +4278,7 @@ private: // simplification is possible only if original phi/selects were not // simplified yet. // Using this mapping we can find the current value in AddrToBase. - SimplificationTracker ST(SQ); + SimplificationTracker ST; // First step, DFS to create PHI nodes for all intermediate blocks. // Also fill traverse order for the second step. @@ -4465,7 +4437,6 @@ private: PHI->addIncoming(ST.Get(Map[PV]), B); } } - Map[Current] = ST.Simplify(V); } } @@ -5856,8 +5827,7 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr, // the graph are compatible. bool PhiOrSelectSeen = false; SmallVector<Instruction *, 16> AddrModeInsts; - const SimplifyQuery SQ(*DL, TLInfo); - AddressingModeCombiner AddrModes(SQ, Addr); + AddressingModeCombiner AddrModes(*DL, Addr); TypePromotionTransaction TPT(RemovedInsts); TypePromotionTransaction::ConstRestorationPt LastKnownGood = TPT.getRestorationPoint(); diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp index 178529f..52c43a4 100644 --- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -9084,6 +9084,8 @@ LegalizerHelper::lowerShuffleVector(MachineInstr &MI) { SmallVector<Register, 32> BuildVec; LLT EltTy = DstTy.getScalarType(); + DenseMap<unsigned, Register> CachedExtract; + for (int Idx : Mask) { if (Idx < 0) { if (!Undef.isValid()) @@ -9097,9 +9099,13 @@ LegalizerHelper::lowerShuffleVector(MachineInstr &MI) { int NumElts = Src0Ty.getNumElements(); Register SrcVec = Idx < NumElts ? Src0Reg : Src1Reg; int ExtractIdx = Idx < NumElts ? Idx : Idx - NumElts; - auto IdxK = MIRBuilder.buildConstant(IdxTy, ExtractIdx); - auto Extract = MIRBuilder.buildExtractVectorElement(EltTy, SrcVec, IdxK); - BuildVec.push_back(Extract.getReg(0)); + auto [It, Inserted] = CachedExtract.try_emplace(Idx); + if (Inserted) { + auto IdxK = MIRBuilder.buildConstant(IdxTy, ExtractIdx); + It->second = + MIRBuilder.buildExtractVectorElement(EltTy, SrcVec, IdxK).getReg(0); + } + BuildVec.push_back(It->second); } assert(DstTy.isVector() && "Unexpected scalar G_SHUFFLE_VECTOR"); diff --git a/llvm/lib/CodeGen/RegisterUsageInfo.cpp b/llvm/lib/CodeGen/RegisterUsageInfo.cpp index 7a4628a..2ef380f 100644 --- a/llvm/lib/CodeGen/RegisterUsageInfo.cpp +++ b/llvm/lib/CodeGen/RegisterUsageInfo.cpp @@ -44,7 +44,7 @@ void PhysicalRegisterUsageInfo::setTargetMachine(const TargetMachine &TM) { } bool PhysicalRegisterUsageInfo::doInitialization(Module &M) { - RegMasks.grow(M.size()); + RegMasks.reserve(M.size()); return false; } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index dee0909..a522650 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -2015,9 +2015,9 @@ SDValue SelectionDAGBuilder::getValueImpl(const Value *V) { Register InReg = FuncInfo.InitializeRegForValue(Inst); std::optional<CallingConv::ID> CallConv; - auto *CI = dyn_cast<CallInst>(Inst); - if (CI && !CI->isInlineAsm()) - CallConv = CI->getCallingConv(); + auto *CB = dyn_cast<CallBase>(Inst); + if (CB && !CB->isInlineAsm()) + CallConv = CB->getCallingConv(); RegsForValue RFV(*DAG.getContext(), TLI, DAG.getDataLayout(), InReg, Inst->getType(), CallConv); diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 920dff9..da4e409 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -9899,6 +9899,18 @@ SDValue TargetLowering::expandBSWAP(SDNode *N, SelectionDAG &DAG) const { // Use a rotate by 8. This can be further expanded if necessary. return DAG.getNode(ISD::ROTL, dl, VT, Op, DAG.getConstant(8, dl, SHVT)); case MVT::i32: + // This is meant for ARM speficially, which has ROTR but no ROTL. + if (isOperationLegalOrCustom(ISD::ROTR, VT)) { + SDValue Mask = DAG.getConstant(0x00FF00FF, dl, VT); + // (x & 0x00FF00FF) rotr 8 | (x rotl 8) & 0x00FF00FF + SDValue And = DAG.getNode(ISD::AND, dl, VT, Op, Mask); + SDValue Rotr = + DAG.getNode(ISD::ROTR, dl, VT, And, DAG.getConstant(8, dl, SHVT)); + SDValue Rotl = + DAG.getNode(ISD::ROTR, dl, VT, Op, DAG.getConstant(24, dl, SHVT)); + SDValue And2 = DAG.getNode(ISD::AND, dl, VT, Rotl, Mask); + return DAG.getNode(ISD::OR, dl, VT, Rotr, And2); + } Tmp4 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(24, dl, SHVT)); Tmp3 = DAG.getNode(ISD::AND, dl, VT, Op, DAG.getConstant(0xFF00, dl, VT)); diff --git a/llvm/lib/CodeGen/TargetOptionsImpl.cpp b/llvm/lib/CodeGen/TargetOptionsImpl.cpp index 049efe8..c33bf8b 100644 --- a/llvm/lib/CodeGen/TargetOptionsImpl.cpp +++ b/llvm/lib/CodeGen/TargetOptionsImpl.cpp @@ -44,7 +44,7 @@ bool TargetOptions::FramePointerIsReserved(const MachineFunction &MF) const { return false; return StringSwitch<bool>(FPAttr.getValueAsString()) - .Cases("all", "non-leaf", "reserved", true) + .Cases({"all", "non-leaf", "reserved"}, true) .Case("none", false); } diff --git a/llvm/lib/ExecutionEngine/Orc/Core.cpp b/llvm/lib/ExecutionEngine/Orc/Core.cpp index 8d413a3..d029ac5 100644 --- a/llvm/lib/ExecutionEngine/Orc/Core.cpp +++ b/llvm/lib/ExecutionEngine/Orc/Core.cpp @@ -2901,13 +2901,23 @@ ExecutionSession::IL_emit(MaterializationResponsibility &MR, for (auto &SN : ER.Ready) IL_collectQueries( - EQ.Updated, SN->defs(), + EQ.Completed, SN->defs(), [](JITDylib::SymbolTableEntry &E) { E.setState(SymbolState::Ready); }, [](AsynchronousSymbolQuery &Q, JITDylib &JD, NonOwningSymbolStringPtr Name, JITDylib::SymbolTableEntry &E) { Q.notifySymbolMetRequiredState(SymbolStringPtr(Name), E.getSymbol()); }); + // std::erase_if is not available in C++17, and llvm::erase_if does not work + // here. + for (auto it = EQ.Completed.begin(), end = EQ.Completed.end(); it != end;) { + if ((*it)->isComplete()) { + ++it; + } else { + it = EQ.Completed.erase(it); + } + } + #ifdef EXPENSIVE_CHECKS verifySessionState("exiting ExecutionSession::IL_emit"); #endif @@ -3043,9 +3053,8 @@ Error ExecutionSession::OL_notifyEmitted( } } - for (auto &UQ : EmitQueries->Updated) - if (UQ->isComplete()) - UQ->handleComplete(*this); + for (auto &UQ : EmitQueries->Completed) + UQ->handleComplete(*this); // If there are any bad dependencies then return an error. if (!BadDeps.empty()) { diff --git a/llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt b/llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt index ca8192b..9275586 100644 --- a/llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt +++ b/llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt @@ -16,11 +16,9 @@ add_llvm_component_library(LLVMOrcTargetProcess ExecutorSharedMemoryMapperService.cpp DefaultHostBootstrapValues.cpp ExecutorResolver.cpp - LibraryResolver.cpp JITLoaderGDB.cpp JITLoaderPerf.cpp JITLoaderVTune.cpp - LibraryScanner.cpp OrcRTBootstrap.cpp RegisterEHFrames.cpp SimpleExecutorDylibManager.cpp @@ -38,8 +36,6 @@ add_llvm_component_library(LLVMOrcTargetProcess LINK_COMPONENTS ${intel_jit_profiling} - BinaryFormat - Object OrcShared Support TargetParser diff --git a/llvm/lib/ExecutionEngine/Orc/TargetProcess/LibraryResolver.cpp b/llvm/lib/ExecutionEngine/Orc/TargetProcess/LibraryResolver.cpp deleted file mode 100644 index 9d25b74..0000000 --- a/llvm/lib/ExecutionEngine/Orc/TargetProcess/LibraryResolver.cpp +++ /dev/null @@ -1,369 +0,0 @@ -//===- LibraryResolver.cpp - Library Resolution of Unresolved Symbols ---===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// Library resolution impl for unresolved symbols -// -//===----------------------------------------------------------------------===// - -#include "llvm/ExecutionEngine/Orc/TargetProcess/LibraryResolver.h" -#include "llvm/ExecutionEngine/Orc/TargetProcess/LibraryScanner.h" - -#include "llvm/ADT/StringSet.h" - -#include "llvm/BinaryFormat/MachO.h" -#include "llvm/Object/COFF.h" -#include "llvm/Object/ELF.h" -#include "llvm/Object/ELFObjectFile.h" -#include "llvm/Object/MachO.h" -#include "llvm/Object/ObjectFile.h" -#include "llvm/Support/Error.h" - -#include <mutex> -#include <thread> - -#define DEBUG_TYPE "orc-resolver" - -namespace llvm::orc { - -LibraryResolver::LibraryResolver(const LibraryResolver::Setup &S) - : LibPathCache(S.Cache ? S.Cache : std::make_shared<LibraryPathCache>()), - LibPathResolver(S.PResolver - ? S.PResolver - : std::make_shared<PathResolver>(LibPathCache)), - ScanHelper(S.BasePaths, LibPathCache, LibPathResolver), - FB(S.FilterBuilder), LibMgr(), - ShouldScanCall(S.ShouldScanCall ? S.ShouldScanCall - : [](StringRef) -> bool { return true; }), - scanBatchSize(S.ScanBatchSize) { - - if (ScanHelper.getAllUnits().empty()) { - LLVM_DEBUG(dbgs() << "Warning: No base paths provided for scanning.\n"); - } -} - -std::unique_ptr<LibraryResolutionDriver> -LibraryResolutionDriver::create(const LibraryResolver::Setup &S) { - auto LR = std::make_unique<LibraryResolver>(S); - return std::unique_ptr<LibraryResolutionDriver>( - new LibraryResolutionDriver(std::move(LR))); -} - -void LibraryResolutionDriver::addScanPath(const std::string &Path, PathType K) { - LR->ScanHelper.addBasePath(Path, K); -} - -bool LibraryResolutionDriver::markLibraryLoaded(StringRef Path) { - auto Lib = LR->LibMgr.getLibrary(Path); - if (!Lib) - return false; - - Lib->setState(LibraryManager::LibState::Loaded); - - return true; -} - -bool LibraryResolutionDriver::markLibraryUnLoaded(StringRef Path) { - auto Lib = LR->LibMgr.getLibrary(Path); - if (!Lib) - return false; - - Lib->setState(LibraryManager::LibState::Unloaded); - - return true; -} - -void LibraryResolutionDriver::resolveSymbols( - std::vector<std::string> Syms, - LibraryResolver::OnSearchComplete OnCompletion, - const SearchConfig &Config) { - LR->searchSymbolsInLibraries(Syms, std::move(OnCompletion), Config); -} - -static bool shouldIgnoreSymbol(const object::SymbolRef &Sym, - uint32_t IgnoreFlags) { - Expected<uint32_t> FlagsOrErr = Sym.getFlags(); - if (!FlagsOrErr) { - consumeError(FlagsOrErr.takeError()); - return true; - } - - uint32_t Flags = *FlagsOrErr; - - using Filter = SymbolEnumeratorOptions; - if ((IgnoreFlags & Filter::IgnoreUndefined) && - (Flags & object::SymbolRef::SF_Undefined)) - return true; - if ((IgnoreFlags & Filter::IgnoreIndirect) && - (Flags & object::SymbolRef::SF_Indirect)) - return true; - if ((IgnoreFlags & Filter::IgnoreWeak) && - (Flags & object::SymbolRef::SF_Weak)) - return true; - - return false; -} - -bool SymbolEnumerator::enumerateSymbols(StringRef Path, OnEachSymbolFn OnEach, - const SymbolEnumeratorOptions &Opts) { - if (Path.empty()) - return false; - - ObjectFileLoader ObjLoader(Path); - - auto ObjOrErr = ObjLoader.getObjectFile(); - if (!ObjOrErr) { - std::string ErrMsg; - handleAllErrors(ObjOrErr.takeError(), - [&](const ErrorInfoBase &EIB) { ErrMsg = EIB.message(); }); - LLVM_DEBUG(dbgs() << "Failed loading object file: " << Path - << "\nError: " << ErrMsg << "\n"); - return false; - } - - object::ObjectFile *Obj = &ObjOrErr.get(); - - auto processSymbolRange = - [&](object::ObjectFile::symbol_iterator_range Range) -> EnumerateResult { - for (const auto &Sym : Range) { - if (shouldIgnoreSymbol(Sym, Opts.FilterFlags)) - continue; - - auto NameOrErr = Sym.getName(); - if (!NameOrErr) { - consumeError(NameOrErr.takeError()); - continue; - } - - StringRef Name = *NameOrErr; - if (Name.empty()) - continue; - - EnumerateResult Res = OnEach(Name); - if (Res != EnumerateResult::Continue) - return Res; - } - return EnumerateResult::Continue; - }; - - EnumerateResult Res = processSymbolRange(Obj->symbols()); - if (Res != EnumerateResult::Continue) - return Res == EnumerateResult::Stop; - - if (Obj->isELF()) { - const auto *ElfObj = cast<object::ELFObjectFileBase>(Obj); - Res = processSymbolRange(ElfObj->getDynamicSymbolIterators()); - if (Res != EnumerateResult::Continue) - return Res == EnumerateResult::Stop; - } else if (Obj->isCOFF()) { - const auto *CoffObj = cast<object::COFFObjectFile>(Obj); - for (auto I = CoffObj->export_directory_begin(), - E = CoffObj->export_directory_end(); - I != E; ++I) { - StringRef Name; - if (I->getSymbolName(Name)) - continue; - if (Name.empty()) - continue; - - if (OnEach(Name) != EnumerateResult::Continue) - return false; - } - } else if (Obj->isMachO()) { - } - - return true; -} - -class SymbolSearchContext { -public: - SymbolSearchContext(SymbolQuery &Q) : Q(Q) {} - - bool hasSearched(LibraryInfo *Lib) const { return Searched.count(Lib); } - - void markSearched(LibraryInfo *Lib) { Searched.insert(Lib); } - - inline bool allResolved() const { return Q.allResolved(); } - - SymbolQuery &query() { return Q; } - -private: - SymbolQuery &Q; - DenseSet<LibraryInfo *> Searched; -}; - -void LibraryResolver::resolveSymbolsInLibrary( - LibraryInfo &Lib, SymbolQuery &UnresolvedSymbols, - const SymbolEnumeratorOptions &Opts) { - LLVM_DEBUG(dbgs() << "Checking unresolved symbols " - << " in library : " << Lib.getFileName() << "\n";); - StringSet<> DiscoveredSymbols; - - if (!UnresolvedSymbols.hasUnresolved()) { - LLVM_DEBUG(dbgs() << "Skipping library: " << Lib.getFullPath() - << " — unresolved symbols exist.\n";); - return; - } - - bool HasEnumerated = false; - auto enumerateSymbolsIfNeeded = [&]() { - if (HasEnumerated) - return; - - HasEnumerated = true; - - LLVM_DEBUG(dbgs() << "Enumerating symbols in library: " << Lib.getFullPath() - << "\n";); - SymbolEnumerator::enumerateSymbols( - Lib.getFullPath(), - [&](StringRef sym) { - DiscoveredSymbols.insert(sym); - return EnumerateResult::Continue; - }, - Opts); - - if (DiscoveredSymbols.empty()) { - LLVM_DEBUG(dbgs() << " No symbols and remove library : " - << Lib.getFullPath() << "\n";); - LibMgr.removeLibrary(Lib.getFullPath()); - return; - } - }; - - if (!Lib.hasFilter()) { - LLVM_DEBUG(dbgs() << "Building filter for library: " << Lib.getFullPath() - << "\n";); - enumerateSymbolsIfNeeded(); - SmallVector<StringRef> SymbolVec; - SymbolVec.reserve(DiscoveredSymbols.size()); - for (const auto &KV : DiscoveredSymbols) - SymbolVec.push_back(KV.first()); - - Lib.ensureFilterBuilt(FB, SymbolVec); - LLVM_DEBUG({ - dbgs() << "DiscoveredSymbols : " << DiscoveredSymbols.size() << "\n"; - for (const auto &KV : DiscoveredSymbols) - dbgs() << "DiscoveredSymbols : " << KV.first() << "\n"; - }); - } - - const auto &Unresolved = UnresolvedSymbols.getUnresolvedSymbols(); - bool HadAnySym = false; - LLVM_DEBUG(dbgs() << "Total unresolved symbols : " << Unresolved.size() - << "\n";); - for (const auto &Sym : Unresolved) { - if (Lib.mayContain(Sym)) { - LLVM_DEBUG(dbgs() << "Checking symbol '" << Sym - << "' in library: " << Lib.getFullPath() << "\n";); - enumerateSymbolsIfNeeded(); - if (DiscoveredSymbols.count(Sym) > 0) { - LLVM_DEBUG(dbgs() << " Resolved symbol: " << Sym - << " in library: " << Lib.getFullPath() << "\n";); - UnresolvedSymbols.resolve(Sym, Lib.getFullPath()); - HadAnySym = true; - } - } - } - - using LibraryState = LibraryManager::LibState; - if (HadAnySym && Lib.getState() != LibraryState::Loaded) - Lib.setState(LibraryState::Queried); -} - -void LibraryResolver::searchSymbolsInLibraries( - std::vector<std::string> &SymbolList, OnSearchComplete OnComplete, - const SearchConfig &Config) { - SymbolQuery Q(SymbolList); - - using LibraryState = LibraryManager::LibState; - using LibraryType = PathType; - auto tryResolveFrom = [&](LibraryState S, LibraryType K) { - LLVM_DEBUG(dbgs() << "Trying resolve from state=" << static_cast<int>(S) - << " type=" << static_cast<int>(K) << "\n";); - - SymbolSearchContext Ctx(Q); - while (!Ctx.allResolved()) { - - for (auto &Lib : LibMgr.getView(S, K)) { - if (Ctx.hasSearched(Lib.get())) - continue; - - // can use Async here? - resolveSymbolsInLibrary(*Lib, Ctx.query(), Config.Options); - Ctx.markSearched(Lib.get()); - - if (Ctx.allResolved()) - return; - } - - if (Ctx.allResolved()) - return; - - if (!scanLibrariesIfNeeded(K, scanBatchSize)) - break; // no more new libs to scan - } - }; - - for (const auto &[St, Ty] : Config.Policy.Plan) { - tryResolveFrom(St, Ty); - if (Q.allResolved()) - break; - } - - // done: - LLVM_DEBUG({ - dbgs() << "Search complete.\n"; - for (const auto &r : Q.getAllResults()) - dbgs() << "Resolved Symbol:" << r->Name << " -> " << r->ResolvedLibPath - << "\n"; - }); - - OnComplete(Q); -} - -bool LibraryResolver::scanLibrariesIfNeeded(PathType PK, size_t BatchSize) { - LLVM_DEBUG(dbgs() << "LibraryResolver::scanLibrariesIfNeeded: Scanning for " - << (PK == PathType::User ? "User" : "System") - << " libraries\n";); - if (!ScanHelper.leftToScan(PK)) - return false; - - LibraryScanner Scanner(ScanHelper, LibMgr, ShouldScanCall); - Scanner.scanNext(PK, BatchSize); - return true; -} - -bool LibraryResolver::symbolExistsInLibrary(const LibraryInfo &Lib, - StringRef SymName, - std::vector<std::string> *AllSyms) { - SymbolEnumeratorOptions Opts; - return symbolExistsInLibrary(Lib, SymName, AllSyms, Opts); -} - -bool LibraryResolver::symbolExistsInLibrary( - const LibraryInfo &Lib, StringRef SymName, - std::vector<std::string> *AllSyms, const SymbolEnumeratorOptions &Opts) { - bool Found = false; - - SymbolEnumerator::enumerateSymbols( - Lib.getFullPath(), - [&](StringRef Sym) { - if (AllSyms) - AllSyms->emplace_back(Sym.str()); - - if (Sym == SymName) { - Found = true; - } - - return EnumerateResult::Continue; - }, - Opts); - - return Found; -} - -} // end namespace llvm::orc diff --git a/llvm/lib/ExecutionEngine/Orc/TargetProcess/LibraryScanner.cpp b/llvm/lib/ExecutionEngine/Orc/TargetProcess/LibraryScanner.cpp deleted file mode 100644 index f1e8b5d..0000000 --- a/llvm/lib/ExecutionEngine/Orc/TargetProcess/LibraryScanner.cpp +++ /dev/null @@ -1,1161 +0,0 @@ -//===- LibraryScanner.cpp - Provide Library Scanning Implementation ----===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "llvm/ExecutionEngine/Orc/TargetProcess/LibraryScanner.h" -#include "llvm/ExecutionEngine/Orc/TargetProcess/LibraryResolver.h" - -#include "llvm/ADT/StringExtras.h" -#include "llvm/Object/COFF.h" -#include "llvm/Object/ELF.h" -#include "llvm/Object/ELFObjectFile.h" -#include "llvm/Object/ELFTypes.h" -#include "llvm/Object/MachO.h" -#include "llvm/Object/MachOUniversal.h" -#include "llvm/Object/ObjectFile.h" -#include "llvm/Support/Error.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/Program.h" -#include "llvm/TargetParser/Host.h" -#include "llvm/TargetParser/Triple.h" - -#ifdef LLVM_ON_UNIX -#include <sys/stat.h> -#include <unistd.h> -#endif // LLVM_ON_UNIX - -#ifdef __APPLE__ -#include <sys/stat.h> -#undef LC_LOAD_DYLIB -#undef LC_RPATH -#endif // __APPLE__ - -#define DEBUG_TYPE "orc-scanner" - -namespace llvm::orc { - -void handleError(Error Err, StringRef context = "") { - consumeError(handleErrors(std::move(Err), [&](const ErrorInfoBase &EIB) { - dbgs() << "LLVM Error"; - if (!context.empty()) - dbgs() << " [" << context << "]"; - dbgs() << ": " << EIB.message() << "\n"; - })); -} - -bool ObjectFileLoader::isArchitectureCompatible(const object::ObjectFile &Obj) { - Triple HostTriple(sys::getDefaultTargetTriple()); - Triple ObjTriple = Obj.makeTriple(); - - LLVM_DEBUG({ - dbgs() << "Host triple: " << HostTriple.str() - << ", Object triple: " << ObjTriple.str() << "\n"; - }); - - if (ObjTriple.getArch() != Triple::UnknownArch && - HostTriple.getArch() != ObjTriple.getArch()) - return false; - - if (ObjTriple.getOS() != Triple::UnknownOS && - HostTriple.getOS() != ObjTriple.getOS()) - return false; - - if (ObjTriple.getEnvironment() != Triple::UnknownEnvironment && - HostTriple.getEnvironment() != Triple::UnknownEnvironment && - HostTriple.getEnvironment() != ObjTriple.getEnvironment()) - return false; - - return true; -} - -Expected<object::OwningBinary<object::ObjectFile>> -ObjectFileLoader::loadObjectFileWithOwnership(StringRef FilePath) { - LLVM_DEBUG(dbgs() << "ObjectFileLoader: Attempting to open file " << FilePath - << "\n";); - auto BinOrErr = object::createBinary(FilePath); - if (!BinOrErr) { - LLVM_DEBUG(dbgs() << "ObjectFileLoader: Failed to open file " << FilePath - << "\n";); - return BinOrErr.takeError(); - } - - LLVM_DEBUG(dbgs() << "ObjectFileLoader: Successfully opened file " << FilePath - << "\n";); - - auto OwningBin = BinOrErr->takeBinary(); - object::Binary *Bin = OwningBin.first.get(); - - if (Bin->isArchive()) { - LLVM_DEBUG(dbgs() << "ObjectFileLoader: File is an archive, not supported: " - << FilePath << "\n";); - return createStringError(std::errc::invalid_argument, - "Archive files are not supported: %s", - FilePath.str().c_str()); - } - -#if defined(__APPLE__) - if (auto *UB = dyn_cast<object::MachOUniversalBinary>(Bin)) { - LLVM_DEBUG(dbgs() << "ObjectFileLoader: Detected Mach-O universal binary: " - << FilePath << "\n";); - for (auto ObjForArch : UB->objects()) { - auto ObjOrErr = ObjForArch.getAsObjectFile(); - if (!ObjOrErr) { - LLVM_DEBUG( - dbgs() - << "ObjectFileLoader: Skipping invalid architecture slice\n";); - - consumeError(ObjOrErr.takeError()); - continue; - } - - std::unique_ptr<object::ObjectFile> Obj = std::move(ObjOrErr.get()); - if (isArchitectureCompatible(*Obj)) { - LLVM_DEBUG( - dbgs() << "ObjectFileLoader: Found compatible object slice\n";); - - return object::OwningBinary<object::ObjectFile>( - std::move(Obj), std::move(OwningBin.second)); - - } else { - LLVM_DEBUG(dbgs() << "ObjectFileLoader: Incompatible architecture " - "slice skipped\n";); - } - } - LLVM_DEBUG(dbgs() << "ObjectFileLoader: No compatible slices found in " - "universal binary\n";); - return createStringError(inconvertibleErrorCode(), - "No compatible object found in fat binary: %s", - FilePath.str().c_str()); - } -#endif - - auto ObjOrErr = - object::ObjectFile::createObjectFile(Bin->getMemoryBufferRef()); - if (!ObjOrErr) { - LLVM_DEBUG(dbgs() << "ObjectFileLoader: Failed to create object file\n";); - return ObjOrErr.takeError(); - } - LLVM_DEBUG(dbgs() << "ObjectFileLoader: Detected object file\n";); - - std::unique_ptr<object::ObjectFile> Obj = std::move(*ObjOrErr); - if (!isArchitectureCompatible(*Obj)) { - LLVM_DEBUG(dbgs() << "ObjectFileLoader: Incompatible architecture: " - << FilePath << "\n";); - return createStringError(inconvertibleErrorCode(), - "Incompatible object file: %s", - FilePath.str().c_str()); - } - - LLVM_DEBUG(dbgs() << "ObjectFileLoader: Object file is compatible\n";); - - return object::OwningBinary<object::ObjectFile>(std::move(Obj), - std::move(OwningBin.second)); -} - -template <class ELFT> -bool isELFSharedLibrary(const object::ELFFile<ELFT> &ELFObj) { - if (ELFObj.getHeader().e_type != ELF::ET_DYN) - return false; - - auto PHOrErr = ELFObj.program_headers(); - if (!PHOrErr) { - consumeError(PHOrErr.takeError()); - return true; - } - - for (auto Phdr : *PHOrErr) { - if (Phdr.p_type == ELF::PT_INTERP) - return false; - } - - return true; -} - -bool isSharedLibraryObject(object::ObjectFile &Obj) { - if (Obj.isELF()) { - if (auto *ELF32LE = dyn_cast<object::ELF32LEObjectFile>(&Obj)) - return isELFSharedLibrary(ELF32LE->getELFFile()); - if (auto *ELF64LE = dyn_cast<object::ELF64LEObjectFile>(&Obj)) - return isELFSharedLibrary(ELF64LE->getELFFile()); - if (auto *ELF32BE = dyn_cast<object::ELF32BEObjectFile>(&Obj)) - return isELFSharedLibrary(ELF32BE->getELFFile()); - if (auto *ELF64BE = dyn_cast<object::ELF64BEObjectFile>(&Obj)) - return isELFSharedLibrary(ELF64BE->getELFFile()); - } else if (Obj.isMachO()) { - const object::MachOObjectFile *MachO = - dyn_cast<object::MachOObjectFile>(&Obj); - if (!MachO) { - LLVM_DEBUG(dbgs() << "Failed to cast to MachOObjectFile.\n";); - return false; - } - LLVM_DEBUG({ - bool Result = - MachO->getHeader().filetype == MachO::HeaderFileType::MH_DYLIB; - dbgs() << "Mach-O filetype: " << MachO->getHeader().filetype - << " (MH_DYLIB == " << MachO::HeaderFileType::MH_DYLIB - << "), shared: " << Result << "\n"; - }); - - return MachO->getHeader().filetype == MachO::HeaderFileType::MH_DYLIB; - } else if (Obj.isCOFF()) { - const object::COFFObjectFile *coff = dyn_cast<object::COFFObjectFile>(&Obj); - if (!coff) - return false; - return coff->getCharacteristics() & COFF::IMAGE_FILE_DLL; - } else { - LLVM_DEBUG(dbgs() << "Binary is not an ObjectFile.\n";); - } - - return false; -} - -bool DylibPathValidator::isSharedLibrary(StringRef Path) { - LLVM_DEBUG(dbgs() << "Checking if path is a shared library: " << Path - << "\n";); - - auto FileType = sys::fs::get_file_type(Path, /*Follow*/ true); - if (FileType != sys::fs::file_type::regular_file) { - LLVM_DEBUG(dbgs() << "File type is not a regular file for path: " << Path - << "\n";); - return false; - } - - file_magic MagicCode; - identify_magic(Path, MagicCode); - - // Skip archives. - if (MagicCode == file_magic::archive) - return false; - - // Universal binary handling. -#if defined(__APPLE__) - if (MagicCode == file_magic::macho_universal_binary) { - ObjectFileLoader ObjLoader(Path); - auto ObjOrErr = ObjLoader.getObjectFile(); - if (!ObjOrErr) { - consumeError(ObjOrErr.takeError()); - return false; - } - return isSharedLibraryObject(ObjOrErr.get()); - } -#endif - - // Object file inspection for PE/COFF, ELF, and Mach-O - bool NeedsObjectInspection = -#if defined(_WIN32) - (MagicCode == file_magic::pecoff_executable); -#elif defined(__APPLE__) - (MagicCode == file_magic::macho_fixed_virtual_memory_shared_lib || - MagicCode == file_magic::macho_dynamically_linked_shared_lib || - MagicCode == file_magic::macho_dynamically_linked_shared_lib_stub); -#elif defined(LLVM_ON_UNIX) -#ifdef __CYGWIN__ - (MagicCode == file_magic::pecoff_executable); -#else - (MagicCode == file_magic::elf_shared_object); -#endif -#else -#error "Unsupported platform." -#endif - - if (NeedsObjectInspection) { - ObjectFileLoader ObjLoader(Path); - auto ObjOrErr = ObjLoader.getObjectFile(); - if (!ObjOrErr) { - consumeError(ObjOrErr.takeError()); - return false; - } - return isSharedLibraryObject(ObjOrErr.get()); - } - - LLVM_DEBUG(dbgs() << "Path is not identified as a shared library: " << Path - << "\n";); - return false; -} - -void DylibSubstitutor::configure(StringRef LoaderPath) { - SmallString<512> ExecPath(sys::fs::getMainExecutable(nullptr, nullptr)); - sys::path::remove_filename(ExecPath); - - SmallString<512> LoaderDir; - if (LoaderPath.empty()) { - LoaderDir = ExecPath; - } else { - LoaderDir = LoaderPath.str(); - if (!sys::fs::is_directory(LoaderPath)) - sys::path::remove_filename(LoaderDir); - } - -#ifdef __APPLE__ - Placeholders["@loader_path"] = std::string(LoaderDir); - Placeholders["@executable_path"] = std::string(ExecPath); -#else - Placeholders["$origin"] = std::string(LoaderDir); -#endif -} - -std::optional<std::string> -SearchPathResolver::resolve(StringRef Stem, const DylibSubstitutor &Subst, - DylibPathValidator &Validator) const { - for (const auto &SP : Paths) { - std::string Base = Subst.substitute(SP); - - SmallString<512> FullPath(Base); - if (!PlaceholderPrefix.empty() && - Stem.starts_with_insensitive(PlaceholderPrefix)) - FullPath.append(Stem.drop_front(PlaceholderPrefix.size())); - else - sys::path::append(FullPath, Stem); - - LLVM_DEBUG(dbgs() << "SearchPathResolver::resolve FullPath = " << FullPath - << "\n";); - - if (auto Valid = Validator.validate(FullPath.str())) - return Valid; - } - - return std::nullopt; -} - -std::optional<std::string> -DylibResolverImpl::tryWithExtensions(StringRef LibStem) const { - LLVM_DEBUG(dbgs() << "tryWithExtensions: baseName = " << LibStem << "\n";); - SmallVector<SmallString<256>, 8> Candidates; - - // Add extensions by platform -#if defined(__APPLE__) - Candidates.emplace_back(LibStem); - Candidates.back() += ".dylib"; -#elif defined(_WIN32) - Candidates.emplace_back(LibStem); - Candidates.back() += ".dll"; -#else - Candidates.emplace_back(LibStem); - Candidates.back() += ".so"; -#endif - - // Optionally try "lib" prefix if not already there - StringRef FileName = sys::path::filename(LibStem); - StringRef Base = sys::path::parent_path(LibStem); - if (!FileName.starts_with("lib")) { - SmallString<256> WithPrefix(Base); - if (!WithPrefix.empty()) - sys::path::append(WithPrefix, ""); // ensure separator if needed - WithPrefix += "lib"; - WithPrefix += FileName; - -#if defined(__APPLE__) - WithPrefix += ".dylib"; -#elif defined(_WIN32) - WithPrefix += ".dll"; -#else - WithPrefix += ".so"; -#endif - - Candidates.push_back(std::move(WithPrefix)); - } - - LLVM_DEBUG({ - dbgs() << " Candidates to try:\n"; - for (const auto &C : Candidates) - dbgs() << " " << C << "\n"; - }); - - // Try all variants using tryAllPaths - for (const auto &Name : Candidates) { - - LLVM_DEBUG(dbgs() << " Trying candidate: " << Name << "\n";); - - for (const auto &R : Resolvers) { - if (auto Res = R.resolve(Name, Substitutor, Validator)) - return Res; - } - } - - LLVM_DEBUG(dbgs() << " -> No candidate Resolved.\n";); - - return std::nullopt; -} - -std::optional<std::string> -DylibResolverImpl::resolve(StringRef LibStem, bool VariateLibStem) const { - LLVM_DEBUG(dbgs() << "Resolving library stem: " << LibStem << "\n";); - - // If it is an absolute path, don't try iterate over the paths. - if (sys::path::is_absolute(LibStem)) { - LLVM_DEBUG(dbgs() << " -> Absolute path detected.\n";); - return Validator.validate(LibStem); - } - - if (!LibStem.starts_with_insensitive("@rpath")) { - if (auto norm = Validator.validate(Substitutor.substitute(LibStem))) { - LLVM_DEBUG(dbgs() << " -> Resolved after substitution: " << *norm - << "\n";); - - return norm; - } - } - - for (const auto &R : Resolvers) { - LLVM_DEBUG(dbgs() << " -> Resolving via search path ... \n";); - if (auto Result = R.resolve(LibStem, Substitutor, Validator)) { - LLVM_DEBUG(dbgs() << " -> Resolved via search path: " << *Result - << "\n";); - - return Result; - } - } - - // Expand libStem with paths, extensions, etc. - // std::string foundName; - if (VariateLibStem) { - LLVM_DEBUG(dbgs() << " -> Trying with extensions...\n";); - - if (auto Norm = tryWithExtensions(LibStem)) { - LLVM_DEBUG(dbgs() << " -> Resolved via tryWithExtensions: " << *Norm - << "\n";); - - return Norm; - } - } - - LLVM_DEBUG(dbgs() << " -> Could not resolve: " << LibStem << "\n";); - - return std::nullopt; -} - -#ifndef _WIN32 -mode_t PathResolver::lstatCached(StringRef Path) { - // If already cached - retun cached result - if (auto Cache = LibPathCache->read_lstat(Path)) - return *Cache; - - // Not cached: perform lstat and store - struct stat buf{}; - mode_t st_mode = (lstat(Path.str().c_str(), &buf) == -1) ? 0 : buf.st_mode; - - LibPathCache->insert_lstat(Path, st_mode); - - return st_mode; -} - -std::optional<std::string> PathResolver::readlinkCached(StringRef Path) { - // If already cached - retun cached result - if (auto Cache = LibPathCache->read_link(Path)) - return Cache; - - // If result not in cache - call system function and cache result - char buf[PATH_MAX]; - ssize_t len; - if ((len = readlink(Path.str().c_str(), buf, sizeof(buf))) != -1) { - buf[len] = '\0'; - std::string s(buf); - LibPathCache->insert_link(Path, s); - return s; - } - return std::nullopt; -} - -void createComponent(StringRef Path, StringRef BasePath, bool BaseIsResolved, - SmallVector<StringRef, 16> &Component) { - StringRef Separator = sys::path::get_separator(); - if (!BaseIsResolved) { - if (Path[0] == '~' && - (Path.size() == 1 || sys::path::is_separator(Path[1]))) { - static SmallString<128> HomeP; - if (HomeP.str().empty()) - sys::path::home_directory(HomeP); - StringRef(HomeP).split(Component, Separator, /*MaxSplit*/ -1, - /*KeepEmpty*/ false); - } else if (BasePath.empty()) { - static SmallString<256> CurrentPath; - if (CurrentPath.str().empty()) - sys::fs::current_path(CurrentPath); - StringRef(CurrentPath) - .split(Component, Separator, /*MaxSplit*/ -1, /*KeepEmpty*/ false); - } else { - BasePath.split(Component, Separator, /*MaxSplit*/ -1, - /*KeepEmpty*/ false); - } - } - - Path.split(Component, Separator, /*MaxSplit*/ -1, /*KeepEmpty*/ false); -} - -void normalizePathSegments(SmallVector<StringRef, 16> &PathParts) { - SmallVector<StringRef, 16> NormalizedPath; - for (auto &Part : PathParts) { - if (Part == ".") { - continue; - } else if (Part == "..") { - if (!NormalizedPath.empty() && NormalizedPath.back() != "..") { - NormalizedPath.pop_back(); - } else { - NormalizedPath.push_back(".."); - } - } else { - NormalizedPath.push_back(Part); - } - } - PathParts.swap(NormalizedPath); -} -#endif - -std::optional<std::string> PathResolver::realpathCached(StringRef Path, - std::error_code &EC, - StringRef Base, - bool BaseIsResolved, - long SymLoopLevel) { - EC.clear(); - - if (Path.empty()) { - EC = std::make_error_code(std::errc::no_such_file_or_directory); - LLVM_DEBUG(dbgs() << "PathResolver::realpathCached: Empty path\n";); - - return std::nullopt; - } - - if (SymLoopLevel <= 0) { - EC = std::make_error_code(std::errc::too_many_symbolic_link_levels); - LLVM_DEBUG( - dbgs() << "PathResolver::realpathCached: Too many Symlink levels: " - << Path << "\n";); - - return std::nullopt; - } - - // If already cached - retun cached result - bool isRelative = sys::path::is_relative(Path); - if (!isRelative) { - if (auto Cached = LibPathCache->read_realpath(Path)) { - EC = Cached->ErrnoCode; - if (EC) { - LLVM_DEBUG(dbgs() << "PathResolver::realpathCached: Cached (error) for " - << Path << "\n";); - } else { - LLVM_DEBUG( - dbgs() << "PathResolver::realpathCached: Cached (success) for " - << Path << " => " << Cached->canonicalPath << "\n";); - } - return Cached->canonicalPath.empty() - ? std::nullopt - : std::make_optional(Cached->canonicalPath); - } - } - - LLVM_DEBUG(dbgs() << "PathResolver::realpathCached: Resolving path: " << Path - << "\n";); - - // If result not in cache - call system function and cache result - - StringRef Separator(sys::path::get_separator()); - SmallString<256> Resolved(Separator); -#ifndef _WIN32 - SmallVector<StringRef, 16> Components; - - if (isRelative) { - if (BaseIsResolved) { - Resolved.assign(Base); - LLVM_DEBUG(dbgs() << " Using Resolved base: " << Base << "\n";); - } - createComponent(Path, Base, BaseIsResolved, Components); - } else { - Path.split(Components, Separator, /*MaxSplit*/ -1, /*KeepEmpty*/ false); - } - - normalizePathSegments(Components); - LLVM_DEBUG({ - for (auto &C : Components) - dbgs() << " " << C << " "; - - dbgs() << "\n"; - }); - - // Handle path list items - for (const auto &Component : Components) { - if (Component == ".") - continue; - if (Component == "..") { - // collapse "a/b/../c" to "a/c" - size_t S = Resolved.rfind(Separator); - if (S != llvm::StringRef::npos) - Resolved.resize(S); - if (Resolved.empty()) - Resolved = Separator; - continue; - } - - size_t oldSize = Resolved.size(); - sys::path::append(Resolved, Component); - const char *ResolvedPath = Resolved.c_str(); - LLVM_DEBUG(dbgs() << " Processing Component: " << Component << " => " - << ResolvedPath << "\n";); - mode_t st_mode = lstatCached(ResolvedPath); - - if (S_ISLNK(st_mode)) { - LLVM_DEBUG(dbgs() << " Found symlink: " << ResolvedPath << "\n";); - - auto SymlinkOpt = readlinkCached(ResolvedPath); - if (!SymlinkOpt) { - EC = std::make_error_code(std::errc::no_such_file_or_directory); - LibPathCache->insert_realpath(Path, LibraryPathCache::PathInfo{"", EC}); - LLVM_DEBUG(dbgs() << " Failed to read symlink: " << ResolvedPath - << "\n";); - - return std::nullopt; - } - - StringRef Symlink = *SymlinkOpt; - LLVM_DEBUG(dbgs() << " Symlink points to: " << Symlink << "\n";); - - std::string resolvedBase = ""; - if (sys::path::is_relative(Symlink)) { - Resolved.resize(oldSize); - resolvedBase = Resolved.str().str(); - } - - auto RealSymlink = - realpathCached(Symlink, EC, resolvedBase, - /*BaseIsResolved=*/true, SymLoopLevel - 1); - if (!RealSymlink) { - LibPathCache->insert_realpath(Path, LibraryPathCache::PathInfo{"", EC}); - LLVM_DEBUG(dbgs() << " Failed to resolve symlink target: " << Symlink - << "\n";); - - return std::nullopt; - } - - Resolved.assign(*RealSymlink); - LLVM_DEBUG(dbgs() << " Symlink Resolved to: " << Resolved << "\n";); - - } else if (st_mode == 0) { - EC = std::make_error_code(std::errc::no_such_file_or_directory); - LibPathCache->insert_realpath(Path, LibraryPathCache::PathInfo{"", EC}); - LLVM_DEBUG(dbgs() << " Component does not exist: " << ResolvedPath - << "\n";); - - return std::nullopt; - } - } -#else - sys::fs::real_path(Path, Resolved); // Windows fallback -#endif - - std::string Canonical = Resolved.str().str(); - { - LibPathCache->insert_realpath(Path, LibraryPathCache::PathInfo{ - Canonical, - std::error_code() // success - }); - } - LLVM_DEBUG(dbgs() << "PathResolver::realpathCached: Final Resolved: " << Path - << " => " << Canonical << "\n";); - return Canonical; -} - -void LibraryScanHelper::addBasePath(const std::string &Path, PathType K) { - std::error_code EC; - std::string Canon = resolveCanonical(Path, EC); - if (EC) { - LLVM_DEBUG( - dbgs() - << "LibraryScanHelper::addBasePath: Failed to canonicalize path: " - << Path << "\n";); - return; - } - std::unique_lock<std::shared_mutex> Lock(Mtx); - if (LibSearchPaths.count(Canon)) { - LLVM_DEBUG(dbgs() << "LibraryScanHelper::addBasePath: Already added: " - << Canon << "\n";); - return; - } - K = K == PathType::Unknown ? classifyKind(Canon) : K; - auto SP = std::make_shared<LibrarySearchPath>(Canon, K); - LibSearchPaths[Canon] = SP; - - if (K == PathType::User) { - LLVM_DEBUG(dbgs() << "LibraryScanHelper::addBasePath: Added User path: " - << Canon << "\n";); - UnscannedUsr.push_back(StringRef(SP->BasePath)); - } else { - LLVM_DEBUG(dbgs() << "LibraryScanHelper::addBasePath: Added System path: " - << Canon << "\n";); - UnscannedSys.push_back(StringRef(SP->BasePath)); - } -} - -std::vector<std::shared_ptr<LibrarySearchPath>> -LibraryScanHelper::getNextBatch(PathType K, size_t BatchSize) { - std::vector<std::shared_ptr<LibrarySearchPath>> Result; - auto &Queue = (K == PathType::User) ? UnscannedUsr : UnscannedSys; - - std::unique_lock<std::shared_mutex> Lock(Mtx); - - while (!Queue.empty() && (BatchSize == 0 || Result.size() < BatchSize)) { - StringRef Base = Queue.front(); - auto It = LibSearchPaths.find(Base); - if (It != LibSearchPaths.end()) { - auto &SP = It->second; - ScanState Expected = ScanState::NotScanned; - if (SP->State.compare_exchange_strong(Expected, ScanState::Scanning)) { - Result.push_back(SP); - } - } - Queue.pop_front(); - } - - return Result; -} - -bool LibraryScanHelper::isTrackedBasePath(StringRef Path) const { - std::error_code EC; - std::string Canon = resolveCanonical(Path, EC); - if (EC) - return false; - - std::shared_lock<std::shared_mutex> Lock(Mtx); - return LibSearchPaths.count(Canon) > 0; -} - -bool LibraryScanHelper::leftToScan(PathType K) const { - std::shared_lock<std::shared_mutex> Lock(Mtx); - for (const auto &KV : LibSearchPaths) { - const auto &SP = KV.second; - if (SP->Kind == K && SP->State == ScanState::NotScanned) - return true; - } - return false; -} - -void LibraryScanHelper::resetToScan() { - std::shared_lock<std::shared_mutex> Lock(Mtx); - - for (auto &[_, SP] : LibSearchPaths) { - ScanState Expected = ScanState::Scanned; - - if (!SP->State.compare_exchange_strong(Expected, ScanState::NotScanned)) - continue; - - auto &TargetList = - (SP->Kind == PathType::User) ? UnscannedUsr : UnscannedSys; - TargetList.emplace_back(SP->BasePath); - } -} - -std::vector<std::shared_ptr<LibrarySearchPath>> -LibraryScanHelper::getAllUnits() const { - std::shared_lock<std::shared_mutex> Lock(Mtx); - std::vector<std::shared_ptr<LibrarySearchPath>> Result; - Result.reserve(LibSearchPaths.size()); - for (const auto &[_, SP] : LibSearchPaths) { - Result.push_back(SP); - } - return Result; -} - -std::string LibraryScanHelper::resolveCanonical(StringRef Path, - std::error_code &EC) const { - auto Canon = LibPathResolver->resolve(Path, EC); - return EC ? Path.str() : *Canon; -} - -PathType LibraryScanHelper::classifyKind(StringRef Path) const { - // Detect home directory - const char *Home = getenv("HOME"); - if (Home && Path.find(Home) == 0) - return PathType::User; - - static const std::array<std::string, 5> UserPrefixes = { - "/usr/local", // often used by users for manual installs - "/opt/homebrew", // common on macOS - "/opt/local", // MacPorts - "/home", // Linux home dirs - "/Users", // macOS user dirs - }; - - for (const auto &Prefix : UserPrefixes) { - if (Path.find(Prefix) == 0) - return PathType::User; - } - - return PathType::System; -} - -Expected<LibraryDepsInfo> parseMachODeps(const object::MachOObjectFile &Obj) { - LibraryDepsInfo Libdeps; - LLVM_DEBUG(dbgs() << "Parsing Mach-O dependencies...\n";); - for (const auto &Command : Obj.load_commands()) { - switch (Command.C.cmd) { - case MachO::LC_LOAD_DYLIB: { - MachO::dylib_command dylibCmd = Obj.getDylibIDLoadCommand(Command); - const char *name = Command.Ptr + dylibCmd.dylib.name; - Libdeps.addDep(name); - LLVM_DEBUG(dbgs() << " Found LC_LOAD_DYLIB: " << name << "\n";); - } break; - case MachO::LC_LOAD_WEAK_DYLIB: - case MachO::LC_REEXPORT_DYLIB: - case MachO::LC_LOAD_UPWARD_DYLIB: - case MachO::LC_LAZY_LOAD_DYLIB: - break; - case MachO::LC_RPATH: { - // Extract RPATH - MachO::rpath_command rpathCmd = Obj.getRpathCommand(Command); - const char *rpath = Command.Ptr + rpathCmd.path; - LLVM_DEBUG(dbgs() << " Found LC_RPATH: " << rpath << "\n";); - - SmallVector<StringRef, 4> RawPaths; - SplitString(StringRef(rpath), RawPaths, - sys::EnvPathSeparator == ':' ? ":" : ";"); - - for (const auto &raw : RawPaths) { - Libdeps.addRPath(raw.str()); // Convert to std::string - LLVM_DEBUG(dbgs() << " Parsed RPATH entry: " << raw << "\n";); - } - break; - } - } - } - - return Expected<LibraryDepsInfo>(std::move(Libdeps)); -} - -template <class ELFT> -static Expected<StringRef> getDynamicStrTab(const object::ELFFile<ELFT> &Elf) { - auto DynamicEntriesOrError = Elf.dynamicEntries(); - if (!DynamicEntriesOrError) - return DynamicEntriesOrError.takeError(); - - for (const typename ELFT::Dyn &Dyn : *DynamicEntriesOrError) { - if (Dyn.d_tag == ELF::DT_STRTAB) { - auto MappedAddrOrError = Elf.toMappedAddr(Dyn.getPtr()); - if (!MappedAddrOrError) - return MappedAddrOrError.takeError(); - return StringRef(reinterpret_cast<const char *>(*MappedAddrOrError)); - } - } - - // If the dynamic segment is not present, we fall back on the sections. - auto SectionsOrError = Elf.sections(); - if (!SectionsOrError) - return SectionsOrError.takeError(); - - for (const typename ELFT::Shdr &Sec : *SectionsOrError) { - if (Sec.sh_type == ELF::SHT_DYNSYM) - return Elf.getStringTableForSymtab(Sec); - } - - return make_error<StringError>("dynamic string table not found", - inconvertibleErrorCode()); -} - -template <typename ELFT> -Expected<LibraryDepsInfo> parseELF(const object::ELFFile<ELFT> &Elf) { - LibraryDepsInfo Deps; - Expected<StringRef> StrTabOrErr = getDynamicStrTab(Elf); - if (!StrTabOrErr) - return StrTabOrErr.takeError(); - - const char *Data = StrTabOrErr->data(); - - auto DynamicEntriesOrError = Elf.dynamicEntries(); - if (!DynamicEntriesOrError) { - return DynamicEntriesOrError.takeError(); - } - - for (const typename ELFT::Dyn &Dyn : *DynamicEntriesOrError) { - switch (Dyn.d_tag) { - case ELF::DT_NEEDED: - Deps.addDep(Data + Dyn.d_un.d_val); - break; - case ELF::DT_RPATH: { - SmallVector<StringRef, 4> RawPaths; - SplitString(Data + Dyn.d_un.d_val, RawPaths, - sys::EnvPathSeparator == ':' ? ":" : ";"); - for (const auto &raw : RawPaths) - Deps.addRPath(raw.str()); - break; - } - case ELF::DT_RUNPATH: { - SmallVector<StringRef, 4> RawPaths; - SplitString(Data + Dyn.d_un.d_val, RawPaths, - sys::EnvPathSeparator == ':' ? ":" : ";"); - for (const auto &raw : RawPaths) - Deps.addRunPath(raw.str()); - break; - } - case ELF::DT_FLAGS_1: - // Check if this is not a pie executable. - if (Dyn.d_un.d_val & ELF::DF_1_PIE) - Deps.isPIE = true; - break; - // (Dyn.d_tag == ELF::DT_NULL) continue; - // (Dyn.d_tag == ELF::DT_AUXILIARY || Dyn.d_tag == ELF::DT_FILTER) - default: - break; - } - } - - return Expected<LibraryDepsInfo>(std::move(Deps)); -} - -Expected<LibraryDepsInfo> parseELFDeps(const object::ELFObjectFileBase &Obj) { - using namespace object; - LLVM_DEBUG(dbgs() << "parseELFDeps: Detected ELF object\n";); - if (const auto *ELF = dyn_cast<ELF32LEObjectFile>(&Obj)) - return parseELF(ELF->getELFFile()); - else if (const auto *ELF = dyn_cast<ELF32BEObjectFile>(&Obj)) - return parseELF(ELF->getELFFile()); - else if (const auto *ELF = dyn_cast<ELF64LEObjectFile>(&Obj)) - return parseELF(ELF->getELFFile()); - else if (const auto *ELF = dyn_cast<ELF64BEObjectFile>(&Obj)) - return parseELF(ELF->getELFFile()); - - LLVM_DEBUG(dbgs() << "parseELFDeps: Unknown ELF format\n";); - return createStringError(std::errc::not_supported, "Unknown ELF format"); -} - -Expected<LibraryDepsInfo> LibraryScanner::extractDeps(StringRef FilePath) { - LLVM_DEBUG(dbgs() << "extractDeps: Attempting to open file " << FilePath - << "\n";); - - ObjectFileLoader ObjLoader(FilePath); - auto ObjOrErr = ObjLoader.getObjectFile(); - if (!ObjOrErr) { - LLVM_DEBUG(dbgs() << "extractDeps: Failed to open " << FilePath << "\n";); - return ObjOrErr.takeError(); - } - - object::ObjectFile *Obj = &ObjOrErr.get(); - - if (auto *elfObj = dyn_cast<object::ELFObjectFileBase>(Obj)) { - LLVM_DEBUG(dbgs() << "extractDeps: File " << FilePath - << " is an ELF object\n";); - - return parseELFDeps(*elfObj); - } - - if (auto *macho = dyn_cast<object::MachOObjectFile>(Obj)) { - LLVM_DEBUG(dbgs() << "extractDeps: File " << FilePath - << " is a Mach-O object\n";); - return parseMachODeps(*macho); - } - - if (Obj->isCOFF()) { - // TODO: COFF support - return LibraryDepsInfo(); - } - - LLVM_DEBUG(dbgs() << "extractDeps: Unsupported binary format for file " - << FilePath << "\n";); - return createStringError(inconvertibleErrorCode(), - "Unsupported binary format: %s", - FilePath.str().c_str()); -} - -std::optional<std::string> LibraryScanner::shouldScan(StringRef FilePath) { - std::error_code EC; - - LLVM_DEBUG(dbgs() << "[shouldScan] Checking: " << FilePath << "\n";); - - // [1] Check file existence early - if (!sys::fs::exists(FilePath)) { - LLVM_DEBUG(dbgs() << " -> Skipped: file does not exist.\n";); - - return std::nullopt; - } - - // [2] Resolve to canonical path - auto CanonicalPathOpt = ScanHelper.resolve(FilePath, EC); - if (EC || !CanonicalPathOpt) { - LLVM_DEBUG(dbgs() << " -> Skipped: failed to resolve path (EC=" - << EC.message() << ").\n";); - - return std::nullopt; - } - - const std::string &CanonicalPath = *CanonicalPathOpt; - LLVM_DEBUG(dbgs() << " -> Canonical path: " << CanonicalPath << "\n"); - - // [3] Check if it's a directory — skip directories - if (sys::fs::is_directory(CanonicalPath)) { - LLVM_DEBUG(dbgs() << " -> Skipped: path is a directory.\n";); - - return std::nullopt; - } - - // [4] Skip if it's not a shared library. - if (!DylibPathValidator::isSharedLibrary(CanonicalPath)) { - LLVM_DEBUG(dbgs() << " -> Skipped: not a shared library.\n";); - return std::nullopt; - } - - // [5] Skip if we've already seen this path (via cache) - if (ScanHelper.hasSeenOrMark(CanonicalPath)) { - LLVM_DEBUG(dbgs() << " -> Skipped: already seen.\n";); - - return std::nullopt; - } - - // [6] Already tracked in LibraryManager? - if (LibMgr.hasLibrary(CanonicalPath)) { - LLVM_DEBUG(dbgs() << " -> Skipped: already tracked by LibraryManager.\n";); - - return std::nullopt; - } - - // [7] Run user-defined hook (default: always true) - if (!ShouldScanCall(CanonicalPath)) { - LLVM_DEBUG(dbgs() << " -> Skipped: user-defined hook rejected.\n";); - - return std::nullopt; - } - - LLVM_DEBUG(dbgs() << " -> Accepted: ready to scan " << CanonicalPath - << "\n";); - return CanonicalPath; -} - -void LibraryScanner::handleLibrary(StringRef FilePath, PathType K, int level) { - LLVM_DEBUG(dbgs() << "LibraryScanner::handleLibrary: Scanning: " << FilePath - << ", level=" << level << "\n";); - auto CanonPathOpt = shouldScan(FilePath); - if (!CanonPathOpt) { - LLVM_DEBUG(dbgs() << " Skipped (shouldScan returned false): " << FilePath - << "\n";); - - return; - } - const std::string CanonicalPath = *CanonPathOpt; - - auto DepsOrErr = extractDeps(CanonicalPath); - if (!DepsOrErr) { - LLVM_DEBUG(dbgs() << " Failed to extract deps for: " << CanonicalPath - << "\n";); - handleError(DepsOrErr.takeError()); - return; - } - - LibraryDepsInfo &Deps = *DepsOrErr; - - LLVM_DEBUG({ - dbgs() << " Found deps : \n"; - for (const auto &dep : Deps.deps) - dbgs() << " : " << dep << "\n"; - dbgs() << " Found @rpath : " << Deps.rpath.size() << "\n"; - for (const auto &r : Deps.rpath) - dbgs() << " : " << r << "\n"; - dbgs() << " Found @runpath : \n"; - for (const auto &r : Deps.runPath) - dbgs() << " : " << r << "\n"; - }); - - if (Deps.isPIE && level == 0) { - LLVM_DEBUG(dbgs() << " Skipped PIE executable at top level: " - << CanonicalPath << "\n";); - - return; - } - - bool Added = LibMgr.addLibrary(CanonicalPath, K); - if (!Added) { - LLVM_DEBUG(dbgs() << " Already added: " << CanonicalPath << "\n";); - return; - } - - // Heuristic 1: No RPATH/RUNPATH, skip deps - if (Deps.rpath.empty() && Deps.runPath.empty()) { - LLVM_DEBUG( - dbgs() << "LibraryScanner::handleLibrary: Skipping deps (Heuristic1): " - << CanonicalPath << "\n";); - return; - } - - // Heuristic 2: All RPATH and RUNPATH already tracked - auto allTracked = [&](const auto &Paths) { - LLVM_DEBUG(dbgs() << " Checking : " << Paths.size() << "\n";); - return std::all_of(Paths.begin(), Paths.end(), [&](StringRef P) { - LLVM_DEBUG(dbgs() << " Checking isTrackedBasePath : " << P << "\n";); - return ScanHelper.isTrackedBasePath( - DylibResolver::resolvelinkerFlag(P, CanonicalPath)); - }); - }; - - if (allTracked(Deps.rpath) && allTracked(Deps.runPath)) { - LLVM_DEBUG( - dbgs() << "LibraryScanner::handleLibrary: Skipping deps (Heuristic2): " - << CanonicalPath << "\n";); - return; - } - - DylibPathValidator Validator(ScanHelper.getPathResolver()); - DylibResolver Resolver(Validator); - Resolver.configure(CanonicalPath, - {{Deps.rpath, SearchPathType::RPath}, - {ScanHelper.getSearchPaths(), SearchPathType::UsrOrSys}, - {Deps.runPath, SearchPathType::RunPath}}); - for (StringRef Dep : Deps.deps) { - LLVM_DEBUG(dbgs() << " Resolving dep: " << Dep << "\n";); - auto DepFullOpt = Resolver.resolve(Dep); - if (!DepFullOpt) { - LLVM_DEBUG(dbgs() << " Failed to resolve dep: " << Dep << "\n";); - - continue; - } - LLVM_DEBUG(dbgs() << " Resolved dep to: " << *DepFullOpt << "\n";); - - handleLibrary(*DepFullOpt, K, level + 1); - } -} - -void LibraryScanner::scanBaseDir(std::shared_ptr<LibrarySearchPath> SP) { - if (!sys::fs::is_directory(SP->BasePath) || SP->BasePath.empty()) { - LLVM_DEBUG( - dbgs() << "LibraryScanner::scanBaseDir: Invalid or empty basePath: " - << SP->BasePath << "\n";); - return; - } - - LLVM_DEBUG(dbgs() << "LibraryScanner::scanBaseDir: Scanning directory: " - << SP->BasePath << "\n";); - std::error_code EC; - - SP->State.store(ScanState::Scanning); - - for (sys::fs::directory_iterator It(SP->BasePath, EC), end; It != end && !EC; - It.increment(EC)) { - auto Entry = *It; - if (!Entry.status()) - continue; - - auto Status = *Entry.status(); - if (sys::fs::is_regular_file(Status) || sys::fs::is_symlink_file(Status)) { - LLVM_DEBUG(dbgs() << " Found file: " << Entry.path() << "\n";); - // async support ? - handleLibrary(Entry.path(), SP->Kind); - } - } - - SP->State.store(ScanState::Scanned); -} - -void LibraryScanner::scanNext(PathType K, size_t BatchSize) { - LLVM_DEBUG(dbgs() << "LibraryScanner::scanNext: Scanning next batch of size " - << BatchSize << " for kind " - << (K == PathType::User ? "User" : "System") << "\n";); - - auto SearchPaths = ScanHelper.getNextBatch(K, BatchSize); - for (auto &SP : SearchPaths) { - LLVM_DEBUG(dbgs() << " Scanning unit with basePath: " << SP->BasePath - << "\n";); - - scanBaseDir(SP); - } -} - -} // end namespace llvm::orc diff --git a/llvm/lib/IR/DebugProgramInstruction.cpp b/llvm/lib/IR/DebugProgramInstruction.cpp index 2b9b0f9..d9357bb 100644 --- a/llvm/lib/IR/DebugProgramInstruction.cpp +++ b/llvm/lib/IR/DebugProgramInstruction.cpp @@ -665,11 +665,11 @@ void DbgMarker::eraseFromParent() { } iterator_range<DbgRecord::self_iterator> DbgMarker::getDbgRecordRange() { - return make_range(StoredDbgRecords.begin(), StoredDbgRecords.end()); + return StoredDbgRecords; } iterator_range<DbgRecord::const_self_iterator> DbgMarker::getDbgRecordRange() const { - return make_range(StoredDbgRecords.begin(), StoredDbgRecords.end()); + return StoredDbgRecords; } void DbgRecord::removeFromParent() { diff --git a/llvm/lib/MC/MCParser/MasmParser.cpp b/llvm/lib/MC/MCParser/MasmParser.cpp index d4901d9..8a8f111 100644 --- a/llvm/lib/MC/MCParser/MasmParser.cpp +++ b/llvm/lib/MC/MCParser/MasmParser.cpp @@ -5844,11 +5844,11 @@ bool MasmParser::lookUpField(const StructInfo &Structure, StringRef Member, bool MasmParser::lookUpType(StringRef Name, AsmTypeInfo &Info) const { unsigned Size = StringSwitch<unsigned>(Name) - .CasesLower("byte", "db", "sbyte", 1) - .CasesLower("word", "dw", "sword", 2) - .CasesLower("dword", "dd", "sdword", 4) - .CasesLower("fword", "df", 6) - .CasesLower("qword", "dq", "sqword", 8) + .CasesLower({"byte", "db", "sbyte"}, 1) + .CasesLower({"word", "dw", "sword"}, 2) + .CasesLower({"dword", "dd", "sdword"}, 4) + .CasesLower({"fword", "df"}, 6) + .CasesLower({"qword", "dq", "sqword"}, 8) .CaseLower("real4", 4) .CaseLower("real8", 8) .CaseLower("real10", 10) diff --git a/llvm/lib/Support/SpecialCaseList.cpp b/llvm/lib/Support/SpecialCaseList.cpp index f74e52a..3a97185 100644 --- a/llvm/lib/Support/SpecialCaseList.cpp +++ b/llvm/lib/Support/SpecialCaseList.cpp @@ -89,14 +89,36 @@ void SpecialCaseList::GlobMatcher::preprocess(bool BySize) { return A.Name.size() < B.Name.size(); }); } + + for (const auto &G : reverse(Globs)) { + StringRef Prefix = G.Pattern.prefix(); + StringRef Suffix = G.Pattern.suffix(); + + auto &SToGlob = PrefixSuffixToGlob.emplace(Prefix).first->second; + auto &V = SToGlob.emplace(reverse(Suffix)).first->second; + V.emplace_back(&G); + } } void SpecialCaseList::GlobMatcher::match( StringRef Query, llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const { - for (const auto &G : reverse(Globs)) - if (G.Pattern.match(Query)) - return Cb(G.Name, G.LineNo); + if (!PrefixSuffixToGlob.empty()) { + for (const auto &[_, SToGlob] : PrefixSuffixToGlob.find_prefixes(Query)) { + for (const auto &[_, V] : SToGlob.find_prefixes(reverse(Query))) { + for (const auto *G : V) { + if (G->Pattern.match(Query)) { + Cb(G->Name, G->LineNo); + // As soon as we find a match in the vector, we can break for this + // vector, since the globs are already sorted by priority within the + // prefix group. However, we continue searching other prefix groups + // in the map, as they may contain a better match overall. + break; + } + } + } + } + } } SpecialCaseList::Matcher::Matcher(bool UseGlobs, bool RemoveDotSlash) diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp index d5117da..457e540 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -5151,7 +5151,15 @@ void AArch64InstrInfo::copyPhysReg(MachineBasicBlock &MBB, // GPR32 zeroing if (AArch64::GPR32spRegClass.contains(DestReg) && SrcReg == AArch64::WZR) { - if (Subtarget.hasZeroCycleZeroingGPR32()) { + if (Subtarget.hasZeroCycleZeroingGPR64() && + !Subtarget.hasZeroCycleZeroingGPR32()) { + MCRegister DestRegX = RI.getMatchingSuperReg(DestReg, AArch64::sub_32, + &AArch64::GPR64spRegClass); + assert(DestRegX.isValid() && "Destination super-reg not valid"); + BuildMI(MBB, I, DL, get(AArch64::MOVZXi), DestRegX) + .addImm(0) + .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSL, 0)); + } else if (Subtarget.hasZeroCycleZeroingGPR32()) { BuildMI(MBB, I, DL, get(AArch64::MOVZWi), DestReg) .addImm(0) .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSL, 0)); diff --git a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h index d1832f4..f680a5e 100644 --- a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h +++ b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h @@ -651,7 +651,7 @@ struct AArch64FunctionInfo final : public yaml::MachineFunctionInfo { AArch64FunctionInfo(const llvm::AArch64FunctionInfo &MFI); void mappingImpl(yaml::IO &YamlIO) override; - ~AArch64FunctionInfo() = default; + ~AArch64FunctionInfo() override = default; }; template <> struct MappingTraits<AArch64FunctionInfo> { diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.h b/llvm/lib/Target/AArch64/AArch64RegisterInfo.h index 72a7676..47d76f3 100644 --- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.h +++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.h @@ -154,7 +154,7 @@ public: bool shouldAnalyzePhysregInMachineLoopInfo(MCRegister R) const override; - virtual bool isIgnoredCVReg(MCRegister LLVMReg) const override; + bool isIgnoredCVReg(MCRegister LLVMReg) const override; }; } // end namespace llvm diff --git a/llvm/lib/Target/AMDGPU/AMDGPUHSAMetadataStreamer.h b/llvm/lib/Target/AMDGPU/AMDGPUHSAMetadataStreamer.h index 1b4b113..6bad4dbd 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUHSAMetadataStreamer.h +++ b/llvm/lib/Target/AMDGPU/AMDGPUHSAMetadataStreamer.h @@ -131,7 +131,7 @@ protected: public: MetadataStreamerMsgPackV4() = default; - ~MetadataStreamerMsgPackV4() = default; + ~MetadataStreamerMsgPackV4() override = default; bool emitTo(AMDGPUTargetStreamer &TargetStreamer) override; @@ -154,7 +154,7 @@ protected: public: MetadataStreamerMsgPackV5() = default; - ~MetadataStreamerMsgPackV5() = default; + ~MetadataStreamerMsgPackV5() override = default; }; class MetadataStreamerMsgPackV6 final : public MetadataStreamerMsgPackV5 { @@ -163,7 +163,7 @@ protected: public: MetadataStreamerMsgPackV6() = default; - ~MetadataStreamerMsgPackV6() = default; + ~MetadataStreamerMsgPackV6() override = default; void emitKernelAttrs(const AMDGPUTargetMachine &TM, const MachineFunction &MF, msgpack::MapDocNode Kern) override; diff --git a/llvm/lib/Target/AMDGPU/AMDGPUMIRFormatter.h b/llvm/lib/Target/AMDGPU/AMDGPUMIRFormatter.h index c5c9473..0804133 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUMIRFormatter.h +++ b/llvm/lib/Target/AMDGPU/AMDGPUMIRFormatter.h @@ -26,20 +26,19 @@ struct PerFunctionMIParsingState; class AMDGPUMIRFormatter final : public MIRFormatter { public: AMDGPUMIRFormatter() = default; - virtual ~AMDGPUMIRFormatter() = default; + ~AMDGPUMIRFormatter() override = default; /// Implement target specific printing for machine operand immediate value, so /// that we can have more meaningful mnemonic than a 64-bit integer. Passing /// None to OpIdx means the index is unknown. - virtual void printImm(raw_ostream &OS, const MachineInstr &MI, - std::optional<unsigned> OpIdx, - int64_t Imm) const override; + void printImm(raw_ostream &OS, const MachineInstr &MI, + std::optional<unsigned> OpIdx, int64_t Imm) const override; /// Implement target specific parsing of immediate mnemonics. The mnemonic is /// a string with a leading dot. - virtual bool parseImmMnemonic(const unsigned OpCode, const unsigned OpIdx, - StringRef Src, int64_t &Imm, - ErrorCallbackType ErrorCallback) const override; + bool parseImmMnemonic(const unsigned OpCode, const unsigned OpIdx, + StringRef Src, int64_t &Imm, + ErrorCallbackType ErrorCallback) const override; /// Implement target specific parsing of target custom pseudo source value. bool diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp index 02c5390..6214f4d 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp @@ -740,7 +740,7 @@ static StringRef getGPUOrDefault(const Triple &TT, StringRef GPU) { return "r600"; } -static Reloc::Model getEffectiveRelocModel(std::optional<Reloc::Model> RM) { +static Reloc::Model getEffectiveRelocModel() { // The AMDGPU toolchain only supports generating shared objects, so we // must always use PIC. return Reloc::PIC_; @@ -754,8 +754,8 @@ AMDGPUTargetMachine::AMDGPUTargetMachine(const Target &T, const Triple &TT, CodeGenOptLevel OptLevel) : CodeGenTargetMachineImpl( T, TT.computeDataLayout(), TT, getGPUOrDefault(TT, CPU), FS, Options, - getEffectiveRelocModel(RM), - getEffectiveCodeModel(CM, CodeModel::Small), OptLevel), + getEffectiveRelocModel(), getEffectiveCodeModel(CM, CodeModel::Small), + OptLevel), TLOF(createTLOF(getTargetTriple())) { initAsmInfo(); if (TT.isAMDGCN()) { diff --git a/llvm/lib/Target/AMDGPU/MCA/AMDGPUCustomBehaviour.h b/llvm/lib/Target/AMDGPU/MCA/AMDGPUCustomBehaviour.h index cbc7427..4d0c163 100644 --- a/llvm/lib/Target/AMDGPU/MCA/AMDGPUCustomBehaviour.h +++ b/llvm/lib/Target/AMDGPU/MCA/AMDGPUCustomBehaviour.h @@ -32,7 +32,7 @@ public: AMDGPUInstrPostProcess(const MCSubtargetInfo &STI, const MCInstrInfo &MCII) : InstrPostProcess(STI, MCII) {} - ~AMDGPUInstrPostProcess() = default; + ~AMDGPUInstrPostProcess() override = default; void postProcessInstruction(Instruction &Inst, const MCInst &MCI) override; }; @@ -88,7 +88,7 @@ public: AMDGPUCustomBehaviour(const MCSubtargetInfo &STI, const mca::SourceMgr &SrcMgr, const MCInstrInfo &MCII); - ~AMDGPUCustomBehaviour() = default; + ~AMDGPUCustomBehaviour() override = default; /// This method is used to determine if an instruction /// should be allowed to be dispatched. The return value is /// how many cycles until the instruction can be dispatched. diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.h b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.h index 54fcd2a..246a3f8 100644 --- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.h +++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.h @@ -64,7 +64,7 @@ private: ArrayRef<const MCExpr *> Args; AMDGPUMCExpr(VariantKind Kind, ArrayRef<const MCExpr *> Args, MCContext &Ctx); - ~AMDGPUMCExpr(); + ~AMDGPUMCExpr() override; bool evaluateExtraSGPRs(MCValue &Res, const MCAssembler *Asm) const; bool evaluateTotalNumVGPR(MCValue &Res, const MCAssembler *Asm) const; diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.h b/llvm/lib/Target/AMDGPU/SIInstrInfo.h index 5fdedda..dc23a21 100644 --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.h +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.h @@ -1640,7 +1640,7 @@ public: unsigned *PredCost = nullptr) const override; InstructionUniformity - getInstructionUniformity(const MachineInstr &MI) const override final; + getInstructionUniformity(const MachineInstr &MI) const final; InstructionUniformity getGenericInstructionUniformity(const MachineInstr &MI) const; diff --git a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h index 2c1a13c..019c3b7 100644 --- a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h +++ b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h @@ -311,7 +311,7 @@ struct SIMachineFunctionInfo final : public yaml::MachineFunctionInfo { const llvm::MachineFunction &MF); void mappingImpl(yaml::IO &YamlIO) override; - ~SIMachineFunctionInfo() = default; + ~SIMachineFunctionInfo() override = default; }; template <> struct MappingTraits<SIMachineFunctionInfo> { diff --git a/llvm/lib/Target/AMDGPU/SIMemoryLegalizer.cpp b/llvm/lib/Target/AMDGPU/SIMemoryLegalizer.cpp index 07264d9..a177a42 100644 --- a/llvm/lib/Target/AMDGPU/SIMemoryLegalizer.cpp +++ b/llvm/lib/Target/AMDGPU/SIMemoryLegalizer.cpp @@ -640,7 +640,7 @@ public: bool finalizeStore(MachineInstr &MI, bool Atomic) const override; - virtual bool handleCooperativeAtomic(MachineInstr &MI) const override; + bool handleCooperativeAtomic(MachineInstr &MI) const override; bool insertRelease(MachineBasicBlock::iterator &MI, SIAtomicScope Scope, SIAtomicAddrSpace AddrSpace, bool IsCrossAddrSpaceOrdering, diff --git a/llvm/lib/Target/ARM/ARMConstantPoolValue.h b/llvm/lib/Target/ARM/ARMConstantPoolValue.h index 261070a..e21b2c9 100644 --- a/llvm/lib/Target/ARM/ARMConstantPoolValue.h +++ b/llvm/lib/Target/ARM/ARMConstantPoolValue.h @@ -176,9 +176,7 @@ public: using promoted_iterator = SmallPtrSet<const GlobalVariable *, 1>::iterator; - iterator_range<promoted_iterator> promotedGlobals() { - return iterator_range<promoted_iterator>(GVars.begin(), GVars.end()); - } + iterator_range<promoted_iterator> promotedGlobals() { return GVars; } const Constant *getPromotedGlobalInit() const { return CVal; diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td index 53be167..10d4cd5 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.td +++ b/llvm/lib/Target/ARM/ARMInstrInfo.td @@ -6546,23 +6546,25 @@ def KCFI_CHECK_ARM : PseudoInst<(outs), (ins GPR:$ptr, i32imm:$type), NoItinerary, []>, Sched<[]>, Requires<[IsARM]> { - let Size = 28; // 7 instructions (bic, ldr, 4x eor, beq, udf) + let Size = 40; // worst-case 10 instructions @ 4 bytes each + // (push, bic, ldr, 4x eor, pop, beq, udf) } def KCFI_CHECK_Thumb2 : PseudoInst<(outs), (ins GPR:$ptr, i32imm:$type), NoItinerary, []>, Sched<[]>, Requires<[IsThumb2]> { - let Size = - 32; // worst-case 9 instructions (push, bic, ldr, 4x eor, pop, beq.w, udf) + let Size = 34; // worst-case (push.w[2], bic[4], ldr[4], 4x eor[16], pop.w[2], + // beq.w[4], udf[2]) } def KCFI_CHECK_Thumb1 : PseudoInst<(outs), (ins GPR:$ptr, i32imm:$type), NoItinerary, []>, Sched<[]>, Requires<[IsThumb1Only]> { - let Size = 50; // worst-case 25 instructions (pushes, bic helper, type - // building, cmp, pops) + let Size = 38; // worst-case 19 instructions @ 2 bytes each + // (2x push, 3x bic-helper, subs+ldr, 13x type-building, cmp, + // 2x pop, beq, bkpt) } //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/ARM/ARMMachineFunctionInfo.h b/llvm/lib/Target/ARM/ARMMachineFunctionInfo.h index a9c4b53..72eb3d0 100644 --- a/llvm/lib/Target/ARM/ARMMachineFunctionInfo.h +++ b/llvm/lib/Target/ARM/ARMMachineFunctionInfo.h @@ -312,7 +312,7 @@ struct ARMFunctionInfo final : public yaml::MachineFunctionInfo { ARMFunctionInfo(const llvm::ARMFunctionInfo &MFI); void mappingImpl(yaml::IO &YamlIO) override; - ~ARMFunctionInfo() = default; + ~ARMFunctionInfo() override = default; }; template <> struct MappingTraits<ARMFunctionInfo> { diff --git a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp index 3a840a3..5548ad1 100644 --- a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp +++ b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp @@ -40,7 +40,7 @@ class AVRDisassembler : public MCDisassembler { public: AVRDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) : MCDisassembler(STI, Ctx) {} - virtual ~AVRDisassembler() = default; + ~AVRDisassembler() override = default; DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, ArrayRef<uint8_t> Bytes, uint64_t Address, diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRELFObjectWriter.cpp b/llvm/lib/Target/AVR/MCTargetDesc/AVRELFObjectWriter.cpp index 619efb3..03c60e8 100644 --- a/llvm/lib/Target/AVR/MCTargetDesc/AVRELFObjectWriter.cpp +++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRELFObjectWriter.cpp @@ -24,7 +24,7 @@ class AVRELFObjectWriter : public MCELFObjectTargetWriter { public: AVRELFObjectWriter(uint8_t OSABI); - virtual ~AVRELFObjectWriter() = default; + ~AVRELFObjectWriter() override = default; unsigned getRelocType(const MCFixup &, const MCValue &, bool IsPCRel) const override; diff --git a/llvm/lib/Target/BPF/BPFAsmPrinter.h b/llvm/lib/Target/BPF/BPFAsmPrinter.h index 0cfb283..90ef207 100644 --- a/llvm/lib/Target/BPF/BPFAsmPrinter.h +++ b/llvm/lib/Target/BPF/BPFAsmPrinter.h @@ -32,7 +32,7 @@ public: void emitInstruction(const MachineInstr *MI) override; MCSymbol *getJTPublicSymbol(unsigned JTI); - virtual void emitJumpTableInfo() override; + void emitJumpTableInfo() override; static char ID; diff --git a/llvm/lib/Target/BPF/BPFCheckAndAdjustIR.cpp b/llvm/lib/Target/BPF/BPFCheckAndAdjustIR.cpp index e3c39a1..b12985d 100644 --- a/llvm/lib/Target/BPF/BPFCheckAndAdjustIR.cpp +++ b/llvm/lib/Target/BPF/BPFCheckAndAdjustIR.cpp @@ -46,7 +46,7 @@ class BPFCheckAndAdjustIR final : public ModulePass { public: static char ID; BPFCheckAndAdjustIR() : ModulePass(ID) {} - virtual void getAnalysisUsage(AnalysisUsage &AU) const override; + void getAnalysisUsage(AnalysisUsage &AU) const override; private: void checkIR(Module &M); diff --git a/llvm/lib/Target/BPF/BPFTargetLoweringObjectFile.h b/llvm/lib/Target/BPF/BPFTargetLoweringObjectFile.h index f3064c0c..af3542e 100644 --- a/llvm/lib/Target/BPF/BPFTargetLoweringObjectFile.h +++ b/llvm/lib/Target/BPF/BPFTargetLoweringObjectFile.h @@ -16,7 +16,7 @@ namespace llvm { class BPFTargetLoweringObjectFileELF : public TargetLoweringObjectFileELF { public: - virtual MCSection * + MCSection * getSectionForJumpTable(const Function &F, const TargetMachine &TM, const MachineJumpTableEntry *JTE) const override; }; diff --git a/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp b/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp index c5e26c1..9de4c9d 100644 --- a/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp @@ -62,8 +62,7 @@ static cl::opt<bool> cl::desc("Enable the merge base offset pass"), cl::init(true), cl::Hidden); -static Reloc::Model getEffectiveRelocModel(const Triple &TT, - std::optional<Reloc::Model> RM) { +static Reloc::Model getEffectiveRelocModel(std::optional<Reloc::Model> RM) { return RM.value_or(Reloc::Static); } @@ -92,7 +91,7 @@ LoongArchTargetMachine::LoongArchTargetMachine( const TargetOptions &Options, std::optional<Reloc::Model> RM, std::optional<CodeModel::Model> CM, CodeGenOptLevel OL, bool JIT) : CodeGenTargetMachineImpl(T, TT.computeDataLayout(), TT, CPU, FS, Options, - getEffectiveRelocModel(TT, RM), + getEffectiveRelocModel(RM), getEffectiveLoongArchCodeModel(TT, CM), OL), TLOF(std::make_unique<TargetLoweringObjectFileELF>()) { initAsmInfo(); diff --git a/llvm/lib/Target/M68k/M68kTargetMachine.cpp b/llvm/lib/Target/M68k/M68kTargetMachine.cpp index 847c27ba..f525d43 100644 --- a/llvm/lib/Target/M68k/M68kTargetMachine.cpp +++ b/llvm/lib/Target/M68k/M68kTargetMachine.cpp @@ -46,13 +46,9 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeM68kTarget() { namespace { -Reloc::Model getEffectiveRelocModel(const Triple &TT, - std::optional<Reloc::Model> RM) { +Reloc::Model getEffectiveRelocModel(std::optional<Reloc::Model> RM) { // If not defined we default to static - if (!RM.has_value()) - return Reloc::Static; - - return *RM; + return RM.value_or(Reloc::Static); } CodeModel::Model getEffectiveCodeModel(std::optional<CodeModel::Model> CM, @@ -73,7 +69,7 @@ M68kTargetMachine::M68kTargetMachine(const Target &T, const Triple &TT, std::optional<CodeModel::Model> CM, CodeGenOptLevel OL, bool JIT) : CodeGenTargetMachineImpl(T, TT.computeDataLayout(), TT, CPU, FS, Options, - getEffectiveRelocModel(TT, RM), + getEffectiveRelocModel(RM), ::getEffectiveCodeModel(CM, JIT), OL), TLOF(std::make_unique<M68kELFTargetObjectFile>()), Subtarget(TT, CPU, FS, *this) { diff --git a/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp b/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp index 4aecaf1..8e791e6 100644 --- a/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp +++ b/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp @@ -635,7 +635,7 @@ public: B.setChangeObserver(*this); } - ~InstManager() { B.stopObservingChanges(); } + ~InstManager() override { B.stopObservingChanges(); } void createdInstr(MachineInstr &MI) override { InstList.insert(&MI); } void erasingInstr(MachineInstr &MI) override {} diff --git a/llvm/lib/Target/RISCV/MCA/RISCVCustomBehaviour.h b/llvm/lib/Target/RISCV/MCA/RISCVCustomBehaviour.h index 34efa0b..4ccd3cf 100644 --- a/llvm/lib/Target/RISCV/MCA/RISCVCustomBehaviour.h +++ b/llvm/lib/Target/RISCV/MCA/RISCVCustomBehaviour.h @@ -33,7 +33,7 @@ public: explicit RISCVLMULInstrument(StringRef Data) : Instrument(DESC_NAME, Data) {} - ~RISCVLMULInstrument() = default; + ~RISCVLMULInstrument() override = default; uint8_t getLMUL() const; }; @@ -45,7 +45,7 @@ public: explicit RISCVSEWInstrument(StringRef Data) : Instrument(DESC_NAME, Data) {} - ~RISCVSEWInstrument() = default; + ~RISCVSEWInstrument() override = default; uint8_t getSEW() const; }; diff --git a/llvm/lib/Target/RISCV/RISCVConstantPoolValue.h b/llvm/lib/Target/RISCV/RISCVConstantPoolValue.h index b69904d..b2ce57a 100644 --- a/llvm/lib/Target/RISCV/RISCVConstantPoolValue.h +++ b/llvm/lib/Target/RISCV/RISCVConstantPoolValue.h @@ -37,7 +37,7 @@ private: RISCVCPKind Kind; public: - ~RISCVConstantPoolValue() = default; + ~RISCVConstantPoolValue() override = default; static RISCVConstantPoolValue *Create(const GlobalValue *GV); static RISCVConstantPoolValue *Create(LLVMContext &C, StringRef S); diff --git a/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h b/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h index 4fa93f1..f9be80f 100644 --- a/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h +++ b/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h @@ -31,7 +31,7 @@ struct RISCVMachineFunctionInfo final : public yaml::MachineFunctionInfo { RISCVMachineFunctionInfo(const llvm::RISCVMachineFunctionInfo &MFI); void mappingImpl(yaml::IO &YamlIO) override; - ~RISCVMachineFunctionInfo() = default; + ~RISCVMachineFunctionInfo() override = default; }; template <> struct MappingTraits<RISCVMachineFunctionInfo> { diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp index f81b1e12..ae54ff1 100644 --- a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp +++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp @@ -141,8 +141,7 @@ extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() { initializeRISCVAsmPrinterPass(*PR); } -static Reloc::Model getEffectiveRelocModel(const Triple &TT, - std::optional<Reloc::Model> RM) { +static Reloc::Model getEffectiveRelocModel(std::optional<Reloc::Model> RM) { return RM.value_or(Reloc::Static); } @@ -154,7 +153,7 @@ RISCVTargetMachine::RISCVTargetMachine(const Target &T, const Triple &TT, CodeGenOptLevel OL, bool JIT) : CodeGenTargetMachineImpl( T, TT.computeDataLayout(Options.MCOptions.getABIName()), TT, CPU, FS, - Options, getEffectiveRelocModel(TT, RM), + Options, getEffectiveRelocModel(RM), getEffectiveCodeModel(CM, CodeModel::Small), OL), TLOF(std::make_unique<RISCVELFTargetObjectFile>()) { initAsmInfo(); diff --git a/llvm/lib/Target/SPIRV/SPIRVLegalizePointerCast.cpp b/llvm/lib/Target/SPIRV/SPIRVLegalizePointerCast.cpp index 28a1690..6e444c9 100644 --- a/llvm/lib/Target/SPIRV/SPIRVLegalizePointerCast.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVLegalizePointerCast.cpp @@ -347,7 +347,7 @@ class SPIRVLegalizePointerCast : public FunctionPass { public: SPIRVLegalizePointerCast(SPIRVTargetMachine *TM) : FunctionPass(ID), TM(TM) {} - virtual bool runOnFunction(Function &F) override { + bool runOnFunction(Function &F) override { const SPIRVSubtarget &ST = TM->getSubtarget<SPIRVSubtarget>(F); GR = ST.getSPIRVGlobalRegistry(); DeadInstructions.clear(); diff --git a/llvm/lib/Target/SPIRV/SPIRVMergeRegionExitTargets.cpp b/llvm/lib/Target/SPIRV/SPIRVMergeRegionExitTargets.cpp index 60d39c9..aba9cf7 100644 --- a/llvm/lib/Target/SPIRV/SPIRVMergeRegionExitTargets.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVMergeRegionExitTargets.cpp @@ -234,7 +234,7 @@ public: } #endif - virtual bool runOnFunction(Function &F) override { + bool runOnFunction(Function &F) override { LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); auto *TopLevelRegion = getAnalysis<SPIRVConvergenceRegionAnalysisWrapperPass>() diff --git a/llvm/lib/Target/SPIRV/SPIRVStripConvergentIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVStripConvergentIntrinsics.cpp index e621bcd44..b1a8d1a 100644 --- a/llvm/lib/Target/SPIRV/SPIRVStripConvergentIntrinsics.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVStripConvergentIntrinsics.cpp @@ -28,7 +28,7 @@ public: SPIRVStripConvergentIntrinsics() : FunctionPass(ID) {} - virtual bool runOnFunction(Function &F) override { + bool runOnFunction(Function &F) override { DenseSet<Instruction *> ToRemove; // Is the instruction is a convergent intrinsic, add it to kill-list and diff --git a/llvm/lib/Target/SPIRV/SPIRVStructurizer.cpp b/llvm/lib/Target/SPIRV/SPIRVStructurizer.cpp index 5b149f8..ea634fb 100644 --- a/llvm/lib/Target/SPIRV/SPIRVStructurizer.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVStructurizer.cpp @@ -1113,7 +1113,7 @@ public: SPIRVStructurizer() : FunctionPass(ID) {} - virtual bool runOnFunction(Function &F) override { + bool runOnFunction(Function &F) override { bool Modified = false; // In LLVM, Switches are allowed to have several cases branching to the same diff --git a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp index e585e5a..b4dadaa 100644 --- a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp +++ b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp @@ -36,7 +36,7 @@ class SparcDisassembler : public MCDisassembler { public: SparcDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) : MCDisassembler(STI, Ctx) {} - virtual ~SparcDisassembler() = default; + ~SparcDisassembler() override = default; DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, ArrayRef<uint8_t> Bytes, uint64_t Address, diff --git a/llvm/lib/Target/SystemZ/SystemZMachineScheduler.h b/llvm/lib/Target/SystemZ/SystemZMachineScheduler.h index 1ff6cc8..ba325b5 100644 --- a/llvm/lib/Target/SystemZ/SystemZMachineScheduler.h +++ b/llvm/lib/Target/SystemZ/SystemZMachineScheduler.h @@ -111,7 +111,7 @@ class SystemZPostRASchedStrategy : public MachineSchedStrategy { public: SystemZPostRASchedStrategy(const MachineSchedContext *C); - virtual ~SystemZPostRASchedStrategy(); + ~SystemZPostRASchedStrategy() override; /// Called for a region before scheduling. void initPolicy(MachineBasicBlock::iterator Begin, diff --git a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.h b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.h index b1de145..bea8b9f 100644 --- a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.h +++ b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.h @@ -101,7 +101,7 @@ public: int getStackPointerBias() final { return 2048; } /// Destroys the object. Bogus destructor overriding base class destructor - ~SystemZXPLINK64Registers() = default; + ~SystemZXPLINK64Registers() override = default; }; /// ELF calling convention specific use registers @@ -124,7 +124,7 @@ public: int getStackPointerBias() final { return 0; } /// Destroys the object. Bogus destructor overriding base class destructor - ~SystemZELFRegisters() = default; + ~SystemZELFRegisters() override = default; }; struct SystemZRegisterInfo : public SystemZGenRegisterInfo { diff --git a/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp b/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp index aad826b..465e074 100644 --- a/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp +++ b/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp @@ -36,7 +36,7 @@ class VEDisassembler : public MCDisassembler { public: VEDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) : MCDisassembler(STI, Ctx) {} - virtual ~VEDisassembler() = default; + ~VEDisassembler() override = default; DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, ArrayRef<uint8_t> Bytes, uint64_t Address, diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp index 45bbf12..9175b27 100644 --- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp +++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp @@ -102,7 +102,7 @@ struct WebAssemblyOperand : public MCParsedAsmOperand { WebAssemblyOperand(SMLoc Start, SMLoc End, CaLOp C) : Kind(CatchList), StartLoc(Start), EndLoc(End), CaL(C) {} - ~WebAssemblyOperand() { + ~WebAssemblyOperand() override { if (isBrList()) BrL.~BrLOp(); if (isCatchList()) diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h b/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h index 40ae4ae..ff4d6469 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h +++ b/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h @@ -192,7 +192,7 @@ struct WebAssemblyFunctionInfo final : public yaml::MachineFunctionInfo { const llvm::WebAssemblyFunctionInfo &MFI); void mappingImpl(yaml::IO &YamlIO) override; - ~WebAssemblyFunctionInfo() = default; + ~WebAssemblyFunctionInfo() override = default; }; template <> struct MappingTraits<WebAssemblyFunctionInfo> { diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp index a9c638c..621640c 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp @@ -127,16 +127,11 @@ LLVMInitializeWebAssemblyTarget() { // WebAssembly Lowering public interface. //===----------------------------------------------------------------------===// -static Reloc::Model getEffectiveRelocModel(std::optional<Reloc::Model> RM, - const Triple &TT) { - if (!RM) { - // Default to static relocation model. This should always be more optimial - // than PIC since the static linker can determine all global addresses and - // assume direct function calls. - return Reloc::Static; - } - - return *RM; +static Reloc::Model getEffectiveRelocModel(std::optional<Reloc::Model> RM) { + // Default to static relocation model. This should always be more optimial + // than PIC since the static linker can determine all global addresses and + // assume direct function calls. + return RM.value_or(Reloc::Static); } using WebAssembly::WasmEnableEH; @@ -197,7 +192,7 @@ WebAssemblyTargetMachine::WebAssemblyTargetMachine( const TargetOptions &Options, std::optional<Reloc::Model> RM, std::optional<CodeModel::Model> CM, CodeGenOptLevel OL, bool JIT) : CodeGenTargetMachineImpl(T, TT.computeDataLayout(), TT, CPU, FS, Options, - getEffectiveRelocModel(RM, TT), + getEffectiveRelocModel(RM), getEffectiveCodeModel(CM, CodeModel::Large), OL), TLOF(new WebAssemblyTargetObjectFile()), UsesMultivalueABI(Options.MCOptions.getABIName() == "experimental-mv") { diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp index ac251fd..127ee67 100644 --- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -3533,10 +3533,10 @@ bool X86AsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name, while (isLockRepeatNtPrefix(Name.lower())) { unsigned Prefix = StringSwitch<unsigned>(Name) - .Cases("lock", "lock", X86::IP_HAS_LOCK) - .Cases("rep", "repe", "repz", X86::IP_HAS_REPEAT) - .Cases("repne", "repnz", X86::IP_HAS_REPEAT_NE) - .Cases("notrack", "notrack", X86::IP_HAS_NOTRACK) + .Case("lock", X86::IP_HAS_LOCK) + .Cases({"rep", "repe", "repz"}, X86::IP_HAS_REPEAT) + .Cases({"repne", "repnz"}, X86::IP_HAS_REPEAT_NE) + .Case("notrack", X86::IP_HAS_NOTRACK) .Default(X86::IP_NO_PREFIX); // Invalid prefix (impossible) Flags |= Prefix; if (getLexer().is(AsmToken::EndOfStatement)) { diff --git a/llvm/lib/Target/X86/MCA/X86CustomBehaviour.h b/llvm/lib/Target/X86/MCA/X86CustomBehaviour.h index d6197f3..05a1c22 100644 --- a/llvm/lib/Target/X86/MCA/X86CustomBehaviour.h +++ b/llvm/lib/Target/X86/MCA/X86CustomBehaviour.h @@ -37,7 +37,7 @@ public: X86InstrPostProcess(const MCSubtargetInfo &STI, const MCInstrInfo &MCII) : InstrPostProcess(STI, MCII) {} - ~X86InstrPostProcess() = default; + ~X86InstrPostProcess() override = default; void postProcessInstruction(Instruction &Inst, const MCInst &MCI) override; }; diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp index 1c06dc4..af5a698 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp @@ -491,7 +491,7 @@ namespace X86_MC { class X86MCInstrAnalysis : public MCInstrAnalysis { X86MCInstrAnalysis(const X86MCInstrAnalysis &) = delete; X86MCInstrAnalysis &operator=(const X86MCInstrAnalysis &) = delete; - virtual ~X86MCInstrAnalysis() = default; + ~X86MCInstrAnalysis() override = default; public: X86MCInstrAnalysis(const MCInstrInfo *MCII) : MCInstrAnalysis(MCII) {} diff --git a/llvm/lib/Target/X86/X86.h b/llvm/lib/Target/X86/X86.h index 6261fad..706ab2b 100644 --- a/llvm/lib/Target/X86/X86.h +++ b/llvm/lib/Target/X86/X86.h @@ -160,6 +160,14 @@ FunctionPass *createX86PartialReductionPass(); /// // Analyzes and emits pseudos to support Win x64 Unwind V2. FunctionPass *createX86WinEHUnwindV2Pass(); +/// The pass transforms load/store <256 x i32> to AMX load/store intrinsics +/// or split the data to two <128 x i32>. +FunctionPass *createX86LowerAMXTypePass(); + +/// The pass transforms amx intrinsics to scalar operation if the function has +/// optnone attribute or it is O0. +FunctionPass *createX86LowerAMXIntrinsicsPass(); + InstructionSelector *createX86InstructionSelector(const X86TargetMachine &TM, const X86Subtarget &, const X86RegisterBankInfo &); diff --git a/llvm/lib/Target/X86/X86DomainReassignment.cpp b/llvm/lib/Target/X86/X86DomainReassignment.cpp index 339e2f3..5d19011 100644 --- a/llvm/lib/Target/X86/X86DomainReassignment.cpp +++ b/llvm/lib/Target/X86/X86DomainReassignment.cpp @@ -324,9 +324,7 @@ public: bool insertEdge(Register Reg) { return Edges.insert(Reg).second; } using const_edge_iterator = DenseSet<Register>::const_iterator; - iterator_range<const_edge_iterator> edges() const { - return iterator_range<const_edge_iterator>(Edges.begin(), Edges.end()); - } + iterator_range<const_edge_iterator> edges() const { return Edges; } void addInstruction(MachineInstr *I) { Instrs.push_back(I); diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp index 62073ec..4393f6e 100644 --- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -4721,9 +4721,6 @@ bool X86DAGToDAGISel::tryVPTERNLOG(SDNode *N) { if (!(Subtarget->hasVLX() || NVT.is512BitVector())) return false; - SDValue N0 = N->getOperand(0); - SDValue N1 = N->getOperand(1); - auto getFoldableLogicOp = [](SDValue Op) { // Peek through single use bitcast. if (Op.getOpcode() == ISD::BITCAST && Op.hasOneUse()) @@ -4740,13 +4737,47 @@ bool X86DAGToDAGISel::tryVPTERNLOG(SDNode *N) { return SDValue(); }; - SDValue A, FoldableOp; - if ((FoldableOp = getFoldableLogicOp(N1))) { - A = N0; - } else if ((FoldableOp = getFoldableLogicOp(N0))) { - A = N1; - } else - return false; + SDValue N0, N1, A, FoldableOp; + + // Identify and (optionally) peel an outer NOT that wraps a pure logic tree + auto tryPeelOuterNotWrappingLogic = [&](SDNode *Op) { + if (Op->getOpcode() == ISD::XOR && Op->hasOneUse() && + ISD::isBuildVectorAllOnes(Op->getOperand(1).getNode())) { + SDValue InnerOp = Op->getOperand(0); + + if (!getFoldableLogicOp(InnerOp)) + return SDValue(); + + N0 = InnerOp.getOperand(0); + N1 = InnerOp.getOperand(1); + if ((FoldableOp = getFoldableLogicOp(N1))) { + A = N0; + return InnerOp; + } + if ((FoldableOp = getFoldableLogicOp(N0))) { + A = N1; + return InnerOp; + } + } + return SDValue(); + }; + + bool PeeledOuterNot = false; + SDNode *OriN = N; + if (SDValue InnerOp = tryPeelOuterNotWrappingLogic(N)) { + PeeledOuterNot = true; + N = InnerOp.getNode(); + } else { + N0 = N->getOperand(0); + N1 = N->getOperand(1); + + if ((FoldableOp = getFoldableLogicOp(N1))) + A = N0; + else if ((FoldableOp = getFoldableLogicOp(N0))) + A = N1; + else + return false; + } SDValue B = FoldableOp.getOperand(0); SDValue C = FoldableOp.getOperand(1); @@ -4798,7 +4829,10 @@ bool X86DAGToDAGISel::tryVPTERNLOG(SDNode *N) { case ISD::XOR: Imm ^= TernlogMagicA; break; } - return matchVPTERNLOG(N, ParentA, ParentB, ParentC, A, B, C, Imm); + if (PeeledOuterNot) + Imm = ~Imm; + + return matchVPTERNLOG(OriN, ParentA, ParentB, ParentC, A, B, C, Imm); } /// If the high bits of an 'and' operand are known zero, try setting the diff --git a/llvm/lib/Target/X86/X86MachineFunctionInfo.h b/llvm/lib/Target/X86/X86MachineFunctionInfo.h index 5f974e5..1bda505 100644 --- a/llvm/lib/Target/X86/X86MachineFunctionInfo.h +++ b/llvm/lib/Target/X86/X86MachineFunctionInfo.h @@ -43,7 +43,7 @@ struct X86MachineFunctionInfo final : public yaml::MachineFunctionInfo { X86MachineFunctionInfo(const llvm::X86MachineFunctionInfo &MFI); void mappingImpl(yaml::IO &YamlIO) override; - ~X86MachineFunctionInfo() = default; + ~X86MachineFunctionInfo() override = default; }; template <> struct MappingTraits<X86MachineFunctionInfo> { diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp index 077d29f..3b59ebb 100644 --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -272,6 +272,9 @@ AA::getInitialValueForObj(Attributor &A, const AbstractAttribute &QueryingAA, } if (RangePtr && !RangePtr->offsetOrSizeAreUnknown()) { + int64_t StorageSize = DL.getTypeStoreSize(&Ty); + if (StorageSize != RangePtr->Size) + return nullptr; APInt Offset = APInt(64, RangePtr->Offset); return ConstantFoldLoadFromConst(Initializer, &Ty, Offset, DL); } diff --git a/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp b/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp index fe66f13..4db92e7 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp @@ -89,6 +89,60 @@ const SCEV *vputils::getSCEVExprForVPValue(VPValue *V, ScalarEvolution &SE) { .Default([&SE](const VPRecipeBase *) { return SE.getCouldNotCompute(); }); } +bool vputils::isSingleScalar(const VPValue *VPV) { + auto PreservesUniformity = [](unsigned Opcode) -> bool { + if (Instruction::isBinaryOp(Opcode) || Instruction::isCast(Opcode)) + return true; + switch (Opcode) { + case Instruction::GetElementPtr: + case Instruction::ICmp: + case Instruction::FCmp: + case Instruction::Select: + case VPInstruction::Not: + case VPInstruction::Broadcast: + case VPInstruction::PtrAdd: + return true; + default: + return false; + } + }; + + // A live-in must be uniform across the scope of VPlan. + if (VPV->isLiveIn()) + return true; + + if (auto *Rep = dyn_cast<VPReplicateRecipe>(VPV)) { + const VPRegionBlock *RegionOfR = Rep->getRegion(); + // Don't consider recipes in replicate regions as uniform yet; their first + // lane cannot be accessed when executing the replicate region for other + // lanes. + if (RegionOfR && RegionOfR->isReplicator()) + return false; + return Rep->isSingleScalar() || (PreservesUniformity(Rep->getOpcode()) && + all_of(Rep->operands(), isSingleScalar)); + } + if (isa<VPWidenGEPRecipe, VPDerivedIVRecipe, VPBlendRecipe, + VPWidenSelectRecipe>(VPV)) + return all_of(VPV->getDefiningRecipe()->operands(), isSingleScalar); + if (auto *WidenR = dyn_cast<VPWidenRecipe>(VPV)) { + return PreservesUniformity(WidenR->getOpcode()) && + all_of(WidenR->operands(), isSingleScalar); + } + if (auto *VPI = dyn_cast<VPInstruction>(VPV)) + return VPI->isSingleScalar() || VPI->isVectorToScalar() || + (PreservesUniformity(VPI->getOpcode()) && + all_of(VPI->operands(), isSingleScalar)); + if (isa<VPPartialReductionRecipe>(VPV)) + return false; + if (isa<VPReductionRecipe>(VPV)) + return true; + if (auto *Expr = dyn_cast<VPExpressionRecipe>(VPV)) + return Expr->isSingleScalar(); + + // VPExpandSCEVRecipes must be placed in the entry and are always uniform. + return isa<VPExpandSCEVRecipe>(VPV); +} + bool vputils::isUniformAcrossVFsAndUFs(VPValue *V) { // Live-ins are uniform. if (V->isLiveIn()) diff --git a/llvm/lib/Transforms/Vectorize/VPlanUtils.h b/llvm/lib/Transforms/Vectorize/VPlanUtils.h index 840a5b9..37cd413 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanUtils.h +++ b/llvm/lib/Transforms/Vectorize/VPlanUtils.h @@ -41,59 +41,7 @@ const SCEV *getSCEVExprForVPValue(VPValue *V, ScalarEvolution &SE); /// Returns true if \p VPV is a single scalar, either because it produces the /// same value for all lanes or only has its first lane used. -inline bool isSingleScalar(const VPValue *VPV) { - auto PreservesUniformity = [](unsigned Opcode) -> bool { - if (Instruction::isBinaryOp(Opcode) || Instruction::isCast(Opcode)) - return true; - switch (Opcode) { - case Instruction::GetElementPtr: - case Instruction::ICmp: - case Instruction::FCmp: - case Instruction::Select: - case VPInstruction::Not: - case VPInstruction::Broadcast: - case VPInstruction::PtrAdd: - return true; - default: - return false; - } - }; - - // A live-in must be uniform across the scope of VPlan. - if (VPV->isLiveIn()) - return true; - - if (auto *Rep = dyn_cast<VPReplicateRecipe>(VPV)) { - const VPRegionBlock *RegionOfR = Rep->getRegion(); - // Don't consider recipes in replicate regions as uniform yet; their first - // lane cannot be accessed when executing the replicate region for other - // lanes. - if (RegionOfR && RegionOfR->isReplicator()) - return false; - return Rep->isSingleScalar() || (PreservesUniformity(Rep->getOpcode()) && - all_of(Rep->operands(), isSingleScalar)); - } - if (isa<VPWidenGEPRecipe, VPDerivedIVRecipe, VPBlendRecipe, - VPWidenSelectRecipe>(VPV)) - return all_of(VPV->getDefiningRecipe()->operands(), isSingleScalar); - if (auto *WidenR = dyn_cast<VPWidenRecipe>(VPV)) { - return PreservesUniformity(WidenR->getOpcode()) && - all_of(WidenR->operands(), isSingleScalar); - } - if (auto *VPI = dyn_cast<VPInstruction>(VPV)) - return VPI->isSingleScalar() || VPI->isVectorToScalar() || - (PreservesUniformity(VPI->getOpcode()) && - all_of(VPI->operands(), isSingleScalar)); - if (isa<VPPartialReductionRecipe>(VPV)) - return false; - if (isa<VPReductionRecipe>(VPV)) - return true; - if (auto *Expr = dyn_cast<VPExpressionRecipe>(VPV)) - return Expr->isSingleScalar(); - - // VPExpandSCEVRecipes must be placed in the entry and are alway uniform. - return isa<VPExpandSCEVRecipe>(VPV); -} +bool isSingleScalar(const VPValue *VPV); /// Return true if \p V is a header mask in \p Plan. bool isHeaderMask(const VPValue *V, const VPlan &Plan); |
