From 467432899bc2f71842ed1b24d24c094da02af7d4 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Thu, 1 Dec 2022 15:23:53 -0800 Subject: [PATCH] MemoryLocation: convert Optional to std::optional --- llvm/include/llvm/Analysis/MemoryLocation.h | 17 +++++++-------- llvm/lib/Analysis/MemoryLocation.cpp | 21 ++++++++++--------- llvm/lib/CodeGen/StackProtector.cpp | 3 ++- llvm/lib/Target/Hexagon/HexagonVectorCombine.cpp | 4 ++-- llvm/lib/Transforms/IPO/AttributorAttributes.cpp | 4 ++-- llvm/lib/Transforms/IPO/FunctionAttrs.cpp | 3 ++- llvm/lib/Transforms/IPO/OpenMPOpt.cpp | 10 +++++---- .../InstCombine/InstructionCombining.cpp | 5 +++-- .../lib/Transforms/Scalar/DeadStoreElimination.cpp | 24 ++++++++++++---------- 9 files changed, 50 insertions(+), 41 deletions(-) diff --git a/llvm/include/llvm/Analysis/MemoryLocation.h b/llvm/include/llvm/Analysis/MemoryLocation.h index dfac494..0dba415 100644 --- a/llvm/include/llvm/Analysis/MemoryLocation.h +++ b/llvm/include/llvm/Analysis/MemoryLocation.h @@ -16,10 +16,11 @@ #define LLVM_ANALYSIS_MEMORYLOCATION_H #include "llvm/ADT/DenseMapInfo.h" -#include "llvm/ADT/Optional.h" #include "llvm/IR/Metadata.h" #include "llvm/Support/TypeSize.h" +#include + namespace llvm { class CallBase; @@ -39,9 +40,9 @@ class VAArgInst; class Value; // Represents the size of a MemoryLocation. Logically, it's an -// Optional that also carries a bit to represent whether the integer -// it contains, N, is 'precise'. Precise, in this context, means that we know -// that the area of storage referenced by the given MemoryLocation must be +// std::optional that also carries a bit to represent whether the +// integer it contains, N, is 'precise'. Precise, in this context, means that we +// know that the area of storage referenced by the given MemoryLocation must be // precisely N bytes. An imprecise value is formed as the union of two or more // precise values, and can conservatively represent all of the values unioned // into it. Importantly, imprecise values are an *upper-bound* on the size of a @@ -62,7 +63,7 @@ class Value; // we'll ever actually do so. // // If asked to represent a pathologically large value, this will degrade to -// None. +// std::nullopt. class LocationSize { enum : uint64_t { BeforeOrAfterPointer = ~uint64_t(0), @@ -242,7 +243,7 @@ public: static MemoryLocation get(const Instruction *Inst) { return *MemoryLocation::getOrNone(Inst); } - static Optional getOrNone(const Instruction *Inst); + static std::optional getOrNone(const Instruction *Inst); /// Return a location representing the source of a memory transfer. static MemoryLocation getForSource(const MemTransferInst *MTI); @@ -254,8 +255,8 @@ public: static MemoryLocation getForDest(const MemIntrinsic *MI); static MemoryLocation getForDest(const AtomicMemIntrinsic *MI); static MemoryLocation getForDest(const AnyMemIntrinsic *MI); - static Optional getForDest(const CallBase *CI, - const TargetLibraryInfo &TLI); + static std::optional getForDest(const CallBase *CI, + const TargetLibraryInfo &TLI); /// Return a location representing a particular argument of a call. static MemoryLocation getForArgument(const CallBase *Call, unsigned ArgIdx, diff --git a/llvm/lib/Analysis/MemoryLocation.cpp b/llvm/lib/Analysis/MemoryLocation.cpp index fb23f0b..e839f9e 100644 --- a/llvm/lib/Analysis/MemoryLocation.cpp +++ b/llvm/lib/Analysis/MemoryLocation.cpp @@ -74,7 +74,8 @@ MemoryLocation MemoryLocation::get(const AtomicRMWInst *RMWI) { RMWI->getAAMetadata()); } -Optional MemoryLocation::getOrNone(const Instruction *Inst) { +std::optional +MemoryLocation::getOrNone(const Instruction *Inst) { switch (Inst->getOpcode()) { case Instruction::Load: return get(cast(Inst)); @@ -87,7 +88,7 @@ Optional MemoryLocation::getOrNone(const Instruction *Inst) { case Instruction::AtomicRMW: return get(cast(Inst)); default: - return None; + return std::nullopt; } } @@ -117,39 +118,39 @@ MemoryLocation MemoryLocation::getForDest(const AnyMemIntrinsic *MI) { return getForArgument(MI, 0, nullptr); } -Optional +std::optional MemoryLocation::getForDest(const CallBase *CB, const TargetLibraryInfo &TLI) { if (!CB->onlyAccessesArgMemory()) - return None; + return std::nullopt; if (CB->hasOperandBundles()) // TODO: remove implementation restriction - return None; + return std::nullopt; Value *UsedV = nullptr; std::optional UsedIdx; for (unsigned i = 0; i < CB->arg_size(); i++) { if (!CB->getArgOperand(i)->getType()->isPointerTy()) continue; - if (CB->onlyReadsMemory(i)) - continue; + if (CB->onlyReadsMemory(i)) + continue; if (!UsedV) { // First potentially writing parameter UsedV = CB->getArgOperand(i); UsedIdx = i; continue; } - UsedIdx = None; + UsedIdx = std::nullopt; if (UsedV != CB->getArgOperand(i)) // Can't describe writing to two distinct locations. // TODO: This results in an inprecision when two values derived from the // same object are passed as arguments to the same function. - return None; + return std::nullopt; } if (!UsedV) // We don't currently have a way to represent a "does not write" result // and thus have to be conservative and return unknown. - return None; + return std::nullopt; if (UsedIdx) return getForArgument(CB, *UsedIdx, &TLI); diff --git a/llvm/lib/CodeGen/StackProtector.cpp b/llvm/lib/CodeGen/StackProtector.cpp index 2eef88b..2f0056f 100644 --- a/llvm/lib/CodeGen/StackProtector.cpp +++ b/llvm/lib/CodeGen/StackProtector.cpp @@ -46,6 +46,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" +#include #include using namespace llvm; @@ -166,7 +167,7 @@ bool StackProtector::HasAddressTaken(const Instruction *AI, const auto *I = cast(U); // If this instruction accesses memory make sure it doesn't access beyond // the bounds of the allocated object. - Optional MemLoc = MemoryLocation::getOrNone(I); + std::optional MemLoc = MemoryLocation::getOrNone(I); if (MemLoc && MemLoc->Size.hasValue() && !TypeSize::isKnownGE(AllocSize, TypeSize::getFixed(MemLoc->Size.getValue()))) diff --git a/llvm/lib/Target/Hexagon/HexagonVectorCombine.cpp b/llvm/lib/Target/Hexagon/HexagonVectorCombine.cpp index 9837ca98..2e350cd 100644 --- a/llvm/lib/Target/Hexagon/HexagonVectorCombine.cpp +++ b/llvm/lib/Target/Hexagon/HexagonVectorCombine.cpp @@ -15,7 +15,6 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/None.h" -#include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Analysis/AliasAnalysis.h" @@ -2391,7 +2390,8 @@ auto HexagonVectorCombine::isSafeToMoveBeforeInBB(const Instruction &In, BasicBlock::const_iterator To, const T &IgnoreInsts) const -> bool { - auto getLocOrNone = [this](const Instruction &I) -> Optional { + auto getLocOrNone = + [this](const Instruction &I) -> std::optional { if (const auto *II = dyn_cast(&I)) { switch (II->getIntrinsicID()) { case Intrinsic::masked_load: diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp index 541975c..875f7e2 100644 --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -2292,7 +2292,7 @@ static int64_t getKnownNonNullAndDerefBytesForUse( return DerefAA.getKnownDereferenceableBytes(); } - Optional Loc = MemoryLocation::getOrNone(I); + std::optional Loc = MemoryLocation::getOrNone(I); if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() || I->isVolatile()) return 0; @@ -4238,7 +4238,7 @@ struct AADereferenceableImpl : AADereferenceable { if (!UseV->getType()->isPointerTy()) return; - Optional Loc = MemoryLocation::getOrNone(I); + std::optional Loc = MemoryLocation::getOrNone(I); if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() || I->isVolatile()) return; diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp index 3058dc2..3f61dbe 100644 --- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp +++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp @@ -63,6 +63,7 @@ #include #include #include +#include #include using namespace llvm; @@ -211,7 +212,7 @@ static MemoryEffects checkFunctionMemoryAccess(Function &F, bool ThisBody, if (MR == ModRefInfo::NoModRef) continue; - Optional Loc = MemoryLocation::getOrNone(&I); + std::optional Loc = MemoryLocation::getOrNone(&I); if (!Loc) { // If no location is known, conservatively assume anything can be // accessed. diff --git a/llvm/lib/Transforms/IPO/OpenMPOpt.cpp b/llvm/lib/Transforms/IPO/OpenMPOpt.cpp index 9181ce5..571ce33 100644 --- a/llvm/lib/Transforms/IPO/OpenMPOpt.cpp +++ b/llvm/lib/Transforms/IPO/OpenMPOpt.cpp @@ -50,6 +50,7 @@ #include "llvm/Transforms/Utils/CallGraphUpdater.h" #include +#include using namespace llvm; using namespace omp; @@ -1508,7 +1509,7 @@ private: continue; auto IsPotentiallyAffectedByBarrier = - [](Optional Loc) { + [](std::optional Loc) { const Value *Obj = (Loc && Loc->Ptr) ? getUnderlyingObject(Loc->Ptr) : nullptr; @@ -1538,11 +1539,12 @@ private: }; if (MemIntrinsic *MI = dyn_cast(I)) { - Optional Loc = MemoryLocation::getForDest(MI); + std::optional Loc = + MemoryLocation::getForDest(MI); if (IsPotentiallyAffectedByBarrier(Loc)) return false; if (MemTransferInst *MTI = dyn_cast(I)) { - Optional Loc = + std::optional Loc = MemoryLocation::getForSource(MTI); if (IsPotentiallyAffectedByBarrier(Loc)) return false; @@ -1554,7 +1556,7 @@ private: if (LI->hasMetadata(LLVMContext::MD_invariant_load)) continue; - Optional Loc = MemoryLocation::getOrNone(I); + std::optional Loc = MemoryLocation::getOrNone(I); if (IsPotentiallyAffectedByBarrier(Loc)) return false; } diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index 828828e..4aefcad6 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -105,6 +105,7 @@ #include #include #include +#include #include #include @@ -2709,7 +2710,7 @@ static bool isRemovableWrite(CallBase &CB, Value *UsedV, // If the only possible side effect of the call is writing to the alloca, // and the result isn't used, we can safely remove any reads implied by the // call including those which might read the alloca itself. - Optional Dest = MemoryLocation::getForDest(&CB, TLI); + std::optional Dest = MemoryLocation::getForDest(&CB, TLI); return Dest && Dest->Ptr == UsedV; } @@ -4003,7 +4004,7 @@ static bool SoleWriteToDeadLocal(Instruction *I, TargetLibraryInfo &TLI) { // to allow reload along used path as described below. Otherwise, this // is simply a store to a dead allocation which will be removed. return false; - Optional Dest = MemoryLocation::getForDest(CB, TLI); + std::optional Dest = MemoryLocation::getForDest(CB, TLI); if (!Dest) return false; auto *AI = dyn_cast(getUnderlyingObject(Dest->Ptr)); diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp index 21603c9..a60f88a 100644 --- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -86,6 +86,7 @@ #include #include #include +#include #include using namespace llvm; @@ -1045,9 +1046,9 @@ struct DSEState { return !I.first->second; } - Optional getLocForWrite(Instruction *I) const { + std::optional getLocForWrite(Instruction *I) const { if (!I->mayWriteToMemory()) - return None; + return std::nullopt; if (auto *CB = dyn_cast(I)) return MemoryLocation::getForDest(CB, TLI); @@ -1157,7 +1158,7 @@ struct DSEState { /// If \p I is a memory terminator like llvm.lifetime.end or free, return a /// pair with the MemoryLocation terminated by \p I and a boolean flag /// indicating whether \p I is a free-like call. - Optional> + std::optional> getLocForTerminator(Instruction *I) const { uint64_t Len; Value *Ptr; @@ -1170,7 +1171,7 @@ struct DSEState { return {std::make_pair(MemoryLocation::getAfter(FreedOp), true)}; } - return None; + return std::nullopt; } /// Returns true if \p I is a memory terminator instruction like @@ -1185,7 +1186,7 @@ struct DSEState { /// instruction \p AccessI. bool isMemTerminator(const MemoryLocation &Loc, Instruction *AccessI, Instruction *MaybeTerm) { - Optional> MaybeTermLoc = + std::optional> MaybeTermLoc = getLocForTerminator(MaybeTerm); if (!MaybeTermLoc) @@ -1296,7 +1297,7 @@ struct DSEState { !KillingI->mayReadFromMemory(); // Find the next clobbering Mod access for DefLoc, starting at StartAccess. - Optional CurrentLoc; + std::optional CurrentLoc; for (;; Current = cast(Current)->getDefiningAccess()) { LLVM_DEBUG({ dbgs() << " visiting " << *Current; @@ -2024,12 +2025,13 @@ static bool eliminateDeadStores(Function &F, AliasAnalysis &AA, MemorySSA &MSSA, continue; Instruction *KillingI = KillingDef->getMemoryInst(); - Optional MaybeKillingLoc; - if (State.isMemTerminatorInst(KillingI)) - MaybeKillingLoc = State.getLocForTerminator(KillingI).transform( - [](const std::pair &P) { return P.first; }); - else + std::optional MaybeKillingLoc; + if (State.isMemTerminatorInst(KillingI)) { + if (auto KillingLoc = State.getLocForTerminator(KillingI)) + MaybeKillingLoc = KillingLoc->first; + } else { MaybeKillingLoc = State.getLocForWrite(KillingI); + } if (!MaybeKillingLoc) { LLVM_DEBUG(dbgs() << "Failed to find analyzable write location for " -- 2.7.4