LLVM  8.0.1
Macros | Functions
InstCombineLoadStoreAlloca.cpp File Reference
#include "InstCombineInternal.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/Loads.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
Include dependency graph for InstCombineLoadStoreAlloca.cpp:

Go to the source code of this file.

Macros

#define DEBUG_TYPE   "instcombine"
 

Functions

 STATISTIC (NumDeadStore, "Number of dead stores eliminated")
 
 STATISTIC (NumGlobalCopies, "Number of allocas copied from constant global")
 
static bool pointsToConstantGlobal (Value *V)
 pointsToConstantGlobal - Return true if V (possibly indirectly) points to some part of a constant global variable. More...
 
static bool isOnlyCopiedFromConstantGlobal (Value *V, MemTransferInst *&TheCopy, SmallVectorImpl< Instruction *> &ToDelete)
 isOnlyCopiedFromConstantGlobal - Recursively walk the uses of a (derived) pointer to an alloca. More...
 
static MemTransferInstisOnlyCopiedFromConstantGlobal (AllocaInst *AI, SmallVectorImpl< Instruction *> &ToDelete)
 isOnlyCopiedFromConstantGlobal - Return true if the specified alloca is only modified by a copy from a constant global. More...
 
static bool isDereferenceableForAllocaSize (const Value *V, const AllocaInst *AI, const DataLayout &DL)
 Returns true if V is dereferenceable for size of alloca. More...
 
static InstructionsimplifyAllocaArraySize (InstCombiner &IC, AllocaInst &AI)
 
static bool isSupportedAtomicType (Type *Ty)
 
static LoadInstcombineLoadToNewType (InstCombiner &IC, LoadInst &LI, Type *NewTy, const Twine &Suffix="")
 Helper to combine a load to a new type. More...
 
static StoreInstcombineStoreToNewValue (InstCombiner &IC, StoreInst &SI, Value *V)
 Combine a store to a new type. More...
 
static bool isMinMaxWithLoads (Value *V)
 Returns true if instruction represent minmax pattern like: select ((cmp load V1, load V2), V1, V2). More...
 
static InstructioncombineLoadToOperationType (InstCombiner &IC, LoadInst &LI)
 Combine loads to match the type of their uses' value after looking through intervening bitcasts. More...
 
static InstructionunpackLoadToAggregate (InstCombiner &IC, LoadInst &LI)
 
static bool isObjectSizeLessThanOrEq (Value *V, uint64_t MaxSize, const DataLayout &DL)
 
static bool canReplaceGEPIdxWithZero (InstCombiner &IC, GetElementPtrInst *GEPI, Instruction *MemI, unsigned &Idx)
 
template<typename T >
static InstructionreplaceGEPIdxWithZero (InstCombiner &IC, Value *Ptr, T &MemI)
 
static bool canSimplifyNullStoreOrGEP (StoreInst &SI)
 
static bool canSimplifyNullLoadOrGEP (LoadInst &LI, Value *Op)
 
static ValuelikeBitCastFromVector (InstCombiner &IC, Value *V)
 Look for extractelement/insertvalue sequence that acts like a bitcast. More...
 
static bool combineStoreToValueType (InstCombiner &IC, StoreInst &SI)
 Combine stores to match the type of value being stored. More...
 
static bool unpackStoreToAggregate (InstCombiner &IC, StoreInst &SI)
 
static bool equivalentAddressValues (Value *A, Value *B)
 equivalentAddressValues - Test if A and B will obviously have the same value. More...
 
static bool removeBitcastsFromLoadStoreOnMinMax (InstCombiner &IC, StoreInst &SI)
 Converts store (bitcast (load (bitcast (select ...)))) to store (load (select ...)), where select is minmax: select ((cmp load V1, load V2), V1, V2). More...
 

Macro Definition Documentation

◆ DEBUG_TYPE

#define DEBUG_TYPE   "instcombine"

Definition at line 31 of file InstCombineLoadStoreAlloca.cpp.

Function Documentation

◆ canReplaceGEPIdxWithZero()

static bool canReplaceGEPIdxWithZero ( InstCombiner IC,
GetElementPtrInst GEPI,
Instruction MemI,
unsigned Idx 
)
static

◆ canSimplifyNullLoadOrGEP()

static bool canSimplifyNullLoadOrGEP ( LoadInst LI,
Value Op 
)
static

◆ canSimplifyNullStoreOrGEP()

static bool canSimplifyNullStoreOrGEP ( StoreInst SI)
static

◆ combineLoadToNewType()

static LoadInst* combineLoadToNewType ( InstCombiner IC,
LoadInst LI,
Type NewTy,
const Twine Suffix = "" 
)
static

Helper to combine a load to a new type.

This just does the work of combining a load to a new type. It handles metadata, etc., and returns the new instruction. The NewTy should be the loaded value type. This will convert it to a pointer, cast the operand to that pointer type, load it, etc.

Note that this will create all of the instructions with whatever insert point the InstCombiner currently is using.

Definition at line 452 of file InstCombineLoadStoreAlloca.cpp.

References assert(), llvm::InstCombiner::Builder, llvm::copyNonnullMetadata(), llvm::copyRangeMetadata(), llvm::IRBuilder< T, Inserter >::CreateAlignedLoad(), llvm::IRBuilder< T, Inserter >::CreateBitCast(), llvm::LoadInst::getAlignment(), llvm::Instruction::getAllMetadata(), llvm::Value::getContext(), llvm::InstCombiner::getDataLayout(), llvm::Value::getName(), llvm::LoadInst::getOrdering(), llvm::LoadInst::getPointerAddressSpace(), llvm::Type::getPointerAddressSpace(), llvm::Type::getPointerElementType(), llvm::LoadInst::getPointerOperand(), llvm::Type::getPointerTo(), llvm::LoadInst::getSyncScopeID(), llvm::Value::getType(), llvm::Instruction::isAtomic(), llvm::Type::isPointerTy(), isSupportedAtomicType(), llvm::LoadInst::isVolatile(), llvm::PatternMatch::m_BitCast(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::match(), llvm::LLVMContext::MD_access_group, llvm::LLVMContext::MD_alias_scope, llvm::LLVMContext::MD_align, llvm::LLVMContext::MD_dbg, llvm::LLVMContext::MD_dereferenceable, llvm::LLVMContext::MD_dereferenceable_or_null, llvm::LLVMContext::MD_fpmath, llvm::LLVMContext::MD_invariant_load, llvm::LLVMContext::MD_mem_parallel_loop_access, llvm::LLVMContext::MD_noalias, llvm::LLVMContext::MD_nonnull, llvm::LLVMContext::MD_nontemporal, llvm::LLVMContext::MD_prof, llvm::LLVMContext::MD_range, llvm::LLVMContext::MD_tbaa, llvm::LLVMContext::MD_tbaa_struct, N, llvm::LoadInst::setAtomic(), and llvm::Instruction::setMetadata().

Referenced by combineLoadToOperationType(), removeBitcastsFromLoadStoreOnMinMax(), and unpackLoadToAggregate().

◆ combineLoadToOperationType()

static Instruction* combineLoadToOperationType ( InstCombiner IC,
LoadInst LI 
)
static

Combine loads to match the type of their uses' value after looking through intervening bitcasts.

The core idea here is that if the result of a load is used in an operation, we should load the type most conducive to that operation. For example, when loading an integer and converting that immediately to a pointer, we should instead directly load a pointer.

However, this routine must never change the width of a load or the number of loads as that would introduce a semantic change. This combine is expected to be a semantic no-op which just allows loads to more closely model the types of their consuming operations.

Currently, we also refuse to change the precise type used for an atomic load or a volatile load. This is debatable, and might be reasonable to change later. However, it is risky in case some backend or other part of LLVM is relying on the exact type loaded to select appropriate atomic operations.

Definition at line 610 of file InstCombineLoadStoreAlloca.cpp.

References llvm::all_of(), assert(), llvm::InstCombiner::Builder, combineLoadToNewType(), combineStoreToNewValue(), llvm::dyn_cast(), llvm::InstCombiner::eraseInstFromFunction(), llvm::Value::getContext(), llvm::InstCombiner::getDataLayout(), llvm::Type::getIntNTy(), llvm::LoadInst::getPointerOperand(), llvm::Value::getType(), llvm::DataLayout::getTypeSizeInBits(), llvm::DataLayout::getTypeStoreSizeInBits(), llvm::Value::hasOneUse(), llvm::Instruction::isAtomic(), llvm::Type::isIntegerTy(), llvm::DataLayout::isLegalInteger(), isMinMaxWithLoads(), llvm::DataLayout::isNonIntegralPointerType(), llvm::Type::isSized(), isSupportedAtomicType(), llvm::Value::isSwiftError(), llvm::LoadInst::isUnordered(), llvm::peekThroughBitcast(), llvm::Value::replaceAllUsesWith(), llvm::IRBuilderBase::SetInsertPoint(), SI, llvm::Value::use_empty(), llvm::Instruction::user_back(), llvm::Value::user_begin(), llvm::Value::user_end(), and llvm::Value::users().

Referenced by llvm::InstCombiner::visitLoadInst().

◆ combineStoreToNewValue()

static StoreInst* combineStoreToNewValue ( InstCombiner IC,
StoreInst SI,
Value V 
)
static

◆ combineStoreToValueType()

static bool combineStoreToValueType ( InstCombiner IC,
StoreInst SI 
)
static

Combine stores to match the type of value being stored.

The core idea here is that the memory does not have any intrinsic type and where we can we should match the type of a store to the type of value being stored.

However, this routine must never change the width of a store or the number of stores as that would introduce a semantic change. This combine is expected to be a semantic no-op which just allows stores to more closely model the types of their incoming values.

Currently, we also refuse to change the precise type used for an atomic or volatile store. This is debatable, and might be reasonable to change later. However, it is risky in case some backend or other part of LLVM is relying on the exact type stored to select appropriate atomic operations.

Returns
true if the store was successfully combined away. This indicates the caller must erase the store instruction. We have to let the caller erase the store instruction as otherwise there is no way to signal whether it was combined or not: IC.EraseInstFromFunction returns a null pointer.

Definition at line 1176 of file InstCombineLoadStoreAlloca.cpp.

References combineStoreToNewValue(), llvm::StoreInst::getPointerOperand(), llvm::Value::getType(), llvm::StoreInst::getValueOperand(), llvm::Instruction::isAtomic(), isSupportedAtomicType(), llvm::Value::isSwiftError(), llvm::StoreInst::isUnordered(), and likeBitCastFromVector().

Referenced by llvm::InstCombiner::visitStoreInst().

◆ equivalentAddressValues()

static bool equivalentAddressValues ( Value A,
Value B 
)
static

equivalentAddressValues - Test if A and B will obviously have the same value.

This includes recognizing that t0 and t1 will have the same value in code like this: t0 = getelementptr @a, 0, 3 store i32 0, i32* t0 t1 = getelementptr @a, 0, 3 t2 = load i32* t1

Definition at line 1328 of file InstCombineLoadStoreAlloca.cpp.

Referenced by llvm::InstCombiner::visitStoreInst().

◆ isDereferenceableForAllocaSize()

static bool isDereferenceableForAllocaSize ( const Value V,
const AllocaInst AI,
const DataLayout DL 
)
static

◆ isMinMaxWithLoads()

static bool isMinMaxWithLoads ( Value V)
static

◆ isObjectSizeLessThanOrEq()

static bool isObjectSizeLessThanOrEq ( Value V,
uint64_t  MaxSize,
const DataLayout DL 
)
static

◆ isOnlyCopiedFromConstantGlobal() [1/2]

static bool isOnlyCopiedFromConstantGlobal ( Value V,
MemTransferInst *&  TheCopy,
SmallVectorImpl< Instruction *> &  ToDelete 
)
static

isOnlyCopiedFromConstantGlobal - Recursively walk the uses of a (derived) pointer to an alloca.

Ignore any reads of the pointer, return false if we see any stores or other unknown uses. If we see pointer arithmetic, keep track of whether it moves the pointer (with IsOffset) but otherwise traverse the uses. If we see a memcpy/memmove that targets an unoffseted pointer to the alloca, and if the source pointer is a pointer to a constant global, we can optimize this.

Definition at line 60 of file InstCombineLoadStoreAlloca.cpp.

References assert(), llvm::dyn_cast(), llvm::SmallVectorImpl< T >::emplace_back(), llvm::SmallVectorBase::empty(), GEP, llvm::MemTransferBase< BaseCL >::getSource(), I, llvm::MemIntrinsic::isVolatile(), MI, pointsToConstantGlobal(), llvm::SmallVectorImpl< T >::pop_back_val(), and llvm::SmallVectorTemplateBase< T >::push_back().

Referenced by isOnlyCopiedFromConstantGlobal(), and llvm::InstCombiner::visitAllocaInst().

◆ isOnlyCopiedFromConstantGlobal() [2/2]

static MemTransferInst* isOnlyCopiedFromConstantGlobal ( AllocaInst AI,
SmallVectorImpl< Instruction *> &  ToDelete 
)
static

isOnlyCopiedFromConstantGlobal - Return true if the specified alloca is only modified by a copy from a constant global.

If we can prove this, we can replace any uses of the alloca with uses of the global directly.

Definition at line 163 of file InstCombineLoadStoreAlloca.cpp.

References isOnlyCopiedFromConstantGlobal().

◆ isSupportedAtomicType()

static bool isSupportedAtomicType ( Type Ty)
static

◆ likeBitCastFromVector()

static Value* likeBitCastFromVector ( InstCombiner IC,
Value V 
)
static

Look for extractelement/insertvalue sequence that acts like a bitcast.

Returns
underlying value that was "cast", or nullptr otherwise.

For example, if we have:

%E0 = extractelement <2 x double> %U, i32 0
%V0 = insertvalue [2 x double] undef, double %E0, 0
%E1 = extractelement <2 x double> %U, i32 1
%V1 = insertvalue [2 x double] %V0, double %E1, 1

and the layout of a <2 x double> is isomorphic to a [2 x double], then V1 can be safely approximated by a conceptual "bitcast" of U. Note that U may contain non-undef values where V1 has undef.

Definition at line 1115 of file InstCombineLoadStoreAlloca.cpp.

References llvm::dyn_cast(), E, llvm::InstCombiner::getDataLayout(), llvm::Value::getType(), llvm::ARM_MB::ST, and llvm::RISCVFenceField::W.

Referenced by combineStoreToValueType().

◆ pointsToConstantGlobal()

static bool pointsToConstantGlobal ( Value V)
static

pointsToConstantGlobal - Return true if V (possibly indirectly) points to some part of a constant global variable.

This intentionally only accepts constant expressions because we can't rewrite arbitrary instructions.

Definition at line 39 of file InstCombineLoadStoreAlloca.cpp.

Referenced by isOnlyCopiedFromConstantGlobal().

◆ removeBitcastsFromLoadStoreOnMinMax()

static bool removeBitcastsFromLoadStoreOnMinMax ( InstCombiner IC,
StoreInst SI 
)
static

◆ replaceGEPIdxWithZero()

template<typename T >
static Instruction* replaceGEPIdxWithZero ( InstCombiner IC,
Value Ptr,
T MemI 
)
static

◆ simplifyAllocaArraySize()

static Instruction* simplifyAllocaArraySize ( InstCombiner IC,
AllocaInst AI 
)
static

◆ STATISTIC() [1/2]

STATISTIC ( NumDeadStore  ,
"Number of dead stores eliminated"   
)

◆ STATISTIC() [2/2]

STATISTIC ( NumGlobalCopies  ,
"Number of allocas copied from constant global"   
)

◆ unpackLoadToAggregate()

static Instruction* unpackLoadToAggregate ( InstCombiner IC,
LoadInst LI 
)
static

◆ unpackStoreToAggregate()

static bool unpackStoreToAggregate ( InstCombiner IC,
StoreInst SI 
)
static