aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/Analysis
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-08-20 20:50:12 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-08-20 20:50:12 +0000
commite6d1592492a3a379186bfb02bd0f4eda0669c0d5 (patch)
tree599ab169a01f1c86eda9adc774edaedde2f2db5b /include/llvm/Analysis
parent1a56a5ead7a2e84bee8240f5f6b033b5f1707154 (diff)
Notes
Diffstat (limited to 'include/llvm/Analysis')
-rw-r--r--include/llvm/Analysis/AliasAnalysis.h239
-rw-r--r--include/llvm/Analysis/AliasAnalysisEvaluator.h7
-rw-r--r--include/llvm/Analysis/AliasSetTracker.h28
-rw-r--r--include/llvm/Analysis/AssumptionCache.h15
-rw-r--r--include/llvm/Analysis/BasicAliasAnalysis.h34
-rw-r--r--include/llvm/Analysis/BlockFrequencyInfo.h10
-rw-r--r--include/llvm/Analysis/BlockFrequencyInfoImpl.h33
-rw-r--r--include/llvm/Analysis/BranchProbabilityInfo.h7
-rw-r--r--include/llvm/Analysis/CFG.h32
-rw-r--r--include/llvm/Analysis/CFGPrinter.h7
-rw-r--r--include/llvm/Analysis/CFLAliasAnalysisUtils.h7
-rw-r--r--include/llvm/Analysis/CFLAndersAliasAnalysis.h10
-rw-r--r--include/llvm/Analysis/CFLSteensAliasAnalysis.h14
-rw-r--r--include/llvm/Analysis/CGSCCPassManager.h396
-rw-r--r--include/llvm/Analysis/CallGraph.h24
-rw-r--r--include/llvm/Analysis/CallGraphSCCPass.h7
-rw-r--r--include/llvm/Analysis/CallPrinter.h7
-rw-r--r--include/llvm/Analysis/CaptureTracking.h7
-rw-r--r--include/llvm/Analysis/CmpInstAnalysis.h7
-rw-r--r--include/llvm/Analysis/CodeMetrics.h16
-rw-r--r--include/llvm/Analysis/ConstantFolding.h22
-rw-r--r--include/llvm/Analysis/DOTGraphTraitsPass.h7
-rw-r--r--include/llvm/Analysis/DemandedBits.h7
-rw-r--r--include/llvm/Analysis/DependenceAnalysis.h11
-rw-r--r--include/llvm/Analysis/DivergenceAnalysis.h7
-rw-r--r--include/llvm/Analysis/DomPrinter.h7
-rw-r--r--include/llvm/Analysis/DomTreeUpdater.h309
-rw-r--r--include/llvm/Analysis/DominanceFrontier.h7
-rw-r--r--include/llvm/Analysis/DominanceFrontierImpl.h7
-rw-r--r--include/llvm/Analysis/EHPersonalities.h7
-rw-r--r--include/llvm/Analysis/GlobalsModRef.h15
-rw-r--r--include/llvm/Analysis/GuardUtils.h30
-rw-r--r--include/llvm/Analysis/IVDescriptors.h28
-rw-r--r--include/llvm/Analysis/IVUsers.h7
-rw-r--r--include/llvm/Analysis/IndirectCallPromotionAnalysis.h7
-rw-r--r--include/llvm/Analysis/IndirectCallVisitor.h7
-rw-r--r--include/llvm/Analysis/InlineCost.h21
-rw-r--r--include/llvm/Analysis/InstructionPrecedenceTracking.h9
-rw-r--r--include/llvm/Analysis/InstructionSimplify.h33
-rw-r--r--include/llvm/Analysis/Interval.h7
-rw-r--r--include/llvm/Analysis/IntervalIterator.h7
-rw-r--r--include/llvm/Analysis/IntervalPartition.h7
-rw-r--r--include/llvm/Analysis/IteratedDominanceFrontier.h154
-rw-r--r--include/llvm/Analysis/LazyBlockFrequencyInfo.h7
-rw-r--r--include/llvm/Analysis/LazyBranchProbabilityInfo.h7
-rw-r--r--include/llvm/Analysis/LazyCallGraph.h32
-rw-r--r--include/llvm/Analysis/LazyValueInfo.h7
-rw-r--r--include/llvm/Analysis/LegacyDivergenceAnalysis.h7
-rw-r--r--include/llvm/Analysis/Lint.h7
-rw-r--r--include/llvm/Analysis/Loads.h29
-rw-r--r--include/llvm/Analysis/LoopAccessAnalysis.h13
-rw-r--r--include/llvm/Analysis/LoopAnalysisManager.h10
-rw-r--r--include/llvm/Analysis/LoopInfo.h249
-rw-r--r--include/llvm/Analysis/LoopInfoImpl.h85
-rw-r--r--include/llvm/Analysis/LoopIterator.h7
-rw-r--r--include/llvm/Analysis/LoopPass.h7
-rw-r--r--include/llvm/Analysis/LoopUnrollAnalyzer.h7
-rw-r--r--include/llvm/Analysis/MemoryBuiltins.h50
-rw-r--r--include/llvm/Analysis/MemoryDependenceAnalysis.h26
-rw-r--r--include/llvm/Analysis/MemoryLocation.h7
-rw-r--r--include/llvm/Analysis/MemorySSA.h49
-rw-r--r--include/llvm/Analysis/MemorySSAUpdater.h42
-rw-r--r--include/llvm/Analysis/ModuleSummaryAnalysis.h7
-rw-r--r--include/llvm/Analysis/MustExecute.h7
-rw-r--r--include/llvm/Analysis/ObjCARCAliasAnalysis.h16
-rw-r--r--include/llvm/Analysis/ObjCARCAnalysisUtils.h7
-rw-r--r--include/llvm/Analysis/ObjCARCInstKind.h11
-rw-r--r--include/llvm/Analysis/OptimizationRemarkEmitter.h11
-rw-r--r--include/llvm/Analysis/OrderedBasicBlock.h15
-rw-r--r--include/llvm/Analysis/OrderedInstructions.h7
-rw-r--r--include/llvm/Analysis/PHITransAddr.h7
-rw-r--r--include/llvm/Analysis/Passes.h7
-rw-r--r--include/llvm/Analysis/PhiValues.h7
-rw-r--r--include/llvm/Analysis/PostDominators.h7
-rw-r--r--include/llvm/Analysis/ProfileSummaryInfo.h16
-rw-r--r--include/llvm/Analysis/PtrUseVisitor.h11
-rw-r--r--include/llvm/Analysis/RegionInfo.h7
-rw-r--r--include/llvm/Analysis/RegionInfoImpl.h7
-rw-r--r--include/llvm/Analysis/RegionIterator.h7
-rw-r--r--include/llvm/Analysis/RegionPass.h7
-rw-r--r--include/llvm/Analysis/RegionPrinter.h7
-rw-r--r--include/llvm/Analysis/ScalarEvolution.h72
-rw-r--r--include/llvm/Analysis/ScalarEvolutionAliasAnalysis.h10
-rw-r--r--include/llvm/Analysis/ScalarEvolutionExpander.h17
-rw-r--r--include/llvm/Analysis/ScalarEvolutionExpressions.h156
-rw-r--r--include/llvm/Analysis/ScalarEvolutionNormalization.h7
-rw-r--r--include/llvm/Analysis/ScopedNoAliasAA.h16
-rw-r--r--include/llvm/Analysis/SparsePropagation.h15
-rw-r--r--include/llvm/Analysis/StackSafetyAnalysis.h7
-rw-r--r--include/llvm/Analysis/SyncDependenceAnalysis.h7
-rw-r--r--include/llvm/Analysis/SyntheticCountsUtils.h7
-rw-r--r--include/llvm/Analysis/TargetFolder.h11
-rw-r--r--include/llvm/Analysis/TargetLibraryInfo.def65
-rw-r--r--include/llvm/Analysis/TargetLibraryInfo.h14
-rw-r--r--include/llvm/Analysis/TargetTransformInfo.h235
-rw-r--r--include/llvm/Analysis/TargetTransformInfoImpl.h191
-rw-r--r--include/llvm/Analysis/Trace.h7
-rw-r--r--include/llvm/Analysis/TypeBasedAliasAnalysis.h19
-rw-r--r--include/llvm/Analysis/TypeMetadataUtils.h7
-rw-r--r--include/llvm/Analysis/Utils/Local.h7
-rw-r--r--include/llvm/Analysis/ValueLattice.h7
-rw-r--r--include/llvm/Analysis/ValueLatticeUtils.h7
-rw-r--r--include/llvm/Analysis/ValueTracking.h64
-rw-r--r--include/llvm/Analysis/VecFuncs.def250
-rw-r--r--include/llvm/Analysis/VectorUtils.h81
105 files changed, 2597 insertions, 1131 deletions
diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h
index e2a2ac0622e8..948341554f23 100644
--- a/include/llvm/Analysis/AliasAnalysis.h
+++ b/include/llvm/Analysis/AliasAnalysis.h
@@ -1,9 +1,8 @@
//===- llvm/Analysis/AliasAnalysis.h - Alias Analysis Interface -*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -38,6 +37,7 @@
#ifndef LLVM_ANALYSIS_ALIASANALYSIS_H
#define LLVM_ANALYSIS_ALIASANALYSIS_H
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
@@ -286,6 +286,28 @@ createModRefInfo(const FunctionModRefBehavior FMRB) {
return ModRefInfo(FMRB & static_cast<int>(ModRefInfo::ModRef));
}
+/// This class stores info we want to provide to or retain within an alias
+/// query. By default, the root query is stateless and starts with a freshly
+/// constructed info object. Specific alias analyses can use this query info to
+/// store per-query state that is important for recursive or nested queries to
+/// avoid recomputing. To enable preserving this state across multiple queries
+/// where safe (due to the IR not changing), use a `BatchAAResults` wrapper.
+/// The information stored in an `AAQueryInfo` is currently limitted to the
+/// caches used by BasicAA, but can further be extended to fit other AA needs.
+class AAQueryInfo {
+public:
+ using LocPair = std::pair<MemoryLocation, MemoryLocation>;
+ using AliasCacheT = SmallDenseMap<LocPair, AliasResult, 8>;
+ AliasCacheT AliasCache;
+
+ using IsCapturedCacheT = SmallDenseMap<const Value *, bool, 8>;
+ IsCapturedCacheT IsCapturedCache;
+
+ AAQueryInfo() : AliasCache(), IsCapturedCache() {}
+};
+
+class BatchAAResults;
+
class AAResults {
public:
// Make these results default constructable and movable. We have to spell
@@ -600,32 +622,8 @@ public:
/// helpers above.
ModRefInfo getModRefInfo(const Instruction *I,
const Optional<MemoryLocation> &OptLoc) {
- if (OptLoc == None) {
- if (const auto *Call = dyn_cast<CallBase>(I)) {
- return createModRefInfo(getModRefBehavior(Call));
- }
- }
-
- const MemoryLocation &Loc = OptLoc.getValueOr(MemoryLocation());
-
- switch (I->getOpcode()) {
- case Instruction::VAArg: return getModRefInfo((const VAArgInst*)I, Loc);
- case Instruction::Load: return getModRefInfo((const LoadInst*)I, Loc);
- case Instruction::Store: return getModRefInfo((const StoreInst*)I, Loc);
- case Instruction::Fence: return getModRefInfo((const FenceInst*)I, Loc);
- case Instruction::AtomicCmpXchg:
- return getModRefInfo((const AtomicCmpXchgInst*)I, Loc);
- case Instruction::AtomicRMW:
- return getModRefInfo((const AtomicRMWInst*)I, Loc);
- case Instruction::Call: return getModRefInfo((const CallInst*)I, Loc);
- case Instruction::Invoke: return getModRefInfo((const InvokeInst*)I,Loc);
- case Instruction::CatchPad:
- return getModRefInfo((const CatchPadInst *)I, Loc);
- case Instruction::CatchRet:
- return getModRefInfo((const CatchReturnInst *)I, Loc);
- default:
- return ModRefInfo::NoModRef;
- }
+ AAQueryInfo AAQIP;
+ return getModRefInfo(I, OptLoc, AAQIP);
}
/// A convenience wrapper for constructing the memory location.
@@ -692,6 +690,69 @@ public:
}
private:
+ AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
+ AAQueryInfo &AAQI);
+ bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI,
+ bool OrLocal = false);
+ ModRefInfo getModRefInfo(Instruction *I, const CallBase *Call2,
+ AAQueryInfo &AAQIP);
+ ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
+ AAQueryInfo &AAQI);
+ ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2,
+ AAQueryInfo &AAQI);
+ ModRefInfo getModRefInfo(const VAArgInst *V, const MemoryLocation &Loc,
+ AAQueryInfo &AAQI);
+ ModRefInfo getModRefInfo(const LoadInst *L, const MemoryLocation &Loc,
+ AAQueryInfo &AAQI);
+ ModRefInfo getModRefInfo(const StoreInst *S, const MemoryLocation &Loc,
+ AAQueryInfo &AAQI);
+ ModRefInfo getModRefInfo(const FenceInst *S, const MemoryLocation &Loc,
+ AAQueryInfo &AAQI);
+ ModRefInfo getModRefInfo(const AtomicCmpXchgInst *CX,
+ const MemoryLocation &Loc, AAQueryInfo &AAQI);
+ ModRefInfo getModRefInfo(const AtomicRMWInst *RMW, const MemoryLocation &Loc,
+ AAQueryInfo &AAQI);
+ ModRefInfo getModRefInfo(const CatchPadInst *I, const MemoryLocation &Loc,
+ AAQueryInfo &AAQI);
+ ModRefInfo getModRefInfo(const CatchReturnInst *I, const MemoryLocation &Loc,
+ AAQueryInfo &AAQI);
+ ModRefInfo getModRefInfo(const Instruction *I,
+ const Optional<MemoryLocation> &OptLoc,
+ AAQueryInfo &AAQIP) {
+ if (OptLoc == None) {
+ if (const auto *Call = dyn_cast<CallBase>(I)) {
+ return createModRefInfo(getModRefBehavior(Call));
+ }
+ }
+
+ const MemoryLocation &Loc = OptLoc.getValueOr(MemoryLocation());
+
+ switch (I->getOpcode()) {
+ case Instruction::VAArg:
+ return getModRefInfo((const VAArgInst *)I, Loc, AAQIP);
+ case Instruction::Load:
+ return getModRefInfo((const LoadInst *)I, Loc, AAQIP);
+ case Instruction::Store:
+ return getModRefInfo((const StoreInst *)I, Loc, AAQIP);
+ case Instruction::Fence:
+ return getModRefInfo((const FenceInst *)I, Loc, AAQIP);
+ case Instruction::AtomicCmpXchg:
+ return getModRefInfo((const AtomicCmpXchgInst *)I, Loc, AAQIP);
+ case Instruction::AtomicRMW:
+ return getModRefInfo((const AtomicRMWInst *)I, Loc, AAQIP);
+ case Instruction::Call:
+ return getModRefInfo((const CallInst *)I, Loc, AAQIP);
+ case Instruction::Invoke:
+ return getModRefInfo((const InvokeInst *)I, Loc, AAQIP);
+ case Instruction::CatchPad:
+ return getModRefInfo((const CatchPadInst *)I, Loc, AAQIP);
+ case Instruction::CatchRet:
+ return getModRefInfo((const CatchReturnInst *)I, Loc, AAQIP);
+ default:
+ return ModRefInfo::NoModRef;
+ }
+ }
+
class Concept;
template <typename T> class Model;
@@ -703,6 +764,47 @@ private:
std::vector<std::unique_ptr<Concept>> AAs;
std::vector<AnalysisKey *> AADeps;
+
+ friend class BatchAAResults;
+};
+
+/// This class is a wrapper over an AAResults, and it is intended to be used
+/// only when there are no IR changes inbetween queries. BatchAAResults is
+/// reusing the same `AAQueryInfo` to preserve the state across queries,
+/// esentially making AA work in "batch mode". The internal state cannot be
+/// cleared, so to go "out-of-batch-mode", the user must either use AAResults,
+/// or create a new BatchAAResults.
+class BatchAAResults {
+ AAResults &AA;
+ AAQueryInfo AAQI;
+
+public:
+ BatchAAResults(AAResults &AAR) : AA(AAR), AAQI() {}
+ AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB) {
+ return AA.alias(LocA, LocB, AAQI);
+ }
+ bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal = false) {
+ return AA.pointsToConstantMemory(Loc, AAQI, OrLocal);
+ }
+ ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc) {
+ return AA.getModRefInfo(Call, Loc, AAQI);
+ }
+ ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2) {
+ return AA.getModRefInfo(Call1, Call2, AAQI);
+ }
+ ModRefInfo getModRefInfo(const Instruction *I,
+ const Optional<MemoryLocation> &OptLoc) {
+ return AA.getModRefInfo(I, OptLoc, AAQI);
+ }
+ ModRefInfo getModRefInfo(Instruction *I, const CallBase *Call2) {
+ return AA.getModRefInfo(I, Call2, AAQI);
+ }
+ ModRefInfo getArgModRefInfo(const CallBase *Call, unsigned ArgIdx) {
+ return AA.getArgModRefInfo(Call, ArgIdx);
+ }
+ FunctionModRefBehavior getModRefBehavior(const CallBase *Call) {
+ return AA.getModRefBehavior(Call);
+ }
};
/// Temporary typedef for legacy code that uses a generic \c AliasAnalysis
@@ -735,12 +837,12 @@ public:
/// each other. This is the interface that must be implemented by specific
/// alias analysis implementations.
virtual AliasResult alias(const MemoryLocation &LocA,
- const MemoryLocation &LocB) = 0;
+ const MemoryLocation &LocB, AAQueryInfo &AAQI) = 0;
/// Checks whether the given location points to constant memory, or if
/// \p OrLocal is true whether it points to a local alloca.
virtual bool pointsToConstantMemory(const MemoryLocation &Loc,
- bool OrLocal) = 0;
+ AAQueryInfo &AAQI, bool OrLocal) = 0;
/// @}
//===--------------------------------------------------------------------===//
@@ -764,13 +866,14 @@ public:
/// getModRefInfo (for call sites) - Return information about whether
/// a particular call site modifies or reads the specified memory location.
virtual ModRefInfo getModRefInfo(const CallBase *Call,
- const MemoryLocation &Loc) = 0;
+ const MemoryLocation &Loc,
+ AAQueryInfo &AAQI) = 0;
/// Return information about whether two call sites may refer to the same set
/// of memory locations. See the AA documentation for details:
/// http://llvm.org/docs/AliasAnalysis.html#ModRefInfo
- virtual ModRefInfo getModRefInfo(const CallBase *Call1,
- const CallBase *Call2) = 0;
+ virtual ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2,
+ AAQueryInfo &AAQI) = 0;
/// @}
};
@@ -792,14 +895,14 @@ public:
void setAAResults(AAResults *NewAAR) override { Result.setAAResults(NewAAR); }
- AliasResult alias(const MemoryLocation &LocA,
- const MemoryLocation &LocB) override {
- return Result.alias(LocA, LocB);
+ AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
+ AAQueryInfo &AAQI) override {
+ return Result.alias(LocA, LocB, AAQI);
}
- bool pointsToConstantMemory(const MemoryLocation &Loc,
+ bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI,
bool OrLocal) override {
- return Result.pointsToConstantMemory(Loc, OrLocal);
+ return Result.pointsToConstantMemory(Loc, AAQI, OrLocal);
}
ModRefInfo getArgModRefInfo(const CallBase *Call, unsigned ArgIdx) override {
@@ -814,14 +917,14 @@ public:
return Result.getModRefBehavior(F);
}
- ModRefInfo getModRefInfo(const CallBase *Call,
- const MemoryLocation &Loc) override {
- return Result.getModRefInfo(Call, Loc);
+ ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
+ AAQueryInfo &AAQI) override {
+ return Result.getModRefInfo(Call, Loc, AAQI);
}
- ModRefInfo getModRefInfo(const CallBase *Call1,
- const CallBase *Call2) override {
- return Result.getModRefInfo(Call1, Call2);
+ ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2,
+ AAQueryInfo &AAQI) override {
+ return Result.getModRefInfo(Call1, Call2, AAQI);
}
};
@@ -867,13 +970,16 @@ protected:
AAResultsProxy(AAResults *AAR, DerivedT &CurrentResult)
: AAR(AAR), CurrentResult(CurrentResult) {}
- AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB) {
- return AAR ? AAR->alias(LocA, LocB) : CurrentResult.alias(LocA, LocB);
+ AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
+ AAQueryInfo &AAQI) {
+ return AAR ? AAR->alias(LocA, LocB, AAQI)
+ : CurrentResult.alias(LocA, LocB, AAQI);
}
- bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal) {
- return AAR ? AAR->pointsToConstantMemory(Loc, OrLocal)
- : CurrentResult.pointsToConstantMemory(Loc, OrLocal);
+ bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI,
+ bool OrLocal) {
+ return AAR ? AAR->pointsToConstantMemory(Loc, AAQI, OrLocal)
+ : CurrentResult.pointsToConstantMemory(Loc, AAQI, OrLocal);
}
ModRefInfo getArgModRefInfo(const CallBase *Call, unsigned ArgIdx) {
@@ -890,14 +996,16 @@ protected:
return AAR ? AAR->getModRefBehavior(F) : CurrentResult.getModRefBehavior(F);
}
- ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc) {
- return AAR ? AAR->getModRefInfo(Call, Loc)
- : CurrentResult.getModRefInfo(Call, Loc);
+ ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
+ AAQueryInfo &AAQI) {
+ return AAR ? AAR->getModRefInfo(Call, Loc, AAQI)
+ : CurrentResult.getModRefInfo(Call, Loc, AAQI);
}
- ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2) {
- return AAR ? AAR->getModRefInfo(Call1, Call2)
- : CurrentResult.getModRefInfo(Call1, Call2);
+ ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2,
+ AAQueryInfo &AAQI) {
+ return AAR ? AAR->getModRefInfo(Call1, Call2, AAQI)
+ : CurrentResult.getModRefInfo(Call1, Call2, AAQI);
}
};
@@ -921,11 +1029,13 @@ protected:
AAResultsProxy getBestAAResults() { return AAResultsProxy(AAR, derived()); }
public:
- AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB) {
+ AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
+ AAQueryInfo &AAQI) {
return MayAlias;
}
- bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal) {
+ bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI,
+ bool OrLocal) {
return false;
}
@@ -941,11 +1051,13 @@ public:
return FMRB_UnknownModRefBehavior;
}
- ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc) {
+ ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
+ AAQueryInfo &AAQI) {
return ModRefInfo::ModRef;
}
- ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2) {
+ ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2,
+ AAQueryInfo &AAQI) {
return ModRefInfo::ModRef;
}
};
@@ -984,6 +1096,11 @@ bool isIdentifiedFunctionLocal(const Value *V);
/// This manager effectively wraps the AnalysisManager for registering alias
/// analyses. When you register your alias analysis with this manager, it will
/// ensure the analysis itself is registered with its AnalysisManager.
+///
+/// The result of this analysis is only invalidated if one of the particular
+/// aggregated AA results end up being invalidated. This removes the need to
+/// explicitly preserve the results of `AAManager`. Note that analyses should no
+/// longer be registered once the `AAManager` is run.
class AAManager : public AnalysisInfoMixin<AAManager> {
public:
using Result = AAResults;
diff --git a/include/llvm/Analysis/AliasAnalysisEvaluator.h b/include/llvm/Analysis/AliasAnalysisEvaluator.h
index 0941814a56c3..972eceaa3ba9 100644
--- a/include/llvm/Analysis/AliasAnalysisEvaluator.h
+++ b/include/llvm/Analysis/AliasAnalysisEvaluator.h
@@ -1,9 +1,8 @@
//===- AliasAnalysisEvaluator.h - Alias Analysis Accuracy Evaluator -------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
diff --git a/include/llvm/Analysis/AliasSetTracker.h b/include/llvm/Analysis/AliasSetTracker.h
index 7ed5cd5c4734..34a509b7f4bb 100644
--- a/include/llvm/Analysis/AliasSetTracker.h
+++ b/include/llvm/Analysis/AliasSetTracker.h
@@ -1,9 +1,8 @@
//===- llvm/Analysis/AliasSetTracker.h - Build Alias Sets -------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -37,6 +36,8 @@ namespace llvm {
class AliasSetTracker;
class BasicBlock;
class LoadInst;
+class Loop;
+class MemorySSA;
class AnyMemSetInst;
class AnyMemTransferInst;
class raw_ostream;
@@ -294,7 +295,8 @@ private:
void removeFromTracker(AliasSetTracker &AST);
void addPointer(AliasSetTracker &AST, PointerRec &Entry, LocationSize Size,
- const AAMDNodes &AAInfo, bool KnownMustAlias = false);
+ const AAMDNodes &AAInfo, bool KnownMustAlias = false,
+ bool SkipSizeUpdate = false);
void addUnknownInst(Instruction *I, AliasAnalysis &AA);
void removeUnknownInst(AliasSetTracker &AST, Instruction *I) {
@@ -310,10 +312,10 @@ private:
}
public:
- /// Return true if the specified pointer "may" (or must) alias one of the
- /// members in the set.
- bool aliasesPointer(const Value *Ptr, LocationSize Size,
- const AAMDNodes &AAInfo, AliasAnalysis &AA) const;
+ /// If the specified pointer "may" (or must) alias one of the members in the
+ /// set return the appropriate AliasResult. Otherwise return NoAlias.
+ AliasResult aliasesPointer(const Value *Ptr, LocationSize Size,
+ const AAMDNodes &AAInfo, AliasAnalysis &AA) const;
bool aliasesUnknownInst(const Instruction *Inst, AliasAnalysis &AA) const;
};
@@ -341,6 +343,8 @@ class AliasSetTracker {
struct ASTCallbackVHDenseMapInfo : public DenseMapInfo<Value *> {};
AliasAnalysis &AA;
+ MemorySSA *MSSA;
+ Loop *L;
ilist<AliasSet> AliasSets;
using PointerMapType = DenseMap<ASTCallbackVH, AliasSet::PointerRec *,
@@ -353,6 +357,8 @@ public:
/// Create an empty collection of AliasSets, and use the specified alias
/// analysis object to disambiguate load and store addresses.
explicit AliasSetTracker(AliasAnalysis &aa) : AA(aa) {}
+ explicit AliasSetTracker(AliasAnalysis &aa, MemorySSA *mssa, Loop *l)
+ : AA(aa), MSSA(mssa), L(l) {}
~AliasSetTracker() { clear(); }
/// These methods are used to add different types of instructions to the alias
@@ -377,6 +383,7 @@ public:
void add(BasicBlock &BB); // Add all instructions in basic block
void add(const AliasSetTracker &AST); // Add alias relations from another AST
void addUnknown(Instruction *I);
+ void addAllInstructionsInLoopUsingMSSA();
void clear();
@@ -439,7 +446,8 @@ private:
AliasSet &addPointer(MemoryLocation Loc, AliasSet::AccessLattice E);
AliasSet *mergeAliasSetsForPointer(const Value *Ptr, LocationSize Size,
- const AAMDNodes &AAInfo);
+ const AAMDNodes &AAInfo,
+ bool &MustAliasAll);
/// Merge all alias sets into a single set that is considered to alias any
/// pointer.
diff --git a/include/llvm/Analysis/AssumptionCache.h b/include/llvm/Analysis/AssumptionCache.h
index 46538b1fa86f..b42846472f2e 100644
--- a/include/llvm/Analysis/AssumptionCache.h
+++ b/include/llvm/Analysis/AssumptionCache.h
@@ -1,9 +1,8 @@
//===- 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.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -104,6 +103,10 @@ public:
/// not already be in the cache.
void registerAssumption(CallInst *CI);
+ /// Remove an \@llvm.assume intrinsic from this function's cache if it has
+ /// been added to the cache earlier.
+ void unregisterAssumption(CallInst *CI);
+
/// Update the cache of values being affected by this assumption (i.e.
/// the values about which this assumption provides information).
void updateAffectedValues(CallInst *CI);
@@ -209,6 +212,10 @@ public:
/// existing cache will be returned.
AssumptionCache &getAssumptionCache(Function &F);
+ /// Return the cached assumptions for a function if it has already been
+ /// scanned. Otherwise return nullptr.
+ AssumptionCache *lookupAssumptionCache(Function &F);
+
AssumptionCacheTracker();
~AssumptionCacheTracker() override;
diff --git a/include/llvm/Analysis/BasicAliasAnalysis.h b/include/llvm/Analysis/BasicAliasAnalysis.h
index 820d7ac0935a..22e8c4b474cb 100644
--- a/include/llvm/Analysis/BasicAliasAnalysis.h
+++ b/include/llvm/Analysis/BasicAliasAnalysis.h
@@ -1,9 +1,8 @@
//===- BasicAliasAnalysis.h - Stateless, local Alias Analysis ---*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
@@ -82,14 +81,18 @@ public:
bool invalidate(Function &Fn, const PreservedAnalyses &PA,
FunctionAnalysisManager::Invalidator &Inv);
- AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB);
+ AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
+ AAQueryInfo &AAQI);
- ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc);
+ ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
+ AAQueryInfo &AAQI);
- ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2);
+ ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2,
+ AAQueryInfo &AAQI);
/// Chases pointers until we find a (constant global) or not.
- bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal);
+ bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI,
+ bool OrLocal);
/// Get the location associated with a pointer argument of a callsite.
ModRefInfo getArgModRefInfo(const CallBase *Call, unsigned ArgIdx);
@@ -141,11 +144,6 @@ private:
SmallVector<VariableGEPIndex, 4> VarIndices;
};
- /// Track alias queries to guard against recursion.
- using LocPair = std::pair<MemoryLocation, MemoryLocation>;
- using AliasCacheTy = SmallDenseMap<LocPair, AliasResult, 8>;
- AliasCacheTy AliasCache;
-
/// Tracks phi nodes we have visited.
///
/// When interpret "Value" pointer equality as value equality we need to make
@@ -200,22 +198,24 @@ private:
AliasResult aliasGEP(const GEPOperator *V1, LocationSize V1Size,
const AAMDNodes &V1AAInfo, const Value *V2,
LocationSize V2Size, const AAMDNodes &V2AAInfo,
- const Value *UnderlyingV1, const Value *UnderlyingV2);
+ const Value *UnderlyingV1, const Value *UnderlyingV2,
+ AAQueryInfo &AAQI);
AliasResult aliasPHI(const PHINode *PN, LocationSize PNSize,
const AAMDNodes &PNAAInfo, const Value *V2,
LocationSize V2Size, const AAMDNodes &V2AAInfo,
- const Value *UnderV2);
+ const Value *UnderV2, AAQueryInfo &AAQI);
AliasResult aliasSelect(const SelectInst *SI, LocationSize SISize,
const AAMDNodes &SIAAInfo, const Value *V2,
LocationSize V2Size, const AAMDNodes &V2AAInfo,
- const Value *UnderV2);
+ const Value *UnderV2, AAQueryInfo &AAQI);
AliasResult aliasCheck(const Value *V1, LocationSize V1Size,
AAMDNodes V1AATag, const Value *V2,
LocationSize V2Size, AAMDNodes V2AATag,
- const Value *O1 = nullptr, const Value *O2 = nullptr);
+ AAQueryInfo &AAQI, const Value *O1 = nullptr,
+ const Value *O2 = nullptr);
};
/// Analysis pass providing a never-invalidated alias analysis result.
diff --git a/include/llvm/Analysis/BlockFrequencyInfo.h b/include/llvm/Analysis/BlockFrequencyInfo.h
index 0b2618735697..8bcfd7ff8f58 100644
--- a/include/llvm/Analysis/BlockFrequencyInfo.h
+++ b/include/llvm/Analysis/BlockFrequencyInfo.h
@@ -1,9 +1,8 @@
//===- BlockFrequencyInfo.h - Block Frequency Analysis ----------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -68,7 +67,8 @@ public:
/// Returns the estimated profile count of \p BB.
/// This computes the relative block frequency of \p BB and multiplies it by
/// the enclosing function's count (if available) and returns the value.
- Optional<uint64_t> getBlockProfileCount(const BasicBlock *BB) const;
+ Optional<uint64_t> getBlockProfileCount(const BasicBlock *BB,
+ bool AllowSynthetic = false) const;
/// Returns the estimated profile count of \p Freq.
/// This uses the frequency \p Freq and multiplies it by
diff --git a/include/llvm/Analysis/BlockFrequencyInfoImpl.h b/include/llvm/Analysis/BlockFrequencyInfoImpl.h
index 25b2efd33c98..bfe4fb14a2b8 100644
--- a/include/llvm/Analysis/BlockFrequencyInfoImpl.h
+++ b/include/llvm/Analysis/BlockFrequencyInfoImpl.h
@@ -1,9 +1,8 @@
//==- BlockFrequencyInfoImpl.h - Block Frequency Implementation --*- C++ -*-==//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -160,10 +159,6 @@ inline raw_ostream &operator<<(raw_ostream &OS, BlockMass X) {
} // end namespace bfi_detail
-template <> struct isPodLike<bfi_detail::BlockMass> {
- static const bool value = true;
-};
-
/// Base class for BlockFrequencyInfoImpl
///
/// BlockFrequencyInfoImplBase has supporting data structures and some
@@ -187,9 +182,9 @@ public:
struct BlockNode {
using IndexType = uint32_t;
- IndexType Index = std::numeric_limits<uint32_t>::max();
+ IndexType Index;
- BlockNode() = default;
+ BlockNode() : Index(std::numeric_limits<uint32_t>::max()) {}
BlockNode(IndexType Index) : Index(Index) {}
bool operator==(const BlockNode &X) const { return Index == X.Index; }
@@ -525,9 +520,11 @@ public:
BlockFrequency getBlockFreq(const BlockNode &Node) const;
Optional<uint64_t> getBlockProfileCount(const Function &F,
- const BlockNode &Node) const;
+ const BlockNode &Node,
+ bool AllowSynthetic = false) const;
Optional<uint64_t> getProfileCountFromFreq(const Function &F,
- uint64_t Freq) const;
+ uint64_t Freq,
+ bool AllowSynthetic = false) const;
bool isIrrLoopHeader(const BlockNode &Node);
void setBlockFreq(const BlockNode &Node, uint64_t Freq);
@@ -973,13 +970,17 @@ public:
}
Optional<uint64_t> getBlockProfileCount(const Function &F,
- const BlockT *BB) const {
- return BlockFrequencyInfoImplBase::getBlockProfileCount(F, getNode(BB));
+ const BlockT *BB,
+ bool AllowSynthetic = false) const {
+ return BlockFrequencyInfoImplBase::getBlockProfileCount(F, getNode(BB),
+ AllowSynthetic);
}
Optional<uint64_t> getProfileCountFromFreq(const Function &F,
- uint64_t Freq) const {
- return BlockFrequencyInfoImplBase::getProfileCountFromFreq(F, Freq);
+ uint64_t Freq,
+ bool AllowSynthetic = false) const {
+ return BlockFrequencyInfoImplBase::getProfileCountFromFreq(F, Freq,
+ AllowSynthetic);
}
bool isIrrLoopHeader(const BlockT *BB) {
diff --git a/include/llvm/Analysis/BranchProbabilityInfo.h b/include/llvm/Analysis/BranchProbabilityInfo.h
index 45277db46090..97cb730d16c7 100644
--- a/include/llvm/Analysis/BranchProbabilityInfo.h
+++ b/include/llvm/Analysis/BranchProbabilityInfo.h
@@ -1,9 +1,8 @@
//===- BranchProbabilityInfo.h - Branch Probability Analysis ----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/CFG.h b/include/llvm/Analysis/CFG.h
index caae0b6e2a8f..bb55e76ac86a 100644
--- a/include/llvm/Analysis/CFG.h
+++ b/include/llvm/Analysis/CFG.h
@@ -1,9 +1,8 @@
//===-- Analysis/CFG.h - BasicBlock Analyses --------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -48,8 +47,8 @@ unsigned GetSuccessorNumber(const BasicBlock *BB, const BasicBlock *Succ);
bool isCriticalEdge(const Instruction *TI, unsigned SuccNum,
bool AllowIdenticalEdges = false);
-/// Determine whether instruction 'To' is reachable from 'From',
-/// returning true if uncertain.
+/// Determine whether instruction 'To' is reachable from 'From', without passing
+/// through any blocks in ExclusionSet, returning true if uncertain.
///
/// Determine whether there is a path from From to To within a single function.
/// Returns false only if we can prove that once 'From' has been executed then
@@ -63,9 +62,10 @@ bool isCriticalEdge(const Instruction *TI, unsigned SuccNum,
/// we find a block that dominates the block containing 'To'. DT is most useful
/// on branchy code but not loops, and LI is most useful on code with loops but
/// does not help on branchy code outside loops.
-bool isPotentiallyReachable(const Instruction *From, const Instruction *To,
- const DominatorTree *DT = nullptr,
- const LoopInfo *LI = nullptr);
+bool isPotentiallyReachable(
+ const Instruction *From, const Instruction *To,
+ const SmallPtrSetImpl<BasicBlock *> *ExclusionSet = nullptr,
+ const DominatorTree *DT = nullptr, const LoopInfo *LI = nullptr);
/// Determine whether block 'To' is reachable from 'From', returning
/// true if uncertain.
@@ -89,6 +89,20 @@ bool isPotentiallyReachableFromMany(SmallVectorImpl<BasicBlock *> &Worklist,
const DominatorTree *DT = nullptr,
const LoopInfo *LI = nullptr);
+/// Determine whether there is at least one path from a block in
+/// 'Worklist' to 'StopBB' without passing through any blocks in
+/// 'ExclusionSet', returning true if uncertain.
+///
+/// Determine whether there is a path from at least one block in Worklist to
+/// StopBB within a single function without passing through any of the blocks
+/// in 'ExclusionSet'. Returns false only if we can prove that once any block
+/// in 'Worklist' has been reached then 'StopBB' can not be executed.
+/// Conservatively returns true.
+bool isPotentiallyReachableFromMany(
+ SmallVectorImpl<BasicBlock *> &Worklist, BasicBlock *StopBB,
+ const SmallPtrSetImpl<BasicBlock *> *ExclusionSet,
+ const DominatorTree *DT = nullptr, const LoopInfo *LI = nullptr);
+
/// Return true if the control flow in \p RPOTraversal is irreducible.
///
/// This is a generic implementation to detect CFG irreducibility based on loop
diff --git a/include/llvm/Analysis/CFGPrinter.h b/include/llvm/Analysis/CFGPrinter.h
index 5996dd90bcfd..aaefc11653dd 100644
--- a/include/llvm/Analysis/CFGPrinter.h
+++ b/include/llvm/Analysis/CFGPrinter.h
@@ -1,9 +1,8 @@
//===-- CFGPrinter.h - CFG printer external interface -----------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/CFLAliasAnalysisUtils.h b/include/llvm/Analysis/CFLAliasAnalysisUtils.h
index 981a8ddc2289..02f999a5b913 100644
--- a/include/llvm/Analysis/CFLAliasAnalysisUtils.h
+++ b/include/llvm/Analysis/CFLAliasAnalysisUtils.h
@@ -1,9 +1,8 @@
//=- CFLAliasAnalysisUtils.h - Utilities for CFL Alias Analysis ----*- C++-*-=//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// \file
diff --git a/include/llvm/Analysis/CFLAndersAliasAnalysis.h b/include/llvm/Analysis/CFLAndersAliasAnalysis.h
index 8ae72553ab94..7c8b42b1d8d2 100644
--- a/include/llvm/Analysis/CFLAndersAliasAnalysis.h
+++ b/include/llvm/Analysis/CFLAndersAliasAnalysis.h
@@ -1,9 +1,8 @@
//==- CFLAndersAliasAnalysis.h - Unification-based Alias Analysis -*- C++-*-==//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
@@ -61,7 +60,8 @@ public:
const cflaa::AliasSummary *getAliasSummary(const Function &);
AliasResult query(const MemoryLocation &, const MemoryLocation &);
- AliasResult alias(const MemoryLocation &, const MemoryLocation &);
+ AliasResult alias(const MemoryLocation &, const MemoryLocation &,
+ AAQueryInfo &);
private:
/// Ensures that the given function is available in the cache.
diff --git a/include/llvm/Analysis/CFLSteensAliasAnalysis.h b/include/llvm/Analysis/CFLSteensAliasAnalysis.h
index 09e366f11e18..cc7a47cd9a5f 100644
--- a/include/llvm/Analysis/CFLSteensAliasAnalysis.h
+++ b/include/llvm/Analysis/CFLSteensAliasAnalysis.h
@@ -1,9 +1,8 @@
//==- CFLSteensAliasAnalysis.h - Unification-based Alias Analysis -*- C++-*-==//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
@@ -70,7 +69,8 @@ public:
AliasResult query(const MemoryLocation &LocA, const MemoryLocation &LocB);
- AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB) {
+ AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
+ AAQueryInfo &AAQI) {
if (LocA.Ptr == LocB.Ptr)
return MustAlias;
@@ -80,11 +80,11 @@ public:
// ConstantExpr, but every query needs to have at least one Value tied to a
// Function, and neither GlobalValues nor ConstantExprs are.
if (isa<Constant>(LocA.Ptr) && isa<Constant>(LocB.Ptr))
- return AAResultBase::alias(LocA, LocB);
+ return AAResultBase::alias(LocA, LocB, AAQI);
AliasResult QueryResult = query(LocA, LocB);
if (QueryResult == MayAlias)
- return AAResultBase::alias(LocA, LocB);
+ return AAResultBase::alias(LocA, LocB, AAQI);
return QueryResult;
}
diff --git a/include/llvm/Analysis/CGSCCPassManager.h b/include/llvm/Analysis/CGSCCPassManager.h
index 61b99f6c3e6b..8af5fb86995a 100644
--- a/include/llvm/Analysis/CGSCCPassManager.h
+++ b/include/llvm/Analysis/CGSCCPassManager.h
@@ -1,9 +1,8 @@
//===- CGSCCPassManager.h - Call graph pass management ----------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
@@ -292,6 +291,21 @@ struct CGSCCUpdateResult {
/// post-order walk.
LazyCallGraph::SCC *UpdatedC;
+ /// Preserved analyses across SCCs.
+ ///
+ /// We specifically want to allow CGSCC passes to mutate ancestor IR
+ /// (changing both the CG structure and the function IR itself). However,
+ /// this means we need to take special care to correctly mark what analyses
+ /// are preserved *across* SCCs. We have to track this out-of-band here
+ /// because within the main `PassManeger` infrastructure we need to mark
+ /// everything within an SCC as preserved in order to avoid repeatedly
+ /// invalidating the same analyses as we unnest pass managers and adaptors.
+ /// So we track the cross-SCC version of the preserved analyses here from any
+ /// code that does direct invalidation of SCC analyses, and then use it
+ /// whenever we move forward in the post-order walk of SCCs before running
+ /// passes over the new SCC.
+ PreservedAnalyses CrossSCCPA;
+
/// A hacky area where the inliner can retain history about inlining
/// decisions that mutated the call graph's SCC structure in order to avoid
/// infinite inlining. See the comments in the inliner's CG update logic.
@@ -339,175 +353,7 @@ public:
}
/// Runs the CGSCC pass across every SCC in the module.
- PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM) {
- // Setup the CGSCC analysis manager from its proxy.
- CGSCCAnalysisManager &CGAM =
- AM.getResult<CGSCCAnalysisManagerModuleProxy>(M).getManager();
-
- // Get the call graph for this module.
- LazyCallGraph &CG = AM.getResult<LazyCallGraphAnalysis>(M);
-
- // We keep worklists to allow us to push more work onto the pass manager as
- // the passes are run.
- SmallPriorityWorklist<LazyCallGraph::RefSCC *, 1> RCWorklist;
- SmallPriorityWorklist<LazyCallGraph::SCC *, 1> CWorklist;
-
- // Keep sets for invalidated SCCs and RefSCCs that should be skipped when
- // iterating off the worklists.
- SmallPtrSet<LazyCallGraph::RefSCC *, 4> InvalidRefSCCSet;
- SmallPtrSet<LazyCallGraph::SCC *, 4> InvalidSCCSet;
-
- SmallDenseSet<std::pair<LazyCallGraph::Node *, LazyCallGraph::SCC *>, 4>
- InlinedInternalEdges;
-
- CGSCCUpdateResult UR = {RCWorklist, CWorklist, InvalidRefSCCSet,
- InvalidSCCSet, nullptr, nullptr,
- InlinedInternalEdges};
-
- // Request PassInstrumentation from analysis manager, will use it to run
- // instrumenting callbacks for the passes later.
- PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(M);
-
- PreservedAnalyses PA = PreservedAnalyses::all();
- CG.buildRefSCCs();
- for (auto RCI = CG.postorder_ref_scc_begin(),
- RCE = CG.postorder_ref_scc_end();
- RCI != RCE;) {
- assert(RCWorklist.empty() &&
- "Should always start with an empty RefSCC worklist");
- // The postorder_ref_sccs range we are walking is lazily constructed, so
- // we only push the first one onto the worklist. The worklist allows us
- // to capture *new* RefSCCs created during transformations.
- //
- // We really want to form RefSCCs lazily because that makes them cheaper
- // to update as the program is simplified and allows us to have greater
- // cache locality as forming a RefSCC touches all the parts of all the
- // functions within that RefSCC.
- //
- // We also eagerly increment the iterator to the next position because
- // the CGSCC passes below may delete the current RefSCC.
- RCWorklist.insert(&*RCI++);
-
- do {
- LazyCallGraph::RefSCC *RC = RCWorklist.pop_back_val();
- if (InvalidRefSCCSet.count(RC)) {
- LLVM_DEBUG(dbgs() << "Skipping an invalid RefSCC...\n");
- continue;
- }
-
- assert(CWorklist.empty() &&
- "Should always start with an empty SCC worklist");
-
- LLVM_DEBUG(dbgs() << "Running an SCC pass across the RefSCC: " << *RC
- << "\n");
-
- // Push the initial SCCs in reverse post-order as we'll pop off the
- // back and so see this in post-order.
- for (LazyCallGraph::SCC &C : llvm::reverse(*RC))
- CWorklist.insert(&C);
-
- do {
- LazyCallGraph::SCC *C = CWorklist.pop_back_val();
- // Due to call graph mutations, we may have invalid SCCs or SCCs from
- // other RefSCCs in the worklist. The invalid ones are dead and the
- // other RefSCCs should be queued above, so we just need to skip both
- // scenarios here.
- if (InvalidSCCSet.count(C)) {
- LLVM_DEBUG(dbgs() << "Skipping an invalid SCC...\n");
- continue;
- }
- if (&C->getOuterRefSCC() != RC) {
- LLVM_DEBUG(dbgs()
- << "Skipping an SCC that is now part of some other "
- "RefSCC...\n");
- continue;
- }
-
- do {
- // Check that we didn't miss any update scenario.
- assert(!InvalidSCCSet.count(C) && "Processing an invalid SCC!");
- assert(C->begin() != C->end() && "Cannot have an empty SCC!");
- assert(&C->getOuterRefSCC() == RC &&
- "Processing an SCC in a different RefSCC!");
-
- UR.UpdatedRC = nullptr;
- UR.UpdatedC = nullptr;
-
- // Check the PassInstrumentation's BeforePass callbacks before
- // running the pass, skip its execution completely if asked to
- // (callback returns false).
- if (!PI.runBeforePass<LazyCallGraph::SCC>(Pass, *C))
- continue;
-
- PreservedAnalyses PassPA = Pass.run(*C, CGAM, CG, UR);
-
- if (UR.InvalidatedSCCs.count(C))
- PI.runAfterPassInvalidated<LazyCallGraph::SCC>(Pass);
- else
- PI.runAfterPass<LazyCallGraph::SCC>(Pass, *C);
-
- // Update the SCC and RefSCC if necessary.
- C = UR.UpdatedC ? UR.UpdatedC : C;
- RC = UR.UpdatedRC ? UR.UpdatedRC : RC;
-
- // If the CGSCC pass wasn't able to provide a valid updated SCC,
- // the current SCC may simply need to be skipped if invalid.
- if (UR.InvalidatedSCCs.count(C)) {
- LLVM_DEBUG(dbgs()
- << "Skipping invalidated root or island SCC!\n");
- break;
- }
- // Check that we didn't miss any update scenario.
- assert(C->begin() != C->end() && "Cannot have an empty SCC!");
-
- // We handle invalidating the CGSCC analysis manager's information
- // for the (potentially updated) SCC here. Note that any other SCCs
- // whose structure has changed should have been invalidated by
- // whatever was updating the call graph. This SCC gets invalidated
- // late as it contains the nodes that were actively being
- // processed.
- CGAM.invalidate(*C, PassPA);
-
- // Then intersect the preserved set so that invalidation of module
- // analyses will eventually occur when the module pass completes.
- PA.intersect(std::move(PassPA));
-
- // The pass may have restructured the call graph and refined the
- // current SCC and/or RefSCC. We need to update our current SCC and
- // RefSCC pointers to follow these. Also, when the current SCC is
- // refined, re-run the SCC pass over the newly refined SCC in order
- // to observe the most precise SCC model available. This inherently
- // cannot cycle excessively as it only happens when we split SCCs
- // apart, at most converging on a DAG of single nodes.
- // FIXME: If we ever start having RefSCC passes, we'll want to
- // iterate there too.
- if (UR.UpdatedC)
- LLVM_DEBUG(dbgs()
- << "Re-running SCC passes after a refinement of the "
- "current SCC: "
- << *UR.UpdatedC << "\n");
-
- // Note that both `C` and `RC` may at this point refer to deleted,
- // invalid SCC and RefSCCs respectively. But we will short circuit
- // the processing when we check them in the loop above.
- } while (UR.UpdatedC);
- } while (!CWorklist.empty());
-
- // We only need to keep internal inlined edge information within
- // a RefSCC, clear it to save on space and let the next time we visit
- // any of these functions have a fresh start.
- InlinedInternalEdges.clear();
- } while (!RCWorklist.empty());
- }
-
- // By definition we preserve the call garph, all SCC analyses, and the
- // analysis proxies by handling them above and in any nested pass managers.
- PA.preserveSet<AllAnalysesOn<LazyCallGraph::SCC>>();
- PA.preserve<LazyCallGraphAnalysis>();
- PA.preserve<CGSCCAnalysisManagerModuleProxy>();
- PA.preserve<FunctionAnalysisManagerModuleProxy>();
- return PA;
- }
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
private:
CGSCCPassT Pass;
@@ -873,6 +719,210 @@ DevirtSCCRepeatedPass<PassT> createDevirtSCCRepeatedPass(PassT Pass,
return DevirtSCCRepeatedPass<PassT>(std::move(Pass), MaxIterations);
}
+// Out-of-line implementation details for templates below this point.
+
+template <typename CGSCCPassT>
+PreservedAnalyses
+ModuleToPostOrderCGSCCPassAdaptor<CGSCCPassT>::run(Module &M,
+ ModuleAnalysisManager &AM) {
+ // Setup the CGSCC analysis manager from its proxy.
+ CGSCCAnalysisManager &CGAM =
+ AM.getResult<CGSCCAnalysisManagerModuleProxy>(M).getManager();
+
+ // Get the call graph for this module.
+ LazyCallGraph &CG = AM.getResult<LazyCallGraphAnalysis>(M);
+
+ // We keep worklists to allow us to push more work onto the pass manager as
+ // the passes are run.
+ SmallPriorityWorklist<LazyCallGraph::RefSCC *, 1> RCWorklist;
+ SmallPriorityWorklist<LazyCallGraph::SCC *, 1> CWorklist;
+
+ // Keep sets for invalidated SCCs and RefSCCs that should be skipped when
+ // iterating off the worklists.
+ SmallPtrSet<LazyCallGraph::RefSCC *, 4> InvalidRefSCCSet;
+ SmallPtrSet<LazyCallGraph::SCC *, 4> InvalidSCCSet;
+
+ SmallDenseSet<std::pair<LazyCallGraph::Node *, LazyCallGraph::SCC *>, 4>
+ InlinedInternalEdges;
+
+ CGSCCUpdateResult UR = {
+ RCWorklist, CWorklist, InvalidRefSCCSet, InvalidSCCSet,
+ nullptr, nullptr, PreservedAnalyses::all(), InlinedInternalEdges};
+
+ // Request PassInstrumentation from analysis manager, will use it to run
+ // instrumenting callbacks for the passes later.
+ PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(M);
+
+ PreservedAnalyses PA = PreservedAnalyses::all();
+ CG.buildRefSCCs();
+ for (auto RCI = CG.postorder_ref_scc_begin(),
+ RCE = CG.postorder_ref_scc_end();
+ RCI != RCE;) {
+ assert(RCWorklist.empty() &&
+ "Should always start with an empty RefSCC worklist");
+ // The postorder_ref_sccs range we are walking is lazily constructed, so
+ // we only push the first one onto the worklist. The worklist allows us
+ // to capture *new* RefSCCs created during transformations.
+ //
+ // We really want to form RefSCCs lazily because that makes them cheaper
+ // to update as the program is simplified and allows us to have greater
+ // cache locality as forming a RefSCC touches all the parts of all the
+ // functions within that RefSCC.
+ //
+ // We also eagerly increment the iterator to the next position because
+ // the CGSCC passes below may delete the current RefSCC.
+ RCWorklist.insert(&*RCI++);
+
+ do {
+ LazyCallGraph::RefSCC *RC = RCWorklist.pop_back_val();
+ if (InvalidRefSCCSet.count(RC)) {
+ LLVM_DEBUG(dbgs() << "Skipping an invalid RefSCC...\n");
+ continue;
+ }
+
+ assert(CWorklist.empty() &&
+ "Should always start with an empty SCC worklist");
+
+ LLVM_DEBUG(dbgs() << "Running an SCC pass across the RefSCC: " << *RC
+ << "\n");
+
+ // Push the initial SCCs in reverse post-order as we'll pop off the
+ // back and so see this in post-order.
+ for (LazyCallGraph::SCC &C : llvm::reverse(*RC))
+ CWorklist.insert(&C);
+
+ do {
+ LazyCallGraph::SCC *C = CWorklist.pop_back_val();
+ // Due to call graph mutations, we may have invalid SCCs or SCCs from
+ // other RefSCCs in the worklist. The invalid ones are dead and the
+ // other RefSCCs should be queued above, so we just need to skip both
+ // scenarios here.
+ if (InvalidSCCSet.count(C)) {
+ LLVM_DEBUG(dbgs() << "Skipping an invalid SCC...\n");
+ continue;
+ }
+ if (&C->getOuterRefSCC() != RC) {
+ LLVM_DEBUG(dbgs() << "Skipping an SCC that is now part of some other "
+ "RefSCC...\n");
+ continue;
+ }
+
+ // Ensure we can proxy analysis updates from from the CGSCC analysis
+ // manager into the Function analysis manager by getting a proxy here.
+ // FIXME: This seems like a bit of a hack. We should find a cleaner
+ // or more costructive way to ensure this happens.
+ (void)CGAM.getResult<FunctionAnalysisManagerCGSCCProxy>(*C, CG);
+
+ // Each time we visit a new SCC pulled off the worklist,
+ // a transformation of a child SCC may have also modified this parent
+ // and invalidated analyses. So we invalidate using the update record's
+ // cross-SCC preserved set. This preserved set is intersected by any
+ // CGSCC pass that handles invalidation (primarily pass managers) prior
+ // to marking its SCC as preserved. That lets us track everything that
+ // might need invalidation across SCCs without excessive invalidations
+ // on a single SCC.
+ //
+ // This essentially allows SCC passes to freely invalidate analyses
+ // of any ancestor SCC. If this becomes detrimental to successfully
+ // caching analyses, we could force each SCC pass to manually
+ // invalidate the analyses for any SCCs other than themselves which
+ // are mutated. However, that seems to lose the robustness of the
+ // pass-manager driven invalidation scheme.
+ //
+ // FIXME: This is redundant in one case -- the top of the worklist may
+ // *also* be the same SCC we just ran over (and invalidated for). In
+ // that case, we'll end up doing a redundant invalidation here as
+ // a consequence.
+ CGAM.invalidate(*C, UR.CrossSCCPA);
+
+ do {
+ // Check that we didn't miss any update scenario.
+ assert(!InvalidSCCSet.count(C) && "Processing an invalid SCC!");
+ assert(C->begin() != C->end() && "Cannot have an empty SCC!");
+ assert(&C->getOuterRefSCC() == RC &&
+ "Processing an SCC in a different RefSCC!");
+
+ UR.UpdatedRC = nullptr;
+ UR.UpdatedC = nullptr;
+
+ // Check the PassInstrumentation's BeforePass callbacks before
+ // running the pass, skip its execution completely if asked to
+ // (callback returns false).
+ if (!PI.runBeforePass<LazyCallGraph::SCC>(Pass, *C))
+ continue;
+
+ PreservedAnalyses PassPA = Pass.run(*C, CGAM, CG, UR);
+
+ if (UR.InvalidatedSCCs.count(C))
+ PI.runAfterPassInvalidated<LazyCallGraph::SCC>(Pass);
+ else
+ PI.runAfterPass<LazyCallGraph::SCC>(Pass, *C);
+
+ // Update the SCC and RefSCC if necessary.
+ C = UR.UpdatedC ? UR.UpdatedC : C;
+ RC = UR.UpdatedRC ? UR.UpdatedRC : RC;
+
+ // If the CGSCC pass wasn't able to provide a valid updated SCC,
+ // the current SCC may simply need to be skipped if invalid.
+ if (UR.InvalidatedSCCs.count(C)) {
+ LLVM_DEBUG(dbgs() << "Skipping invalidated root or island SCC!\n");
+ break;
+ }
+ // Check that we didn't miss any update scenario.
+ assert(C->begin() != C->end() && "Cannot have an empty SCC!");
+
+ // We handle invalidating the CGSCC analysis manager's information
+ // for the (potentially updated) SCC here. Note that any other SCCs
+ // whose structure has changed should have been invalidated by
+ // whatever was updating the call graph. This SCC gets invalidated
+ // late as it contains the nodes that were actively being
+ // processed.
+ CGAM.invalidate(*C, PassPA);
+
+ // Then intersect the preserved set so that invalidation of module
+ // analyses will eventually occur when the module pass completes.
+ // Also intersect with the cross-SCC preserved set to capture any
+ // cross-SCC invalidation.
+ UR.CrossSCCPA.intersect(PassPA);
+ PA.intersect(std::move(PassPA));
+
+ // The pass may have restructured the call graph and refined the
+ // current SCC and/or RefSCC. We need to update our current SCC and
+ // RefSCC pointers to follow these. Also, when the current SCC is
+ // refined, re-run the SCC pass over the newly refined SCC in order
+ // to observe the most precise SCC model available. This inherently
+ // cannot cycle excessively as it only happens when we split SCCs
+ // apart, at most converging on a DAG of single nodes.
+ // FIXME: If we ever start having RefSCC passes, we'll want to
+ // iterate there too.
+ if (UR.UpdatedC)
+ LLVM_DEBUG(dbgs()
+ << "Re-running SCC passes after a refinement of the "
+ "current SCC: "
+ << *UR.UpdatedC << "\n");
+
+ // Note that both `C` and `RC` may at this point refer to deleted,
+ // invalid SCC and RefSCCs respectively. But we will short circuit
+ // the processing when we check them in the loop above.
+ } while (UR.UpdatedC);
+ } while (!CWorklist.empty());
+
+ // We only need to keep internal inlined edge information within
+ // a RefSCC, clear it to save on space and let the next time we visit
+ // any of these functions have a fresh start.
+ InlinedInternalEdges.clear();
+ } while (!RCWorklist.empty());
+ }
+
+ // By definition we preserve the call garph, all SCC analyses, and the
+ // analysis proxies by handling them above and in any nested pass managers.
+ PA.preserveSet<AllAnalysesOn<LazyCallGraph::SCC>>();
+ PA.preserve<LazyCallGraphAnalysis>();
+ PA.preserve<CGSCCAnalysisManagerModuleProxy>();
+ PA.preserve<FunctionAnalysisManagerModuleProxy>();
+ return PA;
+}
+
// Clear out the debug logging macro.
#undef DEBUG_TYPE
diff --git a/include/llvm/Analysis/CallGraph.h b/include/llvm/Analysis/CallGraph.h
index f109cf2fac4d..7a10183c4d91 100644
--- a/include/llvm/Analysis/CallGraph.h
+++ b/include/llvm/Analysis/CallGraph.h
@@ -1,9 +1,8 @@
//===- CallGraph.h - Build a Module's call graph ----------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
@@ -48,8 +47,8 @@
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/Function.h"
+#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/ValueHandle.h"
@@ -230,11 +229,11 @@ public:
}
/// Adds a function to the list of functions called by this one.
- void addCalledFunction(CallSite CS, CallGraphNode *M) {
- assert(!CS.getInstruction() || !CS.getCalledFunction() ||
- !CS.getCalledFunction()->isIntrinsic() ||
- !Intrinsic::isLeaf(CS.getCalledFunction()->getIntrinsicID()));
- CalledFunctions.emplace_back(CS.getInstruction(), M);
+ void addCalledFunction(CallBase *Call, CallGraphNode *M) {
+ assert(!Call || !Call->getCalledFunction() ||
+ !Call->getCalledFunction()->isIntrinsic() ||
+ !Intrinsic::isLeaf(Call->getCalledFunction()->getIntrinsicID()));
+ CalledFunctions.emplace_back(Call, M);
M->AddRef();
}
@@ -247,7 +246,7 @@ public:
/// Removes the edge in the node for the specified call site.
///
/// Note that this method takes linear time, so it should be used sparingly.
- void removeCallEdgeFor(CallSite CS);
+ void removeCallEdgeFor(CallBase &Call);
/// Removes all call edges from this node to the specified callee
/// function.
@@ -264,7 +263,8 @@ public:
/// new one.
///
/// Note that this method takes linear time, so it should be used sparingly.
- void replaceCallEdge(CallSite CS, CallSite NewCS, CallGraphNode *NewNode);
+ void replaceCallEdge(CallBase &Call, CallBase &NewCall,
+ CallGraphNode *NewNode);
private:
friend class CallGraph;
diff --git a/include/llvm/Analysis/CallGraphSCCPass.h b/include/llvm/Analysis/CallGraphSCCPass.h
index ace54607634c..1b5b7e2f039e 100644
--- a/include/llvm/Analysis/CallGraphSCCPass.h
+++ b/include/llvm/Analysis/CallGraphSCCPass.h
@@ -1,9 +1,8 @@
//===- CallGraphSCCPass.h - Pass that operates BU on call graph -*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/CallPrinter.h b/include/llvm/Analysis/CallPrinter.h
index 8b697d5aa149..8d4159f3ddc0 100644
--- a/include/llvm/Analysis/CallPrinter.h
+++ b/include/llvm/Analysis/CallPrinter.h
@@ -1,9 +1,8 @@
//===-- CallPrinter.h - Call graph printer external interface ----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/CaptureTracking.h b/include/llvm/Analysis/CaptureTracking.h
index aaaaff9ae252..ca7abd34fea2 100644
--- a/include/llvm/Analysis/CaptureTracking.h
+++ b/include/llvm/Analysis/CaptureTracking.h
@@ -1,9 +1,8 @@
//===----- llvm/Analysis/CaptureTracking.h - Pointer capture ----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/CmpInstAnalysis.h b/include/llvm/Analysis/CmpInstAnalysis.h
index 0e9c6a96b0f4..3d34cd12aea4 100644
--- a/include/llvm/Analysis/CmpInstAnalysis.h
+++ b/include/llvm/Analysis/CmpInstAnalysis.h
@@ -1,9 +1,8 @@
//===-- CmpInstAnalysis.h - Utils to help fold compare insts ----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/CodeMetrics.h b/include/llvm/Analysis/CodeMetrics.h
index 752902238522..1482b66a3080 100644
--- a/include/llvm/Analysis/CodeMetrics.h
+++ b/include/llvm/Analysis/CodeMetrics.h
@@ -1,9 +1,8 @@
//===- CodeMetrics.h - Code cost measurements -------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -17,7 +16,6 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/IR/CallSite.h"
namespace llvm {
class AssumptionCache;
@@ -29,14 +27,6 @@ class DataLayout;
class TargetTransformInfo;
class Value;
-/// Check whether a call will lower to something small.
-///
-/// This tests checks whether this callsite will lower to something
-/// significantly cheaper than a traditional call, often a single
-/// instruction. Note that if isInstructionFree(CS.getInstruction()) would
-/// return true, so will this function.
-bool callIsSmall(ImmutableCallSite CS);
-
/// Utility to calculate the size and a few similar metrics for a set
/// of basic blocks.
struct CodeMetrics {
diff --git a/include/llvm/Analysis/ConstantFolding.h b/include/llvm/Analysis/ConstantFolding.h
index 192c1abddcd2..2385b6f09c40 100644
--- a/include/llvm/Analysis/ConstantFolding.h
+++ b/include/llvm/Analysis/ConstantFolding.h
@@ -1,9 +1,8 @@
//===-- ConstantFolding.h - Fold instructions into constants ----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -23,7 +22,7 @@
namespace llvm {
class APInt;
template <typename T> class ArrayRef;
-class CallSite;
+class CallBase;
class Constant;
class ConstantExpr;
class ConstantVector;
@@ -31,7 +30,6 @@ class DataLayout;
class Function;
class GlobalValue;
class Instruction;
-class ImmutableCallSite;
class TargetLibraryInfo;
class Type;
@@ -73,6 +71,12 @@ ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS,
Constant *RHS, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr);
+/// Attempt to constant fold a unary operation with the specified
+/// operand. If it fails, it returns a constant expression of the specified
+/// operands.
+Constant *ConstantFoldUnaryOpOperand(unsigned Opcode, Constant *Op,
+ const DataLayout &DL);
+
/// Attempt to constant fold a binary operation with the specified
/// operands. If it fails, it returns a constant expression of the specified
/// operands.
@@ -139,11 +143,11 @@ Constant *ConstantFoldLoadThroughGEPIndices(Constant *C,
/// canConstantFoldCallTo - Return true if its even possible to fold a call to
/// the specified function.
-bool canConstantFoldCallTo(ImmutableCallSite CS, const Function *F);
+bool canConstantFoldCallTo(const CallBase *Call, const Function *F);
/// ConstantFoldCall - Attempt to constant fold a call to the specified function
/// with the specified arguments, returning null if unsuccessful.
-Constant *ConstantFoldCall(ImmutableCallSite CS, Function *F,
+Constant *ConstantFoldCall(const CallBase *Call, Function *F,
ArrayRef<Constant *> Operands,
const TargetLibraryInfo *TLI = nullptr);
@@ -155,7 +159,7 @@ Constant *ConstantFoldLoadThroughBitcast(Constant *C, Type *DestTy,
/// Check whether the given call has no side-effects.
/// Specifically checks for math routimes which sometimes set errno.
-bool isMathLibCallNoop(CallSite CS, const TargetLibraryInfo *TLI);
+bool isMathLibCallNoop(const CallBase *Call, const TargetLibraryInfo *TLI);
}
#endif
diff --git a/include/llvm/Analysis/DOTGraphTraitsPass.h b/include/llvm/Analysis/DOTGraphTraitsPass.h
index b7447a0547d5..0410a3314659 100644
--- a/include/llvm/Analysis/DOTGraphTraitsPass.h
+++ b/include/llvm/Analysis/DOTGraphTraitsPass.h
@@ -1,9 +1,8 @@
//===-- DOTGraphTraitsPass.h - Print/View dotty graphs-----------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/DemandedBits.h b/include/llvm/Analysis/DemandedBits.h
index 4c4e3f6c99e7..04db3eb57c18 100644
--- a/include/llvm/Analysis/DemandedBits.h
+++ b/include/llvm/Analysis/DemandedBits.h
@@ -1,9 +1,8 @@
//===- llvm/Analysis/DemandedBits.h - Determine demanded bits ---*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/DependenceAnalysis.h b/include/llvm/Analysis/DependenceAnalysis.h
index 69d0e2c1513e..997013a5fc8e 100644
--- a/include/llvm/Analysis/DependenceAnalysis.h
+++ b/include/llvm/Analysis/DependenceAnalysis.h
@@ -1,9 +1,8 @@
//===-- llvm/Analysis/DependenceAnalysis.h -------------------- -*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -275,6 +274,10 @@ template <typename T> class ArrayRef;
LoopInfo *LI)
: AA(AA), SE(SE), LI(LI), F(F) {}
+ /// Handle transitive invalidation when the cached analysis results go away.
+ bool invalidate(Function &F, const PreservedAnalyses &PA,
+ FunctionAnalysisManager::Invalidator &Inv);
+
/// depends - Tests for a dependence between the Src and Dst instructions.
/// Returns NULL if no dependence; otherwise, returns a Dependence (or a
/// FullDependence) with as much information as can be gleaned.
diff --git a/include/llvm/Analysis/DivergenceAnalysis.h b/include/llvm/Analysis/DivergenceAnalysis.h
index d834862db095..3cfb9d13df94 100644
--- a/include/llvm/Analysis/DivergenceAnalysis.h
+++ b/include/llvm/Analysis/DivergenceAnalysis.h
@@ -1,9 +1,8 @@
//===- llvm/Analysis/DivergenceAnalysis.h - Divergence Analysis -*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/DomPrinter.h b/include/llvm/Analysis/DomPrinter.h
index 0ed28994995a..a177f877b295 100644
--- a/include/llvm/Analysis/DomPrinter.h
+++ b/include/llvm/Analysis/DomPrinter.h
@@ -1,9 +1,8 @@
//===-- DomPrinter.h - Dom printer external interface ------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/DomTreeUpdater.h b/include/llvm/Analysis/DomTreeUpdater.h
new file mode 100644
index 000000000000..5ccce2e064cc
--- /dev/null
+++ b/include/llvm/Analysis/DomTreeUpdater.h
@@ -0,0 +1,309 @@
+//===- DomTreeUpdater.h - DomTree/Post DomTree Updater ----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the DomTreeUpdater class, which provides a uniform way to
+// update dominator tree related data structures.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_DOMTREEUPDATER_H
+#define LLVM_ANALYSIS_DOMTREEUPDATER_H
+
+#include "llvm/Analysis/PostDominators.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/ValueHandle.h"
+#include "llvm/Support/GenericDomTree.h"
+#include <functional>
+#include <vector>
+
+namespace llvm {
+class DomTreeUpdater {
+public:
+ enum class UpdateStrategy : unsigned char { Eager = 0, Lazy = 1 };
+
+ explicit DomTreeUpdater(UpdateStrategy Strategy_) : Strategy(Strategy_) {}
+ DomTreeUpdater(DominatorTree &DT_, UpdateStrategy Strategy_)
+ : DT(&DT_), Strategy(Strategy_) {}
+ DomTreeUpdater(DominatorTree *DT_, UpdateStrategy Strategy_)
+ : DT(DT_), Strategy(Strategy_) {}
+ DomTreeUpdater(PostDominatorTree &PDT_, UpdateStrategy Strategy_)
+ : PDT(&PDT_), Strategy(Strategy_) {}
+ DomTreeUpdater(PostDominatorTree *PDT_, UpdateStrategy Strategy_)
+ : PDT(PDT_), Strategy(Strategy_) {}
+ DomTreeUpdater(DominatorTree &DT_, PostDominatorTree &PDT_,
+ UpdateStrategy Strategy_)
+ : DT(&DT_), PDT(&PDT_), Strategy(Strategy_) {}
+ DomTreeUpdater(DominatorTree *DT_, PostDominatorTree *PDT_,
+ UpdateStrategy Strategy_)
+ : DT(DT_), PDT(PDT_), Strategy(Strategy_) {}
+
+ ~DomTreeUpdater() { flush(); }
+
+ /// Returns true if the current strategy is Lazy.
+ bool isLazy() const { return Strategy == UpdateStrategy::Lazy; };
+
+ /// Returns true if the current strategy is Eager.
+ bool isEager() const { return Strategy == UpdateStrategy::Eager; };
+
+ /// Returns true if it holds a DominatorTree.
+ bool hasDomTree() const { return DT != nullptr; }
+
+ /// Returns true if it holds a PostDominatorTree.
+ bool hasPostDomTree() const { return PDT != nullptr; }
+
+ /// Returns true if there is BasicBlock awaiting deletion.
+ /// The deletion will only happen until a flush event and
+ /// all available trees are up-to-date.
+ /// Returns false under Eager UpdateStrategy.
+ bool hasPendingDeletedBB() const { return !DeletedBBs.empty(); }
+
+ /// Returns true if DelBB is awaiting deletion.
+ /// Returns false under Eager UpdateStrategy.
+ bool isBBPendingDeletion(BasicBlock *DelBB) const;
+
+ /// Returns true if either of DT or PDT is valid and the tree has at
+ /// least one update pending. If DT or PDT is nullptr it is treated
+ /// as having no pending updates. This function does not check
+ /// whether there is BasicBlock awaiting deletion.
+ /// Returns false under Eager UpdateStrategy.
+ bool hasPendingUpdates() const;
+
+ /// Returns true if there are DominatorTree updates queued.
+ /// Returns false under Eager UpdateStrategy or DT is nullptr.
+ bool hasPendingDomTreeUpdates() const;
+
+ /// Returns true if there are PostDominatorTree updates queued.
+ /// Returns false under Eager UpdateStrategy or PDT is nullptr.
+ bool hasPendingPostDomTreeUpdates() const;
+
+ ///@{
+ /// \name Mutation APIs
+ ///
+ /// These methods provide APIs for submitting updates to the DominatorTree and
+ /// the PostDominatorTree.
+ ///
+ /// Note: There are two strategies to update the DominatorTree and the
+ /// PostDominatorTree:
+ /// 1. Eager UpdateStrategy: Updates are submitted and then flushed
+ /// immediately.
+ /// 2. Lazy UpdateStrategy: Updates are submitted but only flushed when you
+ /// explicitly call Flush APIs. It is recommended to use this update strategy
+ /// when you submit a bunch of updates multiple times which can then
+ /// add up to a large number of updates between two queries on the
+ /// DominatorTree. The incremental updater can reschedule the updates or
+ /// decide to recalculate the dominator tree in order to speedup the updating
+ /// process depending on the number of updates.
+ ///
+ /// Although GenericDomTree provides several update primitives,
+ /// it is not encouraged to use these APIs directly.
+
+ /// Submit updates to all available trees.
+ /// The Eager Strategy flushes updates immediately while the Lazy Strategy
+ /// queues the updates.
+ ///
+ /// Note: The "existence" of an edge in a CFG refers to the CFG which DTU is
+ /// in sync with + all updates before that single update.
+ ///
+ /// CAUTION!
+ /// 1. It is required for the state of the LLVM IR to be updated
+ /// *before* submitting the updates because the internal update routine will
+ /// analyze the current state of the CFG to determine whether an update
+ /// is valid.
+ /// 2. It is illegal to submit any update that has already been submitted,
+ /// i.e., you are supposed not to insert an existent edge or delete a
+ /// nonexistent edge.
+ void applyUpdates(ArrayRef<DominatorTree::UpdateType> Updates);
+
+ /// Submit updates to all available trees. It will also
+ /// 1. discard duplicated updates,
+ /// 2. remove invalid updates. (Invalid updates means deletion of an edge that
+ /// still exists or insertion of an edge that does not exist.)
+ /// The Eager Strategy flushes updates immediately while the Lazy Strategy
+ /// queues the updates.
+ ///
+ /// Note: The "existence" of an edge in a CFG refers to the CFG which DTU is
+ /// in sync with + all updates before that single update.
+ ///
+ /// CAUTION!
+ /// 1. It is required for the state of the LLVM IR to be updated
+ /// *before* submitting the updates because the internal update routine will
+ /// analyze the current state of the CFG to determine whether an update
+ /// is valid.
+ /// 2. It is illegal to submit any update that has already been submitted,
+ /// i.e., you are supposed not to insert an existent edge or delete a
+ /// nonexistent edge.
+ /// 3. It is only legal to submit updates to an edge in the order CFG changes
+ /// are made. The order you submit updates on different edges is not
+ /// restricted.
+ void applyUpdatesPermissive(ArrayRef<DominatorTree::UpdateType> Updates);
+
+ /// Notify DTU that the entry block was replaced.
+ /// Recalculate all available trees and flush all BasicBlocks
+ /// awaiting deletion immediately.
+ void recalculate(Function &F);
+
+ /// \deprecated { Submit an edge insertion to all available trees. The Eager
+ /// Strategy flushes this update immediately while the Lazy Strategy queues
+ /// the update. An internal function checks if the edge exists in the CFG in
+ /// DEBUG mode. CAUTION! This function has to be called *after* making the
+ /// update on the actual CFG. It is illegal to submit any update that has
+ /// already been applied. }
+ LLVM_ATTRIBUTE_DEPRECATED(void insertEdge(BasicBlock *From, BasicBlock *To),
+ "Use applyUpdates() instead.");
+
+ /// \deprecated {Submit an edge insertion to all available trees.
+ /// Under either Strategy, an invalid update will be discard silently.
+ /// Invalid update means inserting an edge that does not exist in the CFG.
+ /// The Eager Strategy flushes this update immediately while the Lazy Strategy
+ /// queues the update. It is only recommended to use this method when you
+ /// want to discard an invalid update.
+ /// CAUTION! It is illegal to submit any update that has already been
+ /// submitted. }
+ LLVM_ATTRIBUTE_DEPRECATED(void insertEdgeRelaxed(BasicBlock *From,
+ BasicBlock *To),
+ "Use applyUpdatesPermissive() instead.");
+
+ /// \deprecated { Submit an edge deletion to all available trees. The Eager
+ /// Strategy flushes this update immediately while the Lazy Strategy queues
+ /// the update. An internal function checks if the edge doesn't exist in the
+ /// CFG in DEBUG mode.
+ /// CAUTION! This function has to be called *after* making the update on the
+ /// actual CFG. It is illegal to submit any update that has already been
+ /// submitted. }
+ LLVM_ATTRIBUTE_DEPRECATED(void deleteEdge(BasicBlock *From, BasicBlock *To),
+ "Use applyUpdates() instead.");
+
+ /// \deprecated { Submit an edge deletion to all available trees.
+ /// Under either Strategy, an invalid update will be discard silently.
+ /// Invalid update means deleting an edge that exists in the CFG.
+ /// The Eager Strategy flushes this update immediately while the Lazy Strategy
+ /// queues the update. It is only recommended to use this method when you
+ /// want to discard an invalid update.
+ /// CAUTION! It is illegal to submit any update that has already been
+ /// submitted. }
+ LLVM_ATTRIBUTE_DEPRECATED(void deleteEdgeRelaxed(BasicBlock *From,
+ BasicBlock *To),
+ "Use applyUpdatesPermissive() instead.");
+
+ /// Delete DelBB. DelBB will be removed from its Parent and
+ /// erased from available trees if it exists and finally get deleted.
+ /// Under Eager UpdateStrategy, DelBB will be processed immediately.
+ /// Under Lazy UpdateStrategy, DelBB will be queued until a flush event and
+ /// all available trees are up-to-date. Assert if any instruction of DelBB is
+ /// modified while awaiting deletion. When both DT and PDT are nullptrs, DelBB
+ /// will be queued until flush() is called.
+ void deleteBB(BasicBlock *DelBB);
+
+ /// Delete DelBB. DelBB will be removed from its Parent and
+ /// erased from available trees if it exists. Then the callback will
+ /// be called. Finally, DelBB will be deleted.
+ /// Under Eager UpdateStrategy, DelBB will be processed immediately.
+ /// Under Lazy UpdateStrategy, DelBB will be queued until a flush event and
+ /// all available trees are up-to-date. Assert if any instruction of DelBB is
+ /// modified while awaiting deletion. Multiple callbacks can be queued for one
+ /// DelBB under Lazy UpdateStrategy.
+ void callbackDeleteBB(BasicBlock *DelBB,
+ std::function<void(BasicBlock *)> Callback);
+
+ ///@}
+
+ ///@{
+ /// \name Flush APIs
+ ///
+ /// CAUTION! By the moment these flush APIs are called, the current CFG needs
+ /// to be the same as the CFG which DTU is in sync with + all updates
+ /// submitted.
+
+ /// Flush DomTree updates and return DomTree.
+ /// It flushes Deleted BBs if both trees are up-to-date.
+ /// It must only be called when it has a DomTree.
+ DominatorTree &getDomTree();
+
+ /// Flush PostDomTree updates and return PostDomTree.
+ /// It flushes Deleted BBs if both trees are up-to-date.
+ /// It must only be called when it has a PostDomTree.
+ PostDominatorTree &getPostDomTree();
+
+ /// Apply all pending updates to available trees and flush all BasicBlocks
+ /// awaiting deletion.
+
+ void flush();
+
+ ///@}
+
+ /// Debug method to help view the internal state of this class.
+ LLVM_DUMP_METHOD void dump() const;
+
+private:
+ class CallBackOnDeletion final : public CallbackVH {
+ public:
+ CallBackOnDeletion(BasicBlock *V,
+ std::function<void(BasicBlock *)> Callback)
+ : CallbackVH(V), DelBB(V), Callback_(Callback) {}
+
+ private:
+ BasicBlock *DelBB = nullptr;
+ std::function<void(BasicBlock *)> Callback_;
+
+ void deleted() override {
+ Callback_(DelBB);
+ CallbackVH::deleted();
+ }
+ };
+
+ SmallVector<DominatorTree::UpdateType, 16> PendUpdates;
+ size_t PendDTUpdateIndex = 0;
+ size_t PendPDTUpdateIndex = 0;
+ DominatorTree *DT = nullptr;
+ PostDominatorTree *PDT = nullptr;
+ const UpdateStrategy Strategy;
+ SmallPtrSet<BasicBlock *, 8> DeletedBBs;
+ std::vector<CallBackOnDeletion> Callbacks;
+ bool IsRecalculatingDomTree = false;
+ bool IsRecalculatingPostDomTree = false;
+
+ /// First remove all the instructions of DelBB and then make sure DelBB has a
+ /// valid terminator instruction which is necessary to have when DelBB still
+ /// has to be inside of its parent Function while awaiting deletion under Lazy
+ /// UpdateStrategy to prevent other routines from asserting the state of the
+ /// IR is inconsistent. Assert if DelBB is nullptr or has predecessors.
+ void validateDeleteBB(BasicBlock *DelBB);
+
+ /// Returns true if at least one BasicBlock is deleted.
+ bool forceFlushDeletedBB();
+
+ /// Helper function to apply all pending DomTree updates.
+ void applyDomTreeUpdates();
+
+ /// Helper function to apply all pending PostDomTree updates.
+ void applyPostDomTreeUpdates();
+
+ /// Helper function to flush deleted BasicBlocks if all available
+ /// trees are up-to-date.
+ void tryFlushDeletedBB();
+
+ /// Drop all updates applied by all available trees and delete BasicBlocks if
+ /// all available trees are up-to-date.
+ void dropOutOfDateUpdates();
+
+ /// Erase Basic Block node that has been unlinked from Function
+ /// in the DomTree and PostDomTree.
+ void eraseDelBBNode(BasicBlock *DelBB);
+
+ /// Returns true if the update appears in the LLVM IR.
+ /// It is used to check whether an update is valid in
+ /// insertEdge/deleteEdge or is unnecessary in the batch update.
+ bool isUpdateValid(DominatorTree::UpdateType Update) const;
+
+ /// Returns true if the update is self dominance.
+ bool isSelfDominance(DominatorTree::UpdateType Update) const;
+};
+} // namespace llvm
+
+#endif // LLVM_ANALYSIS_DOMTREEUPDATER_H
diff --git a/include/llvm/Analysis/DominanceFrontier.h b/include/llvm/Analysis/DominanceFrontier.h
index d94c420d7177..c0bf30e162dd 100644
--- a/include/llvm/Analysis/DominanceFrontier.h
+++ b/include/llvm/Analysis/DominanceFrontier.h
@@ -1,9 +1,8 @@
//===- llvm/Analysis/DominanceFrontier.h - Dominator Frontiers --*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/DominanceFrontierImpl.h b/include/llvm/Analysis/DominanceFrontierImpl.h
index 99224c0bf131..aa764be93b91 100644
--- a/include/llvm/Analysis/DominanceFrontierImpl.h
+++ b/include/llvm/Analysis/DominanceFrontierImpl.h
@@ -1,9 +1,8 @@
//===- llvm/Analysis/DominanceFrontier.h - Dominator Frontiers --*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/EHPersonalities.h b/include/llvm/Analysis/EHPersonalities.h
index fe0e65b828ca..d89aa11617b5 100644
--- a/include/llvm/Analysis/EHPersonalities.h
+++ b/include/llvm/Analysis/EHPersonalities.h
@@ -1,9 +1,8 @@
//===- EHPersonalities.h - Compute EH-related information -----------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/llvm/Analysis/GlobalsModRef.h b/include/llvm/Analysis/GlobalsModRef.h
index 3a664ca6ef50..d3fcfc2d41ab 100644
--- a/include/llvm/Analysis/GlobalsModRef.h
+++ b/include/llvm/Analysis/GlobalsModRef.h
@@ -1,9 +1,8 @@
//===- GlobalsModRef.h - Simple Mod/Ref AA for Globals ----------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
@@ -85,10 +84,12 @@ public:
//------------------------------------------------
// Implement the AliasAnalysis API
//
- AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB);
+ AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
+ AAQueryInfo &AAQI);
using AAResultBase::getModRefInfo;
- ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc);
+ ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
+ AAQueryInfo &AAQI);
/// getModRefBehavior - Return the behavior of the specified function if
/// called from the specified call site. The call site may be null in which
@@ -114,7 +115,7 @@ private:
bool isNonEscapingGlobalNoAlias(const GlobalValue *GV, const Value *V);
ModRefInfo getModRefInfoForArgument(const CallBase *Call,
- const GlobalValue *GV);
+ const GlobalValue *GV, AAQueryInfo &AAQI);
};
/// Analysis pass providing a never-invalidated alias analysis result.
diff --git a/include/llvm/Analysis/GuardUtils.h b/include/llvm/Analysis/GuardUtils.h
index 3b151eeafc81..41e7b7c06c75 100644
--- a/include/llvm/Analysis/GuardUtils.h
+++ b/include/llvm/Analysis/GuardUtils.h
@@ -1,9 +1,8 @@
//===-- GuardUtils.h - Utils for work with guards ---------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// Utils that are used to perform analyzes related to guards and their
@@ -15,12 +14,31 @@
namespace llvm {
+class BasicBlock;
class User;
+class Value;
-/// Returns true iff \p U has semantics of a guard.
+/// Returns true iff \p U has semantics of a guard expressed in a form of call
+/// of llvm.experimental.guard intrinsic.
bool isGuard(const User *U);
+/// Returns true iff \p U has semantics of a guard expressed in a form of a
+/// widenable conditional branch to deopt block.
+bool isGuardAsWidenableBranch(const User *U);
+
+/// If U is widenable branch looking like:
+/// %cond = ...
+/// %wc = call i1 @llvm.experimental.widenable.condition()
+/// %branch_cond = and i1 %cond, %wc
+/// br i1 %branch_cond, label %if_true_bb, label %if_false_bb ; <--- U
+/// The function returns true, and the values %cond and %wc and blocks
+/// %if_true_bb, if_false_bb are returned in
+/// the parameters (Condition, WidenableCondition, IfTrueBB and IfFalseFF)
+/// respectively. If \p U does not match this pattern, return false.
+bool parseWidenableBranch(const User *U, Value *&Condition,
+ Value *&WidenableCondition, BasicBlock *&IfTrueBB,
+ BasicBlock *&IfFalseBB);
+
} // llvm
#endif // LLVM_ANALYSIS_GUARDUTILS_H
-
diff --git a/include/llvm/Analysis/IVDescriptors.h b/include/llvm/Analysis/IVDescriptors.h
index 64b4ae23cc59..7be1fd3f5788 100644
--- a/include/llvm/Analysis/IVDescriptors.h
+++ b/include/llvm/Analysis/IVDescriptors.h
@@ -1,9 +1,8 @@
//===- llvm/Analysis/IVDescriptors.h - IndVar Descriptors -------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -90,10 +89,12 @@ public:
RecurrenceDescriptor() = default;
RecurrenceDescriptor(Value *Start, Instruction *Exit, RecurrenceKind K,
- MinMaxRecurrenceKind MK, Instruction *UAI, Type *RT,
- bool Signed, SmallPtrSetImpl<Instruction *> &CI)
- : StartValue(Start), LoopExitInstr(Exit), Kind(K), MinMaxKind(MK),
- UnsafeAlgebraInst(UAI), RecurrenceType(RT), IsSigned(Signed) {
+ FastMathFlags FMF, MinMaxRecurrenceKind MK,
+ Instruction *UAI, Type *RT, bool Signed,
+ SmallPtrSetImpl<Instruction *> &CI)
+ : StartValue(Start), LoopExitInstr(Exit), Kind(K), FMF(FMF),
+ MinMaxKind(MK), UnsafeAlgebraInst(UAI), RecurrenceType(RT),
+ IsSigned(Signed) {
CastInsts.insert(CI.begin(), CI.end());
}
@@ -199,6 +200,8 @@ public:
MinMaxRecurrenceKind getMinMaxRecurrenceKind() { return MinMaxKind; }
+ FastMathFlags getFastMathFlags() { return FMF; }
+
TrackingVH<Value> getRecurrenceStartValue() { return StartValue; }
Instruction *getLoopExitInstr() { return LoopExitInstr; }
@@ -238,6 +241,9 @@ private:
Instruction *LoopExitInstr = nullptr;
// The kind of the recurrence.
RecurrenceKind Kind = RK_NoRecurrence;
+ // The fast-math flags on the recurrent instructions. We propagate these
+ // fast-math flags into the vectorized FP instructions we generate.
+ FastMathFlags FMF;
// If this a min/max recurrence the kind of recurrence.
MinMaxRecurrenceKind MinMaxKind = MRK_Invalid;
// First occurrence of unasfe algebra in the PHI's use-chain.
@@ -309,12 +315,16 @@ public:
/// not have the "fast-math" property. Such operation requires a relaxed FP
/// mode.
bool hasUnsafeAlgebra() {
- return InductionBinOp && !cast<FPMathOperator>(InductionBinOp)->isFast();
+ return (IK == IK_FpInduction) && InductionBinOp &&
+ !cast<FPMathOperator>(InductionBinOp)->isFast();
}
/// Returns induction operator that does not have "fast-math" property
/// and requires FP unsafe mode.
Instruction *getUnsafeAlgebraInst() {
+ if (IK != IK_FpInduction)
+ return nullptr;
+
if (!InductionBinOp || cast<FPMathOperator>(InductionBinOp)->isFast())
return nullptr;
return InductionBinOp;
diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h
index 035b974c5c1d..f8ea3bcca229 100644
--- a/include/llvm/Analysis/IVUsers.h
+++ b/include/llvm/Analysis/IVUsers.h
@@ -1,9 +1,8 @@
//===- llvm/Analysis/IVUsers.h - Induction Variable Users -------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/IndirectCallPromotionAnalysis.h b/include/llvm/Analysis/IndirectCallPromotionAnalysis.h
index be3a28424cf5..8a05e913a910 100644
--- a/include/llvm/Analysis/IndirectCallPromotionAnalysis.h
+++ b/include/llvm/Analysis/IndirectCallPromotionAnalysis.h
@@ -1,9 +1,8 @@
//===- IndirectCallPromotionAnalysis.h - Indirect call analysis -*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
diff --git a/include/llvm/Analysis/IndirectCallVisitor.h b/include/llvm/Analysis/IndirectCallVisitor.h
index d00cf63368f1..1d1f3f4cc5c0 100644
--- a/include/llvm/Analysis/IndirectCallVisitor.h
+++ b/include/llvm/Analysis/IndirectCallVisitor.h
@@ -1,9 +1,8 @@
//===-- IndirectCallVisitor.h - indirect call visitor ---------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/InlineCost.h b/include/llvm/Analysis/InlineCost.h
index 4c270354b0c4..611c9de24e47 100644
--- a/include/llvm/Analysis/InlineCost.h
+++ b/include/llvm/Analysis/InlineCost.h
@@ -1,9 +1,8 @@
//===- InlineCost.h - Cost analysis for inliner -----------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -23,7 +22,7 @@
namespace llvm {
class AssumptionCacheTracker;
class BlockFrequencyInfo;
-class CallSite;
+class CallBase;
class DataLayout;
class Function;
class ProfileSummaryInfo;
@@ -68,10 +67,10 @@ class InlineCost {
};
/// The estimated cost of inlining this callsite.
- const int Cost;
+ int Cost;
/// The adjusted threshold against which this cost was computed.
- const int Threshold;
+ int Threshold;
/// Must be set for Always and Never instances.
const char *Reason = nullptr;
@@ -200,7 +199,7 @@ InlineParams getInlineParams(unsigned OptLevel, unsigned SizeOptLevel);
/// Return the cost associated with a callsite, including parameter passing
/// and the call/return instruction.
-int getCallsiteCost(CallSite CS, const DataLayout &DL);
+int getCallsiteCost(CallBase &Call, const DataLayout &DL);
/// Get an InlineCost object representing the cost of inlining this
/// callsite.
@@ -214,7 +213,7 @@ int getCallsiteCost(CallSite CS, const DataLayout &DL);
/// Also note that calling this function *dynamically* computes the cost of
/// inlining the callsite. It is an expensive, heavyweight call.
InlineCost getInlineCost(
- CallSite CS, const InlineParams &Params, TargetTransformInfo &CalleeTTI,
+ CallBase &Call, const InlineParams &Params, TargetTransformInfo &CalleeTTI,
std::function<AssumptionCache &(Function &)> &GetAssumptionCache,
Optional<function_ref<BlockFrequencyInfo &(Function &)>> GetBFI,
ProfileSummaryInfo *PSI, OptimizationRemarkEmitter *ORE = nullptr);
@@ -225,14 +224,14 @@ InlineCost getInlineCost(
/// parameter in all other respects.
//
InlineCost
-getInlineCost(CallSite CS, Function *Callee, const InlineParams &Params,
+getInlineCost(CallBase &Call, Function *Callee, const InlineParams &Params,
TargetTransformInfo &CalleeTTI,
std::function<AssumptionCache &(Function &)> &GetAssumptionCache,
Optional<function_ref<BlockFrequencyInfo &(Function &)>> GetBFI,
ProfileSummaryInfo *PSI, OptimizationRemarkEmitter *ORE);
/// Minimal filter to detect invalid constructs for inlining.
-bool isInlineViable(Function &Callee);
+InlineResult isInlineViable(Function &Callee);
}
#endif
diff --git a/include/llvm/Analysis/InstructionPrecedenceTracking.h b/include/llvm/Analysis/InstructionPrecedenceTracking.h
index 073e6ec3b7f6..3c3981066a49 100644
--- a/include/llvm/Analysis/InstructionPrecedenceTracking.h
+++ b/include/llvm/Analysis/InstructionPrecedenceTracking.h
@@ -1,9 +1,8 @@
//===-- InstructionPrecedenceTracking.h -------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// Implements a class that is able to define some instructions as "special"
@@ -93,7 +92,7 @@ public:
/// example, throwing calls and guards do not always do this. If we need to know
/// for sure that some instruction is guaranteed to execute if the given block
/// is reached, then we need to make sure that there is no implicit control flow
-/// instruction (ICFI) preceeding it. For example, this check is required if we
+/// instruction (ICFI) preceding it. For example, this check is required if we
/// perform PRE moving non-speculable instruction to other place.
class ImplicitControlFlowTracking : public InstructionPrecedenceTracking {
public:
diff --git a/include/llvm/Analysis/InstructionSimplify.h b/include/llvm/Analysis/InstructionSimplify.h
index 6662e91037e1..054ffca7215e 100644
--- a/include/llvm/Analysis/InstructionSimplify.h
+++ b/include/llvm/Analysis/InstructionSimplify.h
@@ -1,9 +1,8 @@
//===-- InstructionSimplify.h - Fold instrs into simpler forms --*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -41,8 +40,8 @@ class Function;
template <typename T, typename... TArgs> class AnalysisManager;
template <class T> class ArrayRef;
class AssumptionCache;
+class CallBase;
class DominatorTree;
-class ImmutableCallSite;
class DataLayout;
class FastMathFlags;
struct LoopStandardAnalysisResults;
@@ -118,6 +117,10 @@ struct SimplifyQuery {
// deprecated.
// Please use the SimplifyQuery versions in new code.
+/// Given operand for an FNeg, fold the result or return null.
+Value *SimplifyFNegInst(Value *Op, FastMathFlags FMF,
+ const SimplifyQuery &Q);
+
/// Given operands for an Add, fold the result or return null.
Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
const SimplifyQuery &Q);
@@ -228,6 +231,15 @@ Value *SimplifyShuffleVectorInst(Value *Op0, Value *Op1, Constant *Mask,
Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
const SimplifyQuery &Q);
+/// Given operand for a UnaryOperator, fold the result or return null.
+Value *SimplifyUnOp(unsigned Opcode, Value *Op, const SimplifyQuery &Q);
+
+/// Given operand for an FP UnaryOperator, fold the result or return null.
+/// In contrast to SimplifyUnOp, try to use FastMathFlag when folding the
+/// result. In case we don't need FastMathFlags, simply fall to SimplifyUnOp.
+Value *SimplifyFPUnOp(unsigned Opcode, Value *Op, FastMathFlags FMF,
+ const SimplifyQuery &Q);
+
/// Given operands for a BinaryOperator, fold the result or return null.
Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
const SimplifyQuery &Q);
@@ -239,16 +251,7 @@ Value *SimplifyFPBinOp(unsigned Opcode, Value *LHS, Value *RHS,
FastMathFlags FMF, const SimplifyQuery &Q);
/// Given a callsite, fold the result or return null.
-Value *SimplifyCall(ImmutableCallSite CS, const SimplifyQuery &Q);
-
-/// Given a function and iterators over arguments, fold the result or return
-/// null.
-Value *SimplifyCall(ImmutableCallSite CS, Value *V, User::op_iterator ArgBegin,
- User::op_iterator ArgEnd, const SimplifyQuery &Q);
-
-/// Given a function and set of arguments, fold the result or return null.
-Value *SimplifyCall(ImmutableCallSite CS, Value *V, ArrayRef<Value *> Args,
- const SimplifyQuery &Q);
+Value *SimplifyCall(CallBase *Call, const SimplifyQuery &Q);
/// See if we can compute a simplified version of this instruction. If not,
/// return null.
diff --git a/include/llvm/Analysis/Interval.h b/include/llvm/Analysis/Interval.h
index f3714dddedd5..5c9a4535bc7f 100644
--- a/include/llvm/Analysis/Interval.h
+++ b/include/llvm/Analysis/Interval.h
@@ -1,9 +1,8 @@
//===- llvm/Analysis/Interval.h - Interval Class Declaration ----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/IntervalIterator.h b/include/llvm/Analysis/IntervalIterator.h
index 6ffcae592e98..efaaf9715b3d 100644
--- a/include/llvm/Analysis/IntervalIterator.h
+++ b/include/llvm/Analysis/IntervalIterator.h
@@ -1,9 +1,8 @@
//===- IntervalIterator.h - Interval Iterator Declaration -------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/IntervalPartition.h b/include/llvm/Analysis/IntervalPartition.h
index 50335165711f..5b127c25a2b8 100644
--- a/include/llvm/Analysis/IntervalPartition.h
+++ b/include/llvm/Analysis/IntervalPartition.h
@@ -1,9 +1,8 @@
//===- IntervalPartition.h - Interval partition Calculation -----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/IteratedDominanceFrontier.h b/include/llvm/Analysis/IteratedDominanceFrontier.h
index 3083db75b81c..7c826780c318 100644
--- a/include/llvm/Analysis/IteratedDominanceFrontier.h
+++ b/include/llvm/Analysis/IteratedDominanceFrontier.h
@@ -1,101 +1,89 @@
//===- IteratedDominanceFrontier.h - Calculate IDF --------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-/// \file
-/// Compute iterated dominance frontiers using a linear time algorithm.
-///
-/// The algorithm used here is based on:
-///
-/// Sreedhar and Gao. A linear time algorithm for placing phi-nodes.
-/// In Proceedings of the 22nd ACM SIGPLAN-SIGACT Symposium on Principles of
-/// Programming Languages
-/// POPL '95. ACM, New York, NY, 62-73.
-///
-/// It has been modified to not explicitly use the DJ graph data structure and
-/// to directly compute pruned SSA using per-variable liveness information.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_IDF_H
#define LLVM_ANALYSIS_IDF_H
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CFGDiff.h"
-#include "llvm/IR/Dominators.h"
+#include "llvm/Support/GenericIteratedDominanceFrontier.h"
namespace llvm {
-/// Determine the iterated dominance frontier, given a set of defining
-/// blocks, and optionally, a set of live-in blocks.
-///
-/// In turn, the results can be used to place phi nodes.
-///
-/// This algorithm is a linear time computation of Iterated Dominance Frontiers,
-/// pruned using the live-in set.
-/// By default, liveness is not used to prune the IDF computation.
-/// The template parameters should be either BasicBlock* or Inverse<BasicBlock
-/// *>, depending on if you want the forward or reverse IDF.
-template <class NodeTy, bool IsPostDom>
-class IDFCalculator {
- public:
- IDFCalculator(DominatorTreeBase<BasicBlock, IsPostDom> &DT)
- : DT(DT), GD(nullptr), useLiveIn(false) {}
-
- IDFCalculator(DominatorTreeBase<BasicBlock, IsPostDom> &DT,
- const GraphDiff<BasicBlock *, IsPostDom> *GD)
- : DT(DT), GD(GD), useLiveIn(false) {}
-
- /// Give the IDF calculator the set of blocks in which the value is
- /// defined. This is equivalent to the set of starting blocks it should be
- /// calculating the IDF for (though later gets pruned based on liveness).
- ///
- /// Note: This set *must* live for the entire lifetime of the IDF calculator.
- void setDefiningBlocks(const SmallPtrSetImpl<BasicBlock *> &Blocks) {
- DefBlocks = &Blocks;
- }
-
- /// Give the IDF calculator the set of blocks in which the value is
- /// live on entry to the block. This is used to prune the IDF calculation to
- /// not include blocks where any phi insertion would be dead.
- ///
- /// Note: This set *must* live for the entire lifetime of the IDF calculator.
-
- void setLiveInBlocks(const SmallPtrSetImpl<BasicBlock *> &Blocks) {
- LiveInBlocks = &Blocks;
- useLiveIn = true;
- }
+class BasicBlock;
- /// Reset the live-in block set to be empty, and tell the IDF
- /// calculator to not use liveness anymore.
- void resetLiveInBlocks() {
- LiveInBlocks = nullptr;
- useLiveIn = false;
+namespace IDFCalculatorDetail {
+
+/// Specialization for BasicBlock for the optional use of GraphDiff.
+template <bool IsPostDom> struct ChildrenGetterTy<BasicBlock, IsPostDom> {
+ using NodeRef = BasicBlock *;
+ using ChildrenTy = SmallVector<BasicBlock *, 8>;
+
+ ChildrenGetterTy() = default;
+ ChildrenGetterTy(const GraphDiff<BasicBlock *, IsPostDom> *GD) : GD(GD) {
+ assert(GD);
}
- /// Calculate iterated dominance frontiers
- ///
- /// This uses the linear-time phi algorithm based on DJ-graphs mentioned in
- /// the file-level comment. It performs DF->IDF pruning using the live-in
- /// set, to avoid computing the IDF for blocks where an inserted PHI node
- /// would be dead.
- void calculate(SmallVectorImpl<BasicBlock *> &IDFBlocks);
-
-private:
- DominatorTreeBase<BasicBlock, IsPostDom> &DT;
- const GraphDiff<BasicBlock *, IsPostDom> *GD;
- bool useLiveIn;
- const SmallPtrSetImpl<BasicBlock *> *LiveInBlocks;
- const SmallPtrSetImpl<BasicBlock *> *DefBlocks;
+ ChildrenTy get(const NodeRef &N);
+
+ const GraphDiff<BasicBlock *, IsPostDom> *GD = nullptr;
};
-typedef IDFCalculator<BasicBlock *, false> ForwardIDFCalculator;
-typedef IDFCalculator<Inverse<BasicBlock *>, true> ReverseIDFCalculator;
+
+} // end of namespace IDFCalculatorDetail
+
+template <bool IsPostDom>
+class IDFCalculator final : public IDFCalculatorBase<BasicBlock, IsPostDom> {
+public:
+ using IDFCalculatorBase =
+ typename llvm::IDFCalculatorBase<BasicBlock, IsPostDom>;
+ using ChildrenGetterTy = typename IDFCalculatorBase::ChildrenGetterTy;
+
+ IDFCalculator(DominatorTreeBase<BasicBlock, IsPostDom> &DT)
+ : IDFCalculatorBase(DT) {}
+
+ IDFCalculator(DominatorTreeBase<BasicBlock, IsPostDom> &DT,
+ const GraphDiff<BasicBlock *, IsPostDom> *GD)
+ : IDFCalculatorBase(DT, ChildrenGetterTy(GD)) {
+ assert(GD);
+ }
+};
+
+using ForwardIDFCalculator = IDFCalculator<false>;
+using ReverseIDFCalculator = IDFCalculator<true>;
+
+//===----------------------------------------------------------------------===//
+// Implementation.
+//===----------------------------------------------------------------------===//
+
+namespace IDFCalculatorDetail {
+
+template <bool IsPostDom>
+typename ChildrenGetterTy<BasicBlock, IsPostDom>::ChildrenTy
+ChildrenGetterTy<BasicBlock, IsPostDom>::get(const NodeRef &N) {
+
+ using OrderedNodeTy =
+ typename IDFCalculatorBase<BasicBlock, IsPostDom>::OrderedNodeTy;
+
+ if (!GD) {
+ auto Children = children<OrderedNodeTy>(N);
+ return {Children.begin(), Children.end()};
+ }
+
+ using SnapShotBBPairTy =
+ std::pair<const GraphDiff<BasicBlock *, IsPostDom> *, OrderedNodeTy>;
+
+ ChildrenTy Ret;
+ for (const auto &SnapShotBBPair : children<SnapShotBBPairTy>({GD, N}))
+ Ret.emplace_back(SnapShotBBPair.second);
+ return Ret;
}
+
+} // end of namespace IDFCalculatorDetail
+
+} // end of namespace llvm
+
#endif
diff --git a/include/llvm/Analysis/LazyBlockFrequencyInfo.h b/include/llvm/Analysis/LazyBlockFrequencyInfo.h
index d1afb63d7e08..0e7dc943bacf 100644
--- a/include/llvm/Analysis/LazyBlockFrequencyInfo.h
+++ b/include/llvm/Analysis/LazyBlockFrequencyInfo.h
@@ -1,9 +1,8 @@
//===- LazyBlockFrequencyInfo.h - Lazy Block Frequency Analysis -*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/LazyBranchProbabilityInfo.h b/include/llvm/Analysis/LazyBranchProbabilityInfo.h
index 9e6bcfedcbb9..cae0778cd16d 100644
--- a/include/llvm/Analysis/LazyBranchProbabilityInfo.h
+++ b/include/llvm/Analysis/LazyBranchProbabilityInfo.h
@@ -1,9 +1,8 @@
//===- LazyBranchProbabilityInfo.h - Lazy Branch Probability ----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/LazyCallGraph.h b/include/llvm/Analysis/LazyCallGraph.h
index d1ec6a9dcc55..2d83929211e2 100644
--- a/include/llvm/Analysis/LazyCallGraph.h
+++ b/include/llvm/Analysis/LazyCallGraph.h
@@ -1,9 +1,8 @@
//===- LazyCallGraph.h - Analysis of a Module's call graph ------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
@@ -39,6 +38,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
@@ -1083,12 +1083,26 @@ public:
continue;
}
+ // The blockaddress constant expression is a weird special case, we can't
+ // generically walk its operands the way we do for all other constants.
if (BlockAddress *BA = dyn_cast<BlockAddress>(C)) {
- // The blockaddress constant expression is a weird special case, we
- // can't generically walk its operands the way we do for all other
- // constants.
- if (Visited.insert(BA->getFunction()).second)
- Worklist.push_back(BA->getFunction());
+ // If we've already visited the function referred to by the block
+ // address, we don't need to revisit it.
+ if (Visited.count(BA->getFunction()))
+ continue;
+
+ // If all of the blockaddress' users are instructions within the
+ // referred to function, we don't need to insert a cycle.
+ if (llvm::all_of(BA->users(), [&](User *U) {
+ if (Instruction *I = dyn_cast<Instruction>(U))
+ return I->getFunction() == BA->getFunction();
+ return false;
+ }))
+ continue;
+
+ // Otherwise we should go visit the referred to function.
+ Visited.insert(BA->getFunction());
+ Worklist.push_back(BA->getFunction());
continue;
}
diff --git a/include/llvm/Analysis/LazyValueInfo.h b/include/llvm/Analysis/LazyValueInfo.h
index 1a4fdb591427..570a5044f6f8 100644
--- a/include/llvm/Analysis/LazyValueInfo.h
+++ b/include/llvm/Analysis/LazyValueInfo.h
@@ -1,9 +1,8 @@
//===- LazyValueInfo.h - Value constraint analysis --------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/LegacyDivergenceAnalysis.h b/include/llvm/Analysis/LegacyDivergenceAnalysis.h
index fc426ad7fb64..0a338b816640 100644
--- a/include/llvm/Analysis/LegacyDivergenceAnalysis.h
+++ b/include/llvm/Analysis/LegacyDivergenceAnalysis.h
@@ -1,9 +1,8 @@
//===- llvm/Analysis/LegacyDivergenceAnalysis.h - KernelDivergence Analysis -*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/Lint.h b/include/llvm/Analysis/Lint.h
index db5919fd91c7..0fea81e215c9 100644
--- a/include/llvm/Analysis/Lint.h
+++ b/include/llvm/Analysis/Lint.h
@@ -1,9 +1,8 @@
//===-- llvm/Analysis/Lint.h - LLVM IR Lint ---------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/Loads.h b/include/llvm/Analysis/Loads.h
index f110c28bfc6d..5df6bb02308d 100644
--- a/include/llvm/Analysis/Loads.h
+++ b/include/llvm/Analysis/Loads.h
@@ -1,9 +1,8 @@
//===- Loads.h - Local load analysis --------------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -26,7 +25,8 @@ class MDNode;
/// Return true if this is always a dereferenceable pointer. If the context
/// instruction is specified perform context-sensitive analysis and return true
/// if the pointer is dereferenceable at the specified instruction.
-bool isDereferenceablePointer(const Value *V, const DataLayout &DL,
+bool isDereferenceablePointer(const Value *V, Type *Ty,
+ const DataLayout &DL,
const Instruction *CtxI = nullptr,
const DominatorTree *DT = nullptr);
@@ -34,8 +34,8 @@ bool isDereferenceablePointer(const Value *V, const DataLayout &DL,
/// greater or equal than requested. If the context instruction is specified
/// performs context-sensitive analysis and returns true if the pointer is
/// dereferenceable at the specified instruction.
-bool isDereferenceableAndAlignedPointer(const Value *V, unsigned Align,
- const DataLayout &DL,
+bool isDereferenceableAndAlignedPointer(const Value *V, Type *Ty,
+ unsigned Align, const DataLayout &DL,
const Instruction *CtxI = nullptr,
const DominatorTree *DT = nullptr);
@@ -56,7 +56,20 @@ bool isDereferenceableAndAlignedPointer(const Value *V, unsigned Align,
/// If it is not obviously safe to load from the specified pointer, we do a
/// quick local scan of the basic block containing ScanFrom, to determine if
/// the address is already accessed.
-bool isSafeToLoadUnconditionally(Value *V, unsigned Align,
+bool isSafeToLoadUnconditionally(Value *V, unsigned Align, APInt &Size,
+ const DataLayout &DL,
+ Instruction *ScanFrom = nullptr,
+ const DominatorTree *DT = nullptr);
+
+/// Return true if we know that executing a load from this value cannot trap.
+///
+/// If DT and ScanFrom are specified this method performs context-sensitive
+/// analysis and returns true if it is safe to load immediately before ScanFrom.
+///
+/// If it is not obviously safe to load from the specified pointer, we do a
+/// quick local scan of the basic block containing ScanFrom, to determine if
+/// the address is already accessed.
+bool isSafeToLoadUnconditionally(Value *V, Type *Ty, unsigned Align,
const DataLayout &DL,
Instruction *ScanFrom = nullptr,
const DominatorTree *DT = nullptr);
diff --git a/include/llvm/Analysis/LoopAccessAnalysis.h b/include/llvm/Analysis/LoopAccessAnalysis.h
index 4ed00e207753..9e9aaa32c64f 100644
--- a/include/llvm/Analysis/LoopAccessAnalysis.h
+++ b/include/llvm/Analysis/LoopAccessAnalysis.h
@@ -1,9 +1,8 @@
//===- llvm/Analysis/LoopAccessAnalysis.h -----------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -523,6 +522,11 @@ public:
/// no memory dependence cycles.
bool canVectorizeMemory() const { return CanVecMem; }
+ /// Return true if there is a convergent operation in the loop. There may
+ /// still be reported runtime pointer checks that would be required, but it is
+ /// not legal to insert them.
+ bool hasConvergentOp() const { return HasConvergentOp; }
+
const RuntimePointerChecking *getRuntimePointerChecking() const {
return PtrRtChecking.get();
}
@@ -643,6 +647,7 @@ private:
/// Cache the result of analyzeLoop.
bool CanVecMem;
+ bool HasConvergentOp;
/// Indicator that there are non vectorizable stores to a uniform address.
bool HasDependenceInvolvingLoopInvariantAddress;
diff --git a/include/llvm/Analysis/LoopAnalysisManager.h b/include/llvm/Analysis/LoopAnalysisManager.h
index 00e562c4f31f..368a810cfa67 100644
--- a/include/llvm/Analysis/LoopAnalysisManager.h
+++ b/include/llvm/Analysis/LoopAnalysisManager.h
@@ -1,9 +1,8 @@
//===- LoopAnalysisManager.h - Loop analysis management ---------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
@@ -62,9 +61,6 @@ struct LoopStandardAnalysisResults {
MemorySSA *MSSA;
};
-/// Enables memory ssa as a dependency for loop passes.
-extern cl::opt<bool> EnableMSSALoopDependency;
-
/// Extern template declaration for the analysis set for this IR unit.
extern template class AllAnalysesOn<Loop>;
diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h
index 72873546a068..584eb3a8c854 100644
--- a/include/llvm/Analysis/LoopInfo.h
+++ b/include/llvm/Analysis/LoopInfo.h
@@ -1,9 +1,8 @@
//===- llvm/Analysis/LoopInfo.h - Natural Loop Calculator -------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -55,8 +54,11 @@ namespace llvm {
class DominatorTree;
class LoopInfo;
class Loop;
+class InductionDescriptor;
class MDNode;
+class MemorySSAUpdater;
class PHINode;
+class ScalarEvolution;
class raw_ostream;
template <class N, bool IsPostDom> class DominatorTreeBase;
template <class N, class M> class LoopInfoBase;
@@ -199,9 +201,10 @@ public:
}
/// True if terminator in the block can branch to another block that is
- /// outside of the current loop.
+ /// outside of the current loop. \p BB must be inside the loop.
bool isLoopExiting(const BlockT *BB) const {
assert(!isInvalid() && "Loop not in a valid state!");
+ assert(contains(BB) && "Exiting block must be part of the loop");
for (const auto &Succ : children<const BlockT *>(BB)) {
if (!contains(Succ))
return true;
@@ -267,16 +270,20 @@ public:
/// Return all unique successor blocks of this loop.
/// These are the blocks _outside of the current loop_ which are branched to.
- /// This assumes that loop exits are in canonical form, i.e. all exits are
- /// dedicated exits.
void getUniqueExitBlocks(SmallVectorImpl<BlockT *> &ExitBlocks) const;
+ /// Return all unique successor blocks of this loop except successors from
+ /// Latch block are not considered. If the exit comes from Latch has also
+ /// non Latch predecessor in a loop it will be added to ExitBlocks.
+ /// These are the blocks _outside of the current loop_ which are branched to.
+ void getUniqueNonLatchExitBlocks(SmallVectorImpl<BlockT *> &ExitBlocks) const;
+
/// If getUniqueExitBlocks would return exactly one block, return that block.
/// Otherwise return null.
BlockT *getUniqueExitBlock() const;
/// Edge type.
- typedef std::pair<const BlockT *, const BlockT *> Edge;
+ typedef std::pair<BlockT *, BlockT *> Edge;
/// Return all pairs of (_inside_block_,_outside_block_).
void getExitEdges(SmallVectorImpl<Edge> &ExitEdges) const;
@@ -309,6 +316,40 @@ public:
LoopLatches.push_back(Pred);
}
+ /// Return all inner loops in the loop nest rooted by the loop in preorder,
+ /// with siblings in forward program order.
+ template <class Type>
+ static void getInnerLoopsInPreorder(const LoopT &L,
+ SmallVectorImpl<Type> &PreOrderLoops) {
+ SmallVector<LoopT *, 4> PreOrderWorklist;
+ PreOrderWorklist.append(L.rbegin(), L.rend());
+
+ while (!PreOrderWorklist.empty()) {
+ LoopT *L = PreOrderWorklist.pop_back_val();
+ // Sub-loops are stored in forward program order, but will process the
+ // worklist backwards so append them in reverse order.
+ PreOrderWorklist.append(L->rbegin(), L->rend());
+ PreOrderLoops.push_back(L);
+ }
+ }
+
+ /// Return all loops in the loop nest rooted by the loop in preorder, with
+ /// siblings in forward program order.
+ SmallVector<const LoopT *, 4> getLoopsInPreorder() const {
+ SmallVector<const LoopT *, 4> PreOrderLoops;
+ const LoopT *CurLoop = static_cast<const LoopT *>(this);
+ PreOrderLoops.push_back(CurLoop);
+ getInnerLoopsInPreorder(*CurLoop, PreOrderLoops);
+ return PreOrderLoops;
+ }
+ SmallVector<LoopT *, 4> getLoopsInPreorder() {
+ SmallVector<LoopT *, 4> PreOrderLoops;
+ LoopT *CurLoop = static_cast<LoopT *>(this);
+ PreOrderLoops.push_back(CurLoop);
+ getInnerLoopsInPreorder(*CurLoop, PreOrderLoops);
+ return PreOrderLoops;
+ }
+
//===--------------------------------------------------------------------===//
// APIs for updating loop information after changing the CFG
//
@@ -471,7 +512,7 @@ public:
public:
LocRange() {}
- LocRange(DebugLoc Start) : Start(std::move(Start)), End(std::move(Start)) {}
+ LocRange(DebugLoc Start) : Start(Start), End(Start) {}
LocRange(DebugLoc Start, DebugLoc End)
: Start(std::move(Start)), End(std::move(End)) {}
@@ -499,7 +540,8 @@ public:
/// If InsertPt is specified, it is the point to hoist instructions to.
/// If null, the terminator of the loop preheader is used.
bool makeLoopInvariant(Value *V, bool &Changed,
- Instruction *InsertPt = nullptr) const;
+ Instruction *InsertPt = nullptr,
+ MemorySSAUpdater *MSSAU = nullptr) const;
/// If the given instruction is inside of the loop and it can be hoisted, do
/// so to make it trivially loop-invariant.
@@ -511,7 +553,8 @@ public:
/// If null, the terminator of the loop preheader is used.
///
bool makeLoopInvariant(Instruction *I, bool &Changed,
- Instruction *InsertPt = nullptr) const;
+ Instruction *InsertPt = nullptr,
+ MemorySSAUpdater *MSSAU = nullptr) const;
/// Check to see if the loop has a canonical induction variable: an integer
/// recurrence that starts at 0 and increments by one each time through the
@@ -522,6 +565,170 @@ public:
///
PHINode *getCanonicalInductionVariable() const;
+ /// Obtain the unique incoming and back edge. Return false if they are
+ /// non-unique or the loop is dead; otherwise, return true.
+ bool getIncomingAndBackEdge(BasicBlock *&Incoming,
+ BasicBlock *&Backedge) const;
+
+ /// Below are some utilities to get loop bounds and induction variable, and
+ /// check if a given phinode is an auxiliary induction variable, as well as
+ /// checking if the loop is canonical.
+ ///
+ /// Here is an example:
+ /// \code
+ /// for (int i = lb; i < ub; i+=step)
+ /// <loop body>
+ /// --- pseudo LLVMIR ---
+ /// beforeloop:
+ /// guardcmp = (lb < ub)
+ /// if (guardcmp) goto preheader; else goto afterloop
+ /// preheader:
+ /// loop:
+ /// i_1 = phi[{lb, preheader}, {i_2, latch}]
+ /// <loop body>
+ /// i_2 = i_1 + step
+ /// latch:
+ /// cmp = (i_2 < ub)
+ /// if (cmp) goto loop
+ /// exit:
+ /// afterloop:
+ /// \endcode
+ ///
+ /// - getBounds
+ /// - getInitialIVValue --> lb
+ /// - getStepInst --> i_2 = i_1 + step
+ /// - getStepValue --> step
+ /// - getFinalIVValue --> ub
+ /// - getCanonicalPredicate --> '<'
+ /// - getDirection --> Increasing
+ ///
+ /// - getInductionVariable --> i_1
+ /// - isAuxiliaryInductionVariable(x) --> true if x == i_1
+ /// - isCanonical --> false
+ struct LoopBounds {
+ /// Return the LoopBounds object if
+ /// - the given \p IndVar is an induction variable
+ /// - the initial value of the induction variable can be found
+ /// - the step instruction of the induction variable can be found
+ /// - the final value of the induction variable can be found
+ ///
+ /// Else None.
+ static Optional<Loop::LoopBounds> getBounds(const Loop &L, PHINode &IndVar,
+ ScalarEvolution &SE);
+
+ /// Get the initial value of the loop induction variable.
+ Value &getInitialIVValue() const { return InitialIVValue; }
+
+ /// Get the instruction that updates the loop induction variable.
+ Instruction &getStepInst() const { return StepInst; }
+
+ /// Get the step that the loop induction variable gets updated by in each
+ /// loop iteration. Return nullptr if not found.
+ Value *getStepValue() const { return StepValue; }
+
+ /// Get the final value of the loop induction variable.
+ Value &getFinalIVValue() const { return FinalIVValue; }
+
+ /// Return the canonical predicate for the latch compare instruction, if
+ /// able to be calcuated. Else BAD_ICMP_PREDICATE.
+ ///
+ /// A predicate is considered as canonical if requirements below are all
+ /// satisfied:
+ /// 1. The first successor of the latch branch is the loop header
+ /// If not, inverse the predicate.
+ /// 2. One of the operands of the latch comparison is StepInst
+ /// If not, and
+ /// - if the current calcuated predicate is not ne or eq, flip the
+ /// predicate.
+ /// - else if the loop is increasing, return slt
+ /// (notice that it is safe to change from ne or eq to sign compare)
+ /// - else if the loop is decreasing, return sgt
+ /// (notice that it is safe to change from ne or eq to sign compare)
+ ///
+ /// Here is an example when both (1) and (2) are not satisfied:
+ /// \code
+ /// loop.header:
+ /// %iv = phi [%initialiv, %loop.preheader], [%inc, %loop.header]
+ /// %inc = add %iv, %step
+ /// %cmp = slt %iv, %finaliv
+ /// br %cmp, %loop.exit, %loop.header
+ /// loop.exit:
+ /// \endcode
+ /// - The second successor of the latch branch is the loop header instead
+ /// of the first successor (slt -> sge)
+ /// - The first operand of the latch comparison (%cmp) is the IndVar (%iv)
+ /// instead of the StepInst (%inc) (sge -> sgt)
+ ///
+ /// The predicate would be sgt if both (1) and (2) are satisfied.
+ /// getCanonicalPredicate() returns sgt for this example.
+ /// Note: The IR is not changed.
+ ICmpInst::Predicate getCanonicalPredicate() const;
+
+ /// An enum for the direction of the loop
+ /// - for (int i = 0; i < ub; ++i) --> Increasing
+ /// - for (int i = ub; i > 0; --i) --> Descresing
+ /// - for (int i = x; i != y; i+=z) --> Unknown
+ enum class Direction { Increasing, Decreasing, Unknown };
+
+ /// Get the direction of the loop.
+ Direction getDirection() const;
+
+ private:
+ LoopBounds(const Loop &Loop, Value &I, Instruction &SI, Value *SV, Value &F,
+ ScalarEvolution &SE)
+ : L(Loop), InitialIVValue(I), StepInst(SI), StepValue(SV),
+ FinalIVValue(F), SE(SE) {}
+
+ const Loop &L;
+
+ // The initial value of the loop induction variable
+ Value &InitialIVValue;
+
+ // The instruction that updates the loop induction variable
+ Instruction &StepInst;
+
+ // The value that the loop induction variable gets updated by in each loop
+ // iteration
+ Value *StepValue;
+
+ // The final value of the loop induction variable
+ Value &FinalIVValue;
+
+ ScalarEvolution &SE;
+ };
+
+ /// Return the struct LoopBounds collected if all struct members are found,
+ /// else None.
+ Optional<LoopBounds> getBounds(ScalarEvolution &SE) const;
+
+ /// Return the loop induction variable if found, else return nullptr.
+ /// An instruction is considered as the loop induction variable if
+ /// - it is an induction variable of the loop; and
+ /// - it is used to determine the condition of the branch in the loop latch
+ ///
+ /// Note: the induction variable doesn't need to be canonical, i.e. starts at
+ /// zero and increments by one each time through the loop (but it can be).
+ PHINode *getInductionVariable(ScalarEvolution &SE) const;
+
+ /// Get the loop induction descriptor for the loop induction variable. Return
+ /// true if the loop induction variable is found.
+ bool getInductionDescriptor(ScalarEvolution &SE,
+ InductionDescriptor &IndDesc) const;
+
+ /// Return true if the given PHINode \p AuxIndVar is
+ /// - in the loop header
+ /// - not used outside of the loop
+ /// - incremented by a loop invariant step for each loop iteration
+ /// - step instruction opcode should be add or sub
+ /// Note: auxiliary induction variable is not required to be used in the
+ /// conditional branch in the loop latch. (but it can be)
+ bool isAuxiliaryInductionVariable(PHINode &AuxIndVar,
+ ScalarEvolution &SE) const;
+
+ /// Return true if the loop induction variable starts at zero and increments
+ /// by one each time through the loop.
+ bool isCanonical(ScalarEvolution &SE) const;
+
/// Return true if the Loop is in LCSSA form.
bool isLCSSAForm(DominatorTree &DT) const;
@@ -1015,6 +1222,26 @@ MDNode *findOptionMDForLoop(const Loop *TheLoop, StringRef Name);
/// is representing an access group.
bool isValidAsAccessGroup(MDNode *AccGroup);
+/// Create a new LoopID after the loop has been transformed.
+///
+/// This can be used when no follow-up loop attributes are defined
+/// (llvm::makeFollowupLoopID returning None) to stop transformations to be
+/// applied again.
+///
+/// @param Context The LLVMContext in which to create the new LoopID.
+/// @param OrigLoopID The original LoopID; can be nullptr if the original
+/// loop has no LoopID.
+/// @param RemovePrefixes Remove all loop attributes that have these prefixes.
+/// Use to remove metadata of the transformation that has
+/// been applied.
+/// @param AddAttrs Add these loop attributes to the new LoopID.
+///
+/// @return A new LoopID that can be applied using Loop::setLoopID().
+llvm::MDNode *
+makePostTransformationMetadata(llvm::LLVMContext &Context, MDNode *OrigLoopID,
+ llvm::ArrayRef<llvm::StringRef> RemovePrefixes,
+ llvm::ArrayRef<llvm::MDNode *> AddAttrs);
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Analysis/LoopInfoImpl.h b/include/llvm/Analysis/LoopInfoImpl.h
index 2b807919fedf..4c33dac9e21e 100644
--- a/include/llvm/Analysis/LoopInfoImpl.h
+++ b/include/llvm/Analysis/LoopInfoImpl.h
@@ -1,9 +1,8 @@
//===- llvm/Analysis/LoopInfoImpl.h - Natural Loop Calculator ---*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -96,49 +95,36 @@ bool LoopBase<BlockT, LoopT>::hasDedicatedExits() const {
return true;
}
+// Helper function to get unique loop exits. Pred is a predicate pointing to
+// BasicBlocks in a loop which should be considered to find loop exits.
+template <class BlockT, class LoopT, typename PredicateT>
+void getUniqueExitBlocksHelper(const LoopT *L,
+ SmallVectorImpl<BlockT *> &ExitBlocks,
+ PredicateT Pred) {
+ assert(!L->isInvalid() && "Loop not in a valid state!");
+ SmallPtrSet<BlockT *, 32> Visited;
+ auto Filtered = make_filter_range(L->blocks(), Pred);
+ for (BlockT *BB : Filtered)
+ for (BlockT *Successor : children<BlockT *>(BB))
+ if (!L->contains(Successor))
+ if (Visited.insert(Successor).second)
+ ExitBlocks.push_back(Successor);
+}
+
template <class BlockT, class LoopT>
void LoopBase<BlockT, LoopT>::getUniqueExitBlocks(
SmallVectorImpl<BlockT *> &ExitBlocks) const {
- typedef GraphTraits<BlockT *> BlockTraits;
- typedef GraphTraits<Inverse<BlockT *>> InvBlockTraits;
-
- assert(hasDedicatedExits() &&
- "getUniqueExitBlocks assumes the loop has canonical form exits!");
-
- SmallVector<BlockT *, 32> SwitchExitBlocks;
- for (BlockT *Block : this->blocks()) {
- SwitchExitBlocks.clear();
- for (BlockT *Successor : children<BlockT *>(Block)) {
- // If block is inside the loop then it is not an exit block.
- if (contains(Successor))
- continue;
-
- BlockT *FirstPred = *InvBlockTraits::child_begin(Successor);
-
- // If current basic block is this exit block's first predecessor then only
- // insert exit block in to the output ExitBlocks vector. This ensures that
- // same exit block is not inserted twice into ExitBlocks vector.
- if (Block != FirstPred)
- continue;
-
- // If a terminator has more then two successors, for example SwitchInst,
- // then it is possible that there are multiple edges from current block to
- // one exit block.
- if (std::distance(BlockTraits::child_begin(Block),
- BlockTraits::child_end(Block)) <= 2) {
- ExitBlocks.push_back(Successor);
- continue;
- }
+ getUniqueExitBlocksHelper(this, ExitBlocks,
+ [](const BlockT *BB) { return true; });
+}
- // In case of multiple edges from current block to exit block, collect
- // only one edge in ExitBlocks. Use switchExitBlocks to keep track of
- // duplicate edges.
- if (!is_contained(SwitchExitBlocks, Successor)) {
- SwitchExitBlocks.push_back(Successor);
- ExitBlocks.push_back(Successor);
- }
- }
- }
+template <class BlockT, class LoopT>
+void LoopBase<BlockT, LoopT>::getUniqueNonLatchExitBlocks(
+ SmallVectorImpl<BlockT *> &ExitBlocks) const {
+ const BlockT *Latch = getLoopLatch();
+ assert(Latch && "Latch block must exists");
+ getUniqueExitBlocksHelper(this, ExitBlocks,
+ [Latch](const BlockT *BB) { return BB != Latch; });
}
template <class BlockT, class LoopT>
@@ -588,16 +574,9 @@ SmallVector<LoopT *, 4> LoopInfoBase<BlockT, LoopT>::getLoopsInPreorder() {
// FIXME: If we change the order of LoopInfo we will want to remove the
// reverse here.
for (LoopT *RootL : reverse(*this)) {
- assert(PreOrderWorklist.empty() &&
- "Must start with an empty preorder walk worklist.");
- PreOrderWorklist.push_back(RootL);
- do {
- LoopT *L = PreOrderWorklist.pop_back_val();
- // Sub-loops are stored in forward program order, but will process the
- // worklist backwards so append them in reverse order.
- PreOrderWorklist.append(L->rbegin(), L->rend());
- PreOrderLoops.push_back(L);
- } while (!PreOrderWorklist.empty());
+ auto PreOrderLoopsInRootL = RootL->getLoopsInPreorder();
+ PreOrderLoops.append(PreOrderLoopsInRootL.begin(),
+ PreOrderLoopsInRootL.end());
}
return PreOrderLoops;
diff --git a/include/llvm/Analysis/LoopIterator.h b/include/llvm/Analysis/LoopIterator.h
index 91c54b23029b..fa4da4283f55 100644
--- a/include/llvm/Analysis/LoopIterator.h
+++ b/include/llvm/Analysis/LoopIterator.h
@@ -1,9 +1,8 @@
//===--------- LoopIterator.h - Iterate over loop blocks --------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// This file defines iterators to visit the basic blocks within a loop.
diff --git a/include/llvm/Analysis/LoopPass.h b/include/llvm/Analysis/LoopPass.h
index 86cfecd9df11..9215ab34ec6d 100644
--- a/include/llvm/Analysis/LoopPass.h
+++ b/include/llvm/Analysis/LoopPass.h
@@ -1,9 +1,8 @@
//===- LoopPass.h - LoopPass class ----------------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/LoopUnrollAnalyzer.h b/include/llvm/Analysis/LoopUnrollAnalyzer.h
index f45bf0b223b8..5f332e3cac16 100644
--- a/include/llvm/Analysis/LoopUnrollAnalyzer.h
+++ b/include/llvm/Analysis/LoopUnrollAnalyzer.h
@@ -1,9 +1,8 @@
//===- llvm/Analysis/LoopUnrollAnalyzer.h - Loop Unroll Analyzer-*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/MemoryBuiltins.h b/include/llvm/Analysis/MemoryBuiltins.h
index 5418128f16ef..49f9e58ffad7 100644
--- a/include/llvm/Analysis/MemoryBuiltins.h
+++ b/include/llvm/Analysis/MemoryBuiltins.h
@@ -1,9 +1,8 @@
//==- llvm/Analysis/MemoryBuiltins.h - Calls to memory builtins --*- C++ -*-==//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -19,6 +18,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/TargetFolder.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstVisitor.h"
@@ -84,6 +84,15 @@ bool isMallocOrCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
bool isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
bool LookThroughBitCast = false);
+/// Tests if a value is a call or invoke to a library function that
+/// reallocates memory (e.g., realloc).
+bool isReallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
+ bool LookThroughBitCast = false);
+
+/// Tests if a function is a call or invoke to a library function that
+/// reallocates memory (e.g., realloc).
+bool isReallocLikeFn(const Function *F, const TargetLibraryInfo *TLI);
+
//===----------------------------------------------------------------------===//
// malloc Call Utility Functions.
//
@@ -135,6 +144,9 @@ inline CallInst *extractCallocCall(Value *I, const TargetLibraryInfo *TLI) {
// free Call Utility Functions.
//
+/// isLibFreeFunction - Returns true if the function is a builtin free()
+bool isLibFreeFunction(const Function *F, const LibFunc TLIFn);
+
/// isFreeCall - Returns non-null if the value is a call to the builtin free()
const CallInst *isFreeCall(const Value *I, const TargetLibraryInfo *TLI);
@@ -178,14 +190,13 @@ bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL,
const TargetLibraryInfo *TLI, ObjectSizeOpts Opts = {});
/// Try to turn a call to \@llvm.objectsize into an integer value of the given
-/// Type. Returns null on failure.
-/// If MustSucceed is true, this function will not return null, and may return
-/// conservative values governed by the second argument of the call to
-/// objectsize.
-ConstantInt *lowerObjectSizeCall(IntrinsicInst *ObjectSize,
- const DataLayout &DL,
- const TargetLibraryInfo *TLI,
- bool MustSucceed);
+/// Type. Returns null on failure. If MustSucceed is true, this function will
+/// not return null, and may return conservative values governed by the second
+/// argument of the call to objectsize.
+Value *lowerObjectSizeCall(IntrinsicInst *ObjectSize, const DataLayout &DL,
+ const TargetLibraryInfo *TLI, bool MustSucceed);
+
+
using SizeOffsetType = std::pair<APInt, APInt>;
@@ -252,7 +263,7 @@ using SizeOffsetEvalType = std::pair<Value *, Value *>;
/// May create code to compute the result at run-time.
class ObjectSizeOffsetEvaluator
: public InstVisitor<ObjectSizeOffsetEvaluator, SizeOffsetEvalType> {
- using BuilderTy = IRBuilder<TargetFolder>;
+ using BuilderTy = IRBuilder<TargetFolder, IRBuilderCallbackInserter>;
using WeakEvalType = std::pair<WeakTrackingVH, WeakTrackingVH>;
using CacheMapTy = DenseMap<const Value *, WeakEvalType>;
using PtrSetTy = SmallPtrSet<const Value *, 8>;
@@ -265,17 +276,18 @@ class ObjectSizeOffsetEvaluator
Value *Zero;
CacheMapTy CacheMap;
PtrSetTy SeenVals;
- bool RoundToAlign;
-
- SizeOffsetEvalType unknown() {
- return std::make_pair(nullptr, nullptr);
- }
+ ObjectSizeOpts EvalOpts;
+ SmallPtrSet<Instruction *, 8> InsertedInstructions;
SizeOffsetEvalType compute_(Value *V);
public:
+ static SizeOffsetEvalType unknown() {
+ return std::make_pair(nullptr, nullptr);
+ }
+
ObjectSizeOffsetEvaluator(const DataLayout &DL, const TargetLibraryInfo *TLI,
- LLVMContext &Context, bool RoundToAlign = false);
+ LLVMContext &Context, ObjectSizeOpts EvalOpts = {});
SizeOffsetEvalType compute(Value *V);
diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h
index 958d4fe4b832..e2669c2fa601 100644
--- a/include/llvm/Analysis/MemoryDependenceAnalysis.h
+++ b/include/llvm/Analysis/MemoryDependenceAnalysis.h
@@ -1,9 +1,8 @@
//===- llvm/Analysis/MemoryDependenceAnalysis.h - Memory Deps ---*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -382,7 +381,8 @@ public:
///
/// See the class comment for more details. It is illegal to call this on
/// non-memory instructions.
- MemDepResult getDependency(Instruction *QueryInst);
+ MemDepResult getDependency(Instruction *QueryInst,
+ OrderedBasicBlock *OBB = nullptr);
/// Perform a full dependency query for the specified call, returning the set
/// of blocks that the value is potentially live across.
@@ -448,14 +448,14 @@ public:
BasicBlock::iterator ScanIt,
BasicBlock *BB,
Instruction *QueryInst = nullptr,
- unsigned *Limit = nullptr);
-
- MemDepResult getSimplePointerDependencyFrom(const MemoryLocation &MemLoc,
- bool isLoad,
- BasicBlock::iterator ScanIt,
- BasicBlock *BB,
- Instruction *QueryInst,
- unsigned *Limit = nullptr);
+ unsigned *Limit = nullptr,
+ OrderedBasicBlock *OBB = nullptr);
+
+ MemDepResult
+ getSimplePointerDependencyFrom(const MemoryLocation &MemLoc, bool isLoad,
+ BasicBlock::iterator ScanIt, BasicBlock *BB,
+ Instruction *QueryInst, unsigned *Limit,
+ OrderedBasicBlock *OBB);
/// This analysis looks for other loads and stores with invariant.group
/// metadata and the same pointer operand. Returns Unknown if it does not
diff --git a/include/llvm/Analysis/MemoryLocation.h b/include/llvm/Analysis/MemoryLocation.h
index fca18c1b5999..7c26353e618b 100644
--- a/include/llvm/Analysis/MemoryLocation.h
+++ b/include/llvm/Analysis/MemoryLocation.h
@@ -1,9 +1,8 @@
//===- MemoryLocation.h - Memory location descriptions ----------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
diff --git a/include/llvm/Analysis/MemorySSA.h b/include/llvm/Analysis/MemorySSA.h
index 17e2d0c73977..b7730be75354 100644
--- a/include/llvm/Analysis/MemorySSA.h
+++ b/include/llvm/Analysis/MemorySSA.h
@@ -1,9 +1,8 @@
//===- MemorySSA.h - Build Memory SSA ---------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -105,6 +104,9 @@
namespace llvm {
+/// Enables memory ssa as a dependency for loop passes.
+extern cl::opt<bool> EnableMSSALoopDependency;
+
class Function;
class Instruction;
class MemoryAccess;
@@ -701,6 +703,11 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(MemoryPhi, MemoryAccess)
class MemorySSA {
public:
MemorySSA(Function &, AliasAnalysis *, DominatorTree *);
+
+ // MemorySSA must remain where it's constructed; Walkers it creates store
+ // pointers to it.
+ MemorySSA(MemorySSA &&) = delete;
+
~MemorySSA();
MemorySSAWalker *getWalker();
@@ -776,9 +783,6 @@ public:
/// all uses, uses appear in the right places). This is used by unit tests.
void verifyMemorySSA() const;
- /// Check clobber sanity for an access.
- void checkClobberSanityAccess(const MemoryAccess *MA) const;
-
/// Used in various insertion functions to specify whether we are talking
/// about the beginning or end of a block.
enum InsertionPlace { Beginning, End };
@@ -793,7 +797,6 @@ protected:
void verifyDomination(Function &F) const;
void verifyOrdering(Function &F) const;
void verifyDominationNumbers(const Function &F) const;
- void verifyClobberSanity(const Function &F) const;
// This is used by the use optimizer and updater.
AccessList *getWritableBlockAccesses(const BasicBlock *BB) const {
@@ -830,13 +833,13 @@ protected:
const MemoryUseOrDef *Template = nullptr);
private:
- class ClobberWalkerBase;
- class CachingWalker;
- class SkipSelfWalker;
+ template <class AliasAnalysisType> class ClobberWalkerBase;
+ template <class AliasAnalysisType> class CachingWalker;
+ template <class AliasAnalysisType> class SkipSelfWalker;
class OptimizeUses;
- CachingWalker *getWalkerImpl();
- void buildMemorySSA();
+ CachingWalker<AliasAnalysis> *getWalkerImpl();
+ void buildMemorySSA(BatchAAResults &BAA);
void optimizeUses();
void prepareForMoveTo(MemoryAccess *, BasicBlock *);
@@ -850,7 +853,8 @@ private:
void markUnreachableAsLiveOnEntry(BasicBlock *BB);
bool dominatesUse(const MemoryAccess *, const MemoryAccess *) const;
MemoryPhi *createMemoryPhi(BasicBlock *BB);
- MemoryUseOrDef *createNewAccess(Instruction *,
+ template <typename AliasAnalysisType>
+ MemoryUseOrDef *createNewAccess(Instruction *, AliasAnalysisType *,
const MemoryUseOrDef *Template = nullptr);
MemoryAccess *findDominatingDef(BasicBlock *, enum InsertionPlace);
void placePHINodes(const SmallPtrSetImpl<BasicBlock *> &);
@@ -886,9 +890,9 @@ private:
mutable DenseMap<const MemoryAccess *, unsigned long> BlockNumbering;
// Memory SSA building info
- std::unique_ptr<ClobberWalkerBase> WalkerBase;
- std::unique_ptr<CachingWalker> Walker;
- std::unique_ptr<SkipSelfWalker> SkipWalker;
+ std::unique_ptr<ClobberWalkerBase<AliasAnalysis>> WalkerBase;
+ std::unique_ptr<CachingWalker<AliasAnalysis>> Walker;
+ std::unique_ptr<SkipSelfWalker<AliasAnalysis>> SkipWalker;
unsigned NextID;
};
@@ -932,6 +936,9 @@ public:
MemorySSA &getMSSA() { return *MSSA.get(); }
std::unique_ptr<MemorySSA> MSSA;
+
+ bool invalidate(Function &F, const PreservedAnalyses &PA,
+ FunctionAnalysisManager::Invalidator &Inv);
};
Result run(Function &F, FunctionAnalysisManager &AM);
@@ -1044,8 +1051,6 @@ public:
/// the walker it uses or returns.
virtual void invalidateInfo(MemoryAccess *) {}
- virtual void verify(const MemorySSA *MSSA) { assert(MSSA == this->MSSA); }
-
protected:
friend class MemorySSA; // For updating MSSA pointer in MemorySSA move
// constructor.
@@ -1101,15 +1106,15 @@ public:
assert(Access && "Tried to access past the end of our iterator");
// Go to the first argument for phis, and the defining access for everything
// else.
- if (MemoryPhi *MP = dyn_cast<MemoryPhi>(Access))
+ if (const MemoryPhi *MP = dyn_cast<MemoryPhi>(Access))
return MP->getIncomingValue(ArgNo);
return cast<MemoryUseOrDef>(Access)->getDefiningAccess();
}
using BaseT::operator++;
- memoryaccess_def_iterator &operator++() {
+ memoryaccess_def_iterator_base &operator++() {
assert(Access && "Hit end of iterator");
- if (MemoryPhi *MP = dyn_cast<MemoryPhi>(Access)) {
+ if (const MemoryPhi *MP = dyn_cast<MemoryPhi>(Access)) {
if (++ArgNo >= MP->getNumIncomingValues()) {
ArgNo = 0;
Access = nullptr;
diff --git a/include/llvm/Analysis/MemorySSAUpdater.h b/include/llvm/Analysis/MemorySSAUpdater.h
index 169d5bd9fa8b..d4d8040c1ff6 100644
--- a/include/llvm/Analysis/MemorySSAUpdater.h
+++ b/include/llvm/Analysis/MemorySSAUpdater.h
@@ -1,9 +1,8 @@
//===- MemorySSAUpdater.h - Memory SSA Updater-------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -32,6 +31,7 @@
#ifndef LLVM_ANALYSIS_MEMORYSSAUPDATER_H
#define LLVM_ANALYSIS_MEMORYSSAUPDATER_H
+#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
@@ -106,7 +106,12 @@ public:
/// Update the MemoryPhi in `To` to have a single incoming edge from `From`,
/// following a CFG change that replaced multiple edges (switch) with a direct
/// branch.
- void removeDuplicatePhiEdgesBetween(BasicBlock *From, BasicBlock *To);
+ void removeDuplicatePhiEdgesBetween(const BasicBlock *From,
+ const BasicBlock *To);
+ /// Update MemorySSA when inserting a unique backedge block for a loop.
+ void updatePhisWhenInsertingUniqueBackedgeBlock(BasicBlock *LoopHeader,
+ BasicBlock *LoopPreheader,
+ BasicBlock *BackedgeBlock);
/// Update MemorySSA after a loop was cloned, given the blocks in RPO order,
/// the exit blocks and a 1:1 mapping of all blocks and instructions
/// cloned. This involves duplicating all defs and uses in the cloned blocks
@@ -222,14 +227,14 @@ public:
/// associated with it is erased from the program. For example, if a store or
/// load is simply erased (not replaced), removeMemoryAccess should be called
/// on the MemoryAccess for that store/load.
- void removeMemoryAccess(MemoryAccess *);
+ void removeMemoryAccess(MemoryAccess *, bool OptimizePhis = false);
/// Remove MemoryAccess for a given instruction, if a MemoryAccess exists.
/// This should be called when an instruction (load/store) is deleted from
/// the program.
- void removeMemoryAccess(const Instruction *I) {
+ void removeMemoryAccess(const Instruction *I, bool OptimizePhis = false) {
if (MemoryAccess *MA = MSSA->getMemoryAccess(I))
- removeMemoryAccess(MA);
+ removeMemoryAccess(MA, OptimizePhis);
}
/// Remove all MemoryAcceses in a set of BasicBlocks about to be deleted.
@@ -239,7 +244,17 @@ public:
/// Deleted blocks still have successor info, but their predecessor edges and
/// Phi nodes may already be updated. Instructions in DeadBlocks should be
/// deleted after this call.
- void removeBlocks(const SmallPtrSetImpl<BasicBlock *> &DeadBlocks);
+ void removeBlocks(const SmallSetVector<BasicBlock *, 8> &DeadBlocks);
+
+ /// Instruction I will be changed to an unreachable. Remove all accesses in
+ /// I's block that follow I (inclusive), and update the Phis in the blocks'
+ /// successors.
+ void changeToUnreachable(const Instruction *I);
+
+ /// Conditional branch BI is changed or replaced with an unconditional branch
+ /// to `To`. Update Phis in BI's successors to remove BI's BB.
+ void changeCondBranchToUnconditionalTo(const BranchInst *BI,
+ const BasicBlock *To);
/// Get handle on MemorySSA.
MemorySSA* getMemorySSA() const { return MSSA; }
@@ -262,6 +277,7 @@ private:
MemoryAccess *recursePhi(MemoryAccess *Phi);
template <class RangeType>
MemoryAccess *tryRemoveTrivialPhi(MemoryPhi *Phi, RangeType &Operands);
+ void tryRemoveTrivialPhis(ArrayRef<WeakVH> UpdatedPHIs);
void fixupDefs(const SmallVectorImpl<WeakVH> &);
// Clone all uses and defs from BB to NewBB given a 1:1 map of all
// instructions and blocks cloned, and a map of MemoryPhi : Definition
@@ -272,8 +288,14 @@ private:
// not necessarily be MemoryPhis themselves, they may be MemoryDefs. As such,
// the map is between MemoryPhis and MemoryAccesses, where the MemoryAccesses
// may be MemoryPhis or MemoryDefs and not MemoryUses.
+ // If CloneWasSimplified = true, the clone was exact. Otherwise, assume that
+ // the clone involved simplifications that may have: (1) turned a MemoryUse
+ // into an instruction that MemorySSA has no representation for, or (2) turned
+ // a MemoryDef into a MemoryUse or an instruction that MemorySSA has no
+ // representation for. No other cases are supported.
void cloneUsesAndDefs(BasicBlock *BB, BasicBlock *NewBB,
- const ValueToValueMapTy &VMap, PhiToDefMap &MPhiMap);
+ const ValueToValueMapTy &VMap, PhiToDefMap &MPhiMap,
+ bool CloneWasSimplified = false);
template <typename Iter>
void privateUpdateExitBlocksForClonedLoop(ArrayRef<BasicBlock *> ExitBlocks,
Iter ValuesBegin, Iter ValuesEnd,
diff --git a/include/llvm/Analysis/ModuleSummaryAnalysis.h b/include/llvm/Analysis/ModuleSummaryAnalysis.h
index 9af7859cb4bf..1572a49e3384 100644
--- a/include/llvm/Analysis/ModuleSummaryAnalysis.h
+++ b/include/llvm/Analysis/ModuleSummaryAnalysis.h
@@ -1,9 +1,8 @@
//===- ModuleSummaryAnalysis.h - Module summary index builder ---*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
diff --git a/include/llvm/Analysis/MustExecute.h b/include/llvm/Analysis/MustExecute.h
index ad3222c17e62..3ef539c89d97 100644
--- a/include/llvm/Analysis/MustExecute.h
+++ b/include/llvm/Analysis/MustExecute.h
@@ -1,9 +1,8 @@
//===- MustExecute.h - Is an instruction known to execute--------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
diff --git a/include/llvm/Analysis/ObjCARCAliasAnalysis.h b/include/llvm/Analysis/ObjCARCAliasAnalysis.h
index 58a67042ea2d..b4f4e5f29768 100644
--- a/include/llvm/Analysis/ObjCARCAliasAnalysis.h
+++ b/include/llvm/Analysis/ObjCARCAliasAnalysis.h
@@ -1,9 +1,8 @@
//===- ObjCARCAliasAnalysis.h - ObjC ARC Alias Analysis ---------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
@@ -53,14 +52,17 @@ public:
return false;
}
- AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB);
- bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal);
+ AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
+ AAQueryInfo &AAQI);
+ bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI,
+ bool OrLocal);
using AAResultBase::getModRefBehavior;
FunctionModRefBehavior getModRefBehavior(const Function *F);
using AAResultBase::getModRefInfo;
- ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc);
+ ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
+ AAQueryInfo &AAQI);
};
/// Analysis pass providing a never-invalidated alias analysis result.
diff --git a/include/llvm/Analysis/ObjCARCAnalysisUtils.h b/include/llvm/Analysis/ObjCARCAnalysisUtils.h
index 1f497fab35da..522abd756c9f 100644
--- a/include/llvm/Analysis/ObjCARCAnalysisUtils.h
+++ b/include/llvm/Analysis/ObjCARCAnalysisUtils.h
@@ -1,9 +1,8 @@
//===- ObjCARCAnalysisUtils.h - ObjC ARC Analysis Utilities -----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
diff --git a/include/llvm/Analysis/ObjCARCInstKind.h b/include/llvm/Analysis/ObjCARCInstKind.h
index 018ea1f851be..dc6093a7b86c 100644
--- a/include/llvm/Analysis/ObjCARCInstKind.h
+++ b/include/llvm/Analysis/ObjCARCInstKind.h
@@ -1,9 +1,8 @@
//===- ObjCARCInstKind.h - ARC instruction equivalence classes --*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -75,6 +74,10 @@ bool IsForwarding(ARCInstKind Class);
/// passed a null pointer.
bool IsNoopOnNull(ARCInstKind Class);
+/// Test if the given class represents instructions which do nothing if
+/// passed a global variable.
+bool IsNoopOnGlobal(ARCInstKind Class);
+
/// Test if the given class represents instructions which are always safe
/// to mark with the "tail" keyword.
bool IsAlwaysTail(ARCInstKind Class);
diff --git a/include/llvm/Analysis/OptimizationRemarkEmitter.h b/include/llvm/Analysis/OptimizationRemarkEmitter.h
index fa838696e2f8..7b8404404ce7 100644
--- a/include/llvm/Analysis/OptimizationRemarkEmitter.h
+++ b/include/llvm/Analysis/OptimizationRemarkEmitter.h
@@ -1,9 +1,8 @@
//===- OptimizationRemarkEmitter.h - Optimization Diagnostic ----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -78,7 +77,7 @@ public:
// remarks enabled. We can't currently check whether remarks are requested
// for the calling pass since that requires actually building the remark.
- if (F->getContext().getDiagnosticsOutputFile() ||
+ if (F->getContext().getRemarkStreamer() ||
F->getContext().getDiagHandlerPtr()->isAnyRemarkEnabled()) {
auto R = RemarkBuilder();
emit((DiagnosticInfoOptimizationBase &)R);
@@ -93,7 +92,7 @@ public:
/// provide more context so that non-trivial false positives can be quickly
/// detected by the user.
bool allowExtraAnalysis(StringRef PassName) const {
- return (F->getContext().getDiagnosticsOutputFile() ||
+ return (F->getContext().getRemarkStreamer() ||
F->getContext().getDiagHandlerPtr()->isAnyRemarkEnabled(PassName));
}
diff --git a/include/llvm/Analysis/OrderedBasicBlock.h b/include/llvm/Analysis/OrderedBasicBlock.h
index 0776aa626005..ae64c0189f5e 100644
--- a/include/llvm/Analysis/OrderedBasicBlock.h
+++ b/include/llvm/Analysis/OrderedBasicBlock.h
@@ -1,9 +1,8 @@
//===- llvm/Analysis/OrderedBasicBlock.h --------------------- -*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -60,6 +59,14 @@ public:
/// only relevant to compare relative instructions positions inside \p BB.
/// Returns false for A == B.
bool dominates(const Instruction *A, const Instruction *B);
+
+ /// Remove \p from the ordering, if it is present.
+ void eraseInstruction(const Instruction *I);
+
+ /// Replace \p Old with \p New in the ordering. \p New is assigned the
+ /// numbering of \p Old, so it must be inserted at the same position in the
+ /// IR.
+ void replaceInstruction(const Instruction *Old, const Instruction *New);
};
} // End llvm namespace
diff --git a/include/llvm/Analysis/OrderedInstructions.h b/include/llvm/Analysis/OrderedInstructions.h
index 7e3850b87c57..967b146b52de 100644
--- a/include/llvm/Analysis/OrderedInstructions.h
+++ b/include/llvm/Analysis/OrderedInstructions.h
@@ -1,9 +1,8 @@
//===- llvm/Transforms/Utils/OrderedInstructions.h -------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/PHITransAddr.h b/include/llvm/Analysis/PHITransAddr.h
index 0a335b6be6c7..54a07f053478 100644
--- a/include/llvm/Analysis/PHITransAddr.h
+++ b/include/llvm/Analysis/PHITransAddr.h
@@ -1,9 +1,8 @@
//===- PHITransAddr.h - PHI Translation for Addresses -----------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/Passes.h b/include/llvm/Analysis/Passes.h
index 081dd5000835..d9c97dff8c6e 100644
--- a/include/llvm/Analysis/Passes.h
+++ b/include/llvm/Analysis/Passes.h
@@ -1,9 +1,8 @@
//===-- llvm/Analysis/Passes.h - Constructors for analyses ------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/PhiValues.h b/include/llvm/Analysis/PhiValues.h
index 76204ac1bc6c..124fa2191694 100644
--- a/include/llvm/Analysis/PhiValues.h
+++ b/include/llvm/Analysis/PhiValues.h
@@ -1,9 +1,8 @@
//===- PhiValues.h - Phi Value Analysis -------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/PostDominators.h b/include/llvm/Analysis/PostDominators.h
index f2dc8d135d71..87d2e0318d0a 100644
--- a/include/llvm/Analysis/PostDominators.h
+++ b/include/llvm/Analysis/PostDominators.h
@@ -1,9 +1,8 @@
//=- llvm/Analysis/PostDominators.h - Post Dominator Calculation --*- C++ -*-=//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/ProfileSummaryInfo.h b/include/llvm/Analysis/ProfileSummaryInfo.h
index 3aef4be72d71..f309d344b8d1 100644
--- a/include/llvm/Analysis/ProfileSummaryInfo.h
+++ b/include/llvm/Analysis/ProfileSummaryInfo.h
@@ -1,9 +1,8 @@
//===- llvm/Analysis/ProfileSummaryInfo.h - profile summary ---*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -74,6 +73,12 @@ public:
Summary->getKind() == ProfileSummary::PSK_Instr;
}
+ /// Returns true if module \c M has context sensitive instrumentation profile.
+ bool hasCSInstrumentationProfile() {
+ return hasProfileSummary() &&
+ Summary->getKind() == ProfileSummary::PSK_CSInstr;
+ }
+
/// Handle the invalidation of this information.
///
/// When used as a result of \c ProfileSummaryAnalysis this method will be
@@ -87,7 +92,8 @@ public:
/// Returns the profile count for \p CallInst.
Optional<uint64_t> getProfileCount(const Instruction *CallInst,
- BlockFrequencyInfo *BFI);
+ BlockFrequencyInfo *BFI,
+ bool AllowSynthetic = false);
/// Returns true if the working set size of the code is considered huge.
bool hasHugeWorkingSetSize();
/// Returns true if \p F has hot function entry.
diff --git a/include/llvm/Analysis/PtrUseVisitor.h b/include/llvm/Analysis/PtrUseVisitor.h
index b34b25c75040..fbf04c841d30 100644
--- a/include/llvm/Analysis/PtrUseVisitor.h
+++ b/include/llvm/Analysis/PtrUseVisitor.h
@@ -1,9 +1,8 @@
//===- PtrUseVisitor.h - InstVisitors over a pointers uses ------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -257,6 +256,10 @@ protected:
enqueueUsers(BC);
}
+ void visitAddrSpaceCastInst(AddrSpaceCastInst &ASC) {
+ enqueueUsers(ASC);
+ }
+
void visitPtrToIntInst(PtrToIntInst &I) {
PI.setEscaped(&I);
}
diff --git a/include/llvm/Analysis/RegionInfo.h b/include/llvm/Analysis/RegionInfo.h
index 27f6cc197927..8bcc3e851200 100644
--- a/include/llvm/Analysis/RegionInfo.h
+++ b/include/llvm/Analysis/RegionInfo.h
@@ -1,9 +1,8 @@
//===- RegionInfo.h - SESE region analysis ----------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/RegionInfoImpl.h b/include/llvm/Analysis/RegionInfoImpl.h
index 5904214aa925..c59c09dd2095 100644
--- a/include/llvm/Analysis/RegionInfoImpl.h
+++ b/include/llvm/Analysis/RegionInfoImpl.h
@@ -1,9 +1,8 @@
//===- RegionInfoImpl.h - SESE region detection analysis --------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// Detects single entry single exit regions in the control flow graph.
diff --git a/include/llvm/Analysis/RegionIterator.h b/include/llvm/Analysis/RegionIterator.h
index 4fd92fcde20b..72bc5bbcb506 100644
--- a/include/llvm/Analysis/RegionIterator.h
+++ b/include/llvm/Analysis/RegionIterator.h
@@ -1,9 +1,8 @@
//===- RegionIterator.h - Iterators to iteratate over Regions ---*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// This file defines the iterators to iterate over the elements of a Region.
diff --git a/include/llvm/Analysis/RegionPass.h b/include/llvm/Analysis/RegionPass.h
index b3da91c89cbd..5b1864a37629 100644
--- a/include/llvm/Analysis/RegionPass.h
+++ b/include/llvm/Analysis/RegionPass.h
@@ -1,9 +1,8 @@
//===- RegionPass.h - RegionPass class --------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/RegionPrinter.h b/include/llvm/Analysis/RegionPrinter.h
index e132eaea5674..154ac35c486a 100644
--- a/include/llvm/Analysis/RegionPrinter.h
+++ b/include/llvm/Analysis/RegionPrinter.h
@@ -1,9 +1,8 @@
//===-- RegionPrinter.h - Region printer external interface -----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h
index 8f4200b07e5c..0bd98ef37e7a 100644
--- a/include/llvm/Analysis/ScalarEvolution.h
+++ b/include/llvm/Analysis/ScalarEvolution.h
@@ -1,9 +1,8 @@
//===- llvm/Analysis/ScalarEvolution.h - Scalar Evolution -------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -85,6 +84,9 @@ class SCEV : public FoldingSetNode {
const unsigned short SCEVType;
protected:
+ // Estimated complexity of this node's expression tree size.
+ const unsigned short ExpressionSize;
+
/// This field is initialized to zero and may be used in subclasses to store
/// miscellaneous information.
unsigned short SubclassData = 0;
@@ -116,8 +118,9 @@ public:
NoWrapMask = (1 << 3) - 1
};
- explicit SCEV(const FoldingSetNodeIDRef ID, unsigned SCEVTy)
- : FastID(ID), SCEVType(SCEVTy) {}
+ explicit SCEV(const FoldingSetNodeIDRef ID, unsigned SCEVTy,
+ unsigned short ExpressionSize)
+ : FastID(ID), SCEVType(SCEVTy), ExpressionSize(ExpressionSize) {}
SCEV(const SCEV &) = delete;
SCEV &operator=(const SCEV &) = delete;
@@ -138,6 +141,19 @@ public:
/// Return true if the specified scev is negated, but not a constant.
bool isNonConstantNegative() const;
+ // Returns estimated size of the mathematical expression represented by this
+ // SCEV. The rules of its calculation are following:
+ // 1) Size of a SCEV without operands (like constants and SCEVUnknown) is 1;
+ // 2) Size SCEV with operands Op1, Op2, ..., OpN is calculated by formula:
+ // (1 + Size(Op1) + ... + Size(OpN)).
+ // This value gives us an estimation of time we need to traverse through this
+ // SCEV and all its operands recursively. We may use it to avoid performing
+ // heavy transformations on SCEVs of excessive size for sake of saving the
+ // compilation time.
+ unsigned short getExpressionSize() const {
+ return ExpressionSize;
+ }
+
/// Print out the internal representation of this scalar to the specified
/// stream. This should really only be used for debugging purposes.
void print(raw_ostream &OS) const;
@@ -521,7 +537,7 @@ public:
const SCEV *getConstant(ConstantInt *V);
const SCEV *getConstant(const APInt &Val);
const SCEV *getConstant(Type *Ty, uint64_t V, bool isSigned = false);
- const SCEV *getTruncateExpr(const SCEV *Op, Type *Ty);
+ const SCEV *getTruncateExpr(const SCEV *Op, Type *Ty, unsigned Depth = 0);
const SCEV *getZeroExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth = 0);
const SCEV *getSignExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth = 0);
const SCEV *getAnyExtendExpr(const SCEV *Op, Type *Ty);
@@ -582,6 +598,8 @@ public:
/// \p IndexExprs The expressions for the indices.
const SCEV *getGEPExpr(GEPOperator *GEP,
const SmallVectorImpl<const SCEV *> &IndexExprs);
+ const SCEV *getMinMaxExpr(unsigned Kind,
+ SmallVectorImpl<const SCEV *> &Operands);
const SCEV *getSMaxExpr(const SCEV *LHS, const SCEV *RHS);
const SCEV *getSMaxExpr(SmallVectorImpl<const SCEV *> &Operands);
const SCEV *getUMaxExpr(const SCEV *LHS, const SCEV *RHS);
@@ -619,11 +637,13 @@ public:
/// Return a SCEV corresponding to a conversion of the input value to the
/// specified type. If the type must be extended, it is zero extended.
- const SCEV *getTruncateOrZeroExtend(const SCEV *V, Type *Ty);
+ const SCEV *getTruncateOrZeroExtend(const SCEV *V, Type *Ty,
+ unsigned Depth = 0);
/// Return a SCEV corresponding to a conversion of the input value to the
/// specified type. If the type must be extended, it is sign extended.
- const SCEV *getTruncateOrSignExtend(const SCEV *V, Type *Ty);
+ const SCEV *getTruncateOrSignExtend(const SCEV *V, Type *Ty,
+ unsigned Depth = 0);
/// Return a SCEV corresponding to a conversion of the input value to the
/// specified type. If the type must be extended, it is zero extended. The
@@ -726,9 +746,12 @@ public:
unsigned getSmallConstantTripMultiple(const Loop *L,
BasicBlock *ExitingBlock);
- /// Get the expression for the number of loop iterations for which this loop
- /// is guaranteed not to exit via ExitingBlock. Otherwise return
- /// SCEVCouldNotCompute.
+ /// Return the number of times the backedge executes before the given exit
+ /// would be taken; if not exactly computable, return SCEVCouldNotCompute.
+ /// For a single exit loop, this value is equivelent to the result of
+ /// getBackedgeTakenCount. The loop is guaranteed to exit (via *some* exit)
+ /// before the backedge is executed (ExitCount + 1) times. Note that there
+ /// is no guarantee about *which* exit is taken on the exiting iteration.
const SCEV *getExitCount(const Loop *L, BasicBlock *ExitingBlock);
/// If the specified loop has a predictable backedge-taken count, return it,
@@ -764,6 +787,13 @@ public:
/// backedge-taken count.
bool hasLoopInvariantBackedgeTakenCount(const Loop *L);
+ // This method should be called by the client when it made any change that
+ // would invalidate SCEV's answers, and the client wants to remove all loop
+ // information held internally by ScalarEvolution. This is intended to be used
+ // when the alternative to forget a loop is too expensive (i.e. large loop
+ // bodies).
+ void forgetAllLoops();
+
/// This method should be called by the client when it has changed a loop in
/// a way that may effect ScalarEvolution's ability to compute a trip count,
/// or if the loop is deleted. This call is potentially expensive for large
@@ -1273,7 +1303,7 @@ private:
using EdgeExitInfo = std::pair<BasicBlock *, ExitLimit>;
/// Initialize BackedgeTakenInfo from a list of exact exit counts.
- BackedgeTakenInfo(SmallVectorImpl<EdgeExitInfo> &&ExitCounts, bool Complete,
+ BackedgeTakenInfo(ArrayRef<EdgeExitInfo> ExitCounts, bool Complete,
const SCEV *MaxCount, bool MaxOrZero);
/// Test whether this BackedgeTakenInfo contains any computed information,
@@ -1826,15 +1856,15 @@ private:
bool NoWrap);
/// Get add expr already created or create a new one.
- const SCEV *getOrCreateAddExpr(SmallVectorImpl<const SCEV *> &Ops,
+ const SCEV *getOrCreateAddExpr(ArrayRef<const SCEV *> Ops,
SCEV::NoWrapFlags Flags);
/// Get mul expr already created or create a new one.
- const SCEV *getOrCreateMulExpr(SmallVectorImpl<const SCEV *> &Ops,
+ const SCEV *getOrCreateMulExpr(ArrayRef<const SCEV *> Ops,
SCEV::NoWrapFlags Flags);
// Get addrec expr already created or create a new one.
- const SCEV *getOrCreateAddRecExpr(SmallVectorImpl<const SCEV *> &Ops,
+ const SCEV *getOrCreateAddRecExpr(ArrayRef<const SCEV *> Ops,
const Loop *L, SCEV::NoWrapFlags Flags);
/// Return x if \p Val is f(x) where f is a 1-1 function.
@@ -1853,6 +1883,16 @@ private:
/// Assign A and B to LHS and RHS, respectively.
bool matchURem(const SCEV *Expr, const SCEV *&LHS, const SCEV *&RHS);
+ /// Look for a SCEV expression with type `SCEVType` and operands `Ops` in
+ /// `UniqueSCEVs`.
+ ///
+ /// The first component of the returned tuple is the SCEV if found and null
+ /// otherwise. The second component is the `FoldingSetNodeID` that was
+ /// constructed to look up the SCEV and the third component is the insertion
+ /// point.
+ std::tuple<const SCEV *, FoldingSetNodeID, void *>
+ findExistingSCEVInCache(int SCEVType, ArrayRef<const SCEV *> Ops);
+
FoldingSet<SCEV> UniqueSCEVs;
FoldingSet<SCEVPredicate> UniquePreds;
BumpPtrAllocator SCEVAllocator;
diff --git a/include/llvm/Analysis/ScalarEvolutionAliasAnalysis.h b/include/llvm/Analysis/ScalarEvolutionAliasAnalysis.h
index 329be51e5eac..98d53237d4a0 100644
--- a/include/llvm/Analysis/ScalarEvolutionAliasAnalysis.h
+++ b/include/llvm/Analysis/ScalarEvolutionAliasAnalysis.h
@@ -1,9 +1,8 @@
//===- ScalarEvolutionAliasAnalysis.h - SCEV-based AA -----------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
@@ -31,7 +30,8 @@ public:
explicit SCEVAAResult(ScalarEvolution &SE) : AAResultBase(), SE(SE) {}
SCEVAAResult(SCEVAAResult &&Arg) : AAResultBase(std::move(Arg)), SE(Arg.SE) {}
- AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB);
+ AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
+ AAQueryInfo &AAQI);
private:
Value *GetBaseValue(const SCEV *S);
diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h
index 58d42680d6bc..a519f93216b3 100644
--- a/include/llvm/Analysis/ScalarEvolutionExpander.h
+++ b/include/llvm/Analysis/ScalarEvolutionExpander.h
@@ -1,9 +1,8 @@
//===---- llvm/Analysis/ScalarEvolutionExpander.h - SCEV Exprs --*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -316,8 +315,10 @@ namespace llvm {
SmallPtrSetImpl<const SCEV *> &Processed);
/// Insert the specified binary operator, doing a small amount of work to
- /// avoid inserting an obviously redundant operation.
- Value *InsertBinop(Instruction::BinaryOps Opcode, Value *LHS, Value *RHS);
+ /// avoid inserting an obviously redundant operation, and hoisting to an
+ /// outer loop when the opportunity is there and it is safe.
+ Value *InsertBinop(Instruction::BinaryOps Opcode, Value *LHS, Value *RHS,
+ SCEV::NoWrapFlags Flags, bool IsSafeToHoist);
/// Arrange for there to be a cast of V to Ty at IP, reusing an existing
/// cast if a suitable one exists, moving an existing cast if a suitable one
@@ -368,6 +369,10 @@ namespace llvm {
Value *visitUMaxExpr(const SCEVUMaxExpr *S);
+ Value *visitSMinExpr(const SCEVSMinExpr *S);
+
+ Value *visitUMinExpr(const SCEVUMinExpr *S);
+
Value *visitUnknown(const SCEVUnknown *S) {
return S->getValue();
}
diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h
index 42e76094eb2b..d008af7b7e6f 100644
--- a/include/llvm/Analysis/ScalarEvolutionExpressions.h
+++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h
@@ -1,9 +1,8 @@
//===- llvm/Analysis/ScalarEvolutionExpressions.h - SCEV Exprs --*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -40,7 +39,7 @@ class Type;
// These should be ordered in terms of increasing complexity to make the
// folders simpler.
scConstant, scTruncate, scZeroExtend, scSignExtend, scAddExpr, scMulExpr,
- scUDivExpr, scAddRecExpr, scUMaxExpr, scSMaxExpr,
+ scUDivExpr, scAddRecExpr, scUMaxExpr, scSMaxExpr, scUMinExpr, scSMinExpr,
scUnknown, scCouldNotCompute
};
@@ -51,7 +50,7 @@ class Type;
ConstantInt *V;
SCEVConstant(const FoldingSetNodeIDRef ID, ConstantInt *v) :
- SCEV(ID, scConstant), V(v) {}
+ SCEV(ID, scConstant, 1), V(v) {}
public:
ConstantInt *getValue() const { return V; }
@@ -65,6 +64,13 @@ class Type;
}
};
+ static unsigned short computeExpressionSize(ArrayRef<const SCEV *> Args) {
+ APInt Size(16, 1);
+ for (auto *Arg : Args)
+ Size = Size.uadd_sat(APInt(16, Arg->getExpressionSize()));
+ return (unsigned short)Size.getZExtValue();
+ }
+
/// This is the base class for unary cast operator classes.
class SCEVCastExpr : public SCEV {
protected:
@@ -142,9 +148,10 @@ class Type;
const SCEV *const *Operands;
size_t NumOperands;
- SCEVNAryExpr(const FoldingSetNodeIDRef ID,
- enum SCEVTypes T, const SCEV *const *O, size_t N)
- : SCEV(ID, T), Operands(O), NumOperands(N) {}
+ SCEVNAryExpr(const FoldingSetNodeIDRef ID, enum SCEVTypes T,
+ const SCEV *const *O, size_t N)
+ : SCEV(ID, T, computeExpressionSize(makeArrayRef(O, N))), Operands(O),
+ NumOperands(N) {}
public:
size_t getNumOperands() const { return NumOperands; }
@@ -183,10 +190,9 @@ class Type;
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const SCEV *S) {
- return S->getSCEVType() == scAddExpr ||
- S->getSCEVType() == scMulExpr ||
- S->getSCEVType() == scSMaxExpr ||
- S->getSCEVType() == scUMaxExpr ||
+ return S->getSCEVType() == scAddExpr || S->getSCEVType() == scMulExpr ||
+ S->getSCEVType() == scSMaxExpr || S->getSCEVType() == scUMaxExpr ||
+ S->getSCEVType() == scSMinExpr || S->getSCEVType() == scUMinExpr ||
S->getSCEVType() == scAddRecExpr;
}
};
@@ -201,10 +207,9 @@ class Type;
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const SCEV *S) {
- return S->getSCEVType() == scAddExpr ||
- S->getSCEVType() == scMulExpr ||
- S->getSCEVType() == scSMaxExpr ||
- S->getSCEVType() == scUMaxExpr;
+ return S->getSCEVType() == scAddExpr || S->getSCEVType() == scMulExpr ||
+ S->getSCEVType() == scSMaxExpr || S->getSCEVType() == scUMaxExpr ||
+ S->getSCEVType() == scSMinExpr || S->getSCEVType() == scUMinExpr;
}
/// Set flags for a non-recurrence without clearing previously set flags.
@@ -258,7 +263,8 @@ class Type;
const SCEV *RHS;
SCEVUDivExpr(const FoldingSetNodeIDRef ID, const SCEV *lhs, const SCEV *rhs)
- : SCEV(ID, scUDivExpr), LHS(lhs), RHS(rhs) {}
+ : SCEV(ID, scUDivExpr, computeExpressionSize({lhs, rhs})), LHS(lhs),
+ RHS(rhs) {}
public:
const SCEV *getLHS() const { return LHS; }
@@ -358,18 +364,54 @@ class Type;
}
};
- /// This class represents a signed maximum selection.
- class SCEVSMaxExpr : public SCEVCommutativeExpr {
+ /// This node is the base class min/max selections.
+ class SCEVMinMaxExpr : public SCEVCommutativeExpr {
friend class ScalarEvolution;
- SCEVSMaxExpr(const FoldingSetNodeIDRef ID,
- const SCEV *const *O, size_t N)
- : SCEVCommutativeExpr(ID, scSMaxExpr, O, N) {
- // Max never overflows.
+ static bool isMinMaxType(enum SCEVTypes T) {
+ return T == scSMaxExpr || T == scUMaxExpr || T == scSMinExpr ||
+ T == scUMinExpr;
+ }
+
+ protected:
+ /// Note: Constructing subclasses via this constructor is allowed
+ SCEVMinMaxExpr(const FoldingSetNodeIDRef ID, enum SCEVTypes T,
+ const SCEV *const *O, size_t N)
+ : SCEVCommutativeExpr(ID, T, O, N) {
+ assert(isMinMaxType(T));
+ // Min and max never overflow
setNoWrapFlags((NoWrapFlags)(FlagNUW | FlagNSW));
}
public:
+ static bool classof(const SCEV *S) {
+ return isMinMaxType(static_cast<SCEVTypes>(S->getSCEVType()));
+ }
+
+ static enum SCEVTypes negate(enum SCEVTypes T) {
+ switch (T) {
+ case scSMaxExpr:
+ return scSMinExpr;
+ case scSMinExpr:
+ return scSMaxExpr;
+ case scUMaxExpr:
+ return scUMinExpr;
+ case scUMinExpr:
+ return scUMaxExpr;
+ default:
+ llvm_unreachable("Not a min or max SCEV type!");
+ }
+ }
+ };
+
+ /// This class represents a signed maximum selection.
+ class SCEVSMaxExpr : public SCEVMinMaxExpr {
+ friend class ScalarEvolution;
+
+ SCEVSMaxExpr(const FoldingSetNodeIDRef ID, const SCEV *const *O, size_t N)
+ : SCEVMinMaxExpr(ID, scSMaxExpr, O, N) {}
+
+ public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const SCEV *S) {
return S->getSCEVType() == scSMaxExpr;
@@ -377,15 +419,11 @@ class Type;
};
/// This class represents an unsigned maximum selection.
- class SCEVUMaxExpr : public SCEVCommutativeExpr {
+ class SCEVUMaxExpr : public SCEVMinMaxExpr {
friend class ScalarEvolution;
- SCEVUMaxExpr(const FoldingSetNodeIDRef ID,
- const SCEV *const *O, size_t N)
- : SCEVCommutativeExpr(ID, scUMaxExpr, O, N) {
- // Max never overflows.
- setNoWrapFlags((NoWrapFlags)(FlagNUW | FlagNSW));
- }
+ SCEVUMaxExpr(const FoldingSetNodeIDRef ID, const SCEV *const *O, size_t N)
+ : SCEVMinMaxExpr(ID, scUMaxExpr, O, N) {}
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
@@ -394,6 +432,34 @@ class Type;
}
};
+ /// This class represents a signed minimum selection.
+ class SCEVSMinExpr : public SCEVMinMaxExpr {
+ friend class ScalarEvolution;
+
+ SCEVSMinExpr(const FoldingSetNodeIDRef ID, const SCEV *const *O, size_t N)
+ : SCEVMinMaxExpr(ID, scSMinExpr, O, N) {}
+
+ public:
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static bool classof(const SCEV *S) {
+ return S->getSCEVType() == scSMinExpr;
+ }
+ };
+
+ /// This class represents an unsigned minimum selection.
+ class SCEVUMinExpr : public SCEVMinMaxExpr {
+ friend class ScalarEvolution;
+
+ SCEVUMinExpr(const FoldingSetNodeIDRef ID, const SCEV *const *O, size_t N)
+ : SCEVMinMaxExpr(ID, scUMinExpr, O, N) {}
+
+ public:
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static bool classof(const SCEV *S) {
+ return S->getSCEVType() == scUMinExpr;
+ }
+ };
+
/// This means that we are dealing with an entirely unknown SCEV
/// value, and only represent it as its LLVM Value. This is the
/// "bottom" value for the analysis.
@@ -411,7 +477,7 @@ class Type;
SCEVUnknown(const FoldingSetNodeIDRef ID, Value *V,
ScalarEvolution *se, SCEVUnknown *next) :
- SCEV(ID, scUnknown), CallbackVH(V), SE(se), Next(next) {}
+ SCEV(ID, scUnknown, 1), CallbackVH(V), SE(se), Next(next) {}
// Implement CallbackVH.
void deleted() override;
@@ -466,6 +532,10 @@ class Type;
return ((SC*)this)->visitSMaxExpr((const SCEVSMaxExpr*)S);
case scUMaxExpr:
return ((SC*)this)->visitUMaxExpr((const SCEVUMaxExpr*)S);
+ case scSMinExpr:
+ return ((SC *)this)->visitSMinExpr((const SCEVSMinExpr *)S);
+ case scUMinExpr:
+ return ((SC *)this)->visitUMinExpr((const SCEVUMinExpr *)S);
case scUnknown:
return ((SC*)this)->visitUnknown((const SCEVUnknown*)S);
case scCouldNotCompute:
@@ -519,6 +589,8 @@ class Type;
case scMulExpr:
case scSMaxExpr:
case scUMaxExpr:
+ case scSMinExpr:
+ case scUMinExpr:
case scAddRecExpr:
for (const auto *Op : cast<SCEVNAryExpr>(S)->operands())
push(Op);
@@ -681,6 +753,26 @@ class Type;
return !Changed ? Expr : SE.getUMaxExpr(Operands);
}
+ const SCEV *visitSMinExpr(const SCEVSMinExpr *Expr) {
+ SmallVector<const SCEV *, 2> Operands;
+ bool Changed = false;
+ for (auto *Op : Expr->operands()) {
+ Operands.push_back(((SC *)this)->visit(Op));
+ Changed |= Op != Operands.back();
+ }
+ return !Changed ? Expr : SE.getSMinExpr(Operands);
+ }
+
+ const SCEV *visitUMinExpr(const SCEVUMinExpr *Expr) {
+ SmallVector<const SCEV *, 2> Operands;
+ bool Changed = false;
+ for (auto *Op : Expr->operands()) {
+ Operands.push_back(((SC *)this)->visit(Op));
+ Changed |= Op != Operands.back();
+ }
+ return !Changed ? Expr : SE.getUMinExpr(Operands);
+ }
+
const SCEV *visitUnknown(const SCEVUnknown *Expr) {
return Expr;
}
diff --git a/include/llvm/Analysis/ScalarEvolutionNormalization.h b/include/llvm/Analysis/ScalarEvolutionNormalization.h
index 51c92121c8f0..1a05594a46ec 100644
--- a/include/llvm/Analysis/ScalarEvolutionNormalization.h
+++ b/include/llvm/Analysis/ScalarEvolutionNormalization.h
@@ -1,9 +1,8 @@
//===- llvm/Analysis/ScalarEvolutionNormalization.h - See below -*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/ScopedNoAliasAA.h b/include/llvm/Analysis/ScopedNoAliasAA.h
index 1356c6e9198a..dae733bd2015 100644
--- a/include/llvm/Analysis/ScopedNoAliasAA.h
+++ b/include/llvm/Analysis/ScopedNoAliasAA.h
@@ -1,9 +1,8 @@
//===- ScopedNoAliasAA.h - Scoped No-Alias Alias Analysis -------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -40,9 +39,12 @@ public:
return false;
}
- AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB);
- ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc);
- ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2);
+ AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
+ AAQueryInfo &AAQI);
+ ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
+ AAQueryInfo &AAQI);
+ ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2,
+ AAQueryInfo &AAQI);
private:
bool mayAliasInScopes(const MDNode *Scopes, const MDNode *NoAlias) const;
diff --git a/include/llvm/Analysis/SparsePropagation.h b/include/llvm/Analysis/SparsePropagation.h
index 02a2e64268b7..fac92e4a25a4 100644
--- a/include/llvm/Analysis/SparsePropagation.h
+++ b/include/llvm/Analysis/SparsePropagation.h
@@ -1,9 +1,8 @@
//===- SparsePropagation.h - Sparse Conditional Property Propagation ------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -330,12 +329,8 @@ void SparseSolver<LatticeKey, LatticeVal, KeyInfo>::getFeasibleSuccessors(
return;
}
- if (TI.isExceptionalTerminator()) {
- Succs.assign(Succs.size(), true);
- return;
- }
-
- if (isa<IndirectBrInst>(TI)) {
+ if (TI.isExceptionalTerminator() ||
+ TI.isIndirectTerminator()) {
Succs.assign(Succs.size(), true);
return;
}
diff --git a/include/llvm/Analysis/StackSafetyAnalysis.h b/include/llvm/Analysis/StackSafetyAnalysis.h
index 8a151650a34c..f9d8b08ac142 100644
--- a/include/llvm/Analysis/StackSafetyAnalysis.h
+++ b/include/llvm/Analysis/StackSafetyAnalysis.h
@@ -1,9 +1,8 @@
//===- StackSafetyAnalysis.h - Stack memory safety analysis -----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/SyncDependenceAnalysis.h b/include/llvm/Analysis/SyncDependenceAnalysis.h
index df693d9d8e8c..099403b47757 100644
--- a/include/llvm/Analysis/SyncDependenceAnalysis.h
+++ b/include/llvm/Analysis/SyncDependenceAnalysis.h
@@ -1,9 +1,8 @@
//===- SyncDependenceAnalysis.h - Divergent Branch Dependence -*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/SyntheticCountsUtils.h b/include/llvm/Analysis/SyntheticCountsUtils.h
index db80bef001e2..b9b4c98bfc35 100644
--- a/include/llvm/Analysis/SyntheticCountsUtils.h
+++ b/include/llvm/Analysis/SyntheticCountsUtils.h
@@ -1,9 +1,8 @@
//===- SyntheticCountsUtils.h - utilities for count propagation--*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/TargetFolder.h b/include/llvm/Analysis/TargetFolder.h
index ae75d3773362..7ab6562be440 100644
--- a/include/llvm/Analysis/TargetFolder.h
+++ b/include/llvm/Analysis/TargetFolder.h
@@ -1,9 +1,8 @@
//====- TargetFolder.h - Constant folding helper ---------------*- C++ -*-====//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -125,6 +124,10 @@ public:
return Fold(ConstantExpr::getNot(C));
}
+ Constant *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const {
+ return Fold(ConstantExpr::get(Opc, C));
+ }
+
//===--------------------------------------------------------------------===//
// Memory Instructions
//===--------------------------------------------------------------------===//
diff --git a/include/llvm/Analysis/TargetLibraryInfo.def b/include/llvm/Analysis/TargetLibraryInfo.def
index 518a85ee1a01..afed404f04c0 100644
--- a/include/llvm/Analysis/TargetLibraryInfo.def
+++ b/include/llvm/Analysis/TargetLibraryInfo.def
@@ -1,9 +1,8 @@
//===-- TargetLibraryInfo.def - Library information -------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -12,6 +11,15 @@
// Which is defined depends on whether TLI_DEFINE_ENUM is defined or
// TLI_DEFINE_STRING is defined. Only one should be defined at a time.
+// NOTE: The nofree attribute is added to Libfuncs which are not
+// listed as free or realloc functions in MemoryBuiltins.cpp
+//
+// When adding a function which frees memory include the LibFunc
+// in lib/Analysis/MemoryBuiltins.cpp "isLibFreeFunction".
+//
+// When adding a LibFunc which reallocates memory include the LibFunc
+// in lib/Analysis/MemoryBuiltins.cpp "AllocationFnData[]".
+
#if !(defined(TLI_DEFINE_ENUM) || defined(TLI_DEFINE_STRING))
#error "Must define TLI_DEFINE_ENUM or TLI_DEFINE_STRING for TLI .def."
#elif defined(TLI_DEFINE_ENUM) && defined(TLI_DEFINE_STRING)
@@ -330,6 +338,10 @@ TLI_DEFINE_STRING_INTERNAL("__logf_finite")
/// long double __logl_finite(long double x);
TLI_DEFINE_ENUM_INTERNAL(logl_finite)
TLI_DEFINE_STRING_INTERNAL("__logl_finite")
+/// void *__memccpy_chk(void *dst, const void *src, int c, size_t n,
+/// size_t dstsize)
+TLI_DEFINE_ENUM_INTERNAL(memccpy_chk)
+TLI_DEFINE_STRING_INTERNAL("__memccpy_chk")
/// void *__memcpy_chk(void *s1, const void *s2, size_t n, size_t s1size);
TLI_DEFINE_ENUM_INTERNAL(memcpy_chk)
TLI_DEFINE_STRING_INTERNAL("__memcpy_chk")
@@ -373,6 +385,23 @@ TLI_DEFINE_STRING_INTERNAL("__sinpi")
/// float __sinpif(float x);
TLI_DEFINE_ENUM_INTERNAL(sinpif)
TLI_DEFINE_STRING_INTERNAL("__sinpif")
+/// int __small_fprintf(FILE *stream, const char *format, ...);
+TLI_DEFINE_ENUM_INTERNAL(small_fprintf)
+TLI_DEFINE_STRING_INTERNAL("__small_fprintf")
+/// int __small_printf(const char *format, ...);
+TLI_DEFINE_ENUM_INTERNAL(small_printf)
+TLI_DEFINE_STRING_INTERNAL("__small_printf")
+/// int __small_sprintf(char *str, const char *format, ...);
+TLI_DEFINE_ENUM_INTERNAL(small_sprintf)
+TLI_DEFINE_STRING_INTERNAL("__small_sprintf")
+/// int __snprintf_chk(char *s, size_t n, int flags, size_t slen,
+/// const char *format, ...);
+TLI_DEFINE_ENUM_INTERNAL(snprintf_chk)
+TLI_DEFINE_STRING_INTERNAL("__snprintf_chk")
+/// int __sprintf_chk(char *str, int flags, size_t str_len,
+/// const char *format, ...);
+TLI_DEFINE_ENUM_INTERNAL(sprintf_chk)
+TLI_DEFINE_STRING_INTERNAL("__sprintf_chk")
/// double __sqrt_finite(double x);
TLI_DEFINE_ENUM_INTERNAL(sqrt_finite)
TLI_DEFINE_STRING_INTERNAL("__sqrt_finite")
@@ -388,12 +417,26 @@ TLI_DEFINE_STRING_INTERNAL("__stpcpy_chk")
/// char *__stpncpy_chk(char *s1, const char *s2, size_t n, size_t s1size);
TLI_DEFINE_ENUM_INTERNAL(stpncpy_chk)
TLI_DEFINE_STRING_INTERNAL("__stpncpy_chk")
+/// char *__strcat_chk(char *s1, const char *s2, size_t s1size);
+TLI_DEFINE_ENUM_INTERNAL(strcat_chk)
+TLI_DEFINE_STRING_INTERNAL("__strcat_chk")
/// char *__strcpy_chk(char *s1, const char *s2, size_t s1size);
TLI_DEFINE_ENUM_INTERNAL(strcpy_chk)
TLI_DEFINE_STRING_INTERNAL("__strcpy_chk")
/// char * __strdup(const char *s);
TLI_DEFINE_ENUM_INTERNAL(dunder_strdup)
TLI_DEFINE_STRING_INTERNAL("__strdup")
+/// size_t __strlcat_chk(char *dst, const char *src, size_t size,
+/// size_t dstsize);
+TLI_DEFINE_ENUM_INTERNAL(strlcat_chk)
+TLI_DEFINE_STRING_INTERNAL("__strlcat_chk")
+/// size_t __strlcpy_chk(char *dst, const char *src, size_t size,
+/// size_t dstsize);
+TLI_DEFINE_ENUM_INTERNAL(strlcpy_chk)
+TLI_DEFINE_STRING_INTERNAL("__strlcpy_chk")
+/// char *strncat_chk(char *s1, const char *s2, size_t n, size_t s1size);
+TLI_DEFINE_ENUM_INTERNAL(strncat_chk)
+TLI_DEFINE_STRING_INTERNAL("__strncat_chk")
/// char *__strncpy_chk(char *s1, const char *s2, size_t n, size_t s1size);
TLI_DEFINE_ENUM_INTERNAL(strncpy_chk)
TLI_DEFINE_STRING_INTERNAL("__strncpy_chk")
@@ -403,6 +446,14 @@ TLI_DEFINE_STRING_INTERNAL("__strndup")
/// char * __strtok_r(char *s, const char *delim, char **save_ptr);
TLI_DEFINE_ENUM_INTERNAL(dunder_strtok_r)
TLI_DEFINE_STRING_INTERNAL("__strtok_r")
+/// int __vsnprintf_chk(char *s, size_t n, int flags, size_t slen,
+/// const char *format, va_list ap);
+TLI_DEFINE_ENUM_INTERNAL(vsnprintf_chk)
+TLI_DEFINE_STRING_INTERNAL("__vsnprintf_chk")
+/// int __vsprintf_chk(char *s, int flags, size_t slen, const char *format,
+/// va_list ap);
+TLI_DEFINE_ENUM_INTERNAL(vsprintf_chk)
+TLI_DEFINE_STRING_INTERNAL("__vsprintf_chk")
/// int abs(int j);
TLI_DEFINE_ENUM_INTERNAL(abs)
TLI_DEFINE_STRING_INTERNAL("abs")
@@ -1192,6 +1243,12 @@ TLI_DEFINE_STRING_INTERNAL("strcspn")
/// char *strdup(const char *s1);
TLI_DEFINE_ENUM_INTERNAL(strdup)
TLI_DEFINE_STRING_INTERNAL("strdup")
+/// size_t strlcat(char *dst, const char *src, size_t size);
+TLI_DEFINE_ENUM_INTERNAL(strlcat)
+TLI_DEFINE_STRING_INTERNAL("strlcat")
+/// size_t strlcpy(char *dst, const char *src, size_t size);
+TLI_DEFINE_ENUM_INTERNAL(strlcpy)
+TLI_DEFINE_STRING_INTERNAL("strlcpy")
/// size_t strlen(const char *s);
TLI_DEFINE_ENUM_INTERNAL(strlen)
TLI_DEFINE_STRING_INTERNAL("strlen")
diff --git a/include/llvm/Analysis/TargetLibraryInfo.h b/include/llvm/Analysis/TargetLibraryInfo.h
index a3fe834022f7..4b5200f5a838 100644
--- a/include/llvm/Analysis/TargetLibraryInfo.h
+++ b/include/llvm/Analysis/TargetLibraryInfo.h
@@ -1,9 +1,8 @@
//===-- TargetLibraryInfo.h - Library information ---------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -87,6 +86,7 @@ public:
enum VectorLibrary {
NoLibrary, // Don't use any vector library.
Accelerate, // Use Accelerate framework.
+ MASSV, // IBM MASS vector library.
SVML // Intel short vector math library.
};
@@ -281,9 +281,9 @@ public:
case LibFunc_trunc: case LibFunc_truncf: case LibFunc_truncl:
case LibFunc_log2: case LibFunc_log2f: case LibFunc_log2l:
case LibFunc_exp2: case LibFunc_exp2f: case LibFunc_exp2l:
- case LibFunc_memcmp: case LibFunc_strcmp: case LibFunc_strcpy:
- case LibFunc_stpcpy: case LibFunc_strlen: case LibFunc_strnlen:
- case LibFunc_memchr: case LibFunc_mempcpy:
+ case LibFunc_memcmp: case LibFunc_bcmp: case LibFunc_strcmp:
+ case LibFunc_strcpy: case LibFunc_stpcpy: case LibFunc_strlen:
+ case LibFunc_strnlen: case LibFunc_memchr: case LibFunc_mempcpy:
return true;
}
return false;
diff --git a/include/llvm/Analysis/TargetTransformInfo.h b/include/llvm/Analysis/TargetTransformInfo.h
index 223175d17c2d..7574b811bc1c 100644
--- a/include/llvm/Analysis/TargetTransformInfo.h
+++ b/include/llvm/Analysis/TargetTransformInfo.h
@@ -1,9 +1,8 @@
//===- TargetTransformInfo.h ------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
@@ -28,6 +27,10 @@
#include "llvm/Pass.h"
#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/Analysis/AssumptionCache.h"
#include <functional>
namespace llvm {
@@ -36,6 +39,8 @@ namespace Intrinsic {
enum ID : unsigned;
}
+class AssumptionCache;
+class BranchInst;
class Function;
class GlobalValue;
class IntrinsicInst;
@@ -45,6 +50,7 @@ class SCEV;
class ScalarEvolution;
class StoreInst;
class SwitchInst;
+class TargetLibraryInfo;
class Type;
class User;
class Value;
@@ -73,6 +79,30 @@ struct MemIntrinsicInfo {
}
};
+/// Attributes of a target dependent hardware loop.
+struct HardwareLoopInfo {
+ HardwareLoopInfo() = delete;
+ HardwareLoopInfo(Loop *L) : L(L) {}
+ Loop *L = nullptr;
+ BasicBlock *ExitBlock = nullptr;
+ BranchInst *ExitBranch = nullptr;
+ const SCEV *ExitCount = nullptr;
+ IntegerType *CountType = nullptr;
+ Value *LoopDecrement = nullptr; // Decrement the loop counter by this
+ // value in every iteration.
+ bool IsNestingLegal = false; // Can a hardware loop be a parent to
+ // another hardware loop?
+ bool CounterInReg = false; // Should loop counter be updated in
+ // the loop via a phi?
+ bool PerformEntryTest = false; // Generate the intrinsic which also performs
+ // icmp ne zero on the loop counter value and
+ // produces an i1 to guard the loop entry.
+ bool isHardwareLoopCandidate(ScalarEvolution &SE, LoopInfo &LI,
+ DominatorTree &DT, bool ForceNestedLoop = false,
+ bool ForceHardwareLoopPHI = false);
+ bool canAnalyze(LoopInfo &LI);
+};
+
/// This pass provides access to the codegen interfaces that are needed
/// for IR-level transformations.
class TargetTransformInfo {
@@ -81,7 +111,7 @@ public:
/// API below.
///
/// This is used by targets to construct a TTI wrapping their target-specific
- /// implementaion that encodes appropriate costs for their target.
+ /// implementation that encodes appropriate costs for their target.
template <typename T> TargetTransformInfo(T Impl);
/// Construct a baseline TTI object using a minimal implementation of
@@ -209,18 +239,21 @@ public:
/// This is the most basic query for estimating call cost: it only knows the
/// function type and (potentially) the number of arguments at the call site.
/// The latter is only interesting for varargs function types.
- int getCallCost(FunctionType *FTy, int NumArgs = -1) const;
+ int getCallCost(FunctionType *FTy, int NumArgs = -1,
+ const User *U = nullptr) const;
/// Estimate the cost of calling a specific function when lowered.
///
/// This overload adds the ability to reason about the particular function
/// being called in the event it is a library call with special lowering.
- int getCallCost(const Function *F, int NumArgs = -1) const;
+ int getCallCost(const Function *F, int NumArgs = -1,
+ const User *U = nullptr) const;
/// Estimate the cost of calling a specific function when lowered.
///
/// This overload allows specifying a set of candidate argument values.
- int getCallCost(const Function *F, ArrayRef<const Value *> Arguments) const;
+ int getCallCost(const Function *F, ArrayRef<const Value *> Arguments,
+ const User *U = nullptr) const;
/// \returns A value by which our inlining threshold should be multiplied.
/// This is primarily used to bump up the inlining threshold wholesale on
@@ -230,17 +263,35 @@ public:
/// individual classes of instructions would be better.
unsigned getInliningThresholdMultiplier() const;
+ /// \returns Vector bonus in percent.
+ ///
+ /// Vector bonuses: We want to more aggressively inline vector-dense kernels
+ /// and apply this bonus based on the percentage of vector instructions. A
+ /// bonus is applied if the vector instructions exceed 50% and half that amount
+ /// is applied if it exceeds 10%. Note that these bonuses are some what
+ /// arbitrary and evolved over time by accident as much as because they are
+ /// principled bonuses.
+ /// FIXME: It would be nice to base the bonus values on something more
+ /// scientific. A target may has no bonus on vector instructions.
+ int getInlinerVectorBonusPercent() const;
+
/// Estimate the cost of an intrinsic when lowered.
///
/// Mirrors the \c getCallCost method but uses an intrinsic identifier.
int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
- ArrayRef<Type *> ParamTys) const;
+ ArrayRef<Type *> ParamTys,
+ const User *U = nullptr) const;
/// Estimate the cost of an intrinsic when lowered.
///
/// Mirrors the \c getCallCost method but uses an intrinsic identifier.
int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
- ArrayRef<const Value *> Arguments) const;
+ ArrayRef<const Value *> Arguments,
+ const User *U = nullptr) const;
+
+ /// \return the expected cost of a memcpy, which could e.g. depend on the
+ /// source/destination type and alignment and the number of bytes copied.
+ int getMemcpyCost(const Instruction *I) const;
/// \return The estimated number of case clusters when lowering \p 'SI'.
/// \p JTSize Set a jump table size only when \p SI is suitable for a jump
@@ -296,7 +347,7 @@ public:
// Returns true for the target specific
// set of operations which produce uniform result
- // even taking non-unform arguments
+ // even taking non-uniform arguments
bool isAlwaysUniform(const Value *V) const;
/// Returns the address space ID for a target's 'flat' address space. Note
@@ -437,6 +488,13 @@ public:
void getUnrollingPreferences(Loop *L, ScalarEvolution &,
UnrollingPreferences &UP) const;
+ /// Query the target whether it would be profitable to convert the given loop
+ /// into a hardware loop.
+ bool isHardwareLoopProfitable(Loop *L, ScalarEvolution &SE,
+ AssumptionCache &AC,
+ TargetLibraryInfo *LibInfo,
+ HardwareLoopInfo &HWLoopInfo) const;
+
/// @}
/// \name Scalar Target Information
@@ -483,21 +541,40 @@ public:
/// calculation for the instructions in a loop.
bool canMacroFuseCmp() const;
+ /// Return true if the target can save a compare for loop count, for example
+ /// hardware loop saves a compare.
+ bool canSaveCmp(Loop *L, BranchInst **BI, ScalarEvolution *SE, LoopInfo *LI,
+ DominatorTree *DT, AssumptionCache *AC,
+ TargetLibraryInfo *LibInfo) const;
+
/// \return True is LSR should make efforts to create/preserve post-inc
/// addressing mode expressions.
bool shouldFavorPostInc() const;
- /// Return true if the target supports masked load/store
- /// AVX2 and AVX-512 targets allow masks for consecutive load and store
+ /// Return true if LSR should make efforts to generate indexed addressing
+ /// modes that operate across loop iterations.
+ bool shouldFavorBackedgeIndex(const Loop *L) const;
+
+ /// Return true if the target supports masked load.
bool isLegalMaskedStore(Type *DataType) const;
+ /// Return true if the target supports masked store.
bool isLegalMaskedLoad(Type *DataType) const;
- /// Return true if the target supports masked gather/scatter
- /// AVX-512 fully supports gather and scatter for vectors with 32 and 64
- /// bits scalar type.
+ /// Return true if the target supports nontemporal store.
+ bool isLegalNTStore(Type *DataType, unsigned Alignment) const;
+ /// Return true if the target supports nontemporal load.
+ bool isLegalNTLoad(Type *DataType, unsigned Alignment) const;
+
+ /// Return true if the target supports masked scatter.
bool isLegalMaskedScatter(Type *DataType) const;
+ /// Return true if the target supports masked gather.
bool isLegalMaskedGather(Type *DataType) const;
+ /// Return true if the target supports masked compress store.
+ bool isLegalMaskedCompressStore(Type *DataType) const;
+ /// Return true if the target supports masked expand load.
+ bool isLegalMaskedExpandLoad(Type *DataType) const;
+
/// Return true if the target has a unified operation to calculate division
/// and remainder. If so, the additional implicit multiplication and
/// subtraction required to calculate a remainder from division are free. This
@@ -576,17 +653,35 @@ public:
/// Don't restrict interleaved unrolling to small loops.
bool enableAggressiveInterleaving(bool LoopHasReductions) const;
- /// If not nullptr, enable inline expansion of memcmp. IsZeroCmp is
- /// true if this is the expansion of memcmp(p1, p2, s) == 0.
+ /// Returns options for expansion of memcmp. IsZeroCmp is
+ // true if this is the expansion of memcmp(p1, p2, s) == 0.
struct MemCmpExpansionOptions {
+ // Return true if memcmp expansion is enabled.
+ operator bool() const { return MaxNumLoads > 0; }
+
+ // Maximum number of load operations.
+ unsigned MaxNumLoads = 0;
+
// The list of available load sizes (in bytes), sorted in decreasing order.
SmallVector<unsigned, 8> LoadSizes;
+
+ // For memcmp expansion when the memcmp result is only compared equal or
+ // not-equal to 0, allow up to this number of load pairs per block. As an
+ // example, this may allow 'memcmp(a, b, 3) == 0' in a single block:
+ // a0 = load2bytes &a[0]
+ // b0 = load2bytes &b[0]
+ // a2 = load1byte &a[2]
+ // b2 = load1byte &b[2]
+ // r = cmp eq (a0 ^ b0 | a2 ^ b2), 0
+ unsigned NumLoadsPerBlock = 1;
+
// Set to true to allow overlapping loads. For example, 7-byte compares can
// be done with two 4-byte compares instead of 4+2+1-byte compares. This
// requires all loads in LoadSizes to be doable in an unaligned way.
bool AllowOverlappingLoads = false;
};
- const MemCmpExpansionOptions *enableMemCmpExpansion(bool IsZeroCmp) const;
+ MemCmpExpansionOptions enableMemCmpExpansion(bool OptSize,
+ bool IsZeroCmp) const;
/// Enable matching of interleaved access groups.
bool enableInterleavedAccessVectorization() const;
@@ -700,7 +795,7 @@ public:
bool shouldMaximizeVectorBandwidth(bool OptSize) const;
/// \return The minimum vectorization factor for types of given element
- /// bit width, or 0 if there is no mimimum VF. The returned value only
+ /// bit width, or 0 if there is no minimum VF. The returned value only
/// applies when shouldMaximizeVectorBandwidth returns true.
unsigned getMinimumVF(unsigned ElemWidth) const;
@@ -1005,6 +1100,11 @@ public:
/// \returns True if the target wants to expand the given reduction intrinsic
/// into a shuffle sequence.
bool shouldExpandReduction(const IntrinsicInst *II) const;
+
+ /// \returns the size cost of rematerializing a GlobalValue address relative
+ /// to a stack reload.
+ unsigned getGISelRematGlobalCost() const;
+
/// @}
private:
@@ -1035,15 +1135,18 @@ public:
virtual int getGEPCost(Type *PointeeType, const Value *Ptr,
ArrayRef<const Value *> Operands) = 0;
virtual int getExtCost(const Instruction *I, const Value *Src) = 0;
- virtual int getCallCost(FunctionType *FTy, int NumArgs) = 0;
- virtual int getCallCost(const Function *F, int NumArgs) = 0;
+ virtual int getCallCost(FunctionType *FTy, int NumArgs, const User *U) = 0;
+ virtual int getCallCost(const Function *F, int NumArgs, const User *U) = 0;
virtual int getCallCost(const Function *F,
- ArrayRef<const Value *> Arguments) = 0;
+ ArrayRef<const Value *> Arguments, const User *U) = 0;
virtual unsigned getInliningThresholdMultiplier() = 0;
+ virtual int getInlinerVectorBonusPercent() = 0;
virtual int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
- ArrayRef<Type *> ParamTys) = 0;
+ ArrayRef<Type *> ParamTys, const User *U) = 0;
virtual int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
- ArrayRef<const Value *> Arguments) = 0;
+ ArrayRef<const Value *> Arguments,
+ const User *U) = 0;
+ virtual int getMemcpyCost(const Instruction *I) = 0;
virtual unsigned getEstimatedNumberOfCaseClusters(const SwitchInst &SI,
unsigned &JTSize) = 0;
virtual int
@@ -1055,6 +1158,10 @@ public:
virtual bool isLoweredToCall(const Function *F) = 0;
virtual void getUnrollingPreferences(Loop *L, ScalarEvolution &,
UnrollingPreferences &UP) = 0;
+ virtual bool isHardwareLoopProfitable(Loop *L, ScalarEvolution &SE,
+ AssumptionCache &AC,
+ TargetLibraryInfo *LibInfo,
+ HardwareLoopInfo &HWLoopInfo) = 0;
virtual bool isLegalAddImmediate(int64_t Imm) = 0;
virtual bool isLegalICmpImmediate(int64_t Imm) = 0;
virtual bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV,
@@ -1065,11 +1172,19 @@ public:
virtual bool isLSRCostLess(TargetTransformInfo::LSRCost &C1,
TargetTransformInfo::LSRCost &C2) = 0;
virtual bool canMacroFuseCmp() = 0;
+ virtual bool canSaveCmp(Loop *L, BranchInst **BI, ScalarEvolution *SE,
+ LoopInfo *LI, DominatorTree *DT, AssumptionCache *AC,
+ TargetLibraryInfo *LibInfo) = 0;
virtual bool shouldFavorPostInc() const = 0;
+ virtual bool shouldFavorBackedgeIndex(const Loop *L) const = 0;
virtual bool isLegalMaskedStore(Type *DataType) = 0;
virtual bool isLegalMaskedLoad(Type *DataType) = 0;
+ virtual bool isLegalNTStore(Type *DataType, unsigned Alignment) = 0;
+ virtual bool isLegalNTLoad(Type *DataType, unsigned Alignment) = 0;
virtual bool isLegalMaskedScatter(Type *DataType) = 0;
virtual bool isLegalMaskedGather(Type *DataType) = 0;
+ virtual bool isLegalMaskedCompressStore(Type *DataType) = 0;
+ virtual bool isLegalMaskedExpandLoad(Type *DataType) = 0;
virtual bool hasDivRemOp(Type *DataType, bool IsSigned) = 0;
virtual bool hasVolatileVariant(Instruction *I, unsigned AddrSpace) = 0;
virtual bool prefersVectorizedAddressing() = 0;
@@ -1092,8 +1207,8 @@ public:
unsigned VF) = 0;
virtual bool supportsEfficientVectorElementLoadStore() = 0;
virtual bool enableAggressiveInterleaving(bool LoopHasReductions) = 0;
- virtual const MemCmpExpansionOptions *enableMemCmpExpansion(
- bool IsZeroCmp) const = 0;
+ virtual MemCmpExpansionOptions
+ enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const = 0;
virtual bool enableInterleavedAccessVectorization() = 0;
virtual bool enableMaskedInterleavedAccessVectorization() = 0;
virtual bool isFPVectorizationPotentiallyUnsafe() = 0;
@@ -1210,6 +1325,7 @@ public:
virtual bool useReductionIntrinsic(unsigned Opcode, Type *Ty,
ReductionFlags) const = 0;
virtual bool shouldExpandReduction(const IntrinsicInst *II) const = 0;
+ virtual unsigned getGISelRematGlobalCost() const = 0;
virtual int getInstructionLatency(const Instruction *I) = 0;
};
@@ -1235,26 +1351,33 @@ public:
int getExtCost(const Instruction *I, const Value *Src) override {
return Impl.getExtCost(I, Src);
}
- int getCallCost(FunctionType *FTy, int NumArgs) override {
- return Impl.getCallCost(FTy, NumArgs);
+ int getCallCost(FunctionType *FTy, int NumArgs, const User *U) override {
+ return Impl.getCallCost(FTy, NumArgs, U);
}
- int getCallCost(const Function *F, int NumArgs) override {
- return Impl.getCallCost(F, NumArgs);
+ int getCallCost(const Function *F, int NumArgs, const User *U) override {
+ return Impl.getCallCost(F, NumArgs, U);
}
int getCallCost(const Function *F,
- ArrayRef<const Value *> Arguments) override {
- return Impl.getCallCost(F, Arguments);
+ ArrayRef<const Value *> Arguments, const User *U) override {
+ return Impl.getCallCost(F, Arguments, U);
}
unsigned getInliningThresholdMultiplier() override {
return Impl.getInliningThresholdMultiplier();
}
+ int getInlinerVectorBonusPercent() override {
+ return Impl.getInlinerVectorBonusPercent();
+ }
int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
- ArrayRef<Type *> ParamTys) override {
- return Impl.getIntrinsicCost(IID, RetTy, ParamTys);
+ ArrayRef<Type *> ParamTys, const User *U = nullptr) override {
+ return Impl.getIntrinsicCost(IID, RetTy, ParamTys, U);
}
int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
- ArrayRef<const Value *> Arguments) override {
- return Impl.getIntrinsicCost(IID, RetTy, Arguments);
+ ArrayRef<const Value *> Arguments,
+ const User *U = nullptr) override {
+ return Impl.getIntrinsicCost(IID, RetTy, Arguments, U);
+ }
+ int getMemcpyCost(const Instruction *I) override {
+ return Impl.getMemcpyCost(I);
}
int getUserCost(const User *U, ArrayRef<const Value *> Operands) override {
return Impl.getUserCost(U, Operands);
@@ -1279,6 +1402,12 @@ public:
UnrollingPreferences &UP) override {
return Impl.getUnrollingPreferences(L, SE, UP);
}
+ bool isHardwareLoopProfitable(Loop *L, ScalarEvolution &SE,
+ AssumptionCache &AC,
+ TargetLibraryInfo *LibInfo,
+ HardwareLoopInfo &HWLoopInfo) override {
+ return Impl.isHardwareLoopProfitable(L, SE, AC, LibInfo, HWLoopInfo);
+ }
bool isLegalAddImmediate(int64_t Imm) override {
return Impl.isLegalAddImmediate(Imm);
}
@@ -1299,21 +1428,42 @@ public:
bool canMacroFuseCmp() override {
return Impl.canMacroFuseCmp();
}
+ bool canSaveCmp(Loop *L, BranchInst **BI,
+ ScalarEvolution *SE,
+ LoopInfo *LI, DominatorTree *DT, AssumptionCache *AC,
+ TargetLibraryInfo *LibInfo) override {
+ return Impl.canSaveCmp(L, BI, SE, LI, DT, AC, LibInfo);
+ }
bool shouldFavorPostInc() const override {
return Impl.shouldFavorPostInc();
}
+ bool shouldFavorBackedgeIndex(const Loop *L) const override {
+ return Impl.shouldFavorBackedgeIndex(L);
+ }
bool isLegalMaskedStore(Type *DataType) override {
return Impl.isLegalMaskedStore(DataType);
}
bool isLegalMaskedLoad(Type *DataType) override {
return Impl.isLegalMaskedLoad(DataType);
}
+ bool isLegalNTStore(Type *DataType, unsigned Alignment) override {
+ return Impl.isLegalNTStore(DataType, Alignment);
+ }
+ bool isLegalNTLoad(Type *DataType, unsigned Alignment) override {
+ return Impl.isLegalNTLoad(DataType, Alignment);
+ }
bool isLegalMaskedScatter(Type *DataType) override {
return Impl.isLegalMaskedScatter(DataType);
}
bool isLegalMaskedGather(Type *DataType) override {
return Impl.isLegalMaskedGather(DataType);
}
+ bool isLegalMaskedCompressStore(Type *DataType) override {
+ return Impl.isLegalMaskedCompressStore(DataType);
+ }
+ bool isLegalMaskedExpandLoad(Type *DataType) override {
+ return Impl.isLegalMaskedExpandLoad(DataType);
+ }
bool hasDivRemOp(Type *DataType, bool IsSigned) override {
return Impl.hasDivRemOp(DataType, IsSigned);
}
@@ -1368,9 +1518,9 @@ public:
bool enableAggressiveInterleaving(bool LoopHasReductions) override {
return Impl.enableAggressiveInterleaving(LoopHasReductions);
}
- const MemCmpExpansionOptions *enableMemCmpExpansion(
- bool IsZeroCmp) const override {
- return Impl.enableMemCmpExpansion(IsZeroCmp);
+ MemCmpExpansionOptions enableMemCmpExpansion(bool OptSize,
+ bool IsZeroCmp) const override {
+ return Impl.enableMemCmpExpansion(OptSize, IsZeroCmp);
}
bool enableInterleavedAccessVectorization() override {
return Impl.enableInterleavedAccessVectorization();
@@ -1617,6 +1767,11 @@ public:
bool shouldExpandReduction(const IntrinsicInst *II) const override {
return Impl.shouldExpandReduction(II);
}
+
+ unsigned getGISelRematGlobalCost() const override {
+ return Impl.getGISelRematGlobalCost();
+ }
+
int getInstructionLatency(const Instruction *I) override {
return Impl.getInstructionLatency(I);
}
diff --git a/include/llvm/Analysis/TargetTransformInfoImpl.h b/include/llvm/Analysis/TargetTransformInfoImpl.h
index c9a234deeb7d..b99e1eb9adf0 100644
--- a/include/llvm/Analysis/TargetTransformInfoImpl.h
+++ b/include/llvm/Analysis/TargetTransformInfoImpl.h
@@ -1,9 +1,8 @@
//===- TargetTransformInfoImpl.h --------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
@@ -124,7 +123,7 @@ public:
return TTI::TCC_Basic;
}
- unsigned getCallCost(FunctionType *FTy, int NumArgs) {
+ unsigned getCallCost(FunctionType *FTy, int NumArgs, const User *U) {
assert(FTy && "FunctionType must be provided to this routine.");
// The target-independent implementation just measures the size of the
@@ -141,45 +140,10 @@ public:
unsigned getInliningThresholdMultiplier() { return 1; }
- unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
- ArrayRef<Type *> ParamTys) {
- switch (IID) {
- default:
- // Intrinsics rarely (if ever) have normal argument setup constraints.
- // Model them as having a basic instruction cost.
- // FIXME: This is wrong for libc intrinsics.
- return TTI::TCC_Basic;
+ int getInlinerVectorBonusPercent() { return 150; }
- case Intrinsic::annotation:
- case Intrinsic::assume:
- case Intrinsic::sideeffect:
- case Intrinsic::dbg_declare:
- case Intrinsic::dbg_value:
- case Intrinsic::dbg_label:
- case Intrinsic::invariant_start:
- case Intrinsic::invariant_end:
- case Intrinsic::launder_invariant_group:
- case Intrinsic::strip_invariant_group:
- case Intrinsic::is_constant:
- case Intrinsic::lifetime_start:
- case Intrinsic::lifetime_end:
- case Intrinsic::objectsize:
- case Intrinsic::ptr_annotation:
- case Intrinsic::var_annotation:
- case Intrinsic::experimental_gc_result:
- case Intrinsic::experimental_gc_relocate:
- case Intrinsic::coro_alloc:
- case Intrinsic::coro_begin:
- case Intrinsic::coro_free:
- case Intrinsic::coro_end:
- case Intrinsic::coro_frame:
- case Intrinsic::coro_size:
- case Intrinsic::coro_suspend:
- case Intrinsic::coro_param:
- case Intrinsic::coro_subfn_addr:
- // These intrinsics don't actually represent code after lowering.
- return TTI::TCC_Free;
- }
+ unsigned getMemcpyCost(const Instruction *I) {
+ return TTI::TCC_Expensive;
}
bool hasBranchDivergence() { return false; }
@@ -228,6 +192,13 @@ public:
return true;
}
+ bool isHardwareLoopProfitable(Loop *L, ScalarEvolution &SE,
+ AssumptionCache &AC,
+ TargetLibraryInfo *LibInfo,
+ HardwareLoopInfo &HWLoopInfo) {
+ return false;
+ }
+
void getUnrollingPreferences(Loop *, ScalarEvolution &,
TTI::UnrollingPreferences &) {}
@@ -252,16 +223,42 @@ public:
bool canMacroFuseCmp() { return false; }
+ bool canSaveCmp(Loop *L, BranchInst **BI, ScalarEvolution *SE, LoopInfo *LI,
+ DominatorTree *DT, AssumptionCache *AC,
+ TargetLibraryInfo *LibInfo) {
+ return false;
+ }
+
bool shouldFavorPostInc() const { return false; }
+ bool shouldFavorBackedgeIndex(const Loop *L) const { return false; }
+
bool isLegalMaskedStore(Type *DataType) { return false; }
bool isLegalMaskedLoad(Type *DataType) { return false; }
+ bool isLegalNTStore(Type *DataType, unsigned Alignment) {
+ // By default, assume nontemporal memory stores are available for stores
+ // that are aligned and have a size that is a power of 2.
+ unsigned DataSize = DL.getTypeStoreSize(DataType);
+ return Alignment >= DataSize && isPowerOf2_32(DataSize);
+ }
+
+ bool isLegalNTLoad(Type *DataType, unsigned Alignment) {
+ // By default, assume nontemporal memory loads are available for loads that
+ // are aligned and have a size that is a power of 2.
+ unsigned DataSize = DL.getTypeStoreSize(DataType);
+ return Alignment >= DataSize && isPowerOf2_32(DataSize);
+ }
+
bool isLegalMaskedScatter(Type *DataType) { return false; }
bool isLegalMaskedGather(Type *DataType) { return false; }
+ bool isLegalMaskedCompressStore(Type *DataType) { return false; }
+
+ bool isLegalMaskedExpandLoad(Type *DataType) { return false; }
+
bool hasDivRemOp(Type *DataType, bool IsSigned) { return false; }
bool hasVolatileVariant(Instruction *I, unsigned AddrSpace) { return false; }
@@ -307,9 +304,9 @@ public:
bool enableAggressiveInterleaving(bool LoopHasReductions) { return false; }
- const TTI::MemCmpExpansionOptions *enableMemCmpExpansion(
- bool IsZeroCmp) const {
- return nullptr;
+ TTI::MemCmpExpansionOptions enableMemCmpExpansion(bool OptSize,
+ bool IsZeroCmp) const {
+ return {};
}
bool enableInterleavedAccessVectorization() { return false; }
@@ -583,6 +580,10 @@ public:
return true;
}
+ unsigned getGISelRematGlobalCost() const {
+ return 1;
+ }
+
protected:
// Obtain the minimum required size to hold the value (without the sign)
// In case of a vector it returns the min required size for one element.
@@ -679,7 +680,7 @@ protected:
public:
using BaseT::getCallCost;
- unsigned getCallCost(const Function *F, int NumArgs) {
+ unsigned getCallCost(const Function *F, int NumArgs, const User *U) {
assert(F && "A concrete function must be provided to this routine.");
if (NumArgs < 0)
@@ -691,35 +692,34 @@ public:
FunctionType *FTy = F->getFunctionType();
SmallVector<Type *, 8> ParamTys(FTy->param_begin(), FTy->param_end());
return static_cast<T *>(this)
- ->getIntrinsicCost(IID, FTy->getReturnType(), ParamTys);
+ ->getIntrinsicCost(IID, FTy->getReturnType(), ParamTys, U);
}
if (!static_cast<T *>(this)->isLoweredToCall(F))
return TTI::TCC_Basic; // Give a basic cost if it will be lowered
// directly.
- return static_cast<T *>(this)->getCallCost(F->getFunctionType(), NumArgs);
+ return static_cast<T *>(this)->getCallCost(F->getFunctionType(), NumArgs, U);
}
- unsigned getCallCost(const Function *F, ArrayRef<const Value *> Arguments) {
+ unsigned getCallCost(const Function *F, ArrayRef<const Value *> Arguments,
+ const User *U) {
// Simply delegate to generic handling of the call.
// FIXME: We should use instsimplify or something else to catch calls which
// will constant fold with these arguments.
- return static_cast<T *>(this)->getCallCost(F, Arguments.size());
+ return static_cast<T *>(this)->getCallCost(F, Arguments.size(), U);
}
using BaseT::getGEPCost;
int getGEPCost(Type *PointeeType, const Value *Ptr,
ArrayRef<const Value *> Operands) {
- const GlobalValue *BaseGV = nullptr;
- if (Ptr != nullptr) {
- // TODO: will remove this when pointers have an opaque type.
- assert(Ptr->getType()->getScalarType()->getPointerElementType() ==
- PointeeType &&
- "explicit pointee type doesn't match operand's pointee type");
- BaseGV = dyn_cast<GlobalValue>(Ptr->stripPointerCasts());
- }
+ assert(PointeeType && Ptr && "can't get GEPCost of nullptr");
+ // TODO: will remove this when pointers have an opaque type.
+ assert(Ptr->getType()->getScalarType()->getPointerElementType() ==
+ PointeeType &&
+ "explicit pointee type doesn't match operand's pointee type");
+ auto *BaseGV = dyn_cast<GlobalValue>(Ptr->stripPointerCasts());
bool HasBaseReg = (BaseGV == nullptr);
auto PtrSizeBits = DL.getPointerTypeSizeInBits(Ptr->getType());
@@ -762,21 +762,60 @@ public:
}
}
- // Assumes the address space is 0 when Ptr is nullptr.
- unsigned AS =
- (Ptr == nullptr ? 0 : Ptr->getType()->getPointerAddressSpace());
-
if (static_cast<T *>(this)->isLegalAddressingMode(
TargetType, const_cast<GlobalValue *>(BaseGV),
- BaseOffset.sextOrTrunc(64).getSExtValue(), HasBaseReg, Scale, AS))
+ BaseOffset.sextOrTrunc(64).getSExtValue(), HasBaseReg, Scale,
+ Ptr->getType()->getPointerAddressSpace()))
return TTI::TCC_Free;
return TTI::TCC_Basic;
}
- using BaseT::getIntrinsicCost;
+ unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
+ ArrayRef<Type *> ParamTys, const User *U) {
+ switch (IID) {
+ default:
+ // Intrinsics rarely (if ever) have normal argument setup constraints.
+ // Model them as having a basic instruction cost.
+ return TTI::TCC_Basic;
+
+ // TODO: other libc intrinsics.
+ case Intrinsic::memcpy:
+ return static_cast<T *>(this)->getMemcpyCost(dyn_cast<Instruction>(U));
+
+ case Intrinsic::annotation:
+ case Intrinsic::assume:
+ case Intrinsic::sideeffect:
+ case Intrinsic::dbg_declare:
+ case Intrinsic::dbg_value:
+ case Intrinsic::dbg_label:
+ case Intrinsic::invariant_start:
+ case Intrinsic::invariant_end:
+ case Intrinsic::launder_invariant_group:
+ case Intrinsic::strip_invariant_group:
+ case Intrinsic::is_constant:
+ case Intrinsic::lifetime_start:
+ case Intrinsic::lifetime_end:
+ case Intrinsic::objectsize:
+ case Intrinsic::ptr_annotation:
+ case Intrinsic::var_annotation:
+ case Intrinsic::experimental_gc_result:
+ case Intrinsic::experimental_gc_relocate:
+ case Intrinsic::coro_alloc:
+ case Intrinsic::coro_begin:
+ case Intrinsic::coro_free:
+ case Intrinsic::coro_end:
+ case Intrinsic::coro_frame:
+ case Intrinsic::coro_size:
+ case Intrinsic::coro_suspend:
+ case Intrinsic::coro_param:
+ case Intrinsic::coro_subfn_addr:
+ // These intrinsics don't actually represent code after lowering.
+ return TTI::TCC_Free;
+ }
+ }
unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
- ArrayRef<const Value *> Arguments) {
+ ArrayRef<const Value *> Arguments, const User *U) {
// Delegate to the generic intrinsic handling code. This mostly provides an
// opportunity for targets to (for example) special case the cost of
// certain intrinsics based on constants used as arguments.
@@ -784,7 +823,7 @@ public:
ParamTys.reserve(Arguments.size());
for (unsigned Idx = 0, Size = Arguments.size(); Idx != Size; ++Idx)
ParamTys.push_back(Arguments[Idx]->getType());
- return static_cast<T *>(this)->getIntrinsicCost(IID, RetTy, ParamTys);
+ return static_cast<T *>(this)->getIntrinsicCost(IID, RetTy, ParamTys, U);
}
unsigned getUserCost(const User *U, ArrayRef<const Value *> Operands) {
@@ -808,22 +847,18 @@ public:
// Just use the called value type.
Type *FTy = CS.getCalledValue()->getType()->getPointerElementType();
return static_cast<T *>(this)
- ->getCallCost(cast<FunctionType>(FTy), CS.arg_size());
+ ->getCallCost(cast<FunctionType>(FTy), CS.arg_size(), U);
}
SmallVector<const Value *, 8> Arguments(CS.arg_begin(), CS.arg_end());
- return static_cast<T *>(this)->getCallCost(F, Arguments);
+ return static_cast<T *>(this)->getCallCost(F, Arguments, U);
}
- if (const CastInst *CI = dyn_cast<CastInst>(U)) {
- // Result of a cmp instruction is often extended (to be used by other
- // cmp instructions, logical or return instructions). These are usually
- // nop on most sane targets.
- if (isa<CmpInst>(CI->getOperand(0)))
- return TTI::TCC_Free;
- if (isa<SExtInst>(CI) || isa<ZExtInst>(CI) || isa<FPExtInst>(CI))
- return static_cast<T *>(this)->getExtCost(CI, Operands.back());
- }
+ if (isa<SExtInst>(U) || isa<ZExtInst>(U) || isa<FPExtInst>(U))
+ // The old behaviour of generally treating extensions of icmp to be free
+ // has been removed. A target that needs it should override getUserCost().
+ return static_cast<T *>(this)->getExtCost(cast<Instruction>(U),
+ Operands.back());
return static_cast<T *>(this)->getOperationCost(
Operator::getOpcode(U), U->getType(),
diff --git a/include/llvm/Analysis/Trace.h b/include/llvm/Analysis/Trace.h
index b05d384ab1a3..a1ffd03c4053 100644
--- a/include/llvm/Analysis/Trace.h
+++ b/include/llvm/Analysis/Trace.h
@@ -1,9 +1,8 @@
//===- llvm/Analysis/Trace.h - Represent one trace of LLVM code -*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/TypeBasedAliasAnalysis.h b/include/llvm/Analysis/TypeBasedAliasAnalysis.h
index d2e6df22425e..344f26806618 100644
--- a/include/llvm/Analysis/TypeBasedAliasAnalysis.h
+++ b/include/llvm/Analysis/TypeBasedAliasAnalysis.h
@@ -1,9 +1,8 @@
//===- TypeBasedAliasAnalysis.h - Type-Based Alias Analysis -----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -41,12 +40,16 @@ public:
return false;
}
- AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB);
- bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal);
+ AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
+ AAQueryInfo &AAQI);
+ bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI,
+ bool OrLocal);
FunctionModRefBehavior getModRefBehavior(const CallBase *Call);
FunctionModRefBehavior getModRefBehavior(const Function *F);
- ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc);
- ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2);
+ ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
+ AAQueryInfo &AAQI);
+ ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2,
+ AAQueryInfo &AAQI);
private:
bool Aliases(const MDNode *A, const MDNode *B) const;
diff --git a/include/llvm/Analysis/TypeMetadataUtils.h b/include/llvm/Analysis/TypeMetadataUtils.h
index 3bf9c5d20741..82cf8efeea54 100644
--- a/include/llvm/Analysis/TypeMetadataUtils.h
+++ b/include/llvm/Analysis/TypeMetadataUtils.h
@@ -1,9 +1,8 @@
//===- TypeMetadataUtils.h - Utilities related to type metadata --*- C++ -*-==//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/Utils/Local.h b/include/llvm/Analysis/Utils/Local.h
index b4141bbff28d..acbdf5dca32c 100644
--- a/include/llvm/Analysis/Utils/Local.h
+++ b/include/llvm/Analysis/Utils/Local.h
@@ -1,9 +1,8 @@
//===- Local.h - Functions to perform local transformations -----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/ValueLattice.h b/include/llvm/Analysis/ValueLattice.h
index 0744ca617e48..56519d7d0857 100644
--- a/include/llvm/Analysis/ValueLattice.h
+++ b/include/llvm/Analysis/ValueLattice.h
@@ -1,9 +1,8 @@
//===- ValueLattice.h - Value constraint analysis ---------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/include/llvm/Analysis/ValueLatticeUtils.h b/include/llvm/Analysis/ValueLatticeUtils.h
index 02072672e56e..a3bbb96129bf 100644
--- a/include/llvm/Analysis/ValueLatticeUtils.h
+++ b/include/llvm/Analysis/ValueLatticeUtils.h
@@ -1,9 +1,8 @@
//===-- ValueLatticeUtils.h - Utils for solving lattices --------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h
index f46fdfcb608e..fa7e0e0eef7e 100644
--- a/include/llvm/Analysis/ValueTracking.h
+++ b/include/llvm/Analysis/ValueTracking.h
@@ -1,9 +1,8 @@
//===- llvm/Analysis/ValueTracking.h - Walk computations --------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -17,8 +16,10 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallSet.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Intrinsics.h"
#include <cassert>
@@ -29,10 +30,10 @@ namespace llvm {
class AddOperator;
class APInt;
class AssumptionCache;
-class DataLayout;
class DominatorTree;
class GEPOperator;
class IntrinsicInst;
+class WithOverflowInst;
struct KnownBits;
class Loop;
class LoopInfo;
@@ -223,7 +224,7 @@ class Value;
/// 0.0 etc. If the value can't be handled with a repeated byte store (e.g.
/// i16 0x1234), return null. If the value is entirely undef and padding,
/// return undef.
- Value *isBytewiseValue(Value *V);
+ Value *isBytewiseValue(Value *V, const DataLayout &DL);
/// Given an aggregrate and an sequence of indices, see if the scalar value
/// indexed is already around as a register, for example if it were inserted
@@ -237,8 +238,18 @@ class Value;
/// Analyze the specified pointer to see if it can be expressed as a base
/// pointer plus a constant offset. Return the base and offset to the caller.
- Value *GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset,
- const DataLayout &DL);
+ ///
+ /// This is a wrapper around Value::stripAndAccumulateConstantOffsets that
+ /// creates and later unpacks the required APInt.
+ inline Value *GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset,
+ const DataLayout &DL) {
+ APInt OffsetAPInt(DL.getIndexTypeSizeInBits(Ptr->getType()), 0);
+ Value *Base =
+ Ptr->stripAndAccumulateConstantOffsets(DL, OffsetAPInt,
+ /* AllowNonInbounds */ true);
+ Offset = OffsetAPInt.getSExtValue();
+ return Base;
+ }
inline const Value *GetPointerBaseWithConstantOffset(const Value *Ptr,
int64_t &Offset,
const DataLayout &DL) {
@@ -351,7 +362,8 @@ class Value;
/// Since A[i] and A[i-1] are independent pointers, getUnderlyingObjects
/// should not assume that Curr and Prev share the same underlying object thus
/// it shouldn't look through the phi above.
- void GetUnderlyingObjects(Value *V, SmallVectorImpl<Value *> &Objects,
+ void GetUnderlyingObjects(const Value *V,
+ SmallVectorImpl<const Value *> &Objects,
const DataLayout &DL, LoopInfo *LI = nullptr,
unsigned MaxLookup = 6);
@@ -411,7 +423,16 @@ class Value;
bool isValidAssumeForContext(const Instruction *I, const Instruction *CxtI,
const DominatorTree *DT = nullptr);
- enum class OverflowResult { AlwaysOverflows, MayOverflow, NeverOverflows };
+ enum class OverflowResult {
+ /// Always overflows in the direction of signed/unsigned min value.
+ AlwaysOverflowsLow,
+ /// Always overflows in the direction of signed/unsigned max value.
+ AlwaysOverflowsHigh,
+ /// May or may not overflow.
+ MayOverflow,
+ /// Never overflows.
+ NeverOverflows,
+ };
OverflowResult computeOverflowForUnsignedMul(const Value *LHS,
const Value *RHS,
@@ -455,12 +476,17 @@ class Value;
const Instruction *CxtI,
const DominatorTree *DT);
- /// Returns true if the arithmetic part of the \p II 's result is
+ /// Returns true if the arithmetic part of the \p WO 's result is
/// used only along the paths control dependent on the computation
- /// not overflowing, \p II being an <op>.with.overflow intrinsic.
- bool isOverflowIntrinsicNoWrap(const IntrinsicInst *II,
+ /// not overflowing, \p WO being an <op>.with.overflow intrinsic.
+ bool isOverflowIntrinsicNoWrap(const WithOverflowInst *WO,
const DominatorTree &DT);
+
+ /// Determine the possible constant range of an integer or vector of integer
+ /// value. This is intended as a cheap, non-recursive check.
+ ConstantRange computeConstantRange(const Value *V, bool UseInstrInfo = true);
+
/// Return true if this function can prove that the instruction I will
/// always transfer execution to one of its successors (including the next
/// instruction that follows within a basic block). E.g. this is not
@@ -506,6 +532,12 @@ class Value;
/// value (all bits poison).
const Value *getGuaranteedNonFullPoisonOp(const Instruction *I);
+ /// Return true if the given instruction must trigger undefined behavior.
+ /// when I is executed with any operands which appear in KnownPoison holding
+ /// a full-poison value at the point of execution.
+ bool mustTriggerUB(const Instruction *I,
+ const SmallSet<const Value *, 16>& KnownPoison);
+
/// Return true if this function can prove that if PoisonI is executed
/// and yields a full-poison value (all bits poison), then that will
/// trigger undefined behavior.
@@ -584,6 +616,12 @@ class Value;
return Result;
}
+ /// Determine the pattern that a select with the given compare as its
+ /// predicate and given values as its true/false operands would match.
+ SelectPatternResult matchDecomposedSelectPattern(
+ CmpInst *CmpI, Value *TrueVal, Value *FalseVal, Value *&LHS, Value *&RHS,
+ Instruction::CastOps *CastOp = nullptr, unsigned Depth = 0);
+
/// Return the canonical comparison predicate for the specified
/// minimum/maximum flavor.
CmpInst::Predicate getMinMaxPred(SelectPatternFlavor SPF,
diff --git a/include/llvm/Analysis/VecFuncs.def b/include/llvm/Analysis/VecFuncs.def
new file mode 100644
index 000000000000..4c9206266d9a
--- /dev/null
+++ b/include/llvm/Analysis/VecFuncs.def
@@ -0,0 +1,250 @@
+//===-- VecFuncs.def - Library information -------------*- C++ -*-----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This .def file will create mappings from scalar math functions to vector
+// functions along with their vectorization factor. The current support includes
+// such mappings for Accelerate framework, MASS vector library, and SVML library.
+
+#if !(defined(TLI_DEFINE_VECFUNC))
+#define TLI_DEFINE_VECFUNC(SCAL, VEC, VF) {SCAL, VEC, VF},
+#endif
+
+#if defined(TLI_DEFINE_ACCELERATE_VECFUNCS)
+// Accelerate framework's Vector Functions
+
+// Floating-Point Arithmetic and Auxiliary Functions
+TLI_DEFINE_VECFUNC("ceilf", "vceilf", 4)
+TLI_DEFINE_VECFUNC("fabsf", "vfabsf", 4)
+TLI_DEFINE_VECFUNC("llvm.fabs.f32", "vfabsf", 4)
+TLI_DEFINE_VECFUNC("floorf", "vfloorf", 4)
+TLI_DEFINE_VECFUNC("sqrtf", "vsqrtf", 4)
+TLI_DEFINE_VECFUNC("llvm.sqrt.f32", "vsqrtf", 4)
+
+// Exponential and Logarithmic Functions
+TLI_DEFINE_VECFUNC("expf", "vexpf", 4)
+TLI_DEFINE_VECFUNC("llvm.exp.f32", "vexpf", 4)
+TLI_DEFINE_VECFUNC("expm1f", "vexpm1f", 4)
+TLI_DEFINE_VECFUNC("logf", "vlogf", 4)
+TLI_DEFINE_VECFUNC("llvm.log.f32", "vlogf", 4)
+TLI_DEFINE_VECFUNC("log1pf", "vlog1pf", 4)
+TLI_DEFINE_VECFUNC("log10f", "vlog10f", 4)
+TLI_DEFINE_VECFUNC("llvm.log10.f32", "vlog10f", 4)
+TLI_DEFINE_VECFUNC("logbf", "vlogbf", 4)
+
+// Trigonometric Functions
+TLI_DEFINE_VECFUNC("sinf", "vsinf", 4)
+TLI_DEFINE_VECFUNC("llvm.sin.f32", "vsinf", 4)
+TLI_DEFINE_VECFUNC("cosf", "vcosf", 4)
+TLI_DEFINE_VECFUNC("llvm.cos.f32", "vcosf", 4)
+TLI_DEFINE_VECFUNC("tanf", "vtanf", 4)
+TLI_DEFINE_VECFUNC("asinf", "vasinf", 4)
+TLI_DEFINE_VECFUNC("acosf", "vacosf", 4)
+TLI_DEFINE_VECFUNC("atanf", "vatanf", 4)
+
+// Hyperbolic Functions
+TLI_DEFINE_VECFUNC("sinhf", "vsinhf", 4)
+TLI_DEFINE_VECFUNC("coshf", "vcoshf", 4)
+TLI_DEFINE_VECFUNC("tanhf", "vtanhf", 4)
+TLI_DEFINE_VECFUNC("asinhf", "vasinhf", 4)
+TLI_DEFINE_VECFUNC("acoshf", "vacoshf", 4)
+TLI_DEFINE_VECFUNC("atanhf", "vatanhf", 4)
+
+
+#elif defined(TLI_DEFINE_MASSV_VECFUNCS)
+// IBM MASS library's vector Functions
+
+// Floating-Point Arithmetic and Auxiliary Functions
+TLI_DEFINE_VECFUNC("cbrt", "__cbrtd2_massv", 2)
+TLI_DEFINE_VECFUNC("cbrtf", "__cbrtf4_massv", 4)
+TLI_DEFINE_VECFUNC("pow", "__powd2_massv", 2)
+TLI_DEFINE_VECFUNC("llvm.pow.f64", "__powd2_massv", 2)
+TLI_DEFINE_VECFUNC("powf", "__powf4_massv", 4)
+TLI_DEFINE_VECFUNC("llvm.pow.f32", "__powf4_massv", 4)
+TLI_DEFINE_VECFUNC("sqrt", "__sqrtd2_massv", 2)
+TLI_DEFINE_VECFUNC("llvm.sqrt.f64", "__sqrtd2_massv", 2)
+TLI_DEFINE_VECFUNC("sqrtf", "__sqrtf4_massv", 4)
+TLI_DEFINE_VECFUNC("llvm.sqrt.f32", "__sqrtf4_massv", 4)
+
+// Exponential and Logarithmic Functions
+TLI_DEFINE_VECFUNC("exp", "__expd2_massv", 2)
+TLI_DEFINE_VECFUNC("llvm.exp.f64", "__expd2_massv", 2)
+TLI_DEFINE_VECFUNC("expf", "__expf4_massv", 4)
+TLI_DEFINE_VECFUNC("llvm.exp.f32", "__expf4_massv", 4)
+TLI_DEFINE_VECFUNC("exp2", "__exp2d2_massv", 2)
+TLI_DEFINE_VECFUNC("llvm.exp2.f64", "__exp2d2_massv", 2)
+TLI_DEFINE_VECFUNC("exp2f", "__exp2f4_massv", 4)
+TLI_DEFINE_VECFUNC("llvm.exp2.f32", "__exp2f4_massv", 4)
+TLI_DEFINE_VECFUNC("expm1", "__expm1d2_massv", 2)
+TLI_DEFINE_VECFUNC("expm1f", "__expm1f4_massv", 4)
+TLI_DEFINE_VECFUNC("log", "__logd2_massv", 2)
+TLI_DEFINE_VECFUNC("llvm.log.f64", "__logd2_massv", 2)
+TLI_DEFINE_VECFUNC("logf", "__logf4_massv", 4)
+TLI_DEFINE_VECFUNC("llvm.log.f32", "__logf4_massv", 4)
+TLI_DEFINE_VECFUNC("log1p", "__log1pd2_massv", 2)
+TLI_DEFINE_VECFUNC("log1pf", "__log1pf4_massv", 4)
+TLI_DEFINE_VECFUNC("log10", "__log10d2_massv", 2)
+TLI_DEFINE_VECFUNC("llvm.log10.f64", "__log10d2_massv", 2)
+TLI_DEFINE_VECFUNC("log10f", "__log10f4_massv", 4)
+TLI_DEFINE_VECFUNC("llvm.log10.f32", "__log10f4_massv", 4)
+TLI_DEFINE_VECFUNC("log2", "__log2d2_massv", 2)
+TLI_DEFINE_VECFUNC("llvm.log2.f64", "__log2d2_massv", 2)
+TLI_DEFINE_VECFUNC("log2f", "__log2f4_massv", 4)
+TLI_DEFINE_VECFUNC("llvm.log2.f32", "__log2f4_massv", 4)
+
+// Trigonometric Functions
+TLI_DEFINE_VECFUNC("sin", "__sind2_massv", 2)
+TLI_DEFINE_VECFUNC("llvm.sin.f64", "__sind2_massv", 2)
+TLI_DEFINE_VECFUNC("sinf", "__sinf4_massv", 4)
+TLI_DEFINE_VECFUNC("llvm.sin.f32", "__sinf4_massv", 4)
+TLI_DEFINE_VECFUNC("cos", "__cosd2_massv", 2)
+TLI_DEFINE_VECFUNC("llvm.cos.f64", "__cosd2_massv", 2)
+TLI_DEFINE_VECFUNC("cosf", "__cosf4_massv", 4)
+TLI_DEFINE_VECFUNC("llvm.cos.f32", "__cosf4_massv", 4)
+TLI_DEFINE_VECFUNC("tan", "__tand2_massv", 2)
+TLI_DEFINE_VECFUNC("tanf", "__tanf4_massv", 4)
+TLI_DEFINE_VECFUNC("asin", "__asind2_massv", 2)
+TLI_DEFINE_VECFUNC("asinf", "__asinf4_massv", 4)
+TLI_DEFINE_VECFUNC("acos", "__acosd2_massv", 2)
+TLI_DEFINE_VECFUNC("acosf", "__acosf4_massv", 4)
+TLI_DEFINE_VECFUNC("atan", "__atand2_massv", 2)
+TLI_DEFINE_VECFUNC("atanf", "__atanf4_massv", 4)
+TLI_DEFINE_VECFUNC("atan2", "__atan2d2_massv", 2)
+TLI_DEFINE_VECFUNC("atan2f", "__atan2f4_massv", 4)
+
+// Hyperbolic Functions
+TLI_DEFINE_VECFUNC("sinh", "__sinhd2_massv", 2)
+TLI_DEFINE_VECFUNC("sinhf", "__sinhf4_massv", 4)
+TLI_DEFINE_VECFUNC("cosh", "__coshd2_massv", 2)
+TLI_DEFINE_VECFUNC("coshf", "__coshf4_massv", 4)
+TLI_DEFINE_VECFUNC("tanh", "__tanhd2_massv", 2)
+TLI_DEFINE_VECFUNC("tanhf", "__tanhf4_massv", 4)
+TLI_DEFINE_VECFUNC("asinh", "__asinhd2_massv", 2)
+TLI_DEFINE_VECFUNC("asinhf", "__asinhf4_massv", 4)
+TLI_DEFINE_VECFUNC("acosh", "__acoshd2_massv", 2)
+TLI_DEFINE_VECFUNC("acoshf", "__acoshf4_massv", 4)
+TLI_DEFINE_VECFUNC("atanh", "__atanhd2_massv", 2)
+TLI_DEFINE_VECFUNC("atanhf", "__atanhf4_massv", 4)
+
+
+#elif defined(TLI_DEFINE_SVML_VECFUNCS)
+// Intel SVM library's Vector Functions
+
+TLI_DEFINE_VECFUNC("sin", "__svml_sin2", 2)
+TLI_DEFINE_VECFUNC("sin", "__svml_sin4", 4)
+TLI_DEFINE_VECFUNC("sin", "__svml_sin8", 8)
+
+TLI_DEFINE_VECFUNC("sinf", "__svml_sinf4", 4)
+TLI_DEFINE_VECFUNC("sinf", "__svml_sinf8", 8)
+TLI_DEFINE_VECFUNC("sinf", "__svml_sinf16", 16)
+
+TLI_DEFINE_VECFUNC("llvm.sin.f64", "__svml_sin2", 2)
+TLI_DEFINE_VECFUNC("llvm.sin.f64", "__svml_sin4", 4)
+TLI_DEFINE_VECFUNC("llvm.sin.f64", "__svml_sin8", 8)
+
+TLI_DEFINE_VECFUNC("llvm.sin.f32", "__svml_sinf4", 4)
+TLI_DEFINE_VECFUNC("llvm.sin.f32", "__svml_sinf8", 8)
+TLI_DEFINE_VECFUNC("llvm.sin.f32", "__svml_sinf16", 16)
+
+TLI_DEFINE_VECFUNC("cos", "__svml_cos2", 2)
+TLI_DEFINE_VECFUNC("cos", "__svml_cos4", 4)
+TLI_DEFINE_VECFUNC("cos", "__svml_cos8", 8)
+
+TLI_DEFINE_VECFUNC("cosf", "__svml_cosf4", 4)
+TLI_DEFINE_VECFUNC("cosf", "__svml_cosf8", 8)
+TLI_DEFINE_VECFUNC("cosf", "__svml_cosf16", 16)
+
+TLI_DEFINE_VECFUNC("llvm.cos.f64", "__svml_cos2", 2)
+TLI_DEFINE_VECFUNC("llvm.cos.f64", "__svml_cos4", 4)
+TLI_DEFINE_VECFUNC("llvm.cos.f64", "__svml_cos8", 8)
+
+TLI_DEFINE_VECFUNC("llvm.cos.f32", "__svml_cosf4", 4)
+TLI_DEFINE_VECFUNC("llvm.cos.f32", "__svml_cosf8", 8)
+TLI_DEFINE_VECFUNC("llvm.cos.f32", "__svml_cosf16", 16)
+
+TLI_DEFINE_VECFUNC("pow", "__svml_pow2", 2)
+TLI_DEFINE_VECFUNC("pow", "__svml_pow4", 4)
+TLI_DEFINE_VECFUNC("pow", "__svml_pow8", 8)
+
+TLI_DEFINE_VECFUNC("powf", "__svml_powf4", 4)
+TLI_DEFINE_VECFUNC("powf", "__svml_powf8", 8)
+TLI_DEFINE_VECFUNC("powf", "__svml_powf16", 16)
+
+TLI_DEFINE_VECFUNC("__pow_finite", "__svml_pow2", 2)
+TLI_DEFINE_VECFUNC("__pow_finite", "__svml_pow4", 4)
+TLI_DEFINE_VECFUNC("__pow_finite", "__svml_pow8", 8)
+
+TLI_DEFINE_VECFUNC("__powf_finite", "__svml_powf4", 4)
+TLI_DEFINE_VECFUNC("__powf_finite", "__svml_powf8", 8)
+TLI_DEFINE_VECFUNC("__powf_finite", "__svml_powf16", 16)
+
+TLI_DEFINE_VECFUNC("llvm.pow.f64", "__svml_pow2", 2)
+TLI_DEFINE_VECFUNC("llvm.pow.f64", "__svml_pow4", 4)
+TLI_DEFINE_VECFUNC("llvm.pow.f64", "__svml_pow8", 8)
+
+TLI_DEFINE_VECFUNC("llvm.pow.f32", "__svml_powf4", 4)
+TLI_DEFINE_VECFUNC("llvm.pow.f32", "__svml_powf8", 8)
+TLI_DEFINE_VECFUNC("llvm.pow.f32", "__svml_powf16", 16)
+
+TLI_DEFINE_VECFUNC("exp", "__svml_exp2", 2)
+TLI_DEFINE_VECFUNC("exp", "__svml_exp4", 4)
+TLI_DEFINE_VECFUNC("exp", "__svml_exp8", 8)
+
+TLI_DEFINE_VECFUNC("expf", "__svml_expf4", 4)
+TLI_DEFINE_VECFUNC("expf", "__svml_expf8", 8)
+TLI_DEFINE_VECFUNC("expf", "__svml_expf16", 16)
+
+TLI_DEFINE_VECFUNC("__exp_finite", "__svml_exp2", 2)
+TLI_DEFINE_VECFUNC("__exp_finite", "__svml_exp4", 4)
+TLI_DEFINE_VECFUNC("__exp_finite", "__svml_exp8", 8)
+
+TLI_DEFINE_VECFUNC("__expf_finite", "__svml_expf4", 4)
+TLI_DEFINE_VECFUNC("__expf_finite", "__svml_expf8", 8)
+TLI_DEFINE_VECFUNC("__expf_finite", "__svml_expf16", 16)
+
+TLI_DEFINE_VECFUNC("llvm.exp.f64", "__svml_exp2", 2)
+TLI_DEFINE_VECFUNC("llvm.exp.f64", "__svml_exp4", 4)
+TLI_DEFINE_VECFUNC("llvm.exp.f64", "__svml_exp8", 8)
+
+TLI_DEFINE_VECFUNC("llvm.exp.f32", "__svml_expf4", 4)
+TLI_DEFINE_VECFUNC("llvm.exp.f32", "__svml_expf8", 8)
+TLI_DEFINE_VECFUNC("llvm.exp.f32", "__svml_expf16", 16)
+
+TLI_DEFINE_VECFUNC("log", "__svml_log2", 2)
+TLI_DEFINE_VECFUNC("log", "__svml_log4", 4)
+TLI_DEFINE_VECFUNC("log", "__svml_log8", 8)
+
+TLI_DEFINE_VECFUNC("logf", "__svml_logf4", 4)
+TLI_DEFINE_VECFUNC("logf", "__svml_logf8", 8)
+TLI_DEFINE_VECFUNC("logf", "__svml_logf16", 16)
+
+TLI_DEFINE_VECFUNC("__log_finite", "__svml_log2", 2)
+TLI_DEFINE_VECFUNC("__log_finite", "__svml_log4", 4)
+TLI_DEFINE_VECFUNC("__log_finite", "__svml_log8", 8)
+
+TLI_DEFINE_VECFUNC("__logf_finite", "__svml_logf4", 4)
+TLI_DEFINE_VECFUNC("__logf_finite", "__svml_logf8", 8)
+TLI_DEFINE_VECFUNC("__logf_finite", "__svml_logf16", 16)
+
+TLI_DEFINE_VECFUNC("llvm.log.f64", "__svml_log2", 2)
+TLI_DEFINE_VECFUNC("llvm.log.f64", "__svml_log4", 4)
+TLI_DEFINE_VECFUNC("llvm.log.f64", "__svml_log8", 8)
+
+TLI_DEFINE_VECFUNC("llvm.log.f32", "__svml_logf4", 4)
+TLI_DEFINE_VECFUNC("llvm.log.f32", "__svml_logf8", 8)
+TLI_DEFINE_VECFUNC("llvm.log.f32", "__svml_logf16", 16)
+
+
+#else
+#error "Must choose which vector library functions are to be defined."
+#endif
+
+#undef TLI_DEFINE_VECFUNC
+#undef TLI_DEFINE_ACCELERATE_VECFUNCS
+#undef TLI_DEFINE_MASSV_VECFUNCS
+#undef TLI_DEFINE_SVML_VECFUNCS
+
diff --git a/include/llvm/Analysis/VectorUtils.h b/include/llvm/Analysis/VectorUtils.h
index be4d4f17b9ad..d93d2bc4570b 100644
--- a/include/llvm/Analysis/VectorUtils.h
+++ b/include/llvm/Analysis/VectorUtils.h
@@ -1,9 +1,8 @@
//===- llvm/Analysis/VectorUtils.h - Vector utilities -----------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -18,6 +17,7 @@
#include "llvm/Analysis/LoopAccessAnalysis.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/IRBuilder.h"
+#include "llvm/Support/CheckedArithmetic.h"
namespace llvm {
@@ -36,13 +36,12 @@ enum ID : unsigned;
}
/// Identify if the intrinsic is trivially vectorizable.
-/// This method returns true if the intrinsic's argument types are all
-/// scalars for the scalar form of the intrinsic and all vectors for
-/// the vector form of the intrinsic.
+/// This method returns true if the intrinsic's argument types are all scalars
+/// for the scalar form of the intrinsic and all vectors (or scalars handled by
+/// hasVectorInstrinsicScalarOpd) for the vector form of the intrinsic.
bool isTriviallyVectorizable(Intrinsic::ID ID);
-/// Identifies if the intrinsic has a scalar operand. It checks for
-/// ctlz,cttz and powi special intrinsics whose argument is scalar.
+/// Identifies if the vector form of the intrinsic has a scalar operand.
bool hasVectorInstrinsicScalarOpd(Intrinsic::ID ID, unsigned ScalarOpdIdx);
/// Returns intrinsic ID for call.
@@ -78,6 +77,12 @@ Value *findScalarElement(Value *V, unsigned EltNo);
/// a sequence of instructions that broadcast a single value into a vector.
const Value *getSplatValue(const Value *V);
+/// Return true if the input value is known to be a vector with all identical
+/// elements (potentially including undefined elements).
+/// This may be more powerful than the related getSplatValue() because it is
+/// not limited by finding a scalar source value to a splatted vector.
+bool isSplatValue(const Value *V, unsigned Depth = 0);
+
/// Compute a map of integer instructions to their minimum legal type
/// size.
///
@@ -223,6 +228,20 @@ Constant *createSequentialMask(IRBuilder<> &Builder, unsigned Start,
/// elements, it will be padded with undefs.
Value *concatenateVectors(IRBuilder<> &Builder, ArrayRef<Value *> Vecs);
+/// Given a mask vector of the form <Y x i1>, Return true if all of the
+/// elements of this predicate mask are false or undef. That is, return true
+/// if all lanes can be assumed inactive.
+bool maskIsAllZeroOrUndef(Value *Mask);
+
+/// Given a mask vector of the form <Y x i1>, Return true if all of the
+/// elements of this predicate mask are true or undef. That is, return true
+/// if all lanes can be assumed active.
+bool maskIsAllOneOrUndef(Value *Mask);
+
+/// Given a mask vector of the form <Y x i1>, return an APInt (of bitwidth Y)
+/// for each lane which may be active.
+APInt possiblyDemandedEltsInMask(Value *Mask);
+
/// The group of interleaved loads/stores sharing the same stride and
/// close to each other.
///
@@ -251,10 +270,10 @@ Value *concatenateVectors(IRBuilder<> &Builder, ArrayRef<Value *> Vecs);
/// the interleaved store group doesn't allow gaps.
template <typename InstTy> class InterleaveGroup {
public:
- InterleaveGroup(unsigned Factor, bool Reverse, unsigned Align)
+ InterleaveGroup(uint32_t Factor, bool Reverse, uint32_t Align)
: Factor(Factor), Reverse(Reverse), Align(Align), InsertPos(nullptr) {}
- InterleaveGroup(InstTy *Instr, int Stride, unsigned Align)
+ InterleaveGroup(InstTy *Instr, int32_t Stride, uint32_t Align)
: Align(Align), InsertPos(Instr) {
assert(Align && "The alignment should be non-zero");
@@ -266,19 +285,23 @@ public:
}
bool isReverse() const { return Reverse; }
- unsigned getFactor() const { return Factor; }
- unsigned getAlignment() const { return Align; }
- unsigned getNumMembers() const { return Members.size(); }
+ uint32_t getFactor() const { return Factor; }
+ uint32_t getAlignment() const { return Align; }
+ uint32_t getNumMembers() const { return Members.size(); }
/// Try to insert a new member \p Instr with index \p Index and
/// alignment \p NewAlign. The index is related to the leader and it could be
/// negative if it is the new leader.
///
/// \returns false if the instruction doesn't belong to the group.
- bool insertMember(InstTy *Instr, int Index, unsigned NewAlign) {
+ bool insertMember(InstTy *Instr, int32_t Index, uint32_t NewAlign) {
assert(NewAlign && "The new member's alignment should be non-zero");
- int Key = Index + SmallestKey;
+ // Make sure the key fits in an int32_t.
+ Optional<int32_t> MaybeKey = checkedAdd(Index, SmallestKey);
+ if (!MaybeKey)
+ return false;
+ int32_t Key = *MaybeKey;
// Skip if there is already a member with the same index.
if (Members.find(Key) != Members.end())
@@ -286,13 +309,19 @@ public:
if (Key > LargestKey) {
// The largest index is always less than the interleave factor.
- if (Index >= static_cast<int>(Factor))
+ if (Index >= static_cast<int32_t>(Factor))
return false;
LargestKey = Key;
} else if (Key < SmallestKey) {
+
+ // Make sure the largest index fits in an int32_t.
+ Optional<int32_t> MaybeLargestIndex = checkedSub(LargestKey, Key);
+ if (!MaybeLargestIndex)
+ return false;
+
// The largest index is always less than the interleave factor.
- if (LargestKey - Key >= static_cast<int>(Factor))
+ if (*MaybeLargestIndex >= static_cast<int64_t>(Factor))
return false;
SmallestKey = Key;
@@ -307,8 +336,8 @@ public:
/// Get the member with the given index \p Index
///
/// \returns nullptr if contains no such member.
- InstTy *getMember(unsigned Index) const {
- int Key = SmallestKey + Index;
+ InstTy *getMember(uint32_t Index) const {
+ int32_t Key = SmallestKey + Index;
auto Member = Members.find(Key);
if (Member == Members.end())
return nullptr;
@@ -318,7 +347,7 @@ public:
/// Get the index for the given member. Unlike the key in the member
/// map, the index starts from 0.
- unsigned getIndex(const InstTy *Instr) const {
+ uint32_t getIndex(const InstTy *Instr) const {
for (auto I : Members) {
if (I.second == Instr)
return I.first - SmallestKey;
@@ -356,12 +385,12 @@ public:
}
private:
- unsigned Factor; // Interleave Factor.
+ uint32_t Factor; // Interleave Factor.
bool Reverse;
- unsigned Align;
- DenseMap<int, InstTy *> Members;
- int SmallestKey = 0;
- int LargestKey = 0;
+ uint32_t Align;
+ DenseMap<int32_t, InstTy *> Members;
+ int32_t SmallestKey = 0;
+ int32_t LargestKey = 0;
// To avoid breaking dependences, vectorized instructions of an interleave
// group should be inserted at either the first load or the last store in