92 using namespace PatternMatch;
94 #define DEBUG_TYPE "nary-reassociate"
105 bool doInitialization(
Module &M)
override {
109 bool runOnFunction(
Function &
F)
override;
141 unsigned I,
Type *IndexedType);
145 unsigned I,
Value *LHS,
201 return new NaryReassociate();
204 bool NaryReassociate::runOnFunction(
Function &
F) {
205 if (skipOptnoneFunction(F))
208 AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
209 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
210 SE = &getAnalysis<ScalarEvolution>();
211 TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
212 TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
214 bool Changed =
false, ChangedInThisIteration;
216 ChangedInThisIteration = doOneIteration(F);
217 Changed |= ChangedInThisIteration;
218 }
while (ChangedInThisIteration);
225 case Instruction::Add:
226 case Instruction::GetElementPtr:
233 bool NaryReassociate::doOneIteration(
Function &F) {
234 bool Changed =
false;
243 const SCEV *OldSCEV = SE->getSCEV(
I);
247 I->replaceAllUsesWith(NewI);
253 const SCEV *NewSCEV = SE->getSCEV(
I);
254 SeenExprs[NewSCEV].push_back(
I);
273 if (NewSCEV != OldSCEV)
274 SeenExprs[OldSCEV].push_back(
I);
283 case Instruction::Add:
284 return tryReassociateAdd(cast<BinaryOperator>(I));
285 case Instruction::GetElementPtr:
286 return tryReassociateGEP(cast<GetElementPtrInst>(I));
288 llvm_unreachable(
"should be filtered out by isPotentiallyNaryReassociable");
297 int64_t BaseOffset = 0;
298 bool HasBaseReg =
false;
308 if (isa<SequentialType>(*GTI)) {
310 if (
ConstantInt *ConstIdx = dyn_cast<ConstantInt>(*I)) {
311 BaseOffset += ConstIdx->getSExtValue() * ElementSize;
322 uint64_t
Field = cast<ConstantInt>(*I)->getZExtValue();
329 BaseOffset, HasBaseReg, Scale, AddrSpace);
339 if (isa<SequentialType>(*GTI++)) {
340 if (
auto *NewGEP = tryReassociateGEPAtIndex(GEP, I - 1, *GTI)) {
348 bool NaryReassociate::requiresSignExtension(
Value *Index,
350 unsigned PointerSizeInBits =
356 bool NonNegative, Negative;
369 if (isKnownNonNegative(AO, Ctxt) &&
370 (isKnownNonNegative(LHS, Ctxt) || isKnownNonNegative(RHS, Ctxt)))
380 if (
SExtInst *SExt = dyn_cast<SExtInst>(IndexToSplit)) {
381 IndexToSplit = SExt->getOperand(0);
382 }
else if (
ZExtInst *ZExt = dyn_cast<ZExtInst>(IndexToSplit)) {
384 if (isKnownNonNegative(ZExt->getOperand(0),
GEP))
385 IndexToSplit = ZExt->getOperand(0);
388 if (
AddOperator *AO = dyn_cast<AddOperator>(IndexToSplit)) {
392 if (requiresSignExtension(IndexToSplit, GEP) && maySignOverflow(AO, GEP))
396 if (
auto *NewGEP = tryReassociateGEPAtIndex(GEP, I, LHS, RHS, IndexedType))
401 tryReassociateGEPAtIndex(GEP, I, RHS, LHS, IndexedType))
415 IndexExprs.
push_back(SE->getSCEV(*Index));
417 IndexExprs[
I] = SE->getSCEV(LHS);
418 if (isKnownNonNegative(LHS, GEP) &&
428 const SCEV *CandidateExpr = SE->getGEPExpr(
432 auto *Candidate = findClosestMatchingDominator(CandidateExpr, GEP);
433 if (Candidate ==
nullptr)
439 if (TypeOfCandidate ==
nullptr)
443 uint64_t IndexedSize =
DL->getTypeAllocSize(IndexedType);
445 uint64_t ElementSize =
DL->getTypeAllocSize(ElementType);
460 if (IndexedSize % ElementSize != 0)
465 Type *IntPtrTy =
DL->getIntPtrType(TypeOfCandidate);
466 if (RHS->
getType() != IntPtrTy)
467 RHS = Builder.CreateSExtOrTrunc(RHS, IntPtrTy);
468 if (IndexedSize != ElementSize) {
469 RHS = Builder.CreateMul(
473 cast<GetElementPtrInst>(Builder.CreateGEP(Candidate, RHS));
481 if (
auto *NewI = tryReassociateAdd(LHS, RHS, I))
483 if (
auto *NewI = tryReassociateAdd(RHS, LHS, I))
490 Value *
A =
nullptr, *B =
nullptr;
495 const SCEV *AExpr = SE->getSCEV(A), *BExpr = SE->getSCEV(B);
496 const SCEV *RHSExpr = SE->getSCEV(RHS);
497 if (BExpr != RHSExpr) {
498 if (
auto *NewI = tryReassociatedAdd(SE->getAddExpr(AExpr, RHSExpr), B,
I))
501 if (AExpr != RHSExpr) {
502 if (
auto *NewI = tryReassociatedAdd(SE->getAddExpr(BExpr, RHSExpr),
A,
I))
511 auto Pos = SeenExprs.find(LHSExpr);
513 if (Pos == SeenExprs.end())
518 auto *LHS = findClosestMatchingDominator(LHSExpr, I);
528 NaryReassociate::findClosestMatchingDominator(
const SCEV *CandidateExpr,
530 auto Pos = SeenExprs.find(CandidateExpr);
531 if (Pos == SeenExprs.end())
534 auto &Candidates = Pos->second;
539 while (!Candidates.empty()) {
541 if (DT->dominates(Candidate, Dominatee))
543 Candidates.pop_back();
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type (if unknown returns 0).
void push_back(const T &Elt)
A parsed version of the target data layout string in and methods for querying it. ...
Type * getIndexedType() const
Value * getPointerOperand()
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Type * getSourceElementType() const
A Module instance is used to store all the information related to an LLVM module. ...
DominatorTree GraphTraits specialization so the DominatorTree can be iterable by generic graph iterat...
void initializeNaryReassociatePass(PassRegistry &)
This class represents zero extension of integer types.
unsigned getNumOperands() const
bool hasNoSignedWrap() const
Test whether this operation is known to never undergo signed overflow, aka the nsw property...
unsigned getPointerAddressSpace() const
Returns the address space of the pointer operand.
ScalarEvolution - This class is the main scalar evolution driver.
An immutable pass that tracks lazily created AssumptionCache objects.
A cache of .assume calls within a function.
This class represents a sign extension of integer types.
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
iterator begin()
Instruction iterator methods.
bool match(Val *V, const Pattern &P)
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
const StructLayout * getStructLayout(StructType *Ty) const
Returns a StructLayout object, indicating the alignment of the struct, its size, and the offsets of i...
StructType - Class to represent struct types.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void setIsInBounds(bool b=true)
setIsInBounds - Set or clear the inbounds flag on this GEP instruction.
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
void takeName(Value *V)
Transfer the name from V to this value.
static bool isGEPFoldable(GetElementPtrInst *GEP, const TargetTransformInfo *TTI, const DataLayout *DL)
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
Type * getElementType() const
static BinaryOperator * CreateAdd(Value *S1, Value *S2, const Twine &Name, Instruction *InsertBefore, Value *FlagsOp)
bool isInBounds() const
isInBounds - Determine whether the GEP has the inbounds flag.
PointerType - Class to represent pointers.
uint64_t getElementOffset(unsigned Idx) const
GetElementPtrInst - an instruction for type-safe pointer arithmetic to access elements of arrays and ...
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
Represent the analysis usage information of a pass.
FunctionPass class - This class is used to implement most global optimizations.
Value * getOperand(unsigned i) const
void ComputeSignBit(Value *V, bool &KnownZero, bool &KnownOne, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr)
ComputeSignBit - Determine whether the sign bit is known to be zero or one.
INITIALIZE_PASS_BEGIN(NaryReassociate,"nary-reassociate","Nary reassociation", false, false) INITIALIZE_PASS_END(NaryReassociate
bool RecursivelyDeleteTriviallyDeadInstructions(Value *V, const TargetLibraryInfo *TLI=nullptr)
RecursivelyDeleteTriviallyDeadInstructions - If the specified value is a trivially dead instruction...
This is the shared class of boolean and integer constants.
uint64_t getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
Type * getType() const
All values are typed, get the type of this value.
Provides information about what library functions are available for the current target.
SequentialType * getType() const
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
SCEV - This class represents an analyzed expression in the program.
bool hasOneUse() const
Return true if there is exactly one user of this value.
LLVM Value Representation.
unsigned getOpcode() const
getOpcode() returns a member of one of the enums like Instruction::Add.
static bool isPotentiallyNaryReassociable(Instruction *I)
Legacy analysis pass which computes a DominatorTree.
FunctionPass * createNaryReassociatePass()
gep_type_iterator gep_type_begin(const User *GEP)