summaryrefslogtreecommitdiff
path: root/include/llvm
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-01-14 15:37:50 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-01-14 15:37:50 +0000
commit581a6d8501ff5614297da837b81ed3b6956361ea (patch)
tree985ee91d0ca1d3e6506ac5ff7e37f5b67adfec09 /include/llvm
parent909545a822eef491158f831688066f0ec2866938 (diff)
Notes
Diffstat (limited to 'include/llvm')
-rw-r--r--include/llvm/ADT/PointerSumType.h2
-rw-r--r--include/llvm/ADT/iterator.h26
-rw-r--r--include/llvm/Analysis/AssumptionCache.h41
-rw-r--r--include/llvm/Analysis/IVUsers.h13
-rw-r--r--include/llvm/Analysis/LazyCallGraph.h2
-rw-r--r--include/llvm/Analysis/LoopAccessAnalysis.h14
-rw-r--r--include/llvm/Analysis/LoopAnalysisManager.h155
-rw-r--r--include/llvm/Analysis/LoopInfo.h13
-rw-r--r--include/llvm/Analysis/LoopPassManager.h149
-rw-r--r--include/llvm/Analysis/MemoryDependenceAnalysis.h10
-rw-r--r--include/llvm/Analysis/TargetTransformInfo.h19
-rw-r--r--include/llvm/Analysis/TargetTransformInfoImpl.h60
-rw-r--r--include/llvm/Analysis/ValueTracking.h8
-rw-r--r--include/llvm/CodeGen/BasicTTIImpl.h3
-rw-r--r--include/llvm/CodeGen/DIE.h14
-rw-r--r--include/llvm/CodeGen/GlobalISel/RegBankSelect.h14
-rw-r--r--include/llvm/CodeGen/GlobalISel/RegisterBank.h7
-rw-r--r--include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h29
-rw-r--r--include/llvm/CodeGen/ISDOpcodes.h28
-rw-r--r--include/llvm/CodeGen/SelectionDAG.h6
-rw-r--r--include/llvm/CodeGen/SelectionDAGNodes.h26
-rw-r--r--include/llvm/DebugInfo/CodeView/CVTypeDumper.h56
-rw-r--r--include/llvm/DebugInfo/CodeView/SymbolDumper.h8
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeDatabase.h55
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h53
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h67
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeDumper.h108
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeDumperBase.h0
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h29
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFDie.h74
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFFormValue.h3
-rw-r--r--include/llvm/DebugInfo/MSF/StreamArray.h38
-rw-r--r--include/llvm/IR/DIBuilder.h27
-rw-r--r--include/llvm/IR/DebugInfoMetadata.h25
-rw-r--r--include/llvm/IR/GlobalObject.h36
-rw-r--r--include/llvm/IR/Intrinsics.td27
-rw-r--r--include/llvm/IR/IntrinsicsAArch64.td6
-rw-r--r--include/llvm/IR/IntrinsicsARM.td5
-rw-r--r--include/llvm/IR/ModuleSummaryIndex.h6
-rw-r--r--include/llvm/IR/ModuleSummaryIndexYAML.h2
-rw-r--r--include/llvm/Object/Decompressor.h64
-rw-r--r--include/llvm/ObjectYAML/DWARFYAML.h73
-rw-r--r--include/llvm/ObjectYAML/MachOYAML.h1
-rw-r--r--include/llvm/Passes/PassBuilder.h2
-rw-r--r--include/llvm/ProfileData/InstrProf.h9
-rw-r--r--include/llvm/Support/CommandLine.h2
-rw-r--r--include/llvm/Support/Dwarf.h2
-rw-r--r--include/llvm/Support/FileOutputBuffer.h3
-rw-r--r--include/llvm/Support/GenericDomTree.h37
-rw-r--r--include/llvm/Target/TargetLowering.h154
-rw-r--r--include/llvm/Target/TargetMachine.h27
-rw-r--r--include/llvm/Target/TargetSelectionDAG.td51
-rw-r--r--include/llvm/Target/TargetSubtargetInfo.h20
-rw-r--r--include/llvm/Transforms/Scalar/IVUsersPrinter.h30
-rw-r--r--include/llvm/Transforms/Scalar/IndVarSimplify.h5
-rw-r--r--include/llvm/Transforms/Scalar/LICM.h5
-rw-r--r--include/llvm/Transforms/Scalar/LoopAccessAnalysisPrinter.h31
-rw-r--r--include/llvm/Transforms/Scalar/LoopDeletion.h5
-rw-r--r--include/llvm/Transforms/Scalar/LoopIdiomRecognize.h5
-rw-r--r--include/llvm/Transforms/Scalar/LoopInstSimplify.h5
-rw-r--r--include/llvm/Transforms/Scalar/LoopPassManager.h363
-rw-r--r--include/llvm/Transforms/Scalar/LoopRotation.h5
-rw-r--r--include/llvm/Transforms/Scalar/LoopSimplifyCFG.h5
-rw-r--r--include/llvm/Transforms/Scalar/LoopStrengthReduce.h5
-rw-r--r--include/llvm/Transforms/Scalar/LoopUnrollPass.h5
-rw-r--r--include/llvm/Transforms/Utils/LoopUtils.h25
-rw-r--r--include/llvm/Transforms/Utils/UnrollLoop.h6
-rw-r--r--include/llvm/Transforms/Vectorize/LoopVectorize.h2
-rw-r--r--include/llvm/XRay/Trace.h71
-rw-r--r--include/llvm/XRay/XRayRecord.h76
-rw-r--r--include/llvm/XRay/YAMLXRayRecord.h99
71 files changed, 1710 insertions, 747 deletions
diff --git a/include/llvm/ADT/PointerSumType.h b/include/llvm/ADT/PointerSumType.h
index 005b1c645c935..062544eedf84b 100644
--- a/include/llvm/ADT/PointerSumType.h
+++ b/include/llvm/ADT/PointerSumType.h
@@ -94,7 +94,7 @@ public:
return HelperT::template Lookup<N>::TraitsT::getFromVoidPointer(getImpl());
}
- operator bool() const { return Value & HelperT::PointerMask; }
+ explicit operator bool() const { return Value & HelperT::PointerMask; }
bool operator==(const PointerSumType &R) const { return Value == R.Value; }
bool operator!=(const PointerSumType &R) const { return Value != R.Value; }
bool operator<(const PointerSumType &R) const { return Value < R.Value; }
diff --git a/include/llvm/ADT/iterator.h b/include/llvm/ADT/iterator.h
index 9ccacc10db0d5..6470e09db86cc 100644
--- a/include/llvm/ADT/iterator.h
+++ b/include/llvm/ADT/iterator.h
@@ -33,6 +33,32 @@ namespace llvm {
/// Another abstraction that this doesn't provide is implementing increment in
/// terms of addition of one. These aren't equivalent for all iterator
/// categories, and respecting that adds a lot of complexity for little gain.
+///
+/// Classes wishing to use `iterator_facade_base` should implement the following
+/// methods:
+///
+/// Forward Iterators:
+/// (All of the following methods)
+/// - DerivedT &operator=(const DerivedT &R);
+/// - bool operator==(const DerivedT &R) const;
+/// - const T &operator*() const;
+/// - T &operator*();
+/// - DerivedT &operator++();
+///
+/// Bidirectional Iterators:
+/// (All methods of forward iterators, plus the following)
+/// - DerivedT &operator--();
+///
+/// Random-access Iterators:
+/// (All methods of bidirectional iterators excluding the following)
+/// - DerivedT &operator++();
+/// - DerivedT &operator--();
+/// (and plus the following)
+/// - bool operator<(const DerivedT &RHS) const;
+/// - DifferenceTypeT operator-(const DerivedT &R) const;
+/// - DerivedT &operator+=(DifferenceTypeT N);
+/// - DerivedT &operator-=(DifferenceTypeT N);
+///
template <typename DerivedT, typename IteratorCategoryT, typename T,
typename DifferenceTypeT = std::ptrdiff_t, typename PointerT = T *,
typename ReferenceT = T &>
diff --git a/include/llvm/Analysis/AssumptionCache.h b/include/llvm/Analysis/AssumptionCache.h
index 406a1fe9f5608..b50545a0484be 100644
--- a/include/llvm/Analysis/AssumptionCache.h
+++ b/include/llvm/Analysis/AssumptionCache.h
@@ -46,6 +46,30 @@ class AssumptionCache {
/// intrinsic.
SmallVector<WeakVH, 4> AssumeHandles;
+ class AffectedValueCallbackVH final : public CallbackVH {
+ AssumptionCache *AC;
+ void deleted() override;
+ void allUsesReplacedWith(Value *) override;
+
+ public:
+ using DMI = DenseMapInfo<Value *>;
+
+ AffectedValueCallbackVH(Value *V, AssumptionCache *AC = nullptr)
+ : CallbackVH(V), AC(AC) {}
+ };
+
+ friend AffectedValueCallbackVH;
+
+ /// \brief A map of values about which an assumption might be providing
+ /// information to the relevant set of assumptions.
+ using AffectedValuesMap =
+ DenseMap<AffectedValueCallbackVH, SmallVector<WeakVH, 1>,
+ AffectedValueCallbackVH::DMI>;
+ AffectedValuesMap AffectedValues;
+
+ /// Get the vector of assumptions which affect a value from the cache.
+ SmallVector<WeakVH, 1> &getAffectedValues(Value *V);
+
/// \brief Flag tracking whether we have scanned the function yet.
///
/// We want to be as lazy about this as possible, and so we scan the function
@@ -66,11 +90,16 @@ public:
/// not already be in the cache.
void registerAssumption(CallInst *CI);
+ /// \brief Update the cache of values being affected by this assumption (i.e.
+ /// the values about which this assumption provides information).
+ void updateAffectedValues(CallInst *CI);
+
/// \brief Clear the cache of @llvm.assume intrinsics for a function.
///
/// It will be re-scanned the next time it is requested.
void clear() {
AssumeHandles.clear();
+ AffectedValues.clear();
Scanned = false;
}
@@ -87,6 +116,18 @@ public:
scanFunction();
return AssumeHandles;
}
+
+ /// \brief Access the list of assumptions which affect this value.
+ MutableArrayRef<WeakVH> assumptionsFor(const Value *V) {
+ if (!Scanned)
+ scanFunction();
+
+ auto AVI = AffectedValues.find_as(const_cast<Value *>(V));
+ if (AVI == AffectedValues.end())
+ return MutableArrayRef<WeakVH>();
+
+ return AVI->second;
+ }
};
/// \brief A function analysis which provides an \c AssumptionCache.
diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h
index e1a5467d8b633..bb572dd5603b4 100644
--- a/include/llvm/Analysis/IVUsers.h
+++ b/include/llvm/Analysis/IVUsers.h
@@ -15,8 +15,8 @@
#ifndef LLVM_ANALYSIS_IVUSERS_H
#define LLVM_ANALYSIS_IVUSERS_H
+#include "llvm/Analysis/LoopAnalysisManager.h"
#include "llvm/Analysis/LoopPass.h"
-#include "llvm/Analysis/LoopPassManager.h"
#include "llvm/Analysis/ScalarEvolutionNormalization.h"
#include "llvm/IR/ValueHandle.h"
@@ -193,17 +193,10 @@ class IVUsersAnalysis : public AnalysisInfoMixin<IVUsersAnalysis> {
public:
typedef IVUsers Result;
- IVUsers run(Loop &L, LoopAnalysisManager &AM);
+ IVUsers run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR);
};
-/// Printer pass for the \c IVUsers for a loop.
-class IVUsersPrinterPass : public PassInfoMixin<IVUsersPrinterPass> {
- raw_ostream &OS;
-
-public:
- explicit IVUsersPrinterPass(raw_ostream &OS) : OS(OS) {}
- PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM);
-};
}
#endif
diff --git a/include/llvm/Analysis/LazyCallGraph.h b/include/llvm/Analysis/LazyCallGraph.h
index 566e526f89b37..bca0aebe2eefa 100644
--- a/include/llvm/Analysis/LazyCallGraph.h
+++ b/include/llvm/Analysis/LazyCallGraph.h
@@ -148,7 +148,7 @@ public:
///
/// This happens when an edge has been deleted. We leave the edge objects
/// around but clear them.
- operator bool() const;
+ explicit operator bool() const;
/// Returnss the \c Kind of the edge.
Kind getKind() const;
diff --git a/include/llvm/Analysis/LoopAccessAnalysis.h b/include/llvm/Analysis/LoopAccessAnalysis.h
index 76066f6003e7e..901b193c7e2d4 100644
--- a/include/llvm/Analysis/LoopAccessAnalysis.h
+++ b/include/llvm/Analysis/LoopAccessAnalysis.h
@@ -20,7 +20,7 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AliasSetTracker.h"
-#include "llvm/Analysis/LoopPassManager.h"
+#include "llvm/Analysis/LoopAnalysisManager.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/ValueHandle.h"
@@ -753,18 +753,8 @@ class LoopAccessAnalysis
public:
typedef LoopAccessInfo Result;
- Result run(Loop &, LoopAnalysisManager &);
- static StringRef name() { return "LoopAccessAnalysis"; }
-};
-
-/// \brief Printer pass for the \c LoopAccessInfo results.
-class LoopAccessInfoPrinterPass
- : public PassInfoMixin<LoopAccessInfoPrinterPass> {
- raw_ostream &OS;
-public:
- explicit LoopAccessInfoPrinterPass(raw_ostream &OS) : OS(OS) {}
- PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM);
+ Result run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR);
};
inline Instruction *MemoryDepChecker::Dependence::getSource(
diff --git a/include/llvm/Analysis/LoopAnalysisManager.h b/include/llvm/Analysis/LoopAnalysisManager.h
new file mode 100644
index 0000000000000..17da516889b00
--- /dev/null
+++ b/include/llvm/Analysis/LoopAnalysisManager.h
@@ -0,0 +1,155 @@
+//===- LoopAnalysisManager.h - Loop analysis management ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// This header provides classes for managing per-loop analyses. These are
+/// typically used as part of a loop pass pipeline over the loop nests of
+/// a function.
+///
+/// Loop analyses are allowed to make some simplifying assumptions:
+/// 1) Loops are, where possible, in simplified form.
+/// 2) Loops are *always* in LCSSA form.
+/// 3) A collection of analysis results are available:
+/// - LoopInfo
+/// - DominatorTree
+/// - ScalarEvolution
+/// - AAManager
+///
+/// The primary mechanism to provide these invariants is the loop pass manager,
+/// but they can also be manually provided in order to reason about a loop from
+/// outside of a dedicated pass manager.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_LOOPANALYSISMANAGER_H
+#define LLVM_ANALYSIS_LOOPANALYSISMANAGER_H
+
+#include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/ADT/PriorityWorklist.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/BasicAliasAnalysis.h"
+#include "llvm/Analysis/GlobalsModRef.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+/// The adaptor from a function pass to a loop pass computes these analyses and
+/// makes them available to the loop passes "for free". Each loop pass is
+/// expected expected to update these analyses if necessary to ensure they're
+/// valid after it runs.
+struct LoopStandardAnalysisResults {
+ AAResults &AA;
+ AssumptionCache &AC;
+ DominatorTree &DT;
+ LoopInfo &LI;
+ ScalarEvolution &SE;
+ TargetLibraryInfo &TLI;
+ TargetTransformInfo &TTI;
+};
+
+/// Extern template declaration for the analysis set for this IR unit.
+extern template class AllAnalysesOn<Loop>;
+
+extern template class AnalysisManager<Loop, LoopStandardAnalysisResults &>;
+/// \brief The loop analysis manager.
+///
+/// See the documentation for the AnalysisManager template for detail
+/// documentation. This typedef serves as a convenient way to refer to this
+/// construct in the adaptors and proxies used to integrate this into the larger
+/// pass manager infrastructure.
+typedef AnalysisManager<Loop, LoopStandardAnalysisResults &>
+ LoopAnalysisManager;
+
+/// A proxy from a \c LoopAnalysisManager to a \c Function.
+typedef InnerAnalysisManagerProxy<LoopAnalysisManager, Function>
+ LoopAnalysisManagerFunctionProxy;
+
+/// A specialized result for the \c LoopAnalysisManagerFunctionProxy which
+/// retains a \c LoopInfo reference.
+///
+/// This allows it to collect loop objects for which analysis results may be
+/// cached in the \c LoopAnalysisManager.
+template <> class LoopAnalysisManagerFunctionProxy::Result {
+public:
+ explicit Result(LoopAnalysisManager &InnerAM, LoopInfo &LI)
+ : InnerAM(&InnerAM), LI(&LI) {}
+ Result(Result &&Arg) : InnerAM(std::move(Arg.InnerAM)), LI(Arg.LI) {
+ // We have to null out the analysis manager in the moved-from state
+ // because we are taking ownership of the responsibilty to clear the
+ // analysis state.
+ Arg.InnerAM = nullptr;
+ }
+ Result &operator=(Result &&RHS) {
+ InnerAM = RHS.InnerAM;
+ LI = RHS.LI;
+ // We have to null out the analysis manager in the moved-from state
+ // because we are taking ownership of the responsibilty to clear the
+ // analysis state.
+ RHS.InnerAM = nullptr;
+ return *this;
+ }
+ ~Result() {
+ // InnerAM is cleared in a moved from state where there is nothing to do.
+ if (!InnerAM)
+ return;
+
+ // Clear out the analysis manager if we're being destroyed -- it means we
+ // didn't even see an invalidate call when we got invalidated.
+ InnerAM->clear();
+ }
+
+ /// Accessor for the analysis manager.
+ LoopAnalysisManager &getManager() { return *InnerAM; }
+
+ /// Handler for invalidation of the proxy for a particular function.
+ ///
+ /// If the proxy, \c LoopInfo, and associated analyses are preserved, this
+ /// will merely forward the invalidation event to any cached loop analysis
+ /// results for loops within this function.
+ ///
+ /// If the necessary loop infrastructure is not preserved, this will forcibly
+ /// clear all of the cached analysis results that are keyed on the \c
+ /// LoopInfo for this function.
+ bool invalidate(Function &F, const PreservedAnalyses &PA,
+ FunctionAnalysisManager::Invalidator &Inv);
+
+private:
+ LoopAnalysisManager *InnerAM;
+ LoopInfo *LI;
+};
+
+/// Provide a specialized run method for the \c LoopAnalysisManagerFunctionProxy
+/// so it can pass the \c LoopInfo to the result.
+template <>
+LoopAnalysisManagerFunctionProxy::Result
+LoopAnalysisManagerFunctionProxy::run(Function &F, FunctionAnalysisManager &AM);
+
+// Ensure the \c LoopAnalysisManagerFunctionProxy is provided as an extern
+// template.
+extern template class InnerAnalysisManagerProxy<LoopAnalysisManager, Function>;
+
+extern template class OuterAnalysisManagerProxy<FunctionAnalysisManager, Loop,
+ LoopStandardAnalysisResults &>;
+/// A proxy from a \c FunctionAnalysisManager to a \c Loop.
+typedef OuterAnalysisManagerProxy<FunctionAnalysisManager, Loop,
+ LoopStandardAnalysisResults &>
+ FunctionAnalysisManagerLoopProxy;
+
+/// Returns the minimum set of Analyses that all loop passes must preserve.
+PreservedAnalyses getLoopPassPreservedAnalyses();
+}
+
+#endif // LLVM_ANALYSIS_LOOPANALYSISMANAGER_H
diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h
index 0c99c6297c1e6..20e6af2727fe0 100644
--- a/include/llvm/Analysis/LoopInfo.h
+++ b/include/llvm/Analysis/LoopInfo.h
@@ -853,17 +853,8 @@ public:
void getAnalysisUsage(AnalysisUsage &AU) const override;
};
-/// \brief Pass for printing a loop's contents as LLVM's text IR assembly.
-class PrintLoopPass : public PassInfoMixin<PrintLoopPass> {
- raw_ostream &OS;
- std::string Banner;
-
-public:
- PrintLoopPass();
- PrintLoopPass(raw_ostream &OS, const std::string &Banner = "");
-
- PreservedAnalyses run(Loop &L, AnalysisManager<Loop> &);
-};
+/// Function to print a loop's contents as LLVM's text IR assembly.
+void printLoop(Loop &L, raw_ostream &OS, const std::string &Banner = "");
} // End llvm namespace
diff --git a/include/llvm/Analysis/LoopPassManager.h b/include/llvm/Analysis/LoopPassManager.h
deleted file mode 100644
index ae9c16502feb5..0000000000000
--- a/include/llvm/Analysis/LoopPassManager.h
+++ /dev/null
@@ -1,149 +0,0 @@
-//===- LoopPassManager.h - Loop pass management -----------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-/// \file
-///
-/// This header provides classes for managing passes over loops in LLVM IR.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ANALYSIS_LOOPPASSMANAGER_H
-#define LLVM_ANALYSIS_LOOPPASSMANAGER_H
-
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/ScalarEvolution.h"
-#include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/IR/Dominators.h"
-#include "llvm/IR/PassManager.h"
-
-namespace llvm {
-
-extern template class PassManager<Loop>;
-/// \brief The loop pass manager.
-///
-/// See the documentation for the PassManager template for details. It runs a
-/// sequency of loop passes over each loop that the manager is run over. This
-/// typedef serves as a convenient way to refer to this construct.
-typedef PassManager<Loop> LoopPassManager;
-
-extern template class AnalysisManager<Loop>;
-/// \brief The loop analysis manager.
-///
-/// See the documentation for the AnalysisManager template for detail
-/// documentation. This typedef serves as a convenient way to refer to this
-/// construct in the adaptors and proxies used to integrate this into the larger
-/// pass manager infrastructure.
-typedef AnalysisManager<Loop> LoopAnalysisManager;
-
-/// A proxy from a \c LoopAnalysisManager to a \c Function.
-typedef InnerAnalysisManagerProxy<LoopAnalysisManager, Function>
- LoopAnalysisManagerFunctionProxy;
-
-/// Specialization of the invalidate method for the \c
-/// LoopAnalysisManagerFunctionProxy's result.
-template <>
-bool LoopAnalysisManagerFunctionProxy::Result::invalidate(
- Function &F, const PreservedAnalyses &PA,
- FunctionAnalysisManager::Invalidator &Inv);
-
-// Ensure the \c LoopAnalysisManagerFunctionProxy is provided as an extern
-// template.
-extern template class InnerAnalysisManagerProxy<LoopAnalysisManager, Function>;
-
-extern template class OuterAnalysisManagerProxy<FunctionAnalysisManager, Loop>;
-/// A proxy from a \c FunctionAnalysisManager to a \c Loop.
-typedef OuterAnalysisManagerProxy<FunctionAnalysisManager, Loop>
- FunctionAnalysisManagerLoopProxy;
-
-/// Returns the minimum set of Analyses that all loop passes must preserve.
-PreservedAnalyses getLoopPassPreservedAnalyses();
-
-/// \brief Adaptor that maps from a function to its loops.
-///
-/// Designed to allow composition of a LoopPass(Manager) and a
-/// FunctionPassManager. Note that if this pass is constructed with a \c
-/// FunctionAnalysisManager it will run the \c LoopAnalysisManagerFunctionProxy
-/// analysis prior to running the loop passes over the function to enable a \c
-/// LoopAnalysisManager to be used within this run safely.
-template <typename LoopPassT>
-class FunctionToLoopPassAdaptor
- : public PassInfoMixin<FunctionToLoopPassAdaptor<LoopPassT>> {
-public:
- explicit FunctionToLoopPassAdaptor(LoopPassT Pass)
- : Pass(std::move(Pass)) {}
-
- /// \brief Runs the loop passes across every loop in the function.
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
- // Setup the loop analysis manager from its proxy.
- LoopAnalysisManager &LAM =
- AM.getResult<LoopAnalysisManagerFunctionProxy>(F).getManager();
- // Get the loop structure for this function
- LoopInfo &LI = AM.getResult<LoopAnalysis>(F);
-
- // Also precompute all of the function analyses used by loop passes.
- // FIXME: These should be handed into the loop passes when the loop pass
- // management layer is reworked to follow the design of CGSCC.
- (void)AM.getResult<AAManager>(F);
- (void)AM.getResult<DominatorTreeAnalysis>(F);
- (void)AM.getResult<ScalarEvolutionAnalysis>(F);
- (void)AM.getResult<TargetLibraryAnalysis>(F);
-
- PreservedAnalyses PA = PreservedAnalyses::all();
-
- // We want to visit the loops in reverse post-order. We'll build the stack
- // of loops to visit in Loops by first walking the loops in pre-order.
- SmallVector<Loop *, 2> Loops;
- SmallVector<Loop *, 2> WorkList(LI.begin(), LI.end());
- while (!WorkList.empty()) {
- Loop *L = WorkList.pop_back_val();
- WorkList.insert(WorkList.end(), L->begin(), L->end());
- Loops.push_back(L);
- }
-
- // Now pop each element off of the stack to visit the loops in reverse
- // post-order.
- for (auto *L : reverse(Loops)) {
- PreservedAnalyses PassPA = Pass.run(*L, LAM);
- // FIXME: We should verify the set of analyses relevant to Loop passes
- // are preserved.
-
- // We know that the loop pass couldn't have invalidated any other loop's
- // analyses (that's the contract of a loop pass), so directly handle the
- // loop analysis manager's invalidation here.
- LAM.invalidate(*L, PassPA);
-
- // Then intersect the preserved set so that invalidation of module
- // analyses will eventually occur when the module pass completes.
- PA.intersect(std::move(PassPA));
- }
-
- // By definition we preserve the proxy. We also preserve all analyses on
- // Loops. This precludes *any* invalidation of loop analyses by the proxy,
- // but that's OK because we've taken care to invalidate analyses in the
- // loop analysis manager incrementally above.
- PA.preserveSet<AllAnalysesOn<Loop>>();
- PA.preserve<LoopAnalysisManagerFunctionProxy>();
- return PA;
- }
-
-private:
- LoopPassT Pass;
-};
-
-/// \brief A function to deduce a loop pass type and wrap it in the templated
-/// adaptor.
-template <typename LoopPassT>
-FunctionToLoopPassAdaptor<LoopPassT>
-createFunctionToLoopPassAdaptor(LoopPassT Pass) {
- return FunctionToLoopPassAdaptor<LoopPassT>(std::move(Pass));
-}
-}
-
-#endif // LLVM_ANALYSIS_LOOPPASSMANAGER_H
diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h
index 33dbd22f7a20f..a401887016c94 100644
--- a/include/llvm/Analysis/MemoryDependenceAnalysis.h
+++ b/include/llvm/Analysis/MemoryDependenceAnalysis.h
@@ -302,6 +302,10 @@ private:
NonLocalPointerInfo() : Size(MemoryLocation::UnknownSize) {}
};
+ /// Cache storing single nonlocal def for the instruction.
+ /// It is set when nonlocal def would be found in function returning only
+ /// local dependencies.
+ DenseMap<Instruction *, NonLocalDepResult> NonLocalDefsCache;
/// This map stores the cached results of doing a pointer lookup at the
/// bottom of a block.
///
@@ -441,9 +445,9 @@ public:
/// This analysis looks for other loads and stores with invariant.group
/// metadata and the same pointer operand. Returns Unknown if it does not
/// find anything, and Def if it can be assumed that 2 instructions load or
- /// store the same value.
- /// FIXME: This analysis works only on single block because of restrictions
- /// at the call site.
+ /// store the same value and NonLocal which indicate that non-local Def was
+ /// found, which can be retrieved by calling getNonLocalPointerDependency
+ /// with the same queried instruction.
MemDepResult getInvariantGroupPointerDependency(LoadInst *LI, BasicBlock *BB);
/// Looks at a memory location for a load (specified by MemLocBase, Offs, and
diff --git a/include/llvm/Analysis/TargetTransformInfo.h b/include/llvm/Analysis/TargetTransformInfo.h
index b4a6c5c2fae09..209f05c279d03 100644
--- a/include/llvm/Analysis/TargetTransformInfo.h
+++ b/include/llvm/Analysis/TargetTransformInfo.h
@@ -55,6 +55,11 @@ struct MemIntrinsicInfo {
// Same Id is set by the target for corresponding load/store intrinsics.
unsigned short MatchingId;
int NumMemRefs;
+
+ /// This is the pointer that the intrinsic is loading from or storing to.
+ /// If this is non-null, then analysis/optimization passes can assume that
+ /// this intrinsic is functionally equivalent to a load/store from this
+ /// pointer.
Value *PtrVal;
};
@@ -518,11 +523,15 @@ public:
unsigned getMaxInterleaveFactor(unsigned VF) const;
/// \return The expected cost of arithmetic ops, such as mul, xor, fsub, etc.
+ /// \p Args is an optional argument which holds the instruction operands
+ /// values so the TTI can analyize those values searching for special
+ /// cases\optimizations based on those values.
int getArithmeticInstrCost(
unsigned Opcode, Type *Ty, OperandValueKind Opd1Info = OK_AnyValue,
OperandValueKind Opd2Info = OK_AnyValue,
OperandValueProperties Opd1PropInfo = OP_None,
- OperandValueProperties Opd2PropInfo = OP_None) const;
+ OperandValueProperties Opd2PropInfo = OP_None,
+ ArrayRef<const Value *> Args = ArrayRef<const Value *>()) const;
/// \return The cost of a shuffle instruction of kind Kind and of type Tp.
/// The index and subtype parameters are used by the subvector insertion and
@@ -763,7 +772,8 @@ public:
getArithmeticInstrCost(unsigned Opcode, Type *Ty, OperandValueKind Opd1Info,
OperandValueKind Opd2Info,
OperandValueProperties Opd1PropInfo,
- OperandValueProperties Opd2PropInfo) = 0;
+ OperandValueProperties Opd2PropInfo,
+ ArrayRef<const Value *> Args) = 0;
virtual int getShuffleCost(ShuffleKind Kind, Type *Tp, int Index,
Type *SubTp) = 0;
virtual int getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src) = 0;
@@ -984,9 +994,10 @@ public:
getArithmeticInstrCost(unsigned Opcode, Type *Ty, OperandValueKind Opd1Info,
OperandValueKind Opd2Info,
OperandValueProperties Opd1PropInfo,
- OperandValueProperties Opd2PropInfo) override {
+ OperandValueProperties Opd2PropInfo,
+ ArrayRef<const Value *> Args) override {
return Impl.getArithmeticInstrCost(Opcode, Ty, Opd1Info, Opd2Info,
- Opd1PropInfo, Opd2PropInfo);
+ Opd1PropInfo, Opd2PropInfo, Args);
}
int getShuffleCost(ShuffleKind Kind, Type *Tp, int Index,
Type *SubTp) override {
diff --git a/include/llvm/Analysis/TargetTransformInfoImpl.h b/include/llvm/Analysis/TargetTransformInfoImpl.h
index 1d7edbaf7df04..cafc40723c9d6 100644
--- a/include/llvm/Analysis/TargetTransformInfoImpl.h
+++ b/include/llvm/Analysis/TargetTransformInfoImpl.h
@@ -306,7 +306,8 @@ public:
TTI::OperandValueKind Opd1Info,
TTI::OperandValueKind Opd2Info,
TTI::OperandValueProperties Opd1PropInfo,
- TTI::OperandValueProperties Opd2PropInfo) {
+ TTI::OperandValueProperties Opd2PropInfo,
+ ArrayRef<const Value *> Args) {
return 1;
}
@@ -427,6 +428,63 @@ public:
return VF;
}
protected:
+ // Obtain the minimum required size to hold the value (without the sign)
+ // In case of a vector it returns the min required size for one element.
+ unsigned minRequiredElementSize(const Value* Val, bool &isSigned) {
+ if (isa<ConstantDataVector>(Val) || isa<ConstantVector>(Val)) {
+ const auto* VectorValue = cast<Constant>(Val);
+
+ // In case of a vector need to pick the max between the min
+ // required size for each element
+ auto *VT = cast<VectorType>(Val->getType());
+
+ // Assume unsigned elements
+ isSigned = false;
+
+ // The max required size is the total vector width divided by num
+ // of elements in the vector
+ unsigned MaxRequiredSize = VT->getBitWidth() / VT->getNumElements();
+
+ unsigned MinRequiredSize = 0;
+ for(unsigned i = 0, e = VT->getNumElements(); i < e; ++i) {
+ if (auto* IntElement =
+ dyn_cast<ConstantInt>(VectorValue->getAggregateElement(i))) {
+ bool signedElement = IntElement->getValue().isNegative();
+ // Get the element min required size.
+ unsigned ElementMinRequiredSize =
+ IntElement->getValue().getMinSignedBits() - 1;
+ // In case one element is signed then all the vector is signed.
+ isSigned |= signedElement;
+ // Save the max required bit size between all the elements.
+ MinRequiredSize = std::max(MinRequiredSize, ElementMinRequiredSize);
+ }
+ else {
+ // not an int constant element
+ return MaxRequiredSize;
+ }
+ }
+ return MinRequiredSize;
+ }
+
+ if (const auto* CI = dyn_cast<ConstantInt>(Val)) {
+ isSigned = CI->getValue().isNegative();
+ return CI->getValue().getMinSignedBits() - 1;
+ }
+
+ if (const auto* Cast = dyn_cast<SExtInst>(Val)) {
+ isSigned = true;
+ return Cast->getSrcTy()->getScalarSizeInBits() - 1;
+ }
+
+ if (const auto* Cast = dyn_cast<ZExtInst>(Val)) {
+ isSigned = false;
+ return Cast->getSrcTy()->getScalarSizeInBits();
+ }
+
+ isSigned = false;
+ return Val->getType()->getScalarSizeInBits();
+ }
+
bool isStridedAccess(const SCEV *Ptr) {
return Ptr && isa<SCEVAddRecExpr>(Ptr);
}
diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h
index dd767217345af..aaf6f888e06f5 100644
--- a/include/llvm/Analysis/ValueTracking.h
+++ b/include/llvm/Analysis/ValueTracking.h
@@ -169,8 +169,12 @@ template <typename T> class ArrayRef;
/// Return true if we can prove that the specified FP value is either a NaN or
/// never less than 0.0.
- bool CannotBeOrderedLessThanZero(const Value *V, const TargetLibraryInfo *TLI,
- unsigned Depth = 0);
+ /// If \p IncludeNeg0 is false, -0.0 is considered less than 0.0.
+ bool CannotBeOrderedLessThanZero(const Value *V, const TargetLibraryInfo *TLI);
+
+ /// \returns true if we can prove that the specified FP value has a 0 sign
+ /// bit.
+ bool SignBitMustBeZero(const Value *V, const TargetLibraryInfo *TLI);
/// If the specified value can be set by repeating the same byte in memory,
/// return the i8 value that it is represented with. This is true for all i8
diff --git a/include/llvm/CodeGen/BasicTTIImpl.h b/include/llvm/CodeGen/BasicTTIImpl.h
index 8e96336b981f1..7efdbcccdef56 100644
--- a/include/llvm/CodeGen/BasicTTIImpl.h
+++ b/include/llvm/CodeGen/BasicTTIImpl.h
@@ -308,7 +308,8 @@ public:
TTI::OperandValueKind Opd1Info = TTI::OK_AnyValue,
TTI::OperandValueKind Opd2Info = TTI::OK_AnyValue,
TTI::OperandValueProperties Opd1PropInfo = TTI::OP_None,
- TTI::OperandValueProperties Opd2PropInfo = TTI::OP_None) {
+ TTI::OperandValueProperties Opd2PropInfo = TTI::OP_None,
+ ArrayRef<const Value *> Args = ArrayRef<const Value *>()) {
// Check if any of the operands are vector operands.
const TargetLoweringBase *TLI = getTLI();
int ISD = TLI->InstructionOpcodeToISD(Opcode);
diff --git a/include/llvm/CodeGen/DIE.h b/include/llvm/CodeGen/DIE.h
index 09c3bf6a1b56c..95c4b4248bbd0 100644
--- a/include/llvm/CodeGen/DIE.h
+++ b/include/llvm/CodeGen/DIE.h
@@ -52,13 +52,20 @@ class DIEAbbrevData {
/// Dwarf form code.
dwarf::Form Form;
+ /// Dwarf attribute value for DW_FORM_implicit_const
+ int64_t Value;
+
public:
- DIEAbbrevData(dwarf::Attribute A, dwarf::Form F) : Attribute(A), Form(F) {}
+ DIEAbbrevData(dwarf::Attribute A, dwarf::Form F)
+ : Attribute(A), Form(F), Value(0) {}
+ DIEAbbrevData(dwarf::Attribute A, int64_t V)
+ : Attribute(A), Form(dwarf::DW_FORM_implicit_const), Value(V) {}
/// Accessors.
/// @{
dwarf::Attribute getAttribute() const { return Attribute; }
dwarf::Form getForm() const { return Form; }
+ int64_t getValue() const { return Value; }
/// @}
/// Used to gather unique data for the abbreviation folding set.
@@ -102,6 +109,11 @@ public:
Data.push_back(DIEAbbrevData(Attribute, Form));
}
+ /// Adds attribute with DW_FORM_implicit_const value
+ void AddImplicitConstAttribute(dwarf::Attribute Attribute, int64_t Value) {
+ Data.push_back(DIEAbbrevData(Attribute, Value));
+ }
+
/// Used to gather unique data for the abbreviation folding set.
void Profile(FoldingSetNodeID &ID) const;
diff --git a/include/llvm/CodeGen/GlobalISel/RegBankSelect.h b/include/llvm/CodeGen/GlobalISel/RegBankSelect.h
index 106fc9ffb8b5e..b331533cd7fb0 100644
--- a/include/llvm/CodeGen/GlobalISel/RegBankSelect.h
+++ b/include/llvm/CodeGen/GlobalISel/RegBankSelect.h
@@ -76,6 +76,7 @@ class MachineBlockFrequencyInfo;
class MachineRegisterInfo;
class TargetPassConfig;
class TargetRegisterInfo;
+class raw_ostream;
/// This pass implements the reg bank selector pass used in the GlobalISel
/// pipeline. At the end of this pass, all register operands have been assigned
@@ -450,6 +451,18 @@ private:
bool operator>(const MappingCost &Cost) const {
return *this != Cost && Cost < *this;
}
+
+ /// Print this on dbgs() stream.
+ void dump() const;
+
+ /// Print this on \p OS;
+ void print(raw_ostream &OS) const;
+
+ /// Overload the stream operator for easy debug printing.
+ friend raw_ostream &operator<<(raw_ostream &OS, const MappingCost &Cost) {
+ Cost.print(OS);
+ return OS;
+ }
};
/// Interface to the target lowering info related
@@ -626,6 +639,7 @@ public:
/// \endcode
bool runOnMachineFunction(MachineFunction &MF) override;
};
+
} // End namespace llvm.
#endif
diff --git a/include/llvm/CodeGen/GlobalISel/RegisterBank.h b/include/llvm/CodeGen/GlobalISel/RegisterBank.h
index 075677d30179a..b05bf99482438 100644
--- a/include/llvm/CodeGen/GlobalISel/RegisterBank.h
+++ b/include/llvm/CodeGen/GlobalISel/RegisterBank.h
@@ -41,11 +41,8 @@ private:
friend RegisterBankInfo;
public:
- /// The default constructor will leave the object in
- /// an invalid state. I.e. isValid() == false.
- /// The fields must be updated to fix that and only
- /// RegisterBankInfo instances are allowed to do that
- RegisterBank();
+ RegisterBank(unsigned ID, const char *Name, unsigned Size,
+ const uint32_t *ContainedRegClasses);
/// Get the identifier of this register bank.
unsigned getID() const { return ID; }
diff --git a/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h b/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
index 4d4a226eb2d2b..312dc9314d45a 100644
--- a/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
+++ b/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
@@ -384,10 +384,6 @@ protected:
/// Create a RegisterBankInfo that can accomodate up to \p NumRegBanks
/// RegisterBank instances.
- ///
- /// \note For the verify method to succeed all the \p NumRegBanks
- /// must be initialized by createRegisterBank and updated with
- /// addRegBankCoverage RegisterBank.
RegisterBankInfo(RegisterBank **RegBanks, unsigned NumRegBanks);
/// This constructor is meaningless.
@@ -400,31 +396,6 @@ protected:
llvm_unreachable("This constructor should not be executed");
}
- /// Create a new register bank with the given parameter and add it
- /// to RegBanks.
- /// \pre \p ID must not already be used.
- /// \pre \p ID < NumRegBanks.
- void createRegisterBank(unsigned ID, const char *Name);
-
- /// Add \p RCId to the set of register class that the register bank,
- /// identified \p ID, covers.
- /// This method transitively adds all the sub classes and the subreg-classes
- /// of \p RCId to the set of covered register classes.
- /// It also adjusts the size of the register bank to reflect the maximal
- /// size of a value that can be hold into that register bank.
- ///
- /// \note This method does *not* add the super classes of \p RCId.
- /// The rationale is if \p ID covers the registers of \p RCId, that
- /// does not necessarily mean that \p ID covers the set of registers
- /// of RCId's superclasses.
- /// This method does *not* add the superreg classes as well for consistents.
- /// The expected use is to add the coverage top-down with respect to the
- /// register hierarchy.
- ///
- /// \todo TableGen should just generate the BitSet vector for us.
- void addRegBankCoverage(unsigned ID, unsigned RCId,
- const TargetRegisterInfo &TRI);
-
/// Get the register bank identified by \p ID.
RegisterBank &getRegBank(unsigned ID) {
assert(ID < getNumRegBanks() && "Accessing an unknown register bank");
diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h
index 420b03ec02bdc..df700bf0c53d9 100644
--- a/include/llvm/CodeGen/ISDOpcodes.h
+++ b/include/llvm/CodeGen/ISDOpcodes.h
@@ -503,19 +503,6 @@ namespace ISD {
/// address spaces.
ADDRSPACECAST,
- /// CONVERT_RNDSAT - This operator is used to support various conversions
- /// between various types (float, signed, unsigned and vectors of those
- /// types) with rounding and saturation. NOTE: Avoid using this operator as
- /// most target don't support it and the operator might be removed in the
- /// future. It takes the following arguments:
- /// 0) value
- /// 1) dest type (type to convert to)
- /// 2) src type (type to convert from)
- /// 3) rounding imm
- /// 4) saturation imm
- /// 5) ISD::CvtCode indicating the type of conversion to do
- CONVERT_RNDSAT,
-
/// FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions
/// and truncation for half-precision (16 bit) floating numbers. These nodes
/// form a semi-softened interface for dealing with f16 (as an i16), which
@@ -927,21 +914,6 @@ namespace ISD {
/// SETCC_INVALID if it is not possible to represent the resultant comparison.
CondCode getSetCCAndOperation(CondCode Op1, CondCode Op2, bool isInteger);
- //===--------------------------------------------------------------------===//
- /// This enum defines the various converts CONVERT_RNDSAT supports.
- enum CvtCode {
- CVT_FF, /// Float from Float
- CVT_FS, /// Float from Signed
- CVT_FU, /// Float from Unsigned
- CVT_SF, /// Signed from Float
- CVT_UF, /// Unsigned from Float
- CVT_SS, /// Signed from Signed
- CVT_SU, /// Signed from Unsigned
- CVT_US, /// Unsigned from Signed
- CVT_UU, /// Unsigned from Unsigned
- CVT_INVALID /// Marker - Invalid opcode
- };
-
} // end llvm::ISD namespace
} // end llvm namespace
diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h
index 7927982e782d1..54d0436e4ab83 100644
--- a/include/llvm/CodeGen/SelectionDAG.h
+++ b/include/llvm/CodeGen/SelectionDAG.h
@@ -626,12 +626,6 @@ public:
SDValue getCondCode(ISD::CondCode Cond);
- /// Returns the ConvertRndSat Note: Avoid using this node because it may
- /// disappear in the future and most targets don't support it.
- SDValue getConvertRndSat(EVT VT, const SDLoc &dl, SDValue Val, SDValue DTy,
- SDValue STy, SDValue Rnd, SDValue Sat,
- ISD::CvtCode Code);
-
/// Return an ISD::VECTOR_SHUFFLE node. The number of elements in VT,
/// which must be a vector type, must match the number of mask elements
/// NumElts. An integer mask element equal to -1 is treated as undefined.
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
index d4b7170eac3c5..b6f5424dbbd73 100644
--- a/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -1860,26 +1860,6 @@ public:
}
};
-/// NOTE: avoid using this node as this may disappear in the
-/// future and most targets don't support it.
-class CvtRndSatSDNode : public SDNode {
- ISD::CvtCode CvtCode;
-
- friend class SelectionDAG;
-
- explicit CvtRndSatSDNode(EVT VT, unsigned Order, const DebugLoc &dl,
- ISD::CvtCode Code)
- : SDNode(ISD::CONVERT_RNDSAT, Order, dl, getSDVTList(VT)), CvtCode(Code) {
- }
-
-public:
- ISD::CvtCode getCvtCode() const { return CvtCode; }
-
- static bool classof(const SDNode *N) {
- return N->getOpcode() == ISD::CONVERT_RNDSAT;
- }
-};
-
/// This class is used to represent EVT's, which are used
/// to parameterize some operations.
class VTSDNode : public SDNode {
@@ -2041,7 +2021,7 @@ public:
friend class SelectionDAG;
MaskedStoreSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
- bool isTrunc, bool isCompressing, EVT MemVT,
+ bool isTrunc, bool isCompressing, EVT MemVT,
MachineMemOperand *MMO)
: MaskedLoadStoreSDNode(ISD::MSTORE, Order, dl, VTs, MemVT, MMO) {
StoreSDNodeBits.IsTruncating = isTrunc;
@@ -2054,8 +2034,8 @@ public:
bool isTruncatingStore() const { return StoreSDNodeBits.IsTruncating; }
/// Returns true if the op does a compression to the vector before storing.
- /// The node contiguously stores the active elements (integers or floats)
- /// in src (those with their respective bit set in writemask k) to unaligned
+ /// The node contiguously stores the active elements (integers or floats)
+ /// in src (those with their respective bit set in writemask k) to unaligned
/// memory at base_addr.
bool isCompressingStore() const { return StoreSDNodeBits.IsCompressing; }
diff --git a/include/llvm/DebugInfo/CodeView/CVTypeDumper.h b/include/llvm/DebugInfo/CodeView/CVTypeDumper.h
new file mode 100644
index 0000000000000..e1dd6a10b5a16
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/CVTypeDumper.h
@@ -0,0 +1,56 @@
+//===-- CVTypeDumper.h - CodeView type info dumper --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_CVTYPEDUMPER_H
+#define LLVM_DEBUGINFO_CODEVIEW_CVTYPEDUMPER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
+#include "llvm/Support/ScopedPrinter.h"
+
+namespace llvm {
+
+namespace codeview {
+
+/// Dumper for CodeView type streams found in COFF object files and PDB files.
+class CVTypeDumper {
+public:
+ explicit CVTypeDumper(TypeDatabase &TypeDB) : TypeDB(TypeDB) {}
+
+ /// Dumps one type record. Returns false if there was a type parsing error,
+ /// and true otherwise. This should be called in order, since the dumper
+ /// maintains state about previous records which are necessary for cross
+ /// type references.
+ Error dump(const CVType &Record, TypeVisitorCallbacks &Dumper);
+
+ /// Dumps the type records in Types. Returns false if there was a type stream
+ /// parse error, and true otherwise.
+ Error dump(const CVTypeArray &Types, TypeVisitorCallbacks &Dumper);
+
+ /// Dumps the type records in Data. Returns false if there was a type stream
+ /// parse error, and true otherwise. Use this method instead of the
+ /// CVTypeArray overload when type records are laid out contiguously in
+ /// memory.
+ Error dump(ArrayRef<uint8_t> Data, TypeVisitorCallbacks &Dumper);
+
+ static void printTypeIndex(ScopedPrinter &Printer, StringRef FieldName,
+ TypeIndex TI, TypeDatabase &DB);
+
+private:
+ TypeDatabase &TypeDB;
+};
+
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_TYPEDUMPER_H
diff --git a/include/llvm/DebugInfo/CodeView/SymbolDumper.h b/include/llvm/DebugInfo/CodeView/SymbolDumper.h
index eb63f7895a1e5..a5419b37e7761 100644
--- a/include/llvm/DebugInfo/CodeView/SymbolDumper.h
+++ b/include/llvm/DebugInfo/CodeView/SymbolDumper.h
@@ -20,15 +20,15 @@ namespace llvm {
class ScopedPrinter;
namespace codeview {
-class CVTypeDumper;
+class TypeDatabase;
/// Dumper for CodeView symbol streams found in COFF object files and PDB files.
class CVSymbolDumper {
public:
- CVSymbolDumper(ScopedPrinter &W, CVTypeDumper &CVTD,
+ CVSymbolDumper(ScopedPrinter &W, TypeDatabase &TypeDB,
std::unique_ptr<SymbolDumpDelegate> ObjDelegate,
bool PrintRecordBytes)
- : W(W), CVTD(CVTD), ObjDelegate(std::move(ObjDelegate)),
+ : W(W), TypeDB(TypeDB), ObjDelegate(std::move(ObjDelegate)),
PrintRecordBytes(PrintRecordBytes) {}
/// Dumps one type record. Returns false if there was a type parsing error,
@@ -43,7 +43,7 @@ public:
private:
ScopedPrinter &W;
- CVTypeDumper &CVTD;
+ TypeDatabase &TypeDB;
std::unique_ptr<SymbolDumpDelegate> ObjDelegate;
bool PrintRecordBytes;
diff --git a/include/llvm/DebugInfo/CodeView/TypeDatabase.h b/include/llvm/DebugInfo/CodeView/TypeDatabase.h
new file mode 100644
index 0000000000000..cccc2868ffb5f
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/TypeDatabase.h
@@ -0,0 +1,55 @@
+//===- TypeDatabase.h - A collection of CodeView type records ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPEDATABASE_H
+#define LLVM_DEBUGINFO_CODEVIEW_TYPEDATABASE_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/StringSaver.h"
+
+namespace llvm {
+namespace codeview {
+class TypeDatabase {
+public:
+ TypeDatabase() : TypeNameStorage(Allocator) {}
+
+ /// Gets the type index for the next type record.
+ TypeIndex getNextTypeIndex() const;
+
+ /// Records the name of a type, and reserves its type index.
+ void recordType(StringRef Name, CVType Data);
+
+ /// Saves the name in a StringSet and creates a stable StringRef.
+ StringRef saveTypeName(StringRef TypeName);
+
+ StringRef getTypeName(TypeIndex Index) const;
+
+ bool containsTypeIndex(TypeIndex Index) const;
+
+ uint32_t size() const;
+
+private:
+ BumpPtrAllocator Allocator;
+
+ /// All user defined type records in .debug$T live in here. Type indices
+ /// greater than 0x1000 are user defined. Subtract 0x1000 from the index to
+ /// index into this vector.
+ SmallVector<StringRef, 10> CVUDTNames;
+ SmallVector<CVType, 10> TypeRecords;
+
+ StringSaver TypeNameStorage;
+};
+}
+}
+
+#endif \ No newline at end of file
diff --git a/include/llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h b/include/llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h
new file mode 100644
index 0000000000000..39d234cf9814d
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h
@@ -0,0 +1,53 @@
+//===-- TypeDatabaseVisitor.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPEDATABASEVISITOR_H
+#define LLVM_DEBUGINFO_CODEVIEW_TYPEDATABASEVISITOR_H
+
+#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
+
+namespace llvm {
+namespace codeview {
+
+/// Dumper for CodeView type streams found in COFF object files and PDB files.
+class TypeDatabaseVisitor : public TypeVisitorCallbacks {
+public:
+ explicit TypeDatabaseVisitor(TypeDatabase &TypeDB) : TypeDB(TypeDB) {}
+
+ /// Paired begin/end actions for all types. Receives all record data,
+ /// including the fixed-length record prefix.
+ Error visitTypeBegin(CVType &Record) override;
+ Error visitTypeEnd(CVType &Record) override;
+ Error visitMemberBegin(CVMemberRecord &Record) override;
+ Error visitMemberEnd(CVMemberRecord &Record) override;
+
+#define TYPE_RECORD(EnumName, EnumVal, Name) \
+ Error visitKnownRecord(CVType &CVR, Name##Record &Record) override;
+#define MEMBER_RECORD(EnumName, EnumVal, Name) \
+ Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override;
+#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#include "TypeRecords.def"
+
+private:
+ bool IsInFieldList = false;
+
+ /// Name of the current type. Only valid before visitTypeEnd.
+ StringRef Name;
+
+ TypeDatabase &TypeDB;
+};
+
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_TYPEDUMPER_H
diff --git a/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h b/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h
new file mode 100644
index 0000000000000..a466e42981582
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h
@@ -0,0 +1,67 @@
+//===-- TypeDumpVisitor.h - CodeView type info dumper -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPEDUMPVISITOR_H
+#define LLVM_DEBUGINFO_CODEVIEW_TYPEDUMPVISITOR_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
+
+namespace llvm {
+class ScopedPrinter;
+
+namespace codeview {
+
+/// Dumper for CodeView type streams found in COFF object files and PDB files.
+class TypeDumpVisitor : public TypeVisitorCallbacks {
+public:
+ TypeDumpVisitor(TypeDatabase &TypeDB, ScopedPrinter *W, bool PrintRecordBytes)
+ : W(W), PrintRecordBytes(PrintRecordBytes), TypeDB(TypeDB) {}
+
+ void printTypeIndex(StringRef FieldName, TypeIndex TI) const;
+
+ /// Action to take on unknown types. By default, they are ignored.
+ Error visitUnknownType(CVType &Record) override;
+ Error visitUnknownMember(CVMemberRecord &Record) override;
+
+ /// Paired begin/end actions for all types. Receives all record data,
+ /// including the fixed-length record prefix.
+ Error visitTypeBegin(CVType &Record) override;
+ Error visitTypeEnd(CVType &Record) override;
+ Error visitMemberBegin(CVMemberRecord &Record) override;
+ Error visitMemberEnd(CVMemberRecord &Record) override;
+
+#define TYPE_RECORD(EnumName, EnumVal, Name) \
+ Error visitKnownRecord(CVType &CVR, Name##Record &Record) override;
+#define MEMBER_RECORD(EnumName, EnumVal, Name) \
+ Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override;
+#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#include "TypeRecords.def"
+
+private:
+ void printMemberAttributes(MemberAttributes Attrs);
+ void printMemberAttributes(MemberAccess Access, MethodKind Kind,
+ MethodOptions Options);
+
+ ScopedPrinter *W;
+
+ bool PrintRecordBytes = false;
+
+ TypeDatabase &TypeDB;
+};
+
+} // end namespace codeview
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/DebugInfo/CodeView/TypeDumper.h b/include/llvm/DebugInfo/CodeView/TypeDumper.h
deleted file mode 100644
index 5a8b555cec02b..0000000000000
--- a/include/llvm/DebugInfo/CodeView/TypeDumper.h
+++ /dev/null
@@ -1,108 +0,0 @@
-//===-- TypeDumper.h - CodeView type info dumper ----------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPEDUMPER_H
-#define LLVM_DEBUGINFO_CODEVIEW_TYPEDUMPER_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringSet.h"
-#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
-
-namespace llvm {
-class ScopedPrinter;
-
-namespace codeview {
-
-/// Dumper for CodeView type streams found in COFF object files and PDB files.
-class CVTypeDumper : public TypeVisitorCallbacks {
-public:
- CVTypeDumper(ScopedPrinter *W, bool PrintRecordBytes)
- : W(W), PrintRecordBytes(PrintRecordBytes) {}
-
- StringRef getTypeName(TypeIndex TI);
- void printTypeIndex(StringRef FieldName, TypeIndex TI);
-
- /// Dumps one type record. Returns false if there was a type parsing error,
- /// and true otherwise. This should be called in order, since the dumper
- /// maintains state about previous records which are necessary for cross
- /// type references.
- Error dump(const CVRecord<TypeLeafKind> &Record);
-
- /// Dumps the type records in Types. Returns false if there was a type stream
- /// parse error, and true otherwise.
- Error dump(const CVTypeArray &Types);
-
- /// Dumps the type records in Data. Returns false if there was a type stream
- /// parse error, and true otherwise. Use this method instead of the
- /// CVTypeArray overload when type records are laid out contiguously in
- /// memory.
- Error dump(ArrayRef<uint8_t> Data);
-
- /// Gets the type index for the next type record.
- unsigned getNextTypeIndex() const {
- return 0x1000 + CVUDTNames.size();
- }
-
- /// Records the name of a type, and reserves its type index.
- void recordType(StringRef Name) { CVUDTNames.push_back(Name); }
-
- /// Saves the name in a StringSet and creates a stable StringRef.
- StringRef saveName(StringRef TypeName) {
- return TypeNames.insert(TypeName).first->getKey();
- }
-
- void setPrinter(ScopedPrinter *P);
- ScopedPrinter *getPrinter() { return W; }
-
- /// Action to take on unknown types. By default, they are ignored.
- Error visitUnknownType(CVType &Record) override;
- Error visitUnknownMember(CVMemberRecord &Record) override;
-
- /// Paired begin/end actions for all types. Receives all record data,
- /// including the fixed-length record prefix.
- Error visitTypeBegin(CVType &Record) override;
- Error visitTypeEnd(CVType &Record) override;
- Error visitMemberBegin(CVMemberRecord &Record) override;
- Error visitMemberEnd(CVMemberRecord &Record) override;
-
-#define TYPE_RECORD(EnumName, EnumVal, Name) \
- Error visitKnownRecord(CVType &CVR, Name##Record &Record) override;
-#define MEMBER_RECORD(EnumName, EnumVal, Name) \
- Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override;
-#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "TypeRecords.def"
-
-private:
- void printMemberAttributes(MemberAttributes Attrs);
- void printMemberAttributes(MemberAccess Access, MethodKind Kind,
- MethodOptions Options);
-
- ScopedPrinter *W;
-
- bool IsInFieldList = false;
- bool PrintRecordBytes = false;
-
- /// Name of the current type. Only valid before visitTypeEnd.
- StringRef Name;
-
- /// All user defined type records in .debug$T live in here. Type indices
- /// greater than 0x1000 are user defined. Subtract 0x1000 from the index to
- /// index into this vector.
- SmallVector<StringRef, 10> CVUDTNames;
-
- StringSet<> TypeNames;
-};
-
-} // end namespace codeview
-} // end namespace llvm
-
-#endif // LLVM_DEBUGINFO_CODEVIEW_TYPEDUMPER_H
diff --git a/include/llvm/DebugInfo/CodeView/TypeDumperBase.h b/include/llvm/DebugInfo/CodeView/TypeDumperBase.h
new file mode 100644
index 0000000000000..e69de29bb2d1d
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/TypeDumperBase.h
diff --git a/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h b/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h
index 778817f57bf57..db9bd506be897 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h
@@ -23,21 +23,32 @@ class raw_ostream;
class DWARFAbbreviationDeclaration {
public:
struct AttributeSpec {
- AttributeSpec(dwarf::Attribute A, dwarf::Form F, Optional<uint8_t> S)
- : Attr(A), Form(F), ByteSize(S) {}
+ AttributeSpec(dwarf::Attribute A, dwarf::Form F, Optional<int64_t> V)
+ : Attr(A), Form(F), ByteSizeOrValue(V) {}
dwarf::Attribute Attr;
dwarf::Form Form;
- /// If ByteSize has a value, then it contains the fixed size in bytes for
- /// the Form in this object. If ByteSize doesn't have a value, then the
- /// byte size of Form either varies according to the DWARFUnit that it is
- /// contained in or the value size varies and must be decoded from the
- /// debug information in order to determine its size.
- Optional<uint8_t> ByteSize;
+ /// The following field is used for ByteSize for non-implicit_const
+ /// attributes and as value for implicit_const ones, indicated by
+ /// Form == DW_FORM_implicit_const.
+ /// The following cases are distinguished:
+ /// * Form != DW_FORM_implicit_const and ByteSizeOrValue has a value:
+ /// ByteSizeOrValue contains the fixed size in bytes
+ /// for the Form in this object.
+ /// * Form != DW_FORM_implicit_const and ByteSizeOrValue is None:
+ /// byte size of Form either varies according to the DWARFUnit
+ /// that it is contained in or the value size varies and must be
+ /// decoded from the debug information in order to determine its size.
+ /// * Form == DW_FORM_implicit_const:
+ /// ByteSizeOrValue contains value for the implicit_const attribute.
+ Optional<int64_t> ByteSizeOrValue;
+ bool isImplicitConst() const {
+ return Form == dwarf::DW_FORM_implicit_const;
+ }
/// Get the fixed byte size of this Form if possible. This function might
/// use the DWARFUnit to calculate the size of the Form, like for
/// DW_AT_address and DW_AT_ref_addr, so this isn't just an accessor for
/// the ByteSize member.
- Optional<uint8_t> getByteSize(const DWARFUnit &U) const;
+ Optional<int64_t> getByteSize(const DWARFUnit &U) const;
};
typedef SmallVector<AttributeSpec, 8> AttributeSpecVector;
diff --git a/include/llvm/DebugInfo/DWARF/DWARFDie.h b/include/llvm/DebugInfo/DWARF/DWARFDie.h
index 5a24b7c872995..e335e28b39d73 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFDie.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFDie.h
@@ -147,21 +147,6 @@ public:
/// DW_AT_abstract_origin referenced DIEs.
///
/// \param Attr the attribute to extract.
- /// \param FailValue the value to return if this DIE doesn't have this
- /// attribute.
- /// \returns the address value of the attribute or FailValue if the
- /// attribute doesn't exist or if the attribute's form isn't a form that
- /// describes an address.
- uint64_t getAttributeValueAsAddress(dwarf::Attribute Attr,
- uint64_t FailValue) const;
-
- /// Extract the specified attribute from this DIE as an address.
- ///
- /// Extract an attribute value from this DIE only. This call doesn't look
- /// for the attribute value in any DW_AT_specification or
- /// DW_AT_abstract_origin referenced DIEs.
- ///
- /// \param Attr the attribute to extract.
/// \returns an optional value for the attribute.
Optional<uint64_t> getAttributeValueAsAddress(dwarf::Attribute Attr) const;
@@ -172,21 +157,6 @@ public:
/// DW_AT_abstract_origin referenced DIEs.
///
/// \param Attr the attribute to extract.
- /// \param FailValue the value to return if this DIE doesn't have this
- /// attribute.
- /// \returns the signed integer constant value of the attribute or FailValue
- /// if the attribute doesn't exist or if the attribute's form isn't a form
- /// that describes a signed integer.
- int64_t getAttributeValueAsSignedConstant(dwarf::Attribute Attr,
- int64_t FailValue) const;
-
- /// Extract the specified attribute from this DIE as a signed integer.
- ///
- /// Extract an attribute value from this DIE only. This call doesn't look
- /// for the attribute value in any DW_AT_specification or
- /// DW_AT_abstract_origin referenced DIEs.
- ///
- /// \param Attr the attribute to extract.
/// \returns an optional value for the attribute.
Optional<int64_t>
getAttributeValueAsSignedConstant(dwarf::Attribute Attr) const;
@@ -198,21 +168,6 @@ public:
/// DW_AT_abstract_origin referenced DIEs.
///
/// \param Attr the attribute to extract.
- /// \param FailValue the value to return if this DIE doesn't have this
- /// attribute.
- /// \returns the unsigned integer constant value of the attribute or FailValue
- /// if the attribute doesn't exist or if the attribute's form isn't a form
- /// that describes an unsigned integer.
- uint64_t getAttributeValueAsUnsignedConstant(dwarf::Attribute Attr,
- uint64_t FailValue) const;
-
- /// Extract the specified attribute from this DIE as an unsigned integer.
- ///
- /// Extract an attribute value from this DIE only. This call doesn't look
- /// for the attribute value in any DW_AT_specification or
- /// DW_AT_abstract_origin referenced DIEs.
- ///
- /// \param Attr the attribute to extract.
/// \returns an optional value for the attribute.
Optional<uint64_t>
getAttributeValueAsUnsignedConstant(dwarf::Attribute Attr) const;
@@ -224,21 +179,6 @@ public:
/// DW_AT_abstract_origin referenced DIEs.
///
/// \param Attr the attribute to extract.
- /// \param FailValue the value to return if this DIE doesn't have this
- /// attribute.
- /// \returns the unsigned integer constant value of the attribute or FailValue
- /// if the attribute doesn't exist or if the attribute's form isn't a form
- /// that describes a reference.
- uint64_t getAttributeValueAsReference(dwarf::Attribute Attr,
- uint64_t FailValue) const;
-
- /// Extract the specified attribute from this DIE as absolute DIE Offset.
- ///
- /// Extract an attribute value from this DIE only. This call doesn't look
- /// for the attribute value in any DW_AT_specification or
- /// DW_AT_abstract_origin referenced DIEs.
- ///
- /// \param Attr the attribute to extract.
/// \returns an optional value for the attribute.
Optional<uint64_t> getAttributeValueAsReference(dwarf::Attribute Attr) const;
@@ -249,20 +189,6 @@ public:
/// DW_AT_abstract_origin referenced DIEs.
///
/// \param Attr the attribute to extract.
- /// \param FailValue the value to return if this DIE doesn't have this
- /// attribute.
- /// \returns the unsigned integer constant value of the attribute or FailValue
- /// if the attribute doesn't exist or if the attribute's form isn't a form
- /// that describes a section offset.
- uint64_t getAttributeValueAsSectionOffset(dwarf::Attribute Attr,
- uint64_t FailValue) const;
- /// Extract the specified attribute from this DIE as absolute section offset.
- ///
- /// Extract an attribute value from this DIE only. This call doesn't look
- /// for the attribute value in any DW_AT_specification or
- /// DW_AT_abstract_origin referenced DIEs.
- ///
- /// \param Attr the attribute to extract.
/// \returns an optional value for the attribute.
Optional<uint64_t>
getAttributeValueAsSectionOffset(dwarf::Attribute Attr) const;
diff --git a/include/llvm/DebugInfo/DWARF/DWARFFormValue.h b/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
index 920880cea10ca..1b7659dfb04ac 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
@@ -57,6 +57,9 @@ public:
DWARFFormValue(dwarf::Form F = dwarf::Form(0)) : Form(F), U(nullptr) {}
dwarf::Form getForm() const { return Form; }
void setForm(dwarf::Form F) { Form = F; }
+ void setUValue(uint64_t V) { Value.uval = V; }
+ void setSValue(int64_t V) { Value.sval = V; }
+ void setPValue(const char *V) { Value.cstr = V; }
bool isFormClass(FormClass FC) const;
const DWARFUnit *getUnit() const { return U; }
void dump(raw_ostream &OS) const;
diff --git a/include/llvm/DebugInfo/MSF/StreamArray.h b/include/llvm/DebugInfo/MSF/StreamArray.h
index 3bba80d807f3f..5dfeb8c524af3 100644
--- a/include/llvm/DebugInfo/MSF/StreamArray.h
+++ b/include/llvm/DebugInfo/MSF/StreamArray.h
@@ -153,30 +153,24 @@ public:
return ThisValue;
}
- IterType &operator+=(std::ptrdiff_t N) {
- while (N > 0) {
- // We are done with the current record, discard it so that we are
- // positioned at the next record.
- IterRef = IterRef.drop_front(ThisLen);
- if (IterRef.getLength() == 0) {
- // There is nothing after the current record, we must make this an end
- // iterator.
+ IterType &operator++() {
+ // We are done with the current record, discard it so that we are
+ // positioned at the next record.
+ IterRef = IterRef.drop_front(ThisLen);
+ if (IterRef.getLength() == 0) {
+ // There is nothing after the current record, we must make this an end
+ // iterator.
+ moveToEnd();
+ } else {
+ // There is some data after the current record.
+ auto EC = Extract(IterRef, ThisLen, ThisValue);
+ if (EC) {
+ consumeError(std::move(EC));
+ markError();
+ } else if (ThisLen == 0) {
+ // An empty record? Make this an end iterator.
moveToEnd();
- return *this;
- } else {
- // There is some data after the current record.
- auto EC = Extract(IterRef, ThisLen, ThisValue);
- if (EC) {
- consumeError(std::move(EC));
- markError();
- return *this;
- } else if (ThisLen == 0) {
- // An empty record? Make this an end iterator.
- moveToEnd();
- return *this;
- }
}
- --N;
}
return *this;
}
diff --git a/include/llvm/IR/DIBuilder.h b/include/llvm/IR/DIBuilder.h
index 932ae51b39dc5..48cb7fe5df6f3 100644
--- a/include/llvm/IR/DIBuilder.h
+++ b/include/llvm/IR/DIBuilder.h
@@ -17,7 +17,9 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/None.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/IR/DebugInfo.h"
@@ -51,6 +53,10 @@ namespace llvm {
SmallVector<Metadata *, 4> AllSubprograms;
SmallVector<Metadata *, 4> AllGVs;
SmallVector<TrackingMDNodeRef, 4> AllImportedModules;
+ /// Map Macro parent (which can be DIMacroFile or nullptr) to a list of
+ /// Metadata all of type DIMacroNode.
+ /// DIMacroNode's with nullptr parent are DICompileUnit direct children.
+ MapVector<MDNode *, SetVector<Metadata *>> AllMacrosPerParent;
/// Track nodes that may be unresolved.
SmallVector<TrackingMDNodeRef, 4> UnresolvedNodes;
@@ -116,6 +122,24 @@ namespace llvm {
DIFile::ChecksumKind CSKind = DIFile::CSK_None,
StringRef Checksum = StringRef());
+ /// Create debugging information entry for a macro.
+ /// \param Parent Macro parent (could be nullptr).
+ /// \param Line Source line number where the macro is defined.
+ /// \param MacroType DW_MACINFO_define or DW_MACINFO_undef.
+ /// \param Name Macro name.
+ /// \param Value Macro value.
+ DIMacro *createMacro(DIMacroFile *Parent, unsigned Line, unsigned MacroType,
+ StringRef Name, StringRef Value = StringRef());
+
+ /// Create debugging information temporary entry for a macro file.
+ /// List of macro node direct children will be calculated by DIBuilder,
+ /// using the \p Parent relationship.
+ /// \param Parent Macro file parent (could be nullptr).
+ /// \param Line Source line number where the macro file is included.
+ /// \param File File descriptor containing the name of the macro file.
+ DIMacroFile *createTempMacroFile(DIMacroFile *Parent, unsigned Line,
+ DIFile *File);
+
/// Create a single enumerator value.
DIEnumerator *createEnumerator(StringRef Name, int64_t Val);
@@ -447,6 +471,9 @@ namespace llvm {
/// Get a DINodeArray, create one if required.
DINodeArray getOrCreateArray(ArrayRef<Metadata *> Elements);
+ /// Get a DIMacroNodeArray, create one if required.
+ DIMacroNodeArray getOrCreateMacroArray(ArrayRef<Metadata *> Elements);
+
/// Get a DITypeRefArray, create one if required.
DITypeRefArray getOrCreateTypeArray(ArrayRef<Metadata *> Elements);
diff --git a/include/llvm/IR/DebugInfoMetadata.h b/include/llvm/IR/DebugInfoMetadata.h
index 26f4626ead10e..187855225c505 100644
--- a/include/llvm/IR/DebugInfoMetadata.h
+++ b/include/llvm/IR/DebugInfoMetadata.h
@@ -1295,16 +1295,12 @@ public:
/// Check \c this can be discriminated from \c RHS in a linetable entry.
/// Scope and inlined-at chains are not recorded in the linetable, so they
/// cannot be used to distinguish basic blocks.
- ///
- /// The current implementation is weaker than it should be, since it just
- /// checks filename and line.
- ///
- /// FIXME: Add a check for getDiscriminator().
- /// FIXME: Add a check for getColumn().
- /// FIXME: Change the getFilename() check to getFile() (or add one for
- /// getDirectory()).
bool canDiscriminate(const DILocation &RHS) const {
- return getFilename() != RHS.getFilename() || getLine() != RHS.getLine();
+ return getLine() != RHS.getLine() ||
+ getColumn() != RHS.getColumn() ||
+ getDiscriminator() != RHS.getDiscriminator() ||
+ getFilename() != RHS.getFilename() ||
+ getDirectory() != RHS.getDirectory();
}
/// Get the DWARF discriminator.
@@ -1327,10 +1323,13 @@ public:
/// represented in a single line entry. In this case, no location
/// should be set.
///
- /// Currently this function is simply a stub, and no location will be
- /// used for all cases.
- static DILocation *getMergedLocation(const DILocation *LocA,
- const DILocation *LocB) {
+ /// Currently the function does not create a new location. If the locations
+ /// are the same, or cannot be discriminated, the first location is returned.
+ /// Otherwise an empty location will be used.
+ static const DILocation *getMergedLocation(const DILocation *LocA,
+ const DILocation *LocB) {
+ if (LocA && LocB && (LocA == LocB || !LocA->canDiscriminate(*LocB)))
+ return LocA;
return nullptr;
}
diff --git a/include/llvm/IR/GlobalObject.h b/include/llvm/IR/GlobalObject.h
index 11eb713a4e1d9..1057f564aab3b 100644
--- a/include/llvm/IR/GlobalObject.h
+++ b/include/llvm/IR/GlobalObject.h
@@ -37,11 +37,11 @@ protected:
setGlobalValueSubClassData(0);
}
- std::string Section; // Section to emit this into, empty means default
Comdat *ObjComdat;
enum {
LastAlignmentBit = 4,
HasMetadataHashEntryBit,
+ HasSectionHashEntryBit,
GlobalObjectBits,
};
@@ -66,8 +66,26 @@ public:
unsigned getGlobalObjectSubClassData() const;
void setGlobalObjectSubClassData(unsigned Val);
- bool hasSection() const { return !getSection().empty(); }
- StringRef getSection() const { return Section; }
+ /// Check if this global has a custom object file section.
+ ///
+ /// This is more efficient than calling getSection() and checking for an empty
+ /// string.
+ bool hasSection() const {
+ return getGlobalValueSubClassData() & (1 << HasSectionHashEntryBit);
+ }
+
+ /// Get the custom section of this global if it has one.
+ ///
+ /// If this global does not have a custom section, this will be empty and the
+ /// default object file section (.text, .data, etc) will be used.
+ StringRef getSection() const {
+ return hasSection() ? getSectionImpl() : StringRef();
+ }
+
+ /// Change the section for this global.
+ ///
+ /// Setting the section to the empty string tells LLVM to choose an
+ /// appropriate default object file section.
void setSection(StringRef S);
bool hasComdat() const { return getComdat() != nullptr; }
@@ -134,14 +152,20 @@ public:
void clearMetadata();
private:
+ void setGlobalObjectFlag(unsigned Bit, bool Val) {
+ unsigned Mask = 1 << Bit;
+ setGlobalValueSubClassData((~Mask & getGlobalValueSubClassData()) |
+ (Val ? Mask : 0u));
+ }
+
bool hasMetadataHashEntry() const {
return getGlobalValueSubClassData() & (1 << HasMetadataHashEntryBit);
}
void setHasMetadataHashEntry(bool HasEntry) {
- unsigned Mask = 1 << HasMetadataHashEntryBit;
- setGlobalValueSubClassData((~Mask & getGlobalValueSubClassData()) |
- (HasEntry ? Mask : 0u));
+ setGlobalObjectFlag(HasMetadataHashEntryBit, HasEntry);
}
+
+ StringRef getSectionImpl() const;
};
} // end namespace llvm
diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td
index 33fd17f20dbe2..89ae94270888b 100644
--- a/include/llvm/IR/Intrinsics.td
+++ b/include/llvm/IR/Intrinsics.td
@@ -578,8 +578,8 @@ def int_invariant_end : Intrinsic<[],
llvm_anyptr_ty],
[IntrArgMemOnly, NoCapture<2>]>;
-def int_invariant_group_barrier : Intrinsic<[llvm_ptr_ty],
- [llvm_ptr_ty],
+def int_invariant_group_barrier : Intrinsic<[llvm_ptr_ty],
+ [llvm_ptr_ty],
[IntrNoMem]>;
//===------------------------ Stackmap Intrinsics -------------------------===//
@@ -683,29 +683,6 @@ def int_convert_to_fp16 : Intrinsic<[llvm_i16_ty], [llvm_anyfloat_ty]>;
def int_convert_from_fp16 : Intrinsic<[llvm_anyfloat_ty], [llvm_i16_ty]>;
}
-// These convert intrinsics are to support various conversions between
-// various types with rounding and saturation. NOTE: avoid using these
-// intrinsics as they might be removed sometime in the future and
-// most targets don't support them.
-def int_convertff : Intrinsic<[llvm_anyfloat_ty],
- [llvm_anyfloat_ty, llvm_i32_ty, llvm_i32_ty]>;
-def int_convertfsi : Intrinsic<[llvm_anyfloat_ty],
- [llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>;
-def int_convertfui : Intrinsic<[llvm_anyfloat_ty],
- [llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>;
-def int_convertsif : Intrinsic<[llvm_anyint_ty],
- [llvm_anyfloat_ty, llvm_i32_ty, llvm_i32_ty]>;
-def int_convertuif : Intrinsic<[llvm_anyint_ty],
- [llvm_anyfloat_ty, llvm_i32_ty, llvm_i32_ty]>;
-def int_convertss : Intrinsic<[llvm_anyint_ty],
- [llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>;
-def int_convertsu : Intrinsic<[llvm_anyint_ty],
- [llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>;
-def int_convertus : Intrinsic<[llvm_anyint_ty],
- [llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>;
-def int_convertuu : Intrinsic<[llvm_anyint_ty],
- [llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>;
-
// Clear cache intrinsic, default to ignore (ie. emit nothing)
// maps to void __clear_cache() on supporting platforms
def int_clear_cache : Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty],
diff --git a/include/llvm/IR/IntrinsicsAArch64.td b/include/llvm/IR/IntrinsicsAArch64.td
index d1e331775b7bf..2c45d148e34b3 100644
--- a/include/llvm/IR/IntrinsicsAArch64.td
+++ b/include/llvm/IR/IntrinsicsAArch64.td
@@ -38,12 +38,6 @@ def int_aarch64_udiv : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>,
def int_aarch64_hint : Intrinsic<[], [llvm_i32_ty]>;
//===----------------------------------------------------------------------===//
-// RBIT
-
-def int_aarch64_rbit : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>],
- [IntrNoMem]>;
-
-//===----------------------------------------------------------------------===//
// Data Barrier Instructions
def int_aarch64_dmb : GCCBuiltin<"__builtin_arm_dmb">, Intrinsic<[], [llvm_i32_ty]>;
diff --git a/include/llvm/IR/IntrinsicsARM.td b/include/llvm/IR/IntrinsicsARM.td
index 0995985968853..24239689a62ee 100644
--- a/include/llvm/IR/IntrinsicsARM.td
+++ b/include/llvm/IR/IntrinsicsARM.td
@@ -156,11 +156,6 @@ def int_arm_hint : Intrinsic<[], [llvm_i32_ty]>;
def int_arm_dbg : Intrinsic<[], [llvm_i32_ty]>;
//===----------------------------------------------------------------------===//
-// RBIT
-
-def int_arm_rbit : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
-
-//===----------------------------------------------------------------------===//
// UND (reserved undefined sequence)
def int_arm_undefined : Intrinsic<[], [llvm_i32_ty]>;
diff --git a/include/llvm/IR/ModuleSummaryIndex.h b/include/llvm/IR/ModuleSummaryIndex.h
index ecb0435a1e11b..83c4ae0112161 100644
--- a/include/llvm/IR/ModuleSummaryIndex.h
+++ b/include/llvm/IR/ModuleSummaryIndex.h
@@ -317,10 +317,10 @@ struct TypeTestResolution {
/// All-Ones Bit Vectors")
} TheKind = Unsat;
- /// Range of the size expressed as a bit width. For example, if the size is in
- /// range [0,256), this number will be 8. This helps generate the most compact
+ /// Range of size-1 expressed as a bit width. For example, if the size is in
+ /// range [1,256], this number will be 8. This helps generate the most compact
/// instruction sequences.
- unsigned SizeBitWidth = 0;
+ unsigned SizeM1BitWidth = 0;
};
struct TypeIdSummary {
diff --git a/include/llvm/IR/ModuleSummaryIndexYAML.h b/include/llvm/IR/ModuleSummaryIndexYAML.h
index aeb66633f2c85..e2880ec6fec8d 100644
--- a/include/llvm/IR/ModuleSummaryIndexYAML.h
+++ b/include/llvm/IR/ModuleSummaryIndexYAML.h
@@ -29,7 +29,7 @@ template <> struct ScalarEnumerationTraits<TypeTestResolution::Kind> {
template <> struct MappingTraits<TypeTestResolution> {
static void mapping(IO &io, TypeTestResolution &res) {
io.mapOptional("Kind", res.TheKind);
- io.mapOptional("SizeBitWidth", res.SizeBitWidth);
+ io.mapOptional("SizeM1BitWidth", res.SizeM1BitWidth);
}
};
diff --git a/include/llvm/Object/Decompressor.h b/include/llvm/Object/Decompressor.h
new file mode 100644
index 0000000000000..a11857d546aae
--- /dev/null
+++ b/include/llvm/Object/Decompressor.h
@@ -0,0 +1,64 @@
+//===-- Decompressor.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===/
+
+#ifndef LLVM_OBJECT_DECOMPRESSOR_H
+#define LLVM_OBJECT_DECOMPRESSOR_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Object/ObjectFile.h"
+
+namespace llvm {
+namespace object {
+
+/// @brief Decompressor helps to handle decompression of compressed sections.
+class Decompressor {
+public:
+ /// @brief Create decompressor object.
+ /// @param Name Section name.
+ /// @param Data Section content.
+ /// @param IsLE Flag determines if Data is in little endian form.
+ /// @param Is64Bit Flag determines if object is 64 bit.
+ static Expected<Decompressor> create(StringRef Name, StringRef Data,
+ bool IsLE, bool Is64Bit);
+
+ /// @brief Resize the buffer and uncompress section data into it.
+ /// @param Out Destination buffer.
+ Error decompress(SmallString<32> &Out);
+
+ /// @brief Uncompress section data to raw buffer provided.
+ /// @param Buffer Destination buffer.
+ Error decompress(MutableArrayRef<char> Buffer);
+
+ /// @brief Return memory buffer size required for decompression.
+ uint64_t getDecompressedSize() { return DecompressedSize; }
+
+ /// @brief Return true if section is compressed, including gnu-styled case.
+ static bool isCompressed(const object::SectionRef &Section);
+
+ /// @brief Return true if section is a ELF compressed one.
+ static bool isCompressedELFSection(uint64_t Flags, StringRef Name);
+
+ /// @brief Return true if section name matches gnu style compressed one.
+ static bool isGnuStyle(StringRef Name);
+
+private:
+ Decompressor(StringRef Data);
+
+ Error consumeCompressedGnuHeader();
+ Error consumeCompressedZLibHeader(bool Is64Bit, bool IsLittleEndian);
+
+ StringRef SectionData;
+ uint64_t DecompressedSize;
+};
+
+} // end namespace object
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_DECOMPRESSOR_H
diff --git a/include/llvm/ObjectYAML/DWARFYAML.h b/include/llvm/ObjectYAML/DWARFYAML.h
index 222cad61a9923..d031b5ac404c5 100644
--- a/include/llvm/ObjectYAML/DWARFYAML.h
+++ b/include/llvm/ObjectYAML/DWARFYAML.h
@@ -85,6 +85,41 @@ struct Unit {
std::vector<Entry> Entries;
};
+struct File {
+ StringRef Name;
+ uint64_t DirIdx;
+ uint64_t ModTime;
+ uint64_t Length;
+};
+
+struct LineTableOpcode {
+ dwarf::LineNumberOps Opcode;
+ uint64_t ExtLen;
+ dwarf::LineNumberExtendedOps SubOpcode;
+ uint64_t Data;
+ int64_t SData;
+ File FileEntry;
+ std::vector<llvm::yaml::Hex8> UnknownOpcodeData;
+ std::vector<llvm::yaml::Hex64> StandardOpcodeData;
+};
+
+struct LineTable {
+ uint32_t TotalLength;
+ uint64_t TotalLength64;
+ uint16_t Version;
+ uint64_t PrologueLength;
+ uint8_t MinInstLength;
+ uint8_t MaxOpsPerInst;
+ uint8_t DefaultIsStmt;
+ uint8_t LineBase;
+ uint8_t LineRange;
+ uint8_t OpcodeBase;
+ std::vector<uint8_t> StandardOpcodeLengths;
+ std::vector<StringRef> IncludeDirs;
+ std::vector<File> Files;
+ std::vector<LineTableOpcode> Opcodes;
+};
+
struct Data {
bool IsLittleEndian;
std::vector<Abbrev> AbbrevDecls;
@@ -98,6 +133,8 @@ struct Data {
std::vector<Unit> CompileUnits;
+ std::vector<LineTable> DebugLines;
+
bool isEmpty() const;
};
@@ -105,6 +142,7 @@ struct Data {
} // namespace llvm
LLVM_YAML_IS_SEQUENCE_VECTOR(uint8_t)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex64)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::StringRef)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex8)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::AttributeAbbrev)
@@ -115,6 +153,9 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::PubEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Unit)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::FormValue)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Entry)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::File)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::LineTable)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::LineTableOpcode)
namespace llvm {
namespace yaml {
@@ -159,6 +200,18 @@ template <> struct MappingTraits<DWARFYAML::FormValue> {
static void mapping(IO &IO, DWARFYAML::FormValue &FormValue);
};
+template <> struct MappingTraits<DWARFYAML::File> {
+ static void mapping(IO &IO, DWARFYAML::File &File);
+};
+
+template <> struct MappingTraits<DWARFYAML::LineTableOpcode> {
+ static void mapping(IO &IO, DWARFYAML::LineTableOpcode &LineTableOpcode);
+};
+
+template <> struct MappingTraits<DWARFYAML::LineTable> {
+ static void mapping(IO &IO, DWARFYAML::LineTable &LineTable);
+};
+
#define HANDLE_DW_TAG(unused, name) \
io.enumCase(value, "DW_TAG_" #name, dwarf::DW_TAG_##name);
@@ -169,6 +222,26 @@ template <> struct ScalarEnumerationTraits<dwarf::Tag> {
}
};
+#define HANDLE_DW_LNS(unused, name) \
+ io.enumCase(value, "DW_LNS_" #name, dwarf::DW_LNS_##name);
+
+template <> struct ScalarEnumerationTraits<dwarf::LineNumberOps> {
+ static void enumeration(IO &io, dwarf::LineNumberOps &value) {
+#include "llvm/Support/Dwarf.def"
+ io.enumFallback<Hex8>(value);
+ }
+};
+
+#define HANDLE_DW_LNE(unused, name) \
+ io.enumCase(value, "DW_LNE_" #name, dwarf::DW_LNE_##name);
+
+template <> struct ScalarEnumerationTraits<dwarf::LineNumberExtendedOps> {
+ static void enumeration(IO &io, dwarf::LineNumberExtendedOps &value) {
+#include "llvm/Support/Dwarf.def"
+ io.enumFallback<Hex16>(value);
+ }
+};
+
#define HANDLE_DW_AT(unused, name) \
io.enumCase(value, "DW_AT_" #name, dwarf::DW_AT_##name);
diff --git a/include/llvm/ObjectYAML/MachOYAML.h b/include/llvm/ObjectYAML/MachOYAML.h
index 6b7a924f51438..9ec32d265bcae 100644
--- a/include/llvm/ObjectYAML/MachOYAML.h
+++ b/include/llvm/ObjectYAML/MachOYAML.h
@@ -139,7 +139,6 @@ struct UniversalBinary {
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::LoadCommand)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::Section)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex64)
LLVM_YAML_IS_SEQUENCE_VECTOR(int64_t)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::RebaseOpcode)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::BindOpcode)
diff --git a/include/llvm/Passes/PassBuilder.h b/include/llvm/Passes/PassBuilder.h
index ba3238c860447..d76c13984d11c 100644
--- a/include/llvm/Passes/PassBuilder.h
+++ b/include/llvm/Passes/PassBuilder.h
@@ -18,8 +18,8 @@
#include "llvm/ADT/Optional.h"
#include "llvm/Analysis/CGSCCPassManager.h"
-#include "llvm/Analysis/LoopPassManager.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/Transforms/Scalar/LoopPassManager.h"
#include <vector>
namespace llvm {
diff --git a/include/llvm/ProfileData/InstrProf.h b/include/llvm/ProfileData/InstrProf.h
index 094f3af005d37..c7e558efa3dcc 100644
--- a/include/llvm/ProfileData/InstrProf.h
+++ b/include/llvm/ProfileData/InstrProf.h
@@ -230,6 +230,15 @@ class InstrProfSymtab;
/// bytes. This method decodes the string and populates the \c Symtab.
Error readPGOFuncNameStrings(StringRef NameStrings, InstrProfSymtab &Symtab);
+/// Check if INSTR_PROF_RAW_VERSION_VAR is defined. This global is only being
+/// set in IR PGO compilation.
+bool isIRPGOFlagSet(const Module *M);
+
+/// Check if we can safely rename this Comdat function. Instances of the same
+/// comdat function may have different control flows thus can not share the
+/// same counter variable.
+bool canRenameComdatFunc(const Function &F, bool CheckAddressTaken = false);
+
enum InstrProfValueKind : uint32_t {
#define VALUE_PROF_KIND(Enumerator, Value) Enumerator = Value,
#include "llvm/ProfileData/InstrProfData.inc"
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
index 204672f88dd9f..8d4ac81d29429 100644
--- a/include/llvm/Support/CommandLine.h
+++ b/include/llvm/Support/CommandLine.h
@@ -201,7 +201,7 @@ public:
void reset();
- operator bool() const;
+ explicit operator bool() const;
StringRef getName() const { return Name; }
StringRef getDescription() const { return Description; }
diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h
index 1a984037da090..8336b9df9df0d 100644
--- a/include/llvm/Support/Dwarf.h
+++ b/include/llvm/Support/Dwarf.h
@@ -207,7 +207,7 @@ enum DiscriminantList {
};
/// Line Number Standard Opcode Encodings.
-enum LineNumberOps {
+enum LineNumberOps : uint8_t {
#define HANDLE_DW_LNS(ID, NAME) DW_LNS_##NAME = ID,
#include "llvm/Support/Dwarf.def"
};
diff --git a/include/llvm/Support/FileOutputBuffer.h b/include/llvm/Support/FileOutputBuffer.h
index 3bcf64a8a08bd..2c054c75374be 100644
--- a/include/llvm/Support/FileOutputBuffer.h
+++ b/include/llvm/Support/FileOutputBuffer.h
@@ -78,11 +78,12 @@ private:
FileOutputBuffer &operator=(const FileOutputBuffer &) = delete;
FileOutputBuffer(std::unique_ptr<llvm::sys::fs::mapped_file_region> R,
- StringRef Path, StringRef TempPath);
+ StringRef Path, StringRef TempPath, bool IsRegular);
std::unique_ptr<llvm::sys::fs::mapped_file_region> Region;
SmallString<128> FinalPath;
SmallString<128> TempPath;
+ bool IsRegular;
};
} // end namespace llvm
diff --git a/include/llvm/Support/GenericDomTree.h b/include/llvm/Support/GenericDomTree.h
index 07a53438085a0..6e6ee40016440 100644
--- a/include/llvm/Support/GenericDomTree.h
+++ b/include/llvm/Support/GenericDomTree.h
@@ -571,9 +571,15 @@ public:
// API to update (Post)DominatorTree information based on modifications to
// the CFG...
- /// addNewBlock - Add a new node to the dominator tree information. This
- /// creates a new node as a child of DomBB dominator node,linking it into
- /// the children list of the immediate dominator.
+ /// Add a new node to the dominator tree information.
+ ///
+ /// This creates a new node as a child of DomBB dominator node, linking it
+ /// into the children list of the immediate dominator.
+ ///
+ /// \param BB New node in CFG.
+ /// \param DomBB CFG node that is dominator for BB.
+ /// \returns New dominator tree node that represents new CFG node.
+ ///
DomTreeNodeBase<NodeT> *addNewBlock(NodeT *BB, NodeT *DomBB) {
assert(getNode(BB) == nullptr && "Block already in dominator tree!");
DomTreeNodeBase<NodeT> *IDomNode = getNode(DomBB);
@@ -583,6 +589,31 @@ public:
llvm::make_unique<DomTreeNodeBase<NodeT>>(BB, IDomNode))).get();
}
+ /// Add a new node to the forward dominator tree and make it a new root.
+ ///
+ /// \param BB New node in CFG.
+ /// \returns New dominator tree node that represents new CFG node.
+ ///
+ DomTreeNodeBase<NodeT> *setNewRoot(NodeT *BB) {
+ assert(getNode(BB) == nullptr && "Block already in dominator tree!");
+ assert(!this->isPostDominator() &&
+ "Cannot change root of post-dominator tree");
+ DFSInfoValid = false;
+ auto &Roots = DominatorBase<NodeT>::Roots;
+ DomTreeNodeBase<NodeT> *NewNode = (DomTreeNodes[BB] =
+ llvm::make_unique<DomTreeNodeBase<NodeT>>(BB, nullptr)).get();
+ if (Roots.empty()) {
+ addRoot(BB);
+ } else {
+ assert(Roots.size() == 1);
+ NodeT *OldRoot = Roots.front();
+ DomTreeNodes[OldRoot] =
+ NewNode->addChild(std::move(DomTreeNodes[OldRoot]));
+ Roots[0] = BB;
+ }
+ return RootNode = NewNode;
+ }
+
/// changeImmediateDominator - This method is used to update the dominator
/// tree information when a node's immediate dominator changes.
///
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index fb43ef19a6450..3728a7a8cb179 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -23,66 +23,80 @@
#ifndef LLVM_TARGET_TARGETLOWERING_H
#define LLVM_TARGET_TARGETLOWERING_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/DAGCombine.h"
+#include "llvm/CodeGen/ISDOpcodes.h"
+#include "llvm/CodeGen/MachineValueType.h"
#include "llvm/CodeGen/RuntimeLibcalls.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
+#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/CallingConv.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InlineAsm.h"
+#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Type.h"
#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/Support/AtomicOrdering.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Target/TargetCallingConv.h"
#include "llvm/Target/TargetMachine.h"
+#include <algorithm>
+#include <cassert>
#include <climits>
+#include <cstdint>
+#include <iterator>
#include <map>
+#include <string>
+#include <utility>
#include <vector>
namespace llvm {
- class BranchProbability;
- class CallInst;
- class CCState;
- class CCValAssign;
- class FastISel;
- class FunctionLoweringInfo;
- class ImmutableCallSite;
- class IntrinsicInst;
- class MachineBasicBlock;
- class MachineFunction;
- class MachineInstr;
- class MachineJumpTableInfo;
- class MachineLoop;
- class MachineRegisterInfo;
- class Mangler;
- class MCContext;
- class MCExpr;
- class MCSymbol;
- template<typename T> class SmallVectorImpl;
- class DataLayout;
- class TargetRegisterClass;
- class TargetLibraryInfo;
- class TargetLoweringObjectFile;
- class Value;
-
- namespace Sched {
- enum Preference {
- None, // No preference
- Source, // Follow source order.
- RegPressure, // Scheduling for lowest register pressure.
- Hybrid, // Scheduling for both latency and register pressure.
- ILP, // Scheduling for ILP in low register pressure mode.
- VLIW // Scheduling for VLIW targets.
- };
- }
+
+class BranchProbability;
+class CCState;
+class CCValAssign;
+class FastISel;
+class FunctionLoweringInfo;
+class IntrinsicInst;
+class MachineBasicBlock;
+class MachineFunction;
+class MachineInstr;
+class MachineJumpTableInfo;
+class MachineLoop;
+class MachineRegisterInfo;
+class MCContext;
+class MCExpr;
+class TargetRegisterClass;
+class TargetLibraryInfo;
+class TargetRegisterInfo;
+class Value;
+
+namespace Sched {
+
+ enum Preference {
+ None, // No preference
+ Source, // Follow source order.
+ RegPressure, // Scheduling for lowest register pressure.
+ Hybrid, // Scheduling for both latency and register pressure.
+ ILP, // Scheduling for ILP in low register pressure mode.
+ VLIW // Scheduling for VLIW targets.
+ };
+
+} // end namespace Sched
/// This base class for TargetLowering contains the SelectionDAG-independent
/// parts that can be used from the rest of CodeGen.
class TargetLoweringBase {
- TargetLoweringBase(const TargetLoweringBase&) = delete;
- void operator=(const TargetLoweringBase&) = delete;
-
public:
/// This enum indicates whether operations are valid for a target, and if not,
/// what action should be used to make them valid.
@@ -166,7 +180,9 @@ public:
/// NOTE: The TargetMachine owns TLOF.
explicit TargetLoweringBase(const TargetMachine &TM);
- virtual ~TargetLoweringBase() {}
+ TargetLoweringBase(const TargetLoweringBase&) = delete;
+ void operator=(const TargetLoweringBase&) = delete;
+ virtual ~TargetLoweringBase() = default;
protected:
/// \brief Initialize all of the actions to default values.
@@ -599,19 +615,18 @@ public:
MVT &RegisterVT) const;
struct IntrinsicInfo {
- unsigned opc; // target opcode
- EVT memVT; // memory VT
- const Value* ptrVal; // value representing memory location
- int offset; // offset off of ptrVal
- unsigned size; // the size of the memory location
- // (taken from memVT if zero)
- unsigned align; // alignment
- bool vol; // is volatile?
- bool readMem; // reads memory?
- bool writeMem; // writes memory?
-
- IntrinsicInfo() : opc(0), ptrVal(nullptr), offset(0), size(0), align(1),
- vol(false), readMem(false), writeMem(false) {}
+ unsigned opc = 0; // target opcode
+ EVT memVT; // memory VT
+ const Value* ptrVal = nullptr; // value representing memory location
+ int offset = 0; // offset off of ptrVal
+ unsigned size = 0; // the size of the memory location
+ // (taken from memVT if zero)
+ unsigned align = 1; // alignment
+ bool vol = false; // is volatile?
+ bool readMem = false; // reads memory?
+ bool writeMem = false; // writes memory?
+
+ IntrinsicInfo() = default;
};
/// Given an intrinsic, checks if on the target the intrinsic will need to map
@@ -823,7 +838,6 @@ public:
getCondCodeAction(CC, VT) == Custom;
}
-
/// If the action for this operation is to promote, this method returns the
/// ValueType to promote to.
MVT getTypeToPromoteTo(unsigned Op, MVT VT) const {
@@ -1643,11 +1657,11 @@ public:
/// If Scale is zero, there is no ScaleReg. Scale of 1 indicates a reg with
/// no scale.
struct AddrMode {
- GlobalValue *BaseGV;
- int64_t BaseOffs;
- bool HasBaseReg;
- int64_t Scale;
- AddrMode() : BaseGV(nullptr), BaseOffs(0), HasBaseReg(false), Scale(0) {}
+ GlobalValue *BaseGV = nullptr;
+ int64_t BaseOffs = 0;
+ bool HasBaseReg = false;
+ int64_t Scale = 0;
+ AddrMode() = default;
};
/// Return true if the addressing mode represented by AM is legal for this
@@ -2093,8 +2107,6 @@ protected:
private:
LegalizeKind getTypeConversion(LLVMContext &Context, EVT VT) const;
-private:
-
/// Targets can specify ISD nodes that they would like PerformDAGCombine
/// callbacks for by calling setTargetDAGCombine(), which sets a bit in this
/// array.
@@ -2192,7 +2204,6 @@ protected:
/// \see enableExtLdPromotion.
bool EnableExtLdPromotion;
-protected:
/// Return true if the value types that can be represented by the specified
/// register class are all legal.
bool isLegalRC(const TargetRegisterClass *RC) const;
@@ -2209,12 +2220,12 @@ protected:
/// This class also defines callbacks that targets must implement to lower
/// target-specific constructs to SelectionDAG operators.
class TargetLowering : public TargetLoweringBase {
- TargetLowering(const TargetLowering&) = delete;
- void operator=(const TargetLowering&) = delete;
-
public:
struct DAGCombinerInfo;
+ TargetLowering(const TargetLowering&) = delete;
+ void operator=(const TargetLowering&) = delete;
+
/// NOTE: The TargetMachine owns TLOF.
explicit TargetLowering(const TargetMachine &TM);
@@ -2376,6 +2387,7 @@ public:
void *DC; // The DAG Combiner object.
CombineLevel Level;
bool CalledByLegalizer;
+
public:
SelectionDAG &DAG;
@@ -2542,7 +2554,7 @@ public:
ArgListEntry() : isSExt(false), isZExt(false), isInReg(false),
isSRet(false), isNest(false), isByVal(false), isInAlloca(false),
isReturned(false), isSwiftSelf(false), isSwiftError(false),
- Alignment(0) { }
+ Alignment(0) {}
void setAttributes(ImmutableCallSite *CS, unsigned AttrIdx);
};
@@ -2681,7 +2693,6 @@ public:
ArgListTy &getArgs() {
return Args;
}
-
};
/// This function lowers an abstract call to a function into an actual call.
@@ -3118,6 +3129,13 @@ public:
EVT DataVT, SelectionDAG &DAG,
bool IsCompressedMemory) const;
+ /// Get a pointer to vector element \p Idx located in memory for a vector of
+ /// type \p VecVT starting at a base address of \p VecPtr. If \p Idx is out of
+ /// bounds the returned pointer is unspecified, but will be within the vector
+ /// bounds.
+ SDValue getVectorElementPointer(SelectionDAG &DAG, SDValue VecPtr, EVT VecVT,
+ SDValue Idx) const;
+
//===--------------------------------------------------------------------===//
// Instruction Emitting Hooks
//
@@ -3169,6 +3187,6 @@ void GetReturnInfo(Type *ReturnType, AttributeSet attr,
SmallVectorImpl<ISD::OutputArg> &Outs,
const TargetLowering &TLI, const DataLayout &DL);
-} // end llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_TARGET_TARGETLOWERING_H
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index f5493283eee6f..b1d8f8f1e9173 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -20,36 +20,26 @@
#include "llvm/Pass.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Target/TargetOptions.h"
-#include <cassert>
#include <string>
namespace llvm {
-class InstrItineraryData;
class GlobalValue;
-class Mangler;
class MachineFunctionInitializer;
-class MachineModuleInfo;
+class Mangler;
class MCAsmInfo;
class MCContext;
class MCInstrInfo;
class MCRegisterInfo;
class MCSubtargetInfo;
class MCSymbol;
+class raw_pwrite_stream;
class Target;
-class TargetLibraryInfo;
-class TargetFrameLowering;
-class TargetIRAnalysis;
class TargetIntrinsicInfo;
-class TargetLowering;
+class TargetIRAnalysis;
+class TargetLoweringObjectFile;
class TargetPassConfig;
-class TargetRegisterInfo;
class TargetSubtargetInfo;
-class TargetTransformInfo;
-class formatted_raw_ostream;
-class raw_ostream;
-class raw_pwrite_stream;
-class TargetLoweringObjectFile;
// The old pass manager infrastructure is hidden in a legacy namespace now.
namespace legacy {
@@ -64,8 +54,6 @@ using legacy::PassManagerBase;
/// interface.
///
class TargetMachine {
- TargetMachine(const TargetMachine &) = delete;
- void operator=(const TargetMachine &) = delete;
protected: // Can only create subclasses.
TargetMachine(const Target &T, StringRef DataLayoutString,
const Triple &TargetTriple, StringRef CPU, StringRef FS,
@@ -103,8 +91,11 @@ protected: // Can only create subclasses.
unsigned O0WantsFastISel : 1;
public:
+ const TargetOptions DefaultOptions;
mutable TargetOptions Options;
+ TargetMachine(const TargetMachine &) = delete;
+ void operator=(const TargetMachine &) = delete;
virtual ~TargetMachine();
const Target &getTarget() const { return TheTarget; }
@@ -310,6 +301,6 @@ public:
bool DisableVerify = true) override;
};
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_TARGET_TARGETMACHINE_H
diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td
index 4ddf7d77a23af..55e2c2bce3db9 100644
--- a/include/llvm/Target/TargetSelectionDAG.td
+++ b/include/llvm/Target/TargetSelectionDAG.td
@@ -575,9 +575,6 @@ def intrinsic_w_chain : SDNode<"ISD::INTRINSIC_W_CHAIN",
def intrinsic_wo_chain : SDNode<"ISD::INTRINSIC_WO_CHAIN",
SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>, []>;
-// Do not use cvt directly. Use cvt forms below
-def cvt : SDNode<"ISD::CONVERT_RNDSAT", SDTConvertOp>;
-
def SDT_assertext : SDTypeProfile<1, 1,
[SDTCisInt<0>, SDTCisInt<1>, SDTCisSameAs<1, 0>]>;
def assertsext : SDNode<"ISD::AssertSext", SDT_assertext>;
@@ -1085,54 +1082,6 @@ def atomic_load_64 :
}]>;
//===----------------------------------------------------------------------===//
-// Selection DAG CONVERT_RNDSAT patterns
-
-def cvtff : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
- (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
- return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_FF;
- }]>;
-
-def cvtss : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
- (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
- return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_SS;
- }]>;
-
-def cvtsu : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
- (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
- return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_SU;
- }]>;
-
-def cvtus : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
- (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
- return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_US;
- }]>;
-
-def cvtuu : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
- (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
- return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_UU;
- }]>;
-
-def cvtsf : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
- (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
- return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_SF;
- }]>;
-
-def cvtuf : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
- (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
- return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_UF;
- }]>;
-
-def cvtfs : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
- (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
- return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_FS;
- }]>;
-
-def cvtfu : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
- (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
- return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_FU;
- }]>;
-
-//===----------------------------------------------------------------------===//
// Selection DAG Pattern Support.
//
// Patterns are what are actually matched against by the target-flavored
diff --git a/include/llvm/Target/TargetSubtargetInfo.h b/include/llvm/Target/TargetSubtargetInfo.h
index bf4331383cb0d..0b43515960216 100644
--- a/include/llvm/Target/TargetSubtargetInfo.h
+++ b/include/llvm/Target/TargetSubtargetInfo.h
@@ -14,23 +14,26 @@
#ifndef LLVM_TARGET_TARGETSUBTARGETINFO_H
#define LLVM_TARGET_TARGETSUBTARGETINFO_H
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/PBQPRAConstraint.h"
#include "llvm/CodeGen/SchedulerRegistry.h"
#include "llvm/CodeGen/ScheduleDAGMutation.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/CodeGen.h"
+#include <memory>
#include <vector>
namespace llvm {
class CallLowering;
-class DataLayout;
class InstructionSelector;
class LegalizerInfo;
-class MachineFunction;
class MachineInstr;
class RegisterBankInfo;
class SDep;
+class SelectionDAGTargetInfo;
class SUnit;
class TargetFrameLowering;
class TargetInstrInfo;
@@ -38,9 +41,7 @@ class TargetLowering;
class TargetRegisterClass;
class TargetRegisterInfo;
class TargetSchedModel;
-class SelectionDAGTargetInfo;
struct MachineSchedPolicy;
-template <typename T> class SmallVectorImpl;
//===----------------------------------------------------------------------===//
///
@@ -49,10 +50,6 @@ template <typename T> class SmallVectorImpl;
/// be exposed through a TargetSubtargetInfo-derived class.
///
class TargetSubtargetInfo : public MCSubtargetInfo {
- TargetSubtargetInfo(const TargetSubtargetInfo &) = delete;
- void operator=(const TargetSubtargetInfo &) = delete;
- TargetSubtargetInfo() = delete;
-
protected: // Can only create subclasses...
TargetSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS,
ArrayRef<SubtargetFeatureKV> PF,
@@ -69,6 +66,9 @@ public:
typedef enum { ANTIDEP_NONE, ANTIDEP_CRITICAL, ANTIDEP_ALL } AntiDepBreakMode;
typedef SmallVectorImpl<const TargetRegisterClass *> RegClassVector;
+ TargetSubtargetInfo() = delete;
+ TargetSubtargetInfo(const TargetSubtargetInfo &) = delete;
+ void operator=(const TargetSubtargetInfo &) = delete;
virtual ~TargetSubtargetInfo();
virtual bool isXRaySupported() const { return false; }
@@ -229,6 +229,6 @@ public:
virtual bool enableSubRegLiveness() const { return false; }
};
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_TARGET_TARGETSUBTARGETINFO_H
diff --git a/include/llvm/Transforms/Scalar/IVUsersPrinter.h b/include/llvm/Transforms/Scalar/IVUsersPrinter.h
new file mode 100644
index 0000000000000..fad00d86a95f1
--- /dev/null
+++ b/include/llvm/Transforms/Scalar/IVUsersPrinter.h
@@ -0,0 +1,30 @@
+//===- IVUsersPrinter.h - Induction Variable Users Printing -----*- 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_IVUSERSPRINTER_H
+#define LLVM_TRANSFORMS_SCALAR_IVUSERSPRINTER_H
+
+#include "llvm/Analysis/IVUsers.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Scalar/LoopPassManager.h"
+
+namespace llvm {
+
+/// Printer pass for the \c IVUsers for a loop.
+class IVUsersPrinterPass : public PassInfoMixin<IVUsersPrinterPass> {
+ raw_ostream &OS;
+
+public:
+ explicit IVUsersPrinterPass(raw_ostream &OS) : OS(OS) {}
+ PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR, LPMUpdater &U);
+};
+}
+
+#endif
diff --git a/include/llvm/Transforms/Scalar/IndVarSimplify.h b/include/llvm/Transforms/Scalar/IndVarSimplify.h
index 24a31594b1530..4a4683f1a07df 100644
--- a/include/llvm/Transforms/Scalar/IndVarSimplify.h
+++ b/include/llvm/Transforms/Scalar/IndVarSimplify.h
@@ -16,14 +16,15 @@
#define LLVM_TRANSFORMS_SCALAR_INDVARSIMPLIFY_H
#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/LoopPassManager.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/Transforms/Scalar/LoopPassManager.h"
namespace llvm {
class IndVarSimplifyPass : public PassInfoMixin<IndVarSimplifyPass> {
public:
- PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM);
+ PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR, LPMUpdater &U);
};
}
diff --git a/include/llvm/Transforms/Scalar/LICM.h b/include/llvm/Transforms/Scalar/LICM.h
index 39bbc72f8cb4c..68ad190c7647d 100644
--- a/include/llvm/Transforms/Scalar/LICM.h
+++ b/include/llvm/Transforms/Scalar/LICM.h
@@ -34,15 +34,16 @@
#define LLVM_TRANSFORMS_SCALAR_LICM_H
#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/LoopPassManager.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/Transforms/Scalar/LoopPassManager.h"
namespace llvm {
/// Performs Loop Invariant Code Motion Pass.
class LICMPass : public PassInfoMixin<LICMPass> {
public:
- PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM);
+ PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR, LPMUpdater &U);
};
} // end namespace llvm
diff --git a/include/llvm/Transforms/Scalar/LoopAccessAnalysisPrinter.h b/include/llvm/Transforms/Scalar/LoopAccessAnalysisPrinter.h
new file mode 100644
index 0000000000000..5eddd5fdc7e7e
--- /dev/null
+++ b/include/llvm/Transforms/Scalar/LoopAccessAnalysisPrinter.h
@@ -0,0 +1,31 @@
+//===- llvm/Analysis/LoopAccessAnalysisPrinter.h ----------------*- 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_LOOPACCESSANALYSISPRINTER_H
+#define LLVM_TRANSFORMS_SCALAR_LOOPACCESSANALYSISPRINTER_H
+
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Scalar/LoopPassManager.h"
+
+namespace llvm {
+
+/// \brief Printer pass for the \c LoopAccessInfo results.
+class LoopAccessInfoPrinterPass
+ : public PassInfoMixin<LoopAccessInfoPrinterPass> {
+ raw_ostream &OS;
+
+public:
+ explicit LoopAccessInfoPrinterPass(raw_ostream &OS) : OS(OS) {}
+ PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR, LPMUpdater &U);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/Scalar/LoopDeletion.h b/include/llvm/Transforms/Scalar/LoopDeletion.h
index 891f08faa48a9..b44f823a82cac 100644
--- a/include/llvm/Transforms/Scalar/LoopDeletion.h
+++ b/include/llvm/Transforms/Scalar/LoopDeletion.h
@@ -15,16 +15,17 @@
#define LLVM_TRANSFORMS_SCALAR_LOOPDELETION_H
#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/LoopPassManager.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/Transforms/Scalar/LoopPassManager.h"
namespace llvm {
class LoopDeletionPass : public PassInfoMixin<LoopDeletionPass> {
public:
LoopDeletionPass() {}
- PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM);
+ PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR, LPMUpdater &U);
bool runImpl(Loop *L, DominatorTree &DT, ScalarEvolution &SE,
LoopInfo &loopInfo);
diff --git a/include/llvm/Transforms/Scalar/LoopIdiomRecognize.h b/include/llvm/Transforms/Scalar/LoopIdiomRecognize.h
index 0c052ddd2fe7b..40349e8f7fe06 100644
--- a/include/llvm/Transforms/Scalar/LoopIdiomRecognize.h
+++ b/include/llvm/Transforms/Scalar/LoopIdiomRecognize.h
@@ -17,15 +17,16 @@
#define LLVM_TRANSFORMS_SCALAR_LOOPIDIOMRECOGNIZE_H
#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/LoopPassManager.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/Transforms/Scalar/LoopPassManager.h"
namespace llvm {
/// Performs Loop Idiom Recognize Pass.
class LoopIdiomRecognizePass : public PassInfoMixin<LoopIdiomRecognizePass> {
public:
- PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM);
+ PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR, LPMUpdater &U);
};
} // end namespace llvm
diff --git a/include/llvm/Transforms/Scalar/LoopInstSimplify.h b/include/llvm/Transforms/Scalar/LoopInstSimplify.h
index e30f4a97b78e0..bb8bc29577a2d 100644
--- a/include/llvm/Transforms/Scalar/LoopInstSimplify.h
+++ b/include/llvm/Transforms/Scalar/LoopInstSimplify.h
@@ -15,15 +15,16 @@
#define LLVM_TRANSFORMS_SCALAR_LOOPINSTSIMPLIFY_H
#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/LoopPassManager.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/Transforms/Scalar/LoopPassManager.h"
namespace llvm {
/// Performs Loop Inst Simplify Pass.
class LoopInstSimplifyPass : public PassInfoMixin<LoopInstSimplifyPass> {
public:
- PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM);
+ PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR, LPMUpdater &U);
};
} // end namespace llvm
diff --git a/include/llvm/Transforms/Scalar/LoopPassManager.h b/include/llvm/Transforms/Scalar/LoopPassManager.h
new file mode 100644
index 0000000000000..b0e6dd6f4c081
--- /dev/null
+++ b/include/llvm/Transforms/Scalar/LoopPassManager.h
@@ -0,0 +1,363 @@
+//===- LoopPassManager.h - Loop pass management -----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// This header provides classes for managing a pipeline of passes over loops
+/// in LLVM IR.
+///
+/// The primary loop pass pipeline is managed in a very particular way to
+/// provide a set of core guarantees:
+/// 1) Loops are, where possible, in simplified form.
+/// 2) Loops are *always* in LCSSA form.
+/// 3) A collection of Loop-specific analysis results are available:
+/// - LoopInfo
+/// - DominatorTree
+/// - ScalarEvolution
+/// - AAManager
+/// 4) All loop passes preserve #1 (where possible), #2, and #3.
+/// 5) Loop passes run over each loop in the loop nest from the innermost to
+/// the outermost. Specifically, all inner loops are processed before
+/// passes run over outer loops. When running the pipeline across an inner
+/// loop creates new inner loops, those are added and processed in this
+/// order as well.
+///
+/// This process is designed to facilitate transformations which simplify,
+/// reduce, and remove loops. For passes which are more oriented towards
+/// optimizing loops, especially optimizing loop *nests* instead of single
+/// loops in isolation, this framework is less interesting.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_SCALAR_LOOPPASSMANAGER_H
+#define LLVM_TRANSFORMS_SCALAR_LOOPPASSMANAGER_H
+
+#include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/ADT/PriorityWorklist.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/BasicAliasAnalysis.h"
+#include "llvm/Analysis/GlobalsModRef.h"
+#include "llvm/Analysis/LoopAnalysisManager.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+// Forward declarations of an update tracking API used in the pass manager.
+class LPMUpdater;
+
+// Explicit specialization and instantiation declarations for the pass manager.
+// See the comments on the definition of the specialization for details on how
+// it differs from the primary template.
+template <>
+PreservedAnalyses
+PassManager<Loop, LoopAnalysisManager, LoopStandardAnalysisResults &,
+ LPMUpdater &>::run(Loop &InitialL, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AnalysisResults,
+ LPMUpdater &U);
+extern template class PassManager<Loop, LoopAnalysisManager,
+ LoopStandardAnalysisResults &, LPMUpdater &>;
+
+/// \brief The Loop pass manager.
+///
+/// See the documentation for the PassManager template for details. It runs
+/// a sequence of Loop passes over each Loop that the manager is run over. This
+/// typedef serves as a convenient way to refer to this construct.
+typedef PassManager<Loop, LoopAnalysisManager, LoopStandardAnalysisResults &,
+ LPMUpdater &>
+ LoopPassManager;
+
+/// A partial specialization of the require analysis template pass to forward
+/// the extra parameters from a transformation's run method to the
+/// AnalysisManager's getResult.
+template <typename AnalysisT>
+struct RequireAnalysisPass<AnalysisT, Loop, LoopAnalysisManager,
+ LoopStandardAnalysisResults &, LPMUpdater &>
+ : PassInfoMixin<
+ RequireAnalysisPass<AnalysisT, Loop, LoopAnalysisManager,
+ LoopStandardAnalysisResults &, LPMUpdater &>> {
+ PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR, LPMUpdater &) {
+ (void)AM.template getResult<AnalysisT>(L, AR);
+ return PreservedAnalyses::all();
+ }
+};
+
+/// An alias template to easily name a require analysis loop pass.
+template <typename AnalysisT>
+using RequireAnalysisLoopPass =
+ RequireAnalysisPass<AnalysisT, Loop, LoopAnalysisManager,
+ LoopStandardAnalysisResults &, LPMUpdater &>;
+
+namespace internal {
+/// Helper to implement appending of loops onto a worklist.
+///
+/// We want to process loops in postorder, but the worklist is a LIFO data
+/// structure, so we append to it in *reverse* postorder.
+///
+/// For trees, a preorder traversal is a viable reverse postorder, so we
+/// actually append using a preorder walk algorithm.
+template <typename RangeT>
+inline void appendLoopsToWorklist(RangeT &&Loops,
+ SmallPriorityWorklist<Loop *, 4> &Worklist) {
+ // We use an internal worklist to build up the preorder traversal without
+ // recursion.
+ SmallVector<Loop *, 4> PreOrderLoops, PreOrderWorklist;
+
+ // We walk the initial sequence of loops in reverse because we generally want
+ // to visit defs before uses and the worklist is LIFO.
+ for (Loop *RootL : reverse(Loops)) {
+ assert(PreOrderLoops.empty() && "Must start with an empty preorder walk.");
+ assert(PreOrderWorklist.empty() &&
+ "Must start with an empty preorder walk worklist.");
+ PreOrderWorklist.push_back(RootL);
+ do {
+ Loop *L = PreOrderWorklist.pop_back_val();
+ PreOrderWorklist.append(L->begin(), L->end());
+ PreOrderLoops.push_back(L);
+ } while (!PreOrderWorklist.empty());
+
+ Worklist.insert(std::move(PreOrderLoops));
+ PreOrderLoops.clear();
+ }
+}
+}
+
+template <typename LoopPassT> class FunctionToLoopPassAdaptor;
+
+/// This class provides an interface for updating the loop pass manager based
+/// on mutations to the loop nest.
+///
+/// A reference to an instance of this class is passed as an argument to each
+/// Loop pass, and Loop passes should use it to update LPM infrastructure if
+/// they modify the loop nest structure.
+class LPMUpdater {
+public:
+ /// This can be queried by loop passes which run other loop passes (like pass
+ /// managers) to know whether the loop needs to be skipped due to updates to
+ /// the loop nest.
+ ///
+ /// If this returns true, the loop object may have been deleted, so passes
+ /// should take care not to touch the object.
+ bool skipCurrentLoop() const { return SkipCurrentLoop; }
+
+ /// Loop passes should use this method to indicate they have deleted a loop
+ /// from the nest.
+ ///
+ /// Note that this loop must either be the current loop or a subloop of the
+ /// current loop. This routine must be called prior to removing the loop from
+ /// the loop nest.
+ ///
+ /// 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.");
+ if (&L == CurrentL)
+ SkipCurrentLoop = true;
+ }
+
+ /// Loop passes should use this method to indicate they have added new child
+ /// loops of the current loop.
+ ///
+ /// \p NewChildLoops must contain only the immediate children. Any nested
+ /// loops within them will be visited in postorder as usual for the loop pass
+ /// manager.
+ void addChildLoops(ArrayRef<Loop *> NewChildLoops) {
+ // Insert ourselves back into the worklist first, as this loop should be
+ // revisited after all the children have been processed.
+ Worklist.insert(CurrentL);
+
+#ifndef NDEBUG
+ for (Loop *NewL : NewChildLoops)
+ assert(NewL->getParentLoop() == CurrentL && "All of the new loops must "
+ "be immediate children of "
+ "the current loop!");
+#endif
+
+ internal::appendLoopsToWorklist(NewChildLoops, Worklist);
+
+ // Also skip further processing of the current loop--it will be revisited
+ // after all of its newly added children are accounted for.
+ SkipCurrentLoop = true;
+ }
+
+ /// Loop passes should use this method to indicate they have added new
+ /// sibling loops to the current loop.
+ ///
+ /// \p NewSibLoops must only contain the immediate sibling loops. Any nested
+ /// loops within them will be visited in postorder as usual for the loop pass
+ /// manager.
+ void addSiblingLoops(ArrayRef<Loop *> NewSibLoops) {
+#ifndef NDEBUG
+ for (Loop *NewL : NewSibLoops)
+ assert(NewL->getParentLoop() == ParentL &&
+ "All of the new loops must be siblings of the current loop!");
+#endif
+
+ internal::appendLoopsToWorklist(NewSibLoops, Worklist);
+
+ // No need to skip the current loop or revisit it, as sibling loops
+ // shouldn't impact anything.
+ }
+
+private:
+ template <typename LoopPassT> friend class llvm::FunctionToLoopPassAdaptor;
+
+ /// The \c FunctionToLoopPassAdaptor's worklist of loops to process.
+ SmallPriorityWorklist<Loop *, 4> &Worklist;
+
+ /// The analysis manager for use in the current loop nest.
+ LoopAnalysisManager &LAM;
+
+ Loop *CurrentL;
+ bool SkipCurrentLoop;
+
+#ifndef NDEBUG
+ // In debug builds we also track the parent loop to implement asserts even in
+ // the face of loop deletion.
+ Loop *ParentL;
+#endif
+
+ LPMUpdater(SmallPriorityWorklist<Loop *, 4> &Worklist,
+ LoopAnalysisManager &LAM)
+ : Worklist(Worklist), LAM(LAM) {}
+};
+
+/// \brief Adaptor that maps from a function to its loops.
+///
+/// Designed to allow composition of a LoopPass(Manager) and a
+/// FunctionPassManager. Note that if this pass is constructed with a \c
+/// FunctionAnalysisManager it will run the \c LoopAnalysisManagerFunctionProxy
+/// analysis prior to running the loop passes over the function to enable a \c
+/// LoopAnalysisManager to be used within this run safely.
+template <typename LoopPassT>
+class FunctionToLoopPassAdaptor
+ : public PassInfoMixin<FunctionToLoopPassAdaptor<LoopPassT>> {
+public:
+ explicit FunctionToLoopPassAdaptor(LoopPassT Pass) : Pass(std::move(Pass)) {}
+
+ /// \brief Runs the loop passes across every loop in the function.
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
+ // Setup the loop analysis manager from its proxy.
+ LoopAnalysisManager &LAM =
+ AM.getResult<LoopAnalysisManagerFunctionProxy>(F).getManager();
+ // Get the loop structure for this function
+ LoopInfo &LI = AM.getResult<LoopAnalysis>(F);
+
+ // If there are no loops, there is nothing to do here.
+ if (LI.empty())
+ return PreservedAnalyses::all();
+
+ // Get the analysis results needed by loop passes.
+ 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)};
+
+ PreservedAnalyses PA = PreservedAnalyses::all();
+
+ // A postorder worklist of loops to process.
+ SmallPriorityWorklist<Loop *, 4> Worklist;
+
+ // Register the worklist and loop analysis manager so that loop passes can
+ // update them when they mutate the loop nest structure.
+ LPMUpdater Updater(Worklist, LAM);
+
+ // Add the loop nests in the reverse order of LoopInfo. For some reason,
+ // they are stored in RPO w.r.t. the control flow graph in LoopInfo. For
+ // the purpose of unrolling, loop deletion, and LICM, we largely want to
+ // work forward across the CFG so that we visit defs before uses and can
+ // propagate simplifications from one loop nest into the next.
+ // FIXME: Consider changing the order in LoopInfo.
+ internal::appendLoopsToWorklist(reverse(LI), Worklist);
+
+ do {
+ Loop *L = Worklist.pop_back_val();
+
+ // Reset the update structure for this loop.
+ Updater.CurrentL = L;
+ Updater.SkipCurrentLoop = false;
+#ifndef NDEBUG
+ Updater.ParentL = L->getParentLoop();
+#endif
+
+ PreservedAnalyses PassPA = Pass.run(*L, LAM, LAR, Updater);
+ // FIXME: We should verify the set of analyses relevant to Loop passes
+ // are preserved.
+
+ // If the loop hasn't been deleted, we need to handle invalidation here.
+ if (!Updater.skipCurrentLoop())
+ // We know that the loop pass couldn't have invalidated any other
+ // loop's analyses (that's the contract of a loop pass), so directly
+ // handle the loop analysis manager's invalidation here.
+ LAM.invalidate(*L, PassPA);
+
+ // Then intersect the preserved set so that invalidation of module
+ // analyses will eventually occur when the module pass completes.
+ PA.intersect(std::move(PassPA));
+ } while (!Worklist.empty());
+
+ // By definition we preserve the proxy. We also preserve all analyses on
+ // Loops. This precludes *any* invalidation of loop analyses by the proxy,
+ // but that's OK because we've taken care to invalidate analyses in the
+ // loop analysis manager incrementally above.
+ PA.preserveSet<AllAnalysesOn<Loop>>();
+ PA.preserve<LoopAnalysisManagerFunctionProxy>();
+ // We also preserve the set of standard analyses.
+ PA.preserve<AssumptionAnalysis>();
+ PA.preserve<DominatorTreeAnalysis>();
+ PA.preserve<LoopAnalysis>();
+ PA.preserve<ScalarEvolutionAnalysis>();
+ // FIXME: What we really want to do here is preserve an AA category, but
+ // that concept doesn't exist yet.
+ PA.preserve<AAManager>();
+ PA.preserve<BasicAA>();
+ PA.preserve<GlobalsAA>();
+ PA.preserve<SCEVAA>();
+ return PA;
+ }
+
+private:
+ LoopPassT Pass;
+};
+
+/// \brief A function to deduce a loop pass type and wrap it in the templated
+/// adaptor.
+template <typename LoopPassT>
+FunctionToLoopPassAdaptor<LoopPassT>
+createFunctionToLoopPassAdaptor(LoopPassT Pass) {
+ return FunctionToLoopPassAdaptor<LoopPassT>(std::move(Pass));
+}
+
+/// \brief Pass for printing a loop's contents as textual IR.
+class PrintLoopPass : public PassInfoMixin<PrintLoopPass> {
+ raw_ostream &OS;
+ std::string Banner;
+
+public:
+ PrintLoopPass();
+ PrintLoopPass(raw_ostream &OS, const std::string &Banner = "");
+
+ PreservedAnalyses run(Loop &L, LoopAnalysisManager &,
+ LoopStandardAnalysisResults &, LPMUpdater &);
+};
+}
+
+#endif // LLVM_TRANSFORMS_SCALAR_LOOPPASSMANAGER_H
diff --git a/include/llvm/Transforms/Scalar/LoopRotation.h b/include/llvm/Transforms/Scalar/LoopRotation.h
index 54b8ec545ed2b..ea8d5618e6f7d 100644
--- a/include/llvm/Transforms/Scalar/LoopRotation.h
+++ b/include/llvm/Transforms/Scalar/LoopRotation.h
@@ -15,8 +15,8 @@
#define LLVM_TRANSFORMS_SCALAR_LOOPROTATION_H
#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/LoopPassManager.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/Transforms/Scalar/LoopPassManager.h"
namespace llvm {
@@ -24,7 +24,8 @@ namespace llvm {
class LoopRotatePass : public PassInfoMixin<LoopRotatePass> {
public:
LoopRotatePass(bool EnableHeaderDuplication = true);
- PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM);
+ PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR, LPMUpdater &U);
private:
const bool EnableHeaderDuplication;
diff --git a/include/llvm/Transforms/Scalar/LoopSimplifyCFG.h b/include/llvm/Transforms/Scalar/LoopSimplifyCFG.h
index 2f06782052c5e..7628c7413eac5 100644
--- a/include/llvm/Transforms/Scalar/LoopSimplifyCFG.h
+++ b/include/llvm/Transforms/Scalar/LoopSimplifyCFG.h
@@ -18,15 +18,16 @@
#define LLVM_TRANSFORMS_SCALAR_LOOPSIMPLIFYCFG_H
#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/LoopPassManager.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/Transforms/Scalar/LoopPassManager.h"
namespace llvm {
/// Performs basic CFG simplifications to assist other loop passes.
class LoopSimplifyCFGPass : public PassInfoMixin<LoopSimplifyCFGPass> {
public:
- PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM);
+ PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR, LPMUpdater &U);
};
} // end namespace llvm
diff --git a/include/llvm/Transforms/Scalar/LoopStrengthReduce.h b/include/llvm/Transforms/Scalar/LoopStrengthReduce.h
index 11c0d9bce85b1..ebcb32125262b 100644
--- a/include/llvm/Transforms/Scalar/LoopStrengthReduce.h
+++ b/include/llvm/Transforms/Scalar/LoopStrengthReduce.h
@@ -23,15 +23,16 @@
#define LLVM_TRANSFORMS_SCALAR_LOOPSTRENGTHREDUCE_H
#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/LoopPassManager.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/Transforms/Scalar/LoopPassManager.h"
namespace llvm {
/// Performs Loop Strength Reduce Pass.
class LoopStrengthReducePass : public PassInfoMixin<LoopStrengthReducePass> {
public:
- PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM);
+ PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR, LPMUpdater &U);
};
} // end namespace llvm
diff --git a/include/llvm/Transforms/Scalar/LoopUnrollPass.h b/include/llvm/Transforms/Scalar/LoopUnrollPass.h
index 74a7258df5fc3..9da95ef81fad4 100644
--- a/include/llvm/Transforms/Scalar/LoopUnrollPass.h
+++ b/include/llvm/Transforms/Scalar/LoopUnrollPass.h
@@ -11,8 +11,8 @@
#define LLVM_TRANSFORMS_SCALAR_LOOPUNROLLPASS_H
#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/LoopPassManager.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/Transforms/Scalar/LoopPassManager.h"
namespace llvm {
@@ -23,7 +23,8 @@ struct LoopUnrollPass : public PassInfoMixin<LoopUnrollPass> {
Optional<bool> ProvidedRuntime;
Optional<bool> ProvidedUpperBound;
- PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM);
+ PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR, LPMUpdater &U);
};
} // end namespace llvm
diff --git a/include/llvm/Transforms/Utils/LoopUtils.h b/include/llvm/Transforms/Utils/LoopUtils.h
index 845069d4260a4..27b45c4fa9416 100644
--- a/include/llvm/Transforms/Utils/LoopUtils.h
+++ b/include/llvm/Transforms/Utils/LoopUtils.h
@@ -29,6 +29,7 @@ class DataLayout;
class DominatorTree;
class Loop;
class LoopInfo;
+class OptimizationRemarkEmitter;
class Pass;
class PredicatedScalarEvolution;
class PredIteratorCache;
@@ -404,11 +405,11 @@ bool formLCSSARecursively(Loop &L, DominatorTree &DT, LoopInfo *LI,
/// uses before definitions, allowing us to sink a loop body in one pass without
/// iteration. Takes DomTreeNode, AliasAnalysis, LoopInfo, DominatorTree,
/// DataLayout, TargetLibraryInfo, Loop, AliasSet information for all
-/// instructions of the loop and loop safety information as arguments.
-/// It returns changed status.
+/// 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 *);
+ 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
@@ -416,10 +417,11 @@ bool sinkRegion(DomTreeNode *, AliasAnalysis *, LoopInfo *, DominatorTree *,
/// before uses, allowing us to hoist a loop body in one pass without iteration.
/// Takes DomTreeNode, AliasAnalysis, LoopInfo, DominatorTree, DataLayout,
/// TargetLibraryInfo, Loop, AliasSet information for all instructions of the
-/// loop and loop safety information as arguments. It returns changed status.
+/// loop and loop safety information as arguments. Diagnostics is emitted via \p
+/// ORE. It returns changed status.
bool hoistRegion(DomTreeNode *, AliasAnalysis *, LoopInfo *, DominatorTree *,
TargetLibraryInfo *, Loop *, AliasSetTracker *,
- LoopSafetyInfo *);
+ LoopSafetyInfo *, OptimizationRemarkEmitter *ORE);
/// \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
@@ -427,12 +429,14 @@ bool hoistRegion(DomTreeNode *, AliasAnalysis *, LoopInfo *, DominatorTree *,
/// 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. It returns changed status.
+/// information as arguments. Diagnostics is emitted via \p ORE. It returns
+/// changed status.
bool promoteLoopAccessesToScalars(AliasSet &, SmallVectorImpl<BasicBlock *> &,
SmallVectorImpl<Instruction *> &,
PredIteratorCache &, LoopInfo *,
DominatorTree *, const TargetLibraryInfo *,
- Loop *, AliasSetTracker *, LoopSafetyInfo *);
+ Loop *, AliasSetTracker *, LoopSafetyInfo *,
+ OptimizationRemarkEmitter *);
/// \brief Computes safety information for a loop
/// checks loop body & header for the possibility of may throw
@@ -478,11 +482,12 @@ void getLoopAnalysisUsage(AnalysisUsage &AU);
/// preheader to loop body (no speculation).
/// If SafetyInfo is not null, we are checking for hoisting/sinking
/// instructions from loop body to preheader/exit. Check if the instruction
-/// can execute specultatively.
-///
+/// can execute speculatively.
+/// If \p ORE is set use it to emit optimization remarks.
bool canSinkOrHoistInst(Instruction &I, AAResults *AA, DominatorTree *DT,
Loop *CurLoop, AliasSetTracker *CurAST,
- LoopSafetyInfo *SafetyInfo);
+ LoopSafetyInfo *SafetyInfo,
+ OptimizationRemarkEmitter *ORE = nullptr);
}
#endif
diff --git a/include/llvm/Transforms/Utils/UnrollLoop.h b/include/llvm/Transforms/Utils/UnrollLoop.h
index 2ea28f2d4e136..f322bea7aa2e8 100644
--- a/include/llvm/Transforms/Utils/UnrollLoop.h
+++ b/include/llvm/Transforms/Utils/UnrollLoop.h
@@ -33,6 +33,12 @@ class Pass;
class OptimizationRemarkEmitter;
class ScalarEvolution;
+typedef SmallDenseMap<const Loop *, Loop *, 4> NewLoopsMap;
+
+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,
diff --git a/include/llvm/Transforms/Vectorize/LoopVectorize.h b/include/llvm/Transforms/Vectorize/LoopVectorize.h
index 2efc7ca4f8a1d..73d1f264c37b5 100644
--- a/include/llvm/Transforms/Vectorize/LoopVectorize.h
+++ b/include/llvm/Transforms/Vectorize/LoopVectorize.h
@@ -57,12 +57,12 @@
#include "llvm/Analysis/DemandedBits.h"
#include "llvm/Analysis/LoopAccessAnalysis.h"
#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/LoopPassManager.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 {
diff --git a/include/llvm/XRay/Trace.h b/include/llvm/XRay/Trace.h
new file mode 100644
index 0000000000000..6b033d686b062
--- /dev/null
+++ b/include/llvm/XRay/Trace.h
@@ -0,0 +1,71 @@
+//===- Trace.h - XRay Trace Abstraction -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines the XRay Trace class representing records in an XRay trace file.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_XRAY_TRACE_H
+#define LLVM_XRAY_TRACE_H
+
+#include <cstdint>
+#include <vector>
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/XRay/XRayRecord.h"
+
+namespace llvm {
+namespace xray {
+
+/// A Trace object represents the records that have been loaded from XRay
+/// log files generated by instrumented binaries. We encapsulate the logic of
+/// reading the traces in factory functions that populate the Trace object
+/// appropriately.
+///
+/// Trace objects provide an accessor to an XRayFileHeader which says more about
+/// details of the file from which the XRay trace was loaded from.
+///
+/// Usage:
+///
+/// if (auto TraceOrErr = loadTraceFile("xray-log.something.xray")) {
+/// auto& T = *TraceOrErr;
+/// // T.getFileHeader() will provide information from the trace header.
+/// for (const XRayRecord &R : T) {
+/// // ... do something with R here.
+/// }
+/// } else {
+/// // Handle the error here.
+/// }
+///
+class Trace {
+ XRayFileHeader FileHeader;
+ std::vector<XRayRecord> Records;
+
+ typedef std::vector<XRayRecord>::const_iterator citerator;
+
+ friend Expected<Trace> loadTraceFile(StringRef, bool);
+
+public:
+ /// Provides access to the loaded XRay trace file header.
+ const XRayFileHeader &getFileHeader() const { return FileHeader; }
+
+ citerator begin() const { return Records.begin(); }
+ citerator end() const { return Records.end(); }
+ size_t size() const { return Records.size(); }
+};
+
+/// This function will attempt to load XRay trace records from the provided
+/// |Filename|.
+Expected<Trace> loadTraceFile(StringRef Filename, bool Sort = false);
+
+} // namespace xray
+} // namespace llvm
+
+#endif // LLVM_XRAY_TRACE_H
diff --git a/include/llvm/XRay/XRayRecord.h b/include/llvm/XRay/XRayRecord.h
new file mode 100644
index 0000000000000..a96846136ec33
--- /dev/null
+++ b/include/llvm/XRay/XRayRecord.h
@@ -0,0 +1,76 @@
+//===- XRayRecord.h - XRay Trace Record -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file replicates the record definition for XRay log entries. This should
+// follow the evolution of the log record versions supported in the compiler-rt
+// xray project.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_XRAY_XRAY_RECORD_H
+#define LLVM_XRAY_XRAY_RECORD_H
+
+#include <cstdint>
+
+namespace llvm {
+namespace xray {
+
+/// XRay traces all have a header providing some top-matter information useful
+/// to help tools determine how to interpret the information available in the
+/// trace.
+struct XRayFileHeader {
+ /// Version of the XRay implementation that produced this file.
+ uint16_t Version = 0;
+
+ /// A numeric identifier for the type of file this is. Best used in
+ /// combination with Version.
+ uint16_t Type = 0;
+
+ /// Whether the CPU that produced the timestamp counters (TSC) move at a
+ /// constant rate.
+ bool ConstantTSC;
+
+ /// Whether the CPU that produced the timestamp counters (TSC) do not stop.
+ bool NonstopTSC;
+
+ /// The number of cycles per second for the CPU that produced the timestamp
+ /// counter (TSC) values. Useful for estimating the amount of time that
+ /// elapsed between two TSCs on some platforms.
+ uint64_t CycleFrequency = 0;
+};
+
+/// Determines the supported types of records that could be seen in XRay traces.
+/// This may or may not correspond to actual record types in the raw trace (as
+/// the loader implementation may synthesize this information in the process of
+/// of loading).
+enum class RecordTypes { ENTER, EXIT };
+
+struct XRayRecord {
+ /// The type of record.
+ uint16_t RecordType;
+
+ /// The CPU where the thread is running. We assume number of CPUs <= 256.
+ uint8_t CPU;
+
+ /// Identifies the type of record.
+ RecordTypes Type;
+
+ /// The function ID for the record.
+ int32_t FuncId;
+
+ /// Get the full 8 bytes of the TSC when we get the log record.
+ uint64_t TSC;
+
+ /// The thread ID for the currently running thread.
+ uint32_t TId;
+};
+
+} // namespace xray
+} // namespace llvm
+
+#endif // LLVM_XRAY_XRAY_RECORD_H
diff --git a/include/llvm/XRay/YAMLXRayRecord.h b/include/llvm/XRay/YAMLXRayRecord.h
new file mode 100644
index 0000000000000..f5836b3922421
--- /dev/null
+++ b/include/llvm/XRay/YAMLXRayRecord.h
@@ -0,0 +1,99 @@
+//===- YAMLXRayRecord.h - XRay Record YAML Support Definitions ------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Types and traits specialisations for YAML I/O of XRay log entries.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_XRAY_YAML_XRAY_RECORD_H
+#define LLVM_XRAY_YAML_XRAY_RECORD_H
+
+#include <type_traits>
+
+#include "llvm/Support/YAMLTraits.h"
+#include "llvm/XRay/XRayRecord.h"
+
+namespace llvm {
+namespace xray {
+
+struct YAMLXRayFileHeader {
+ uint16_t Version;
+ uint16_t Type;
+ bool ConstantTSC;
+ bool NonstopTSC;
+ uint64_t CycleFrequency;
+};
+
+struct YAMLXRayRecord {
+ uint16_t RecordType;
+ uint8_t CPU;
+ RecordTypes Type;
+ int32_t FuncId;
+ std::string Function;
+ uint64_t TSC;
+ uint32_t TId;
+};
+
+struct YAMLXRayTrace {
+ YAMLXRayFileHeader Header;
+ std::vector<YAMLXRayRecord> Records;
+};
+
+} // namespace xray
+
+namespace yaml {
+
+// YAML Traits
+// -----------
+template <> struct ScalarEnumerationTraits<xray::RecordTypes> {
+ static void enumeration(IO &IO, xray::RecordTypes &Type) {
+ IO.enumCase(Type, "function-enter", xray::RecordTypes::ENTER);
+ IO.enumCase(Type, "function-exit", xray::RecordTypes::EXIT);
+ }
+};
+
+template <> struct MappingTraits<xray::YAMLXRayFileHeader> {
+ static void mapping(IO &IO, xray::YAMLXRayFileHeader &Header) {
+ IO.mapRequired("version", Header.Version);
+ IO.mapRequired("type", Header.Type);
+ IO.mapRequired("constant-tsc", Header.ConstantTSC);
+ IO.mapRequired("nonstop-tsc", Header.NonstopTSC);
+ IO.mapRequired("cycle-frequency", Header.CycleFrequency);
+ }
+};
+
+template <> struct MappingTraits<xray::YAMLXRayRecord> {
+ static void mapping(IO &IO, xray::YAMLXRayRecord &Record) {
+ // FIXME: Make this type actually be descriptive
+ IO.mapRequired("type", Record.RecordType);
+ IO.mapRequired("func-id", Record.FuncId);
+ IO.mapOptional("function", Record.Function);
+ IO.mapRequired("cpu", Record.CPU);
+ IO.mapRequired("thread", Record.TId);
+ IO.mapRequired("kind", Record.Type);
+ IO.mapRequired("tsc", Record.TSC);
+ }
+
+ static constexpr bool flow = true;
+};
+
+template <> struct MappingTraits<xray::YAMLXRayTrace> {
+ static void mapping(IO &IO, xray::YAMLXRayTrace &Trace) {
+ // A trace file contains two parts, the header and the list of all the
+ // trace records.
+ IO.mapRequired("header", Trace.Header);
+ IO.mapRequired("records", Trace.Records);
+ }
+};
+
+} // namespace yaml
+} // namespace llvm
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(xray::YAMLXRayRecord)
+
+#endif // LLVM_XRAY_YAML_XRAY_RECORD_H