123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- Loads.h - Local load analysis --------------------------------------===//
- //
- // 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 file declares simple local analyses for load instructions.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_ANALYSIS_LOADS_H
- #define LLVM_ANALYSIS_LOADS_H
- #include "llvm/IR/BasicBlock.h"
- #include "llvm/Support/CommandLine.h"
- namespace llvm {
- class AAResults;
- class DataLayout;
- class DominatorTree;
- class Instruction;
- class LoadInst;
- class Loop;
- class MDNode;
- class ScalarEvolution;
- /// Return true if this is always a dereferenceable pointer. If the context
- /// instruction is specified perform context-sensitive analysis and return true
- /// if the pointer is dereferenceable at the specified instruction.
- bool isDereferenceablePointer(const Value *V, Type *Ty,
- const DataLayout &DL,
- const Instruction *CtxI = nullptr,
- const DominatorTree *DT = nullptr);
- /// Returns true if V is always a dereferenceable pointer with alignment
- /// greater or equal than requested. If the context instruction is specified
- /// performs context-sensitive analysis and returns true if the pointer is
- /// dereferenceable at the specified instruction.
- bool isDereferenceableAndAlignedPointer(const Value *V, Type *Ty,
- MaybeAlign Alignment,
- const DataLayout &DL,
- const Instruction *CtxI = nullptr,
- const DominatorTree *DT = nullptr);
- /// Returns true if V is always dereferenceable for Size byte with alignment
- /// greater or equal than requested. If the context instruction is specified
- /// performs context-sensitive analysis and returns true if the pointer is
- /// dereferenceable at the specified instruction.
- bool isDereferenceableAndAlignedPointer(const Value *V, Align Alignment,
- const APInt &Size, const DataLayout &DL,
- const Instruction *CtxI = nullptr,
- const DominatorTree *DT = nullptr);
- /// Return true if we know that executing a load from this value cannot trap.
- ///
- /// If DT and ScanFrom are specified this method performs context-sensitive
- /// analysis and returns true if it is safe to load immediately before ScanFrom.
- ///
- /// If it is not obviously safe to load from the specified pointer, we do a
- /// quick local scan of the basic block containing ScanFrom, to determine if
- /// the address is already accessed.
- bool isSafeToLoadUnconditionally(Value *V, Align Alignment, APInt &Size,
- const DataLayout &DL,
- Instruction *ScanFrom = nullptr,
- const DominatorTree *DT = nullptr);
- /// Return true if we can prove that the given load (which is assumed to be
- /// within the specified loop) would access only dereferenceable memory, and
- /// be properly aligned on every iteration of the specified loop regardless of
- /// its placement within the loop. (i.e. does not require predication beyond
- /// that required by the the header itself and could be hoisted into the header
- /// if desired.) This is more powerful than the variants above when the
- /// address loaded from is analyzeable by SCEV.
- bool isDereferenceableAndAlignedInLoop(LoadInst *LI, Loop *L,
- ScalarEvolution &SE,
- DominatorTree &DT);
- /// Return true if we know that executing a load from this value cannot trap.
- ///
- /// If DT and ScanFrom are specified this method performs context-sensitive
- /// analysis and returns true if it is safe to load immediately before ScanFrom.
- ///
- /// If it is not obviously safe to load from the specified pointer, we do a
- /// quick local scan of the basic block containing ScanFrom, to determine if
- /// the address is already accessed.
- bool isSafeToLoadUnconditionally(Value *V, Type *Ty, Align Alignment,
- const DataLayout &DL,
- Instruction *ScanFrom = nullptr,
- const DominatorTree *DT = nullptr);
- /// The default number of maximum instructions to scan in the block, used by
- /// FindAvailableLoadedValue().
- extern cl::opt<unsigned> DefMaxInstsToScan;
- /// Scan backwards to see if we have the value of the given load available
- /// locally within a small number of instructions.
- ///
- /// You can use this function to scan across multiple blocks: after you call
- /// this function, if ScanFrom points at the beginning of the block, it's safe
- /// to continue scanning the predecessors.
- ///
- /// Note that performing load CSE requires special care to make sure the
- /// metadata is set appropriately. In particular, aliasing metadata needs
- /// to be merged. (This doesn't matter for store-to-load forwarding because
- /// the only relevant load gets deleted.)
- ///
- /// \param Load The load we want to replace.
- /// \param ScanBB The basic block to scan.
- /// \param [in,out] ScanFrom The location to start scanning from. When this
- /// function returns, it points at the last instruction scanned.
- /// \param MaxInstsToScan The maximum number of instructions to scan. If this
- /// is zero, the whole block will be scanned.
- /// \param AA Optional pointer to alias analysis, to make the scan more
- /// precise.
- /// \param [out] IsLoadCSE Whether the returned value is a load from the same
- /// location in memory, as opposed to the value operand of a store.
- ///
- /// \returns The found value, or nullptr if no value is found.
- Value *FindAvailableLoadedValue(LoadInst *Load,
- BasicBlock *ScanBB,
- BasicBlock::iterator &ScanFrom,
- unsigned MaxInstsToScan = DefMaxInstsToScan,
- AAResults *AA = nullptr,
- bool *IsLoadCSE = nullptr,
- unsigned *NumScanedInst = nullptr);
- /// Scan backwards to see if we have the value of the given pointer available
- /// locally within a small number of instructions.
- ///
- /// You can use this function to scan across multiple blocks: after you call
- /// this function, if ScanFrom points at the beginning of the block, it's safe
- /// to continue scanning the predecessors.
- ///
- /// \param Ptr The pointer we want the load and store to originate from.
- /// \param AccessTy The access type of the pointer.
- /// \param AtLeastAtomic Are we looking for at-least an atomic load/store ? In
- /// case it is false, we can return an atomic or non-atomic load or store. In
- /// case it is true, we need to return an atomic load or store.
- /// \param ScanBB The basic block to scan.
- /// \param [in,out] ScanFrom The location to start scanning from. When this
- /// function returns, it points at the last instruction scanned.
- /// \param MaxInstsToScan The maximum number of instructions to scan. If this
- /// is zero, the whole block will be scanned.
- /// \param AA Optional pointer to alias analysis, to make the scan more
- /// precise.
- /// \param [out] IsLoadCSE Whether the returned value is a load from the same
- /// location in memory, as opposed to the value operand of a store.
- ///
- /// \returns The found value, or nullptr if no value is found.
- Value *FindAvailablePtrLoadStore(Value *Ptr, Type *AccessTy, bool AtLeastAtomic,
- BasicBlock *ScanBB,
- BasicBlock::iterator &ScanFrom,
- unsigned MaxInstsToScan, AAResults *AA,
- bool *IsLoadCSE, unsigned *NumScanedInst);
- /// Returns true if a pointer value \p A can be replace with another pointer
- /// value \B if they are deemed equal through some means (e.g. information from
- /// conditions).
- /// NOTE: the current implementations is incomplete and unsound. It does not
- /// reject all invalid cases yet, but will be made stricter in the future. In
- /// particular this means returning true means unknown if replacement is safe.
- bool canReplacePointersIfEqual(Value *A, Value *B, const DataLayout &DL,
- Instruction *CtxI);
- }
- #endif
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|