#include "llvm/IR/InstVisitor.h"
#include "llvm/IR/ValueHandle.h"
#include <cstdint>
+#include <optional>
#include <utility>
namespace llvm {
/// calls that return their argument. A mapper function can be used to replace
/// one Value* (operand to the allocation) with another. This is useful when
/// doing abstract interpretation.
-Optional<APInt> getAllocSize(
+std::optional<APInt> getAllocSize(
const CallBase *CB, const TargetLibraryInfo *TLI,
function_ref<const Value *(const Value *)> Mapper = [](const Value *V) {
return V;
/// If a function is part of an allocation family (e.g.
/// malloc/realloc/calloc/free), return the identifier for its family
/// of functions.
-Optional<StringRef> getAllocationFamily(const Value *I,
- const TargetLibraryInfo *TLI);
+std::optional<StringRef> getAllocationFamily(const Value *I,
+ const TargetLibraryInfo *TLI);
//===----------------------------------------------------------------------===//
// Utility functions to compute size of objects.
/// Returns the allocation data for the given value if it's a call to a known
/// allocation function.
-static Optional<AllocFnsTy>
+static std::optional<AllocFnsTy>
getAllocationDataForFunction(const Function *Callee, AllocType AllocTy,
const TargetLibraryInfo *TLI) {
// Don't perform a slow TLI lookup, if this function doesn't return a pointer
return std::nullopt;
}
-static Optional<AllocFnsTy> getAllocationData(const Value *V, AllocType AllocTy,
- const TargetLibraryInfo *TLI) {
+static std::optional<AllocFnsTy>
+getAllocationData(const Value *V, AllocType AllocTy,
+ const TargetLibraryInfo *TLI) {
bool IsNoBuiltinCall;
if (const Function *Callee = getCalledFunction(V, IsNoBuiltinCall))
if (!IsNoBuiltinCall)
return std::nullopt;
}
-static Optional<AllocFnsTy>
+static std::optional<AllocFnsTy>
getAllocationData(const Value *V, AllocType AllocTy,
function_ref<const TargetLibraryInfo &(Function &)> GetTLI) {
bool IsNoBuiltinCall;
return std::nullopt;
}
-static Optional<AllocFnsTy> getAllocationSize(const Value *V,
- const TargetLibraryInfo *TLI) {
+static std::optional<AllocFnsTy>
+getAllocationSize(const Value *V, const TargetLibraryInfo *TLI) {
bool IsNoBuiltinCall;
const Function *Callee =
getCalledFunction(V, IsNoBuiltinCall);
// Prefer to use existing information over allocsize. This will give us an
// accurate AllocTy.
if (!IsNoBuiltinCall)
- if (Optional<AllocFnsTy> Data =
+ if (std::optional<AllocFnsTy> Data =
getAllocationDataForFunction(Callee, AnyAlloc, TLI))
return Data;
Value *llvm::getAllocAlignment(const CallBase *V,
const TargetLibraryInfo *TLI) {
- const Optional<AllocFnsTy> FnData = getAllocationData(V, AnyAlloc, TLI);
+ const std::optional<AllocFnsTy> FnData = getAllocationData(V, AnyAlloc, TLI);
if (FnData && FnData->AlignParam >= 0) {
return V->getOperand(FnData->AlignParam);
}
return true;
}
-Optional<APInt>
+std::optional<APInt>
llvm::getAllocSize(const CallBase *CB, const TargetLibraryInfo *TLI,
function_ref<const Value *(const Value *)> Mapper) {
// Note: This handles both explicitly listed allocation functions and
// allocsize. The code structure could stand to be cleaned up a bit.
- Optional<AllocFnsTy> FnData = getAllocationSize(CB, TLI);
+ std::optional<AllocFnsTy> FnData = getAllocationSize(CB, TLI);
if (!FnData)
return std::nullopt;
};
// clang-format on
-Optional<FreeFnsTy> getFreeFunctionDataForFunction(const Function *Callee,
- const LibFunc TLIFn) {
+std::optional<FreeFnsTy> getFreeFunctionDataForFunction(const Function *Callee,
+ const LibFunc TLIFn) {
const auto *Iter =
find_if(FreeFnData, [TLIFn](const std::pair<LibFunc, FreeFnsTy> &P) {
return P.first == TLIFn;
return Iter->second;
}
-Optional<StringRef> llvm::getAllocationFamily(const Value *I,
- const TargetLibraryInfo *TLI) {
+std::optional<StringRef>
+llvm::getAllocationFamily(const Value *I, const TargetLibraryInfo *TLI) {
bool IsNoBuiltin;
const Function *Callee = getCalledFunction(I, IsNoBuiltin);
if (Callee == nullptr || IsNoBuiltin)
/// isLibFreeFunction - Returns true if the function is a builtin free()
bool llvm::isLibFreeFunction(const Function *F, const LibFunc TLIFn) {
- Optional<FreeFnsTy> FnData = getFreeFunctionDataForFunction(F, TLIFn);
+ std::optional<FreeFnsTy> FnData = getFreeFunctionDataForFunction(F, TLIFn);
if (!FnData)
return checkFnAllocKind(F, AllocFnKind::Free);
}
SizeOffsetType ObjectSizeOffsetVisitor::visitCallBase(CallBase &CB) {
- if (Optional<APInt> Size = getAllocSize(&CB, TLI))
+ if (std::optional<APInt> Size = getAllocSize(&CB, TLI))
return std::make_pair(*Size, Zero);
return unknown();
}
}
SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitCallBase(CallBase &CB) {
- Optional<AllocFnsTy> FnData = getAllocationSize(&CB, TLI);
+ std::optional<AllocFnsTy> FnData = getAllocationSize(&CB, TLI);
if (!FnData)
return unknown();
const DataLayout &DL = A.getInfoCache().getDL();
Value *Size;
- Optional<APInt> SizeAPI = getSize(A, *this, AI);
+ std::optional<APInt> SizeAPI = getSize(A, *this, AI);
if (SizeAPI) {
Size = ConstantInt::get(AI.CB->getContext(), *SizeAPI);
} else {
return std::nullopt;
}
- Optional<APInt> getSize(Attributor &A, const AbstractAttribute &AA,
- AllocationInfo &AI) {
+ std::optional<APInt> getSize(Attributor &A, const AbstractAttribute &AA,
+ AllocationInfo &AI) {
auto Mapper = [&](const Value *V) -> const Value * {
bool UsedAssumedInformation = false;
if (std::optional<Constant *> SimpleV =
}
}
- Optional<APInt> Size = getSize(A, *this, AI);
+ std::optional<APInt> Size = getSize(A, *this, AI);
if (MaxHeapToStackSize != -1) {
if (!Size || Size.value().ugt(MaxHeapToStackSize)) {
LLVM_DEBUG({