diff options
Diffstat (limited to 'llvm/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp')
-rw-r--r-- | llvm/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp | 80 |
1 files changed, 58 insertions, 22 deletions
diff --git a/llvm/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp index 8b8d6590aa6..ce40af1223f 100644 --- a/llvm/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp +++ b/llvm/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp @@ -1,4 +1,4 @@ -//===-- StraightLineStrengthReduce.cpp - ------------------------*- C++ -*-===// +//===- StraightLineStrengthReduce.cpp - -----------------------------------===// // // The LLVM Compiler Infrastructure // @@ -55,26 +55,45 @@ // // - When (i' - i) is constant but i and i' are not, we could still perform // SLSR. + +#include "llvm/ADT/APInt.h" +#include "llvm/ADT/DepthFirstIterator.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/Analysis/ValueTracking.h" +#include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Dominators.h" +#include "llvm/IR/GetElementPtrTypeIterator.h" #include "llvm/IR/IRBuilder.h" +#include "llvm/IR/InstrTypes.h" +#include "llvm/IR/Instruction.h" +#include "llvm/IR/Instructions.h" #include "llvm/IR/Module.h" +#include "llvm/IR/Operator.h" #include "llvm/IR/PatternMatch.h" -#include "llvm/Support/raw_ostream.h" +#include "llvm/IR/Type.h" +#include "llvm/IR/Value.h" +#include "llvm/Pass.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/Local.h" +#include <cassert> +#include <cstdint> +#include <limits> #include <list> #include <vector> using namespace llvm; using namespace PatternMatch; -namespace { +static const unsigned UnknownAddressSpace = + std::numeric_limits<unsigned>::max(); -static const unsigned UnknownAddressSpace = ~0u; +namespace { class StraightLineStrengthReduce : public FunctionPass { public: @@ -88,20 +107,22 @@ public: GEP, // &B[..][i * S][..] }; - Candidate() - : CandidateKind(Invalid), Base(nullptr), Index(nullptr), - Stride(nullptr), Ins(nullptr), Basis(nullptr) {} + Candidate() = default; Candidate(Kind CT, const SCEV *B, ConstantInt *Idx, Value *S, Instruction *I) - : CandidateKind(CT), Base(B), Index(Idx), Stride(S), Ins(I), - Basis(nullptr) {} - Kind CandidateKind; - const SCEV *Base; + : CandidateKind(CT), Base(B), Index(Idx), Stride(S), Ins(I) {} + + Kind CandidateKind = Invalid; + + const SCEV *Base = nullptr; + // Note that Index and Stride of a GEP candidate do not necessarily have the // same integer type. In that case, during rewriting, Stride will be // sign-extended or truncated to Index's type. - ConstantInt *Index; - Value *Stride; + ConstantInt *Index = nullptr; + + Value *Stride = nullptr; + // The instruction this candidate corresponds to. It helps us to rewrite a // candidate with respect to its immediate basis. Note that one instruction // can correspond to multiple candidates depending on how you associate the @@ -116,16 +137,16 @@ public: // or // // <Base: b, Index: 2, Stride: a + 1> - Instruction *Ins; + Instruction *Ins = nullptr; + // Points to the immediate basis of this candidate, or nullptr if we cannot // find any basis for this candidate. - Candidate *Basis; + Candidate *Basis = nullptr; }; static char ID; - StraightLineStrengthReduce() - : FunctionPass(ID), DL(nullptr), DT(nullptr), TTI(nullptr) { + StraightLineStrengthReduce() : FunctionPass(ID) { initializeStraightLineStrengthReducePass(*PassRegistry::getPassRegistry()); } @@ -148,46 +169,58 @@ private: // Returns true if Basis is a basis for C, i.e., Basis dominates C and they // share the same base and stride. bool isBasisFor(const Candidate &Basis, const Candidate &C); + // Returns whether the candidate can be folded into an addressing mode. bool isFoldable(const Candidate &C, TargetTransformInfo *TTI, const DataLayout *DL); + // Returns true if C is already in a simplest form and not worth being // rewritten. bool isSimplestForm(const Candidate &C); + // Checks whether I is in a candidate form. If so, adds all the matching forms // to Candidates, and tries to find the immediate basis for each of them. void allocateCandidatesAndFindBasis(Instruction *I); + // Allocate candidates and find bases for Add instructions. void allocateCandidatesAndFindBasisForAdd(Instruction *I); + // Given I = LHS + RHS, factors RHS into i * S and makes (LHS + i * S) a // candidate. void allocateCandidatesAndFindBasisForAdd(Value *LHS, Value *RHS, Instruction *I); // Allocate candidates and find bases for Mul instructions. void allocateCandidatesAndFindBasisForMul(Instruction *I); + // Splits LHS into Base + Index and, if succeeds, calls // allocateCandidatesAndFindBasis. void allocateCandidatesAndFindBasisForMul(Value *LHS, Value *RHS, Instruction *I); + // Allocate candidates and find bases for GetElementPtr instructions. void allocateCandidatesAndFindBasisForGEP(GetElementPtrInst *GEP); + // A helper function that scales Idx with ElementSize before invoking // allocateCandidatesAndFindBasis. void allocateCandidatesAndFindBasisForGEP(const SCEV *B, ConstantInt *Idx, Value *S, uint64_t ElementSize, Instruction *I); + // Adds the given form <CT, B, Idx, S> to Candidates, and finds its immediate // basis. void allocateCandidatesAndFindBasis(Candidate::Kind CT, const SCEV *B, ConstantInt *Idx, Value *S, Instruction *I); + // Rewrites candidate C with respect to Basis. void rewriteCandidateWithBasis(const Candidate &C, const Candidate &Basis); + // A helper function that factors ArrayIdx to a product of a stride and a // constant index, and invokes allocateCandidatesAndFindBasis with the // factorings. void factorArrayIndex(Value *ArrayIdx, const SCEV *Base, uint64_t ElementSize, GetElementPtrInst *GEP); + // Emit code that computes the "bump" from Basis to C. If the candidate is a // GEP and the bump is not divisible by the element size of the GEP, this // function sets the BumpWithUglyGEP flag to notify its caller to bump the @@ -196,19 +229,22 @@ private: IRBuilder<> &Builder, const DataLayout *DL, bool &BumpWithUglyGEP); - const DataLayout *DL; - DominatorTree *DT; + const DataLayout *DL = nullptr; + DominatorTree *DT = nullptr; ScalarEvolution *SE; - TargetTransformInfo *TTI; + TargetTransformInfo *TTI = nullptr; std::list<Candidate> Candidates; + // Temporarily holds all instructions that are unlinked (but not deleted) by // rewriteCandidateWithBasis. These instructions will be actually removed // after all rewriting finishes. std::vector<Instruction *> UnlinkedInstructions; }; -} // anonymous namespace + +} // end anonymous namespace char StraightLineStrengthReduce::ID = 0; + INITIALIZE_PASS_BEGIN(StraightLineStrengthReduce, "slsr", "Straight line strength reduction", false, false) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) @@ -650,8 +686,8 @@ void StraightLineStrengthReduce::rewriteCandidateWithBasis( else Reduced = Builder.CreateGEP(nullptr, Basis.Ins, Bump); } + break; } - break; default: llvm_unreachable("C.CandidateKind is invalid"); }; |