diff options
Diffstat (limited to 'lib/Transforms/Scalar/StraightLineStrengthReduce.cpp')
| -rw-r--r-- | lib/Transforms/Scalar/StraightLineStrengthReduce.cpp | 80 | 
1 files changed, 58 insertions, 22 deletions
| diff --git a/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp b/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp index 8b8d6590aa6a..ce40af1223f6 100644 --- a/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp +++ b/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");    }; | 
