aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/CodeGenPrepare.cpp42
-rw-r--r--llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp12
-rw-r--r--llvm/lib/CodeGen/RegisterUsageInfo.cpp2
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp6
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp12
-rw-r--r--llvm/lib/CodeGen/TargetOptionsImpl.cpp2
-rw-r--r--llvm/lib/ExecutionEngine/Orc/Core.cpp17
-rw-r--r--llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt4
-rw-r--r--llvm/lib/ExecutionEngine/Orc/TargetProcess/LibraryResolver.cpp369
-rw-r--r--llvm/lib/ExecutionEngine/Orc/TargetProcess/LibraryScanner.cpp1161
-rw-r--r--llvm/lib/IR/DebugProgramInstruction.cpp4
-rw-r--r--llvm/lib/MC/MCParser/MasmParser.cpp10
-rw-r--r--llvm/lib/Support/SpecialCaseList.cpp28
-rw-r--r--llvm/lib/Target/AArch64/AArch64InstrInfo.cpp10
-rw-r--r--llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h2
-rw-r--r--llvm/lib/Target/AArch64/AArch64RegisterInfo.h2
-rw-r--r--llvm/lib/Target/AMDGPU/AMDGPUHSAMetadataStreamer.h6
-rw-r--r--llvm/lib/Target/AMDGPU/AMDGPUMIRFormatter.h13
-rw-r--r--llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp6
-rw-r--r--llvm/lib/Target/AMDGPU/MCA/AMDGPUCustomBehaviour.h4
-rw-r--r--llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.h2
-rw-r--r--llvm/lib/Target/AMDGPU/SIInstrInfo.h2
-rw-r--r--llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h2
-rw-r--r--llvm/lib/Target/AMDGPU/SIMemoryLegalizer.cpp2
-rw-r--r--llvm/lib/Target/ARM/ARMConstantPoolValue.h4
-rw-r--r--llvm/lib/Target/ARM/ARMInstrInfo.td12
-rw-r--r--llvm/lib/Target/ARM/ARMMachineFunctionInfo.h2
-rw-r--r--llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp2
-rw-r--r--llvm/lib/Target/AVR/MCTargetDesc/AVRELFObjectWriter.cpp2
-rw-r--r--llvm/lib/Target/BPF/BPFAsmPrinter.h2
-rw-r--r--llvm/lib/Target/BPF/BPFCheckAndAdjustIR.cpp2
-rw-r--r--llvm/lib/Target/BPF/BPFTargetLoweringObjectFile.h2
-rw-r--r--llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp5
-rw-r--r--llvm/lib/Target/M68k/M68kTargetMachine.cpp10
-rw-r--r--llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp2
-rw-r--r--llvm/lib/Target/RISCV/MCA/RISCVCustomBehaviour.h4
-rw-r--r--llvm/lib/Target/RISCV/RISCVConstantPoolValue.h2
-rw-r--r--llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h2
-rw-r--r--llvm/lib/Target/RISCV/RISCVTargetMachine.cpp5
-rw-r--r--llvm/lib/Target/SPIRV/SPIRVLegalizePointerCast.cpp2
-rw-r--r--llvm/lib/Target/SPIRV/SPIRVMergeRegionExitTargets.cpp2
-rw-r--r--llvm/lib/Target/SPIRV/SPIRVStripConvergentIntrinsics.cpp2
-rw-r--r--llvm/lib/Target/SPIRV/SPIRVStructurizer.cpp2
-rw-r--r--llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp2
-rw-r--r--llvm/lib/Target/SystemZ/SystemZMachineScheduler.h2
-rw-r--r--llvm/lib/Target/SystemZ/SystemZRegisterInfo.h4
-rw-r--r--llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp2
-rw-r--r--llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp2
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h2
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp17
-rw-r--r--llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp8
-rw-r--r--llvm/lib/Target/X86/MCA/X86CustomBehaviour.h2
-rw-r--r--llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp2
-rw-r--r--llvm/lib/Target/X86/X86.h8
-rw-r--r--llvm/lib/Target/X86/X86DomainReassignment.cpp4
-rw-r--r--llvm/lib/Target/X86/X86ISelDAGToDAG.cpp56
-rw-r--r--llvm/lib/Target/X86/X86MachineFunctionInfo.h2
-rw-r--r--llvm/lib/Transforms/IPO/Attributor.cpp3
-rw-r--r--llvm/lib/Transforms/Vectorize/VPlanUtils.cpp54
-rw-r--r--llvm/lib/Transforms/Vectorize/VPlanUtils.h54
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);