36#define AA_NAME "alignment-from-assumptions"
37#define DEBUG_TYPE AA_NAME
41 "Number of loads changed by alignment assumptions");
43 "Number of stores changed by alignment assumptions");
45 "Number of memory intrinsics changed by alignment assumptions");
73char AlignmentFromAssumptions::ID = 0;
74static const char aip_name[] =
"Alignment from assumptions";
84 return new AlignmentFromAssumptions();
94 const SCEV *AlignSCEV,
99 LLVM_DEBUG(
dbgs() <<
"\talignment relative to " << *AlignSCEV <<
" is "
100 << *DiffUnitsSCEV <<
" (diff: " << *DiffSCEV <<
")\n");
103 dyn_cast<SCEVConstant>(DiffUnitsSCEV)) {
104 int64_t DiffUnits = ConstDUSCEV->getValue()->getSExtValue();
110 return cast<SCEVConstant>(AlignSCEV)->getValue()->getAlignValue();
114 uint64_t DiffUnitsAbs = std::abs(DiffUnits);
116 return Align(DiffUnitsAbs);
135 if (isa<SCEVCouldNotCompute>(DiffSCEV))
147 << *AlignSCEV <<
" and offset " << *OffSCEV
148 <<
" using diff " << *DiffSCEV <<
"\n");
152 return *NewAlignment;
155 if (
const SCEVAddRecExpr *DiffARSCEV = dyn_cast<SCEVAddRecExpr>(DiffSCEV)) {
163 const SCEV *DiffStartSCEV = DiffARSCEV->getStart();
164 const SCEV *DiffIncSCEV = DiffARSCEV->getStepRecurrence(*SE);
167 << *DiffStartSCEV <<
" and inc " << *DiffIncSCEV <<
"\n");
182 if (!NewAlignment || !NewIncAlignment)
185 const Align NewAlign = *NewAlignment;
186 const Align NewIncAlign = *NewIncAlignment;
187 if (NewAlign > NewIncAlign) {
192 if (NewIncAlign > NewAlign) {
197 assert(NewIncAlign == NewAlign);
209 const SCEV *&AlignSCEV,
210 const SCEV *&OffSCEV) {
216 AAPtr = AlignOB.
Inputs[0].get();
221 if (!isa<SCEVConstant>(AlignSCEV))
225 if (AlignOB.
Inputs.size() == 3)
236 const SCEV *AlignSCEV, *OffSCEV;
242 if (isa<ConstantData>(AAPtr))
258 while (!WorkList.
empty()) {
260 if (
LoadInst *LI = dyn_cast<LoadInst>(J)) {
264 LI->getPointerOperand(),
SE);
265 if (NewAlignment > LI->getAlign()) {
266 LI->setAlignment(NewAlignment);
267 ++NumLoadAlignChanged;
269 }
else if (
StoreInst *
SI = dyn_cast<StoreInst>(J)) {
273 SI->getPointerOperand(),
SE);
274 if (NewAlignment >
SI->getAlign()) {
275 SI->setAlignment(NewAlignment);
276 ++NumStoreAlignChanged;
281 Align NewDestAlignment =
286 if (NewDestAlignment > *
MI->getDestAlign()) {
287 MI->setDestAlignment(NewDestAlignment);
288 ++NumMemIntAlignChanged;
294 Align NewSrcAlignment =
300 if (NewSrcAlignment > *MTI->getSourceAlign()) {
301 MTI->setSourceAlignment(NewSrcAlignment);
302 ++NumMemIntAlignChanged;
312 if (!Visited.
count(K))
320bool AlignmentFromAssumptions::runOnFunction(
Function &
F) {
324 auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
F);
325 ScalarEvolution *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
326 DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
328 return Impl.runImpl(
F, AC, SE, DT);
337 bool Changed =
false;
340 CallInst *Call = cast<CallInst>(AssumeVH);
341 for (
unsigned Idx = 0;
Idx < Call->getNumOperandBundles();
Idx++)
static MaybeAlign getNewAlignmentDiff(const SCEV *DiffSCEV, const SCEV *AlignSCEV, ScalarEvolution *SE)
static const char aip_name[]
static Align getNewAlignment(const SCEV *AASCEV, const SCEV *AlignSCEV, const SCEV *OffSCEV, Value *Ptr, ScalarEvolution *SE)
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This is the interface for a simple mod/ref and alias analysis over globals.
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallPtrSet class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
A container for analyses that lazily runs them and caches their results.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
A function analysis which provides an AssumptionCache.
An immutable pass that tracks lazily created AssumptionCache objects.
A cache of @llvm.assume calls within a function.
MutableArrayRef< ResultElem > assumptions()
Access the list of assumption handles currently tracked for this function.
Represents analyses that only rely on functions' control flow.
This class represents a function call, abstracting a target machine's calling convention.
Analysis pass which computes a DominatorTree.
Legacy analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
FunctionPass class - This class is used to implement most global optimizations.
virtual bool runOnFunction(Function &F)=0
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
Legacy wrapper pass to provide the GlobalsAAResult object.
An instruction for reading from memory.
The legacy pass manager's analysis pass to compute loop information.
This is the common base class for memset/memcpy/memmove.
This class wraps the llvm.memcpy/memmove intrinsics.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
void preserveSet()
Mark an analysis set as preserved.
void preserve()
Mark an analysis as preserved.
This node represents a polynomial recurrence on the trip count of the specified loop.
This class represents a constant integer value.
This class represents an analyzed expression in the program.
Type * getType() const
Return the LLVM type of this SCEV expression.
Analysis pass that exposes the ScalarEvolution for a function.
The main scalar evolution driver.
const SCEV * getURemExpr(const SCEV *LHS, const SCEV *RHS)
Represents an unsigned remainder expression based on unsigned division.
const SCEV * getZero(Type *Ty)
Return a SCEV for the constant 0 of a specific type.
const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
const SCEV * getNoopOrSignExtend(const SCEV *V, Type *Ty)
Return a SCEV corresponding to a conversion of the input value to the specified type.
Type * getEffectiveSCEVType(Type *Ty) const
Return a type with the same bitwidth as the given type and which represents how SCEV will treat the g...
const SCEV * getMinusSCEV(const SCEV *LHS, const SCEV *RHS, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Return LHS-RHS.
const SCEV * getTruncateOrZeroExtend(const SCEV *V, Type *Ty, unsigned Depth=0)
Return a SCEV corresponding to a conversion of the input value to the specified type.
const SCEV * getAddExpr(SmallVectorImpl< const SCEV * > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Get a canonical add expression, or something simpler if possible.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
The instances of the Type class are immutable: once they are created, they are never changed.
static IntegerType * getInt64Ty(LLVMContext &C)
LLVM Value Representation.
iterator_range< user_iterator > users()
const Value * stripPointerCastsSameRepresentation() const
Strip off pointer casts, all-zero GEPs and address space casts but ensures the representation of the ...
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
std::string DebugStr(const Align &A)
void initializeAlignmentFromAssumptionsPass(PassRegistry &)
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
FunctionPass * createAlignmentFromAssumptionsPass()
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isValidAssumeForContext(const Instruction *I, const Instruction *CxtI, const DominatorTree *DT=nullptr)
Return true if it is valid to use the assumptions provided by an assume intrinsic,...
This struct is a compact representation of a valid (non-zero power of two) alignment.
bool extractAlignmentInfo(CallInst *I, unsigned Idx, Value *&AAPtr, const SCEV *&AlignSCEV, const SCEV *&OffSCEV)
bool processAssumption(CallInst *I, unsigned Idx)
bool runImpl(Function &F, AssumptionCache &AC, ScalarEvolution *SE_, DominatorTree *DT_)
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
A lightweight accessor for an operand bundle meant to be passed around by value.
StringRef getTagName() const
Return the tag of this operand bundle as a string.