diff options
Diffstat (limited to 'llvm/lib/Transforms/AggressiveInstCombine')
3 files changed, 48 insertions, 17 deletions
diff --git a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp index 59b94567a9c2..d315c7f13ac2 100644 --- a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp +++ b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp @@ -16,6 +16,7 @@ #include "AggressiveInstCombineInternal.h" #include "llvm-c/Initialization.h" #include "llvm-c/Transforms/AggressiveInstCombine.h" +#include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/BasicAliasAnalysis.h" #include "llvm/Analysis/GlobalsModRef.h" @@ -28,11 +29,17 @@ #include "llvm/InitializePasses.h" #include "llvm/Pass.h" #include "llvm/Transforms/Utils/Local.h" + using namespace llvm; using namespace PatternMatch; #define DEBUG_TYPE "aggressive-instcombine" +STATISTIC(NumAnyOrAllBitsSet, "Number of any/all-bits-set patterns folded"); +STATISTIC(NumGuardedRotates, + "Number of guarded rotates transformed into funnel shifts"); +STATISTIC(NumPopCountRecognized, "Number of popcount idioms recognized"); + namespace { /// Contains expression pattern combiner logic. /// This class provides both the logic to combine expression patterns and @@ -148,6 +155,7 @@ static bool foldGuardedRotateToFunnelShift(Instruction &I) { IRBuilder<> Builder(PhiBB, PhiBB->getFirstInsertionPt()); Function *F = Intrinsic::getDeclaration(Phi.getModule(), IID, Phi.getType()); Phi.replaceAllUsesWith(Builder.CreateCall(F, {RotSrc, RotSrc, RotAmt})); + ++NumGuardedRotates; return true; } @@ -248,6 +256,7 @@ static bool foldAnyOrAllBitsSet(Instruction &I) { : Builder.CreateIsNotNull(And); Value *Zext = Builder.CreateZExt(Cmp, I.getType()); I.replaceAllUsesWith(Zext); + ++NumAnyOrAllBitsSet; return true; } @@ -308,6 +317,7 @@ static bool tryToRecognizePopCount(Instruction &I) { Function *Func = Intrinsic::getDeclaration( I.getModule(), Intrinsic::ctpop, I.getType()); I.replaceAllUsesWith(Builder.CreateCall(Func, {Root})); + ++NumPopCountRecognized; return true; } } diff --git a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombineInternal.h b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombineInternal.h index 44e1c45664e7..42bcadfc7dcd 100644 --- a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombineInternal.h +++ b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombineInternal.h @@ -16,14 +16,8 @@ #define LLVM_LIB_TRANSFORMS_AGGRESSIVEINSTCOMBINE_COMBINEINTERNAL_H #include "llvm/ADT/MapVector.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/Analysis/AliasAnalysis.h" -#include "llvm/Analysis/BasicAliasAnalysis.h" -#include "llvm/Analysis/ConstantFolding.h" -#include "llvm/Analysis/GlobalsModRef.h" -#include "llvm/Analysis/TargetLibraryInfo.h" -#include "llvm/IR/DataLayout.h" -#include "llvm/Pass.h" +#include "llvm/ADT/SmallVector.h" + using namespace llvm; //===----------------------------------------------------------------------===// @@ -47,7 +41,12 @@ using namespace llvm; namespace llvm { class DataLayout; class DominatorTree; + class Function; + class Instruction; class TargetLibraryInfo; + class TruncInst; + class Type; + class Value; class TruncInstCombine { TargetLibraryInfo &TLI; diff --git a/llvm/lib/Transforms/AggressiveInstCombine/TruncInstCombine.cpp b/llvm/lib/Transforms/AggressiveInstCombine/TruncInstCombine.cpp index 7c5767912fd3..5cd40c66227f 100644 --- a/llvm/lib/Transforms/AggressiveInstCombine/TruncInstCombine.cpp +++ b/llvm/lib/Transforms/AggressiveInstCombine/TruncInstCombine.cpp @@ -25,17 +25,25 @@ //===----------------------------------------------------------------------===// #include "AggressiveInstCombineInternal.h" -#include "llvm/ADT/MapVector.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/Statistic.h" #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Dominators.h" +#include "llvm/IR/Instruction.h" #include "llvm/IR/IRBuilder.h" + using namespace llvm; #define DEBUG_TYPE "aggressive-instcombine" +STATISTIC( + NumDAGsReduced, + "Number of truncations eliminated by reducing bit width of expression DAG"); +STATISTIC(NumInstrsReduced, + "Number of instructions whose bit width was reduced"); + /// Given an instruction and a container, it fills all the relevant operands of /// that instruction, with respect to the Trunc expression dag optimizaton. static void getRelevantOperands(Instruction *I, SmallVectorImpl<Value *> &Ops) { @@ -56,6 +64,10 @@ static void getRelevantOperands(Instruction *I, SmallVectorImpl<Value *> &Ops) { Ops.push_back(I->getOperand(0)); Ops.push_back(I->getOperand(1)); break; + case Instruction::Select: + Ops.push_back(I->getOperand(1)); + Ops.push_back(I->getOperand(2)); + break; default: llvm_unreachable("Unreachable!"); } @@ -114,7 +126,8 @@ bool TruncInstCombine::buildTruncExpressionDag() { case Instruction::Mul: case Instruction::And: case Instruction::Or: - case Instruction::Xor: { + case Instruction::Xor: + case Instruction::Select: { SmallVector<Value *, 2> Operands; getRelevantOperands(I, Operands); for (Value *Operand : Operands) @@ -123,7 +136,7 @@ bool TruncInstCombine::buildTruncExpressionDag() { } default: // TODO: Can handle more cases here: - // 1. select, shufflevector, extractelement, insertelement + // 1. shufflevector, extractelement, insertelement // 2. udiv, urem // 3. shl, lshr, ashr // 4. phi node(and loop handling) @@ -194,7 +207,7 @@ unsigned TruncInstCombine::getMinBitWidth() { unsigned IOpBitwidth = InstInfoMap.lookup(IOp).ValidBitWidth; if (IOpBitwidth >= ValidBitWidth) continue; - InstInfoMap[IOp].ValidBitWidth = std::max(ValidBitWidth, IOpBitwidth); + InstInfoMap[IOp].ValidBitWidth = ValidBitWidth; Worklist.push_back(IOp); } } @@ -276,8 +289,10 @@ Type *TruncInstCombine::getBestTruncatedType() { /// version of \p Ty, otherwise return \p Ty. static Type *getReducedType(Value *V, Type *Ty) { assert(Ty && !Ty->isVectorTy() && "Expect Scalar Type"); - if (auto *VTy = dyn_cast<VectorType>(V->getType())) - return VectorType::get(Ty, VTy->getNumElements()); + if (auto *VTy = dyn_cast<VectorType>(V->getType())) { + // FIXME: should this handle scalable vectors? + return FixedVectorType::get(Ty, VTy->getNumElements()); + } return Ty; } @@ -286,9 +301,7 @@ Value *TruncInstCombine::getReducedOperand(Value *V, Type *SclTy) { if (auto *C = dyn_cast<Constant>(V)) { C = ConstantExpr::getIntegerCast(C, Ty, false); // If we got a constantexpr back, try to simplify it with DL info. - if (Constant *FoldedC = ConstantFoldConstant(C, DL, &TLI)) - C = FoldedC; - return C; + return ConstantFoldConstant(C, DL, &TLI); } auto *I = cast<Instruction>(V); @@ -298,6 +311,7 @@ Value *TruncInstCombine::getReducedOperand(Value *V, Type *SclTy) { } void TruncInstCombine::ReduceExpressionDag(Type *SclTy) { + NumInstrsReduced += InstInfoMap.size(); for (auto &Itr : InstInfoMap) { // Forward Instruction *I = Itr.first; TruncInstCombine::Info &NodeInfo = Itr.second; @@ -351,6 +365,13 @@ void TruncInstCombine::ReduceExpressionDag(Type *SclTy) { Res = Builder.CreateBinOp((Instruction::BinaryOps)Opc, LHS, RHS); break; } + case Instruction::Select: { + Value *Op0 = I->getOperand(0); + Value *LHS = getReducedOperand(I->getOperand(1), SclTy); + Value *RHS = getReducedOperand(I->getOperand(2), SclTy); + Res = Builder.CreateSelect(Op0, LHS, RHS); + break; + } default: llvm_unreachable("Unhandled instruction"); } @@ -409,6 +430,7 @@ bool TruncInstCombine::run(Function &F) { "dominated by: " << CurrentTruncInst << '\n'); ReduceExpressionDag(NewDstSclTy); + ++NumDAGsReduced; MadeIRChange = true; } } |