llvm/llvm/lib/Analysis/MemoryBuiltins.cpp

//===- MemoryBuiltins.cpp - Identify calls to memory builtins -------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This family of functions identifies calls to builtin functions that allocate
// or free memory.
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/MemoryBuiltins.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/TargetFolder.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/Utils/Local.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <cstdint>
#include <iterator>
#include <numeric>
#include <optional>
#include <type_traits>
#include <utility>

usingnamespacellvm;

#define DEBUG_TYPE

static cl::opt<unsigned> ObjectSizeOffsetVisitorMaxVisitInstructions(
    "object-size-offset-visitor-max-visit-instructions",
    cl::desc("Maximum number of instructions for ObjectSizeOffsetVisitor to "
             "look at"),
    cl::init(100));

enum AllocType : uint8_t {};

enum class MallocFamily {};

StringRef mangledNameForMallocFamily(const MallocFamily &Family) {}

struct AllocFnsTy {};

// clang-format off
// FIXME: certain users need more information. E.g., SimplifyLibCalls needs to
// know which functions are nounwind, noalias, nocapture parameters, etc.
static const std::pair<LibFunc, AllocFnsTy> AllocationFnData[] =;
// clang-format on

static const Function *getCalledFunction(const Value *V) {}

/// Returns the allocation data for the given value if it's a call to a known
/// allocation function.
static std::optional<AllocFnsTy>
getAllocationDataForFunction(const Function *Callee, AllocType AllocTy,
                             const TargetLibraryInfo *TLI) {}

static std::optional<AllocFnsTy>
getAllocationData(const Value *V, AllocType AllocTy,
                  const TargetLibraryInfo *TLI) {}

static std::optional<AllocFnsTy>
getAllocationData(const Value *V, AllocType AllocTy,
                  function_ref<const TargetLibraryInfo &(Function &)> GetTLI) {}

static std::optional<AllocFnsTy>
getAllocationSize(const CallBase *CB, const TargetLibraryInfo *TLI) {}

static AllocFnKind getAllocFnKind(const Value *V) {}

static AllocFnKind getAllocFnKind(const Function *F) {}

static bool checkFnAllocKind(const Value *V, AllocFnKind Wanted) {}

static bool checkFnAllocKind(const Function *F, AllocFnKind Wanted) {}

/// Tests if a value is a call or invoke to a library function that
/// allocates or reallocates memory (either malloc, calloc, realloc, or strdup
/// like).
bool llvm::isAllocationFn(const Value *V, const TargetLibraryInfo *TLI) {}
bool llvm::isAllocationFn(
    const Value *V,
    function_ref<const TargetLibraryInfo &(Function &)> GetTLI) {}

/// Tests if a value is a call or invoke to a library function that
/// allocates memory via new.
bool llvm::isNewLikeFn(const Value *V, const TargetLibraryInfo *TLI) {}

/// Tests if a value is a call or invoke to a library function that
/// allocates memory similar to malloc or calloc.
bool llvm::isMallocOrCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI) {}

/// Tests if a value is a call or invoke to a library function that
/// allocates memory (either malloc, calloc, or strdup like).
bool llvm::isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI) {}

/// Tests if a functions is a call or invoke to a library function that
/// reallocates memory (e.g., realloc).
bool llvm::isReallocLikeFn(const Function *F) {}

Value *llvm::getReallocatedOperand(const CallBase *CB) {}

bool llvm::isRemovableAlloc(const CallBase *CB, const TargetLibraryInfo *TLI) {}

Value *llvm::getAllocAlignment(const CallBase *V,
                               const TargetLibraryInfo *TLI) {}

/// When we're compiling N-bit code, and the user uses parameters that are
/// greater than N bits (e.g. uint64_t on a 32-bit build), we can run into
/// trouble with APInt size issues. This function handles resizing + overflow
/// checks for us. Check and zext or trunc \p I depending on IntTyBits and
/// I's value.
static bool CheckedZextOrTrunc(APInt &I, unsigned IntTyBits) {}

std::optional<APInt>
llvm::getAllocSize(const CallBase *CB, const TargetLibraryInfo *TLI,
                   function_ref<const Value *(const Value *)> Mapper) {}

Constant *llvm::getInitialValueOfAllocation(const Value *V,
                                            const TargetLibraryInfo *TLI,
                                            Type *Ty) {}

struct FreeFnsTy {};

// clang-format off
static const std::pair<LibFunc, FreeFnsTy> FreeFnData[] =;
// clang-format on

std::optional<FreeFnsTy> getFreeFunctionDataForFunction(const Function *Callee,
                                                        const LibFunc TLIFn) {}

std::optional<StringRef>
llvm::getAllocationFamily(const Value *I, const TargetLibraryInfo *TLI) {}

/// isLibFreeFunction - Returns true if the function is a builtin free()
bool llvm::isLibFreeFunction(const Function *F, const LibFunc TLIFn) {}

Value *llvm::getFreedOperand(const CallBase *CB, const TargetLibraryInfo *TLI) {}

//===----------------------------------------------------------------------===//
//  Utility functions to compute size of objects.
//
static APInt getSizeWithOverflow(const SizeOffsetAPInt &Data) {}

/// Compute the size of the object pointed by Ptr. Returns true and the
/// object size in Size if successful, and false otherwise.
/// If RoundToAlign is true, then Size is rounded up to the alignment of
/// allocas, byval arguments, and global variables.
bool llvm::getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL,
                         const TargetLibraryInfo *TLI, ObjectSizeOpts Opts) {}

Value *llvm::lowerObjectSizeCall(IntrinsicInst *ObjectSize,
                                 const DataLayout &DL,
                                 const TargetLibraryInfo *TLI,
                                 bool MustSucceed) {}

Value *llvm::lowerObjectSizeCall(
    IntrinsicInst *ObjectSize, const DataLayout &DL,
    const TargetLibraryInfo *TLI, AAResults *AA, bool MustSucceed,
    SmallVectorImpl<Instruction *> *InsertedInstructions) {}

STATISTIC(ObjectVisitorArgument,
          "Number of arguments with unsolved size and offset");
STATISTIC(ObjectVisitorLoad,
          "Number of load instructions with unsolved size and offset");

APInt ObjectSizeOffsetVisitor::align(APInt Size, MaybeAlign Alignment) {}

ObjectSizeOffsetVisitor::ObjectSizeOffsetVisitor(const DataLayout &DL,
                                                 const TargetLibraryInfo *TLI,
                                                 LLVMContext &Context,
                                                 ObjectSizeOpts Options)
    :{}

SizeOffsetAPInt ObjectSizeOffsetVisitor::compute(Value *V) {}

SizeOffsetAPInt ObjectSizeOffsetVisitor::computeImpl(Value *V) {}

SizeOffsetAPInt ObjectSizeOffsetVisitor::computeValue(Value *V) {}

bool ObjectSizeOffsetVisitor::CheckedZextOrTrunc(APInt &I) {}

SizeOffsetAPInt ObjectSizeOffsetVisitor::visitAllocaInst(AllocaInst &I) {}

SizeOffsetAPInt ObjectSizeOffsetVisitor::visitArgument(Argument &A) {}

SizeOffsetAPInt ObjectSizeOffsetVisitor::visitCallBase(CallBase &CB) {}

SizeOffsetAPInt
ObjectSizeOffsetVisitor::visitConstantPointerNull(ConstantPointerNull &CPN) {}

SizeOffsetAPInt
ObjectSizeOffsetVisitor::visitExtractElementInst(ExtractElementInst &) {}

SizeOffsetAPInt
ObjectSizeOffsetVisitor::visitExtractValueInst(ExtractValueInst &) {}

SizeOffsetAPInt ObjectSizeOffsetVisitor::visitGlobalAlias(GlobalAlias &GA) {}

SizeOffsetAPInt
ObjectSizeOffsetVisitor::visitGlobalVariable(GlobalVariable &GV) {}

SizeOffsetAPInt ObjectSizeOffsetVisitor::visitIntToPtrInst(IntToPtrInst &) {}

SizeOffsetAPInt ObjectSizeOffsetVisitor::findLoadSizeOffset(
    LoadInst &Load, BasicBlock &BB, BasicBlock::iterator From,
    SmallDenseMap<BasicBlock *, SizeOffsetAPInt, 8> &VisitedBlocks,
    unsigned &ScannedInstCount) {}

SizeOffsetAPInt ObjectSizeOffsetVisitor::visitLoadInst(LoadInst &LI) {}

SizeOffsetAPInt
ObjectSizeOffsetVisitor::combineSizeOffset(SizeOffsetAPInt LHS,
                                           SizeOffsetAPInt RHS) {}

SizeOffsetAPInt ObjectSizeOffsetVisitor::visitPHINode(PHINode &PN) {}

SizeOffsetAPInt ObjectSizeOffsetVisitor::visitSelectInst(SelectInst &I) {}

SizeOffsetAPInt ObjectSizeOffsetVisitor::visitUndefValue(UndefValue &) {}

SizeOffsetAPInt ObjectSizeOffsetVisitor::visitInstruction(Instruction &I) {}

// Just set these right here...
SizeOffsetValue::SizeOffsetValue(const SizeOffsetWeakTrackingVH &SOT)
    :{}

ObjectSizeOffsetEvaluator::ObjectSizeOffsetEvaluator(
    const DataLayout &DL, const TargetLibraryInfo *TLI, LLVMContext &Context,
    ObjectSizeOpts EvalOpts)
    :{}

SizeOffsetValue ObjectSizeOffsetEvaluator::compute(Value *V) {}

SizeOffsetValue ObjectSizeOffsetEvaluator::compute_(Value *V) {}

SizeOffsetValue ObjectSizeOffsetEvaluator::visitAllocaInst(AllocaInst &I) {}

SizeOffsetValue ObjectSizeOffsetEvaluator::visitCallBase(CallBase &CB) {}

SizeOffsetValue
ObjectSizeOffsetEvaluator::visitExtractElementInst(ExtractElementInst &) {}

SizeOffsetValue
ObjectSizeOffsetEvaluator::visitExtractValueInst(ExtractValueInst &) {}

SizeOffsetValue ObjectSizeOffsetEvaluator::visitGEPOperator(GEPOperator &GEP) {}

SizeOffsetValue ObjectSizeOffsetEvaluator::visitIntToPtrInst(IntToPtrInst &) {}

SizeOffsetValue ObjectSizeOffsetEvaluator::visitLoadInst(LoadInst &LI) {}

SizeOffsetValue ObjectSizeOffsetEvaluator::visitPHINode(PHINode &PHI) {}

SizeOffsetValue ObjectSizeOffsetEvaluator::visitSelectInst(SelectInst &I) {}

SizeOffsetValue ObjectSizeOffsetEvaluator::visitInstruction(Instruction &I) {}