diff --git a/llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp b/llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp --- a/llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp +++ b/llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp @@ -160,6 +160,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Statistic.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/ScalarEvolution.h" @@ -177,7 +178,6 @@ #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" -#include "llvm/IR/Module.h" #include "llvm/IR/PassManager.h" #include "llvm/IR/PatternMatch.h" #include "llvm/IR/Type.h" @@ -201,6 +201,8 @@ #define DEBUG_TYPE "separate-const-offset-from-gep" +STATISTIC(NumSplittedGEPs, "Number of splitted GEPs"); + static cl::opt DisableSeparateConstOffsetFromGEP( "disable-separate-const-offset-from-gep", cl::init(false), cl::desc("Do not separate the constant offset from a GEP instruction"), @@ -257,15 +259,15 @@ /// successful, returns C and update UserChain as a def-use chain from C to V; /// otherwise, UserChain is empty. /// - /// \p V The given expression - /// \p SignExtended Whether V will be sign-extended in the computation - /// of the GEP index - /// \p ZeroExtended Whether V will be zero-extended in the computation - /// of the GEP index - /// \p NonNegative Whether V is guaranteed to be non-negative. For - /// example, an index of an inbounds GEP is guaranteed - /// to be non-negative. Levaraging this, we can better - /// split inbounds GEPs. + /// \p V The given expression + /// \p SignExtended Whether V will be sign-extended in the computation of the + /// GEP index + /// \p ZeroExtended Whether V will be zero-extended in the computation of the + /// GEP index + /// \p NonNegative Whether V is guaranteed to be non-negative. For example, + /// an index of an inbounds GEP is guaranteed to be + /// non-negative. Levaraging this, we can better split + /// inbounds GEPs. APInt find(Value *V, bool SignExtended, bool ZeroExtended, bool NonNegative); /// A helper function to look into both operands of a binary operator. @@ -995,6 +997,9 @@ /*BaseGV=*/nullptr, AccumulativeByteOffset, /*HasBaseReg=*/true, /*Scale=*/0, AddrSpace)) { + LLVM_DEBUG( + dbgs() + << "Don't optimize. The backend doesn't support the addressing mode\n"); return Changed; } } @@ -1094,6 +1099,8 @@ Instruction *NewGEP = GEP->clone(); NewGEP->insertBefore(GEP); + LLVM_DEBUG(dbgs() << "Created new base GEP " << *NewGEP << "\n"); + // Per ANSI C standard, signed / unsigned = unsigned and signed % unsigned = // unsigned.. Therefore, we cast ElementTypeSizeOfGEP to signed because it is // used with unsigned integers later. @@ -1140,8 +1147,11 @@ } GEP->replaceAllUsesWith(NewGEP); + LLVM_DEBUG(dbgs() << "Replaced GEP " << *GEP << " with new one " << *GEP << "\n"); GEP->eraseFromParent(); + NumSplittedGEPs++; + return true; }