summaryrefslogtreecommitdiff
path: root/include/llvm/Transforms
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-12-18 20:10:56 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-12-18 20:10:56 +0000
commit044eb2f6afba375a914ac9d8024f8f5142bb912e (patch)
tree1475247dc9f9fe5be155ebd4c9069c75aadf8c20 /include/llvm/Transforms
parenteb70dddbd77e120e5d490bd8fbe7ff3f8fa81c6b (diff)
Notes
Diffstat (limited to 'include/llvm/Transforms')
-rw-r--r--include/llvm/Transforms/IPO.h4
-rw-r--r--include/llvm/Transforms/IPO/ArgumentPromotion.h5
-rw-r--r--include/llvm/Transforms/IPO/CalledValuePropagation.h35
-rw-r--r--include/llvm/Transforms/IPO/ConstantMerge.h6
-rw-r--r--include/llvm/Transforms/IPO/DeadArgumentElimination.h39
-rw-r--r--include/llvm/Transforms/IPO/ElimAvailExtern.h6
-rw-r--r--include/llvm/Transforms/IPO/FunctionAttrs.h10
-rw-r--r--include/llvm/Transforms/IPO/FunctionImport.h37
-rw-r--r--include/llvm/Transforms/IPO/GlobalDCE.h2
-rw-r--r--include/llvm/Transforms/IPO/GlobalOpt.h5
-rw-r--r--include/llvm/Transforms/IPO/GlobalSplit.h8
-rw-r--r--include/llvm/Transforms/IPO/Inliner.h17
-rw-r--r--include/llvm/Transforms/IPO/LowerTypeTests.h2
-rw-r--r--include/llvm/Transforms/IPO/PartialInlining.h9
-rw-r--r--include/llvm/Transforms/IPO/SCCP.h8
-rw-r--r--include/llvm/Transforms/Instrumentation.h44
-rw-r--r--include/llvm/Transforms/Instrumentation/BoundsChecking.h29
-rw-r--r--include/llvm/Transforms/PGOInstrumentation.h26
-rw-r--r--include/llvm/Transforms/SampleProfile.h17
-rw-r--r--include/llvm/Transforms/Scalar.h48
-rw-r--r--include/llvm/Transforms/Scalar/ADCE.h8
-rw-r--r--include/llvm/Transforms/Scalar/CallSiteSplitting.h29
-rw-r--r--include/llvm/Transforms/Scalar/ConstantHoisting.h44
-rw-r--r--include/llvm/Transforms/Scalar/CorrelatedValuePropagation.h8
-rw-r--r--include/llvm/Transforms/Scalar/DeadStoreElimination.h14
-rw-r--r--include/llvm/Transforms/Scalar/DivRemPairs.h31
-rw-r--r--include/llvm/Transforms/Scalar/EarlyCSE.h10
-rw-r--r--include/llvm/Transforms/Scalar/GVN.h93
-rw-r--r--include/llvm/Transforms/Scalar/GVNExpression.h80
-rw-r--r--include/llvm/Transforms/Scalar/IndVarSimplify.h9
-rw-r--r--include/llvm/Transforms/Scalar/JumpThreading.h37
-rw-r--r--include/llvm/Transforms/Scalar/LoopDistribute.h3
-rw-r--r--include/llvm/Transforms/Scalar/LoopIdiomRecognize.h9
-rw-r--r--include/llvm/Transforms/Scalar/LoopInstSimplify.h9
-rw-r--r--include/llvm/Transforms/Scalar/LoopLoadElimination.h10
-rw-r--r--include/llvm/Transforms/Scalar/LoopPassManager.h30
-rw-r--r--include/llvm/Transforms/Scalar/LoopStrengthReduce.h9
-rw-r--r--include/llvm/Transforms/Scalar/LoopUnrollPass.h44
-rw-r--r--include/llvm/Transforms/Scalar/LowerExpectIntrinsic.h2
-rw-r--r--include/llvm/Transforms/Scalar/MemCpyOptimizer.h24
-rw-r--r--include/llvm/Transforms/Scalar/NaryReassociate.h31
-rw-r--r--include/llvm/Transforms/Scalar/NewGVN.h11
-rw-r--r--include/llvm/Transforms/Scalar/Reassociate.h28
-rw-r--r--include/llvm/Transforms/Scalar/RewriteStatepointsForGC.h39
-rw-r--r--include/llvm/Transforms/Scalar/SCCP.h10
-rw-r--r--include/llvm/Transforms/Scalar/SROA.h16
-rw-r--r--include/llvm/Transforms/Scalar/SimpleLoopUnswitch.h6
-rw-r--r--include/llvm/Transforms/Scalar/SimplifyCFG.h34
-rw-r--r--include/llvm/Transforms/Scalar/SpeculateAroundPHIs.h111
-rw-r--r--include/llvm/Transforms/Utils/AddDiscriminators.h5
-rw-r--r--include/llvm/Transforms/Utils/BasicBlockUtils.h36
-rw-r--r--include/llvm/Transforms/Utils/BypassSlowDivision.h42
-rw-r--r--include/llvm/Transforms/Utils/CallPromotionUtils.h44
-rw-r--r--include/llvm/Transforms/Utils/Cloning.h8
-rw-r--r--include/llvm/Transforms/Utils/CmpInstAnalysis.h70
-rw-r--r--include/llvm/Transforms/Utils/CodeExtractor.h64
-rw-r--r--include/llvm/Transforms/Utils/EntryExitInstrumenter.h36
-rw-r--r--include/llvm/Transforms/Utils/Evaluator.h11
-rw-r--r--include/llvm/Transforms/Utils/FunctionComparator.h29
-rw-r--r--include/llvm/Transforms/Utils/Local.h172
-rw-r--r--include/llvm/Transforms/Utils/LoopUtils.h68
-rw-r--r--include/llvm/Transforms/Utils/LowerMemIntrinsics.h6
-rw-r--r--include/llvm/Transforms/Utils/Mem2Reg.h7
-rw-r--r--include/llvm/Transforms/Utils/ModuleUtils.h3
-rw-r--r--include/llvm/Transforms/Utils/SSAUpdater.h29
-rw-r--r--include/llvm/Transforms/Utils/SSAUpdaterImpl.h75
-rw-r--r--include/llvm/Transforms/Utils/SimplifyIndVar.h3
-rw-r--r--include/llvm/Transforms/Utils/SimplifyLibCalls.h8
-rw-r--r--include/llvm/Transforms/Utils/SplitModule.h5
-rw-r--r--include/llvm/Transforms/Utils/SymbolRewriter.h8
-rw-r--r--include/llvm/Transforms/Utils/UnrollLoop.h48
-rw-r--r--include/llvm/Transforms/Utils/ValueMapper.h16
-rw-r--r--include/llvm/Transforms/Vectorize/LoopVectorize.h31
-rw-r--r--include/llvm/Transforms/Vectorize/SLPVectorizer.h73
74 files changed, 1441 insertions, 602 deletions
diff --git a/include/llvm/Transforms/IPO.h b/include/llvm/Transforms/IPO.h
index 39ceb19525b3c..ce20a726b7832 100644
--- a/include/llvm/Transforms/IPO.h
+++ b/include/llvm/Transforms/IPO.h
@@ -216,6 +216,10 @@ ModulePass *createMetaRenamerPass();
/// manager.
ModulePass *createBarrierNoopPass();
+/// createCalledValuePropagationPass - Attach metadata to indirct call sites
+/// indicating the set of functions they may target at run-time.
+ModulePass *createCalledValuePropagationPass();
+
/// What to do with the summary when running passes that operate on it.
enum class PassSummaryAction {
None, ///< Do nothing.
diff --git a/include/llvm/Transforms/IPO/ArgumentPromotion.h b/include/llvm/Transforms/IPO/ArgumentPromotion.h
index 724ff72f3b5a1..82ffc69a166ee 100644
--- a/include/llvm/Transforms/IPO/ArgumentPromotion.h
+++ b/include/llvm/Transforms/IPO/ArgumentPromotion.h
@@ -12,6 +12,7 @@
#include "llvm/Analysis/CGSCCPassManager.h"
#include "llvm/Analysis/LazyCallGraph.h"
+#include "llvm/IR/PassManager.h"
namespace llvm {
@@ -26,6 +27,6 @@ public:
LazyCallGraph &CG, CGSCCUpdateResult &UR);
};
-}
+} // end namespace llvm
-#endif
+#endif // LLVM_TRANSFORMS_IPO_ARGUMENTPROMOTION_H
diff --git a/include/llvm/Transforms/IPO/CalledValuePropagation.h b/include/llvm/Transforms/IPO/CalledValuePropagation.h
new file mode 100644
index 0000000000000..352bdc7ac17f1
--- /dev/null
+++ b/include/llvm/Transforms/IPO/CalledValuePropagation.h
@@ -0,0 +1,35 @@
+//===- CalledValuePropagation.h - Propagate called values -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a transformation that attaches !callees metadata to
+// indirect call sites. For a given call site, the metadata, if present,
+// indicates the set of functions the call site could possibly target at
+// run-time. This metadata is added to indirect call sites when the set of
+// possible targets can be determined by analysis and is known to be small. The
+// analysis driving the transformation is similar to constant propagation and
+// makes uses of the generic sparse propagation solver.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_CALLEDVALUEPROPAGATION_H
+#define LLVM_TRANSFORMS_IPO_CALLEDVALUEPROPAGATION_H
+
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class CalledValuePropagationPass
+ : public PassInfoMixin<CalledValuePropagationPass> {
+public:
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
+};
+} // namespace llvm
+
+#endif // LLVM_TRANSFORMS_IPO_CALLEDVALUEPROPAGATION_H
diff --git a/include/llvm/Transforms/IPO/ConstantMerge.h b/include/llvm/Transforms/IPO/ConstantMerge.h
index 1d4da43f6a7bb..e04d3ae1a40ed 100644
--- a/include/llvm/Transforms/IPO/ConstantMerge.h
+++ b/include/llvm/Transforms/IPO/ConstantMerge.h
@@ -20,16 +20,18 @@
#ifndef LLVM_TRANSFORMS_IPO_CONSTANTMERGE_H
#define LLVM_TRANSFORMS_IPO_CONSTANTMERGE_H
-#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
namespace llvm {
+class Module;
+
/// A pass that merges duplicate global constants into a single constant.
class ConstantMergePass : public PassInfoMixin<ConstantMergePass> {
public:
PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
};
-}
+
+} // end namespace llvm
#endif // LLVM_TRANSFORMS_IPO_CONSTANTMERGE_H
diff --git a/include/llvm/Transforms/IPO/DeadArgumentElimination.h b/include/llvm/Transforms/IPO/DeadArgumentElimination.h
index e179afa956f6e..ba5666f20a9bf 100644
--- a/include/llvm/Transforms/IPO/DeadArgumentElimination.h
+++ b/include/llvm/Transforms/IPO/DeadArgumentElimination.h
@@ -20,15 +20,21 @@
#ifndef LLVM_TRANSFORMS_IPO_DEADARGUMENTELIMINATION_H
#define LLVM_TRANSFORMS_IPO_DEADARGUMENTELIMINATION_H
-#include "llvm/IR/Module.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/IR/Function.h"
#include "llvm/IR/PassManager.h"
-
#include <map>
#include <set>
#include <string>
+#include <tuple>
namespace llvm {
+class Module;
+class Use;
+class Value;
+
/// Eliminate dead arguments (and return values) from functions.
class DeadArgumentEliminationPass
: public PassInfoMixin<DeadArgumentEliminationPass> {
@@ -37,12 +43,13 @@ public:
/// argument. Used so that arguments and return values can be used
/// interchangeably.
struct RetOrArg {
- RetOrArg(const Function *F, unsigned Idx, bool IsArg)
- : F(F), Idx(Idx), IsArg(IsArg) {}
const Function *F;
unsigned Idx;
bool IsArg;
+ RetOrArg(const Function *F, unsigned Idx, bool IsArg)
+ : F(F), Idx(Idx), IsArg(IsArg) {}
+
/// Make RetOrArg comparable, so we can put it into a map.
bool operator<(const RetOrArg &O) const {
return std::tie(F, Idx, IsArg) < std::tie(O.F, O.Idx, O.IsArg);
@@ -67,16 +74,23 @@ public:
/// thus become dead in the end.
enum Liveness { Live, MaybeLive };
+ DeadArgumentEliminationPass(bool ShouldHackArguments_ = false)
+ : ShouldHackArguments(ShouldHackArguments_) {}
+
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
+
/// Convenience wrapper
RetOrArg CreateRet(const Function *F, unsigned Idx) {
return RetOrArg(F, Idx, false);
}
+
/// Convenience wrapper
RetOrArg CreateArg(const Function *F, unsigned Idx) {
return RetOrArg(F, Idx, true);
}
- typedef std::multimap<RetOrArg, RetOrArg> UseMap;
+ using UseMap = std::multimap<RetOrArg, RetOrArg>;
+
/// This maps a return value or argument to any MaybeLive return values or
/// arguments it uses. This allows the MaybeLive values to be marked live
/// when any of its users is marked live.
@@ -93,25 +107,21 @@ public:
/// directly to F.
UseMap Uses;
- typedef std::set<RetOrArg> LiveSet;
- typedef std::set<const Function *> LiveFuncSet;
+ using LiveSet = std::set<RetOrArg>;
+ using LiveFuncSet = std::set<const Function *>;
/// This set contains all values that have been determined to be live.
LiveSet LiveValues;
+
/// This set contains all values that are cannot be changed in any way.
LiveFuncSet LiveFunctions;
- typedef SmallVector<RetOrArg, 5> UseVector;
+ using UseVector = SmallVector<RetOrArg, 5>;
/// This allows this pass to do double-duty as the dead arg hacking pass
/// (used only by bugpoint).
bool ShouldHackArguments = false;
-public:
- DeadArgumentEliminationPass(bool ShouldHackArguments_ = false)
- : ShouldHackArguments(ShouldHackArguments_) {}
- PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
-
private:
Liveness MarkIfNotLive(RetOrArg Use, UseVector &MaybeLiveUses);
Liveness SurveyUse(const Use *U, UseVector &MaybeLiveUses,
@@ -128,6 +138,7 @@ private:
bool DeleteDeadVarargs(Function &Fn);
bool RemoveDeadArgumentsFromCallers(Function &Fn);
};
-}
+
+} // end namespace llvm
#endif // LLVM_TRANSFORMS_IPO_DEADARGUMENTELIMINATION_H
diff --git a/include/llvm/Transforms/IPO/ElimAvailExtern.h b/include/llvm/Transforms/IPO/ElimAvailExtern.h
index 88a0e9bd8ce0f..94cb954fd2d5a 100644
--- a/include/llvm/Transforms/IPO/ElimAvailExtern.h
+++ b/include/llvm/Transforms/IPO/ElimAvailExtern.h
@@ -15,17 +15,19 @@
#ifndef LLVM_TRANSFORMS_IPO_ELIMAVAILEXTERN_H
#define LLVM_TRANSFORMS_IPO_ELIMAVAILEXTERN_H
-#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
namespace llvm {
+class Module;
+
/// A pass that transforms external global definitions into declarations.
class EliminateAvailableExternallyPass
: public PassInfoMixin<EliminateAvailableExternallyPass> {
public:
PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
};
-}
+
+} // end namespace llvm
#endif // LLVM_TRANSFORMS_IPO_ELIMAVAILEXTERN_H
diff --git a/include/llvm/Transforms/IPO/FunctionAttrs.h b/include/llvm/Transforms/IPO/FunctionAttrs.h
index 36dd06b85b417..dc9f18c794107 100644
--- a/include/llvm/Transforms/IPO/FunctionAttrs.h
+++ b/include/llvm/Transforms/IPO/FunctionAttrs.h
@@ -1,4 +1,4 @@
-//===-- FunctionAttrs.h - Compute function attrs --------------------------===//
+//===- FunctionAttrs.h - Compute function attributes ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,9 +6,11 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
/// \file
/// Provides passes for computing function attributes based on interprocedural
/// analyses.
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TRANSFORMS_IPO_FUNCTIONATTRS_H
@@ -21,6 +23,9 @@
namespace llvm {
class AAResults;
+class Function;
+class Module;
+class Pass;
/// The three kinds of memory access relevant to 'readonly' and
/// 'readnone' attributes.
@@ -66,6 +71,7 @@ class ReversePostOrderFunctionAttrsPass
public:
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
};
-}
+
+} // end namespace llvm
#endif // LLVM_TRANSFORMS_IPO_FUNCTIONATTRS_H
diff --git a/include/llvm/Transforms/IPO/FunctionImport.h b/include/llvm/Transforms/IPO/FunctionImport.h
index de35cdf052e1f..39e5b5c8ae6f1 100644
--- a/include/llvm/Transforms/IPO/FunctionImport.h
+++ b/include/llvm/Transforms/IPO/FunctionImport.h
@@ -7,23 +7,26 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_FUNCTIONIMPORT_H
-#define LLVM_FUNCTIONIMPORT_H
+#ifndef LLVM_TRANSFORMS_IPO_FUNCTIONIMPORT_H
+#define LLVM_TRANSFORMS_IPO_FUNCTIONIMPORT_H
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/ModuleSummaryIndex.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Support/Error.h"
-
#include <functional>
#include <map>
+#include <memory>
+#include <string>
+#include <system_error>
#include <unordered_set>
#include <utility>
namespace llvm {
-class LLVMContext;
-class GlobalValueSummary;
+
class Module;
/// The function importer is automatically importing function from other modules
@@ -34,19 +37,19 @@ public:
/// containing all the functions to import for a source module.
/// The keys is the GUID identifying a function to import, and the value
/// is the threshold applied when deciding to import it.
- typedef std::map<GlobalValue::GUID, unsigned> FunctionsToImportTy;
+ using FunctionsToImportTy = std::map<GlobalValue::GUID, unsigned>;
/// The map contains an entry for every module to import from, the key being
/// the module identifier to pass to the ModuleLoader. The value is the set of
/// functions to import.
- typedef StringMap<FunctionsToImportTy> ImportMapTy;
+ using ImportMapTy = StringMap<FunctionsToImportTy>;
/// The set contains an entry for every global value the module exports.
- typedef std::unordered_set<GlobalValue::GUID> ExportSetTy;
+ using ExportSetTy = std::unordered_set<GlobalValue::GUID>;
/// A function of this type is used to load modules referenced by the index.
- typedef std::function<Expected<std::unique_ptr<Module>>(StringRef Identifier)>
- ModuleLoaderTy;
+ using ModuleLoaderTy =
+ std::function<Expected<std::unique_ptr<Module>>(StringRef Identifier)>;
/// Create a Function Importer.
FunctionImporter(const ModuleSummaryIndex &Index, ModuleLoaderTy ModuleLoader)
@@ -95,6 +98,15 @@ void ComputeCrossModuleImportForModule(
StringRef ModulePath, const ModuleSummaryIndex &Index,
FunctionImporter::ImportMapTy &ImportList);
+/// Mark all external summaries in \p Index for import into the given module.
+/// Used for distributed builds using a distributed index.
+///
+/// \p ImportList will be populated with a map that can be passed to
+/// FunctionImporter::importFunctions() above (see description there).
+void ComputeCrossModuleImportForModuleFromIndex(
+ StringRef ModulePath, const ModuleSummaryIndex &Index,
+ FunctionImporter::ImportMapTy &ImportList);
+
/// Compute all the symbols that are "dead": i.e these that can't be reached
/// in the graph from any of the given symbols listed in
/// \p GUIDPreservedSymbols.
@@ -132,6 +144,7 @@ void thinLTOResolveWeakForLinkerModule(Module &TheModule,
/// during global summary-based analysis.
void thinLTOInternalizeModule(Module &TheModule,
const GVSummaryMapTy &DefinedGlobals);
-}
-#endif // LLVM_FUNCTIONIMPORT_H
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_IPO_FUNCTIONIMPORT_H
diff --git a/include/llvm/Transforms/IPO/GlobalDCE.h b/include/llvm/Transforms/IPO/GlobalDCE.h
index 9ca939c15b62e..7ca241f4645a9 100644
--- a/include/llvm/Transforms/IPO/GlobalDCE.h
+++ b/include/llvm/Transforms/IPO/GlobalDCE.h
@@ -35,7 +35,7 @@ private:
SmallPtrSet<GlobalValue*, 32> AliveGlobals;
/// Global -> Global that uses this global.
- std::unordered_multimap<GlobalValue *, GlobalValue *> GVDependencies;
+ DenseMap<GlobalValue *, SmallPtrSet<GlobalValue *, 4>> GVDependencies;
/// Constant -> Globals that use this global cache.
std::unordered_map<Constant *, SmallPtrSet<GlobalValue *, 8>>
diff --git a/include/llvm/Transforms/IPO/GlobalOpt.h b/include/llvm/Transforms/IPO/GlobalOpt.h
index ab9116810be1b..5b4878604eab1 100644
--- a/include/llvm/Transforms/IPO/GlobalOpt.h
+++ b/include/llvm/Transforms/IPO/GlobalOpt.h
@@ -16,17 +16,18 @@
#ifndef LLVM_TRANSFORMS_IPO_GLOBALOPT_H
#define LLVM_TRANSFORMS_IPO_GLOBALOPT_H
-#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
namespace llvm {
+class Module;
+
/// Optimize globals that never have their address taken.
class GlobalOptPass : public PassInfoMixin<GlobalOptPass> {
public:
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
};
-}
+} // end namespace llvm
#endif // LLVM_TRANSFORMS_IPO_GLOBALOPT_H
diff --git a/include/llvm/Transforms/IPO/GlobalSplit.h b/include/llvm/Transforms/IPO/GlobalSplit.h
index fb2c2d27338e0..56cefb7886fec 100644
--- a/include/llvm/Transforms/IPO/GlobalSplit.h
+++ b/include/llvm/Transforms/IPO/GlobalSplit.h
@@ -17,14 +17,18 @@
#ifndef LLVM_TRANSFORMS_IPO_GLOBALSPLIT_H
#define LLVM_TRANSFORMS_IPO_GLOBALSPLIT_H
-#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
namespace llvm {
+
+class Module;
+
/// Pass to perform split of global variables.
class GlobalSplitPass : public PassInfoMixin<GlobalSplitPass> {
public:
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
};
-}
+
+} // end namespace llvm
+
#endif // LLVM_TRANSFORMS_IPO_GLOBALSPLIT_H
diff --git a/include/llvm/Transforms/IPO/Inliner.h b/include/llvm/Transforms/IPO/Inliner.h
index b3ca5156e3883..eda8cf462b507 100644
--- a/include/llvm/Transforms/IPO/Inliner.h
+++ b/include/llvm/Transforms/IPO/Inliner.h
@@ -14,15 +14,15 @@
#include "llvm/Analysis/CallGraphSCCPass.h"
#include "llvm/Analysis/InlineCost.h"
#include "llvm/Analysis/LazyCallGraph.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/IR/CallSite.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/Transforms/Utils/ImportedFunctionsInliningStatistics.h"
+#include <utility>
namespace llvm {
+
class AssumptionCacheTracker;
-class CallSite;
-class DataLayout;
-class InlineCost;
-class OptimizationRemarkEmitter;
+class CallGraph;
class ProfileSummaryInfo;
/// This class contains all of the helper code which is used to perform the
@@ -44,6 +44,7 @@ struct LegacyInlinerBase : public CallGraphSCCPass {
bool runOnSCC(CallGraphSCC &SCC) override;
using llvm::Pass::doFinalization;
+
/// Remove now-dead linkonce functions at the end of processing to avoid
/// breaking the SCC traversal.
bool doFinalization(CallGraph &CG) override;
@@ -69,7 +70,7 @@ struct LegacyInlinerBase : public CallGraphSCCPass {
private:
// Insert @llvm.lifetime intrinsics.
- bool InsertLifetime;
+ bool InsertLifetime = true;
protected:
AssumptionCacheTracker *ACT;
@@ -103,6 +104,6 @@ private:
InlineParams Params;
};
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_TRANSFORMS_IPO_INLINER_H
diff --git a/include/llvm/Transforms/IPO/LowerTypeTests.h b/include/llvm/Transforms/IPO/LowerTypeTests.h
index a2b888ce9ffa3..3bcfe65df5502 100644
--- a/include/llvm/Transforms/IPO/LowerTypeTests.h
+++ b/include/llvm/Transforms/IPO/LowerTypeTests.h
@@ -16,7 +16,6 @@
#define LLVM_TRANSFORMS_IPO_LOWERTYPETESTS_H
#include "llvm/ADT/SmallVector.h"
-#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
#include <cstdint>
#include <cstring>
@@ -26,6 +25,7 @@
namespace llvm {
+class Module;
class raw_ostream;
namespace lowertypetests {
diff --git a/include/llvm/Transforms/IPO/PartialInlining.h b/include/llvm/Transforms/IPO/PartialInlining.h
index 15407fc36a225..ec6dd36dae06e 100644
--- a/include/llvm/Transforms/IPO/PartialInlining.h
+++ b/include/llvm/Transforms/IPO/PartialInlining.h
@@ -1,4 +1,4 @@
-//===- PartialInlining.h - Inline parts of functions --------------------===//
+//===- PartialInlining.h - Inline parts of functions ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,15 +15,18 @@
#ifndef LLVM_TRANSFORMS_IPO_PARTIALINLINING_H
#define LLVM_TRANSFORMS_IPO_PARTIALINLINING_H
-#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
namespace llvm {
+class Module;
+
/// Pass to remove unused function declarations.
class PartialInlinerPass : public PassInfoMixin<PartialInlinerPass> {
public:
PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
};
-}
+
+} // end namespace llvm
+
#endif // LLVM_TRANSFORMS_IPO_PARTIALINLINING_H
diff --git a/include/llvm/Transforms/IPO/SCCP.h b/include/llvm/Transforms/IPO/SCCP.h
index 7082006f14a6f..fdb7865fbac31 100644
--- a/include/llvm/Transforms/IPO/SCCP.h
+++ b/include/llvm/Transforms/IPO/SCCP.h
@@ -21,14 +21,18 @@
#ifndef LLVM_TRANSFORMS_IPO_SCCP_H
#define LLVM_TRANSFORMS_IPO_SCCP_H
-#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
namespace llvm {
+
+class Module;
+
/// Pass to perform interprocedural constant propagation.
class IPSCCPPass : public PassInfoMixin<IPSCCPPass> {
public:
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
};
-}
+
+} // end namespace llvm
+
#endif // LLVM_TRANSFORMS_IPO_SCCP_H
diff --git a/include/llvm/Transforms/Instrumentation.h b/include/llvm/Transforms/Instrumentation.h
index f2fc6dc8dad5e..cd6b770f76ac0 100644
--- a/include/llvm/Transforms/Instrumentation.h
+++ b/include/llvm/Transforms/Instrumentation.h
@@ -22,24 +22,11 @@
#include <string>
#include <vector>
-#if defined(__GNUC__) && defined(__linux__) && !defined(ANDROID)
-inline void *getDFSanArgTLSPtrForJIT() {
- extern __thread __attribute__((tls_model("initial-exec")))
- void *__dfsan_arg_tls;
- return (void *)&__dfsan_arg_tls;
-}
-
-inline void *getDFSanRetValTLSPtrForJIT() {
- extern __thread __attribute__((tls_model("initial-exec")))
- void *__dfsan_retval_tls;
- return (void *)&__dfsan_retval_tls;
-}
-#endif
-
namespace llvm {
class FunctionPass;
class ModulePass;
+class OptimizationRemarkEmitter;
/// Instrumentation passes often insert conditional checks into entry blocks.
/// Call this function before splitting the entry block to move instructions
@@ -90,9 +77,12 @@ ModulePass *createPGOIndirectCallPromotionLegacyPass(bool InLTO = false,
bool SamplePGO = false);
FunctionPass *createPGOMemOPSizeOptLegacyPass();
-// Helper function to check if it is legal to promote indirect call \p Inst
-// to a direct call of function \p F. Stores the reason in \p Reason.
-bool isLegalToPromote(Instruction *Inst, Function *F, const char **Reason);
+// The pgo-specific indirect call promotion function declared below is used by
+// the pgo-driven indirect call promotion and sample profile passes. It's a
+// wrapper around llvm::promoteCall, et al. that additionally computes !prof
+// metadata. We place it in a pgo namespace so it's not confused with the
+// generic utilities.
+namespace pgo {
// Helper function that transforms Inst (either an indirect-call instruction, or
// an invoke instruction , to a conditional call to F. This is like:
@@ -109,7 +99,9 @@ bool isLegalToPromote(Instruction *Inst, Function *F, const char **Reason);
// Returns the promoted direct call instruction.
Instruction *promoteIndirectCall(Instruction *Inst, Function *F, uint64_t Count,
uint64_t TotalCount,
- bool AttachProfToDirectCall);
+ bool AttachProfToDirectCall,
+ OptimizationRemarkEmitter *ORE);
+} // namespace pgo
/// Options for the frontend instrumentation based profiling pass.
struct InstrProfOptions {
@@ -141,6 +133,8 @@ ModulePass *createAddressSanitizerModulePass(bool CompileKernel = false,
FunctionPass *createMemorySanitizerPass(int TrackOrigins = 0,
bool Recover = false);
+FunctionPass *createHWAddressSanitizerPass();
+
// Insert ThreadSanitizer (race detection) instrumentation
FunctionPass *createThreadSanitizerPass();
@@ -181,7 +175,9 @@ struct SanitizerCoverageOptions {
bool TracePC = false;
bool TracePCGuard = false;
bool Inline8bitCounters = false;
+ bool PCTable = false;
bool NoPrune = false;
+ bool StackDepth = false;
SanitizerCoverageOptions() = default;
};
@@ -190,18 +186,6 @@ struct SanitizerCoverageOptions {
ModulePass *createSanitizerCoverageModulePass(
const SanitizerCoverageOptions &Options = SanitizerCoverageOptions());
-#if defined(__GNUC__) && defined(__linux__) && !defined(ANDROID)
-inline ModulePass *createDataFlowSanitizerPassForJIT(
- const std::vector<std::string> &ABIListFiles = std::vector<std::string>()) {
- return createDataFlowSanitizerPass(ABIListFiles, getDFSanArgTLSPtrForJIT,
- getDFSanRetValTLSPtrForJIT);
-}
-#endif
-
-// BoundsChecking - This pass instruments the code to perform run-time bounds
-// checking on loads, stores, and other memory intrinsics.
-FunctionPass *createBoundsCheckingPass();
-
/// \brief Calculate what to divide by to scale counts.
///
/// Given the maximum count, calculate a divisor that will scale all the
diff --git a/include/llvm/Transforms/Instrumentation/BoundsChecking.h b/include/llvm/Transforms/Instrumentation/BoundsChecking.h
new file mode 100644
index 0000000000000..3d4f62c121c25
--- /dev/null
+++ b/include/llvm/Transforms/Instrumentation/BoundsChecking.h
@@ -0,0 +1,29 @@
+//===- BoundsChecking.h - Bounds checking instrumentation -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_BOUNDSCHECKING_H
+#define LLVM_TRANSFORMS_INSTRUMENTATION_BOUNDSCHECKING_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+/// A pass to instrument code and perform run-time bounds checking on loads,
+/// stores, and other memory intrinsics.
+struct BoundsCheckingPass : PassInfoMixin<BoundsCheckingPass> {
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+
+
+/// Legacy pass creation function for the above pass.
+FunctionPass *createBoundsCheckingLegacyPass();
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_INSTRUMENTATION_BOUNDSCHECKING_H
diff --git a/include/llvm/Transforms/PGOInstrumentation.h b/include/llvm/Transforms/PGOInstrumentation.h
index 19263f0f8071d..c2cc76c422dae 100644
--- a/include/llvm/Transforms/PGOInstrumentation.h
+++ b/include/llvm/Transforms/PGOInstrumentation.h
@@ -1,4 +1,4 @@
-//===- Transforms/PGOInstrumentation.h - PGO gen/use passes ---*- C++ -*-===//
+//===- Transforms/PGOInstrumentation.h - PGO gen/use passes -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,19 +6,27 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
/// \file
/// This file provides the interface for IR based instrumentation passes (
/// (profile-gen, and profile-use).
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TRANSFORMS_PGOINSTRUMENTATION_H
#define LLVM_TRANSFORMS_PGOINSTRUMENTATION_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/IR/PassManager.h"
-#include "llvm/Transforms/Instrumentation.h"
+#include <cstdint>
+#include <string>
namespace llvm {
+class Function;
+class Instruction;
+class Module;
+
/// The instrumentation (profile-instr-gen) pass for IR based PGO.
class PGOInstrumentationGen : public PassInfoMixin<PGOInstrumentationGen> {
public:
@@ -28,9 +36,10 @@ public:
/// The profile annotation (profile-instr-use) pass for IR based PGO.
class PGOInstrumentationUse : public PassInfoMixin<PGOInstrumentationUse> {
public:
- PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
PGOInstrumentationUse(std::string Filename = "");
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+
private:
std::string ProfileFileName;
};
@@ -40,6 +49,7 @@ class PGOIndirectCallPromotion : public PassInfoMixin<PGOIndirectCallPromotion>
public:
PGOIndirectCallPromotion(bool IsInLTO = false, bool SamplePGO = false)
: InLTO(IsInLTO), SamplePGO(SamplePGO) {}
+
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
private:
@@ -50,12 +60,16 @@ private:
/// The profile size based optimization pass for memory intrinsics.
class PGOMemOPSizeOpt : public PassInfoMixin<PGOMemOPSizeOpt> {
public:
- PGOMemOPSizeOpt() {}
+ PGOMemOPSizeOpt() = default;
+
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};
void setProfMetadata(Module *M, Instruction *TI, ArrayRef<uint64_t> EdgeCounts,
uint64_t MaxCount);
-} // End llvm namespace
-#endif
+void setIrrLoopHeaderMetadata(Module *M, Instruction *TI, uint64_t Count);
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_PGOINSTRUMENTATION_H
diff --git a/include/llvm/Transforms/SampleProfile.h b/include/llvm/Transforms/SampleProfile.h
index c984fe74ba939..f5a8590e14a1c 100644
--- a/include/llvm/Transforms/SampleProfile.h
+++ b/include/llvm/Transforms/SampleProfile.h
@@ -1,4 +1,4 @@
-//===- Transforms/SampleProfile.h - SamplePGO pass--------------*- C++ -*-===//
+//===- Transforms/SampleProfile.h - SamplePGO pass --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,26 +6,35 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
/// \file
/// This file provides the interface for the sampled PGO loader pass.
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TRANSFORMS_SAMPLEPROFILE_H
#define LLVM_TRANSFORMS_SAMPLEPROFILE_H
#include "llvm/IR/PassManager.h"
+#include <string>
namespace llvm {
+class Module;
+
/// The sample profiler data loader pass.
class SampleProfileLoaderPass : public PassInfoMixin<SampleProfileLoaderPass> {
public:
+ SampleProfileLoaderPass(std::string File = "", bool IsThinLTOPreLink = false)
+ : ProfileFileName(File), IsThinLTOPreLink(IsThinLTOPreLink) {}
+
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
- SampleProfileLoaderPass(std::string File = "") : ProfileFileName(File) {}
private:
std::string ProfileFileName;
+ bool IsThinLTOPreLink;
};
-} // End llvm namespace
-#endif
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_SAMPLEPROFILE_H
diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h
index 1913a9d5da027..49186bc5cd666 100644
--- a/include/llvm/Transforms/Scalar.h
+++ b/include/llvm/Transforms/Scalar.h
@@ -73,6 +73,14 @@ FunctionPass *createDeadCodeEliminationPass();
//
FunctionPass *createDeadStoreEliminationPass();
+
+//===----------------------------------------------------------------------===//
+//
+// CallSiteSplitting - This pass split call-site based on its known argument
+// values.
+FunctionPass *createCallSiteSplittingPass();
+
+
//===----------------------------------------------------------------------===//
//
// AggressiveDCE - This pass uses the SSA based Aggressive DCE algorithm. This
@@ -184,7 +192,7 @@ Pass *createLoopInstSimplifyPass();
//
Pass *createLoopUnrollPass(int OptLevel = 2, int Threshold = -1, int Count = -1,
int AllowPartial = -1, int Runtime = -1,
- int UpperBound = -1);
+ int UpperBound = -1, int AllowPeeling = -1);
// Create an unrolling pass for full unrolling that uses exact trip count only.
Pass *createSimpleLoopUnrollPass(int OptLevel = 2);
@@ -255,18 +263,12 @@ FunctionPass *createJumpThreadingPass(int Threshold = -1);
//===----------------------------------------------------------------------===//
//
// CFGSimplification - Merge basic blocks, eliminate unreachable blocks,
-// simplify terminator instructions, etc...
+// simplify terminator instructions, convert switches to lookup tables, etc.
//
FunctionPass *createCFGSimplificationPass(
- int Threshold = -1, std::function<bool(const Function &)> Ftor = nullptr);
-
-//===----------------------------------------------------------------------===//
-//
-// LateCFGSimplification - Like CFGSimplification, but may also
-// convert switches to lookup tables.
-//
-FunctionPass *createLateCFGSimplificationPass(
- int Threshold = -1, std::function<bool(const Function &)> Ftor = nullptr);
+ unsigned Threshold = 1, bool ForwardSwitchCond = false,
+ bool ConvertSwitch = false, bool KeepLoops = true, bool SinkCommon = false,
+ std::function<bool(const Function &)> Ftor = nullptr);
//===----------------------------------------------------------------------===//
//
@@ -377,6 +379,12 @@ FunctionPass *createNewGVNPass();
//===----------------------------------------------------------------------===//
//
+// DivRemPairs - Hoist/decompose integer division and remainder instructions.
+//
+FunctionPass *createDivRemPairsPass();
+
+//===----------------------------------------------------------------------===//
+//
// MemCpyOpt - This pass performs optimizations related to eliminating memcpy
// calls and/or combining multiple stores into memset's.
//
@@ -422,6 +430,12 @@ Pass *createLowerGuardIntrinsicPass();
//===----------------------------------------------------------------------===//
//
+// MergeICmps - Merge integer comparison chains into a memcmp
+//
+Pass *createMergeICmpsPass();
+
+//===----------------------------------------------------------------------===//
+//
// ValuePropagation - Propagate CFG-derived value information
//
Pass *createCorrelatedValuePropagationPass();
@@ -507,7 +521,7 @@ FunctionPass *createPlaceSafepointsPass();
// RewriteStatepointsForGC - Rewrite any gc.statepoints which do not yet have
// explicit relocations to include explicit relocations.
//
-ModulePass *createRewriteStatepointsForGCPass();
+ModulePass *createRewriteStatepointsForGCLegacyPass();
//===----------------------------------------------------------------------===//
//
@@ -568,6 +582,16 @@ ModulePass *createNameAnonGlobalPass();
// used.
//
FunctionPass *createLibCallsShrinkWrapPass();
+
+//===----------------------------------------------------------------------===//
+//
+// EntryExitInstrumenter pass - Instrument function entry/exit with calls to
+// mcount(), @__cyg_profile_func_{enter,exit} and the like. There are two
+// variants, intended to run pre- and post-inlining, respectively.
+//
+FunctionPass *createEntryExitInstrumenterPass();
+FunctionPass *createPostInlineEntryExitInstrumenterPass();
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Transforms/Scalar/ADCE.h b/include/llvm/Transforms/Scalar/ADCE.h
index b9b7e1c0c99fd..f98af62c1a76f 100644
--- a/include/llvm/Transforms/Scalar/ADCE.h
+++ b/include/llvm/Transforms/Scalar/ADCE.h
@@ -1,4 +1,4 @@
-//===- ADCE.h - Aggressive dead code elimination --------------------------===//
+//===- ADCE.h - Aggressive dead code elimination ----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,11 +17,12 @@
#ifndef LLVM_TRANSFORMS_SCALAR_ADCE_H
#define LLVM_TRANSFORMS_SCALAR_ADCE_H
-#include "llvm/IR/Function.h"
#include "llvm/IR/PassManager.h"
namespace llvm {
+class Function;
+
/// A DCE pass that assumes instructions are dead until proven otherwise.
///
/// This pass eliminates dead code by optimistically assuming that all
@@ -31,6 +32,7 @@ namespace llvm {
struct ADCEPass : PassInfoMixin<ADCEPass> {
PreservedAnalyses run(Function &F, FunctionAnalysisManager &);
};
-}
+
+} // end namespace llvm
#endif // LLVM_TRANSFORMS_SCALAR_ADCE_H
diff --git a/include/llvm/Transforms/Scalar/CallSiteSplitting.h b/include/llvm/Transforms/Scalar/CallSiteSplitting.h
new file mode 100644
index 0000000000000..5ab951a49f2c8
--- /dev/null
+++ b/include/llvm/Transforms/Scalar/CallSiteSplitting.h
@@ -0,0 +1,29 @@
+//===- CallSiteSplitting..h - Callsite Splitting ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_SCALAR_CALLSITESPLITTING__H
+#define LLVM_TRANSFORMS_SCALAR_CALLSITESPLITTING__H
+
+#include "llvm/ADT/SetVector.h"
+#include "llvm/Analysis/AssumptionCache.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/Support/Compiler.h"
+#include <vector>
+
+namespace llvm {
+
+struct CallSiteSplittingPass : PassInfoMixin<CallSiteSplittingPass> {
+ /// \brief Run the pass over the function.
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_SCALAR_CALLSITESPLITTING__H
diff --git a/include/llvm/Transforms/Scalar/ConstantHoisting.h b/include/llvm/Transforms/Scalar/ConstantHoisting.h
index a2a9afc083a0b..d3322dc1c414a 100644
--- a/include/llvm/Transforms/Scalar/ConstantHoisting.h
+++ b/include/llvm/Transforms/Scalar/ConstantHoisting.h
@@ -1,4 +1,4 @@
-//===-- ConstantHoisting.h - Prepare code for expensive constants ---------===//
+//==- ConstantHoisting.h - Prepare code for expensive constants --*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
@@ -31,41 +31,53 @@
// This optimization is only applied to integer constants in instructions and
// simple (this means not nested) constant cast expressions. For example:
// %0 = load i64* inttoptr (i64 big_constant to i64*)
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TRANSFORMS_SCALAR_CONSTANTHOISTING_H
#define LLVM_TRANSFORMS_SCALAR_CONSTANTHOISTING_H
-#include "llvm/Analysis/BlockFrequencyInfo.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/IR/Dominators.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/PassManager.h"
+#include <algorithm>
+#include <vector>
namespace llvm {
+class BasicBlock;
+class BlockFrequencyInfo;
+class Constant;
+class ConstantInt;
+class DominatorTree;
+class Function;
+class Instruction;
+class TargetTransformInfo;
+
/// A private "module" namespace for types and utilities used by
/// ConstantHoisting. These are implementation details and should not be used by
/// clients.
namespace consthoist {
+
/// \brief Keeps track of the user of a constant and the operand index where the
/// constant is used.
struct ConstantUser {
Instruction *Inst;
unsigned OpndIdx;
- ConstantUser(Instruction *Inst, unsigned Idx) : Inst(Inst), OpndIdx(Idx) { }
+ ConstantUser(Instruction *Inst, unsigned Idx) : Inst(Inst), OpndIdx(Idx) {}
};
-typedef SmallVector<ConstantUser, 8> ConstantUseListType;
+using ConstantUseListType = SmallVector<ConstantUser, 8>;
/// \brief Keeps track of a constant candidate and its uses.
struct ConstantCandidate {
ConstantUseListType Uses;
ConstantInt *ConstInt;
- unsigned CumulativeCost;
+ unsigned CumulativeCost = 0;
- ConstantCandidate(ConstantInt *ConstInt)
- : ConstInt(ConstInt), CumulativeCost(0) { }
+ ConstantCandidate(ConstantInt *ConstInt) : ConstInt(ConstInt) {}
/// \brief Add the user to the use list and update the cost.
void addUser(Instruction *Inst, unsigned Idx, unsigned Cost) {
@@ -81,17 +93,18 @@ struct RebasedConstantInfo {
Constant *Offset;
RebasedConstantInfo(ConstantUseListType &&Uses, Constant *Offset)
- : Uses(std::move(Uses)), Offset(Offset) { }
+ : Uses(std::move(Uses)), Offset(Offset) {}
};
-typedef SmallVector<RebasedConstantInfo, 4> RebasedConstantListType;
+using RebasedConstantListType = SmallVector<RebasedConstantInfo, 4>;
/// \brief A base constant and all its rebased constants.
struct ConstantInfo {
ConstantInt *BaseConstant;
RebasedConstantListType RebasedConstants;
};
-}
+
+} // end namespace consthoist
class ConstantHoistingPass : public PassInfoMixin<ConstantHoistingPass> {
public:
@@ -108,8 +121,8 @@ public:
}
private:
- typedef DenseMap<ConstantInt *, unsigned> ConstCandMapType;
- typedef std::vector<consthoist::ConstantCandidate> ConstCandVecType;
+ using ConstCandMapType = DenseMap<ConstantInt *, unsigned>;
+ using ConstCandVecType = std::vector<consthoist::ConstantCandidate>;
const TargetTransformInfo *TTI;
DominatorTree *DT;
@@ -148,6 +161,7 @@ private:
void deleteDeadCastInst() const;
bool optimizeConstants(Function &Fn);
};
-}
+
+} // end namespace llvm
#endif // LLVM_TRANSFORMS_SCALAR_CONSTANTHOISTING_H
diff --git a/include/llvm/Transforms/Scalar/CorrelatedValuePropagation.h b/include/llvm/Transforms/Scalar/CorrelatedValuePropagation.h
index 38816bbed0680..20930699b5578 100644
--- a/include/llvm/Transforms/Scalar/CorrelatedValuePropagation.h
+++ b/include/llvm/Transforms/Scalar/CorrelatedValuePropagation.h
@@ -1,4 +1,4 @@
-//===---- CorrelatedValuePropagation.h --------------------------*- C++ -*-===//
+//===- CorrelatedValuePropagation.h -----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,15 +10,17 @@
#ifndef LLVM_TRANSFORMS_SCALAR_CORRELATEDVALUEPROPAGATION_H
#define LLVM_TRANSFORMS_SCALAR_CORRELATEDVALUEPROPAGATION_H
-#include "llvm/IR/Function.h"
#include "llvm/IR/PassManager.h"
namespace llvm {
+class Function;
+
struct CorrelatedValuePropagationPass
: PassInfoMixin<CorrelatedValuePropagationPass> {
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};
-}
+
+} // end namespace llvm
#endif // LLVM_TRANSFORMS_SCALAR_CORRELATEDVALUEPROPAGATION_H
diff --git a/include/llvm/Transforms/Scalar/DeadStoreElimination.h b/include/llvm/Transforms/Scalar/DeadStoreElimination.h
index 3ae999dfb5424..cfeb218142321 100644
--- a/include/llvm/Transforms/Scalar/DeadStoreElimination.h
+++ b/include/llvm/Transforms/Scalar/DeadStoreElimination.h
@@ -1,4 +1,4 @@
-//===- DeadStoreElimination.h - Fast Dead Store Elimination -------------===//
+//===- DeadStoreElimination.h - Fast Dead Store Elimination -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,20 +15,22 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_TRANSFORMS_SCALAR_DSE_H
-#define LLVM_TRANSFORMS_SCALAR_DSE_H
+#ifndef LLVM_TRANSFORMS_SCALAR_DEADSTOREELIMINATION_H
+#define LLVM_TRANSFORMS_SCALAR_DEADSTOREELIMINATION_H
-#include "llvm/IR/Function.h"
#include "llvm/IR/PassManager.h"
namespace llvm {
+class Function;
+
/// This class implements a trivial dead store elimination. We consider
/// only the redundant stores that are local to a single Basic Block.
class DSEPass : public PassInfoMixin<DSEPass> {
public:
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
};
-}
-#endif // LLVM_TRANSFORMS_SCALAR_DSE_H
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_SCALAR_DEADSTOREELIMINATION_H
diff --git a/include/llvm/Transforms/Scalar/DivRemPairs.h b/include/llvm/Transforms/Scalar/DivRemPairs.h
new file mode 100644
index 0000000000000..0a4346f33b12b
--- /dev/null
+++ b/include/llvm/Transforms/Scalar/DivRemPairs.h
@@ -0,0 +1,31 @@
+//===- DivRemPairs.h - Hoist/decompose integer division and remainder -----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass hoists and/or decomposes integer division and remainder
+// instructions to enable CFG improvements and better codegen.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_SCALAR_DIVREMPAIRS_H
+#define LLVM_TRANSFORMS_SCALAR_DIVREMPAIRS_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+/// Hoist/decompose integer division and remainder instructions to enable CFG
+/// improvements and better codegen.
+struct DivRemPairsPass : public PassInfoMixin<DivRemPairsPass> {
+public:
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &);
+};
+
+}
+#endif // LLVM_TRANSFORMS_SCALAR_DIVREMPAIRS_H
+
diff --git a/include/llvm/Transforms/Scalar/EarlyCSE.h b/include/llvm/Transforms/Scalar/EarlyCSE.h
index 969ab78bfd19f..dca3b2dbf04f4 100644
--- a/include/llvm/Transforms/Scalar/EarlyCSE.h
+++ b/include/llvm/Transforms/Scalar/EarlyCSE.h
@@ -6,19 +6,21 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
/// \file
/// This file provides the interface for a simple, fast CSE pass.
-///
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TRANSFORMS_SCALAR_EARLYCSE_H
#define LLVM_TRANSFORMS_SCALAR_EARLYCSE_H
-#include "llvm/IR/Function.h"
#include "llvm/IR/PassManager.h"
namespace llvm {
+class Function;
+
/// \brief A simple and fast domtree-based CSE pass.
///
/// This pass does a simple depth-first walk over the dominator tree,
@@ -35,6 +37,6 @@ struct EarlyCSEPass : PassInfoMixin<EarlyCSEPass> {
bool UseMemorySSA;
};
-}
+} // end namespace llvm
-#endif
+#endif // LLVM_TRANSFORMS_SCALAR_EARLYCSE_H
diff --git a/include/llvm/Transforms/Scalar/GVN.h b/include/llvm/Transforms/Scalar/GVN.h
index f25ab40640dfc..440d3f67c35a7 100644
--- a/include/llvm/Transforms/Scalar/GVN.h
+++ b/include/llvm/Transforms/Scalar/GVN.h
@@ -18,26 +18,48 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/SetVector.h"
-#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Analysis/AssumptionCache.h"
-#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/MemoryDependenceAnalysis.h"
#include "llvm/IR/Dominators.h"
-#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Transforms/Utils/OrderedInstructions.h"
+#include <cstdint>
+#include <utility>
+#include <vector>
namespace llvm {
+
+class AssumptionCache;
+class BasicBlock;
+class BranchInst;
+class CallInst;
+class Constant;
+class ExtractValueInst;
+class Function;
+class FunctionPass;
+class IntrinsicInst;
+class LoadInst;
+class LoopInfo;
class OptimizationRemarkEmitter;
+class PHINode;
+class TargetLibraryInfo;
+class Value;
/// A private "module" namespace for types and utilities used by GVN. These
/// are implementation details and should not be used by clients.
namespace gvn LLVM_LIBRARY_VISIBILITY {
+
struct AvailableValue;
struct AvailableValueInBlock;
class GVNLegacyPass;
-}
+
+} // end namespace gvn
/// The core GVN pass object.
///
@@ -45,6 +67,7 @@ class GVNLegacyPass;
/// this particular pass here.
class GVN : public PassInfoMixin<GVN> {
public:
+ struct Expression;
/// \brief Run the pass over the function.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
@@ -60,25 +83,45 @@ public:
AliasAnalysis *getAliasAnalysis() const { return VN.getAliasAnalysis(); }
MemoryDependenceResults &getMemDep() const { return *MD; }
- struct Expression;
-
/// This class holds the mapping between values and value numbers. It is used
/// as an efficient mechanism to determine the expression-wise equivalence of
/// two values.
class ValueTable {
DenseMap<Value *, uint32_t> valueNumbering;
DenseMap<Expression, uint32_t> expressionNumbering;
+
+ // Expressions is the vector of Expression. ExprIdx is the mapping from
+ // value number to the index of Expression in Expressions. We use it
+ // instead of a DenseMap because filling such mapping is faster than
+ // filling a DenseMap and the compile time is a little better.
+ uint32_t nextExprNumber;
+
+ std::vector<Expression> Expressions;
+ std::vector<uint32_t> ExprIdx;
+
+ // Value number to PHINode mapping. Used for phi-translate in scalarpre.
+ DenseMap<uint32_t, PHINode *> NumberingPhi;
+
+ // Cache for phi-translate in scalarpre.
+ using PhiTranslateMap =
+ DenseMap<std::pair<uint32_t, const BasicBlock *>, uint32_t>;
+ PhiTranslateMap PhiTranslateTable;
+
AliasAnalysis *AA;
MemoryDependenceResults *MD;
DominatorTree *DT;
- uint32_t nextValueNumber;
+ uint32_t nextValueNumber = 1;
Expression createExpr(Instruction *I);
Expression createCmpExpr(unsigned Opcode, CmpInst::Predicate Predicate,
Value *LHS, Value *RHS);
Expression createExtractvalueExpr(ExtractValueInst *EI);
uint32_t lookupOrAddCall(CallInst *C);
+ uint32_t phiTranslateImpl(const BasicBlock *BB, const BasicBlock *PhiBlock,
+ uint32_t Num, GVN &Gvn);
+ std::pair<uint32_t, bool> assignExpNewValueNum(Expression &exp);
+ bool areAllValsInBB(uint32_t num, const BasicBlock *BB, GVN &Gvn);
public:
ValueTable();
@@ -87,9 +130,12 @@ public:
~ValueTable();
uint32_t lookupOrAdd(Value *V);
- uint32_t lookup(Value *V) const;
+ uint32_t lookup(Value *V, bool Verify = true) const;
uint32_t lookupOrAddCmp(unsigned Opcode, CmpInst::Predicate Pred,
Value *LHS, Value *RHS);
+ uint32_t phiTranslate(const BasicBlock *BB, const BasicBlock *PhiBlock,
+ uint32_t Num, GVN &Gvn);
+ void eraseTranslateCacheEntry(uint32_t Num, const BasicBlock &CurrBlock);
bool exists(Value *V) const;
void add(Value *V, uint32_t num);
void clear();
@@ -112,7 +158,11 @@ private:
AssumptionCache *AC;
SetVector<BasicBlock *> DeadBlocks;
OptimizationRemarkEmitter *ORE;
+ // Maps a block to the topmost instruction with implicit control flow in it.
+ DenseMap<const BasicBlock *, const Instruction *>
+ FirstImplicitControlFlowInsts;
+ OrderedInstructions *OI;
ValueTable VN;
/// A mapping from value numbers to lists of Value*'s that
@@ -128,12 +178,16 @@ private:
// Block-local map of equivalent values to their leader, does not
// propagate to any successors. Entries added mid-block are applied
// to the remaining instructions in the block.
- SmallMapVector<llvm::Value *, llvm::Constant *, 4> ReplaceWithConstMap;
+ SmallMapVector<Value *, Constant *, 4> ReplaceWithConstMap;
SmallVector<Instruction *, 8> InstrsToErase;
- typedef SmallVector<NonLocalDepResult, 64> LoadDepVect;
- typedef SmallVector<gvn::AvailableValueInBlock, 64> AvailValInBlkVect;
- typedef SmallVector<BasicBlock *, 64> UnavailBlkVect;
+ // Map the block to reversed postorder traversal number. It is used to
+ // find back edge easily.
+ DenseMap<const BasicBlock *, uint32_t> BlockRPONumber;
+
+ using LoadDepVect = SmallVector<NonLocalDepResult, 64>;
+ using AvailValInBlkVect = SmallVector<gvn::AvailableValueInBlock, 64>;
+ using UnavailBlkVect = SmallVector<BasicBlock *, 64>;
bool runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT,
const TargetLibraryInfo &RunTLI, AAResults &RunAA,
@@ -192,17 +246,20 @@ private:
bool processLoad(LoadInst *L);
bool processNonLocalLoad(LoadInst *L);
bool processAssumeIntrinsic(IntrinsicInst *II);
+
/// Given a local dependency (Def or Clobber) determine if a value is
/// available for the load. Returns true if an value is known to be
/// available and populates Res. Returns false otherwise.
bool AnalyzeLoadAvailability(LoadInst *LI, MemDepResult DepInfo,
Value *Address, gvn::AvailableValue &Res);
+
/// Given a list of non-local dependencies, determine if a value is
/// available for the load in each specified block. If it is, add it to
/// ValuesPerBlock. If not, add it to UnavailableBlocks.
void AnalyzeLoadAvailability(LoadInst *LI, LoadDepVect &Deps,
AvailValInBlkVect &ValuesPerBlock,
UnavailBlkVect &UnavailableBlocks);
+
bool PerformLoadPRE(LoadInst *LI, AvailValInBlkVect &ValuesPerBlock,
UnavailBlkVect &UnavailableBlocks);
@@ -214,9 +271,10 @@ private:
bool performPRE(Function &F);
bool performScalarPRE(Instruction *I);
bool performScalarPREInsertion(Instruction *Instr, BasicBlock *Pred,
- unsigned int ValNo);
+ BasicBlock *Curr, unsigned int ValNo);
Value *findLeader(const BasicBlock *BB, uint32_t num);
void cleanupGlobalSets();
+ void fillImplicitControlFlowInfo(BasicBlock *BB);
void verifyRemoved(const Instruction *I) const;
bool splitCriticalEdges();
BasicBlock *splitCriticalEdges(BasicBlock *Pred, BasicBlock *Succ);
@@ -226,6 +284,7 @@ private:
bool processFoldableCondBr(BranchInst *BI);
void addDeadBlock(BasicBlock *BB);
void assignValNumForDeadCode();
+ void assignBlockRPONumber(Function &F);
};
/// Create a legacy GVN pass. This also allows parameterizing whether or not
@@ -238,12 +297,14 @@ struct GVNHoistPass : PassInfoMixin<GVNHoistPass> {
/// \brief Run the pass over the function.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};
+
/// \brief Uses an "inverted" value numbering to decide the similarity of
/// expressions and sinks similar expressions into successors.
struct GVNSinkPass : PassInfoMixin<GVNSinkPass> {
/// \brief Run the pass over the function.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_SCALAR_GVN_H
diff --git a/include/llvm/Transforms/Scalar/GVNExpression.h b/include/llvm/Transforms/Scalar/GVNExpression.h
index f603ebcbca7cc..99dae15a3ac00 100644
--- a/include/llvm/Transforms/Scalar/GVNExpression.h
+++ b/include/llvm/Transforms/Scalar/GVNExpression.h
@@ -1,4 +1,4 @@
-//======- GVNExpression.h - GVN Expression classes --------------*- C++ -*-===//
+//===- GVNExpression.h - GVN Expression classes -----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,11 +6,12 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
/// \file
///
/// The header file for the GVN pass that contains expression handling
/// classes
-///
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TRANSFORMS_SCALAR_GVNEXPRESSION_H
@@ -25,7 +26,7 @@
#include "llvm/Support/Allocator.h"
#include "llvm/Support/ArrayRecycler.h"
#include "llvm/Support/Casting.h"
-#include "llvm/Support/Debug.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
@@ -34,6 +35,9 @@
namespace llvm {
+class BasicBlock;
+class Type;
+
namespace GVNExpression {
enum ExpressionType {
@@ -58,17 +62,18 @@ class Expression {
private:
ExpressionType EType;
unsigned Opcode;
- mutable hash_code HashVal;
+ mutable hash_code HashVal = 0;
public:
Expression(ExpressionType ET = ET_Base, unsigned O = ~2U)
- : EType(ET), Opcode(O), HashVal(0) {}
+ : EType(ET), Opcode(O) {}
Expression(const Expression &) = delete;
Expression &operator=(const Expression &) = delete;
virtual ~Expression();
static unsigned getEmptyKey() { return ~0U; }
static unsigned getTombstoneKey() { return ~1U; }
+
bool operator!=(const Expression &Other) const { return !(*this == Other); }
bool operator==(const Expression &Other) const {
if (getOpcode() != Other.getOpcode())
@@ -83,6 +88,7 @@ public:
return equals(Other);
}
+
hash_code getComputedHash() const {
// It's theoretically possible for a thing to hash to zero. In that case,
// we will just compute the hash a few extra times, which is no worse that
@@ -93,6 +99,7 @@ public:
}
virtual bool equals(const Expression &Other) const { return true; }
+
// Return true if the two expressions are exactly the same, including the
// normally ignored fields.
virtual bool exactlyEquals(const Expression &Other) const {
@@ -106,9 +113,7 @@ public:
// We deliberately leave the expression type out of the hash value.
virtual hash_code getHashValue() const { return getOpcode(); }
- //
// Debugging support
- //
virtual void printInternal(raw_ostream &OS, bool PrintEType) const {
if (PrintEType)
OS << "etype = " << getExpressionType() << ",";
@@ -131,19 +136,19 @@ inline raw_ostream &operator<<(raw_ostream &OS, const Expression &E) {
class BasicExpression : public Expression {
private:
- typedef ArrayRecycler<Value *> RecyclerType;
- typedef RecyclerType::Capacity RecyclerCapacity;
- Value **Operands;
+ using RecyclerType = ArrayRecycler<Value *>;
+ using RecyclerCapacity = RecyclerType::Capacity;
+
+ Value **Operands = nullptr;
unsigned MaxOperands;
- unsigned NumOperands;
- Type *ValueType;
+ unsigned NumOperands = 0;
+ Type *ValueType = nullptr;
public:
BasicExpression(unsigned NumOperands)
: BasicExpression(NumOperands, ET_Basic) {}
BasicExpression(unsigned NumOperands, ExpressionType ET)
- : Expression(ET), Operands(nullptr), MaxOperands(NumOperands),
- NumOperands(0), ValueType(nullptr) {}
+ : Expression(ET), MaxOperands(NumOperands) {}
BasicExpression() = delete;
BasicExpression(const BasicExpression &) = delete;
BasicExpression &operator=(const BasicExpression &) = delete;
@@ -174,8 +179,9 @@ public:
unsigned getNumOperands() const { return NumOperands; }
- typedef Value **op_iterator;
- typedef Value *const *const_op_iterator;
+ using op_iterator = Value **;
+ using const_op_iterator = Value *const *;
+
op_iterator op_begin() { return Operands; }
op_iterator op_end() { return Operands + NumOperands; }
const_op_iterator op_begin() const { return Operands; }
@@ -219,9 +225,7 @@ public:
hash_combine_range(op_begin(), op_end()));
}
- //
// Debugging support
- //
void printInternal(raw_ostream &OS, bool PrintEType) const override {
if (PrintEType)
OS << "ExpressionTypeBasic, ";
@@ -240,7 +244,8 @@ public:
class op_inserter
: public std::iterator<std::output_iterator_tag, void, void, void, void> {
private:
- typedef BasicExpression Container;
+ using Container = BasicExpression;
+
Container *BE;
public:
@@ -263,15 +268,16 @@ private:
public:
MemoryExpression(unsigned NumOperands, enum ExpressionType EType,
const MemoryAccess *MemoryLeader)
- : BasicExpression(NumOperands, EType), MemoryLeader(MemoryLeader){};
-
+ : BasicExpression(NumOperands, EType), MemoryLeader(MemoryLeader) {}
MemoryExpression() = delete;
MemoryExpression(const MemoryExpression &) = delete;
MemoryExpression &operator=(const MemoryExpression &) = delete;
+
static bool classof(const Expression *EB) {
return EB->getExpressionType() > ET_MemoryStart &&
EB->getExpressionType() < ET_MemoryEnd;
}
+
hash_code getHashValue() const override {
return hash_combine(this->BasicExpression::getHashValue(), MemoryLeader);
}
@@ -305,9 +311,7 @@ public:
return EB->getExpressionType() == ET_Call;
}
- //
// Debugging support
- //
void printInternal(raw_ostream &OS, bool PrintEType) const override {
if (PrintEType)
OS << "ExpressionTypeCall, ";
@@ -326,11 +330,13 @@ public:
LoadExpression(unsigned NumOperands, LoadInst *L,
const MemoryAccess *MemoryLeader)
: LoadExpression(ET_Load, NumOperands, L, MemoryLeader) {}
+
LoadExpression(enum ExpressionType EType, unsigned NumOperands, LoadInst *L,
const MemoryAccess *MemoryLeader)
: MemoryExpression(NumOperands, EType, MemoryLeader), Load(L) {
Alignment = L ? L->getAlignment() : 0;
}
+
LoadExpression() = delete;
LoadExpression(const LoadExpression &) = delete;
LoadExpression &operator=(const LoadExpression &) = delete;
@@ -352,9 +358,7 @@ public:
cast<LoadExpression>(Other).getLoadInst() == getLoadInst();
}
- //
// Debugging support
- //
void printInternal(raw_ostream &OS, bool PrintEType) const override {
if (PrintEType)
OS << "ExpressionTypeLoad, ";
@@ -388,13 +392,13 @@ public:
Value *getStoredValue() const { return StoredValue; }
bool equals(const Expression &Other) const override;
+
bool exactlyEquals(const Expression &Other) const override {
return Expression::exactlyEquals(Other) &&
cast<StoreExpression>(Other).getStoreInst() == getStoreInst();
}
// Debugging support
- //
void printInternal(raw_ostream &OS, bool PrintEType) const override {
if (PrintEType)
OS << "ExpressionTypeStore, ";
@@ -409,14 +413,13 @@ public:
class AggregateValueExpression final : public BasicExpression {
private:
unsigned MaxIntOperands;
- unsigned NumIntOperands;
- unsigned *IntOperands;
+ unsigned NumIntOperands = 0;
+ unsigned *IntOperands = nullptr;
public:
AggregateValueExpression(unsigned NumOperands, unsigned NumIntOperands)
: BasicExpression(NumOperands, ET_AggregateValue),
- MaxIntOperands(NumIntOperands), NumIntOperands(0),
- IntOperands(nullptr) {}
+ MaxIntOperands(NumIntOperands) {}
AggregateValueExpression() = delete;
AggregateValueExpression(const AggregateValueExpression &) = delete;
AggregateValueExpression &
@@ -427,8 +430,8 @@ public:
return EB->getExpressionType() == ET_AggregateValue;
}
- typedef unsigned *int_arg_iterator;
- typedef const unsigned *const_int_arg_iterator;
+ using int_arg_iterator = unsigned *;
+ using const_int_arg_iterator = const unsigned *;
int_arg_iterator int_op_begin() { return IntOperands; }
int_arg_iterator int_op_end() { return IntOperands + NumIntOperands; }
@@ -463,9 +466,7 @@ public:
hash_combine_range(int_op_begin(), int_op_end()));
}
- //
// Debugging support
- //
void printInternal(raw_ostream &OS, bool PrintEType) const override {
if (PrintEType)
OS << "ExpressionTypeAggregateValue, ";
@@ -481,7 +482,8 @@ public:
class int_op_inserter
: public std::iterator<std::output_iterator_tag, void, void, void, void> {
private:
- typedef AggregateValueExpression Container;
+ using Container = AggregateValueExpression;
+
Container *AVE;
public:
@@ -524,9 +526,7 @@ public:
return hash_combine(this->BasicExpression::getHashValue(), BB);
}
- //
// Debugging support
- //
void printInternal(raw_ostream &OS, bool PrintEType) const override {
if (PrintEType)
OS << "ExpressionTypePhi, ";
@@ -573,9 +573,7 @@ public:
VariableValue->getType(), VariableValue);
}
- //
// Debugging support
- //
void printInternal(raw_ostream &OS, bool PrintEType) const override {
if (PrintEType)
OS << "ExpressionTypeVariable, ";
@@ -612,9 +610,7 @@ public:
ConstantValue->getType(), ConstantValue);
}
- //
// Debugging support
- //
void printInternal(raw_ostream &OS, bool PrintEType) const override {
if (PrintEType)
OS << "ExpressionTypeConstant, ";
@@ -649,9 +645,7 @@ public:
return hash_combine(this->Expression::getHashValue(), Inst);
}
- //
// Debugging support
- //
void printInternal(raw_ostream &OS, bool PrintEType) const override {
if (PrintEType)
OS << "ExpressionTypeUnknown, ";
diff --git a/include/llvm/Transforms/Scalar/IndVarSimplify.h b/include/llvm/Transforms/Scalar/IndVarSimplify.h
index 4a4683f1a07df..e321c8fc6e9cf 100644
--- a/include/llvm/Transforms/Scalar/IndVarSimplify.h
+++ b/include/llvm/Transforms/Scalar/IndVarSimplify.h
@@ -15,17 +15,20 @@
#ifndef LLVM_TRANSFORMS_SCALAR_INDVARSIMPLIFY_H
#define LLVM_TRANSFORMS_SCALAR_INDVARSIMPLIFY_H
-#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/LoopAnalysisManager.h"
#include "llvm/IR/PassManager.h"
-#include "llvm/Transforms/Scalar/LoopPassManager.h"
namespace llvm {
+class Loop;
+class LPMUpdater;
+
class IndVarSimplifyPass : public PassInfoMixin<IndVarSimplifyPass> {
public:
PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
LoopStandardAnalysisResults &AR, LPMUpdater &U);
};
-}
+
+} // end namespace llvm
#endif // LLVM_TRANSFORMS_SCALAR_INDVARSIMPLIFY_H
diff --git a/include/llvm/Transforms/Scalar/JumpThreading.h b/include/llvm/Transforms/Scalar/JumpThreading.h
index 1da86132591b7..a9466713b8e65 100644
--- a/include/llvm/Transforms/Scalar/JumpThreading.h
+++ b/include/llvm/Transforms/Scalar/JumpThreading.h
@@ -6,41 +6,57 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
/// \file
/// See the comments on JumpThreadingPass.
-///
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TRANSFORMS_SCALAR_JUMPTHREADING_H
#define LLVM_TRANSFORMS_SCALAR_JUMPTHREADING_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/BlockFrequencyInfo.h"
-#include "llvm/Analysis/BlockFrequencyInfoImpl.h"
#include "llvm/Analysis/BranchProbabilityInfo.h"
-#include "llvm/Analysis/LazyValueInfo.h"
-#include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/ValueHandle.h"
+#include <memory>
+#include <utility>
namespace llvm {
+class BasicBlock;
+class BinaryOperator;
+class BranchInst;
+class CmpInst;
+class Constant;
+class Function;
+class Instruction;
+class IntrinsicInst;
+class LazyValueInfo;
+class LoadInst;
+class PHINode;
+class TargetLibraryInfo;
+class Value;
+
/// A private "module" namespace for types and utilities used by
/// JumpThreading.
/// These are implementation details and should not be used by clients.
namespace jumpthreading {
+
// These are at global scope so static functions can use them too.
-typedef SmallVectorImpl<std::pair<Constant *, BasicBlock *>> PredValueInfo;
-typedef SmallVector<std::pair<Constant *, BasicBlock *>, 8> PredValueInfoTy;
+using PredValueInfo = SmallVectorImpl<std::pair<Constant *, BasicBlock *>>;
+using PredValueInfoTy = SmallVector<std::pair<Constant *, BasicBlock *>, 8>;
// This is used to keep track of what kind of constant we're currently hoping
// to find.
enum ConstantPreference { WantInteger, WantBlockAddress };
-}
+
+} // end namespace jumpthreading
/// This pass performs 'jump threading', which looks at blocks that have
/// multiple predecessors and multiple successors. If one or more of the
@@ -57,7 +73,6 @@ enum ConstantPreference { WantInteger, WantBlockAddress };
///
/// In this case, the unconditional branch at the end of the first if can be
/// revectored to the false side of the second if.
-///
class JumpThreadingPass : public PassInfoMixin<JumpThreadingPass> {
TargetLibraryInfo *TLI;
LazyValueInfo *LVI;
@@ -141,4 +156,4 @@ private:
} // end namespace llvm
-#endif
+#endif // LLVM_TRANSFORMS_SCALAR_JUMPTHREADING_H
diff --git a/include/llvm/Transforms/Scalar/LoopDistribute.h b/include/llvm/Transforms/Scalar/LoopDistribute.h
index ddde5954c2189..2bf1c9d696d5b 100644
--- a/include/llvm/Transforms/Scalar/LoopDistribute.h
+++ b/include/llvm/Transforms/Scalar/LoopDistribute.h
@@ -21,10 +21,13 @@
namespace llvm {
+class Function;
+
class LoopDistributePass : public PassInfoMixin<LoopDistributePass> {
public:
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};
+
} // end namespace llvm
#endif // LLVM_TRANSFORMS_SCALAR_LOOPDISTRIBUTE_H
diff --git a/include/llvm/Transforms/Scalar/LoopIdiomRecognize.h b/include/llvm/Transforms/Scalar/LoopIdiomRecognize.h
index 40349e8f7fe06..7added8d2c617 100644
--- a/include/llvm/Transforms/Scalar/LoopIdiomRecognize.h
+++ b/include/llvm/Transforms/Scalar/LoopIdiomRecognize.h
@@ -1,4 +1,4 @@
-//===- LoopIdiomRecognize.h - Loop Idiom Recognize Pass -------*- C++ -*-===//
+//===- LoopIdiomRecognize.h - Loop Idiom Recognize Pass ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,18 +16,21 @@
#ifndef LLVM_TRANSFORMS_SCALAR_LOOPIDIOMRECOGNIZE_H
#define LLVM_TRANSFORMS_SCALAR_LOOPIDIOMRECOGNIZE_H
-#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/LoopAnalysisManager.h"
#include "llvm/IR/PassManager.h"
-#include "llvm/Transforms/Scalar/LoopPassManager.h"
namespace llvm {
+class Loop;
+class LPMUpdater;
+
/// Performs Loop Idiom Recognize Pass.
class LoopIdiomRecognizePass : public PassInfoMixin<LoopIdiomRecognizePass> {
public:
PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
LoopStandardAnalysisResults &AR, LPMUpdater &U);
};
+
} // end namespace llvm
#endif // LLVM_TRANSFORMS_SCALAR_LOOPIDIOMRECOGNIZE_H
diff --git a/include/llvm/Transforms/Scalar/LoopInstSimplify.h b/include/llvm/Transforms/Scalar/LoopInstSimplify.h
index bb8bc29577a2d..04dc79c3fa573 100644
--- a/include/llvm/Transforms/Scalar/LoopInstSimplify.h
+++ b/include/llvm/Transforms/Scalar/LoopInstSimplify.h
@@ -1,4 +1,4 @@
-//===- LoopInstSimplify.h - Loop Inst Simplify Pass -------*- C++ -*-===//
+//===- LoopInstSimplify.h - Loop Inst Simplify Pass -------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,18 +14,21 @@
#ifndef LLVM_TRANSFORMS_SCALAR_LOOPINSTSIMPLIFY_H
#define LLVM_TRANSFORMS_SCALAR_LOOPINSTSIMPLIFY_H
-#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/LoopAnalysisManager.h"
#include "llvm/IR/PassManager.h"
-#include "llvm/Transforms/Scalar/LoopPassManager.h"
namespace llvm {
+class Loop;
+class LPMUpdater;
+
/// Performs Loop Inst Simplify Pass.
class LoopInstSimplifyPass : public PassInfoMixin<LoopInstSimplifyPass> {
public:
PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
LoopStandardAnalysisResults &AR, LPMUpdater &U);
};
+
} // end namespace llvm
#endif // LLVM_TRANSFORMS_SCALAR_LOOPINSTSIMPLIFY_H
diff --git a/include/llvm/Transforms/Scalar/LoopLoadElimination.h b/include/llvm/Transforms/Scalar/LoopLoadElimination.h
index 7a007a7e822d2..b0514a4a7c989 100644
--- a/include/llvm/Transforms/Scalar/LoopLoadElimination.h
+++ b/include/llvm/Transforms/Scalar/LoopLoadElimination.h
@@ -1,4 +1,4 @@
-//===---- LoopLoadElimination.h ---------------------------------*- C++ -*-===//
+//===- LoopLoadElimination.h ------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,11 +6,12 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
/// \file
/// This header defines the LoopLoadEliminationPass object. This pass forwards
/// loaded values around loop backedges to allow their use in subsequent
/// iterations.
-///
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TRANSFORMS_SCALAR_LOOPLOADELIMINATION_H
@@ -20,11 +21,14 @@
namespace llvm {
+class Function;
+
/// Pass to forward loads in a loop around the backedge to subsequent
/// iterations.
struct LoopLoadEliminationPass : public PassInfoMixin<LoopLoadEliminationPass> {
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};
-}
+
+} // end namespace llvm
#endif // LLVM_TRANSFORMS_SCALAR_LOOPLOADELIMINATION_H
diff --git a/include/llvm/Transforms/Scalar/LoopPassManager.h b/include/llvm/Transforms/Scalar/LoopPassManager.h
index 715b11d3d9749..473b97dc7e8d4 100644
--- a/include/llvm/Transforms/Scalar/LoopPassManager.h
+++ b/include/llvm/Transforms/Scalar/LoopPassManager.h
@@ -164,10 +164,11 @@ public:
/// If this is called for the current loop, in addition to clearing any
/// state, this routine will mark that the current loop should be skipped by
/// the rest of the pass management infrastructure.
- void markLoopAsDeleted(Loop &L) {
- LAM.clear(L);
- assert(CurrentL->contains(&L) && "Cannot delete a loop outside of the "
- "subloop tree currently being processed.");
+ void markLoopAsDeleted(Loop &L, llvm::StringRef Name) {
+ LAM.clear(L, Name);
+ assert((&L == CurrentL || CurrentL->contains(&L)) &&
+ "Cannot delete a loop outside of the "
+ "subloop tree currently being processed.");
if (&L == CurrentL)
SkipCurrentLoop = true;
}
@@ -216,6 +217,19 @@ public:
// shouldn't impact anything.
}
+ /// Restart the current loop.
+ ///
+ /// Loop passes should call this method to indicate the current loop has been
+ /// sufficiently changed that it should be re-visited from the begining of
+ /// the loop pass pipeline rather than continuing.
+ void revisitCurrentLoop() {
+ // Tell the currently in-flight pipeline to stop running.
+ SkipCurrentLoop = true;
+
+ // And insert ourselves back into the worklist.
+ Worklist.insert(CurrentL);
+ }
+
private:
template <typename LoopPassT> friend class llvm::FunctionToLoopPassAdaptor;
@@ -271,13 +285,17 @@ public:
return PA;
// Get the analysis results needed by loop passes.
+ MemorySSA *MSSA = EnableMSSALoopDependency
+ ? (&AM.getResult<MemorySSAAnalysis>(F).getMSSA())
+ : nullptr;
LoopStandardAnalysisResults LAR = {AM.getResult<AAManager>(F),
AM.getResult<AssumptionAnalysis>(F),
AM.getResult<DominatorTreeAnalysis>(F),
AM.getResult<LoopAnalysis>(F),
AM.getResult<ScalarEvolutionAnalysis>(F),
AM.getResult<TargetLibraryAnalysis>(F),
- AM.getResult<TargetIRAnalysis>(F)};
+ AM.getResult<TargetIRAnalysis>(F),
+ MSSA};
// Setup the loop analysis manager from its proxy. It is important that
// this is only done when there are loops to process and we have built the
@@ -345,6 +363,8 @@ public:
PA.preserve<DominatorTreeAnalysis>();
PA.preserve<LoopAnalysis>();
PA.preserve<ScalarEvolutionAnalysis>();
+ // FIXME: Uncomment this when all loop passes preserve MemorySSA
+ // PA.preserve<MemorySSAAnalysis>();
// FIXME: What we really want to do here is preserve an AA category, but
// that concept doesn't exist yet.
PA.preserve<AAManager>();
diff --git a/include/llvm/Transforms/Scalar/LoopStrengthReduce.h b/include/llvm/Transforms/Scalar/LoopStrengthReduce.h
index ebcb32125262b..62c038a3857d6 100644
--- a/include/llvm/Transforms/Scalar/LoopStrengthReduce.h
+++ b/include/llvm/Transforms/Scalar/LoopStrengthReduce.h
@@ -1,4 +1,4 @@
-//===- LoopStrengthReduce.h - Loop Strength Reduce Pass -------*- C++ -*-===//
+//===- LoopStrengthReduce.h - Loop Strength Reduce Pass ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -22,18 +22,21 @@
#ifndef LLVM_TRANSFORMS_SCALAR_LOOPSTRENGTHREDUCE_H
#define LLVM_TRANSFORMS_SCALAR_LOOPSTRENGTHREDUCE_H
-#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/LoopAnalysisManager.h"
#include "llvm/IR/PassManager.h"
-#include "llvm/Transforms/Scalar/LoopPassManager.h"
namespace llvm {
+class Loop;
+class LPMUpdater;
+
/// Performs Loop Strength Reduce Pass.
class LoopStrengthReducePass : public PassInfoMixin<LoopStrengthReducePass> {
public:
PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
LoopStandardAnalysisResults &AR, LPMUpdater &U);
};
+
} // end namespace llvm
#endif // LLVM_TRANSFORMS_SCALAR_LOOPSTRENGTHREDUCE_H
diff --git a/include/llvm/Transforms/Scalar/LoopUnrollPass.h b/include/llvm/Transforms/Scalar/LoopUnrollPass.h
index 7253bd09766ef..9848e0d54f2bf 100644
--- a/include/llvm/Transforms/Scalar/LoopUnrollPass.h
+++ b/include/llvm/Transforms/Scalar/LoopUnrollPass.h
@@ -10,40 +10,40 @@
#ifndef LLVM_TRANSFORMS_SCALAR_LOOPUNROLLPASS_H
#define LLVM_TRANSFORMS_SCALAR_LOOPUNROLLPASS_H
-#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/LoopAnalysisManager.h"
#include "llvm/IR/PassManager.h"
-#include "llvm/Transforms/Scalar/LoopPassManager.h"
namespace llvm {
-class LoopUnrollPass : public PassInfoMixin<LoopUnrollPass> {
- const bool AllowPartialUnrolling;
+class Function;
+class Loop;
+class LPMUpdater;
+
+/// Loop unroll pass that only does full loop unrolling.
+class LoopFullUnrollPass : public PassInfoMixin<LoopFullUnrollPass> {
const int OptLevel;
- explicit LoopUnrollPass(bool AllowPartialUnrolling, int OptLevel)
- : AllowPartialUnrolling(AllowPartialUnrolling), OptLevel(OptLevel) {}
+public:
+ explicit LoopFullUnrollPass(int OptLevel = 2) : OptLevel(OptLevel) {}
+
+ PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR, LPMUpdater &U);
+};
+
+/// Loop unroll pass that will support both full and partial unrolling.
+/// It is a function pass to have access to function and module analyses.
+/// It will also put loops into canonical form (simplified and LCSSA).
+class LoopUnrollPass : public PassInfoMixin<LoopUnrollPass> {
+ const int OptLevel;
public:
- /// Create an instance of the loop unroll pass that will support both full
- /// and partial unrolling.
- ///
/// This uses the target information (or flags) to control the thresholds for
/// different unrolling stategies but supports all of them.
- static LoopUnrollPass create(int OptLevel = 2) {
- return LoopUnrollPass(/*AllowPartialUnrolling*/ true, OptLevel);
- }
-
- /// Create an instance of the loop unroll pass that only does full loop
- /// unrolling.
- ///
- /// This will disable any runtime or partial unrolling.
- static LoopUnrollPass createFull(int OptLevel = 2) {
- return LoopUnrollPass(/*AllowPartialUnrolling*/ false, OptLevel);
- }
+ explicit LoopUnrollPass(int OptLevel = 2) : OptLevel(OptLevel) {}
- PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
- LoopStandardAnalysisResults &AR, LPMUpdater &U);
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};
+
} // end namespace llvm
#endif // LLVM_TRANSFORMS_SCALAR_LOOPUNROLLPASS_H
diff --git a/include/llvm/Transforms/Scalar/LowerExpectIntrinsic.h b/include/llvm/Transforms/Scalar/LowerExpectIntrinsic.h
index f688e7f19986c..ab9dec0311b2b 100644
--- a/include/llvm/Transforms/Scalar/LowerExpectIntrinsic.h
+++ b/include/llvm/Transforms/Scalar/LowerExpectIntrinsic.h
@@ -24,7 +24,7 @@ namespace llvm {
struct LowerExpectIntrinsicPass : PassInfoMixin<LowerExpectIntrinsicPass> {
/// \brief Run the pass over the function.
///
- /// This will lower all of th expect intrinsic calls in this function into
+ /// This will lower all of the expect intrinsic calls in this function into
/// branch weight metadata. That metadata will subsequently feed the analysis
/// of the probabilities and frequencies of the CFG. After running this pass,
/// no more expect intrinsics remain, allowing the rest of the optimizer to
diff --git a/include/llvm/Transforms/Scalar/MemCpyOptimizer.h b/include/llvm/Transforms/Scalar/MemCpyOptimizer.h
index f52872dd2ea78..046c808bd0511 100644
--- a/include/llvm/Transforms/Scalar/MemCpyOptimizer.h
+++ b/include/llvm/Transforms/Scalar/MemCpyOptimizer.h
@@ -1,4 +1,4 @@
-//===---- MemCpyOptimizer.h - memcpy optimization ---------------*- C++ -*-===//
+//===- MemCpyOptimizer.h - memcpy optimization ------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,20 +16,27 @@
#define LLVM_TRANSFORMS_SCALAR_MEMCPYOPTIMIZER_H
#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Analysis/AssumptionCache.h"
-#include "llvm/Analysis/MemoryDependenceAnalysis.h"
-#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/Dominators.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/CallSite.h"
#include "llvm/IR/PassManager.h"
#include <cstdint>
#include <functional>
namespace llvm {
+class AssumptionCache;
+class CallInst;
+class DominatorTree;
+class Function;
+class Instruction;
+class MemCpyInst;
+class MemMoveInst;
+class MemoryDependenceResults;
+class MemSetInst;
+class StoreInst;
+class TargetLibraryInfo;
+class Value;
+
class MemCpyOptPass : public PassInfoMixin<MemCpyOptPass> {
MemoryDependenceResults *MD = nullptr;
TargetLibraryInfo *TLI = nullptr;
@@ -41,6 +48,7 @@ public:
MemCpyOptPass() = default;
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+
// Glue for the old PM.
bool runImpl(Function &F, MemoryDependenceResults *MD_,
TargetLibraryInfo *TLI_,
diff --git a/include/llvm/Transforms/Scalar/NaryReassociate.h b/include/llvm/Transforms/Scalar/NaryReassociate.h
index f35707eeb3f04..e835bd5f0761c 100644
--- a/include/llvm/Transforms/Scalar/NaryReassociate.h
+++ b/include/llvm/Transforms/Scalar/NaryReassociate.h
@@ -1,4 +1,4 @@
-//===- NaryReassociate.h - Reassociate n-ary expressions ------------------===//
+//===- NaryReassociate.h - Reassociate n-ary expressions --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -81,15 +81,25 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/Analysis/AssumptionCache.h"
-#include "llvm/Analysis/ScalarEvolution.h"
-#include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/IR/Dominators.h"
-#include "llvm/IR/Function.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/IR/ValueHandle.h"
namespace llvm {
+
+class AssumptionCache;
+class BinaryOperator;
+class DataLayout;
+class DominatorTree;
+class Function;
+class GetElementPtrInst;
+class Instruction;
+class ScalarEvolution;
+class SCEV;
+class TargetLibraryInfo;
+class TargetTransformInfo;
+class Type;
+class Value;
+
class NaryReassociatePass : public PassInfoMixin<NaryReassociatePass> {
public:
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
@@ -109,6 +119,7 @@ private:
// Reassociate GEP for better CSE.
Instruction *tryReassociateGEP(GetElementPtrInst *GEP);
+
// Try splitting GEP at the I-th index and see whether either part can be
// CSE'ed. This is a helper function for tryReassociateGEP.
//
@@ -118,6 +129,7 @@ private:
// ..., i-th index).
GetElementPtrInst *tryReassociateGEPAtIndex(GetElementPtrInst *GEP,
unsigned I, Type *IndexedType);
+
// Given GEP's I-th index = LHS + RHS, see whether &Base[..][LHS][..] or
// &Base[..][RHS][..] can be CSE'ed and rewrite GEP accordingly.
GetElementPtrInst *tryReassociateGEPAtIndex(GetElementPtrInst *GEP,
@@ -146,6 +158,7 @@ private:
// \c CandidateExpr. Returns null if not found.
Instruction *findClosestMatchingDominator(const SCEV *CandidateExpr,
Instruction *Dominatee);
+
// GetElementPtrInst implicitly sign-extends an index if the index is shorter
// than the pointer size. This function returns whether Index is shorter than
// GEP's pointer size, i.e., whether Index needs to be sign-extended in order
@@ -158,6 +171,7 @@ private:
ScalarEvolution *SE;
TargetLibraryInfo *TLI;
TargetTransformInfo *TTI;
+
// A lookup table quickly telling which instructions compute the given SCEV.
// Note that there can be multiple instructions at different locations
// computing to the same SCEV, so we map a SCEV to an instruction list. For
@@ -169,6 +183,7 @@ private:
// bar(a + b);
DenseMap<const SCEV *, SmallVector<WeakTrackingVH, 2>> SeenExprs;
};
-} // namespace llvm
+
+} // end namespace llvm
#endif // LLVM_TRANSFORMS_SCALAR_NARYREASSOCIATE_H
diff --git a/include/llvm/Transforms/Scalar/NewGVN.h b/include/llvm/Transforms/Scalar/NewGVN.h
index d0425aa4345ff..05db25502dc3c 100644
--- a/include/llvm/Transforms/Scalar/NewGVN.h
+++ b/include/llvm/Transforms/Scalar/NewGVN.h
@@ -1,4 +1,4 @@
-//===----- NewGVN.h - Global Value Numbering Pass ---------------*- C++ -*-===//
+//===- NewGVN.h - Global Value Numbering Pass -------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,9 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
/// \file
/// This file provides the interface for LLVM's Global Value Numbering pass.
-///
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TRANSFORMS_SCALAR_NEWGVN_H
@@ -17,12 +18,16 @@
#include "llvm/IR/PassManager.h"
namespace llvm {
+
+class Function;
+
class NewGVNPass : public PassInfoMixin<NewGVNPass> {
public:
/// \brief Run the pass over the function.
PreservedAnalyses run(Function &F, AnalysisManager<Function> &AM);
};
-}
+
+} // end namespace llvm
#endif // LLVM_TRANSFORMS_SCALAR_NEWGVN_H
diff --git a/include/llvm/Transforms/Scalar/Reassociate.h b/include/llvm/Transforms/Scalar/Reassociate.h
index a30a7176baa8b..9997dfa5b6f3a 100644
--- a/include/llvm/Transforms/Scalar/Reassociate.h
+++ b/include/llvm/Transforms/Scalar/Reassociate.h
@@ -23,22 +23,33 @@
#ifndef LLVM_TRANSFORMS_SCALAR_REASSOCIATE_H
#define LLVM_TRANSFORMS_SCALAR_REASSOCIATE_H
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/Operator.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/IR/ValueHandle.h"
namespace llvm {
+class APInt;
+class BasicBlock;
+class BinaryOperator;
+class Function;
+class Instruction;
+class Value;
+
/// A private "module" namespace for types and utilities used by Reassociate.
/// These are implementation details and should not be used by clients.
namespace reassociate {
+
struct ValueEntry {
unsigned Rank;
Value *Op;
+
ValueEntry(unsigned R, Value *O) : Rank(R), Op(O) {}
};
+
inline bool operator<(const ValueEntry &LHS, const ValueEntry &RHS) {
return LHS.Rank > RHS.Rank; // Sort so that highest rank goes to start.
}
@@ -48,17 +59,26 @@ inline bool operator<(const ValueEntry &LHS, const ValueEntry &RHS) {
struct Factor {
Value *Base;
unsigned Power;
+
Factor(Value *Base, unsigned Power) : Base(Base), Power(Power) {}
};
class XorOpnd;
-}
+
+} // end namespace reassociate
/// Reassociate commutative expressions.
class ReassociatePass : public PassInfoMixin<ReassociatePass> {
DenseMap<BasicBlock *, unsigned> RankMap;
DenseMap<AssertingVH<Value>, unsigned> ValueRankMap;
SetVector<AssertingVH<Instruction>> RedoInsts;
+
+ // Arbitrary, but prevents quadratic behavior.
+ static const unsigned GlobalReassociateLimit = 10;
+ static const unsigned NumBinaryOps =
+ Instruction::BinaryOpsEnd - Instruction::BinaryOpsBegin;
+ DenseMap<std::pair<Value *, Value *>, unsigned> PairMap[NumBinaryOps];
+
bool MadeChange;
public:
@@ -92,7 +112,9 @@ private:
SetVector<AssertingVH<Instruction>> &Insts);
void OptimizeInst(Instruction *I);
Instruction *canonicalizeNegConstExpr(Instruction *I);
+ void BuildPairMap(ReversePostOrderTraversal<Function *> &RPOT);
};
-}
+
+} // end namespace llvm
#endif // LLVM_TRANSFORMS_SCALAR_REASSOCIATE_H
diff --git a/include/llvm/Transforms/Scalar/RewriteStatepointsForGC.h b/include/llvm/Transforms/Scalar/RewriteStatepointsForGC.h
new file mode 100644
index 0000000000000..128f176f44203
--- /dev/null
+++ b/include/llvm/Transforms/Scalar/RewriteStatepointsForGC.h
@@ -0,0 +1,39 @@
+//===- RewriteStatepointsForGC.h - ------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides interface to "Rewrite Statepoints for GC" pass.
+//
+// This passe rewrites call/invoke instructions so as to make potential
+// relocations performed by the garbage collector explicit in the IR.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_SCALAR_REWRITE_STATEPOINTS_FOR_GC_H
+#define LLVM_TRANSFORMS_SCALAR_REWRITE_STATEPOINTS_FOR_GC_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class DominatorTree;
+class Function;
+class Module;
+class TargetTransformInfo;
+class TargetLibraryInfo;
+
+struct RewriteStatepointsForGC : public PassInfoMixin<RewriteStatepointsForGC> {
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+
+ bool runOnFunction(Function &F, DominatorTree &, TargetTransformInfo &,
+ const TargetLibraryInfo &);
+};
+
+} // namespace llvm
+
+#endif // LLVM_TRANSFORMS_SCALAR_REWRITE_STATEPOINTS_FOR_GC_H
diff --git a/include/llvm/Transforms/Scalar/SCCP.h b/include/llvm/Transforms/Scalar/SCCP.h
index 6e7f77fe2c501..b93287fff907a 100644
--- a/include/llvm/Transforms/Scalar/SCCP.h
+++ b/include/llvm/Transforms/Scalar/SCCP.h
@@ -6,7 +6,8 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-/// \file
+//
+// \file
// This file implements sparse conditional constant propagation and merging:
//
// Specifically, this:
@@ -15,22 +16,23 @@
// * Proves values to be constant, and replaces them with constants
// * Proves conditional branches to be unconditional
//
-///
//===----------------------------------------------------------------------===//
#ifndef LLVM_TRANSFORMS_SCALAR_SCCP_H
#define LLVM_TRANSFORMS_SCALAR_SCCP_H
-#include "llvm/IR/Function.h"
#include "llvm/IR/PassManager.h"
namespace llvm {
+class Function;
+
/// This pass performs function-level constant propagation and merging.
class SCCPPass : public PassInfoMixin<SCCPPass> {
public:
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};
-}
+
+} // end namespace llvm
#endif // LLVM_TRANSFORMS_SCALAR_SCCP_H
diff --git a/include/llvm/Transforms/Scalar/SROA.h b/include/llvm/Transforms/Scalar/SROA.h
index 3080b75ba8949..4a321e75c68b8 100644
--- a/include/llvm/Transforms/Scalar/SROA.h
+++ b/include/llvm/Transforms/Scalar/SROA.h
@@ -17,15 +17,23 @@
#define LLVM_TRANSFORMS_SCALAR_SROA_H
#include "llvm/ADT/SetVector.h"
-#include "llvm/Analysis/AssumptionCache.h"
-#include "llvm/IR/Dominators.h"
-#include "llvm/IR/Function.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Support/Compiler.h"
#include <vector>
namespace llvm {
+class AllocaInst;
+class AssumptionCache;
+class DominatorTree;
+class Function;
+class Instruction;
+class LLVMContext;
+class PHINode;
+class SelectInst;
+class Use;
+
/// A private "module" namespace for types and utilities used by SROA. These
/// are implementation details and should not be used by clients.
namespace sroa LLVM_LIBRARY_VISIBILITY {
@@ -122,7 +130,7 @@ private:
bool splitAlloca(AllocaInst &AI, sroa::AllocaSlices &AS);
bool runOnAlloca(AllocaInst &AI);
void clobberUse(Use &U);
- void deleteDeadInstructions(SmallPtrSetImpl<AllocaInst *> &DeletedAllocas);
+ bool deleteDeadInstructions(SmallPtrSetImpl<AllocaInst *> &DeletedAllocas);
bool promoteAllocas(Function &F);
};
diff --git a/include/llvm/Transforms/Scalar/SimpleLoopUnswitch.h b/include/llvm/Transforms/Scalar/SimpleLoopUnswitch.h
index d7282ac6a7813..63bfe6373d04f 100644
--- a/include/llvm/Transforms/Scalar/SimpleLoopUnswitch.h
+++ b/include/llvm/Transforms/Scalar/SimpleLoopUnswitch.h
@@ -36,8 +36,10 @@ namespace llvm {
/// of the loop, to make the unswitching opportunity obvious.
///
class SimpleLoopUnswitchPass : public PassInfoMixin<SimpleLoopUnswitchPass> {
+ bool NonTrivial;
+
public:
- SimpleLoopUnswitchPass() = default;
+ SimpleLoopUnswitchPass(bool NonTrivial = false) : NonTrivial(NonTrivial) {}
PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
LoopStandardAnalysisResults &AR, LPMUpdater &U);
@@ -46,7 +48,7 @@ public:
/// Create the legacy pass object for the simple loop unswitcher.
///
/// See the documentaion for `SimpleLoopUnswitchPass` for details.
-Pass *createSimpleLoopUnswitchLegacyPass();
+Pass *createSimpleLoopUnswitchLegacyPass(bool NonTrivial = false);
} // end namespace llvm
diff --git a/include/llvm/Transforms/Scalar/SimplifyCFG.h b/include/llvm/Transforms/Scalar/SimplifyCFG.h
index 54b51c405ad41..1afb9c7f954f4 100644
--- a/include/llvm/Transforms/Scalar/SimplifyCFG.h
+++ b/include/llvm/Transforms/Scalar/SimplifyCFG.h
@@ -17,26 +17,34 @@
#include "llvm/IR/Function.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/Transforms/Utils/Local.h"
namespace llvm {
-/// \brief A pass to simplify and canonicalize the CFG of a function.
+/// A pass to simplify and canonicalize the CFG of a function.
///
-/// This pass iteratively simplifies the entire CFG of a function, removing
-/// unnecessary control flows and bringing it into the canonical form expected
-/// by the rest of the mid-level optimizer.
+/// This pass iteratively simplifies the entire CFG of a function. It may change
+/// or remove control flow to put the CFG into a canonical form expected by
+/// other passes of the mid-level optimizer. Depending on the specified options,
+/// it may further optimize control-flow to create non-canonical forms.
class SimplifyCFGPass : public PassInfoMixin<SimplifyCFGPass> {
- int BonusInstThreshold;
- bool LateSimplifyCFG;
+ SimplifyCFGOptions Options;
public:
- /// \brief Construct a pass with the default thresholds
- /// and switch optimizations.
- SimplifyCFGPass();
-
- /// \brief Construct a pass with a specific bonus threshold
- /// and optional switch optimizations.
- SimplifyCFGPass(int BonusInstThreshold, bool LateSimplifyCFG);
+ /// The default constructor sets the pass options to create canonical IR,
+ /// rather than optimal IR. That is, by default we bypass transformations that
+ /// are likely to improve performance but make analysis for other passes more
+ /// difficult.
+ SimplifyCFGPass()
+ : SimplifyCFGPass(SimplifyCFGOptions()
+ .forwardSwitchCondToPhi(false)
+ .convertSwitchToLookupTable(false)
+ .needCanonicalLoops(true)
+ .sinkCommonInsts(false)) {}
+
+
+ /// Construct a pass with optional optimizations.
+ SimplifyCFGPass(const SimplifyCFGOptions &PassOptions);
/// \brief Run the pass over the function.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
diff --git a/include/llvm/Transforms/Scalar/SpeculateAroundPHIs.h b/include/llvm/Transforms/Scalar/SpeculateAroundPHIs.h
new file mode 100644
index 0000000000000..f39e03d22d656
--- /dev/null
+++ b/include/llvm/Transforms/Scalar/SpeculateAroundPHIs.h
@@ -0,0 +1,111 @@
+//===- SpeculateAroundPHIs.h - Speculate around PHIs ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_SCALAR_SPECULATEAROUNDPHIS_H
+#define LLVM_TRANSFORMS_SCALAR_SPECULATEAROUNDPHIS_H
+
+#include "llvm/ADT/SetVector.h"
+#include "llvm/Analysis/AssumptionCache.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/Support/Compiler.h"
+#include <vector>
+
+namespace llvm {
+
+/// This pass handles simple speculating of instructions around PHIs when
+/// doing so is profitable for a particular target despite duplicated
+/// instructions.
+///
+/// The motivating example are PHIs of constants which will require
+/// materializing the constants along each edge. If the PHI is used by an
+/// instruction where the target can materialize the constant as part of the
+/// instruction, it is profitable to speculate those instructions around the
+/// PHI node. This can reduce dynamic instruction count as well as decrease
+/// register pressure.
+///
+/// Consider this IR for example:
+/// ```
+/// entry:
+/// br i1 %flag, label %a, label %b
+///
+/// a:
+/// br label %exit
+///
+/// b:
+/// br label %exit
+///
+/// exit:
+/// %p = phi i32 [ 7, %a ], [ 11, %b ]
+/// %sum = add i32 %arg, %p
+/// ret i32 %sum
+/// ```
+/// To materialize the inputs to this PHI node may require an explicit
+/// instruction. For example, on x86 this would turn into something like
+/// ```
+/// testq %eax, %eax
+/// movl $7, %rNN
+/// jne .L
+/// movl $11, %rNN
+/// .L:
+/// addl %edi, %rNN
+/// movl %rNN, %eax
+/// retq
+/// ```
+/// When these constants can be folded directly into another instruction, it
+/// would be preferable to avoid the potential for register pressure (above we
+/// can easily avoid it, but that isn't always true) and simply duplicate the
+/// instruction using the PHI:
+/// ```
+/// entry:
+/// br i1 %flag, label %a, label %b
+///
+/// a:
+/// %sum.1 = add i32 %arg, 7
+/// br label %exit
+///
+/// b:
+/// %sum.2 = add i32 %arg, 11
+/// br label %exit
+///
+/// exit:
+/// %p = phi i32 [ %sum.1, %a ], [ %sum.2, %b ]
+/// ret i32 %p
+/// ```
+/// Which will generate something like the following on x86:
+/// ```
+/// testq %eax, %eax
+/// addl $7, %edi
+/// jne .L
+/// addl $11, %edi
+/// .L:
+/// movl %edi, %eax
+/// retq
+/// ```
+///
+/// It is important to note that this pass is never intended to handle more
+/// complex cases where speculating around PHIs allows simplifications of the
+/// IR itself or other subsequent optimizations. Those can and should already
+/// be handled before this pass is ever run by a more powerful analysis that
+/// can reason about equivalences and common subexpressions. Classically, those
+/// cases would be handled by a GVN-powered PRE or similar transform. This
+/// pass, in contrast, is *only* interested in cases where despite no
+/// simplifications to the IR itself, speculation is *faster* to execute. The
+/// result of this is that the cost models which are appropriate to consider
+/// here are relatively simple ones around execution and codesize cost, without
+/// any need to consider simplifications or other transformations.
+struct SpeculateAroundPHIsPass : PassInfoMixin<SpeculateAroundPHIsPass> {
+ /// \brief Run the pass over the function.
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_SCALAR_SPECULATEAROUNDPHIS_H
diff --git a/include/llvm/Transforms/Utils/AddDiscriminators.h b/include/llvm/Transforms/Utils/AddDiscriminators.h
index a877583009922..4dad06e6c1254 100644
--- a/include/llvm/Transforms/Utils/AddDiscriminators.h
+++ b/include/llvm/Transforms/Utils/AddDiscriminators.h
@@ -1,4 +1,4 @@
-//===- AddDiscriminators.h -------------------------------------*- C++ -*-===//
+//===- AddDiscriminators.h --------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -20,10 +20,13 @@
namespace llvm {
+class Function;
+
class AddDiscriminatorsPass : public PassInfoMixin<AddDiscriminatorsPass> {
public:
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};
+
} // end namespace llvm
#endif // LLVM_TRANSFORMS_UTILS_ADDDISCRIMINATORS_H
diff --git a/include/llvm/Transforms/Utils/BasicBlockUtils.h b/include/llvm/Transforms/Utils/BasicBlockUtils.h
index 85bb053135a65..74f75509f550e 100644
--- a/include/llvm/Transforms/Utils/BasicBlockUtils.h
+++ b/include/llvm/Transforms/Utils/BasicBlockUtils.h
@@ -1,4 +1,4 @@
-//===-- Transform/Utils/BasicBlockUtils.h - BasicBlock Utils ----*- C++ -*-===//
+//===- Transform/Utils/BasicBlockUtils.h - BasicBlock Utils -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -25,13 +25,17 @@
namespace llvm {
-class MemoryDependenceResults;
+class BlockFrequencyInfo;
+class BranchProbabilityInfo;
class DominatorTree;
-class LoopInfo;
+class Function;
class Instruction;
+class LoopInfo;
class MDNode;
+class MemoryDependenceResults;
class ReturnInst;
class TargetLibraryInfo;
+class Value;
/// Delete the specified block, which must have no predecessors.
void DeleteDeadBlock(BasicBlock *BB);
@@ -118,7 +122,6 @@ struct CriticalEdgeSplittingOptions {
/// IndirectBrInst. Splitting these edges will almost always create an invalid
/// program because the address of the new block won't be the one that is jumped
/// to.
-///
BasicBlock *SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum,
const CriticalEdgeSplittingOptions &Options =
CriticalEdgeSplittingOptions());
@@ -194,7 +197,6 @@ BasicBlock *SplitBlock(BasicBlock *Old, Instruction *SplitPt,
/// no other analyses. In particular, it does not preserve LoopSimplify
/// (because it's complicated to handle the case where one of the edges being
/// split is an exit of a loop with other exits).
-///
BasicBlock *SplitBlockPredecessors(BasicBlock *BB, ArrayRef<BasicBlock *> Preds,
const char *Suffix,
DominatorTree *DT = nullptr,
@@ -212,7 +214,6 @@ BasicBlock *SplitBlockPredecessors(BasicBlock *BB, ArrayRef<BasicBlock *> Preds,
/// no other analyses. In particular, it does not preserve LoopSimplify
/// (because it's complicated to handle the case where one of the edges being
/// split is an exit of a loop with other exits).
-///
void SplitLandingPadPredecessors(BasicBlock *OrigBB,
ArrayRef<BasicBlock *> Preds,
const char *Suffix, const char *Suffix2,
@@ -284,6 +285,29 @@ void SplitBlockAndInsertIfThenElse(Value *Cond, Instruction *SplitBefore,
Value *GetIfCondition(BasicBlock *BB, BasicBlock *&IfTrue,
BasicBlock *&IfFalse);
+// Split critical edges where the source of the edge is an indirectbr
+// instruction. This isn't always possible, but we can handle some easy cases.
+// This is useful because MI is unable to split such critical edges,
+// which means it will not be able to sink instructions along those edges.
+// This is especially painful for indirect branches with many successors, where
+// we end up having to prepare all outgoing values in the origin block.
+//
+// Our normal algorithm for splitting critical edges requires us to update
+// the outgoing edges of the edge origin block, but for an indirectbr this
+// is hard, since it would require finding and updating the block addresses
+// the indirect branch uses. But if a block only has a single indirectbr
+// predecessor, with the others being regular branches, we can do it in a
+// different way.
+// Say we have A -> D, B -> D, I -> D where only I -> D is an indirectbr.
+// We can split D into D0 and D1, where D0 contains only the PHIs from D,
+// and D1 is the D block body. We can then duplicate D0 as D0A and D0B, and
+// create the following structure:
+// A -> D0A, B -> D0A, I -> D0B, D0A -> D1, D0B -> D1
+// If BPI and BFI aren't non-null, BPI/BFI will be updated accordingly.
+bool SplitIndirectBrCriticalEdges(Function &F,
+ BranchProbabilityInfo *BPI = nullptr,
+ BlockFrequencyInfo *BFI = nullptr);
+
} // end namespace llvm
#endif // LLVM_TRANSFORMS_UTILS_BASICBLOCKUTILS_H
diff --git a/include/llvm/Transforms/Utils/BypassSlowDivision.h b/include/llvm/Transforms/Utils/BypassSlowDivision.h
index af0d60b2625f7..6eca5ed2154e2 100644
--- a/include/llvm/Transforms/Utils/BypassSlowDivision.h
+++ b/include/llvm/Transforms/Utils/BypassSlowDivision.h
@@ -1,4 +1,4 @@
-//===- llvm/Transforms/Utils/BypassSlowDivision.h --------------*- C++ -*-===//
+//===- llvm/Transforms/Utils/BypassSlowDivision.h ---------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,10 +19,44 @@
#define LLVM_TRANSFORMS_UTILS_BYPASSSLOWDIVISION_H
#include "llvm/ADT/DenseMap.h"
-#include "llvm/IR/Function.h"
+#include "llvm/ADT/DenseMapInfo.h"
+#include <cstdint>
namespace llvm {
+class BasicBlock;
+class Value;
+
+struct DivRemMapKey {
+ bool SignedOp;
+ Value *Dividend;
+ Value *Divisor;
+
+ DivRemMapKey(bool InSignedOp, Value *InDividend, Value *InDivisor)
+ : SignedOp(InSignedOp), Dividend(InDividend), Divisor(InDivisor) {}
+};
+
+template <> struct DenseMapInfo<DivRemMapKey> {
+ static bool isEqual(const DivRemMapKey &Val1, const DivRemMapKey &Val2) {
+ return Val1.SignedOp == Val2.SignedOp && Val1.Dividend == Val2.Dividend &&
+ Val1.Divisor == Val2.Divisor;
+ }
+
+ static DivRemMapKey getEmptyKey() {
+ return DivRemMapKey(false, nullptr, nullptr);
+ }
+
+ static DivRemMapKey getTombstoneKey() {
+ return DivRemMapKey(true, nullptr, nullptr);
+ }
+
+ static unsigned getHashValue(const DivRemMapKey &Val) {
+ return (unsigned)(reinterpret_cast<uintptr_t>(Val.Dividend) ^
+ reinterpret_cast<uintptr_t>(Val.Divisor)) ^
+ (unsigned)Val.SignedOp;
+ }
+};
+
/// This optimization identifies DIV instructions in a BB that can be
/// profitably bypassed and carried out with a shorter, faster divide.
///
@@ -31,6 +65,6 @@ namespace llvm {
bool bypassSlowDivision(
BasicBlock *BB, const DenseMap<unsigned int, unsigned int> &BypassWidth);
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_TRANSFORMS_UTILS_BYPASSSLOWDIVISION_H
diff --git a/include/llvm/Transforms/Utils/CallPromotionUtils.h b/include/llvm/Transforms/Utils/CallPromotionUtils.h
new file mode 100644
index 0000000000000..e0bf85781d811
--- /dev/null
+++ b/include/llvm/Transforms/Utils/CallPromotionUtils.h
@@ -0,0 +1,44 @@
+//===- CallPromotionUtils.h - Utilities for call promotion ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares utilities useful for promoting indirect call sites to
+// direct call sites.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_CALLPROMOTIONUTILS_H
+#define LLVM_TRANSFORMS_UTILS_CALLPROMOTIONUTILS_H
+
+#include "llvm/IR/CallSite.h"
+
+namespace llvm {
+
+/// Return true if the given indirect call site can be made to call \p Callee.
+///
+/// This function ensures that the number and type of the call site's arguments
+/// and return value match those of the given function. If the types do not
+/// match exactly, they must at least be bitcast compatible. If \p FailureReason
+/// is non-null and the indirect call cannot be promoted, the failure reason
+/// will be stored in it.
+bool isLegalToPromote(CallSite CS, Function *Callee,
+ const char **FailureReason = nullptr);
+
+/// Promote the given indirect call site to conditionally call \p Callee.
+///
+/// This function creates an if-then-else structure at the location of the call
+/// site. The original call site is promoted and moved into the "then" block. A
+/// clone of the indirect call site is placed in the "else" block and returned.
+/// If \p BranchWeights is non-null, it will be used to set !prof metadata on
+/// the new conditional branch.
+Instruction *promoteCallWithIfThenElse(CallSite CS, Function *Callee,
+ MDNode *BranchWeights = nullptr);
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_UTILS_CALLPROMOTIONUTILS_H
diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h
index 2a8b89d862821..178bae76cef64 100644
--- a/include/llvm/Transforms/Utils/Cloning.h
+++ b/include/llvm/Transforms/Utils/Cloning.h
@@ -227,12 +227,18 @@ public:
/// *inlined* code to minimize the actual inserted code, it must not delete
/// code in the caller as users of this routine may have pointers to
/// instructions in the caller that need to remain stable.
+///
+/// If ForwardVarArgsTo is passed, inlining a function with varargs is allowed
+/// and all varargs at the callsite will be passed to any calls to
+/// ForwardVarArgsTo. The caller of InlineFunction has to make sure any varargs
+/// are only used by ForwardVarArgsTo.
bool InlineFunction(CallInst *C, InlineFunctionInfo &IFI,
AAResults *CalleeAAR = nullptr, bool InsertLifetime = true);
bool InlineFunction(InvokeInst *II, InlineFunctionInfo &IFI,
AAResults *CalleeAAR = nullptr, bool InsertLifetime = true);
bool InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
- AAResults *CalleeAAR = nullptr, bool InsertLifetime = true);
+ AAResults *CalleeAAR = nullptr, bool InsertLifetime = true,
+ Function *ForwardVarArgsTo = nullptr);
/// \brief Clones a loop \p OrigLoop. Returns the loop and the blocks in \p
/// Blocks.
diff --git a/include/llvm/Transforms/Utils/CmpInstAnalysis.h b/include/llvm/Transforms/Utils/CmpInstAnalysis.h
deleted file mode 100644
index 5ec3888d4538c..0000000000000
--- a/include/llvm/Transforms/Utils/CmpInstAnalysis.h
+++ /dev/null
@@ -1,70 +0,0 @@
-//===-- 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.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file holds routines to help analyse compare instructions
-// and fold them into constants or other compare instructions
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_UTILS_CMPINSTANALYSIS_H
-#define LLVM_TRANSFORMS_UTILS_CMPINSTANALYSIS_H
-
-#include "llvm/IR/InstrTypes.h"
-
-namespace llvm {
- class ICmpInst;
- class Value;
-
- /// Encode a icmp predicate into a three bit mask. These bits are carefully
- /// arranged to allow folding of expressions such as:
- ///
- /// (A < B) | (A > B) --> (A != B)
- ///
- /// Note that this is only valid if the first and second predicates have the
- /// same sign. It is illegal to do: (A u< B) | (A s> B)
- ///
- /// Three bits are used to represent the condition, as follows:
- /// 0 A > B
- /// 1 A == B
- /// 2 A < B
- ///
- /// <=> Value Definition
- /// 000 0 Always false
- /// 001 1 A > B
- /// 010 2 A == B
- /// 011 3 A >= B
- /// 100 4 A < B
- /// 101 5 A != B
- /// 110 6 A <= B
- /// 111 7 Always true
- ///
- unsigned getICmpCode(const ICmpInst *ICI, bool InvertPred = false);
-
- /// This is the complement of getICmpCode, which turns an opcode and two
- /// operands into either a constant true or false, or the predicate for a new
- /// ICmp instruction. The sign is passed in to determine which kind of
- /// predicate to use in the new icmp instruction.
- /// Non-NULL return value will be a true or false constant.
- /// NULL return means a new ICmp is needed. The predicate for which is output
- /// in NewICmpPred.
- Value *getICmpValue(bool Sign, unsigned Code, Value *LHS, Value *RHS,
- CmpInst::Predicate &NewICmpPred);
-
- /// Return true if both predicates match sign or if at least one of them is an
- /// equality comparison (which is signless).
- bool PredicatesFoldable(CmpInst::Predicate p1, CmpInst::Predicate p2);
-
- /// Decompose an icmp into the form ((X & Y) pred Z) if possible. The returned
- /// predicate is either == or !=. Returns false if decomposition fails.
- bool decomposeBitTestICmp(const ICmpInst *I, CmpInst::Predicate &Pred,
- Value *&X, Value *&Y, Value *&Z);
-
-} // end namespace llvm
-
-#endif
diff --git a/include/llvm/Transforms/Utils/CodeExtractor.h b/include/llvm/Transforms/Utils/CodeExtractor.h
index 682b353ab5ae8..63d34511102dc 100644
--- a/include/llvm/Transforms/Utils/CodeExtractor.h
+++ b/include/llvm/Transforms/Utils/CodeExtractor.h
@@ -1,4 +1,4 @@
-//===-- Transform/Utils/CodeExtractor.h - Code extraction util --*- C++ -*-===//
+//===- Transform/Utils/CodeExtractor.h - Code extraction util ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,22 +15,24 @@
#ifndef LLVM_TRANSFORMS_UTILS_CODEEXTRACTOR_H
#define LLVM_TRANSFORMS_UTILS_CODEEXTRACTOR_H
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SetVector.h"
+#include <limits>
namespace llvm {
-template <typename T> class ArrayRef;
- class BasicBlock;
- class BlockFrequency;
- class BlockFrequencyInfo;
- class BranchProbabilityInfo;
- class DominatorTree;
- class Function;
- class Instruction;
- class Loop;
- class Module;
- class RegionNode;
- class Type;
- class Value;
+
+class BasicBlock;
+class BlockFrequency;
+class BlockFrequencyInfo;
+class BranchProbabilityInfo;
+class DominatorTree;
+class Function;
+class Instruction;
+class Loop;
+class Module;
+class Type;
+class Value;
/// \brief Utility class for extracting code into a new function.
///
@@ -46,7 +48,7 @@ template <typename T> class ArrayRef;
/// 3) Add allocas for any scalar outputs, adding all of the outputs' allocas
/// as arguments, and inserting stores to the arguments for any scalars.
class CodeExtractor {
- typedef SetVector<Value *> ValueSet;
+ using ValueSet = SetVector<Value *>;
// Various bits of state computed on construction.
DominatorTree *const DT;
@@ -54,27 +56,27 @@ template <typename T> class ArrayRef;
BlockFrequencyInfo *BFI;
BranchProbabilityInfo *BPI;
+ // If true, varargs functions can be extracted.
+ bool AllowVarArgs;
+
// Bits of intermediate state computed at various phases of extraction.
SetVector<BasicBlock *> Blocks;
- unsigned NumExitBlocks;
+ unsigned NumExitBlocks = std::numeric_limits<unsigned>::max();
Type *RetTy;
public:
-
- /// \brief Check to see if a block is valid for extraction.
- ///
- /// Blocks containing EHPads, allocas, invokes, or vastarts are not valid.
- static bool isBlockValidForExtraction(const BasicBlock &BB);
-
/// \brief Create a code extractor for a sequence of blocks.
///
/// Given a sequence of basic blocks where the first block in the sequence
/// dominates the rest, prepare a code extractor object for pulling this
/// sequence out into its new function. When a DominatorTree is also given,
- /// extra checking and transformations are enabled.
+ /// extra checking and transformations are enabled. If AllowVarArgs is true,
+ /// vararg functions can be extracted. This is safe, if all vararg handling
+ /// code is extracted, including vastart.
CodeExtractor(ArrayRef<BasicBlock *> BBs, DominatorTree *DT = nullptr,
bool AggregateArgs = false, BlockFrequencyInfo *BFI = nullptr,
- BranchProbabilityInfo *BPI = nullptr);
+ BranchProbabilityInfo *BPI = nullptr,
+ bool AllowVarArgs = false);
/// \brief Create a code extractor for a loop body.
///
@@ -84,6 +86,14 @@ template <typename T> class ArrayRef;
BlockFrequencyInfo *BFI = nullptr,
BranchProbabilityInfo *BPI = nullptr);
+ /// \brief Check to see if a block is valid for extraction.
+ ///
+ /// Blocks containing EHPads, allocas and invokes are not valid. If
+ /// AllowVarArgs is true, blocks with vastart can be extracted. This is
+ /// safe, if all vararg handling code is extracted, including vastart.
+ static bool isBlockValidForExtraction(const BasicBlock &BB,
+ bool AllowVarArgs);
+
/// \brief Perform the extraction, returning the new function.
///
/// Returns zero when called on a CodeExtractor instance where isEligible
@@ -112,6 +122,7 @@ template <typename T> class ArrayRef;
///
/// Returns true if it is safe to do the code motion.
bool isLegalToShrinkwrapLifetimeMarkers(Instruction *AllocaAddr) const;
+
/// Find the set of allocas whose life ranges are contained within the
/// outlined region.
///
@@ -155,6 +166,7 @@ template <typename T> class ArrayRef;
ValueSet &inputs,
ValueSet &outputs);
};
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_UTILS_CODEEXTRACTOR_H
diff --git a/include/llvm/Transforms/Utils/EntryExitInstrumenter.h b/include/llvm/Transforms/Utils/EntryExitInstrumenter.h
new file mode 100644
index 0000000000000..f50c5c9220816
--- /dev/null
+++ b/include/llvm/Transforms/Utils/EntryExitInstrumenter.h
@@ -0,0 +1,36 @@
+//===- EntryExitInstrumenter.h - Function Entry/Exit Instrumentation ------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// EntryExitInstrumenter pass - Instrument function entry/exit with calls to
+// mcount(), @__cyg_profile_func_{enter,exit} and the like. There are two
+// variants, intended to run pre- and post-inlining, respectively.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_ENTRYEXITINSTRUMENTER_H
+#define LLVM_TRANSFORMS_UTILS_ENTRYEXITINSTRUMENTER_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class Function;
+
+struct EntryExitInstrumenterPass
+ : public PassInfoMixin<EntryExitInstrumenterPass> {
+ EntryExitInstrumenterPass(bool PostInlining) : PostInlining(PostInlining) {}
+
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+
+ bool PostInlining;
+};
+
+} // namespace llvm
+
+#endif // LLVM_TRANSFORMS_UTILS_ENTRYEXITINSTRUMENTER_H
diff --git a/include/llvm/Transforms/Utils/Evaluator.h b/include/llvm/Transforms/Utils/Evaluator.h
index 07f12f41b3bcd..0e987b93177aa 100644
--- a/include/llvm/Transforms/Utils/Evaluator.h
+++ b/include/llvm/Transforms/Utils/Evaluator.h
@@ -1,4 +1,4 @@
-//===-- Evaluator.h - LLVM IR evaluator -------------------------*- C++ -*-===//
+//===- Evaluator.h - LLVM IR evaluator --------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,9 +18,10 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/Constant.h"
#include "llvm/IR/GlobalVariable.h"
-
+#include "llvm/IR/Value.h"
+#include "llvm/Support/Casting.h"
+#include <cassert>
#include <deque>
#include <memory>
@@ -114,6 +115,6 @@ private:
const TargetLibraryInfo *TLI;
};
-}
+} // end namespace llvm
-#endif
+#endif // LLVM_TRANSFORMS_UTILS_EVALUATOR_H
diff --git a/include/llvm/Transforms/Utils/FunctionComparator.h b/include/llvm/Transforms/Utils/FunctionComparator.h
index b0f10eafaa95f..7698a068717a9 100644
--- a/include/llvm/Transforms/Utils/FunctionComparator.h
+++ b/include/llvm/Transforms/Utils/FunctionComparator.h
@@ -15,10 +15,10 @@
#ifndef LLVM_TRANSFORMS_UTILS_FUNCTIONCOMPARATOR_H
#define LLVM_TRANSFORMS_UTILS_FUNCTIONCOMPARATOR_H
-#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/IR/Function.h"
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/Instructions.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/ValueMap.h"
#include "llvm/Support/AtomicOrdering.h"
@@ -28,7 +28,17 @@
namespace llvm {
-class GetElementPtrInst;
+class APFloat;
+class APInt;
+class BasicBlock;
+class Constant;
+class Function;
+class GlobalValue;
+class InlineAsm;
+class Instruction;
+class MDNode;
+class Type;
+class Value;
/// GlobalNumberState assigns an integer to each global value in the program,
/// which is used by the comparison routine to order references to globals. This
@@ -43,14 +53,16 @@ class GetElementPtrInst;
/// compare those, but this would not work for stripped bitcodes or for those
/// few symbols without a name.
class GlobalNumberState {
- struct Config : ValueMapConfig<GlobalValue*> {
+ struct Config : ValueMapConfig<GlobalValue *> {
enum { FollowRAUW = false };
};
+
// Each GlobalValue is mapped to an identifier. The Config ensures when RAUW
// occurs, the mapping does not change. Tracking changes is unnecessary, and
// also problematic for weak symbols (which may be overwritten).
- typedef ValueMap<GlobalValue *, uint64_t, Config> ValueNumberMap;
+ using ValueNumberMap = ValueMap<GlobalValue *, uint64_t, Config>;
ValueNumberMap GlobalNumbers;
+
// The next unused serial number to assign to a global.
uint64_t NextNumber = 0;
@@ -66,6 +78,10 @@ public:
return MapIter->second;
}
+ void erase(GlobalValue *Global) {
+ GlobalNumbers.erase(Global);
+ }
+
void clear() {
GlobalNumbers.clear();
}
@@ -83,9 +99,10 @@ public:
/// Test whether the two functions have equivalent behaviour.
int compare();
+
/// Hash a function. Equivalent functions will have the same hash, and unequal
/// functions will have different hashes with high probability.
- typedef uint64_t FunctionHash;
+ using FunctionHash = uint64_t;
static FunctionHash functionHash(Function &);
protected:
diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h
index 30b27616cd982..01db88bc15c2f 100644
--- a/include/llvm/Transforms/Utils/Local.h
+++ b/include/llvm/Transforms/Utils/Local.h
@@ -1,4 +1,4 @@
-//===-- Local.h - Functions to perform local transformations ----*- C++ -*-===//
+//===- Local.h - Functions to perform local transformations -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,39 +15,95 @@
#ifndef LLVM_TRANSFORMS_UTILS_LOCAL_H
#define LLVM_TRANSFORMS_UTILS_LOCAL_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/IR/CallSite.h"
+#include "llvm/IR/Constant.h"
+#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/GetElementPtrTypeIterator.h"
-#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Operator.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/User.h"
+#include "llvm/IR/Value.h"
+#include "llvm/Support/Casting.h"
+#include <cstdint>
+#include <limits>
namespace llvm {
-class User;
+class AllocaInst;
+class AssumptionCache;
class BasicBlock;
-class Function;
class BranchInst;
-class Instruction;
class CallInst;
-class DbgDeclareInst;
+class DbgInfoIntrinsic;
class DbgValueInst;
-class StoreInst;
+class DIBuilder;
+class Function;
+class Instruction;
+class LazyValueInfo;
class LoadInst;
-class Value;
+class MDNode;
class PHINode;
-class AllocaInst;
-class AssumptionCache;
-class ConstantExpr;
-class DataLayout;
+class StoreInst;
class TargetLibraryInfo;
class TargetTransformInfo;
-class DIBuilder;
-class DominatorTree;
-class LazyValueInfo;
-template<typename T> class SmallVectorImpl;
+/// A set of parameters used to control the transforms in the SimplifyCFG pass.
+/// Options may change depending on the position in the optimization pipeline.
+/// For example, canonical form that includes switches and branches may later be
+/// replaced by lookup tables and selects.
+struct SimplifyCFGOptions {
+ int BonusInstThreshold;
+ bool ForwardSwitchCondToPhi;
+ bool ConvertSwitchToLookupTable;
+ bool NeedCanonicalLoop;
+ bool SinkCommonInsts;
+ AssumptionCache *AC;
+
+ SimplifyCFGOptions(unsigned BonusThreshold = 1,
+ bool ForwardSwitchCond = false,
+ bool SwitchToLookup = false, bool CanonicalLoops = true,
+ bool SinkCommon = false,
+ AssumptionCache *AssumpCache = nullptr)
+ : BonusInstThreshold(BonusThreshold),
+ ForwardSwitchCondToPhi(ForwardSwitchCond),
+ ConvertSwitchToLookupTable(SwitchToLookup),
+ NeedCanonicalLoop(CanonicalLoops),
+ SinkCommonInsts(SinkCommon),
+ AC(AssumpCache) {}
+
+ // Support 'builder' pattern to set members by name at construction time.
+ SimplifyCFGOptions &bonusInstThreshold(int I) {
+ BonusInstThreshold = I;
+ return *this;
+ }
+ SimplifyCFGOptions &forwardSwitchCondToPhi(bool B) {
+ ForwardSwitchCondToPhi = B;
+ return *this;
+ }
+ SimplifyCFGOptions &convertSwitchToLookupTable(bool B) {
+ ConvertSwitchToLookupTable = B;
+ return *this;
+ }
+ SimplifyCFGOptions &needCanonicalLoops(bool B) {
+ NeedCanonicalLoop = B;
+ return *this;
+ }
+ SimplifyCFGOptions &sinkCommonInsts(bool B) {
+ SinkCommonInsts = B;
+ return *this;
+ }
+ SimplifyCFGOptions &setAssumptionCache(AssumptionCache *Cache) {
+ AC = Cache;
+ return *this;
+ }
+};
//===----------------------------------------------------------------------===//
// Local constant propagation.
@@ -133,17 +189,15 @@ bool TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB);
/// values, but instcombine orders them so it usually won't matter.
bool EliminateDuplicatePHINodes(BasicBlock *BB);
-/// This function is used to do simplification of a CFG. For
-/// example, it adjusts branches to branches to eliminate the extra hop, it
-/// eliminates unreachable basic blocks, and does other "peephole" optimization
-/// of the CFG. It returns true if a modification was made, possibly deleting
-/// the basic block that was pointed to. LoopHeaders is an optional input
-/// parameter, providing the set of loop header that SimplifyCFG should not
-/// eliminate.
-bool SimplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
- unsigned BonusInstThreshold, AssumptionCache *AC = nullptr,
- SmallPtrSetImpl<BasicBlock *> *LoopHeaders = nullptr,
- bool LateSimplifyCFG = false);
+/// This function is used to do simplification of a CFG. For example, it
+/// adjusts branches to branches to eliminate the extra hop, it eliminates
+/// unreachable basic blocks, and does other peephole optimization of the CFG.
+/// It returns true if a modification was made, possibly deleting the basic
+/// block that was pointed to. LoopHeaders is an optional input parameter
+/// providing the set of loop headers that SimplifyCFG should not eliminate.
+bool simplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
+ const SimplifyCFGOptions &Options = {},
+ SmallPtrSetImpl<BasicBlock *> *LoopHeaders = nullptr);
/// This function is used to flatten a CFG. For example, it uses parallel-and
/// and parallel-or mode to collapse if-conditions and merge if-regions with
@@ -185,10 +239,10 @@ unsigned getOrEnforceKnownAlignment(Value *V, unsigned PrefAlign,
const DominatorTree *DT = nullptr);
/// Try to infer an alignment for the specified pointer.
-static inline unsigned getKnownAlignment(Value *V, const DataLayout &DL,
- const Instruction *CxtI = nullptr,
- AssumptionCache *AC = nullptr,
- const DominatorTree *DT = nullptr) {
+inline unsigned getKnownAlignment(Value *V, const DataLayout &DL,
+ const Instruction *CxtI = nullptr,
+ AssumptionCache *AC = nullptr,
+ const DominatorTree *DT = nullptr) {
return getOrEnforceKnownAlignment(V, 0, DL, CxtI, AC, DT);
}
@@ -210,7 +264,8 @@ Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &DL, User *GEP,
// Build a mask for high order bits.
unsigned IntPtrWidth = IntPtrTy->getScalarType()->getIntegerBitWidth();
- uint64_t PtrSizeMask = ~0ULL >> (64 - IntPtrWidth);
+ uint64_t PtrSizeMask =
+ std::numeric_limits<uint64_t>::max() >> (64 - IntPtrWidth);
gep_type_iterator GTI = gep_type_begin(GEP);
for (User::op_iterator i = GEP->op_begin() + 1, e = GEP->op_end(); i != e;
@@ -262,46 +317,50 @@ Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &DL, User *GEP,
///
/// Inserts a llvm.dbg.value intrinsic before a store to an alloca'd value
-/// that has an associated llvm.dbg.decl intrinsic.
-void ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
+/// that has an associated llvm.dbg.declare or llvm.dbg.addr intrinsic.
+void ConvertDebugDeclareToDebugValue(DbgInfoIntrinsic *DII,
StoreInst *SI, DIBuilder &Builder);
/// Inserts a llvm.dbg.value intrinsic before a load of an alloca'd value
-/// that has an associated llvm.dbg.decl intrinsic.
-void ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
+/// that has an associated llvm.dbg.declare or llvm.dbg.addr intrinsic.
+void ConvertDebugDeclareToDebugValue(DbgInfoIntrinsic *DII,
LoadInst *LI, DIBuilder &Builder);
-/// Inserts a llvm.dbg.value intrinsic after a phi of an alloca'd value
-/// that has an associated llvm.dbg.decl intrinsic.
-void ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
+/// Inserts a llvm.dbg.value intrinsic after a phi that has an associated
+/// llvm.dbg.declare or llvm.dbg.addr intrinsic.
+void ConvertDebugDeclareToDebugValue(DbgInfoIntrinsic *DII,
PHINode *LI, DIBuilder &Builder);
/// Lowers llvm.dbg.declare intrinsics into appropriate set of
/// llvm.dbg.value intrinsics.
bool LowerDbgDeclare(Function &F);
-/// Finds the llvm.dbg.declare intrinsic corresponding to an alloca, if any.
-DbgDeclareInst *FindAllocaDbgDeclare(Value *V);
+/// Finds all intrinsics declaring local variables as living in the memory that
+/// 'V' points to. This may include a mix of dbg.declare and
+/// dbg.addr intrinsics.
+TinyPtrVector<DbgInfoIntrinsic *> FindDbgAddrUses(Value *V);
/// Finds the llvm.dbg.value intrinsics describing a value.
void findDbgValues(SmallVectorImpl<DbgValueInst *> &DbgValues, Value *V);
-/// Replaces llvm.dbg.declare instruction when the address it describes
-/// is replaced with a new value. If Deref is true, an additional DW_OP_deref is
-/// prepended to the expression. If Offset is non-zero, a constant displacement
-/// is added to the expression (after the optional Deref). Offset can be
-/// negative.
+/// Replaces llvm.dbg.declare instruction when the address it
+/// describes is replaced with a new value. If Deref is true, an
+/// additional DW_OP_deref is prepended to the expression. If Offset
+/// is non-zero, a constant displacement is added to the expression
+/// (between the optional Deref operations). Offset can be negative.
bool replaceDbgDeclare(Value *Address, Value *NewAddress,
Instruction *InsertBefore, DIBuilder &Builder,
- bool Deref, int Offset);
+ bool DerefBefore, int Offset, bool DerefAfter);
/// Replaces llvm.dbg.declare instruction when the alloca it describes
-/// is replaced with a new value. If Deref is true, an additional DW_OP_deref is
-/// prepended to the expression. If Offset is non-zero, a constant displacement
-/// is added to the expression (after the optional Deref). Offset can be
-/// negative. New llvm.dbg.declare is inserted immediately before AI.
+/// is replaced with a new value. If Deref is true, an additional
+/// DW_OP_deref is prepended to the expression. If Offset is non-zero,
+/// a constant displacement is added to the expression (between the
+/// optional Deref operations). Offset can be negative. The new
+/// llvm.dbg.declare is inserted immediately before AI.
bool replaceDbgDeclareForAlloca(AllocaInst *AI, Value *NewAllocaAddress,
- DIBuilder &Builder, bool Deref, int Offset = 0);
+ DIBuilder &Builder, bool DerefBefore,
+ int Offset, bool DerefAfter);
/// Replaces multiple llvm.dbg.value instructions when the alloca it describes
/// is replaced with a new value. If Offset is non-zero, a constant displacement
@@ -369,7 +428,6 @@ unsigned replaceDominatedUsesWith(Value *From, Value *To, DominatorTree &DT,
unsigned replaceDominatedUsesWith(Value *From, Value *To, DominatorTree &DT,
const BasicBlock *BB);
-
/// Return true if the CallSite CS calls a gc leaf function.
///
/// A leaf function is a function that does not safepoint the thread during its
@@ -378,7 +436,7 @@ unsigned replaceDominatedUsesWith(Value *From, Value *To, DominatorTree &DT,
///
/// Most passes can and should ignore this information, and it is only used
/// during lowering by the GC infrastructure.
-bool callsGCLeafFunction(ImmutableCallSite CS);
+bool callsGCLeafFunction(ImmutableCallSite CS, const TargetLibraryInfo &TLI);
/// Copy a nonnull metadata node to a new load instruction.
///
@@ -397,7 +455,7 @@ void copyRangeMetadata(const DataLayout &DL, const LoadInst &OldLI, MDNode *N,
// Intrinsic pattern matching
//
-/// Try and match a bswap or bitreverse idiom.
+/// Try to match a bswap or bitreverse idiom.
///
/// If an idiom is matched, an intrinsic call is inserted before \c I. Any added
/// instructions are returned in \c InsertedInsts. They will all have been added
@@ -431,6 +489,6 @@ void maybeMarkSanitizerLibraryCallNoBuiltin(CallInst *CI,
/// value?
bool canReplaceOperandWithVariable(const Instruction *I, unsigned OpIdx);
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_TRANSFORMS_UTILS_LOCAL_H
diff --git a/include/llvm/Transforms/Utils/LoopUtils.h b/include/llvm/Transforms/Utils/LoopUtils.h
index 94e20b83754e7..7506661365070 100644
--- a/include/llvm/Transforms/Utils/LoopUtils.h
+++ b/include/llvm/Transforms/Utils/LoopUtils.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
@@ -305,10 +306,13 @@ public:
/// induction, the induction descriptor \p D will contain the data describing
/// this induction. If by some other means the caller has a better SCEV
/// expression for \p Phi than the one returned by the ScalarEvolution
- /// analysis, it can be passed through \p Expr.
- static bool isInductionPHI(PHINode *Phi, const Loop* L, ScalarEvolution *SE,
- InductionDescriptor &D,
- const SCEV *Expr = nullptr);
+ /// analysis, it can be passed through \p Expr. If the def-use chain
+ /// associated with the phi includes casts (that we know we can ignore
+ /// under proper runtime checks), they are passed through \p CastsToIgnore.
+ static bool
+ isInductionPHI(PHINode *Phi, const Loop* L, ScalarEvolution *SE,
+ InductionDescriptor &D, const SCEV *Expr = nullptr,
+ SmallVectorImpl<Instruction *> *CastsToIgnore = nullptr);
/// Returns true if \p Phi is a floating point induction in the loop \p L.
/// If \p Phi is an induction, the induction descriptor \p D will contain
@@ -330,15 +334,13 @@ public:
/// not have the "fast-math" property. Such operation requires a relaxed FP
/// mode.
bool hasUnsafeAlgebra() {
- return InductionBinOp &&
- !cast<FPMathOperator>(InductionBinOp)->hasUnsafeAlgebra();
+ return InductionBinOp && !cast<FPMathOperator>(InductionBinOp)->isFast();
}
/// Returns induction operator that does not have "fast-math" property
/// and requires FP unsafe mode.
Instruction *getUnsafeAlgebraInst() {
- if (!InductionBinOp ||
- cast<FPMathOperator>(InductionBinOp)->hasUnsafeAlgebra())
+ if (!InductionBinOp || cast<FPMathOperator>(InductionBinOp)->isFast())
return nullptr;
return InductionBinOp;
}
@@ -349,10 +351,18 @@ public:
Instruction::BinaryOpsEnd;
}
+ /// Returns a reference to the type cast instructions in the induction
+ /// update chain, that are redundant when guarded with a runtime
+ /// SCEV overflow check.
+ const SmallVectorImpl<Instruction *> &getCastInsts() const {
+ return RedundantCasts;
+ }
+
private:
/// Private constructor - used by \c isInductionPHI.
InductionDescriptor(Value *Start, InductionKind K, const SCEV *Step,
- BinaryOperator *InductionBinOp = nullptr);
+ BinaryOperator *InductionBinOp = nullptr,
+ SmallVectorImpl<Instruction *> *Casts = nullptr);
/// Start value.
TrackingVH<Value> StartValue;
@@ -362,6 +372,9 @@ private:
const SCEV *Step = nullptr;
// Instruction that advances induction variable.
BinaryOperator *InductionBinOp = nullptr;
+ // Instructions used for type-casts of the induction variable,
+ // that are redundant when guarded with a runtime SCEV overflow check.
+ SmallVector<Instruction *, 2> RedundantCasts;
};
BasicBlock *InsertPreheaderForLoop(Loop *L, DominatorTree *DT, LoopInfo *LI,
@@ -423,8 +436,9 @@ bool formLCSSARecursively(Loop &L, DominatorTree &DT, LoopInfo *LI,
/// instructions of the loop and loop safety information as
/// arguments. Diagnostics is emitted via \p ORE. It returns changed status.
bool sinkRegion(DomTreeNode *, AliasAnalysis *, LoopInfo *, DominatorTree *,
- TargetLibraryInfo *, Loop *, AliasSetTracker *,
- LoopSafetyInfo *, OptimizationRemarkEmitter *ORE);
+ TargetLibraryInfo *, TargetTransformInfo *, Loop *,
+ AliasSetTracker *, LoopSafetyInfo *,
+ OptimizationRemarkEmitter *ORE);
/// \brief Walk the specified region of the CFG (defined by all blocks
/// dominated by the specified block, and that are in the current loop) in depth
@@ -438,21 +452,41 @@ bool hoistRegion(DomTreeNode *, AliasAnalysis *, LoopInfo *, DominatorTree *,
TargetLibraryInfo *, Loop *, AliasSetTracker *,
LoopSafetyInfo *, OptimizationRemarkEmitter *ORE);
+/// This function deletes dead loops. The caller of this function needs to
+/// guarantee that the loop is infact dead.
+/// The function requires a bunch or prerequisites to be present:
+/// - The loop needs to be in LCSSA form
+/// - The loop needs to have a Preheader
+/// - A unique dedicated exit block must exist
+///
+/// This also updates the relevant analysis information in \p DT, \p SE, and \p
+/// LI if pointers to those are provided.
+/// It also updates the loop PM if an updater struct is provided.
+
+void deleteDeadLoop(Loop *L, DominatorTree *DT, ScalarEvolution *SE,
+ LoopInfo *LI);
+
/// \brief Try to promote memory values to scalars by sinking stores out of
/// the loop and moving loads to before the loop. We do this by looping over
/// the stores in the loop, looking for stores to Must pointers which are
-/// loop invariant. It takes AliasSet, Loop exit blocks vector, loop exit blocks
-/// insertion point vector, PredIteratorCache, LoopInfo, DominatorTree, Loop,
-/// AliasSet information for all instructions of the loop and loop safety
-/// information as arguments. Diagnostics is emitted via \p ORE. It returns
-/// changed status.
-bool promoteLoopAccessesToScalars(AliasSet &, SmallVectorImpl<BasicBlock *> &,
+/// loop invariant. It takes a set of must-alias values, Loop exit blocks
+/// vector, loop exit blocks insertion point vector, PredIteratorCache,
+/// LoopInfo, DominatorTree, Loop, AliasSet information for all instructions
+/// of the loop and loop safety information as arguments.
+/// Diagnostics is emitted via \p ORE. It returns changed status.
+bool promoteLoopAccessesToScalars(const SmallSetVector<Value *, 8> &,
+ SmallVectorImpl<BasicBlock *> &,
SmallVectorImpl<Instruction *> &,
PredIteratorCache &, LoopInfo *,
DominatorTree *, const TargetLibraryInfo *,
Loop *, AliasSetTracker *, LoopSafetyInfo *,
OptimizationRemarkEmitter *);
+/// Does a BFS from a given node to all of its children inside a given loop.
+/// The returned vector of nodes includes the starting point.
+SmallVector<DomTreeNode *, 16> collectChildrenInLoop(DomTreeNode *N,
+ const Loop *CurLoop);
+
/// \brief Computes safety information for a loop
/// checks loop body & header for the possibility of may throw
/// exception, it takes LoopSafetyInfo and loop as argument.
diff --git a/include/llvm/Transforms/Utils/LowerMemIntrinsics.h b/include/llvm/Transforms/Utils/LowerMemIntrinsics.h
index 4554b5cbc6440..2b7d0f67a3245 100644
--- a/include/llvm/Transforms/Utils/LowerMemIntrinsics.h
+++ b/include/llvm/Transforms/Utils/LowerMemIntrinsics.h
@@ -25,12 +25,6 @@ class MemSetInst;
class TargetTransformInfo;
class Value;
-/// Emit a loop implementing the semantics of llvm.memcpy with the equivalent
-/// arguments at \p InsertBefore.
-void createMemCpyLoop(Instruction *InsertBefore, Value *SrcAddr, Value *DstAddr,
- Value *CopyLen, unsigned SrcAlign, unsigned DestAlign,
- bool SrcIsVolatile, bool DstIsVolatile);
-
/// Emit a loop implementing the semantics of llvm.memcpy where the size is not
/// a compile-time constant. Loop will be insterted at \p InsertBefore.
void createMemCpyLoopUnknownSize(Instruction *InsertBefore, Value *SrcAddr,
diff --git a/include/llvm/Transforms/Utils/Mem2Reg.h b/include/llvm/Transforms/Utils/Mem2Reg.h
index 1fe186d6c3ad9..407684338a3b7 100644
--- a/include/llvm/Transforms/Utils/Mem2Reg.h
+++ b/include/llvm/Transforms/Utils/Mem2Reg.h
@@ -15,14 +15,17 @@
#ifndef LLVM_TRANSFORMS_UTILS_MEM2REG_H
#define LLVM_TRANSFORMS_UTILS_MEM2REG_H
-#include "llvm/IR/Function.h"
#include "llvm/IR/PassManager.h"
namespace llvm {
+
+class Function;
+
class PromotePass : public PassInfoMixin<PromotePass> {
public:
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};
-}
+
+} // end namespace llvm
#endif // LLVM_TRANSFORMS_UTILS_MEM2REG_H
diff --git a/include/llvm/Transforms/Utils/ModuleUtils.h b/include/llvm/Transforms/Utils/ModuleUtils.h
index e9793fe4b6666..4b9bc82938106 100644
--- a/include/llvm/Transforms/Utils/ModuleUtils.h
+++ b/include/llvm/Transforms/Utils/ModuleUtils.h
@@ -85,7 +85,8 @@ void filterDeadComdatFunctions(
Module &M, SmallVectorImpl<Function *> &DeadComdatFunctions);
/// \brief Produce a unique identifier for this module by taking the MD5 sum of
-/// the names of the module's strong external symbols.
+/// the names of the module's strong external symbols that are not comdat
+/// members.
///
/// This identifier is normally guaranteed to be unique, or the program would
/// fail to link due to multiply defined symbols.
diff --git a/include/llvm/Transforms/Utils/SSAUpdater.h b/include/llvm/Transforms/Utils/SSAUpdater.h
index 8cbcdf47156ea..6cd9f1539b0b3 100644
--- a/include/llvm/Transforms/Utils/SSAUpdater.h
+++ b/include/llvm/Transforms/Utils/SSAUpdater.h
@@ -1,4 +1,4 @@
-//===-- SSAUpdater.h - Unstructured SSA Update Tool -------------*- C++ -*-===//
+//===- SSAUpdater.h - Unstructured SSA Update Tool --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,6 +14,7 @@
#ifndef LLVM_TRANSFORMS_UTILS_SSAUPDATER_H
#define LLVM_TRANSFORMS_UTILS_SSAUPDATER_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include <string>
@@ -22,10 +23,9 @@ namespace llvm {
class BasicBlock;
class Instruction;
class LoadInst;
-template <typename T> class ArrayRef;
+class PHINode;
template <typename T> class SmallVectorImpl;
template <typename T> class SSAUpdaterTraits;
-class PHINode;
class Type;
class Use;
class Value;
@@ -42,7 +42,6 @@ class SSAUpdater {
private:
/// This keeps track of which value to use on a per-block basis. When we
/// insert PHI nodes, we keep track of them here.
- //typedef DenseMap<BasicBlock*, Value*> AvailableValsTy;
void *AV = nullptr;
/// ProtoType holds the type of the values being rewritten.
@@ -53,12 +52,12 @@ private:
/// If this is non-null, the SSAUpdater adds all PHI nodes that it creates to
/// the vector.
- SmallVectorImpl<PHINode*> *InsertedPHIs;
+ SmallVectorImpl<PHINode *> *InsertedPHIs;
public:
/// If InsertedPHIs is specified, it will be filled
/// in with all PHI Nodes created by rewriting.
- explicit SSAUpdater(SmallVectorImpl<PHINode*> *InsertedPHIs = nullptr);
+ explicit SSAUpdater(SmallVectorImpl<PHINode *> *InsertedPHIs = nullptr);
SSAUpdater(const SSAUpdater &) = delete;
SSAUpdater &operator=(const SSAUpdater &) = delete;
~SSAUpdater();
@@ -136,7 +135,7 @@ protected:
SSAUpdater &SSA;
public:
- LoadAndStorePromoter(ArrayRef<const Instruction*> Insts,
+ LoadAndStorePromoter(ArrayRef<const Instruction *> Insts,
SSAUpdater &S, StringRef Name = StringRef());
virtual ~LoadAndStorePromoter() = default;
@@ -145,32 +144,28 @@ public:
/// Insts is a list of loads and stores to promote, and Name is the basename
/// for the PHIs to insert. After this is complete, the loads and stores are
/// removed from the code.
- void run(const SmallVectorImpl<Instruction*> &Insts) const;
+ void run(const SmallVectorImpl<Instruction *> &Insts) const;
/// \brief Return true if the specified instruction is in the Inst list.
///
/// The Insts list is the one passed into the constructor. Clients should
/// implement this with a more efficient version if possible.
virtual bool isInstInList(Instruction *I,
- const SmallVectorImpl<Instruction*> &Insts) const;
+ const SmallVectorImpl<Instruction *> &Insts) const;
/// \brief This hook is invoked after all the stores are found and inserted as
/// available values.
- virtual void doExtraRewritesBeforeFinalDeletion() const {
- }
+ virtual void doExtraRewritesBeforeFinalDeletion() const {}
/// \brief Clients can choose to implement this to get notified right before
/// a load is RAUW'd another value.
- virtual void replaceLoadWithValue(LoadInst *LI, Value *V) const {
- }
+ virtual void replaceLoadWithValue(LoadInst *LI, Value *V) const {}
/// \brief Called before each instruction is deleted.
- virtual void instructionDeleted(Instruction *I) const {
- }
+ virtual void instructionDeleted(Instruction *I) const {}
/// \brief Called to update debug info associated with the instruction.
- virtual void updateDebugInfo(Instruction *I) const {
- }
+ virtual void updateDebugInfo(Instruction *I) const {}
};
} // end namespace llvm
diff --git a/include/llvm/Transforms/Utils/SSAUpdaterImpl.h b/include/llvm/Transforms/Utils/SSAUpdaterImpl.h
index 2dd205d8b2af2..b1611d49a456e 100644
--- a/include/llvm/Transforms/Utils/SSAUpdaterImpl.h
+++ b/include/llvm/Transforms/Utils/SSAUpdaterImpl.h
@@ -1,4 +1,4 @@
-//===-- SSAUpdaterImpl.h - SSA Updater Implementation -----------*- C++ -*-===//
+//===- SSAUpdaterImpl.h - SSA Updater Implementation ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,17 +17,14 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
#define DEBUG_TYPE "ssaupdater"
namespace llvm {
-class CastInst;
-class PHINode;
template<typename T> class SSAUpdaterTraits;
template<typename UpdaterT>
@@ -35,51 +32,67 @@ class SSAUpdaterImpl {
private:
UpdaterT *Updater;
- typedef SSAUpdaterTraits<UpdaterT> Traits;
- typedef typename Traits::BlkT BlkT;
- typedef typename Traits::ValT ValT;
- typedef typename Traits::PhiT PhiT;
+ using Traits = SSAUpdaterTraits<UpdaterT>;
+ using BlkT = typename Traits::BlkT;
+ using ValT = typename Traits::ValT;
+ using PhiT = typename Traits::PhiT;
/// BBInfo - Per-basic block information used internally by SSAUpdaterImpl.
/// The predecessors of each block are cached here since pred_iterator is
/// slow and we need to iterate over the blocks at least a few times.
class BBInfo {
public:
- BlkT *BB; // Back-pointer to the corresponding block.
- ValT AvailableVal; // Value to use in this block.
- BBInfo *DefBB; // Block that defines the available value.
- int BlkNum; // Postorder number.
- BBInfo *IDom; // Immediate dominator.
- unsigned NumPreds; // Number of predecessor blocks.
- BBInfo **Preds; // Array[NumPreds] of predecessor blocks.
- PhiT *PHITag; // Marker for existing PHIs that match.
+ // Back-pointer to the corresponding block.
+ BlkT *BB;
+
+ // Value to use in this block.
+ ValT AvailableVal;
+
+ // Block that defines the available value.
+ BBInfo *DefBB;
+
+ // Postorder number.
+ int BlkNum = 0;
+
+ // Immediate dominator.
+ BBInfo *IDom = nullptr;
+
+ // Number of predecessor blocks.
+ unsigned NumPreds = 0;
+
+ // Array[NumPreds] of predecessor blocks.
+ BBInfo **Preds = nullptr;
+
+ // Marker for existing PHIs that match.
+ PhiT *PHITag = nullptr;
BBInfo(BlkT *ThisBB, ValT V)
- : BB(ThisBB), AvailableVal(V), DefBB(V ? this : nullptr), BlkNum(0),
- IDom(nullptr), NumPreds(0), Preds(nullptr), PHITag(nullptr) {}
+ : BB(ThisBB), AvailableVal(V), DefBB(V ? this : nullptr) {}
};
- typedef DenseMap<BlkT*, ValT> AvailableValsTy;
+ using AvailableValsTy = DenseMap<BlkT *, ValT>;
+
AvailableValsTy *AvailableVals;
- SmallVectorImpl<PhiT*> *InsertedPHIs;
+ SmallVectorImpl<PhiT *> *InsertedPHIs;
+
+ using BlockListTy = SmallVectorImpl<BBInfo *>;
+ using BBMapTy = DenseMap<BlkT *, BBInfo *>;
- typedef SmallVectorImpl<BBInfo*> BlockListTy;
- typedef DenseMap<BlkT*, BBInfo*> BBMapTy;
BBMapTy BBMap;
BumpPtrAllocator Allocator;
public:
explicit SSAUpdaterImpl(UpdaterT *U, AvailableValsTy *A,
- SmallVectorImpl<PhiT*> *Ins) :
- Updater(U), AvailableVals(A), InsertedPHIs(Ins) { }
+ SmallVectorImpl<PhiT *> *Ins) :
+ Updater(U), AvailableVals(A), InsertedPHIs(Ins) {}
/// GetValue - Check to see if AvailableVals has an entry for the specified
/// BB and if so, return it. If not, construct SSA form by first
/// calculating the required placement of PHIs and then inserting new PHIs
/// where needed.
ValT GetValue(BlkT *BB) {
- SmallVector<BBInfo*, 100> BlockList;
+ SmallVector<BBInfo *, 100> BlockList;
BBInfo *PseudoEntry = BuildBlockList(BB, &BlockList);
// Special case: bail out if BB is unreachable.
@@ -101,8 +114,8 @@ public:
/// Create BBInfo structures for the blocks and append them to the block
/// list.
BBInfo *BuildBlockList(BlkT *BB, BlockListTy *BlockList) {
- SmallVector<BBInfo*, 10> RootList;
- SmallVector<BBInfo*, 64> WorkList;
+ SmallVector<BBInfo *, 10> RootList;
+ SmallVector<BBInfo *, 64> WorkList;
BBInfo *Info = new (Allocator) BBInfo(BB, 0);
BBMap[BB] = Info;
@@ -111,7 +124,7 @@ public:
// Search backward from BB, creating BBInfos along the way and stopping
// when reaching blocks that define the value. Record those defining
// blocks on the RootList.
- SmallVector<BlkT*, 10> Preds;
+ SmallVector<BlkT *, 10> Preds;
while (!WorkList.empty()) {
Info = WorkList.pop_back_val();
Preds.clear();
@@ -395,7 +408,7 @@ public:
/// CheckIfPHIMatches - Check if a PHI node matches the placement and values
/// in the BBMap.
bool CheckIfPHIMatches(PhiT *PHI) {
- SmallVector<PhiT*, 20> WorkList;
+ SmallVector<PhiT *, 20> WorkList;
WorkList.push_back(PHI);
// Mark that the block containing this PHI has been visited.
@@ -453,7 +466,7 @@ public:
}
};
-} // end llvm namespace
+} // end namespace llvm
#undef DEBUG_TYPE // "ssaupdater"
diff --git a/include/llvm/Transforms/Utils/SimplifyIndVar.h b/include/llvm/Transforms/Utils/SimplifyIndVar.h
index 8d50aeb10d6eb..a1dfed29a22d3 100644
--- a/include/llvm/Transforms/Utils/SimplifyIndVar.h
+++ b/include/llvm/Transforms/Utils/SimplifyIndVar.h
@@ -26,6 +26,7 @@ class Loop;
class LoopInfo;
class PHINode;
class ScalarEvolution;
+class SCEVExpander;
/// Interface for visiting interesting IV users that are recognized but not
/// simplified by this utility.
@@ -47,7 +48,7 @@ public:
/// by using ScalarEvolution to analyze the IV's recurrence.
bool simplifyUsersOfIV(PHINode *CurrIV, ScalarEvolution *SE, DominatorTree *DT,
LoopInfo *LI, SmallVectorImpl<WeakTrackingVH> &Dead,
- IVVisitor *V = nullptr);
+ SCEVExpander &Rewriter, IVVisitor *V = nullptr);
/// SimplifyLoopIVs - Simplify users of induction variables within this
/// loop. This does not actually change or add IVs.
diff --git a/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/include/llvm/Transforms/Utils/SimplifyLibCalls.h
index 6aba9b2298b10..73a62f59203b4 100644
--- a/include/llvm/Transforms/Utils/SimplifyLibCalls.h
+++ b/include/llvm/Transforms/Utils/SimplifyLibCalls.h
@@ -28,6 +28,7 @@ class Instruction;
class TargetLibraryInfo;
class BasicBlock;
class Function;
+class OptimizationRemarkEmitter;
/// \brief This class implements simplifications for calls to fortified library
/// functions (__st*cpy_chk, __memcpy_chk, __memmove_chk, __memset_chk), to,
@@ -73,6 +74,7 @@ private:
FortifiedLibCallSimplifier FortifiedSimplifier;
const DataLayout &DL;
const TargetLibraryInfo *TLI;
+ OptimizationRemarkEmitter &ORE;
bool UnsafeFPShrink;
function_ref<void(Instruction *, Value *)> Replacer;
@@ -87,6 +89,7 @@ private:
public:
LibCallSimplifier(const DataLayout &DL, const TargetLibraryInfo *TLI,
+ OptimizationRemarkEmitter &ORE,
function_ref<void(Instruction *, Value *)> Replacer =
&replaceAllUsesWithDefault);
@@ -126,14 +129,19 @@ private:
Value *optimizeStringMemoryLibCall(CallInst *CI, IRBuilder<> &B);
// Math Library Optimizations
+ Value *optimizeCAbs(CallInst *CI, IRBuilder<> &B);
Value *optimizeCos(CallInst *CI, IRBuilder<> &B);
Value *optimizePow(CallInst *CI, IRBuilder<> &B);
+ Value *replacePowWithSqrt(CallInst *Pow, IRBuilder<> &B);
Value *optimizeExp2(CallInst *CI, IRBuilder<> &B);
Value *optimizeFMinFMax(CallInst *CI, IRBuilder<> &B);
Value *optimizeLog(CallInst *CI, IRBuilder<> &B);
Value *optimizeSqrt(CallInst *CI, IRBuilder<> &B);
Value *optimizeSinCosPi(CallInst *CI, IRBuilder<> &B);
Value *optimizeTan(CallInst *CI, IRBuilder<> &B);
+ // Wrapper for all floating point library call optimizations
+ Value *optimizeFloatingPointLibCall(CallInst *CI, LibFunc Func,
+ IRBuilder<> &B);
// Integer Library Call Optimizations
Value *optimizeFFS(CallInst *CI, IRBuilder<> &B);
diff --git a/include/llvm/Transforms/Utils/SplitModule.h b/include/llvm/Transforms/Utils/SplitModule.h
index b7a3bcf4f86a5..d2c31f2701acc 100644
--- a/include/llvm/Transforms/Utils/SplitModule.h
+++ b/include/llvm/Transforms/Utils/SplitModule.h
@@ -22,7 +22,6 @@
namespace llvm {
class Module;
-class StringRef;
/// Splits the module M into N linkable partitions. The function ModuleCallback
/// is called N times passing each individual partition as the MPart argument.
@@ -39,6 +38,6 @@ void SplitModule(
function_ref<void(std::unique_ptr<Module> MPart)> ModuleCallback,
bool PreserveLocals = false);
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_TRANSFORMS_UTILS_SPLITMODULE_H
diff --git a/include/llvm/Transforms/Utils/SymbolRewriter.h b/include/llvm/Transforms/Utils/SymbolRewriter.h
index 93658989fba57..e0caf7741ff39 100644
--- a/include/llvm/Transforms/Utils/SymbolRewriter.h
+++ b/include/llvm/Transforms/Utils/SymbolRewriter.h
@@ -1,4 +1,4 @@
-//===-- SymbolRewriter.h - Symbol Rewriting Pass ----------------*- C++ -*-===//
+//===- SymbolRewriter.h - Symbol Rewriting Pass -----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -33,7 +33,6 @@
#ifndef LLVM_TRANSFORMS_UTILS_SYMBOLREWRITER_H
#define LLVM_TRANSFORMS_UTILS_SYMBOLREWRITER_H
-#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
#include <list>
#include <memory>
@@ -42,6 +41,8 @@
namespace llvm {
class MemoryBuffer;
+class Module;
+class ModulePass;
namespace yaml {
@@ -89,7 +90,7 @@ private:
const Type Kind;
};
-typedef std::list<std::unique_ptr<RewriteDescriptor>> RewriteDescriptorList;
+using RewriteDescriptorList = std::list<std::unique_ptr<RewriteDescriptor>>;
class RewriteMapParser {
public:
@@ -120,6 +121,7 @@ ModulePass *createRewriteSymbolsPass(SymbolRewriter::RewriteDescriptorList &);
class RewriteSymbolPass : public PassInfoMixin<RewriteSymbolPass> {
public:
RewriteSymbolPass() { loadAndParseMapFiles(); }
+
RewriteSymbolPass(SymbolRewriter::RewriteDescriptorList &DL) {
Descriptors.splice(Descriptors.begin(), DL);
}
diff --git a/include/llvm/Transforms/Utils/UnrollLoop.h b/include/llvm/Transforms/Utils/UnrollLoop.h
index a3115ad16914d..12aa3bc6e7709 100644
--- a/include/llvm/Transforms/Utils/UnrollLoop.h
+++ b/include/llvm/Transforms/Utils/UnrollLoop.h
@@ -16,40 +16,57 @@
#ifndef LLVM_TRANSFORMS_UTILS_UNROLLLOOP_H
#define LLVM_TRANSFORMS_UTILS_UNROLLLOOP_H
-// Needed because we can't forward-declare the nested struct
-// TargetTransformInfo::UnrollingPreferences
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/TargetTransformInfo.h"
namespace llvm {
-class StringRef;
class AssumptionCache;
+class BasicBlock;
class DominatorTree;
class Loop;
class LoopInfo;
-class LPPassManager;
class MDNode;
-class Pass;
class OptimizationRemarkEmitter;
class ScalarEvolution;
-typedef SmallDenseMap<const Loop *, Loop *, 4> NewLoopsMap;
+using NewLoopsMap = SmallDenseMap<const Loop *, Loop *, 4>;
const Loop* addClonedBlockToLoopInfo(BasicBlock *OriginalBB,
BasicBlock *ClonedBB, LoopInfo *LI,
NewLoopsMap &NewLoops);
-bool UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool Force,
- bool AllowRuntime, bool AllowExpensiveTripCount,
- bool PreserveCondBr, bool PreserveOnlyFirst,
- unsigned TripMultiple, unsigned PeelCount, LoopInfo *LI,
- ScalarEvolution *SE, DominatorTree *DT, AssumptionCache *AC,
- OptimizationRemarkEmitter *ORE, bool PreserveLCSSA);
+/// Represents the result of a \c UnrollLoop invocation.
+enum class LoopUnrollResult {
+ /// The loop was not modified.
+ Unmodified,
+
+ /// The loop was partially unrolled -- we still have a loop, but with a
+ /// smaller trip count. We may also have emitted epilogue loop if the loop
+ /// had a non-constant trip count.
+ PartiallyUnrolled,
+
+ /// The loop was fully unrolled into straight-line code. We no longer have
+ /// any back-edges.
+ FullyUnrolled
+};
+
+LoopUnrollResult UnrollLoop(Loop *L, unsigned Count, unsigned TripCount,
+ bool Force, bool AllowRuntime,
+ bool AllowExpensiveTripCount, bool PreserveCondBr,
+ bool PreserveOnlyFirst, unsigned TripMultiple,
+ unsigned PeelCount, bool UnrollRemainder,
+ LoopInfo *LI, ScalarEvolution *SE,
+ DominatorTree *DT, AssumptionCache *AC,
+ OptimizationRemarkEmitter *ORE, bool PreserveLCSSA);
bool UnrollRuntimeLoopRemainder(Loop *L, unsigned Count,
bool AllowExpensiveTripCount,
- bool UseEpilogRemainder, LoopInfo *LI,
+ bool UseEpilogRemainder, bool UnrollRemainder,
+ LoopInfo *LI,
ScalarEvolution *SE, DominatorTree *DT,
+ AssumptionCache *AC,
bool PreserveLCSSA);
void computePeelCount(Loop *L, unsigned LoopSize,
@@ -60,6 +77,7 @@ bool peelLoop(Loop *L, unsigned PeelCount, LoopInfo *LI, ScalarEvolution *SE,
DominatorTree *DT, AssumptionCache *AC, bool PreserveLCSSA);
MDNode *GetUnrollMetadata(MDNode *LoopID, StringRef Name);
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_UTILS_UNROLLLOOP_H
diff --git a/include/llvm/Transforms/Utils/ValueMapper.h b/include/llvm/Transforms/Utils/ValueMapper.h
index 45ef8246dcd16..4ecb23ea19518 100644
--- a/include/llvm/Transforms/Utils/ValueMapper.h
+++ b/include/llvm/Transforms/Utils/ValueMapper.h
@@ -21,9 +21,17 @@
namespace llvm {
-class Value;
+class Constant;
+class Function;
+class GlobalAlias;
+class GlobalVariable;
class Instruction;
-typedef ValueMap<const Value *, WeakTrackingVH> ValueToValueMapTy;
+class MDNode;
+class Metadata;
+class Type;
+class Value;
+
+using ValueToValueMapTy = ValueMap<const Value *, WeakTrackingVH>;
/// This is a class that can be implemented by clients to remap types when
/// cloning constants and instructions.
@@ -44,10 +52,10 @@ class ValueMaterializer {
virtual void anchor(); // Out of line method.
protected:
- ~ValueMaterializer() = default;
ValueMaterializer() = default;
ValueMaterializer(const ValueMaterializer &) = default;
ValueMaterializer &operator=(const ValueMaterializer &) = default;
+ ~ValueMaterializer() = default;
public:
/// This method can be implemented to generate a mapped Value on demand. For
@@ -91,7 +99,7 @@ enum RemapFlags {
RF_NullMapMissingGlobalValues = 8,
};
-static inline RemapFlags operator|(RemapFlags LHS, RemapFlags RHS) {
+inline RemapFlags operator|(RemapFlags LHS, RemapFlags RHS) {
return RemapFlags(unsigned(LHS) | unsigned(RHS));
}
diff --git a/include/llvm/Transforms/Vectorize/LoopVectorize.h b/include/llvm/Transforms/Vectorize/LoopVectorize.h
index 57d10c4c74734..32b56d372ea16 100644
--- a/include/llvm/Transforms/Vectorize/LoopVectorize.h
+++ b/include/llvm/Transforms/Vectorize/LoopVectorize.h
@@ -1,4 +1,4 @@
-//===---- LoopVectorize.h ---------------------------------------*- C++ -*-===//
+//===- LoopVectorize.h ------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -49,27 +49,29 @@
#ifndef LLVM_TRANSFORMS_VECTORIZE_LOOPVECTORIZE_H
#define LLVM_TRANSFORMS_VECTORIZE_LOOPVECTORIZE_H
-#include "llvm/ADT/MapVector.h"
#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Analysis/AssumptionCache.h"
-#include "llvm/Analysis/BasicAliasAnalysis.h"
-#include "llvm/Analysis/BlockFrequencyInfo.h"
-#include "llvm/Analysis/DemandedBits.h"
-#include "llvm/Analysis/LoopAccessAnalysis.h"
-#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/OptimizationDiagnosticInfo.h"
-#include "llvm/Analysis/ScalarEvolution.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/IR/Function.h"
#include "llvm/IR/PassManager.h"
-#include "llvm/Transforms/Scalar/LoopPassManager.h"
#include <functional>
namespace llvm {
+class AssumptionCache;
+class BlockFrequencyInfo;
+class DemandedBits;
+class DominatorTree;
+class Function;
+class Loop;
+class LoopAccessInfo;
+class LoopInfo;
+class OptimizationRemarkEmitter;
+class ScalarEvolution;
+class TargetLibraryInfo;
+class TargetTransformInfo;
+
/// The LoopVectorize Pass.
struct LoopVectorizePass : public PassInfoMixin<LoopVectorizePass> {
bool DisableUnrolling = false;
+
/// If true, consider all loops for vectorization.
/// If false, only loops that explicitly request vectorization are
/// considered.
@@ -99,6 +101,7 @@ struct LoopVectorizePass : public PassInfoMixin<LoopVectorizePass> {
bool processLoop(Loop *L);
};
-}
+
+} // end namespace llvm
#endif // LLVM_TRANSFORMS_VECTORIZE_LOOPVECTORIZE_H
diff --git a/include/llvm/Transforms/Vectorize/SLPVectorizer.h b/include/llvm/Transforms/Vectorize/SLPVectorizer.h
index 6f258191e89eb..25f264c4722c4 100644
--- a/include/llvm/Transforms/Vectorize/SLPVectorizer.h
+++ b/include/llvm/Transforms/Vectorize/SLPVectorizer.h
@@ -1,4 +1,4 @@
-//===---- SLPVectorizer.h ---------------------------------------*- C++ -*-===//
+//===- SLPVectorizer.h ------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,30 +19,48 @@
#ifndef LLVM_TRANSFORMS_VECTORIZE_SLPVECTORIZER_H
#define LLVM_TRANSFORMS_VECTORIZE_SLPVECTORIZER_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Analysis/AssumptionCache.h"
-#include "llvm/Analysis/DemandedBits.h"
-#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/OptimizationDiagnosticInfo.h"
-#include "llvm/Analysis/ScalarEvolution.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/IR/Function.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/IR/ValueHandle.h"
namespace llvm {
+class AssumptionCache;
+class BasicBlock;
+class CmpInst;
+class DataLayout;
+class DemandedBits;
+class DominatorTree;
+class Function;
+class InsertElementInst;
+class InsertValueInst;
+class Instruction;
+class LoopInfo;
+class OptimizationRemarkEmitter;
+class PHINode;
+class ScalarEvolution;
+class StoreInst;
+class TargetLibraryInfo;
+class TargetTransformInfo;
+class Value;
+
/// A private "module" namespace for types and utilities used by this pass.
/// These are implementation details and should not be used by clients.
namespace slpvectorizer {
+
class BoUpSLP;
-}
+
+} // end namespace slpvectorizer
struct SLPVectorizerPass : public PassInfoMixin<SLPVectorizerPass> {
- typedef SmallVector<StoreInst *, 8> StoreList;
- typedef MapVector<Value *, StoreList> StoreListMap;
- typedef SmallVector<WeakTrackingVH, 8> WeakTrackingVHList;
- typedef MapVector<Value *, WeakTrackingVHList> WeakTrackingVHListMap;
+ using StoreList = SmallVector<StoreInst *, 8>;
+ using StoreListMap = MapVector<Value *, StoreList>;
+ using WeakTrackingVHList = SmallVector<WeakTrackingVH, 8>;
+ using WeakTrackingVHListMap = MapVector<Value *, WeakTrackingVHList>;
ScalarEvolution *SE = nullptr;
TargetTransformInfo *TTI = nullptr;
@@ -78,14 +96,16 @@ private:
/// \brief Try to vectorize a list of operands.
/// \@param BuildVector A list of users to ignore for the purpose of
- /// scheduling and that don't need extracting.
+ /// scheduling and cost estimation when NeedExtraction
+ /// is false.
/// \returns true if a value was vectorized.
bool tryToVectorizeList(ArrayRef<Value *> VL, slpvectorizer::BoUpSLP &R,
ArrayRef<Value *> BuildVector = None,
- bool AllowReorder = false);
+ bool AllowReorder = false,
+ bool NeedExtraction = false);
- /// \brief Try to vectorize a chain that may start at the operands of \p V.
- bool tryToVectorize(BinaryOperator *V, slpvectorizer::BoUpSLP &R);
+ /// \brief Try to vectorize a chain that may start at the operands of \p I.
+ bool tryToVectorize(Instruction *I, slpvectorizer::BoUpSLP &R);
/// \brief Vectorize the store instructions collected in Stores.
bool vectorizeStoreChains(slpvectorizer::BoUpSLP &R);
@@ -100,6 +120,22 @@ private:
slpvectorizer::BoUpSLP &R,
TargetTransformInfo *TTI);
+ /// Try to vectorize trees that start at insertvalue instructions.
+ bool vectorizeInsertValueInst(InsertValueInst *IVI, BasicBlock *BB,
+ slpvectorizer::BoUpSLP &R);
+
+ /// Try to vectorize trees that start at insertelement instructions.
+ bool vectorizeInsertElementInst(InsertElementInst *IEI, BasicBlock *BB,
+ slpvectorizer::BoUpSLP &R);
+
+ /// Try to vectorize trees that start at compare instructions.
+ bool vectorizeCmpInst(CmpInst *CI, BasicBlock *BB, slpvectorizer::BoUpSLP &R);
+
+ /// Tries to vectorize constructs started from CmpInst, InsertValueInst or
+ /// InsertElementInst instructions.
+ bool vectorizeSimpleInstructions(SmallVectorImpl<WeakVH> &Instructions,
+ BasicBlock *BB, slpvectorizer::BoUpSLP &R);
+
/// \brief Scan the basic block and look for patterns that are likely to start
/// a vectorization chain.
bool vectorizeChainsInBlock(BasicBlock *BB, slpvectorizer::BoUpSLP &R);
@@ -115,6 +151,7 @@ private:
/// The getelementptr instructions in a basic block organized by base pointer.
WeakTrackingVHListMap GEPs;
};
-}
+
+} // end namespace llvm
#endif // LLVM_TRANSFORMS_VECTORIZE_SLPVECTORIZER_H