LLVM API Documentation
#include "llvm/Transforms/Scalar.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AssumptionTracker.h"
#include "llvm/Analysis/Loads.h"
#include "llvm/Analysis/PtrUseVisitor.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstVisitor.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Operator.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/TimeValue.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/PromoteMemToReg.h"
#include "llvm/Transforms/Utils/SSAUpdater.h"
Go to the source code of this file.
Classes | |
struct | llvm::isPodLike< Slice > |
class | AllocaSlices::SliceBuilder |
Builder for the alloca slices. More... | |
Namespaces | |
namespace | llvm |
List of target independent CodeGen pass IDs. | |
Defines | |
#define | DEBUG_TYPE "sroa" |
Functions | |
STATISTIC (NumAllocasAnalyzed,"Number of allocas analyzed for replacement") | |
STATISTIC (NumAllocaPartitions,"Number of alloca partitions formed") | |
STATISTIC (MaxPartitionsPerAlloca,"Maximum number of partitions per alloca") | |
STATISTIC (NumAllocaPartitionUses,"Number of alloca partition uses rewritten") | |
STATISTIC (MaxUsesPerAllocaPartition,"Maximum number of uses of a partition") | |
STATISTIC (NumNewAllocas,"Number of new, smaller allocas introduced") | |
STATISTIC (NumPromoted,"Number of allocas promoted to SSA values") | |
STATISTIC (NumLoadsSpeculated,"Number of loads speculated to allow promotion") | |
STATISTIC (NumDeleted,"Number of instructions deleted") | |
STATISTIC (NumVectorized,"Number of vectorized aggregates") | |
static Value * | foldSelectInst (SelectInst &SI) |
static Value * | foldPHINodeOrSelectInst (Instruction &I) |
A helper that folds a PHI node or a select. | |
INITIALIZE_PASS_BEGIN (SROA,"sroa","Scalar Replacement Of Aggregates", false, false) INITIALIZE_PASS_END(SROA | |
Scalar Replacement Of static false Type * | findCommonType (AllocaSlices::const_iterator B, AllocaSlices::const_iterator E, uint64_t EndOffset) |
static bool | isSafePHIToSpeculate (PHINode &PN, const DataLayout *DL=nullptr) |
static void | speculatePHINodeLoads (PHINode &PN) |
static bool | isSafeSelectToSpeculate (SelectInst &SI, const DataLayout *DL=nullptr) |
static void | speculateSelectInstLoads (SelectInst &SI) |
static Value * | buildGEP (IRBuilderTy &IRB, Value *BasePtr, SmallVectorImpl< Value * > &Indices, Twine NamePrefix) |
Build a GEP out of a base pointer and indices. | |
static Value * | getNaturalGEPWithType (IRBuilderTy &IRB, const DataLayout &DL, Value *BasePtr, Type *Ty, Type *TargetTy, SmallVectorImpl< Value * > &Indices, Twine NamePrefix) |
Get a natural GEP off of the BasePtr walking through Ty toward TargetTy without changing the offset of the pointer. | |
static Value * | getNaturalGEPRecursively (IRBuilderTy &IRB, const DataLayout &DL, Value *Ptr, Type *Ty, APInt &Offset, Type *TargetTy, SmallVectorImpl< Value * > &Indices, Twine NamePrefix) |
Recursively compute indices for a natural GEP. | |
static Value * | getNaturalGEPWithOffset (IRBuilderTy &IRB, const DataLayout &DL, Value *Ptr, APInt Offset, Type *TargetTy, SmallVectorImpl< Value * > &Indices, Twine NamePrefix) |
Get a natural GEP from a base pointer to a particular offset and resulting in a particular type. | |
static Value * | getAdjustedPtr (IRBuilderTy &IRB, const DataLayout &DL, Value *Ptr, APInt Offset, Type *PointerTy, Twine NamePrefix) |
Compute an adjusted pointer from Ptr by Offset bytes where the resulting pointer has PointerTy. | |
static bool | canConvertValue (const DataLayout &DL, Type *OldTy, Type *NewTy) |
Test whether we can convert a value from the old to the new type. | |
static Value * | convertValue (const DataLayout &DL, IRBuilderTy &IRB, Value *V, Type *NewTy) |
Generic routine to convert an SSA value to a value of a different type. | |
static bool | isVectorPromotionViableForSlice (const DataLayout &DL, AllocaSlices &S, uint64_t SliceBeginOffset, uint64_t SliceEndOffset, VectorType *Ty, uint64_t ElementSize, AllocaSlices::const_iterator I) |
Test whether the given slice use can be promoted to a vector. | |
static bool | isVectorPromotionViable (const DataLayout &DL, Type *AllocaTy, AllocaSlices &S, uint64_t SliceBeginOffset, uint64_t SliceEndOffset, AllocaSlices::const_iterator I, AllocaSlices::const_iterator E, ArrayRef< AllocaSlices::iterator > SplitUses) |
Test whether the given alloca partitioning and range of slices can be promoted to a vector. | |
static bool | isIntegerWideningViableForSlice (const DataLayout &DL, Type *AllocaTy, uint64_t AllocBeginOffset, uint64_t Size, AllocaSlices &S, AllocaSlices::const_iterator I, bool &WholeAllocaOp) |
Test whether a slice of an alloca is valid for integer widening. | |
static bool | isIntegerWideningViable (const DataLayout &DL, Type *AllocaTy, uint64_t AllocBeginOffset, AllocaSlices &S, AllocaSlices::const_iterator I, AllocaSlices::const_iterator E, ArrayRef< AllocaSlices::iterator > SplitUses) |
Test whether the given alloca partition's integer operations can be widened to promotable ones. | |
static Value * | extractInteger (const DataLayout &DL, IRBuilderTy &IRB, Value *V, IntegerType *Ty, uint64_t Offset, const Twine &Name) |
static Value * | insertInteger (const DataLayout &DL, IRBuilderTy &IRB, Value *Old, Value *V, uint64_t Offset, const Twine &Name) |
static Value * | extractVector (IRBuilderTy &IRB, Value *V, unsigned BeginIndex, unsigned EndIndex, const Twine &Name) |
static Value * | insertVector (IRBuilderTy &IRB, Value *Old, Value *V, unsigned BeginIndex, const Twine &Name) |
static Type * | stripAggregateTypeWrapping (const DataLayout &DL, Type *Ty) |
Strip aggregate type wrapping. | |
static Type * | getTypePartition (const DataLayout &DL, Type *Ty, uint64_t Offset, uint64_t Size) |
Try to find a partition of the aggregate type passed in for a given offset and size. | |
static void | removeFinishedSplitUses (SmallVectorImpl< AllocaSlices::iterator > &SplitUses, uint64_t &MaxSplitUseEndOffset, uint64_t Offset) |
static void | enqueueUsersInWorklist (Instruction &I, SmallVectorImpl< Instruction * > &Worklist, SmallPtrSetImpl< Instruction * > &Visited) |
Variables | |
static cl::opt< bool > | ForceSSAUpdater ("force-ssa-updater", cl::init(false), cl::Hidden) |
static cl::opt< bool > | SROARandomShuffleSlices ("sroa-random-shuffle-slices", cl::init(false), cl::Hidden) |
static cl::opt< bool > | SROAStrictInbounds ("sroa-strict-inbounds", cl::init(false), cl::Hidden) |
sroa | |
Scalar Replacement Of | Aggregates |
Scalar Replacement Of | false |
This transformation implements the well known scalar replacement of aggregates transformation. It tries to identify promotable elements of an aggregate alloca, and promote them to registers. It will also try to convert uses of an element (or set of elements) of an alloca into a vector or bitfield-style integer scalar if appropriate.
It works to do this with minimal slicing of the alloca so that regions which are merely transferred in and out of external memory remain unchanged and are not decomposed to scalar code.
Because this also performs alloca promotion, it can be thought of as also serving the purpose of SSA formation. The algorithm iterates on the function until all opportunities for promotion have been realized.
Definition in file SROA.cpp.
#define DEBUG_TYPE "sroa" |
static Value* buildGEP | ( | IRBuilderTy & | IRB, |
Value * | BasePtr, | ||
SmallVectorImpl< Value * > & | Indices, | ||
Twine | NamePrefix | ||
) | [static] |
Build a GEP out of a base pointer and indices.
This will return the BasePtr if that is valid, or build a new GEP instruction using the IRBuilder if GEP-ing is needed.
Definition at line 1271 of file SROA.cpp.
References llvm::SmallVectorTemplateCommon< T, typename >::back(), llvm::SmallVectorBase::empty(), isZero(), and llvm::SmallVectorTemplateCommon< T, typename >::size().
Referenced by getNaturalGEPWithType().
static bool canConvertValue | ( | const DataLayout & | DL, |
Type * | OldTy, | ||
Type * | NewTy | ||
) | [static] |
Test whether we can convert a value from the old to the new type.
This predicate should be used to guard calls to convertValue in order to ensure that we only try to convert viable values. The strategy is that we will peel off single element struct and array wrappings to get to an underlying value, and convert that value.
Definition at line 1545 of file SROA.cpp.
References llvm::Type::getScalarType(), llvm::DataLayout::getTypeSizeInBits(), llvm::Type::isIntegerTy(), llvm::Type::isPointerTy(), and llvm::Type::isSingleValueType().
Referenced by convertValue(), isIntegerWideningViable(), isIntegerWideningViableForSlice(), and isVectorPromotionViableForSlice().
static Value* convertValue | ( | const DataLayout & | DL, |
IRBuilderTy & | IRB, | ||
Value * | V, | ||
Type * | NewTy | ||
) | [static] |
Generic routine to convert an SSA value to a value of a different type.
This will try various different casting techniques, such as bitcasts, inttoptr, and ptrtoint casts. Use the canConvertValue
predicate to test two types for viability with this routine.
Definition at line 1578 of file SROA.cpp.
References canConvertValue(), llvm::DataLayout::getIntPtrType(), llvm::Type::getScalarType(), llvm::Value::getType(), llvm::Type::isIntegerTy(), llvm::Type::isPointerTy(), and llvm::Type::isVectorTy().
static void enqueueUsersInWorklist | ( | Instruction & | I, |
SmallVectorImpl< Instruction * > & | Worklist, | ||
SmallPtrSetImpl< Instruction * > & | Visited | ||
) | [static] |
Definition at line 3533 of file SROA.cpp.
References llvm::SmallPtrSetImpl< PtrType >::insert(), llvm::SmallVectorTemplateBase< T, isPodLike >::push_back(), and llvm::Value::users().
static Value* extractInteger | ( | const DataLayout & | DL, |
IRBuilderTy & | IRB, | ||
Value * | V, | ||
IntegerType * | Ty, | ||
uint64_t | Offset, | ||
const Twine & | Name | ||
) | [static] |
Definition at line 1863 of file SROA.cpp.
References llvm::dbgs(), DEBUG, llvm::IntegerType::getBitWidth(), llvm::Value::getType(), llvm::DataLayout::getTypeStoreSize(), and llvm::DataLayout::isBigEndian().
static Value* extractVector | ( | IRBuilderTy & | IRB, |
Value * | V, | ||
unsigned | BeginIndex, | ||
unsigned | EndIndex, | ||
const Twine & | Name | ||
) | [static] |
Definition at line 1917 of file SROA.cpp.
References llvm::dbgs(), DEBUG, llvm::VectorType::getNumElements(), llvm::Value::getType(), llvm::SmallVectorTemplateBase< T, isPodLike< T >::value >::push_back(), and llvm::SmallVectorImpl< T >::reserve().
Scalar Replacement Of static false Type* findCommonType | ( | AllocaSlices::const_iterator | B, |
AllocaSlices::const_iterator | E, | ||
uint64_t | EndOffset | ||
) | [static] |
Walk the range of a partitioning looking for a common type to cover this sequence of slices.
Definition at line 1015 of file SROA.cpp.
References llvm::IntegerType::getBitWidth(), llvm::Value::getType(), llvm::StoreInst::getValueOperand(), and I.
static Value* foldPHINodeOrSelectInst | ( | Instruction & | I | ) | [static] |
A helper that folds a PHI node or a select.
Definition at line 329 of file SROA.cpp.
References foldSelectInst().
static Value* foldSelectInst | ( | SelectInst & | SI | ) | [static] |
Definition at line 316 of file SROA.cpp.
References llvm::SelectInst::getCondition(), and llvm::User::getOperand().
Referenced by foldPHINodeOrSelectInst().
static Value* getAdjustedPtr | ( | IRBuilderTy & | IRB, |
const DataLayout & | DL, | ||
Value * | Ptr, | ||
APInt | Offset, | ||
Type * | PointerTy, | ||
Twine | NamePrefix | ||
) | [static] |
Compute an adjusted pointer from Ptr by Offset bytes where the resulting pointer has PointerTy.
This tries very hard to compute a "natural" GEP which arrives at the offset and produces the pointer type desired. Where it cannot, it will try to use the natural GEP to arrive at the offset and bitcast to the type. Where that fails, it will try to use an existing i8* and GEP to the byte offset and bitcast to the type.
The strategy for finding the more natural GEPs is to peel off layers of the pointer, walking back through bit casts and GEPs, searching for a base pointer from which we can compute a natural GEP with the desired properties. The algorithm tries to fold as many constant indices into a single GEP as possible, thus making each GEP more independent of the surrounding code.
Definition at line 1450 of file SROA.cpp.
References llvm::SmallVectorImpl< T >::clear(), llvm::Instruction::eraseFromParent(), llvm::APInt::getBitWidth(), getNaturalGEPWithOffset(), llvm::Type::getPointerAddressSpace(), llvm::Type::getPointerElementType(), llvm::Value::getType(), llvm::SmallPtrSetImpl< PtrType >::insert(), llvm::Type::isIntegerTy(), llvm::Type::isPointerTy(), P, and llvm::Value::use_empty().
static Value* getNaturalGEPRecursively | ( | IRBuilderTy & | IRB, |
const DataLayout & | DL, | ||
Value * | Ptr, | ||
Type * | Ty, | ||
APInt & | Offset, | ||
Type * | TargetTy, | ||
SmallVectorImpl< Value * > & | Indices, | ||
Twine | NamePrefix | ||
) | [static] |
Recursively compute indices for a natural GEP.
This is the recursive step for getNaturalGEPWithOffset that walks down the element types adding appropriate indices for the GEP.
Definition at line 1337 of file SROA.cpp.
References llvm::dyn_cast(), llvm::APInt::getBitWidth(), llvm::StructLayout::getElementContainingOffset(), llvm::StructLayout::getElementOffset(), llvm::StructType::getElementType(), getNaturalGEPWithType(), llvm::StructLayout::getSizeInBytes(), llvm::DataLayout::getStructLayout(), llvm::DataLayout::getTypeAllocSize(), llvm::DataLayout::getTypeSizeInBits(), llvm::APInt::getZExtValue(), llvm::Type::isPointerTy(), llvm::SmallVectorTemplateBase< T, isPodLike >::push_back(), llvm::APInt::sdiv(), and llvm::APInt::uge().
Referenced by getNaturalGEPWithOffset().
static Value* getNaturalGEPWithOffset | ( | IRBuilderTy & | IRB, |
const DataLayout & | DL, | ||
Value * | Ptr, | ||
APInt | Offset, | ||
Type * | TargetTy, | ||
SmallVectorImpl< Value * > & | Indices, | ||
Twine | NamePrefix | ||
) | [static] |
Get a natural GEP from a base pointer to a particular offset and resulting in a particular type.
The goal is to produce a "natural" looking GEP that works with the existing composite types to arrive at the appropriate offset and element type for a pointer. TargetTy is the element type the returned GEP should point-to if possible. We recurse by decreasing Offset, adding the appropriate index to Indices, and setting Ty to the result subtype.
If no natural GEP can be constructed, this function returns null.
Definition at line 1410 of file SROA.cpp.
References llvm::PointerType::getAddressSpace(), llvm::APInt::getBitWidth(), llvm::SequentialType::getElementType(), llvm::Type::getInt8PtrTy(), getNaturalGEPRecursively(), llvm::Value::getType(), llvm::DataLayout::getTypeAllocSize(), llvm::Type::isIntegerTy(), llvm::Type::isSized(), llvm::SmallVectorTemplateBase< T, isPodLike >::push_back(), and llvm::APInt::sdiv().
Referenced by getAdjustedPtr().
static Value* getNaturalGEPWithType | ( | IRBuilderTy & | IRB, |
const DataLayout & | DL, | ||
Value * | BasePtr, | ||
Type * | Ty, | ||
Type * | TargetTy, | ||
SmallVectorImpl< Value * > & | Indices, | ||
Twine | NamePrefix | ||
) | [static] |
Get a natural GEP off of the BasePtr walking through Ty toward TargetTy without changing the offset of the pointer.
This routine assumes we've already established a properly offset GEP with Indices, and arrived at the Ty type. The goal is to continue to GEP with zero-indices down through type layers until we find one the same as TargetTy. If we can't find one with the same type, we at least try to use one with the same size. If none of that works, we just produce the GEP as indicated by Indices to have the correct offset.
Definition at line 1293 of file SROA.cpp.
References buildGEP(), llvm::SmallVectorTemplateCommon< T, typename >::end(), llvm::SmallVectorImpl< T >::erase(), llvm::DataLayout::getPointerTypeSizeInBits(), llvm::Value::getType(), llvm::Type::isPointerTy(), and llvm::SmallVectorTemplateBase< T, isPodLike >::push_back().
Referenced by getNaturalGEPRecursively().
static Type* getTypePartition | ( | const DataLayout & | DL, |
Type * | Ty, | ||
uint64_t | Offset, | ||
uint64_t | Size | ||
) | [static] |
Try to find a partition of the aggregate type passed in for a given offset and size.
This recurses through the aggregate type and tries to compute a subtype based on the offset and size. When the offset and size span a sub-section of an array, it will even compute a new array type for that sub-section, and the same for structs.
Note that this routine is very strict and tries to find a partition of the type which produces the *exact* right offset and size. It is not forgiving when the size or offset cause either end of type-based partition to be off. Also, this is a best-effort routine. It is reasonable to give up and not return a type if necessary.
Definition at line 3012 of file SROA.cpp.
References llvm::dyn_cast(), llvm::StructType::element_begin(), llvm::StructType::element_end(), llvm::Type::getContext(), llvm::StructLayout::getElementContainingOffset(), llvm::StructLayout::getElementOffset(), llvm::StructType::getElementType(), llvm::StructLayout::getSizeInBytes(), llvm::DataLayout::getStructLayout(), llvm::DataLayout::getTypeAllocSize(), llvm::StructType::isPacked(), llvm::makeArrayRef(), and stripAggregateTypeWrapping().
INITIALIZE_PASS_BEGIN | ( | SROA | , |
"sroa" | , | ||
"Scalar Replacement Of Aggregates" | , | ||
false | , | ||
false | |||
) |
static Value* insertInteger | ( | const DataLayout & | DL, |
IRBuilderTy & | IRB, | ||
Value * | Old, | ||
Value * | V, | ||
uint64_t | Offset, | ||
const Twine & | Name | ||
) | [static] |
Definition at line 1886 of file SROA.cpp.
References llvm::dbgs(), DEBUG, llvm::IntegerType::getBitWidth(), llvm::Value::getType(), llvm::DataLayout::getTypeStoreSize(), llvm::DataLayout::isBigEndian(), llvm::APIntOps::shl(), and llvm::APInt::zext().
static Value* insertVector | ( | IRBuilderTy & | IRB, |
Value * | Old, | ||
Value * | V, | ||
unsigned | BeginIndex, | ||
const Twine & | Name | ||
) | [static] |
Definition at line 1945 of file SROA.cpp.
References llvm::SmallVectorImpl< T >::clear(), llvm::dbgs(), DEBUG, llvm::dyn_cast(), llvm::VectorType::getNumElements(), llvm::Value::getType(), llvm::SmallVectorTemplateBase< T, isPodLike< T >::value >::push_back(), and llvm::SmallVectorImpl< T >::reserve().
static bool isIntegerWideningViable | ( | const DataLayout & | DL, |
Type * | AllocaTy, | ||
uint64_t | AllocBeginOffset, | ||
AllocaSlices & | S, | ||
AllocaSlices::const_iterator | I, | ||
AllocaSlices::const_iterator | E, | ||
ArrayRef< AllocaSlices::iterator > | SplitUses | ||
) | [static] |
Test whether the given alloca partition's integer operations can be widened to promotable ones.
This is a quick test to check whether we can rewrite the integer loads and stores to a particular alloca into wider loads and stores and be able to promote the resulting alloca.
Definition at line 1817 of file SROA.cpp.
References llvm::ArrayRef< T >::begin(), canConvertValue(), llvm::ArrayRef< T >::end(), llvm::Type::getContext(), llvm::DataLayout::getTypeSizeInBits(), llvm::DataLayout::getTypeStoreSize(), llvm::DataLayout::getTypeStoreSizeInBits(), I, isIntegerWideningViableForSlice(), and llvm::DataLayout::isLegalInteger().
static bool isIntegerWideningViableForSlice | ( | const DataLayout & | DL, |
Type * | AllocaTy, | ||
uint64_t | AllocBeginOffset, | ||
uint64_t | Size, | ||
AllocaSlices & | S, | ||
AllocaSlices::const_iterator | I, | ||
bool & | WholeAllocaOp | ||
) | [static] |
Test whether a slice of an alloca is valid for integer widening.
This implements the necessary checking for the isIntegerWideningViable
test below on a single slice of the alloca.
Definition at line 1749 of file SROA.cpp.
References canConvertValue(), llvm::IntrinsicInst::getIntrinsicID(), llvm::Value::getType(), llvm::DataLayout::getTypeStoreSizeInBits(), llvm::StoreInst::getValueOperand(), llvm::LoadInst::isVolatile(), llvm::StoreInst::isVolatile(), and llvm::AArch64CC::MI.
Referenced by isIntegerWideningViable().
static bool isSafePHIToSpeculate | ( | PHINode & | PN, |
const DataLayout * | DL = nullptr |
||
) | [static] |
PHI instructions that use an alloca and are subsequently loaded can be rewritten to load both input pointers in the pred blocks and then PHI the results, allowing the load of the alloca to be promoted. From this: P2 = phi [i32* Alloca, i32* Other] V = load i32* P2 to: V1 = load i32* Alloca -> will be mem2reg'd ... V2 = load i32* Other ... V = phi [i32 V1, i32 V2]
We can do this to a select if its only uses are loads and if the operands to the select can be loaded unconditionally.
FIXME: This should be hoisted into a generic utility, likely in Transforms/Util/Local.h
Definition at line 1082 of file SROA.cpp.
References llvm::dyn_cast(), llvm::LoadInst::getAlignment(), llvm::PHINode::getIncomingBlock(), llvm::PHINode::getIncomingValue(), llvm::PHINode::getNumIncomingValues(), llvm::TerminatorInst::getNumSuccessors(), llvm::Instruction::getParent(), llvm::BasicBlock::getTerminator(), llvm::Value::isDereferenceablePointer(), llvm::isSafeToLoadUnconditionally(), llvm::LoadInst::isSimple(), LI, llvm::Instruction::mayHaveSideEffects(), and llvm::Value::users().
static bool isSafeSelectToSpeculate | ( | SelectInst & | SI, |
const DataLayout * | DL = nullptr |
||
) | [static] |
Select instructions that use an alloca and are subsequently loaded can be rewritten to load both input pointers and then select between the result, allowing the load of the alloca to be promoted. From this: P2 = select i1 cond, i32* Alloca, i32* Other V = load i32* P2 to: V1 = load i32* Alloca -> will be mem2reg'd V2 = load i32* Other V = select i1 cond, i32 V1, i32 V2
We can do this to a select if its only uses are loads and if the operand to the select can be loaded unconditionally.
Definition at line 1202 of file SROA.cpp.
References llvm::dyn_cast(), llvm::LoadInst::getAlignment(), llvm::SelectInst::getFalseValue(), llvm::SelectInst::getTrueValue(), llvm::Value::isDereferenceablePointer(), llvm::isSafeToLoadUnconditionally(), llvm::LoadInst::isSimple(), and llvm::Value::users().
static bool isVectorPromotionViable | ( | const DataLayout & | DL, |
Type * | AllocaTy, | ||
AllocaSlices & | S, | ||
uint64_t | SliceBeginOffset, | ||
uint64_t | SliceEndOffset, | ||
AllocaSlices::const_iterator | I, | ||
AllocaSlices::const_iterator | E, | ||
ArrayRef< AllocaSlices::iterator > | SplitUses | ||
) | [static] |
Test whether the given alloca partitioning and range of slices can be promoted to a vector.
This is a quick test to check whether we can rewrite a particular alloca partition (and its newly formed alloca) into a vector alloca with only whole-vector loads and stores such that it could be promoted to a vector SSA value. We only can ensure this for a limited set of operations, and we don't want to do the rewrites unless we are confident that the result will be promotable, so we have an early test here.
Definition at line 1711 of file SROA.cpp.
References llvm::ArrayRef< T >::begin(), llvm::dyn_cast(), llvm::ArrayRef< T >::end(), llvm::Type::getScalarType(), llvm::DataLayout::getTypeSizeInBits(), I, and isVectorPromotionViableForSlice().
static bool isVectorPromotionViableForSlice | ( | const DataLayout & | DL, |
AllocaSlices & | S, | ||
uint64_t | SliceBeginOffset, | ||
uint64_t | SliceEndOffset, | ||
VectorType * | Ty, | ||
uint64_t | ElementSize, | ||
AllocaSlices::const_iterator | I | ||
) | [static] |
Test whether the given slice use can be promoted to a vector.
This function is called to test each entry in a partioning which is slated for a single slice.
Definition at line 1632 of file SROA.cpp.
References canConvertValue(), llvm::Type::getContext(), llvm::SequentialType::getElementType(), llvm::IntrinsicInst::getIntrinsicID(), llvm::VectorType::getNumElements(), llvm::Value::getType(), llvm::StoreInst::getValueOperand(), llvm::Type::isIntegerTy(), llvm::LoadInst::isVolatile(), llvm::StoreInst::isVolatile(), and llvm::AArch64CC::MI.
Referenced by isVectorPromotionViable().
static void removeFinishedSplitUses | ( | SmallVectorImpl< AllocaSlices::iterator > & | SplitUses, |
uint64_t & | MaxSplitUseEndOffset, | ||
uint64_t | Offset | ||
) | [static] |
Definition at line 3276 of file SROA.cpp.
References llvm::SmallVectorTemplateCommon< T >::begin(), llvm::SmallVectorImpl< T >::clear(), llvm::SmallVectorTemplateCommon< T >::end(), llvm::SmallVectorImpl< T >::erase(), I, and llvm::SmallVectorTemplateCommon< T >::size().
static void speculatePHINodeLoads | ( | PHINode & | PN | ) | [static] |
Definition at line 1146 of file SROA.cpp.
References llvm::PHINode::addIncoming(), Align(), llvm::dbgs(), DEBUG, llvm::Instruction::eraseFromParent(), llvm::Instruction::getAAMetadata(), llvm::LoadInst::getAlignment(), llvm::PHINode::getIncomingBlock(), llvm::PHINode::getIncomingValue(), llvm::Value::getName(), llvm::PHINode::getNumIncomingValues(), llvm::BasicBlock::getTerminator(), llvm::Value::getType(), llvm::SPII::Load, llvm::Value::replaceAllUsesWith(), llvm::Instruction::setAAMetadata(), llvm::LoadInst::setAlignment(), llvm::Value::use_empty(), and llvm::Instruction::user_back().
static void speculateSelectInstLoads | ( | SelectInst & | SI | ) | [static] |
Definition at line 1228 of file SROA.cpp.
References llvm::dbgs(), DEBUG, llvm::Instruction::eraseFromParent(), llvm::Instruction::getAAMetadata(), llvm::LoadInst::getAlignment(), llvm::SelectInst::getCondition(), llvm::SelectInst::getFalseValue(), llvm::Value::getName(), llvm::SelectInst::getTrueValue(), llvm::LoadInst::isSimple(), llvm::Value::replaceAllUsesWith(), llvm::Instruction::setAAMetadata(), llvm::LoadInst::setAlignment(), llvm::Value::use_empty(), and llvm::Instruction::user_back().
STATISTIC | ( | NumAllocasAnalyzed | , |
"Number of allocas analyzed for replacement" | |||
) |
STATISTIC | ( | NumAllocaPartitions | , |
"Number of alloca partitions formed" | |||
) |
STATISTIC | ( | MaxPartitionsPerAlloca | , |
"Maximum number of partitions per alloca" | |||
) |
STATISTIC | ( | NumAllocaPartitionUses | , |
"Number of alloca partition uses rewritten" | |||
) |
STATISTIC | ( | MaxUsesPerAllocaPartition | , |
"Maximum number of uses of a partition" | |||
) |
STATISTIC | ( | NumNewAllocas | , |
"Number of | new, | ||
smaller allocas introduced" | |||
) |
STATISTIC | ( | NumPromoted | , |
"Number of allocas promoted to SSA values" | |||
) |
STATISTIC | ( | NumDeleted | , |
"Number of instructions deleted" | |||
) |
STATISTIC | ( | NumVectorized | , |
"Number of vectorized aggregates" | |||
) |
static Type* stripAggregateTypeWrapping | ( | const DataLayout & | DL, |
Type * | Ty | ||
) | [static] |
Strip aggregate type wrapping.
This removes no-op aggregate types wrapping an underlying type. It will strip as many layers of types as it can without changing either the type size or the allocated size.
Definition at line 2974 of file SROA.cpp.
References llvm::StructLayout::getElementContainingOffset(), llvm::DataLayout::getStructLayout(), llvm::DataLayout::getTypeAllocSize(), llvm::DataLayout::getTypeSizeInBits(), and llvm::Type::isSingleValueType().
Referenced by getTypePartition().
Scalar Replacement Of Aggregates |
cl::opt<bool> ForceSSAUpdater("force-ssa-updater", cl::init(false), cl::Hidden) [static] |
Hidden option to force the pass to not use DomTree and mem2reg, instead forming SSA values through the SSAUpdater infrastructure.
cl::opt<bool> SROARandomShuffleSlices("sroa-random-shuffle-slices", cl::init(false), cl::Hidden) [static] |
Hidden option to enable randomly shuffling the slices to help uncover instability in their order.
cl::opt<bool> SROAStrictInbounds("sroa-strict-inbounds", cl::init(false), cl::Hidden) [static] |
Hidden option to experiment with completely strict handling of inbounds GEPs.