forked from OSchip/llvm-project
[Transforms] Fix some Clang-tidy modernize and Include What You Use warnings; other minor fixes (NFC).
llvm-svn: 315940
This commit is contained in:
parent
608e1b57cf
commit
dd40f5e7c1
|
@ -15,17 +15,20 @@
|
|||
#ifndef LLVM_TRANSFORMS_SCALAR_INDVARSIMPLIFY_H
|
||||
#define LLVM_TRANSFORMS_SCALAR_INDVARSIMPLIFY_H
|
||||
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Analysis/LoopAnalysisManager.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Transforms/Scalar/LoopPassManager.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class Loop;
|
||||
class LPMUpdater;
|
||||
|
||||
class IndVarSimplifyPass : public PassInfoMixin<IndVarSimplifyPass> {
|
||||
public:
|
||||
PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
|
||||
LoopStandardAnalysisResults &AR, LPMUpdater &U);
|
||||
};
|
||||
}
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_TRANSFORMS_SCALAR_INDVARSIMPLIFY_H
|
||||
|
|
|
@ -21,10 +21,13 @@
|
|||
|
||||
namespace llvm {
|
||||
|
||||
class Function;
|
||||
|
||||
class LoopDistributePass : public PassInfoMixin<LoopDistributePass> {
|
||||
public:
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_TRANSFORMS_SCALAR_LOOPDISTRIBUTE_H
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===- LoopIdiomRecognize.h - Loop Idiom Recognize Pass -------*- C++ -*-===//
|
||||
//===- LoopIdiomRecognize.h - Loop Idiom Recognize Pass ---------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -16,18 +16,21 @@
|
|||
#ifndef LLVM_TRANSFORMS_SCALAR_LOOPIDIOMRECOGNIZE_H
|
||||
#define LLVM_TRANSFORMS_SCALAR_LOOPIDIOMRECOGNIZE_H
|
||||
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Analysis/LoopAnalysisManager.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Transforms/Scalar/LoopPassManager.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class Loop;
|
||||
class LPMUpdater;
|
||||
|
||||
/// Performs Loop Idiom Recognize Pass.
|
||||
class LoopIdiomRecognizePass : public PassInfoMixin<LoopIdiomRecognizePass> {
|
||||
public:
|
||||
PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
|
||||
LoopStandardAnalysisResults &AR, LPMUpdater &U);
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_TRANSFORMS_SCALAR_LOOPIDIOMRECOGNIZE_H
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===- LoopInstSimplify.h - Loop Inst Simplify Pass -------*- C++ -*-===//
|
||||
//===- LoopInstSimplify.h - Loop Inst Simplify Pass -------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -14,18 +14,21 @@
|
|||
#ifndef LLVM_TRANSFORMS_SCALAR_LOOPINSTSIMPLIFY_H
|
||||
#define LLVM_TRANSFORMS_SCALAR_LOOPINSTSIMPLIFY_H
|
||||
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Analysis/LoopAnalysisManager.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Transforms/Scalar/LoopPassManager.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class Loop;
|
||||
class LPMUpdater;
|
||||
|
||||
/// Performs Loop Inst Simplify Pass.
|
||||
class LoopInstSimplifyPass : public PassInfoMixin<LoopInstSimplifyPass> {
|
||||
public:
|
||||
PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
|
||||
LoopStandardAnalysisResults &AR, LPMUpdater &U);
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_TRANSFORMS_SCALAR_LOOPINSTSIMPLIFY_H
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===---- LoopLoadElimination.h ---------------------------------*- C++ -*-===//
|
||||
//===- LoopLoadElimination.h ------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -6,11 +6,12 @@
|
|||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
/// \file
|
||||
/// This header defines the LoopLoadEliminationPass object. This pass forwards
|
||||
/// loaded values around loop backedges to allow their use in subsequent
|
||||
/// iterations.
|
||||
///
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_TRANSFORMS_SCALAR_LOOPLOADELIMINATION_H
|
||||
|
@ -20,11 +21,14 @@
|
|||
|
||||
namespace llvm {
|
||||
|
||||
class Function;
|
||||
|
||||
/// Pass to forward loads in a loop around the backedge to subsequent
|
||||
/// iterations.
|
||||
struct LoopLoadEliminationPass : public PassInfoMixin<LoopLoadEliminationPass> {
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
};
|
||||
}
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_TRANSFORMS_SCALAR_LOOPLOADELIMINATION_H
|
||||
|
|
|
@ -25,27 +25,54 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Transforms/Scalar/IndVarSimplify.h"
|
||||
#include "llvm/ADT/APFloat.h"
|
||||
#include "llvm/ADT/APInt.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/None.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Analysis/GlobalsModRef.h"
|
||||
#include "llvm/ADT/iterator_range.h"
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Analysis/LoopPass.h"
|
||||
#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
|
||||
#include "llvm/Analysis/ScalarEvolution.h"
|
||||
#include "llvm/Analysis/ScalarEvolutionExpander.h"
|
||||
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
|
||||
#include "llvm/Analysis/TargetLibraryInfo.h"
|
||||
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/IR/CFG.h"
|
||||
#include "llvm/IR/Constant.h"
|
||||
#include "llvm/IR/ConstantRange.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
#include "llvm/IR/Dominators.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/InstrTypes.h"
|
||||
#include "llvm/IR/Instruction.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/IntrinsicInst.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/Intrinsics.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/Operator.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/IR/PatternMatch.h"
|
||||
#include "llvm/IR/Type.h"
|
||||
#include "llvm/IR/Use.h"
|
||||
#include "llvm/IR/User.h"
|
||||
#include "llvm/IR/Value.h"
|
||||
#include "llvm/IR/ValueHandle.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Transforms/Scalar.h"
|
||||
#include "llvm/Transforms/Scalar/LoopPassManager.h"
|
||||
|
@ -53,6 +80,10 @@
|
|||
#include "llvm/Transforms/Utils/Local.h"
|
||||
#include "llvm/Transforms/Utils/LoopUtils.h"
|
||||
#include "llvm/Transforms/Utils/SimplifyIndVar.h"
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "indvars"
|
||||
|
@ -91,6 +122,7 @@ DisableLFTR("disable-lftr", cl::Hidden, cl::init(false),
|
|||
cl::desc("Disable Linear Function Test Replace optimization"));
|
||||
|
||||
namespace {
|
||||
|
||||
struct RewritePhi;
|
||||
|
||||
class IndVarSimplify {
|
||||
|
@ -131,7 +163,8 @@ public:
|
|||
|
||||
bool run(Loop *L);
|
||||
};
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
/// Return true if the SCEV expansion generated by the rewriter can replace the
|
||||
/// original value. SCEV guarantees that it produces the same value, but the way
|
||||
|
@ -251,7 +284,6 @@ static bool ConvertToSInt(const APFloat &APF, int64_t &IntVal) {
|
|||
/// is converted into
|
||||
/// for(int i = 0; i < 10000; ++i)
|
||||
/// bar((double)i);
|
||||
///
|
||||
void IndVarSimplify::handleFloatingPointIV(Loop *L, PHINode *PN) {
|
||||
unsigned IncomingEdge = L->contains(PN->getIncomingBlock(0));
|
||||
unsigned BackEdge = IncomingEdge^1;
|
||||
|
@ -305,7 +337,6 @@ void IndVarSimplify::handleFloatingPointIV(Loop *L, PHINode *PN) {
|
|||
L->contains(TheBr->getSuccessor(1))))
|
||||
return;
|
||||
|
||||
|
||||
// If it isn't a comparison with an integer-as-fp (the exit value), we can't
|
||||
// transform it.
|
||||
ConstantFP *ExitValueVal = dyn_cast<ConstantFP>(Compare->getOperand(1));
|
||||
|
@ -373,7 +404,6 @@ void IndVarSimplify::handleFloatingPointIV(Loop *L, PHINode *PN) {
|
|||
// transform the IV.
|
||||
if (Leftover != 0 && int32_t(ExitValue+IncValue) < ExitValue)
|
||||
return;
|
||||
|
||||
} else {
|
||||
// If we have a negative stride, we require the init to be greater than the
|
||||
// exit value.
|
||||
|
@ -452,7 +482,6 @@ void IndVarSimplify::rewriteNonIntegerIVs(Loop *L) {
|
|||
// First step. Check to see if there are any floating-point recurrences.
|
||||
// If there are, change them into integer recurrences, permitting analysis by
|
||||
// the SCEV routines.
|
||||
//
|
||||
BasicBlock *Header = L->getHeader();
|
||||
|
||||
SmallVector<WeakTrackingVH, 8> PHIs;
|
||||
|
@ -472,18 +501,26 @@ void IndVarSimplify::rewriteNonIntegerIVs(Loop *L) {
|
|||
}
|
||||
|
||||
namespace {
|
||||
|
||||
// Collect information about PHI nodes which can be transformed in
|
||||
// rewriteLoopExitValues.
|
||||
struct RewritePhi {
|
||||
PHINode *PN;
|
||||
unsigned Ith; // Ith incoming value.
|
||||
Value *Val; // Exit value after expansion.
|
||||
bool HighCost; // High Cost when expansion.
|
||||
|
||||
// Ith incoming value.
|
||||
unsigned Ith;
|
||||
|
||||
// Exit value after expansion.
|
||||
Value *Val;
|
||||
|
||||
// High Cost when expansion.
|
||||
bool HighCost;
|
||||
|
||||
RewritePhi(PHINode *P, unsigned I, Value *V, bool H)
|
||||
: PN(P), Ith(I), Val(V), HighCost(H) {}
|
||||
};
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
Value *IndVarSimplify::expandSCEVIfNeeded(SCEVExpander &Rewriter, const SCEV *S,
|
||||
Loop *L, Instruction *InsertPt,
|
||||
|
@ -747,7 +784,6 @@ void IndVarSimplify::rewriteFirstIterationLoopExitValues(Loop *L) {
|
|||
/// aggressively.
|
||||
bool IndVarSimplify::canLoopBeDeleted(
|
||||
Loop *L, SmallVector<RewritePhi, 8> &RewritePhiSet) {
|
||||
|
||||
BasicBlock *Preheader = L->getLoopPreheader();
|
||||
// If there is no preheader, the loop will not be deleted.
|
||||
if (!Preheader)
|
||||
|
@ -790,7 +826,9 @@ bool IndVarSimplify::canLoopBeDeleted(
|
|||
}
|
||||
|
||||
for (auto *BB : L->blocks())
|
||||
if (any_of(*BB, [](Instruction &I) { return I.mayHaveSideEffects(); }))
|
||||
if (llvm::any_of(*BB, [](Instruction &I) {
|
||||
return I.mayHaveSideEffects();
|
||||
}))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -801,15 +839,21 @@ bool IndVarSimplify::canLoopBeDeleted(
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
namespace {
|
||||
|
||||
// Collect information about induction variables that are used by sign/zero
|
||||
// extend operations. This information is recorded by CollectExtend and provides
|
||||
// the input to WidenIV.
|
||||
struct WideIVInfo {
|
||||
PHINode *NarrowIV = nullptr;
|
||||
Type *WidestNativeType = nullptr; // Widest integer type created [sz]ext
|
||||
bool IsSigned = false; // Was a sext user seen before a zext?
|
||||
|
||||
// Widest integer type created [sz]ext
|
||||
Type *WidestNativeType = nullptr;
|
||||
|
||||
// Was a sext user seen before a zext?
|
||||
bool IsSigned = false;
|
||||
};
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
/// Update information about the induction variable that is extended by this
|
||||
/// sign or zero extend operation. This is used to determine the final width of
|
||||
|
@ -885,7 +929,6 @@ struct NarrowIVDefUse {
|
|||
/// creating any new induction variables. To do this, it creates a new phi of
|
||||
/// the wider type and redirects all users, either removing extends or inserting
|
||||
/// truncs whenever we stop propagating the type.
|
||||
///
|
||||
class WidenIV {
|
||||
// Parameters
|
||||
PHINode *OrigPhi;
|
||||
|
@ -902,22 +945,24 @@ class WidenIV {
|
|||
bool HasGuards;
|
||||
|
||||
// Result
|
||||
PHINode *WidePhi;
|
||||
Instruction *WideInc;
|
||||
const SCEV *WideIncExpr;
|
||||
PHINode *WidePhi = nullptr;
|
||||
Instruction *WideInc = nullptr;
|
||||
const SCEV *WideIncExpr = nullptr;
|
||||
SmallVectorImpl<WeakTrackingVH> &DeadInsts;
|
||||
|
||||
SmallPtrSet<Instruction *,16> Widened;
|
||||
SmallVector<NarrowIVDefUse, 8> NarrowIVUsers;
|
||||
|
||||
enum ExtendKind { ZeroExtended, SignExtended, Unknown };
|
||||
|
||||
// A map tracking the kind of extension used to widen each narrow IV
|
||||
// and narrow IV user.
|
||||
// Key: pointer to a narrow IV or IV user.
|
||||
// Value: the kind of extension used to widen this Instruction.
|
||||
DenseMap<AssertingVH<Instruction>, ExtendKind> ExtendKindMap;
|
||||
|
||||
typedef std::pair<AssertingVH<Value>, AssertingVH<Instruction>> DefUserPair;
|
||||
using DefUserPair = std::pair<AssertingVH<Value>, AssertingVH<Instruction>>;
|
||||
|
||||
// A map with control-dependent ranges for post increment IV uses. The key is
|
||||
// a pair of IV def and a use of this def denoting the context. The value is
|
||||
// a ConstantRange representing possible values of the def at the given
|
||||
|
@ -935,6 +980,7 @@ class WidenIV {
|
|||
|
||||
void calculatePostIncRanges(PHINode *OrigPhi);
|
||||
void calculatePostIncRange(Instruction *NarrowDef, Instruction *NarrowUser);
|
||||
|
||||
void updatePostIncRangeInfo(Value *Def, Instruction *UseI, ConstantRange R) {
|
||||
DefUserPair Key(Def, UseI);
|
||||
auto It = PostIncRangeInfos.find(Key);
|
||||
|
@ -950,8 +996,7 @@ public:
|
|||
bool HasGuards)
|
||||
: OrigPhi(WI.NarrowIV), WideType(WI.WidestNativeType), LI(LInfo),
|
||||
L(LI->getLoopFor(OrigPhi->getParent())), SE(SEv), DT(DTree),
|
||||
HasGuards(HasGuards), WidePhi(nullptr), WideInc(nullptr),
|
||||
WideIncExpr(nullptr), DeadInsts(DI) {
|
||||
HasGuards(HasGuards), DeadInsts(DI) {
|
||||
assert(L->getHeader() == OrigPhi->getParent() && "Phi must be an IV");
|
||||
ExtendKindMap[OrigPhi] = WI.IsSigned ? SignExtended : ZeroExtended;
|
||||
}
|
||||
|
@ -969,7 +1014,7 @@ protected:
|
|||
|
||||
ExtendKind getExtendKind(Instruction *I);
|
||||
|
||||
typedef std::pair<const SCEVAddRecExpr *, ExtendKind> WidenedRecTy;
|
||||
using WidenedRecTy = std::pair<const SCEVAddRecExpr *, ExtendKind>;
|
||||
|
||||
WidenedRecTy getWideRecurrence(NarrowIVDefUse DU);
|
||||
|
||||
|
@ -984,7 +1029,8 @@ protected:
|
|||
|
||||
void pushNarrowIVUsers(Instruction *NarrowDef, Instruction *WideDef);
|
||||
};
|
||||
} // anonymous namespace
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
/// Perform a quick domtree based check for loop invariance assuming that V is
|
||||
/// used within the loop. LoopInfo::isLoopInvariant() seems gratuitous for this
|
||||
|
@ -1182,7 +1228,6 @@ const SCEV *WidenIV::getSCEVByOpCode(const SCEV *LHS, const SCEV *RHS,
|
|||
/// operands is an AddRec for this loop, return the AddRec and the kind of
|
||||
/// extension used.
|
||||
WidenIV::WidenedRecTy WidenIV::getExtendedOperandRecurrence(NarrowIVDefUse DU) {
|
||||
|
||||
// Handle the common case of add<nsw/nuw>
|
||||
const unsigned OpCode = DU.NarrowUse->getOpcode();
|
||||
// Only Add/Sub/Mul instructions supported yet.
|
||||
|
@ -1310,7 +1355,7 @@ bool WidenIV::widenLoopCompare(NarrowIVDefUse DU) {
|
|||
Value *Op = Cmp->getOperand(Cmp->getOperand(0) == DU.NarrowDef ? 1 : 0);
|
||||
unsigned CastWidth = SE->getTypeSizeInBits(Op->getType());
|
||||
unsigned IVWidth = SE->getTypeSizeInBits(WideType);
|
||||
assert (CastWidth <= IVWidth && "Unexpected width while widening compare.");
|
||||
assert(CastWidth <= IVWidth && "Unexpected width while widening compare.");
|
||||
|
||||
// Widen the compare instruction.
|
||||
IRBuilder<> Builder(
|
||||
|
@ -1461,7 +1506,6 @@ Instruction *WidenIV::widenIVUse(NarrowIVDefUse DU, SCEVExpander &Rewriter) {
|
|||
}
|
||||
|
||||
/// Add eligible users of NarrowDef to NarrowIVUsers.
|
||||
///
|
||||
void WidenIV::pushNarrowIVUsers(Instruction *NarrowDef, Instruction *WideDef) {
|
||||
const SCEV *NarrowSCEV = SE->getSCEV(NarrowDef);
|
||||
bool NonNegativeDef =
|
||||
|
@ -1494,7 +1538,6 @@ void WidenIV::pushNarrowIVUsers(Instruction *NarrowDef, Instruction *WideDef) {
|
|||
///
|
||||
/// It would be simpler to delete uses as they are processed, but we must avoid
|
||||
/// invalidating SCEV expressions.
|
||||
///
|
||||
PHINode *WidenIV::createWideIV(SCEVExpander &Rewriter) {
|
||||
// Is this phi an induction variable?
|
||||
const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(SE->getSCEV(OrigPhi));
|
||||
|
@ -1696,12 +1739,12 @@ void WidenIV::calculatePostIncRanges(PHINode *OrigPhi) {
|
|||
// Live IV Reduction - Minimize IVs live across the loop.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Simplification of IV users based on SCEV evaluation.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
namespace {
|
||||
|
||||
class IndVarSimplifyVisitor : public IVVisitor {
|
||||
ScalarEvolution *SE;
|
||||
const TargetTransformInfo *TTI;
|
||||
|
@ -1721,14 +1764,14 @@ public:
|
|||
// Implement the interface used by simplifyUsersOfIV.
|
||||
void visitCast(CastInst *Cast) override { visitIVCast(Cast, WI, SE, TTI); }
|
||||
};
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
/// Iteratively perform simplification on a worklist of IV users. Each
|
||||
/// successive simplification may push more users which may themselves be
|
||||
/// candidates for simplification.
|
||||
///
|
||||
/// Sign/Zero extend elimination is interleaved with IV simplification.
|
||||
///
|
||||
void IndVarSimplify::simplifyAndExtend(Loop *L,
|
||||
SCEVExpander &Rewriter,
|
||||
LoopInfo *LI) {
|
||||
|
@ -2502,8 +2545,10 @@ PreservedAnalyses IndVarSimplifyPass::run(Loop &L, LoopAnalysisManager &AM,
|
|||
}
|
||||
|
||||
namespace {
|
||||
|
||||
struct IndVarSimplifyLegacyPass : public LoopPass {
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
|
||||
IndVarSimplifyLegacyPass() : LoopPass(ID) {
|
||||
initializeIndVarSimplifyLegacyPassPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
@ -2530,9 +2575,11 @@ struct IndVarSimplifyLegacyPass : public LoopPass {
|
|||
getLoopAnalysisUsage(AU);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
char IndVarSimplifyLegacyPass::ID = 0;
|
||||
|
||||
INITIALIZE_PASS_BEGIN(IndVarSimplifyLegacyPass, "indvars",
|
||||
"Induction Variable Simplification", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(LoopPass)
|
||||
|
|
|
@ -23,32 +23,61 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Transforms/Scalar/LoopDistribute.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/DepthFirstIterator.h"
|
||||
#include "llvm/ADT/EquivalenceClasses.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Analysis/BlockFrequencyInfo.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/ADT/iterator_range.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/GlobalsModRef.h"
|
||||
#include "llvm/Analysis/LoopAccessAnalysis.h"
|
||||
#include "llvm/Analysis/LoopAnalysisManager.h"
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
|
||||
#include "llvm/Analysis/ScalarEvolution.h"
|
||||
#include "llvm/Analysis/TargetLibraryInfo.h"
|
||||
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/DiagnosticInfo.h"
|
||||
#include "llvm/IR/Dominators.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/InstrTypes.h"
|
||||
#include "llvm/IR/Instruction.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/Metadata.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/IR/Value.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Transforms/Scalar/LoopPassManager.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Transforms/Scalar.h"
|
||||
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
||||
#include "llvm/Transforms/Utils/Cloning.h"
|
||||
#include "llvm/Transforms/Utils/LoopUtils.h"
|
||||
#include "llvm/Transforms/Utils/LoopVersioning.h"
|
||||
#include "llvm/Transforms/Utils/ValueMapper.h"
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
#define LDIST_NAME "loop-distribute"
|
||||
#define DEBUG_TYPE LDIST_NAME
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
static cl::opt<bool>
|
||||
LDistVerify("loop-distribute-verify", cl::Hidden,
|
||||
cl::desc("Turn on DominatorTree and LoopInfo verification "
|
||||
|
@ -81,14 +110,15 @@ static cl::opt<bool> EnableLoopDistribute(
|
|||
STATISTIC(NumLoopsDistributed, "Number of loops distributed");
|
||||
|
||||
namespace {
|
||||
|
||||
/// \brief Maintains the set of instructions of the loop for a partition before
|
||||
/// cloning. After cloning, it hosts the new loop.
|
||||
class InstPartition {
|
||||
typedef SmallPtrSet<Instruction *, 8> InstructionSet;
|
||||
using InstructionSet = SmallPtrSet<Instruction *, 8>;
|
||||
|
||||
public:
|
||||
InstPartition(Instruction *I, Loop *L, bool DepCycle = false)
|
||||
: DepCycle(DepCycle), OrigLoop(L), ClonedLoop(nullptr) {
|
||||
: DepCycle(DepCycle), OrigLoop(L) {
|
||||
Set.insert(I);
|
||||
}
|
||||
|
||||
|
@ -220,7 +250,7 @@ private:
|
|||
|
||||
/// \brief The cloned loop. If this partition is mapped to the original loop,
|
||||
/// this is null.
|
||||
Loop *ClonedLoop;
|
||||
Loop *ClonedLoop = nullptr;
|
||||
|
||||
/// \brief The blocks of ClonedLoop including the preheader. If this
|
||||
/// partition is mapped to the original loop, this is empty.
|
||||
|
@ -235,7 +265,7 @@ private:
|
|||
/// \brief Holds the set of Partitions. It populates them, merges them and then
|
||||
/// clones the loops.
|
||||
class InstPartitionContainer {
|
||||
typedef DenseMap<Instruction *, int> InstToPartitionIdT;
|
||||
using InstToPartitionIdT = DenseMap<Instruction *, int>;
|
||||
|
||||
public:
|
||||
InstPartitionContainer(Loop *L, LoopInfo *LI, DominatorTree *DT)
|
||||
|
@ -308,8 +338,8 @@ public:
|
|||
///
|
||||
/// Return if any partitions were merged.
|
||||
bool mergeToAvoidDuplicatedLoads() {
|
||||
typedef DenseMap<Instruction *, InstPartition *> LoadToPartitionT;
|
||||
typedef EquivalenceClasses<InstPartition *> ToBeMergedT;
|
||||
using LoadToPartitionT = DenseMap<Instruction *, InstPartition *>;
|
||||
using ToBeMergedT = EquivalenceClasses<InstPartition *>;
|
||||
|
||||
LoadToPartitionT LoadToPartition;
|
||||
ToBeMergedT ToBeMerged;
|
||||
|
@ -511,7 +541,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
typedef std::list<InstPartition> PartitionContainerT;
|
||||
using PartitionContainerT = std::list<InstPartition>;
|
||||
|
||||
/// \brief List of partitions.
|
||||
PartitionContainerT PartitionContainer;
|
||||
|
@ -552,17 +582,17 @@ private:
|
|||
/// By traversing the memory instructions in program order and accumulating this
|
||||
/// number, we know whether any unsafe dependence crosses over a program point.
|
||||
class MemoryInstructionDependences {
|
||||
typedef MemoryDepChecker::Dependence Dependence;
|
||||
using Dependence = MemoryDepChecker::Dependence;
|
||||
|
||||
public:
|
||||
struct Entry {
|
||||
Instruction *Inst;
|
||||
unsigned NumUnsafeDependencesStartOrEnd;
|
||||
unsigned NumUnsafeDependencesStartOrEnd = 0;
|
||||
|
||||
Entry(Instruction *Inst) : Inst(Inst), NumUnsafeDependencesStartOrEnd(0) {}
|
||||
Entry(Instruction *Inst) : Inst(Inst) {}
|
||||
};
|
||||
|
||||
typedef SmallVector<Entry, 8> AccessesType;
|
||||
using AccessesType = SmallVector<Entry, 8>;
|
||||
|
||||
AccessesType::const_iterator begin() const { return Accesses.begin(); }
|
||||
AccessesType::const_iterator end() const { return Accesses.end(); }
|
||||
|
@ -594,7 +624,7 @@ class LoopDistributeForLoop {
|
|||
public:
|
||||
LoopDistributeForLoop(Loop *L, Function *F, LoopInfo *LI, DominatorTree *DT,
|
||||
ScalarEvolution *SE, OptimizationRemarkEmitter *ORE)
|
||||
: L(L), F(F), LI(LI), LAI(nullptr), DT(DT), SE(SE), ORE(ORE) {
|
||||
: L(L), F(F), LI(LI), DT(DT), SE(SE), ORE(ORE) {
|
||||
setForced();
|
||||
}
|
||||
|
||||
|
@ -861,7 +891,7 @@ private:
|
|||
|
||||
// Analyses used.
|
||||
LoopInfo *LI;
|
||||
const LoopAccessInfo *LAI;
|
||||
const LoopAccessInfo *LAI = nullptr;
|
||||
DominatorTree *DT;
|
||||
ScalarEvolution *SE;
|
||||
OptimizationRemarkEmitter *ORE;
|
||||
|
@ -875,6 +905,8 @@ private:
|
|||
Optional<bool> IsForced;
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
/// Shared implementation between new and old PMs.
|
||||
static bool runImpl(Function &F, LoopInfo *LI, DominatorTree *DT,
|
||||
ScalarEvolution *SE, OptimizationRemarkEmitter *ORE,
|
||||
|
@ -905,9 +937,13 @@ static bool runImpl(Function &F, LoopInfo *LI, DominatorTree *DT,
|
|||
return Changed;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/// \brief The pass class.
|
||||
class LoopDistributeLegacy : public FunctionPass {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
LoopDistributeLegacy() : FunctionPass(ID) {
|
||||
// The default is set by the caller.
|
||||
initializeLoopDistributeLegacyPass(*PassRegistry::getPassRegistry());
|
||||
|
@ -938,10 +974,9 @@ public:
|
|||
AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
|
||||
AU.addPreserved<GlobalsAAWrapperPass>();
|
||||
}
|
||||
|
||||
static char ID;
|
||||
};
|
||||
} // anonymous namespace
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
PreservedAnalyses LoopDistributePass::run(Function &F,
|
||||
FunctionAnalysisManager &AM) {
|
||||
|
@ -975,6 +1010,7 @@ PreservedAnalyses LoopDistributePass::run(Function &F,
|
|||
}
|
||||
|
||||
char LoopDistributeLegacy::ID;
|
||||
|
||||
static const char ldist_name[] = "Loop Distribution";
|
||||
|
||||
INITIALIZE_PASS_BEGIN(LoopDistributeLegacy, LDIST_NAME, ldist_name, false,
|
||||
|
@ -986,6 +1022,4 @@ INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
|
|||
INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass)
|
||||
INITIALIZE_PASS_END(LoopDistributeLegacy, LDIST_NAME, ldist_name, false, false)
|
||||
|
||||
namespace llvm {
|
||||
FunctionPass *createLoopDistributePass() { return new LoopDistributeLegacy(); }
|
||||
}
|
||||
FunctionPass *llvm::createLoopDistributePass() { return new LoopDistributeLegacy(); }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===-- LoopIdiomRecognize.cpp - Loop idiom recognition -------------------===//
|
||||
//===- LoopIdiomRecognize.cpp - Loop idiom recognition --------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -38,32 +38,64 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Transforms/Scalar/LoopIdiomRecognize.h"
|
||||
#include "llvm/ADT/APInt.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/MapVector.h"
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
||||
#include "llvm/Analysis/GlobalsModRef.h"
|
||||
#include "llvm/Analysis/LoopAccessAnalysis.h"
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Analysis/LoopPass.h"
|
||||
#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
|
||||
#include "llvm/Analysis/MemoryLocation.h"
|
||||
#include "llvm/Analysis/ScalarEvolution.h"
|
||||
#include "llvm/Analysis/ScalarEvolutionExpander.h"
|
||||
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
|
||||
#include "llvm/Analysis/TargetLibraryInfo.h"
|
||||
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||
#include "llvm/Analysis/ValueTracking.h"
|
||||
#include "llvm/IR/Attributes.h"
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/IR/Constant.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/DebugLoc.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
#include "llvm/IR/Dominators.h"
|
||||
#include "llvm/IR/GlobalValue.h"
|
||||
#include "llvm/IR/GlobalVariable.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/InstrTypes.h"
|
||||
#include "llvm/IR/Instruction.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/IntrinsicInst.h"
|
||||
#include "llvm/IR/Intrinsics.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/IR/Type.h"
|
||||
#include "llvm/IR/User.h"
|
||||
#include "llvm/IR/Value.h"
|
||||
#include "llvm/IR/ValueHandle.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Transforms/Scalar.h"
|
||||
#include "llvm/Transforms/Scalar/LoopPassManager.h"
|
||||
#include "llvm/Transforms/Utils/BuildLibCalls.h"
|
||||
#include "llvm/Transforms/Utils/Local.h"
|
||||
#include "llvm/Transforms/Utils/LoopUtils.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "loop-idiom"
|
||||
|
@ -80,7 +112,7 @@ static cl::opt<bool> UseLIRCodeSizeHeurs(
|
|||
namespace {
|
||||
|
||||
class LoopIdiomRecognize {
|
||||
Loop *CurLoop;
|
||||
Loop *CurLoop = nullptr;
|
||||
AliasAnalysis *AA;
|
||||
DominatorTree *DT;
|
||||
LoopInfo *LI;
|
||||
|
@ -96,20 +128,21 @@ public:
|
|||
TargetLibraryInfo *TLI,
|
||||
const TargetTransformInfo *TTI,
|
||||
const DataLayout *DL)
|
||||
: CurLoop(nullptr), AA(AA), DT(DT), LI(LI), SE(SE), TLI(TLI), TTI(TTI),
|
||||
DL(DL) {}
|
||||
: AA(AA), DT(DT), LI(LI), SE(SE), TLI(TLI), TTI(TTI), DL(DL) {}
|
||||
|
||||
bool runOnLoop(Loop *L);
|
||||
|
||||
private:
|
||||
typedef SmallVector<StoreInst *, 8> StoreList;
|
||||
typedef MapVector<Value *, StoreList> StoreListMap;
|
||||
using StoreList = SmallVector<StoreInst *, 8>;
|
||||
using StoreListMap = MapVector<Value *, StoreList>;
|
||||
|
||||
StoreListMap StoreRefsForMemset;
|
||||
StoreListMap StoreRefsForMemsetPattern;
|
||||
StoreList StoreRefsForMemcpy;
|
||||
bool HasMemset;
|
||||
bool HasMemsetPattern;
|
||||
bool HasMemcpy;
|
||||
|
||||
/// Return code for isLegalStore()
|
||||
enum LegalStoreKind {
|
||||
None = 0,
|
||||
|
@ -164,6 +197,7 @@ private:
|
|||
class LoopIdiomRecognizeLegacyPass : public LoopPass {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
explicit LoopIdiomRecognizeLegacyPass() : LoopPass(ID) {
|
||||
initializeLoopIdiomRecognizeLegacyPassPass(
|
||||
*PassRegistry::getPassRegistry());
|
||||
|
@ -190,14 +224,16 @@ public:
|
|||
|
||||
/// This transformation requires natural loop information & requires that
|
||||
/// loop preheaders be inserted into the CFG.
|
||||
///
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.addRequired<TargetLibraryInfoWrapperPass>();
|
||||
AU.addRequired<TargetTransformInfoWrapperPass>();
|
||||
getLoopAnalysisUsage(AU);
|
||||
}
|
||||
};
|
||||
} // End anonymous namespace.
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
char LoopIdiomRecognizeLegacyPass::ID = 0;
|
||||
|
||||
PreservedAnalyses LoopIdiomRecognizePass::run(Loop &L, LoopAnalysisManager &AM,
|
||||
LoopStandardAnalysisResults &AR,
|
||||
|
@ -211,7 +247,6 @@ PreservedAnalyses LoopIdiomRecognizePass::run(Loop &L, LoopAnalysisManager &AM,
|
|||
return getLoopPassPreservedAnalyses();
|
||||
}
|
||||
|
||||
char LoopIdiomRecognizeLegacyPass::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(LoopIdiomRecognizeLegacyPass, "loop-idiom",
|
||||
"Recognize loop idioms", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(LoopPass)
|
||||
|
@ -354,7 +389,6 @@ static Constant *getMemSetPatternValue(Value *V, const DataLayout *DL) {
|
|||
|
||||
LoopIdiomRecognize::LegalStoreKind
|
||||
LoopIdiomRecognize::isLegalStore(StoreInst *SI) {
|
||||
|
||||
// Don't touch volatile stores.
|
||||
if (SI->isVolatile())
|
||||
return LegalStoreKind::None;
|
||||
|
@ -1488,7 +1522,7 @@ static CallInst *createCTLZIntrinsic(IRBuilder<> &IRBuilder, Value *Val,
|
|||
/// PhiX = PHI [InitX, DefX]
|
||||
/// CntInst = CntPhi + 1
|
||||
/// DefX = PhiX >> 1
|
||||
// LOOP_BODY
|
||||
/// LOOP_BODY
|
||||
/// Br: loop if (DefX != 0)
|
||||
/// Use(CntPhi) or Use(CntInst)
|
||||
///
|
||||
|
|
|
@ -12,22 +12,33 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Transforms/Scalar/LoopInstSimplify.h"
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/InstructionSimplify.h"
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Analysis/LoopPass.h"
|
||||
#include "llvm/Analysis/ScalarEvolution.h"
|
||||
#include "llvm/Analysis/TargetLibraryInfo.h"
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/IR/CFG.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/Dominators.h"
|
||||
#include "llvm/IR/Instruction.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/IR/User.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Transforms/Scalar.h"
|
||||
#include "llvm/Transforms/Scalar/LoopPassManager.h"
|
||||
#include "llvm/Transforms/Utils/Local.h"
|
||||
#include "llvm/Transforms/Utils/LoopUtils.h"
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "loop-instsimplify"
|
||||
|
@ -45,7 +56,7 @@ static bool SimplifyLoopInst(Loop *L, DominatorTree *DT, LoopInfo *LI,
|
|||
|
||||
// The bit we are stealing from the pointer represents whether this basic
|
||||
// block is the header of a subloop, in which case we only process its phis.
|
||||
typedef PointerIntPair<BasicBlock *, 1> WorklistItem;
|
||||
using WorklistItem = PointerIntPair<BasicBlock *, 1>;
|
||||
SmallVector<WorklistItem, 16> VisitStack;
|
||||
SmallPtrSet<BasicBlock *, 32> Visited;
|
||||
|
||||
|
@ -151,9 +162,11 @@ static bool SimplifyLoopInst(Loop *L, DominatorTree *DT, LoopInfo *LI,
|
|||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class LoopInstSimplifyLegacyPass : public LoopPass {
|
||||
public:
|
||||
static char ID; // Pass ID, replacement for typeid
|
||||
|
||||
LoopInstSimplifyLegacyPass() : LoopPass(ID) {
|
||||
initializeLoopInstSimplifyLegacyPassPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
@ -181,7 +194,8 @@ public:
|
|||
getLoopAnalysisUsage(AU);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
PreservedAnalyses LoopInstSimplifyPass::run(Loop &L, LoopAnalysisManager &AM,
|
||||
LoopStandardAnalysisResults &AR,
|
||||
|
@ -195,6 +209,7 @@ PreservedAnalyses LoopInstSimplifyPass::run(Loop &L, LoopAnalysisManager &AM,
|
|||
}
|
||||
|
||||
char LoopInstSimplifyLegacyPass::ID = 0;
|
||||
|
||||
INITIALIZE_PASS_BEGIN(LoopInstSimplifyLegacyPass, "loop-instsimplify",
|
||||
"Simplify instructions in loops", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===- LoopInterchange.cpp - Loop interchange pass------------------------===//
|
||||
//===- LoopInterchange.cpp - Loop interchange pass-------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -13,33 +13,38 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/BlockFrequencyInfo.h"
|
||||
#include "llvm/Analysis/CodeMetrics.h"
|
||||
#include "llvm/Analysis/DependenceAnalysis.h"
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Analysis/LoopIterator.h"
|
||||
#include "llvm/Analysis/LoopPass.h"
|
||||
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
|
||||
#include "llvm/Analysis/ScalarEvolution.h"
|
||||
#include "llvm/Analysis/ScalarEvolutionExpander.h"
|
||||
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
|
||||
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||
#include "llvm/Analysis/ValueTracking.h"
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/DiagnosticInfo.h"
|
||||
#include "llvm/IR/Dominators.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/InstIterator.h"
|
||||
#include "llvm/IR/IntrinsicInst.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/InstrTypes.h"
|
||||
#include "llvm/IR/Instruction.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/Type.h"
|
||||
#include "llvm/IR/User.h"
|
||||
#include "llvm/IR/Value.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Transforms/Scalar.h"
|
||||
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
||||
#include "llvm/Transforms/Utils/LoopUtils.h"
|
||||
#include <cassert>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
|
@ -51,10 +56,12 @@ static cl::opt<int> LoopInterchangeCostThreshold(
|
|||
|
||||
namespace {
|
||||
|
||||
typedef SmallVector<Loop *, 8> LoopVector;
|
||||
using LoopVector = SmallVector<Loop *, 8>;
|
||||
|
||||
// TODO: Check if we can use a sparse matrix here.
|
||||
typedef std::vector<std::vector<char>> CharMatrix;
|
||||
using CharMatrix = std::vector<std::vector<char>>;
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
// Maximum number of dependencies that can be handled in the dependency matrix.
|
||||
static const unsigned MaxMemInstrCount = 100;
|
||||
|
@ -62,10 +69,8 @@ static const unsigned MaxMemInstrCount = 100;
|
|||
// Maximum loop depth supported.
|
||||
static const unsigned MaxLoopNestDepth = 10;
|
||||
|
||||
struct LoopInterchange;
|
||||
|
||||
#ifdef DUMP_DEP_MATRICIES
|
||||
void printDepMatrix(CharMatrix &DepMatrix) {
|
||||
static void printDepMatrix(CharMatrix &DepMatrix) {
|
||||
for (auto &Row : DepMatrix) {
|
||||
for (auto D : Row)
|
||||
DEBUG(dbgs() << D << " ");
|
||||
|
@ -76,7 +81,8 @@ void printDepMatrix(CharMatrix &DepMatrix) {
|
|||
|
||||
static bool populateDependencyMatrix(CharMatrix &DepMatrix, unsigned Level,
|
||||
Loop *L, DependenceInfo *DI) {
|
||||
typedef SmallVector<Value *, 16> ValueVector;
|
||||
using ValueVector = SmallVector<Value *, 16>;
|
||||
|
||||
ValueVector MemInstr;
|
||||
|
||||
// For each block.
|
||||
|
@ -168,7 +174,7 @@ static bool populateDependencyMatrix(CharMatrix &DepMatrix, unsigned Level,
|
|||
}
|
||||
|
||||
// We don't have a DepMatrix to check legality return false.
|
||||
if (DepMatrix.size() == 0)
|
||||
if (DepMatrix.empty())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -213,7 +219,6 @@ static bool containsNoDependence(CharMatrix &DepMatrix, unsigned Row,
|
|||
static bool validDepInterchange(CharMatrix &DepMatrix, unsigned Row,
|
||||
unsigned OuterLoopId, char InnerDep,
|
||||
char OuterDep) {
|
||||
|
||||
if (isOuterMostDepPositive(DepMatrix, Row, OuterLoopId))
|
||||
return false;
|
||||
|
||||
|
@ -252,7 +257,6 @@ static bool validDepInterchange(CharMatrix &DepMatrix, unsigned Row,
|
|||
static bool isLegalToInterChangeLoops(CharMatrix &DepMatrix,
|
||||
unsigned InnerLoopId,
|
||||
unsigned OuterLoopId) {
|
||||
|
||||
unsigned NumRows = DepMatrix.size();
|
||||
// For each row check if it is valid to interchange.
|
||||
for (unsigned Row = 0; Row < NumRows; ++Row) {
|
||||
|
@ -267,7 +271,6 @@ static bool isLegalToInterChangeLoops(CharMatrix &DepMatrix,
|
|||
}
|
||||
|
||||
static void populateWorklist(Loop &L, SmallVector<LoopVector, 8> &V) {
|
||||
|
||||
DEBUG(dbgs() << "Calling populateWorklist on Func: "
|
||||
<< L.getHeader()->getParent()->getName() << " Loop: %"
|
||||
<< L.getHeader()->getName() << '\n');
|
||||
|
@ -317,6 +320,8 @@ static PHINode *getInductionVariable(Loop *L, ScalarEvolution *SE) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/// LoopInterchangeLegality checks if it is legal to interchange the loop.
|
||||
class LoopInterchangeLegality {
|
||||
public:
|
||||
|
@ -324,11 +329,12 @@ public:
|
|||
LoopInfo *LI, DominatorTree *DT, bool PreserveLCSSA,
|
||||
OptimizationRemarkEmitter *ORE)
|
||||
: OuterLoop(Outer), InnerLoop(Inner), SE(SE), LI(LI), DT(DT),
|
||||
PreserveLCSSA(PreserveLCSSA), ORE(ORE), InnerLoopHasReduction(false) {}
|
||||
PreserveLCSSA(PreserveLCSSA), ORE(ORE) {}
|
||||
|
||||
/// Check if the loops can be interchanged.
|
||||
bool canInterchangeLoops(unsigned InnerLoopId, unsigned OuterLoopId,
|
||||
CharMatrix &DepMatrix);
|
||||
|
||||
/// Check if the loop structure is understood. We do not handle triangular
|
||||
/// loops for now.
|
||||
bool isLoopStructureUnderstood(PHINode *InnerInductionVar);
|
||||
|
@ -345,6 +351,7 @@ private:
|
|||
bool findInductionAndReductions(Loop *L,
|
||||
SmallVector<PHINode *, 8> &Inductions,
|
||||
SmallVector<PHINode *, 8> &Reductions);
|
||||
|
||||
Loop *OuterLoop;
|
||||
Loop *InnerLoop;
|
||||
|
||||
|
@ -352,10 +359,11 @@ private:
|
|||
LoopInfo *LI;
|
||||
DominatorTree *DT;
|
||||
bool PreserveLCSSA;
|
||||
|
||||
/// Interface to emit optimization remarks.
|
||||
OptimizationRemarkEmitter *ORE;
|
||||
|
||||
bool InnerLoopHasReduction;
|
||||
bool InnerLoopHasReduction = false;
|
||||
};
|
||||
|
||||
/// LoopInterchangeProfitability checks if it is profitable to interchange the
|
||||
|
@ -378,6 +386,7 @@ private:
|
|||
|
||||
/// Scev analysis.
|
||||
ScalarEvolution *SE;
|
||||
|
||||
/// Interface to emit optimization remarks.
|
||||
OptimizationRemarkEmitter *ORE;
|
||||
};
|
||||
|
@ -412,6 +421,7 @@ private:
|
|||
|
||||
/// Scev analysis.
|
||||
ScalarEvolution *SE;
|
||||
|
||||
LoopInfo *LI;
|
||||
DominatorTree *DT;
|
||||
BasicBlock *LoopExit;
|
||||
|
@ -421,16 +431,16 @@ private:
|
|||
// Main LoopInterchange Pass.
|
||||
struct LoopInterchange : public FunctionPass {
|
||||
static char ID;
|
||||
ScalarEvolution *SE;
|
||||
LoopInfo *LI;
|
||||
DependenceInfo *DI;
|
||||
DominatorTree *DT;
|
||||
ScalarEvolution *SE = nullptr;
|
||||
LoopInfo *LI = nullptr;
|
||||
DependenceInfo *DI = nullptr;
|
||||
DominatorTree *DT = nullptr;
|
||||
bool PreserveLCSSA;
|
||||
|
||||
/// Interface to emit optimization remarks.
|
||||
OptimizationRemarkEmitter *ORE;
|
||||
|
||||
LoopInterchange()
|
||||
: FunctionPass(ID), SE(nullptr), LI(nullptr), DI(nullptr), DT(nullptr) {
|
||||
LoopInterchange() : FunctionPass(ID) {
|
||||
initializeLoopInterchangePass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
|
@ -498,7 +508,6 @@ struct LoopInterchange : public FunctionPass {
|
|||
}
|
||||
|
||||
bool processLoopList(LoopVector LoopList, Function &F) {
|
||||
|
||||
bool Changed = false;
|
||||
unsigned LoopNestDepth = LoopList.size();
|
||||
if (LoopNestDepth < 2) {
|
||||
|
@ -577,7 +586,6 @@ struct LoopInterchange : public FunctionPass {
|
|||
bool processLoop(LoopVector LoopList, unsigned InnerLoopId,
|
||||
unsigned OuterLoopId, BasicBlock *LoopNestExit,
|
||||
std::vector<std::vector<char>> &DependencyMatrix) {
|
||||
|
||||
DEBUG(dbgs() << "Processing Inner Loop Id = " << InnerLoopId
|
||||
<< " and OuterLoopId = " << OuterLoopId << "\n");
|
||||
Loop *InnerLoop = LoopList[InnerLoopId];
|
||||
|
@ -611,9 +619,10 @@ struct LoopInterchange : public FunctionPass {
|
|||
}
|
||||
};
|
||||
|
||||
} // end of namespace
|
||||
} // end anonymous namespace
|
||||
|
||||
bool LoopInterchangeLegality::areAllUsesReductions(Instruction *Ins, Loop *L) {
|
||||
return none_of(Ins->users(), [=](User *U) -> bool {
|
||||
return llvm::none_of(Ins->users(), [=](User *U) -> bool {
|
||||
auto *UserIns = dyn_cast<PHINode>(U);
|
||||
RecurrenceDescriptor RD;
|
||||
return !UserIns || !RecurrenceDescriptor::isReductionPHI(UserIns, L, RD);
|
||||
|
@ -679,10 +688,8 @@ bool LoopInterchangeLegality::tightlyNested(Loop *OuterLoop, Loop *InnerLoop) {
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool LoopInterchangeLegality::isLoopStructureUnderstood(
|
||||
PHINode *InnerInduction) {
|
||||
|
||||
unsigned Num = InnerInduction->getNumOperands();
|
||||
BasicBlock *InnerLoopPreheader = InnerLoop->getLoopPreheader();
|
||||
for (unsigned i = 0; i < Num; ++i) {
|
||||
|
@ -761,7 +768,6 @@ static BasicBlock *getLoopLatchExitBlock(BasicBlock *LatchBlock,
|
|||
// This function indicates the current limitations in the transform as a result
|
||||
// of which we do not proceed.
|
||||
bool LoopInterchangeLegality::currentLimitations() {
|
||||
|
||||
BasicBlock *InnerLoopPreHeader = InnerLoop->getLoopPreheader();
|
||||
BasicBlock *InnerLoopHeader = InnerLoop->getHeader();
|
||||
BasicBlock *InnerLoopLatch = InnerLoop->getLoopLatch();
|
||||
|
@ -918,7 +924,7 @@ bool LoopInterchangeLegality::currentLimitations() {
|
|||
// instruction.
|
||||
|
||||
bool FoundInduction = false;
|
||||
for (const Instruction &I : reverse(*InnerLoopLatch)) {
|
||||
for (const Instruction &I : llvm::reverse(*InnerLoopLatch)) {
|
||||
if (isa<BranchInst>(I) || isa<CmpInst>(I) || isa<TruncInst>(I) ||
|
||||
isa<ZExtInst>(I))
|
||||
continue;
|
||||
|
@ -959,7 +965,6 @@ bool LoopInterchangeLegality::currentLimitations() {
|
|||
bool LoopInterchangeLegality::canInterchangeLoops(unsigned InnerLoopId,
|
||||
unsigned OuterLoopId,
|
||||
CharMatrix &DepMatrix) {
|
||||
|
||||
if (!isLegalToInterChangeLoops(DepMatrix, InnerLoopId, OuterLoopId)) {
|
||||
DEBUG(dbgs() << "Failed interchange InnerLoopId = " << InnerLoopId
|
||||
<< " and OuterLoopId = " << OuterLoopId
|
||||
|
@ -1101,7 +1106,6 @@ static bool isProfitableForVectorization(unsigned InnerLoopId,
|
|||
bool LoopInterchangeProfitability::isProfitable(unsigned InnerLoopId,
|
||||
unsigned OuterLoopId,
|
||||
CharMatrix &DepMatrix) {
|
||||
|
||||
// TODO: Add better profitability checks.
|
||||
// e.g
|
||||
// 1) Construct dependency matrix and move the one with no loop carried dep
|
||||
|
@ -1167,7 +1171,7 @@ bool LoopInterchangeTransform::transform() {
|
|||
bool Transformed = false;
|
||||
Instruction *InnerIndexVar;
|
||||
|
||||
if (InnerLoop->getSubLoops().size() == 0) {
|
||||
if (InnerLoop->getSubLoops().empty()) {
|
||||
BasicBlock *InnerLoopPreHeader = InnerLoop->getLoopPreheader();
|
||||
DEBUG(dbgs() << "Calling Split Inner Loop\n");
|
||||
PHINode *InductionPHI = getInductionVariable(InnerLoop, SE);
|
||||
|
@ -1181,7 +1185,6 @@ bool LoopInterchangeTransform::transform() {
|
|||
else
|
||||
InnerIndexVar = dyn_cast<Instruction>(InductionPHI->getIncomingValue(0));
|
||||
|
||||
//
|
||||
// Split at the place were the induction variable is
|
||||
// incremented/decremented.
|
||||
// TODO: This splitting logic may not work always. Fix this.
|
||||
|
@ -1210,7 +1213,6 @@ void LoopInterchangeTransform::splitInnerLoopLatch(Instruction *Inc) {
|
|||
}
|
||||
|
||||
void LoopInterchangeTransform::splitInnerLoopHeader() {
|
||||
|
||||
// Split the inner loop header out. Here make sure that the reduction PHI's
|
||||
// stay in the innerloop body.
|
||||
BasicBlock *InnerLoopHeader = InnerLoop->getHeader();
|
||||
|
@ -1266,7 +1268,6 @@ void LoopInterchangeTransform::updateIncomingBlock(BasicBlock *CurrBlock,
|
|||
}
|
||||
|
||||
bool LoopInterchangeTransform::adjustLoopBranches() {
|
||||
|
||||
DEBUG(dbgs() << "adjustLoopBranches called\n");
|
||||
// Adjust the loop preheader
|
||||
BasicBlock *InnerLoopHeader = InnerLoop->getHeader();
|
||||
|
@ -1374,8 +1375,8 @@ bool LoopInterchangeTransform::adjustLoopBranches() {
|
|||
|
||||
return true;
|
||||
}
|
||||
void LoopInterchangeTransform::adjustLoopPreheaders() {
|
||||
|
||||
void LoopInterchangeTransform::adjustLoopPreheaders() {
|
||||
// We have interchanged the preheaders so we need to interchange the data in
|
||||
// the preheader as well.
|
||||
// This is because the content of inner preheader was previously executed
|
||||
|
@ -1395,7 +1396,6 @@ void LoopInterchangeTransform::adjustLoopPreheaders() {
|
|||
}
|
||||
|
||||
bool LoopInterchangeTransform::adjustLoopLinks() {
|
||||
|
||||
// Adjust all branches in the inner and outer loop.
|
||||
bool Changed = adjustLoopBranches();
|
||||
if (Changed)
|
||||
|
@ -1404,6 +1404,7 @@ bool LoopInterchangeTransform::adjustLoopLinks() {
|
|||
}
|
||||
|
||||
char LoopInterchange::ID = 0;
|
||||
|
||||
INITIALIZE_PASS_BEGIN(LoopInterchange, "loop-interchange",
|
||||
"Interchanges loops for cache reuse", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
|
||||
|
|
|
@ -28,22 +28,29 @@
|
|||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/GlobalsModRef.h"
|
||||
#include "llvm/Analysis/LoopAccessAnalysis.h"
|
||||
#include "llvm/Analysis/LoopAnalysisManager.h"
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Analysis/ScalarEvolution.h"
|
||||
#include "llvm/Analysis/ScalarEvolutionExpander.h"
|
||||
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
|
||||
#include "llvm/Analysis/TargetLibraryInfo.h"
|
||||
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/Dominators.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/IR/Type.h"
|
||||
#include "llvm/IR/Value.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Transforms/Scalar.h"
|
||||
#include "llvm/Transforms/Utils/LoopVersioning.h"
|
||||
#include <algorithm>
|
||||
|
@ -53,11 +60,11 @@
|
|||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
#define LLE_OPTION "loop-load-elim"
|
||||
#define DEBUG_TYPE LLE_OPTION
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
static cl::opt<unsigned> CheckPerElim(
|
||||
"runtime-check-per-loop-load-elim", cl::Hidden,
|
||||
cl::desc("Max number of memchecks allowed per eliminated load on average"),
|
||||
|
@ -127,10 +134,12 @@ struct StoreToLoadForwardingCandidate {
|
|||
#endif
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
/// \brief Check if the store dominates all latches, so as long as there is no
|
||||
/// intervening store this value will be loaded in the next iteration.
|
||||
bool doesStoreDominatesAllLatches(BasicBlock *StoreBlock, Loop *L,
|
||||
DominatorTree *DT) {
|
||||
static bool doesStoreDominatesAllLatches(BasicBlock *StoreBlock, Loop *L,
|
||||
DominatorTree *DT) {
|
||||
SmallVector<BasicBlock *, 8> Latches;
|
||||
L->getLoopLatches(Latches);
|
||||
return llvm::all_of(Latches, [&](const BasicBlock *Latch) {
|
||||
|
@ -143,6 +152,8 @@ static bool isLoadConditional(LoadInst *Load, Loop *L) {
|
|||
return Load->getParent() != L->getHeader();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/// \brief The per-loop class that does most of the work.
|
||||
class LoadEliminationForLoop {
|
||||
public:
|
||||
|
@ -241,8 +252,8 @@ public:
|
|||
std::forward_list<StoreToLoadForwardingCandidate> &Candidates) {
|
||||
// If Store is nullptr it means that we have multiple stores forwarding to
|
||||
// this store.
|
||||
typedef DenseMap<LoadInst *, const StoreToLoadForwardingCandidate *>
|
||||
LoadToSingleCandT;
|
||||
using LoadToSingleCandT =
|
||||
DenseMap<LoadInst *, const StoreToLoadForwardingCandidate *>;
|
||||
LoadToSingleCandT LoadToSingleCand;
|
||||
|
||||
for (const auto &Cand : Candidates) {
|
||||
|
@ -393,7 +404,6 @@ public:
|
|||
void
|
||||
propagateStoredValueToLoadUsers(const StoreToLoadForwardingCandidate &Cand,
|
||||
SCEVExpander &SEE) {
|
||||
//
|
||||
// loop:
|
||||
// %x = load %gep_i
|
||||
// = ... %x
|
||||
|
@ -431,6 +441,7 @@ public:
|
|||
bool processLoop() {
|
||||
DEBUG(dbgs() << "\nIn \"" << L->getHeader()->getParent()->getName()
|
||||
<< "\" checking " << *L << "\n");
|
||||
|
||||
// Look for store-to-load forwarding cases across the
|
||||
// backedge. E.g.:
|
||||
//
|
||||
|
@ -558,6 +569,8 @@ private:
|
|||
PredicatedScalarEvolution PSE;
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
static bool
|
||||
eliminateLoadsAcrossLoops(Function &F, LoopInfo &LI, DominatorTree &DT,
|
||||
function_ref<const LoopAccessInfo &(Loop &)> GetLAI) {
|
||||
|
@ -584,10 +597,14 @@ eliminateLoadsAcrossLoops(Function &F, LoopInfo &LI, DominatorTree &DT,
|
|||
return Changed;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/// \brief The pass. Most of the work is delegated to the per-loop
|
||||
/// LoadEliminationForLoop class.
|
||||
class LoopLoadElimination : public FunctionPass {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
LoopLoadElimination() : FunctionPass(ID) {
|
||||
initializeLoopLoadEliminationPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
@ -616,13 +633,12 @@ public:
|
|||
AU.addPreserved<DominatorTreeWrapperPass>();
|
||||
AU.addPreserved<GlobalsAAWrapperPass>();
|
||||
}
|
||||
|
||||
static char ID;
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
char LoopLoadElimination::ID;
|
||||
|
||||
static const char LLE_name[] = "Loop Load Elimination";
|
||||
|
||||
INITIALIZE_PASS_BEGIN(LoopLoadElimination, LLE_OPTION, LLE_name, false, false)
|
||||
|
@ -633,9 +649,7 @@ INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
|
|||
INITIALIZE_PASS_DEPENDENCY(LoopSimplify)
|
||||
INITIALIZE_PASS_END(LoopLoadElimination, LLE_OPTION, LLE_name, false, false)
|
||||
|
||||
namespace llvm {
|
||||
|
||||
FunctionPass *createLoopLoadEliminationPass() {
|
||||
FunctionPass *llvm::createLoopLoadEliminationPass() {
|
||||
return new LoopLoadElimination();
|
||||
}
|
||||
|
||||
|
@ -662,5 +676,3 @@ PreservedAnalyses LoopLoadEliminationPass::run(Function &F,
|
|||
PreservedAnalyses PA;
|
||||
return PA;
|
||||
}
|
||||
|
||||
} // end namespace llvm
|
||||
|
|
Loading…
Reference in New Issue