mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 20:23:11 +01:00
Remove the AssumptionCache
After r289755, the AssumptionCache is no longer needed. Variables affected by assumptions are now found by using the new operand-bundle-based scheme. This new scheme is more computationally efficient, and also we need much less code... llvm-svn: 289756
This commit is contained in:
parent
502475d4f3
commit
f224db75d2
@ -1,168 +0,0 @@
|
||||
//===- llvm/Analysis/AssumptionCache.h - Track @llvm.assume ---*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains a pass that keeps track of @llvm.assume intrinsics in
|
||||
// the functions of a module (allowing assumptions within any function to be
|
||||
// found cheaply by other parts of the optimizer).
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ANALYSIS_ASSUMPTIONCACHE_H
|
||||
#define LLVM_ANALYSIS_ASSUMPTIONCACHE_H
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/ValueHandle.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include <memory>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// \brief A cache of @llvm.assume calls within a function.
|
||||
///
|
||||
/// This cache provides fast lookup of assumptions within a function by caching
|
||||
/// them and amortizing the cost of scanning for them across all queries. The
|
||||
/// cache is also conservatively self-updating so that it will never return
|
||||
/// incorrect results about a function even as the function is being mutated.
|
||||
/// However, flushing the cache and rebuilding it (or explicitly updating it)
|
||||
/// may allow it to discover new assumptions.
|
||||
class AssumptionCache {
|
||||
/// \brief The function for which this cache is handling assumptions.
|
||||
///
|
||||
/// We track this to lazily populate our assumptions.
|
||||
Function &F;
|
||||
|
||||
/// \brief Vector of weak value handles to calls of the @llvm.assume
|
||||
/// intrinsic.
|
||||
SmallVector<WeakVH, 4> AssumeHandles;
|
||||
|
||||
/// \brief Flag tracking whether we have scanned the function yet.
|
||||
///
|
||||
/// We want to be as lazy about this as possible, and so we scan the function
|
||||
/// at the last moment.
|
||||
bool Scanned;
|
||||
|
||||
/// \brief Scan the function for assumptions and add them to the cache.
|
||||
void scanFunction();
|
||||
|
||||
public:
|
||||
/// \brief Construct an AssumptionCache from a function by scanning all of
|
||||
/// its instructions.
|
||||
AssumptionCache(Function &F) : F(F), Scanned(false) {}
|
||||
|
||||
/// \brief Add an @llvm.assume intrinsic to this function's cache.
|
||||
///
|
||||
/// The call passed in must be an instruction within this function and must
|
||||
/// not already be in the cache.
|
||||
void registerAssumption(CallInst *CI);
|
||||
|
||||
/// \brief Clear the cache of @llvm.assume intrinsics for a function.
|
||||
///
|
||||
/// It will be re-scanned the next time it is requested.
|
||||
void clear() {
|
||||
AssumeHandles.clear();
|
||||
Scanned = false;
|
||||
}
|
||||
|
||||
/// \brief Access the list of assumption handles currently tracked for this
|
||||
/// function.
|
||||
///
|
||||
/// Note that these produce weak handles that may be null. The caller must
|
||||
/// handle that case.
|
||||
/// FIXME: We should replace this with pointee_iterator<filter_iterator<...>>
|
||||
/// when we can write that to filter out the null values. Then caller code
|
||||
/// will become simpler.
|
||||
MutableArrayRef<WeakVH> assumptions() {
|
||||
if (!Scanned)
|
||||
scanFunction();
|
||||
return AssumeHandles;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief A function analysis which provides an \c AssumptionCache.
|
||||
///
|
||||
/// This analysis is intended for use with the new pass manager and will vend
|
||||
/// assumption caches for a given function.
|
||||
class AssumptionAnalysis : public AnalysisInfoMixin<AssumptionAnalysis> {
|
||||
friend AnalysisInfoMixin<AssumptionAnalysis>;
|
||||
static AnalysisKey Key;
|
||||
|
||||
public:
|
||||
typedef AssumptionCache Result;
|
||||
|
||||
AssumptionCache run(Function &F, FunctionAnalysisManager &) {
|
||||
return AssumptionCache(F);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Printer pass for the \c AssumptionAnalysis results.
|
||||
class AssumptionPrinterPass : public PassInfoMixin<AssumptionPrinterPass> {
|
||||
raw_ostream &OS;
|
||||
|
||||
public:
|
||||
explicit AssumptionPrinterPass(raw_ostream &OS) : OS(OS) {}
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
};
|
||||
|
||||
/// \brief An immutable pass that tracks lazily created \c AssumptionCache
|
||||
/// objects.
|
||||
///
|
||||
/// This is essentially a workaround for the legacy pass manager's weaknesses
|
||||
/// which associates each assumption cache with Function and clears it if the
|
||||
/// function is deleted. The nature of the AssumptionCache is that it is not
|
||||
/// invalidated by any changes to the function body and so this is sufficient
|
||||
/// to be conservatively correct.
|
||||
class AssumptionCacheTracker : public ImmutablePass {
|
||||
/// A callback value handle applied to function objects, which we use to
|
||||
/// delete our cache of intrinsics for a function when it is deleted.
|
||||
class FunctionCallbackVH final : public CallbackVH {
|
||||
AssumptionCacheTracker *ACT;
|
||||
void deleted() override;
|
||||
|
||||
public:
|
||||
typedef DenseMapInfo<Value *> DMI;
|
||||
|
||||
FunctionCallbackVH(Value *V, AssumptionCacheTracker *ACT = nullptr)
|
||||
: CallbackVH(V), ACT(ACT) {}
|
||||
};
|
||||
|
||||
friend FunctionCallbackVH;
|
||||
|
||||
typedef DenseMap<FunctionCallbackVH, std::unique_ptr<AssumptionCache>,
|
||||
FunctionCallbackVH::DMI> FunctionCallsMap;
|
||||
FunctionCallsMap AssumptionCaches;
|
||||
|
||||
public:
|
||||
/// \brief Get the cached assumptions for a function.
|
||||
///
|
||||
/// If no assumptions are cached, this will scan the function. Otherwise, the
|
||||
/// existing cache will be returned.
|
||||
AssumptionCache &getAssumptionCache(Function &F);
|
||||
|
||||
AssumptionCacheTracker();
|
||||
~AssumptionCacheTracker() override;
|
||||
|
||||
void releaseMemory() override { AssumptionCaches.shrink_and_clear(); }
|
||||
|
||||
void verifyAnalysis() const override;
|
||||
bool doFinalization(Module &) override {
|
||||
verifyAnalysis();
|
||||
return false;
|
||||
}
|
||||
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
@ -16,7 +16,6 @@
|
||||
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/TargetLibraryInfo.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/GetElementPtrTypeIterator.h"
|
||||
@ -27,7 +26,6 @@
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
||||
namespace llvm {
|
||||
class AssumptionCache;
|
||||
class DominatorTree;
|
||||
class LoopInfo;
|
||||
|
||||
@ -41,21 +39,20 @@ class BasicAAResult : public AAResultBase<BasicAAResult> {
|
||||
|
||||
const DataLayout &DL;
|
||||
const TargetLibraryInfo &TLI;
|
||||
AssumptionCache &AC;
|
||||
DominatorTree *DT;
|
||||
LoopInfo *LI;
|
||||
|
||||
public:
|
||||
BasicAAResult(const DataLayout &DL, const TargetLibraryInfo &TLI,
|
||||
AssumptionCache &AC, DominatorTree *DT = nullptr,
|
||||
DominatorTree *DT = nullptr,
|
||||
LoopInfo *LI = nullptr)
|
||||
: AAResultBase(), DL(DL), TLI(TLI), AC(AC), DT(DT), LI(LI) {}
|
||||
: AAResultBase(), DL(DL), TLI(TLI), DT(DT), LI(LI) {}
|
||||
|
||||
BasicAAResult(const BasicAAResult &Arg)
|
||||
: AAResultBase(Arg), DL(Arg.DL), TLI(Arg.TLI), AC(Arg.AC), DT(Arg.DT),
|
||||
: AAResultBase(Arg), DL(Arg.DL), TLI(Arg.TLI), DT(Arg.DT),
|
||||
LI(Arg.LI) {}
|
||||
BasicAAResult(BasicAAResult &&Arg)
|
||||
: AAResultBase(std::move(Arg)), DL(Arg.DL), TLI(Arg.TLI), AC(Arg.AC),
|
||||
: AAResultBase(std::move(Arg)), DL(Arg.DL), TLI(Arg.TLI),
|
||||
DT(Arg.DT), LI(Arg.LI) {}
|
||||
|
||||
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB);
|
||||
@ -145,11 +142,11 @@ private:
|
||||
static const Value *
|
||||
GetLinearExpression(const Value *V, APInt &Scale, APInt &Offset,
|
||||
unsigned &ZExtBits, unsigned &SExtBits,
|
||||
const DataLayout &DL, unsigned Depth, AssumptionCache *AC,
|
||||
const DataLayout &DL, unsigned Depth,
|
||||
DominatorTree *DT, bool &NSW, bool &NUW);
|
||||
|
||||
static bool DecomposeGEPExpression(const Value *V, DecomposedGEP &Decomposed,
|
||||
const DataLayout &DL, AssumptionCache *AC, DominatorTree *DT);
|
||||
const DataLayout &DL, DominatorTree *DT);
|
||||
|
||||
static bool isGEPBaseAtNegativeOffset(const GEPOperator *GEPOp,
|
||||
const DecomposedGEP &DecompGEP, const DecomposedGEP &DecompObject,
|
||||
@ -166,7 +163,7 @@ private:
|
||||
bool
|
||||
constantOffsetHeuristic(const SmallVectorImpl<VariableGEPIndex> &VarIndices,
|
||||
uint64_t V1Size, uint64_t V2Size, int64_t BaseOffset,
|
||||
AssumptionCache *AC, DominatorTree *DT);
|
||||
DominatorTree *DT);
|
||||
|
||||
bool isValueEqualInPotentialCycles(const Value *V1, const Value *V2);
|
||||
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include "llvm/IR/CallSite.h"
|
||||
|
||||
namespace llvm {
|
||||
class AssumptionCache;
|
||||
class BasicBlock;
|
||||
class Loop;
|
||||
class Function;
|
||||
@ -91,12 +90,12 @@ struct CodeMetrics {
|
||||
|
||||
/// \brief Collect a loop's ephemeral values (those used only by an assume
|
||||
/// or similar intrinsics in the loop).
|
||||
static void collectEphemeralValues(const Loop *L, AssumptionCache *AC,
|
||||
static void collectEphemeralValues(const Loop *L,
|
||||
SmallPtrSetImpl<const Value *> &EphValues);
|
||||
|
||||
/// \brief Collect a functions's ephemeral values (those used only by an
|
||||
/// assume or similar intrinsics in the function).
|
||||
static void collectEphemeralValues(const Function *L, AssumptionCache *AC,
|
||||
static void collectEphemeralValues(const Function *L,
|
||||
SmallPtrSetImpl<const Value *> &EphValues);
|
||||
};
|
||||
|
||||
|
@ -34,12 +34,11 @@ class FunctionPass;
|
||||
class Function;
|
||||
class Instruction;
|
||||
class DominatorTree;
|
||||
class AssumptionCache;
|
||||
|
||||
class DemandedBits {
|
||||
public:
|
||||
DemandedBits(Function &F, AssumptionCache &AC, DominatorTree &DT) :
|
||||
F(F), AC(AC), DT(DT), Analyzed(false) {}
|
||||
DemandedBits(Function &F, DominatorTree &DT) :
|
||||
F(F), DT(DT), Analyzed(false) {}
|
||||
|
||||
/// Return the bits demanded from instruction I.
|
||||
APInt getDemandedBits(Instruction *I);
|
||||
@ -51,7 +50,6 @@ public:
|
||||
|
||||
private:
|
||||
Function &F;
|
||||
AssumptionCache &AC;
|
||||
DominatorTree &DT;
|
||||
|
||||
void performAnalysis();
|
||||
|
@ -22,7 +22,6 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class AssumptionCache;
|
||||
class DominatorTree;
|
||||
class Instruction;
|
||||
class Value;
|
||||
@ -94,7 +93,6 @@ private:
|
||||
class IVUsers {
|
||||
friend class IVStrideUse;
|
||||
Loop *L;
|
||||
AssumptionCache *AC;
|
||||
LoopInfo *LI;
|
||||
DominatorTree *DT;
|
||||
ScalarEvolution *SE;
|
||||
@ -108,11 +106,11 @@ class IVUsers {
|
||||
SmallPtrSet<const Value *, 32> EphValues;
|
||||
|
||||
public:
|
||||
IVUsers(Loop *L, AssumptionCache *AC, LoopInfo *LI, DominatorTree *DT,
|
||||
IVUsers(Loop *L, LoopInfo *LI, DominatorTree *DT,
|
||||
ScalarEvolution *SE);
|
||||
|
||||
IVUsers(IVUsers &&X)
|
||||
: L(std::move(X.L)), AC(std::move(X.AC)), DT(std::move(X.DT)),
|
||||
: L(std::move(X.L)), DT(std::move(X.DT)),
|
||||
SE(std::move(X.SE)), Processed(std::move(X.Processed)),
|
||||
IVUses(std::move(X.IVUses)), EphValues(std::move(X.EphValues)) {
|
||||
for (IVStrideUse &U : IVUses)
|
||||
|
@ -15,12 +15,10 @@
|
||||
#define LLVM_ANALYSIS_INLINECOST_H
|
||||
|
||||
#include "llvm/Analysis/CallGraphSCCPass.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include <cassert>
|
||||
#include <climits>
|
||||
|
||||
namespace llvm {
|
||||
class AssumptionCacheTracker;
|
||||
class CallSite;
|
||||
class DataLayout;
|
||||
class Function;
|
||||
@ -170,7 +168,6 @@ InlineParams getInlineParams(unsigned OptLevel, unsigned SizeOptLevel);
|
||||
InlineCost
|
||||
getInlineCost(CallSite CS, const InlineParams &Params,
|
||||
TargetTransformInfo &CalleeTTI,
|
||||
std::function<AssumptionCache &(Function &)> &GetAssumptionCache,
|
||||
ProfileSummaryInfo *PSI);
|
||||
|
||||
/// \brief Get an InlineCost with the callee explicitly specified.
|
||||
@ -181,7 +178,6 @@ getInlineCost(CallSite CS, const InlineParams &Params,
|
||||
InlineCost
|
||||
getInlineCost(CallSite CS, Function *Callee, const InlineParams &Params,
|
||||
TargetTransformInfo &CalleeTTI,
|
||||
std::function<AssumptionCache &(Function &)> &GetAssumptionCache,
|
||||
ProfileSummaryInfo *PSI);
|
||||
|
||||
/// \brief Minimal filter to detect invalid constructs for inlining.
|
||||
|
@ -37,7 +37,6 @@
|
||||
namespace llvm {
|
||||
template<typename T>
|
||||
class ArrayRef;
|
||||
class AssumptionCache;
|
||||
class DominatorTree;
|
||||
class Instruction;
|
||||
class DataLayout;
|
||||
@ -51,7 +50,6 @@ namespace llvm {
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for a Sub, fold the result or return null.
|
||||
@ -59,7 +57,6 @@ namespace llvm {
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an FAdd, fold the result or return null.
|
||||
@ -67,7 +64,6 @@ namespace llvm {
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an FSub, fold the result or return null.
|
||||
@ -75,7 +71,6 @@ namespace llvm {
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an FMul, fold the result or return null.
|
||||
@ -83,28 +78,24 @@ namespace llvm {
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for a Mul, fold the result or return null.
|
||||
Value *SimplifyMulInst(Value *LHS, Value *RHS, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an SDiv, fold the result or return null.
|
||||
Value *SimplifySDivInst(Value *LHS, Value *RHS, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for a UDiv, fold the result or return null.
|
||||
Value *SimplifyUDivInst(Value *LHS, Value *RHS, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an FDiv, fold the result or return null.
|
||||
@ -112,21 +103,18 @@ namespace llvm {
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an SRem, fold the result or return null.
|
||||
Value *SimplifySRemInst(Value *LHS, Value *RHS, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for a URem, fold the result or return null.
|
||||
Value *SimplifyURemInst(Value *LHS, Value *RHS, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an FRem, fold the result or return null.
|
||||
@ -134,7 +122,6 @@ namespace llvm {
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for a Shl, fold the result or return null.
|
||||
@ -142,7 +129,6 @@ namespace llvm {
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for a LShr, fold the result or return null.
|
||||
@ -150,7 +136,6 @@ namespace llvm {
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for a AShr, fold the result or return nulll.
|
||||
@ -158,28 +143,24 @@ namespace llvm {
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an And, fold the result or return null.
|
||||
Value *SimplifyAndInst(Value *LHS, Value *RHS, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an Or, fold the result or return null.
|
||||
Value *SimplifyOrInst(Value *LHS, Value *RHS, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an Xor, fold the result or return null.
|
||||
Value *SimplifyXorInst(Value *LHS, Value *RHS, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an ICmpInst, fold the result or return null.
|
||||
@ -187,7 +168,6 @@ namespace llvm {
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an FCmpInst, fold the result or return null.
|
||||
@ -195,7 +175,6 @@ namespace llvm {
|
||||
FastMathFlags FMF, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for a SelectInst, fold the result or return null.
|
||||
@ -203,7 +182,6 @@ namespace llvm {
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for a GetElementPtrInst, fold the result or return null.
|
||||
@ -211,7 +189,6 @@ namespace llvm {
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an InsertValueInst, fold the result or return null.
|
||||
@ -219,7 +196,6 @@ namespace llvm {
|
||||
ArrayRef<unsigned> Idxs, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an ExtractValueInst, fold the result or return null.
|
||||
@ -227,7 +203,6 @@ namespace llvm {
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an ExtractElementInst, fold the result or return null.
|
||||
@ -235,7 +210,6 @@ namespace llvm {
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for a CastInst, fold the result or return null.
|
||||
@ -243,7 +217,6 @@ namespace llvm {
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
//=== Helper functions for higher up the class hierarchy.
|
||||
@ -254,7 +227,6 @@ namespace llvm {
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for a BinaryOperator, fold the result or return null.
|
||||
@ -262,7 +234,6 @@ namespace llvm {
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an FP BinaryOperator, fold the result or return null.
|
||||
@ -272,7 +243,6 @@ namespace llvm {
|
||||
const FastMathFlags &FMF, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given a function and iterators over arguments, fold the result or return
|
||||
@ -281,22 +251,19 @@ namespace llvm {
|
||||
User::op_iterator ArgEnd, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given a function and set of arguments, fold the result or return null.
|
||||
Value *SimplifyCall(Value *V, ArrayRef<Value *> Args, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// See if we can compute a simplified version of this instruction. If not,
|
||||
/// return null.
|
||||
Value *SimplifyInstruction(Instruction *I, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr);
|
||||
const DominatorTree *DT = nullptr);
|
||||
|
||||
/// Replace all uses of 'I' with 'SimpleV' and simplify the uses recursively.
|
||||
///
|
||||
@ -307,8 +274,7 @@ namespace llvm {
|
||||
/// The function returns true if any simplifications were performed.
|
||||
bool replaceAndRecursivelySimplify(Instruction *I, Value *SimpleV,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr);
|
||||
const DominatorTree *DT = nullptr);
|
||||
|
||||
/// Recursively attempt to simplify an instruction.
|
||||
///
|
||||
@ -318,8 +284,7 @@ namespace llvm {
|
||||
/// performed.
|
||||
bool recursivelySimplifyInstruction(Instruction *I,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr);
|
||||
const DominatorTree *DT = nullptr);
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "llvm/Pass.h"
|
||||
|
||||
namespace llvm {
|
||||
class AssumptionCache;
|
||||
class Constant;
|
||||
class ConstantRange;
|
||||
class DataLayout;
|
||||
@ -31,7 +30,6 @@ namespace llvm {
|
||||
/// This pass computes, caches, and vends lazy value constraint information.
|
||||
class LazyValueInfo {
|
||||
friend class LazyValueInfoWrapperPass;
|
||||
AssumptionCache *AC = nullptr;
|
||||
class TargetLibraryInfo *TLI = nullptr;
|
||||
DominatorTree *DT = nullptr;
|
||||
void *PImpl = nullptr;
|
||||
@ -40,16 +38,15 @@ class LazyValueInfo {
|
||||
public:
|
||||
~LazyValueInfo();
|
||||
LazyValueInfo() {}
|
||||
LazyValueInfo(AssumptionCache *AC_, TargetLibraryInfo *TLI_,
|
||||
LazyValueInfo(TargetLibraryInfo *TLI_,
|
||||
DominatorTree *DT_)
|
||||
: AC(AC_), TLI(TLI_), DT(DT_) {}
|
||||
: TLI(TLI_), DT(DT_) {}
|
||||
LazyValueInfo(LazyValueInfo &&Arg)
|
||||
: AC(Arg.AC), TLI(Arg.TLI), DT(Arg.DT), PImpl(Arg.PImpl) {
|
||||
: TLI(Arg.TLI), DT(Arg.DT), PImpl(Arg.PImpl) {
|
||||
Arg.PImpl = nullptr;
|
||||
}
|
||||
LazyValueInfo &operator=(LazyValueInfo &&Arg) {
|
||||
releaseMemory();
|
||||
AC = Arg.AC;
|
||||
TLI = Arg.TLI;
|
||||
DT = Arg.DT;
|
||||
PImpl = Arg.PImpl;
|
||||
|
@ -30,7 +30,6 @@ class Function;
|
||||
class FunctionPass;
|
||||
class Instruction;
|
||||
class CallSite;
|
||||
class AssumptionCache;
|
||||
class MemoryDependenceResults;
|
||||
class PredIteratorCache;
|
||||
class DominatorTree;
|
||||
@ -339,16 +338,15 @@ private:
|
||||
|
||||
/// Current AA implementation, just a cache.
|
||||
AliasAnalysis &AA;
|
||||
AssumptionCache &AC;
|
||||
const TargetLibraryInfo &TLI;
|
||||
DominatorTree &DT;
|
||||
PredIteratorCache PredCache;
|
||||
|
||||
public:
|
||||
MemoryDependenceResults(AliasAnalysis &AA, AssumptionCache &AC,
|
||||
MemoryDependenceResults(AliasAnalysis &AA,
|
||||
const TargetLibraryInfo &TLI,
|
||||
DominatorTree &DT)
|
||||
: AA(AA), AC(AC), TLI(TLI), DT(DT) {}
|
||||
: AA(AA), TLI(TLI), DT(DT) {}
|
||||
|
||||
/// Some methods limit the number of instructions they will examine.
|
||||
/// The return value of this method is the default limit that will be
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "llvm/IR/Instruction.h"
|
||||
|
||||
namespace llvm {
|
||||
class AssumptionCache;
|
||||
class DominatorTree;
|
||||
class DataLayout;
|
||||
class TargetLibraryInfo;
|
||||
@ -43,15 +42,12 @@ class PHITransAddr {
|
||||
/// TLI - The target library info if known, otherwise null.
|
||||
const TargetLibraryInfo *TLI;
|
||||
|
||||
/// A cache of @llvm.assume calls used by SimplifyInstruction.
|
||||
AssumptionCache *AC;
|
||||
|
||||
/// InstInputs - The inputs for our symbolic address.
|
||||
SmallVector<Instruction*, 4> InstInputs;
|
||||
|
||||
public:
|
||||
PHITransAddr(Value *addr, const DataLayout &DL, AssumptionCache *AC)
|
||||
: Addr(addr), DL(DL), TLI(nullptr), AC(AC) {
|
||||
PHITransAddr(Value *addr, const DataLayout &DL)
|
||||
: Addr(addr), DL(DL), TLI(nullptr) {
|
||||
// If the address is an instruction, the whole thing is considered an input.
|
||||
if (Instruction *I = dyn_cast<Instruction>(Addr))
|
||||
InstInputs.push_back(I);
|
||||
|
@ -37,7 +37,6 @@
|
||||
|
||||
namespace llvm {
|
||||
class APInt;
|
||||
class AssumptionCache;
|
||||
class Constant;
|
||||
class ConstantInt;
|
||||
class DominatorTree;
|
||||
@ -475,9 +474,6 @@ private:
|
||||
///
|
||||
TargetLibraryInfo &TLI;
|
||||
|
||||
/// The tracker for @llvm.assume intrinsics in this function.
|
||||
AssumptionCache &AC;
|
||||
|
||||
/// The dominator tree.
|
||||
///
|
||||
DominatorTree &DT;
|
||||
@ -1114,7 +1110,7 @@ private:
|
||||
bool isAddRecNeverPoison(const Instruction *I, const Loop *L);
|
||||
|
||||
public:
|
||||
ScalarEvolution(Function &F, TargetLibraryInfo &TLI, AssumptionCache &AC,
|
||||
ScalarEvolution(Function &F, TargetLibraryInfo &TLI,
|
||||
DominatorTree &DT, LoopInfo &LI);
|
||||
~ScalarEvolution();
|
||||
ScalarEvolution(ScalarEvolution &&Arg);
|
||||
|
@ -24,7 +24,6 @@ namespace llvm {
|
||||
template <typename T> class ArrayRef;
|
||||
class APInt;
|
||||
class AddOperator;
|
||||
class AssumptionCache;
|
||||
class DataLayout;
|
||||
class DominatorTree;
|
||||
class GEPOperator;
|
||||
@ -50,7 +49,6 @@ template <typename T> class ArrayRef;
|
||||
/// for all of the elements in the vector.
|
||||
void computeKnownBits(const Value *V, APInt &KnownZero, APInt &KnownOne,
|
||||
const DataLayout &DL, unsigned Depth = 0,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
/// Compute known bits from the range metadata.
|
||||
@ -61,7 +59,6 @@ template <typename T> class ArrayRef;
|
||||
/// Return true if LHS and RHS have no common bits set.
|
||||
bool haveNoCommonBitsSet(const Value *LHS, const Value *RHS,
|
||||
const DataLayout &DL,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
|
||||
@ -69,7 +66,6 @@ template <typename T> class ArrayRef;
|
||||
/// wrapper around computeKnownBits.
|
||||
void ComputeSignBit(const Value *V, bool &KnownZero, bool &KnownOne,
|
||||
const DataLayout &DL, unsigned Depth = 0,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
|
||||
@ -80,7 +76,6 @@ template <typename T> class ArrayRef;
|
||||
/// value is either a power of two or zero.
|
||||
bool isKnownToBeAPowerOfTwo(const Value *V, const DataLayout &DL,
|
||||
bool OrZero = false, unsigned Depth = 0,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
|
||||
@ -89,35 +84,30 @@ template <typename T> class ArrayRef;
|
||||
/// defined. Supports values with integer or pointer type and vectors of
|
||||
/// integers.
|
||||
bool isKnownNonZero(const Value *V, const DataLayout &DL, unsigned Depth = 0,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
|
||||
/// Returns true if the give value is known to be non-negative.
|
||||
bool isKnownNonNegative(const Value *V, const DataLayout &DL,
|
||||
unsigned Depth = 0,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
|
||||
/// Returns true if the given value is known be positive (i.e. non-negative
|
||||
/// and non-zero).
|
||||
bool isKnownPositive(const Value *V, const DataLayout &DL, unsigned Depth = 0,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
|
||||
/// Returns true if the given value is known be negative (i.e. non-positive
|
||||
/// and non-zero).
|
||||
bool isKnownNegative(const Value *V, const DataLayout &DL, unsigned Depth = 0,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
|
||||
/// Return true if the given values are known to be non-equal when defined.
|
||||
/// Supports scalar integer types only.
|
||||
bool isKnownNonEqual(const Value *V1, const Value *V2, const DataLayout &DL,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
|
||||
@ -132,7 +122,7 @@ template <typename T> class ArrayRef;
|
||||
/// for all of the elements in the vector.
|
||||
bool MaskedValueIsZero(const Value *V, const APInt &Mask,
|
||||
const DataLayout &DL,
|
||||
unsigned Depth = 0, AssumptionCache *AC = nullptr,
|
||||
unsigned Depth = 0,
|
||||
const Instruction *CxtI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
|
||||
@ -144,7 +134,7 @@ template <typename T> class ArrayRef;
|
||||
/// sign bits for the vector element with the mininum number of known sign
|
||||
/// bits.
|
||||
unsigned ComputeNumSignBits(const Value *Op, const DataLayout &DL,
|
||||
unsigned Depth = 0, AssumptionCache *AC = nullptr,
|
||||
unsigned Depth = 0,
|
||||
const Instruction *CxtI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
|
||||
@ -325,24 +315,20 @@ template <typename T> class ArrayRef;
|
||||
OverflowResult computeOverflowForUnsignedMul(const Value *LHS,
|
||||
const Value *RHS,
|
||||
const DataLayout &DL,
|
||||
AssumptionCache *AC,
|
||||
const Instruction *CxtI,
|
||||
const DominatorTree *DT);
|
||||
OverflowResult computeOverflowForUnsignedAdd(const Value *LHS,
|
||||
const Value *RHS,
|
||||
const DataLayout &DL,
|
||||
AssumptionCache *AC,
|
||||
const Instruction *CxtI,
|
||||
const DominatorTree *DT);
|
||||
OverflowResult computeOverflowForSignedAdd(const Value *LHS, const Value *RHS,
|
||||
const DataLayout &DL,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
/// This version also leverages the sign bit of Add if known.
|
||||
OverflowResult computeOverflowForSignedAdd(const AddOperator *Add,
|
||||
const DataLayout &DL,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
|
||||
@ -475,7 +461,6 @@ template <typename T> class ArrayRef;
|
||||
const DataLayout &DL,
|
||||
bool InvertAPred = false,
|
||||
unsigned Depth = 0,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
} // end namespace llvm
|
||||
|
@ -68,7 +68,6 @@ void initializeAliasSetPrinterPass(PassRegistry&);
|
||||
void initializeAlignmentFromAssumptionsPass(PassRegistry&);
|
||||
void initializeAlwaysInlinerLegacyPassPass(PassRegistry&);
|
||||
void initializeArgPromotionPass(PassRegistry&);
|
||||
void initializeAssumptionCacheTrackerPass(PassRegistry &);
|
||||
void initializeAtomicExpandPass(PassRegistry&);
|
||||
void initializeBBVectorizePass(PassRegistry&);
|
||||
void initializeBDCELegacyPassPass(PassRegistry &);
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include "llvm/Transforms/Utils/ImportedFunctionsInliningStatistics.h"
|
||||
|
||||
namespace llvm {
|
||||
class AssumptionCacheTracker;
|
||||
class CallSite;
|
||||
class DataLayout;
|
||||
class InlineCost;
|
||||
@ -77,7 +76,6 @@ private:
|
||||
bool InsertLifetime;
|
||||
|
||||
protected:
|
||||
AssumptionCacheTracker *ACT;
|
||||
ProfileSummaryInfo *PSI;
|
||||
ImportedFunctionsInliningStatistics ImportedFunctionsStats;
|
||||
};
|
||||
|
@ -30,8 +30,7 @@ struct AlignmentFromAssumptionsPass
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
|
||||
// Glue for old PM.
|
||||
bool runImpl(Function &F, AssumptionCache &AC, ScalarEvolution *SE_,
|
||||
DominatorTree *DT_);
|
||||
bool runImpl(Function &F, ScalarEvolution *SE_, DominatorTree *DT_);
|
||||
|
||||
// For memory transfers, we need a common alignment for both the source and
|
||||
// destination. If we have a new alignment for only one operand of a transfer
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Analysis/MemoryDependenceAnalysis.h"
|
||||
#include "llvm/IR/Dominators.h"
|
||||
@ -109,7 +108,6 @@ private:
|
||||
MemoryDependenceResults *MD;
|
||||
DominatorTree *DT;
|
||||
const TargetLibraryInfo *TLI;
|
||||
AssumptionCache *AC;
|
||||
SetVector<BasicBlock *> DeadBlocks;
|
||||
OptimizationRemarkEmitter *ORE;
|
||||
|
||||
@ -135,7 +133,7 @@ private:
|
||||
typedef SmallVector<gvn::AvailableValueInBlock, 64> AvailValInBlkVect;
|
||||
typedef SmallVector<BasicBlock *, 64> UnavailBlkVect;
|
||||
|
||||
bool runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT,
|
||||
bool runImpl(Function &F, DominatorTree &RunDT,
|
||||
const TargetLibraryInfo &RunTLI, AAResults &RunAA,
|
||||
MemoryDependenceResults *RunMD, LoopInfo *LI,
|
||||
OptimizationRemarkEmitter *ORE);
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/GlobalsModRef.h"
|
||||
#include "llvm/Analysis/MemoryDependenceAnalysis.h"
|
||||
#include "llvm/Analysis/TargetLibraryInfo.h"
|
||||
@ -33,7 +32,6 @@ class MemCpyOptPass : public PassInfoMixin<MemCpyOptPass> {
|
||||
MemoryDependenceResults *MD = nullptr;
|
||||
TargetLibraryInfo *TLI = nullptr;
|
||||
std::function<AliasAnalysis &()> LookupAliasAnalysis;
|
||||
std::function<AssumptionCache &()> LookupAssumptionCache;
|
||||
std::function<DominatorTree &()> LookupDomTree;
|
||||
|
||||
public:
|
||||
@ -43,7 +41,6 @@ public:
|
||||
bool runImpl(Function &F, MemoryDependenceResults *MD_,
|
||||
TargetLibraryInfo *TLI_,
|
||||
std::function<AliasAnalysis &()> LookupAliasAnalysis_,
|
||||
std::function<AssumptionCache &()> LookupAssumptionCache_,
|
||||
std::function<DominatorTree &()> LookupDomTree_);
|
||||
|
||||
private:
|
||||
|
@ -81,7 +81,6 @@
|
||||
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/ScalarEvolution.h"
|
||||
#include "llvm/Analysis/TargetLibraryInfo.h"
|
||||
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||
@ -95,7 +94,7 @@ public:
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
|
||||
// Glue for old PM.
|
||||
bool runImpl(Function &F, AssumptionCache *AC_, DominatorTree *DT_,
|
||||
bool runImpl(Function &F, DominatorTree *DT_,
|
||||
ScalarEvolution *SE_, TargetLibraryInfo *TLI_,
|
||||
TargetTransformInfo *TTI_);
|
||||
|
||||
@ -152,7 +151,6 @@ private:
|
||||
// to be an index of GEP.
|
||||
bool requiresSignExtension(Value *Index, GetElementPtrInst *GEP);
|
||||
|
||||
AssumptionCache *AC;
|
||||
const DataLayout *DL;
|
||||
DominatorTree *DT;
|
||||
ScalarEvolution *SE;
|
||||
|
@ -17,12 +17,14 @@
|
||||
#define LLVM_TRANSFORMS_SCALAR_SROA_H
|
||||
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/IR/Dominators.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
|
||||
namespace llvm {
|
||||
class AllocaInst;
|
||||
class SelectInst;
|
||||
class PHINode;
|
||||
|
||||
/// A private "module" namespace for types and utilities used by SROA. These
|
||||
/// are implementation details and should not be used by clients.
|
||||
@ -54,7 +56,6 @@ class SROALegacyPass;
|
||||
class SROA : public PassInfoMixin<SROA> {
|
||||
LLVMContext *C;
|
||||
DominatorTree *DT;
|
||||
AssumptionCache *AC;
|
||||
|
||||
/// \brief Worklist of alloca instructions to simplify.
|
||||
///
|
||||
@ -99,7 +100,7 @@ class SROA : public PassInfoMixin<SROA> {
|
||||
SetVector<SelectInst *, SmallVector<SelectInst *, 2>> SpeculatableSelects;
|
||||
|
||||
public:
|
||||
SROA() : C(nullptr), DT(nullptr), AC(nullptr) {}
|
||||
SROA() : C(nullptr), DT(nullptr) {}
|
||||
|
||||
/// \brief Run the pass over the function.
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
@ -109,8 +110,7 @@ private:
|
||||
friend class sroa::SROALegacyPass;
|
||||
|
||||
/// Helper used by both the public run method and by the legacy pass.
|
||||
PreservedAnalyses runImpl(Function &F, DominatorTree &RunDT,
|
||||
AssumptionCache &RunAC);
|
||||
PreservedAnalyses runImpl(Function &F, DominatorTree &RunDT);
|
||||
|
||||
bool presplitLoadsAndStores(AllocaInst &AI, sroa::AllocaSlices &AS);
|
||||
AllocaInst *rewritePartition(AllocaInst &AI, sroa::AllocaSlices &AS,
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/IR/ValueHandle.h"
|
||||
#include "llvm/IR/ValueMap.h"
|
||||
#include "llvm/Transforms/Utils/ValueMapper.h"
|
||||
@ -46,7 +45,6 @@ class DataLayout;
|
||||
class Loop;
|
||||
class LoopInfo;
|
||||
class AllocaInst;
|
||||
class AssumptionCacheTracker;
|
||||
class DominatorTree;
|
||||
|
||||
/// Return an exact copy of the specified module
|
||||
@ -176,15 +174,12 @@ void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
|
||||
/// InlineFunction call, and records the auxiliary results produced by it.
|
||||
class InlineFunctionInfo {
|
||||
public:
|
||||
explicit InlineFunctionInfo(CallGraph *cg = nullptr,
|
||||
std::function<AssumptionCache &(Function &)>
|
||||
*GetAssumptionCache = nullptr)
|
||||
: CG(cg), GetAssumptionCache(GetAssumptionCache) {}
|
||||
explicit InlineFunctionInfo(CallGraph *cg = nullptr)
|
||||
: CG(cg) {}
|
||||
|
||||
/// CG - If non-null, InlineFunction will update the callgraph to reflect the
|
||||
/// changes it makes.
|
||||
CallGraph *CG;
|
||||
std::function<AssumptionCache &(Function &)> *GetAssumptionCache;
|
||||
|
||||
/// StaticAllocas - InlineFunction fills this in with all static allocas that
|
||||
/// get copied into the caller.
|
||||
|
@ -38,7 +38,6 @@ class LoadInst;
|
||||
class Value;
|
||||
class PHINode;
|
||||
class AllocaInst;
|
||||
class AssumptionCache;
|
||||
class ConstantExpr;
|
||||
class DataLayout;
|
||||
class TargetLibraryInfo;
|
||||
@ -137,7 +136,7 @@ bool EliminateDuplicatePHINodes(BasicBlock *BB);
|
||||
/// parameter, providing the set of loop header that SimplifyCFG should not
|
||||
/// eliminate.
|
||||
bool SimplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
|
||||
unsigned BonusInstThreshold, AssumptionCache *AC = nullptr,
|
||||
unsigned BonusInstThreshold,
|
||||
SmallPtrSetImpl<BasicBlock *> *LoopHeaders = nullptr);
|
||||
|
||||
/// This function is used to flatten a CFG. For example, it uses parallel-and
|
||||
@ -176,15 +175,13 @@ AllocaInst *DemotePHIToStack(PHINode *P, Instruction *AllocaPoint = nullptr);
|
||||
unsigned getOrEnforceKnownAlignment(Value *V, unsigned PrefAlign,
|
||||
const DataLayout &DL,
|
||||
const Instruction *CxtI = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
|
||||
/// Try to infer an alignment for the specified pointer.
|
||||
static inline unsigned getKnownAlignment(Value *V, const DataLayout &DL,
|
||||
const Instruction *CxtI = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const DominatorTree *DT = nullptr) {
|
||||
return getOrEnforceKnownAlignment(V, 0, DL, CxtI, AC, DT);
|
||||
return getOrEnforceKnownAlignment(V, 0, DL, CxtI, DT);
|
||||
}
|
||||
|
||||
/// Given a getelementptr instruction/constantexpr, emit the code necessary to
|
||||
|
@ -39,7 +39,6 @@
|
||||
#ifndef LLVM_TRANSFORMS_UTILS_LOOPSIMPLIFY_H
|
||||
#define LLVM_TRANSFORMS_UTILS_LOOPSIMPLIFY_H
|
||||
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/ScalarEvolution.h"
|
||||
#include "llvm/IR/Dominators.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
@ -58,7 +57,7 @@ public:
|
||||
/// it into a simplified loop nest with preheaders and single backedges. It will
|
||||
/// update \c AliasAnalysis and \c ScalarEvolution analyses if they're non-null.
|
||||
bool simplifyLoop(Loop *L, DominatorTree *DT, LoopInfo *LI, ScalarEvolution *SE,
|
||||
AssumptionCache *AC, bool PreserveLCSSA);
|
||||
bool PreserveLCSSA);
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
|
@ -23,7 +23,6 @@
|
||||
namespace llvm {
|
||||
class AliasSet;
|
||||
class AliasSetTracker;
|
||||
class AssumptionCache;
|
||||
class BasicBlock;
|
||||
class DataLayout;
|
||||
class DominatorTree;
|
||||
|
@ -963,7 +963,7 @@ private:
|
||||
if (WalkingPhi && Location.Ptr) {
|
||||
PHITransAddr Translator(
|
||||
const_cast<Value *>(Location.Ptr),
|
||||
OriginalAccess->getBlock()->getModule()->getDataLayout(), nullptr);
|
||||
OriginalAccess->getBlock()->getModule()->getDataLayout());
|
||||
if (!Translator.PHITranslateValue(OriginalAccess->getBlock(),
|
||||
DefIterator.getPhiArgBlock(), nullptr,
|
||||
false))
|
||||
|
@ -21,7 +21,6 @@ template <typename T> class ArrayRef;
|
||||
class AllocaInst;
|
||||
class DominatorTree;
|
||||
class AliasSetTracker;
|
||||
class AssumptionCache;
|
||||
|
||||
/// \brief Return true if this alloca is legal for promotion.
|
||||
///
|
||||
@ -41,8 +40,7 @@ bool isAllocaPromotable(const AllocaInst *AI);
|
||||
/// If AST is specified, the specified tracker is updated to reflect changes
|
||||
/// made to the IR.
|
||||
void PromoteMemToReg(ArrayRef<AllocaInst *> Allocas, DominatorTree &DT,
|
||||
AliasSetTracker *AST = nullptr,
|
||||
AssumptionCache *AC = nullptr);
|
||||
AliasSetTracker *AST = nullptr);
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
|
@ -23,7 +23,6 @@
|
||||
namespace llvm {
|
||||
|
||||
class StringRef;
|
||||
class AssumptionCache;
|
||||
class DominatorTree;
|
||||
class Loop;
|
||||
class LoopInfo;
|
||||
@ -37,7 +36,7 @@ bool UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool Force,
|
||||
bool AllowRuntime, bool AllowExpensiveTripCount,
|
||||
bool PreserveCondBr, bool PreserveOnlyFirst,
|
||||
unsigned TripMultiple, unsigned PeelCount, LoopInfo *LI,
|
||||
ScalarEvolution *SE, DominatorTree *DT, AssumptionCache *AC,
|
||||
ScalarEvolution *SE, DominatorTree *DT,
|
||||
OptimizationRemarkEmitter *ORE, bool PreserveLCSSA);
|
||||
|
||||
bool UnrollRuntimeLoopRemainder(Loop *L, unsigned Count,
|
||||
|
@ -51,7 +51,6 @@
|
||||
|
||||
#include "llvm/ADT/MapVector.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
||||
#include "llvm/Analysis/BlockFrequencyInfo.h"
|
||||
#include "llvm/Analysis/DemandedBits.h"
|
||||
@ -83,7 +82,6 @@ struct LoopVectorizePass : public PassInfoMixin<LoopVectorizePass> {
|
||||
TargetLibraryInfo *TLI;
|
||||
DemandedBits *DB;
|
||||
AliasAnalysis *AA;
|
||||
AssumptionCache *AC;
|
||||
std::function<const LoopAccessInfo &(Loop &)> *GetLAA;
|
||||
OptimizationRemarkEmitter *ORE;
|
||||
|
||||
@ -95,7 +93,7 @@ struct LoopVectorizePass : public PassInfoMixin<LoopVectorizePass> {
|
||||
bool runImpl(Function &F, ScalarEvolution &SE_, LoopInfo &LI_,
|
||||
TargetTransformInfo &TTI_, DominatorTree &DT_,
|
||||
BlockFrequencyInfo &BFI_, TargetLibraryInfo *TLI_,
|
||||
DemandedBits &DB_, AliasAnalysis &AA_, AssumptionCache &AC_,
|
||||
DemandedBits &DB_, AliasAnalysis &AA_,
|
||||
std::function<const LoopAccessInfo &(Loop &)> &GetLAA_,
|
||||
OptimizationRemarkEmitter &ORE);
|
||||
|
||||
|
@ -21,7 +21,6 @@
|
||||
|
||||
#include "llvm/ADT/MapVector.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/DemandedBits.h"
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Analysis/ScalarEvolution.h"
|
||||
@ -49,7 +48,6 @@ struct SLPVectorizerPass : public PassInfoMixin<SLPVectorizerPass> {
|
||||
AliasAnalysis *AA = nullptr;
|
||||
LoopInfo *LI = nullptr;
|
||||
DominatorTree *DT = nullptr;
|
||||
AssumptionCache *AC = nullptr;
|
||||
DemandedBits *DB = nullptr;
|
||||
const DataLayout *DL = nullptr;
|
||||
|
||||
@ -59,7 +57,7 @@ public:
|
||||
// Glue for old PM.
|
||||
bool runImpl(Function &F, ScalarEvolution *SE_, TargetTransformInfo *TTI_,
|
||||
TargetLibraryInfo *TLI_, AliasAnalysis *AA_, LoopInfo *LI_,
|
||||
DominatorTree *DT_, AssumptionCache *AC_, DemandedBits *DB_);
|
||||
DominatorTree *DT_, DemandedBits *DB_);
|
||||
|
||||
private:
|
||||
/// \brief Collect store and getelementptr instructions and organize them
|
||||
|
@ -1,140 +0,0 @@
|
||||
//===- AssumptionCache.cpp - Cache finding @llvm.assume calls -------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains a pass that keeps track of @llvm.assume intrinsics in
|
||||
// the functions of a module.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/IR/CallSite.h"
|
||||
#include "llvm/IR/Dominators.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/IntrinsicInst.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/IR/PatternMatch.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
using namespace llvm;
|
||||
using namespace llvm::PatternMatch;
|
||||
|
||||
void AssumptionCache::scanFunction() {
|
||||
assert(!Scanned && "Tried to scan the function twice!");
|
||||
assert(AssumeHandles.empty() && "Already have assumes when scanning!");
|
||||
|
||||
// Go through all instructions in all blocks, add all calls to @llvm.assume
|
||||
// to this cache.
|
||||
for (BasicBlock &B : F)
|
||||
for (Instruction &II : B)
|
||||
if (match(&II, m_Intrinsic<Intrinsic::assume>()))
|
||||
AssumeHandles.push_back(&II);
|
||||
|
||||
// Mark the scan as complete.
|
||||
Scanned = true;
|
||||
}
|
||||
|
||||
void AssumptionCache::registerAssumption(CallInst *CI) {
|
||||
assert(match(CI, m_Intrinsic<Intrinsic::assume>()) &&
|
||||
"Registered call does not call @llvm.assume");
|
||||
|
||||
// If we haven't scanned the function yet, just drop this assumption. It will
|
||||
// be found when we scan later.
|
||||
if (!Scanned)
|
||||
return;
|
||||
|
||||
AssumeHandles.push_back(CI);
|
||||
|
||||
#ifndef NDEBUG
|
||||
assert(CI->getParent() &&
|
||||
"Cannot register @llvm.assume call not in a basic block");
|
||||
assert(&F == CI->getParent()->getParent() &&
|
||||
"Cannot register @llvm.assume call not in this function");
|
||||
|
||||
// We expect the number of assumptions to be small, so in an asserts build
|
||||
// check that we don't accumulate duplicates and that all assumptions point
|
||||
// to the same function.
|
||||
SmallPtrSet<Value *, 16> AssumptionSet;
|
||||
for (auto &VH : AssumeHandles) {
|
||||
if (!VH)
|
||||
continue;
|
||||
|
||||
assert(&F == cast<Instruction>(VH)->getParent()->getParent() &&
|
||||
"Cached assumption not inside this function!");
|
||||
assert(match(cast<CallInst>(VH), m_Intrinsic<Intrinsic::assume>()) &&
|
||||
"Cached something other than a call to @llvm.assume!");
|
||||
assert(AssumptionSet.insert(VH).second &&
|
||||
"Cache contains multiple copies of a call!");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
AnalysisKey AssumptionAnalysis::Key;
|
||||
|
||||
PreservedAnalyses AssumptionPrinterPass::run(Function &F,
|
||||
FunctionAnalysisManager &AM) {
|
||||
AssumptionCache &AC = AM.getResult<AssumptionAnalysis>(F);
|
||||
|
||||
OS << "Cached assumptions for function: " << F.getName() << "\n";
|
||||
for (auto &VH : AC.assumptions())
|
||||
if (VH)
|
||||
OS << " " << *cast<CallInst>(VH)->getArgOperand(0) << "\n";
|
||||
|
||||
return PreservedAnalyses::all();
|
||||
}
|
||||
|
||||
void AssumptionCacheTracker::FunctionCallbackVH::deleted() {
|
||||
auto I = ACT->AssumptionCaches.find_as(cast<Function>(getValPtr()));
|
||||
if (I != ACT->AssumptionCaches.end())
|
||||
ACT->AssumptionCaches.erase(I);
|
||||
// 'this' now dangles!
|
||||
}
|
||||
|
||||
AssumptionCache &AssumptionCacheTracker::getAssumptionCache(Function &F) {
|
||||
// We probe the function map twice to try and avoid creating a value handle
|
||||
// around the function in common cases. This makes insertion a bit slower,
|
||||
// but if we have to insert we're going to scan the whole function so that
|
||||
// shouldn't matter.
|
||||
auto I = AssumptionCaches.find_as(&F);
|
||||
if (I != AssumptionCaches.end())
|
||||
return *I->second;
|
||||
|
||||
// Ok, build a new cache by scanning the function, insert it and the value
|
||||
// handle into our map, and return the newly populated cache.
|
||||
auto IP = AssumptionCaches.insert(std::make_pair(
|
||||
FunctionCallbackVH(&F, this), llvm::make_unique<AssumptionCache>(F)));
|
||||
assert(IP.second && "Scanning function already in the map?");
|
||||
return *IP.first->second;
|
||||
}
|
||||
|
||||
void AssumptionCacheTracker::verifyAnalysis() const {
|
||||
#ifndef NDEBUG
|
||||
SmallPtrSet<const CallInst *, 4> AssumptionSet;
|
||||
for (const auto &I : AssumptionCaches) {
|
||||
for (auto &VH : I.second->assumptions())
|
||||
if (VH)
|
||||
AssumptionSet.insert(cast<CallInst>(VH));
|
||||
|
||||
for (const BasicBlock &B : cast<Function>(*I.first))
|
||||
for (const Instruction &II : B)
|
||||
if (match(&II, m_Intrinsic<Intrinsic::assume>()))
|
||||
assert(AssumptionSet.count(cast<CallInst>(&II)) &&
|
||||
"Assumption in scanned function not in cache");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
AssumptionCacheTracker::AssumptionCacheTracker() : ImmutablePass(ID) {
|
||||
initializeAssumptionCacheTrackerPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
AssumptionCacheTracker::~AssumptionCacheTracker() {}
|
||||
|
||||
INITIALIZE_PASS(AssumptionCacheTracker, "assumption-cache-tracker",
|
||||
"Assumption Cache Tracker", false, true)
|
||||
char AssumptionCacheTracker::ID = 0;
|
@ -23,7 +23,6 @@
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Analysis/MemoryBuiltins.h"
|
||||
#include "llvm/Analysis/ValueTracking.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
@ -182,7 +181,7 @@ static bool isObjectSize(const Value *V, uint64_t Size, const DataLayout &DL,
|
||||
/*static*/ const Value *BasicAAResult::GetLinearExpression(
|
||||
const Value *V, APInt &Scale, APInt &Offset, unsigned &ZExtBits,
|
||||
unsigned &SExtBits, const DataLayout &DL, unsigned Depth,
|
||||
AssumptionCache *AC, DominatorTree *DT, bool &NSW, bool &NUW) {
|
||||
DominatorTree *DT, bool &NSW, bool &NUW) {
|
||||
assert(V->getType()->isIntegerTy() && "Not an integer value");
|
||||
|
||||
// Limit our recursion depth.
|
||||
@ -221,7 +220,7 @@ static bool isObjectSize(const Value *V, uint64_t Size, const DataLayout &DL,
|
||||
case Instruction::Or:
|
||||
// X|C == X+C if all the bits in C are unset in X. Otherwise we can't
|
||||
// analyze it.
|
||||
if (!MaskedValueIsZero(BOp->getOperand(0), RHSC->getValue(), DL, 0, AC,
|
||||
if (!MaskedValueIsZero(BOp->getOperand(0), RHSC->getValue(), DL, 0,
|
||||
BOp, DT)) {
|
||||
Scale = 1;
|
||||
Offset = 0;
|
||||
@ -230,23 +229,23 @@ static bool isObjectSize(const Value *V, uint64_t Size, const DataLayout &DL,
|
||||
LLVM_FALLTHROUGH;
|
||||
case Instruction::Add:
|
||||
V = GetLinearExpression(BOp->getOperand(0), Scale, Offset, ZExtBits,
|
||||
SExtBits, DL, Depth + 1, AC, DT, NSW, NUW);
|
||||
SExtBits, DL, Depth + 1, DT, NSW, NUW);
|
||||
Offset += RHS;
|
||||
break;
|
||||
case Instruction::Sub:
|
||||
V = GetLinearExpression(BOp->getOperand(0), Scale, Offset, ZExtBits,
|
||||
SExtBits, DL, Depth + 1, AC, DT, NSW, NUW);
|
||||
SExtBits, DL, Depth + 1, DT, NSW, NUW);
|
||||
Offset -= RHS;
|
||||
break;
|
||||
case Instruction::Mul:
|
||||
V = GetLinearExpression(BOp->getOperand(0), Scale, Offset, ZExtBits,
|
||||
SExtBits, DL, Depth + 1, AC, DT, NSW, NUW);
|
||||
SExtBits, DL, Depth + 1, DT, NSW, NUW);
|
||||
Offset *= RHS;
|
||||
Scale *= RHS;
|
||||
break;
|
||||
case Instruction::Shl:
|
||||
V = GetLinearExpression(BOp->getOperand(0), Scale, Offset, ZExtBits,
|
||||
SExtBits, DL, Depth + 1, AC, DT, NSW, NUW);
|
||||
SExtBits, DL, Depth + 1, DT, NSW, NUW);
|
||||
Offset <<= RHS.getLimitedValue();
|
||||
Scale <<= RHS.getLimitedValue();
|
||||
// the semantics of nsw and nuw for left shifts don't match those of
|
||||
@ -273,7 +272,7 @@ static bool isObjectSize(const Value *V, uint64_t Size, const DataLayout &DL,
|
||||
unsigned OldZExtBits = ZExtBits, OldSExtBits = SExtBits;
|
||||
const Value *Result =
|
||||
GetLinearExpression(CastOp, Scale, Offset, ZExtBits, SExtBits, DL,
|
||||
Depth + 1, AC, DT, NSW, NUW);
|
||||
Depth + 1, DT, NSW, NUW);
|
||||
|
||||
// zext(zext(%x)) == zext(%x), and similarly for sext; we'll handle this
|
||||
// by just incrementing the number of bits we've extended by.
|
||||
@ -344,7 +343,7 @@ static int64_t adjustToPointerSize(int64_t Offset, unsigned PointerSize) {
|
||||
/// depth (MaxLookupSearchDepth). When DataLayout not is around, it just looks
|
||||
/// through pointer casts.
|
||||
bool BasicAAResult::DecomposeGEPExpression(const Value *V,
|
||||
DecomposedGEP &Decomposed, const DataLayout &DL, AssumptionCache *AC,
|
||||
DecomposedGEP &Decomposed, const DataLayout &DL,
|
||||
DominatorTree *DT) {
|
||||
// Limit recursion depth to limit compile time in crazy cases.
|
||||
unsigned MaxLookup = MaxLookupSearchDepth;
|
||||
@ -385,10 +384,9 @@ bool BasicAAResult::DecomposeGEPExpression(const Value *V,
|
||||
// If it's not a GEP, hand it off to SimplifyInstruction to see if it
|
||||
// can come up with something. This matches what GetUnderlyingObject does.
|
||||
if (const Instruction *I = dyn_cast<Instruction>(V))
|
||||
// TODO: Get a DominatorTree and AssumptionCache and use them here
|
||||
// (these are both now available in this function, but this should be
|
||||
// updated when GetUnderlyingObject is updated). TLI should be
|
||||
// provided also.
|
||||
// TODO: Get a DominatorTree and use it here (it is now available in
|
||||
// this function, but this should be updated when GetUnderlyingObject
|
||||
// is updated). TLI should be provided also.
|
||||
if (const Value *Simplified =
|
||||
SimplifyInstruction(const_cast<Instruction *>(I), DL)) {
|
||||
V = Simplified;
|
||||
@ -450,7 +448,7 @@ bool BasicAAResult::DecomposeGEPExpression(const Value *V,
|
||||
APInt IndexScale(Width, 0), IndexOffset(Width, 0);
|
||||
bool NSW = true, NUW = true;
|
||||
Index = GetLinearExpression(Index, IndexScale, IndexOffset, ZExtBits,
|
||||
SExtBits, DL, 0, AC, DT, NSW, NUW);
|
||||
SExtBits, DL, 0, DT, NSW, NUW);
|
||||
|
||||
// The GEP index scale ("Scale") scales C1*V+C2, yielding (C1*V+C2)*Scale.
|
||||
// This gives us an aggregate computation of (C1*Scale)*V + C2*Scale.
|
||||
@ -1058,9 +1056,9 @@ AliasResult BasicAAResult::aliasGEP(const GEPOperator *GEP1, uint64_t V1Size,
|
||||
const Value *UnderlyingV2) {
|
||||
DecomposedGEP DecompGEP1, DecompGEP2;
|
||||
bool GEP1MaxLookupReached =
|
||||
DecomposeGEPExpression(GEP1, DecompGEP1, DL, &AC, DT);
|
||||
DecomposeGEPExpression(GEP1, DecompGEP1, DL, DT);
|
||||
bool GEP2MaxLookupReached =
|
||||
DecomposeGEPExpression(V2, DecompGEP2, DL, &AC, DT);
|
||||
DecomposeGEPExpression(V2, DecompGEP2, DL, DT);
|
||||
|
||||
int64_t GEP1BaseOffset = DecompGEP1.StructOffset + DecompGEP1.OtherOffset;
|
||||
int64_t GEP2BaseOffset = DecompGEP2.StructOffset + DecompGEP2.OtherOffset;
|
||||
@ -1222,7 +1220,7 @@ AliasResult BasicAAResult::aliasGEP(const GEPOperator *GEP1, uint64_t V1Size,
|
||||
|
||||
bool SignKnownZero, SignKnownOne;
|
||||
ComputeSignBit(const_cast<Value *>(V), SignKnownZero, SignKnownOne, DL,
|
||||
0, &AC, nullptr, DT);
|
||||
0, nullptr, DT);
|
||||
|
||||
// Zero-extension widens the variable, and so forces the sign
|
||||
// bit to zero.
|
||||
@ -1257,7 +1255,7 @@ AliasResult BasicAAResult::aliasGEP(const GEPOperator *GEP1, uint64_t V1Size,
|
||||
return NoAlias;
|
||||
|
||||
if (constantOffsetHeuristic(DecompGEP1.VarIndices, V1Size, V2Size,
|
||||
GEP1BaseOffset, &AC, DT))
|
||||
GEP1BaseOffset, DT))
|
||||
return NoAlias;
|
||||
}
|
||||
|
||||
@ -1659,7 +1657,7 @@ void BasicAAResult::GetIndexDifference(
|
||||
|
||||
bool BasicAAResult::constantOffsetHeuristic(
|
||||
const SmallVectorImpl<VariableGEPIndex> &VarIndices, uint64_t V1Size,
|
||||
uint64_t V2Size, int64_t BaseOffset, AssumptionCache *AC,
|
||||
uint64_t V2Size, int64_t BaseOffset,
|
||||
DominatorTree *DT) {
|
||||
if (VarIndices.size() != 2 || V1Size == MemoryLocation::UnknownSize ||
|
||||
V2Size == MemoryLocation::UnknownSize)
|
||||
@ -1682,11 +1680,11 @@ bool BasicAAResult::constantOffsetHeuristic(
|
||||
bool NSW = true, NUW = true;
|
||||
unsigned V0ZExtBits = 0, V0SExtBits = 0, V1ZExtBits = 0, V1SExtBits = 0;
|
||||
const Value *V0 = GetLinearExpression(Var0.V, V0Scale, V0Offset, V0ZExtBits,
|
||||
V0SExtBits, DL, 0, AC, DT, NSW, NUW);
|
||||
V0SExtBits, DL, 0, DT, NSW, NUW);
|
||||
NSW = true;
|
||||
NUW = true;
|
||||
const Value *V1 = GetLinearExpression(Var1.V, V1Scale, V1Offset, V1ZExtBits,
|
||||
V1SExtBits, DL, 0, AC, DT, NSW, NUW);
|
||||
V1SExtBits, DL, 0, DT, NSW, NUW);
|
||||
|
||||
if (V0Scale != V1Scale || V0ZExtBits != V1ZExtBits ||
|
||||
V0SExtBits != V1SExtBits || !isValueEqualInPotentialCycles(V0, V1))
|
||||
@ -1720,7 +1718,6 @@ AnalysisKey BasicAA::Key;
|
||||
BasicAAResult BasicAA::run(Function &F, FunctionAnalysisManager &AM) {
|
||||
return BasicAAResult(F.getParent()->getDataLayout(),
|
||||
AM.getResult<TargetLibraryAnalysis>(F),
|
||||
AM.getResult<AssumptionAnalysis>(F),
|
||||
&AM.getResult<DominatorTreeAnalysis>(F),
|
||||
AM.getCachedResult<LoopAnalysis>(F));
|
||||
}
|
||||
@ -1734,7 +1731,6 @@ void BasicAAWrapperPass::anchor() {}
|
||||
|
||||
INITIALIZE_PASS_BEGIN(BasicAAWrapperPass, "basicaa",
|
||||
"Basic Alias Analysis (stateless AA impl)", true, true)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
|
||||
INITIALIZE_PASS_END(BasicAAWrapperPass, "basicaa",
|
||||
@ -1745,13 +1741,12 @@ FunctionPass *llvm::createBasicAAWrapperPass() {
|
||||
}
|
||||
|
||||
bool BasicAAWrapperPass::runOnFunction(Function &F) {
|
||||
auto &ACT = getAnalysis<AssumptionCacheTracker>();
|
||||
auto &TLIWP = getAnalysis<TargetLibraryInfoWrapperPass>();
|
||||
auto &DTWP = getAnalysis<DominatorTreeWrapperPass>();
|
||||
auto *LIWP = getAnalysisIfAvailable<LoopInfoWrapperPass>();
|
||||
|
||||
Result.reset(new BasicAAResult(F.getParent()->getDataLayout(), TLIWP.getTLI(),
|
||||
ACT.getAssumptionCache(F), &DTWP.getDomTree(),
|
||||
&DTWP.getDomTree(),
|
||||
LIWP ? &LIWP->getLoopInfo() : nullptr));
|
||||
|
||||
return false;
|
||||
@ -1759,7 +1754,6 @@ bool BasicAAWrapperPass::runOnFunction(Function &F) {
|
||||
|
||||
void BasicAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.setPreservesAll();
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
AU.addRequired<DominatorTreeWrapperPass>();
|
||||
AU.addRequired<TargetLibraryInfoWrapperPass>();
|
||||
}
|
||||
@ -1767,6 +1761,5 @@ void BasicAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
BasicAAResult llvm::createLegacyPMBasicAAResult(Pass &P, Function &F) {
|
||||
return BasicAAResult(
|
||||
F.getParent()->getDataLayout(),
|
||||
P.getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(),
|
||||
P.getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F));
|
||||
P.getAnalysis<TargetLibraryInfoWrapperPass>().getTLI());
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ add_llvm_library(LLVMAnalysis
|
||||
AliasAnalysisSummary.cpp
|
||||
AliasSetTracker.cpp
|
||||
Analysis.cpp
|
||||
AssumptionCache.cpp
|
||||
BasicAliasAnalysis.cpp
|
||||
BlockFrequencyInfo.cpp
|
||||
BlockFrequencyInfoImpl.cpp
|
||||
|
@ -11,7 +11,6 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/CodeMetrics.h"
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||
@ -71,8 +70,7 @@ static void completeEphemeralValues(SmallPtrSetImpl<const Value *> &Visited,
|
||||
|
||||
// Find all ephemeral values.
|
||||
void CodeMetrics::collectEphemeralValues(
|
||||
const Loop *L, AssumptionCache *AC,
|
||||
SmallPtrSetImpl<const Value *> &EphValues) {
|
||||
const Loop *L, SmallPtrSetImpl<const Value *> &EphValues) {
|
||||
SmallPtrSet<const Value *, 32> Visited;
|
||||
SmallVector<const Value *, 16> Worklist;
|
||||
|
||||
@ -87,8 +85,7 @@ void CodeMetrics::collectEphemeralValues(
|
||||
}
|
||||
|
||||
void CodeMetrics::collectEphemeralValues(
|
||||
const Function *F, AssumptionCache *AC,
|
||||
SmallPtrSetImpl<const Value *> &EphValues) {
|
||||
const Function *F, SmallPtrSetImpl<const Value *> &EphValues) {
|
||||
SmallPtrSet<const Value *, 32> Visited;
|
||||
SmallVector<const Value *, 16> Worklist;
|
||||
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/ValueTracking.h"
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/IR/CFG.h"
|
||||
@ -45,7 +44,6 @@ using namespace llvm;
|
||||
char DemandedBitsWrapperPass::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(DemandedBitsWrapperPass, "demanded-bits",
|
||||
"Demanded bits analysis", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
|
||||
INITIALIZE_PASS_END(DemandedBitsWrapperPass, "demanded-bits",
|
||||
"Demanded bits analysis", false, false)
|
||||
@ -56,7 +54,6 @@ DemandedBitsWrapperPass::DemandedBitsWrapperPass() : FunctionPass(ID) {
|
||||
|
||||
void DemandedBitsWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.setPreservesCFG();
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
AU.addRequired<DominatorTreeWrapperPass>();
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
@ -88,13 +85,13 @@ void DemandedBits::determineLiveOperandBits(
|
||||
KnownZero = APInt(BitWidth, 0);
|
||||
KnownOne = APInt(BitWidth, 0);
|
||||
computeKnownBits(const_cast<Value *>(V1), KnownZero, KnownOne, DL, 0,
|
||||
&AC, UserI, &DT);
|
||||
UserI, &DT);
|
||||
|
||||
if (V2) {
|
||||
KnownZero2 = APInt(BitWidth, 0);
|
||||
KnownOne2 = APInt(BitWidth, 0);
|
||||
computeKnownBits(const_cast<Value *>(V2), KnownZero2, KnownOne2, DL,
|
||||
0, &AC, UserI, &DT);
|
||||
0, UserI, &DT);
|
||||
}
|
||||
};
|
||||
|
||||
@ -248,9 +245,8 @@ void DemandedBits::determineLiveOperandBits(
|
||||
}
|
||||
|
||||
bool DemandedBitsWrapperPass::runOnFunction(Function &F) {
|
||||
auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
|
||||
auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||
DB.emplace(F, AC, DT);
|
||||
DB.emplace(F, DT);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -390,9 +386,8 @@ AnalysisKey DemandedBitsAnalysis::Key;
|
||||
|
||||
DemandedBits DemandedBitsAnalysis::run(Function &F,
|
||||
FunctionAnalysisManager &AM) {
|
||||
auto &AC = AM.getResult<AssumptionAnalysis>(F);
|
||||
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
|
||||
return DemandedBits(F, AC, DT);
|
||||
return DemandedBits(F, DT);
|
||||
}
|
||||
|
||||
PreservedAnalyses DemandedBitsPrinterPass::run(Function &F,
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
#include "llvm/Analysis/IVUsers.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/CodeMetrics.h"
|
||||
#include "llvm/Analysis/LoopPass.h"
|
||||
#include "llvm/Analysis/LoopPassManager.h"
|
||||
@ -41,8 +40,7 @@ IVUsers IVUsersAnalysis::run(Loop &L, LoopAnalysisManager &AM) {
|
||||
AM.getResult<FunctionAnalysisManagerLoopProxy>(L).getManager();
|
||||
Function *F = L.getHeader()->getParent();
|
||||
|
||||
return IVUsers(&L, FAM.getCachedResult<AssumptionAnalysis>(*F),
|
||||
FAM.getCachedResult<LoopAnalysis>(*F),
|
||||
return IVUsers(&L, FAM.getCachedResult<LoopAnalysis>(*F),
|
||||
FAM.getCachedResult<DominatorTreeAnalysis>(*F),
|
||||
FAM.getCachedResult<ScalarEvolutionAnalysis>(*F));
|
||||
}
|
||||
@ -55,7 +53,6 @@ PreservedAnalyses IVUsersPrinterPass::run(Loop &L, LoopAnalysisManager &AM) {
|
||||
char IVUsersWrapperPass::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(IVUsersWrapperPass, "iv-users",
|
||||
"Induction Variable Users", false, true)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
|
||||
@ -263,12 +260,11 @@ IVStrideUse &IVUsers::AddUser(Instruction *User, Value *Operand) {
|
||||
return IVUses.back();
|
||||
}
|
||||
|
||||
IVUsers::IVUsers(Loop *L, AssumptionCache *AC, LoopInfo *LI, DominatorTree *DT,
|
||||
ScalarEvolution *SE)
|
||||
: L(L), AC(AC), LI(LI), DT(DT), SE(SE), IVUses() {
|
||||
IVUsers::IVUsers(Loop *L, LoopInfo *LI, DominatorTree *DT, ScalarEvolution *SE)
|
||||
: L(L), LI(LI), DT(DT), SE(SE), IVUses() {
|
||||
// Collect ephemeral values so that AddUsersIfInteresting skips them.
|
||||
EphValues.clear();
|
||||
CodeMetrics::collectEphemeralValues(L, AC, EphValues);
|
||||
CodeMetrics::collectEphemeralValues(L, EphValues);
|
||||
|
||||
// Find all uses of induction variables in this loop, and categorize
|
||||
// them by stride. Start by finding all of the PHI nodes in the header for
|
||||
@ -317,7 +313,6 @@ IVUsersWrapperPass::IVUsersWrapperPass() : LoopPass(ID) {
|
||||
}
|
||||
|
||||
void IVUsersWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
AU.addRequired<LoopInfoWrapperPass>();
|
||||
AU.addRequired<DominatorTreeWrapperPass>();
|
||||
AU.addRequired<ScalarEvolutionWrapperPass>();
|
||||
@ -325,13 +320,11 @@ void IVUsersWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
}
|
||||
|
||||
bool IVUsersWrapperPass::runOnLoop(Loop *L, LPPassManager &LPM) {
|
||||
auto *AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
|
||||
*L->getHeader()->getParent());
|
||||
auto *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
|
||||
auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||
auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
|
||||
|
||||
IU.reset(new IVUsers(L, AC, LI, DT, SE));
|
||||
IU.reset(new IVUsers(L, LI, DT, SE));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/CodeMetrics.h"
|
||||
#include "llvm/Analysis/ConstantFolding.h"
|
||||
#include "llvm/Analysis/InstructionSimplify.h"
|
||||
@ -69,9 +68,6 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
|
||||
/// The TargetTransformInfo available for this compilation.
|
||||
const TargetTransformInfo &TTI;
|
||||
|
||||
/// Getter for the cache of @llvm.assume intrinsics.
|
||||
std::function<AssumptionCache &(Function &)> &GetAssumptionCache;
|
||||
|
||||
/// Profile summary information.
|
||||
ProfileSummaryInfo *PSI;
|
||||
|
||||
@ -201,20 +197,19 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
|
||||
|
||||
public:
|
||||
CallAnalyzer(const TargetTransformInfo &TTI,
|
||||
std::function<AssumptionCache &(Function &)> &GetAssumptionCache,
|
||||
ProfileSummaryInfo *PSI, Function &Callee, CallSite CSArg,
|
||||
const InlineParams &Params)
|
||||
: TTI(TTI), GetAssumptionCache(GetAssumptionCache), PSI(PSI), F(Callee),
|
||||
CandidateCS(CSArg), Params(Params), Threshold(Params.DefaultThreshold),
|
||||
Cost(0), IsCallerRecursive(false), IsRecursiveCall(false),
|
||||
ExposesReturnsTwice(false), HasDynamicAlloca(false),
|
||||
ContainsNoDuplicateCall(false), HasReturn(false), HasIndirectBr(false),
|
||||
HasFrameEscape(false), AllocatedSize(0), NumInstructions(0),
|
||||
NumVectorInstructions(0), FiftyPercentVectorBonus(0),
|
||||
TenPercentVectorBonus(0), VectorBonus(0), NumConstantArgs(0),
|
||||
NumConstantOffsetPtrArgs(0), NumAllocaArgs(0), NumConstantPtrCmps(0),
|
||||
NumConstantPtrDiffs(0), NumInstructionsSimplified(0),
|
||||
SROACostSavings(0), SROACostSavingsLost(0) {}
|
||||
: TTI(TTI), PSI(PSI), F(Callee), CandidateCS(CSArg), Params(Params),
|
||||
Threshold(Params.DefaultThreshold), Cost(0), IsCallerRecursive(false),
|
||||
IsRecursiveCall(false), ExposesReturnsTwice(false),
|
||||
HasDynamicAlloca(false), ContainsNoDuplicateCall(false),
|
||||
HasReturn(false), HasIndirectBr(false), HasFrameEscape(false),
|
||||
AllocatedSize(0), NumInstructions(0), NumVectorInstructions(0),
|
||||
FiftyPercentVectorBonus(0), TenPercentVectorBonus(0), VectorBonus(0),
|
||||
NumConstantArgs(0), NumConstantOffsetPtrArgs(0), NumAllocaArgs(0),
|
||||
NumConstantPtrCmps(0), NumConstantPtrDiffs(0),
|
||||
NumInstructionsSimplified(0), SROACostSavings(0),
|
||||
SROACostSavingsLost(0) {}
|
||||
|
||||
bool analyzeCall(CallSite CS);
|
||||
|
||||
@ -962,7 +957,7 @@ bool CallAnalyzer::visitCallSite(CallSite CS) {
|
||||
// out. Pretend to inline the function, with a custom threshold.
|
||||
auto IndirectCallParams = Params;
|
||||
IndirectCallParams.DefaultThreshold = InlineConstants::IndirectCallThreshold;
|
||||
CallAnalyzer CA(TTI, GetAssumptionCache, PSI, *F, CS, IndirectCallParams);
|
||||
CallAnalyzer CA(TTI, PSI, *F, CS, IndirectCallParams);
|
||||
if (CA.analyzeCall(CS)) {
|
||||
// We were able to inline the indirect call! Subtract the cost from the
|
||||
// threshold to get the bonus we want to apply, but don't go below zero.
|
||||
@ -1318,7 +1313,7 @@ bool CallAnalyzer::analyzeCall(CallSite CS) {
|
||||
// the ephemeral values multiple times (and they're completely determined by
|
||||
// the callee, so this is purely duplicate work).
|
||||
SmallPtrSet<const Value *, 32> EphValues;
|
||||
CodeMetrics::collectEphemeralValues(&F, &GetAssumptionCache(F), EphValues);
|
||||
CodeMetrics::collectEphemeralValues(&F, EphValues);
|
||||
|
||||
// The worklist of live basic blocks in the callee *after* inlining. We avoid
|
||||
// adding basic blocks of the callee which can be proven to be dead for this
|
||||
@ -1451,17 +1446,13 @@ static bool functionsHaveCompatibleAttributes(Function *Caller,
|
||||
|
||||
InlineCost llvm::getInlineCost(
|
||||
CallSite CS, const InlineParams &Params, TargetTransformInfo &CalleeTTI,
|
||||
std::function<AssumptionCache &(Function &)> &GetAssumptionCache,
|
||||
ProfileSummaryInfo *PSI) {
|
||||
return getInlineCost(CS, CS.getCalledFunction(), Params, CalleeTTI,
|
||||
GetAssumptionCache, PSI);
|
||||
return getInlineCost(CS, CS.getCalledFunction(), Params, CalleeTTI, PSI);
|
||||
}
|
||||
|
||||
InlineCost llvm::getInlineCost(
|
||||
CallSite CS, Function *Callee, const InlineParams &Params,
|
||||
TargetTransformInfo &CalleeTTI,
|
||||
std::function<AssumptionCache &(Function &)> &GetAssumptionCache,
|
||||
ProfileSummaryInfo *PSI) {
|
||||
TargetTransformInfo &CalleeTTI, ProfileSummaryInfo *PSI) {
|
||||
|
||||
// Cannot inline indirect calls.
|
||||
if (!Callee)
|
||||
@ -1495,7 +1486,7 @@ InlineCost llvm::getInlineCost(
|
||||
DEBUG(llvm::dbgs() << " Analyzing call of " << Callee->getName()
|
||||
<< "...\n");
|
||||
|
||||
CallAnalyzer CA(CalleeTTI, GetAssumptionCache, PSI, *Callee, CS, Params);
|
||||
CallAnalyzer CA(CalleeTTI, PSI, *Callee, CS, Params);
|
||||
bool ShouldInline = CA.analyzeCall(CS);
|
||||
|
||||
DEBUG(CA.dump());
|
||||
|
@ -50,13 +50,11 @@ struct Query {
|
||||
const DataLayout &DL;
|
||||
const TargetLibraryInfo *TLI;
|
||||
const DominatorTree *DT;
|
||||
AssumptionCache *AC;
|
||||
const Instruction *CxtI;
|
||||
|
||||
Query(const DataLayout &DL, const TargetLibraryInfo *tli,
|
||||
const DominatorTree *dt, AssumptionCache *ac = nullptr,
|
||||
const Instruction *cxti = nullptr)
|
||||
: DL(DL), TLI(tli), DT(dt), AC(ac), CxtI(cxti) {}
|
||||
const DominatorTree *dt, const Instruction *cxti = nullptr)
|
||||
: DL(DL), TLI(tli), DT(dt), CxtI(cxti) {}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
@ -584,9 +582,8 @@ static Value *SimplifyAddInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
|
||||
|
||||
Value *llvm::SimplifyAddInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
|
||||
const DataLayout &DL, const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC,
|
||||
const Instruction *CxtI) {
|
||||
return ::SimplifyAddInst(Op0, Op1, isNSW, isNUW, Query(DL, TLI, DT, AC, CxtI),
|
||||
const DominatorTree *DT, const Instruction *CxtI) {
|
||||
return ::SimplifyAddInst(Op0, Op1, isNSW, isNUW, Query(DL, TLI, DT, CxtI),
|
||||
RecursionLimit);
|
||||
}
|
||||
|
||||
@ -691,7 +688,7 @@ static Value *SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
|
||||
unsigned BitWidth = Op1->getType()->getScalarSizeInBits();
|
||||
APInt KnownZero(BitWidth, 0);
|
||||
APInt KnownOne(BitWidth, 0);
|
||||
computeKnownBits(Op1, KnownZero, KnownOne, Q.DL, 0, Q.AC, Q.CxtI, Q.DT);
|
||||
computeKnownBits(Op1, KnownZero, KnownOne, Q.DL, 0, Q.CxtI, Q.DT);
|
||||
if (KnownZero == ~APInt::getSignBit(BitWidth)) {
|
||||
// Op1 is either 0 or the minimum signed value. If the sub is NSW, then
|
||||
// Op1 must be 0 because negating the minimum signed value is undefined.
|
||||
@ -797,9 +794,8 @@ static Value *SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
|
||||
|
||||
Value *llvm::SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
|
||||
const DataLayout &DL, const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC,
|
||||
const Instruction *CxtI) {
|
||||
return ::SimplifySubInst(Op0, Op1, isNSW, isNUW, Query(DL, TLI, DT, AC, CxtI),
|
||||
const DominatorTree *DT, const Instruction *CxtI) {
|
||||
return ::SimplifySubInst(Op0, Op1, isNSW, isNUW, Query(DL, TLI, DT, CxtI),
|
||||
RecursionLimit);
|
||||
}
|
||||
|
||||
@ -966,35 +962,35 @@ static Value *SimplifyMulInst(Value *Op0, Value *Op1, const Query &Q,
|
||||
Value *llvm::SimplifyFAddInst(Value *Op0, Value *Op1, FastMathFlags FMF,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC,
|
||||
const DominatorTree *DT,
|
||||
const Instruction *CxtI) {
|
||||
return ::SimplifyFAddInst(Op0, Op1, FMF, Query(DL, TLI, DT, AC, CxtI),
|
||||
return ::SimplifyFAddInst(Op0, Op1, FMF, Query(DL, TLI, DT, CxtI),
|
||||
RecursionLimit);
|
||||
}
|
||||
|
||||
Value *llvm::SimplifyFSubInst(Value *Op0, Value *Op1, FastMathFlags FMF,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC,
|
||||
const DominatorTree *DT,
|
||||
const Instruction *CxtI) {
|
||||
return ::SimplifyFSubInst(Op0, Op1, FMF, Query(DL, TLI, DT, AC, CxtI),
|
||||
return ::SimplifyFSubInst(Op0, Op1, FMF, Query(DL, TLI, DT, CxtI),
|
||||
RecursionLimit);
|
||||
}
|
||||
|
||||
Value *llvm::SimplifyFMulInst(Value *Op0, Value *Op1, FastMathFlags FMF,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC,
|
||||
const DominatorTree *DT,
|
||||
const Instruction *CxtI) {
|
||||
return ::SimplifyFMulInst(Op0, Op1, FMF, Query(DL, TLI, DT, AC, CxtI),
|
||||
return ::SimplifyFMulInst(Op0, Op1, FMF, Query(DL, TLI, DT, CxtI),
|
||||
RecursionLimit);
|
||||
}
|
||||
|
||||
Value *llvm::SimplifyMulInst(Value *Op0, Value *Op1, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC,
|
||||
const DominatorTree *DT,
|
||||
const Instruction *CxtI) {
|
||||
return ::SimplifyMulInst(Op0, Op1, Query(DL, TLI, DT, AC, CxtI),
|
||||
return ::SimplifyMulInst(Op0, Op1, Query(DL, TLI, DT, CxtI),
|
||||
RecursionLimit);
|
||||
}
|
||||
|
||||
@ -1093,9 +1089,9 @@ static Value *SimplifySDivInst(Value *Op0, Value *Op1, const Query &Q,
|
||||
|
||||
Value *llvm::SimplifySDivInst(Value *Op0, Value *Op1, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC,
|
||||
const DominatorTree *DT,
|
||||
const Instruction *CxtI) {
|
||||
return ::SimplifySDivInst(Op0, Op1, Query(DL, TLI, DT, AC, CxtI),
|
||||
return ::SimplifySDivInst(Op0, Op1, Query(DL, TLI, DT, CxtI),
|
||||
RecursionLimit);
|
||||
}
|
||||
|
||||
@ -1111,9 +1107,9 @@ static Value *SimplifyUDivInst(Value *Op0, Value *Op1, const Query &Q,
|
||||
|
||||
Value *llvm::SimplifyUDivInst(Value *Op0, Value *Op1, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC,
|
||||
const DominatorTree *DT,
|
||||
const Instruction *CxtI) {
|
||||
return ::SimplifyUDivInst(Op0, Op1, Query(DL, TLI, DT, AC, CxtI),
|
||||
return ::SimplifyUDivInst(Op0, Op1, Query(DL, TLI, DT, CxtI),
|
||||
RecursionLimit);
|
||||
}
|
||||
|
||||
@ -1158,9 +1154,9 @@ static Value *SimplifyFDivInst(Value *Op0, Value *Op1, FastMathFlags FMF,
|
||||
Value *llvm::SimplifyFDivInst(Value *Op0, Value *Op1, FastMathFlags FMF,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC,
|
||||
const DominatorTree *DT,
|
||||
const Instruction *CxtI) {
|
||||
return ::SimplifyFDivInst(Op0, Op1, FMF, Query(DL, TLI, DT, AC, CxtI),
|
||||
return ::SimplifyFDivInst(Op0, Op1, FMF, Query(DL, TLI, DT, CxtI),
|
||||
RecursionLimit);
|
||||
}
|
||||
|
||||
@ -1234,9 +1230,9 @@ static Value *SimplifySRemInst(Value *Op0, Value *Op1, const Query &Q,
|
||||
|
||||
Value *llvm::SimplifySRemInst(Value *Op0, Value *Op1, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC,
|
||||
const DominatorTree *DT,
|
||||
const Instruction *CxtI) {
|
||||
return ::SimplifySRemInst(Op0, Op1, Query(DL, TLI, DT, AC, CxtI),
|
||||
return ::SimplifySRemInst(Op0, Op1, Query(DL, TLI, DT, CxtI),
|
||||
RecursionLimit);
|
||||
}
|
||||
|
||||
@ -1252,9 +1248,9 @@ static Value *SimplifyURemInst(Value *Op0, Value *Op1, const Query &Q,
|
||||
|
||||
Value *llvm::SimplifyURemInst(Value *Op0, Value *Op1, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC,
|
||||
const DominatorTree *DT,
|
||||
const Instruction *CxtI) {
|
||||
return ::SimplifyURemInst(Op0, Op1, Query(DL, TLI, DT, AC, CxtI),
|
||||
return ::SimplifyURemInst(Op0, Op1, Query(DL, TLI, DT, CxtI),
|
||||
RecursionLimit);
|
||||
}
|
||||
|
||||
@ -1280,9 +1276,9 @@ static Value *SimplifyFRemInst(Value *Op0, Value *Op1, FastMathFlags FMF,
|
||||
Value *llvm::SimplifyFRemInst(Value *Op0, Value *Op1, FastMathFlags FMF,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC,
|
||||
const DominatorTree *DT,
|
||||
const Instruction *CxtI) {
|
||||
return ::SimplifyFRemInst(Op0, Op1, FMF, Query(DL, TLI, DT, AC, CxtI),
|
||||
return ::SimplifyFRemInst(Op0, Op1, FMF, Query(DL, TLI, DT, CxtI),
|
||||
RecursionLimit);
|
||||
}
|
||||
|
||||
@ -1350,7 +1346,7 @@ static Value *SimplifyShift(unsigned Opcode, Value *Op0, Value *Op1,
|
||||
unsigned BitWidth = Op1->getType()->getScalarSizeInBits();
|
||||
APInt KnownZero(BitWidth, 0);
|
||||
APInt KnownOne(BitWidth, 0);
|
||||
computeKnownBits(Op1, KnownZero, KnownOne, Q.DL, 0, Q.AC, Q.CxtI, Q.DT);
|
||||
computeKnownBits(Op1, KnownZero, KnownOne, Q.DL, 0, Q.CxtI, Q.DT);
|
||||
if (KnownOne.getLimitedValue() >= BitWidth)
|
||||
return UndefValue::get(Op0->getType());
|
||||
|
||||
@ -1386,8 +1382,8 @@ static Value *SimplifyRightShift(unsigned Opcode, Value *Op0, Value *Op1,
|
||||
unsigned BitWidth = Op0->getType()->getScalarSizeInBits();
|
||||
APInt Op0KnownZero(BitWidth, 0);
|
||||
APInt Op0KnownOne(BitWidth, 0);
|
||||
computeKnownBits(Op0, Op0KnownZero, Op0KnownOne, Q.DL, /*Depth=*/0, Q.AC,
|
||||
Q.CxtI, Q.DT);
|
||||
computeKnownBits(Op0, Op0KnownZero, Op0KnownOne, Q.DL, /*Depth=*/0, Q.CxtI,
|
||||
Q.DT);
|
||||
if (Op0KnownOne[0])
|
||||
return Op0;
|
||||
}
|
||||
@ -1416,9 +1412,9 @@ static Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
|
||||
|
||||
Value *llvm::SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
|
||||
const DataLayout &DL, const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC,
|
||||
const DominatorTree *DT,
|
||||
const Instruction *CxtI) {
|
||||
return ::SimplifyShlInst(Op0, Op1, isNSW, isNUW, Query(DL, TLI, DT, AC, CxtI),
|
||||
return ::SimplifyShlInst(Op0, Op1, isNSW, isNUW, Query(DL, TLI, DT, CxtI),
|
||||
RecursionLimit);
|
||||
}
|
||||
|
||||
@ -1441,9 +1437,9 @@ static Value *SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact,
|
||||
Value *llvm::SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC,
|
||||
const DominatorTree *DT,
|
||||
const Instruction *CxtI) {
|
||||
return ::SimplifyLShrInst(Op0, Op1, isExact, Query(DL, TLI, DT, AC, CxtI),
|
||||
return ::SimplifyLShrInst(Op0, Op1, isExact, Query(DL, TLI, DT, CxtI),
|
||||
RecursionLimit);
|
||||
}
|
||||
|
||||
@ -1465,7 +1461,7 @@ static Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact,
|
||||
return X;
|
||||
|
||||
// Arithmetic shifting an all-sign-bit value is a no-op.
|
||||
unsigned NumSignBits = ComputeNumSignBits(Op0, Q.DL, 0, Q.AC, Q.CxtI, Q.DT);
|
||||
unsigned NumSignBits = ComputeNumSignBits(Op0, Q.DL, 0, Q.CxtI, Q.DT);
|
||||
if (NumSignBits == Op0->getType()->getScalarSizeInBits())
|
||||
return Op0;
|
||||
|
||||
@ -1475,9 +1471,9 @@ static Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact,
|
||||
Value *llvm::SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC,
|
||||
const DominatorTree *DT,
|
||||
const Instruction *CxtI) {
|
||||
return ::SimplifyAShrInst(Op0, Op1, isExact, Query(DL, TLI, DT, AC, CxtI),
|
||||
return ::SimplifyAShrInst(Op0, Op1, isExact, Query(DL, TLI, DT, CxtI),
|
||||
RecursionLimit);
|
||||
}
|
||||
|
||||
@ -1659,11 +1655,9 @@ static Value *SimplifyAndInst(Value *Op0, Value *Op1, const Query &Q,
|
||||
// A & (-A) = A if A is a power of two or zero.
|
||||
if (match(Op0, m_Neg(m_Specific(Op1))) ||
|
||||
match(Op1, m_Neg(m_Specific(Op0)))) {
|
||||
if (isKnownToBeAPowerOfTwo(Op0, Q.DL, /*OrZero*/ true, 0, Q.AC, Q.CxtI,
|
||||
Q.DT))
|
||||
if (isKnownToBeAPowerOfTwo(Op0, Q.DL, /*OrZero*/ true, 0, Q.CxtI, Q.DT))
|
||||
return Op0;
|
||||
if (isKnownToBeAPowerOfTwo(Op1, Q.DL, /*OrZero*/ true, 0, Q.AC, Q.CxtI,
|
||||
Q.DT))
|
||||
if (isKnownToBeAPowerOfTwo(Op1, Q.DL, /*OrZero*/ true, 0, Q.CxtI, Q.DT))
|
||||
return Op1;
|
||||
}
|
||||
|
||||
@ -1728,9 +1722,9 @@ static Value *SimplifyAndInst(Value *Op0, Value *Op1, const Query &Q,
|
||||
|
||||
Value *llvm::SimplifyAndInst(Value *Op0, Value *Op1, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC,
|
||||
const DominatorTree *DT,
|
||||
const Instruction *CxtI) {
|
||||
return ::SimplifyAndInst(Op0, Op1, Query(DL, TLI, DT, AC, CxtI),
|
||||
return ::SimplifyAndInst(Op0, Op1, Query(DL, TLI, DT, CxtI),
|
||||
RecursionLimit);
|
||||
}
|
||||
|
||||
@ -1910,10 +1904,10 @@ static Value *SimplifyOrInst(Value *Op0, Value *Op1, const Query &Q,
|
||||
match(A, m_Add(m_Value(V1), m_Value(V2)))) {
|
||||
// Add commutes, try both ways.
|
||||
if (V1 == B &&
|
||||
MaskedValueIsZero(V2, C2->getValue(), Q.DL, 0, Q.AC, Q.CxtI, Q.DT))
|
||||
MaskedValueIsZero(V2, C2->getValue(), Q.DL, 0, Q.CxtI, Q.DT))
|
||||
return A;
|
||||
if (V2 == B &&
|
||||
MaskedValueIsZero(V1, C2->getValue(), Q.DL, 0, Q.AC, Q.CxtI, Q.DT))
|
||||
MaskedValueIsZero(V1, C2->getValue(), Q.DL, 0, Q.CxtI, Q.DT))
|
||||
return A;
|
||||
}
|
||||
// Or commutes, try both ways.
|
||||
@ -1921,10 +1915,10 @@ static Value *SimplifyOrInst(Value *Op0, Value *Op1, const Query &Q,
|
||||
match(B, m_Add(m_Value(V1), m_Value(V2)))) {
|
||||
// Add commutes, try both ways.
|
||||
if (V1 == A &&
|
||||
MaskedValueIsZero(V2, C1->getValue(), Q.DL, 0, Q.AC, Q.CxtI, Q.DT))
|
||||
MaskedValueIsZero(V2, C1->getValue(), Q.DL, 0, Q.CxtI, Q.DT))
|
||||
return B;
|
||||
if (V2 == A &&
|
||||
MaskedValueIsZero(V1, C1->getValue(), Q.DL, 0, Q.AC, Q.CxtI, Q.DT))
|
||||
MaskedValueIsZero(V1, C1->getValue(), Q.DL, 0, Q.CxtI, Q.DT))
|
||||
return B;
|
||||
}
|
||||
}
|
||||
@ -1941,9 +1935,9 @@ static Value *SimplifyOrInst(Value *Op0, Value *Op1, const Query &Q,
|
||||
|
||||
Value *llvm::SimplifyOrInst(Value *Op0, Value *Op1, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC,
|
||||
const DominatorTree *DT,
|
||||
const Instruction *CxtI) {
|
||||
return ::SimplifyOrInst(Op0, Op1, Query(DL, TLI, DT, AC, CxtI),
|
||||
return ::SimplifyOrInst(Op0, Op1, Query(DL, TLI, DT, CxtI),
|
||||
RecursionLimit);
|
||||
}
|
||||
|
||||
@ -1995,9 +1989,9 @@ static Value *SimplifyXorInst(Value *Op0, Value *Op1, const Query &Q,
|
||||
|
||||
Value *llvm::SimplifyXorInst(Value *Op0, Value *Op1, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC,
|
||||
const DominatorTree *DT,
|
||||
const Instruction *CxtI) {
|
||||
return ::SimplifyXorInst(Op0, Op1, Query(DL, TLI, DT, AC, CxtI),
|
||||
return ::SimplifyXorInst(Op0, Op1, Query(DL, TLI, DT, CxtI),
|
||||
RecursionLimit);
|
||||
}
|
||||
|
||||
@ -2312,44 +2306,44 @@ static Value *simplifyICmpWithZero(CmpInst::Predicate Pred, Value *LHS,
|
||||
return getTrue(ITy);
|
||||
case ICmpInst::ICMP_EQ:
|
||||
case ICmpInst::ICMP_ULE:
|
||||
if (isKnownNonZero(LHS, Q.DL, 0, Q.AC, Q.CxtI, Q.DT))
|
||||
if (isKnownNonZero(LHS, Q.DL, 0, Q.CxtI, Q.DT))
|
||||
return getFalse(ITy);
|
||||
break;
|
||||
case ICmpInst::ICMP_NE:
|
||||
case ICmpInst::ICMP_UGT:
|
||||
if (isKnownNonZero(LHS, Q.DL, 0, Q.AC, Q.CxtI, Q.DT))
|
||||
if (isKnownNonZero(LHS, Q.DL, 0, Q.CxtI, Q.DT))
|
||||
return getTrue(ITy);
|
||||
break;
|
||||
case ICmpInst::ICMP_SLT:
|
||||
ComputeSignBit(LHS, LHSKnownNonNegative, LHSKnownNegative, Q.DL, 0, Q.AC,
|
||||
Q.CxtI, Q.DT);
|
||||
ComputeSignBit(LHS, LHSKnownNonNegative, LHSKnownNegative, Q.DL, 0, Q.CxtI,
|
||||
Q.DT);
|
||||
if (LHSKnownNegative)
|
||||
return getTrue(ITy);
|
||||
if (LHSKnownNonNegative)
|
||||
return getFalse(ITy);
|
||||
break;
|
||||
case ICmpInst::ICMP_SLE:
|
||||
ComputeSignBit(LHS, LHSKnownNonNegative, LHSKnownNegative, Q.DL, 0, Q.AC,
|
||||
Q.CxtI, Q.DT);
|
||||
ComputeSignBit(LHS, LHSKnownNonNegative, LHSKnownNegative, Q.DL, 0, Q.CxtI,
|
||||
Q.DT);
|
||||
if (LHSKnownNegative)
|
||||
return getTrue(ITy);
|
||||
if (LHSKnownNonNegative && isKnownNonZero(LHS, Q.DL, 0, Q.AC, Q.CxtI, Q.DT))
|
||||
if (LHSKnownNonNegative && isKnownNonZero(LHS, Q.DL, 0, Q.CxtI, Q.DT))
|
||||
return getFalse(ITy);
|
||||
break;
|
||||
case ICmpInst::ICMP_SGE:
|
||||
ComputeSignBit(LHS, LHSKnownNonNegative, LHSKnownNegative, Q.DL, 0, Q.AC,
|
||||
Q.CxtI, Q.DT);
|
||||
ComputeSignBit(LHS, LHSKnownNonNegative, LHSKnownNegative, Q.DL, 0, Q.CxtI,
|
||||
Q.DT);
|
||||
if (LHSKnownNegative)
|
||||
return getFalse(ITy);
|
||||
if (LHSKnownNonNegative)
|
||||
return getTrue(ITy);
|
||||
break;
|
||||
case ICmpInst::ICMP_SGT:
|
||||
ComputeSignBit(LHS, LHSKnownNonNegative, LHSKnownNegative, Q.DL, 0, Q.AC,
|
||||
Q.CxtI, Q.DT);
|
||||
ComputeSignBit(LHS, LHSKnownNonNegative, LHSKnownNegative, Q.DL, 0, Q.CxtI,
|
||||
Q.DT);
|
||||
if (LHSKnownNegative)
|
||||
return getFalse(ITy);
|
||||
if (LHSKnownNonNegative && isKnownNonZero(LHS, Q.DL, 0, Q.AC, Q.CxtI, Q.DT))
|
||||
if (LHSKnownNonNegative && isKnownNonZero(LHS, Q.DL, 0, Q.CxtI, Q.DT))
|
||||
return getTrue(ITy);
|
||||
break;
|
||||
}
|
||||
@ -2580,9 +2574,9 @@ static Value *simplifyICmpWithBinOp(CmpInst::Predicate Pred, Value *LHS,
|
||||
bool RHSKnownNonNegative, RHSKnownNegative;
|
||||
bool YKnownNonNegative, YKnownNegative;
|
||||
ComputeSignBit(RHS, RHSKnownNonNegative, RHSKnownNegative, Q.DL, 0,
|
||||
Q.AC, Q.CxtI, Q.DT);
|
||||
ComputeSignBit(Y, YKnownNonNegative, YKnownNegative, Q.DL, 0, Q.AC,
|
||||
Q.CxtI, Q.DT);
|
||||
ComputeSignBit(Y, YKnownNonNegative, YKnownNegative, Q.DL, 0, Q.CxtI,
|
||||
Q.DT);
|
||||
if (RHSKnownNonNegative && YKnownNegative)
|
||||
return Pred == ICmpInst::ICMP_SLT ? getTrue(ITy) : getFalse(ITy);
|
||||
if (RHSKnownNegative || YKnownNonNegative)
|
||||
@ -2600,9 +2594,9 @@ static Value *simplifyICmpWithBinOp(CmpInst::Predicate Pred, Value *LHS,
|
||||
bool LHSKnownNonNegative, LHSKnownNegative;
|
||||
bool YKnownNonNegative, YKnownNegative;
|
||||
ComputeSignBit(LHS, LHSKnownNonNegative, LHSKnownNegative, Q.DL, 0,
|
||||
Q.AC, Q.CxtI, Q.DT);
|
||||
ComputeSignBit(Y, YKnownNonNegative, YKnownNegative, Q.DL, 0, Q.AC,
|
||||
Q.CxtI, Q.DT);
|
||||
ComputeSignBit(Y, YKnownNonNegative, YKnownNegative, Q.DL, 0, Q.CxtI,
|
||||
Q.DT);
|
||||
if (LHSKnownNonNegative && YKnownNegative)
|
||||
return Pred == ICmpInst::ICMP_SGT ? getTrue(ITy) : getFalse(ITy);
|
||||
if (LHSKnownNegative || YKnownNonNegative)
|
||||
@ -2658,8 +2652,8 @@ static Value *simplifyICmpWithBinOp(CmpInst::Predicate Pred, Value *LHS,
|
||||
break;
|
||||
case ICmpInst::ICMP_SGT:
|
||||
case ICmpInst::ICMP_SGE:
|
||||
ComputeSignBit(RHS, KnownNonNegative, KnownNegative, Q.DL, 0, Q.AC,
|
||||
Q.CxtI, Q.DT);
|
||||
ComputeSignBit(RHS, KnownNonNegative, KnownNegative, Q.DL, 0, Q.CxtI,
|
||||
Q.DT);
|
||||
if (!KnownNonNegative)
|
||||
break;
|
||||
LLVM_FALLTHROUGH;
|
||||
@ -2669,8 +2663,8 @@ static Value *simplifyICmpWithBinOp(CmpInst::Predicate Pred, Value *LHS,
|
||||
return getFalse(ITy);
|
||||
case ICmpInst::ICMP_SLT:
|
||||
case ICmpInst::ICMP_SLE:
|
||||
ComputeSignBit(RHS, KnownNonNegative, KnownNegative, Q.DL, 0, Q.AC,
|
||||
Q.CxtI, Q.DT);
|
||||
ComputeSignBit(RHS, KnownNonNegative, KnownNegative, Q.DL, 0, Q.CxtI,
|
||||
Q.DT);
|
||||
if (!KnownNonNegative)
|
||||
break;
|
||||
LLVM_FALLTHROUGH;
|
||||
@ -2689,8 +2683,8 @@ static Value *simplifyICmpWithBinOp(CmpInst::Predicate Pred, Value *LHS,
|
||||
break;
|
||||
case ICmpInst::ICMP_SGT:
|
||||
case ICmpInst::ICMP_SGE:
|
||||
ComputeSignBit(LHS, KnownNonNegative, KnownNegative, Q.DL, 0, Q.AC,
|
||||
Q.CxtI, Q.DT);
|
||||
ComputeSignBit(LHS, KnownNonNegative, KnownNegative, Q.DL, 0, Q.CxtI,
|
||||
Q.DT);
|
||||
if (!KnownNonNegative)
|
||||
break;
|
||||
LLVM_FALLTHROUGH;
|
||||
@ -2700,8 +2694,8 @@ static Value *simplifyICmpWithBinOp(CmpInst::Predicate Pred, Value *LHS,
|
||||
return getTrue(ITy);
|
||||
case ICmpInst::ICMP_SLT:
|
||||
case ICmpInst::ICMP_SLE:
|
||||
ComputeSignBit(LHS, KnownNonNegative, KnownNegative, Q.DL, 0, Q.AC,
|
||||
Q.CxtI, Q.DT);
|
||||
ComputeSignBit(LHS, KnownNonNegative, KnownNegative, Q.DL, 0, Q.CxtI,
|
||||
Q.DT);
|
||||
if (!KnownNonNegative)
|
||||
break;
|
||||
LLVM_FALLTHROUGH;
|
||||
@ -3226,7 +3220,7 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||
|
||||
// icmp eq|ne X, Y -> false|true if X != Y
|
||||
if ((Pred == ICmpInst::ICMP_EQ || Pred == ICmpInst::ICMP_NE) &&
|
||||
isKnownNonEqual(LHS, RHS, Q.DL, Q.AC, Q.CxtI, Q.DT)) {
|
||||
isKnownNonEqual(LHS, RHS, Q.DL, Q.CxtI, Q.DT)) {
|
||||
LLVMContext &Ctx = LHS->getType()->getContext();
|
||||
return Pred == ICmpInst::ICMP_NE ?
|
||||
ConstantInt::getTrue(Ctx) : ConstantInt::getFalse(Ctx);
|
||||
@ -3285,7 +3279,7 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||
unsigned BitWidth = RHSVal->getBitWidth();
|
||||
APInt LHSKnownZero(BitWidth, 0);
|
||||
APInt LHSKnownOne(BitWidth, 0);
|
||||
computeKnownBits(LHS, LHSKnownZero, LHSKnownOne, Q.DL, /*Depth=*/0, Q.AC,
|
||||
computeKnownBits(LHS, LHSKnownZero, LHSKnownOne, Q.DL, /*Depth=*/0,
|
||||
Q.CxtI, Q.DT);
|
||||
if (((LHSKnownZero & *RHSVal) != 0) || ((LHSKnownOne & ~(*RHSVal)) != 0))
|
||||
return Pred == ICmpInst::ICMP_EQ ? ConstantInt::getFalse(ITy)
|
||||
@ -3311,9 +3305,9 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||
Value *llvm::SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC,
|
||||
const DominatorTree *DT,
|
||||
const Instruction *CxtI) {
|
||||
return ::SimplifyICmpInst(Predicate, LHS, RHS, Query(DL, TLI, DT, AC, CxtI),
|
||||
return ::SimplifyICmpInst(Predicate, LHS, RHS, Query(DL, TLI, DT, CxtI),
|
||||
RecursionLimit);
|
||||
}
|
||||
|
||||
@ -3444,10 +3438,10 @@ static Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||
Value *llvm::SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||
FastMathFlags FMF, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC,
|
||||
const DominatorTree *DT,
|
||||
const Instruction *CxtI) {
|
||||
return ::SimplifyFCmpInst(Predicate, LHS, RHS, FMF,
|
||||
Query(DL, TLI, DT, AC, CxtI), RecursionLimit);
|
||||
Query(DL, TLI, DT, CxtI), RecursionLimit);
|
||||
}
|
||||
|
||||
/// See if V simplifies when its operand Op is replaced with RepOp.
|
||||
@ -3714,10 +3708,10 @@ static Value *SimplifySelectInst(Value *CondVal, Value *TrueVal,
|
||||
Value *llvm::SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC,
|
||||
const DominatorTree *DT,
|
||||
const Instruction *CxtI) {
|
||||
return ::SimplifySelectInst(Cond, TrueVal, FalseVal,
|
||||
Query(DL, TLI, DT, AC, CxtI), RecursionLimit);
|
||||
Query(DL, TLI, DT, CxtI), RecursionLimit);
|
||||
}
|
||||
|
||||
/// Given operands for an GetElementPtrInst, see if we can fold the result.
|
||||
@ -3833,10 +3827,10 @@ static Value *SimplifyGEPInst(Type *SrcTy, ArrayRef<Value *> Ops,
|
||||
Value *llvm::SimplifyGEPInst(Type *SrcTy, ArrayRef<Value *> Ops,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC,
|
||||
const DominatorTree *DT,
|
||||
const Instruction *CxtI) {
|
||||
return ::SimplifyGEPInst(SrcTy, Ops,
|
||||
Query(DL, TLI, DT, AC, CxtI), RecursionLimit);
|
||||
Query(DL, TLI, DT, CxtI), RecursionLimit);
|
||||
}
|
||||
|
||||
/// Given operands for an InsertValueInst, see if we can fold the result.
|
||||
@ -3870,9 +3864,9 @@ static Value *SimplifyInsertValueInst(Value *Agg, Value *Val,
|
||||
|
||||
Value *llvm::SimplifyInsertValueInst(
|
||||
Value *Agg, Value *Val, ArrayRef<unsigned> Idxs, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI, const DominatorTree *DT, AssumptionCache *AC,
|
||||
const TargetLibraryInfo *TLI, const DominatorTree *DT,
|
||||
const Instruction *CxtI) {
|
||||
return ::SimplifyInsertValueInst(Agg, Val, Idxs, Query(DL, TLI, DT, AC, CxtI),
|
||||
return ::SimplifyInsertValueInst(Agg, Val, Idxs, Query(DL, TLI, DT, CxtI),
|
||||
RecursionLimit);
|
||||
}
|
||||
|
||||
@ -3905,9 +3899,8 @@ Value *llvm::SimplifyExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT,
|
||||
AssumptionCache *AC,
|
||||
const Instruction *CxtI) {
|
||||
return ::SimplifyExtractValueInst(Agg, Idxs, Query(DL, TLI, DT, AC, CxtI),
|
||||
return ::SimplifyExtractValueInst(Agg, Idxs, Query(DL, TLI, DT, CxtI),
|
||||
RecursionLimit);
|
||||
}
|
||||
|
||||
@ -3938,8 +3931,8 @@ static Value *SimplifyExtractElementInst(Value *Vec, Value *Idx, const Query &,
|
||||
|
||||
Value *llvm::SimplifyExtractElementInst(
|
||||
Value *Vec, Value *Idx, const DataLayout &DL, const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC, const Instruction *CxtI) {
|
||||
return ::SimplifyExtractElementInst(Vec, Idx, Query(DL, TLI, DT, AC, CxtI),
|
||||
const DominatorTree *DT, const Instruction *CxtI) {
|
||||
return ::SimplifyExtractElementInst(Vec, Idx, Query(DL, TLI, DT, CxtI),
|
||||
RecursionLimit);
|
||||
}
|
||||
|
||||
@ -4013,9 +4006,9 @@ static Value *SimplifyCastInst(unsigned CastOpc, Value *Op,
|
||||
Value *llvm::SimplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC,
|
||||
const DominatorTree *DT,
|
||||
const Instruction *CxtI) {
|
||||
return ::SimplifyCastInst(CastOpc, Op, Ty, Query(DL, TLI, DT, AC, CxtI),
|
||||
return ::SimplifyCastInst(CastOpc, Op, Ty, Query(DL, TLI, DT, CxtI),
|
||||
RecursionLimit);
|
||||
}
|
||||
|
||||
@ -4108,18 +4101,18 @@ static Value *SimplifyFPBinOp(unsigned Opcode, Value *LHS, Value *RHS,
|
||||
|
||||
Value *llvm::SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
|
||||
const DataLayout &DL, const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC,
|
||||
const DominatorTree *DT,
|
||||
const Instruction *CxtI) {
|
||||
return ::SimplifyBinOp(Opcode, LHS, RHS, Query(DL, TLI, DT, AC, CxtI),
|
||||
return ::SimplifyBinOp(Opcode, LHS, RHS, Query(DL, TLI, DT, CxtI),
|
||||
RecursionLimit);
|
||||
}
|
||||
|
||||
Value *llvm::SimplifyFPBinOp(unsigned Opcode, Value *LHS, Value *RHS,
|
||||
const FastMathFlags &FMF, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC,
|
||||
const DominatorTree *DT,
|
||||
const Instruction *CxtI) {
|
||||
return ::SimplifyFPBinOp(Opcode, LHS, RHS, FMF, Query(DL, TLI, DT, AC, CxtI),
|
||||
return ::SimplifyFPBinOp(Opcode, LHS, RHS, FMF, Query(DL, TLI, DT, CxtI),
|
||||
RecursionLimit);
|
||||
}
|
||||
|
||||
@ -4133,9 +4126,9 @@ static Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||
|
||||
Value *llvm::SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||
const DataLayout &DL, const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC,
|
||||
const DominatorTree *DT,
|
||||
const Instruction *CxtI) {
|
||||
return ::SimplifyCmpInst(Predicate, LHS, RHS, Query(DL, TLI, DT, AC, CxtI),
|
||||
return ::SimplifyCmpInst(Predicate, LHS, RHS, Query(DL, TLI, DT, CxtI),
|
||||
RecursionLimit);
|
||||
}
|
||||
|
||||
@ -4335,24 +4328,24 @@ static Value *SimplifyCall(Value *V, IterTy ArgBegin, IterTy ArgEnd,
|
||||
Value *llvm::SimplifyCall(Value *V, User::op_iterator ArgBegin,
|
||||
User::op_iterator ArgEnd, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI, const DominatorTree *DT,
|
||||
AssumptionCache *AC, const Instruction *CxtI) {
|
||||
return ::SimplifyCall(V, ArgBegin, ArgEnd, Query(DL, TLI, DT, AC, CxtI),
|
||||
const Instruction *CxtI) {
|
||||
return ::SimplifyCall(V, ArgBegin, ArgEnd, Query(DL, TLI, DT, CxtI),
|
||||
RecursionLimit);
|
||||
}
|
||||
|
||||
Value *llvm::SimplifyCall(Value *V, ArrayRef<Value *> Args,
|
||||
const DataLayout &DL, const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC,
|
||||
const DominatorTree *DT,
|
||||
const Instruction *CxtI) {
|
||||
return ::SimplifyCall(V, Args.begin(), Args.end(),
|
||||
Query(DL, TLI, DT, AC, CxtI), RecursionLimit);
|
||||
Query(DL, TLI, DT, CxtI), RecursionLimit);
|
||||
}
|
||||
|
||||
/// See if we can compute a simplified version of this instruction.
|
||||
/// If not, this returns null.
|
||||
Value *llvm::SimplifyInstruction(Instruction *I, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC) {
|
||||
const DominatorTree *DT) {
|
||||
Value *Result;
|
||||
|
||||
switch (I->getOpcode()) {
|
||||
@ -4361,137 +4354,137 @@ Value *llvm::SimplifyInstruction(Instruction *I, const DataLayout &DL,
|
||||
break;
|
||||
case Instruction::FAdd:
|
||||
Result = SimplifyFAddInst(I->getOperand(0), I->getOperand(1),
|
||||
I->getFastMathFlags(), DL, TLI, DT, AC, I);
|
||||
I->getFastMathFlags(), DL, TLI, DT, I);
|
||||
break;
|
||||
case Instruction::Add:
|
||||
Result = SimplifyAddInst(I->getOperand(0), I->getOperand(1),
|
||||
cast<BinaryOperator>(I)->hasNoSignedWrap(),
|
||||
cast<BinaryOperator>(I)->hasNoUnsignedWrap(), DL,
|
||||
TLI, DT, AC, I);
|
||||
TLI, DT, I);
|
||||
break;
|
||||
case Instruction::FSub:
|
||||
Result = SimplifyFSubInst(I->getOperand(0), I->getOperand(1),
|
||||
I->getFastMathFlags(), DL, TLI, DT, AC, I);
|
||||
I->getFastMathFlags(), DL, TLI, DT, I);
|
||||
break;
|
||||
case Instruction::Sub:
|
||||
Result = SimplifySubInst(I->getOperand(0), I->getOperand(1),
|
||||
cast<BinaryOperator>(I)->hasNoSignedWrap(),
|
||||
cast<BinaryOperator>(I)->hasNoUnsignedWrap(), DL,
|
||||
TLI, DT, AC, I);
|
||||
TLI, DT, I);
|
||||
break;
|
||||
case Instruction::FMul:
|
||||
Result = SimplifyFMulInst(I->getOperand(0), I->getOperand(1),
|
||||
I->getFastMathFlags(), DL, TLI, DT, AC, I);
|
||||
I->getFastMathFlags(), DL, TLI, DT, I);
|
||||
break;
|
||||
case Instruction::Mul:
|
||||
Result =
|
||||
SimplifyMulInst(I->getOperand(0), I->getOperand(1), DL, TLI, DT, AC, I);
|
||||
SimplifyMulInst(I->getOperand(0), I->getOperand(1), DL, TLI, DT, I);
|
||||
break;
|
||||
case Instruction::SDiv:
|
||||
Result = SimplifySDivInst(I->getOperand(0), I->getOperand(1), DL, TLI, DT,
|
||||
AC, I);
|
||||
I);
|
||||
break;
|
||||
case Instruction::UDiv:
|
||||
Result = SimplifyUDivInst(I->getOperand(0), I->getOperand(1), DL, TLI, DT,
|
||||
AC, I);
|
||||
I);
|
||||
break;
|
||||
case Instruction::FDiv:
|
||||
Result = SimplifyFDivInst(I->getOperand(0), I->getOperand(1),
|
||||
I->getFastMathFlags(), DL, TLI, DT, AC, I);
|
||||
I->getFastMathFlags(), DL, TLI, DT, I);
|
||||
break;
|
||||
case Instruction::SRem:
|
||||
Result = SimplifySRemInst(I->getOperand(0), I->getOperand(1), DL, TLI, DT,
|
||||
AC, I);
|
||||
I);
|
||||
break;
|
||||
case Instruction::URem:
|
||||
Result = SimplifyURemInst(I->getOperand(0), I->getOperand(1), DL, TLI, DT,
|
||||
AC, I);
|
||||
I);
|
||||
break;
|
||||
case Instruction::FRem:
|
||||
Result = SimplifyFRemInst(I->getOperand(0), I->getOperand(1),
|
||||
I->getFastMathFlags(), DL, TLI, DT, AC, I);
|
||||
I->getFastMathFlags(), DL, TLI, DT, I);
|
||||
break;
|
||||
case Instruction::Shl:
|
||||
Result = SimplifyShlInst(I->getOperand(0), I->getOperand(1),
|
||||
cast<BinaryOperator>(I)->hasNoSignedWrap(),
|
||||
cast<BinaryOperator>(I)->hasNoUnsignedWrap(), DL,
|
||||
TLI, DT, AC, I);
|
||||
TLI, DT, I);
|
||||
break;
|
||||
case Instruction::LShr:
|
||||
Result = SimplifyLShrInst(I->getOperand(0), I->getOperand(1),
|
||||
cast<BinaryOperator>(I)->isExact(), DL, TLI, DT,
|
||||
AC, I);
|
||||
I);
|
||||
break;
|
||||
case Instruction::AShr:
|
||||
Result = SimplifyAShrInst(I->getOperand(0), I->getOperand(1),
|
||||
cast<BinaryOperator>(I)->isExact(), DL, TLI, DT,
|
||||
AC, I);
|
||||
I);
|
||||
break;
|
||||
case Instruction::And:
|
||||
Result =
|
||||
SimplifyAndInst(I->getOperand(0), I->getOperand(1), DL, TLI, DT, AC, I);
|
||||
SimplifyAndInst(I->getOperand(0), I->getOperand(1), DL, TLI, DT, I);
|
||||
break;
|
||||
case Instruction::Or:
|
||||
Result =
|
||||
SimplifyOrInst(I->getOperand(0), I->getOperand(1), DL, TLI, DT, AC, I);
|
||||
SimplifyOrInst(I->getOperand(0), I->getOperand(1), DL, TLI, DT, I);
|
||||
break;
|
||||
case Instruction::Xor:
|
||||
Result =
|
||||
SimplifyXorInst(I->getOperand(0), I->getOperand(1), DL, TLI, DT, AC, I);
|
||||
SimplifyXorInst(I->getOperand(0), I->getOperand(1), DL, TLI, DT, I);
|
||||
break;
|
||||
case Instruction::ICmp:
|
||||
Result =
|
||||
SimplifyICmpInst(cast<ICmpInst>(I)->getPredicate(), I->getOperand(0),
|
||||
I->getOperand(1), DL, TLI, DT, AC, I);
|
||||
I->getOperand(1), DL, TLI, DT, I);
|
||||
break;
|
||||
case Instruction::FCmp:
|
||||
Result = SimplifyFCmpInst(cast<FCmpInst>(I)->getPredicate(),
|
||||
I->getOperand(0), I->getOperand(1),
|
||||
I->getFastMathFlags(), DL, TLI, DT, AC, I);
|
||||
I->getFastMathFlags(), DL, TLI, DT, I);
|
||||
break;
|
||||
case Instruction::Select:
|
||||
Result = SimplifySelectInst(I->getOperand(0), I->getOperand(1),
|
||||
I->getOperand(2), DL, TLI, DT, AC, I);
|
||||
I->getOperand(2), DL, TLI, DT, I);
|
||||
break;
|
||||
case Instruction::GetElementPtr: {
|
||||
SmallVector<Value*, 8> Ops(I->op_begin(), I->op_end());
|
||||
Result = SimplifyGEPInst(cast<GetElementPtrInst>(I)->getSourceElementType(),
|
||||
Ops, DL, TLI, DT, AC, I);
|
||||
Ops, DL, TLI, DT, I);
|
||||
break;
|
||||
}
|
||||
case Instruction::InsertValue: {
|
||||
InsertValueInst *IV = cast<InsertValueInst>(I);
|
||||
Result = SimplifyInsertValueInst(IV->getAggregateOperand(),
|
||||
IV->getInsertedValueOperand(),
|
||||
IV->getIndices(), DL, TLI, DT, AC, I);
|
||||
IV->getIndices(), DL, TLI, DT, I);
|
||||
break;
|
||||
}
|
||||
case Instruction::ExtractValue: {
|
||||
auto *EVI = cast<ExtractValueInst>(I);
|
||||
Result = SimplifyExtractValueInst(EVI->getAggregateOperand(),
|
||||
EVI->getIndices(), DL, TLI, DT, AC, I);
|
||||
EVI->getIndices(), DL, TLI, DT, I);
|
||||
break;
|
||||
}
|
||||
case Instruction::ExtractElement: {
|
||||
auto *EEI = cast<ExtractElementInst>(I);
|
||||
Result = SimplifyExtractElementInst(
|
||||
EEI->getVectorOperand(), EEI->getIndexOperand(), DL, TLI, DT, AC, I);
|
||||
EEI->getVectorOperand(), EEI->getIndexOperand(), DL, TLI, DT, I);
|
||||
break;
|
||||
}
|
||||
case Instruction::PHI:
|
||||
Result = SimplifyPHINode(cast<PHINode>(I), Query(DL, TLI, DT, AC, I));
|
||||
Result = SimplifyPHINode(cast<PHINode>(I), Query(DL, TLI, DT, I));
|
||||
break;
|
||||
case Instruction::Call: {
|
||||
CallSite CS(cast<CallInst>(I));
|
||||
Result = SimplifyCall(CS.getCalledValue(), CS.arg_begin(), CS.arg_end(), DL,
|
||||
TLI, DT, AC, I);
|
||||
TLI, DT, I);
|
||||
break;
|
||||
}
|
||||
#define HANDLE_CAST_INST(num, opc, clas) case Instruction::opc:
|
||||
#include "llvm/IR/Instruction.def"
|
||||
#undef HANDLE_CAST_INST
|
||||
Result = SimplifyCastInst(I->getOpcode(), I->getOperand(0), I->getType(),
|
||||
DL, TLI, DT, AC, I);
|
||||
DL, TLI, DT, I);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4501,7 +4494,7 @@ Value *llvm::SimplifyInstruction(Instruction *I, const DataLayout &DL,
|
||||
unsigned BitWidth = I->getType()->getScalarSizeInBits();
|
||||
APInt KnownZero(BitWidth, 0);
|
||||
APInt KnownOne(BitWidth, 0);
|
||||
computeKnownBits(I, KnownZero, KnownOne, DL, /*Depth*/0, AC, I, DT);
|
||||
computeKnownBits(I, KnownZero, KnownOne, DL, /*Depth*/0, I, DT);
|
||||
if ((KnownZero | KnownOne).isAllOnesValue())
|
||||
Result = ConstantInt::get(I->getType(), KnownOne);
|
||||
}
|
||||
@ -4525,8 +4518,7 @@ Value *llvm::SimplifyInstruction(Instruction *I, const DataLayout &DL,
|
||||
/// in simplified value does not count toward this.
|
||||
static bool replaceAndRecursivelySimplifyImpl(Instruction *I, Value *SimpleV,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT,
|
||||
AssumptionCache *AC) {
|
||||
const DominatorTree *DT) {
|
||||
bool Simplified = false;
|
||||
SmallSetVector<Instruction *, 8> Worklist;
|
||||
const DataLayout &DL = I->getModule()->getDataLayout();
|
||||
@ -4555,7 +4547,7 @@ static bool replaceAndRecursivelySimplifyImpl(Instruction *I, Value *SimpleV,
|
||||
I = Worklist[Idx];
|
||||
|
||||
// See if this instruction simplifies.
|
||||
SimpleV = SimplifyInstruction(I, DL, TLI, DT, AC);
|
||||
SimpleV = SimplifyInstruction(I, DL, TLI, DT);
|
||||
if (!SimpleV)
|
||||
continue;
|
||||
|
||||
@ -4581,16 +4573,14 @@ static bool replaceAndRecursivelySimplifyImpl(Instruction *I, Value *SimpleV,
|
||||
|
||||
bool llvm::recursivelySimplifyInstruction(Instruction *I,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT,
|
||||
AssumptionCache *AC) {
|
||||
return replaceAndRecursivelySimplifyImpl(I, nullptr, TLI, DT, AC);
|
||||
const DominatorTree *DT) {
|
||||
return replaceAndRecursivelySimplifyImpl(I, nullptr, TLI, DT);
|
||||
}
|
||||
|
||||
bool llvm::replaceAndRecursivelySimplify(Instruction *I, Value *SimpleV,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT,
|
||||
AssumptionCache *AC) {
|
||||
const DominatorTree *DT) {
|
||||
assert(I != SimpleV && "replaceAndRecursivelySimplify(X,X) is not valid!");
|
||||
assert(SimpleV && "Must provide a simplified value.");
|
||||
return replaceAndRecursivelySimplifyImpl(I, SimpleV, TLI, DT, AC);
|
||||
return replaceAndRecursivelySimplifyImpl(I, SimpleV, TLI, DT);
|
||||
}
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include "llvm/Analysis/LazyValueInfo.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/ConstantFolding.h"
|
||||
#include "llvm/Analysis/TargetLibraryInfo.h"
|
||||
#include "llvm/Analysis/ValueTracking.h"
|
||||
@ -42,7 +41,6 @@ using namespace PatternMatch;
|
||||
char LazyValueInfoWrapperPass::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(LazyValueInfoWrapperPass, "lazy-value-info",
|
||||
"Lazy Value Information Analysis", false, true)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
|
||||
INITIALIZE_PASS_END(LazyValueInfoWrapperPass, "lazy-value-info",
|
||||
"Lazy Value Information Analysis", false, true)
|
||||
@ -579,7 +577,6 @@ namespace {
|
||||
return true;
|
||||
}
|
||||
|
||||
AssumptionCache *AC; ///< A pointer to the cache of @llvm.assume calls.
|
||||
const DataLayout &DL; ///< A mandatory DataLayout
|
||||
DominatorTree *DT; ///< An optional DT pointer.
|
||||
|
||||
@ -638,9 +635,8 @@ namespace {
|
||||
/// PredBB to OldSucc has been threaded to be from PredBB to NewSucc.
|
||||
void threadEdge(BasicBlock *PredBB,BasicBlock *OldSucc,BasicBlock *NewSucc);
|
||||
|
||||
LazyValueInfoImpl(AssumptionCache *AC, const DataLayout &DL,
|
||||
DominatorTree *DT = nullptr)
|
||||
: AC(AC), DL(DL), DT(DT) {}
|
||||
LazyValueInfoImpl(const DataLayout &DL, DominatorTree *DT = nullptr)
|
||||
: DL(DL), DT(DT) {}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
@ -1460,18 +1456,16 @@ void LazyValueInfoImpl::threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc,
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// This lazily constructs the LazyValueInfoImpl.
|
||||
static LazyValueInfoImpl &getImpl(void *&PImpl, AssumptionCache *AC,
|
||||
const DataLayout *DL,
|
||||
static LazyValueInfoImpl &getImpl(void *&PImpl, const DataLayout *DL,
|
||||
DominatorTree *DT = nullptr) {
|
||||
if (!PImpl) {
|
||||
assert(DL && "getCache() called with a null DataLayout");
|
||||
PImpl = new LazyValueInfoImpl(AC, *DL, DT);
|
||||
PImpl = new LazyValueInfoImpl(*DL, DT);
|
||||
}
|
||||
return *static_cast<LazyValueInfoImpl*>(PImpl);
|
||||
}
|
||||
|
||||
bool LazyValueInfoWrapperPass::runOnFunction(Function &F) {
|
||||
Info.AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
|
||||
const DataLayout &DL = F.getParent()->getDataLayout();
|
||||
|
||||
DominatorTreeWrapperPass *DTWP =
|
||||
@ -1480,7 +1474,7 @@ bool LazyValueInfoWrapperPass::runOnFunction(Function &F) {
|
||||
Info.TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
|
||||
|
||||
if (Info.PImpl)
|
||||
getImpl(Info.PImpl, Info.AC, &DL, Info.DT).clear();
|
||||
getImpl(Info.PImpl, &DL, Info.DT).clear();
|
||||
|
||||
// Fully lazy.
|
||||
return false;
|
||||
@ -1488,7 +1482,6 @@ bool LazyValueInfoWrapperPass::runOnFunction(Function &F) {
|
||||
|
||||
void LazyValueInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.setPreservesAll();
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
AU.addRequired<TargetLibraryInfoWrapperPass>();
|
||||
}
|
||||
|
||||
@ -1499,7 +1492,7 @@ LazyValueInfo::~LazyValueInfo() { releaseMemory(); }
|
||||
void LazyValueInfo::releaseMemory() {
|
||||
// If the cache was allocated, free it.
|
||||
if (PImpl) {
|
||||
delete &getImpl(PImpl, AC, nullptr);
|
||||
delete &getImpl(PImpl, nullptr);
|
||||
PImpl = nullptr;
|
||||
}
|
||||
}
|
||||
@ -1507,11 +1500,10 @@ void LazyValueInfo::releaseMemory() {
|
||||
void LazyValueInfoWrapperPass::releaseMemory() { Info.releaseMemory(); }
|
||||
|
||||
LazyValueInfo LazyValueAnalysis::run(Function &F, FunctionAnalysisManager &FAM) {
|
||||
auto &AC = FAM.getResult<AssumptionAnalysis>(F);
|
||||
auto &TLI = FAM.getResult<TargetLibraryAnalysis>(F);
|
||||
auto *DT = FAM.getCachedResult<DominatorTreeAnalysis>(F);
|
||||
|
||||
return LazyValueInfo(&AC, &TLI, DT);
|
||||
return LazyValueInfo(&TLI, DT);
|
||||
}
|
||||
|
||||
/// Returns true if we can statically tell that this value will never be a
|
||||
@ -1536,7 +1528,7 @@ Constant *LazyValueInfo::getConstant(Value *V, BasicBlock *BB,
|
||||
|
||||
const DataLayout &DL = BB->getModule()->getDataLayout();
|
||||
LVILatticeVal Result =
|
||||
getImpl(PImpl, AC, &DL, DT).getValueInBlock(V, BB, CxtI);
|
||||
getImpl(PImpl, &DL, DT).getValueInBlock(V, BB, CxtI);
|
||||
|
||||
if (Result.isConstant())
|
||||
return Result.getConstant();
|
||||
@ -1554,7 +1546,7 @@ ConstantRange LazyValueInfo::getConstantRange(Value *V, BasicBlock *BB,
|
||||
unsigned Width = V->getType()->getIntegerBitWidth();
|
||||
const DataLayout &DL = BB->getModule()->getDataLayout();
|
||||
LVILatticeVal Result =
|
||||
getImpl(PImpl, AC, &DL, DT).getValueInBlock(V, BB, CxtI);
|
||||
getImpl(PImpl, &DL, DT).getValueInBlock(V, BB, CxtI);
|
||||
if (Result.isUndefined())
|
||||
return ConstantRange(Width, /*isFullSet=*/false);
|
||||
if (Result.isConstantRange())
|
||||
@ -1573,7 +1565,7 @@ Constant *LazyValueInfo::getConstantOnEdge(Value *V, BasicBlock *FromBB,
|
||||
Instruction *CxtI) {
|
||||
const DataLayout &DL = FromBB->getModule()->getDataLayout();
|
||||
LVILatticeVal Result =
|
||||
getImpl(PImpl, AC, &DL, DT).getValueOnEdge(V, FromBB, ToBB, CxtI);
|
||||
getImpl(PImpl, &DL, DT).getValueOnEdge(V, FromBB, ToBB, CxtI);
|
||||
|
||||
if (Result.isConstant())
|
||||
return Result.getConstant();
|
||||
@ -1661,7 +1653,7 @@ LazyValueInfo::getPredicateOnEdge(unsigned Pred, Value *V, Constant *C,
|
||||
Instruction *CxtI) {
|
||||
const DataLayout &DL = FromBB->getModule()->getDataLayout();
|
||||
LVILatticeVal Result =
|
||||
getImpl(PImpl, AC, &DL, DT).getValueOnEdge(V, FromBB, ToBB, CxtI);
|
||||
getImpl(PImpl, &DL, DT).getValueOnEdge(V, FromBB, ToBB, CxtI);
|
||||
|
||||
return getPredicateResult(Pred, C, Result, DL, TLI);
|
||||
}
|
||||
@ -1681,7 +1673,7 @@ LazyValueInfo::getPredicateAt(unsigned Pred, Value *V, Constant *C,
|
||||
return LazyValueInfo::True;
|
||||
}
|
||||
const DataLayout &DL = CxtI->getModule()->getDataLayout();
|
||||
LVILatticeVal Result = getImpl(PImpl, AC, &DL, DT).getValueAt(V, CxtI);
|
||||
LVILatticeVal Result = getImpl(PImpl, &DL, DT).getValueAt(V, CxtI);
|
||||
Tristate Ret = getPredicateResult(Pred, C, Result, DL, TLI);
|
||||
if (Ret != Unknown)
|
||||
return Ret;
|
||||
@ -1771,13 +1763,13 @@ void LazyValueInfo::threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc,
|
||||
BasicBlock *NewSucc) {
|
||||
if (PImpl) {
|
||||
const DataLayout &DL = PredBB->getModule()->getDataLayout();
|
||||
getImpl(PImpl, AC, &DL, DT).threadEdge(PredBB, OldSucc, NewSucc);
|
||||
getImpl(PImpl, &DL, DT).threadEdge(PredBB, OldSucc, NewSucc);
|
||||
}
|
||||
}
|
||||
|
||||
void LazyValueInfo::eraseBlock(BasicBlock *BB) {
|
||||
if (PImpl) {
|
||||
const DataLayout &DL = BB->getModule()->getDataLayout();
|
||||
getImpl(PImpl, AC, &DL, DT).eraseBlock(BB);
|
||||
getImpl(PImpl, &DL, DT).eraseBlock(BB);
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,6 @@
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/ConstantFolding.h"
|
||||
#include "llvm/Analysis/InstructionSimplify.h"
|
||||
#include "llvm/Analysis/Loads.h"
|
||||
@ -128,7 +127,6 @@ namespace {
|
||||
Module *Mod;
|
||||
const DataLayout *DL;
|
||||
AliasAnalysis *AA;
|
||||
AssumptionCache *AC;
|
||||
DominatorTree *DT;
|
||||
TargetLibraryInfo *TLI;
|
||||
|
||||
@ -145,7 +143,6 @@ namespace {
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.setPreservesAll();
|
||||
AU.addRequired<AAResultsWrapperPass>();
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
AU.addRequired<TargetLibraryInfoWrapperPass>();
|
||||
AU.addRequired<DominatorTreeWrapperPass>();
|
||||
}
|
||||
@ -185,7 +182,6 @@ namespace {
|
||||
char Lint::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(Lint, "lint", "Statically lint-checks LLVM IR",
|
||||
false, true)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
|
||||
@ -203,7 +199,6 @@ bool Lint::runOnFunction(Function &F) {
|
||||
Mod = F.getParent();
|
||||
DL = &F.getParent()->getDataLayout();
|
||||
AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
|
||||
AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
|
||||
DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||
TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
|
||||
visit(F);
|
||||
@ -525,8 +520,7 @@ void Lint::visitShl(BinaryOperator &I) {
|
||||
"Undefined result: Shift count out of range", &I);
|
||||
}
|
||||
|
||||
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT,
|
||||
AssumptionCache *AC) {
|
||||
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT) {
|
||||
// Assume undef could be zero.
|
||||
if (isa<UndefValue>(V))
|
||||
return true;
|
||||
@ -535,7 +529,7 @@ static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT,
|
||||
if (!VecTy) {
|
||||
unsigned BitWidth = V->getType()->getIntegerBitWidth();
|
||||
APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0);
|
||||
computeKnownBits(V, KnownZero, KnownOne, DL, 0, AC,
|
||||
computeKnownBits(V, KnownZero, KnownOne, DL, 0,
|
||||
dyn_cast<Instruction>(V), DT);
|
||||
return KnownZero.isAllOnesValue();
|
||||
}
|
||||
@ -566,22 +560,22 @@ static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT,
|
||||
}
|
||||
|
||||
void Lint::visitSDiv(BinaryOperator &I) {
|
||||
Assert(!isZero(I.getOperand(1), I.getModule()->getDataLayout(), DT, AC),
|
||||
Assert(!isZero(I.getOperand(1), I.getModule()->getDataLayout(), DT),
|
||||
"Undefined behavior: Division by zero", &I);
|
||||
}
|
||||
|
||||
void Lint::visitUDiv(BinaryOperator &I) {
|
||||
Assert(!isZero(I.getOperand(1), I.getModule()->getDataLayout(), DT, AC),
|
||||
Assert(!isZero(I.getOperand(1), I.getModule()->getDataLayout(), DT),
|
||||
"Undefined behavior: Division by zero", &I);
|
||||
}
|
||||
|
||||
void Lint::visitSRem(BinaryOperator &I) {
|
||||
Assert(!isZero(I.getOperand(1), I.getModule()->getDataLayout(), DT, AC),
|
||||
Assert(!isZero(I.getOperand(1), I.getModule()->getDataLayout(), DT),
|
||||
"Undefined behavior: Division by zero", &I);
|
||||
}
|
||||
|
||||
void Lint::visitURem(BinaryOperator &I) {
|
||||
Assert(!isZero(I.getOperand(1), I.getModule()->getDataLayout(), DT, AC),
|
||||
Assert(!isZero(I.getOperand(1), I.getModule()->getDataLayout(), DT),
|
||||
"Undefined behavior: Division by zero", &I);
|
||||
}
|
||||
|
||||
@ -699,7 +693,7 @@ Value *Lint::findValueImpl(Value *V, bool OffsetOk,
|
||||
|
||||
// As a last resort, try SimplifyInstruction or constant folding.
|
||||
if (Instruction *Inst = dyn_cast<Instruction>(V)) {
|
||||
if (Value *W = SimplifyInstruction(Inst, *DL, TLI, DT, AC))
|
||||
if (Value *W = SimplifyInstruction(Inst, *DL, TLI, DT))
|
||||
return findValueImpl(W, OffsetOk, Visited);
|
||||
} else if (auto *C = dyn_cast<Constant>(V)) {
|
||||
if (Value *W = ConstantFoldConstant(C, *DL, TLI))
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/MemoryBuiltins.h"
|
||||
#include "llvm/Analysis/PHITransAddr.h"
|
||||
#include "llvm/Analysis/OrderedBasicBlock.h"
|
||||
@ -891,7 +890,7 @@ void MemoryDependenceResults::getNonLocalPointerDependency(
|
||||
return;
|
||||
}
|
||||
const DataLayout &DL = FromBB->getModule()->getDataLayout();
|
||||
PHITransAddr Address(const_cast<Value *>(Loc.Ptr), DL, &AC);
|
||||
PHITransAddr Address(const_cast<Value *>(Loc.Ptr), DL);
|
||||
|
||||
// This is the set of blocks we've inspected, and the pointer we consider in
|
||||
// each block. Because of critical edges, we currently bail out if querying
|
||||
@ -1648,17 +1647,15 @@ AnalysisKey MemoryDependenceAnalysis::Key;
|
||||
MemoryDependenceResults
|
||||
MemoryDependenceAnalysis::run(Function &F, FunctionAnalysisManager &AM) {
|
||||
auto &AA = AM.getResult<AAManager>(F);
|
||||
auto &AC = AM.getResult<AssumptionAnalysis>(F);
|
||||
auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
|
||||
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
|
||||
return MemoryDependenceResults(AA, AC, TLI, DT);
|
||||
return MemoryDependenceResults(AA, TLI, DT);
|
||||
}
|
||||
|
||||
char MemoryDependenceWrapperPass::ID = 0;
|
||||
|
||||
INITIALIZE_PASS_BEGIN(MemoryDependenceWrapperPass, "memdep",
|
||||
"Memory Dependence Analysis", false, true)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
|
||||
@ -1677,7 +1674,6 @@ void MemoryDependenceWrapperPass::releaseMemory() {
|
||||
|
||||
void MemoryDependenceWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.setPreservesAll();
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
AU.addRequired<DominatorTreeWrapperPass>();
|
||||
AU.addRequiredTransitive<AAResultsWrapperPass>();
|
||||
AU.addRequiredTransitive<TargetLibraryInfoWrapperPass>();
|
||||
@ -1689,9 +1685,8 @@ unsigned MemoryDependenceResults::getDefaultBlockScanLimit() const {
|
||||
|
||||
bool MemoryDependenceWrapperPass::runOnFunction(Function &F) {
|
||||
auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
|
||||
auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
|
||||
auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
|
||||
auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||
MemDep.emplace(AA, AC, TLI, DT);
|
||||
MemDep.emplace(AA, TLI, DT);
|
||||
return false;
|
||||
}
|
||||
|
@ -227,7 +227,7 @@ Value *PHITransAddr::PHITranslateSubExpr(Value *V, BasicBlock *CurBB,
|
||||
|
||||
// Simplify the GEP to handle 'gep x, 0' -> x etc.
|
||||
if (Value *V = SimplifyGEPInst(GEP->getSourceElementType(),
|
||||
GEPOps, DL, TLI, DT, AC)) {
|
||||
GEPOps, DL, TLI, DT)) {
|
||||
for (unsigned i = 0, e = GEPOps.size(); i != e; ++i)
|
||||
RemoveInstInputs(GEPOps[i], InstInputs);
|
||||
|
||||
@ -276,7 +276,7 @@ Value *PHITransAddr::PHITranslateSubExpr(Value *V, BasicBlock *CurBB,
|
||||
}
|
||||
|
||||
// See if the add simplifies away.
|
||||
if (Value *Res = SimplifyAddInst(LHS, RHS, isNSW, isNUW, DL, TLI, DT, AC)) {
|
||||
if (Value *Res = SimplifyAddInst(LHS, RHS, isNSW, isNUW, DL, TLI, DT)) {
|
||||
// If we simplified the operands, the LHS is no longer an input, but Res
|
||||
// is.
|
||||
RemoveInstInputs(LHS, InstInputs);
|
||||
@ -367,7 +367,7 @@ InsertPHITranslatedSubExpr(Value *InVal, BasicBlock *CurBB,
|
||||
SmallVectorImpl<Instruction*> &NewInsts) {
|
||||
// See if we have a version of this value already available and dominating
|
||||
// PredBB. If so, there is no need to insert a new instance of it.
|
||||
PHITransAddr Tmp(InVal, DL, AC);
|
||||
PHITransAddr Tmp(InVal, DL);
|
||||
if (!Tmp.PHITranslateValue(CurBB, PredBB, &DT, /*MustDominate=*/true))
|
||||
return Tmp.getAddr();
|
||||
|
||||
|
@ -64,8 +64,8 @@
|
||||
#include "llvm/ADT/ScopeExit.h"
|
||||
#include "llvm/ADT/Sequence.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/ConstantFolding.h"
|
||||
#include "llvm/Analysis/InstructionSimplify.h"
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
@ -4322,7 +4322,7 @@ const SCEV *ScalarEvolution::createNodeForPHI(PHINode *PN) {
|
||||
// PHI's incoming blocks are in a different loop, in which case doing so
|
||||
// risks breaking LCSSA form. Instcombine would normally zap these, but
|
||||
// it doesn't have DominatorTree information, so it may miss cases.
|
||||
if (Value *V = SimplifyInstruction(PN, getDataLayout(), &TLI, &DT, &AC))
|
||||
if (Value *V = SimplifyInstruction(PN, getDataLayout(), &TLI, &DT))
|
||||
if (LI.replacementPreservesLCSSAForm(PN, V))
|
||||
return getSCEV(V);
|
||||
|
||||
@ -4510,7 +4510,7 @@ ScalarEvolution::GetMinTrailingZeros(const SCEV *S) {
|
||||
// For a SCEVUnknown, ask ValueTracking.
|
||||
unsigned BitWidth = getTypeSizeInBits(U->getType());
|
||||
APInt Zeros(BitWidth, 0), Ones(BitWidth, 0);
|
||||
computeKnownBits(U->getValue(), Zeros, Ones, getDataLayout(), 0, &AC,
|
||||
computeKnownBits(U->getValue(), Zeros, Ones, getDataLayout(), 0,
|
||||
nullptr, &DT);
|
||||
return Zeros.countTrailingOnes();
|
||||
}
|
||||
@ -4681,14 +4681,14 @@ ScalarEvolution::getRange(const SCEV *S,
|
||||
if (SignHint == ScalarEvolution::HINT_RANGE_UNSIGNED) {
|
||||
// For a SCEVUnknown, ask ValueTracking.
|
||||
APInt Zeros(BitWidth, 0), Ones(BitWidth, 0);
|
||||
computeKnownBits(U->getValue(), Zeros, Ones, DL, 0, &AC, nullptr, &DT);
|
||||
computeKnownBits(U->getValue(), Zeros, Ones, DL, 0, nullptr, &DT);
|
||||
if (Ones != ~Zeros + 1)
|
||||
ConservativeResult =
|
||||
ConservativeResult.intersectWith(ConstantRange(Ones, ~Zeros + 1));
|
||||
} else {
|
||||
assert(SignHint == ScalarEvolution::HINT_RANGE_SIGNED &&
|
||||
"generalize as needed!");
|
||||
unsigned NS = ComputeNumSignBits(U->getValue(), DL, 0, &AC, nullptr, &DT);
|
||||
unsigned NS = ComputeNumSignBits(U->getValue(), DL, 0, nullptr, &DT);
|
||||
if (NS > 1)
|
||||
ConservativeResult = ConservativeResult.intersectWith(
|
||||
ConstantRange(APInt::getSignedMinValue(BitWidth).ashr(NS - 1),
|
||||
@ -5177,7 +5177,7 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
|
||||
unsigned BitWidth = A.getBitWidth();
|
||||
APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0);
|
||||
computeKnownBits(BO->LHS, KnownZero, KnownOne, getDataLayout(),
|
||||
0, &AC, nullptr, &DT);
|
||||
0, nullptr, &DT);
|
||||
|
||||
APInt EffectiveMask =
|
||||
APInt::getLowBitsSet(BitWidth, BitWidth - LZ - TZ).shl(TZ);
|
||||
@ -6372,7 +6372,7 @@ ScalarEvolution::ExitLimit ScalarEvolution::computeShiftCompareExitLimit(
|
||||
// bitwidth(K) iterations.
|
||||
Value *FirstValue = PN->getIncomingValueForBlock(Predecessor);
|
||||
bool KnownZero, KnownOne;
|
||||
ComputeSignBit(FirstValue, KnownZero, KnownOne, DL, 0, nullptr,
|
||||
ComputeSignBit(FirstValue, KnownZero, KnownOne, DL, 0,
|
||||
Predecessor->getTerminator(), &DT);
|
||||
auto *Ty = cast<IntegerType>(RHS->getType());
|
||||
if (KnownZero)
|
||||
@ -9534,9 +9534,8 @@ ScalarEvolution::SCEVCallbackVH::SCEVCallbackVH(Value *V, ScalarEvolution *se)
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
ScalarEvolution::ScalarEvolution(Function &F, TargetLibraryInfo &TLI,
|
||||
AssumptionCache &AC, DominatorTree &DT,
|
||||
LoopInfo &LI)
|
||||
: F(F), TLI(TLI), AC(AC), DT(DT), LI(LI),
|
||||
DominatorTree &DT, LoopInfo &LI)
|
||||
: F(F), TLI(TLI), DT(DT), LI(LI),
|
||||
CouldNotCompute(new SCEVCouldNotCompute()),
|
||||
WalkingBEDominatingConds(false), ProvingSplitPredicate(false),
|
||||
ValuesAtScopes(64), LoopDispositions(64), BlockDispositions(64),
|
||||
@ -9558,7 +9557,7 @@ ScalarEvolution::ScalarEvolution(Function &F, TargetLibraryInfo &TLI,
|
||||
}
|
||||
|
||||
ScalarEvolution::ScalarEvolution(ScalarEvolution &&Arg)
|
||||
: F(Arg.F), HasGuards(Arg.HasGuards), TLI(Arg.TLI), AC(Arg.AC), DT(Arg.DT),
|
||||
: F(Arg.F), HasGuards(Arg.HasGuards), TLI(Arg.TLI), DT(Arg.DT),
|
||||
LI(Arg.LI), CouldNotCompute(std::move(Arg.CouldNotCompute)),
|
||||
ValueExprMap(std::move(Arg.ValueExprMap)),
|
||||
PendingLoopPredicates(std::move(Arg.PendingLoopPredicates)),
|
||||
@ -10029,7 +10028,7 @@ void ScalarEvolution::verify() const {
|
||||
|
||||
// Gather stringified backedge taken counts for all loops using a fresh
|
||||
// ScalarEvolution object.
|
||||
ScalarEvolution SE2(F, TLI, AC, DT, LI);
|
||||
ScalarEvolution SE2(F, TLI, DT, LI);
|
||||
for (LoopInfo::reverse_iterator I = LI.rbegin(), E = LI.rend(); I != E; ++I)
|
||||
getLoopBackedgeTakenCounts(*I, BackedgeDumpsNew, SE2);
|
||||
|
||||
@ -10070,7 +10069,6 @@ AnalysisKey ScalarEvolutionAnalysis::Key;
|
||||
ScalarEvolution ScalarEvolutionAnalysis::run(Function &F,
|
||||
FunctionAnalysisManager &AM) {
|
||||
return ScalarEvolution(F, AM.getResult<TargetLibraryAnalysis>(F),
|
||||
AM.getResult<AssumptionAnalysis>(F),
|
||||
AM.getResult<DominatorTreeAnalysis>(F),
|
||||
AM.getResult<LoopAnalysis>(F));
|
||||
}
|
||||
@ -10083,7 +10081,6 @@ ScalarEvolutionPrinterPass::run(Function &F, FunctionAnalysisManager &AM) {
|
||||
|
||||
INITIALIZE_PASS_BEGIN(ScalarEvolutionWrapperPass, "scalar-evolution",
|
||||
"Scalar Evolution Analysis", false, true)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
|
||||
@ -10098,7 +10095,6 @@ ScalarEvolutionWrapperPass::ScalarEvolutionWrapperPass() : FunctionPass(ID) {
|
||||
bool ScalarEvolutionWrapperPass::runOnFunction(Function &F) {
|
||||
SE.reset(new ScalarEvolution(
|
||||
F, getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(),
|
||||
getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F),
|
||||
getAnalysis<DominatorTreeWrapperPass>().getDomTree(),
|
||||
getAnalysis<LoopInfoWrapperPass>().getLoopInfo()));
|
||||
return false;
|
||||
@ -10119,7 +10115,6 @@ void ScalarEvolutionWrapperPass::verifyAnalysis() const {
|
||||
|
||||
void ScalarEvolutionWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.setPreservesAll();
|
||||
AU.addRequiredTransitive<AssumptionCacheTracker>();
|
||||
AU.addRequiredTransitive<LoopInfoWrapperPass>();
|
||||
AU.addRequiredTransitive<DominatorTreeWrapperPass>();
|
||||
AU.addRequiredTransitive<TargetLibraryInfoWrapperPass>();
|
||||
|
@ -1800,7 +1800,7 @@ unsigned SCEVExpander::replaceCongruentIVs(Loop *L, const DominatorTree *DT,
|
||||
// so narrow phis can reuse them.
|
||||
for (PHINode *Phi : Phis) {
|
||||
auto SimplifyPHINode = [&](PHINode *PN) -> Value * {
|
||||
if (Value *V = SimplifyInstruction(PN, DL, &SE.TLI, &SE.DT, &SE.AC))
|
||||
if (Value *V = SimplifyInstruction(PN, DL, &SE.TLI, &SE.DT))
|
||||
return V;
|
||||
if (!SE.isSCEVable(PN->getType()))
|
||||
return nullptr;
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include "llvm/Analysis/ValueTracking.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/Analysis/InstructionSimplify.h"
|
||||
#include "llvm/Analysis/MemoryBuiltins.h"
|
||||
#include "llvm/Analysis/Loads.h"
|
||||
@ -73,7 +73,6 @@ namespace {
|
||||
// figuring out if we can use it.
|
||||
struct Query {
|
||||
const DataLayout &DL;
|
||||
AssumptionCache *AC;
|
||||
const Instruction *CxtI;
|
||||
const DominatorTree *DT;
|
||||
|
||||
@ -89,12 +88,11 @@ struct Query {
|
||||
std::array<const Value *, MaxDepth> Excluded;
|
||||
unsigned NumExcluded;
|
||||
|
||||
Query(const DataLayout &DL, AssumptionCache *AC, const Instruction *CxtI,
|
||||
const DominatorTree *DT)
|
||||
: DL(DL), AC(AC), CxtI(CxtI), DT(DT), NumExcluded(0) {}
|
||||
Query(const DataLayout &DL, const Instruction *CxtI, const DominatorTree *DT)
|
||||
: DL(DL), CxtI(CxtI), DT(DT), NumExcluded(0) {}
|
||||
|
||||
Query(const Query &Q, const Value *NewExcl)
|
||||
: DL(Q.DL), AC(Q.AC), CxtI(Q.CxtI), DT(Q.DT), NumExcluded(Q.NumExcluded) {
|
||||
: DL(Q.DL), CxtI(Q.CxtI), DT(Q.DT), NumExcluded(Q.NumExcluded) {
|
||||
Excluded = Q.Excluded;
|
||||
Excluded[NumExcluded++] = NewExcl;
|
||||
assert(NumExcluded <= Excluded.size());
|
||||
@ -130,15 +128,15 @@ static void computeKnownBits(const Value *V, APInt &KnownZero, APInt &KnownOne,
|
||||
|
||||
void llvm::computeKnownBits(const Value *V, APInt &KnownZero, APInt &KnownOne,
|
||||
const DataLayout &DL, unsigned Depth,
|
||||
AssumptionCache *AC, const Instruction *CxtI,
|
||||
const Instruction *CxtI,
|
||||
const DominatorTree *DT) {
|
||||
::computeKnownBits(V, KnownZero, KnownOne, Depth,
|
||||
Query(DL, AC, safeCxtI(V, CxtI), DT));
|
||||
Query(DL, safeCxtI(V, CxtI), DT));
|
||||
}
|
||||
|
||||
bool llvm::haveNoCommonBitsSet(const Value *LHS, const Value *RHS,
|
||||
const DataLayout &DL,
|
||||
AssumptionCache *AC, const Instruction *CxtI,
|
||||
const Instruction *CxtI,
|
||||
const DominatorTree *DT) {
|
||||
assert(LHS->getType() == RHS->getType() &&
|
||||
"LHS and RHS should have the same type");
|
||||
@ -147,8 +145,8 @@ bool llvm::haveNoCommonBitsSet(const Value *LHS, const Value *RHS,
|
||||
IntegerType *IT = cast<IntegerType>(LHS->getType()->getScalarType());
|
||||
APInt LHSKnownZero(IT->getBitWidth(), 0), LHSKnownOne(IT->getBitWidth(), 0);
|
||||
APInt RHSKnownZero(IT->getBitWidth(), 0), RHSKnownOne(IT->getBitWidth(), 0);
|
||||
computeKnownBits(LHS, LHSKnownZero, LHSKnownOne, DL, 0, AC, CxtI, DT);
|
||||
computeKnownBits(RHS, RHSKnownZero, RHSKnownOne, DL, 0, AC, CxtI, DT);
|
||||
computeKnownBits(LHS, LHSKnownZero, LHSKnownOne, DL, 0, CxtI, DT);
|
||||
computeKnownBits(RHS, RHSKnownZero, RHSKnownOne, DL, 0, CxtI, DT);
|
||||
return (LHSKnownZero | RHSKnownZero).isAllOnesValue();
|
||||
}
|
||||
|
||||
@ -157,10 +155,10 @@ static void ComputeSignBit(const Value *V, bool &KnownZero, bool &KnownOne,
|
||||
|
||||
void llvm::ComputeSignBit(const Value *V, bool &KnownZero, bool &KnownOne,
|
||||
const DataLayout &DL, unsigned Depth,
|
||||
AssumptionCache *AC, const Instruction *CxtI,
|
||||
const Instruction *CxtI,
|
||||
const DominatorTree *DT) {
|
||||
::ComputeSignBit(V, KnownZero, KnownOne, Depth,
|
||||
Query(DL, AC, safeCxtI(V, CxtI), DT));
|
||||
Query(DL, safeCxtI(V, CxtI), DT));
|
||||
}
|
||||
|
||||
static bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero, unsigned Depth,
|
||||
@ -168,58 +166,51 @@ static bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero, unsigned Depth,
|
||||
|
||||
bool llvm::isKnownToBeAPowerOfTwo(const Value *V, const DataLayout &DL,
|
||||
bool OrZero,
|
||||
unsigned Depth, AssumptionCache *AC,
|
||||
const Instruction *CxtI,
|
||||
unsigned Depth, const Instruction *CxtI,
|
||||
const DominatorTree *DT) {
|
||||
return ::isKnownToBeAPowerOfTwo(V, OrZero, Depth,
|
||||
Query(DL, AC, safeCxtI(V, CxtI), DT));
|
||||
Query(DL, safeCxtI(V, CxtI), DT));
|
||||
}
|
||||
|
||||
static bool isKnownNonZero(const Value *V, unsigned Depth, const Query &Q);
|
||||
|
||||
bool llvm::isKnownNonZero(const Value *V, const DataLayout &DL, unsigned Depth,
|
||||
AssumptionCache *AC, const Instruction *CxtI,
|
||||
const DominatorTree *DT) {
|
||||
return ::isKnownNonZero(V, Depth, Query(DL, AC, safeCxtI(V, CxtI), DT));
|
||||
const Instruction *CxtI, const DominatorTree *DT) {
|
||||
return ::isKnownNonZero(V, Depth, Query(DL, safeCxtI(V, CxtI), DT));
|
||||
}
|
||||
|
||||
bool llvm::isKnownNonNegative(const Value *V, const DataLayout &DL,
|
||||
unsigned Depth,
|
||||
AssumptionCache *AC, const Instruction *CxtI,
|
||||
unsigned Depth, const Instruction *CxtI,
|
||||
const DominatorTree *DT) {
|
||||
bool NonNegative, Negative;
|
||||
ComputeSignBit(V, NonNegative, Negative, DL, Depth, AC, CxtI, DT);
|
||||
ComputeSignBit(V, NonNegative, Negative, DL, Depth, CxtI, DT);
|
||||
return NonNegative;
|
||||
}
|
||||
|
||||
bool llvm::isKnownPositive(const Value *V, const DataLayout &DL, unsigned Depth,
|
||||
AssumptionCache *AC, const Instruction *CxtI,
|
||||
const DominatorTree *DT) {
|
||||
const Instruction *CxtI, const DominatorTree *DT) {
|
||||
if (auto *CI = dyn_cast<ConstantInt>(V))
|
||||
return CI->getValue().isStrictlyPositive();
|
||||
|
||||
// TODO: We'd doing two recursive queries here. We should factor this such
|
||||
// that only a single query is needed.
|
||||
return isKnownNonNegative(V, DL, Depth, AC, CxtI, DT) &&
|
||||
isKnownNonZero(V, DL, Depth, AC, CxtI, DT);
|
||||
return isKnownNonNegative(V, DL, Depth, CxtI, DT) &&
|
||||
isKnownNonZero(V, DL, Depth, CxtI, DT);
|
||||
}
|
||||
|
||||
bool llvm::isKnownNegative(const Value *V, const DataLayout &DL, unsigned Depth,
|
||||
AssumptionCache *AC, const Instruction *CxtI,
|
||||
const DominatorTree *DT) {
|
||||
const Instruction *CxtI, const DominatorTree *DT) {
|
||||
bool NonNegative, Negative;
|
||||
ComputeSignBit(V, NonNegative, Negative, DL, Depth, AC, CxtI, DT);
|
||||
ComputeSignBit(V, NonNegative, Negative, DL, Depth, CxtI, DT);
|
||||
return Negative;
|
||||
}
|
||||
|
||||
static bool isKnownNonEqual(const Value *V1, const Value *V2, const Query &Q);
|
||||
|
||||
bool llvm::isKnownNonEqual(const Value *V1, const Value *V2,
|
||||
const DataLayout &DL,
|
||||
AssumptionCache *AC, const Instruction *CxtI,
|
||||
const DataLayout &DL, const Instruction *CxtI,
|
||||
const DominatorTree *DT) {
|
||||
return ::isKnownNonEqual(V1, V2, Query(DL, AC,
|
||||
safeCxtI(V1, safeCxtI(V2, CxtI)),
|
||||
return ::isKnownNonEqual(V1, V2, Query(DL, safeCxtI(V1, safeCxtI(V2, CxtI)),
|
||||
DT));
|
||||
}
|
||||
|
||||
@ -228,20 +219,19 @@ static bool MaskedValueIsZero(const Value *V, const APInt &Mask, unsigned Depth,
|
||||
|
||||
bool llvm::MaskedValueIsZero(const Value *V, const APInt &Mask,
|
||||
const DataLayout &DL,
|
||||
unsigned Depth, AssumptionCache *AC,
|
||||
const Instruction *CxtI, const DominatorTree *DT) {
|
||||
unsigned Depth, const Instruction *CxtI,
|
||||
const DominatorTree *DT) {
|
||||
return ::MaskedValueIsZero(V, Mask, Depth,
|
||||
Query(DL, AC, safeCxtI(V, CxtI), DT));
|
||||
Query(DL, safeCxtI(V, CxtI), DT));
|
||||
}
|
||||
|
||||
static unsigned ComputeNumSignBits(const Value *V, unsigned Depth,
|
||||
const Query &Q);
|
||||
|
||||
unsigned llvm::ComputeNumSignBits(const Value *V, const DataLayout &DL,
|
||||
unsigned Depth, AssumptionCache *AC,
|
||||
const Instruction *CxtI,
|
||||
unsigned Depth, const Instruction *CxtI,
|
||||
const DominatorTree *DT) {
|
||||
return ::ComputeNumSignBits(V, Depth, Query(DL, AC, safeCxtI(V, CxtI), DT));
|
||||
return ::ComputeNumSignBits(V, Depth, Query(DL, safeCxtI(V, CxtI), DT));
|
||||
}
|
||||
|
||||
static void computeKnownBitsAddSub(bool Add, const Value *Op0, const Value *Op1,
|
||||
@ -521,7 +511,7 @@ static void computeKnownBitsFromAssume(const Value *V, APInt &KnownZero,
|
||||
const Query &Q) {
|
||||
// Use of assumptions is context-sensitive. If we don't have a context, we
|
||||
// cannot use them!
|
||||
if (!Q.AC || !Q.CxtI)
|
||||
if (!Q.CxtI)
|
||||
return;
|
||||
|
||||
unsigned BitWidth = KnownZero.getBitWidth();
|
||||
@ -3128,7 +3118,7 @@ Value *llvm::GetUnderlyingObject(Value *V, const DataLayout &DL,
|
||||
|
||||
// See if InstructionSimplify knows any relevant tricks.
|
||||
if (Instruction *I = dyn_cast<Instruction>(V))
|
||||
// TODO: Acquire a DominatorTree and AssumptionCache and use them.
|
||||
// TODO: Acquire a DominatorTree and use it.
|
||||
if (Value *Simplified = SimplifyInstruction(I, DL, nullptr)) {
|
||||
V = Simplified;
|
||||
continue;
|
||||
@ -3413,7 +3403,6 @@ bool llvm::isKnownNonNullAt(const Value *V, const Instruction *CtxI,
|
||||
OverflowResult llvm::computeOverflowForUnsignedMul(const Value *LHS,
|
||||
const Value *RHS,
|
||||
const DataLayout &DL,
|
||||
AssumptionCache *AC,
|
||||
const Instruction *CxtI,
|
||||
const DominatorTree *DT) {
|
||||
// Multiplying n * m significant bits yields a result of n + m significant
|
||||
@ -3427,10 +3416,8 @@ OverflowResult llvm::computeOverflowForUnsignedMul(const Value *LHS,
|
||||
APInt LHSKnownOne(BitWidth, 0);
|
||||
APInt RHSKnownZero(BitWidth, 0);
|
||||
APInt RHSKnownOne(BitWidth, 0);
|
||||
computeKnownBits(LHS, LHSKnownZero, LHSKnownOne, DL, /*Depth=*/0, AC, CxtI,
|
||||
DT);
|
||||
computeKnownBits(RHS, RHSKnownZero, RHSKnownOne, DL, /*Depth=*/0, AC, CxtI,
|
||||
DT);
|
||||
computeKnownBits(LHS, LHSKnownZero, LHSKnownOne, DL, /*Depth=*/0, CxtI, DT);
|
||||
computeKnownBits(RHS, RHSKnownZero, RHSKnownOne, DL, /*Depth=*/0, CxtI, DT);
|
||||
// Note that underestimating the number of zero bits gives a more
|
||||
// conservative answer.
|
||||
unsigned ZeroBits = LHSKnownZero.countLeadingOnes() +
|
||||
@ -3464,16 +3451,15 @@ OverflowResult llvm::computeOverflowForUnsignedMul(const Value *LHS,
|
||||
OverflowResult llvm::computeOverflowForUnsignedAdd(const Value *LHS,
|
||||
const Value *RHS,
|
||||
const DataLayout &DL,
|
||||
AssumptionCache *AC,
|
||||
const Instruction *CxtI,
|
||||
const DominatorTree *DT) {
|
||||
bool LHSKnownNonNegative, LHSKnownNegative;
|
||||
ComputeSignBit(LHS, LHSKnownNonNegative, LHSKnownNegative, DL, /*Depth=*/0,
|
||||
AC, CxtI, DT);
|
||||
CxtI, DT);
|
||||
if (LHSKnownNonNegative || LHSKnownNegative) {
|
||||
bool RHSKnownNonNegative, RHSKnownNegative;
|
||||
ComputeSignBit(RHS, RHSKnownNonNegative, RHSKnownNegative, DL, /*Depth=*/0,
|
||||
AC, CxtI, DT);
|
||||
CxtI, DT);
|
||||
|
||||
if (LHSKnownNegative && RHSKnownNegative) {
|
||||
// The sign bit is set in both cases: this MUST overflow.
|
||||
@ -3495,7 +3481,6 @@ static OverflowResult computeOverflowForSignedAdd(const Value *LHS,
|
||||
const Value *RHS,
|
||||
const AddOperator *Add,
|
||||
const DataLayout &DL,
|
||||
AssumptionCache *AC,
|
||||
const Instruction *CxtI,
|
||||
const DominatorTree *DT) {
|
||||
if (Add && Add->hasNoSignedWrap()) {
|
||||
@ -3505,9 +3490,9 @@ static OverflowResult computeOverflowForSignedAdd(const Value *LHS,
|
||||
bool LHSKnownNonNegative, LHSKnownNegative;
|
||||
bool RHSKnownNonNegative, RHSKnownNegative;
|
||||
ComputeSignBit(LHS, LHSKnownNonNegative, LHSKnownNegative, DL, /*Depth=*/0,
|
||||
AC, CxtI, DT);
|
||||
CxtI, DT);
|
||||
ComputeSignBit(RHS, RHSKnownNonNegative, RHSKnownNegative, DL, /*Depth=*/0,
|
||||
AC, CxtI, DT);
|
||||
CxtI, DT);
|
||||
|
||||
if ((LHSKnownNonNegative && RHSKnownNegative) ||
|
||||
(LHSKnownNegative && RHSKnownNonNegative)) {
|
||||
@ -3529,7 +3514,7 @@ static OverflowResult computeOverflowForSignedAdd(const Value *LHS,
|
||||
if (LHSOrRHSKnownNonNegative || LHSOrRHSKnownNegative) {
|
||||
bool AddKnownNonNegative, AddKnownNegative;
|
||||
ComputeSignBit(Add, AddKnownNonNegative, AddKnownNegative, DL,
|
||||
/*Depth=*/0, AC, CxtI, DT);
|
||||
/*Depth=*/0, CxtI, DT);
|
||||
if ((AddKnownNonNegative && LHSOrRHSKnownNonNegative) ||
|
||||
(AddKnownNegative && LHSOrRHSKnownNegative)) {
|
||||
return OverflowResult::NeverOverflows;
|
||||
@ -3603,20 +3588,18 @@ bool llvm::isOverflowIntrinsicNoWrap(const IntrinsicInst *II,
|
||||
|
||||
OverflowResult llvm::computeOverflowForSignedAdd(const AddOperator *Add,
|
||||
const DataLayout &DL,
|
||||
AssumptionCache *AC,
|
||||
const Instruction *CxtI,
|
||||
const DominatorTree *DT) {
|
||||
return ::computeOverflowForSignedAdd(Add->getOperand(0), Add->getOperand(1),
|
||||
Add, DL, AC, CxtI, DT);
|
||||
Add, DL, CxtI, DT);
|
||||
}
|
||||
|
||||
OverflowResult llvm::computeOverflowForSignedAdd(const Value *LHS,
|
||||
const Value *RHS,
|
||||
const DataLayout &DL,
|
||||
AssumptionCache *AC,
|
||||
const Instruction *CxtI,
|
||||
const DominatorTree *DT) {
|
||||
return ::computeOverflowForSignedAdd(LHS, RHS, nullptr, DL, AC, CxtI, DT);
|
||||
return ::computeOverflowForSignedAdd(LHS, RHS, nullptr, DL, CxtI, DT);
|
||||
}
|
||||
|
||||
bool llvm::isGuaranteedToTransferExecutionToSuccessor(const Instruction *I) {
|
||||
@ -4147,8 +4130,7 @@ SelectPatternResult llvm::matchSelectPattern(Value *V, Value *&LHS, Value *&RHS,
|
||||
static bool isTruePredicate(CmpInst::Predicate Pred,
|
||||
const Value *LHS, const Value *RHS,
|
||||
const DataLayout &DL, unsigned Depth,
|
||||
AssumptionCache *AC, const Instruction *CxtI,
|
||||
const DominatorTree *DT) {
|
||||
const Instruction *CxtI, const DominatorTree *DT) {
|
||||
assert(!LHS->getType()->isVectorTy() && "TODO: extend to handle vectors!");
|
||||
if (ICmpInst::isTrueWhenEqual(Pred) && LHS == RHS)
|
||||
return true;
|
||||
@ -4186,7 +4168,7 @@ static bool isTruePredicate(CmpInst::Predicate Pred,
|
||||
match(B, m_Or(m_Specific(X), m_APInt(CB)))) {
|
||||
unsigned BitWidth = CA->getBitWidth();
|
||||
APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0);
|
||||
computeKnownBits(X, KnownZero, KnownOne, DL, Depth + 1, AC, CxtI, DT);
|
||||
computeKnownBits(X, KnownZero, KnownOne, DL, Depth + 1, CxtI, DT);
|
||||
|
||||
if ((KnownZero & *CA) == *CA && (KnownZero & *CB) == *CB)
|
||||
return true;
|
||||
@ -4211,25 +4193,24 @@ static Optional<bool>
|
||||
isImpliedCondOperands(CmpInst::Predicate Pred, const Value *ALHS,
|
||||
const Value *ARHS, const Value *BLHS,
|
||||
const Value *BRHS, const DataLayout &DL,
|
||||
unsigned Depth, AssumptionCache *AC,
|
||||
const Instruction *CxtI, const DominatorTree *DT) {
|
||||
unsigned Depth, const Instruction *CxtI,
|
||||
const DominatorTree *DT) {
|
||||
switch (Pred) {
|
||||
default:
|
||||
return None;
|
||||
|
||||
case CmpInst::ICMP_SLT:
|
||||
case CmpInst::ICMP_SLE:
|
||||
if (isTruePredicate(CmpInst::ICMP_SLE, BLHS, ALHS, DL, Depth, AC, CxtI,
|
||||
if (isTruePredicate(CmpInst::ICMP_SLE, BLHS, ALHS, DL, Depth, CxtI,
|
||||
DT) &&
|
||||
isTruePredicate(CmpInst::ICMP_SLE, ARHS, BRHS, DL, Depth, AC, CxtI, DT))
|
||||
isTruePredicate(CmpInst::ICMP_SLE, ARHS, BRHS, DL, Depth, CxtI, DT))
|
||||
return true;
|
||||
return None;
|
||||
|
||||
case CmpInst::ICMP_ULT:
|
||||
case CmpInst::ICMP_ULE:
|
||||
if (isTruePredicate(CmpInst::ICMP_ULE, BLHS, ALHS, DL, Depth, AC, CxtI,
|
||||
DT) &&
|
||||
isTruePredicate(CmpInst::ICMP_ULE, ARHS, BRHS, DL, Depth, AC, CxtI, DT))
|
||||
if (isTruePredicate(CmpInst::ICMP_ULE, BLHS, ALHS, DL, Depth, CxtI, DT) &&
|
||||
isTruePredicate(CmpInst::ICMP_ULE, ARHS, BRHS, DL, Depth, CxtI, DT))
|
||||
return true;
|
||||
return None;
|
||||
}
|
||||
@ -4293,8 +4274,7 @@ isImpliedCondMatchingImmOperands(CmpInst::Predicate APred, const Value *ALHS,
|
||||
|
||||
Optional<bool> llvm::isImpliedCondition(const Value *LHS, const Value *RHS,
|
||||
const DataLayout &DL, bool InvertAPred,
|
||||
unsigned Depth, AssumptionCache *AC,
|
||||
const Instruction *CxtI,
|
||||
unsigned Depth, const Instruction *CxtI,
|
||||
const DominatorTree *DT) {
|
||||
// A mismatch occurs when we compare a scalar cmp to a vector cmp, for example.
|
||||
if (LHS->getType() != RHS->getType())
|
||||
@ -4347,8 +4327,8 @@ Optional<bool> llvm::isImpliedCondition(const Value *LHS, const Value *RHS,
|
||||
}
|
||||
|
||||
if (APred == BPred)
|
||||
return isImpliedCondOperands(APred, ALHS, ARHS, BLHS, BRHS, DL, Depth, AC,
|
||||
CxtI, DT);
|
||||
return isImpliedCondOperands(APred, ALHS, ARHS, BLHS, BRHS, DL, Depth, CxtI,
|
||||
DT);
|
||||
|
||||
return None;
|
||||
}
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/AliasAnalysisEvaluator.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
||||
#include "llvm/Analysis/BlockFrequencyInfo.h"
|
||||
#include "llvm/Analysis/BlockFrequencyInfoImpl.h"
|
||||
|
@ -94,7 +94,6 @@ CGSCC_PASS("no-op-cgscc", NoOpCGSCCPass())
|
||||
#define FUNCTION_ANALYSIS(NAME, CREATE_PASS)
|
||||
#endif
|
||||
FUNCTION_ANALYSIS("aa", AAManager())
|
||||
FUNCTION_ANALYSIS("assumptions", AssumptionAnalysis())
|
||||
FUNCTION_ANALYSIS("block-freq", BlockFrequencyAnalysis())
|
||||
FUNCTION_ANALYSIS("branch-prob", BranchProbabilityAnalysis())
|
||||
FUNCTION_ANALYSIS("domtree", DominatorTreeAnalysis())
|
||||
@ -170,7 +169,6 @@ FUNCTION_PASS("loop-data-prefetch", LoopDataPrefetchPass())
|
||||
FUNCTION_PASS("loop-distribute", LoopDistributePass())
|
||||
FUNCTION_PASS("loop-vectorize", LoopVectorizePass())
|
||||
FUNCTION_PASS("print", PrintFunctionPass(dbgs()))
|
||||
FUNCTION_PASS("print<assumptions>", AssumptionPrinterPass(dbgs()))
|
||||
FUNCTION_PASS("print<block-freq>", BlockFrequencyPrinterPass(dbgs()))
|
||||
FUNCTION_PASS("print<branch-prob>", BranchProbabilityPrinterPass(dbgs()))
|
||||
FUNCTION_PASS("print<domtree>", DominatorTreePrinterPass(dbgs()))
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
#include "llvm/Transforms/IPO/AlwaysInliner.h"
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/CallGraph.h"
|
||||
#include "llvm/Analysis/InlineCost.h"
|
||||
#include "llvm/Analysis/ProfileSummaryInfo.h"
|
||||
@ -90,7 +89,6 @@ public:
|
||||
char AlwaysInlinerLegacyPass::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(AlwaysInlinerLegacyPass, "always-inline",
|
||||
"Inliner for always_inline functions", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
||||
#include "llvm/Analysis/CallGraph.h"
|
||||
#include "llvm/Analysis/CallGraphSCCPass.h"
|
||||
@ -66,7 +65,6 @@ namespace {
|
||||
///
|
||||
struct ArgPromotion : public CallGraphSCCPass {
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
AU.addRequired<TargetLibraryInfoWrapperPass>();
|
||||
getAAResultsAnalysisUsage(AU);
|
||||
CallGraphSCCPass::getAnalysisUsage(AU);
|
||||
@ -106,7 +104,6 @@ DoPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote,
|
||||
char ArgPromotion::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(ArgPromotion, "argpromotion",
|
||||
"Promote 'by reference' arguments to scalars", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
|
||||
INITIALIZE_PASS_END(ArgPromotion, "argpromotion",
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
||||
#include "llvm/Analysis/CallGraph.h"
|
||||
#include "llvm/Analysis/CallGraphSCCPass.h"
|
||||
@ -1103,7 +1102,6 @@ struct PostOrderFunctionAttrsLegacyPass : public CallGraphSCCPass {
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.setPreservesCFG();
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
getAAResultsAnalysisUsage(AU);
|
||||
CallGraphSCCPass::getAnalysisUsage(AU);
|
||||
}
|
||||
@ -1113,7 +1111,6 @@ struct PostOrderFunctionAttrsLegacyPass : public CallGraphSCCPass {
|
||||
char PostOrderFunctionAttrsLegacyPass::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(PostOrderFunctionAttrsLegacyPass, "functionattrs",
|
||||
"Deduce function attributes", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass)
|
||||
INITIALIZE_PASS_END(PostOrderFunctionAttrsLegacyPass, "functionattrs",
|
||||
"Deduce function attributes", false, false)
|
||||
|
@ -11,7 +11,6 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/CallGraph.h"
|
||||
#include "llvm/Analysis/InlineCost.h"
|
||||
#include "llvm/Analysis/ProfileSummaryInfo.h"
|
||||
@ -56,11 +55,7 @@ public:
|
||||
InlineCost getInlineCost(CallSite CS) override {
|
||||
Function *Callee = CS.getCalledFunction();
|
||||
TargetTransformInfo &TTI = TTIWP->getTTI(*Callee);
|
||||
std::function<AssumptionCache &(Function &)> GetAssumptionCache =
|
||||
[&](Function &F) -> AssumptionCache & {
|
||||
return ACT->getAssumptionCache(F);
|
||||
};
|
||||
return llvm::getInlineCost(CS, Params, TTI, GetAssumptionCache, PSI);
|
||||
return llvm::getInlineCost(CS, Params, TTI, PSI);
|
||||
}
|
||||
|
||||
bool runOnSCC(CallGraphSCC &SCC) override;
|
||||
@ -76,7 +71,6 @@ private:
|
||||
char SimpleInliner::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(SimpleInliner, "inline", "Function Integration/Inlining",
|
||||
false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
||||
#include "llvm/Analysis/CallGraph.h"
|
||||
#include "llvm/Analysis/InlineCost.h"
|
||||
@ -85,7 +84,6 @@ Inliner::Inliner(char &ID, bool InsertLifetime)
|
||||
/// If the derived class implements this method, it should
|
||||
/// always explicitly call the implementation here.
|
||||
void Inliner::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
AU.addRequired<ProfileSummaryInfoWrapperPass>();
|
||||
AU.addRequired<TargetLibraryInfoWrapperPass>();
|
||||
getAAResultsAnalysisUsage(AU);
|
||||
@ -423,7 +421,6 @@ bool Inliner::runOnSCC(CallGraphSCC &SCC) {
|
||||
|
||||
static bool
|
||||
inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
|
||||
std::function<AssumptionCache &(Function &)> GetAssumptionCache,
|
||||
ProfileSummaryInfo *PSI, TargetLibraryInfo &TLI,
|
||||
bool InsertLifetime,
|
||||
function_ref<InlineCost(CallSite CS)> GetInlineCost,
|
||||
@ -496,7 +493,7 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
|
||||
std::swap(CallSites[i--], CallSites[--FirstCallInSCC]);
|
||||
|
||||
InlinedArrayAllocasTy InlinedArrayAllocas;
|
||||
InlineFunctionInfo InlineInfo(&CG, &GetAssumptionCache);
|
||||
InlineFunctionInfo InlineInfo(&CG);
|
||||
|
||||
// Now that we have all of the call sites, loop over them and inline them if
|
||||
// it looks profitable to do so.
|
||||
@ -632,7 +629,6 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
|
||||
|
||||
bool Inliner::inlineCalls(CallGraphSCC &SCC) {
|
||||
CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph();
|
||||
ACT = &getAnalysis<AssumptionCacheTracker>();
|
||||
PSI = getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
|
||||
auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
|
||||
// We compute dedicated AA results for each function in the SCC as needed. We
|
||||
@ -645,10 +641,7 @@ bool Inliner::inlineCalls(CallGraphSCC &SCC) {
|
||||
AAR.emplace(createLegacyPMAAResults(*this, F, *BAR));
|
||||
return *AAR;
|
||||
};
|
||||
auto GetAssumptionCache = [&](Function &F) -> AssumptionCache & {
|
||||
return ACT->getAssumptionCache(F);
|
||||
};
|
||||
return inlineCallsImpl(SCC, CG, GetAssumptionCache, PSI, TLI, InsertLifetime,
|
||||
return inlineCallsImpl(SCC, CG, PSI, TLI, InsertLifetime,
|
||||
[this](CallSite CS) { return getInlineCost(CS); },
|
||||
AARGetter, ImportedFunctionsStats);
|
||||
}
|
||||
|
@ -46,19 +46,11 @@ struct PartialInlinerLegacyPass : public ModulePass {
|
||||
initializePartialInlinerLegacyPassPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
}
|
||||
bool runOnModule(Module &M) override {
|
||||
if (skipModule(M))
|
||||
return false;
|
||||
|
||||
AssumptionCacheTracker *ACT = &getAnalysis<AssumptionCacheTracker>();
|
||||
std::function<AssumptionCache &(Function &)> GetAssumptionCache =
|
||||
[&ACT](Function &F) -> AssumptionCache & {
|
||||
return ACT->getAssumptionCache(F);
|
||||
};
|
||||
InlineFunctionInfo IFI(nullptr, &GetAssumptionCache);
|
||||
InlineFunctionInfo IFI(nullptr);
|
||||
return PartialInlinerImpl(IFI).run(M);
|
||||
}
|
||||
};
|
||||
@ -200,11 +192,8 @@ bool PartialInlinerImpl::run(Module &M) {
|
||||
}
|
||||
|
||||
char PartialInlinerLegacyPass::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(PartialInlinerLegacyPass, "partial-inliner",
|
||||
"Partial Inliner", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_END(PartialInlinerLegacyPass, "partial-inliner",
|
||||
"Partial Inliner", false, false)
|
||||
INITIALIZE_PASS(PartialInlinerLegacyPass, "partial-inliner",
|
||||
"Partial Inliner", false, false)
|
||||
|
||||
ModulePass *llvm::createPartialInliningPass() {
|
||||
return new PartialInlinerLegacyPass();
|
||||
@ -212,12 +201,7 @@ ModulePass *llvm::createPartialInliningPass() {
|
||||
|
||||
PreservedAnalyses PartialInlinerPass::run(Module &M,
|
||||
ModuleAnalysisManager &AM) {
|
||||
auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
|
||||
std::function<AssumptionCache &(Function &)> GetAssumptionCache =
|
||||
[&FAM](Function &F) -> AssumptionCache & {
|
||||
return FAM.getResult<AssumptionAnalysis>(F);
|
||||
};
|
||||
InlineFunctionInfo IFI(nullptr, &GetAssumptionCache);
|
||||
InlineFunctionInfo IFI(nullptr);
|
||||
if (PartialInlinerImpl(IFI).run(M))
|
||||
return PreservedAnalyses::none();
|
||||
return PreservedAnalyses::all();
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Analysis/PostDominators.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
@ -142,13 +141,11 @@ private:
|
||||
class SampleProfileLoader {
|
||||
public:
|
||||
SampleProfileLoader(StringRef Name = SampleProfileFile)
|
||||
: DT(nullptr), PDT(nullptr), LI(nullptr), ACT(nullptr), Reader(),
|
||||
Samples(nullptr), Filename(Name), ProfileIsValid(false),
|
||||
TotalCollectedSamples(0) {}
|
||||
: DT(nullptr), PDT(nullptr), LI(nullptr), Reader(), Samples(nullptr),
|
||||
Filename(Name), ProfileIsValid(false), TotalCollectedSamples(0) {}
|
||||
|
||||
bool doInitialization(Module &M);
|
||||
bool runOnModule(Module &M);
|
||||
void setACT(AssumptionCacheTracker *A) { ACT = A; }
|
||||
|
||||
void dump() { Reader->dump(); }
|
||||
|
||||
@ -207,8 +204,6 @@ protected:
|
||||
std::unique_ptr<DominatorTreeBase<BasicBlock>> PDT;
|
||||
std::unique_ptr<LoopInfo> LI;
|
||||
|
||||
AssumptionCacheTracker *ACT;
|
||||
|
||||
/// \brief Predecessors for each basic block in the CFG.
|
||||
BlockEdgeMap Predecessors;
|
||||
|
||||
@ -255,10 +250,6 @@ public:
|
||||
StringRef getPassName() const override { return "Sample profile pass"; }
|
||||
bool runOnModule(Module &M) override;
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
}
|
||||
|
||||
private:
|
||||
SampleProfileLoader SampleLoader;
|
||||
};
|
||||
@ -624,8 +615,6 @@ SampleProfileLoader::findFunctionSamples(const Instruction &Inst) const {
|
||||
bool SampleProfileLoader::inlineHotFunctions(Function &F) {
|
||||
bool Changed = false;
|
||||
LLVMContext &Ctx = F.getContext();
|
||||
std::function<AssumptionCache &(Function &)> GetAssumptionCache = [&](
|
||||
Function &F) -> AssumptionCache & { return ACT->getAssumptionCache(F); };
|
||||
while (true) {
|
||||
bool LocalChanged = false;
|
||||
SmallVector<Instruction *, 10> CIS;
|
||||
@ -646,7 +635,7 @@ bool SampleProfileLoader::inlineHotFunctions(Function &F) {
|
||||
}
|
||||
}
|
||||
for (auto I : CIS) {
|
||||
InlineFunctionInfo IFI(nullptr, ACT ? &GetAssumptionCache : nullptr);
|
||||
InlineFunctionInfo IFI(nullptr);
|
||||
CallSite CS(I);
|
||||
Function *CalledFunction = CS.getCalledFunction();
|
||||
if (!CalledFunction || !CalledFunction->getSubprogram())
|
||||
@ -1274,11 +1263,8 @@ bool SampleProfileLoader::emitAnnotations(Function &F) {
|
||||
}
|
||||
|
||||
char SampleProfileLoaderLegacyPass::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(SampleProfileLoaderLegacyPass, "sample-profile",
|
||||
"Sample Profile loader", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_END(SampleProfileLoaderLegacyPass, "sample-profile",
|
||||
"Sample Profile loader", false, false)
|
||||
INITIALIZE_PASS(SampleProfileLoaderLegacyPass, "sample-profile",
|
||||
"Sample Profile loader", false, false)
|
||||
|
||||
bool SampleProfileLoader::doInitialization(Module &M) {
|
||||
auto &Ctx = M.getContext();
|
||||
@ -1321,8 +1307,6 @@ bool SampleProfileLoader::runOnModule(Module &M) {
|
||||
}
|
||||
|
||||
bool SampleProfileLoaderLegacyPass::runOnModule(Module &M) {
|
||||
// FIXME: pass in AssumptionCache correctly for the new pass manager.
|
||||
SampleLoader.setACT(&getAnalysis<AssumptionCacheTracker>());
|
||||
return SampleLoader.runOnModule(M);
|
||||
}
|
||||
|
||||
|
@ -1035,7 +1035,7 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
if (Value *V = SimplifyAddInst(LHS, RHS, I.hasNoSignedWrap(),
|
||||
I.hasNoUnsignedWrap(), DL, &TLI, &DT, &AC))
|
||||
I.hasNoUnsignedWrap(), DL, &TLI, &DT))
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
// (A*B)+(A*C) -> A*(B+C) etc
|
||||
@ -1154,7 +1154,7 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
// A+B --> A|B iff A and B have no bits set in common.
|
||||
if (haveNoCommonBitsSet(LHS, RHS, DL, &AC, &I, &DT))
|
||||
if (haveNoCommonBitsSet(LHS, RHS, DL, &I, &DT))
|
||||
return BinaryOperator::CreateOr(LHS, RHS);
|
||||
|
||||
if (Constant *CRHS = dyn_cast<Constant>(RHS)) {
|
||||
@ -1317,7 +1317,7 @@ Instruction *InstCombiner::visitFAdd(BinaryOperator &I) {
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
if (Value *V =
|
||||
SimplifyFAddInst(LHS, RHS, I.getFastMathFlags(), DL, &TLI, &DT, &AC))
|
||||
SimplifyFAddInst(LHS, RHS, I.getFastMathFlags(), DL, &TLI, &DT))
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
if (isa<Constant>(RHS)) {
|
||||
@ -1493,7 +1493,7 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
if (Value *V = SimplifySubInst(Op0, Op1, I.hasNoSignedWrap(),
|
||||
I.hasNoUnsignedWrap(), DL, &TLI, &DT, &AC))
|
||||
I.hasNoUnsignedWrap(), DL, &TLI, &DT))
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
// (A*B)-(A*C) -> A*(B-C) etc
|
||||
@ -1704,7 +1704,7 @@ Instruction *InstCombiner::visitFSub(BinaryOperator &I) {
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
if (Value *V =
|
||||
SimplifyFSubInst(Op0, Op1, I.getFastMathFlags(), DL, &TLI, &DT, &AC))
|
||||
SimplifyFSubInst(Op0, Op1, I.getFastMathFlags(), DL, &TLI, &DT))
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
// fsub nsz 0, X ==> fsub nsz -0.0, X
|
||||
|
@ -1265,7 +1265,7 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
|
||||
if (Value *V = SimplifyVectorOp(I))
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
if (Value *V = SimplifyAndInst(Op0, Op1, DL, &TLI, &DT, &AC))
|
||||
if (Value *V = SimplifyAndInst(Op0, Op1, DL, &TLI, &DT))
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
// (A|B)&(A|C) -> A|(B&C) etc
|
||||
@ -1650,17 +1650,17 @@ Value *InstCombiner::FoldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
|
||||
Value *Mask = nullptr;
|
||||
Value *Masked = nullptr;
|
||||
if (LAnd->getOperand(0) == RAnd->getOperand(0) &&
|
||||
isKnownToBeAPowerOfTwo(LAnd->getOperand(1), DL, false, 0, &AC, CxtI,
|
||||
isKnownToBeAPowerOfTwo(LAnd->getOperand(1), DL, false, 0, CxtI,
|
||||
&DT) &&
|
||||
isKnownToBeAPowerOfTwo(RAnd->getOperand(1), DL, false, 0, &AC, CxtI,
|
||||
isKnownToBeAPowerOfTwo(RAnd->getOperand(1), DL, false, 0, CxtI,
|
||||
&DT)) {
|
||||
Mask = Builder->CreateOr(LAnd->getOperand(1), RAnd->getOperand(1));
|
||||
Masked = Builder->CreateAnd(LAnd->getOperand(0), Mask);
|
||||
} else if (LAnd->getOperand(1) == RAnd->getOperand(1) &&
|
||||
isKnownToBeAPowerOfTwo(LAnd->getOperand(0), DL, false, 0, &AC,
|
||||
CxtI, &DT) &&
|
||||
isKnownToBeAPowerOfTwo(RAnd->getOperand(0), DL, false, 0, &AC,
|
||||
CxtI, &DT)) {
|
||||
isKnownToBeAPowerOfTwo(LAnd->getOperand(0), DL, false, 0, CxtI,
|
||||
&DT) &&
|
||||
isKnownToBeAPowerOfTwo(RAnd->getOperand(0), DL, false, 0, CxtI,
|
||||
&DT)) {
|
||||
Mask = Builder->CreateOr(LAnd->getOperand(0), RAnd->getOperand(0));
|
||||
Masked = Builder->CreateAnd(LAnd->getOperand(1), Mask);
|
||||
}
|
||||
@ -2081,7 +2081,7 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
|
||||
if (Value *V = SimplifyVectorOp(I))
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
if (Value *V = SimplifyOrInst(Op0, Op1, DL, &TLI, &DT, &AC))
|
||||
if (Value *V = SimplifyOrInst(Op0, Op1, DL, &TLI, &DT))
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
// (A&B)|(A&C) -> A&(B|C) etc
|
||||
@ -2434,7 +2434,7 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
|
||||
if (Value *V = SimplifyVectorOp(I))
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
if (Value *V = SimplifyXorInst(Op0, Op1, DL, &TLI, &DT, &AC))
|
||||
if (Value *V = SimplifyXorInst(Op0, Op1, DL, &TLI, &DT))
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
// (A&B)^(A&C) -> A&(B^C) etc
|
||||
|
@ -109,8 +109,8 @@ static Constant *getNegativeIsTrueBoolVec(ConstantDataVector *V) {
|
||||
}
|
||||
|
||||
Instruction *InstCombiner::SimplifyMemTransfer(MemIntrinsic *MI) {
|
||||
unsigned DstAlign = getKnownAlignment(MI->getArgOperand(0), DL, MI, &AC, &DT);
|
||||
unsigned SrcAlign = getKnownAlignment(MI->getArgOperand(1), DL, MI, &AC, &DT);
|
||||
unsigned DstAlign = getKnownAlignment(MI->getArgOperand(0), DL, MI, &DT);
|
||||
unsigned SrcAlign = getKnownAlignment(MI->getArgOperand(1), DL, MI, &DT);
|
||||
unsigned MinAlign = std::min(DstAlign, SrcAlign);
|
||||
unsigned CopyAlign = MI->getAlignment();
|
||||
|
||||
@ -210,7 +210,7 @@ Instruction *InstCombiner::SimplifyMemTransfer(MemIntrinsic *MI) {
|
||||
}
|
||||
|
||||
Instruction *InstCombiner::SimplifyMemSet(MemSetInst *MI) {
|
||||
unsigned Alignment = getKnownAlignment(MI->getDest(), DL, MI, &AC, &DT);
|
||||
unsigned Alignment = getKnownAlignment(MI->getDest(), DL, MI, &DT);
|
||||
if (MI->getAlignment() < Alignment) {
|
||||
MI->setAlignment(ConstantInt::get(MI->getAlignmentType(),
|
||||
Alignment, false));
|
||||
@ -1358,7 +1358,7 @@ Instruction *InstCombiner::visitVACopyInst(VACopyInst &I) {
|
||||
Instruction *InstCombiner::visitCallInst(CallInst &CI) {
|
||||
auto Args = CI.arg_operands();
|
||||
if (Value *V = SimplifyCall(CI.getCalledValue(), Args.begin(), Args.end(), DL,
|
||||
&TLI, &DT, &AC))
|
||||
&TLI, &DT))
|
||||
return replaceInstUsesWith(CI, V);
|
||||
|
||||
if (isFreeCall(&CI, &TLI))
|
||||
@ -1558,7 +1558,7 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
|
||||
case Intrinsic::ppc_altivec_lvx:
|
||||
case Intrinsic::ppc_altivec_lvxl:
|
||||
// Turn PPC lvx -> load if the pointer is known aligned.
|
||||
if (getOrEnforceKnownAlignment(II->getArgOperand(0), 16, DL, II, &AC,
|
||||
if (getOrEnforceKnownAlignment(II->getArgOperand(0), 16, DL, II,
|
||||
&DT) >= 16) {
|
||||
Value *Ptr = Builder->CreateBitCast(II->getArgOperand(0),
|
||||
PointerType::getUnqual(II->getType()));
|
||||
@ -1575,7 +1575,7 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
|
||||
case Intrinsic::ppc_altivec_stvx:
|
||||
case Intrinsic::ppc_altivec_stvxl:
|
||||
// Turn stvx -> store if the pointer is known aligned.
|
||||
if (getOrEnforceKnownAlignment(II->getArgOperand(1), 16, DL, II, &AC,
|
||||
if (getOrEnforceKnownAlignment(II->getArgOperand(1), 16, DL, II,
|
||||
&DT) >= 16) {
|
||||
Type *OpPtrTy =
|
||||
PointerType::getUnqual(II->getArgOperand(0)->getType());
|
||||
@ -1592,7 +1592,7 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
|
||||
}
|
||||
case Intrinsic::ppc_qpx_qvlfs:
|
||||
// Turn PPC QPX qvlfs -> load if the pointer is known aligned.
|
||||
if (getOrEnforceKnownAlignment(II->getArgOperand(0), 16, DL, II, &AC,
|
||||
if (getOrEnforceKnownAlignment(II->getArgOperand(0), 16, DL, II,
|
||||
&DT) >= 16) {
|
||||
Type *VTy = VectorType::get(Builder->getFloatTy(),
|
||||
II->getType()->getVectorNumElements());
|
||||
@ -1604,7 +1604,7 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
|
||||
break;
|
||||
case Intrinsic::ppc_qpx_qvlfd:
|
||||
// Turn PPC QPX qvlfd -> load if the pointer is known aligned.
|
||||
if (getOrEnforceKnownAlignment(II->getArgOperand(0), 32, DL, II, &AC,
|
||||
if (getOrEnforceKnownAlignment(II->getArgOperand(0), 32, DL, II,
|
||||
&DT) >= 32) {
|
||||
Value *Ptr = Builder->CreateBitCast(II->getArgOperand(0),
|
||||
PointerType::getUnqual(II->getType()));
|
||||
@ -1613,7 +1613,7 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
|
||||
break;
|
||||
case Intrinsic::ppc_qpx_qvstfs:
|
||||
// Turn PPC QPX qvstfs -> store if the pointer is known aligned.
|
||||
if (getOrEnforceKnownAlignment(II->getArgOperand(1), 16, DL, II, &AC,
|
||||
if (getOrEnforceKnownAlignment(II->getArgOperand(1), 16, DL, II,
|
||||
&DT) >= 16) {
|
||||
Type *VTy = VectorType::get(Builder->getFloatTy(),
|
||||
II->getArgOperand(0)->getType()->getVectorNumElements());
|
||||
@ -1625,7 +1625,7 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
|
||||
break;
|
||||
case Intrinsic::ppc_qpx_qvstfd:
|
||||
// Turn PPC QPX qvstfd -> store if the pointer is known aligned.
|
||||
if (getOrEnforceKnownAlignment(II->getArgOperand(1), 32, DL, II, &AC,
|
||||
if (getOrEnforceKnownAlignment(II->getArgOperand(1), 32, DL, II,
|
||||
&DT) >= 32) {
|
||||
Type *OpPtrTy =
|
||||
PointerType::getUnqual(II->getArgOperand(0)->getType());
|
||||
@ -2239,7 +2239,7 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
|
||||
case Intrinsic::arm_neon_vst3lane:
|
||||
case Intrinsic::arm_neon_vst4lane: {
|
||||
unsigned MemAlign =
|
||||
getKnownAlignment(II->getArgOperand(0), DL, II, &AC, &DT);
|
||||
getKnownAlignment(II->getArgOperand(0), DL, II, &DT);
|
||||
unsigned AlignArg = II->getNumArgOperands() - 1;
|
||||
ConstantInt *IntrAlign = dyn_cast<ConstantInt>(II->getArgOperand(AlignArg));
|
||||
if (IntrAlign && IntrAlign->getZExtValue() < MemAlign) {
|
||||
|
@ -4122,7 +4122,7 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
|
||||
}
|
||||
|
||||
if (Value *V =
|
||||
SimplifyICmpInst(I.getPredicate(), Op0, Op1, DL, &TLI, &DT, &AC, &I))
|
||||
SimplifyICmpInst(I.getPredicate(), Op0, Op1, DL, &TLI, &DT, &I))
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
// comparing -val or val with non-zero is the same as just comparing val
|
||||
@ -4284,7 +4284,7 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
|
||||
// if A is a power of 2.
|
||||
if (match(Op0, m_And(m_Value(A), m_Not(m_Value(B)))) &&
|
||||
match(Op1, m_Zero()) &&
|
||||
isKnownToBeAPowerOfTwo(A, DL, false, 0, &AC, &I, &DT) && I.isEquality())
|
||||
isKnownToBeAPowerOfTwo(A, DL, false, 0, &I, &DT) && I.isEquality())
|
||||
return new ICmpInst(I.getInversePredicate(),
|
||||
Builder->CreateAnd(A, B),
|
||||
Op1);
|
||||
@ -4607,7 +4607,7 @@ Instruction *InstCombiner::visitFCmpInst(FCmpInst &I) {
|
||||
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
|
||||
|
||||
if (Value *V = SimplifyFCmpInst(I.getPredicate(), Op0, Op1,
|
||||
I.getFastMathFlags(), DL, &TLI, &DT, &AC, &I))
|
||||
I.getFastMathFlags(), DL, &TLI, &DT, &I))
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
// Simplify 'fcmp pred X, X'
|
||||
|
@ -16,7 +16,6 @@
|
||||
#define LLVM_LIB_TRANSFORMS_INSTCOMBINE_INSTCOMBINEINTERNAL_H
|
||||
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Analysis/TargetFolder.h"
|
||||
#include "llvm/Analysis/ValueTracking.h"
|
||||
@ -179,7 +178,6 @@ private:
|
||||
AliasAnalysis *AA;
|
||||
|
||||
// Required analyses.
|
||||
AssumptionCache &AC;
|
||||
TargetLibraryInfo &TLI;
|
||||
DominatorTree &DT;
|
||||
const DataLayout &DL;
|
||||
@ -193,19 +191,17 @@ private:
|
||||
public:
|
||||
InstCombiner(InstCombineWorklist &Worklist, BuilderTy *Builder,
|
||||
bool MinimizeSize, bool ExpensiveCombines, AliasAnalysis *AA,
|
||||
AssumptionCache &AC, TargetLibraryInfo &TLI,
|
||||
DominatorTree &DT, const DataLayout &DL, LoopInfo *LI)
|
||||
TargetLibraryInfo &TLI, DominatorTree &DT, const DataLayout &DL,
|
||||
LoopInfo *LI)
|
||||
: Worklist(Worklist), Builder(Builder), MinimizeSize(MinimizeSize),
|
||||
ExpensiveCombines(ExpensiveCombines), AA(AA), AC(AC), TLI(TLI), DT(DT),
|
||||
DL(DL), LI(LI), MadeIRChange(false) {}
|
||||
ExpensiveCombines(ExpensiveCombines), AA(AA), TLI(TLI), DT(DT), DL(DL),
|
||||
LI(LI), MadeIRChange(false) {}
|
||||
|
||||
/// \brief Run the combiner over the entire worklist until it is empty.
|
||||
///
|
||||
/// \returns true if the IR is changed.
|
||||
bool run();
|
||||
|
||||
AssumptionCache &getAssumptionCache() const { return AC; }
|
||||
|
||||
const DataLayout &getDataLayout() const { return DL; }
|
||||
|
||||
DominatorTree &getDominatorTree() const { return DT; }
|
||||
@ -475,30 +471,28 @@ public:
|
||||
|
||||
void computeKnownBits(Value *V, APInt &KnownZero, APInt &KnownOne,
|
||||
unsigned Depth, Instruction *CxtI) const {
|
||||
return llvm::computeKnownBits(V, KnownZero, KnownOne, DL, Depth, &AC, CxtI,
|
||||
&DT);
|
||||
return llvm::computeKnownBits(V, KnownZero, KnownOne, DL, Depth, CxtI, &DT);
|
||||
}
|
||||
|
||||
bool MaskedValueIsZero(Value *V, const APInt &Mask, unsigned Depth = 0,
|
||||
Instruction *CxtI = nullptr) const {
|
||||
return llvm::MaskedValueIsZero(V, Mask, DL, Depth, &AC, CxtI, &DT);
|
||||
return llvm::MaskedValueIsZero(V, Mask, DL, Depth, CxtI, &DT);
|
||||
}
|
||||
unsigned ComputeNumSignBits(Value *Op, unsigned Depth = 0,
|
||||
Instruction *CxtI = nullptr) const {
|
||||
return llvm::ComputeNumSignBits(Op, DL, Depth, &AC, CxtI, &DT);
|
||||
return llvm::ComputeNumSignBits(Op, DL, Depth, CxtI, &DT);
|
||||
}
|
||||
void ComputeSignBit(Value *V, bool &KnownZero, bool &KnownOne,
|
||||
unsigned Depth = 0, Instruction *CxtI = nullptr) const {
|
||||
return llvm::ComputeSignBit(V, KnownZero, KnownOne, DL, Depth, &AC, CxtI,
|
||||
&DT);
|
||||
return llvm::ComputeSignBit(V, KnownZero, KnownOne, DL, Depth, CxtI, &DT);
|
||||
}
|
||||
OverflowResult computeOverflowForUnsignedMul(Value *LHS, Value *RHS,
|
||||
const Instruction *CxtI) {
|
||||
return llvm::computeOverflowForUnsignedMul(LHS, RHS, DL, &AC, CxtI, &DT);
|
||||
return llvm::computeOverflowForUnsignedMul(LHS, RHS, DL, CxtI, &DT);
|
||||
}
|
||||
OverflowResult computeOverflowForUnsignedAdd(Value *LHS, Value *RHS,
|
||||
const Instruction *CxtI) {
|
||||
return llvm::computeOverflowForUnsignedAdd(LHS, RHS, DL, &AC, CxtI, &DT);
|
||||
return llvm::computeOverflowForUnsignedAdd(LHS, RHS, DL, CxtI, &DT);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -286,7 +286,7 @@ Instruction *InstCombiner::visitAllocaInst(AllocaInst &AI) {
|
||||
SmallVector<Instruction *, 4> ToDelete;
|
||||
if (MemTransferInst *Copy = isOnlyCopiedFromConstantGlobal(&AI, ToDelete)) {
|
||||
unsigned SourceAlign = getOrEnforceKnownAlignment(
|
||||
Copy->getSource(), AI.getAlignment(), DL, &AI, &AC, &DT);
|
||||
Copy->getSource(), AI.getAlignment(), DL, &AI, &DT);
|
||||
if (AI.getAlignment() <= SourceAlign) {
|
||||
DEBUG(dbgs() << "Found alloca equal to global: " << AI << '\n');
|
||||
DEBUG(dbgs() << " memcpy = " << *Copy << '\n');
|
||||
@ -826,7 +826,7 @@ Instruction *InstCombiner::visitLoadInst(LoadInst &LI) {
|
||||
|
||||
// Attempt to improve the alignment.
|
||||
unsigned KnownAlign = getOrEnforceKnownAlignment(
|
||||
Op, DL.getPrefTypeAlignment(LI.getType()), DL, &LI, &AC, &DT);
|
||||
Op, DL.getPrefTypeAlignment(LI.getType()), DL, &LI, &DT);
|
||||
unsigned LoadAlign = LI.getAlignment();
|
||||
unsigned EffectiveLoadAlign =
|
||||
LoadAlign != 0 ? LoadAlign : DL.getABITypeAlignment(LI.getType());
|
||||
@ -1199,7 +1199,7 @@ Instruction *InstCombiner::visitStoreInst(StoreInst &SI) {
|
||||
|
||||
// Attempt to improve the alignment.
|
||||
unsigned KnownAlign = getOrEnforceKnownAlignment(
|
||||
Ptr, DL.getPrefTypeAlignment(Val->getType()), DL, &SI, &AC, &DT);
|
||||
Ptr, DL.getPrefTypeAlignment(Val->getType()), DL, &SI, &DT);
|
||||
unsigned StoreAlign = SI.getAlignment();
|
||||
unsigned EffectiveStoreAlign =
|
||||
StoreAlign != 0 ? StoreAlign : DL.getABITypeAlignment(Val->getType());
|
||||
|
@ -48,8 +48,7 @@ static Value *simplifyValueKnownNonZero(Value *V, InstCombiner &IC,
|
||||
BinaryOperator *I = dyn_cast<BinaryOperator>(V);
|
||||
if (I && I->isLogicalShift() &&
|
||||
isKnownToBeAPowerOfTwo(I->getOperand(0), IC.getDataLayout(), false, 0,
|
||||
&IC.getAssumptionCache(), &CxtI,
|
||||
&IC.getDominatorTree())) {
|
||||
&CxtI, &IC.getDominatorTree())) {
|
||||
// We know that this is an exact/nuw shift and that the input is a
|
||||
// non-zero context as well.
|
||||
if (Value *V2 = simplifyValueKnownNonZero(I->getOperand(0), IC, CxtI)) {
|
||||
@ -179,7 +178,7 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
|
||||
if (Value *V = SimplifyVectorOp(I))
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
if (Value *V = SimplifyMulInst(Op0, Op1, DL, &TLI, &DT, &AC))
|
||||
if (Value *V = SimplifyMulInst(Op0, Op1, DL, &TLI, &DT))
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
if (Value *V = SimplifyUsingDistributiveLaws(I))
|
||||
@ -545,7 +544,7 @@ Instruction *InstCombiner::visitFMul(BinaryOperator &I) {
|
||||
std::swap(Op0, Op1);
|
||||
|
||||
if (Value *V =
|
||||
SimplifyFMulInst(Op0, Op1, I.getFastMathFlags(), DL, &TLI, &DT, &AC))
|
||||
SimplifyFMulInst(Op0, Op1, I.getFastMathFlags(), DL, &TLI, &DT))
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
bool AllowReassociate = I.hasUnsafeAlgebra();
|
||||
@ -1061,7 +1060,7 @@ Instruction *InstCombiner::visitUDiv(BinaryOperator &I) {
|
||||
if (Value *V = SimplifyVectorOp(I))
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
if (Value *V = SimplifyUDivInst(Op0, Op1, DL, &TLI, &DT, &AC))
|
||||
if (Value *V = SimplifyUDivInst(Op0, Op1, DL, &TLI, &DT))
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
// Handle the integer div common cases
|
||||
@ -1134,7 +1133,7 @@ Instruction *InstCombiner::visitSDiv(BinaryOperator &I) {
|
||||
if (Value *V = SimplifyVectorOp(I))
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
if (Value *V = SimplifySDivInst(Op0, Op1, DL, &TLI, &DT, &AC))
|
||||
if (Value *V = SimplifySDivInst(Op0, Op1, DL, &TLI, &DT))
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
// Handle the integer div common cases
|
||||
@ -1197,7 +1196,7 @@ Instruction *InstCombiner::visitSDiv(BinaryOperator &I) {
|
||||
return BO;
|
||||
}
|
||||
|
||||
if (isKnownToBeAPowerOfTwo(Op1, DL, /*OrZero*/ true, 0, &AC, &I, &DT)) {
|
||||
if (isKnownToBeAPowerOfTwo(Op1, DL, /*OrZero*/ true, 0, &I, &DT)) {
|
||||
// X sdiv (1 << Y) -> X udiv (1 << Y) ( -> X u>> Y)
|
||||
// Safe because the only negative value (1 << Y) can take on is
|
||||
// INT_MIN, and X sdiv INT_MIN == X udiv INT_MIN == 0 if X doesn't have
|
||||
@ -1249,7 +1248,7 @@ Instruction *InstCombiner::visitFDiv(BinaryOperator &I) {
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
if (Value *V = SimplifyFDivInst(Op0, Op1, I.getFastMathFlags(),
|
||||
DL, &TLI, &DT, &AC))
|
||||
DL, &TLI, &DT))
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
if (isa<Constant>(Op0))
|
||||
@ -1423,7 +1422,7 @@ Instruction *InstCombiner::visitURem(BinaryOperator &I) {
|
||||
if (Value *V = SimplifyVectorOp(I))
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
if (Value *V = SimplifyURemInst(Op0, Op1, DL, &TLI, &DT, &AC))
|
||||
if (Value *V = SimplifyURemInst(Op0, Op1, DL, &TLI, &DT))
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
if (Instruction *common = commonIRemTransforms(I))
|
||||
@ -1436,7 +1435,7 @@ Instruction *InstCombiner::visitURem(BinaryOperator &I) {
|
||||
I.getType());
|
||||
|
||||
// X urem Y -> X and Y-1, where Y is a power of 2,
|
||||
if (isKnownToBeAPowerOfTwo(Op1, DL, /*OrZero*/ true, 0, &AC, &I, &DT)) {
|
||||
if (isKnownToBeAPowerOfTwo(Op1, DL, /*OrZero*/ true, 0, &I, &DT)) {
|
||||
Constant *N1 = Constant::getAllOnesValue(I.getType());
|
||||
Value *Add = Builder->CreateAdd(Op1, N1);
|
||||
return BinaryOperator::CreateAnd(Op0, Add);
|
||||
@ -1466,7 +1465,7 @@ Instruction *InstCombiner::visitSRem(BinaryOperator &I) {
|
||||
if (Value *V = SimplifyVectorOp(I))
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
if (Value *V = SimplifySRemInst(Op0, Op1, DL, &TLI, &DT, &AC))
|
||||
if (Value *V = SimplifySRemInst(Op0, Op1, DL, &TLI, &DT))
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
// Handle the integer rem common cases
|
||||
@ -1542,7 +1541,7 @@ Instruction *InstCombiner::visitFRem(BinaryOperator &I) {
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
if (Value *V = SimplifyFRemInst(Op0, Op1, I.getFastMathFlags(),
|
||||
DL, &TLI, &DT, &AC))
|
||||
DL, &TLI, &DT))
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
// Handle cases involving: rem X, (select Cond, Y, Z)
|
||||
|
@ -880,7 +880,7 @@ Instruction *InstCombiner::SliceUpIllegalIntegerPHI(PHINode &FirstPhi) {
|
||||
// PHINode simplification
|
||||
//
|
||||
Instruction *InstCombiner::visitPHINode(PHINode &PN) {
|
||||
if (Value *V = SimplifyInstruction(&PN, DL, &TLI, &DT, &AC))
|
||||
if (Value *V = SimplifyInstruction(&PN, DL, &TLI, &DT))
|
||||
return replaceInstUsesWith(PN, V);
|
||||
|
||||
if (Instruction *Result = FoldPHIArgZextsIntoPHI(PN))
|
||||
@ -937,7 +937,7 @@ Instruction *InstCombiner::visitPHINode(PHINode &PN) {
|
||||
for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
|
||||
Instruction *CtxI = PN.getIncomingBlock(i)->getTerminator();
|
||||
Value *VA = PN.getIncomingValue(i);
|
||||
if (isKnownNonZero(VA, DL, 0, &AC, CtxI, &DT)) {
|
||||
if (isKnownNonZero(VA, DL, 0, CtxI, &DT)) {
|
||||
if (!NonZeroConst)
|
||||
NonZeroConst = GetAnyNonZeroConstInt(PN);
|
||||
PN.setIncomingValue(i, NonZeroConst);
|
||||
|
@ -1101,7 +1101,7 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
|
||||
Type *SelType = SI.getType();
|
||||
|
||||
if (Value *V =
|
||||
SimplifySelectInst(CondVal, TrueVal, FalseVal, DL, &TLI, &DT, &AC))
|
||||
SimplifySelectInst(CondVal, TrueVal, FalseVal, DL, &TLI, &DT))
|
||||
return replaceInstUsesWith(SI, V);
|
||||
|
||||
if (Instruction *I = canonicalizeSelectToShuffle(SI))
|
||||
|
@ -722,7 +722,7 @@ Instruction *InstCombiner::visitShl(BinaryOperator &I) {
|
||||
|
||||
if (Value *V =
|
||||
SimplifyShlInst(I.getOperand(0), I.getOperand(1), I.hasNoSignedWrap(),
|
||||
I.hasNoUnsignedWrap(), DL, &TLI, &DT, &AC))
|
||||
I.hasNoUnsignedWrap(), DL, &TLI, &DT))
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
if (Instruction *V = commonShiftTransforms(I))
|
||||
@ -763,7 +763,7 @@ Instruction *InstCombiner::visitLShr(BinaryOperator &I) {
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
if (Value *V = SimplifyLShrInst(I.getOperand(0), I.getOperand(1), I.isExact(),
|
||||
DL, &TLI, &DT, &AC))
|
||||
DL, &TLI, &DT))
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
if (Instruction *R = commonShiftTransforms(I))
|
||||
@ -807,7 +807,7 @@ Instruction *InstCombiner::visitAShr(BinaryOperator &I) {
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
if (Value *V = SimplifyAShrInst(I.getOperand(0), I.getOperand(1), I.isExact(),
|
||||
DL, &TLI, &DT, &AC))
|
||||
DL, &TLI, &DT))
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
if (Instruction *R = commonShiftTransforms(I))
|
||||
|
@ -145,7 +145,7 @@ Instruction *InstCombiner::scalarizePHI(ExtractElementInst &EI, PHINode *PN) {
|
||||
|
||||
Instruction *InstCombiner::visitExtractElementInst(ExtractElementInst &EI) {
|
||||
if (Value *V = SimplifyExtractElementInst(
|
||||
EI.getVectorOperand(), EI.getIndexOperand(), DL, &TLI, &DT, &AC))
|
||||
EI.getVectorOperand(), EI.getIndexOperand(), DL, &TLI, &DT))
|
||||
return replaceInstUsesWith(EI, V);
|
||||
|
||||
// If vector val is constant with all elements the same, replace EI with
|
||||
|
@ -40,7 +40,6 @@
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
||||
#include "llvm/Analysis/CFG.h"
|
||||
#include "llvm/Analysis/ConstantFolding.h"
|
||||
@ -683,14 +682,14 @@ Value *InstCombiner::SimplifyUsingDistributiveLaws(BinaryOperator &I) {
|
||||
if (SI0->getCondition() == SI1->getCondition()) {
|
||||
Value *SI = nullptr;
|
||||
if (Value *V = SimplifyBinOp(TopLevelOpcode, SI0->getFalseValue(),
|
||||
SI1->getFalseValue(), DL, &TLI, &DT, &AC))
|
||||
SI1->getFalseValue(), DL, &TLI, &DT))
|
||||
SI = Builder->CreateSelect(SI0->getCondition(),
|
||||
Builder->CreateBinOp(TopLevelOpcode,
|
||||
SI0->getTrueValue(),
|
||||
SI1->getTrueValue()),
|
||||
V);
|
||||
if (Value *V = SimplifyBinOp(TopLevelOpcode, SI0->getTrueValue(),
|
||||
SI1->getTrueValue(), DL, &TLI, &DT, &AC))
|
||||
SI1->getTrueValue(), DL, &TLI, &DT))
|
||||
SI = Builder->CreateSelect(
|
||||
SI0->getCondition(), V,
|
||||
Builder->CreateBinOp(TopLevelOpcode, SI0->getFalseValue(),
|
||||
@ -1374,7 +1373,7 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
|
||||
SmallVector<Value*, 8> Ops(GEP.op_begin(), GEP.op_end());
|
||||
|
||||
if (Value *V =
|
||||
SimplifyGEPInst(GEP.getSourceElementType(), Ops, DL, &TLI, &DT, &AC))
|
||||
SimplifyGEPInst(GEP.getSourceElementType(), Ops, DL, &TLI, &DT))
|
||||
return replaceInstUsesWith(GEP, V);
|
||||
|
||||
Value *PtrOp = GEP.getOperand(0);
|
||||
@ -2289,7 +2288,7 @@ Instruction *InstCombiner::visitExtractValueInst(ExtractValueInst &EV) {
|
||||
return replaceInstUsesWith(EV, Agg);
|
||||
|
||||
if (Value *V =
|
||||
SimplifyExtractValueInst(Agg, EV.getIndices(), DL, &TLI, &DT, &AC))
|
||||
SimplifyExtractValueInst(Agg, EV.getIndices(), DL, &TLI, &DT))
|
||||
return replaceInstUsesWith(EV, V);
|
||||
|
||||
if (InsertValueInst *IV = dyn_cast<InsertValueInst>(Agg)) {
|
||||
@ -3115,8 +3114,8 @@ static bool prepareICWorklistFromFunction(Function &F, const DataLayout &DL,
|
||||
|
||||
static bool
|
||||
combineInstructionsOverFunction(Function &F, InstCombineWorklist &Worklist,
|
||||
AliasAnalysis *AA, AssumptionCache &AC,
|
||||
TargetLibraryInfo &TLI, DominatorTree &DT,
|
||||
AliasAnalysis *AA, TargetLibraryInfo &TLI,
|
||||
DominatorTree &DT,
|
||||
bool ExpensiveCombines = true,
|
||||
LoopInfo *LI = nullptr) {
|
||||
auto &DL = F.getParent()->getDataLayout();
|
||||
@ -3126,12 +3125,8 @@ combineInstructionsOverFunction(Function &F, InstCombineWorklist &Worklist,
|
||||
/// instructions into the worklist when they are created.
|
||||
IRBuilder<TargetFolder, IRBuilderCallbackInserter> Builder(
|
||||
F.getContext(), TargetFolder(DL),
|
||||
IRBuilderCallbackInserter([&Worklist, &AC](Instruction *I) {
|
||||
IRBuilderCallbackInserter([&Worklist](Instruction *I) {
|
||||
Worklist.Add(I);
|
||||
|
||||
using namespace llvm::PatternMatch;
|
||||
if (match(I, m_Intrinsic<Intrinsic::assume>()))
|
||||
AC.registerAssumption(cast<CallInst>(I));
|
||||
}));
|
||||
|
||||
// Lower dbg.declare intrinsics otherwise their value may be clobbered
|
||||
@ -3148,7 +3143,7 @@ combineInstructionsOverFunction(Function &F, InstCombineWorklist &Worklist,
|
||||
bool Changed = prepareICWorklistFromFunction(F, DL, &TLI, Worklist);
|
||||
|
||||
InstCombiner IC(Worklist, &Builder, F.optForMinSize(), ExpensiveCombines,
|
||||
AA, AC, TLI, DT, DL, LI);
|
||||
AA, TLI, DT, DL, LI);
|
||||
Changed |= IC.run();
|
||||
|
||||
if (!Changed)
|
||||
@ -3160,14 +3155,13 @@ combineInstructionsOverFunction(Function &F, InstCombineWorklist &Worklist,
|
||||
|
||||
PreservedAnalyses InstCombinePass::run(Function &F,
|
||||
FunctionAnalysisManager &AM) {
|
||||
auto &AC = AM.getResult<AssumptionAnalysis>(F);
|
||||
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
|
||||
auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
|
||||
|
||||
auto *LI = AM.getCachedResult<LoopAnalysis>(F);
|
||||
|
||||
// FIXME: The AliasAnalysis is not yet supported in the new pass manager
|
||||
if (!combineInstructionsOverFunction(F, Worklist, nullptr, AC, TLI, DT,
|
||||
if (!combineInstructionsOverFunction(F, Worklist, nullptr, TLI, DT,
|
||||
ExpensiveCombines, LI))
|
||||
// No changes, all analyses are preserved.
|
||||
return PreservedAnalyses::all();
|
||||
@ -3182,7 +3176,6 @@ PreservedAnalyses InstCombinePass::run(Function &F,
|
||||
void InstructionCombiningPass::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.setPreservesCFG();
|
||||
AU.addRequired<AAResultsWrapperPass>();
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
AU.addRequired<TargetLibraryInfoWrapperPass>();
|
||||
AU.addRequired<DominatorTreeWrapperPass>();
|
||||
AU.addPreserved<DominatorTreeWrapperPass>();
|
||||
@ -3197,7 +3190,6 @@ bool InstructionCombiningPass::runOnFunction(Function &F) {
|
||||
|
||||
// Required analyses.
|
||||
auto AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
|
||||
auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
|
||||
auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
|
||||
auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||
|
||||
@ -3205,14 +3197,13 @@ bool InstructionCombiningPass::runOnFunction(Function &F) {
|
||||
auto *LIWP = getAnalysisIfAvailable<LoopInfoWrapperPass>();
|
||||
auto *LI = LIWP ? &LIWP->getLoopInfo() : nullptr;
|
||||
|
||||
return combineInstructionsOverFunction(F, Worklist, AA, AC, TLI, DT,
|
||||
return combineInstructionsOverFunction(F, Worklist, AA, TLI, DT,
|
||||
ExpensiveCombines, LI);
|
||||
}
|
||||
|
||||
char InstructionCombiningPass::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(InstructionCombiningPass, "instcombine",
|
||||
"Combine redundant instructions", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/GlobalsModRef.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
|
||||
#include "llvm/Analysis/ValueTracking.h"
|
||||
@ -54,7 +53,6 @@ struct AlignmentFromAssumptions : public FunctionPass {
|
||||
bool runOnFunction(Function &F) override;
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
AU.addRequired<ScalarEvolutionWrapperPass>();
|
||||
AU.addRequired<DominatorTreeWrapperPass>();
|
||||
|
||||
@ -74,7 +72,6 @@ char AlignmentFromAssumptions::ID = 0;
|
||||
static const char aip_name[] = "Alignment from assumptions";
|
||||
INITIALIZE_PASS_BEGIN(AlignmentFromAssumptions, AA_NAME,
|
||||
aip_name, false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
|
||||
INITIALIZE_PASS_END(AlignmentFromAssumptions, AA_NAME,
|
||||
@ -408,15 +405,13 @@ bool AlignmentFromAssumptions::runOnFunction(Function &F) {
|
||||
if (skipFunction(F))
|
||||
return false;
|
||||
|
||||
auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
|
||||
ScalarEvolution *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
|
||||
DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||
|
||||
return Impl.runImpl(F, AC, SE, DT);
|
||||
return Impl.runImpl(F, SE, DT);
|
||||
}
|
||||
|
||||
bool AlignmentFromAssumptionsPass::runImpl(Function &F, AssumptionCache &AC,
|
||||
ScalarEvolution *SE_,
|
||||
bool AlignmentFromAssumptionsPass::runImpl(Function &F, ScalarEvolution *SE_,
|
||||
DominatorTree *DT_) {
|
||||
SE = SE_;
|
||||
DT = DT_;
|
||||
@ -438,10 +433,9 @@ bool AlignmentFromAssumptionsPass::runImpl(Function &F, AssumptionCache &AC,
|
||||
PreservedAnalyses
|
||||
AlignmentFromAssumptionsPass::run(Function &F, FunctionAnalysisManager &AM) {
|
||||
|
||||
AssumptionCache &AC = AM.getResult<AssumptionAnalysis>(F);
|
||||
ScalarEvolution &SE = AM.getResult<ScalarEvolutionAnalysis>(F);
|
||||
DominatorTree &DT = AM.getResult<DominatorTreeAnalysis>(F);
|
||||
bool Changed = runImpl(F, AC, &SE, &DT);
|
||||
bool Changed = runImpl(F, &SE, &DT);
|
||||
|
||||
// FIXME: We need to invalidate this to avoid PR28400. Is there a better
|
||||
// solution?
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include "llvm/ADT/Hashing.h"
|
||||
#include "llvm/ADT/ScopedHashTable.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/GlobalsModRef.h"
|
||||
#include "llvm/Analysis/InstructionSimplify.h"
|
||||
#include "llvm/Analysis/TargetLibraryInfo.h"
|
||||
@ -251,7 +250,6 @@ public:
|
||||
const TargetLibraryInfo &TLI;
|
||||
const TargetTransformInfo &TTI;
|
||||
DominatorTree &DT;
|
||||
AssumptionCache &AC;
|
||||
MemorySSA *MSSA;
|
||||
typedef RecyclingAllocator<
|
||||
BumpPtrAllocator, ScopedHashTableVal<SimpleValue, Value *>> AllocatorTy;
|
||||
@ -314,8 +312,8 @@ public:
|
||||
|
||||
/// \brief Set up the EarlyCSE runner for a particular function.
|
||||
EarlyCSE(const TargetLibraryInfo &TLI, const TargetTransformInfo &TTI,
|
||||
DominatorTree &DT, AssumptionCache &AC, MemorySSA *MSSA)
|
||||
: TLI(TLI), TTI(TTI), DT(DT), AC(AC), MSSA(MSSA), CurrentGeneration(0) {}
|
||||
DominatorTree &DT, MemorySSA *MSSA)
|
||||
: TLI(TLI), TTI(TTI), DT(DT), MSSA(MSSA), CurrentGeneration(0) {}
|
||||
|
||||
bool run();
|
||||
|
||||
@ -672,7 +670,7 @@ bool EarlyCSE::processNode(DomTreeNode *Node) {
|
||||
|
||||
// If the instruction can be simplified (e.g. X+0 = X) then replace it with
|
||||
// its simpler value.
|
||||
if (Value *V = SimplifyInstruction(Inst, DL, &TLI, &DT, &AC)) {
|
||||
if (Value *V = SimplifyInstruction(Inst, DL, &TLI, &DT)) {
|
||||
DEBUG(dbgs() << "EarlyCSE Simplify: " << *Inst << " to: " << *V << '\n');
|
||||
bool Killed = false;
|
||||
if (!Inst->use_empty()) {
|
||||
@ -958,11 +956,10 @@ PreservedAnalyses EarlyCSEPass::run(Function &F,
|
||||
auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
|
||||
auto &TTI = AM.getResult<TargetIRAnalysis>(F);
|
||||
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
|
||||
auto &AC = AM.getResult<AssumptionAnalysis>(F);
|
||||
auto *MSSA =
|
||||
UseMemorySSA ? &AM.getResult<MemorySSAAnalysis>(F).getMSSA() : nullptr;
|
||||
|
||||
EarlyCSE CSE(TLI, TTI, DT, AC, MSSA);
|
||||
EarlyCSE CSE(TLI, TTI, DT, MSSA);
|
||||
|
||||
if (!CSE.run())
|
||||
return PreservedAnalyses::all();
|
||||
@ -1004,17 +1001,15 @@ public:
|
||||
auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
|
||||
auto &TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
|
||||
auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||
auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
|
||||
auto *MSSA =
|
||||
UseMemorySSA ? &getAnalysis<MemorySSAWrapperPass>().getMSSA() : nullptr;
|
||||
|
||||
EarlyCSE CSE(TLI, TTI, DT, AC, MSSA);
|
||||
EarlyCSE CSE(TLI, TTI, DT, MSSA);
|
||||
|
||||
return CSE.run();
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
AU.addRequired<DominatorTreeWrapperPass>();
|
||||
AU.addRequired<TargetLibraryInfoWrapperPass>();
|
||||
AU.addRequired<TargetTransformInfoWrapperPass>();
|
||||
@ -1036,7 +1031,6 @@ char EarlyCSELegacyPass::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(EarlyCSELegacyPass, "early-cse", "Early CSE", false,
|
||||
false)
|
||||
INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
|
||||
INITIALIZE_PASS_END(EarlyCSELegacyPass, "early-cse", "Early CSE", false, false)
|
||||
@ -1057,7 +1051,6 @@ FunctionPass *llvm::createEarlyCSEPass(bool UseMemorySSA) {
|
||||
INITIALIZE_PASS_BEGIN(EarlyCSEMemSSALegacyPass, "early-cse-memssa",
|
||||
"Early CSE w/ MemorySSA", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass)
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/CFG.h"
|
||||
#include "llvm/Analysis/ConstantFolding.h"
|
||||
#include "llvm/Analysis/GlobalsModRef.h"
|
||||
@ -582,14 +581,13 @@ PreservedAnalyses GVN::run(Function &F, FunctionAnalysisManager &AM) {
|
||||
// significant! Re-ordering these variables will cause GVN when run alone to
|
||||
// be less effective! We should fix memdep and basic-aa to not exhibit this
|
||||
// behavior, but until then don't change the order here.
|
||||
auto &AC = AM.getResult<AssumptionAnalysis>(F);
|
||||
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
|
||||
auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
|
||||
auto &AA = AM.getResult<AAManager>(F);
|
||||
auto &MemDep = AM.getResult<MemoryDependenceAnalysis>(F);
|
||||
auto *LI = AM.getCachedResult<LoopAnalysis>(F);
|
||||
auto &ORE = AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
|
||||
bool Changed = runImpl(F, AC, DT, TLI, AA, &MemDep, LI, &ORE);
|
||||
bool Changed = runImpl(F, DT, TLI, AA, &MemDep, LI, &ORE);
|
||||
if (!Changed)
|
||||
return PreservedAnalyses::all();
|
||||
PreservedAnalyses PA;
|
||||
@ -1534,7 +1532,7 @@ bool GVN::PerformLoadPRE(LoadInst *LI, AvailValInBlkVect &ValuesPerBlock,
|
||||
// If all preds have a single successor, then we know it is safe to insert
|
||||
// the load on the pred (?!?), so we can insert code to materialize the
|
||||
// pointer if it is not available.
|
||||
PHITransAddr Address(LI->getPointerOperand(), DL, AC);
|
||||
PHITransAddr Address(LI->getPointerOperand(), DL);
|
||||
Value *LoadPtr = nullptr;
|
||||
LoadPtr = Address.PHITranslateWithInsertion(LoadBB, UnavailablePred,
|
||||
*DT, NewInsts);
|
||||
@ -2103,7 +2101,7 @@ bool GVN::processInstruction(Instruction *I) {
|
||||
// example if it determines that %y is equal to %x then the instruction
|
||||
// "%z = and i32 %x, %y" becomes "%z = and i32 %x, %x" which we now simplify.
|
||||
const DataLayout &DL = I->getModule()->getDataLayout();
|
||||
if (Value *V = SimplifyInstruction(I, DL, TLI, DT, AC)) {
|
||||
if (Value *V = SimplifyInstruction(I, DL, TLI, DT)) {
|
||||
bool Changed = false;
|
||||
if (!I->use_empty()) {
|
||||
I->replaceAllUsesWith(V);
|
||||
@ -2232,11 +2230,10 @@ bool GVN::processInstruction(Instruction *I) {
|
||||
}
|
||||
|
||||
/// runOnFunction - This is the main transformation entry point for a function.
|
||||
bool GVN::runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT,
|
||||
bool GVN::runImpl(Function &F, DominatorTree &RunDT,
|
||||
const TargetLibraryInfo &RunTLI, AAResults &RunAA,
|
||||
MemoryDependenceResults *RunMD, LoopInfo *LI,
|
||||
OptimizationRemarkEmitter *RunORE) {
|
||||
AC = &RunAC;
|
||||
DT = &RunDT;
|
||||
VN.setDomTree(DT);
|
||||
TLI = &RunTLI;
|
||||
@ -2753,8 +2750,7 @@ public:
|
||||
auto *LIWP = getAnalysisIfAvailable<LoopInfoWrapperPass>();
|
||||
|
||||
return Impl.runImpl(
|
||||
F, getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F),
|
||||
getAnalysis<DominatorTreeWrapperPass>().getDomTree(),
|
||||
F, getAnalysis<DominatorTreeWrapperPass>().getDomTree(),
|
||||
getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(),
|
||||
getAnalysis<AAResultsWrapperPass>().getAAResults(),
|
||||
NoLoads ? nullptr
|
||||
@ -2764,7 +2760,6 @@ public:
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
AU.addRequired<DominatorTreeWrapperPass>();
|
||||
AU.addRequired<TargetLibraryInfoWrapperPass>();
|
||||
if (!NoLoads)
|
||||
@ -2789,7 +2784,6 @@ FunctionPass *llvm::createGVNPass(bool NoLoads) {
|
||||
}
|
||||
|
||||
INITIALIZE_PASS_BEGIN(GVNLegacyPass, "gvn", "Global Value Numbering", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_DEPENDENCY(MemoryDependenceWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
|
||||
|
@ -1336,7 +1336,7 @@ bool LoopConstrainer::run() {
|
||||
auto *L = createClonedLoopStructure(
|
||||
&OriginalLoop, OriginalLoop.getParentLoop(), PreLoop.Map);
|
||||
formLCSSARecursively(*L, DT, &LI, &SE);
|
||||
simplifyLoop(L, &DT, &LI, &SE, nullptr, true);
|
||||
simplifyLoop(L, &DT, &LI, &SE, true);
|
||||
// Pre loops are slow paths, we do not need to perform any loop
|
||||
// optimizations on them.
|
||||
DisableAllLoopOptsOnLoop(*L);
|
||||
@ -1346,14 +1346,14 @@ bool LoopConstrainer::run() {
|
||||
auto *L = createClonedLoopStructure(
|
||||
&OriginalLoop, OriginalLoop.getParentLoop(), PostLoop.Map);
|
||||
formLCSSARecursively(*L, DT, &LI, &SE);
|
||||
simplifyLoop(L, &DT, &LI, &SE, nullptr, true);
|
||||
simplifyLoop(L, &DT, &LI, &SE, true);
|
||||
// Post loops are slow paths, we do not need to perform any loop
|
||||
// optimizations on them.
|
||||
DisableAllLoopOptsOnLoop(*L);
|
||||
}
|
||||
|
||||
formLCSSARecursively(OriginalLoop, DT, &LI, &SE);
|
||||
simplifyLoop(&OriginalLoop, &DT, &LI, &SE, nullptr, true);
|
||||
simplifyLoop(&OriginalLoop, &DT, &LI, &SE, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -16,7 +16,6 @@
|
||||
#define DEBUG_TYPE "loop-data-prefetch"
|
||||
#include "llvm/ADT/DepthFirstIterator.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/CodeMetrics.h"
|
||||
#include "llvm/Analysis/InstructionSimplify.h"
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
@ -66,10 +65,10 @@ namespace {
|
||||
/// Loop prefetch implementation class.
|
||||
class LoopDataPrefetch {
|
||||
public:
|
||||
LoopDataPrefetch(AssumptionCache *AC, LoopInfo *LI, ScalarEvolution *SE,
|
||||
LoopDataPrefetch(LoopInfo *LI, ScalarEvolution *SE,
|
||||
const TargetTransformInfo *TTI,
|
||||
OptimizationRemarkEmitter *ORE)
|
||||
: AC(AC), LI(LI), SE(SE), TTI(TTI), ORE(ORE) {}
|
||||
: LI(LI), SE(SE), TTI(TTI), ORE(ORE) {}
|
||||
|
||||
bool run();
|
||||
|
||||
@ -98,7 +97,6 @@ private:
|
||||
return TTI->getMaxPrefetchIterationsAhead();
|
||||
}
|
||||
|
||||
AssumptionCache *AC;
|
||||
LoopInfo *LI;
|
||||
ScalarEvolution *SE;
|
||||
const TargetTransformInfo *TTI;
|
||||
@ -114,7 +112,6 @@ public:
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
AU.addPreserved<DominatorTreeWrapperPass>();
|
||||
AU.addRequired<LoopInfoWrapperPass>();
|
||||
AU.addPreserved<LoopInfoWrapperPass>();
|
||||
@ -133,7 +130,6 @@ public:
|
||||
char LoopDataPrefetchLegacyPass::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(LoopDataPrefetchLegacyPass, "loop-data-prefetch",
|
||||
"Loop Data Prefetch", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass)
|
||||
@ -165,12 +161,11 @@ PreservedAnalyses LoopDataPrefetchPass::run(Function &F,
|
||||
FunctionAnalysisManager &AM) {
|
||||
LoopInfo *LI = &AM.getResult<LoopAnalysis>(F);
|
||||
ScalarEvolution *SE = &AM.getResult<ScalarEvolutionAnalysis>(F);
|
||||
AssumptionCache *AC = &AM.getResult<AssumptionAnalysis>(F);
|
||||
OptimizationRemarkEmitter *ORE =
|
||||
&AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
|
||||
const TargetTransformInfo *TTI = &AM.getResult<TargetIRAnalysis>(F);
|
||||
|
||||
LoopDataPrefetch LDP(AC, LI, SE, TTI, ORE);
|
||||
LoopDataPrefetch LDP(LI, SE, TTI, ORE);
|
||||
bool Changed = LDP.run();
|
||||
|
||||
if (Changed) {
|
||||
@ -189,14 +184,12 @@ bool LoopDataPrefetchLegacyPass::runOnFunction(Function &F) {
|
||||
|
||||
LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
|
||||
ScalarEvolution *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
|
||||
AssumptionCache *AC =
|
||||
&getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
|
||||
OptimizationRemarkEmitter *ORE =
|
||||
&getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
|
||||
const TargetTransformInfo *TTI =
|
||||
&getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
|
||||
|
||||
LoopDataPrefetch LDP(AC, LI, SE, TTI, ORE);
|
||||
LoopDataPrefetch LDP(LI, SE, TTI, ORE);
|
||||
return LDP.run();
|
||||
}
|
||||
|
||||
@ -225,7 +218,7 @@ bool LoopDataPrefetch::runOnLoop(Loop *L) {
|
||||
return MadeChange;
|
||||
|
||||
SmallPtrSet<const Value *, 32> EphValues;
|
||||
CodeMetrics::collectEphemeralValues(L, AC, EphValues);
|
||||
CodeMetrics::collectEphemeralValues(L, EphValues);
|
||||
|
||||
// Calculate the number of iterations ahead to prefetch
|
||||
CodeMetrics Metrics;
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "llvm/Transforms/Scalar/LoopInstSimplify.h"
|
||||
#include "llvm/ADT/STLExtras.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"
|
||||
@ -35,7 +34,6 @@ using namespace llvm;
|
||||
STATISTIC(NumSimplified, "Number of redundant instructions simplified");
|
||||
|
||||
static bool SimplifyLoopInst(Loop *L, DominatorTree *DT, LoopInfo *LI,
|
||||
AssumptionCache *AC,
|
||||
const TargetLibraryInfo *TLI) {
|
||||
SmallVector<BasicBlock *, 8> ExitBlocks;
|
||||
L->getUniqueExitBlocks(ExitBlocks);
|
||||
@ -77,7 +75,7 @@ static bool SimplifyLoopInst(Loop *L, DominatorTree *DT, LoopInfo *LI,
|
||||
|
||||
// Don't bother simplifying unused instructions.
|
||||
if (!I->use_empty()) {
|
||||
Value *V = SimplifyInstruction(I, DL, TLI, DT, AC);
|
||||
Value *V = SimplifyInstruction(I, DL, TLI, DT);
|
||||
if (V && LI->replacementPreservesLCSSAForm(I, V)) {
|
||||
// Mark all uses for resimplification next time round the loop.
|
||||
for (User *U : I->users())
|
||||
@ -165,17 +163,13 @@ public:
|
||||
getAnalysisIfAvailable<DominatorTreeWrapperPass>();
|
||||
DominatorTree *DT = DTWP ? &DTWP->getDomTree() : nullptr;
|
||||
LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
|
||||
AssumptionCache *AC =
|
||||
&getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
|
||||
*L->getHeader()->getParent());
|
||||
const TargetLibraryInfo *TLI =
|
||||
&getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
|
||||
|
||||
return SimplifyLoopInst(L, DT, LI, AC, TLI);
|
||||
return SimplifyLoopInst(L, DT, LI, TLI);
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
AU.addRequired<TargetLibraryInfoWrapperPass>();
|
||||
AU.setPreservesCFG();
|
||||
getLoopAnalysisUsage(AU);
|
||||
@ -192,11 +186,10 @@ PreservedAnalyses LoopInstSimplifyPass::run(Loop &L,
|
||||
// Use getCachedResult because Loop pass cannot trigger a function analysis.
|
||||
auto *DT = FAM.getCachedResult<DominatorTreeAnalysis>(*F);
|
||||
auto *LI = FAM.getCachedResult<LoopAnalysis>(*F);
|
||||
auto *AC = FAM.getCachedResult<AssumptionAnalysis>(*F);
|
||||
const auto *TLI = FAM.getCachedResult<TargetLibraryAnalysis>(*F);
|
||||
assert((LI && AC && TLI) && "Analyses for Loop Inst Simplify not available");
|
||||
assert((LI && TLI) && "Analyses for Loop Inst Simplify not available");
|
||||
|
||||
if (!SimplifyLoopInst(&L, DT, LI, AC, TLI))
|
||||
if (!SimplifyLoopInst(&L, DT, LI, TLI))
|
||||
return PreservedAnalyses::all();
|
||||
|
||||
return getLoopPassPreservedAnalyses();
|
||||
@ -205,7 +198,6 @@ PreservedAnalyses LoopInstSimplifyPass::run(Loop &L,
|
||||
char LoopInstSimplifyLegacyPass::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(LoopInstSimplifyLegacyPass, "loop-instsimplify",
|
||||
"Simplify instructions in loops", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_DEPENDENCY(LoopPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
|
||||
INITIALIZE_PASS_END(LoopInstSimplifyLegacyPass, "loop-instsimplify",
|
||||
|
@ -15,7 +15,6 @@
|
||||
|
||||
#include "llvm/ADT/SmallVector.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"
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/CodeMetrics.h"
|
||||
#include "llvm/Analysis/InstructionSimplify.h"
|
||||
#include "llvm/Analysis/GlobalsModRef.h"
|
||||
@ -55,15 +54,14 @@ class LoopRotate {
|
||||
const unsigned MaxHeaderSize;
|
||||
LoopInfo *LI;
|
||||
const TargetTransformInfo *TTI;
|
||||
AssumptionCache *AC;
|
||||
DominatorTree *DT;
|
||||
ScalarEvolution *SE;
|
||||
|
||||
public:
|
||||
LoopRotate(unsigned MaxHeaderSize, LoopInfo *LI,
|
||||
const TargetTransformInfo *TTI, AssumptionCache *AC,
|
||||
DominatorTree *DT, ScalarEvolution *SE)
|
||||
: MaxHeaderSize(MaxHeaderSize), LI(LI), TTI(TTI), AC(AC), DT(DT), SE(SE) {
|
||||
const TargetTransformInfo *TTI, DominatorTree *DT,
|
||||
ScalarEvolution *SE)
|
||||
: MaxHeaderSize(MaxHeaderSize), LI(LI), TTI(TTI), DT(DT), SE(SE) {
|
||||
}
|
||||
bool processLoop(Loop *L);
|
||||
|
||||
@ -216,7 +214,7 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
|
||||
// duplicate blocks inside it.
|
||||
{
|
||||
SmallPtrSet<const Value *, 32> EphValues;
|
||||
CodeMetrics::collectEphemeralValues(L, AC, EphValues);
|
||||
CodeMetrics::collectEphemeralValues(L, EphValues);
|
||||
|
||||
CodeMetrics Metrics;
|
||||
Metrics.analyzeBasicBlock(OrigHeader, *TTI, EphValues);
|
||||
@ -309,7 +307,7 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
|
||||
// With the operands remapped, see if the instruction constant folds or is
|
||||
// otherwise simplifyable. This commonly occurs because the entry from PHI
|
||||
// nodes allows icmps and other instructions to fold.
|
||||
// FIXME: Provide TLI, DT, AC to SimplifyInstruction.
|
||||
// FIXME: Provide TLI, and DT to SimplifyInstruction.
|
||||
Value *V = SimplifyInstruction(C, DL);
|
||||
if (V && LI->replacementPreservesLCSSAForm(C, V)) {
|
||||
// If so, then delete the temporary instruction and stick the folded value
|
||||
@ -326,10 +324,6 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
|
||||
// Otherwise, stick the new instruction into the new block!
|
||||
C->setName(Inst->getName());
|
||||
C->insertBefore(LoopEntryBranch);
|
||||
|
||||
if (auto *II = dyn_cast<IntrinsicInst>(C))
|
||||
if (II->getIntrinsicID() == Intrinsic::assume)
|
||||
AC->registerAssumption(II);
|
||||
}
|
||||
}
|
||||
|
||||
@ -630,13 +624,12 @@ PreservedAnalyses LoopRotatePass::run(Loop &L, LoopAnalysisManager &AM) {
|
||||
|
||||
auto *LI = FAM.getCachedResult<LoopAnalysis>(*F);
|
||||
const auto *TTI = FAM.getCachedResult<TargetIRAnalysis>(*F);
|
||||
auto *AC = FAM.getCachedResult<AssumptionAnalysis>(*F);
|
||||
assert((LI && TTI && AC) && "Analyses for loop rotation not available");
|
||||
assert((LI && TTI) && "Analyses for loop rotation not available");
|
||||
|
||||
// Optional analyses.
|
||||
auto *DT = FAM.getCachedResult<DominatorTreeAnalysis>(*F);
|
||||
auto *SE = FAM.getCachedResult<ScalarEvolutionAnalysis>(*F);
|
||||
LoopRotate LR(DefaultRotationThreshold, LI, TTI, AC, DT, SE);
|
||||
LoopRotate LR(DefaultRotationThreshold, LI, TTI, DT, SE);
|
||||
|
||||
bool Changed = LR.processLoop(&L);
|
||||
if (!Changed)
|
||||
@ -661,7 +654,6 @@ public:
|
||||
|
||||
// LCSSA form makes instruction renaming easier.
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
AU.addRequired<TargetTransformInfoWrapperPass>();
|
||||
getLoopAnalysisUsage(AU);
|
||||
}
|
||||
@ -673,12 +665,11 @@ public:
|
||||
|
||||
auto *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
|
||||
const auto *TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
|
||||
auto *AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
|
||||
auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
|
||||
auto *DT = DTWP ? &DTWP->getDomTree() : nullptr;
|
||||
auto *SEWP = getAnalysisIfAvailable<ScalarEvolutionWrapperPass>();
|
||||
auto *SE = SEWP ? &SEWP->getSE() : nullptr;
|
||||
LoopRotate LR(MaxHeaderSize, LI, TTI, AC, DT, SE);
|
||||
LoopRotate LR(MaxHeaderSize, LI, TTI, DT, SE);
|
||||
return LR.processLoop(L);
|
||||
}
|
||||
};
|
||||
@ -687,7 +678,6 @@ public:
|
||||
char LoopRotateLegacyPass::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(LoopRotateLegacyPass, "loop-rotate", "Rotate Loops",
|
||||
false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_DEPENDENCY(LoopPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
|
||||
INITIALIZE_PASS_END(LoopRotateLegacyPass, "loop-rotate", "Rotate Loops", false,
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/DependenceAnalysis.h"
|
||||
#include "llvm/Analysis/GlobalsModRef.h"
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
#include "llvm/Transforms/Scalar/LoopUnrollPass.h"
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/CodeMetrics.h"
|
||||
#include "llvm/Analysis/GlobalsModRef.h"
|
||||
#include "llvm/Analysis/InstructionSimplify.h"
|
||||
@ -556,9 +555,9 @@ analyzeLoopUnrollCost(const Loop *L, unsigned TripCount, DominatorTree &DT,
|
||||
static unsigned ApproximateLoopSize(const Loop *L, unsigned &NumCalls,
|
||||
bool &NotDuplicatable, bool &Convergent,
|
||||
const TargetTransformInfo &TTI,
|
||||
AssumptionCache *AC, unsigned BEInsns) {
|
||||
unsigned BEInsns) {
|
||||
SmallPtrSet<const Value *, 32> EphValues;
|
||||
CodeMetrics::collectEphemeralValues(L, AC, EphValues);
|
||||
CodeMetrics::collectEphemeralValues(L, EphValues);
|
||||
|
||||
CodeMetrics Metrics;
|
||||
for (BasicBlock *BB : L->blocks())
|
||||
@ -956,7 +955,7 @@ static bool computeUnrollCount(
|
||||
|
||||
static bool tryToUnrollLoop(Loop *L, DominatorTree &DT, LoopInfo *LI,
|
||||
ScalarEvolution *SE, const TargetTransformInfo &TTI,
|
||||
AssumptionCache &AC, OptimizationRemarkEmitter &ORE,
|
||||
OptimizationRemarkEmitter &ORE,
|
||||
bool PreserveLCSSA,
|
||||
Optional<unsigned> ProvidedCount,
|
||||
Optional<unsigned> ProvidedThreshold,
|
||||
@ -983,7 +982,7 @@ static bool tryToUnrollLoop(Loop *L, DominatorTree &DT, LoopInfo *LI,
|
||||
if (UP.Threshold == 0 && (!UP.Partial || UP.PartialThreshold == 0))
|
||||
return false;
|
||||
unsigned LoopSize = ApproximateLoopSize(
|
||||
L, NumInlineCandidates, NotDuplicatable, Convergent, TTI, &AC, UP.BEInsns);
|
||||
L, NumInlineCandidates, NotDuplicatable, Convergent, TTI, UP.BEInsns);
|
||||
DEBUG(dbgs() << " Loop Size = " << LoopSize << "\n");
|
||||
if (NotDuplicatable) {
|
||||
DEBUG(dbgs() << " Not unrolling loop which contains non-duplicatable"
|
||||
@ -1059,7 +1058,7 @@ static bool tryToUnrollLoop(Loop *L, DominatorTree &DT, LoopInfo *LI,
|
||||
// Unroll the loop.
|
||||
if (!UnrollLoop(L, UP.Count, TripCount, UP.Force, UP.Runtime,
|
||||
UP.AllowExpensiveTripCount, UseUpperBound, MaxOrZero,
|
||||
TripMultiple, UP.PeelCount, LI, SE, &DT, &AC, &ORE,
|
||||
TripMultiple, UP.PeelCount, LI, SE, &DT, &ORE,
|
||||
PreserveLCSSA))
|
||||
return false;
|
||||
|
||||
@ -1104,14 +1103,13 @@ public:
|
||||
ScalarEvolution *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
|
||||
const TargetTransformInfo &TTI =
|
||||
getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
|
||||
auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
|
||||
// For the old PM, we can't use OptimizationRemarkEmitter as an analysis
|
||||
// pass. Function analyses need to be preserved across loop transformations
|
||||
// but ORE cannot be preserved (see comment before the pass definition).
|
||||
OptimizationRemarkEmitter ORE(&F);
|
||||
bool PreserveLCSSA = mustPreserveAnalysisID(LCSSAID);
|
||||
|
||||
return tryToUnrollLoop(L, DT, LI, SE, TTI, AC, ORE, PreserveLCSSA,
|
||||
return tryToUnrollLoop(L, DT, LI, SE, TTI, ORE, PreserveLCSSA,
|
||||
ProvidedCount, ProvidedThreshold,
|
||||
ProvidedAllowPartial, ProvidedRuntime,
|
||||
ProvidedUpperBound);
|
||||
@ -1121,7 +1119,6 @@ public:
|
||||
/// loop preheaders be inserted into the CFG...
|
||||
///
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
AU.addRequired<TargetTransformInfoWrapperPass>();
|
||||
// FIXME: Loop passes are required to preserve domtree, and for now we just
|
||||
// recreate dom info if anything gets unrolled.
|
||||
@ -1132,7 +1129,6 @@ public:
|
||||
|
||||
char LoopUnroll::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(LoopUnroll, "loop-unroll", "Unroll loops", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_DEPENDENCY(LoopPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
|
||||
INITIALIZE_PASS_END(LoopUnroll, "loop-unroll", "Unroll loops", false, false)
|
||||
@ -1164,7 +1160,6 @@ PreservedAnalyses LoopUnrollPass::run(Loop &L, LoopAnalysisManager &AM) {
|
||||
LoopInfo *LI = FAM.getCachedResult<LoopAnalysis>(*F);
|
||||
ScalarEvolution *SE = FAM.getCachedResult<ScalarEvolutionAnalysis>(*F);
|
||||
auto *TTI = FAM.getCachedResult<TargetIRAnalysis>(*F);
|
||||
auto *AC = FAM.getCachedResult<AssumptionAnalysis>(*F);
|
||||
auto *ORE = FAM.getCachedResult<OptimizationRemarkEmitterAnalysis>(*F);
|
||||
if (!DT)
|
||||
report_fatal_error(
|
||||
@ -1178,15 +1173,12 @@ PreservedAnalyses LoopUnrollPass::run(Loop &L, LoopAnalysisManager &AM) {
|
||||
if (!TTI)
|
||||
report_fatal_error(
|
||||
"LoopUnrollPass: TargetIRAnalysis not cached at a higher level");
|
||||
if (!AC)
|
||||
report_fatal_error(
|
||||
"LoopUnrollPass: AssumptionAnalysis not cached at a higher level");
|
||||
if (!ORE)
|
||||
report_fatal_error("LoopUnrollPass: OptimizationRemarkEmitterAnalysis not "
|
||||
"cached at a higher level");
|
||||
|
||||
bool Changed =
|
||||
tryToUnrollLoop(&L, *DT, LI, SE, *TTI, *AC, *ORE, /*PreserveLCSSA*/ true,
|
||||
tryToUnrollLoop(&L, *DT, LI, SE, *TTI, *ORE, /*PreserveLCSSA*/ true,
|
||||
ProvidedCount, ProvidedThreshold, ProvidedAllowPartial,
|
||||
ProvidedRuntime, ProvidedUpperBound);
|
||||
|
||||
|
@ -28,10 +28,10 @@
|
||||
|
||||
#include "llvm/Transforms/Scalar.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Analysis/GlobalsModRef.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/CodeMetrics.h"
|
||||
#include "llvm/Analysis/InstructionSimplify.h"
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
@ -138,8 +138,7 @@ namespace {
|
||||
|
||||
// Analyze loop. Check its size, calculate is it possible to unswitch
|
||||
// it. Returns true if we can unswitch this loop.
|
||||
bool countLoop(const Loop *L, const TargetTransformInfo &TTI,
|
||||
AssumptionCache *AC);
|
||||
bool countLoop(const Loop *L, const TargetTransformInfo &TTI);
|
||||
|
||||
// Clean all data related to given loop.
|
||||
void forgetLoop(const Loop *L);
|
||||
@ -166,7 +165,6 @@ namespace {
|
||||
class LoopUnswitch : public LoopPass {
|
||||
LoopInfo *LI; // Loop information
|
||||
LPPassManager *LPM;
|
||||
AssumptionCache *AC;
|
||||
|
||||
// Used to check if second loop needs processing after
|
||||
// RewriteLoopBodyWithConditionConstant rewrites first loop.
|
||||
@ -215,7 +213,6 @@ namespace {
|
||||
/// loop preheaders be inserted into the CFG.
|
||||
///
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
AU.addRequired<TargetTransformInfoWrapperPass>();
|
||||
getLoopAnalysisUsage(AU);
|
||||
}
|
||||
@ -260,8 +257,7 @@ namespace {
|
||||
|
||||
// Analyze loop. Check its size, calculate is it possible to unswitch
|
||||
// it. Returns true if we can unswitch this loop.
|
||||
bool LUAnalysisCache::countLoop(const Loop *L, const TargetTransformInfo &TTI,
|
||||
AssumptionCache *AC) {
|
||||
bool LUAnalysisCache::countLoop(const Loop *L, const TargetTransformInfo &TTI) {
|
||||
|
||||
LoopPropsMapIt PropsIt;
|
||||
bool Inserted;
|
||||
@ -279,7 +275,7 @@ bool LUAnalysisCache::countLoop(const Loop *L, const TargetTransformInfo &TTI,
|
||||
// This is a very ad-hoc heuristic.
|
||||
|
||||
SmallPtrSet<const Value *, 32> EphValues;
|
||||
CodeMetrics::collectEphemeralValues(L, AC, EphValues);
|
||||
CodeMetrics::collectEphemeralValues(L, EphValues);
|
||||
|
||||
// FIXME: This is overly conservative because it does not take into
|
||||
// consideration code simplification opportunities and code that can
|
||||
@ -378,7 +374,6 @@ void LUAnalysisCache::cloneData(const Loop *NewLoop, const Loop *OldLoop,
|
||||
char LoopUnswitch::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(LoopUnswitch, "loop-unswitch", "Unswitch loops",
|
||||
false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_DEPENDENCY(LoopPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
|
||||
INITIALIZE_PASS_END(LoopUnswitch, "loop-unswitch", "Unswitch loops",
|
||||
@ -445,8 +440,6 @@ bool LoopUnswitch::runOnLoop(Loop *L, LPPassManager &LPM_Ref) {
|
||||
if (skipLoop(L))
|
||||
return false;
|
||||
|
||||
AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
|
||||
*L->getHeader()->getParent());
|
||||
LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
|
||||
LPM = &LPM_Ref;
|
||||
DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||
@ -535,8 +528,7 @@ bool LoopUnswitch::processCurrentLoop() {
|
||||
// Analyze loop cost, and stop unswitching if loop content can not be duplicated.
|
||||
if (!BranchesInfo.countLoop(
|
||||
currentLoop, getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
|
||||
*currentLoop->getHeader()->getParent()),
|
||||
AC))
|
||||
*currentLoop->getHeader()->getParent())))
|
||||
return false;
|
||||
|
||||
// Try trivial unswitch first before loop over other basic blocks in the loop.
|
||||
@ -1128,15 +1120,10 @@ void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
|
||||
}
|
||||
|
||||
// Rewrite the code to refer to itself.
|
||||
for (unsigned i = 0, e = NewBlocks.size(); i != e; ++i) {
|
||||
for (Instruction &I : *NewBlocks[i]) {
|
||||
for (unsigned i = 0, e = NewBlocks.size(); i != e; ++i)
|
||||
for (Instruction &I : *NewBlocks[i])
|
||||
RemapInstruction(&I, VMap,
|
||||
RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
|
||||
if (auto *II = dyn_cast<IntrinsicInst>(&I))
|
||||
if (II->getIntrinsicID() == Intrinsic::assume)
|
||||
AC->registerAssumption(II);
|
||||
}
|
||||
}
|
||||
|
||||
// Rewrite the original preheader to select between versions of the loop.
|
||||
BranchInst *OldBR = cast<BranchInst>(loopPreheader->getTerminator());
|
||||
|
@ -313,7 +313,6 @@ namespace {
|
||||
// This transformation requires dominator postdominator info
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.setPreservesCFG();
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
AU.addRequired<DominatorTreeWrapperPass>();
|
||||
AU.addRequired<MemoryDependenceWrapperPass>();
|
||||
AU.addRequired<AAResultsWrapperPass>();
|
||||
@ -347,7 +346,6 @@ FunctionPass *llvm::createMemCpyOptPass() { return new MemCpyOptLegacyPass(); }
|
||||
|
||||
INITIALIZE_PASS_BEGIN(MemCpyOptLegacyPass, "memcpyopt", "MemCpy Optimization",
|
||||
false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(MemoryDependenceWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
|
||||
@ -1293,11 +1291,10 @@ bool MemCpyOptPass::processByValArgument(CallSite CS, unsigned ArgNo) {
|
||||
|
||||
// If it is greater than the memcpy, then we check to see if we can force the
|
||||
// source of the memcpy to the alignment we need. If we fail, we bail out.
|
||||
AssumptionCache &AC = LookupAssumptionCache();
|
||||
DominatorTree &DT = LookupDomTree();
|
||||
if (MDep->getAlignment() < ByValAlign &&
|
||||
getOrEnforceKnownAlignment(MDep->getSource(), ByValAlign, DL,
|
||||
CS.getInstruction(), &AC, &DT) < ByValAlign)
|
||||
CS.getInstruction(), &DT) < ByValAlign)
|
||||
return false;
|
||||
|
||||
// Verify that the copied-from memory doesn't change in between the memcpy and
|
||||
@ -1376,15 +1373,11 @@ PreservedAnalyses MemCpyOptPass::run(Function &F, FunctionAnalysisManager &AM) {
|
||||
auto LookupAliasAnalysis = [&]() -> AliasAnalysis & {
|
||||
return AM.getResult<AAManager>(F);
|
||||
};
|
||||
auto LookupAssumptionCache = [&]() -> AssumptionCache & {
|
||||
return AM.getResult<AssumptionAnalysis>(F);
|
||||
};
|
||||
auto LookupDomTree = [&]() -> DominatorTree & {
|
||||
return AM.getResult<DominatorTreeAnalysis>(F);
|
||||
};
|
||||
|
||||
bool MadeChange = runImpl(F, &MD, &TLI, LookupAliasAnalysis,
|
||||
LookupAssumptionCache, LookupDomTree);
|
||||
bool MadeChange = runImpl(F, &MD, &TLI, LookupAliasAnalysis, LookupDomTree);
|
||||
if (!MadeChange)
|
||||
return PreservedAnalyses::all();
|
||||
PreservedAnalyses PA;
|
||||
@ -1396,13 +1389,11 @@ PreservedAnalyses MemCpyOptPass::run(Function &F, FunctionAnalysisManager &AM) {
|
||||
bool MemCpyOptPass::runImpl(
|
||||
Function &F, MemoryDependenceResults *MD_, TargetLibraryInfo *TLI_,
|
||||
std::function<AliasAnalysis &()> LookupAliasAnalysis_,
|
||||
std::function<AssumptionCache &()> LookupAssumptionCache_,
|
||||
std::function<DominatorTree &()> LookupDomTree_) {
|
||||
bool MadeChange = false;
|
||||
MD = MD_;
|
||||
TLI = TLI_;
|
||||
LookupAliasAnalysis = std::move(LookupAliasAnalysis_);
|
||||
LookupAssumptionCache = std::move(LookupAssumptionCache_);
|
||||
LookupDomTree = std::move(LookupDomTree_);
|
||||
|
||||
// If we don't have at least memset and memcpy, there is little point of doing
|
||||
@ -1432,13 +1423,9 @@ bool MemCpyOptLegacyPass::runOnFunction(Function &F) {
|
||||
auto LookupAliasAnalysis = [this]() -> AliasAnalysis & {
|
||||
return getAnalysis<AAResultsWrapperPass>().getAAResults();
|
||||
};
|
||||
auto LookupAssumptionCache = [this, &F]() -> AssumptionCache & {
|
||||
return getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
|
||||
};
|
||||
auto LookupDomTree = [this]() -> DominatorTree & {
|
||||
return getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||
};
|
||||
|
||||
return Impl.runImpl(F, MD, TLI, LookupAliasAnalysis, LookupAssumptionCache,
|
||||
LookupDomTree);
|
||||
return Impl.runImpl(F, MD, TLI, LookupAliasAnalysis, LookupDomTree);
|
||||
}
|
||||
|
@ -107,7 +107,6 @@ public:
|
||||
AU.addPreserved<DominatorTreeWrapperPass>();
|
||||
AU.addPreserved<ScalarEvolutionWrapperPass>();
|
||||
AU.addPreserved<TargetLibraryInfoWrapperPass>();
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
AU.addRequired<DominatorTreeWrapperPass>();
|
||||
AU.addRequired<ScalarEvolutionWrapperPass>();
|
||||
AU.addRequired<TargetLibraryInfoWrapperPass>();
|
||||
@ -123,7 +122,6 @@ private:
|
||||
char NaryReassociateLegacyPass::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(NaryReassociateLegacyPass, "nary-reassociate",
|
||||
"Nary reassociation", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
|
||||
@ -139,24 +137,22 @@ bool NaryReassociateLegacyPass::runOnFunction(Function &F) {
|
||||
if (skipFunction(F))
|
||||
return false;
|
||||
|
||||
auto *AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
|
||||
auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||
auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
|
||||
auto *TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
|
||||
auto *TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
|
||||
|
||||
return Impl.runImpl(F, AC, DT, SE, TLI, TTI);
|
||||
return Impl.runImpl(F, DT, SE, TLI, TTI);
|
||||
}
|
||||
|
||||
PreservedAnalyses NaryReassociatePass::run(Function &F,
|
||||
FunctionAnalysisManager &AM) {
|
||||
auto *AC = &AM.getResult<AssumptionAnalysis>(F);
|
||||
auto *DT = &AM.getResult<DominatorTreeAnalysis>(F);
|
||||
auto *SE = &AM.getResult<ScalarEvolutionAnalysis>(F);
|
||||
auto *TLI = &AM.getResult<TargetLibraryAnalysis>(F);
|
||||
auto *TTI = &AM.getResult<TargetIRAnalysis>(F);
|
||||
|
||||
bool Changed = runImpl(F, AC, DT, SE, TLI, TTI);
|
||||
bool Changed = runImpl(F, DT, SE, TLI, TTI);
|
||||
|
||||
// FIXME: We need to invalidate this to avoid PR28400. Is there a better
|
||||
// solution?
|
||||
@ -173,11 +169,10 @@ PreservedAnalyses NaryReassociatePass::run(Function &F,
|
||||
return PA;
|
||||
}
|
||||
|
||||
bool NaryReassociatePass::runImpl(Function &F, AssumptionCache *AC_,
|
||||
DominatorTree *DT_, ScalarEvolution *SE_,
|
||||
bool NaryReassociatePass::runImpl(Function &F, DominatorTree *DT_,
|
||||
ScalarEvolution *SE_,
|
||||
TargetLibraryInfo *TLI_,
|
||||
TargetTransformInfo *TTI_) {
|
||||
AC = AC_;
|
||||
DT = DT_;
|
||||
SE = SE_;
|
||||
TLI = TLI_;
|
||||
@ -307,7 +302,7 @@ NaryReassociatePass::tryReassociateGEPAtIndex(GetElementPtrInst *GEP,
|
||||
IndexToSplit = SExt->getOperand(0);
|
||||
} else if (ZExtInst *ZExt = dyn_cast<ZExtInst>(IndexToSplit)) {
|
||||
// zext can be treated as sext if the source is non-negative.
|
||||
if (isKnownNonNegative(ZExt->getOperand(0), *DL, 0, AC, GEP, DT))
|
||||
if (isKnownNonNegative(ZExt->getOperand(0), *DL, 0, GEP, DT))
|
||||
IndexToSplit = ZExt->getOperand(0);
|
||||
}
|
||||
|
||||
@ -316,7 +311,7 @@ NaryReassociatePass::tryReassociateGEPAtIndex(GetElementPtrInst *GEP,
|
||||
// nsw, we cannot split the add because
|
||||
// sext(LHS + RHS) != sext(LHS) + sext(RHS).
|
||||
if (requiresSignExtension(IndexToSplit, GEP) &&
|
||||
computeOverflowForSignedAdd(AO, *DL, AC, GEP, DT) !=
|
||||
computeOverflowForSignedAdd(AO, *DL, GEP, DT) !=
|
||||
OverflowResult::NeverOverflows)
|
||||
return nullptr;
|
||||
|
||||
@ -345,7 +340,7 @@ NaryReassociatePass::tryReassociateGEPAtIndex(GetElementPtrInst *GEP,
|
||||
IndexExprs.push_back(SE->getSCEV(*Index));
|
||||
// Replace the I-th index with LHS.
|
||||
IndexExprs[I] = SE->getSCEV(LHS);
|
||||
if (isKnownNonNegative(LHS, *DL, 0, AC, GEP, DT) &&
|
||||
if (isKnownNonNegative(LHS, *DL, 0, GEP, DT) &&
|
||||
DL->getTypeSizeInBits(LHS->getType()) <
|
||||
DL->getTypeSizeInBits(GEP->getOperand(I)->getType())) {
|
||||
// Zero-extend LHS if it is non-negative. InstCombine canonicalizes sext to
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/MapVector.h"
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/GlobalsModRef.h"
|
||||
#include "llvm/Analysis/Loads.h"
|
||||
#include "llvm/Analysis/PtrUseVisitor.h"
|
||||
@ -4184,17 +4183,15 @@ bool SROA::promoteAllocas(Function &F) {
|
||||
NumPromoted += PromotableAllocas.size();
|
||||
|
||||
DEBUG(dbgs() << "Promoting allocas with mem2reg...\n");
|
||||
PromoteMemToReg(PromotableAllocas, *DT, nullptr, AC);
|
||||
PromoteMemToReg(PromotableAllocas, *DT, nullptr);
|
||||
PromotableAllocas.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
PreservedAnalyses SROA::runImpl(Function &F, DominatorTree &RunDT,
|
||||
AssumptionCache &RunAC) {
|
||||
PreservedAnalyses SROA::runImpl(Function &F, DominatorTree &RunDT) {
|
||||
DEBUG(dbgs() << "SROA function: " << F.getName() << "\n");
|
||||
C = &F.getContext();
|
||||
DT = &RunDT;
|
||||
AC = &RunAC;
|
||||
|
||||
BasicBlock &EntryBB = F.getEntryBlock();
|
||||
for (BasicBlock::iterator I = EntryBB.begin(), E = std::prev(EntryBB.end());
|
||||
@ -4242,8 +4239,7 @@ PreservedAnalyses SROA::runImpl(Function &F, DominatorTree &RunDT,
|
||||
}
|
||||
|
||||
PreservedAnalyses SROA::run(Function &F, FunctionAnalysisManager &AM) {
|
||||
return runImpl(F, AM.getResult<DominatorTreeAnalysis>(F),
|
||||
AM.getResult<AssumptionAnalysis>(F));
|
||||
return runImpl(F, AM.getResult<DominatorTreeAnalysis>(F));
|
||||
}
|
||||
|
||||
/// A legacy pass for the legacy pass manager that wraps the \c SROA pass.
|
||||
@ -4263,12 +4259,10 @@ public:
|
||||
return false;
|
||||
|
||||
auto PA = Impl.runImpl(
|
||||
F, getAnalysis<DominatorTreeWrapperPass>().getDomTree(),
|
||||
getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F));
|
||||
F, getAnalysis<DominatorTreeWrapperPass>().getDomTree());
|
||||
return !PA.areAllPreserved();
|
||||
}
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
AU.addRequired<DominatorTreeWrapperPass>();
|
||||
AU.addPreserved<GlobalsAAWrapperPass>();
|
||||
AU.setPreservesCFG();
|
||||
@ -4284,7 +4278,6 @@ FunctionPass *llvm::createSROAPass() { return new SROALegacyPass(); }
|
||||
|
||||
INITIALIZE_PASS_BEGIN(SROALegacyPass, "sroa",
|
||||
"Scalar Replacement Of Aggregates", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
|
||||
INITIALIZE_PASS_END(SROALegacyPass, "sroa", "Scalar Replacement Of Aggregates",
|
||||
false, false)
|
||||
|
@ -459,7 +459,7 @@ bool ConstantOffsetExtractor::CanTraceInto(bool SignExtended,
|
||||
// Do not trace into "or" unless it is equivalent to "add". If LHS and RHS
|
||||
// don't have common bits, (LHS | RHS) is equivalent to (LHS + RHS).
|
||||
if (BO->getOpcode() == Instruction::Or &&
|
||||
!haveNoCommonBitsSet(LHS, RHS, DL, nullptr, BO, DT))
|
||||
!haveNoCommonBitsSet(LHS, RHS, DL, BO, DT))
|
||||
return false;
|
||||
|
||||
// In addition, tracing into BO requires that its surrounding s/zext (if
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/CFG.h"
|
||||
#include "llvm/Analysis/GlobalsModRef.h"
|
||||
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||
@ -129,7 +128,6 @@ static bool mergeEmptyReturnBlocks(Function &F) {
|
||||
/// Call SimplifyCFG on all the blocks in the function,
|
||||
/// iterating until no more changes are made.
|
||||
static bool iterativelySimplifyCFG(Function &F, const TargetTransformInfo &TTI,
|
||||
AssumptionCache *AC,
|
||||
unsigned BonusInstThreshold) {
|
||||
bool Changed = false;
|
||||
bool LocalChange = true;
|
||||
@ -145,7 +143,7 @@ static bool iterativelySimplifyCFG(Function &F, const TargetTransformInfo &TTI,
|
||||
|
||||
// Loop over all of the basic blocks and remove them if they are unneeded.
|
||||
for (Function::iterator BBIt = F.begin(); BBIt != F.end(); ) {
|
||||
if (SimplifyCFG(&*BBIt++, TTI, BonusInstThreshold, AC, &LoopHeaders)) {
|
||||
if (SimplifyCFG(&*BBIt++, TTI, BonusInstThreshold, &LoopHeaders)) {
|
||||
LocalChange = true;
|
||||
++NumSimpl;
|
||||
}
|
||||
@ -156,10 +154,10 @@ static bool iterativelySimplifyCFG(Function &F, const TargetTransformInfo &TTI,
|
||||
}
|
||||
|
||||
static bool simplifyFunctionCFG(Function &F, const TargetTransformInfo &TTI,
|
||||
AssumptionCache *AC, int BonusInstThreshold) {
|
||||
int BonusInstThreshold) {
|
||||
bool EverChanged = removeUnreachableBlocks(F);
|
||||
EverChanged |= mergeEmptyReturnBlocks(F);
|
||||
EverChanged |= iterativelySimplifyCFG(F, TTI, AC, BonusInstThreshold);
|
||||
EverChanged |= iterativelySimplifyCFG(F, TTI, BonusInstThreshold);
|
||||
|
||||
// If neither pass changed anything, we're done.
|
||||
if (!EverChanged) return false;
|
||||
@ -173,7 +171,7 @@ static bool simplifyFunctionCFG(Function &F, const TargetTransformInfo &TTI,
|
||||
return true;
|
||||
|
||||
do {
|
||||
EverChanged = iterativelySimplifyCFG(F, TTI, AC, BonusInstThreshold);
|
||||
EverChanged = iterativelySimplifyCFG(F, TTI, BonusInstThreshold);
|
||||
EverChanged |= removeUnreachableBlocks(F);
|
||||
} while (EverChanged);
|
||||
|
||||
@ -189,9 +187,8 @@ SimplifyCFGPass::SimplifyCFGPass(int BonusInstThreshold)
|
||||
PreservedAnalyses SimplifyCFGPass::run(Function &F,
|
||||
FunctionAnalysisManager &AM) {
|
||||
auto &TTI = AM.getResult<TargetIRAnalysis>(F);
|
||||
auto &AC = AM.getResult<AssumptionAnalysis>(F);
|
||||
|
||||
if (!simplifyFunctionCFG(F, TTI, &AC, BonusInstThreshold))
|
||||
if (!simplifyFunctionCFG(F, TTI, BonusInstThreshold))
|
||||
return PreservedAnalyses::all();
|
||||
PreservedAnalyses PA;
|
||||
PA.preserve<GlobalsAA>();
|
||||
@ -214,15 +211,12 @@ struct CFGSimplifyPass : public FunctionPass {
|
||||
if (skipFunction(F) || (PredicateFtor && !PredicateFtor(F)))
|
||||
return false;
|
||||
|
||||
AssumptionCache *AC =
|
||||
&getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
|
||||
const TargetTransformInfo &TTI =
|
||||
getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
|
||||
return simplifyFunctionCFG(F, TTI, AC, BonusInstThreshold);
|
||||
return simplifyFunctionCFG(F, TTI, BonusInstThreshold);
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
AU.addRequired<TargetTransformInfoWrapperPass>();
|
||||
AU.addPreserved<GlobalsAAWrapperPass>();
|
||||
}
|
||||
@ -233,7 +227,6 @@ char CFGSimplifyPass::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(CFGSimplifyPass, "simplifycfg", "Simplify the CFG", false,
|
||||
false)
|
||||
INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_END(CFGSimplifyPass, "simplifycfg", "Simplify the CFG", false,
|
||||
false)
|
||||
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/CallGraph.h"
|
||||
#include "llvm/Analysis/CaptureTracking.h"
|
||||
#include "llvm/Analysis/EHPersonalities.h"
|
||||
@ -1095,11 +1094,8 @@ static void AddAliasScopeMetadata(CallSite CS, ValueToValueMapTy &VMap,
|
||||
/// If the inlined function has non-byval align arguments, then
|
||||
/// add @llvm.assume-based alignment assumptions to preserve this information.
|
||||
static void AddAlignmentAssumptions(CallSite CS, InlineFunctionInfo &IFI) {
|
||||
if (!PreserveAlignmentAssumptions || !IFI.GetAssumptionCache)
|
||||
if (!PreserveAlignmentAssumptions)
|
||||
return;
|
||||
AssumptionCache *AC = IFI.GetAssumptionCache
|
||||
? &(*IFI.GetAssumptionCache)(*CS.getCaller())
|
||||
: nullptr;
|
||||
auto &DL = CS.getCaller()->getParent()->getDataLayout();
|
||||
|
||||
// To avoid inserting redundant assumptions, we should check for assumptions
|
||||
@ -1122,13 +1118,11 @@ static void AddAlignmentAssumptions(CallSite CS, InlineFunctionInfo &IFI) {
|
||||
// If we can already prove the asserted alignment in the context of the
|
||||
// caller, then don't bother inserting the assumption.
|
||||
Value *Arg = CS.getArgument(I->getArgNo());
|
||||
if (getKnownAlignment(Arg, DL, CS.getInstruction(), AC, &DT) >= Align)
|
||||
if (getKnownAlignment(Arg, DL, CS.getInstruction(), &DT) >= Align)
|
||||
continue;
|
||||
|
||||
CallInst *NewAssumption = IRBuilder<>(CS.getInstruction())
|
||||
.CreateAlignmentAssumption(DL, Arg, Align);
|
||||
if (AC)
|
||||
AC->registerAssumption(NewAssumption);
|
||||
IRBuilder<>(CS.getInstruction())
|
||||
.CreateAlignmentAssumption(DL, Arg, Align);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1239,13 +1233,11 @@ static Value *HandleByValArgument(Value *Arg, Instruction *TheCall,
|
||||
if (ByValAlignment <= 1) // 0 = unspecified, 1 = no particular alignment.
|
||||
return Arg;
|
||||
|
||||
AssumptionCache *AC =
|
||||
IFI.GetAssumptionCache ? &(*IFI.GetAssumptionCache)(*Caller) : nullptr;
|
||||
const DataLayout &DL = Caller->getParent()->getDataLayout();
|
||||
|
||||
// If the pointer is already known to be sufficiently aligned, or if we can
|
||||
// round it up to a larger alignment, then we don't need a temporary.
|
||||
if (getOrEnforceKnownAlignment(Arg, ByValAlignment, DL, TheCall, AC) >=
|
||||
if (getOrEnforceKnownAlignment(Arg, ByValAlignment, DL, TheCall) >=
|
||||
ByValAlignment)
|
||||
return Arg;
|
||||
|
||||
@ -1661,16 +1653,6 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
|
||||
|
||||
// Propagate llvm.mem.parallel_loop_access if necessary.
|
||||
PropagateParallelLoopAccessMetadata(CS, VMap);
|
||||
|
||||
// Register any cloned assumptions.
|
||||
if (IFI.GetAssumptionCache)
|
||||
for (BasicBlock &NewBlock :
|
||||
make_range(FirstNewBlock->getIterator(), Caller->end()))
|
||||
for (Instruction &I : NewBlock) {
|
||||
if (auto *II = dyn_cast<IntrinsicInst>(&I))
|
||||
if (II->getIntrinsicID() == Intrinsic::assume)
|
||||
(*IFI.GetAssumptionCache)(*Caller).registerAssumption(II);
|
||||
}
|
||||
}
|
||||
|
||||
// If there are any alloca instructions in the block that used to be the entry
|
||||
@ -2191,10 +2173,8 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
|
||||
// the entries are the same or undef). If so, remove the PHI so it doesn't
|
||||
// block other optimizations.
|
||||
if (PHI) {
|
||||
AssumptionCache *AC =
|
||||
IFI.GetAssumptionCache ? &(*IFI.GetAssumptionCache)(*Caller) : nullptr;
|
||||
auto &DL = Caller->getParent()->getDataLayout();
|
||||
if (Value *V = SimplifyInstruction(PHI, DL, nullptr, nullptr, AC)) {
|
||||
if (Value *V = SimplifyInstruction(PHI, DL, nullptr, nullptr)) {
|
||||
PHI->replaceAllUsesWith(V);
|
||||
PHI->eraseFromParent();
|
||||
}
|
||||
|
@ -1019,14 +1019,13 @@ static unsigned enforceKnownAlignment(Value *V, unsigned Align,
|
||||
unsigned llvm::getOrEnforceKnownAlignment(Value *V, unsigned PrefAlign,
|
||||
const DataLayout &DL,
|
||||
const Instruction *CxtI,
|
||||
AssumptionCache *AC,
|
||||
const DominatorTree *DT) {
|
||||
assert(V->getType()->isPointerTy() &&
|
||||
"getOrEnforceKnownAlignment expects a pointer!");
|
||||
unsigned BitWidth = DL.getPointerTypeSizeInBits(V->getType());
|
||||
|
||||
APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0);
|
||||
computeKnownBits(V, KnownZero, KnownOne, DL, 0, AC, CxtI, DT);
|
||||
computeKnownBits(V, KnownZero, KnownOne, DL, 0, CxtI, DT);
|
||||
unsigned TrailZ = KnownZero.countTrailingOnes();
|
||||
|
||||
// Avoid trouble with ridiculously large TrailZ values, such as
|
||||
|
@ -46,7 +46,6 @@
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/DependenceAnalysis.h"
|
||||
#include "llvm/Analysis/GlobalsModRef.h"
|
||||
#include "llvm/Analysis/InstructionSimplify.h"
|
||||
@ -204,13 +203,12 @@ static void addBlockAndPredsToSet(BasicBlock *InputBB, BasicBlock *StopBlock,
|
||||
|
||||
/// \brief The first part of loop-nestification is to find a PHI node that tells
|
||||
/// us how to partition the loops.
|
||||
static PHINode *findPHIToPartitionLoops(Loop *L, DominatorTree *DT,
|
||||
AssumptionCache *AC) {
|
||||
static PHINode *findPHIToPartitionLoops(Loop *L, DominatorTree *DT) {
|
||||
const DataLayout &DL = L->getHeader()->getModule()->getDataLayout();
|
||||
for (BasicBlock::iterator I = L->getHeader()->begin(); isa<PHINode>(I); ) {
|
||||
PHINode *PN = cast<PHINode>(I);
|
||||
++I;
|
||||
if (Value *V = SimplifyInstruction(PN, DL, nullptr, DT, AC)) {
|
||||
if (Value *V = SimplifyInstruction(PN, DL, nullptr, DT)) {
|
||||
// This is a degenerate PHI already, don't modify it!
|
||||
PN->replaceAllUsesWith(V);
|
||||
PN->eraseFromParent();
|
||||
@ -248,8 +246,7 @@ static PHINode *findPHIToPartitionLoops(Loop *L, DominatorTree *DT,
|
||||
///
|
||||
static Loop *separateNestedLoop(Loop *L, BasicBlock *Preheader,
|
||||
DominatorTree *DT, LoopInfo *LI,
|
||||
ScalarEvolution *SE, bool PreserveLCSSA,
|
||||
AssumptionCache *AC) {
|
||||
ScalarEvolution *SE, bool PreserveLCSSA) {
|
||||
// Don't try to separate loops without a preheader.
|
||||
if (!Preheader)
|
||||
return nullptr;
|
||||
@ -258,7 +255,7 @@ static Loop *separateNestedLoop(Loop *L, BasicBlock *Preheader,
|
||||
BasicBlock *Header = L->getHeader();
|
||||
assert(!Header->isEHPad() && "Can't insert backedge to EH pad");
|
||||
|
||||
PHINode *PN = findPHIToPartitionLoops(L, DT, AC);
|
||||
PHINode *PN = findPHIToPartitionLoops(L, DT);
|
||||
if (!PN) return nullptr; // No known way to partition.
|
||||
|
||||
// Pull out all predecessors that have varying values in the loop. This
|
||||
@ -501,8 +498,7 @@ static BasicBlock *insertUniqueBackedgeBlock(Loop *L, BasicBlock *Preheader,
|
||||
/// \brief Simplify one loop and queue further loops for simplification.
|
||||
static bool simplifyOneLoop(Loop *L, SmallVectorImpl<Loop *> &Worklist,
|
||||
DominatorTree *DT, LoopInfo *LI,
|
||||
ScalarEvolution *SE, AssumptionCache *AC,
|
||||
bool PreserveLCSSA) {
|
||||
ScalarEvolution *SE, bool PreserveLCSSA) {
|
||||
bool Changed = false;
|
||||
ReprocessLoop:
|
||||
|
||||
@ -596,7 +592,7 @@ ReprocessLoop:
|
||||
// common backedge instead.
|
||||
if (L->getNumBackEdges() < 8) {
|
||||
if (Loop *OuterL =
|
||||
separateNestedLoop(L, Preheader, DT, LI, SE, PreserveLCSSA, AC)) {
|
||||
separateNestedLoop(L, Preheader, DT, LI, SE, PreserveLCSSA)) {
|
||||
++NumNested;
|
||||
// Enqueue the outer loop as it should be processed next in our
|
||||
// depth-first nest walk.
|
||||
@ -628,7 +624,7 @@ ReprocessLoop:
|
||||
PHINode *PN;
|
||||
for (BasicBlock::iterator I = L->getHeader()->begin();
|
||||
(PN = dyn_cast<PHINode>(I++)); )
|
||||
if (Value *V = SimplifyInstruction(PN, DL, nullptr, DT, AC)) {
|
||||
if (Value *V = SimplifyInstruction(PN, DL, nullptr, DT)) {
|
||||
if (SE) SE->forgetValue(PN);
|
||||
if (!PreserveLCSSA || LI->replacementPreservesLCSSAForm(PN, V)) {
|
||||
PN->replaceAllUsesWith(V);
|
||||
@ -731,8 +727,7 @@ ReprocessLoop:
|
||||
}
|
||||
|
||||
bool llvm::simplifyLoop(Loop *L, DominatorTree *DT, LoopInfo *LI,
|
||||
ScalarEvolution *SE, AssumptionCache *AC,
|
||||
bool PreserveLCSSA) {
|
||||
ScalarEvolution *SE, bool PreserveLCSSA) {
|
||||
bool Changed = false;
|
||||
|
||||
// Worklist maintains our depth-first queue of loops in this nest to process.
|
||||
@ -749,7 +744,7 @@ bool llvm::simplifyLoop(Loop *L, DominatorTree *DT, LoopInfo *LI,
|
||||
|
||||
while (!Worklist.empty())
|
||||
Changed |= simplifyOneLoop(Worklist.pop_back_val(), Worklist, DT, LI, SE,
|
||||
AC, PreserveLCSSA);
|
||||
PreserveLCSSA);
|
||||
|
||||
return Changed;
|
||||
}
|
||||
@ -764,8 +759,6 @@ namespace {
|
||||
bool runOnFunction(Function &F) override;
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
|
||||
// We need loop information to identify the loops...
|
||||
AU.addRequired<DominatorTreeWrapperPass>();
|
||||
AU.addPreserved<DominatorTreeWrapperPass>();
|
||||
@ -791,7 +784,6 @@ namespace {
|
||||
char LoopSimplify::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(LoopSimplify, "loop-simplify",
|
||||
"Canonicalize natural loops", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
|
||||
INITIALIZE_PASS_END(LoopSimplify, "loop-simplify",
|
||||
@ -810,8 +802,6 @@ bool LoopSimplify::runOnFunction(Function &F) {
|
||||
DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||
auto *SEWP = getAnalysisIfAvailable<ScalarEvolutionWrapperPass>();
|
||||
ScalarEvolution *SE = SEWP ? &SEWP->getSE() : nullptr;
|
||||
AssumptionCache *AC =
|
||||
&getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
|
||||
|
||||
bool PreserveLCSSA = mustPreserveAnalysisID(LCSSAID);
|
||||
#ifndef NDEBUG
|
||||
@ -826,7 +816,7 @@ bool LoopSimplify::runOnFunction(Function &F) {
|
||||
|
||||
// Simplify each loop nest in the function.
|
||||
for (LoopInfo::iterator I = LI->begin(), E = LI->end(); I != E; ++I)
|
||||
Changed |= simplifyLoop(*I, DT, LI, SE, AC, PreserveLCSSA);
|
||||
Changed |= simplifyLoop(*I, DT, LI, SE, PreserveLCSSA);
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (PreserveLCSSA) {
|
||||
@ -844,12 +834,11 @@ PreservedAnalyses LoopSimplifyPass::run(Function &F,
|
||||
LoopInfo *LI = &AM.getResult<LoopAnalysis>(F);
|
||||
DominatorTree *DT = &AM.getResult<DominatorTreeAnalysis>(F);
|
||||
ScalarEvolution *SE = AM.getCachedResult<ScalarEvolutionAnalysis>(F);
|
||||
AssumptionCache *AC = &AM.getResult<AssumptionAnalysis>(F);
|
||||
|
||||
// FIXME: This pass should verify that the loops on which it's operating
|
||||
// are in canonical SSA form, and that the pass itself preserves this form.
|
||||
for (LoopInfo::iterator I = LI->begin(), E = LI->end(); I != E; ++I)
|
||||
Changed |= simplifyLoop(*I, DT, LI, SE, AC, true /* PreserveLCSSA */);
|
||||
Changed |= simplifyLoop(*I, DT, LI, SE, true /* PreserveLCSSA */);
|
||||
|
||||
// FIXME: We need to invalidate this to avoid PR28400. Is there a better
|
||||
// solution?
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "llvm/Transforms/Utils/UnrollLoop.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/InstructionSimplify.h"
|
||||
#include "llvm/Analysis/LoopIterator.h"
|
||||
#include "llvm/Analysis/LoopPass.h"
|
||||
@ -214,8 +213,7 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool Force,
|
||||
bool PreserveCondBr, bool PreserveOnlyFirst,
|
||||
unsigned TripMultiple, unsigned PeelCount, LoopInfo *LI,
|
||||
ScalarEvolution *SE, DominatorTree *DT,
|
||||
AssumptionCache *AC, OptimizationRemarkEmitter *ORE,
|
||||
bool PreserveLCSSA) {
|
||||
OptimizationRemarkEmitter *ORE, bool PreserveLCSSA) {
|
||||
|
||||
BasicBlock *Preheader = L->getLoopPreheader();
|
||||
if (!Preheader) {
|
||||
@ -512,14 +510,9 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool Force,
|
||||
}
|
||||
|
||||
// Remap all instructions in the most recent iteration
|
||||
for (BasicBlock *NewBlock : NewBlocks) {
|
||||
for (Instruction &I : *NewBlock) {
|
||||
for (BasicBlock *NewBlock : NewBlocks)
|
||||
for (Instruction &I : *NewBlock)
|
||||
::remapInstruction(&I, LastValueMap);
|
||||
if (auto *II = dyn_cast<IntrinsicInst>(&I))
|
||||
if (II->getIntrinsicID() == Intrinsic::assume)
|
||||
AC->registerAssumption(II);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Loop over the PHI nodes in the original block, setting incoming values.
|
||||
@ -705,7 +698,7 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool Force,
|
||||
// loops too).
|
||||
// TODO: That potentially might be compile-time expensive. We should try
|
||||
// to fix the loop-simplified form incrementally.
|
||||
simplifyLoop(OuterL, DT, LI, SE, AC, PreserveLCSSA);
|
||||
simplifyLoop(OuterL, DT, LI, SE, PreserveLCSSA);
|
||||
|
||||
// LCSSA must be performed on the outermost affected loop. The unrolled
|
||||
// loop's last loop latch is guaranteed to be in the outermost loop after
|
||||
@ -723,7 +716,7 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool Force,
|
||||
} else {
|
||||
// Simplify loops for which we might've broken loop-simplify form.
|
||||
for (Loop *SubLoop : LoopsToSimplify)
|
||||
simplifyLoop(SubLoop, DT, LI, SE, AC, PreserveLCSSA);
|
||||
simplifyLoop(SubLoop, DT, LI, SE, PreserveLCSSA);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
#include "llvm/Transforms/Utils/Mem2Reg.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/IR/Dominators.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
@ -27,8 +26,7 @@ using namespace llvm;
|
||||
|
||||
STATISTIC(NumPromoted, "Number of alloca's promoted");
|
||||
|
||||
static bool promoteMemoryToRegister(Function &F, DominatorTree &DT,
|
||||
AssumptionCache &AC) {
|
||||
static bool promoteMemoryToRegister(Function &F, DominatorTree &DT) {
|
||||
std::vector<AllocaInst *> Allocas;
|
||||
BasicBlock &BB = F.getEntryBlock(); // Get the entry node for the function
|
||||
bool Changed = false;
|
||||
@ -46,7 +44,7 @@ static bool promoteMemoryToRegister(Function &F, DominatorTree &DT,
|
||||
if (Allocas.empty())
|
||||
break;
|
||||
|
||||
PromoteMemToReg(Allocas, DT, nullptr, &AC);
|
||||
PromoteMemToReg(Allocas, DT, nullptr);
|
||||
NumPromoted += Allocas.size();
|
||||
Changed = true;
|
||||
}
|
||||
@ -55,8 +53,7 @@ static bool promoteMemoryToRegister(Function &F, DominatorTree &DT,
|
||||
|
||||
PreservedAnalyses PromotePass::run(Function &F, FunctionAnalysisManager &AM) {
|
||||
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
|
||||
auto &AC = AM.getResult<AssumptionAnalysis>(F);
|
||||
if (!promoteMemoryToRegister(F, DT, AC))
|
||||
if (!promoteMemoryToRegister(F, DT))
|
||||
return PreservedAnalyses::all();
|
||||
|
||||
// FIXME: This should also 'preserve the CFG'.
|
||||
@ -78,13 +75,10 @@ struct PromoteLegacyPass : public FunctionPass {
|
||||
return false;
|
||||
|
||||
DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||
AssumptionCache &AC =
|
||||
getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
|
||||
return promoteMemoryToRegister(F, DT, AC);
|
||||
return promoteMemoryToRegister(F, DT);
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
AU.addRequired<DominatorTreeWrapperPass>();
|
||||
AU.setPreservesCFG();
|
||||
}
|
||||
@ -95,7 +89,6 @@ char PromoteLegacyPass::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(PromoteLegacyPass, "mem2reg", "Promote Memory to "
|
||||
"Register",
|
||||
false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
|
||||
INITIALIZE_PASS_END(PromoteLegacyPass, "mem2reg", "Promote Memory to Register",
|
||||
false, false)
|
||||
|
@ -228,9 +228,6 @@ struct PromoteMem2Reg {
|
||||
/// An AliasSetTracker object to update. If null, don't update it.
|
||||
AliasSetTracker *AST;
|
||||
|
||||
/// A cache of @llvm.assume intrinsics used by SimplifyInstruction.
|
||||
AssumptionCache *AC;
|
||||
|
||||
/// Reverse mapping of Allocas.
|
||||
DenseMap<AllocaInst *, unsigned> AllocaLookup;
|
||||
|
||||
@ -269,10 +266,10 @@ struct PromoteMem2Reg {
|
||||
|
||||
public:
|
||||
PromoteMem2Reg(ArrayRef<AllocaInst *> Allocas, DominatorTree &DT,
|
||||
AliasSetTracker *AST, AssumptionCache *AC)
|
||||
AliasSetTracker *AST)
|
||||
: Allocas(Allocas.begin(), Allocas.end()), DT(DT),
|
||||
DIB(*DT.getRoot()->getParent()->getParent(), /*AllowUnresolved*/ false),
|
||||
AST(AST), AC(AC) {}
|
||||
AST(AST) {}
|
||||
|
||||
void run();
|
||||
|
||||
@ -693,7 +690,7 @@ void PromoteMem2Reg::run() {
|
||||
PHINode *PN = I->second;
|
||||
|
||||
// If this PHI node merges one value and/or undefs, get the value.
|
||||
if (Value *V = SimplifyInstruction(PN, DL, nullptr, &DT, AC)) {
|
||||
if (Value *V = SimplifyInstruction(PN, DL, nullptr, &DT)) {
|
||||
if (AST && PN->getType()->isPointerTy())
|
||||
AST->deleteValue(PN);
|
||||
PN->replaceAllUsesWith(V);
|
||||
@ -987,10 +984,10 @@ NextIteration:
|
||||
}
|
||||
|
||||
void llvm::PromoteMemToReg(ArrayRef<AllocaInst *> Allocas, DominatorTree &DT,
|
||||
AliasSetTracker *AST, AssumptionCache *AC) {
|
||||
AliasSetTracker *AST) {
|
||||
// If there is nothing to do, bail out...
|
||||
if (Allocas.empty())
|
||||
return;
|
||||
|
||||
PromoteMem2Reg(Allocas, DT, AST, AC).run();
|
||||
PromoteMem2Reg(Allocas, DT, AST).run();
|
||||
}
|
||||
|
@ -166,7 +166,6 @@ class SimplifyCFGOpt {
|
||||
const TargetTransformInfo &TTI;
|
||||
const DataLayout &DL;
|
||||
unsigned BonusInstThreshold;
|
||||
AssumptionCache *AC;
|
||||
SmallPtrSetImpl<BasicBlock *> *LoopHeaders;
|
||||
Value *isValueEqualityComparison(TerminatorInst *TI);
|
||||
BasicBlock *GetValueEqualityComparisonCases(
|
||||
@ -190,9 +189,9 @@ class SimplifyCFGOpt {
|
||||
|
||||
public:
|
||||
SimplifyCFGOpt(const TargetTransformInfo &TTI, const DataLayout &DL,
|
||||
unsigned BonusInstThreshold, AssumptionCache *AC,
|
||||
unsigned BonusInstThreshold,
|
||||
SmallPtrSetImpl<BasicBlock *> *LoopHeaders)
|
||||
: TTI(TTI), DL(DL), BonusInstThreshold(BonusInstThreshold), AC(AC),
|
||||
: TTI(TTI), DL(DL), BonusInstThreshold(BonusInstThreshold),
|
||||
LoopHeaders(LoopHeaders) {}
|
||||
|
||||
bool run(BasicBlock *BB);
|
||||
@ -3474,8 +3473,7 @@ static bool SimplifyIndirectBrOnSelect(IndirectBrInst *IBI, SelectInst *SI) {
|
||||
/// the PHI, merging the third icmp into the switch.
|
||||
static bool TryToSimplifyUncondBranchWithICmpInIt(
|
||||
ICmpInst *ICI, IRBuilder<> &Builder, const DataLayout &DL,
|
||||
const TargetTransformInfo &TTI, unsigned BonusInstThreshold,
|
||||
AssumptionCache *AC) {
|
||||
const TargetTransformInfo &TTI, unsigned BonusInstThreshold) {
|
||||
BasicBlock *BB = ICI->getParent();
|
||||
|
||||
// If the block has any PHIs in it or the icmp has multiple uses, it is too
|
||||
@ -3510,7 +3508,7 @@ static bool TryToSimplifyUncondBranchWithICmpInIt(
|
||||
ICI->eraseFromParent();
|
||||
}
|
||||
// BB is now empty, so it is likely to simplify away.
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold) | true;
|
||||
}
|
||||
|
||||
// Ok, the block is reachable from the default dest. If the constant we're
|
||||
@ -3526,7 +3524,7 @@ static bool TryToSimplifyUncondBranchWithICmpInIt(
|
||||
ICI->replaceAllUsesWith(V);
|
||||
ICI->eraseFromParent();
|
||||
// BB is now empty, so it is likely to simplify away.
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold) | true;
|
||||
}
|
||||
|
||||
// The use of the icmp has to be in the 'end' block, by the only PHI node in
|
||||
@ -4323,17 +4321,16 @@ static bool TurnSwitchRangeIntoICmp(SwitchInst *SI, IRBuilder<> &Builder) {
|
||||
|
||||
/// Compute masked bits for the condition of a switch
|
||||
/// and use it to remove dead cases.
|
||||
static bool EliminateDeadSwitchCases(SwitchInst *SI, AssumptionCache *AC,
|
||||
const DataLayout &DL) {
|
||||
static bool EliminateDeadSwitchCases(SwitchInst *SI, const DataLayout &DL) {
|
||||
Value *Cond = SI->getCondition();
|
||||
unsigned Bits = Cond->getType()->getIntegerBitWidth();
|
||||
APInt KnownZero(Bits, 0), KnownOne(Bits, 0);
|
||||
computeKnownBits(Cond, KnownZero, KnownOne, DL, 0, AC, SI);
|
||||
computeKnownBits(Cond, KnownZero, KnownOne, DL, 0, SI);
|
||||
|
||||
// We can also eliminate cases by determining that their values are outside of
|
||||
// the limited range of the condition based on how many significant (non-sign)
|
||||
// bits are in the condition value.
|
||||
unsigned ExtraSignBits = ComputeNumSignBits(Cond, DL, 0, AC, SI) - 1;
|
||||
unsigned ExtraSignBits = ComputeNumSignBits(Cond, DL, 0, SI) - 1;
|
||||
unsigned MaxSignificantBitsInCond = Bits - ExtraSignBits;
|
||||
|
||||
// Gather dead cases.
|
||||
@ -4753,7 +4750,7 @@ static void RemoveSwitchAfterSelectConversion(SwitchInst *SI, PHINode *PHI,
|
||||
/// phi nodes in a common successor block with only two different
|
||||
/// constant values, replace the switch with select.
|
||||
static bool SwitchToSelect(SwitchInst *SI, IRBuilder<> &Builder,
|
||||
AssumptionCache *AC, const DataLayout &DL,
|
||||
const DataLayout &DL,
|
||||
const TargetTransformInfo &TTI) {
|
||||
Value *const Cond = SI->getCondition();
|
||||
PHINode *PHI = nullptr;
|
||||
@ -5500,12 +5497,12 @@ bool SimplifyCFGOpt::SimplifySwitch(SwitchInst *SI, IRBuilder<> &Builder) {
|
||||
// see if that predecessor totally determines the outcome of this switch.
|
||||
if (BasicBlock *OnlyPred = BB->getSinglePredecessor())
|
||||
if (SimplifyEqualityComparisonWithOnlyPredecessor(SI, OnlyPred, Builder))
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold) | true;
|
||||
|
||||
Value *Cond = SI->getCondition();
|
||||
if (SelectInst *Select = dyn_cast<SelectInst>(Cond))
|
||||
if (SimplifySwitchOnSelect(SI, Select))
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold) | true;
|
||||
|
||||
// If the block only contains the switch, see if we can fold the block
|
||||
// away into any preds.
|
||||
@ -5515,28 +5512,28 @@ bool SimplifyCFGOpt::SimplifySwitch(SwitchInst *SI, IRBuilder<> &Builder) {
|
||||
++BBI;
|
||||
if (SI == &*BBI)
|
||||
if (FoldValueComparisonIntoPredecessors(SI, Builder))
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold) | true;
|
||||
}
|
||||
|
||||
// Try to transform the switch into an icmp and a branch.
|
||||
if (TurnSwitchRangeIntoICmp(SI, Builder))
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold) | true;
|
||||
|
||||
// Remove unreachable cases.
|
||||
if (EliminateDeadSwitchCases(SI, AC, DL))
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
|
||||
if (EliminateDeadSwitchCases(SI, DL))
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold) | true;
|
||||
|
||||
if (SwitchToSelect(SI, Builder, AC, DL, TTI))
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
|
||||
if (SwitchToSelect(SI, Builder, DL, TTI))
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold) | true;
|
||||
|
||||
if (ForwardSwitchConditionToPHI(SI))
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold) | true;
|
||||
|
||||
if (SwitchToLookupTable(SI, Builder, DL, TTI))
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold) | true;
|
||||
|
||||
if (ReduceSwitchRange(SI, Builder, DL, TTI))
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold) | true;
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -5574,7 +5571,7 @@ bool SimplifyCFGOpt::SimplifyIndirectBr(IndirectBrInst *IBI) {
|
||||
|
||||
if (SelectInst *SI = dyn_cast<SelectInst>(IBI->getAddress())) {
|
||||
if (SimplifyIndirectBrOnSelect(IBI, SI))
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold) | true;
|
||||
}
|
||||
return Changed;
|
||||
}
|
||||
@ -5683,7 +5680,7 @@ bool SimplifyCFGOpt::SimplifyUncondBranch(BranchInst *BI,
|
||||
;
|
||||
if (I->isTerminator() &&
|
||||
TryToSimplifyUncondBranchWithICmpInIt(ICI, Builder, DL, TTI,
|
||||
BonusInstThreshold, AC))
|
||||
BonusInstThreshold))
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -5701,7 +5698,7 @@ bool SimplifyCFGOpt::SimplifyUncondBranch(BranchInst *BI,
|
||||
// predecessor and use logical operations to update the incoming value
|
||||
// for PHI nodes in common successor.
|
||||
if (FoldBranchToCommonDest(BI, BonusInstThreshold))
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold) | true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -5726,7 +5723,7 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
|
||||
// switch.
|
||||
if (BasicBlock *OnlyPred = BB->getSinglePredecessor())
|
||||
if (SimplifyEqualityComparisonWithOnlyPredecessor(BI, OnlyPred, Builder))
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold) | true;
|
||||
|
||||
// This block must be empty, except for the setcond inst, if it exists.
|
||||
// Ignore dbg intrinsics.
|
||||
@ -5736,14 +5733,14 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
|
||||
++I;
|
||||
if (&*I == BI) {
|
||||
if (FoldValueComparisonIntoPredecessors(BI, Builder))
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold) | true;
|
||||
} else if (&*I == cast<Instruction>(BI->getCondition())) {
|
||||
++I;
|
||||
// Ignore dbg intrinsics.
|
||||
while (isa<DbgInfoIntrinsic>(I))
|
||||
++I;
|
||||
if (&*I == BI && FoldValueComparisonIntoPredecessors(BI, Builder))
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold) | true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -5770,7 +5767,7 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
|
||||
: ConstantInt::getFalse(BB->getContext());
|
||||
BI->setCondition(CI);
|
||||
RecursivelyDeleteTriviallyDeadInstructions(OldCond);
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold) | true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5779,7 +5776,7 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
|
||||
// branches to us and one of our successors, fold the comparison into the
|
||||
// predecessor and use logical operations to pick the right destination.
|
||||
if (FoldBranchToCommonDest(BI, BonusInstThreshold))
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold) | true;
|
||||
|
||||
// We have a conditional branch to two blocks that are only reachable
|
||||
// from BI. We know that the condbr dominates the two blocks, so see if
|
||||
@ -5788,7 +5785,7 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
|
||||
if (BI->getSuccessor(0)->getSinglePredecessor()) {
|
||||
if (BI->getSuccessor(1)->getSinglePredecessor()) {
|
||||
if (HoistThenElseCodeToIf(BI, TTI))
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold) | true;
|
||||
} else {
|
||||
// If Successor #1 has multiple preds, we may be able to conditionally
|
||||
// execute Successor #0 if it branches to Successor #1.
|
||||
@ -5796,7 +5793,7 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
|
||||
if (Succ0TI->getNumSuccessors() == 1 &&
|
||||
Succ0TI->getSuccessor(0) == BI->getSuccessor(1))
|
||||
if (SpeculativelyExecuteBB(BI, BI->getSuccessor(0), TTI))
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold) | true;
|
||||
}
|
||||
} else if (BI->getSuccessor(1)->getSinglePredecessor()) {
|
||||
// If Successor #0 has multiple preds, we may be able to conditionally
|
||||
@ -5805,7 +5802,7 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
|
||||
if (Succ1TI->getNumSuccessors() == 1 &&
|
||||
Succ1TI->getSuccessor(0) == BI->getSuccessor(0))
|
||||
if (SpeculativelyExecuteBB(BI, BI->getSuccessor(1), TTI))
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold) | true;
|
||||
}
|
||||
|
||||
// If this is a branch on a phi node in the current block, thread control
|
||||
@ -5813,14 +5810,14 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
|
||||
if (PHINode *PN = dyn_cast<PHINode>(BI->getCondition()))
|
||||
if (PN->getParent() == BI->getParent())
|
||||
if (FoldCondBranchOnPHI(BI, DL))
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold) | true;
|
||||
|
||||
// Scan predecessor blocks for conditional branches.
|
||||
for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI)
|
||||
if (BranchInst *PBI = dyn_cast<BranchInst>((*PI)->getTerminator()))
|
||||
if (PBI != BI && PBI->isConditional())
|
||||
if (SimplifyCondBranchToCondBranch(PBI, BI, DL))
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold) | true;
|
||||
|
||||
// Look for diamond patterns.
|
||||
if (MergeCondStores)
|
||||
@ -5828,7 +5825,7 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
|
||||
if (BranchInst *PBI = dyn_cast<BranchInst>(PrevBB->getTerminator()))
|
||||
if (PBI != BI && PBI->isConditional())
|
||||
if (mergeConditionalStores(PBI, BI))
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
|
||||
return SimplifyCFG(BB, TTI, BonusInstThreshold) | true;
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -5990,9 +5987,9 @@ bool SimplifyCFGOpt::run(BasicBlock *BB) {
|
||||
/// of the CFG. It returns true if a modification was made.
|
||||
///
|
||||
bool llvm::SimplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
|
||||
unsigned BonusInstThreshold, AssumptionCache *AC,
|
||||
unsigned BonusInstThreshold,
|
||||
SmallPtrSetImpl<BasicBlock *> *LoopHeaders) {
|
||||
return SimplifyCFGOpt(TTI, BB->getModule()->getDataLayout(),
|
||||
BonusInstThreshold, AC, LoopHeaders)
|
||||
BonusInstThreshold, LoopHeaders)
|
||||
.run(BB);
|
||||
}
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "llvm/ADT/DepthFirstIterator.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/InstructionSimplify.h"
|
||||
#include "llvm/Analysis/TargetLibraryInfo.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
@ -35,7 +34,7 @@ using namespace llvm;
|
||||
STATISTIC(NumSimplified, "Number of redundant instructions removed");
|
||||
|
||||
static bool runImpl(Function &F, const DominatorTree *DT,
|
||||
const TargetLibraryInfo *TLI, AssumptionCache *AC) {
|
||||
const TargetLibraryInfo *TLI) {
|
||||
const DataLayout &DL = F.getParent()->getDataLayout();
|
||||
SmallPtrSet<const Instruction *, 8> S1, S2, *ToSimplify = &S1, *Next = &S2;
|
||||
bool Changed = false;
|
||||
@ -54,7 +53,7 @@ static bool runImpl(Function &F, const DominatorTree *DT,
|
||||
|
||||
// Don't waste time simplifying unused instructions.
|
||||
if (!I->use_empty()) {
|
||||
if (Value *V = SimplifyInstruction(I, DL, TLI, DT, AC)) {
|
||||
if (Value *V = SimplifyInstruction(I, DL, TLI, DT)) {
|
||||
// Mark all uses for resimplification next time round the loop.
|
||||
for (User *U : I->users())
|
||||
Next->insert(cast<Instruction>(U));
|
||||
@ -93,7 +92,6 @@ namespace {
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.setPreservesCFG();
|
||||
AU.addRequired<DominatorTreeWrapperPass>();
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
AU.addRequired<TargetLibraryInfoWrapperPass>();
|
||||
}
|
||||
|
||||
@ -106,9 +104,7 @@ namespace {
|
||||
&getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||
const TargetLibraryInfo *TLI =
|
||||
&getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
|
||||
AssumptionCache *AC =
|
||||
&getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
|
||||
return runImpl(F, DT, TLI, AC);
|
||||
return runImpl(F, DT, TLI);
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -116,7 +112,6 @@ namespace {
|
||||
char InstSimplifier::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(InstSimplifier, "instsimplify",
|
||||
"Remove redundant instructions", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
|
||||
INITIALIZE_PASS_END(InstSimplifier, "instsimplify",
|
||||
@ -132,8 +127,7 @@ PreservedAnalyses InstSimplifierPass::run(Function &F,
|
||||
FunctionAnalysisManager &AM) {
|
||||
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
|
||||
auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
|
||||
auto &AC = AM.getResult<AssumptionAnalysis>(F);
|
||||
bool Changed = runImpl(F, &DT, &TLI, &AC);
|
||||
bool Changed = runImpl(F, &DT, &TLI);
|
||||
if (!Changed)
|
||||
return PreservedAnalyses::all();
|
||||
// FIXME: This should also 'preserve the CFG'.
|
||||
|
@ -461,8 +461,7 @@ Value *LibCallSimplifier::optimizeStrLen(CallInst *CI, IRBuilder<> &B) {
|
||||
unsigned BitWidth = Offset->getType()->getIntegerBitWidth();
|
||||
APInt KnownZero(BitWidth, 0);
|
||||
APInt KnownOne(BitWidth, 0);
|
||||
computeKnownBits(Offset, KnownZero, KnownOne, DL, 0, nullptr, CI,
|
||||
nullptr);
|
||||
computeKnownBits(Offset, KnownZero, KnownOne, DL, 0, CI, nullptr);
|
||||
KnownZero.flipAllBits();
|
||||
size_t ArrSize =
|
||||
cast<ArrayType>(GEP->getSourceElementType())->getNumElements();
|
||||
|
@ -330,7 +330,7 @@ bool Vectorizer::isConsecutiveAccess(Value *A, Value *B) {
|
||||
if (!Safe) {
|
||||
APInt KnownZero(BitWidth, 0);
|
||||
APInt KnownOne(BitWidth, 0);
|
||||
computeKnownBits(OpA, KnownZero, KnownOne, DL, 0, nullptr, OpA, &DT);
|
||||
computeKnownBits(OpA, KnownZero, KnownOne, DL, 0, OpA, &DT);
|
||||
KnownZero &= ~APInt::getHighBitsSet(BitWidth, 1);
|
||||
if (KnownZero != 0)
|
||||
Safe = true;
|
||||
@ -819,7 +819,7 @@ bool Vectorizer::vectorizeStoreChain(
|
||||
|
||||
unsigned NewAlign = getOrEnforceKnownAlignment(S0->getPointerOperand(),
|
||||
StackAdjustedAlignment,
|
||||
DL, S0, nullptr, &DT);
|
||||
DL, S0, &DT);
|
||||
if (NewAlign < StackAdjustedAlignment)
|
||||
return false;
|
||||
}
|
||||
@ -960,7 +960,7 @@ bool Vectorizer::vectorizeLoadChain(
|
||||
|
||||
unsigned NewAlign = getOrEnforceKnownAlignment(L0->getPointerOperand(),
|
||||
StackAdjustedAlignment,
|
||||
DL, L0, nullptr, &DT);
|
||||
DL, L0, &DT);
|
||||
if (NewAlign < StackAdjustedAlignment)
|
||||
return false;
|
||||
|
||||
|
@ -369,12 +369,12 @@ public:
|
||||
InnerLoopVectorizer(Loop *OrigLoop, PredicatedScalarEvolution &PSE,
|
||||
LoopInfo *LI, DominatorTree *DT,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const TargetTransformInfo *TTI, AssumptionCache *AC,
|
||||
const TargetTransformInfo *TTI,
|
||||
OptimizationRemarkEmitter *ORE, unsigned VecWidth,
|
||||
unsigned UnrollFactor, LoopVectorizationLegality *LVL,
|
||||
LoopVectorizationCostModel *CM)
|
||||
: OrigLoop(OrigLoop), PSE(PSE), LI(LI), DT(DT), TLI(TLI), TTI(TTI),
|
||||
AC(AC), ORE(ORE), VF(VecWidth), UF(UnrollFactor),
|
||||
ORE(ORE), VF(VecWidth), UF(UnrollFactor),
|
||||
Builder(PSE.getSE()->getContext()), Induction(nullptr),
|
||||
OldInduction(nullptr), VectorLoopValueMap(UnrollFactor, VecWidth),
|
||||
TripCount(nullptr), VectorTripCount(nullptr), Legal(LVL), Cost(CM),
|
||||
@ -706,8 +706,6 @@ protected:
|
||||
const TargetLibraryInfo *TLI;
|
||||
/// Target Transform Info.
|
||||
const TargetTransformInfo *TTI;
|
||||
/// Assumption Cache.
|
||||
AssumptionCache *AC;
|
||||
/// Interface to emit optimization remarks.
|
||||
OptimizationRemarkEmitter *ORE;
|
||||
|
||||
@ -790,11 +788,11 @@ public:
|
||||
InnerLoopUnroller(Loop *OrigLoop, PredicatedScalarEvolution &PSE,
|
||||
LoopInfo *LI, DominatorTree *DT,
|
||||
const TargetLibraryInfo *TLI,
|
||||
const TargetTransformInfo *TTI, AssumptionCache *AC,
|
||||
const TargetTransformInfo *TTI,
|
||||
OptimizationRemarkEmitter *ORE, unsigned UnrollFactor,
|
||||
LoopVectorizationLegality *LVL,
|
||||
LoopVectorizationCostModel *CM)
|
||||
: InnerLoopVectorizer(OrigLoop, PSE, LI, DT, TLI, TTI, AC, ORE, 1,
|
||||
: InnerLoopVectorizer(OrigLoop, PSE, LI, DT, TLI, TTI, ORE, 1,
|
||||
UnrollFactor, LVL, CM) {}
|
||||
|
||||
private:
|
||||
@ -1850,11 +1848,10 @@ public:
|
||||
LoopInfo *LI, LoopVectorizationLegality *Legal,
|
||||
const TargetTransformInfo &TTI,
|
||||
const TargetLibraryInfo *TLI, DemandedBits *DB,
|
||||
AssumptionCache *AC,
|
||||
OptimizationRemarkEmitter *ORE, const Function *F,
|
||||
const LoopVectorizeHints *Hints)
|
||||
: TheLoop(L), PSE(PSE), LI(LI), Legal(Legal), TTI(TTI), TLI(TLI), DB(DB),
|
||||
AC(AC), ORE(ORE), TheFunction(F), Hints(Hints) {}
|
||||
ORE(ORE), TheFunction(F), Hints(Hints) {}
|
||||
|
||||
/// Information about vectorization costs
|
||||
struct VectorizationFactor {
|
||||
@ -2000,8 +1997,6 @@ public:
|
||||
const TargetLibraryInfo *TLI;
|
||||
/// Demanded bits analysis.
|
||||
DemandedBits *DB;
|
||||
/// Assumption cache.
|
||||
AssumptionCache *AC;
|
||||
/// Interface to emit optimization remarks.
|
||||
OptimizationRemarkEmitter *ORE;
|
||||
|
||||
@ -2115,7 +2110,6 @@ struct LoopVectorize : public FunctionPass {
|
||||
auto *TLIP = getAnalysisIfAvailable<TargetLibraryInfoWrapperPass>();
|
||||
auto *TLI = TLIP ? &TLIP->getTLI() : nullptr;
|
||||
auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
|
||||
auto *AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
|
||||
auto *LAA = &getAnalysis<LoopAccessLegacyAnalysis>();
|
||||
auto *DB = &getAnalysis<DemandedBitsWrapperPass>().getDemandedBits();
|
||||
auto *ORE = &getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
|
||||
@ -2123,12 +2117,11 @@ struct LoopVectorize : public FunctionPass {
|
||||
std::function<const LoopAccessInfo &(Loop &)> GetLAA =
|
||||
[&](Loop &L) -> const LoopAccessInfo & { return LAA->getInfo(&L); };
|
||||
|
||||
return Impl.runImpl(F, *SE, *LI, *TTI, *DT, *BFI, TLI, *DB, *AA, *AC,
|
||||
GetLAA, *ORE);
|
||||
return Impl.runImpl(F, *SE, *LI, *TTI, *DT, *BFI, TLI, *DB, *AA, GetLAA,
|
||||
*ORE);
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
AU.addRequiredID(LoopSimplifyID);
|
||||
AU.addRequiredID(LCSSAID);
|
||||
AU.addRequired<BlockFrequencyInfoWrapperPass>();
|
||||
@ -3056,11 +3049,6 @@ void InnerLoopVectorizer::scalarizeInstruction(Instruction *Instr,
|
||||
// Add the cloned scalar to the scalar map entry.
|
||||
Entry[Part][Lane] = Cloned;
|
||||
|
||||
// If we just cloned a new assumption, add it the assumption cache.
|
||||
if (auto *II = dyn_cast<IntrinsicInst>(Cloned))
|
||||
if (II->getIntrinsicID() == Intrinsic::assume)
|
||||
AC->registerAssumption(II);
|
||||
|
||||
// End if-block.
|
||||
if (IfPredicateInstr)
|
||||
PredicatedInstructions.push_back(std::make_pair(Cloned, Cmp));
|
||||
@ -7164,7 +7152,6 @@ INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(BasicAAWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
|
||||
@ -7193,7 +7180,7 @@ bool LoopVectorizationCostModel::isConsecutiveLoadOrStore(Instruction *Inst) {
|
||||
|
||||
void LoopVectorizationCostModel::collectValuesToIgnore() {
|
||||
// Ignore ephemeral values.
|
||||
CodeMetrics::collectEphemeralValues(TheLoop, AC, ValuesToIgnore);
|
||||
CodeMetrics::collectEphemeralValues(TheLoop, ValuesToIgnore);
|
||||
|
||||
// Ignore type-promoting instructions we identified during reduction
|
||||
// detection.
|
||||
@ -7267,11 +7254,6 @@ void InnerLoopUnroller::scalarizeInstruction(Instruction *Instr,
|
||||
// Add the cloned scalar to the scalar map entry.
|
||||
Entry[Part][0] = Cloned;
|
||||
|
||||
// If we just cloned a new assumption, add it the assumption cache.
|
||||
if (auto *II = dyn_cast<IntrinsicInst>(Cloned))
|
||||
if (II->getIntrinsicID() == Intrinsic::assume)
|
||||
AC->registerAssumption(II);
|
||||
|
||||
// End if-block.
|
||||
if (IfPredicateInstr)
|
||||
PredicatedInstructions.push_back(std::make_pair(Cloned, Cmp));
|
||||
@ -7411,7 +7393,7 @@ bool LoopVectorizePass::processLoop(Loop *L) {
|
||||
}
|
||||
|
||||
// Use the cost model.
|
||||
LoopVectorizationCostModel CM(L, PSE, LI, &LVL, *TTI, TLI, DB, AC, ORE, F,
|
||||
LoopVectorizationCostModel CM(L, PSE, LI, &LVL, *TTI, TLI, DB, ORE, F,
|
||||
&Hints);
|
||||
CM.collectValuesToIgnore();
|
||||
|
||||
@ -7547,8 +7529,7 @@ bool LoopVectorizePass::processLoop(Loop *L) {
|
||||
assert(IC > 1 && "interleave count should not be 1 or 0");
|
||||
// If we decided that it is not legal to vectorize the loop, then
|
||||
// interleave it.
|
||||
InnerLoopUnroller Unroller(L, PSE, LI, DT, TLI, TTI, AC, ORE, IC, &LVL,
|
||||
&CM);
|
||||
InnerLoopUnroller Unroller(L, PSE, LI, DT, TLI, TTI, ORE, IC, &LVL, &CM);
|
||||
Unroller.vectorize();
|
||||
|
||||
ORE->emit(OptimizationRemark(LV_NAME, "Interleaved", L->getStartLoc(),
|
||||
@ -7557,8 +7538,8 @@ bool LoopVectorizePass::processLoop(Loop *L) {
|
||||
<< NV("InterleaveCount", IC) << ")");
|
||||
} else {
|
||||
// If we decided that it is *legal* to vectorize the loop, then do it.
|
||||
InnerLoopVectorizer LB(L, PSE, LI, DT, TLI, TTI, AC, ORE, VF.Width, IC,
|
||||
&LVL, &CM);
|
||||
InnerLoopVectorizer LB(L, PSE, LI, DT, TLI, TTI, ORE, VF.Width, IC, &LVL,
|
||||
&CM);
|
||||
LB.vectorize();
|
||||
++LoopsVectorized;
|
||||
|
||||
@ -7586,7 +7567,7 @@ bool LoopVectorizePass::processLoop(Loop *L) {
|
||||
bool LoopVectorizePass::runImpl(
|
||||
Function &F, ScalarEvolution &SE_, LoopInfo &LI_, TargetTransformInfo &TTI_,
|
||||
DominatorTree &DT_, BlockFrequencyInfo &BFI_, TargetLibraryInfo *TLI_,
|
||||
DemandedBits &DB_, AliasAnalysis &AA_, AssumptionCache &AC_,
|
||||
DemandedBits &DB_, AliasAnalysis &AA_,
|
||||
std::function<const LoopAccessInfo &(Loop &)> &GetLAA_,
|
||||
OptimizationRemarkEmitter &ORE_) {
|
||||
|
||||
@ -7597,7 +7578,6 @@ bool LoopVectorizePass::runImpl(
|
||||
BFI = &BFI_;
|
||||
TLI = TLI_;
|
||||
AA = &AA_;
|
||||
AC = &AC_;
|
||||
GetLAA = &GetLAA_;
|
||||
DB = &DB_;
|
||||
ORE = &ORE_;
|
||||
@ -7647,7 +7627,6 @@ PreservedAnalyses LoopVectorizePass::run(Function &F,
|
||||
auto &BFI = AM.getResult<BlockFrequencyAnalysis>(F);
|
||||
auto *TLI = AM.getCachedResult<TargetLibraryAnalysis>(F);
|
||||
auto &AA = AM.getResult<AAManager>(F);
|
||||
auto &AC = AM.getResult<AssumptionAnalysis>(F);
|
||||
auto &DB = AM.getResult<DemandedBitsAnalysis>(F);
|
||||
auto &ORE = AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
|
||||
|
||||
@ -7657,7 +7636,7 @@ PreservedAnalyses LoopVectorizePass::run(Function &F,
|
||||
return LAM.getResult<LoopAccessAnalysis>(L);
|
||||
};
|
||||
bool Changed =
|
||||
runImpl(F, SE, LI, TTI, DT, BFI, TLI, DB, AA, AC, GetLAA, ORE);
|
||||
runImpl(F, SE, LI, TTI, DT, BFI, TLI, DB, AA, GetLAA, ORE);
|
||||
if (!Changed)
|
||||
return PreservedAnalyses::all();
|
||||
PreservedAnalyses PA;
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/ADT/PostOrderIterator.h"
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Analysis/CodeMetrics.h"
|
||||
#include "llvm/Analysis/GlobalsModRef.h"
|
||||
@ -307,12 +308,11 @@ public:
|
||||
|
||||
BoUpSLP(Function *Func, ScalarEvolution *Se, TargetTransformInfo *Tti,
|
||||
TargetLibraryInfo *TLi, AliasAnalysis *Aa, LoopInfo *Li,
|
||||
DominatorTree *Dt, AssumptionCache *AC, DemandedBits *DB,
|
||||
const DataLayout *DL)
|
||||
DominatorTree *Dt, DemandedBits *DB, const DataLayout *DL)
|
||||
: NumLoadsWantToKeepOrder(0), NumLoadsWantToChangeOrder(0), F(Func),
|
||||
SE(Se), TTI(Tti), TLI(TLi), AA(Aa), LI(Li), DT(Dt), AC(AC), DB(DB),
|
||||
SE(Se), TTI(Tti), TLI(TLi), AA(Aa), LI(Li), DT(Dt), DB(DB),
|
||||
DL(DL), Builder(Se->getContext()) {
|
||||
CodeMetrics::collectEphemeralValues(F, AC, EphValues);
|
||||
CodeMetrics::collectEphemeralValues(F, EphValues);
|
||||
// Use the vector register size specified by the target unless overridden
|
||||
// by a command-line option.
|
||||
// TODO: It would be better to limit the vectorization factor based on
|
||||
@ -901,7 +901,6 @@ private:
|
||||
AliasAnalysis *AA;
|
||||
LoopInfo *LI;
|
||||
DominatorTree *DT;
|
||||
AssumptionCache *AC;
|
||||
DemandedBits *DB;
|
||||
const DataLayout *DL;
|
||||
unsigned MaxVecRegSize; // This is set by TTI or overridden by cl::opt.
|
||||
@ -3540,7 +3539,7 @@ void BoUpSLP::computeMinimumValueSizes() {
|
||||
// Determine the maximum number of bits required to store the scalar
|
||||
// values.
|
||||
for (auto *Scalar : ToDemote) {
|
||||
auto NumSignBits = ComputeNumSignBits(Scalar, *DL, 0, AC, 0, DT);
|
||||
auto NumSignBits = ComputeNumSignBits(Scalar, *DL, 0, 0, DT);
|
||||
auto NumTypeBits = DL->getTypeSizeInBits(Scalar->getType());
|
||||
MaxBitWidth = std::max<unsigned>(NumTypeBits - NumSignBits, MaxBitWidth);
|
||||
}
|
||||
@ -3612,15 +3611,13 @@ struct SLPVectorizer : public FunctionPass {
|
||||
auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
|
||||
auto *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
|
||||
auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||
auto *AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
|
||||
auto *DB = &getAnalysis<DemandedBitsWrapperPass>().getDemandedBits();
|
||||
|
||||
return Impl.runImpl(F, SE, TTI, TLI, AA, LI, DT, AC, DB);
|
||||
return Impl.runImpl(F, SE, TTI, TLI, AA, LI, DT, DB);
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
FunctionPass::getAnalysisUsage(AU);
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
AU.addRequired<ScalarEvolutionWrapperPass>();
|
||||
AU.addRequired<AAResultsWrapperPass>();
|
||||
AU.addRequired<TargetTransformInfoWrapperPass>();
|
||||
@ -3643,10 +3640,9 @@ PreservedAnalyses SLPVectorizerPass::run(Function &F, FunctionAnalysisManager &A
|
||||
auto *AA = &AM.getResult<AAManager>(F);
|
||||
auto *LI = &AM.getResult<LoopAnalysis>(F);
|
||||
auto *DT = &AM.getResult<DominatorTreeAnalysis>(F);
|
||||
auto *AC = &AM.getResult<AssumptionAnalysis>(F);
|
||||
auto *DB = &AM.getResult<DemandedBitsAnalysis>(F);
|
||||
|
||||
bool Changed = runImpl(F, SE, TTI, TLI, AA, LI, DT, AC, DB);
|
||||
bool Changed = runImpl(F, SE, TTI, TLI, AA, LI, DT, DB);
|
||||
if (!Changed)
|
||||
return PreservedAnalyses::all();
|
||||
PreservedAnalyses PA;
|
||||
@ -3661,14 +3657,13 @@ bool SLPVectorizerPass::runImpl(Function &F, ScalarEvolution *SE_,
|
||||
TargetTransformInfo *TTI_,
|
||||
TargetLibraryInfo *TLI_, AliasAnalysis *AA_,
|
||||
LoopInfo *LI_, DominatorTree *DT_,
|
||||
AssumptionCache *AC_, DemandedBits *DB_) {
|
||||
DemandedBits *DB_) {
|
||||
SE = SE_;
|
||||
TTI = TTI_;
|
||||
TLI = TLI_;
|
||||
AA = AA_;
|
||||
LI = LI_;
|
||||
DT = DT_;
|
||||
AC = AC_;
|
||||
DB = DB_;
|
||||
DL = &F.getParent()->getDataLayout();
|
||||
|
||||
@ -3689,7 +3684,7 @@ bool SLPVectorizerPass::runImpl(Function &F, ScalarEvolution *SE_,
|
||||
|
||||
// Use the bottom up slp vectorizer to construct chains that start with
|
||||
// store instructions.
|
||||
BoUpSLP R(&F, SE, TTI, TLI, AA, LI, DT, AC, DB, DL);
|
||||
BoUpSLP R(&F, SE, TTI, TLI, AA, LI, DT, DB, DL);
|
||||
|
||||
// A general note: the vectorizer must use BoUpSLP::eraseInstruction() to
|
||||
// delete instructions.
|
||||
@ -4938,7 +4933,6 @@ static const char lv_name[] = "SLP Vectorizer";
|
||||
INITIALIZE_PASS_BEGIN(SLPVectorizer, SV_NAME, lv_name, false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(LoopSimplify)
|
||||
INITIALIZE_PASS_DEPENDENCY(DemandedBitsWrapperPass)
|
||||
|
@ -1,22 +0,0 @@
|
||||
; RUN: opt < %s -disable-output -passes='print<assumptions>' 2>&1 | FileCheck %s
|
||||
|
||||
target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
|
||||
declare void @llvm.assume(i1)
|
||||
|
||||
define void @test1(i32 %a) {
|
||||
; CHECK-LABEL: Cached assumptions for function: test1
|
||||
; CHECK-NEXT: icmp ne i32 %{{.*}}, 0
|
||||
; CHECK-NEXT: icmp slt i32 %{{.*}}, 0
|
||||
; CHECK-NEXT: icmp sgt i32 %{{.*}}, 0
|
||||
|
||||
entry:
|
||||
%cond1 = icmp ne i32 %a, 0
|
||||
call void @llvm.assume(i1 %cond1)
|
||||
%cond2 = icmp slt i32 %a, 0
|
||||
call void @llvm.assume(i1 %cond2)
|
||||
%cond3 = icmp sgt i32 %a, 0
|
||||
call void @llvm.assume(i1 %cond3)
|
||||
|
||||
ret void
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
; RUN: opt -S -loop-rotate < %s | FileCheck %s
|
||||
; RUN: opt -S -passes='require<targetir>,require<assumptions>,loop(rotate)' < %s | FileCheck %s
|
||||
; RUN: opt -S -passes='require<targetir>,loop(rotate)' < %s | FileCheck %s
|
||||
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
||||
target triple = "x86_64-apple-darwin10.0.0"
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
||||
#include "llvm/Analysis/TargetLibraryInfo.h"
|
||||
#include "llvm/AsmParser/Parser.h"
|
||||
@ -144,7 +143,6 @@ protected:
|
||||
Module M;
|
||||
TargetLibraryInfoImpl TLII;
|
||||
TargetLibraryInfo TLI;
|
||||
std::unique_ptr<AssumptionCache> AC;
|
||||
std::unique_ptr<BasicAAResult> BAR;
|
||||
std::unique_ptr<AAResults> AAR;
|
||||
|
||||
@ -155,8 +153,7 @@ protected:
|
||||
AAR.reset(new AAResults(TLI));
|
||||
|
||||
// Build the various AA results and register them.
|
||||
AC.reset(new AssumptionCache(F));
|
||||
BAR.reset(new BasicAAResult(M.getDataLayout(), TLI, *AC));
|
||||
BAR.reset(new BasicAAResult(M.getDataLayout(), TLI));
|
||||
AAR->addAAResult(*BAR);
|
||||
|
||||
return *AAR;
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#include "llvm/Analysis/ScalarEvolutionExpander.h"
|
||||
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
|
||||
#include "llvm/Analysis/AssumptionCache.h"
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Analysis/TargetLibraryInfo.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
@ -38,17 +37,15 @@ protected:
|
||||
TargetLibraryInfoImpl TLII;
|
||||
TargetLibraryInfo TLI;
|
||||
|
||||
std::unique_ptr<AssumptionCache> AC;
|
||||
std::unique_ptr<DominatorTree> DT;
|
||||
std::unique_ptr<LoopInfo> LI;
|
||||
|
||||
ScalarEvolutionsTest() : M("", Context), TLII(), TLI(TLII) {}
|
||||
|
||||
ScalarEvolution buildSE(Function &F) {
|
||||
AC.reset(new AssumptionCache(F));
|
||||
DT.reset(new DominatorTree(F));
|
||||
LI.reset(new LoopInfo(*DT));
|
||||
return ScalarEvolution(F, TLI, *AC, *DT, *LI);
|
||||
return ScalarEvolution(F, TLI, *DT, *LI);
|
||||
}
|
||||
|
||||
void runWithFunctionAndSE(
|
||||
|
@ -42,10 +42,6 @@ protected:
|
||||
InitializeNativeTarget();
|
||||
InitializeNativeTargetAsmPrinter();
|
||||
|
||||
// FIXME: It isn't at all clear why this is necesasry, but without it we
|
||||
// fail to initialize the AssumptionCacheTracker.
|
||||
initializeAssumptionCacheTrackerPass(*PassRegistry::getPassRegistry());
|
||||
|
||||
#ifdef LLVM_ON_WIN32
|
||||
// On Windows, generate ELF objects by specifying "-elf" in triple
|
||||
HostTriple += "-elf";
|
||||
|
@ -39,7 +39,6 @@ protected:
|
||||
// Things that we need to build after the function is created.
|
||||
struct TestAnalyses {
|
||||
DominatorTree DT;
|
||||
AssumptionCache AC;
|
||||
AAResults AA;
|
||||
BasicAAResult BAA;
|
||||
// We need to defer MSSA construction until AA is *entirely* set up, which
|
||||
@ -48,8 +47,8 @@ protected:
|
||||
MemorySSAWalker *Walker;
|
||||
|
||||
TestAnalyses(MemorySSATest &Test)
|
||||
: DT(*Test.F), AC(*Test.F), AA(Test.TLI),
|
||||
BAA(Test.DL, Test.TLI, AC, &DT) {
|
||||
: DT(*Test.F), AA(Test.TLI),
|
||||
BAA(Test.DL, Test.TLI, &DT) {
|
||||
AA.addAAResult(BAA);
|
||||
MSSA = make_unique<MemorySSA>(*Test.F, &AA, &DT);
|
||||
Walker = MSSA->getWalker();
|
||||
|
Loading…
Reference in New Issue
Block a user