summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Transforms/Utils
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2017-04-02 17:24:58 +0000
committerdim <dim@FreeBSD.org>2017-04-02 17:24:58 +0000
commit60b571e49a90d38697b3aca23020d9da42fc7d7f (patch)
tree99351324c24d6cb146b6285b6caffa4d26fce188 /contrib/llvm/lib/Transforms/Utils
parentbea1b22c7a9bce1dfdd73e6e5b65bc4752215180 (diff)
downloadFreeBSD-src-60b571e49a90d38697b3aca23020d9da42fc7d7f.zip
FreeBSD-src-60b571e49a90d38697b3aca23020d9da42fc7d7f.tar.gz
Update clang, llvm, lld, lldb, compiler-rt and libc++ to 4.0.0 release:
MFC r309142 (by emaste): Add WITH_LLD_AS_LD build knob If set it installs LLD as /usr/bin/ld. LLD (as of version 3.9) is not capable of linking the world and kernel, but can self-host and link many substantial applications. GNU ld continues to be used for the world and kernel build, regardless of how this knob is set. It is on by default for arm64, and off for all other CPU architectures. Sponsored by: The FreeBSD Foundation MFC r310840: Reapply 310775, now it also builds correctly if lldb is disabled: Move llvm-objdump from CLANG_EXTRAS to installed by default We currently install three tools from binutils 2.17.50: as, ld, and objdump. Work is underway to migrate to a permissively-licensed tool-chain, with one goal being the retirement of binutils 2.17.50. LLVM's llvm-objdump is intended to be compatible with GNU objdump although it is currently missing some options and may have formatting differences. Enable it by default for testing and further investigation. It may later be changed to install as /usr/bin/objdump, it becomes a fully viable replacement. Reviewed by: emaste Differential Revision: https://reviews.freebsd.org/D8879 MFC r312855 (by emaste): Rename LLD_AS_LD to LLD_IS_LD, for consistency with CLANG_IS_CC Reported by: Dan McGregor <dan.mcgregor usask.ca> MFC r313559 | glebius | 2017-02-10 18:34:48 +0100 (Fri, 10 Feb 2017) | 5 lines Don't check struct rtentry on FreeBSD, it is an internal kernel structure. On other systems it may be API structure for SIOCADDRT/SIOCDELRT. Reviewed by: emaste, dim MFC r314152 (by jkim): Remove an assembler flag, which is redundant since r309124. The upstream took care of it by introducing a macro NO_EXEC_STACK_DIRECTIVE. http://llvm.org/viewvc/llvm-project?rev=273500&view=rev Reviewed by: dim MFC r314564: Upgrade our copies of clang, llvm, lld, lldb, compiler-rt and libc++ to 4.0.0 (branches/release_40 296509). The release will follow soon. Please note that from 3.5.0 onwards, clang, llvm and lldb require C++11 support to build; see UPDATING for more information. Also note that as of 4.0.0, lld should be able to link the base system on amd64 and aarch64. See the WITH_LLD_IS_LLD setting in src.conf(5). Though please be aware that this is work in progress. Release notes for llvm, clang and lld will be available here: <http://releases.llvm.org/4.0.0/docs/ReleaseNotes.html> <http://releases.llvm.org/4.0.0/tools/clang/docs/ReleaseNotes.html> <http://releases.llvm.org/4.0.0/tools/lld/docs/ReleaseNotes.html> Thanks to Ed Maste, Jan Beich, Antoine Brodin and Eric Fiselier for their help. Relnotes: yes Exp-run: antoine PR: 215969, 216008 MFC r314708: For now, revert r287232 from upstream llvm trunk (by Daniil Fukalov): [SCEV] limit recursion depth of CompareSCEVComplexity Summary: CompareSCEVComplexity goes too deep (50+ on a quite a big unrolled loop) and runs almost infinite time. Added cache of "equal" SCEV pairs to earlier cutoff of further estimation. Recursion depth limit was also introduced as a parameter. Reviewers: sanjoy Subscribers: mzolotukhin, tstellarAMD, llvm-commits Differential Revision: https://reviews.llvm.org/D26389 This commit is the cause of excessive compile times on skein_block.c (and possibly other files) during kernel builds on amd64. We never saw the problematic behavior described in this upstream commit, so for now it is better to revert it. An upstream bug has been filed here: https://bugs.llvm.org/show_bug.cgi?id=32142 Reported by: mjg MFC r314795: Reapply r287232 from upstream llvm trunk (by Daniil Fukalov): [SCEV] limit recursion depth of CompareSCEVComplexity Summary: CompareSCEVComplexity goes too deep (50+ on a quite a big unrolled loop) and runs almost infinite time. Added cache of "equal" SCEV pairs to earlier cutoff of further estimation. Recursion depth limit was also introduced as a parameter. Reviewers: sanjoy Subscribers: mzolotukhin, tstellarAMD, llvm-commits Differential Revision: https://reviews.llvm.org/D26389 Pull in r296992 from upstream llvm trunk (by Sanjoy Das): [SCEV] Decrease the recursion threshold for CompareValueComplexity Fixes PR32142. r287232 accidentally increased the recursion threshold for CompareValueComplexity from 2 to 32. This change reverses that change by introducing a separate flag for CompareValueComplexity's threshold. The latter revision fixes the excessive compile times for skein_block.c. MFC r314907 | mmel | 2017-03-08 12:40:27 +0100 (Wed, 08 Mar 2017) | 7 lines Unbreak ARMv6 world. The new compiler_rt library imported with clang 4.0.0 have several fatal issues (non-functional __udivsi3 for example) with ARM specific instrict functions. As temporary workaround, until upstream solve these problems, disable all thumb[1][2] related feature. MFC r315016: Update clang, llvm, lld, lldb, compiler-rt and libc++ to 4.0.0 release. We were already very close to the last release candidate, so this is a pretty minor update. Relnotes: yes MFC r316005: Revert r314907, and pull in r298713 from upstream compiler-rt trunk (by Weiming Zhao): builtins: Select correct code fragments when compiling for Thumb1/Thum2/ARM ISA. Summary: Value of __ARM_ARCH_ISA_THUMB isn't based on the actual compilation mode (-mthumb, -marm), it reflect's capability of given CPU. Due to this: - use __tbumb__ and __thumb2__ insteand of __ARM_ARCH_ISA_THUMB - use '.thumb' directive consistently in all affected files - decorate all thumb functions using DEFINE_COMPILERRT_THUMB_FUNCTION() --------- Note: This patch doesn't fix broken Thumb1 variant of __udivsi3 ! Reviewers: weimingz, rengolin, compnerd Subscribers: aemerson, dim Differential Revision: https://reviews.llvm.org/D30938 Discussed with: mmel
Diffstat (limited to 'contrib/llvm/lib/Transforms/Utils')
-rw-r--r--contrib/llvm/lib/Transforms/Utils/ASanStackFrameLayout.cpp100
-rw-r--r--contrib/llvm/lib/Transforms/Utils/AddDiscriminators.cpp52
-rw-r--r--contrib/llvm/lib/Transforms/Utils/BreakCriticalEdges.cpp18
-rw-r--r--contrib/llvm/lib/Transforms/Utils/BuildLibCalls.cpp1
-rw-r--r--contrib/llvm/lib/Transforms/Utils/BypassSlowDivision.cpp35
-rw-r--r--contrib/llvm/lib/Transforms/Utils/CloneModule.cpp5
-rw-r--r--contrib/llvm/lib/Transforms/Utils/CmpInstAnalysis.cpp76
-rw-r--r--contrib/llvm/lib/Transforms/Utils/CodeExtractor.cpp147
-rw-r--r--contrib/llvm/lib/Transforms/Utils/CtorUtils.cpp10
-rw-r--r--contrib/llvm/lib/Transforms/Utils/EscapeEnumerator.cpp96
-rw-r--r--contrib/llvm/lib/Transforms/Utils/Evaluator.cpp18
-rw-r--r--contrib/llvm/lib/Transforms/Utils/FlattenCFG.cpp9
-rw-r--r--contrib/llvm/lib/Transforms/Utils/FunctionComparator.cpp919
-rw-r--r--contrib/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp93
-rw-r--r--contrib/llvm/lib/Transforms/Utils/GlobalStatus.cpp7
-rw-r--r--contrib/llvm/lib/Transforms/Utils/ImportedFunctionsInliningStatistics.cpp203
-rw-r--r--contrib/llvm/lib/Transforms/Utils/InlineFunction.cpp216
-rw-r--r--contrib/llvm/lib/Transforms/Utils/LCSSA.cpp59
-rw-r--r--contrib/llvm/lib/Transforms/Utils/LibCallsShrinkWrap.cpp571
-rw-r--r--contrib/llvm/lib/Transforms/Utils/Local.cpp180
-rw-r--r--contrib/llvm/lib/Transforms/Utils/LoopSimplify.cpp55
-rw-r--r--contrib/llvm/lib/Transforms/Utils/LoopUnroll.cpp198
-rw-r--r--contrib/llvm/lib/Transforms/Utils/LoopUnrollPeel.cpp414
-rw-r--r--contrib/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp40
-rw-r--r--contrib/llvm/lib/Transforms/Utils/LoopUtils.cpp174
-rw-r--r--contrib/llvm/lib/Transforms/Utils/LoopVersioning.cpp6
-rw-r--r--contrib/llvm/lib/Transforms/Utils/LowerInvoke.cpp49
-rw-r--r--contrib/llvm/lib/Transforms/Utils/LowerSwitch.cpp8
-rw-r--r--contrib/llvm/lib/Transforms/Utils/Mem2Reg.cpp2
-rw-r--r--contrib/llvm/lib/Transforms/Utils/MemorySSA.cpp1926
-rw-r--r--contrib/llvm/lib/Transforms/Utils/ModuleUtils.cpp104
-rw-r--r--contrib/llvm/lib/Transforms/Utils/NameAnonGlobals.cpp (renamed from contrib/llvm/lib/Transforms/Utils/NameAnonFunctions.cpp)63
-rw-r--r--contrib/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp2
-rw-r--r--contrib/llvm/lib/Transforms/Utils/SSAUpdater.cpp2
-rw-r--r--contrib/llvm/lib/Transforms/Utils/SimplifyCFG.cpp839
-rw-r--r--contrib/llvm/lib/Transforms/Utils/SimplifyInstructions.cpp41
-rw-r--r--contrib/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp148
-rw-r--r--contrib/llvm/lib/Transforms/Utils/StripGCRelocates.cpp80
-rw-r--r--contrib/llvm/lib/Transforms/Utils/StripNonLineTableDebugInfo.cpp42
-rw-r--r--contrib/llvm/lib/Transforms/Utils/SymbolRewriter.cpp80
-rw-r--r--contrib/llvm/lib/Transforms/Utils/Utils.cpp7
-rw-r--r--contrib/llvm/lib/Transforms/Utils/ValueMapper.cpp22
42 files changed, 5845 insertions, 1272 deletions
diff --git a/contrib/llvm/lib/Transforms/Utils/ASanStackFrameLayout.cpp b/contrib/llvm/lib/Transforms/Utils/ASanStackFrameLayout.cpp
index 7e50d4b..df9d5da 100644
--- a/contrib/llvm/lib/Transforms/Utils/ASanStackFrameLayout.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/ASanStackFrameLayout.cpp
@@ -12,7 +12,9 @@
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Utils/ASanStackFrameLayout.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/IR/DebugInfo.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@@ -47,64 +49,102 @@ static size_t VarAndRedzoneSize(size_t Size, size_t Alignment) {
return alignTo(Res, Alignment);
}
-void
+ASanStackFrameLayout
ComputeASanStackFrameLayout(SmallVectorImpl<ASanStackVariableDescription> &Vars,
- size_t Granularity, size_t MinHeaderSize,
- ASanStackFrameLayout *Layout) {
+ size_t Granularity, size_t MinHeaderSize) {
assert(Granularity >= 8 && Granularity <= 64 &&
(Granularity & (Granularity - 1)) == 0);
assert(MinHeaderSize >= 16 && (MinHeaderSize & (MinHeaderSize - 1)) == 0 &&
MinHeaderSize >= Granularity);
- size_t NumVars = Vars.size();
+ const size_t NumVars = Vars.size();
assert(NumVars > 0);
for (size_t i = 0; i < NumVars; i++)
Vars[i].Alignment = std::max(Vars[i].Alignment, kMinAlignment);
std::stable_sort(Vars.begin(), Vars.end(), CompareVars);
- SmallString<2048> StackDescriptionStorage;
- raw_svector_ostream StackDescription(StackDescriptionStorage);
- StackDescription << NumVars;
- Layout->FrameAlignment = std::max(Granularity, Vars[0].Alignment);
- SmallVector<uint8_t, 64> &SB(Layout->ShadowBytes);
- SB.clear();
+
+ ASanStackFrameLayout Layout;
+ Layout.Granularity = Granularity;
+ Layout.FrameAlignment = std::max(Granularity, Vars[0].Alignment);
size_t Offset = std::max(std::max(MinHeaderSize, Granularity),
Vars[0].Alignment);
assert((Offset % Granularity) == 0);
- SB.insert(SB.end(), Offset / Granularity, kAsanStackLeftRedzoneMagic);
for (size_t i = 0; i < NumVars; i++) {
bool IsLast = i == NumVars - 1;
size_t Alignment = std::max(Granularity, Vars[i].Alignment);
(void)Alignment; // Used only in asserts.
size_t Size = Vars[i].Size;
- const char *Name = Vars[i].Name;
assert((Alignment & (Alignment - 1)) == 0);
- assert(Layout->FrameAlignment >= Alignment);
+ assert(Layout.FrameAlignment >= Alignment);
assert((Offset % Alignment) == 0);
assert(Size > 0);
- StackDescription << " " << Offset << " " << Size << " " << strlen(Name)
- << " " << Name;
size_t NextAlignment = IsLast ? Granularity
: std::max(Granularity, Vars[i + 1].Alignment);
- size_t SizeWithRedzone = VarAndRedzoneSize(Vars[i].Size, NextAlignment);
- SB.insert(SB.end(), Size / Granularity, 0);
- if (Size % Granularity)
- SB.insert(SB.end(), Size % Granularity);
- SB.insert(SB.end(), (SizeWithRedzone - Size) / Granularity,
- IsLast ? kAsanStackRightRedzoneMagic
- : kAsanStackMidRedzoneMagic);
+ size_t SizeWithRedzone = VarAndRedzoneSize(Size, NextAlignment);
Vars[i].Offset = Offset;
Offset += SizeWithRedzone;
}
if (Offset % MinHeaderSize) {
- size_t ExtraRedzone = MinHeaderSize - (Offset % MinHeaderSize);
- SB.insert(SB.end(), ExtraRedzone / Granularity,
- kAsanStackRightRedzoneMagic);
- Offset += ExtraRedzone;
+ Offset += MinHeaderSize - (Offset % MinHeaderSize);
+ }
+ Layout.FrameSize = Offset;
+ assert((Layout.FrameSize % MinHeaderSize) == 0);
+ return Layout;
+}
+
+SmallString<64> ComputeASanStackFrameDescription(
+ const SmallVectorImpl<ASanStackVariableDescription> &Vars) {
+ SmallString<2048> StackDescriptionStorage;
+ raw_svector_ostream StackDescription(StackDescriptionStorage);
+ StackDescription << Vars.size();
+
+ for (const auto &Var : Vars) {
+ std::string Name = Var.Name;
+ if (Var.Line) {
+ Name += ":";
+ Name += to_string(Var.Line);
+ }
+ StackDescription << " " << Var.Offset << " " << Var.Size << " "
+ << Name.size() << " " << Name;
}
- Layout->DescriptionString = StackDescription.str();
- Layout->FrameSize = Offset;
- assert((Layout->FrameSize % MinHeaderSize) == 0);
- assert(Layout->FrameSize / Granularity == Layout->ShadowBytes.size());
+ return StackDescription.str();
+}
+
+SmallVector<uint8_t, 64>
+GetShadowBytes(const SmallVectorImpl<ASanStackVariableDescription> &Vars,
+ const ASanStackFrameLayout &Layout) {
+ assert(Vars.size() > 0);
+ SmallVector<uint8_t, 64> SB;
+ SB.clear();
+ const size_t Granularity = Layout.Granularity;
+ SB.resize(Vars[0].Offset / Granularity, kAsanStackLeftRedzoneMagic);
+ for (const auto &Var : Vars) {
+ SB.resize(Var.Offset / Granularity, kAsanStackMidRedzoneMagic);
+
+ SB.resize(SB.size() + Var.Size / Granularity, 0);
+ if (Var.Size % Granularity)
+ SB.push_back(Var.Size % Granularity);
+ }
+ SB.resize(Layout.FrameSize / Granularity, kAsanStackRightRedzoneMagic);
+ return SB;
+}
+
+SmallVector<uint8_t, 64> GetShadowBytesAfterScope(
+ const SmallVectorImpl<ASanStackVariableDescription> &Vars,
+ const ASanStackFrameLayout &Layout) {
+ SmallVector<uint8_t, 64> SB = GetShadowBytes(Vars, Layout);
+ const size_t Granularity = Layout.Granularity;
+
+ for (const auto &Var : Vars) {
+ assert(Var.LifetimeSize <= Var.Size);
+ const size_t LifetimeShadowSize =
+ (Var.LifetimeSize + Granularity - 1) / Granularity;
+ const size_t Offset = Var.Offset / Granularity;
+ std::fill(SB.begin() + Offset, SB.begin() + Offset + LifetimeShadowSize,
+ kAsanStackUseAfterScopeMagic);
+ }
+
+ return SB;
}
} // llvm namespace
diff --git a/contrib/llvm/lib/Transforms/Utils/AddDiscriminators.cpp b/contrib/llvm/lib/Transforms/Utils/AddDiscriminators.cpp
index d034905..2e95926 100644
--- a/contrib/llvm/lib/Transforms/Utils/AddDiscriminators.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/AddDiscriminators.cpp
@@ -57,12 +57,10 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constants.h"
-#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/Module.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
@@ -159,20 +157,14 @@ static bool addDiscriminators(Function &F) {
// If the function has debug information, but the user has disabled
// discriminators, do nothing.
// Simlarly, if the function has no debug info, do nothing.
- // Finally, if this module is built with dwarf versions earlier than 4,
- // do nothing (discriminator support is a DWARF 4 feature).
- if (NoDiscriminators || !F.getSubprogram() ||
- F.getParent()->getDwarfVersion() < 4)
+ if (NoDiscriminators || !F.getSubprogram())
return false;
bool Changed = false;
- Module *M = F.getParent();
- LLVMContext &Ctx = M->getContext();
- DIBuilder Builder(*M, /*AllowUnresolved*/ false);
typedef std::pair<StringRef, unsigned> Location;
- typedef DenseMap<const BasicBlock *, Metadata *> BBScopeMap;
- typedef DenseMap<Location, BBScopeMap> LocationBBMap;
+ typedef DenseSet<const BasicBlock *> BBSet;
+ typedef DenseMap<Location, BBSet> LocationBBMap;
typedef DenseMap<Location, unsigned> LocationDiscriminatorMap;
typedef DenseSet<Location> LocationSet;
@@ -184,32 +176,25 @@ static bool addDiscriminators(Function &F) {
// discriminator for this instruction.
for (BasicBlock &B : F) {
for (auto &I : B.getInstList()) {
- if (isa<DbgInfoIntrinsic>(&I))
+ if (isa<IntrinsicInst>(&I))
continue;
const DILocation *DIL = I.getDebugLoc();
if (!DIL)
continue;
Location L = std::make_pair(DIL->getFilename(), DIL->getLine());
auto &BBMap = LBM[L];
- auto R = BBMap.insert(std::make_pair(&B, (Metadata *)nullptr));
+ auto R = BBMap.insert(&B);
if (BBMap.size() == 1)
continue;
- bool InsertSuccess = R.second;
- Metadata *&NewScope = R.first->second;
- // If we could insert a different block in the same location, a
+ // If we could insert more than one block with the same line+file, a
// discriminator is needed to distinguish both instructions.
- if (InsertSuccess) {
- auto *Scope = DIL->getScope();
- auto *File =
- Builder.createFile(DIL->getFilename(), Scope->getDirectory());
- NewScope = Builder.createLexicalBlockFile(Scope, File, ++LDM[L]);
- }
- I.setDebugLoc(DILocation::get(Ctx, DIL->getLine(), DIL->getColumn(),
- NewScope, DIL->getInlinedAt()));
+ // Only the lowest 7 bits are used to represent a discriminator to fit
+ // it in 1 byte ULEB128 representation.
+ unsigned Discriminator = (R.second ? ++LDM[L] : LDM[L]) & 0x7f;
+ I.setDebugLoc(DIL->cloneWithDiscriminator(Discriminator));
DEBUG(dbgs() << DIL->getFilename() << ":" << DIL->getLine() << ":"
- << DIL->getColumn() << ":"
- << dyn_cast<DILexicalBlockFile>(NewScope)->getDiscriminator()
- << I << "\n");
+ << DIL->getColumn() << ":" << Discriminator << " " << I
+ << "\n");
Changed = true;
}
}
@@ -222,7 +207,7 @@ static bool addDiscriminators(Function &F) {
LocationSet CallLocations;
for (auto &I : B.getInstList()) {
CallInst *Current = dyn_cast<CallInst>(&I);
- if (!Current || isa<DbgInfoIntrinsic>(&I))
+ if (!Current || isa<IntrinsicInst>(&I))
continue;
DILocation *CurrentDIL = Current->getDebugLoc();
@@ -231,13 +216,8 @@ static bool addDiscriminators(Function &F) {
Location L =
std::make_pair(CurrentDIL->getFilename(), CurrentDIL->getLine());
if (!CallLocations.insert(L).second) {
- auto *Scope = CurrentDIL->getScope();
- auto *File = Builder.createFile(CurrentDIL->getFilename(),
- Scope->getDirectory());
- auto *NewScope = Builder.createLexicalBlockFile(Scope, File, ++LDM[L]);
- Current->setDebugLoc(DILocation::get(Ctx, CurrentDIL->getLine(),
- CurrentDIL->getColumn(), NewScope,
- CurrentDIL->getInlinedAt()));
+ Current->setDebugLoc(
+ CurrentDIL->cloneWithDiscriminator((++LDM[L]) & 0x7f));
Changed = true;
}
}
@@ -249,7 +229,7 @@ bool AddDiscriminatorsLegacyPass::runOnFunction(Function &F) {
return addDiscriminators(F);
}
PreservedAnalyses AddDiscriminatorsPass::run(Function &F,
- AnalysisManager<Function> &AM) {
+ FunctionAnalysisManager &AM) {
if (!addDiscriminators(F))
return PreservedAnalyses::all();
diff --git a/contrib/llvm/lib/Transforms/Utils/BreakCriticalEdges.cpp b/contrib/llvm/lib/Transforms/Utils/BreakCriticalEdges.cpp
index 49b646a..175cbd2 100644
--- a/contrib/llvm/lib/Transforms/Utils/BreakCriticalEdges.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/BreakCriticalEdges.cpp
@@ -15,7 +15,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Utils/BreakCriticalEdges.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
@@ -23,10 +23,10 @@
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/Dominators.h"
-#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
using namespace llvm;
@@ -72,6 +72,20 @@ FunctionPass *llvm::createBreakCriticalEdgesPass() {
return new BreakCriticalEdges();
}
+PreservedAnalyses BreakCriticalEdgesPass::run(Function &F,
+ FunctionAnalysisManager &AM) {
+ auto *DT = AM.getCachedResult<DominatorTreeAnalysis>(F);
+ auto *LI = AM.getCachedResult<LoopAnalysis>(F);
+ unsigned N = SplitAllCriticalEdges(F, CriticalEdgeSplittingOptions(DT, LI));
+ NumBroken += N;
+ if (N == 0)
+ return PreservedAnalyses::all();
+ PreservedAnalyses PA;
+ PA.preserve<DominatorTreeAnalysis>();
+ PA.preserve<LoopAnalysis>();
+ return PA;
+}
+
//===----------------------------------------------------------------------===//
// Implementation of the external critical edge manipulation functions
//===----------------------------------------------------------------------===//
diff --git a/contrib/llvm/lib/Transforms/Utils/BuildLibCalls.cpp b/contrib/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
index f4260a9..e61b04f 100644
--- a/contrib/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
@@ -250,6 +250,7 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
Changed |= setDoesNotCapture(F, 2);
return Changed;
case LibFunc::memcpy:
+ case LibFunc::mempcpy:
case LibFunc::memccpy:
case LibFunc::memmove:
Changed |= setDoesNotThrow(F);
diff --git a/contrib/llvm/lib/Transforms/Utils/BypassSlowDivision.cpp b/contrib/llvm/lib/Transforms/Utils/BypassSlowDivision.cpp
index 42287d3..bc2cef2 100644
--- a/contrib/llvm/lib/Transforms/Utils/BypassSlowDivision.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/BypassSlowDivision.cpp
@@ -20,6 +20,7 @@
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instructions.h"
+#include "llvm/Transforms/Utils/Local.h"
using namespace llvm;
@@ -82,13 +83,17 @@ static bool insertFastDiv(Instruction *I, IntegerType *BypassType,
Value *Dividend = I->getOperand(0);
Value *Divisor = I->getOperand(1);
- if (isa<ConstantInt>(Divisor) ||
- (isa<ConstantInt>(Dividend) && isa<ConstantInt>(Divisor))) {
- // Operations with immediate values should have
- // been solved and replaced during compile time.
+ if (isa<ConstantInt>(Divisor)) {
+ // Division by a constant should have been been solved and replaced earlier
+ // in the pipeline.
return false;
}
+ // If the numerator is a constant, bail if it doesn't fit into BypassType.
+ if (ConstantInt *ConstDividend = dyn_cast<ConstantInt>(Dividend))
+ if (ConstDividend->getValue().getActiveBits() > BypassType->getBitWidth())
+ return false;
+
// Basic Block is split before divide
BasicBlock *MainBB = &*I->getParent();
BasicBlock *SuccessorBB = MainBB->splitBasicBlock(I);
@@ -120,8 +125,7 @@ static bool insertFastDiv(Instruction *I, IntegerType *BypassType,
BypassType);
// udiv/urem because optimization only handles positive numbers
- Value *ShortQuotientV = FastBuilder.CreateExactUDiv(ShortDividendV,
- ShortDivisorV);
+ Value *ShortQuotientV = FastBuilder.CreateUDiv(ShortDividendV, ShortDivisorV);
Value *ShortRemainderV = FastBuilder.CreateURem(ShortDividendV,
ShortDivisorV);
Value *FastQuotientV = FastBuilder.CreateCast(Instruction::ZExt,
@@ -151,7 +155,17 @@ static bool insertFastDiv(Instruction *I, IntegerType *BypassType,
// Combine operands into a single value with OR for value testing below
MainBB->getInstList().back().eraseFromParent();
IRBuilder<> MainBuilder(MainBB, MainBB->end());
- Value *OrV = MainBuilder.CreateOr(Dividend, Divisor);
+
+ // We should have bailed out above if the divisor is a constant, but the
+ // dividend may still be a constant. Set OrV to our non-constant operands
+ // OR'ed together.
+ assert(!isa<ConstantInt>(Divisor));
+
+ Value *OrV;
+ if (!isa<ConstantInt>(Dividend))
+ OrV = MainBuilder.CreateOr(Dividend, Divisor);
+ else
+ OrV = Divisor;
// BitMask is inverted to check if the operands are
// larger than the bypass type
@@ -247,5 +261,12 @@ bool llvm::bypassSlowDivision(
MadeChange |= reuseOrInsertFastDiv(I, BT, UseDivOp, UseSignedOp, DivCache);
}
+ // Above we eagerly create divs and rems, as pairs, so that we can efficiently
+ // create divrem machine instructions. Now erase any unused divs / rems so we
+ // don't leave extra instructions sitting around.
+ for (auto &KV : DivCache)
+ for (Instruction *Phi : {KV.second.Quotient, KV.second.Remainder})
+ RecursivelyDeleteTriviallyDeadInstructions(Phi);
+
return MadeChange;
}
diff --git a/contrib/llvm/lib/Transforms/Utils/CloneModule.cpp b/contrib/llvm/lib/Transforms/Utils/CloneModule.cpp
index 17e34c4..7ebeb61 100644
--- a/contrib/llvm/lib/Transforms/Utils/CloneModule.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/CloneModule.cpp
@@ -119,6 +119,11 @@ std::unique_ptr<Module> llvm::CloneModule(
}
if (I->hasInitializer())
GV->setInitializer(MapValue(I->getInitializer(), VMap));
+
+ SmallVector<std::pair<unsigned, MDNode *>, 1> MDs;
+ I->getAllMetadata(MDs);
+ for (auto MD : MDs)
+ GV->addMetadata(MD.first, *MapMetadata(MD.second, VMap));
}
// Similarly, copy over function bodies now...
diff --git a/contrib/llvm/lib/Transforms/Utils/CmpInstAnalysis.cpp b/contrib/llvm/lib/Transforms/Utils/CmpInstAnalysis.cpp
index 3b15a0a..60ae374 100644
--- a/contrib/llvm/lib/Transforms/Utils/CmpInstAnalysis.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/CmpInstAnalysis.cpp
@@ -18,29 +18,6 @@
using namespace llvm;
-/// getICmpCode - Encode a icmp predicate into a three bit mask. These bits
-/// are carefully arranged to allow folding of expressions such as:
-///
-/// (A < B) | (A > B) --> (A != B)
-///
-/// Note that this is only valid if the first and second predicates have the
-/// same sign. Is illegal to do: (A u< B) | (A s> B)
-///
-/// Three bits are used to represent the condition, as follows:
-/// 0 A > B
-/// 1 A == B
-/// 2 A < B
-///
-/// <=> Value Definition
-/// 000 0 Always false
-/// 001 1 A > B
-/// 010 2 A == B
-/// 011 3 A >= B
-/// 100 4 A < B
-/// 101 5 A != B
-/// 110 6 A <= B
-/// 111 7 Always true
-///
unsigned llvm::getICmpCode(const ICmpInst *ICI, bool InvertPred) {
ICmpInst::Predicate Pred = InvertPred ? ICI->getInversePredicate()
: ICI->getPredicate();
@@ -62,13 +39,6 @@ unsigned llvm::getICmpCode(const ICmpInst *ICI, bool InvertPred) {
}
}
-/// getICmpValue - This is the complement of getICmpCode, which turns an
-/// opcode and two operands into either a constant true or false, or the
-/// predicate for a new ICmp instruction. The sign is passed in to determine
-/// which kind of predicate to use in the new icmp instruction.
-/// Non-NULL return value will be a true or false constant.
-/// NULL return means a new ICmp is needed. The predicate for which is
-/// output in NewICmpPred.
Value *llvm::getICmpValue(bool Sign, unsigned Code, Value *LHS, Value *RHS,
CmpInst::Predicate &NewICmpPred) {
switch (Code) {
@@ -87,10 +57,52 @@ Value *llvm::getICmpValue(bool Sign, unsigned Code, Value *LHS, Value *RHS,
return nullptr;
}
-/// PredicatesFoldable - Return true if both predicates match sign or if at
-/// least one of them is an equality comparison (which is signless).
bool llvm::PredicatesFoldable(ICmpInst::Predicate p1, ICmpInst::Predicate p2) {
return (CmpInst::isSigned(p1) == CmpInst::isSigned(p2)) ||
(CmpInst::isSigned(p1) && ICmpInst::isEquality(p2)) ||
(CmpInst::isSigned(p2) && ICmpInst::isEquality(p1));
}
+
+bool llvm::decomposeBitTestICmp(const ICmpInst *I, CmpInst::Predicate &Pred,
+ Value *&X, Value *&Y, Value *&Z) {
+ ConstantInt *C = dyn_cast<ConstantInt>(I->getOperand(1));
+ if (!C)
+ return false;
+
+ switch (I->getPredicate()) {
+ default:
+ return false;
+ case ICmpInst::ICMP_SLT:
+ // X < 0 is equivalent to (X & SignBit) != 0.
+ if (!C->isZero())
+ return false;
+ Y = ConstantInt::get(I->getContext(), APInt::getSignBit(C->getBitWidth()));
+ Pred = ICmpInst::ICMP_NE;
+ break;
+ case ICmpInst::ICMP_SGT:
+ // X > -1 is equivalent to (X & SignBit) == 0.
+ if (!C->isAllOnesValue())
+ return false;
+ Y = ConstantInt::get(I->getContext(), APInt::getSignBit(C->getBitWidth()));
+ Pred = ICmpInst::ICMP_EQ;
+ break;
+ case ICmpInst::ICMP_ULT:
+ // X <u 2^n is equivalent to (X & ~(2^n-1)) == 0.
+ if (!C->getValue().isPowerOf2())
+ return false;
+ Y = ConstantInt::get(I->getContext(), -C->getValue());
+ Pred = ICmpInst::ICMP_EQ;
+ break;
+ case ICmpInst::ICMP_UGT:
+ // X >u 2^n-1 is equivalent to (X & ~(2^n-1)) != 0.
+ if (!(C->getValue() + 1).isPowerOf2())
+ return false;
+ Y = ConstantInt::get(I->getContext(), ~C->getValue());
+ Pred = ICmpInst::ICMP_NE;
+ break;
+ }
+
+ X = I->getOperand(0);
+ Z = ConstantInt::getNullValue(C->getType());
+ return true;
+}
diff --git a/contrib/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/contrib/llvm/lib/Transforms/Utils/CodeExtractor.cpp
index 9f2181f..c514c9c 100644
--- a/contrib/llvm/lib/Transforms/Utils/CodeExtractor.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/CodeExtractor.cpp
@@ -17,6 +17,9 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/Analysis/BlockFrequencyInfo.h"
+#include "llvm/Analysis/BlockFrequencyInfoImpl.h"
+#include "llvm/Analysis/BranchProbabilityInfo.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/RegionInfo.h"
#include "llvm/Analysis/RegionIterator.h"
@@ -26,9 +29,11 @@
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Pass.h"
+#include "llvm/Support/BlockFrequency.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
@@ -49,7 +54,7 @@ AggregateArgsOpt("aggregate-extracted-args", cl::Hidden,
cl::desc("Aggregate arguments to code-extracted functions"));
/// \brief Test whether a block is valid for extraction.
-static bool isBlockValidForExtraction(const BasicBlock &BB) {
+bool CodeExtractor::isBlockValidForExtraction(const BasicBlock &BB) {
// Landing pads must be in the function where they were inserted for cleanup.
if (BB.isEHPad())
return false;
@@ -81,7 +86,7 @@ static SetVector<BasicBlock *> buildExtractionBlockSet(IteratorT BBBegin,
if (!Result.insert(*BBBegin))
llvm_unreachable("Repeated basic blocks in extraction input");
- if (!isBlockValidForExtraction(**BBBegin)) {
+ if (!CodeExtractor::isBlockValidForExtraction(**BBBegin)) {
Result.clear();
return Result;
}
@@ -119,23 +124,30 @@ buildExtractionBlockSet(const RegionNode &RN) {
return buildExtractionBlockSet(R.block_begin(), R.block_end());
}
-CodeExtractor::CodeExtractor(BasicBlock *BB, bool AggregateArgs)
- : DT(nullptr), AggregateArgs(AggregateArgs||AggregateArgsOpt),
- Blocks(buildExtractionBlockSet(BB)), NumExitBlocks(~0U) {}
+CodeExtractor::CodeExtractor(BasicBlock *BB, bool AggregateArgs,
+ BlockFrequencyInfo *BFI,
+ BranchProbabilityInfo *BPI)
+ : DT(nullptr), AggregateArgs(AggregateArgs || AggregateArgsOpt), BFI(BFI),
+ BPI(BPI), Blocks(buildExtractionBlockSet(BB)), NumExitBlocks(~0U) {}
CodeExtractor::CodeExtractor(ArrayRef<BasicBlock *> BBs, DominatorTree *DT,
- bool AggregateArgs)
- : DT(DT), AggregateArgs(AggregateArgs||AggregateArgsOpt),
- Blocks(buildExtractionBlockSet(BBs)), NumExitBlocks(~0U) {}
-
-CodeExtractor::CodeExtractor(DominatorTree &DT, Loop &L, bool AggregateArgs)
- : DT(&DT), AggregateArgs(AggregateArgs||AggregateArgsOpt),
- Blocks(buildExtractionBlockSet(L.getBlocks())), NumExitBlocks(~0U) {}
+ bool AggregateArgs, BlockFrequencyInfo *BFI,
+ BranchProbabilityInfo *BPI)
+ : DT(DT), AggregateArgs(AggregateArgs || AggregateArgsOpt), BFI(BFI),
+ BPI(BPI), Blocks(buildExtractionBlockSet(BBs)), NumExitBlocks(~0U) {}
+
+CodeExtractor::CodeExtractor(DominatorTree &DT, Loop &L, bool AggregateArgs,
+ BlockFrequencyInfo *BFI,
+ BranchProbabilityInfo *BPI)
+ : DT(&DT), AggregateArgs(AggregateArgs || AggregateArgsOpt), BFI(BFI),
+ BPI(BPI), Blocks(buildExtractionBlockSet(L.getBlocks())),
+ NumExitBlocks(~0U) {}
CodeExtractor::CodeExtractor(DominatorTree &DT, const RegionNode &RN,
- bool AggregateArgs)
- : DT(&DT), AggregateArgs(AggregateArgs||AggregateArgsOpt),
- Blocks(buildExtractionBlockSet(RN)), NumExitBlocks(~0U) {}
+ bool AggregateArgs, BlockFrequencyInfo *BFI,
+ BranchProbabilityInfo *BPI)
+ : DT(&DT), AggregateArgs(AggregateArgs || AggregateArgsOpt), BFI(BFI),
+ BPI(BPI), Blocks(buildExtractionBlockSet(RN)), NumExitBlocks(~0U) {}
/// definedInRegion - Return true if the specified value is defined in the
/// extracted region.
@@ -339,7 +351,22 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs,
// If the old function is no-throw, so is the new one.
if (oldFunction->doesNotThrow())
newFunction->setDoesNotThrow();
-
+
+ // Inherit the uwtable attribute if we need to.
+ if (oldFunction->hasUWTable())
+ newFunction->setHasUWTable();
+
+ // Inherit all of the target dependent attributes.
+ // (e.g. If the extracted region contains a call to an x86.sse
+ // instruction we need to make sure that the extracted region has the
+ // "target-features" attribute allowing it to be lowered.
+ // FIXME: This should be changed to check to see if a specific
+ // attribute can not be inherited.
+ AttributeSet OldFnAttrs = oldFunction->getAttributes().getFnAttributes();
+ AttrBuilder AB(OldFnAttrs, AttributeSet::FunctionIndex);
+ for (auto Attr : AB.td_attrs())
+ newFunction->addFnAttr(Attr.first, Attr.second);
+
newFunction->getBasicBlockList().push_back(newRootNode);
// Create an iterator to name all of the arguments we inserted.
@@ -672,6 +699,51 @@ void CodeExtractor::moveCodeToFunction(Function *newFunction) {
}
}
+void CodeExtractor::calculateNewCallTerminatorWeights(
+ BasicBlock *CodeReplacer,
+ DenseMap<BasicBlock *, BlockFrequency> &ExitWeights,
+ BranchProbabilityInfo *BPI) {
+ typedef BlockFrequencyInfoImplBase::Distribution Distribution;
+ typedef BlockFrequencyInfoImplBase::BlockNode BlockNode;
+
+ // Update the branch weights for the exit block.
+ TerminatorInst *TI = CodeReplacer->getTerminator();
+ SmallVector<unsigned, 8> BranchWeights(TI->getNumSuccessors(), 0);
+
+ // Block Frequency distribution with dummy node.
+ Distribution BranchDist;
+
+ // Add each of the frequencies of the successors.
+ for (unsigned i = 0, e = TI->getNumSuccessors(); i < e; ++i) {
+ BlockNode ExitNode(i);
+ uint64_t ExitFreq = ExitWeights[TI->getSuccessor(i)].getFrequency();
+ if (ExitFreq != 0)
+ BranchDist.addExit(ExitNode, ExitFreq);
+ else
+ BPI->setEdgeProbability(CodeReplacer, i, BranchProbability::getZero());
+ }
+
+ // Check for no total weight.
+ if (BranchDist.Total == 0)
+ return;
+
+ // Normalize the distribution so that they can fit in unsigned.
+ BranchDist.normalize();
+
+ // Create normalized branch weights and set the metadata.
+ for (unsigned I = 0, E = BranchDist.Weights.size(); I < E; ++I) {
+ const auto &Weight = BranchDist.Weights[I];
+
+ // Get the weight and update the current BFI.
+ BranchWeights[Weight.TargetNode.Index] = Weight.Amount;
+ BranchProbability BP(Weight.Amount, BranchDist.Total);
+ BPI->setEdgeProbability(CodeReplacer, Weight.TargetNode.Index, BP);
+ }
+ TI->setMetadata(
+ LLVMContext::MD_prof,
+ MDBuilder(TI->getContext()).createBranchWeights(BranchWeights));
+}
+
Function *CodeExtractor::extractCodeRegion() {
if (!isEligible())
return nullptr;
@@ -682,6 +754,19 @@ Function *CodeExtractor::extractCodeRegion() {
// block in the region.
BasicBlock *header = *Blocks.begin();
+ // Calculate the entry frequency of the new function before we change the root
+ // block.
+ BlockFrequency EntryFreq;
+ if (BFI) {
+ assert(BPI && "Both BPI and BFI are required to preserve profile info");
+ for (BasicBlock *Pred : predecessors(header)) {
+ if (Blocks.count(Pred))
+ continue;
+ EntryFreq +=
+ BFI->getBlockFreq(Pred) * BPI->getEdgeProbability(Pred, header);
+ }
+ }
+
// If we have to split PHI nodes or the entry block, do so now.
severSplitPHINodes(header);
@@ -705,12 +790,23 @@ Function *CodeExtractor::extractCodeRegion() {
// Find inputs to, outputs from the code region.
findInputsOutputs(inputs, outputs);
+ // Calculate the exit blocks for the extracted region and the total exit
+ // weights for each of those blocks.
+ DenseMap<BasicBlock *, BlockFrequency> ExitWeights;
SmallPtrSet<BasicBlock *, 1> ExitBlocks;
- for (BasicBlock *Block : Blocks)
+ for (BasicBlock *Block : Blocks) {
for (succ_iterator SI = succ_begin(Block), SE = succ_end(Block); SI != SE;
- ++SI)
- if (!Blocks.count(*SI))
+ ++SI) {
+ if (!Blocks.count(*SI)) {
+ // Update the branch weight for this successor.
+ if (BFI) {
+ BlockFrequency &BF = ExitWeights[*SI];
+ BF += BFI->getBlockFreq(Block) * BPI->getEdgeProbability(Block, *SI);
+ }
ExitBlocks.insert(*SI);
+ }
+ }
+ }
NumExitBlocks = ExitBlocks.size();
// Construct new function based on inputs/outputs & add allocas for all defs.
@@ -719,10 +815,23 @@ Function *CodeExtractor::extractCodeRegion() {
codeReplacer, oldFunction,
oldFunction->getParent());
+ // Update the entry count of the function.
+ if (BFI) {
+ Optional<uint64_t> EntryCount =
+ BFI->getProfileCountFromFreq(EntryFreq.getFrequency());
+ if (EntryCount.hasValue())
+ newFunction->setEntryCount(EntryCount.getValue());
+ BFI->setBlockFreq(codeReplacer, EntryFreq.getFrequency());
+ }
+
emitCallAndSwitchStatement(newFunction, codeReplacer, inputs, outputs);
moveCodeToFunction(newFunction);
+ // Update the branch weights for the exit block.
+ if (BFI && NumExitBlocks > 1)
+ calculateNewCallTerminatorWeights(codeReplacer, ExitWeights, BPI);
+
// Loop over all of the PHI nodes in the header block, and change any
// references to the old incoming edge to be the new incoming edge.
for (BasicBlock::iterator I = header->begin(); isa<PHINode>(I); ++I) {
diff --git a/contrib/llvm/lib/Transforms/Utils/CtorUtils.cpp b/contrib/llvm/lib/Transforms/Utils/CtorUtils.cpp
index b56ff68..6642a97 100644
--- a/contrib/llvm/lib/Transforms/Utils/CtorUtils.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/CtorUtils.cpp
@@ -71,8 +71,8 @@ std::vector<Function *> parseGlobalCtors(GlobalVariable *GV) {
ConstantArray *CA = cast<ConstantArray>(GV->getInitializer());
std::vector<Function *> Result;
Result.reserve(CA->getNumOperands());
- for (User::op_iterator i = CA->op_begin(), e = CA->op_end(); i != e; ++i) {
- ConstantStruct *CS = cast<ConstantStruct>(*i);
+ for (auto &V : CA->operands()) {
+ ConstantStruct *CS = cast<ConstantStruct>(V);
Result.push_back(dyn_cast<Function>(CS->getOperand(1)));
}
return Result;
@@ -94,10 +94,10 @@ GlobalVariable *findGlobalCtors(Module &M) {
return GV;
ConstantArray *CA = cast<ConstantArray>(GV->getInitializer());
- for (User::op_iterator i = CA->op_begin(), e = CA->op_end(); i != e; ++i) {
- if (isa<ConstantAggregateZero>(*i))
+ for (auto &V : CA->operands()) {
+ if (isa<ConstantAggregateZero>(V))
continue;
- ConstantStruct *CS = cast<ConstantStruct>(*i);
+ ConstantStruct *CS = cast<ConstantStruct>(V);
if (isa<ConstantPointerNull>(CS->getOperand(1)))
continue;
diff --git a/contrib/llvm/lib/Transforms/Utils/EscapeEnumerator.cpp b/contrib/llvm/lib/Transforms/Utils/EscapeEnumerator.cpp
new file mode 100644
index 0000000..8c23865
--- /dev/null
+++ b/contrib/llvm/lib/Transforms/Utils/EscapeEnumerator.cpp
@@ -0,0 +1,96 @@
+//===- EscapeEnumerator.cpp -----------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines a helper class that enumerates all possible exits from a function,
+// including exception handling.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/Utils/EscapeEnumerator.h"
+#include "llvm/Analysis/EHPersonalities.h"
+#include "llvm/IR/CallSite.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Transforms/Utils/Local.h"
+using namespace llvm;
+
+static Constant *getDefaultPersonalityFn(Module *M) {
+ LLVMContext &C = M->getContext();
+ Triple T(M->getTargetTriple());
+ EHPersonality Pers = getDefaultEHPersonality(T);
+ return M->getOrInsertFunction(getEHPersonalityName(Pers),
+ FunctionType::get(Type::getInt32Ty(C), true));
+}
+
+IRBuilder<> *EscapeEnumerator::Next() {
+ if (Done)
+ return nullptr;
+
+ // Find all 'return', 'resume', and 'unwind' instructions.
+ while (StateBB != StateE) {
+ BasicBlock *CurBB = &*StateBB++;
+
+ // Branches and invokes do not escape, only unwind, resume, and return
+ // do.
+ TerminatorInst *TI = CurBB->getTerminator();
+ if (!isa<ReturnInst>(TI) && !isa<ResumeInst>(TI))
+ continue;
+
+ Builder.SetInsertPoint(TI);
+ return &Builder;
+ }
+
+ Done = true;
+
+ if (!HandleExceptions)
+ return nullptr;
+
+ if (F.doesNotThrow())
+ return nullptr;
+
+ // Find all 'call' instructions that may throw.
+ SmallVector<Instruction *, 16> Calls;
+ for (BasicBlock &BB : F)
+ for (Instruction &II : BB)
+ if (CallInst *CI = dyn_cast<CallInst>(&II))
+ if (!CI->doesNotThrow())
+ Calls.push_back(CI);
+
+ if (Calls.empty())
+ return nullptr;
+
+ // Create a cleanup block.
+ LLVMContext &C = F.getContext();
+ BasicBlock *CleanupBB = BasicBlock::Create(C, CleanupBBName, &F);
+ Type *ExnTy =
+ StructType::get(Type::getInt8PtrTy(C), Type::getInt32Ty(C), nullptr);
+ if (!F.hasPersonalityFn()) {
+ Constant *PersFn = getDefaultPersonalityFn(F.getParent());
+ F.setPersonalityFn(PersFn);
+ }
+
+ if (isFuncletEHPersonality(classifyEHPersonality(F.getPersonalityFn()))) {
+ report_fatal_error("Funclet EH not supported");
+ }
+
+ LandingPadInst *LPad =
+ LandingPadInst::Create(ExnTy, 1, "cleanup.lpad", CleanupBB);
+ LPad->setCleanup(true);
+ ResumeInst *RI = ResumeInst::Create(LPad, CleanupBB);
+
+ // Transform the 'call' instructions into 'invoke's branching to the
+ // cleanup block. Go in reverse order to make prettier BB names.
+ SmallVector<Value *, 16> Args;
+ for (unsigned I = Calls.size(); I != 0;) {
+ CallInst *CI = cast<CallInst>(Calls[--I]);
+ changeToInvokeAndSplitBasicBlock(CI, CleanupBB);
+ }
+
+ Builder.SetInsertPoint(RI);
+ return &Builder;
+}
diff --git a/contrib/llvm/lib/Transforms/Utils/Evaluator.cpp b/contrib/llvm/lib/Transforms/Utils/Evaluator.cpp
index cd130ab..4adf175 100644
--- a/contrib/llvm/lib/Transforms/Utils/Evaluator.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/Evaluator.cpp
@@ -203,9 +203,9 @@ bool Evaluator::EvaluateBlock(BasicBlock::iterator CurInst,
return false; // no volatile/atomic accesses.
}
Constant *Ptr = getVal(SI->getOperand(1));
- if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ptr)) {
+ if (auto *FoldedPtr = ConstantFoldConstant(Ptr, DL, TLI)) {
DEBUG(dbgs() << "Folding constant ptr expression: " << *Ptr);
- Ptr = ConstantFoldConstantExpression(CE, DL, TLI);
+ Ptr = FoldedPtr;
DEBUG(dbgs() << "; To: " << *Ptr << "\n");
}
if (!isSimpleEnoughPointerToCommit(Ptr)) {
@@ -249,8 +249,8 @@ bool Evaluator::EvaluateBlock(BasicBlock::iterator CurInst,
Constant * const IdxList[] = {IdxZero, IdxZero};
Ptr = ConstantExpr::getGetElementPtr(nullptr, Ptr, IdxList);
- if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ptr))
- Ptr = ConstantFoldConstantExpression(CE, DL, TLI);
+ if (auto *FoldedPtr = ConstantFoldConstant(Ptr, DL, TLI))
+ Ptr = FoldedPtr;
// If we can't improve the situation by introspecting NewTy,
// we have to give up.
@@ -324,8 +324,8 @@ bool Evaluator::EvaluateBlock(BasicBlock::iterator CurInst,
}
Constant *Ptr = getVal(LI->getOperand(0));
- if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ptr)) {
- Ptr = ConstantFoldConstantExpression(CE, DL, TLI);
+ if (auto *FoldedPtr = ConstantFoldConstant(Ptr, DL, TLI)) {
+ Ptr = FoldedPtr;
DEBUG(dbgs() << "Found a constant pointer expression, constant "
"folding: " << *Ptr << "\n");
}
@@ -512,8 +512,8 @@ bool Evaluator::EvaluateBlock(BasicBlock::iterator CurInst,
}
if (!CurInst->use_empty()) {
- if (ConstantExpr *CE = dyn_cast<ConstantExpr>(InstResult))
- InstResult = ConstantFoldConstantExpression(CE, DL, TLI);
+ if (auto *FoldedInstResult = ConstantFoldConstant(InstResult, DL, TLI))
+ InstResult = FoldedInstResult;
setVal(&*CurInst, InstResult);
}
@@ -537,7 +537,7 @@ bool Evaluator::EvaluateFunction(Function *F, Constant *&RetVal,
const SmallVectorImpl<Constant*> &ActualArgs) {
// Check to see if this function is already executing (recursion). If so,
// bail out. TODO: we might want to accept limited recursion.
- if (std::find(CallStack.begin(), CallStack.end(), F) != CallStack.end())
+ if (is_contained(CallStack, F))
return false;
CallStack.push_back(F);
diff --git a/contrib/llvm/lib/Transforms/Utils/FlattenCFG.cpp b/contrib/llvm/lib/Transforms/Utils/FlattenCFG.cpp
index 492ae9f..7b96fbb 100644
--- a/contrib/llvm/lib/Transforms/Utils/FlattenCFG.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/FlattenCFG.cpp
@@ -463,19 +463,14 @@ bool FlattenCFGOpt::MergeIfRegion(BasicBlock *BB, IRBuilder<> &Builder) {
}
bool FlattenCFGOpt::run(BasicBlock *BB) {
- bool Changed = false;
assert(BB && BB->getParent() && "Block not embedded in function!");
assert(BB->getTerminator() && "Degenerate basic block encountered!");
IRBuilder<> Builder(BB);
- if (FlattenParallelAndOr(BB, Builder))
+ if (FlattenParallelAndOr(BB, Builder) || MergeIfRegion(BB, Builder))
return true;
-
- if (MergeIfRegion(BB, Builder))
- return true;
-
- return Changed;
+ return false;
}
/// FlattenCFG - This function is used to flatten a CFG. For
diff --git a/contrib/llvm/lib/Transforms/Utils/FunctionComparator.cpp b/contrib/llvm/lib/Transforms/Utils/FunctionComparator.cpp
new file mode 100644
index 0000000..81a7c4c
--- /dev/null
+++ b/contrib/llvm/lib/Transforms/Utils/FunctionComparator.cpp
@@ -0,0 +1,919 @@
+//===- FunctionComparator.h - Function Comparator -------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the FunctionComparator and GlobalNumberState classes
+// which are used by the MergeFunctions pass for comparing functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/Utils/FunctionComparator.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/IR/CallSite.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/InlineAsm.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "functioncomparator"
+
+int FunctionComparator::cmpNumbers(uint64_t L, uint64_t R) const {
+ if (L < R) return -1;
+ if (L > R) return 1;
+ return 0;
+}
+
+int FunctionComparator::cmpOrderings(AtomicOrdering L, AtomicOrdering R) const {
+ if ((int)L < (int)R) return -1;
+ if ((int)L > (int)R) return 1;
+ return 0;
+}
+
+int FunctionComparator::cmpAPInts(const APInt &L, const APInt &R) const {
+ if (int Res = cmpNumbers(L.getBitWidth(), R.getBitWidth()))
+ return Res;
+ if (L.ugt(R)) return 1;
+ if (R.ugt(L)) return -1;
+ return 0;
+}
+
+int FunctionComparator::cmpAPFloats(const APFloat &L, const APFloat &R) const {
+ // Floats are ordered first by semantics (i.e. float, double, half, etc.),
+ // then by value interpreted as a bitstring (aka APInt).
+ const fltSemantics &SL = L.getSemantics(), &SR = R.getSemantics();
+ if (int Res = cmpNumbers(APFloat::semanticsPrecision(SL),
+ APFloat::semanticsPrecision(SR)))
+ return Res;
+ if (int Res = cmpNumbers(APFloat::semanticsMaxExponent(SL),
+ APFloat::semanticsMaxExponent(SR)))
+ return Res;
+ if (int Res = cmpNumbers(APFloat::semanticsMinExponent(SL),
+ APFloat::semanticsMinExponent(SR)))
+ return Res;
+ if (int Res = cmpNumbers(APFloat::semanticsSizeInBits(SL),
+ APFloat::semanticsSizeInBits(SR)))
+ return Res;
+ return cmpAPInts(L.bitcastToAPInt(), R.bitcastToAPInt());
+}
+
+int FunctionComparator::cmpMem(StringRef L, StringRef R) const {
+ // Prevent heavy comparison, compare sizes first.
+ if (int Res = cmpNumbers(L.size(), R.size()))
+ return Res;
+
+ // Compare strings lexicographically only when it is necessary: only when
+ // strings are equal in size.
+ return L.compare(R);
+}
+
+int FunctionComparator::cmpAttrs(const AttributeSet L,
+ const AttributeSet R) const {
+ if (int Res = cmpNumbers(L.getNumSlots(), R.getNumSlots()))
+ return Res;
+
+ for (unsigned i = 0, e = L.getNumSlots(); i != e; ++i) {
+ AttributeSet::iterator LI = L.begin(i), LE = L.end(i), RI = R.begin(i),
+ RE = R.end(i);
+ for (; LI != LE && RI != RE; ++LI, ++RI) {
+ Attribute LA = *LI;
+ Attribute RA = *RI;
+ if (LA < RA)
+ return -1;
+ if (RA < LA)
+ return 1;
+ }
+ if (LI != LE)
+ return 1;
+ if (RI != RE)
+ return -1;
+ }
+ return 0;
+}
+
+int FunctionComparator::cmpRangeMetadata(const MDNode *L,
+ const MDNode *R) const {
+ if (L == R)
+ return 0;
+ if (!L)
+ return -1;
+ if (!R)
+ return 1;
+ // Range metadata is a sequence of numbers. Make sure they are the same
+ // sequence.
+ // TODO: Note that as this is metadata, it is possible to drop and/or merge
+ // this data when considering functions to merge. Thus this comparison would
+ // return 0 (i.e. equivalent), but merging would become more complicated
+ // because the ranges would need to be unioned. It is not likely that
+ // functions differ ONLY in this metadata if they are actually the same
+ // function semantically.
+ if (int Res = cmpNumbers(L->getNumOperands(), R->getNumOperands()))
+ return Res;
+ for (size_t I = 0; I < L->getNumOperands(); ++I) {
+ ConstantInt *LLow = mdconst::extract<ConstantInt>(L->getOperand(I));
+ ConstantInt *RLow = mdconst::extract<ConstantInt>(R->getOperand(I));
+ if (int Res = cmpAPInts(LLow->getValue(), RLow->getValue()))
+ return Res;
+ }
+ return 0;
+}
+
+int FunctionComparator::cmpOperandBundlesSchema(const Instruction *L,
+ const Instruction *R) const {
+ ImmutableCallSite LCS(L);
+ ImmutableCallSite RCS(R);
+
+ assert(LCS && RCS && "Must be calls or invokes!");
+ assert(LCS.isCall() == RCS.isCall() && "Can't compare otherwise!");
+
+ if (int Res =
+ cmpNumbers(LCS.getNumOperandBundles(), RCS.getNumOperandBundles()))
+ return Res;
+
+ for (unsigned i = 0, e = LCS.getNumOperandBundles(); i != e; ++i) {
+ auto OBL = LCS.getOperandBundleAt(i);
+ auto OBR = RCS.getOperandBundleAt(i);
+
+ if (int Res = OBL.getTagName().compare(OBR.getTagName()))
+ return Res;
+
+ if (int Res = cmpNumbers(OBL.Inputs.size(), OBR.Inputs.size()))
+ return Res;
+ }
+
+ return 0;
+}
+
+/// Constants comparison:
+/// 1. Check whether type of L constant could be losslessly bitcasted to R
+/// type.
+/// 2. Compare constant contents.
+/// For more details see declaration comments.
+int FunctionComparator::cmpConstants(const Constant *L,
+ const Constant *R) const {
+
+ Type *TyL = L->getType();
+ Type *TyR = R->getType();
+
+ // Check whether types are bitcastable. This part is just re-factored
+ // Type::canLosslesslyBitCastTo method, but instead of returning true/false,
+ // we also pack into result which type is "less" for us.
+ int TypesRes = cmpTypes(TyL, TyR);
+ if (TypesRes != 0) {
+ // Types are different, but check whether we can bitcast them.
+ if (!TyL->isFirstClassType()) {
+ if (TyR->isFirstClassType())
+ return -1;
+ // Neither TyL nor TyR are values of first class type. Return the result
+ // of comparing the types
+ return TypesRes;
+ }
+ if (!TyR->isFirstClassType()) {
+ if (TyL->isFirstClassType())
+ return 1;
+ return TypesRes;
+ }
+
+ // Vector -> Vector conversions are always lossless if the two vector types
+ // have the same size, otherwise not.
+ unsigned TyLWidth = 0;
+ unsigned TyRWidth = 0;
+
+ if (auto *VecTyL = dyn_cast<VectorType>(TyL))
+ TyLWidth = VecTyL->getBitWidth();
+ if (auto *VecTyR = dyn_cast<VectorType>(TyR))
+ TyRWidth = VecTyR->getBitWidth();
+
+ if (TyLWidth != TyRWidth)
+ return cmpNumbers(TyLWidth, TyRWidth);
+
+ // Zero bit-width means neither TyL nor TyR are vectors.
+ if (!TyLWidth) {
+ PointerType *PTyL = dyn_cast<PointerType>(TyL);
+ PointerType *PTyR = dyn_cast<PointerType>(TyR);
+ if (PTyL && PTyR) {
+ unsigned AddrSpaceL = PTyL->getAddressSpace();
+ unsigned AddrSpaceR = PTyR->getAddressSpace();
+ if (int Res = cmpNumbers(AddrSpaceL, AddrSpaceR))
+ return Res;
+ }
+ if (PTyL)
+ return 1;
+ if (PTyR)
+ return -1;
+
+ // TyL and TyR aren't vectors, nor pointers. We don't know how to
+ // bitcast them.
+ return TypesRes;
+ }
+ }
+
+ // OK, types are bitcastable, now check constant contents.
+
+ if (L->isNullValue() && R->isNullValue())
+ return TypesRes;
+ if (L->isNullValue() && !R->isNullValue())
+ return 1;
+ if (!L->isNullValue() && R->isNullValue())
+ return -1;
+
+ auto GlobalValueL = const_cast<GlobalValue*>(dyn_cast<GlobalValue>(L));
+ auto GlobalValueR = const_cast<GlobalValue*>(dyn_cast<GlobalValue>(R));
+ if (GlobalValueL && GlobalValueR) {
+ return cmpGlobalValues(GlobalValueL, GlobalValueR);
+ }
+
+ if (int Res = cmpNumbers(L->getValueID(), R->getValueID()))
+ return Res;
+
+ if (const auto *SeqL = dyn_cast<ConstantDataSequential>(L)) {
+ const auto *SeqR = cast<ConstantDataSequential>(R);
+ // This handles ConstantDataArray and ConstantDataVector. Note that we
+ // compare the two raw data arrays, which might differ depending on the host
+ // endianness. This isn't a problem though, because the endiness of a module
+ // will affect the order of the constants, but this order is the same
+ // for a given input module and host platform.
+ return cmpMem(SeqL->getRawDataValues(), SeqR->getRawDataValues());
+ }
+
+ switch (L->getValueID()) {
+ case Value::UndefValueVal:
+ case Value::ConstantTokenNoneVal:
+ return TypesRes;
+ case Value::ConstantIntVal: {
+ const APInt &LInt = cast<ConstantInt>(L)->getValue();
+ const APInt &RInt = cast<ConstantInt>(R)->getValue();
+ return cmpAPInts(LInt, RInt);
+ }
+ case Value::ConstantFPVal: {
+ const APFloat &LAPF = cast<ConstantFP>(L)->getValueAPF();
+ const APFloat &RAPF = cast<ConstantFP>(R)->getValueAPF();
+ return cmpAPFloats(LAPF, RAPF);
+ }
+ case Value::ConstantArrayVal: {
+ const ConstantArray *LA = cast<ConstantArray>(L);
+ const ConstantArray *RA = cast<ConstantArray>(R);
+ uint64_t NumElementsL = cast<ArrayType>(TyL)->getNumElements();
+ uint64_t NumElementsR = cast<ArrayType>(TyR)->getNumElements();
+ if (int Res = cmpNumbers(NumElementsL, NumElementsR))
+ return Res;
+ for (uint64_t i = 0; i < NumElementsL; ++i) {
+ if (int Res = cmpConstants(cast<Constant>(LA->getOperand(i)),
+ cast<Constant>(RA->getOperand(i))))
+ return Res;
+ }
+ return 0;
+ }
+ case Value::ConstantStructVal: {
+ const ConstantStruct *LS = cast<ConstantStruct>(L);
+ const ConstantStruct *RS = cast<ConstantStruct>(R);
+ unsigned NumElementsL = cast<StructType>(TyL)->getNumElements();
+ unsigned NumElementsR = cast<StructType>(TyR)->getNumElements();
+ if (int Res = cmpNumbers(NumElementsL, NumElementsR))
+ return Res;
+ for (unsigned i = 0; i != NumElementsL; ++i) {
+ if (int Res = cmpConstants(cast<Constant>(LS->getOperand(i)),
+ cast<Constant>(RS->getOperand(i))))
+ return Res;
+ }
+ return 0;
+ }
+ case Value::ConstantVectorVal: {
+ const ConstantVector *LV = cast<ConstantVector>(L);
+ const ConstantVector *RV = cast<ConstantVector>(R);
+ unsigned NumElementsL = cast<VectorType>(TyL)->getNumElements();
+ unsigned NumElementsR = cast<VectorType>(TyR)->getNumElements();
+ if (int Res = cmpNumbers(NumElementsL, NumElementsR))
+ return Res;
+ for (uint64_t i = 0; i < NumElementsL; ++i) {
+ if (int Res = cmpConstants(cast<Constant>(LV->getOperand(i)),
+ cast<Constant>(RV->getOperand(i))))
+ return Res;
+ }
+ return 0;
+ }
+ case Value::ConstantExprVal: {
+ const ConstantExpr *LE = cast<ConstantExpr>(L);
+ const ConstantExpr *RE = cast<ConstantExpr>(R);
+ unsigned NumOperandsL = LE->getNumOperands();
+ unsigned NumOperandsR = RE->getNumOperands();
+ if (int Res = cmpNumbers(NumOperandsL, NumOperandsR))
+ return Res;
+ for (unsigned i = 0; i < NumOperandsL; ++i) {
+ if (int Res = cmpConstants(cast<Constant>(LE->getOperand(i)),
+ cast<Constant>(RE->getOperand(i))))
+ return Res;
+ }
+ return 0;
+ }
+ case Value::BlockAddressVal: {
+ const BlockAddress *LBA = cast<BlockAddress>(L);
+ const BlockAddress *RBA = cast<BlockAddress>(R);
+ if (int Res = cmpValues(LBA->getFunction(), RBA->getFunction()))
+ return Res;
+ if (LBA->getFunction() == RBA->getFunction()) {
+ // They are BBs in the same function. Order by which comes first in the
+ // BB order of the function. This order is deterministic.
+ Function* F = LBA->getFunction();
+ BasicBlock *LBB = LBA->getBasicBlock();
+ BasicBlock *RBB = RBA->getBasicBlock();
+ if (LBB == RBB)
+ return 0;
+ for(BasicBlock &BB : F->getBasicBlockList()) {
+ if (&BB == LBB) {
+ assert(&BB != RBB);
+ return -1;
+ }
+ if (&BB == RBB)
+ return 1;
+ }
+ llvm_unreachable("Basic Block Address does not point to a basic block in "
+ "its function.");
+ return -1;
+ } else {
+ // cmpValues said the functions are the same. So because they aren't
+ // literally the same pointer, they must respectively be the left and
+ // right functions.
+ assert(LBA->getFunction() == FnL && RBA->getFunction() == FnR);
+ // cmpValues will tell us if these are equivalent BasicBlocks, in the
+ // context of their respective functions.
+ return cmpValues(LBA->getBasicBlock(), RBA->getBasicBlock());
+ }
+ }
+ default: // Unknown constant, abort.
+ DEBUG(dbgs() << "Looking at valueID " << L->getValueID() << "\n");
+ llvm_unreachable("Constant ValueID not recognized.");
+ return -1;
+ }
+}
+
+int FunctionComparator::cmpGlobalValues(GlobalValue *L, GlobalValue *R) const {
+ uint64_t LNumber = GlobalNumbers->getNumber(L);
+ uint64_t RNumber = GlobalNumbers->getNumber(R);
+ return cmpNumbers(LNumber, RNumber);
+}
+
+/// cmpType - compares two types,
+/// defines total ordering among the types set.
+/// See method declaration comments for more details.
+int FunctionComparator::cmpTypes(Type *TyL, Type *TyR) const {
+ PointerType *PTyL = dyn_cast<PointerType>(TyL);
+ PointerType *PTyR = dyn_cast<PointerType>(TyR);
+
+ const DataLayout &DL = FnL->getParent()->getDataLayout();
+ if (PTyL && PTyL->getAddressSpace() == 0)
+ TyL = DL.getIntPtrType(TyL);
+ if (PTyR && PTyR->getAddressSpace() == 0)
+ TyR = DL.getIntPtrType(TyR);
+
+ if (TyL == TyR)
+ return 0;
+
+ if (int Res = cmpNumbers(TyL->getTypeID(), TyR->getTypeID()))
+ return Res;
+
+ switch (TyL->getTypeID()) {
+ default:
+ llvm_unreachable("Unknown type!");
+ // Fall through in Release mode.
+ LLVM_FALLTHROUGH;
+ case Type::IntegerTyID:
+ return cmpNumbers(cast<IntegerType>(TyL)->getBitWidth(),
+ cast<IntegerType>(TyR)->getBitWidth());
+ // TyL == TyR would have returned true earlier, because types are uniqued.
+ case Type::VoidTyID:
+ case Type::FloatTyID:
+ case Type::DoubleTyID:
+ case Type::X86_FP80TyID:
+ case Type::FP128TyID:
+ case Type::PPC_FP128TyID:
+ case Type::LabelTyID:
+ case Type::MetadataTyID:
+ case Type::TokenTyID:
+ return 0;
+
+ case Type::PointerTyID: {
+ assert(PTyL && PTyR && "Both types must be pointers here.");
+ return cmpNumbers(PTyL->getAddressSpace(), PTyR->getAddressSpace());
+ }
+
+ case Type::StructTyID: {
+ StructType *STyL = cast<StructType>(TyL);
+ StructType *STyR = cast<StructType>(TyR);
+ if (STyL->getNumElements() != STyR->getNumElements())
+ return cmpNumbers(STyL->getNumElements(), STyR->getNumElements());
+
+ if (STyL->isPacked() != STyR->isPacked())
+ return cmpNumbers(STyL->isPacked(), STyR->isPacked());
+
+ for (unsigned i = 0, e = STyL->getNumElements(); i != e; ++i) {
+ if (int Res = cmpTypes(STyL->getElementType(i), STyR->getElementType(i)))
+ return Res;
+ }
+ return 0;
+ }
+
+ case Type::FunctionTyID: {
+ FunctionType *FTyL = cast<FunctionType>(TyL);
+ FunctionType *FTyR = cast<FunctionType>(TyR);
+ if (FTyL->getNumParams() != FTyR->getNumParams())
+ return cmpNumbers(FTyL->getNumParams(), FTyR->getNumParams());
+
+ if (FTyL->isVarArg() != FTyR->isVarArg())
+ return cmpNumbers(FTyL->isVarArg(), FTyR->isVarArg());
+
+ if (int Res = cmpTypes(FTyL->getReturnType(), FTyR->getReturnType()))
+ return Res;
+
+ for (unsigned i = 0, e = FTyL->getNumParams(); i != e; ++i) {
+ if (int Res = cmpTypes(FTyL->getParamType(i), FTyR->getParamType(i)))
+ return Res;
+ }
+ return 0;
+ }
+
+ case Type::ArrayTyID:
+ case Type::VectorTyID: {
+ auto *STyL = cast<SequentialType>(TyL);
+ auto *STyR = cast<SequentialType>(TyR);
+ if (STyL->getNumElements() != STyR->getNumElements())
+ return cmpNumbers(STyL->getNumElements(), STyR->getNumElements());
+ return cmpTypes(STyL->getElementType(), STyR->getElementType());
+ }
+ }
+}
+
+// Determine whether the two operations are the same except that pointer-to-A
+// and pointer-to-B are equivalent. This should be kept in sync with
+// Instruction::isSameOperationAs.
+// Read method declaration comments for more details.
+int FunctionComparator::cmpOperations(const Instruction *L,
+ const Instruction *R,
+ bool &needToCmpOperands) const {
+ needToCmpOperands = true;
+ if (int Res = cmpValues(L, R))
+ return Res;
+
+ // Differences from Instruction::isSameOperationAs:
+ // * replace type comparison with calls to cmpTypes.
+ // * we test for I->getRawSubclassOptionalData (nuw/nsw/tail) at the top.
+ // * because of the above, we don't test for the tail bit on calls later on.
+ if (int Res = cmpNumbers(L->getOpcode(), R->getOpcode()))
+ return Res;
+
+ if (const GetElementPtrInst *GEPL = dyn_cast<GetElementPtrInst>(L)) {
+ needToCmpOperands = false;
+ const GetElementPtrInst *GEPR = cast<GetElementPtrInst>(R);
+ if (int Res =
+ cmpValues(GEPL->getPointerOperand(), GEPR->getPointerOperand()))
+ return Res;
+ return cmpGEPs(GEPL, GEPR);
+ }
+
+ if (int Res = cmpNumbers(L->getNumOperands(), R->getNumOperands()))
+ return Res;
+
+ if (int Res = cmpTypes(L->getType(), R->getType()))
+ return Res;
+
+ if (int Res = cmpNumbers(L->getRawSubclassOptionalData(),
+ R->getRawSubclassOptionalData()))
+ return Res;
+
+ // We have two instructions of identical opcode and #operands. Check to see
+ // if all operands are the same type
+ for (unsigned i = 0, e = L->getNumOperands(); i != e; ++i) {
+ if (int Res =
+ cmpTypes(L->getOperand(i)->getType(), R->getOperand(i)->getType()))
+ return Res;
+ }
+
+ // Check special state that is a part of some instructions.
+ if (const AllocaInst *AI = dyn_cast<AllocaInst>(L)) {
+ if (int Res = cmpTypes(AI->getAllocatedType(),
+ cast<AllocaInst>(R)->getAllocatedType()))
+ return Res;
+ return cmpNumbers(AI->getAlignment(), cast<AllocaInst>(R)->getAlignment());
+ }
+ if (const LoadInst *LI = dyn_cast<LoadInst>(L)) {
+ if (int Res = cmpNumbers(LI->isVolatile(), cast<LoadInst>(R)->isVolatile()))
+ return Res;
+ if (int Res =
+ cmpNumbers(LI->getAlignment(), cast<LoadInst>(R)->getAlignment()))
+ return Res;
+ if (int Res =
+ cmpOrderings(LI->getOrdering(), cast<LoadInst>(R)->getOrdering()))
+ return Res;
+ if (int Res =
+ cmpNumbers(LI->getSynchScope(), cast<LoadInst>(R)->getSynchScope()))
+ return Res;
+ return cmpRangeMetadata(LI->getMetadata(LLVMContext::MD_range),
+ cast<LoadInst>(R)->getMetadata(LLVMContext::MD_range));
+ }
+ if (const StoreInst *SI = dyn_cast<StoreInst>(L)) {
+ if (int Res =
+ cmpNumbers(SI->isVolatile(), cast<StoreInst>(R)->isVolatile()))
+ return Res;
+ if (int Res =
+ cmpNumbers(SI->getAlignment(), cast<StoreInst>(R)->getAlignment()))
+ return Res;
+ if (int Res =
+ cmpOrderings(SI->getOrdering(), cast<StoreInst>(R)->getOrdering()))
+ return Res;
+ return cmpNumbers(SI->getSynchScope(), cast<StoreInst>(R)->getSynchScope());
+ }
+ if (const CmpInst *CI = dyn_cast<CmpInst>(L))
+ return cmpNumbers(CI->getPredicate(), cast<CmpInst>(R)->getPredicate());
+ if (const CallInst *CI = dyn_cast<CallInst>(L)) {
+ if (int Res = cmpNumbers(CI->getCallingConv(),
+ cast<CallInst>(R)->getCallingConv()))
+ return Res;
+ if (int Res =
+ cmpAttrs(CI->getAttributes(), cast<CallInst>(R)->getAttributes()))
+ return Res;
+ if (int Res = cmpOperandBundlesSchema(CI, R))
+ return Res;
+ return cmpRangeMetadata(
+ CI->getMetadata(LLVMContext::MD_range),
+ cast<CallInst>(R)->getMetadata(LLVMContext::MD_range));
+ }
+ if (const InvokeInst *II = dyn_cast<InvokeInst>(L)) {
+ if (int Res = cmpNumbers(II->getCallingConv(),
+ cast<InvokeInst>(R)->getCallingConv()))
+ return Res;
+ if (int Res =
+ cmpAttrs(II->getAttributes(), cast<InvokeInst>(R)->getAttributes()))
+ return Res;
+ if (int Res = cmpOperandBundlesSchema(II, R))
+ return Res;
+ return cmpRangeMetadata(
+ II->getMetadata(LLVMContext::MD_range),
+ cast<InvokeInst>(R)->getMetadata(LLVMContext::MD_range));
+ }
+ if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(L)) {
+ ArrayRef<unsigned> LIndices = IVI->getIndices();
+ ArrayRef<unsigned> RIndices = cast<InsertValueInst>(R)->getIndices();
+ if (int Res = cmpNumbers(LIndices.size(), RIndices.size()))
+ return Res;
+ for (size_t i = 0, e = LIndices.size(); i != e; ++i) {
+ if (int Res = cmpNumbers(LIndices[i], RIndices[i]))
+ return Res;
+ }
+ return 0;
+ }
+ if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(L)) {
+ ArrayRef<unsigned> LIndices = EVI->getIndices();
+ ArrayRef<unsigned> RIndices = cast<ExtractValueInst>(R)->getIndices();
+ if (int Res = cmpNumbers(LIndices.size(), RIndices.size()))
+ return Res;
+ for (size_t i = 0, e = LIndices.size(); i != e; ++i) {
+ if (int Res = cmpNumbers(LIndices[i], RIndices[i]))
+ return Res;
+ }
+ }
+ if (const FenceInst *FI = dyn_cast<FenceInst>(L)) {
+ if (int Res =
+ cmpOrderings(FI->getOrdering(), cast<FenceInst>(R)->getOrdering()))
+ return Res;
+ return cmpNumbers(FI->getSynchScope(), cast<FenceInst>(R)->getSynchScope());
+ }
+ if (const AtomicCmpXchgInst *CXI = dyn_cast<AtomicCmpXchgInst>(L)) {
+ if (int Res = cmpNumbers(CXI->isVolatile(),
+ cast<AtomicCmpXchgInst>(R)->isVolatile()))
+ return Res;
+ if (int Res = cmpNumbers(CXI->isWeak(),
+ cast<AtomicCmpXchgInst>(R)->isWeak()))
+ return Res;
+ if (int Res =
+ cmpOrderings(CXI->getSuccessOrdering(),
+ cast<AtomicCmpXchgInst>(R)->getSuccessOrdering()))
+ return Res;
+ if (int Res =
+ cmpOrderings(CXI->getFailureOrdering(),
+ cast<AtomicCmpXchgInst>(R)->getFailureOrdering()))
+ return Res;
+ return cmpNumbers(CXI->getSynchScope(),
+ cast<AtomicCmpXchgInst>(R)->getSynchScope());
+ }
+ if (const AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(L)) {
+ if (int Res = cmpNumbers(RMWI->getOperation(),
+ cast<AtomicRMWInst>(R)->getOperation()))
+ return Res;
+ if (int Res = cmpNumbers(RMWI->isVolatile(),
+ cast<AtomicRMWInst>(R)->isVolatile()))
+ return Res;
+ if (int Res = cmpOrderings(RMWI->getOrdering(),
+ cast<AtomicRMWInst>(R)->getOrdering()))
+ return Res;
+ return cmpNumbers(RMWI->getSynchScope(),
+ cast<AtomicRMWInst>(R)->getSynchScope());
+ }
+ if (const PHINode *PNL = dyn_cast<PHINode>(L)) {
+ const PHINode *PNR = cast<PHINode>(R);
+ // Ensure that in addition to the incoming values being identical
+ // (checked by the caller of this function), the incoming blocks
+ // are also identical.
+ for (unsigned i = 0, e = PNL->getNumIncomingValues(); i != e; ++i) {
+ if (int Res =
+ cmpValues(PNL->getIncomingBlock(i), PNR->getIncomingBlock(i)))
+ return Res;
+ }
+ }
+ return 0;
+}
+
+// Determine whether two GEP operations perform the same underlying arithmetic.
+// Read method declaration comments for more details.
+int FunctionComparator::cmpGEPs(const GEPOperator *GEPL,
+ const GEPOperator *GEPR) const {
+
+ unsigned int ASL = GEPL->getPointerAddressSpace();
+ unsigned int ASR = GEPR->getPointerAddressSpace();
+
+ if (int Res = cmpNumbers(ASL, ASR))
+ return Res;
+
+ // When we have target data, we can reduce the GEP down to the value in bytes
+ // added to the address.
+ const DataLayout &DL = FnL->getParent()->getDataLayout();
+ unsigned BitWidth = DL.getPointerSizeInBits(ASL);
+ APInt OffsetL(BitWidth, 0), OffsetR(BitWidth, 0);
+ if (GEPL->accumulateConstantOffset(DL, OffsetL) &&
+ GEPR->accumulateConstantOffset(DL, OffsetR))
+ return cmpAPInts(OffsetL, OffsetR);
+ if (int Res = cmpTypes(GEPL->getSourceElementType(),
+ GEPR->getSourceElementType()))
+ return Res;
+
+ if (int Res = cmpNumbers(GEPL->getNumOperands(), GEPR->getNumOperands()))
+ return Res;
+
+ for (unsigned i = 0, e = GEPL->getNumOperands(); i != e; ++i) {
+ if (int Res = cmpValues(GEPL->getOperand(i), GEPR->getOperand(i)))
+ return Res;
+ }
+
+ return 0;
+}
+
+int FunctionComparator::cmpInlineAsm(const InlineAsm *L,
+ const InlineAsm *R) const {
+ // InlineAsm's are uniqued. If they are the same pointer, obviously they are
+ // the same, otherwise compare the fields.
+ if (L == R)
+ return 0;
+ if (int Res = cmpTypes(L->getFunctionType(), R->getFunctionType()))
+ return Res;
+ if (int Res = cmpMem(L->getAsmString(), R->getAsmString()))
+ return Res;
+ if (int Res = cmpMem(L->getConstraintString(), R->getConstraintString()))
+ return Res;
+ if (int Res = cmpNumbers(L->hasSideEffects(), R->hasSideEffects()))
+ return Res;
+ if (int Res = cmpNumbers(L->isAlignStack(), R->isAlignStack()))
+ return Res;
+ if (int Res = cmpNumbers(L->getDialect(), R->getDialect()))
+ return Res;
+ llvm_unreachable("InlineAsm blocks were not uniqued.");
+ return 0;
+}
+
+/// Compare two values used by the two functions under pair-wise comparison. If
+/// this is the first time the values are seen, they're added to the mapping so
+/// that we will detect mismatches on next use.
+/// See comments in declaration for more details.
+int FunctionComparator::cmpValues(const Value *L, const Value *R) const {
+ // Catch self-reference case.
+ if (L == FnL) {
+ if (R == FnR)
+ return 0;
+ return -1;
+ }
+ if (R == FnR) {
+ if (L == FnL)
+ return 0;
+ return 1;
+ }
+
+ const Constant *ConstL = dyn_cast<Constant>(L);
+ const Constant *ConstR = dyn_cast<Constant>(R);
+ if (ConstL && ConstR) {
+ if (L == R)
+ return 0;
+ return cmpConstants(ConstL, ConstR);
+ }
+
+ if (ConstL)
+ return 1;
+ if (ConstR)
+ return -1;
+
+ const InlineAsm *InlineAsmL = dyn_cast<InlineAsm>(L);
+ const InlineAsm *InlineAsmR = dyn_cast<InlineAsm>(R);
+
+ if (InlineAsmL && InlineAsmR)
+ return cmpInlineAsm(InlineAsmL, InlineAsmR);
+ if (InlineAsmL)
+ return 1;
+ if (InlineAsmR)
+ return -1;
+
+ auto LeftSN = sn_mapL.insert(std::make_pair(L, sn_mapL.size())),
+ RightSN = sn_mapR.insert(std::make_pair(R, sn_mapR.size()));
+
+ return cmpNumbers(LeftSN.first->second, RightSN.first->second);
+}
+
+// Test whether two basic blocks have equivalent behaviour.
+int FunctionComparator::cmpBasicBlocks(const BasicBlock *BBL,
+ const BasicBlock *BBR) const {
+ BasicBlock::const_iterator InstL = BBL->begin(), InstLE = BBL->end();
+ BasicBlock::const_iterator InstR = BBR->begin(), InstRE = BBR->end();
+
+ do {
+ bool needToCmpOperands = true;
+ if (int Res = cmpOperations(&*InstL, &*InstR, needToCmpOperands))
+ return Res;
+ if (needToCmpOperands) {
+ assert(InstL->getNumOperands() == InstR->getNumOperands());
+
+ for (unsigned i = 0, e = InstL->getNumOperands(); i != e; ++i) {
+ Value *OpL = InstL->getOperand(i);
+ Value *OpR = InstR->getOperand(i);
+ if (int Res = cmpValues(OpL, OpR))
+ return Res;
+ // cmpValues should ensure this is true.
+ assert(cmpTypes(OpL->getType(), OpR->getType()) == 0);
+ }
+ }
+
+ ++InstL;
+ ++InstR;
+ } while (InstL != InstLE && InstR != InstRE);
+
+ if (InstL != InstLE && InstR == InstRE)
+ return 1;
+ if (InstL == InstLE && InstR != InstRE)
+ return -1;
+ return 0;
+}
+
+int FunctionComparator::compareSignature() const {
+ if (int Res = cmpAttrs(FnL->getAttributes(), FnR->getAttributes()))
+ return Res;
+
+ if (int Res = cmpNumbers(FnL->hasGC(), FnR->hasGC()))
+ return Res;
+
+ if (FnL->hasGC()) {
+ if (int Res = cmpMem(FnL->getGC(), FnR->getGC()))
+ return Res;
+ }
+
+ if (int Res = cmpNumbers(FnL->hasSection(), FnR->hasSection()))
+ return Res;
+
+ if (FnL->hasSection()) {
+ if (int Res = cmpMem(FnL->getSection(), FnR->getSection()))
+ return Res;
+ }
+
+ if (int Res = cmpNumbers(FnL->isVarArg(), FnR->isVarArg()))
+ return Res;
+
+ // TODO: if it's internal and only used in direct calls, we could handle this
+ // case too.
+ if (int Res = cmpNumbers(FnL->getCallingConv(), FnR->getCallingConv()))
+ return Res;
+
+ if (int Res = cmpTypes(FnL->getFunctionType(), FnR->getFunctionType()))
+ return Res;
+
+ assert(FnL->arg_size() == FnR->arg_size() &&
+ "Identically typed functions have different numbers of args!");
+
+ // Visit the arguments so that they get enumerated in the order they're
+ // passed in.
+ for (Function::const_arg_iterator ArgLI = FnL->arg_begin(),
+ ArgRI = FnR->arg_begin(),
+ ArgLE = FnL->arg_end();
+ ArgLI != ArgLE; ++ArgLI, ++ArgRI) {
+ if (cmpValues(&*ArgLI, &*ArgRI) != 0)
+ llvm_unreachable("Arguments repeat!");
+ }
+ return 0;
+}
+
+// Test whether the two functions have equivalent behaviour.
+int FunctionComparator::compare() {
+ beginCompare();
+
+ if (int Res = compareSignature())
+ return Res;
+
+ // We do a CFG-ordered walk since the actual ordering of the blocks in the
+ // linked list is immaterial. Our walk starts at the entry block for both
+ // functions, then takes each block from each terminator in order. As an
+ // artifact, this also means that unreachable blocks are ignored.
+ SmallVector<const BasicBlock *, 8> FnLBBs, FnRBBs;
+ SmallPtrSet<const BasicBlock *, 32> VisitedBBs; // in terms of F1.
+
+ FnLBBs.push_back(&FnL->getEntryBlock());
+ FnRBBs.push_back(&FnR->getEntryBlock());
+
+ VisitedBBs.insert(FnLBBs[0]);
+ while (!FnLBBs.empty()) {
+ const BasicBlock *BBL = FnLBBs.pop_back_val();
+ const BasicBlock *BBR = FnRBBs.pop_back_val();
+
+ if (int Res = cmpValues(BBL, BBR))
+ return Res;
+
+ if (int Res = cmpBasicBlocks(BBL, BBR))
+ return Res;
+
+ const TerminatorInst *TermL = BBL->getTerminator();
+ const TerminatorInst *TermR = BBR->getTerminator();
+
+ assert(TermL->getNumSuccessors() == TermR->getNumSuccessors());
+ for (unsigned i = 0, e = TermL->getNumSuccessors(); i != e; ++i) {
+ if (!VisitedBBs.insert(TermL->getSuccessor(i)).second)
+ continue;
+
+ FnLBBs.push_back(TermL->getSuccessor(i));
+ FnRBBs.push_back(TermR->getSuccessor(i));
+ }
+ }
+ return 0;
+}
+
+namespace {
+
+// Accumulate the hash of a sequence of 64-bit integers. This is similar to a
+// hash of a sequence of 64bit ints, but the entire input does not need to be
+// available at once. This interface is necessary for functionHash because it
+// needs to accumulate the hash as the structure of the function is traversed
+// without saving these values to an intermediate buffer. This form of hashing
+// is not often needed, as usually the object to hash is just read from a
+// buffer.
+class HashAccumulator64 {
+ uint64_t Hash;
+public:
+ // Initialize to random constant, so the state isn't zero.
+ HashAccumulator64() { Hash = 0x6acaa36bef8325c5ULL; }
+ void add(uint64_t V) {
+ Hash = llvm::hashing::detail::hash_16_bytes(Hash, V);
+ }
+ // No finishing is required, because the entire hash value is used.
+ uint64_t getHash() { return Hash; }
+};
+} // end anonymous namespace
+
+// A function hash is calculated by considering only the number of arguments and
+// whether a function is varargs, the order of basic blocks (given by the
+// successors of each basic block in depth first order), and the order of
+// opcodes of each instruction within each of these basic blocks. This mirrors
+// the strategy compare() uses to compare functions by walking the BBs in depth
+// first order and comparing each instruction in sequence. Because this hash
+// does not look at the operands, it is insensitive to things such as the
+// target of calls and the constants used in the function, which makes it useful
+// when possibly merging functions which are the same modulo constants and call
+// targets.
+FunctionComparator::FunctionHash FunctionComparator::functionHash(Function &F) {
+ HashAccumulator64 H;
+ H.add(F.isVarArg());
+ H.add(F.arg_size());
+
+ SmallVector<const BasicBlock *, 8> BBs;
+ SmallSet<const BasicBlock *, 16> VisitedBBs;
+
+ // Walk the blocks in the same order as FunctionComparator::cmpBasicBlocks(),
+ // accumulating the hash of the function "structure." (BB and opcode sequence)
+ BBs.push_back(&F.getEntryBlock());
+ VisitedBBs.insert(BBs[0]);
+ while (!BBs.empty()) {
+ const BasicBlock *BB = BBs.pop_back_val();
+ // This random value acts as a block header, as otherwise the partition of
+ // opcodes into BBs wouldn't affect the hash, only the order of the opcodes
+ H.add(45798);
+ for (auto &Inst : *BB) {
+ H.add(Inst.getOpcode());
+ }
+ const TerminatorInst *Term = BB->getTerminator();
+ for (unsigned i = 0, e = Term->getNumSuccessors(); i != e; ++i) {
+ if (!VisitedBBs.insert(Term->getSuccessor(i)).second)
+ continue;
+ BBs.push_back(Term->getSuccessor(i));
+ }
+ }
+ return H.getHash();
+}
+
+
diff --git a/contrib/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp b/contrib/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp
index fcb25ba..9844190 100644
--- a/contrib/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp
@@ -48,7 +48,7 @@ bool FunctionImportGlobalProcessing::doImportAsDefinition(
GlobalsToImport);
}
-bool FunctionImportGlobalProcessing::doPromoteLocalToGlobal(
+bool FunctionImportGlobalProcessing::shouldPromoteLocalToGlobal(
const GlobalValue *SGV) {
assert(SGV->hasLocalLinkage());
// Both the imported references and the original local variable must
@@ -56,36 +56,57 @@ bool FunctionImportGlobalProcessing::doPromoteLocalToGlobal(
if (!isPerformingImport() && !isModuleExporting())
return false;
- // Local const variables never need to be promoted unless they are address
- // taken. The imported uses can simply use the clone created in this module.
- // For now we are conservative in determining which variables are not
- // address taken by checking the unnamed addr flag. To be more aggressive,
- // the address taken information must be checked earlier during parsing
- // of the module and recorded in the summary index for use when importing
- // from that module.
- auto *GVar = dyn_cast<GlobalVariable>(SGV);
- if (GVar && GVar->isConstant() && GVar->hasGlobalUnnamedAddr())
- return false;
+ if (isPerformingImport()) {
+ assert((!GlobalsToImport->count(SGV) || !isNonRenamableLocal(*SGV)) &&
+ "Attempting to promote non-renamable local");
+ // We don't know for sure yet if we are importing this value (as either
+ // a reference or a def), since we are simply walking all values in the
+ // module. But by necessity if we end up importing it and it is local,
+ // it must be promoted, so unconditionally promote all values in the
+ // importing module.
+ return true;
+ }
- if (GVar && GVar->hasSection())
- // Some sections like "__DATA,__cfstring" are "magic" and promotion is not
- // allowed. Just disable promotion on any GVar with sections right now.
- return false;
+ // When exporting, consult the index. We can have more than one local
+ // with the same GUID, in the case of same-named locals in different but
+ // same-named source files that were compiled in their respective directories
+ // (so the source file name and resulting GUID is the same). Find the one
+ // in this module.
+ auto Summary = ImportIndex.findSummaryInModule(
+ SGV->getGUID(), SGV->getParent()->getModuleIdentifier());
+ assert(Summary && "Missing summary for global value when exporting");
+ auto Linkage = Summary->linkage();
+ if (!GlobalValue::isLocalLinkage(Linkage)) {
+ assert(!isNonRenamableLocal(*SGV) &&
+ "Attempting to promote non-renamable local");
+ return true;
+ }
- // Eventually we only need to promote functions in the exporting module that
- // are referenced by a potentially exported function (i.e. one that is in the
- // summary index).
- return true;
+ return false;
}
-std::string FunctionImportGlobalProcessing::getName(const GlobalValue *SGV) {
+#ifndef NDEBUG
+bool FunctionImportGlobalProcessing::isNonRenamableLocal(
+ const GlobalValue &GV) const {
+ if (!GV.hasLocalLinkage())
+ return false;
+ // This needs to stay in sync with the logic in buildModuleSummaryIndex.
+ if (GV.hasSection())
+ return true;
+ if (Used.count(const_cast<GlobalValue *>(&GV)))
+ return true;
+ return false;
+}
+#endif
+
+std::string FunctionImportGlobalProcessing::getName(const GlobalValue *SGV,
+ bool DoPromote) {
// For locals that must be promoted to global scope, ensure that
// the promoted name uniquely identifies the copy in the original module,
// using the ID assigned during combined index creation. When importing,
// we rename all locals (not just those that are promoted) in order to
// avoid naming conflicts between locals imported from different modules.
- if (SGV->hasLocalLinkage() &&
- (doPromoteLocalToGlobal(SGV) || isPerformingImport()))
+ if (SGV->hasLocalLinkage() && (DoPromote || isPerformingImport()))
return ModuleSummaryIndex::getGlobalNameForLocal(
SGV->getName(),
ImportIndex.getModuleHash(SGV->getParent()->getModuleIdentifier()));
@@ -93,13 +114,14 @@ std::string FunctionImportGlobalProcessing::getName(const GlobalValue *SGV) {
}
GlobalValue::LinkageTypes
-FunctionImportGlobalProcessing::getLinkage(const GlobalValue *SGV) {
+FunctionImportGlobalProcessing::getLinkage(const GlobalValue *SGV,
+ bool DoPromote) {
// Any local variable that is referenced by an exported function needs
// to be promoted to global scope. Since we don't currently know which
// functions reference which local variables/functions, we must treat
// all as potentially exported if this module is exporting anything.
if (isModuleExporting()) {
- if (SGV->hasLocalLinkage() && doPromoteLocalToGlobal(SGV))
+ if (SGV->hasLocalLinkage() && DoPromote)
return GlobalValue::ExternalLinkage;
return SGV->getLinkage();
}
@@ -164,7 +186,7 @@ FunctionImportGlobalProcessing::getLinkage(const GlobalValue *SGV) {
case GlobalValue::PrivateLinkage:
// If we are promoting the local to global scope, it is handled
// similarly to a normal externally visible global.
- if (doPromoteLocalToGlobal(SGV)) {
+ if (DoPromote) {
if (doImportAsDefinition(SGV) && !dyn_cast<GlobalAlias>(SGV))
return GlobalValue::AvailableExternallyLinkage;
else
@@ -190,14 +212,19 @@ FunctionImportGlobalProcessing::getLinkage(const GlobalValue *SGV) {
}
void FunctionImportGlobalProcessing::processGlobalForThinLTO(GlobalValue &GV) {
+ bool DoPromote = false;
if (GV.hasLocalLinkage() &&
- (doPromoteLocalToGlobal(&GV) || isPerformingImport())) {
- GV.setName(getName(&GV));
- GV.setLinkage(getLinkage(&GV));
+ ((DoPromote = shouldPromoteLocalToGlobal(&GV)) || isPerformingImport())) {
+ // Once we change the name or linkage it is difficult to determine
+ // again whether we should promote since shouldPromoteLocalToGlobal needs
+ // to locate the summary (based on GUID from name and linkage). Therefore,
+ // use DoPromote result saved above.
+ GV.setName(getName(&GV, DoPromote));
+ GV.setLinkage(getLinkage(&GV, DoPromote));
if (!GV.hasLocalLinkage())
GV.setVisibility(GlobalValue::HiddenVisibility);
} else
- GV.setLinkage(getLinkage(&GV));
+ GV.setLinkage(getLinkage(&GV, /* DoPromote */ false));
// Remove functions imported as available externally defs from comdats,
// as this is a declaration for the linker, and will be dropped eventually.
@@ -214,14 +241,6 @@ void FunctionImportGlobalProcessing::processGlobalForThinLTO(GlobalValue &GV) {
}
void FunctionImportGlobalProcessing::processGlobalsForThinLTO() {
- if (!moduleCanBeRenamedForThinLTO(M)) {
- // We would have blocked importing from this module by suppressing index
- // generation. We still may be able to import into this module though.
- assert(!isPerformingImport() &&
- "Should have blocked importing from module with local used in ASM");
- return;
- }
-
for (GlobalVariable &GV : M.globals())
processGlobalForThinLTO(GV);
for (Function &SF : M)
diff --git a/contrib/llvm/lib/Transforms/Utils/GlobalStatus.cpp b/contrib/llvm/lib/Transforms/Utils/GlobalStatus.cpp
index 266be41..74ebcda 100644
--- a/contrib/llvm/lib/Transforms/Utils/GlobalStatus.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/GlobalStatus.cpp
@@ -20,9 +20,8 @@ using namespace llvm;
/// and release, then return AcquireRelease.
///
static AtomicOrdering strongerOrdering(AtomicOrdering X, AtomicOrdering Y) {
- if (X == AtomicOrdering::Acquire && Y == AtomicOrdering::Release)
- return AtomicOrdering::AcquireRelease;
- if (Y == AtomicOrdering::Acquire && X == AtomicOrdering::Release)
+ if ((X == AtomicOrdering::Acquire && Y == AtomicOrdering::Release) ||
+ (Y == AtomicOrdering::Acquire && X == AtomicOrdering::Release))
return AtomicOrdering::AcquireRelease;
return (AtomicOrdering)std::max((unsigned)X, (unsigned)Y);
}
@@ -35,7 +34,7 @@ bool llvm::isSafeToDestroyConstant(const Constant *C) {
if (isa<GlobalValue>(C))
return false;
- if (isa<ConstantInt>(C) || isa<ConstantFP>(C))
+ if (isa<ConstantData>(C))
return false;
for (const User *U : C->users())
diff --git a/contrib/llvm/lib/Transforms/Utils/ImportedFunctionsInliningStatistics.cpp b/contrib/llvm/lib/Transforms/Utils/ImportedFunctionsInliningStatistics.cpp
new file mode 100644
index 0000000..ed018bb
--- /dev/null
+++ b/contrib/llvm/lib/Transforms/Utils/ImportedFunctionsInliningStatistics.cpp
@@ -0,0 +1,203 @@
+//===-- ImportedFunctionsInliningStats.cpp ----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Generating inliner statistics for imported functions, mostly useful for
+// ThinLTO.
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/Utils/ImportedFunctionsInliningStatistics.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <iomanip>
+#include <sstream>
+using namespace llvm;
+
+ImportedFunctionsInliningStatistics::InlineGraphNode &
+ImportedFunctionsInliningStatistics::createInlineGraphNode(const Function &F) {
+
+ auto &ValueLookup = NodesMap[F.getName()];
+ if (!ValueLookup) {
+ ValueLookup = llvm::make_unique<InlineGraphNode>();
+ ValueLookup->Imported = F.getMetadata("thinlto_src_module") != nullptr;
+ }
+ return *ValueLookup;
+}
+
+void ImportedFunctionsInliningStatistics::recordInline(const Function &Caller,
+ const Function &Callee) {
+
+ InlineGraphNode &CallerNode = createInlineGraphNode(Caller);
+ InlineGraphNode &CalleeNode = createInlineGraphNode(Callee);
+ CalleeNode.NumberOfInlines++;
+
+ if (!CallerNode.Imported && !CalleeNode.Imported) {
+ // Direct inline from not imported callee to not imported caller, so we
+ // don't have to add this to graph. It might be very helpful if you wanna
+ // get the inliner statistics in compile step where there are no imported
+ // functions. In this case the graph would be empty.
+ CalleeNode.NumberOfRealInlines++;
+ return;
+ }
+
+ CallerNode.InlinedCallees.push_back(&CalleeNode);
+ if (!CallerNode.Imported) {
+ // We could avoid second lookup, but it would make the code ultra ugly.
+ auto It = NodesMap.find(Caller.getName());
+ assert(It != NodesMap.end() && "The node should be already there.");
+ // Save Caller as a starting node for traversal. The string has to be one
+ // from map because Caller can disappear (and function name with it).
+ NonImportedCallers.push_back(It->first());
+ }
+}
+
+void ImportedFunctionsInliningStatistics::setModuleInfo(const Module &M) {
+ ModuleName = M.getName();
+ for (const auto &F : M.functions()) {
+ AllFunctions++;
+ ImportedFunctions += int(F.getMetadata("thinlto_src_module") != nullptr);
+ }
+}
+static std::string getStatString(const char *Msg, int32_t Fraction, int32_t All,
+ const char *PercentageOfMsg,
+ bool LineEnd = true) {
+ double Result = 0;
+ if (All != 0)
+ Result = 100 * static_cast<double>(Fraction) / All;
+
+ std::stringstream Str;
+ Str << std::setprecision(4) << Msg << ": " << Fraction << " [" << Result
+ << "% of " << PercentageOfMsg << "]";
+ if (LineEnd)
+ Str << "\n";
+ return Str.str();
+}
+
+void ImportedFunctionsInliningStatistics::dump(const bool Verbose) {
+ calculateRealInlines();
+ NonImportedCallers.clear();
+
+ int32_t InlinedImportedFunctionsCount = 0;
+ int32_t InlinedNotImportedFunctionsCount = 0;
+
+ int32_t InlinedImportedFunctionsToImportingModuleCount = 0;
+ int32_t InlinedNotImportedFunctionsToImportingModuleCount = 0;
+
+ const auto SortedNodes = getSortedNodes();
+ std::string Out;
+ Out.reserve(5000);
+ raw_string_ostream Ostream(Out);
+
+ Ostream << "------- Dumping inliner stats for [" << ModuleName
+ << "] -------\n";
+
+ if (Verbose)
+ Ostream << "-- List of inlined functions:\n";
+
+ for (const auto &Node : SortedNodes) {
+ assert(Node->second->NumberOfInlines >= Node->second->NumberOfRealInlines);
+ if (Node->second->NumberOfInlines == 0)
+ continue;
+
+ if (Node->second->Imported) {
+ InlinedImportedFunctionsCount++;
+ InlinedImportedFunctionsToImportingModuleCount +=
+ int(Node->second->NumberOfRealInlines > 0);
+ } else {
+ InlinedNotImportedFunctionsCount++;
+ InlinedNotImportedFunctionsToImportingModuleCount +=
+ int(Node->second->NumberOfRealInlines > 0);
+ }
+
+ if (Verbose)
+ Ostream << "Inlined "
+ << (Node->second->Imported ? "imported " : "not imported ")
+ << "function [" << Node->first() << "]"
+ << ": #inlines = " << Node->second->NumberOfInlines
+ << ", #inlines_to_importing_module = "
+ << Node->second->NumberOfRealInlines << "\n";
+ }
+
+ auto InlinedFunctionsCount =
+ InlinedImportedFunctionsCount + InlinedNotImportedFunctionsCount;
+ auto NotImportedFuncCount = AllFunctions - ImportedFunctions;
+ auto ImportedNotInlinedIntoModule =
+ ImportedFunctions - InlinedImportedFunctionsToImportingModuleCount;
+
+ Ostream << "-- Summary:\n"
+ << "All functions: " << AllFunctions
+ << ", imported functions: " << ImportedFunctions << "\n"
+ << getStatString("inlined functions", InlinedFunctionsCount,
+ AllFunctions, "all functions")
+ << getStatString("imported functions inlined anywhere",
+ InlinedImportedFunctionsCount, ImportedFunctions,
+ "imported functions")
+ << getStatString("imported functions inlined into importing module",
+ InlinedImportedFunctionsToImportingModuleCount,
+ ImportedFunctions, "imported functions",
+ /*LineEnd=*/false)
+ << getStatString(", remaining", ImportedNotInlinedIntoModule,
+ ImportedFunctions, "imported functions")
+ << getStatString("non-imported functions inlined anywhere",
+ InlinedNotImportedFunctionsCount,
+ NotImportedFuncCount, "non-imported functions")
+ << getStatString(
+ "non-imported functions inlined into importing module",
+ InlinedNotImportedFunctionsToImportingModuleCount,
+ NotImportedFuncCount, "non-imported functions");
+ Ostream.flush();
+ dbgs() << Out;
+}
+
+void ImportedFunctionsInliningStatistics::calculateRealInlines() {
+ // Removing duplicated Callers.
+ std::sort(NonImportedCallers.begin(), NonImportedCallers.end());
+ NonImportedCallers.erase(
+ std::unique(NonImportedCallers.begin(), NonImportedCallers.end()),
+ NonImportedCallers.end());
+
+ for (const auto &Name : NonImportedCallers) {
+ auto &Node = *NodesMap[Name];
+ if (!Node.Visited)
+ dfs(Node);
+ }
+}
+
+void ImportedFunctionsInliningStatistics::dfs(InlineGraphNode &GraphNode) {
+ assert(!GraphNode.Visited);
+ GraphNode.Visited = true;
+ for (auto *const InlinedFunctionNode : GraphNode.InlinedCallees) {
+ InlinedFunctionNode->NumberOfRealInlines++;
+ if (!InlinedFunctionNode->Visited)
+ dfs(*InlinedFunctionNode);
+ }
+}
+
+ImportedFunctionsInliningStatistics::SortedNodesTy
+ImportedFunctionsInliningStatistics::getSortedNodes() {
+ SortedNodesTy SortedNodes;
+ SortedNodes.reserve(NodesMap.size());
+ for (const NodesMapTy::value_type& Node : NodesMap)
+ SortedNodes.push_back(&Node);
+
+ std::sort(
+ SortedNodes.begin(), SortedNodes.end(),
+ [&](const SortedNodesTy::value_type &Lhs,
+ const SortedNodesTy::value_type &Rhs) {
+ if (Lhs->second->NumberOfInlines != Rhs->second->NumberOfInlines)
+ return Lhs->second->NumberOfInlines > Rhs->second->NumberOfInlines;
+ if (Lhs->second->NumberOfRealInlines != Rhs->second->NumberOfRealInlines)
+ return Lhs->second->NumberOfRealInlines >
+ Rhs->second->NumberOfRealInlines;
+ return Lhs->first() < Rhs->first();
+ });
+ return SortedNodes;
+}
diff --git a/contrib/llvm/lib/Transforms/Utils/InlineFunction.cpp b/contrib/llvm/lib/Transforms/Utils/InlineFunction.cpp
index e82c07f..a40079c 100644
--- a/contrib/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -14,6 +14,7 @@
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
@@ -228,7 +229,7 @@ static Value *getUnwindDestTokenHelper(Instruction *EHPad,
Instruction *ChildPad = cast<Instruction>(Child);
auto Memo = MemoMap.find(ChildPad);
if (Memo == MemoMap.end()) {
- // Haven't figure out this child pad yet; queue it.
+ // Haven't figured out this child pad yet; queue it.
Worklist.push_back(ChildPad);
continue;
}
@@ -366,6 +367,10 @@ static Value *getUnwindDestToken(Instruction *EHPad,
// search up the chain to try to find a funclet with information. Put
// null entries in the memo map to avoid re-processing as we go up.
MemoMap[EHPad] = nullptr;
+#ifndef NDEBUG
+ SmallPtrSet<Instruction *, 4> TempMemos;
+ TempMemos.insert(EHPad);
+#endif
Instruction *LastUselessPad = EHPad;
Value *AncestorToken;
for (AncestorToken = getParentPad(EHPad);
@@ -374,6 +379,13 @@ static Value *getUnwindDestToken(Instruction *EHPad,
// Skip over catchpads since they just follow their catchswitches.
if (isa<CatchPadInst>(AncestorPad))
continue;
+ // If the MemoMap had an entry mapping AncestorPad to nullptr, since we
+ // haven't yet called getUnwindDestTokenHelper for AncestorPad in this
+ // call to getUnwindDestToken, that would mean that AncestorPad had no
+ // information in itself, its descendants, or its ancestors. If that
+ // were the case, then we should also have recorded the lack of information
+ // for the descendant that we're coming from. So assert that we don't
+ // find a null entry in the MemoMap for AncestorPad.
assert(!MemoMap.count(AncestorPad) || MemoMap[AncestorPad]);
auto AncestorMemo = MemoMap.find(AncestorPad);
if (AncestorMemo == MemoMap.end()) {
@@ -384,25 +396,85 @@ static Value *getUnwindDestToken(Instruction *EHPad,
if (UnwindDestToken)
break;
LastUselessPad = AncestorPad;
+ MemoMap[LastUselessPad] = nullptr;
+#ifndef NDEBUG
+ TempMemos.insert(LastUselessPad);
+#endif
}
- // Since the whole tree under LastUselessPad has no information, it all must
- // match UnwindDestToken; record that to avoid repeating the search.
+ // We know that getUnwindDestTokenHelper was called on LastUselessPad and
+ // returned nullptr (and likewise for EHPad and any of its ancestors up to
+ // LastUselessPad), so LastUselessPad has no information from below. Since
+ // getUnwindDestTokenHelper must investigate all downward paths through
+ // no-information nodes to prove that a node has no information like this,
+ // and since any time it finds information it records it in the MemoMap for
+ // not just the immediately-containing funclet but also any ancestors also
+ // exited, it must be the case that, walking downward from LastUselessPad,
+ // visiting just those nodes which have not been mapped to an unwind dest
+ // by getUnwindDestTokenHelper (the nullptr TempMemos notwithstanding, since
+ // they are just used to keep getUnwindDestTokenHelper from repeating work),
+ // any node visited must have been exhaustively searched with no information
+ // for it found.
SmallVector<Instruction *, 8> Worklist(1, LastUselessPad);
while (!Worklist.empty()) {
Instruction *UselessPad = Worklist.pop_back_val();
- assert(!MemoMap.count(UselessPad) || MemoMap[UselessPad] == nullptr);
+ auto Memo = MemoMap.find(UselessPad);
+ if (Memo != MemoMap.end() && Memo->second) {
+ // Here the name 'UselessPad' is a bit of a misnomer, because we've found
+ // that it is a funclet that does have information about unwinding to
+ // a particular destination; its parent was a useless pad.
+ // Since its parent has no information, the unwind edge must not escape
+ // the parent, and must target a sibling of this pad. This local unwind
+ // gives us no information about EHPad. Leave it and the subtree rooted
+ // at it alone.
+ assert(getParentPad(Memo->second) == getParentPad(UselessPad));
+ continue;
+ }
+ // We know we don't have information for UselesPad. If it has an entry in
+ // the MemoMap (mapping it to nullptr), it must be one of the TempMemos
+ // added on this invocation of getUnwindDestToken; if a previous invocation
+ // recorded nullptr, it would have had to prove that the ancestors of
+ // UselessPad, which include LastUselessPad, had no information, and that
+ // in turn would have required proving that the descendants of
+ // LastUselesPad, which include EHPad, have no information about
+ // LastUselessPad, which would imply that EHPad was mapped to nullptr in
+ // the MemoMap on that invocation, which isn't the case if we got here.
+ assert(!MemoMap.count(UselessPad) || TempMemos.count(UselessPad));
+ // Assert as we enumerate users that 'UselessPad' doesn't have any unwind
+ // information that we'd be contradicting by making a map entry for it
+ // (which is something that getUnwindDestTokenHelper must have proved for
+ // us to get here). Just assert on is direct users here; the checks in
+ // this downward walk at its descendants will verify that they don't have
+ // any unwind edges that exit 'UselessPad' either (i.e. they either have no
+ // unwind edges or unwind to a sibling).
MemoMap[UselessPad] = UnwindDestToken;
if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(UselessPad)) {
- for (BasicBlock *HandlerBlock : CatchSwitch->handlers())
- for (User *U : HandlerBlock->getFirstNonPHI()->users())
+ assert(CatchSwitch->getUnwindDest() == nullptr && "Expected useless pad");
+ for (BasicBlock *HandlerBlock : CatchSwitch->handlers()) {
+ auto *CatchPad = HandlerBlock->getFirstNonPHI();
+ for (User *U : CatchPad->users()) {
+ assert(
+ (!isa<InvokeInst>(U) ||
+ (getParentPad(
+ cast<InvokeInst>(U)->getUnwindDest()->getFirstNonPHI()) ==
+ CatchPad)) &&
+ "Expected useless pad");
if (isa<CatchSwitchInst>(U) || isa<CleanupPadInst>(U))
Worklist.push_back(cast<Instruction>(U));
+ }
+ }
} else {
assert(isa<CleanupPadInst>(UselessPad));
- for (User *U : UselessPad->users())
+ for (User *U : UselessPad->users()) {
+ assert(!isa<CleanupReturnInst>(U) && "Expected useless pad");
+ assert((!isa<InvokeInst>(U) ||
+ (getParentPad(
+ cast<InvokeInst>(U)->getUnwindDest()->getFirstNonPHI()) ==
+ UselessPad)) &&
+ "Expected useless pad");
if (isa<CatchSwitchInst>(U) || isa<CleanupPadInst>(U))
Worklist.push_back(cast<Instruction>(U));
+ }
}
}
@@ -463,37 +535,7 @@ static BasicBlock *HandleCallsInBlockInlinedThroughInvoke(
#endif // NDEBUG
}
- // Convert this function call into an invoke instruction. First, split the
- // basic block.
- BasicBlock *Split =
- BB->splitBasicBlock(CI->getIterator(), CI->getName() + ".noexc");
-
- // Delete the unconditional branch inserted by splitBasicBlock
- BB->getInstList().pop_back();
-
- // Create the new invoke instruction.
- SmallVector<Value*, 8> InvokeArgs(CI->arg_begin(), CI->arg_end());
- SmallVector<OperandBundleDef, 1> OpBundles;
-
- CI->getOperandBundlesAsDefs(OpBundles);
-
- // Note: we're round tripping operand bundles through memory here, and that
- // can potentially be avoided with a cleverer API design that we do not have
- // as of this time.
-
- InvokeInst *II =
- InvokeInst::Create(CI->getCalledValue(), Split, UnwindEdge, InvokeArgs,
- OpBundles, CI->getName(), BB);
- II->setDebugLoc(CI->getDebugLoc());
- II->setCallingConv(CI->getCallingConv());
- II->setAttributes(CI->getAttributes());
-
- // Make sure that anything using the call now uses the invoke! This also
- // updates the CallGraph if present, because it uses a WeakVH.
- CI->replaceAllUsesWith(II);
-
- // Delete the original call
- Split->getInstList().pop_front();
+ changeToInvokeAndSplitBasicBlock(CI, UnwindEdge);
return BB;
}
return nullptr;
@@ -718,7 +760,7 @@ static void PropagateParallelLoopAccessMetadata(CallSite CS,
/// When inlining a function that contains noalias scope metadata,
/// this metadata needs to be cloned so that the inlined blocks
-/// have different "unqiue scopes" at every call site. Were this not done, then
+/// have different "unique scopes" at every call site. Were this not done, then
/// aliasing scopes from a function inlined into a caller multiple times could
/// not be differentiated (and this would lead to miscompiles because the
/// non-aliasing property communicated by the metadata could have
@@ -1053,8 +1095,10 @@ static void AddAliasScopeMetadata(CallSite CS, ValueToValueMapTy &VMap,
/// If the inlined function has non-byval align arguments, then
/// add @llvm.assume-based alignment assumptions to preserve this information.
static void AddAlignmentAssumptions(CallSite CS, InlineFunctionInfo &IFI) {
- if (!PreserveAlignmentAssumptions)
+ if (!PreserveAlignmentAssumptions || !IFI.GetAssumptionCache)
return;
+
+ AssumptionCache *AC = &(*IFI.GetAssumptionCache)(*CS.getCaller());
auto &DL = CS.getCaller()->getParent()->getDataLayout();
// To avoid inserting redundant assumptions, we should check for assumptions
@@ -1077,13 +1121,12 @@ static void AddAlignmentAssumptions(CallSite CS, InlineFunctionInfo &IFI) {
// If we can already prove the asserted alignment in the context of the
// caller, then don't bother inserting the assumption.
Value *Arg = CS.getArgument(I->getArgNo());
- if (getKnownAlignment(Arg, DL, CS.getInstruction(),
- &IFI.ACT->getAssumptionCache(*CS.getCaller()),
- &DT) >= Align)
+ if (getKnownAlignment(Arg, DL, CS.getInstruction(), AC, &DT) >= Align)
continue;
- IRBuilder<>(CS.getInstruction())
- .CreateAlignmentAssumption(DL, Arg, Align);
+ CallInst *NewAssumption = IRBuilder<>(CS.getInstruction())
+ .CreateAlignmentAssumption(DL, Arg, Align);
+ AC->registerAssumption(NewAssumption);
}
}
}
@@ -1194,12 +1237,13 @@ static Value *HandleByValArgument(Value *Arg, Instruction *TheCall,
if (ByValAlignment <= 1) // 0 = unspecified, 1 = no particular alignment.
return Arg;
+ AssumptionCache *AC =
+ IFI.GetAssumptionCache ? &(*IFI.GetAssumptionCache)(*Caller) : nullptr;
const DataLayout &DL = Caller->getParent()->getDataLayout();
// If the pointer is already known to be sufficiently aligned, or if we can
// round it up to a larger alignment, then we don't need a temporary.
- if (getOrEnforceKnownAlignment(Arg, ByValAlignment, DL, TheCall,
- &IFI.ACT->getAssumptionCache(*Caller)) >=
+ if (getOrEnforceKnownAlignment(Arg, ByValAlignment, DL, TheCall, AC) >=
ByValAlignment)
return Arg;
@@ -1304,7 +1348,7 @@ static bool allocaWouldBeStaticInEntry(const AllocaInst *AI ) {
/// Update inlined instructions' line numbers to
/// to encode location where these instructions are inlined.
static void fixupLineNumbers(Function *Fn, Function::iterator FI,
- Instruction *TheCall) {
+ Instruction *TheCall, bool CalleeHasDebugInfo) {
const DebugLoc &TheCallDL = TheCall->getDebugLoc();
if (!TheCallDL)
return;
@@ -1326,22 +1370,26 @@ static void fixupLineNumbers(Function *Fn, Function::iterator FI,
for (; FI != Fn->end(); ++FI) {
for (BasicBlock::iterator BI = FI->begin(), BE = FI->end();
BI != BE; ++BI) {
- DebugLoc DL = BI->getDebugLoc();
- if (!DL) {
- // If the inlined instruction has no line number, make it look as if it
- // originates from the call location. This is important for
- // ((__always_inline__, __nodebug__)) functions which must use caller
- // location for all instructions in their function body.
-
- // Don't update static allocas, as they may get moved later.
- if (auto *AI = dyn_cast<AllocaInst>(BI))
- if (allocaWouldBeStaticInEntry(AI))
- continue;
-
- BI->setDebugLoc(TheCallDL);
- } else {
- BI->setDebugLoc(updateInlinedAtInfo(DL, InlinedAtNode, BI->getContext(), IANodes));
+ if (DebugLoc DL = BI->getDebugLoc()) {
+ BI->setDebugLoc(
+ updateInlinedAtInfo(DL, InlinedAtNode, BI->getContext(), IANodes));
+ continue;
}
+
+ if (CalleeHasDebugInfo)
+ continue;
+
+ // If the inlined instruction has no line number, make it look as if it
+ // originates from the call location. This is important for
+ // ((__always_inline__, __nodebug__)) functions which must use caller
+ // location for all instructions in their function body.
+
+ // Don't update static allocas, as they may get moved later.
+ if (auto *AI = dyn_cast<AllocaInst>(BI))
+ if (allocaWouldBeStaticInEntry(AI))
+ continue;
+
+ BI->setDebugLoc(TheCallDL);
}
}
}
@@ -1597,8 +1645,11 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
if (IFI.CG)
UpdateCallGraphAfterInlining(CS, FirstNewBlock, VMap, IFI);
- // Update inlined instructions' line number information.
- fixupLineNumbers(Caller, FirstNewBlock, TheCall);
+ // For 'nodebug' functions, the associated DISubprogram is always null.
+ // Conservatively avoid propagating the callsite debug location to
+ // instructions inlined from a function whose DISubprogram is not null.
+ fixupLineNumbers(Caller, FirstNewBlock, TheCall,
+ CalledFunc->getSubprogram() != nullptr);
// Clone existing noalias metadata if necessary.
CloneAliasScopeMetadata(CS, VMap);
@@ -1609,10 +1660,15 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
// Propagate llvm.mem.parallel_loop_access if necessary.
PropagateParallelLoopAccessMetadata(CS, VMap);
- // FIXME: We could register any cloned assumptions instead of clearing the
- // whole function's cache.
- if (IFI.ACT)
- IFI.ACT->getAssumptionCache(*Caller).clear();
+ // Register any cloned assumptions.
+ if (IFI.GetAssumptionCache)
+ for (BasicBlock &NewBlock :
+ make_range(FirstNewBlock->getIterator(), Caller->end()))
+ for (Instruction &I : NewBlock) {
+ if (auto *II = dyn_cast<IntrinsicInst>(&I))
+ if (II->getIntrinsicID() == Intrinsic::assume)
+ (*IFI.GetAssumptionCache)(*Caller).registerAssumption(II);
+ }
}
// If there are any alloca instructions in the block that used to be the entry
@@ -1708,6 +1764,9 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
IRBuilder<> builder(&FirstNewBlock->front());
for (unsigned ai = 0, ae = IFI.StaticAllocas.size(); ai != ae; ++ai) {
AllocaInst *AI = IFI.StaticAllocas[ai];
+ // Don't mark swifterror allocas. They can't have bitcast uses.
+ if (AI->isSwiftError())
+ continue;
// If the alloca is already scoped to something smaller than the whole
// function then there's no need to add redundant, less accurate markers.
@@ -1949,6 +2008,20 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
std::swap(Returns, NormalReturns);
}
+ // Now that all of the transforms on the inlined code have taken place but
+ // before we splice the inlined code into the CFG and lose track of which
+ // blocks were actually inlined, collect the call sites. We only do this if
+ // call graph updates weren't requested, as those provide value handle based
+ // tracking of inlined call sites instead.
+ if (InlinedFunctionInfo.ContainsCalls && !IFI.CG) {
+ // Otherwise just collect the raw call sites that were inlined.
+ for (BasicBlock &NewBB :
+ make_range(FirstNewBlock->getIterator(), Caller->end()))
+ for (Instruction &I : NewBB)
+ if (auto CS = CallSite(&I))
+ IFI.InlinedCallSites.push_back(CS);
+ }
+
// If we cloned in _exactly one_ basic block, and if that block ends in a
// return instruction, we splice the body of the inlined callee directly into
// the calling basic block.
@@ -2130,9 +2203,10 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
// the entries are the same or undef). If so, remove the PHI so it doesn't
// block other optimizations.
if (PHI) {
+ AssumptionCache *AC =
+ IFI.GetAssumptionCache ? &(*IFI.GetAssumptionCache)(*Caller) : nullptr;
auto &DL = Caller->getParent()->getDataLayout();
- if (Value *V = SimplifyInstruction(PHI, DL, nullptr, nullptr,
- &IFI.ACT->getAssumptionCache(*Caller))) {
+ if (Value *V = SimplifyInstruction(PHI, DL, nullptr, nullptr, AC)) {
PHI->replaceAllUsesWith(V);
PHI->eraseFromParent();
}
diff --git a/contrib/llvm/lib/Transforms/Utils/LCSSA.cpp b/contrib/llvm/lib/Transforms/Utils/LCSSA.cpp
index 0d5a25b..68c6b74 100644
--- a/contrib/llvm/lib/Transforms/Utils/LCSSA.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/LCSSA.cpp
@@ -51,10 +51,19 @@ using namespace llvm;
STATISTIC(NumLCSSA, "Number of live out of a loop variables");
+#ifdef EXPENSIVE_CHECKS
+static bool VerifyLoopLCSSA = true;
+#else
+static bool VerifyLoopLCSSA = false;
+#endif
+static cl::opt<bool,true>
+VerifyLoopLCSSAFlag("verify-loop-lcssa", cl::location(VerifyLoopLCSSA),
+ cl::desc("Verify loop lcssa form (time consuming)"));
+
/// Return true if the specified block is in the list.
static bool isExitBlock(BasicBlock *BB,
const SmallVectorImpl<BasicBlock *> &ExitBlocks) {
- return find(ExitBlocks, BB) != ExitBlocks.end();
+ return is_contained(ExitBlocks, BB);
}
/// For every instruction from the worklist, check to see if it has any uses
@@ -63,19 +72,25 @@ static bool isExitBlock(BasicBlock *BB,
bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
DominatorTree &DT, LoopInfo &LI) {
SmallVector<Use *, 16> UsesToRewrite;
- SmallVector<BasicBlock *, 8> ExitBlocks;
SmallSetVector<PHINode *, 16> PHIsToRemove;
PredIteratorCache PredCache;
bool Changed = false;
+ // Cache the Loop ExitBlocks across this loop. We expect to get a lot of
+ // instructions within the same loops, computing the exit blocks is
+ // expensive, and we're not mutating the loop structure.
+ SmallDenseMap<Loop*, SmallVector<BasicBlock *,1>> LoopExitBlocks;
+
while (!Worklist.empty()) {
UsesToRewrite.clear();
- ExitBlocks.clear();
Instruction *I = Worklist.pop_back_val();
BasicBlock *InstBB = I->getParent();
Loop *L = LI.getLoopFor(InstBB);
- L->getExitBlocks(ExitBlocks);
+ if (!LoopExitBlocks.count(L))
+ L->getExitBlocks(LoopExitBlocks[L]);
+ assert(LoopExitBlocks.count(L));
+ const SmallVectorImpl<BasicBlock *> &ExitBlocks = LoopExitBlocks[L];
if (ExitBlocks.empty())
continue;
@@ -186,14 +201,14 @@ bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
// Otherwise, do full PHI insertion.
SSAUpdate.RewriteUse(*UseToRewrite);
+ }
- // SSAUpdater might have inserted phi-nodes inside other loops. We'll need
- // to post-process them to keep LCSSA form.
- for (PHINode *InsertedPN : InsertedPHIs) {
- if (auto *OtherLoop = LI.getLoopFor(InsertedPN->getParent()))
- if (!L->contains(OtherLoop))
- PostProcessPHIs.push_back(InsertedPN);
- }
+ // SSAUpdater might have inserted phi-nodes inside other loops. We'll need
+ // to post-process them to keep LCSSA form.
+ for (PHINode *InsertedPN : InsertedPHIs) {
+ if (auto *OtherLoop = LI.getLoopFor(InsertedPN->getParent()))
+ if (!L->contains(OtherLoop))
+ PostProcessPHIs.push_back(InsertedPN);
}
// Post process PHI instructions that were inserted into another disjoint
@@ -229,7 +244,7 @@ blockDominatesAnExit(BasicBlock *BB,
DominatorTree &DT,
const SmallVectorImpl<BasicBlock *> &ExitBlocks) {
DomTreeNode *DomNode = DT.getNode(BB);
- return llvm::any_of(ExitBlocks, [&](BasicBlock * EB) {
+ return any_of(ExitBlocks, [&](BasicBlock *EB) {
return DT.dominates(DomNode, DT.getNode(EB));
});
}
@@ -315,6 +330,19 @@ struct LCSSAWrapperPass : public FunctionPass {
ScalarEvolution *SE;
bool runOnFunction(Function &F) override;
+ void verifyAnalysis() const override {
+ // This check is very expensive. On the loop intensive compiles it may cause
+ // up to 10x slowdown. Currently it's disabled by default. LPPassManager
+ // always does limited form of the LCSSA verification. Similar reasoning
+ // was used for the LoopInfo verifier.
+ if (VerifyLoopLCSSA) {
+ assert(all_of(*LI,
+ [&](Loop *L) {
+ return L->isRecursivelyLCSSAForm(*DT, *LI);
+ }) &&
+ "LCSSA form is broken!");
+ }
+ };
/// This transformation requires natural loop information & requires that
/// loop preheaders be inserted into the CFG. It maintains both of these,
@@ -330,6 +358,10 @@ struct LCSSAWrapperPass : public FunctionPass {
AU.addPreserved<GlobalsAAWrapperPass>();
AU.addPreserved<ScalarEvolutionWrapperPass>();
AU.addPreserved<SCEVAAWrapperPass>();
+
+ // This is needed to perform LCSSA verification inside LPPassManager
+ AU.addRequired<LCSSAVerificationPass>();
+ AU.addPreserved<LCSSAVerificationPass>();
}
};
}
@@ -339,6 +371,7 @@ INITIALIZE_PASS_BEGIN(LCSSAWrapperPass, "lcssa", "Loop-Closed SSA Form Pass",
false, false)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(LCSSAVerificationPass)
INITIALIZE_PASS_END(LCSSAWrapperPass, "lcssa", "Loop-Closed SSA Form Pass",
false, false)
@@ -355,7 +388,7 @@ bool LCSSAWrapperPass::runOnFunction(Function &F) {
return formLCSSAOnAllLoops(LI, *DT, SE);
}
-PreservedAnalyses LCSSAPass::run(Function &F, AnalysisManager<Function> &AM) {
+PreservedAnalyses LCSSAPass::run(Function &F, FunctionAnalysisManager &AM) {
auto &LI = AM.getResult<LoopAnalysis>(F);
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
auto *SE = AM.getCachedResult<ScalarEvolutionAnalysis>(F);
diff --git a/contrib/llvm/lib/Transforms/Utils/LibCallsShrinkWrap.cpp b/contrib/llvm/lib/Transforms/Utils/LibCallsShrinkWrap.cpp
new file mode 100644
index 0000000..d97cd75
--- /dev/null
+++ b/contrib/llvm/lib/Transforms/Utils/LibCallsShrinkWrap.cpp
@@ -0,0 +1,571 @@
+//===-- LibCallsShrinkWrap.cpp ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass shrink-wraps a call to function if the result is not used.
+// The call can set errno but is otherwise side effect free. For example:
+// sqrt(val);
+// is transformed to
+// if (val < 0)
+// sqrt(val);
+// Even if the result of library call is not being used, the compiler cannot
+// safely delete the call because the function can set errno on error
+// conditions.
+// Note in many functions, the error condition solely depends on the incoming
+// parameter. In this optimization, we can generate the condition can lead to
+// the errno to shrink-wrap the call. Since the chances of hitting the error
+// condition is low, the runtime call is effectively eliminated.
+//
+// These partially dead calls are usually results of C++ abstraction penalty
+// exposed by inlining.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/Utils/LibCallsShrinkWrap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Analysis/GlobalsModRef.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstVisitor.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/MDBuilder.h"
+#include "llvm/Pass.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+using namespace llvm;
+
+#define DEBUG_TYPE "libcalls-shrinkwrap"
+
+STATISTIC(NumWrappedOneCond, "Number of One-Condition Wrappers Inserted");
+STATISTIC(NumWrappedTwoCond, "Number of Two-Condition Wrappers Inserted");
+
+static cl::opt<bool> LibCallsShrinkWrapDoDomainError(
+ "libcalls-shrinkwrap-domain-error", cl::init(true), cl::Hidden,
+ cl::desc("Perform shrink-wrap on lib calls with domain errors"));
+static cl::opt<bool> LibCallsShrinkWrapDoRangeError(
+ "libcalls-shrinkwrap-range-error", cl::init(true), cl::Hidden,
+ cl::desc("Perform shrink-wrap on lib calls with range errors"));
+static cl::opt<bool> LibCallsShrinkWrapDoPoleError(
+ "libcalls-shrinkwrap-pole-error", cl::init(true), cl::Hidden,
+ cl::desc("Perform shrink-wrap on lib calls with pole errors"));
+
+namespace {
+class LibCallsShrinkWrapLegacyPass : public FunctionPass {
+public:
+ static char ID; // Pass identification, replacement for typeid
+ explicit LibCallsShrinkWrapLegacyPass() : FunctionPass(ID) {
+ initializeLibCallsShrinkWrapLegacyPassPass(
+ *PassRegistry::getPassRegistry());
+ }
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+ bool runOnFunction(Function &F) override;
+};
+}
+
+char LibCallsShrinkWrapLegacyPass::ID = 0;
+INITIALIZE_PASS_BEGIN(LibCallsShrinkWrapLegacyPass, "libcalls-shrinkwrap",
+ "Conditionally eliminate dead library calls", false,
+ false)
+INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
+INITIALIZE_PASS_END(LibCallsShrinkWrapLegacyPass, "libcalls-shrinkwrap",
+ "Conditionally eliminate dead library calls", false, false)
+
+namespace {
+class LibCallsShrinkWrap : public InstVisitor<LibCallsShrinkWrap> {
+public:
+ LibCallsShrinkWrap(const TargetLibraryInfo &TLI) : TLI(TLI), Changed(false){};
+ bool isChanged() const { return Changed; }
+ void visitCallInst(CallInst &CI) { checkCandidate(CI); }
+ void perform() {
+ for (auto &CI : WorkList) {
+ DEBUG(dbgs() << "CDCE calls: " << CI->getCalledFunction()->getName()
+ << "\n");
+ if (perform(CI)) {
+ Changed = true;
+ DEBUG(dbgs() << "Transformed\n");
+ }
+ }
+ }
+
+private:
+ bool perform(CallInst *CI);
+ void checkCandidate(CallInst &CI);
+ void shrinkWrapCI(CallInst *CI, Value *Cond);
+ bool performCallDomainErrorOnly(CallInst *CI, const LibFunc::Func &Func);
+ bool performCallErrors(CallInst *CI, const LibFunc::Func &Func);
+ bool performCallRangeErrorOnly(CallInst *CI, const LibFunc::Func &Func);
+ Value *generateOneRangeCond(CallInst *CI, const LibFunc::Func &Func);
+ Value *generateTwoRangeCond(CallInst *CI, const LibFunc::Func &Func);
+ Value *generateCondForPow(CallInst *CI, const LibFunc::Func &Func);
+
+ // Create an OR of two conditions.
+ Value *createOrCond(CallInst *CI, CmpInst::Predicate Cmp, float Val,
+ CmpInst::Predicate Cmp2, float Val2) {
+ IRBuilder<> BBBuilder(CI);
+ Value *Arg = CI->getArgOperand(0);
+ auto Cond2 = createCond(BBBuilder, Arg, Cmp2, Val2);
+ auto Cond1 = createCond(BBBuilder, Arg, Cmp, Val);
+ return BBBuilder.CreateOr(Cond1, Cond2);
+ }
+
+ // Create a single condition using IRBuilder.
+ Value *createCond(IRBuilder<> &BBBuilder, Value *Arg, CmpInst::Predicate Cmp,
+ float Val) {
+ Constant *V = ConstantFP::get(BBBuilder.getContext(), APFloat(Val));
+ if (!Arg->getType()->isFloatTy())
+ V = ConstantExpr::getFPExtend(V, Arg->getType());
+ return BBBuilder.CreateFCmp(Cmp, Arg, V);
+ }
+
+ // Create a single condition.
+ Value *createCond(CallInst *CI, CmpInst::Predicate Cmp, float Val) {
+ IRBuilder<> BBBuilder(CI);
+ Value *Arg = CI->getArgOperand(0);
+ return createCond(BBBuilder, Arg, Cmp, Val);
+ }
+
+ const TargetLibraryInfo &TLI;
+ SmallVector<CallInst *, 16> WorkList;
+ bool Changed;
+};
+} // end anonymous namespace
+
+// Perform the transformation to calls with errno set by domain error.
+bool LibCallsShrinkWrap::performCallDomainErrorOnly(CallInst *CI,
+ const LibFunc::Func &Func) {
+ Value *Cond = nullptr;
+
+ switch (Func) {
+ case LibFunc::acos: // DomainError: (x < -1 || x > 1)
+ case LibFunc::acosf: // Same as acos
+ case LibFunc::acosl: // Same as acos
+ case LibFunc::asin: // DomainError: (x < -1 || x > 1)
+ case LibFunc::asinf: // Same as asin
+ case LibFunc::asinl: // Same as asin
+ {
+ ++NumWrappedTwoCond;
+ Cond = createOrCond(CI, CmpInst::FCMP_OLT, -1.0f, CmpInst::FCMP_OGT, 1.0f);
+ break;
+ }
+ case LibFunc::cos: // DomainError: (x == +inf || x == -inf)
+ case LibFunc::cosf: // Same as cos
+ case LibFunc::cosl: // Same as cos
+ case LibFunc::sin: // DomainError: (x == +inf || x == -inf)
+ case LibFunc::sinf: // Same as sin
+ case LibFunc::sinl: // Same as sin
+ {
+ ++NumWrappedTwoCond;
+ Cond = createOrCond(CI, CmpInst::FCMP_OEQ, INFINITY, CmpInst::FCMP_OEQ,
+ -INFINITY);
+ break;
+ }
+ case LibFunc::acosh: // DomainError: (x < 1)
+ case LibFunc::acoshf: // Same as acosh
+ case LibFunc::acoshl: // Same as acosh
+ {
+ ++NumWrappedOneCond;
+ Cond = createCond(CI, CmpInst::FCMP_OLT, 1.0f);
+ break;
+ }
+ case LibFunc::sqrt: // DomainError: (x < 0)
+ case LibFunc::sqrtf: // Same as sqrt
+ case LibFunc::sqrtl: // Same as sqrt
+ {
+ ++NumWrappedOneCond;
+ Cond = createCond(CI, CmpInst::FCMP_OLT, 0.0f);
+ break;
+ }
+ default:
+ return false;
+ }
+ shrinkWrapCI(CI, Cond);
+ return true;
+}
+
+// Perform the transformation to calls with errno set by range error.
+bool LibCallsShrinkWrap::performCallRangeErrorOnly(CallInst *CI,
+ const LibFunc::Func &Func) {
+ Value *Cond = nullptr;
+
+ switch (Func) {
+ case LibFunc::cosh:
+ case LibFunc::coshf:
+ case LibFunc::coshl:
+ case LibFunc::exp:
+ case LibFunc::expf:
+ case LibFunc::expl:
+ case LibFunc::exp10:
+ case LibFunc::exp10f:
+ case LibFunc::exp10l:
+ case LibFunc::exp2:
+ case LibFunc::exp2f:
+ case LibFunc::exp2l:
+ case LibFunc::sinh:
+ case LibFunc::sinhf:
+ case LibFunc::sinhl: {
+ Cond = generateTwoRangeCond(CI, Func);
+ break;
+ }
+ case LibFunc::expm1: // RangeError: (709, inf)
+ case LibFunc::expm1f: // RangeError: (88, inf)
+ case LibFunc::expm1l: // RangeError: (11356, inf)
+ {
+ Cond = generateOneRangeCond(CI, Func);
+ break;
+ }
+ default:
+ return false;
+ }
+ shrinkWrapCI(CI, Cond);
+ return true;
+}
+
+// Perform the transformation to calls with errno set by combination of errors.
+bool LibCallsShrinkWrap::performCallErrors(CallInst *CI,
+ const LibFunc::Func &Func) {
+ Value *Cond = nullptr;
+
+ switch (Func) {
+ case LibFunc::atanh: // DomainError: (x < -1 || x > 1)
+ // PoleError: (x == -1 || x == 1)
+ // Overall Cond: (x <= -1 || x >= 1)
+ case LibFunc::atanhf: // Same as atanh
+ case LibFunc::atanhl: // Same as atanh
+ {
+ if (!LibCallsShrinkWrapDoDomainError || !LibCallsShrinkWrapDoPoleError)
+ return false;
+ ++NumWrappedTwoCond;
+ Cond = createOrCond(CI, CmpInst::FCMP_OLE, -1.0f, CmpInst::FCMP_OGE, 1.0f);
+ break;
+ }
+ case LibFunc::log: // DomainError: (x < 0)
+ // PoleError: (x == 0)
+ // Overall Cond: (x <= 0)
+ case LibFunc::logf: // Same as log
+ case LibFunc::logl: // Same as log
+ case LibFunc::log10: // Same as log
+ case LibFunc::log10f: // Same as log
+ case LibFunc::log10l: // Same as log
+ case LibFunc::log2: // Same as log
+ case LibFunc::log2f: // Same as log
+ case LibFunc::log2l: // Same as log
+ case LibFunc::logb: // Same as log
+ case LibFunc::logbf: // Same as log
+ case LibFunc::logbl: // Same as log
+ {
+ if (!LibCallsShrinkWrapDoDomainError || !LibCallsShrinkWrapDoPoleError)
+ return false;
+ ++NumWrappedOneCond;
+ Cond = createCond(CI, CmpInst::FCMP_OLE, 0.0f);
+ break;
+ }
+ case LibFunc::log1p: // DomainError: (x < -1)
+ // PoleError: (x == -1)
+ // Overall Cond: (x <= -1)
+ case LibFunc::log1pf: // Same as log1p
+ case LibFunc::log1pl: // Same as log1p
+ {
+ if (!LibCallsShrinkWrapDoDomainError || !LibCallsShrinkWrapDoPoleError)
+ return false;
+ ++NumWrappedOneCond;
+ Cond = createCond(CI, CmpInst::FCMP_OLE, -1.0f);
+ break;
+ }
+ case LibFunc::pow: // DomainError: x < 0 and y is noninteger
+ // PoleError: x == 0 and y < 0
+ // RangeError: overflow or underflow
+ case LibFunc::powf:
+ case LibFunc::powl: {
+ if (!LibCallsShrinkWrapDoDomainError || !LibCallsShrinkWrapDoPoleError ||
+ !LibCallsShrinkWrapDoRangeError)
+ return false;
+ Cond = generateCondForPow(CI, Func);
+ if (Cond == nullptr)
+ return false;
+ break;
+ }
+ default:
+ return false;
+ }
+ assert(Cond && "performCallErrors should not see an empty condition");
+ shrinkWrapCI(CI, Cond);
+ return true;
+}
+
+// Checks if CI is a candidate for shrinkwrapping and put it into work list if
+// true.
+void LibCallsShrinkWrap::checkCandidate(CallInst &CI) {
+ if (CI.isNoBuiltin())
+ return;
+ // A possible improvement is to handle the calls with the return value being
+ // used. If there is API for fast libcall implementation without setting
+ // errno, we can use the same framework to direct/wrap the call to the fast
+ // API in the error free path, and leave the original call in the slow path.
+ if (!CI.use_empty())
+ return;
+
+ LibFunc::Func Func;
+ Function *Callee = CI.getCalledFunction();
+ if (!Callee)
+ return;
+ if (!TLI.getLibFunc(*Callee, Func) || !TLI.has(Func))
+ return;
+
+ if (CI.getNumArgOperands() == 0)
+ return;
+ // TODO: Handle long double in other formats.
+ Type *ArgType = CI.getArgOperand(0)->getType();
+ if (!(ArgType->isFloatTy() || ArgType->isDoubleTy() ||
+ ArgType->isX86_FP80Ty()))
+ return;
+
+ WorkList.push_back(&CI);
+}
+
+// Generate the upper bound condition for RangeError.
+Value *LibCallsShrinkWrap::generateOneRangeCond(CallInst *CI,
+ const LibFunc::Func &Func) {
+ float UpperBound;
+ switch (Func) {
+ case LibFunc::expm1: // RangeError: (709, inf)
+ UpperBound = 709.0f;
+ break;
+ case LibFunc::expm1f: // RangeError: (88, inf)
+ UpperBound = 88.0f;
+ break;
+ case LibFunc::expm1l: // RangeError: (11356, inf)
+ UpperBound = 11356.0f;
+ break;
+ default:
+ llvm_unreachable("Should be reach here");
+ }
+
+ ++NumWrappedOneCond;
+ return createCond(CI, CmpInst::FCMP_OGT, UpperBound);
+}
+
+// Generate the lower and upper bound condition for RangeError.
+Value *LibCallsShrinkWrap::generateTwoRangeCond(CallInst *CI,
+ const LibFunc::Func &Func) {
+ float UpperBound, LowerBound;
+ switch (Func) {
+ case LibFunc::cosh: // RangeError: (x < -710 || x > 710)
+ case LibFunc::sinh: // Same as cosh
+ LowerBound = -710.0f;
+ UpperBound = 710.0f;
+ break;
+ case LibFunc::coshf: // RangeError: (x < -89 || x > 89)
+ case LibFunc::sinhf: // Same as coshf
+ LowerBound = -89.0f;
+ UpperBound = 89.0f;
+ break;
+ case LibFunc::coshl: // RangeError: (x < -11357 || x > 11357)
+ case LibFunc::sinhl: // Same as coshl
+ LowerBound = -11357.0f;
+ UpperBound = 11357.0f;
+ break;
+ case LibFunc::exp: // RangeError: (x < -745 || x > 709)
+ LowerBound = -745.0f;
+ UpperBound = 709.0f;
+ break;
+ case LibFunc::expf: // RangeError: (x < -103 || x > 88)
+ LowerBound = -103.0f;
+ UpperBound = 88.0f;
+ break;
+ case LibFunc::expl: // RangeError: (x < -11399 || x > 11356)
+ LowerBound = -11399.0f;
+ UpperBound = 11356.0f;
+ break;
+ case LibFunc::exp10: // RangeError: (x < -323 || x > 308)
+ LowerBound = -323.0f;
+ UpperBound = 308.0f;
+ break;
+ case LibFunc::exp10f: // RangeError: (x < -45 || x > 38)
+ LowerBound = -45.0f;
+ UpperBound = 38.0f;
+ break;
+ case LibFunc::exp10l: // RangeError: (x < -4950 || x > 4932)
+ LowerBound = -4950.0f;
+ UpperBound = 4932.0f;
+ break;
+ case LibFunc::exp2: // RangeError: (x < -1074 || x > 1023)
+ LowerBound = -1074.0f;
+ UpperBound = 1023.0f;
+ break;
+ case LibFunc::exp2f: // RangeError: (x < -149 || x > 127)
+ LowerBound = -149.0f;
+ UpperBound = 127.0f;
+ break;
+ case LibFunc::exp2l: // RangeError: (x < -16445 || x > 11383)
+ LowerBound = -16445.0f;
+ UpperBound = 11383.0f;
+ break;
+ default:
+ llvm_unreachable("Should be reach here");
+ }
+
+ ++NumWrappedTwoCond;
+ return createOrCond(CI, CmpInst::FCMP_OGT, UpperBound, CmpInst::FCMP_OLT,
+ LowerBound);
+}
+
+// For pow(x,y), We only handle the following cases:
+// (1) x is a constant && (x >= 1) && (x < MaxUInt8)
+// Cond is: (y > 127)
+// (2) x is a value coming from an integer type.
+// (2.1) if x's bit_size == 8
+// Cond: (x <= 0 || y > 128)
+// (2.2) if x's bit_size is 16
+// Cond: (x <= 0 || y > 64)
+// (2.3) if x's bit_size is 32
+// Cond: (x <= 0 || y > 32)
+// Support for powl(x,y) and powf(x,y) are TBD.
+//
+// Note that condition can be more conservative than the actual condition
+// (i.e. we might invoke the calls that will not set the errno.).
+//
+Value *LibCallsShrinkWrap::generateCondForPow(CallInst *CI,
+ const LibFunc::Func &Func) {
+ // FIXME: LibFunc::powf and powl TBD.
+ if (Func != LibFunc::pow) {
+ DEBUG(dbgs() << "Not handled powf() and powl()\n");
+ return nullptr;
+ }
+
+ Value *Base = CI->getArgOperand(0);
+ Value *Exp = CI->getArgOperand(1);
+ IRBuilder<> BBBuilder(CI);
+
+ // Constant Base case.
+ if (ConstantFP *CF = dyn_cast<ConstantFP>(Base)) {
+ double D = CF->getValueAPF().convertToDouble();
+ if (D < 1.0f || D > APInt::getMaxValue(8).getZExtValue()) {
+ DEBUG(dbgs() << "Not handled pow(): constant base out of range\n");
+ return nullptr;
+ }
+
+ ++NumWrappedOneCond;
+ Constant *V = ConstantFP::get(CI->getContext(), APFloat(127.0f));
+ if (!Exp->getType()->isFloatTy())
+ V = ConstantExpr::getFPExtend(V, Exp->getType());
+ return BBBuilder.CreateFCmp(CmpInst::FCMP_OGT, Exp, V);
+ }
+
+ // If the Base value coming from an integer type.
+ Instruction *I = dyn_cast<Instruction>(Base);
+ if (!I) {
+ DEBUG(dbgs() << "Not handled pow(): FP type base\n");
+ return nullptr;
+ }
+ unsigned Opcode = I->getOpcode();
+ if (Opcode == Instruction::UIToFP || Opcode == Instruction::SIToFP) {
+ unsigned BW = I->getOperand(0)->getType()->getPrimitiveSizeInBits();
+ float UpperV = 0.0f;
+ if (BW == 8)
+ UpperV = 128.0f;
+ else if (BW == 16)
+ UpperV = 64.0f;
+ else if (BW == 32)
+ UpperV = 32.0f;
+ else {
+ DEBUG(dbgs() << "Not handled pow(): type too wide\n");
+ return nullptr;
+ }
+
+ ++NumWrappedTwoCond;
+ Constant *V = ConstantFP::get(CI->getContext(), APFloat(UpperV));
+ Constant *V0 = ConstantFP::get(CI->getContext(), APFloat(0.0f));
+ if (!Exp->getType()->isFloatTy())
+ V = ConstantExpr::getFPExtend(V, Exp->getType());
+ if (!Base->getType()->isFloatTy())
+ V0 = ConstantExpr::getFPExtend(V0, Exp->getType());
+
+ Value *Cond = BBBuilder.CreateFCmp(CmpInst::FCMP_OGT, Exp, V);
+ Value *Cond0 = BBBuilder.CreateFCmp(CmpInst::FCMP_OLE, Base, V0);
+ return BBBuilder.CreateOr(Cond0, Cond);
+ }
+ DEBUG(dbgs() << "Not handled pow(): base not from integer convert\n");
+ return nullptr;
+}
+
+// Wrap conditions that can potentially generate errno to the library call.
+void LibCallsShrinkWrap::shrinkWrapCI(CallInst *CI, Value *Cond) {
+ assert(Cond != nullptr && "hrinkWrapCI is not expecting an empty call inst");
+ MDNode *BranchWeights =
+ MDBuilder(CI->getContext()).createBranchWeights(1, 2000);
+ TerminatorInst *NewInst =
+ SplitBlockAndInsertIfThen(Cond, CI, false, BranchWeights);
+ BasicBlock *CallBB = NewInst->getParent();
+ CallBB->setName("cdce.call");
+ CallBB->getSingleSuccessor()->setName("cdce.end");
+ CI->removeFromParent();
+ CallBB->getInstList().insert(CallBB->getFirstInsertionPt(), CI);
+ DEBUG(dbgs() << "== Basic Block After ==");
+ DEBUG(dbgs() << *CallBB->getSinglePredecessor() << *CallBB
+ << *CallBB->getSingleSuccessor() << "\n");
+}
+
+// Perform the transformation to a single candidate.
+bool LibCallsShrinkWrap::perform(CallInst *CI) {
+ LibFunc::Func Func;
+ Function *Callee = CI->getCalledFunction();
+ assert(Callee && "perform() should apply to a non-empty callee");
+ TLI.getLibFunc(*Callee, Func);
+ assert(Func && "perform() is not expecting an empty function");
+
+ if (LibCallsShrinkWrapDoDomainError && performCallDomainErrorOnly(CI, Func))
+ return true;
+
+ if (LibCallsShrinkWrapDoRangeError && performCallRangeErrorOnly(CI, Func))
+ return true;
+
+ return performCallErrors(CI, Func);
+}
+
+void LibCallsShrinkWrapLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addPreserved<GlobalsAAWrapperPass>();
+ AU.addRequired<TargetLibraryInfoWrapperPass>();
+}
+
+static bool runImpl(Function &F, const TargetLibraryInfo &TLI) {
+ if (F.hasFnAttribute(Attribute::OptimizeForSize))
+ return false;
+ LibCallsShrinkWrap CCDCE(TLI);
+ CCDCE.visit(F);
+ CCDCE.perform();
+ return CCDCE.isChanged();
+}
+
+bool LibCallsShrinkWrapLegacyPass::runOnFunction(Function &F) {
+ auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
+ return runImpl(F, TLI);
+}
+
+namespace llvm {
+char &LibCallsShrinkWrapPassID = LibCallsShrinkWrapLegacyPass::ID;
+
+// Public interface to LibCallsShrinkWrap pass.
+FunctionPass *createLibCallsShrinkWrapPass() {
+ return new LibCallsShrinkWrapLegacyPass();
+}
+
+PreservedAnalyses LibCallsShrinkWrapPass::run(Function &F,
+ FunctionAnalysisManager &FAM) {
+ auto &TLI = FAM.getResult<TargetLibraryAnalysis>(F);
+ bool Changed = runImpl(F, TLI);
+ if (!Changed)
+ return PreservedAnalyses::all();
+ auto PA = PreservedAnalyses();
+ PA.preserve<GlobalsAA>();
+ return PA;
+}
+}
diff --git a/contrib/llvm/lib/Transforms/Utils/Local.cpp b/contrib/llvm/lib/Transforms/Utils/Local.cpp
index f1838d8..6e4174a 100644
--- a/contrib/llvm/lib/Transforms/Utils/Local.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/Local.cpp
@@ -340,6 +340,10 @@ bool llvm::isInstructionTriviallyDead(Instruction *I,
if (Constant *C = dyn_cast<Constant>(CI->getArgOperand(0)))
return C->isNullValue() || isa<UndefValue>(C);
+ if (CallSite CS = CallSite(I))
+ if (isMathLibCallNoop(CS, TLI))
+ return true;
+
return false;
}
@@ -886,6 +890,17 @@ bool llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB) {
}
}
+ // If the unconditional branch we replaced contains llvm.loop metadata, we
+ // add the metadata to the branch instructions in the predecessors.
+ unsigned LoopMDKind = BB->getContext().getMDKindID("llvm.loop");
+ Instruction *TI = BB->getTerminator();
+ if (TI)
+ if (MDNode *LoopMD = TI->getMetadata(LoopMDKind))
+ for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) {
+ BasicBlock *Pred = *PI;
+ Pred->getTerminator()->setMetadata(LoopMDKind, LoopMD);
+ }
+
// Everything that jumped to BB now goes to Succ.
BB->replaceAllUsesWith(Succ);
if (!Succ->hasName()) Succ->takeName(BB);
@@ -1001,10 +1016,6 @@ static unsigned enforceKnownAlignment(Value *V, unsigned Align,
return Align;
}
-/// getOrEnforceKnownAlignment - If the specified pointer has an alignment that
-/// we can determine, return it, otherwise return 0. If PrefAlign is specified,
-/// and it is more than the alignment of the ultimate object, see if we can
-/// increase the alignment of the ultimate object, making this check succeed.
unsigned llvm::getOrEnforceKnownAlignment(Value *V, unsigned PrefAlign,
const DataLayout &DL,
const Instruction *CxtI,
@@ -1057,9 +1068,27 @@ static bool LdStHasDebugValue(DILocalVariable *DIVar, DIExpression *DIExpr,
return false;
}
+/// See if there is a dbg.value intrinsic for DIVar for the PHI node.
+static bool PhiHasDebugValue(DILocalVariable *DIVar,
+ DIExpression *DIExpr,
+ PHINode *APN) {
+ // Since we can't guarantee that the original dbg.declare instrinsic
+ // is removed by LowerDbgDeclare(), we need to make sure that we are
+ // not inserting the same dbg.value intrinsic over and over.
+ DbgValueList DbgValues;
+ FindAllocaDbgValues(DbgValues, APN);
+ for (auto DVI : DbgValues) {
+ assert (DVI->getValue() == APN);
+ assert (DVI->getOffset() == 0);
+ if ((DVI->getVariable() == DIVar) && (DVI->getExpression() == DIExpr))
+ return true;
+ }
+ return false;
+}
+
/// Inserts a llvm.dbg.value intrinsic before a store to an alloca'd value
/// that has an associated llvm.dbg.decl intrinsic.
-bool llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
+void llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
StoreInst *SI, DIBuilder &Builder) {
auto *DIVar = DDI->getVariable();
auto *DIExpr = DDI->getExpression();
@@ -1073,26 +1102,27 @@ bool llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
if (SExtInst *SExt = dyn_cast<SExtInst>(SI->getOperand(0)))
ExtendedArg = dyn_cast<Argument>(SExt->getOperand(0));
if (ExtendedArg) {
- // We're now only describing a subset of the variable. The piece we're
+ // We're now only describing a subset of the variable. The fragment we're
// describing will always be smaller than the variable size, because
// VariableSize == Size of Alloca described by DDI. Since SI stores
// to the alloca described by DDI, if it's first operand is an extend,
// we're guaranteed that before extension, the value was narrower than
// the size of the alloca, hence the size of the described variable.
SmallVector<uint64_t, 3> Ops;
- unsigned PieceOffset = 0;
- // If this already is a bit piece, we drop the bit piece from the expression
- // and record the offset.
- if (DIExpr->isBitPiece()) {
+ unsigned FragmentOffset = 0;
+ // If this already is a bit fragment, we drop the bit fragment from the
+ // expression and record the offset.
+ auto Fragment = DIExpr->getFragmentInfo();
+ if (Fragment) {
Ops.append(DIExpr->elements_begin(), DIExpr->elements_end()-3);
- PieceOffset = DIExpr->getBitPieceOffset();
+ FragmentOffset = Fragment->OffsetInBits;
} else {
Ops.append(DIExpr->elements_begin(), DIExpr->elements_end());
}
- Ops.push_back(dwarf::DW_OP_bit_piece);
- Ops.push_back(PieceOffset); // Offset
+ Ops.push_back(dwarf::DW_OP_LLVM_fragment);
+ Ops.push_back(FragmentOffset);
const DataLayout &DL = DDI->getModule()->getDataLayout();
- Ops.push_back(DL.getTypeSizeInBits(ExtendedArg->getType())); // Size
+ Ops.push_back(DL.getTypeSizeInBits(ExtendedArg->getType()));
auto NewDIExpr = Builder.createExpression(Ops);
if (!LdStHasDebugValue(DIVar, NewDIExpr, SI))
Builder.insertDbgValueIntrinsic(ExtendedArg, 0, DIVar, NewDIExpr,
@@ -1100,19 +1130,18 @@ bool llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
} else if (!LdStHasDebugValue(DIVar, DIExpr, SI))
Builder.insertDbgValueIntrinsic(SI->getOperand(0), 0, DIVar, DIExpr,
DDI->getDebugLoc(), SI);
- return true;
}
/// Inserts a llvm.dbg.value intrinsic before a load of an alloca'd value
/// that has an associated llvm.dbg.decl intrinsic.
-bool llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
+void llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
LoadInst *LI, DIBuilder &Builder) {
auto *DIVar = DDI->getVariable();
auto *DIExpr = DDI->getExpression();
assert(DIVar && "Missing variable");
if (LdStHasDebugValue(DIVar, DIExpr, LI))
- return true;
+ return;
// We are now tracking the loaded value instead of the address. In the
// future if multi-location support is added to the IR, it might be
@@ -1121,7 +1150,28 @@ bool llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
Instruction *DbgValue = Builder.insertDbgValueIntrinsic(
LI, 0, DIVar, DIExpr, DDI->getDebugLoc(), (Instruction *)nullptr);
DbgValue->insertAfter(LI);
- return true;
+}
+
+/// Inserts a llvm.dbg.value intrinsic after a phi
+/// that has an associated llvm.dbg.decl intrinsic.
+void llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
+ PHINode *APN, DIBuilder &Builder) {
+ auto *DIVar = DDI->getVariable();
+ auto *DIExpr = DDI->getExpression();
+ assert(DIVar && "Missing variable");
+
+ if (PhiHasDebugValue(DIVar, DIExpr, APN))
+ return;
+
+ BasicBlock *BB = APN->getParent();
+ auto InsertionPt = BB->getFirstInsertionPt();
+
+ // The block may be a catchswitch block, which does not have a valid
+ // insertion point.
+ // FIXME: Insert dbg.value markers in the successors when appropriate.
+ if (InsertionPt != BB->end())
+ Builder.insertDbgValueIntrinsic(APN, 0, DIVar, DIExpr, DDI->getDebugLoc(),
+ &*InsertionPt);
}
/// Determine whether this alloca is either a VLA or an array.
@@ -1191,6 +1241,16 @@ DbgDeclareInst *llvm::FindAllocaDbgDeclare(Value *V) {
return nullptr;
}
+/// FindAllocaDbgValues - Finds the llvm.dbg.value intrinsics describing the
+/// alloca 'V', if any.
+void llvm::FindAllocaDbgValues(DbgValueList &DbgValues, Value *V) {
+ if (auto *L = LocalAsMetadata::getIfExists(V))
+ if (auto *MDV = MetadataAsValue::getIfExists(V->getContext(), L))
+ for (User *U : MDV->users())
+ if (DbgValueInst *DVI = dyn_cast<DbgValueInst>(U))
+ DbgValues.push_back(DVI);
+}
+
static void DIExprAddDeref(SmallVectorImpl<uint64_t> &Expr) {
Expr.push_back(dwarf::DW_OP_deref);
}
@@ -1310,12 +1370,13 @@ unsigned llvm::removeAllNonTerminatorAndEHPadInstructions(BasicBlock *BB) {
return NumDeadInst;
}
-unsigned llvm::changeToUnreachable(Instruction *I, bool UseLLVMTrap) {
+unsigned llvm::changeToUnreachable(Instruction *I, bool UseLLVMTrap,
+ bool PreserveLCSSA) {
BasicBlock *BB = I->getParent();
// Loop over all of the successors, removing BB's entry from any PHI
// nodes.
for (BasicBlock *Successor : successors(BB))
- Successor->removePredecessor(BB);
+ Successor->removePredecessor(BB, PreserveLCSSA);
// Insert a call to llvm.trap right before this. This turns the undefined
// behavior into a hard fail instead of falling through into random code.
@@ -1360,6 +1421,43 @@ static void changeToCall(InvokeInst *II) {
II->eraseFromParent();
}
+BasicBlock *llvm::changeToInvokeAndSplitBasicBlock(CallInst *CI,
+ BasicBlock *UnwindEdge) {
+ BasicBlock *BB = CI->getParent();
+
+ // Convert this function call into an invoke instruction. First, split the
+ // basic block.
+ BasicBlock *Split =
+ BB->splitBasicBlock(CI->getIterator(), CI->getName() + ".noexc");
+
+ // Delete the unconditional branch inserted by splitBasicBlock
+ BB->getInstList().pop_back();
+
+ // Create the new invoke instruction.
+ SmallVector<Value *, 8> InvokeArgs(CI->arg_begin(), CI->arg_end());
+ SmallVector<OperandBundleDef, 1> OpBundles;
+
+ CI->getOperandBundlesAsDefs(OpBundles);
+
+ // Note: we're round tripping operand bundles through memory here, and that
+ // can potentially be avoided with a cleverer API design that we do not have
+ // as of this time.
+
+ InvokeInst *II = InvokeInst::Create(CI->getCalledValue(), Split, UnwindEdge,
+ InvokeArgs, OpBundles, CI->getName(), BB);
+ II->setDebugLoc(CI->getDebugLoc());
+ II->setCallingConv(CI->getCallingConv());
+ II->setAttributes(CI->getAttributes());
+
+ // Make sure that anything using the call now uses the invoke! This also
+ // updates the CallGraph if present, because it uses a WeakVH.
+ CI->replaceAllUsesWith(II);
+
+ // Delete the original call
+ Split->getInstList().pop_front();
+ return Split;
+}
+
static bool markAliveBlocks(Function &F,
SmallPtrSetImpl<BasicBlock*> &Reachable) {
@@ -1586,10 +1684,10 @@ void llvm::combineMetadata(Instruction *K, const Instruction *J,
SmallVector<std::pair<unsigned, MDNode *>, 4> Metadata;
K->dropUnknownNonDebugMetadata(KnownIDs);
K->getAllMetadataOtherThanDebugLoc(Metadata);
- for (unsigned i = 0, n = Metadata.size(); i < n; ++i) {
- unsigned Kind = Metadata[i].first;
+ for (const auto &MD : Metadata) {
+ unsigned Kind = MD.first;
MDNode *JMD = J->getMetadata(Kind);
- MDNode *KMD = Metadata[i].second;
+ MDNode *KMD = MD.second;
switch (Kind) {
default:
@@ -1646,6 +1744,17 @@ void llvm::combineMetadata(Instruction *K, const Instruction *J,
K->setMetadata(LLVMContext::MD_invariant_group, JMD);
}
+void llvm::combineMetadataForCSE(Instruction *K, const Instruction *J) {
+ unsigned KnownIDs[] = {
+ LLVMContext::MD_tbaa, LLVMContext::MD_alias_scope,
+ LLVMContext::MD_noalias, LLVMContext::MD_range,
+ LLVMContext::MD_invariant_load, LLVMContext::MD_nonnull,
+ LLVMContext::MD_invariant_group, LLVMContext::MD_align,
+ LLVMContext::MD_dereferenceable,
+ LLVMContext::MD_dereferenceable_or_null};
+ combineMetadata(K, J, KnownIDs);
+}
+
unsigned llvm::replaceDominatedUsesWith(Value *From, Value *To,
DominatorTree &DT,
const BasicBlockEdge &Root) {
@@ -1703,6 +1812,7 @@ bool llvm::callsGCLeafFunction(ImmutableCallSite CS) {
return false;
}
+namespace {
/// A potential constituent of a bitreverse or bswap expression. See
/// collectBitParts for a fuller explanation.
struct BitPart {
@@ -1718,6 +1828,7 @@ struct BitPart {
enum { Unset = -1 };
};
+} // end anonymous namespace
/// Analyze the specified subexpression and see if it is capable of providing
/// pieces of a bswap or bitreverse. The subexpression provides a potential
@@ -1954,23 +2065,12 @@ bool llvm::recognizeBSwapOrBitReverseIdiom(
// in ASan/MSan/TSan/DFSan, and thus make us miss some memory accesses,
// we mark affected calls as NoBuiltin, which will disable optimization
// in CodeGen.
-void llvm::maybeMarkSanitizerLibraryCallNoBuiltin(CallInst *CI,
- const TargetLibraryInfo *TLI) {
+void llvm::maybeMarkSanitizerLibraryCallNoBuiltin(
+ CallInst *CI, const TargetLibraryInfo *TLI) {
Function *F = CI->getCalledFunction();
LibFunc::Func Func;
- if (!F || F->hasLocalLinkage() || !F->hasName() ||
- !TLI->getLibFunc(F->getName(), Func))
- return;
- switch (Func) {
- default: break;
- case LibFunc::memcmp:
- case LibFunc::memchr:
- case LibFunc::strcpy:
- case LibFunc::stpcpy:
- case LibFunc::strcmp:
- case LibFunc::strlen:
- case LibFunc::strnlen:
- CI->addAttribute(AttributeSet::FunctionIndex, Attribute::NoBuiltin);
- break;
- }
+ if (F && !F->hasLocalLinkage() && F->hasName() &&
+ TLI->getLibFunc(F->getName(), Func) && TLI->hasOptimizedCodeGen(Func) &&
+ !F->doesNotAccessMemory())
+ CI->addAttribute(AttributeSet::FunctionIndex, Attribute::NoBuiltin);
}
diff --git a/contrib/llvm/lib/Transforms/Utils/LoopSimplify.cpp b/contrib/llvm/lib/Transforms/Utils/LoopSimplify.cpp
index 2846e8f..00cda2a 100644
--- a/contrib/llvm/lib/Transforms/Utils/LoopSimplify.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/LoopSimplify.cpp
@@ -361,25 +361,12 @@ static Loop *separateNestedLoop(Loop *L, BasicBlock *Preheader,
// Fix LCSSA form for L. Some values, which previously were only used inside
// L, can now be used in NewOuter loop. We need to insert phi-nodes for them
// in corresponding exit blocks.
+ // We don't need to form LCSSA recursively, because there cannot be uses
+ // inside a newly created loop of defs from inner loops as those would
+ // already be a use of an LCSSA phi node.
+ formLCSSA(*L, *DT, LI, SE);
- // Go through all instructions in OuterLoopBlocks and check if they are
- // using operands from the inner loop. In this case we'll need to fix LCSSA
- // for these instructions.
- SmallSetVector<Instruction *, 8> WorklistSet;
- for (BasicBlock *OuterBB: OuterLoopBlocks) {
- for (Instruction &I : *OuterBB) {
- for (Value *Op : I.operands()) {
- Instruction *OpI = dyn_cast<Instruction>(Op);
- if (!OpI || !L->contains(OpI))
- continue;
- WorklistSet.insert(OpI);
- }
- }
- }
- SmallVector<Instruction *, 8> Worklist(WorklistSet.begin(),
- WorklistSet.end());
- formLCSSAForInstructions(Worklist, *DT, *LI);
- assert(NewOuter->isRecursivelyLCSSAForm(*DT) &&
+ assert(NewOuter->isRecursivelyLCSSAForm(*DT, *LI) &&
"LCSSA is broken after separating nested loops!");
}
@@ -483,13 +470,21 @@ static BasicBlock *insertUniqueBackedgeBlock(Loop *L, BasicBlock *Preheader,
}
// Now that all of the PHI nodes have been inserted and adjusted, modify the
- // backedge blocks to just to the BEBlock instead of the header.
+ // backedge blocks to jump to the BEBlock instead of the header.
+ // If one of the backedges has llvm.loop metadata attached, we remove
+ // it from the backedge and add it to BEBlock.
+ unsigned LoopMDKind = BEBlock->getContext().getMDKindID("llvm.loop");
+ MDNode *LoopMD = nullptr;
for (unsigned i = 0, e = BackedgeBlocks.size(); i != e; ++i) {
TerminatorInst *TI = BackedgeBlocks[i]->getTerminator();
+ if (!LoopMD)
+ LoopMD = TI->getMetadata(LoopMDKind);
+ TI->setMetadata(LoopMDKind, nullptr);
for (unsigned Op = 0, e = TI->getNumSuccessors(); Op != e; ++Op)
if (TI->getSuccessor(Op) == Header)
TI->setSuccessor(Op, BEBlock);
}
+ BEBlock->getTerminator()->setMetadata(LoopMDKind, LoopMD);
//===--- Update all analyses which we must preserve now -----------------===//
@@ -535,7 +530,7 @@ ReprocessLoop:
// Zap the dead pred's terminator and replace it with unreachable.
TerminatorInst *TI = P->getTerminator();
- changeToUnreachable(TI, /*UseLLVMTrap=*/false);
+ changeToUnreachable(TI, /*UseLLVMTrap=*/false, PreserveLCSSA);
Changed = true;
}
}
@@ -635,8 +630,10 @@ ReprocessLoop:
(PN = dyn_cast<PHINode>(I++)); )
if (Value *V = SimplifyInstruction(PN, DL, nullptr, DT, AC)) {
if (SE) SE->forgetValue(PN);
- PN->replaceAllUsesWith(V);
- PN->eraseFromParent();
+ if (!PreserveLCSSA || LI->replacementPreservesLCSSAForm(PN, V)) {
+ PN->replaceAllUsesWith(V);
+ PN->eraseFromParent();
+ }
}
// If this loop has multiple exits and the exits all go to the same
@@ -821,8 +818,8 @@ bool LoopSimplify::runOnFunction(Function &F) {
if (PreserveLCSSA) {
assert(DT && "DT not available.");
assert(LI && "LI not available.");
- bool InLCSSA =
- all_of(*LI, [&](Loop *L) { return L->isRecursivelyLCSSAForm(*DT); });
+ bool InLCSSA = all_of(
+ *LI, [&](Loop *L) { return L->isRecursivelyLCSSAForm(*DT, *LI); });
assert(InLCSSA && "Requested to preserve LCSSA, but it's already broken.");
}
#endif
@@ -833,8 +830,8 @@ bool LoopSimplify::runOnFunction(Function &F) {
#ifndef NDEBUG
if (PreserveLCSSA) {
- bool InLCSSA =
- all_of(*LI, [&](Loop *L) { return L->isRecursivelyLCSSAForm(*DT); });
+ bool InLCSSA = all_of(
+ *LI, [&](Loop *L) { return L->isRecursivelyLCSSAForm(*DT, *LI); });
assert(InLCSSA && "LCSSA is broken after loop-simplify.");
}
#endif
@@ -842,7 +839,7 @@ bool LoopSimplify::runOnFunction(Function &F) {
}
PreservedAnalyses LoopSimplifyPass::run(Function &F,
- AnalysisManager<Function> &AM) {
+ FunctionAnalysisManager &AM) {
bool Changed = false;
LoopInfo *LI = &AM.getResult<LoopAnalysis>(F);
DominatorTree *DT = &AM.getResult<DominatorTreeAnalysis>(F);
@@ -854,6 +851,10 @@ PreservedAnalyses LoopSimplifyPass::run(Function &F,
for (LoopInfo::iterator I = LI->begin(), E = LI->end(); I != E; ++I)
Changed |= simplifyLoop(*I, DT, LI, SE, AC, true /* PreserveLCSSA */);
+ // FIXME: We need to invalidate this to avoid PR28400. Is there a better
+ // solution?
+ AM.invalidate<ScalarEvolutionAnalysis>(F);
+
if (!Changed)
return PreservedAnalyses::all();
PreservedAnalyses PA;
diff --git a/contrib/llvm/lib/Transforms/Utils/LoopUnroll.cpp b/contrib/llvm/lib/Transforms/Utils/LoopUnroll.cpp
index 7f1f78f..e346ebd 100644
--- a/contrib/llvm/lib/Transforms/Utils/LoopUnroll.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/LoopUnroll.cpp
@@ -23,11 +23,12 @@
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/LoopIterator.h"
#include "llvm/Analysis/LoopPass.h"
+#include "llvm/Analysis/OptimizationDiagnosticInfo.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/Dominators.h"
+#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
@@ -46,7 +47,7 @@ STATISTIC(NumCompletelyUnrolled, "Number of loops completely unrolled");
STATISTIC(NumUnrolled, "Number of loops unrolled (completely or otherwise)");
static cl::opt<bool>
-UnrollRuntimeEpilog("unroll-runtime-epilog", cl::init(true), cl::Hidden,
+UnrollRuntimeEpilog("unroll-runtime-epilog", cl::init(false), cl::Hidden,
cl::desc("Allow runtime unrolled loops to be unrolled "
"with epilog instead of prolog."));
@@ -171,20 +172,58 @@ static bool needToInsertPhisForLCSSA(Loop *L, std::vector<BasicBlock *> Blocks,
return false;
}
+/// Adds ClonedBB to LoopInfo, creates a new loop for ClonedBB if necessary
+/// and adds a mapping from the original loop to the new loop to NewLoops.
+/// Returns nullptr if no new loop was created and a pointer to the
+/// original loop OriginalBB was part of otherwise.
+const Loop* llvm::addClonedBlockToLoopInfo(BasicBlock *OriginalBB,
+ BasicBlock *ClonedBB, LoopInfo *LI,
+ NewLoopsMap &NewLoops) {
+ // Figure out which loop New is in.
+ const Loop *OldLoop = LI->getLoopFor(OriginalBB);
+ assert(OldLoop && "Should (at least) be in the loop being unrolled!");
+
+ Loop *&NewLoop = NewLoops[OldLoop];
+ if (!NewLoop) {
+ // Found a new sub-loop.
+ assert(OriginalBB == OldLoop->getHeader() &&
+ "Header should be first in RPO");
+
+ NewLoop = new Loop();
+ Loop *NewLoopParent = NewLoops.lookup(OldLoop->getParentLoop());
+
+ if (NewLoopParent)
+ NewLoopParent->addChildLoop(NewLoop);
+ else
+ LI->addTopLevelLoop(NewLoop);
+
+ NewLoop->addBasicBlockToLoop(ClonedBB, *LI);
+ return OldLoop;
+ } else {
+ NewLoop->addBasicBlockToLoop(ClonedBB, *LI);
+ return nullptr;
+ }
+}
+
/// Unroll the given loop by Count. The loop must be in LCSSA form. Returns true
/// if unrolling was successful, or false if the loop was unmodified. Unrolling
/// can only fail when the loop's latch block is not terminated by a conditional
/// branch instruction. However, if the trip count (and multiple) are not known,
/// loop unrolling will mostly produce more code that is no faster.
///
-/// TripCount is generally defined as the number of times the loop header
-/// executes. UnrollLoop relaxes the definition to permit early exits: here
-/// TripCount is the iteration on which control exits LatchBlock if no early
-/// exits were taken. Note that UnrollLoop assumes that the loop counter test
-/// terminates LatchBlock in order to remove unnecesssary instances of the
-/// test. In other words, control may exit the loop prior to TripCount
-/// iterations via an early branch, but control may not exit the loop from the
-/// LatchBlock's terminator prior to TripCount iterations.
+/// TripCount is the upper bound of the iteration on which control exits
+/// LatchBlock. Control may exit the loop prior to TripCount iterations either
+/// via an early branch in other loop block or via LatchBlock terminator. This
+/// is relaxed from the general definition of trip count which is the number of
+/// times the loop header executes. Note that UnrollLoop assumes that the loop
+/// counter test is in LatchBlock in order to remove unnecesssary instances of
+/// the test. If control can exit the loop from the LatchBlock's terminator
+/// prior to TripCount iterations, flag PreserveCondBr needs to be set.
+///
+/// PreserveCondBr indicates whether the conditional branch of the LatchBlock
+/// needs to be preserved. It is needed when we use trip count upper bound to
+/// fully unroll the loop. If PreserveOnlyFirst is also set then only the first
+/// conditional branch needs to be preserved.
///
/// Similarly, TripMultiple divides the number of times that the LatchBlock may
/// execute without exiting the loop.
@@ -196,15 +235,21 @@ static bool needToInsertPhisForLCSSA(Loop *L, std::vector<BasicBlock *> Blocks,
/// runtime-unroll the loop if computing RuntimeTripCount will be expensive and
/// AllowExpensiveTripCount is false.
///
+/// If we want to perform PGO-based loop peeling, PeelCount is set to the
+/// number of iterations we want to peel off.
+///
/// The LoopInfo Analysis that is passed will be kept consistent.
///
/// This utility preserves LoopInfo. It will also preserve ScalarEvolution and
/// DominatorTree if they are non-null.
bool llvm::UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool Force,
bool AllowRuntime, bool AllowExpensiveTripCount,
- unsigned TripMultiple, LoopInfo *LI, ScalarEvolution *SE,
- DominatorTree *DT, AssumptionCache *AC,
+ bool PreserveCondBr, bool PreserveOnlyFirst,
+ unsigned TripMultiple, unsigned PeelCount, LoopInfo *LI,
+ ScalarEvolution *SE, DominatorTree *DT,
+ AssumptionCache *AC, OptimizationRemarkEmitter *ORE,
bool PreserveLCSSA) {
+
BasicBlock *Preheader = L->getLoopPreheader();
if (!Preheader) {
DEBUG(dbgs() << " Can't unroll; loop preheader-insertion failed.\n");
@@ -250,9 +295,8 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool Force,
if (TripCount != 0 && Count > TripCount)
Count = TripCount;
- // Don't enter the unroll code if there is nothing to do. This way we don't
- // need to support "partial unrolling by 1".
- if (TripCount == 0 && Count < 2)
+ // Don't enter the unroll code if there is nothing to do.
+ if (TripCount == 0 && Count < 2 && PeelCount == 0)
return false;
assert(Count > 0);
@@ -272,14 +316,22 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool Force,
// now we just recompute LCSSA for the outer loop, but it should be possible
// to fix it in-place.
bool NeedToFixLCSSA = PreserveLCSSA && CompletelyUnroll &&
- std::any_of(ExitBlocks.begin(), ExitBlocks.end(),
- [&](BasicBlock *BB) { return isa<PHINode>(BB->begin()); });
+ any_of(ExitBlocks, [](const BasicBlock *BB) {
+ return isa<PHINode>(BB->begin());
+ });
// We assume a run-time trip count if the compiler cannot
// figure out the loop trip count and the unroll-runtime
// flag is specified.
bool RuntimeTripCount = (TripCount == 0 && Count > 0 && AllowRuntime);
+ assert((!RuntimeTripCount || !PeelCount) &&
+ "Did not expect runtime trip-count unrolling "
+ "and peeling for the same loop");
+
+ if (PeelCount)
+ peelLoop(L, PeelCount, LI, SE, DT, PreserveLCSSA);
+
// Loops containing convergent instructions must have a count that divides
// their TripMultiple.
DEBUG(
@@ -293,9 +345,7 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool Force,
"Unroll count must divide trip multiple if loop contains a "
"convergent operation.");
});
- // Don't output the runtime loop remainder if Count is a multiple of
- // TripMultiple. Such a remainder is never needed, and is unsafe if the loop
- // contains a convergent instruction.
+
if (RuntimeTripCount && TripMultiple % Count != 0 &&
!UnrollRuntimeLoopRemainder(L, Count, AllowExpensiveTripCount,
UnrollRuntimeEpilog, LI, SE, DT,
@@ -322,35 +372,40 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool Force,
(unsigned)GreatestCommonDivisor64(Count, TripMultiple);
}
+ using namespace ore;
// Report the unrolling decision.
- DebugLoc LoopLoc = L->getStartLoc();
- Function *F = Header->getParent();
- LLVMContext &Ctx = F->getContext();
-
if (CompletelyUnroll) {
DEBUG(dbgs() << "COMPLETELY UNROLLING loop %" << Header->getName()
<< " with trip count " << TripCount << "!\n");
- emitOptimizationRemark(Ctx, DEBUG_TYPE, *F, LoopLoc,
- Twine("completely unrolled loop with ") +
- Twine(TripCount) + " iterations");
+ ORE->emit(OptimizationRemark(DEBUG_TYPE, "FullyUnrolled", L->getStartLoc(),
+ L->getHeader())
+ << "completely unrolled loop with "
+ << NV("UnrollCount", TripCount) << " iterations");
+ } else if (PeelCount) {
+ DEBUG(dbgs() << "PEELING loop %" << Header->getName()
+ << " with iteration count " << PeelCount << "!\n");
+ ORE->emit(OptimizationRemark(DEBUG_TYPE, "Peeled", L->getStartLoc(),
+ L->getHeader())
+ << " peeled loop by " << NV("PeelCount", PeelCount)
+ << " iterations");
} else {
- auto EmitDiag = [&](const Twine &T) {
- emitOptimizationRemark(Ctx, DEBUG_TYPE, *F, LoopLoc,
- "unrolled loop by a factor of " + Twine(Count) +
- T);
- };
+ OptimizationRemark Diag(DEBUG_TYPE, "PartialUnrolled", L->getStartLoc(),
+ L->getHeader());
+ Diag << "unrolled loop by a factor of " << NV("UnrollCount", Count);
DEBUG(dbgs() << "UNROLLING loop %" << Header->getName()
<< " by " << Count);
if (TripMultiple == 0 || BreakoutTrip != TripMultiple) {
DEBUG(dbgs() << " with a breakout at trip " << BreakoutTrip);
- EmitDiag(" with a breakout at trip " + Twine(BreakoutTrip));
+ ORE->emit(Diag << " with a breakout at trip "
+ << NV("BreakoutTrip", BreakoutTrip));
} else if (TripMultiple != 1) {
DEBUG(dbgs() << " with " << TripMultiple << " trips per branch");
- EmitDiag(" with " + Twine(TripMultiple) + " trips per branch");
+ ORE->emit(Diag << " with " << NV("TripMultiple", TripMultiple)
+ << " trips per branch");
} else if (RuntimeTripCount) {
DEBUG(dbgs() << " with run-time trip count");
- EmitDiag(" with run-time trip count");
+ ORE->emit(Diag << " with run-time trip count");
}
DEBUG(dbgs() << "!\n");
}
@@ -382,6 +437,15 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool Force,
LoopBlocksDFS::RPOIterator BlockEnd = DFS.endRPO();
std::vector<BasicBlock*> UnrolledLoopBlocks = L->getBlocks();
+
+ // Loop Unrolling might create new loops. While we do preserve LoopInfo, we
+ // might break loop-simplified form for these loops (as they, e.g., would
+ // share the same exit blocks). We'll keep track of loops for which we can
+ // break this so that later we can re-simplify them.
+ SmallSetVector<Loop *, 4> LoopsToSimplify;
+ for (Loop *SubLoop : *L)
+ LoopsToSimplify.insert(SubLoop);
+
for (unsigned It = 1; It != Count; ++It) {
std::vector<BasicBlock*> NewBlocks;
SmallDenseMap<const Loop *, Loop *, 4> NewLoops;
@@ -397,27 +461,14 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool Force,
assert(LI->getLoopFor(*BB) == L && "Header should not be in a sub-loop");
L->addBasicBlockToLoop(New, *LI);
} else {
- // Figure out which loop New is in.
- const Loop *OldLoop = LI->getLoopFor(*BB);
- assert(OldLoop && "Should (at least) be in the loop being unrolled!");
-
- Loop *&NewLoop = NewLoops[OldLoop];
- if (!NewLoop) {
- // Found a new sub-loop.
- assert(*BB == OldLoop->getHeader() &&
- "Header should be first in RPO");
-
- Loop *NewLoopParent = NewLoops.lookup(OldLoop->getParentLoop());
- assert(NewLoopParent &&
- "Expected parent loop before sub-loop in RPO");
- NewLoop = new Loop;
- NewLoopParent->addChildLoop(NewLoop);
+ const Loop *OldLoop = addClonedBlockToLoopInfo(*BB, New, LI, NewLoops);
+ if (OldLoop) {
+ LoopsToSimplify.insert(NewLoops[OldLoop]);
// Forget the old loop, since its inputs may have changed.
if (SE)
SE->forgetLoop(OldLoop);
}
- NewLoop->addBasicBlockToLoop(New, *LI);
}
if (*BB == Header)
@@ -480,9 +531,14 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool Force,
}
// Remap all instructions in the most recent iteration
- for (BasicBlock *NewBlock : NewBlocks)
- for (Instruction &I : *NewBlock)
+ for (BasicBlock *NewBlock : NewBlocks) {
+ for (Instruction &I : *NewBlock) {
::remapInstruction(&I, LastValueMap);
+ if (auto *II = dyn_cast<IntrinsicInst>(&I))
+ if (II->getIntrinsicID() == Intrinsic::assume)
+ AC->registerAssumption(II);
+ }
+ }
}
// Loop over the PHI nodes in the original block, setting incoming values.
@@ -524,12 +580,16 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool Force,
if (CompletelyUnroll) {
if (j == 0)
Dest = LoopExit;
- NeedConditional = false;
- }
-
- // If we know the trip count or a multiple of it, we can safely use an
- // unconditional branch for some iterations.
- if (j != BreakoutTrip && (TripMultiple == 0 || j % TripMultiple != 0)) {
+ // If using trip count upper bound to completely unroll, we need to keep
+ // the conditional branch except the last one because the loop may exit
+ // after any iteration.
+ assert(NeedConditional &&
+ "NeedCondition cannot be modified by both complete "
+ "unrolling and runtime unrolling");
+ NeedConditional = (PreserveCondBr && j && !(PreserveOnlyFirst && i != 0));
+ } else if (j != BreakoutTrip && (TripMultiple == 0 || j % TripMultiple != 0)) {
+ // If we know the trip count or a multiple of it, we can safely use an
+ // unconditional branch for some iterations.
NeedConditional = false;
}
@@ -595,10 +655,6 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool Force,
}
}
- // FIXME: We could register any cloned assumptions instead of clearing the
- // whole function's cache.
- AC->clear();
-
// FIXME: We only preserve DT info for complete unrolling now. Incrementally
// updating domtree after partial loop unrolling should also be easy.
if (DT && !CompletelyUnroll)
@@ -607,7 +663,7 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool Force,
DEBUG(DT->verifyDomTree());
// Simplify any new induction variables in the partially unrolled loop.
- if (SE && !CompletelyUnroll) {
+ if (SE && !CompletelyUnroll && Count > 1) {
SmallVector<WeakVH, 16> DeadInsts;
simplifyLoopIVs(L, SE, DT, LI, DeadInsts);
@@ -636,6 +692,11 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool Force,
}
}
+ // TODO: after peeling or unrolling, previously loop variant conditions are
+ // likely to fold to constants, eagerly propagating those here will require
+ // fewer cleanup passes to be run. Alternatively, a LoopEarlyCSE might be
+ // appropriate.
+
NumCompletelyUnrolled += CompletelyUnroll;
++NumUnrolled;
@@ -663,6 +724,11 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool Force,
if (!OuterL && !CompletelyUnroll)
OuterL = L;
if (OuterL) {
+ // OuterL includes all loops for which we can break loop-simplify, so
+ // it's sufficient to simplify only it (it'll recursively simplify inner
+ // loops too).
+ // TODO: That potentially might be compile-time expensive. We should try
+ // to fix the loop-simplified form incrementally.
simplifyLoop(OuterL, DT, LI, SE, AC, PreserveLCSSA);
// LCSSA must be performed on the outermost affected loop. The unrolled
@@ -678,6 +744,10 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool Force,
else
assert(OuterL->isLCSSAForm(*DT) &&
"Loops should be in LCSSA form after loop-unroll.");
+ } else {
+ // Simplify loops for which we might've broken loop-simplify form.
+ for (Loop *SubLoop : LoopsToSimplify)
+ simplifyLoop(SubLoop, DT, LI, SE, AC, PreserveLCSSA);
}
}
diff --git a/contrib/llvm/lib/Transforms/Utils/LoopUnrollPeel.cpp b/contrib/llvm/lib/Transforms/Utils/LoopUnrollPeel.cpp
new file mode 100644
index 0000000..842cf31
--- /dev/null
+++ b/contrib/llvm/lib/Transforms/Utils/LoopUnrollPeel.cpp
@@ -0,0 +1,414 @@
+//===-- UnrollLoopPeel.cpp - Loop peeling utilities -----------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements some loop unrolling utilities for peeling loops
+// with dynamically inferred (from PGO) trip counts. See LoopUnroll.cpp for
+// unrolling loops with compile-time constant trip counts.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Analysis/LoopIterator.h"
+#include "llvm/Analysis/LoopPass.h"
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/MDBuilder.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+#include "llvm/Transforms/Utils/LoopUtils.h"
+#include "llvm/Transforms/Utils/UnrollLoop.h"
+#include <algorithm>
+
+using namespace llvm;
+
+#define DEBUG_TYPE "loop-unroll"
+STATISTIC(NumPeeled, "Number of loops peeled");
+
+static cl::opt<unsigned> UnrollPeelMaxCount(
+ "unroll-peel-max-count", cl::init(7), cl::Hidden,
+ cl::desc("Max average trip count which will cause loop peeling."));
+
+static cl::opt<unsigned> UnrollForcePeelCount(
+ "unroll-force-peel-count", cl::init(0), cl::Hidden,
+ cl::desc("Force a peel count regardless of profiling information."));
+
+// Check whether we are capable of peeling this loop.
+static bool canPeel(Loop *L) {
+ // Make sure the loop is in simplified form
+ if (!L->isLoopSimplifyForm())
+ return false;
+
+ // Only peel loops that contain a single exit
+ if (!L->getExitingBlock() || !L->getUniqueExitBlock())
+ return false;
+
+ return true;
+}
+
+// Return the number of iterations we want to peel off.
+void llvm::computePeelCount(Loop *L, unsigned LoopSize,
+ TargetTransformInfo::UnrollingPreferences &UP) {
+ UP.PeelCount = 0;
+ if (!canPeel(L))
+ return;
+
+ // Only try to peel innermost loops.
+ if (!L->empty())
+ return;
+
+ // If the user provided a peel count, use that.
+ bool UserPeelCount = UnrollForcePeelCount.getNumOccurrences() > 0;
+ if (UserPeelCount) {
+ DEBUG(dbgs() << "Force-peeling first " << UnrollForcePeelCount
+ << " iterations.\n");
+ UP.PeelCount = UnrollForcePeelCount;
+ return;
+ }
+
+ // If we don't know the trip count, but have reason to believe the average
+ // trip count is low, peeling should be beneficial, since we will usually
+ // hit the peeled section.
+ // We only do this in the presence of profile information, since otherwise
+ // our estimates of the trip count are not reliable enough.
+ if (UP.AllowPeeling && L->getHeader()->getParent()->getEntryCount()) {
+ Optional<unsigned> PeelCount = getLoopEstimatedTripCount(L);
+ if (!PeelCount)
+ return;
+
+ DEBUG(dbgs() << "Profile-based estimated trip count is " << *PeelCount
+ << "\n");
+
+ if (*PeelCount) {
+ if ((*PeelCount <= UnrollPeelMaxCount) &&
+ (LoopSize * (*PeelCount + 1) <= UP.Threshold)) {
+ DEBUG(dbgs() << "Peeling first " << *PeelCount << " iterations.\n");
+ UP.PeelCount = *PeelCount;
+ return;
+ }
+ DEBUG(dbgs() << "Requested peel count: " << *PeelCount << "\n");
+ DEBUG(dbgs() << "Max peel count: " << UnrollPeelMaxCount << "\n");
+ DEBUG(dbgs() << "Peel cost: " << LoopSize * (*PeelCount + 1) << "\n");
+ DEBUG(dbgs() << "Max peel cost: " << UP.Threshold << "\n");
+ }
+ }
+
+ return;
+}
+
+/// \brief Update the branch weights of the latch of a peeled-off loop
+/// iteration.
+/// This sets the branch weights for the latch of the recently peeled off loop
+/// iteration correctly.
+/// Our goal is to make sure that:
+/// a) The total weight of all the copies of the loop body is preserved.
+/// b) The total weight of the loop exit is preserved.
+/// c) The body weight is reasonably distributed between the peeled iterations.
+///
+/// \param Header The copy of the header block that belongs to next iteration.
+/// \param LatchBR The copy of the latch branch that belongs to this iteration.
+/// \param IterNumber The serial number of the iteration that was just
+/// peeled off.
+/// \param AvgIters The average number of iterations we expect the loop to have.
+/// \param[in,out] PeeledHeaderWeight The total number of dynamic loop
+/// iterations that are unaccounted for. As an input, it represents the number
+/// of times we expect to enter the header of the iteration currently being
+/// peeled off. The output is the number of times we expect to enter the
+/// header of the next iteration.
+static void updateBranchWeights(BasicBlock *Header, BranchInst *LatchBR,
+ unsigned IterNumber, unsigned AvgIters,
+ uint64_t &PeeledHeaderWeight) {
+
+ // FIXME: Pick a more realistic distribution.
+ // Currently the proportion of weight we assign to the fall-through
+ // side of the branch drops linearly with the iteration number, and we use
+ // a 0.9 fudge factor to make the drop-off less sharp...
+ if (PeeledHeaderWeight) {
+ uint64_t FallThruWeight =
+ PeeledHeaderWeight * ((float)(AvgIters - IterNumber) / AvgIters * 0.9);
+ uint64_t ExitWeight = PeeledHeaderWeight - FallThruWeight;
+ PeeledHeaderWeight -= ExitWeight;
+
+ unsigned HeaderIdx = (LatchBR->getSuccessor(0) == Header ? 0 : 1);
+ MDBuilder MDB(LatchBR->getContext());
+ MDNode *WeightNode =
+ HeaderIdx ? MDB.createBranchWeights(ExitWeight, FallThruWeight)
+ : MDB.createBranchWeights(FallThruWeight, ExitWeight);
+ LatchBR->setMetadata(LLVMContext::MD_prof, WeightNode);
+ }
+}
+
+/// \brief Clones the body of the loop L, putting it between \p InsertTop and \p
+/// InsertBot.
+/// \param IterNumber The serial number of the iteration currently being
+/// peeled off.
+/// \param Exit The exit block of the original loop.
+/// \param[out] NewBlocks A list of the the blocks in the newly created clone
+/// \param[out] VMap The value map between the loop and the new clone.
+/// \param LoopBlocks A helper for DFS-traversal of the loop.
+/// \param LVMap A value-map that maps instructions from the original loop to
+/// instructions in the last peeled-off iteration.
+static void cloneLoopBlocks(Loop *L, unsigned IterNumber, BasicBlock *InsertTop,
+ BasicBlock *InsertBot, BasicBlock *Exit,
+ SmallVectorImpl<BasicBlock *> &NewBlocks,
+ LoopBlocksDFS &LoopBlocks, ValueToValueMapTy &VMap,
+ ValueToValueMapTy &LVMap, LoopInfo *LI) {
+
+ BasicBlock *Header = L->getHeader();
+ BasicBlock *Latch = L->getLoopLatch();
+ BasicBlock *PreHeader = L->getLoopPreheader();
+
+ Function *F = Header->getParent();
+ LoopBlocksDFS::RPOIterator BlockBegin = LoopBlocks.beginRPO();
+ LoopBlocksDFS::RPOIterator BlockEnd = LoopBlocks.endRPO();
+ Loop *ParentLoop = L->getParentLoop();
+
+ // For each block in the original loop, create a new copy,
+ // and update the value map with the newly created values.
+ for (LoopBlocksDFS::RPOIterator BB = BlockBegin; BB != BlockEnd; ++BB) {
+ BasicBlock *NewBB = CloneBasicBlock(*BB, VMap, ".peel", F);
+ NewBlocks.push_back(NewBB);
+
+ if (ParentLoop)
+ ParentLoop->addBasicBlockToLoop(NewBB, *LI);
+
+ VMap[*BB] = NewBB;
+ }
+
+ // Hook-up the control flow for the newly inserted blocks.
+ // The new header is hooked up directly to the "top", which is either
+ // the original loop preheader (for the first iteration) or the previous
+ // iteration's exiting block (for every other iteration)
+ InsertTop->getTerminator()->setSuccessor(0, cast<BasicBlock>(VMap[Header]));
+
+ // Similarly, for the latch:
+ // The original exiting edge is still hooked up to the loop exit.
+ // The backedge now goes to the "bottom", which is either the loop's real
+ // header (for the last peeled iteration) or the copied header of the next
+ // iteration (for every other iteration)
+ BranchInst *LatchBR =
+ cast<BranchInst>(cast<BasicBlock>(VMap[Latch])->getTerminator());
+ unsigned HeaderIdx = (LatchBR->getSuccessor(0) == Header ? 0 : 1);
+ LatchBR->setSuccessor(HeaderIdx, InsertBot);
+ LatchBR->setSuccessor(1 - HeaderIdx, Exit);
+
+ // The new copy of the loop body starts with a bunch of PHI nodes
+ // that pick an incoming value from either the preheader, or the previous
+ // loop iteration. Since this copy is no longer part of the loop, we
+ // resolve this statically:
+ // For the first iteration, we use the value from the preheader directly.
+ // For any other iteration, we replace the phi with the value generated by
+ // the immediately preceding clone of the loop body (which represents
+ // the previous iteration).
+ for (BasicBlock::iterator I = Header->begin(); isa<PHINode>(I); ++I) {
+ PHINode *NewPHI = cast<PHINode>(VMap[&*I]);
+ if (IterNumber == 0) {
+ VMap[&*I] = NewPHI->getIncomingValueForBlock(PreHeader);
+ } else {
+ Value *LatchVal = NewPHI->getIncomingValueForBlock(Latch);
+ Instruction *LatchInst = dyn_cast<Instruction>(LatchVal);
+ if (LatchInst && L->contains(LatchInst))
+ VMap[&*I] = LVMap[LatchInst];
+ else
+ VMap[&*I] = LatchVal;
+ }
+ cast<BasicBlock>(VMap[Header])->getInstList().erase(NewPHI);
+ }
+
+ // Fix up the outgoing values - we need to add a value for the iteration
+ // we've just created. Note that this must happen *after* the incoming
+ // values are adjusted, since the value going out of the latch may also be
+ // a value coming into the header.
+ for (BasicBlock::iterator I = Exit->begin(); isa<PHINode>(I); ++I) {
+ PHINode *PHI = cast<PHINode>(I);
+ Value *LatchVal = PHI->getIncomingValueForBlock(Latch);
+ Instruction *LatchInst = dyn_cast<Instruction>(LatchVal);
+ if (LatchInst && L->contains(LatchInst))
+ LatchVal = VMap[LatchVal];
+ PHI->addIncoming(LatchVal, cast<BasicBlock>(VMap[Latch]));
+ }
+
+ // LastValueMap is updated with the values for the current loop
+ // which are used the next time this function is called.
+ for (const auto &KV : VMap)
+ LVMap[KV.first] = KV.second;
+}
+
+/// \brief Peel off the first \p PeelCount iterations of loop \p L.
+///
+/// Note that this does not peel them off as a single straight-line block.
+/// Rather, each iteration is peeled off separately, and needs to check the
+/// exit condition.
+/// For loops that dynamically execute \p PeelCount iterations or less
+/// this provides a benefit, since the peeled off iterations, which account
+/// for the bulk of dynamic execution, can be further simplified by scalar
+/// optimizations.
+bool llvm::peelLoop(Loop *L, unsigned PeelCount, LoopInfo *LI,
+ ScalarEvolution *SE, DominatorTree *DT,
+ bool PreserveLCSSA) {
+ if (!canPeel(L))
+ return false;
+
+ LoopBlocksDFS LoopBlocks(L);
+ LoopBlocks.perform(LI);
+
+ BasicBlock *Header = L->getHeader();
+ BasicBlock *PreHeader = L->getLoopPreheader();
+ BasicBlock *Latch = L->getLoopLatch();
+ BasicBlock *Exit = L->getUniqueExitBlock();
+
+ Function *F = Header->getParent();
+
+ // Set up all the necessary basic blocks. It is convenient to split the
+ // preheader into 3 parts - two blocks to anchor the peeled copy of the loop
+ // body, and a new preheader for the "real" loop.
+
+ // Peeling the first iteration transforms.
+ //
+ // PreHeader:
+ // ...
+ // Header:
+ // LoopBody
+ // If (cond) goto Header
+ // Exit:
+ //
+ // into
+ //
+ // InsertTop:
+ // LoopBody
+ // If (!cond) goto Exit
+ // InsertBot:
+ // NewPreHeader:
+ // ...
+ // Header:
+ // LoopBody
+ // If (cond) goto Header
+ // Exit:
+ //
+ // Each following iteration will split the current bottom anchor in two,
+ // and put the new copy of the loop body between these two blocks. That is,
+ // after peeling another iteration from the example above, we'll split
+ // InsertBot, and get:
+ //
+ // InsertTop:
+ // LoopBody
+ // If (!cond) goto Exit
+ // InsertBot:
+ // LoopBody
+ // If (!cond) goto Exit
+ // InsertBot.next:
+ // NewPreHeader:
+ // ...
+ // Header:
+ // LoopBody
+ // If (cond) goto Header
+ // Exit:
+
+ BasicBlock *InsertTop = SplitEdge(PreHeader, Header, DT, LI);
+ BasicBlock *InsertBot =
+ SplitBlock(InsertTop, InsertTop->getTerminator(), DT, LI);
+ BasicBlock *NewPreHeader =
+ SplitBlock(InsertBot, InsertBot->getTerminator(), DT, LI);
+
+ InsertTop->setName(Header->getName() + ".peel.begin");
+ InsertBot->setName(Header->getName() + ".peel.next");
+ NewPreHeader->setName(PreHeader->getName() + ".peel.newph");
+
+ ValueToValueMapTy LVMap;
+
+ // If we have branch weight information, we'll want to update it for the
+ // newly created branches.
+ BranchInst *LatchBR =
+ cast<BranchInst>(cast<BasicBlock>(Latch)->getTerminator());
+ unsigned HeaderIdx = (LatchBR->getSuccessor(0) == Header ? 0 : 1);
+
+ uint64_t TrueWeight, FalseWeight;
+ uint64_t ExitWeight = 0, CurHeaderWeight = 0;
+ if (LatchBR->extractProfMetadata(TrueWeight, FalseWeight)) {
+ ExitWeight = HeaderIdx ? TrueWeight : FalseWeight;
+ // The # of times the loop body executes is the sum of the exit block
+ // weight and the # of times the backedges are taken.
+ CurHeaderWeight = TrueWeight + FalseWeight;
+ }
+
+ // For each peeled-off iteration, make a copy of the loop.
+ for (unsigned Iter = 0; Iter < PeelCount; ++Iter) {
+ SmallVector<BasicBlock *, 8> NewBlocks;
+ ValueToValueMapTy VMap;
+
+ // Subtract the exit weight from the current header weight -- the exit
+ // weight is exactly the weight of the previous iteration's header.
+ // FIXME: due to the way the distribution is constructed, we need a
+ // guard here to make sure we don't end up with non-positive weights.
+ if (ExitWeight < CurHeaderWeight)
+ CurHeaderWeight -= ExitWeight;
+ else
+ CurHeaderWeight = 1;
+
+ cloneLoopBlocks(L, Iter, InsertTop, InsertBot, Exit,
+ NewBlocks, LoopBlocks, VMap, LVMap, LI);
+ updateBranchWeights(InsertBot, cast<BranchInst>(VMap[LatchBR]), Iter,
+ PeelCount, ExitWeight);
+
+ InsertTop = InsertBot;
+ InsertBot = SplitBlock(InsertBot, InsertBot->getTerminator(), DT, LI);
+ InsertBot->setName(Header->getName() + ".peel.next");
+
+ F->getBasicBlockList().splice(InsertTop->getIterator(),
+ F->getBasicBlockList(),
+ NewBlocks[0]->getIterator(), F->end());
+
+ // Remap to use values from the current iteration instead of the
+ // previous one.
+ remapInstructionsInBlocks(NewBlocks, VMap);
+ }
+
+ // Now adjust the phi nodes in the loop header to get their initial values
+ // from the last peeled-off iteration instead of the preheader.
+ for (BasicBlock::iterator I = Header->begin(); isa<PHINode>(I); ++I) {
+ PHINode *PHI = cast<PHINode>(I);
+ Value *NewVal = PHI->getIncomingValueForBlock(Latch);
+ Instruction *LatchInst = dyn_cast<Instruction>(NewVal);
+ if (LatchInst && L->contains(LatchInst))
+ NewVal = LVMap[LatchInst];
+
+ PHI->setIncomingValue(PHI->getBasicBlockIndex(NewPreHeader), NewVal);
+ }
+
+ // Adjust the branch weights on the loop exit.
+ if (ExitWeight) {
+ // The backedge count is the difference of current header weight and
+ // current loop exit weight. If the current header weight is smaller than
+ // the current loop exit weight, we mark the loop backedge weight as 1.
+ uint64_t BackEdgeWeight = 0;
+ if (ExitWeight < CurHeaderWeight)
+ BackEdgeWeight = CurHeaderWeight - ExitWeight;
+ else
+ BackEdgeWeight = 1;
+ MDBuilder MDB(LatchBR->getContext());
+ MDNode *WeightNode =
+ HeaderIdx ? MDB.createBranchWeights(ExitWeight, BackEdgeWeight)
+ : MDB.createBranchWeights(BackEdgeWeight, ExitWeight);
+ LatchBR->setMetadata(LLVMContext::MD_prof, WeightNode);
+ }
+
+ // If the loop is nested, we changed the parent loop, update SE.
+ if (Loop *ParentLoop = L->getParentLoop())
+ SE->forgetLoop(ParentLoop);
+
+ NumPeeled++;
+
+ return true;
+}
diff --git a/contrib/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp b/contrib/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp
index 861a50c..d3ea156 100644
--- a/contrib/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp
@@ -112,6 +112,18 @@ static void ConnectProlog(Loop *L, Value *BECount, unsigned Count,
}
}
+ // Make sure that created prolog loop is in simplified form
+ SmallVector<BasicBlock *, 4> PrologExitPreds;
+ Loop *PrologLoop = LI->getLoopFor(PrologLatch);
+ if (PrologLoop) {
+ for (BasicBlock *PredBB : predecessors(PrologExit))
+ if (PrologLoop->contains(PredBB))
+ PrologExitPreds.push_back(PredBB);
+
+ SplitBlockPredecessors(PrologExit, PrologExitPreds, ".unr-lcssa", DT, LI,
+ PreserveLCSSA);
+ }
+
// Create a branch around the original loop, which is taken if there are no
// iterations remaining to be executed after running the prologue.
Instruction *InsertPt = PrologExit->getTerminator();
@@ -289,16 +301,23 @@ static void CloneLoopBlocks(Loop *L, Value *NewIter,
LI->addTopLevelLoop(NewLoop);
}
+ NewLoopsMap NewLoops;
+ if (NewLoop)
+ NewLoops[L] = NewLoop;
+ else if (ParentLoop)
+ NewLoops[L] = ParentLoop;
+
// For each block in the original loop, create a new copy,
// and update the value map with the newly created values.
for (LoopBlocksDFS::RPOIterator BB = BlockBegin; BB != BlockEnd; ++BB) {
BasicBlock *NewBB = CloneBasicBlock(*BB, VMap, "." + suffix, F);
NewBlocks.push_back(NewBB);
-
- if (NewLoop)
- NewLoop->addBasicBlockToLoop(NewBB, *LI);
- else if (ParentLoop)
- ParentLoop->addBasicBlockToLoop(NewBB, *LI);
+
+ // If we're unrolling the outermost loop, there's no remainder loop,
+ // and this block isn't in a nested loop, then the new block is not
+ // in any loop. Otherwise, add it to loopinfo.
+ if (CreateRemainderLoop || LI->getLoopFor(*BB) != L || ParentLoop)
+ addClonedBlockToLoopInfo(*BB, NewBB, LI, NewLoops);
VMap[*BB] = NewBB;
if (Header == *BB) {
@@ -479,11 +498,6 @@ bool llvm::UnrollRuntimeLoopRemainder(Loop *L, unsigned Count,
if (Log2_32(Count) > BEWidth)
return false;
- // If this loop is nested, then the loop unroller changes the code in the
- // parent loop, so the Scalar Evolution pass needs to be run again.
- if (Loop *ParentLoop = L->getParentLoop())
- SE->forgetLoop(ParentLoop);
-
BasicBlock *Latch = L->getLoopLatch();
// Loop structure is the following:
@@ -673,6 +687,12 @@ bool llvm::UnrollRuntimeLoopRemainder(Loop *L, unsigned Count,
ConnectProlog(L, BECount, Count, PrologExit, PreHeader, NewPreHeader,
VMap, DT, LI, PreserveLCSSA);
}
+
+ // If this loop is nested, then the loop unroller changes the code in the
+ // parent loop, so the Scalar Evolution pass needs to be run again.
+ if (Loop *ParentLoop = L->getParentLoop())
+ SE->forgetLoop(ParentLoop);
+
NumRuntimeUnrolled++;
return true;
}
diff --git a/contrib/llvm/lib/Transforms/Utils/LoopUtils.cpp b/contrib/llvm/lib/Transforms/Utils/LoopUtils.cpp
index 3902c67..c8efa9e 100644
--- a/contrib/llvm/lib/Transforms/Utils/LoopUtils.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/LoopUtils.cpp
@@ -11,14 +11,17 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/Transforms/Utils/LoopUtils.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/BasicAliasAnalysis.h"
-#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/GlobalsModRef.h"
+#include "llvm/Analysis/GlobalsModRef.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
#include "llvm/Analysis/ScalarEvolutionExpander.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
-#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
@@ -26,7 +29,6 @@
#include "llvm/IR/ValueHandle.h"
#include "llvm/Pass.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Transforms/Utils/LoopUtils.h"
using namespace llvm;
using namespace llvm::PatternMatch;
@@ -305,7 +307,7 @@ bool RecurrenceDescriptor::AddReductionVar(PHINode *Phi, RecurrenceKind Kind,
// The instruction used by an outside user must be the last instruction
// before we feed back to the reduction phi. Otherwise, we loose VF-1
// operations on the value.
- if (std::find(Phi->op_begin(), Phi->op_end(), Cur) == Phi->op_end())
+ if (!is_contained(Phi->operands(), Cur))
return false;
ExitInstruction = Cur;
@@ -654,8 +656,8 @@ Value *RecurrenceDescriptor::createMinMaxOp(IRBuilder<> &Builder,
}
InductionDescriptor::InductionDescriptor(Value *Start, InductionKind K,
- const SCEV *Step)
- : StartValue(Start), IK(K), Step(Step) {
+ const SCEV *Step, BinaryOperator *BOp)
+ : StartValue(Start), IK(K), Step(Step), InductionBinOp(BOp) {
assert(IK != IK_NoInduction && "Not an induction");
// Start value type should match the induction kind and the value
@@ -672,7 +674,15 @@ InductionDescriptor::InductionDescriptor(Value *Start, InductionKind K,
assert((IK != IK_PtrInduction || getConstIntStepValue()) &&
"Step value should be constant for pointer induction");
- assert(Step->getType()->isIntegerTy() && "StepValue is not an integer");
+ assert((IK == IK_FpInduction || Step->getType()->isIntegerTy()) &&
+ "StepValue is not an integer");
+
+ assert((IK != IK_FpInduction || Step->getType()->isFloatingPointTy()) &&
+ "StepValue is not FP for FpInduction");
+ assert((IK != IK_FpInduction || (InductionBinOp &&
+ (InductionBinOp->getOpcode() == Instruction::FAdd ||
+ InductionBinOp->getOpcode() == Instruction::FSub))) &&
+ "Binary opcode should be specified for FP induction");
}
int InductionDescriptor::getConsecutiveDirection() const {
@@ -693,6 +703,8 @@ Value *InductionDescriptor::transform(IRBuilder<> &B, Value *Index,
const DataLayout& DL) const {
SCEVExpander Exp(*SE, DL, "induction");
+ assert(Index->getType() == Step->getType() &&
+ "Index type does not match StepValue type");
switch (IK) {
case IK_IntInduction: {
assert(Index->getType() == StartValue->getType() &&
@@ -717,29 +729,113 @@ Value *InductionDescriptor::transform(IRBuilder<> &B, Value *Index,
return Exp.expandCodeFor(S, StartValue->getType(), &*B.GetInsertPoint());
}
case IK_PtrInduction: {
- assert(Index->getType() == Step->getType() &&
- "Index type does not match StepValue type");
assert(isa<SCEVConstant>(Step) &&
"Expected constant step for pointer induction");
const SCEV *S = SE->getMulExpr(SE->getSCEV(Index), Step);
Index = Exp.expandCodeFor(S, Index->getType(), &*B.GetInsertPoint());
return B.CreateGEP(nullptr, StartValue, Index);
}
+ case IK_FpInduction: {
+ assert(Step->getType()->isFloatingPointTy() && "Expected FP Step value");
+ assert(InductionBinOp &&
+ (InductionBinOp->getOpcode() == Instruction::FAdd ||
+ InductionBinOp->getOpcode() == Instruction::FSub) &&
+ "Original bin op should be defined for FP induction");
+
+ Value *StepValue = cast<SCEVUnknown>(Step)->getValue();
+
+ // Floating point operations had to be 'fast' to enable the induction.
+ FastMathFlags Flags;
+ Flags.setUnsafeAlgebra();
+
+ Value *MulExp = B.CreateFMul(StepValue, Index);
+ if (isa<Instruction>(MulExp))
+ // We have to check, the MulExp may be a constant.
+ cast<Instruction>(MulExp)->setFastMathFlags(Flags);
+
+ Value *BOp = B.CreateBinOp(InductionBinOp->getOpcode() , StartValue,
+ MulExp, "induction");
+ if (isa<Instruction>(BOp))
+ cast<Instruction>(BOp)->setFastMathFlags(Flags);
+
+ return BOp;
+ }
case IK_NoInduction:
return nullptr;
}
llvm_unreachable("invalid enum");
}
-bool InductionDescriptor::isInductionPHI(PHINode *Phi,
+bool InductionDescriptor::isFPInductionPHI(PHINode *Phi, const Loop *TheLoop,
+ ScalarEvolution *SE,
+ InductionDescriptor &D) {
+
+ // Here we only handle FP induction variables.
+ assert(Phi->getType()->isFloatingPointTy() && "Unexpected Phi type");
+
+ if (TheLoop->getHeader() != Phi->getParent())
+ return false;
+
+ // The loop may have multiple entrances or multiple exits; we can analyze
+ // this phi if it has a unique entry value and a unique backedge value.
+ if (Phi->getNumIncomingValues() != 2)
+ return false;
+ Value *BEValue = nullptr, *StartValue = nullptr;
+ if (TheLoop->contains(Phi->getIncomingBlock(0))) {
+ BEValue = Phi->getIncomingValue(0);
+ StartValue = Phi->getIncomingValue(1);
+ } else {
+ assert(TheLoop->contains(Phi->getIncomingBlock(1)) &&
+ "Unexpected Phi node in the loop");
+ BEValue = Phi->getIncomingValue(1);
+ StartValue = Phi->getIncomingValue(0);
+ }
+
+ BinaryOperator *BOp = dyn_cast<BinaryOperator>(BEValue);
+ if (!BOp)
+ return false;
+
+ Value *Addend = nullptr;
+ if (BOp->getOpcode() == Instruction::FAdd) {
+ if (BOp->getOperand(0) == Phi)
+ Addend = BOp->getOperand(1);
+ else if (BOp->getOperand(1) == Phi)
+ Addend = BOp->getOperand(0);
+ } else if (BOp->getOpcode() == Instruction::FSub)
+ if (BOp->getOperand(0) == Phi)
+ Addend = BOp->getOperand(1);
+
+ if (!Addend)
+ return false;
+
+ // The addend should be loop invariant
+ if (auto *I = dyn_cast<Instruction>(Addend))
+ if (TheLoop->contains(I))
+ return false;
+
+ // FP Step has unknown SCEV
+ const SCEV *Step = SE->getUnknown(Addend);
+ D = InductionDescriptor(StartValue, IK_FpInduction, Step, BOp);
+ return true;
+}
+
+bool InductionDescriptor::isInductionPHI(PHINode *Phi, const Loop *TheLoop,
PredicatedScalarEvolution &PSE,
InductionDescriptor &D,
bool Assume) {
Type *PhiTy = Phi->getType();
- // We only handle integer and pointer inductions variables.
- if (!PhiTy->isIntegerTy() && !PhiTy->isPointerTy())
+
+ // Handle integer and pointer inductions variables.
+ // Now we handle also FP induction but not trying to make a
+ // recurrent expression from the PHI node in-place.
+
+ if (!PhiTy->isIntegerTy() && !PhiTy->isPointerTy() &&
+ !PhiTy->isFloatTy() && !PhiTy->isDoubleTy() && !PhiTy->isHalfTy())
return false;
+ if (PhiTy->isFloatingPointTy())
+ return isFPInductionPHI(Phi, TheLoop, PSE.getSE(), D);
+
const SCEV *PhiScev = PSE.getSCEV(Phi);
const auto *AR = dyn_cast<SCEVAddRecExpr>(PhiScev);
@@ -752,10 +848,10 @@ bool InductionDescriptor::isInductionPHI(PHINode *Phi,
return false;
}
- return isInductionPHI(Phi, PSE.getSE(), D, AR);
+ return isInductionPHI(Phi, TheLoop, PSE.getSE(), D, AR);
}
-bool InductionDescriptor::isInductionPHI(PHINode *Phi,
+bool InductionDescriptor::isInductionPHI(PHINode *Phi, const Loop *TheLoop,
ScalarEvolution *SE,
InductionDescriptor &D,
const SCEV *Expr) {
@@ -773,15 +869,20 @@ bool InductionDescriptor::isInductionPHI(PHINode *Phi,
return false;
}
- assert(AR->getLoop()->getHeader() == Phi->getParent() &&
- "PHI is an AddRec for a different loop?!");
+ if (AR->getLoop() != TheLoop) {
+ // FIXME: We should treat this as a uniform. Unfortunately, we
+ // don't currently know how to handled uniform PHIs.
+ DEBUG(dbgs() << "LV: PHI is a recurrence with respect to an outer loop.\n");
+ return false;
+ }
+
Value *StartValue =
Phi->getIncomingValueForBlock(AR->getLoop()->getLoopPreheader());
const SCEV *Step = AR->getStepRecurrence(*SE);
// Calculate the pointer stride and check if it is consecutive.
// The stride may be a constant or a loop invariant integer value.
const SCEVConstant *ConstStep = dyn_cast<SCEVConstant>(Step);
- if (!ConstStep && !SE->isLoopInvariant(Step, AR->getLoop()))
+ if (!ConstStep && !SE->isLoopInvariant(Step, TheLoop))
return false;
if (PhiTy->isIntegerTy()) {
@@ -824,7 +925,7 @@ SmallVector<Instruction *, 8> llvm::findDefsUsedOutsideOfLoop(Loop *L) {
// be adapted into a pointer.
for (auto &Inst : *Block) {
auto Users = Inst.users();
- if (std::any_of(Users.begin(), Users.end(), [&](User *U) {
+ if (any_of(Users, [&](User *U) {
auto *Use = cast<Instruction>(U);
return !L->contains(Use->getParent());
}))
@@ -851,6 +952,10 @@ void llvm::getLoopAnalysisUsage(AnalysisUsage &AU) {
AU.addPreservedID(LoopSimplifyID);
AU.addRequiredID(LCSSAID);
AU.addPreservedID(LCSSAID);
+ // This is used in the LPPassManager to perform LCSSA verification on passes
+ // which preserve lcssa form
+ AU.addRequired<LCSSAVerificationPass>();
+ AU.addPreserved<LCSSAVerificationPass>();
// Loop passes are designed to run inside of a loop pass manager which means
// that any function analyses they require must be required by the first loop
@@ -967,3 +1072,36 @@ bool llvm::isGuaranteedToExecute(const Instruction &Inst,
// just a special case of this.)
return true;
}
+
+Optional<unsigned> llvm::getLoopEstimatedTripCount(Loop *L) {
+ // Only support loops with a unique exiting block, and a latch.
+ if (!L->getExitingBlock())
+ return None;
+
+ // Get the branch weights for the the loop's backedge.
+ BranchInst *LatchBR =
+ dyn_cast<BranchInst>(L->getLoopLatch()->getTerminator());
+ if (!LatchBR || LatchBR->getNumSuccessors() != 2)
+ return None;
+
+ assert((LatchBR->getSuccessor(0) == L->getHeader() ||
+ LatchBR->getSuccessor(1) == L->getHeader()) &&
+ "At least one edge out of the latch must go to the header");
+
+ // To estimate the number of times the loop body was executed, we want to
+ // know the number of times the backedge was taken, vs. the number of times
+ // we exited the loop.
+ uint64_t TrueVal, FalseVal;
+ if (!LatchBR->extractProfMetadata(TrueVal, FalseVal))
+ return None;
+
+ if (!TrueVal || !FalseVal)
+ return 0;
+
+ // Divide the count of the backedge by the count of the edge exiting the loop,
+ // rounding to nearest.
+ if (LatchBR->getSuccessor(0) == L->getHeader())
+ return (TrueVal + (FalseVal / 2)) / FalseVal;
+ else
+ return (FalseVal + (TrueVal / 2)) / TrueVal;
+}
diff --git a/contrib/llvm/lib/Transforms/Utils/LoopVersioning.cpp b/contrib/llvm/lib/Transforms/Utils/LoopVersioning.cpp
index b3c6169..29756d9 100644
--- a/contrib/llvm/lib/Transforms/Utils/LoopVersioning.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/LoopVersioning.cpp
@@ -36,7 +36,7 @@ LoopVersioning::LoopVersioning(const LoopAccessInfo &LAI, Loop *L, LoopInfo *LI,
: VersionedLoop(L), NonVersionedLoop(nullptr), LAI(LAI), LI(LI), DT(DT),
SE(SE) {
assert(L->getExitBlock() && "No single exit block");
- assert(L->getLoopPreheader() && "No preheader");
+ assert(L->isLoopSimplifyForm() && "Loop is not in loop-simplify form");
if (UseLAIChecks) {
setAliasChecks(LAI.getRuntimePointerChecking()->getChecks());
setSCEVChecks(LAI.getPSE().getUnionPredicate());
@@ -278,8 +278,8 @@ public:
bool Changed = false;
for (Loop *L : Worklist) {
const LoopAccessInfo &LAI = LAA->getInfo(L);
- if (LAI.getNumRuntimePointerChecks() ||
- !LAI.getPSE().getUnionPredicate().isAlwaysTrue()) {
+ if (L->isLoopSimplifyForm() && (LAI.getNumRuntimePointerChecks() ||
+ !LAI.getPSE().getUnionPredicate().isAlwaysTrue())) {
LoopVersioning LVer(LAI, L, LI, DT, SE);
LVer.versionLoop();
LVer.annotateLoopWithNoAlias();
diff --git a/contrib/llvm/lib/Transforms/Utils/LowerInvoke.cpp b/contrib/llvm/lib/Transforms/Utils/LowerInvoke.cpp
index 1b31c5a..ee84541 100644
--- a/contrib/llvm/lib/Transforms/Utils/LowerInvoke.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/LowerInvoke.cpp
@@ -14,6 +14,7 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/Transforms/Utils/LowerInvoke.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/IR/Instructions.h"
@@ -28,36 +29,29 @@ using namespace llvm;
STATISTIC(NumInvokes, "Number of invokes replaced");
namespace {
- class LowerInvoke : public FunctionPass {
+ class LowerInvokeLegacyPass : public FunctionPass {
public:
static char ID; // Pass identification, replacement for typeid
- explicit LowerInvoke() : FunctionPass(ID) {
- initializeLowerInvokePass(*PassRegistry::getPassRegistry());
+ explicit LowerInvokeLegacyPass() : FunctionPass(ID) {
+ initializeLowerInvokeLegacyPassPass(*PassRegistry::getPassRegistry());
}
bool runOnFunction(Function &F) override;
};
}
-char LowerInvoke::ID = 0;
-INITIALIZE_PASS(LowerInvoke, "lowerinvoke",
+char LowerInvokeLegacyPass::ID = 0;
+INITIALIZE_PASS(LowerInvokeLegacyPass, "lowerinvoke",
"Lower invoke and unwind, for unwindless code generators",
false, false)
-char &llvm::LowerInvokePassID = LowerInvoke::ID;
-
-// Public Interface To the LowerInvoke pass.
-FunctionPass *llvm::createLowerInvokePass() {
- return new LowerInvoke();
-}
-
-bool LowerInvoke::runOnFunction(Function &F) {
+static bool runImpl(Function &F) {
bool Changed = false;
for (BasicBlock &BB : F)
if (InvokeInst *II = dyn_cast<InvokeInst>(BB.getTerminator())) {
- SmallVector<Value*,16> CallArgs(II->op_begin(), II->op_end() - 3);
+ SmallVector<Value *, 16> CallArgs(II->op_begin(), II->op_end() - 3);
// Insert a normal call instruction...
- CallInst *NewCall = CallInst::Create(II->getCalledValue(),
- CallArgs, "", II);
+ CallInst *NewCall =
+ CallInst::Create(II->getCalledValue(), CallArgs, "", II);
NewCall->takeName(II);
NewCall->setCallingConv(II->getCallingConv());
NewCall->setAttributes(II->getAttributes());
@@ -73,7 +67,28 @@ bool LowerInvoke::runOnFunction(Function &F) {
// Remove the invoke instruction now.
BB.getInstList().erase(II);
- ++NumInvokes; Changed = true;
+ ++NumInvokes;
+ Changed = true;
}
return Changed;
}
+
+bool LowerInvokeLegacyPass::runOnFunction(Function &F) {
+ return runImpl(F);
+}
+
+namespace llvm {
+char &LowerInvokePassID = LowerInvokeLegacyPass::ID;
+
+// Public Interface To the LowerInvoke pass.
+FunctionPass *createLowerInvokePass() { return new LowerInvokeLegacyPass(); }
+
+PreservedAnalyses LowerInvokePass::run(Function &F,
+ FunctionAnalysisManager &AM) {
+ bool Changed = runImpl(F);
+ if (!Changed)
+ return PreservedAnalyses::all();
+
+ return PreservedAnalyses::none();
+}
+}
diff --git a/contrib/llvm/lib/Transforms/Utils/LowerSwitch.cpp b/contrib/llvm/lib/Transforms/Utils/LowerSwitch.cpp
index 5c07469..75cd3bc 100644
--- a/contrib/llvm/lib/Transforms/Utils/LowerSwitch.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/LowerSwitch.cpp
@@ -478,10 +478,10 @@ void LowerSwitch::processSwitchInst(SwitchInst *SI,
// cases.
assert(MaxPop > 0 && PopSucc);
Default = PopSucc;
- Cases.erase(std::remove_if(
- Cases.begin(), Cases.end(),
- [PopSucc](const CaseRange &R) { return R.BB == PopSucc; }),
- Cases.end());
+ Cases.erase(
+ remove_if(Cases,
+ [PopSucc](const CaseRange &R) { return R.BB == PopSucc; }),
+ Cases.end());
// If there are no cases left, just branch.
if (Cases.empty()) {
diff --git a/contrib/llvm/lib/Transforms/Utils/Mem2Reg.cpp b/contrib/llvm/lib/Transforms/Utils/Mem2Reg.cpp
index 1419254..24b3b12 100644
--- a/contrib/llvm/lib/Transforms/Utils/Mem2Reg.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/Mem2Reg.cpp
@@ -53,7 +53,7 @@ static bool promoteMemoryToRegister(Function &F, DominatorTree &DT,
return Changed;
}
-PreservedAnalyses PromotePass::run(Function &F, AnalysisManager<Function> &AM) {
+PreservedAnalyses PromotePass::run(Function &F, FunctionAnalysisManager &AM) {
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
auto &AC = AM.getResult<AssumptionAnalysis>(F);
if (!promoteMemoryToRegister(F, DT, AC))
diff --git a/contrib/llvm/lib/Transforms/Utils/MemorySSA.cpp b/contrib/llvm/lib/Transforms/Utils/MemorySSA.cpp
index 8ba3cae..1ce4225 100644
--- a/contrib/llvm/lib/Transforms/Utils/MemorySSA.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/MemorySSA.cpp
@@ -17,6 +17,7 @@
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/Statistic.h"
@@ -60,6 +61,11 @@ INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass)
INITIALIZE_PASS_END(MemorySSAPrinterLegacyPass, "print-memoryssa",
"Memory SSA Printer", false, false)
+static cl::opt<unsigned> MaxCheckLimit(
+ "memssa-check-limit", cl::Hidden, cl::init(100),
+ cl::desc("The maximum number of stores/phis MemorySSA"
+ "will consider trying to walk past (default = 100)"));
+
static cl::opt<bool>
VerifyMemorySSA("verify-memoryssa", cl::init(false), cl::Hidden,
cl::desc("Verify MemorySSA in legacy printer pass."));
@@ -86,7 +92,963 @@ public:
OS << "; " << *MA << "\n";
}
};
+}
+
+namespace {
+/// Our current alias analysis API differentiates heavily between calls and
+/// non-calls, and functions called on one usually assert on the other.
+/// This class encapsulates the distinction to simplify other code that wants
+/// "Memory affecting instructions and related data" to use as a key.
+/// For example, this class is used as a densemap key in the use optimizer.
+class MemoryLocOrCall {
+public:
+ MemoryLocOrCall() : IsCall(false) {}
+ MemoryLocOrCall(MemoryUseOrDef *MUD)
+ : MemoryLocOrCall(MUD->getMemoryInst()) {}
+ MemoryLocOrCall(const MemoryUseOrDef *MUD)
+ : MemoryLocOrCall(MUD->getMemoryInst()) {}
+
+ MemoryLocOrCall(Instruction *Inst) {
+ if (ImmutableCallSite(Inst)) {
+ IsCall = true;
+ CS = ImmutableCallSite(Inst);
+ } else {
+ IsCall = false;
+ // There is no such thing as a memorylocation for a fence inst, and it is
+ // unique in that regard.
+ if (!isa<FenceInst>(Inst))
+ Loc = MemoryLocation::get(Inst);
+ }
+ }
+
+ explicit MemoryLocOrCall(const MemoryLocation &Loc)
+ : IsCall(false), Loc(Loc) {}
+
+ bool IsCall;
+ ImmutableCallSite getCS() const {
+ assert(IsCall);
+ return CS;
+ }
+ MemoryLocation getLoc() const {
+ assert(!IsCall);
+ return Loc;
+ }
+
+ bool operator==(const MemoryLocOrCall &Other) const {
+ if (IsCall != Other.IsCall)
+ return false;
+
+ if (IsCall)
+ return CS.getCalledValue() == Other.CS.getCalledValue();
+ return Loc == Other.Loc;
+ }
+
+private:
+ union {
+ ImmutableCallSite CS;
+ MemoryLocation Loc;
+ };
+};
+}
+
+namespace llvm {
+template <> struct DenseMapInfo<MemoryLocOrCall> {
+ static inline MemoryLocOrCall getEmptyKey() {
+ return MemoryLocOrCall(DenseMapInfo<MemoryLocation>::getEmptyKey());
+ }
+ static inline MemoryLocOrCall getTombstoneKey() {
+ return MemoryLocOrCall(DenseMapInfo<MemoryLocation>::getTombstoneKey());
+ }
+ static unsigned getHashValue(const MemoryLocOrCall &MLOC) {
+ if (MLOC.IsCall)
+ return hash_combine(MLOC.IsCall,
+ DenseMapInfo<const Value *>::getHashValue(
+ MLOC.getCS().getCalledValue()));
+ return hash_combine(
+ MLOC.IsCall, DenseMapInfo<MemoryLocation>::getHashValue(MLOC.getLoc()));
+ }
+ static bool isEqual(const MemoryLocOrCall &LHS, const MemoryLocOrCall &RHS) {
+ return LHS == RHS;
+ }
+};
+
+enum class Reorderability { Always, IfNoAlias, Never };
+
+/// This does one-way checks to see if Use could theoretically be hoisted above
+/// MayClobber. This will not check the other way around.
+///
+/// This assumes that, for the purposes of MemorySSA, Use comes directly after
+/// MayClobber, with no potentially clobbering operations in between them.
+/// (Where potentially clobbering ops are memory barriers, aliased stores, etc.)
+static Reorderability getLoadReorderability(const LoadInst *Use,
+ const LoadInst *MayClobber) {
+ bool VolatileUse = Use->isVolatile();
+ bool VolatileClobber = MayClobber->isVolatile();
+ // Volatile operations may never be reordered with other volatile operations.
+ if (VolatileUse && VolatileClobber)
+ return Reorderability::Never;
+
+ // The lang ref allows reordering of volatile and non-volatile operations.
+ // Whether an aliasing nonvolatile load and volatile load can be reordered,
+ // though, is ambiguous. Because it may not be best to exploit this ambiguity,
+ // we only allow volatile/non-volatile reordering if the volatile and
+ // non-volatile operations don't alias.
+ Reorderability Result = VolatileUse || VolatileClobber
+ ? Reorderability::IfNoAlias
+ : Reorderability::Always;
+
+ // If a load is seq_cst, it cannot be moved above other loads. If its ordering
+ // is weaker, it can be moved above other loads. We just need to be sure that
+ // MayClobber isn't an acquire load, because loads can't be moved above
+ // acquire loads.
+ //
+ // Note that this explicitly *does* allow the free reordering of monotonic (or
+ // weaker) loads of the same address.
+ bool SeqCstUse = Use->getOrdering() == AtomicOrdering::SequentiallyConsistent;
+ bool MayClobberIsAcquire = isAtLeastOrStrongerThan(MayClobber->getOrdering(),
+ AtomicOrdering::Acquire);
+ if (SeqCstUse || MayClobberIsAcquire)
+ return Reorderability::Never;
+ return Result;
+}
+
+static bool instructionClobbersQuery(MemoryDef *MD,
+ const MemoryLocation &UseLoc,
+ const Instruction *UseInst,
+ AliasAnalysis &AA) {
+ Instruction *DefInst = MD->getMemoryInst();
+ assert(DefInst && "Defining instruction not actually an instruction");
+
+ if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(DefInst)) {
+ // These intrinsics will show up as affecting memory, but they are just
+ // markers.
+ switch (II->getIntrinsicID()) {
+ case Intrinsic::lifetime_start:
+ case Intrinsic::lifetime_end:
+ case Intrinsic::invariant_start:
+ case Intrinsic::invariant_end:
+ case Intrinsic::assume:
+ return false;
+ default:
+ break;
+ }
+ }
+
+ ImmutableCallSite UseCS(UseInst);
+ if (UseCS) {
+ ModRefInfo I = AA.getModRefInfo(DefInst, UseCS);
+ return I != MRI_NoModRef;
+ }
+
+ if (auto *DefLoad = dyn_cast<LoadInst>(DefInst)) {
+ if (auto *UseLoad = dyn_cast<LoadInst>(UseInst)) {
+ switch (getLoadReorderability(UseLoad, DefLoad)) {
+ case Reorderability::Always:
+ return false;
+ case Reorderability::Never:
+ return true;
+ case Reorderability::IfNoAlias:
+ return !AA.isNoAlias(UseLoc, MemoryLocation::get(DefLoad));
+ }
+ }
+ }
+
+ return AA.getModRefInfo(DefInst, UseLoc) & MRI_Mod;
+}
+
+static bool instructionClobbersQuery(MemoryDef *MD, const MemoryUseOrDef *MU,
+ const MemoryLocOrCall &UseMLOC,
+ AliasAnalysis &AA) {
+ // FIXME: This is a temporary hack to allow a single instructionClobbersQuery
+ // to exist while MemoryLocOrCall is pushed through places.
+ if (UseMLOC.IsCall)
+ return instructionClobbersQuery(MD, MemoryLocation(), MU->getMemoryInst(),
+ AA);
+ return instructionClobbersQuery(MD, UseMLOC.getLoc(), MU->getMemoryInst(),
+ AA);
+}
+
+// Return true when MD may alias MU, return false otherwise.
+bool defClobbersUseOrDef(MemoryDef *MD, const MemoryUseOrDef *MU,
+ AliasAnalysis &AA) {
+ return instructionClobbersQuery(MD, MU, MemoryLocOrCall(MU), AA);
+}
+}
+
+namespace {
+struct UpwardsMemoryQuery {
+ // True if our original query started off as a call
+ bool IsCall;
+ // The pointer location we started the query with. This will be empty if
+ // IsCall is true.
+ MemoryLocation StartingLoc;
+ // This is the instruction we were querying about.
+ const Instruction *Inst;
+ // The MemoryAccess we actually got called with, used to test local domination
+ const MemoryAccess *OriginalAccess;
+
+ UpwardsMemoryQuery()
+ : IsCall(false), Inst(nullptr), OriginalAccess(nullptr) {}
+
+ UpwardsMemoryQuery(const Instruction *Inst, const MemoryAccess *Access)
+ : IsCall(ImmutableCallSite(Inst)), Inst(Inst), OriginalAccess(Access) {
+ if (!IsCall)
+ StartingLoc = MemoryLocation::get(Inst);
+ }
+};
+
+static bool lifetimeEndsAt(MemoryDef *MD, const MemoryLocation &Loc,
+ AliasAnalysis &AA) {
+ Instruction *Inst = MD->getMemoryInst();
+ if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst)) {
+ switch (II->getIntrinsicID()) {
+ case Intrinsic::lifetime_start:
+ case Intrinsic::lifetime_end:
+ return AA.isMustAlias(MemoryLocation(II->getArgOperand(1)), Loc);
+ default:
+ return false;
+ }
+ }
+ return false;
+}
+
+static bool isUseTriviallyOptimizableToLiveOnEntry(AliasAnalysis &AA,
+ const Instruction *I) {
+ // If the memory can't be changed, then loads of the memory can't be
+ // clobbered.
+ //
+ // FIXME: We should handle invariant groups, as well. It's a bit harder,
+ // because we need to pay close attention to invariant group barriers.
+ return isa<LoadInst>(I) && (I->getMetadata(LLVMContext::MD_invariant_load) ||
+ AA.pointsToConstantMemory(I));
+}
+
+/// Cache for our caching MemorySSA walker.
+class WalkerCache {
+ DenseMap<ConstMemoryAccessPair, MemoryAccess *> Accesses;
+ DenseMap<const MemoryAccess *, MemoryAccess *> Calls;
+
+public:
+ MemoryAccess *lookup(const MemoryAccess *MA, const MemoryLocation &Loc,
+ bool IsCall) const {
+ ++NumClobberCacheLookups;
+ MemoryAccess *R = IsCall ? Calls.lookup(MA) : Accesses.lookup({MA, Loc});
+ if (R)
+ ++NumClobberCacheHits;
+ return R;
+ }
+
+ bool insert(const MemoryAccess *MA, MemoryAccess *To,
+ const MemoryLocation &Loc, bool IsCall) {
+ // This is fine for Phis, since there are times where we can't optimize
+ // them. Making a def its own clobber is never correct, though.
+ assert((MA != To || isa<MemoryPhi>(MA)) &&
+ "Something can't clobber itself!");
+
+ ++NumClobberCacheInserts;
+ bool Inserted;
+ if (IsCall)
+ Inserted = Calls.insert({MA, To}).second;
+ else
+ Inserted = Accesses.insert({{MA, Loc}, To}).second;
+
+ return Inserted;
+ }
+
+ bool remove(const MemoryAccess *MA, const MemoryLocation &Loc, bool IsCall) {
+ return IsCall ? Calls.erase(MA) : Accesses.erase({MA, Loc});
+ }
+
+ void clear() {
+ Accesses.clear();
+ Calls.clear();
+ }
+
+ bool contains(const MemoryAccess *MA) const {
+ for (auto &P : Accesses)
+ if (P.first.first == MA || P.second == MA)
+ return true;
+ for (auto &P : Calls)
+ if (P.first == MA || P.second == MA)
+ return true;
+ return false;
+ }
+};
+
+/// Walks the defining uses of MemoryDefs. Stops after we hit something that has
+/// no defining use (e.g. a MemoryPhi or liveOnEntry). Note that, when comparing
+/// against a null def_chain_iterator, this will compare equal only after
+/// walking said Phi/liveOnEntry.
+struct def_chain_iterator
+ : public iterator_facade_base<def_chain_iterator, std::forward_iterator_tag,
+ MemoryAccess *> {
+ def_chain_iterator() : MA(nullptr) {}
+ def_chain_iterator(MemoryAccess *MA) : MA(MA) {}
+
+ MemoryAccess *operator*() const { return MA; }
+
+ def_chain_iterator &operator++() {
+ // N.B. liveOnEntry has a null defining access.
+ if (auto *MUD = dyn_cast<MemoryUseOrDef>(MA))
+ MA = MUD->getDefiningAccess();
+ else
+ MA = nullptr;
+ return *this;
+ }
+
+ bool operator==(const def_chain_iterator &O) const { return MA == O.MA; }
+
+private:
+ MemoryAccess *MA;
+};
+
+static iterator_range<def_chain_iterator>
+def_chain(MemoryAccess *MA, MemoryAccess *UpTo = nullptr) {
+#ifdef EXPENSIVE_CHECKS
+ assert((!UpTo || find(def_chain(MA), UpTo) != def_chain_iterator()) &&
+ "UpTo isn't in the def chain!");
+#endif
+ return make_range(def_chain_iterator(MA), def_chain_iterator(UpTo));
+}
+
+/// Verifies that `Start` is clobbered by `ClobberAt`, and that nothing
+/// inbetween `Start` and `ClobberAt` can clobbers `Start`.
+///
+/// This is meant to be as simple and self-contained as possible. Because it
+/// uses no cache, etc., it can be relatively expensive.
+///
+/// \param Start The MemoryAccess that we want to walk from.
+/// \param ClobberAt A clobber for Start.
+/// \param StartLoc The MemoryLocation for Start.
+/// \param MSSA The MemorySSA isntance that Start and ClobberAt belong to.
+/// \param Query The UpwardsMemoryQuery we used for our search.
+/// \param AA The AliasAnalysis we used for our search.
+static void LLVM_ATTRIBUTE_UNUSED
+checkClobberSanity(MemoryAccess *Start, MemoryAccess *ClobberAt,
+ const MemoryLocation &StartLoc, const MemorySSA &MSSA,
+ const UpwardsMemoryQuery &Query, AliasAnalysis &AA) {
+ assert(MSSA.dominates(ClobberAt, Start) && "Clobber doesn't dominate start?");
+
+ if (MSSA.isLiveOnEntryDef(Start)) {
+ assert(MSSA.isLiveOnEntryDef(ClobberAt) &&
+ "liveOnEntry must clobber itself");
+ return;
+ }
+
+ bool FoundClobber = false;
+ DenseSet<MemoryAccessPair> VisitedPhis;
+ SmallVector<MemoryAccessPair, 8> Worklist;
+ Worklist.emplace_back(Start, StartLoc);
+ // Walk all paths from Start to ClobberAt, while looking for clobbers. If one
+ // is found, complain.
+ while (!Worklist.empty()) {
+ MemoryAccessPair MAP = Worklist.pop_back_val();
+ // All we care about is that nothing from Start to ClobberAt clobbers Start.
+ // We learn nothing from revisiting nodes.
+ if (!VisitedPhis.insert(MAP).second)
+ continue;
+
+ for (MemoryAccess *MA : def_chain(MAP.first)) {
+ if (MA == ClobberAt) {
+ if (auto *MD = dyn_cast<MemoryDef>(MA)) {
+ // instructionClobbersQuery isn't essentially free, so don't use `|=`,
+ // since it won't let us short-circuit.
+ //
+ // Also, note that this can't be hoisted out of the `Worklist` loop,
+ // since MD may only act as a clobber for 1 of N MemoryLocations.
+ FoundClobber =
+ FoundClobber || MSSA.isLiveOnEntryDef(MD) ||
+ instructionClobbersQuery(MD, MAP.second, Query.Inst, AA);
+ }
+ break;
+ }
+
+ // We should never hit liveOnEntry, unless it's the clobber.
+ assert(!MSSA.isLiveOnEntryDef(MA) && "Hit liveOnEntry before clobber?");
+
+ if (auto *MD = dyn_cast<MemoryDef>(MA)) {
+ (void)MD;
+ assert(!instructionClobbersQuery(MD, MAP.second, Query.Inst, AA) &&
+ "Found clobber before reaching ClobberAt!");
+ continue;
+ }
+
+ assert(isa<MemoryPhi>(MA));
+ Worklist.append(upward_defs_begin({MA, MAP.second}), upward_defs_end());
+ }
+ }
+
+ // If ClobberAt is a MemoryPhi, we can assume something above it acted as a
+ // clobber. Otherwise, `ClobberAt` should've acted as a clobber at some point.
+ assert((isa<MemoryPhi>(ClobberAt) || FoundClobber) &&
+ "ClobberAt never acted as a clobber");
+}
+
+/// Our algorithm for walking (and trying to optimize) clobbers, all wrapped up
+/// in one class.
+class ClobberWalker {
+ /// Save a few bytes by using unsigned instead of size_t.
+ using ListIndex = unsigned;
+
+ /// Represents a span of contiguous MemoryDefs, potentially ending in a
+ /// MemoryPhi.
+ struct DefPath {
+ MemoryLocation Loc;
+ // Note that, because we always walk in reverse, Last will always dominate
+ // First. Also note that First and Last are inclusive.
+ MemoryAccess *First;
+ MemoryAccess *Last;
+ Optional<ListIndex> Previous;
+
+ DefPath(const MemoryLocation &Loc, MemoryAccess *First, MemoryAccess *Last,
+ Optional<ListIndex> Previous)
+ : Loc(Loc), First(First), Last(Last), Previous(Previous) {}
+
+ DefPath(const MemoryLocation &Loc, MemoryAccess *Init,
+ Optional<ListIndex> Previous)
+ : DefPath(Loc, Init, Init, Previous) {}
+ };
+
+ const MemorySSA &MSSA;
+ AliasAnalysis &AA;
+ DominatorTree &DT;
+ WalkerCache &WC;
+ UpwardsMemoryQuery *Query;
+ bool UseCache;
+
+ // Phi optimization bookkeeping
+ SmallVector<DefPath, 32> Paths;
+ DenseSet<ConstMemoryAccessPair> VisitedPhis;
+ DenseMap<const BasicBlock *, MemoryAccess *> WalkTargetCache;
+
+ void setUseCache(bool Use) { UseCache = Use; }
+ bool shouldIgnoreCache() const {
+ // UseCache will only be false when we're debugging, or when expensive
+ // checks are enabled. In either case, we don't care deeply about speed.
+ return LLVM_UNLIKELY(!UseCache);
+ }
+
+ void addCacheEntry(const MemoryAccess *What, MemoryAccess *To,
+ const MemoryLocation &Loc) const {
+// EXPENSIVE_CHECKS because most of these queries are redundant.
+#ifdef EXPENSIVE_CHECKS
+ assert(MSSA.dominates(To, What));
+#endif
+ if (shouldIgnoreCache())
+ return;
+ WC.insert(What, To, Loc, Query->IsCall);
+ }
+
+ MemoryAccess *lookupCache(const MemoryAccess *MA, const MemoryLocation &Loc) {
+ return shouldIgnoreCache() ? nullptr : WC.lookup(MA, Loc, Query->IsCall);
+ }
+
+ void cacheDefPath(const DefPath &DN, MemoryAccess *Target) const {
+ if (shouldIgnoreCache())
+ return;
+
+ for (MemoryAccess *MA : def_chain(DN.First, DN.Last))
+ addCacheEntry(MA, Target, DN.Loc);
+
+ // DefPaths only express the path we walked. So, DN.Last could either be a
+ // thing we want to cache, or not.
+ if (DN.Last != Target)
+ addCacheEntry(DN.Last, Target, DN.Loc);
+ }
+
+ /// Find the nearest def or phi that `From` can legally be optimized to.
+ ///
+ /// FIXME: Deduplicate this with MSSA::findDominatingDef. Ideally, MSSA should
+ /// keep track of this information for us, and allow us O(1) lookups of this
+ /// info.
+ MemoryAccess *getWalkTarget(const MemoryPhi *From) {
+ assert(From->getNumOperands() && "Phi with no operands?");
+
+ BasicBlock *BB = From->getBlock();
+ auto At = WalkTargetCache.find(BB);
+ if (At != WalkTargetCache.end())
+ return At->second;
+
+ SmallVector<const BasicBlock *, 8> ToCache;
+ ToCache.push_back(BB);
+
+ MemoryAccess *Result = MSSA.getLiveOnEntryDef();
+ DomTreeNode *Node = DT.getNode(BB);
+ while ((Node = Node->getIDom())) {
+ auto At = WalkTargetCache.find(BB);
+ if (At != WalkTargetCache.end()) {
+ Result = At->second;
+ break;
+ }
+
+ auto *Accesses = MSSA.getBlockAccesses(Node->getBlock());
+ if (Accesses) {
+ auto Iter = find_if(reverse(*Accesses), [](const MemoryAccess &MA) {
+ return !isa<MemoryUse>(MA);
+ });
+ if (Iter != Accesses->rend()) {
+ Result = const_cast<MemoryAccess *>(&*Iter);
+ break;
+ }
+ }
+
+ ToCache.push_back(Node->getBlock());
+ }
+
+ for (const BasicBlock *BB : ToCache)
+ WalkTargetCache.insert({BB, Result});
+ return Result;
+ }
+
+ /// Result of calling walkToPhiOrClobber.
+ struct UpwardsWalkResult {
+ /// The "Result" of the walk. Either a clobber, the last thing we walked, or
+ /// both.
+ MemoryAccess *Result;
+ bool IsKnownClobber;
+ bool FromCache;
+ };
+
+ /// Walk to the next Phi or Clobber in the def chain starting at Desc.Last.
+ /// This will update Desc.Last as it walks. It will (optionally) also stop at
+ /// StopAt.
+ ///
+ /// This does not test for whether StopAt is a clobber
+ UpwardsWalkResult walkToPhiOrClobber(DefPath &Desc,
+ MemoryAccess *StopAt = nullptr) {
+ assert(!isa<MemoryUse>(Desc.Last) && "Uses don't exist in my world");
+
+ for (MemoryAccess *Current : def_chain(Desc.Last)) {
+ Desc.Last = Current;
+ if (Current == StopAt)
+ return {Current, false, false};
+
+ if (auto *MD = dyn_cast<MemoryDef>(Current))
+ if (MSSA.isLiveOnEntryDef(MD) ||
+ instructionClobbersQuery(MD, Desc.Loc, Query->Inst, AA))
+ return {MD, true, false};
+
+ // Cache checks must be done last, because if Current is a clobber, the
+ // cache will contain the clobber for Current.
+ if (MemoryAccess *MA = lookupCache(Current, Desc.Loc))
+ return {MA, true, true};
+ }
+
+ assert(isa<MemoryPhi>(Desc.Last) &&
+ "Ended at a non-clobber that's not a phi?");
+ return {Desc.Last, false, false};
+ }
+
+ void addSearches(MemoryPhi *Phi, SmallVectorImpl<ListIndex> &PausedSearches,
+ ListIndex PriorNode) {
+ auto UpwardDefs = make_range(upward_defs_begin({Phi, Paths[PriorNode].Loc}),
+ upward_defs_end());
+ for (const MemoryAccessPair &P : UpwardDefs) {
+ PausedSearches.push_back(Paths.size());
+ Paths.emplace_back(P.second, P.first, PriorNode);
+ }
+ }
+
+ /// Represents a search that terminated after finding a clobber. This clobber
+ /// may or may not be present in the path of defs from LastNode..SearchStart,
+ /// since it may have been retrieved from cache.
+ struct TerminatedPath {
+ MemoryAccess *Clobber;
+ ListIndex LastNode;
+ };
+
+ /// Get an access that keeps us from optimizing to the given phi.
+ ///
+ /// PausedSearches is an array of indices into the Paths array. Its incoming
+ /// value is the indices of searches that stopped at the last phi optimization
+ /// target. It's left in an unspecified state.
+ ///
+ /// If this returns None, NewPaused is a vector of searches that terminated
+ /// at StopWhere. Otherwise, NewPaused is left in an unspecified state.
+ Optional<TerminatedPath>
+ getBlockingAccess(MemoryAccess *StopWhere,
+ SmallVectorImpl<ListIndex> &PausedSearches,
+ SmallVectorImpl<ListIndex> &NewPaused,
+ SmallVectorImpl<TerminatedPath> &Terminated) {
+ assert(!PausedSearches.empty() && "No searches to continue?");
+
+ // BFS vs DFS really doesn't make a difference here, so just do a DFS with
+ // PausedSearches as our stack.
+ while (!PausedSearches.empty()) {
+ ListIndex PathIndex = PausedSearches.pop_back_val();
+ DefPath &Node = Paths[PathIndex];
+
+ // If we've already visited this path with this MemoryLocation, we don't
+ // need to do so again.
+ //
+ // NOTE: That we just drop these paths on the ground makes caching
+ // behavior sporadic. e.g. given a diamond:
+ // A
+ // B C
+ // D
+ //
+ // ...If we walk D, B, A, C, we'll only cache the result of phi
+ // optimization for A, B, and D; C will be skipped because it dies here.
+ // This arguably isn't the worst thing ever, since:
+ // - We generally query things in a top-down order, so if we got below D
+ // without needing cache entries for {C, MemLoc}, then chances are
+ // that those cache entries would end up ultimately unused.
+ // - We still cache things for A, so C only needs to walk up a bit.
+ // If this behavior becomes problematic, we can fix without a ton of extra
+ // work.
+ if (!VisitedPhis.insert({Node.Last, Node.Loc}).second)
+ continue;
+
+ UpwardsWalkResult Res = walkToPhiOrClobber(Node, /*StopAt=*/StopWhere);
+ if (Res.IsKnownClobber) {
+ assert(Res.Result != StopWhere || Res.FromCache);
+ // If this wasn't a cache hit, we hit a clobber when walking. That's a
+ // failure.
+ TerminatedPath Term{Res.Result, PathIndex};
+ if (!Res.FromCache || !MSSA.dominates(Res.Result, StopWhere))
+ return Term;
+
+ // Otherwise, it's a valid thing to potentially optimize to.
+ Terminated.push_back(Term);
+ continue;
+ }
+
+ if (Res.Result == StopWhere) {
+ // We've hit our target. Save this path off for if we want to continue
+ // walking.
+ NewPaused.push_back(PathIndex);
+ continue;
+ }
+
+ assert(!MSSA.isLiveOnEntryDef(Res.Result) && "liveOnEntry is a clobber");
+ addSearches(cast<MemoryPhi>(Res.Result), PausedSearches, PathIndex);
+ }
+
+ return None;
+ }
+
+ template <typename T, typename Walker>
+ struct generic_def_path_iterator
+ : public iterator_facade_base<generic_def_path_iterator<T, Walker>,
+ std::forward_iterator_tag, T *> {
+ generic_def_path_iterator() : W(nullptr), N(None) {}
+ generic_def_path_iterator(Walker *W, ListIndex N) : W(W), N(N) {}
+
+ T &operator*() const { return curNode(); }
+
+ generic_def_path_iterator &operator++() {
+ N = curNode().Previous;
+ return *this;
+ }
+
+ bool operator==(const generic_def_path_iterator &O) const {
+ if (N.hasValue() != O.N.hasValue())
+ return false;
+ return !N.hasValue() || *N == *O.N;
+ }
+
+ private:
+ T &curNode() const { return W->Paths[*N]; }
+
+ Walker *W;
+ Optional<ListIndex> N;
+ };
+
+ using def_path_iterator = generic_def_path_iterator<DefPath, ClobberWalker>;
+ using const_def_path_iterator =
+ generic_def_path_iterator<const DefPath, const ClobberWalker>;
+
+ iterator_range<def_path_iterator> def_path(ListIndex From) {
+ return make_range(def_path_iterator(this, From), def_path_iterator());
+ }
+
+ iterator_range<const_def_path_iterator> const_def_path(ListIndex From) const {
+ return make_range(const_def_path_iterator(this, From),
+ const_def_path_iterator());
+ }
+
+ struct OptznResult {
+ /// The path that contains our result.
+ TerminatedPath PrimaryClobber;
+ /// The paths that we can legally cache back from, but that aren't
+ /// necessarily the result of the Phi optimization.
+ SmallVector<TerminatedPath, 4> OtherClobbers;
+ };
+
+ ListIndex defPathIndex(const DefPath &N) const {
+ // The assert looks nicer if we don't need to do &N
+ const DefPath *NP = &N;
+ assert(!Paths.empty() && NP >= &Paths.front() && NP <= &Paths.back() &&
+ "Out of bounds DefPath!");
+ return NP - &Paths.front();
+ }
+
+ /// Try to optimize a phi as best as we can. Returns a SmallVector of Paths
+ /// that act as legal clobbers. Note that this won't return *all* clobbers.
+ ///
+ /// Phi optimization algorithm tl;dr:
+ /// - Find the earliest def/phi, A, we can optimize to
+ /// - Find if all paths from the starting memory access ultimately reach A
+ /// - If not, optimization isn't possible.
+ /// - Otherwise, walk from A to another clobber or phi, A'.
+ /// - If A' is a def, we're done.
+ /// - If A' is a phi, try to optimize it.
+ ///
+ /// A path is a series of {MemoryAccess, MemoryLocation} pairs. A path
+ /// terminates when a MemoryAccess that clobbers said MemoryLocation is found.
+ OptznResult tryOptimizePhi(MemoryPhi *Phi, MemoryAccess *Start,
+ const MemoryLocation &Loc) {
+ assert(Paths.empty() && VisitedPhis.empty() &&
+ "Reset the optimization state.");
+
+ Paths.emplace_back(Loc, Start, Phi, None);
+ // Stores how many "valid" optimization nodes we had prior to calling
+ // addSearches/getBlockingAccess. Necessary for caching if we had a blocker.
+ auto PriorPathsSize = Paths.size();
+
+ SmallVector<ListIndex, 16> PausedSearches;
+ SmallVector<ListIndex, 8> NewPaused;
+ SmallVector<TerminatedPath, 4> TerminatedPaths;
+
+ addSearches(Phi, PausedSearches, 0);
+
+ // Moves the TerminatedPath with the "most dominated" Clobber to the end of
+ // Paths.
+ auto MoveDominatedPathToEnd = [&](SmallVectorImpl<TerminatedPath> &Paths) {
+ assert(!Paths.empty() && "Need a path to move");
+ auto Dom = Paths.begin();
+ for (auto I = std::next(Dom), E = Paths.end(); I != E; ++I)
+ if (!MSSA.dominates(I->Clobber, Dom->Clobber))
+ Dom = I;
+ auto Last = Paths.end() - 1;
+ if (Last != Dom)
+ std::iter_swap(Last, Dom);
+ };
+
+ MemoryPhi *Current = Phi;
+ while (1) {
+ assert(!MSSA.isLiveOnEntryDef(Current) &&
+ "liveOnEntry wasn't treated as a clobber?");
+
+ MemoryAccess *Target = getWalkTarget(Current);
+ // If a TerminatedPath doesn't dominate Target, then it wasn't a legal
+ // optimization for the prior phi.
+ assert(all_of(TerminatedPaths, [&](const TerminatedPath &P) {
+ return MSSA.dominates(P.Clobber, Target);
+ }));
+
+ // FIXME: This is broken, because the Blocker may be reported to be
+ // liveOnEntry, and we'll happily wait for that to disappear (read: never)
+ // For the moment, this is fine, since we do nothing with blocker info.
+ if (Optional<TerminatedPath> Blocker = getBlockingAccess(
+ Target, PausedSearches, NewPaused, TerminatedPaths)) {
+ // Cache our work on the blocking node, since we know that's correct.
+ cacheDefPath(Paths[Blocker->LastNode], Blocker->Clobber);
+
+ // Find the node we started at. We can't search based on N->Last, since
+ // we may have gone around a loop with a different MemoryLocation.
+ auto Iter = find_if(def_path(Blocker->LastNode), [&](const DefPath &N) {
+ return defPathIndex(N) < PriorPathsSize;
+ });
+ assert(Iter != def_path_iterator());
+
+ DefPath &CurNode = *Iter;
+ assert(CurNode.Last == Current);
+
+ // Two things:
+ // A. We can't reliably cache all of NewPaused back. Consider a case
+ // where we have two paths in NewPaused; one of which can't optimize
+ // above this phi, whereas the other can. If we cache the second path
+ // back, we'll end up with suboptimal cache entries. We can handle
+ // cases like this a bit better when we either try to find all
+ // clobbers that block phi optimization, or when our cache starts
+ // supporting unfinished searches.
+ // B. We can't reliably cache TerminatedPaths back here without doing
+ // extra checks; consider a case like:
+ // T
+ // / \
+ // D C
+ // \ /
+ // S
+ // Where T is our target, C is a node with a clobber on it, D is a
+ // diamond (with a clobber *only* on the left or right node, N), and
+ // S is our start. Say we walk to D, through the node opposite N
+ // (read: ignoring the clobber), and see a cache entry in the top
+ // node of D. That cache entry gets put into TerminatedPaths. We then
+ // walk up to C (N is later in our worklist), find the clobber, and
+ // quit. If we append TerminatedPaths to OtherClobbers, we'll cache
+ // the bottom part of D to the cached clobber, ignoring the clobber
+ // in N. Again, this problem goes away if we start tracking all
+ // blockers for a given phi optimization.
+ TerminatedPath Result{CurNode.Last, defPathIndex(CurNode)};
+ return {Result, {}};
+ }
+
+ // If there's nothing left to search, then all paths led to valid clobbers
+ // that we got from our cache; pick the nearest to the start, and allow
+ // the rest to be cached back.
+ if (NewPaused.empty()) {
+ MoveDominatedPathToEnd(TerminatedPaths);
+ TerminatedPath Result = TerminatedPaths.pop_back_val();
+ return {Result, std::move(TerminatedPaths)};
+ }
+
+ MemoryAccess *DefChainEnd = nullptr;
+ SmallVector<TerminatedPath, 4> Clobbers;
+ for (ListIndex Paused : NewPaused) {
+ UpwardsWalkResult WR = walkToPhiOrClobber(Paths[Paused]);
+ if (WR.IsKnownClobber)
+ Clobbers.push_back({WR.Result, Paused});
+ else
+ // Micro-opt: If we hit the end of the chain, save it.
+ DefChainEnd = WR.Result;
+ }
+
+ if (!TerminatedPaths.empty()) {
+ // If we couldn't find the dominating phi/liveOnEntry in the above loop,
+ // do it now.
+ if (!DefChainEnd)
+ for (MemoryAccess *MA : def_chain(Target))
+ DefChainEnd = MA;
+
+ // If any of the terminated paths don't dominate the phi we'll try to
+ // optimize, we need to figure out what they are and quit.
+ const BasicBlock *ChainBB = DefChainEnd->getBlock();
+ for (const TerminatedPath &TP : TerminatedPaths) {
+ // Because we know that DefChainEnd is as "high" as we can go, we
+ // don't need local dominance checks; BB dominance is sufficient.
+ if (DT.dominates(ChainBB, TP.Clobber->getBlock()))
+ Clobbers.push_back(TP);
+ }
+ }
+
+ // If we have clobbers in the def chain, find the one closest to Current
+ // and quit.
+ if (!Clobbers.empty()) {
+ MoveDominatedPathToEnd(Clobbers);
+ TerminatedPath Result = Clobbers.pop_back_val();
+ return {Result, std::move(Clobbers)};
+ }
+
+ assert(all_of(NewPaused,
+ [&](ListIndex I) { return Paths[I].Last == DefChainEnd; }));
+
+ // Because liveOnEntry is a clobber, this must be a phi.
+ auto *DefChainPhi = cast<MemoryPhi>(DefChainEnd);
+
+ PriorPathsSize = Paths.size();
+ PausedSearches.clear();
+ for (ListIndex I : NewPaused)
+ addSearches(DefChainPhi, PausedSearches, I);
+ NewPaused.clear();
+
+ Current = DefChainPhi;
+ }
+ }
+
+ /// Caches everything in an OptznResult.
+ void cacheOptResult(const OptznResult &R) {
+ if (R.OtherClobbers.empty()) {
+ // If we're not going to be caching OtherClobbers, don't bother with
+ // marking visited/etc.
+ for (const DefPath &N : const_def_path(R.PrimaryClobber.LastNode))
+ cacheDefPath(N, R.PrimaryClobber.Clobber);
+ return;
+ }
+
+ // PrimaryClobber is our answer. If we can cache anything back, we need to
+ // stop caching when we visit PrimaryClobber.
+ SmallBitVector Visited(Paths.size());
+ for (const DefPath &N : const_def_path(R.PrimaryClobber.LastNode)) {
+ Visited[defPathIndex(N)] = true;
+ cacheDefPath(N, R.PrimaryClobber.Clobber);
+ }
+
+ for (const TerminatedPath &P : R.OtherClobbers) {
+ for (const DefPath &N : const_def_path(P.LastNode)) {
+ ListIndex NIndex = defPathIndex(N);
+ if (Visited[NIndex])
+ break;
+ Visited[NIndex] = true;
+ cacheDefPath(N, P.Clobber);
+ }
+ }
+ }
+
+ void verifyOptResult(const OptznResult &R) const {
+ assert(all_of(R.OtherClobbers, [&](const TerminatedPath &P) {
+ return MSSA.dominates(P.Clobber, R.PrimaryClobber.Clobber);
+ }));
+ }
+
+ void resetPhiOptznState() {
+ Paths.clear();
+ VisitedPhis.clear();
+ }
+
+public:
+ ClobberWalker(const MemorySSA &MSSA, AliasAnalysis &AA, DominatorTree &DT,
+ WalkerCache &WC)
+ : MSSA(MSSA), AA(AA), DT(DT), WC(WC), UseCache(true) {}
+
+ void reset() { WalkTargetCache.clear(); }
+
+ /// Finds the nearest clobber for the given query, optimizing phis if
+ /// possible.
+ MemoryAccess *findClobber(MemoryAccess *Start, UpwardsMemoryQuery &Q,
+ bool UseWalkerCache = true) {
+ setUseCache(UseWalkerCache);
+ Query = &Q;
+
+ MemoryAccess *Current = Start;
+ // This walker pretends uses don't exist. If we're handed one, silently grab
+ // its def. (This has the nice side-effect of ensuring we never cache uses)
+ if (auto *MU = dyn_cast<MemoryUse>(Start))
+ Current = MU->getDefiningAccess();
+
+ DefPath FirstDesc(Q.StartingLoc, Current, Current, None);
+ // Fast path for the overly-common case (no crazy phi optimization
+ // necessary)
+ UpwardsWalkResult WalkResult = walkToPhiOrClobber(FirstDesc);
+ MemoryAccess *Result;
+ if (WalkResult.IsKnownClobber) {
+ cacheDefPath(FirstDesc, WalkResult.Result);
+ Result = WalkResult.Result;
+ } else {
+ OptznResult OptRes = tryOptimizePhi(cast<MemoryPhi>(FirstDesc.Last),
+ Current, Q.StartingLoc);
+ verifyOptResult(OptRes);
+ cacheOptResult(OptRes);
+ resetPhiOptznState();
+ Result = OptRes.PrimaryClobber.Clobber;
+ }
+
+#ifdef EXPENSIVE_CHECKS
+ checkClobberSanity(Current, Result, Q.StartingLoc, MSSA, Q, AA);
+#endif
+ return Result;
+ }
+
+ void verify(const MemorySSA *MSSA) { assert(MSSA == &this->MSSA); }
+};
+
+struct RenamePassData {
+ DomTreeNode *DTN;
+ DomTreeNode::const_iterator ChildIt;
+ MemoryAccess *IncomingVal;
+
+ RenamePassData(DomTreeNode *D, DomTreeNode::const_iterator It,
+ MemoryAccess *M)
+ : DTN(D), ChildIt(It), IncomingVal(M) {}
+ void swap(RenamePassData &RHS) {
+ std::swap(DTN, RHS.DTN);
+ std::swap(ChildIt, RHS.ChildIt);
+ std::swap(IncomingVal, RHS.IncomingVal);
+ }
+};
+} // anonymous namespace
+namespace llvm {
/// \brief A MemorySSAWalker that does AA walks and caching of lookups to
/// disambiguate accesses.
///
@@ -121,59 +1083,39 @@ public:
/// ret i32 %r
/// }
class MemorySSA::CachingWalker final : public MemorySSAWalker {
+ WalkerCache Cache;
+ ClobberWalker Walker;
+ bool AutoResetWalker;
+
+ MemoryAccess *getClobberingMemoryAccess(MemoryAccess *, UpwardsMemoryQuery &);
+ void verifyRemoved(MemoryAccess *);
+
public:
CachingWalker(MemorySSA *, AliasAnalysis *, DominatorTree *);
~CachingWalker() override;
- MemoryAccess *getClobberingMemoryAccess(const Instruction *) override;
+ using MemorySSAWalker::getClobberingMemoryAccess;
+ MemoryAccess *getClobberingMemoryAccess(MemoryAccess *) override;
MemoryAccess *getClobberingMemoryAccess(MemoryAccess *,
- MemoryLocation &) override;
+ const MemoryLocation &) override;
void invalidateInfo(MemoryAccess *) override;
-protected:
- struct UpwardsMemoryQuery;
- MemoryAccess *doCacheLookup(const MemoryAccess *, const UpwardsMemoryQuery &,
- const MemoryLocation &);
-
- void doCacheInsert(const MemoryAccess *, MemoryAccess *,
- const UpwardsMemoryQuery &, const MemoryLocation &);
+ /// Whether we call resetClobberWalker() after each time we *actually* walk to
+ /// answer a clobber query.
+ void setAutoResetWalker(bool AutoReset) { AutoResetWalker = AutoReset; }
- void doCacheRemove(const MemoryAccess *, const UpwardsMemoryQuery &,
- const MemoryLocation &);
+ /// Drop the walker's persistent data structures. At the moment, this means
+ /// "drop the walker's cache of BasicBlocks ->
+ /// earliest-MemoryAccess-we-can-optimize-to". This is necessary if we're
+ /// going to have DT updates, if we remove MemoryAccesses, etc.
+ void resetClobberWalker() { Walker.reset(); }
-private:
- MemoryAccessPair UpwardsDFSWalk(MemoryAccess *, const MemoryLocation &,
- UpwardsMemoryQuery &, bool);
- MemoryAccess *getClobberingMemoryAccess(MemoryAccess *, UpwardsMemoryQuery &);
- bool instructionClobbersQuery(const MemoryDef *, UpwardsMemoryQuery &,
- const MemoryLocation &Loc) const;
- void verifyRemoved(MemoryAccess *);
- SmallDenseMap<ConstMemoryAccessPair, MemoryAccess *>
- CachedUpwardsClobberingAccess;
- DenseMap<const MemoryAccess *, MemoryAccess *> CachedUpwardsClobberingCall;
- AliasAnalysis *AA;
- DominatorTree *DT;
-};
-}
-
-namespace {
-struct RenamePassData {
- DomTreeNode *DTN;
- DomTreeNode::const_iterator ChildIt;
- MemoryAccess *IncomingVal;
-
- RenamePassData(DomTreeNode *D, DomTreeNode::const_iterator It,
- MemoryAccess *M)
- : DTN(D), ChildIt(It), IncomingVal(M) {}
- void swap(RenamePassData &RHS) {
- std::swap(DTN, RHS.DTN);
- std::swap(ChildIt, RHS.ChildIt);
- std::swap(IncomingVal, RHS.IncomingVal);
+ void verify(const MemorySSA *MSSA) override {
+ MemorySSAWalker::verify(MSSA);
+ Walker.verify(MSSA);
}
};
-}
-namespace llvm {
/// \brief Rename a single basic block into MemorySSA form.
/// Uses the standard SSA renaming algorithm.
/// \returns The new incoming value.
@@ -184,21 +1126,13 @@ MemoryAccess *MemorySSA::renameBlock(BasicBlock *BB,
if (It != PerBlockAccesses.end()) {
AccessList *Accesses = It->second.get();
for (MemoryAccess &L : *Accesses) {
- switch (L.getValueID()) {
- case Value::MemoryUseVal:
- cast<MemoryUse>(&L)->setDefiningAccess(IncomingVal);
- break;
- case Value::MemoryDefVal:
- // We can't legally optimize defs, because we only allow single
- // memory phis/uses on operations, and if we optimize these, we can
- // end up with multiple reaching defs. Uses do not have this
- // problem, since they do not produce a value
- cast<MemoryDef>(&L)->setDefiningAccess(IncomingVal);
+ if (MemoryUseOrDef *MUD = dyn_cast<MemoryUseOrDef>(&L)) {
+ if (MUD->getDefiningAccess() == nullptr)
+ MUD->setDefiningAccess(IncomingVal);
+ if (isa<MemoryDef>(&L))
+ IncomingVal = &L;
+ } else {
IncomingVal = &L;
- break;
- case Value::MemoryPhiVal:
- IncomingVal = &L;
- break;
}
}
}
@@ -295,21 +1229,10 @@ void MemorySSA::markUnreachableAsLiveOnEntry(BasicBlock *BB) {
MemorySSA::MemorySSA(Function &Func, AliasAnalysis *AA, DominatorTree *DT)
: AA(AA), DT(DT), F(Func), LiveOnEntryDef(nullptr), Walker(nullptr),
- NextID(0) {
+ NextID(INVALID_MEMORYACCESS_ID) {
buildMemorySSA();
}
-MemorySSA::MemorySSA(MemorySSA &&MSSA)
- : AA(MSSA.AA), DT(MSSA.DT), F(MSSA.F),
- ValueToMemoryAccess(std::move(MSSA.ValueToMemoryAccess)),
- PerBlockAccesses(std::move(MSSA.PerBlockAccesses)),
- LiveOnEntryDef(std::move(MSSA.LiveOnEntryDef)),
- Walker(std::move(MSSA.Walker)), NextID(MSSA.NextID) {
- // Update the Walker MSSA pointer so it doesn't point to the moved-from MSSA
- // object any more.
- Walker->MSSA = this;
-}
-
MemorySSA::~MemorySSA() {
// Drop all our references
for (const auto &Pair : PerBlockAccesses)
@@ -325,6 +1248,245 @@ MemorySSA::AccessList *MemorySSA::getOrCreateAccessList(const BasicBlock *BB) {
return Res.first->second.get();
}
+/// This class is a batch walker of all MemoryUse's in the program, and points
+/// their defining access at the thing that actually clobbers them. Because it
+/// is a batch walker that touches everything, it does not operate like the
+/// other walkers. This walker is basically performing a top-down SSA renaming
+/// pass, where the version stack is used as the cache. This enables it to be
+/// significantly more time and memory efficient than using the regular walker,
+/// which is walking bottom-up.
+class MemorySSA::OptimizeUses {
+public:
+ OptimizeUses(MemorySSA *MSSA, MemorySSAWalker *Walker, AliasAnalysis *AA,
+ DominatorTree *DT)
+ : MSSA(MSSA), Walker(Walker), AA(AA), DT(DT) {
+ Walker = MSSA->getWalker();
+ }
+
+ void optimizeUses();
+
+private:
+ /// This represents where a given memorylocation is in the stack.
+ struct MemlocStackInfo {
+ // This essentially is keeping track of versions of the stack. Whenever
+ // the stack changes due to pushes or pops, these versions increase.
+ unsigned long StackEpoch;
+ unsigned long PopEpoch;
+ // This is the lower bound of places on the stack to check. It is equal to
+ // the place the last stack walk ended.
+ // Note: Correctness depends on this being initialized to 0, which densemap
+ // does
+ unsigned long LowerBound;
+ const BasicBlock *LowerBoundBlock;
+ // This is where the last walk for this memory location ended.
+ unsigned long LastKill;
+ bool LastKillValid;
+ };
+ void optimizeUsesInBlock(const BasicBlock *, unsigned long &, unsigned long &,
+ SmallVectorImpl<MemoryAccess *> &,
+ DenseMap<MemoryLocOrCall, MemlocStackInfo> &);
+ MemorySSA *MSSA;
+ MemorySSAWalker *Walker;
+ AliasAnalysis *AA;
+ DominatorTree *DT;
+};
+
+/// Optimize the uses in a given block This is basically the SSA renaming
+/// algorithm, with one caveat: We are able to use a single stack for all
+/// MemoryUses. This is because the set of *possible* reaching MemoryDefs is
+/// the same for every MemoryUse. The *actual* clobbering MemoryDef is just
+/// going to be some position in that stack of possible ones.
+///
+/// We track the stack positions that each MemoryLocation needs
+/// to check, and last ended at. This is because we only want to check the
+/// things that changed since last time. The same MemoryLocation should
+/// get clobbered by the same store (getModRefInfo does not use invariantness or
+/// things like this, and if they start, we can modify MemoryLocOrCall to
+/// include relevant data)
+void MemorySSA::OptimizeUses::optimizeUsesInBlock(
+ const BasicBlock *BB, unsigned long &StackEpoch, unsigned long &PopEpoch,
+ SmallVectorImpl<MemoryAccess *> &VersionStack,
+ DenseMap<MemoryLocOrCall, MemlocStackInfo> &LocStackInfo) {
+
+ /// If no accesses, nothing to do.
+ MemorySSA::AccessList *Accesses = MSSA->getWritableBlockAccesses(BB);
+ if (Accesses == nullptr)
+ return;
+
+ // Pop everything that doesn't dominate the current block off the stack,
+ // increment the PopEpoch to account for this.
+ while (!VersionStack.empty()) {
+ BasicBlock *BackBlock = VersionStack.back()->getBlock();
+ if (DT->dominates(BackBlock, BB))
+ break;
+ while (VersionStack.back()->getBlock() == BackBlock)
+ VersionStack.pop_back();
+ ++PopEpoch;
+ }
+ for (MemoryAccess &MA : *Accesses) {
+ auto *MU = dyn_cast<MemoryUse>(&MA);
+ if (!MU) {
+ VersionStack.push_back(&MA);
+ ++StackEpoch;
+ continue;
+ }
+
+ if (isUseTriviallyOptimizableToLiveOnEntry(*AA, MU->getMemoryInst())) {
+ MU->setDefiningAccess(MSSA->getLiveOnEntryDef(), true);
+ continue;
+ }
+
+ MemoryLocOrCall UseMLOC(MU);
+ auto &LocInfo = LocStackInfo[UseMLOC];
+ // If the pop epoch changed, it means we've removed stuff from top of
+ // stack due to changing blocks. We may have to reset the lower bound or
+ // last kill info.
+ if (LocInfo.PopEpoch != PopEpoch) {
+ LocInfo.PopEpoch = PopEpoch;
+ LocInfo.StackEpoch = StackEpoch;
+ // If the lower bound was in something that no longer dominates us, we
+ // have to reset it.
+ // We can't simply track stack size, because the stack may have had
+ // pushes/pops in the meantime.
+ // XXX: This is non-optimal, but only is slower cases with heavily
+ // branching dominator trees. To get the optimal number of queries would
+ // be to make lowerbound and lastkill a per-loc stack, and pop it until
+ // the top of that stack dominates us. This does not seem worth it ATM.
+ // A much cheaper optimization would be to always explore the deepest
+ // branch of the dominator tree first. This will guarantee this resets on
+ // the smallest set of blocks.
+ if (LocInfo.LowerBoundBlock && LocInfo.LowerBoundBlock != BB &&
+ !DT->dominates(LocInfo.LowerBoundBlock, BB)) {
+ // Reset the lower bound of things to check.
+ // TODO: Some day we should be able to reset to last kill, rather than
+ // 0.
+ LocInfo.LowerBound = 0;
+ LocInfo.LowerBoundBlock = VersionStack[0]->getBlock();
+ LocInfo.LastKillValid = false;
+ }
+ } else if (LocInfo.StackEpoch != StackEpoch) {
+ // If all that has changed is the StackEpoch, we only have to check the
+ // new things on the stack, because we've checked everything before. In
+ // this case, the lower bound of things to check remains the same.
+ LocInfo.PopEpoch = PopEpoch;
+ LocInfo.StackEpoch = StackEpoch;
+ }
+ if (!LocInfo.LastKillValid) {
+ LocInfo.LastKill = VersionStack.size() - 1;
+ LocInfo.LastKillValid = true;
+ }
+
+ // At this point, we should have corrected last kill and LowerBound to be
+ // in bounds.
+ assert(LocInfo.LowerBound < VersionStack.size() &&
+ "Lower bound out of range");
+ assert(LocInfo.LastKill < VersionStack.size() &&
+ "Last kill info out of range");
+ // In any case, the new upper bound is the top of the stack.
+ unsigned long UpperBound = VersionStack.size() - 1;
+
+ if (UpperBound - LocInfo.LowerBound > MaxCheckLimit) {
+ DEBUG(dbgs() << "MemorySSA skipping optimization of " << *MU << " ("
+ << *(MU->getMemoryInst()) << ")"
+ << " because there are " << UpperBound - LocInfo.LowerBound
+ << " stores to disambiguate\n");
+ // Because we did not walk, LastKill is no longer valid, as this may
+ // have been a kill.
+ LocInfo.LastKillValid = false;
+ continue;
+ }
+ bool FoundClobberResult = false;
+ while (UpperBound > LocInfo.LowerBound) {
+ if (isa<MemoryPhi>(VersionStack[UpperBound])) {
+ // For phis, use the walker, see where we ended up, go there
+ Instruction *UseInst = MU->getMemoryInst();
+ MemoryAccess *Result = Walker->getClobberingMemoryAccess(UseInst);
+ // We are guaranteed to find it or something is wrong
+ while (VersionStack[UpperBound] != Result) {
+ assert(UpperBound != 0);
+ --UpperBound;
+ }
+ FoundClobberResult = true;
+ break;
+ }
+
+ MemoryDef *MD = cast<MemoryDef>(VersionStack[UpperBound]);
+ // If the lifetime of the pointer ends at this instruction, it's live on
+ // entry.
+ if (!UseMLOC.IsCall && lifetimeEndsAt(MD, UseMLOC.getLoc(), *AA)) {
+ // Reset UpperBound to liveOnEntryDef's place in the stack
+ UpperBound = 0;
+ FoundClobberResult = true;
+ break;
+ }
+ if (instructionClobbersQuery(MD, MU, UseMLOC, *AA)) {
+ FoundClobberResult = true;
+ break;
+ }
+ --UpperBound;
+ }
+ // At the end of this loop, UpperBound is either a clobber, or lower bound
+ // PHI walking may cause it to be < LowerBound, and in fact, < LastKill.
+ if (FoundClobberResult || UpperBound < LocInfo.LastKill) {
+ MU->setDefiningAccess(VersionStack[UpperBound], true);
+ // We were last killed now by where we got to
+ LocInfo.LastKill = UpperBound;
+ } else {
+ // Otherwise, we checked all the new ones, and now we know we can get to
+ // LastKill.
+ MU->setDefiningAccess(VersionStack[LocInfo.LastKill], true);
+ }
+ LocInfo.LowerBound = VersionStack.size() - 1;
+ LocInfo.LowerBoundBlock = BB;
+ }
+}
+
+/// Optimize uses to point to their actual clobbering definitions.
+void MemorySSA::OptimizeUses::optimizeUses() {
+
+ // We perform a non-recursive top-down dominator tree walk
+ struct StackInfo {
+ const DomTreeNode *Node;
+ DomTreeNode::const_iterator Iter;
+ };
+
+ SmallVector<MemoryAccess *, 16> VersionStack;
+ SmallVector<StackInfo, 16> DomTreeWorklist;
+ DenseMap<MemoryLocOrCall, MemlocStackInfo> LocStackInfo;
+ VersionStack.push_back(MSSA->getLiveOnEntryDef());
+
+ unsigned long StackEpoch = 1;
+ unsigned long PopEpoch = 1;
+ for (const auto *DomNode : depth_first(DT->getRootNode()))
+ optimizeUsesInBlock(DomNode->getBlock(), StackEpoch, PopEpoch, VersionStack,
+ LocStackInfo);
+}
+
+void MemorySSA::placePHINodes(
+ const SmallPtrSetImpl<BasicBlock *> &DefiningBlocks,
+ const DenseMap<const BasicBlock *, unsigned int> &BBNumbers) {
+ // Determine where our MemoryPhi's should go
+ ForwardIDFCalculator IDFs(*DT);
+ IDFs.setDefiningBlocks(DefiningBlocks);
+ SmallVector<BasicBlock *, 32> IDFBlocks;
+ IDFs.calculate(IDFBlocks);
+
+ std::sort(IDFBlocks.begin(), IDFBlocks.end(),
+ [&BBNumbers](const BasicBlock *A, const BasicBlock *B) {
+ return BBNumbers.lookup(A) < BBNumbers.lookup(B);
+ });
+
+ // Now place MemoryPhi nodes.
+ for (auto &BB : IDFBlocks) {
+ // Insert phi node
+ AccessList *Accesses = getOrCreateAccessList(BB);
+ MemoryPhi *Phi = new MemoryPhi(BB->getContext(), BB, NextID++);
+ ValueToMemoryAccess[BB] = Phi;
+ // Phi's always are placed at the front of the block.
+ Accesses->push_front(Phi);
+ }
+}
+
void MemorySSA::buildMemorySSA() {
// We create an access to represent "live on entry", for things like
// arguments or users of globals, where the memory they use is defined before
@@ -335,6 +1497,8 @@ void MemorySSA::buildMemorySSA() {
BasicBlock &StartingPoint = F.getEntryBlock();
LiveOnEntryDef = make_unique<MemoryDef>(F.getContext(), nullptr, nullptr,
&StartingPoint, NextID++);
+ DenseMap<const BasicBlock *, unsigned int> BBNumbers;
+ unsigned NextBBNum = 0;
// We maintain lists of memory accesses per-block, trading memory for time. We
// could just look up the memory access for every possible instruction in the
@@ -344,6 +1508,7 @@ void MemorySSA::buildMemorySSA() {
// Go through each block, figure out where defs occur, and chain together all
// the accesses.
for (BasicBlock &B : F) {
+ BBNumbers[&B] = NextBBNum++;
bool InsertIntoDef = false;
AccessList *Accesses = nullptr;
for (Instruction &I : B) {
@@ -361,81 +1526,20 @@ void MemorySSA::buildMemorySSA() {
if (Accesses)
DefUseBlocks.insert(&B);
}
-
- // Compute live-in.
- // Live in is normally defined as "all the blocks on the path from each def to
- // each of it's uses".
- // MemoryDef's are implicit uses of previous state, so they are also uses.
- // This means we don't really have def-only instructions. The only
- // MemoryDef's that are not really uses are those that are of the LiveOnEntry
- // variable (because LiveOnEntry can reach anywhere, and every def is a
- // must-kill of LiveOnEntry).
- // In theory, you could precisely compute live-in by using alias-analysis to
- // disambiguate defs and uses to see which really pair up with which.
- // In practice, this would be really expensive and difficult. So we simply
- // assume all defs are also uses that need to be kept live.
- // Because of this, the end result of this live-in computation will be "the
- // entire set of basic blocks that reach any use".
-
- SmallPtrSet<BasicBlock *, 32> LiveInBlocks;
- SmallVector<BasicBlock *, 64> LiveInBlockWorklist(DefUseBlocks.begin(),
- DefUseBlocks.end());
- // Now that we have a set of blocks where a value is live-in, recursively add
- // predecessors until we find the full region the value is live.
- while (!LiveInBlockWorklist.empty()) {
- BasicBlock *BB = LiveInBlockWorklist.pop_back_val();
-
- // The block really is live in here, insert it into the set. If already in
- // the set, then it has already been processed.
- if (!LiveInBlocks.insert(BB).second)
- continue;
-
- // Since the value is live into BB, it is either defined in a predecessor or
- // live into it to.
- LiveInBlockWorklist.append(pred_begin(BB), pred_end(BB));
- }
-
- // Determine where our MemoryPhi's should go
- ForwardIDFCalculator IDFs(*DT);
- IDFs.setDefiningBlocks(DefiningBlocks);
- IDFs.setLiveInBlocks(LiveInBlocks);
- SmallVector<BasicBlock *, 32> IDFBlocks;
- IDFs.calculate(IDFBlocks);
-
- // Now place MemoryPhi nodes.
- for (auto &BB : IDFBlocks) {
- // Insert phi node
- AccessList *Accesses = getOrCreateAccessList(BB);
- MemoryPhi *Phi = new MemoryPhi(BB->getContext(), BB, NextID++);
- ValueToMemoryAccess.insert(std::make_pair(BB, Phi));
- // Phi's always are placed at the front of the block.
- Accesses->push_front(Phi);
- }
+ placePHINodes(DefiningBlocks, BBNumbers);
// Now do regular SSA renaming on the MemoryDef/MemoryUse. Visited will get
// filled in with all blocks.
SmallPtrSet<BasicBlock *, 16> Visited;
renamePass(DT->getRootNode(), LiveOnEntryDef.get(), Visited);
- MemorySSAWalker *Walker = getWalker();
+ CachingWalker *Walker = getWalkerImpl();
- // Now optimize the MemoryUse's defining access to point to the nearest
- // dominating clobbering def.
- // This ensures that MemoryUse's that are killed by the same store are
- // immediate users of that store, one of the invariants we guarantee.
- for (auto DomNode : depth_first(DT)) {
- BasicBlock *BB = DomNode->getBlock();
- auto AI = PerBlockAccesses.find(BB);
- if (AI == PerBlockAccesses.end())
- continue;
- AccessList *Accesses = AI->second.get();
- for (auto &MA : *Accesses) {
- if (auto *MU = dyn_cast<MemoryUse>(&MA)) {
- Instruction *Inst = MU->getMemoryInst();
- MU->setDefiningAccess(Walker->getClobberingMemoryAccess(Inst));
- }
- }
- }
+ // We're doing a batch of updates; don't drop useful caches between them.
+ Walker->setAutoResetWalker(false);
+ OptimizeUses(this, Walker, AA, DT).optimizeUses();
+ Walker->setAutoResetWalker(true);
+ Walker->resetClobberWalker();
// Mark the uses in unreachable blocks as live on entry, so that they go
// somewhere.
@@ -444,7 +1548,9 @@ void MemorySSA::buildMemorySSA() {
markUnreachableAsLiveOnEntry(&BB);
}
-MemorySSAWalker *MemorySSA::getWalker() {
+MemorySSAWalker *MemorySSA::getWalker() { return getWalkerImpl(); }
+
+MemorySSA::CachingWalker *MemorySSA::getWalkerImpl() {
if (Walker)
return Walker.get();
@@ -456,9 +1562,10 @@ MemoryPhi *MemorySSA::createMemoryPhi(BasicBlock *BB) {
assert(!getMemoryAccess(BB) && "MemoryPhi already exists for this BB");
AccessList *Accesses = getOrCreateAccessList(BB);
MemoryPhi *Phi = new MemoryPhi(BB->getContext(), BB, NextID++);
- ValueToMemoryAccess.insert(std::make_pair(BB, Phi));
+ ValueToMemoryAccess[BB] = Phi;
// Phi's always are placed at the front of the block.
Accesses->push_front(Phi);
+ BlockNumberingValid.erase(BB);
return Phi;
}
@@ -481,39 +1588,64 @@ MemoryAccess *MemorySSA::createMemoryAccessInBB(Instruction *I,
auto *Accesses = getOrCreateAccessList(BB);
if (Point == Beginning) {
// It goes after any phi nodes
- auto AI = std::find_if(
- Accesses->begin(), Accesses->end(),
- [](const MemoryAccess &MA) { return !isa<MemoryPhi>(MA); });
+ auto AI = find_if(
+ *Accesses, [](const MemoryAccess &MA) { return !isa<MemoryPhi>(MA); });
Accesses->insert(AI, NewAccess);
} else {
Accesses->push_back(NewAccess);
}
-
+ BlockNumberingValid.erase(BB);
return NewAccess;
}
-MemoryAccess *MemorySSA::createMemoryAccessBefore(Instruction *I,
- MemoryAccess *Definition,
- MemoryAccess *InsertPt) {
+
+MemoryUseOrDef *MemorySSA::createMemoryAccessBefore(Instruction *I,
+ MemoryAccess *Definition,
+ MemoryUseOrDef *InsertPt) {
assert(I->getParent() == InsertPt->getBlock() &&
"New and old access must be in the same block");
MemoryUseOrDef *NewAccess = createDefinedAccess(I, Definition);
auto *Accesses = getOrCreateAccessList(InsertPt->getBlock());
Accesses->insert(AccessList::iterator(InsertPt), NewAccess);
+ BlockNumberingValid.erase(InsertPt->getBlock());
return NewAccess;
}
-MemoryAccess *MemorySSA::createMemoryAccessAfter(Instruction *I,
- MemoryAccess *Definition,
- MemoryAccess *InsertPt) {
+MemoryUseOrDef *MemorySSA::createMemoryAccessAfter(Instruction *I,
+ MemoryAccess *Definition,
+ MemoryAccess *InsertPt) {
assert(I->getParent() == InsertPt->getBlock() &&
"New and old access must be in the same block");
MemoryUseOrDef *NewAccess = createDefinedAccess(I, Definition);
auto *Accesses = getOrCreateAccessList(InsertPt->getBlock());
Accesses->insertAfter(AccessList::iterator(InsertPt), NewAccess);
+ BlockNumberingValid.erase(InsertPt->getBlock());
return NewAccess;
}
+void MemorySSA::spliceMemoryAccessAbove(MemoryDef *Where,
+ MemoryUseOrDef *What) {
+ assert(What != getLiveOnEntryDef() &&
+ Where != getLiveOnEntryDef() && "Can't splice (above) LOE.");
+ assert(dominates(Where, What) && "Only upwards splices are permitted.");
+
+ if (Where == What)
+ return;
+ if (isa<MemoryDef>(What)) {
+ // TODO: possibly use removeMemoryAccess' more efficient RAUW
+ What->replaceAllUsesWith(What->getDefiningAccess());
+ What->setDefiningAccess(Where->getDefiningAccess());
+ Where->setDefiningAccess(What);
+ }
+ AccessList *Src = getWritableBlockAccesses(What->getBlock());
+ AccessList *Dest = getWritableBlockAccesses(Where->getBlock());
+ Dest->splice(AccessList::iterator(Where), *Src, What);
+
+ BlockNumberingValid.erase(What->getBlock());
+ if (What->getBlock() != Where->getBlock())
+ BlockNumberingValid.erase(Where->getBlock());
+}
+
/// \brief Helper function to create new memory accesses
MemoryUseOrDef *MemorySSA::createNewAccess(Instruction *I) {
// The assume intrinsic has a control dependency which we model by claiming
@@ -542,7 +1674,7 @@ MemoryUseOrDef *MemorySSA::createNewAccess(Instruction *I) {
MUD = new MemoryDef(I->getContext(), nullptr, I, I->getParent(), NextID++);
else
MUD = new MemoryUse(I->getContext(), nullptr, I, I->getParent());
- ValueToMemoryAccess.insert(std::make_pair(I, MUD));
+ ValueToMemoryAccess[I] = MUD;
return MUD;
}
@@ -611,6 +1743,7 @@ static MemoryAccess *onlySingleValue(MemoryPhi *MP) {
void MemorySSA::removeFromLookups(MemoryAccess *MA) {
assert(MA->use_empty() &&
"Trying to remove memory access that still has uses");
+ BlockNumbering.erase(MA);
if (MemoryUseOrDef *MUD = dyn_cast<MemoryUseOrDef>(MA))
MUD->setDefiningAccess(nullptr);
// Invalidate our walker's cache if necessary
@@ -624,7 +1757,9 @@ void MemorySSA::removeFromLookups(MemoryAccess *MA) {
} else {
MemoryInst = MA->getBlock();
}
- ValueToMemoryAccess.erase(MemoryInst);
+ auto VMA = ValueToMemoryAccess.find(MemoryInst);
+ if (VMA->second == MA)
+ ValueToMemoryAccess.erase(VMA);
auto AccessIt = PerBlockAccesses.find(MA->getBlock());
std::unique_ptr<AccessList> &Accesses = AccessIt->second;
@@ -652,8 +1787,27 @@ void MemorySSA::removeMemoryAccess(MemoryAccess *MA) {
}
// Re-point the uses at our defining access
- if (!MA->use_empty())
- MA->replaceAllUsesWith(NewDefTarget);
+ if (!MA->use_empty()) {
+ // Reset optimized on users of this store, and reset the uses.
+ // A few notes:
+ // 1. This is a slightly modified version of RAUW to avoid walking the
+ // uses twice here.
+ // 2. If we wanted to be complete, we would have to reset the optimized
+ // flags on users of phi nodes if doing the below makes a phi node have all
+ // the same arguments. Instead, we prefer users to removeMemoryAccess those
+ // phi nodes, because doing it here would be N^3.
+ if (MA->hasValueHandle())
+ ValueHandleBase::ValueIsRAUWd(MA, NewDefTarget);
+ // Note: We assume MemorySSA is not used in metadata since it's not really
+ // part of the IR.
+
+ while (!MA->use_empty()) {
+ Use &U = *MA->use_begin();
+ if (MemoryUse *MU = dyn_cast<MemoryUse>(U.getUser()))
+ MU->resetOptimized();
+ U.set(NewDefTarget);
+ }
+ }
// The call below to erase will destroy MA, so we can't change the order we
// are doing things here
@@ -674,6 +1828,7 @@ void MemorySSA::verifyMemorySSA() const {
verifyDefUses(F);
verifyDomination(F);
verifyOrdering(F);
+ Walker->verify(this);
}
/// \brief Verify that the order and existence of MemoryAccesses matches the
@@ -717,70 +1872,38 @@ void MemorySSA::verifyOrdering(Function &F) const {
/// \brief Verify the domination properties of MemorySSA by checking that each
/// definition dominates all of its uses.
void MemorySSA::verifyDomination(Function &F) const {
+#ifndef NDEBUG
for (BasicBlock &B : F) {
// Phi nodes are attached to basic blocks
- if (MemoryPhi *MP = getMemoryAccess(&B)) {
- for (User *U : MP->users()) {
- BasicBlock *UseBlock;
- // Phi operands are used on edges, we simulate the right domination by
- // acting as if the use occurred at the end of the predecessor block.
- if (MemoryPhi *P = dyn_cast<MemoryPhi>(U)) {
- for (const auto &Arg : P->operands()) {
- if (Arg == MP) {
- UseBlock = P->getIncomingBlock(Arg);
- break;
- }
- }
- } else {
- UseBlock = cast<MemoryAccess>(U)->getBlock();
- }
- (void)UseBlock;
- assert(DT->dominates(MP->getBlock(), UseBlock) &&
- "Memory PHI does not dominate it's uses");
- }
- }
+ if (MemoryPhi *MP = getMemoryAccess(&B))
+ for (const Use &U : MP->uses())
+ assert(dominates(MP, U) && "Memory PHI does not dominate it's uses");
for (Instruction &I : B) {
MemoryAccess *MD = dyn_cast_or_null<MemoryDef>(getMemoryAccess(&I));
if (!MD)
continue;
- for (User *U : MD->users()) {
- BasicBlock *UseBlock;
- (void)UseBlock;
- // Things are allowed to flow to phi nodes over their predecessor edge.
- if (auto *P = dyn_cast<MemoryPhi>(U)) {
- for (const auto &Arg : P->operands()) {
- if (Arg == MD) {
- UseBlock = P->getIncomingBlock(Arg);
- break;
- }
- }
- } else {
- UseBlock = cast<MemoryAccess>(U)->getBlock();
- }
- assert(DT->dominates(MD->getBlock(), UseBlock) &&
- "Memory Def does not dominate it's uses");
- }
+ for (const Use &U : MD->uses())
+ assert(dominates(MD, U) && "Memory Def does not dominate it's uses");
}
}
+#endif
}
/// \brief Verify the def-use lists in MemorySSA, by verifying that \p Use
/// appears in the use list of \p Def.
-///
-/// llvm_unreachable is used instead of asserts because this may be called in
-/// a build without asserts. In that case, we don't want this to turn into a
-/// nop.
+
void MemorySSA::verifyUseInDefs(MemoryAccess *Def, MemoryAccess *Use) const {
+#ifndef NDEBUG
// The live on entry use may cause us to get a NULL def here
- if (!Def) {
- if (!isLiveOnEntryDef(Use))
- llvm_unreachable("Null def but use not point to live on entry def");
- } else if (std::find(Def->user_begin(), Def->user_end(), Use) ==
- Def->user_end()) {
- llvm_unreachable("Did not find use in def's use list");
- }
+ if (!Def)
+ assert(isLiveOnEntryDef(Use) &&
+ "Null def but use not point to live on entry def");
+ else
+ assert(is_contained(Def->users(), Use) &&
+ "Did not find use in def's use list");
+#endif
}
/// \brief Verify the immediate use information, by walking all the memory
@@ -798,21 +1921,35 @@ void MemorySSA::verifyDefUses(Function &F) const {
}
for (Instruction &I : B) {
- if (MemoryAccess *MA = getMemoryAccess(&I)) {
- assert(isa<MemoryUseOrDef>(MA) &&
- "Found a phi node not attached to a bb");
- verifyUseInDefs(cast<MemoryUseOrDef>(MA)->getDefiningAccess(), MA);
+ if (MemoryUseOrDef *MA = getMemoryAccess(&I)) {
+ verifyUseInDefs(MA->getDefiningAccess(), MA);
}
}
}
}
-MemoryAccess *MemorySSA::getMemoryAccess(const Value *I) const {
- return ValueToMemoryAccess.lookup(I);
+MemoryUseOrDef *MemorySSA::getMemoryAccess(const Instruction *I) const {
+ return cast_or_null<MemoryUseOrDef>(ValueToMemoryAccess.lookup(I));
}
MemoryPhi *MemorySSA::getMemoryAccess(const BasicBlock *BB) const {
- return cast_or_null<MemoryPhi>(getMemoryAccess((const Value *)BB));
+ return cast_or_null<MemoryPhi>(ValueToMemoryAccess.lookup(cast<Value>(BB)));
+}
+
+/// Perform a local numbering on blocks so that instruction ordering can be
+/// determined in constant time.
+/// TODO: We currently just number in order. If we numbered by N, we could
+/// allow at least N-1 sequences of insertBefore or insertAfter (and at least
+/// log2(N) sequences of mixed before and after) without needing to invalidate
+/// the numbering.
+void MemorySSA::renumberBlock(const BasicBlock *B) const {
+ // The pre-increment ensures the numbers really start at 1.
+ unsigned long CurrentNumber = 0;
+ const AccessList *AL = getBlockAccesses(B);
+ assert(AL != nullptr && "Asking to renumber an empty block");
+ for (const auto &I : *AL)
+ BlockNumbering[&I] = ++CurrentNumber;
+ BlockNumberingValid.insert(B);
}
/// \brief Determine, for two memory accesses in the same block,
@@ -821,9 +1958,10 @@ MemoryPhi *MemorySSA::getMemoryAccess(const BasicBlock *BB) const {
bool MemorySSA::locallyDominates(const MemoryAccess *Dominator,
const MemoryAccess *Dominatee) const {
- assert((Dominator->getBlock() == Dominatee->getBlock()) &&
- "Asking for local domination when accesses are in different blocks!");
+ const BasicBlock *DominatorBlock = Dominator->getBlock();
+ assert((DominatorBlock == Dominatee->getBlock()) &&
+ "Asking for local domination when accesses are in different blocks!");
// A node dominates itself.
if (Dominatee == Dominator)
return true;
@@ -838,14 +1976,42 @@ bool MemorySSA::locallyDominates(const MemoryAccess *Dominator,
if (isLiveOnEntryDef(Dominator))
return true;
- // Get the access list for the block
- const AccessList *AccessList = getBlockAccesses(Dominator->getBlock());
- AccessList::const_reverse_iterator It(Dominator->getIterator());
+ if (!BlockNumberingValid.count(DominatorBlock))
+ renumberBlock(DominatorBlock);
+
+ unsigned long DominatorNum = BlockNumbering.lookup(Dominator);
+ // All numbers start with 1
+ assert(DominatorNum != 0 && "Block was not numbered properly");
+ unsigned long DominateeNum = BlockNumbering.lookup(Dominatee);
+ assert(DominateeNum != 0 && "Block was not numbered properly");
+ return DominatorNum < DominateeNum;
+}
+
+bool MemorySSA::dominates(const MemoryAccess *Dominator,
+ const MemoryAccess *Dominatee) const {
+ if (Dominator == Dominatee)
+ return true;
+
+ if (isLiveOnEntryDef(Dominatee))
+ return false;
+
+ if (Dominator->getBlock() != Dominatee->getBlock())
+ return DT->dominates(Dominator->getBlock(), Dominatee->getBlock());
+ return locallyDominates(Dominator, Dominatee);
+}
- // If we hit the beginning of the access list before we hit dominatee, we must
- // dominate it
- return std::none_of(It, AccessList->rend(),
- [&](const MemoryAccess &MA) { return &MA == Dominatee; });
+bool MemorySSA::dominates(const MemoryAccess *Dominator,
+ const Use &Dominatee) const {
+ if (MemoryPhi *MP = dyn_cast<MemoryPhi>(Dominatee.getUser())) {
+ BasicBlock *UseBB = MP->getIncomingBlock(Dominatee);
+ // The def must dominate the incoming block of the phi.
+ if (UseBB != Dominator->getBlock())
+ return DT->dominates(Dominator->getBlock(), UseBB);
+ // If the UseBB and the DefBB are the same, compare locally.
+ return locallyDominates(Dominator, cast<MemoryAccess>(Dominatee));
+ }
+ // If it's not a PHI node use, the normal dominates can already handle it.
+ return dominates(Dominator, cast<MemoryAccess>(Dominatee.getUser()));
}
const static char LiveOnEntryStr[] = "liveOnEntry";
@@ -924,25 +2090,26 @@ bool MemorySSAPrinterLegacyPass::runOnFunction(Function &F) {
return false;
}
-char MemorySSAAnalysis::PassID;
+AnalysisKey MemorySSAAnalysis::Key;
-MemorySSA MemorySSAAnalysis::run(Function &F, AnalysisManager<Function> &AM) {
+MemorySSAAnalysis::Result MemorySSAAnalysis::run(Function &F,
+ FunctionAnalysisManager &AM) {
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
auto &AA = AM.getResult<AAManager>(F);
- return MemorySSA(F, &AA, &DT);
+ return MemorySSAAnalysis::Result(make_unique<MemorySSA>(F, &AA, &DT));
}
PreservedAnalyses MemorySSAPrinterPass::run(Function &F,
FunctionAnalysisManager &AM) {
OS << "MemorySSA for function: " << F.getName() << "\n";
- AM.getResult<MemorySSAAnalysis>(F).print(OS);
+ AM.getResult<MemorySSAAnalysis>(F).getMSSA().print(OS);
return PreservedAnalyses::all();
}
PreservedAnalyses MemorySSAVerifierPass::run(Function &F,
FunctionAnalysisManager &AM) {
- AM.getResult<MemorySSAAnalysis>(F).verifyMemorySSA();
+ AM.getResult<MemorySSAAnalysis>(F).getMSSA().verifyMemorySSA();
return PreservedAnalyses::all();
}
@@ -978,41 +2145,11 @@ MemorySSAWalker::MemorySSAWalker(MemorySSA *M) : MSSA(M) {}
MemorySSA::CachingWalker::CachingWalker(MemorySSA *M, AliasAnalysis *A,
DominatorTree *D)
- : MemorySSAWalker(M), AA(A), DT(D) {}
+ : MemorySSAWalker(M), Walker(*M, *A, *D, Cache), AutoResetWalker(true) {}
MemorySSA::CachingWalker::~CachingWalker() {}
-struct MemorySSA::CachingWalker::UpwardsMemoryQuery {
- // True if we saw a phi whose predecessor was a backedge
- bool SawBackedgePhi;
- // True if our original query started off as a call
- bool IsCall;
- // The pointer location we started the query with. This will be empty if
- // IsCall is true.
- MemoryLocation StartingLoc;
- // This is the instruction we were querying about.
- const Instruction *Inst;
- // Set of visited Instructions for this query.
- DenseSet<MemoryAccessPair> Visited;
- // Vector of visited call accesses for this query. This is separated out
- // because you can always cache and lookup the result of call queries (IE when
- // IsCall == true) for every call in the chain. The calls have no AA location
- // associated with them with them, and thus, no context dependence.
- SmallVector<const MemoryAccess *, 32> VisitedCalls;
- // The MemoryAccess we actually got called with, used to test local domination
- const MemoryAccess *OriginalAccess;
-
- UpwardsMemoryQuery()
- : SawBackedgePhi(false), IsCall(false), Inst(nullptr),
- OriginalAccess(nullptr) {}
-
- UpwardsMemoryQuery(const Instruction *Inst, const MemoryAccess *Access)
- : SawBackedgePhi(false), IsCall(ImmutableCallSite(Inst)), Inst(Inst),
- OriginalAccess(Access) {}
-};
-
void MemorySSA::CachingWalker::invalidateInfo(MemoryAccess *MA) {
-
// TODO: We can do much better cache invalidation with differently stored
// caches. For now, for MemoryUses, we simply remove them
// from the cache, and kill the entire call/non-call cache for everything
@@ -1026,220 +2163,38 @@ void MemorySSA::CachingWalker::invalidateInfo(MemoryAccess *MA) {
// itself.
if (MemoryUse *MU = dyn_cast<MemoryUse>(MA)) {
- UpwardsMemoryQuery Q;
- Instruction *I = MU->getMemoryInst();
- Q.IsCall = bool(ImmutableCallSite(I));
- Q.Inst = I;
- if (!Q.IsCall)
- Q.StartingLoc = MemoryLocation::get(I);
- doCacheRemove(MA, Q, Q.StartingLoc);
+ UpwardsMemoryQuery Q(MU->getMemoryInst(), MU);
+ Cache.remove(MU, Q.StartingLoc, Q.IsCall);
+ MU->resetOptimized();
} else {
// If it is not a use, the best we can do right now is destroy the cache.
- CachedUpwardsClobberingCall.clear();
- CachedUpwardsClobberingAccess.clear();
+ Cache.clear();
}
#ifdef EXPENSIVE_CHECKS
- // Run this only when expensive checks are enabled.
verifyRemoved(MA);
#endif
}
-void MemorySSA::CachingWalker::doCacheRemove(const MemoryAccess *M,
- const UpwardsMemoryQuery &Q,
- const MemoryLocation &Loc) {
- if (Q.IsCall)
- CachedUpwardsClobberingCall.erase(M);
- else
- CachedUpwardsClobberingAccess.erase({M, Loc});
-}
-
-void MemorySSA::CachingWalker::doCacheInsert(const MemoryAccess *M,
- MemoryAccess *Result,
- const UpwardsMemoryQuery &Q,
- const MemoryLocation &Loc) {
- // This is fine for Phis, since there are times where we can't optimize them.
- // Making a def its own clobber is never correct, though.
- assert((Result != M || isa<MemoryPhi>(M)) &&
- "Something can't clobber itself!");
- ++NumClobberCacheInserts;
- if (Q.IsCall)
- CachedUpwardsClobberingCall[M] = Result;
- else
- CachedUpwardsClobberingAccess[{M, Loc}] = Result;
-}
-
-MemoryAccess *
-MemorySSA::CachingWalker::doCacheLookup(const MemoryAccess *M,
- const UpwardsMemoryQuery &Q,
- const MemoryLocation &Loc) {
- ++NumClobberCacheLookups;
- MemoryAccess *Result;
-
- if (Q.IsCall)
- Result = CachedUpwardsClobberingCall.lookup(M);
- else
- Result = CachedUpwardsClobberingAccess.lookup({M, Loc});
-
- if (Result)
- ++NumClobberCacheHits;
- return Result;
-}
-
-bool MemorySSA::CachingWalker::instructionClobbersQuery(
- const MemoryDef *MD, UpwardsMemoryQuery &Q,
- const MemoryLocation &Loc) const {
- Instruction *DefMemoryInst = MD->getMemoryInst();
- assert(DefMemoryInst && "Defining instruction not actually an instruction");
-
- if (!Q.IsCall)
- return AA->getModRefInfo(DefMemoryInst, Loc) & MRI_Mod;
-
- // If this is a call, mark it for caching
- if (ImmutableCallSite(DefMemoryInst))
- Q.VisitedCalls.push_back(MD);
- ModRefInfo I = AA->getModRefInfo(DefMemoryInst, ImmutableCallSite(Q.Inst));
- return I != MRI_NoModRef;
-}
-
-MemoryAccessPair MemorySSA::CachingWalker::UpwardsDFSWalk(
- MemoryAccess *StartingAccess, const MemoryLocation &Loc,
- UpwardsMemoryQuery &Q, bool FollowingBackedge) {
- MemoryAccess *ModifyingAccess = nullptr;
-
- auto DFI = df_begin(StartingAccess);
- for (auto DFE = df_end(StartingAccess); DFI != DFE;) {
- MemoryAccess *CurrAccess = *DFI;
- if (MSSA->isLiveOnEntryDef(CurrAccess))
- return {CurrAccess, Loc};
- // If this is a MemoryDef, check whether it clobbers our current query. This
- // needs to be done before consulting the cache, because the cache reports
- // the clobber for CurrAccess. If CurrAccess is a clobber for this query,
- // and we ask the cache for information first, then we might skip this
- // clobber, which is bad.
- if (auto *MD = dyn_cast<MemoryDef>(CurrAccess)) {
- // If we hit the top, stop following this path.
- // While we can do lookups, we can't sanely do inserts here unless we were
- // to track everything we saw along the way, since we don't know where we
- // will stop.
- if (instructionClobbersQuery(MD, Q, Loc)) {
- ModifyingAccess = CurrAccess;
- break;
- }
- }
- if (auto CacheResult = doCacheLookup(CurrAccess, Q, Loc))
- return {CacheResult, Loc};
-
- // We need to know whether it is a phi so we can track backedges.
- // Otherwise, walk all upward defs.
- if (!isa<MemoryPhi>(CurrAccess)) {
- ++DFI;
- continue;
- }
-
-#ifndef NDEBUG
- // The loop below visits the phi's children for us. Because phis are the
- // only things with multiple edges, skipping the children should always lead
- // us to the end of the loop.
- //
- // Use a copy of DFI because skipChildren would kill our search stack, which
- // would make caching anything on the way back impossible.
- auto DFICopy = DFI;
- assert(DFICopy.skipChildren() == DFE &&
- "Skipping phi's children doesn't end the DFS?");
-#endif
-
- const MemoryAccessPair PHIPair(CurrAccess, Loc);
-
- // Don't try to optimize this phi again if we've already tried to do so.
- if (!Q.Visited.insert(PHIPair).second) {
- ModifyingAccess = CurrAccess;
- break;
- }
-
- std::size_t InitialVisitedCallSize = Q.VisitedCalls.size();
-
- // Recurse on PHI nodes, since we need to change locations.
- // TODO: Allow graphtraits on pairs, which would turn this whole function
- // into a normal single depth first walk.
- MemoryAccess *FirstDef = nullptr;
- for (auto MPI = upward_defs_begin(PHIPair), MPE = upward_defs_end();
- MPI != MPE; ++MPI) {
- bool Backedge =
- !FollowingBackedge &&
- DT->dominates(CurrAccess->getBlock(), MPI.getPhiArgBlock());
-
- MemoryAccessPair CurrentPair =
- UpwardsDFSWalk(MPI->first, MPI->second, Q, Backedge);
- // All the phi arguments should reach the same point if we can bypass
- // this phi. The alternative is that they hit this phi node, which
- // means we can skip this argument.
- if (FirstDef && CurrentPair.first != PHIPair.first &&
- CurrentPair.first != FirstDef) {
- ModifyingAccess = CurrAccess;
- break;
- }
-
- if (!FirstDef)
- FirstDef = CurrentPair.first;
- }
-
- // If we exited the loop early, go with the result it gave us.
- if (!ModifyingAccess) {
- assert(FirstDef && "Found a Phi with no upward defs?");
- ModifyingAccess = FirstDef;
- } else {
- // If we can't optimize this Phi, then we can't safely cache any of the
- // calls we visited when trying to optimize it. Wipe them out now.
- Q.VisitedCalls.resize(InitialVisitedCallSize);
- }
- break;
- }
-
- if (!ModifyingAccess)
- return {MSSA->getLiveOnEntryDef(), Q.StartingLoc};
-
- const BasicBlock *OriginalBlock = StartingAccess->getBlock();
- assert(DFI.getPathLength() > 0 && "We dropped our path?");
- unsigned N = DFI.getPathLength();
- // If we found a clobbering def, the last element in the path will be our
- // clobber, so we don't want to cache that to itself. OTOH, if we optimized a
- // phi, we can add the last thing in the path to the cache, since that won't
- // be the result.
- if (DFI.getPath(N - 1) == ModifyingAccess)
- --N;
- for (; N > 1; --N) {
- MemoryAccess *CacheAccess = DFI.getPath(N - 1);
- BasicBlock *CurrBlock = CacheAccess->getBlock();
- if (!FollowingBackedge)
- doCacheInsert(CacheAccess, ModifyingAccess, Q, Loc);
- if (DT->dominates(CurrBlock, OriginalBlock) &&
- (CurrBlock != OriginalBlock || !FollowingBackedge ||
- MSSA->locallyDominates(CacheAccess, StartingAccess)))
- break;
- }
-
- // Cache everything else on the way back. The caller should cache
- // StartingAccess for us.
- for (; N > 1; --N) {
- MemoryAccess *CacheAccess = DFI.getPath(N - 1);
- doCacheInsert(CacheAccess, ModifyingAccess, Q, Loc);
- }
-
- return {ModifyingAccess, Loc};
-}
-
/// \brief Walk the use-def chains starting at \p MA and find
/// the MemoryAccess that actually clobbers Loc.
///
/// \returns our clobbering memory access
MemoryAccess *MemorySSA::CachingWalker::getClobberingMemoryAccess(
MemoryAccess *StartingAccess, UpwardsMemoryQuery &Q) {
- return UpwardsDFSWalk(StartingAccess, Q.StartingLoc, Q, false).first;
+ MemoryAccess *New = Walker.findClobber(StartingAccess, Q);
+#ifdef EXPENSIVE_CHECKS
+ MemoryAccess *NewNoCache =
+ Walker.findClobber(StartingAccess, Q, /*UseWalkerCache=*/false);
+ assert(NewNoCache == New && "Cache made us hand back a different result?");
+#endif
+ if (AutoResetWalker)
+ resetClobberWalker();
+ return New;
}
MemoryAccess *MemorySSA::CachingWalker::getClobberingMemoryAccess(
- MemoryAccess *StartingAccess, MemoryLocation &Loc) {
+ MemoryAccess *StartingAccess, const MemoryLocation &Loc) {
if (isa<MemoryPhi>(StartingAccess))
return StartingAccess;
@@ -1257,10 +2212,10 @@ MemoryAccess *MemorySSA::CachingWalker::getClobberingMemoryAccess(
UpwardsMemoryQuery Q;
Q.OriginalAccess = StartingUseOrDef;
Q.StartingLoc = Loc;
- Q.Inst = StartingUseOrDef->getMemoryInst();
+ Q.Inst = I;
Q.IsCall = false;
- if (auto CacheResult = doCacheLookup(StartingUseOrDef, Q, Q.StartingLoc))
+ if (auto *CacheResult = Cache.lookup(StartingUseOrDef, Loc, Q.IsCall))
return CacheResult;
// Unlike the other function, do not walk to the def of a def, because we are
@@ -1270,9 +2225,6 @@ MemoryAccess *MemorySSA::CachingWalker::getClobberingMemoryAccess(
: StartingUseOrDef;
MemoryAccess *Clobber = getClobberingMemoryAccess(DefiningAccess, Q);
- // Only cache this if it wouldn't make Clobber point to itself.
- if (Clobber != StartingAccess)
- doCacheInsert(Q.OriginalAccess, Clobber, Q, Q.StartingLoc);
DEBUG(dbgs() << "Starting Memory SSA clobber for " << *I << " is ");
DEBUG(dbgs() << *StartingUseOrDef << "\n");
DEBUG(dbgs() << "Final Memory SSA clobber for " << *I << " is ");
@@ -1281,28 +2233,38 @@ MemoryAccess *MemorySSA::CachingWalker::getClobberingMemoryAccess(
}
MemoryAccess *
-MemorySSA::CachingWalker::getClobberingMemoryAccess(const Instruction *I) {
- // There should be no way to lookup an instruction and get a phi as the
- // access, since we only map BB's to PHI's. So, this must be a use or def.
- auto *StartingAccess = cast<MemoryUseOrDef>(MSSA->getMemoryAccess(I));
-
- bool IsCall = bool(ImmutableCallSite(I));
-
+MemorySSA::CachingWalker::getClobberingMemoryAccess(MemoryAccess *MA) {
+ auto *StartingAccess = dyn_cast<MemoryUseOrDef>(MA);
+ // If this is a MemoryPhi, we can't do anything.
+ if (!StartingAccess)
+ return MA;
+
+ // If this is an already optimized use or def, return the optimized result.
+ // Note: Currently, we do not store the optimized def result because we'd need
+ // a separate field, since we can't use it as the defining access.
+ if (MemoryUse *MU = dyn_cast<MemoryUse>(StartingAccess))
+ if (MU->isOptimized())
+ return MU->getDefiningAccess();
+
+ const Instruction *I = StartingAccess->getMemoryInst();
+ UpwardsMemoryQuery Q(I, StartingAccess);
// We can't sanely do anything with a fences, they conservatively
// clobber all memory, and have no locations to get pointers from to
// try to disambiguate.
- if (!IsCall && I->isFenceLike())
+ if (!Q.IsCall && I->isFenceLike())
return StartingAccess;
- UpwardsMemoryQuery Q;
- Q.OriginalAccess = StartingAccess;
- Q.IsCall = IsCall;
- if (!Q.IsCall)
- Q.StartingLoc = MemoryLocation::get(I);
- Q.Inst = I;
- if (auto CacheResult = doCacheLookup(StartingAccess, Q, Q.StartingLoc))
+ if (auto *CacheResult = Cache.lookup(StartingAccess, Q.StartingLoc, Q.IsCall))
return CacheResult;
+ if (isUseTriviallyOptimizableToLiveOnEntry(*MSSA->AA, I)) {
+ MemoryAccess *LiveOnEntry = MSSA->getLiveOnEntryDef();
+ Cache.insert(StartingAccess, LiveOnEntry, Q.StartingLoc, Q.IsCall);
+ if (MemoryUse *MU = dyn_cast<MemoryUse>(StartingAccess))
+ MU->setDefiningAccess(LiveOnEntry, true);
+ return LiveOnEntry;
+ }
+
// Start with the thing we already think clobbers this location
MemoryAccess *DefiningAccess = StartingAccess->getDefiningAccess();
@@ -1312,50 +2274,32 @@ MemorySSA::CachingWalker::getClobberingMemoryAccess(const Instruction *I) {
return DefiningAccess;
MemoryAccess *Result = getClobberingMemoryAccess(DefiningAccess, Q);
- // DFS won't cache a result for DefiningAccess. So, if DefiningAccess isn't
- // our clobber, be sure that it gets a cache entry, too.
- if (Result != DefiningAccess)
- doCacheInsert(DefiningAccess, Result, Q, Q.StartingLoc);
- doCacheInsert(Q.OriginalAccess, Result, Q, Q.StartingLoc);
- // TODO: When this implementation is more mature, we may want to figure out
- // what this additional caching buys us. It's most likely A Good Thing.
- if (Q.IsCall)
- for (const MemoryAccess *MA : Q.VisitedCalls)
- if (MA != Result)
- doCacheInsert(MA, Result, Q, Q.StartingLoc);
-
DEBUG(dbgs() << "Starting Memory SSA clobber for " << *I << " is ");
DEBUG(dbgs() << *DefiningAccess << "\n");
DEBUG(dbgs() << "Final Memory SSA clobber for " << *I << " is ");
DEBUG(dbgs() << *Result << "\n");
+ if (MemoryUse *MU = dyn_cast<MemoryUse>(StartingAccess))
+ MU->setDefiningAccess(Result, true);
return Result;
}
// Verify that MA doesn't exist in any of the caches.
void MemorySSA::CachingWalker::verifyRemoved(MemoryAccess *MA) {
-#ifndef NDEBUG
- for (auto &P : CachedUpwardsClobberingAccess)
- assert(P.first.first != MA && P.second != MA &&
- "Found removed MemoryAccess in cache.");
- for (auto &P : CachedUpwardsClobberingCall)
- assert(P.first != MA && P.second != MA &&
- "Found removed MemoryAccess in cache.");
-#endif // !NDEBUG
+ assert(!Cache.contains(MA) && "Found removed MemoryAccess in cache.");
}
MemoryAccess *
-DoNothingMemorySSAWalker::getClobberingMemoryAccess(const Instruction *I) {
- MemoryAccess *MA = MSSA->getMemoryAccess(I);
+DoNothingMemorySSAWalker::getClobberingMemoryAccess(MemoryAccess *MA) {
if (auto *Use = dyn_cast<MemoryUseOrDef>(MA))
return Use->getDefiningAccess();
return MA;
}
MemoryAccess *DoNothingMemorySSAWalker::getClobberingMemoryAccess(
- MemoryAccess *StartingAccess, MemoryLocation &) {
+ MemoryAccess *StartingAccess, const MemoryLocation &) {
if (auto *Use = dyn_cast<MemoryUseOrDef>(StartingAccess))
return Use->getDefiningAccess();
return StartingAccess;
}
-}
+} // namespace llvm
diff --git a/contrib/llvm/lib/Transforms/Utils/ModuleUtils.cpp b/contrib/llvm/lib/Transforms/Utils/ModuleUtils.cpp
index eb91885..0d623df 100644
--- a/contrib/llvm/lib/Transforms/Utils/ModuleUtils.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/ModuleUtils.cpp
@@ -89,6 +89,44 @@ void llvm::appendToGlobalDtors(Module &M, Function *F, int Priority, Constant *D
appendToGlobalArray("llvm.global_dtors", M, F, Priority, Data);
}
+static void appendToUsedList(Module &M, StringRef Name, ArrayRef<GlobalValue *> Values) {
+ GlobalVariable *GV = M.getGlobalVariable(Name);
+ SmallPtrSet<Constant *, 16> InitAsSet;
+ SmallVector<Constant *, 16> Init;
+ if (GV) {
+ ConstantArray *CA = dyn_cast<ConstantArray>(GV->getInitializer());
+ for (auto &Op : CA->operands()) {
+ Constant *C = cast_or_null<Constant>(Op);
+ if (InitAsSet.insert(C).second)
+ Init.push_back(C);
+ }
+ GV->eraseFromParent();
+ }
+
+ Type *Int8PtrTy = llvm::Type::getInt8PtrTy(M.getContext());
+ for (auto *V : Values) {
+ Constant *C = ConstantExpr::getBitCast(V, Int8PtrTy);
+ if (InitAsSet.insert(C).second)
+ Init.push_back(C);
+ }
+
+ if (Init.empty())
+ return;
+
+ ArrayType *ATy = ArrayType::get(Int8PtrTy, Init.size());
+ GV = new llvm::GlobalVariable(M, ATy, false, GlobalValue::AppendingLinkage,
+ ConstantArray::get(ATy, Init), Name);
+ GV->setSection("llvm.metadata");
+}
+
+void llvm::appendToUsed(Module &M, ArrayRef<GlobalValue *> Values) {
+ appendToUsedList(M, "llvm.used", Values);
+}
+
+void llvm::appendToCompilerUsed(Module &M, ArrayRef<GlobalValue *> Values) {
+ appendToUsedList(M, "llvm.compiler.used", Values);
+}
+
Function *llvm::checkSanitizerInterfaceFunction(Constant *FuncOrBitcast) {
if (isa<Function>(FuncOrBitcast))
return cast<Function>(FuncOrBitcast);
@@ -104,7 +142,7 @@ std::pair<Function *, Function *> llvm::createSanitizerCtorAndInitFunctions(
ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs,
StringRef VersionCheckName) {
assert(!InitName.empty() && "Expected init function name");
- assert(InitArgTypes.size() == InitArgTypes.size() &&
+ assert(InitArgs.size() == InitArgTypes.size() &&
"Sanitizer's init function expects different number of arguments");
Function *Ctor = Function::Create(
FunctionType::get(Type::getVoidTy(M.getContext()), false),
@@ -126,3 +164,67 @@ std::pair<Function *, Function *> llvm::createSanitizerCtorAndInitFunctions(
}
return std::make_pair(Ctor, InitFunction);
}
+
+void llvm::filterDeadComdatFunctions(
+ Module &M, SmallVectorImpl<Function *> &DeadComdatFunctions) {
+ // Build a map from the comdat to the number of entries in that comdat we
+ // think are dead. If this fully covers the comdat group, then the entire
+ // group is dead. If we find another entry in the comdat group though, we'll
+ // have to preserve the whole group.
+ SmallDenseMap<Comdat *, int, 16> ComdatEntriesCovered;
+ for (Function *F : DeadComdatFunctions) {
+ Comdat *C = F->getComdat();
+ assert(C && "Expected all input GVs to be in a comdat!");
+ ComdatEntriesCovered[C] += 1;
+ }
+
+ auto CheckComdat = [&](Comdat &C) {
+ auto CI = ComdatEntriesCovered.find(&C);
+ if (CI == ComdatEntriesCovered.end())
+ return;
+
+ // If this could have been covered by a dead entry, just subtract one to
+ // account for it.
+ if (CI->second > 0) {
+ CI->second -= 1;
+ return;
+ }
+
+ // If we've already accounted for all the entries that were dead, the
+ // entire comdat is alive so remove it from the map.
+ ComdatEntriesCovered.erase(CI);
+ };
+
+ auto CheckAllComdats = [&] {
+ for (Function &F : M.functions())
+ if (Comdat *C = F.getComdat()) {
+ CheckComdat(*C);
+ if (ComdatEntriesCovered.empty())
+ return;
+ }
+ for (GlobalVariable &GV : M.globals())
+ if (Comdat *C = GV.getComdat()) {
+ CheckComdat(*C);
+ if (ComdatEntriesCovered.empty())
+ return;
+ }
+ for (GlobalAlias &GA : M.aliases())
+ if (Comdat *C = GA.getComdat()) {
+ CheckComdat(*C);
+ if (ComdatEntriesCovered.empty())
+ return;
+ }
+ };
+ CheckAllComdats();
+
+ if (ComdatEntriesCovered.empty()) {
+ DeadComdatFunctions.clear();
+ return;
+ }
+
+ // Remove the entries that were not covering.
+ erase_if(DeadComdatFunctions, [&](GlobalValue *GV) {
+ return ComdatEntriesCovered.find(GV->getComdat()) ==
+ ComdatEntriesCovered.end();
+ });
+}
diff --git a/contrib/llvm/lib/Transforms/Utils/NameAnonFunctions.cpp b/contrib/llvm/lib/Transforms/Utils/NameAnonGlobals.cpp
index c4f3839..34dc1cc 100644
--- a/contrib/llvm/lib/Transforms/Utils/NameAnonFunctions.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/NameAnonGlobals.cpp
@@ -1,4 +1,4 @@
-//===- NameAnonFunctions.cpp - ThinLTO Summary-based Function Import ------===//
+//===- NameAnonGlobals.cpp - ThinLTO Support: Name Unnamed Globals --------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,11 +7,13 @@
//
//===----------------------------------------------------------------------===//
//
-// This file implements naming anonymous function to make sure they can be
-// refered to by ThinLTO.
+// This file implements naming anonymous globals to make sure they can be
+// referred to by ThinLTO.
//
//===----------------------------------------------------------------------===//
+#include "llvm/Transforms/Utils/NameAnonGlobals.h"
+
#include "llvm/ADT/SmallString.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/MD5.h"
@@ -19,8 +21,9 @@
using namespace llvm;
+namespace {
// Compute a "unique" hash for the module based on the name of the public
-// functions.
+// globals.
class ModuleHasher {
Module &TheModule;
std::string TheHash;
@@ -57,46 +60,62 @@ public:
return TheHash;
}
};
+} // end anonymous namespace
-// Rename all the anon functions in the module
-bool llvm::nameUnamedFunctions(Module &M) {
+// Rename all the anon globals in the module
+bool llvm::nameUnamedGlobals(Module &M) {
bool Changed = false;
ModuleHasher ModuleHash(M);
int count = 0;
- for (auto &F : M) {
- if (F.hasName())
- continue;
- F.setName(Twine("anon.") + ModuleHash.get() + "." + Twine(count++));
+ auto RenameIfNeed = [&](GlobalValue &GV) {
+ if (GV.hasName())
+ return;
+ GV.setName(Twine("anon.") + ModuleHash.get() + "." + Twine(count++));
Changed = true;
- }
+ };
+ for (auto &GO : M.global_objects())
+ RenameIfNeed(GO);
+ for (auto &GA : M.aliases())
+ RenameIfNeed(GA);
+
return Changed;
}
namespace {
-// Simple pass that provides a name to every anon function.
-class NameAnonFunction : public ModulePass {
+// Legacy pass that provides a name to every anon globals.
+class NameAnonGlobalLegacyPass : public ModulePass {
public:
/// Pass identification, replacement for typeid
static char ID;
/// Specify pass name for debug output
- const char *getPassName() const override { return "Name Anon Functions"; }
+ StringRef getPassName() const override { return "Name Anon Globals"; }
- explicit NameAnonFunction() : ModulePass(ID) {}
+ explicit NameAnonGlobalLegacyPass() : ModulePass(ID) {}
- bool runOnModule(Module &M) override { return nameUnamedFunctions(M); }
+ bool runOnModule(Module &M) override { return nameUnamedGlobals(M); }
};
-char NameAnonFunction::ID = 0;
+char NameAnonGlobalLegacyPass::ID = 0;
} // anonymous namespace
-INITIALIZE_PASS_BEGIN(NameAnonFunction, "name-anon-functions",
- "Provide a name to nameless functions", false, false)
-INITIALIZE_PASS_END(NameAnonFunction, "name-anon-functions",
- "Provide a name to nameless functions", false, false)
+PreservedAnalyses NameAnonGlobalPass::run(Module &M,
+ ModuleAnalysisManager &AM) {
+ if (!nameUnamedGlobals(M))
+ return PreservedAnalyses::all();
+
+ return PreservedAnalyses::none();
+}
+
+INITIALIZE_PASS_BEGIN(NameAnonGlobalLegacyPass, "name-anon-globals",
+ "Provide a name to nameless globals", false, false)
+INITIALIZE_PASS_END(NameAnonGlobalLegacyPass, "name-anon-globals",
+ "Provide a name to nameless globals", false, false)
namespace llvm {
-ModulePass *createNameAnonFunctionPass() { return new NameAnonFunction(); }
+ModulePass *createNameAnonGlobalPass() {
+ return new NameAnonGlobalLegacyPass();
+}
}
diff --git a/contrib/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/contrib/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
index cbf385d..35faa6f 100644
--- a/contrib/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
@@ -907,6 +907,8 @@ NextIteration:
// The currently active variable for this block is now the PHI.
IncomingVals[AllocaNo] = APN;
+ if (DbgDeclareInst *DDI = AllocaDbgDeclares[AllocaNo])
+ ConvertDebugDeclareToDebugValue(DDI, APN, DIB);
// Get the next phi node.
++PNI;
diff --git a/contrib/llvm/lib/Transforms/Utils/SSAUpdater.cpp b/contrib/llvm/lib/Transforms/Utils/SSAUpdater.cpp
index 88b39dd..8e93ee7 100644
--- a/contrib/llvm/lib/Transforms/Utils/SSAUpdater.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/SSAUpdater.cpp
@@ -482,5 +482,5 @@ bool
LoadAndStorePromoter::isInstInList(Instruction *I,
const SmallVectorImpl<Instruction*> &Insts)
const {
- return std::find(Insts.begin(), Insts.end(), I) != Insts.end();
+ return is_contained(Insts, I);
}
diff --git a/contrib/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/contrib/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index c197317..7b0bddb 100644
--- a/contrib/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -11,27 +11,39 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SetOperations.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/CallSite.h"
#include "llvm/IR/CFG.h"
+#include "llvm/IR/Constant.h"
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Metadata.h"
@@ -40,15 +52,29 @@
#include "llvm/IR/Operator.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Type.h"
+#include "llvm/IR/User.h"
+#include "llvm/IR/Value.h"
+#include "llvm/IR/DebugInfo.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
#include <algorithm>
+#include <cassert>
+#include <climits>
+#include <cstddef>
+#include <cstdint>
+#include <iterator>
#include <map>
#include <set>
+#include <utility>
+#include <vector>
+
using namespace llvm;
using namespace PatternMatch;
@@ -110,6 +136,7 @@ STATISTIC(NumSinkCommons,
STATISTIC(NumSpeculations, "Number of speculative executed instructions");
namespace {
+
// The first field contains the value that the switch produces when a certain
// case group is selected, and the second field is a vector containing the
// cases composing the case group.
@@ -168,13 +195,17 @@ public:
SmallPtrSetImpl<BasicBlock *> *LoopHeaders)
: TTI(TTI), DL(DL), BonusInstThreshold(BonusInstThreshold), AC(AC),
LoopHeaders(LoopHeaders) {}
+
bool run(BasicBlock *BB);
};
-}
+
+} // end anonymous namespace
/// Return true if it is safe to merge these two
/// terminator instructions together.
-static bool SafeToMergeTerminators(TerminatorInst *SI1, TerminatorInst *SI2) {
+static bool
+SafeToMergeTerminators(TerminatorInst *SI1, TerminatorInst *SI2,
+ SmallSetVector<BasicBlock *, 4> *FailBlocks = nullptr) {
if (SI1 == SI2)
return false; // Can't merge with self!
@@ -183,18 +214,22 @@ static bool SafeToMergeTerminators(TerminatorInst *SI1, TerminatorInst *SI2) {
// conflicting incoming values from the two switch blocks.
BasicBlock *SI1BB = SI1->getParent();
BasicBlock *SI2BB = SI2->getParent();
- SmallPtrSet<BasicBlock *, 16> SI1Succs(succ_begin(SI1BB), succ_end(SI1BB));
+ SmallPtrSet<BasicBlock *, 16> SI1Succs(succ_begin(SI1BB), succ_end(SI1BB));
+ bool Fail = false;
for (BasicBlock *Succ : successors(SI2BB))
if (SI1Succs.count(Succ))
for (BasicBlock::iterator BBI = Succ->begin(); isa<PHINode>(BBI); ++BBI) {
PHINode *PN = cast<PHINode>(BBI);
if (PN->getIncomingValueForBlock(SI1BB) !=
- PN->getIncomingValueForBlock(SI2BB))
- return false;
+ PN->getIncomingValueForBlock(SI2BB)) {
+ if (FailBlocks)
+ FailBlocks->insert(Succ);
+ Fail = true;
+ }
}
- return true;
+ return !Fail;
}
/// Return true if it is safe and profitable to merge these two terminator
@@ -621,7 +656,8 @@ private:
}
}
};
-}
+
+} // end anonymous namespace
static void EraseTerminatorInstAndDCECond(TerminatorInst *TI) {
Instruction *Cond = nullptr;
@@ -706,7 +742,7 @@ static bool ValuesOverlap(std::vector<ValueEqualityComparisonCase> &C1,
if (V1->size() > V2->size())
std::swap(V1, V2);
- if (V1->size() == 0)
+ if (V1->empty())
return false;
if (V1->size() == 1) {
// Just scan V2.
@@ -874,6 +910,7 @@ bool SimplifyCFGOpt::SimplifyEqualityComparisonWithOnlyPredecessor(
}
namespace {
+
/// This class implements a stable ordering of constant
/// integers that does not depend on their address. This is important for
/// applications that sort ConstantInt's to ensure uniqueness.
@@ -882,7 +919,8 @@ struct ConstantIntOrdering {
return LHS->getValue().ult(RHS->getValue());
}
};
-}
+
+} // end anonymous namespace
static int ConstantIntSortPredicate(ConstantInt *const *P1,
ConstantInt *const *P2) {
@@ -954,7 +992,16 @@ bool SimplifyCFGOpt::FoldValueComparisonIntoPredecessors(TerminatorInst *TI,
TerminatorInst *PTI = Pred->getTerminator();
Value *PCV = isValueEqualityComparison(PTI); // PredCondVal
- if (PCV == CV && SafeToMergeTerminators(TI, PTI)) {
+ if (PCV == CV && TI != PTI) {
+ SmallSetVector<BasicBlock*, 4> FailBlocks;
+ if (!SafeToMergeTerminators(TI, PTI, &FailBlocks)) {
+ for (auto *Succ : FailBlocks) {
+ std::vector<BasicBlock*> Blocks = { TI->getParent() };
+ if (!SplitBlockPredecessors(Succ, Blocks, ".fold.split"))
+ return false;
+ }
+ }
+
// Figure out which 'cases' to copy from SI to PSI.
std::vector<ValueEqualityComparisonCase> BBCases;
BasicBlock *BBDefault = GetValueEqualityComparisonCases(TI, BBCases);
@@ -1215,7 +1262,7 @@ static bool HoistThenElseCodeToIf(BranchInst *BI,
BIParent->getInstList().splice(BI->getIterator(), BB1->getInstList(), I1);
if (!I2->use_empty())
I2->replaceAllUsesWith(I1);
- I1->intersectOptionalDataWith(I2);
+ I1->andIRFlags(I2);
unsigned KnownIDs[] = {LLVMContext::MD_tbaa,
LLVMContext::MD_range,
LLVMContext::MD_fpmath,
@@ -1227,6 +1274,13 @@ static bool HoistThenElseCodeToIf(BranchInst *BI,
LLVMContext::MD_dereferenceable_or_null,
LLVMContext::MD_mem_parallel_loop_access};
combineMetadata(I1, I2, KnownIDs);
+
+ // I1 and I2 are being combined into a single instruction. Its debug
+ // location is the merged locations of the original instructions.
+ if (!isa<CallInst>(I1))
+ I1->setDebugLoc(
+ DILocation::getMergedLocation(I1->getDebugLoc(), I2->getDebugLoc()));
+
I2->eraseFromParent();
Changed = true;
@@ -1319,172 +1373,462 @@ HoistTerminator:
return true;
}
-/// Given an unconditional branch that goes to BBEnd,
-/// check whether BBEnd has only two predecessors and the other predecessor
-/// ends with an unconditional branch. If it is true, sink any common code
-/// in the two predecessors to BBEnd.
-static bool SinkThenElseCodeToEnd(BranchInst *BI1) {
- assert(BI1->isUnconditional());
- BasicBlock *BB1 = BI1->getParent();
- BasicBlock *BBEnd = BI1->getSuccessor(0);
-
- // Check that BBEnd has two predecessors and the other predecessor ends with
- // an unconditional branch.
- pred_iterator PI = pred_begin(BBEnd), PE = pred_end(BBEnd);
- BasicBlock *Pred0 = *PI++;
- if (PI == PE) // Only one predecessor.
- return false;
- BasicBlock *Pred1 = *PI++;
- if (PI != PE) // More than two predecessors.
+// Is it legal to place a variable in operand \c OpIdx of \c I?
+// FIXME: This should be promoted to Instruction.
+static bool canReplaceOperandWithVariable(const Instruction *I,
+ unsigned OpIdx) {
+ // We can't have a PHI with a metadata type.
+ if (I->getOperand(OpIdx)->getType()->isMetadataTy())
return false;
- BasicBlock *BB2 = (Pred0 == BB1) ? Pred1 : Pred0;
- BranchInst *BI2 = dyn_cast<BranchInst>(BB2->getTerminator());
- if (!BI2 || !BI2->isUnconditional())
+
+ // Early exit.
+ if (!isa<Constant>(I->getOperand(OpIdx)))
+ return true;
+
+ switch (I->getOpcode()) {
+ default:
+ return true;
+ case Instruction::Call:
+ case Instruction::Invoke:
+ // FIXME: many arithmetic intrinsics have no issue taking a
+ // variable, however it's hard to distingish these from
+ // specials such as @llvm.frameaddress that require a constant.
+ if (isa<IntrinsicInst>(I))
+ return false;
+
+ // Constant bundle operands may need to retain their constant-ness for
+ // correctness.
+ if (ImmutableCallSite(I).isBundleOperand(OpIdx))
+ return false;
+
+ return true;
+
+ case Instruction::ShuffleVector:
+ // Shufflevector masks are constant.
+ return OpIdx != 2;
+ case Instruction::ExtractValue:
+ case Instruction::InsertValue:
+ // All operands apart from the first are constant.
+ return OpIdx == 0;
+ case Instruction::Alloca:
return false;
+ case Instruction::GetElementPtr:
+ if (OpIdx == 0)
+ return true;
+ gep_type_iterator It = std::next(gep_type_begin(I), OpIdx - 1);
+ return It.isSequential();
+ }
+}
- // Gather the PHI nodes in BBEnd.
- SmallDenseMap<std::pair<Value *, Value *>, PHINode *> JointValueMap;
- Instruction *FirstNonPhiInBBEnd = nullptr;
- for (BasicBlock::iterator I = BBEnd->begin(), E = BBEnd->end(); I != E; ++I) {
- if (PHINode *PN = dyn_cast<PHINode>(I)) {
- Value *BB1V = PN->getIncomingValueForBlock(BB1);
- Value *BB2V = PN->getIncomingValueForBlock(BB2);
- JointValueMap[std::make_pair(BB1V, BB2V)] = PN;
- } else {
- FirstNonPhiInBBEnd = &*I;
- break;
- }
+// All instructions in Insts belong to different blocks that all unconditionally
+// branch to a common successor. Analyze each instruction and return true if it
+// would be possible to sink them into their successor, creating one common
+// instruction instead. For every value that would be required to be provided by
+// PHI node (because an operand varies in each input block), add to PHIOperands.
+static bool canSinkInstructions(
+ ArrayRef<Instruction *> Insts,
+ DenseMap<Instruction *, SmallVector<Value *, 4>> &PHIOperands) {
+ // Prune out obviously bad instructions to move. Any non-store instruction
+ // must have exactly one use, and we check later that use is by a single,
+ // common PHI instruction in the successor.
+ for (auto *I : Insts) {
+ // These instructions may change or break semantics if moved.
+ if (isa<PHINode>(I) || I->isEHPad() || isa<AllocaInst>(I) ||
+ I->getType()->isTokenTy())
+ return false;
+
+ // Conservatively return false if I is an inline-asm instruction. Sinking
+ // and merging inline-asm instructions can potentially create arguments
+ // that cannot satisfy the inline-asm constraints.
+ if (const auto *C = dyn_cast<CallInst>(I))
+ if (C->isInlineAsm())
+ return false;
+
+ // Everything must have only one use too, apart from stores which
+ // have no uses.
+ if (!isa<StoreInst>(I) && !I->hasOneUse())
+ return false;
}
- if (!FirstNonPhiInBBEnd)
- return false;
- // This does very trivial matching, with limited scanning, to find identical
- // instructions in the two blocks. We scan backward for obviously identical
- // instructions in an identical order.
- BasicBlock::InstListType::reverse_iterator RI1 = BB1->getInstList().rbegin(),
- RE1 = BB1->getInstList().rend(),
- RI2 = BB2->getInstList().rbegin(),
- RE2 = BB2->getInstList().rend();
- // Skip debug info.
- while (RI1 != RE1 && isa<DbgInfoIntrinsic>(&*RI1))
- ++RI1;
- if (RI1 == RE1)
- return false;
- while (RI2 != RE2 && isa<DbgInfoIntrinsic>(&*RI2))
- ++RI2;
- if (RI2 == RE2)
- return false;
- // Skip the unconditional branches.
- ++RI1;
- ++RI2;
+ const Instruction *I0 = Insts.front();
+ for (auto *I : Insts)
+ if (!I->isSameOperationAs(I0))
+ return false;
- bool Changed = false;
- while (RI1 != RE1 && RI2 != RE2) {
- // Skip debug info.
- while (RI1 != RE1 && isa<DbgInfoIntrinsic>(&*RI1))
- ++RI1;
- if (RI1 == RE1)
- return Changed;
- while (RI2 != RE2 && isa<DbgInfoIntrinsic>(&*RI2))
- ++RI2;
- if (RI2 == RE2)
- return Changed;
+ // All instructions in Insts are known to be the same opcode. If they aren't
+ // stores, check the only user of each is a PHI or in the same block as the
+ // instruction, because if a user is in the same block as an instruction
+ // we're contemplating sinking, it must already be determined to be sinkable.
+ if (!isa<StoreInst>(I0)) {
+ auto *PNUse = dyn_cast<PHINode>(*I0->user_begin());
+ auto *Succ = I0->getParent()->getTerminator()->getSuccessor(0);
+ if (!all_of(Insts, [&PNUse,&Succ](const Instruction *I) -> bool {
+ auto *U = cast<Instruction>(*I->user_begin());
+ return (PNUse &&
+ PNUse->getParent() == Succ &&
+ PNUse->getIncomingValueForBlock(I->getParent()) == I) ||
+ U->getParent() == I->getParent();
+ }))
+ return false;
+ }
- Instruction *I1 = &*RI1, *I2 = &*RI2;
- auto InstPair = std::make_pair(I1, I2);
- // I1 and I2 should have a single use in the same PHI node, and they
- // perform the same operation.
- // Cannot move control-flow-involving, volatile loads, vaarg, etc.
- if (isa<PHINode>(I1) || isa<PHINode>(I2) || isa<TerminatorInst>(I1) ||
- isa<TerminatorInst>(I2) || I1->isEHPad() || I2->isEHPad() ||
- isa<AllocaInst>(I1) || isa<AllocaInst>(I2) ||
- I1->mayHaveSideEffects() || I2->mayHaveSideEffects() ||
- I1->mayReadOrWriteMemory() || I2->mayReadOrWriteMemory() ||
- !I1->hasOneUse() || !I2->hasOneUse() || !JointValueMap.count(InstPair))
- return Changed;
+ for (unsigned OI = 0, OE = I0->getNumOperands(); OI != OE; ++OI) {
+ if (I0->getOperand(OI)->getType()->isTokenTy())
+ // Don't touch any operand of token type.
+ return false;
+
+ // Because SROA can't handle speculating stores of selects, try not
+ // to sink loads or stores of allocas when we'd have to create a PHI for
+ // the address operand. Also, because it is likely that loads or stores
+ // of allocas will disappear when Mem2Reg/SROA is run, don't sink them.
+ // This can cause code churn which can have unintended consequences down
+ // the line - see https://llvm.org/bugs/show_bug.cgi?id=30244.
+ // FIXME: This is a workaround for a deficiency in SROA - see
+ // https://llvm.org/bugs/show_bug.cgi?id=30188
+ if (OI == 1 && isa<StoreInst>(I0) &&
+ any_of(Insts, [](const Instruction *I) {
+ return isa<AllocaInst>(I->getOperand(1));
+ }))
+ return false;
+ if (OI == 0 && isa<LoadInst>(I0) && any_of(Insts, [](const Instruction *I) {
+ return isa<AllocaInst>(I->getOperand(0));
+ }))
+ return false;
- // Check whether we should swap the operands of ICmpInst.
- // TODO: Add support of communativity.
- ICmpInst *ICmp1 = dyn_cast<ICmpInst>(I1), *ICmp2 = dyn_cast<ICmpInst>(I2);
- bool SwapOpnds = false;
- if (ICmp1 && ICmp2 && ICmp1->getOperand(0) != ICmp2->getOperand(0) &&
- ICmp1->getOperand(1) != ICmp2->getOperand(1) &&
- (ICmp1->getOperand(0) == ICmp2->getOperand(1) ||
- ICmp1->getOperand(1) == ICmp2->getOperand(0))) {
- ICmp2->swapOperands();
- SwapOpnds = true;
+ auto SameAsI0 = [&I0, OI](const Instruction *I) {
+ assert(I->getNumOperands() == I0->getNumOperands());
+ return I->getOperand(OI) == I0->getOperand(OI);
+ };
+ if (!all_of(Insts, SameAsI0)) {
+ if (!canReplaceOperandWithVariable(I0, OI))
+ // We can't create a PHI from this GEP.
+ return false;
+ // Don't create indirect calls! The called value is the final operand.
+ if ((isa<CallInst>(I0) || isa<InvokeInst>(I0)) && OI == OE - 1) {
+ // FIXME: if the call was *already* indirect, we should do this.
+ return false;
+ }
+ for (auto *I : Insts)
+ PHIOperands[I].push_back(I->getOperand(OI));
}
- if (!I1->isSameOperationAs(I2)) {
- if (SwapOpnds)
- ICmp2->swapOperands();
- return Changed;
+ }
+ return true;
+}
+
+// Assuming canSinkLastInstruction(Blocks) has returned true, sink the last
+// instruction of every block in Blocks to their common successor, commoning
+// into one instruction.
+static bool sinkLastInstruction(ArrayRef<BasicBlock*> Blocks) {
+ auto *BBEnd = Blocks[0]->getTerminator()->getSuccessor(0);
+
+ // canSinkLastInstruction returning true guarantees that every block has at
+ // least one non-terminator instruction.
+ SmallVector<Instruction*,4> Insts;
+ for (auto *BB : Blocks) {
+ Instruction *I = BB->getTerminator();
+ do {
+ I = I->getPrevNode();
+ } while (isa<DbgInfoIntrinsic>(I) && I != &BB->front());
+ if (!isa<DbgInfoIntrinsic>(I))
+ Insts.push_back(I);
+ }
+
+ // The only checking we need to do now is that all users of all instructions
+ // are the same PHI node. canSinkLastInstruction should have checked this but
+ // it is slightly over-aggressive - it gets confused by commutative instructions
+ // so double-check it here.
+ Instruction *I0 = Insts.front();
+ if (!isa<StoreInst>(I0)) {
+ auto *PNUse = dyn_cast<PHINode>(*I0->user_begin());
+ if (!all_of(Insts, [&PNUse](const Instruction *I) -> bool {
+ auto *U = cast<Instruction>(*I->user_begin());
+ return U == PNUse;
+ }))
+ return false;
+ }
+
+ // We don't need to do any more checking here; canSinkLastInstruction should
+ // have done it all for us.
+ SmallVector<Value*, 4> NewOperands;
+ for (unsigned O = 0, E = I0->getNumOperands(); O != E; ++O) {
+ // This check is different to that in canSinkLastInstruction. There, we
+ // cared about the global view once simplifycfg (and instcombine) have
+ // completed - it takes into account PHIs that become trivially
+ // simplifiable. However here we need a more local view; if an operand
+ // differs we create a PHI and rely on instcombine to clean up the very
+ // small mess we may make.
+ bool NeedPHI = any_of(Insts, [&I0, O](const Instruction *I) {
+ return I->getOperand(O) != I0->getOperand(O);
+ });
+ if (!NeedPHI) {
+ NewOperands.push_back(I0->getOperand(O));
+ continue;
}
- // The operands should be either the same or they need to be generated
- // with a PHI node after sinking. We only handle the case where there is
- // a single pair of different operands.
- Value *DifferentOp1 = nullptr, *DifferentOp2 = nullptr;
- unsigned Op1Idx = ~0U;
- for (unsigned I = 0, E = I1->getNumOperands(); I != E; ++I) {
- if (I1->getOperand(I) == I2->getOperand(I))
- continue;
- // Early exit if we have more-than one pair of different operands or if
- // we need a PHI node to replace a constant.
- if (Op1Idx != ~0U || isa<Constant>(I1->getOperand(I)) ||
- isa<Constant>(I2->getOperand(I))) {
- // If we can't sink the instructions, undo the swapping.
- if (SwapOpnds)
- ICmp2->swapOperands();
- return Changed;
+ // Create a new PHI in the successor block and populate it.
+ auto *Op = I0->getOperand(O);
+ assert(!Op->getType()->isTokenTy() && "Can't PHI tokens!");
+ auto *PN = PHINode::Create(Op->getType(), Insts.size(),
+ Op->getName() + ".sink", &BBEnd->front());
+ for (auto *I : Insts)
+ PN->addIncoming(I->getOperand(O), I->getParent());
+ NewOperands.push_back(PN);
+ }
+
+ // Arbitrarily use I0 as the new "common" instruction; remap its operands
+ // and move it to the start of the successor block.
+ for (unsigned O = 0, E = I0->getNumOperands(); O != E; ++O)
+ I0->getOperandUse(O).set(NewOperands[O]);
+ I0->moveBefore(&*BBEnd->getFirstInsertionPt());
+
+ // The debug location for the "common" instruction is the merged locations of
+ // all the commoned instructions. We start with the original location of the
+ // "common" instruction and iteratively merge each location in the loop below.
+ const DILocation *Loc = I0->getDebugLoc();
+
+ // Update metadata and IR flags, and merge debug locations.
+ for (auto *I : Insts)
+ if (I != I0) {
+ Loc = DILocation::getMergedLocation(Loc, I->getDebugLoc());
+ combineMetadataForCSE(I0, I);
+ I0->andIRFlags(I);
+ }
+ if (!isa<CallInst>(I0))
+ I0->setDebugLoc(Loc);
+
+ if (!isa<StoreInst>(I0)) {
+ // canSinkLastInstruction checked that all instructions were used by
+ // one and only one PHI node. Find that now, RAUW it to our common
+ // instruction and nuke it.
+ assert(I0->hasOneUse());
+ auto *PN = cast<PHINode>(*I0->user_begin());
+ PN->replaceAllUsesWith(I0);
+ PN->eraseFromParent();
+ }
+
+ // Finally nuke all instructions apart from the common instruction.
+ for (auto *I : Insts)
+ if (I != I0)
+ I->eraseFromParent();
+
+ return true;
+}
+
+namespace {
+
+ // LockstepReverseIterator - Iterates through instructions
+ // in a set of blocks in reverse order from the first non-terminator.
+ // For example (assume all blocks have size n):
+ // LockstepReverseIterator I([B1, B2, B3]);
+ // *I-- = [B1[n], B2[n], B3[n]];
+ // *I-- = [B1[n-1], B2[n-1], B3[n-1]];
+ // *I-- = [B1[n-2], B2[n-2], B3[n-2]];
+ // ...
+ class LockstepReverseIterator {
+ ArrayRef<BasicBlock*> Blocks;
+ SmallVector<Instruction*,4> Insts;
+ bool Fail;
+ public:
+ LockstepReverseIterator(ArrayRef<BasicBlock*> Blocks) :
+ Blocks(Blocks) {
+ reset();
+ }
+
+ void reset() {
+ Fail = false;
+ Insts.clear();
+ for (auto *BB : Blocks) {
+ Instruction *Inst = BB->getTerminator();
+ for (Inst = Inst->getPrevNode(); Inst && isa<DbgInfoIntrinsic>(Inst);)
+ Inst = Inst->getPrevNode();
+ if (!Inst) {
+ // Block wasn't big enough.
+ Fail = true;
+ return;
+ }
+ Insts.push_back(Inst);
}
- DifferentOp1 = I1->getOperand(I);
- Op1Idx = I;
- DifferentOp2 = I2->getOperand(I);
}
- DEBUG(dbgs() << "SINK common instructions " << *I1 << "\n");
- DEBUG(dbgs() << " " << *I2 << "\n");
-
- // We insert the pair of different operands to JointValueMap and
- // remove (I1, I2) from JointValueMap.
- if (Op1Idx != ~0U) {
- auto &NewPN = JointValueMap[std::make_pair(DifferentOp1, DifferentOp2)];
- if (!NewPN) {
- NewPN =
- PHINode::Create(DifferentOp1->getType(), 2,
- DifferentOp1->getName() + ".sink", &BBEnd->front());
- NewPN->addIncoming(DifferentOp1, BB1);
- NewPN->addIncoming(DifferentOp2, BB2);
- DEBUG(dbgs() << "Create PHI node " << *NewPN << "\n";);
+ bool isValid() const {
+ return !Fail;
+ }
+
+ void operator -- () {
+ if (Fail)
+ return;
+ for (auto *&Inst : Insts) {
+ for (Inst = Inst->getPrevNode(); Inst && isa<DbgInfoIntrinsic>(Inst);)
+ Inst = Inst->getPrevNode();
+ // Already at beginning of block.
+ if (!Inst) {
+ Fail = true;
+ return;
+ }
}
- // I1 should use NewPN instead of DifferentOp1.
- I1->setOperand(Op1Idx, NewPN);
}
- PHINode *OldPN = JointValueMap[InstPair];
- JointValueMap.erase(InstPair);
-
- // We need to update RE1 and RE2 if we are going to sink the first
- // instruction in the basic block down.
- bool UpdateRE1 = (I1 == &BB1->front()), UpdateRE2 = (I2 == &BB2->front());
- // Sink the instruction.
- BBEnd->getInstList().splice(FirstNonPhiInBBEnd->getIterator(),
- BB1->getInstList(), I1);
- if (!OldPN->use_empty())
- OldPN->replaceAllUsesWith(I1);
- OldPN->eraseFromParent();
- if (!I2->use_empty())
- I2->replaceAllUsesWith(I1);
- I1->intersectOptionalDataWith(I2);
- // TODO: Use combineMetadata here to preserve what metadata we can
- // (analogous to the hoisting case above).
- I2->eraseFromParent();
+ ArrayRef<Instruction*> operator * () const {
+ return Insts;
+ }
+ };
+
+} // end anonymous namespace
- if (UpdateRE1)
- RE1 = BB1->getInstList().rend();
- if (UpdateRE2)
- RE2 = BB2->getInstList().rend();
- FirstNonPhiInBBEnd = &*I1;
+/// Given an unconditional branch that goes to BBEnd,
+/// check whether BBEnd has only two predecessors and the other predecessor
+/// ends with an unconditional branch. If it is true, sink any common code
+/// in the two predecessors to BBEnd.
+static bool SinkThenElseCodeToEnd(BranchInst *BI1) {
+ assert(BI1->isUnconditional());
+ BasicBlock *BBEnd = BI1->getSuccessor(0);
+
+ // We support two situations:
+ // (1) all incoming arcs are unconditional
+ // (2) one incoming arc is conditional
+ //
+ // (2) is very common in switch defaults and
+ // else-if patterns;
+ //
+ // if (a) f(1);
+ // else if (b) f(2);
+ //
+ // produces:
+ //
+ // [if]
+ // / \
+ // [f(1)] [if]
+ // | | \
+ // | | \
+ // | [f(2)]|
+ // \ | /
+ // [ end ]
+ //
+ // [end] has two unconditional predecessor arcs and one conditional. The
+ // conditional refers to the implicit empty 'else' arc. This conditional
+ // arc can also be caused by an empty default block in a switch.
+ //
+ // In this case, we attempt to sink code from all *unconditional* arcs.
+ // If we can sink instructions from these arcs (determined during the scan
+ // phase below) we insert a common successor for all unconditional arcs and
+ // connect that to [end], to enable sinking:
+ //
+ // [if]
+ // / \
+ // [x(1)] [if]
+ // | | \
+ // | | \
+ // | [x(2)] |
+ // \ / |
+ // [sink.split] |
+ // \ /
+ // [ end ]
+ //
+ SmallVector<BasicBlock*,4> UnconditionalPreds;
+ Instruction *Cond = nullptr;
+ for (auto *B : predecessors(BBEnd)) {
+ auto *T = B->getTerminator();
+ if (isa<BranchInst>(T) && cast<BranchInst>(T)->isUnconditional())
+ UnconditionalPreds.push_back(B);
+ else if ((isa<BranchInst>(T) || isa<SwitchInst>(T)) && !Cond)
+ Cond = T;
+ else
+ return false;
+ }
+ if (UnconditionalPreds.size() < 2)
+ return false;
+
+ bool Changed = false;
+ // We take a two-step approach to tail sinking. First we scan from the end of
+ // each block upwards in lockstep. If the n'th instruction from the end of each
+ // block can be sunk, those instructions are added to ValuesToSink and we
+ // carry on. If we can sink an instruction but need to PHI-merge some operands
+ // (because they're not identical in each instruction) we add these to
+ // PHIOperands.
+ unsigned ScanIdx = 0;
+ SmallPtrSet<Value*,4> InstructionsToSink;
+ DenseMap<Instruction*, SmallVector<Value*,4>> PHIOperands;
+ LockstepReverseIterator LRI(UnconditionalPreds);
+ while (LRI.isValid() &&
+ canSinkInstructions(*LRI, PHIOperands)) {
+ DEBUG(dbgs() << "SINK: instruction can be sunk: " << *(*LRI)[0] << "\n");
+ InstructionsToSink.insert((*LRI).begin(), (*LRI).end());
+ ++ScanIdx;
+ --LRI;
+ }
+
+ auto ProfitableToSinkInstruction = [&](LockstepReverseIterator &LRI) {
+ unsigned NumPHIdValues = 0;
+ for (auto *I : *LRI)
+ for (auto *V : PHIOperands[I])
+ if (InstructionsToSink.count(V) == 0)
+ ++NumPHIdValues;
+ DEBUG(dbgs() << "SINK: #phid values: " << NumPHIdValues << "\n");
+ unsigned NumPHIInsts = NumPHIdValues / UnconditionalPreds.size();
+ if ((NumPHIdValues % UnconditionalPreds.size()) != 0)
+ NumPHIInsts++;
+
+ return NumPHIInsts <= 1;
+ };
+
+ if (ScanIdx > 0 && Cond) {
+ // Check if we would actually sink anything first! This mutates the CFG and
+ // adds an extra block. The goal in doing this is to allow instructions that
+ // couldn't be sunk before to be sunk - obviously, speculatable instructions
+ // (such as trunc, add) can be sunk and predicated already. So we check that
+ // we're going to sink at least one non-speculatable instruction.
+ LRI.reset();
+ unsigned Idx = 0;
+ bool Profitable = false;
+ while (ProfitableToSinkInstruction(LRI) && Idx < ScanIdx) {
+ if (!isSafeToSpeculativelyExecute((*LRI)[0])) {
+ Profitable = true;
+ break;
+ }
+ --LRI;
+ ++Idx;
+ }
+ if (!Profitable)
+ return false;
+
+ DEBUG(dbgs() << "SINK: Splitting edge\n");
+ // We have a conditional edge and we're going to sink some instructions.
+ // Insert a new block postdominating all blocks we're going to sink from.
+ if (!SplitBlockPredecessors(BI1->getSuccessor(0), UnconditionalPreds,
+ ".sink.split"))
+ // Edges couldn't be split.
+ return false;
+ Changed = true;
+ }
+
+ // Now that we've analyzed all potential sinking candidates, perform the
+ // actual sink. We iteratively sink the last non-terminator of the source
+ // blocks into their common successor unless doing so would require too
+ // many PHI instructions to be generated (currently only one PHI is allowed
+ // per sunk instruction).
+ //
+ // We can use InstructionsToSink to discount values needing PHI-merging that will
+ // actually be sunk in a later iteration. This allows us to be more
+ // aggressive in what we sink. This does allow a false positive where we
+ // sink presuming a later value will also be sunk, but stop half way through
+ // and never actually sink it which means we produce more PHIs than intended.
+ // This is unlikely in practice though.
+ for (unsigned SinkIdx = 0; SinkIdx != ScanIdx; ++SinkIdx) {
+ DEBUG(dbgs() << "SINK: Sink: "
+ << *UnconditionalPreds[0]->getTerminator()->getPrevNode()
+ << "\n");
+
+ // Because we've sunk every instruction in turn, the current instruction to
+ // sink is always at index 0.
+ LRI.reset();
+ if (!ProfitableToSinkInstruction(LRI)) {
+ // Too many PHIs would be created.
+ DEBUG(dbgs() << "SINK: stopping here, too many PHIs would be created!\n");
+ break;
+ }
+
+ if (!sinkLastInstruction(UnconditionalPreds))
+ return Changed;
NumSinkCommons++;
Changed = true;
}
@@ -1539,7 +1883,7 @@ static Value *isSafeToSpeculateStore(Instruction *I, BasicBlock *BrBB,
continue;
--MaxNumInstToLookAt;
- // Could be calling an instruction that effects memory like free().
+ // Could be calling an instruction that affects memory like free().
if (CurI.mayHaveSideEffects() && !isa<StoreInst>(CurI))
return nullptr;
@@ -1822,7 +2166,7 @@ static bool FoldCondBranchOnPHI(BranchInst *BI, const DataLayout &DL) {
return false;
// Can't fold blocks that contain noduplicate or convergent calls.
- if (llvm::any_of(*BB, [](const Instruction &I) {
+ if (any_of(*BB, [](const Instruction &I) {
const CallInst *CI = dyn_cast<CallInst>(&I);
return CI && (CI->cannotDuplicate() || CI->isConvergent());
}))
@@ -2464,6 +2808,11 @@ bool llvm::FoldBranchToCommonDest(BranchInst *BI, unsigned BonusInstThreshold) {
PBI = New_PBI;
}
+ // If BI was a loop latch, it may have had associated loop metadata.
+ // We need to copy it to the new latch, that is, PBI.
+ if (MDNode *LoopMD = BI->getMetadata(LLVMContext::MD_loop))
+ PBI->setMetadata(LLVMContext::MD_loop, LoopMD);
+
// TODO: If BB is reachable from all paths through PredBlock, then we
// could replace PBI's branch probabilities with BI's.
@@ -4150,18 +4499,28 @@ static bool ForwardSwitchConditionToPHI(SwitchInst *SI) {
/// Return true if the backend will be able to handle
/// initializing an array of constants like C.
-static bool ValidLookupTableConstant(Constant *C) {
+static bool ValidLookupTableConstant(Constant *C, const TargetTransformInfo &TTI) {
if (C->isThreadDependent())
return false;
if (C->isDLLImportDependent())
return false;
- if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
- return CE->isGEPWithNoNotionalOverIndexing();
+ if (!isa<ConstantFP>(C) && !isa<ConstantInt>(C) &&
+ !isa<ConstantPointerNull>(C) && !isa<GlobalValue>(C) &&
+ !isa<UndefValue>(C) && !isa<ConstantExpr>(C))
+ return false;
+
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
+ if (!CE->isGEPWithNoNotionalOverIndexing())
+ return false;
+ if (!ValidLookupTableConstant(CE->getOperand(0), TTI))
+ return false;
+ }
+
+ if (!TTI.shouldBuildLookupTablesForConstant(C))
+ return false;
- return isa<ConstantFP>(C) || isa<ConstantInt>(C) ||
- isa<ConstantPointerNull>(C) || isa<GlobalValue>(C) ||
- isa<UndefValue>(C);
+ return true;
}
/// If V is a Constant, return it. Otherwise, try to look up
@@ -4216,7 +4575,7 @@ static bool
GetCaseResults(SwitchInst *SI, ConstantInt *CaseVal, BasicBlock *CaseDest,
BasicBlock **CommonDest,
SmallVectorImpl<std::pair<PHINode *, Constant *>> &Res,
- const DataLayout &DL) {
+ const DataLayout &DL, const TargetTransformInfo &TTI) {
// The block from which we enter the common destination.
BasicBlock *Pred = SI->getParent();
@@ -4228,7 +4587,7 @@ GetCaseResults(SwitchInst *SI, ConstantInt *CaseVal, BasicBlock *CaseDest,
++I) {
if (TerminatorInst *T = dyn_cast<TerminatorInst>(I)) {
// If the terminator is a simple branch, continue to the next block.
- if (T->getNumSuccessors() != 1)
+ if (T->getNumSuccessors() != 1 || T->isExceptional())
return false;
Pred = CaseDest;
CaseDest = T->getSuccessor(0);
@@ -4278,7 +4637,7 @@ GetCaseResults(SwitchInst *SI, ConstantInt *CaseVal, BasicBlock *CaseDest,
return false;
// Be conservative about which kinds of constants we support.
- if (!ValidLookupTableConstant(ConstVal))
+ if (!ValidLookupTableConstant(ConstVal, TTI))
return false;
Res.push_back(std::make_pair(PHI, ConstVal));
@@ -4310,14 +4669,15 @@ static bool InitializeUniqueCases(SwitchInst *SI, PHINode *&PHI,
BasicBlock *&CommonDest,
SwitchCaseResultVectorTy &UniqueResults,
Constant *&DefaultResult,
- const DataLayout &DL) {
+ const DataLayout &DL,
+ const TargetTransformInfo &TTI) {
for (auto &I : SI->cases()) {
ConstantInt *CaseVal = I.getCaseValue();
// Resulting value at phi nodes for this case value.
SwitchCaseResultsTy Results;
if (!GetCaseResults(SI, CaseVal, I.getCaseSuccessor(), &CommonDest, Results,
- DL))
+ DL, TTI))
return false;
// Only one value per case is permitted
@@ -4335,7 +4695,7 @@ static bool InitializeUniqueCases(SwitchInst *SI, PHINode *&PHI,
SmallVector<std::pair<PHINode *, Constant *>, 1> DefaultResults;
BasicBlock *DefaultDest = SI->getDefaultDest();
GetCaseResults(SI, nullptr, SI->getDefaultDest(), &CommonDest, DefaultResults,
- DL);
+ DL, TTI);
// If the default value is not found abort unless the default destination
// is unreachable.
DefaultResult =
@@ -4414,7 +4774,8 @@ static void RemoveSwitchAfterSelectConversion(SwitchInst *SI, PHINode *PHI,
/// phi nodes in a common successor block with only two different
/// constant values, replace the switch with select.
static bool SwitchToSelect(SwitchInst *SI, IRBuilder<> &Builder,
- AssumptionCache *AC, const DataLayout &DL) {
+ AssumptionCache *AC, const DataLayout &DL,
+ const TargetTransformInfo &TTI) {
Value *const Cond = SI->getCondition();
PHINode *PHI = nullptr;
BasicBlock *CommonDest = nullptr;
@@ -4422,7 +4783,7 @@ static bool SwitchToSelect(SwitchInst *SI, IRBuilder<> &Builder,
SwitchCaseResultVectorTy UniqueResults;
// Collect all the cases that will deliver the same value from the switch.
if (!InitializeUniqueCases(SI, PHI, CommonDest, UniqueResults, DefaultResult,
- DL))
+ DL, TTI))
return false;
// Selects choose between maximum two values.
if (UniqueResults.size() != 2)
@@ -4441,6 +4802,7 @@ static bool SwitchToSelect(SwitchInst *SI, IRBuilder<> &Builder,
}
namespace {
+
/// This class represents a lookup table that can be used to replace a switch.
class SwitchLookupTable {
public:
@@ -4497,7 +4859,8 @@ private:
// For ArrayKind, this is the array.
GlobalVariable *Array;
};
-}
+
+} // end anonymous namespace
SwitchLookupTable::SwitchLookupTable(
Module &M, uint64_t TableSize, ConstantInt *Offset,
@@ -4860,7 +5223,7 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
typedef SmallVector<std::pair<PHINode *, Constant *>, 4> ResultsTy;
ResultsTy Results;
if (!GetCaseResults(SI, CaseVal, CI.getCaseSuccessor(), &CommonDest,
- Results, DL))
+ Results, DL, TTI))
return false;
// Append the result from this case to the list for each phi.
@@ -4886,8 +5249,9 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
// If the table has holes, we need a constant result for the default case
// or a bitmask that fits in a register.
SmallVector<std::pair<PHINode *, Constant *>, 4> DefaultResultsList;
- bool HasDefaultResults = GetCaseResults(SI, nullptr, SI->getDefaultDest(),
- &CommonDest, DefaultResultsList, DL);
+ bool HasDefaultResults =
+ GetCaseResults(SI, nullptr, SI->getDefaultDest(), &CommonDest,
+ DefaultResultsList, DL, TTI);
bool NeedMask = (TableHasHoles && !HasDefaultResults);
if (NeedMask) {
@@ -5044,6 +5408,111 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
return true;
}
+static bool isSwitchDense(ArrayRef<int64_t> Values) {
+ // See also SelectionDAGBuilder::isDense(), which this function was based on.
+ uint64_t Diff = (uint64_t)Values.back() - (uint64_t)Values.front();
+ uint64_t Range = Diff + 1;
+ uint64_t NumCases = Values.size();
+ // 40% is the default density for building a jump table in optsize/minsize mode.
+ uint64_t MinDensity = 40;
+
+ return NumCases * 100 >= Range * MinDensity;
+}
+
+// Try and transform a switch that has "holes" in it to a contiguous sequence
+// of cases.
+//
+// A switch such as: switch(i) {case 5: case 9: case 13: case 17:} can be
+// range-reduced to: switch ((i-5) / 4) {case 0: case 1: case 2: case 3:}.
+//
+// This converts a sparse switch into a dense switch which allows better
+// lowering and could also allow transforming into a lookup table.
+static bool ReduceSwitchRange(SwitchInst *SI, IRBuilder<> &Builder,
+ const DataLayout &DL,
+ const TargetTransformInfo &TTI) {
+ auto *CondTy = cast<IntegerType>(SI->getCondition()->getType());
+ if (CondTy->getIntegerBitWidth() > 64 ||
+ !DL.fitsInLegalInteger(CondTy->getIntegerBitWidth()))
+ return false;
+ // Only bother with this optimization if there are more than 3 switch cases;
+ // SDAG will only bother creating jump tables for 4 or more cases.
+ if (SI->getNumCases() < 4)
+ return false;
+
+ // This transform is agnostic to the signedness of the input or case values. We
+ // can treat the case values as signed or unsigned. We can optimize more common
+ // cases such as a sequence crossing zero {-4,0,4,8} if we interpret case values
+ // as signed.
+ SmallVector<int64_t,4> Values;
+ for (auto &C : SI->cases())
+ Values.push_back(C.getCaseValue()->getValue().getSExtValue());
+ std::sort(Values.begin(), Values.end());
+
+ // If the switch is already dense, there's nothing useful to do here.
+ if (isSwitchDense(Values))
+ return false;
+
+ // First, transform the values such that they start at zero and ascend.
+ int64_t Base = Values[0];
+ for (auto &V : Values)
+ V -= Base;
+
+ // Now we have signed numbers that have been shifted so that, given enough
+ // precision, there are no negative values. Since the rest of the transform
+ // is bitwise only, we switch now to an unsigned representation.
+ uint64_t GCD = 0;
+ for (auto &V : Values)
+ GCD = GreatestCommonDivisor64(GCD, (uint64_t)V);
+
+ // This transform can be done speculatively because it is so cheap - it results
+ // in a single rotate operation being inserted. This can only happen if the
+ // factor extracted is a power of 2.
+ // FIXME: If the GCD is an odd number we can multiply by the multiplicative
+ // inverse of GCD and then perform this transform.
+ // FIXME: It's possible that optimizing a switch on powers of two might also
+ // be beneficial - flag values are often powers of two and we could use a CLZ
+ // as the key function.
+ if (GCD <= 1 || !isPowerOf2_64(GCD))
+ // No common divisor found or too expensive to compute key function.
+ return false;
+
+ unsigned Shift = Log2_64(GCD);
+ for (auto &V : Values)
+ V = (int64_t)((uint64_t)V >> Shift);
+
+ if (!isSwitchDense(Values))
+ // Transform didn't create a dense switch.
+ return false;
+
+ // The obvious transform is to shift the switch condition right and emit a
+ // check that the condition actually cleanly divided by GCD, i.e.
+ // C & (1 << Shift - 1) == 0
+ // inserting a new CFG edge to handle the case where it didn't divide cleanly.
+ //
+ // A cheaper way of doing this is a simple ROTR(C, Shift). This performs the
+ // shift and puts the shifted-off bits in the uppermost bits. If any of these
+ // are nonzero then the switch condition will be very large and will hit the
+ // default case.
+
+ auto *Ty = cast<IntegerType>(SI->getCondition()->getType());
+ Builder.SetInsertPoint(SI);
+ auto *ShiftC = ConstantInt::get(Ty, Shift);
+ auto *Sub = Builder.CreateSub(SI->getCondition(), ConstantInt::get(Ty, Base));
+ auto *LShr = Builder.CreateLShr(Sub, ShiftC);
+ auto *Shl = Builder.CreateShl(Sub, Ty->getBitWidth() - Shift);
+ auto *Rot = Builder.CreateOr(LShr, Shl);
+ SI->replaceUsesOfWith(SI->getCondition(), Rot);
+
+ for (SwitchInst::CaseIt C = SI->case_begin(), E = SI->case_end(); C != E;
+ ++C) {
+ auto *Orig = C.getCaseValue();
+ auto Sub = Orig->getValue() - APInt(Ty->getBitWidth(), Base);
+ C.setValue(
+ cast<ConstantInt>(ConstantInt::get(Ty, Sub.lshr(ShiftC->getValue()))));
+ }
+ return true;
+}
+
bool SimplifyCFGOpt::SimplifySwitch(SwitchInst *SI, IRBuilder<> &Builder) {
BasicBlock *BB = SI->getParent();
@@ -5078,7 +5547,7 @@ bool SimplifyCFGOpt::SimplifySwitch(SwitchInst *SI, IRBuilder<> &Builder) {
if (EliminateDeadSwitchCases(SI, AC, DL))
return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
- if (SwitchToSelect(SI, Builder, AC, DL))
+ if (SwitchToSelect(SI, Builder, AC, DL, TTI))
return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
if (ForwardSwitchConditionToPHI(SI))
@@ -5087,6 +5556,9 @@ bool SimplifyCFGOpt::SimplifySwitch(SwitchInst *SI, IRBuilder<> &Builder) {
if (SwitchToLookupTable(SI, Builder, DL, TTI))
return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
+ if (ReduceSwitchRange(SI, Builder, DL, TTI))
+ return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
+
return false;
}
@@ -5397,7 +5869,10 @@ static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I) {
// Now make sure that there are no instructions in between that can alter
// control flow (eg. calls)
- for (BasicBlock::iterator i = ++BasicBlock::iterator(I); &*i != Use; ++i)
+ for (BasicBlock::iterator
+ i = ++BasicBlock::iterator(I),
+ UI = BasicBlock::iterator(dyn_cast<Instruction>(Use));
+ i != UI; ++i)
if (i == I->getParent()->end() || i->mayHaveSideEffects())
return false;
diff --git a/contrib/llvm/lib/Transforms/Utils/SimplifyInstructions.cpp b/contrib/llvm/lib/Transforms/Utils/SimplifyInstructions.cpp
index df29906..1220490 100644
--- a/contrib/llvm/lib/Transforms/Utils/SimplifyInstructions.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/SimplifyInstructions.cpp
@@ -34,14 +34,14 @@ using namespace llvm;
STATISTIC(NumSimplified, "Number of redundant instructions removed");
-static bool runImpl(Function &F, const DominatorTree *DT, const TargetLibraryInfo *TLI,
- AssumptionCache *AC) {
+static bool runImpl(Function &F, const DominatorTree *DT,
+ const TargetLibraryInfo *TLI, AssumptionCache *AC) {
const DataLayout &DL = F.getParent()->getDataLayout();
- SmallPtrSet<const Instruction*, 8> S1, S2, *ToSimplify = &S1, *Next = &S2;
+ SmallPtrSet<const Instruction *, 8> S1, S2, *ToSimplify = &S1, *Next = &S2;
bool Changed = false;
do {
- for (BasicBlock *BB : depth_first(&F.getEntryBlock()))
+ for (BasicBlock *BB : depth_first(&F.getEntryBlock())) {
// Here be subtlety: the iterator must be incremented before the loop
// body (not sure why), so a range-for loop won't work here.
for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) {
@@ -51,8 +51,9 @@ static bool runImpl(Function &F, const DominatorTree *DT, const TargetLibraryInf
// empty and we only bother simplifying instructions that are in it.
if (!ToSimplify->empty() && !ToSimplify->count(I))
continue;
+
// Don't waste time simplifying unused instructions.
- if (!I->use_empty())
+ if (!I->use_empty()) {
if (Value *V = SimplifyInstruction(I, DL, TLI, DT, AC)) {
// Mark all uses for resimplification next time round the loop.
for (User *U : I->users())
@@ -61,16 +62,17 @@ static bool runImpl(Function &F, const DominatorTree *DT, const TargetLibraryInf
++NumSimplified;
Changed = true;
}
- bool res = RecursivelyDeleteTriviallyDeadInstructions(I, TLI);
- if (res) {
- // RecursivelyDeleteTriviallyDeadInstruction can remove
- // more than one instruction, so simply incrementing the
- // iterator does not work. When instructions get deleted
- // re-iterate instead.
- BI = BB->begin(); BE = BB->end();
- Changed |= res;
+ }
+ if (RecursivelyDeleteTriviallyDeadInstructions(I, TLI)) {
+ // RecursivelyDeleteTriviallyDeadInstruction can remove more than one
+ // instruction, so simply incrementing the iterator does not work.
+ // When instructions get deleted re-iterate instead.
+ BI = BB->begin();
+ BE = BB->end();
+ Changed = true;
}
}
+ }
// Place the list of instructions to simplify on the next loop iteration
// into ToSimplify.
@@ -90,6 +92,7 @@ namespace {
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesCFG();
+ AU.addRequired<DominatorTreeWrapperPass>();
AU.addRequired<AssumptionCacheTracker>();
AU.addRequired<TargetLibraryInfoWrapperPass>();
}
@@ -99,9 +102,8 @@ namespace {
if (skipFunction(F))
return false;
- const DominatorTreeWrapperPass *DTWP =
- getAnalysisIfAvailable<DominatorTreeWrapperPass>();
- const DominatorTree *DT = DTWP ? &DTWP->getDomTree() : nullptr;
+ const DominatorTree *DT =
+ &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
const TargetLibraryInfo *TLI =
&getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
AssumptionCache *AC =
@@ -115,6 +117,7 @@ char InstSimplifier::ID = 0;
INITIALIZE_PASS_BEGIN(InstSimplifier, "instsimplify",
"Remove redundant instructions", false, false)
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
+INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
INITIALIZE_PASS_END(InstSimplifier, "instsimplify",
"Remove redundant instructions", false, false)
@@ -126,11 +129,11 @@ FunctionPass *llvm::createInstructionSimplifierPass() {
}
PreservedAnalyses InstSimplifierPass::run(Function &F,
- AnalysisManager<Function> &AM) {
- auto *DT = AM.getCachedResult<DominatorTreeAnalysis>(F);
+ FunctionAnalysisManager &AM) {
+ auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
auto &AC = AM.getResult<AssumptionAnalysis>(F);
- bool Changed = runImpl(F, DT, &TLI, &AC);
+ bool Changed = runImpl(F, &DT, &TLI, &AC);
if (!Changed)
return PreservedAnalyses::all();
// FIXME: This should also 'preserve the CFG'.
diff --git a/contrib/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/contrib/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index c298695..8eaeb10 100644
--- a/contrib/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -56,6 +56,38 @@ static bool ignoreCallingConv(LibFunc::Func Func) {
Func == LibFunc::llabs || Func == LibFunc::strlen;
}
+static bool isCallingConvCCompatible(CallInst *CI) {
+ switch(CI->getCallingConv()) {
+ default:
+ return false;
+ case llvm::CallingConv::C:
+ return true;
+ case llvm::CallingConv::ARM_APCS:
+ case llvm::CallingConv::ARM_AAPCS:
+ case llvm::CallingConv::ARM_AAPCS_VFP: {
+
+ // The iOS ABI diverges from the standard in some cases, so for now don't
+ // try to simplify those calls.
+ if (Triple(CI->getModule()->getTargetTriple()).isiOS())
+ return false;
+
+ auto *FuncTy = CI->getFunctionType();
+
+ if (!FuncTy->getReturnType()->isPointerTy() &&
+ !FuncTy->getReturnType()->isIntegerTy() &&
+ !FuncTy->getReturnType()->isVoidTy())
+ return false;
+
+ for (auto Param : FuncTy->params()) {
+ if (!Param->isPointerTy() && !Param->isIntegerTy())
+ return false;
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
/// Return true if it only matters that the value is equal or not-equal to zero.
static bool isOnlyUsedInZeroEqualityComparison(Value *V) {
for (User *U : V->users()) {
@@ -83,7 +115,7 @@ static bool isOnlyUsedInEqualityComparison(Value *V, Value *With) {
}
static bool callHasFloatingPointArgument(const CallInst *CI) {
- return std::any_of(CI->op_begin(), CI->op_end(), [](const Use &OI) {
+ return any_of(CI->operands(), [](const Use &OI) {
return OI->getType()->isFloatingPointTy();
});
}
@@ -868,7 +900,7 @@ static Value *valueHasFloatPrecision(Value *Val) {
if (ConstantFP *Const = dyn_cast<ConstantFP>(Val)) {
APFloat F = Const->getValueAPF();
bool losesInfo;
- (void)F.convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven,
+ (void)F.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven,
&losesInfo);
if (!losesInfo)
return ConstantFP::get(Const->getContext(), F);
@@ -993,16 +1025,20 @@ Value *LibCallSimplifier::optimizePow(CallInst *CI, IRBuilder<> &B) {
Ret = optimizeUnaryDoubleFP(CI, B, true);
Value *Op1 = CI->getArgOperand(0), *Op2 = CI->getArgOperand(1);
+
+ // pow(1.0, x) -> 1.0
+ if (match(Op1, m_SpecificFP(1.0)))
+ return Op1;
+ // pow(2.0, x) -> llvm.exp2(x)
+ if (match(Op1, m_SpecificFP(2.0))) {
+ Value *Exp2 = Intrinsic::getDeclaration(CI->getModule(), Intrinsic::exp2,
+ CI->getType());
+ return B.CreateCall(Exp2, Op2, "exp2");
+ }
+
+ // There's no llvm.exp10 intrinsic yet, but, maybe, some day there will
+ // be one.
if (ConstantFP *Op1C = dyn_cast<ConstantFP>(Op1)) {
- // pow(1.0, x) -> 1.0
- if (Op1C->isExactlyValue(1.0))
- return Op1C;
- // pow(2.0, x) -> exp2(x)
- if (Op1C->isExactlyValue(2.0) &&
- hasUnaryFloatFn(TLI, Op1->getType(), LibFunc::exp2, LibFunc::exp2f,
- LibFunc::exp2l))
- return emitUnaryFloatFnCall(Op2, TLI->getName(LibFunc::exp2), B,
- Callee->getAttributes());
// pow(10.0, x) -> exp10(x)
if (Op1C->isExactlyValue(10.0) &&
hasUnaryFloatFn(TLI, Op1->getType(), LibFunc::exp10, LibFunc::exp10f,
@@ -1038,6 +1074,24 @@ Value *LibCallSimplifier::optimizePow(CallInst *CI, IRBuilder<> &B) {
if (Op2C->getValueAPF().isZero()) // pow(x, 0.0) -> 1.0
return ConstantFP::get(CI->getType(), 1.0);
+ if (Op2C->isExactlyValue(-0.5) &&
+ hasUnaryFloatFn(TLI, Op2->getType(), LibFunc::sqrt, LibFunc::sqrtf,
+ LibFunc::sqrtl)) {
+ // If -ffast-math:
+ // pow(x, -0.5) -> 1.0 / sqrt(x)
+ if (CI->hasUnsafeAlgebra()) {
+ IRBuilder<>::FastMathFlagGuard Guard(B);
+ B.setFastMathFlags(CI->getFastMathFlags());
+
+ // Here we cannot lower to an intrinsic because C99 sqrt() and llvm.sqrt
+ // are not guaranteed to have the same semantics.
+ Value *Sqrt = emitUnaryFloatFnCall(Op1, TLI->getName(LibFunc::sqrt), B,
+ Callee->getAttributes());
+
+ return B.CreateFDiv(ConstantFP::get(CI->getType(), 1.0), Sqrt, "sqrtrecip");
+ }
+ }
+
if (Op2C->isExactlyValue(0.5) &&
hasUnaryFloatFn(TLI, Op2->getType(), LibFunc::sqrt, LibFunc::sqrtf,
LibFunc::sqrtl) &&
@@ -1048,6 +1102,9 @@ Value *LibCallSimplifier::optimizePow(CallInst *CI, IRBuilder<> &B) {
if (CI->hasUnsafeAlgebra()) {
IRBuilder<>::FastMathFlagGuard Guard(B);
B.setFastMathFlags(CI->getFastMathFlags());
+
+ // Unlike other math intrinsics, sqrt has differerent semantics
+ // from the libc function. See LangRef for details.
return emitUnaryFloatFnCall(Op1, TLI->getName(LibFunc::sqrt), B,
Callee->getAttributes());
}
@@ -1082,6 +1139,10 @@ Value *LibCallSimplifier::optimizePow(CallInst *CI, IRBuilder<> &B) {
!V.isInteger())
return nullptr;
+ // Propagate fast math flags.
+ IRBuilder<>::FastMathFlagGuard Guard(B);
+ B.setFastMathFlags(CI->getFastMathFlags());
+
// We will memoize intermediate products of the Addition Chain.
Value *InnerChain[33] = {nullptr};
InnerChain[1] = Op1;
@@ -1090,9 +1151,8 @@ Value *LibCallSimplifier::optimizePow(CallInst *CI, IRBuilder<> &B) {
// We cannot readily convert a non-double type (like float) to a double.
// So we first convert V to something which could be converted to double.
bool ignored;
- V.convert(APFloat::IEEEdouble, APFloat::rmTowardZero, &ignored);
+ V.convert(APFloat::IEEEdouble(), APFloat::rmTowardZero, &ignored);
- // TODO: Should the new instructions propagate the 'fast' flag of the pow()?
Value *FMul = getPow(InnerChain, V.convertToDouble(), B);
// For negative exponents simply compute the reciprocal.
if (Op2C->isNegative())
@@ -1150,19 +1210,11 @@ Value *LibCallSimplifier::optimizeExp2(CallInst *CI, IRBuilder<> &B) {
Value *LibCallSimplifier::optimizeFabs(CallInst *CI, IRBuilder<> &B) {
Function *Callee = CI->getCalledFunction();
- Value *Ret = nullptr;
StringRef Name = Callee->getName();
if (Name == "fabs" && hasFloatVersion(Name))
- Ret = optimizeUnaryDoubleFP(CI, B, false);
+ return optimizeUnaryDoubleFP(CI, B, false);
- Value *Op = CI->getArgOperand(0);
- if (Instruction *I = dyn_cast<Instruction>(Op)) {
- // Fold fabs(x * x) -> x * x; any squared FP value must already be positive.
- if (I->getOpcode() == Instruction::FMul)
- if (I->getOperand(0) == I->getOperand(1))
- return Op;
- }
- return Ret;
+ return nullptr;
}
Value *LibCallSimplifier::optimizeFMinFMax(CallInst *CI, IRBuilder<> &B) {
@@ -1428,6 +1480,12 @@ Value *LibCallSimplifier::optimizeSinCosPi(CallInst *CI, IRBuilder<> &B) {
Value *Sin, *Cos, *SinCos;
insertSinCosCall(B, CI->getCalledFunction(), Arg, IsFloat, Sin, Cos, SinCos);
+ auto replaceTrigInsts = [this](SmallVectorImpl<CallInst *> &Calls,
+ Value *Res) {
+ for (CallInst *C : Calls)
+ replaceAllUsesWith(C, Res);
+ };
+
replaceTrigInsts(SinCalls, Sin);
replaceTrigInsts(CosCalls, Cos);
replaceTrigInsts(SinCosCalls, SinCos);
@@ -1472,32 +1530,16 @@ void LibCallSimplifier::classifyArgUse(
}
}
-void LibCallSimplifier::replaceTrigInsts(SmallVectorImpl<CallInst *> &Calls,
- Value *Res) {
- for (CallInst *C : Calls)
- replaceAllUsesWith(C, Res);
-}
-
//===----------------------------------------------------------------------===//
// Integer Library Call Optimizations
//===----------------------------------------------------------------------===//
Value *LibCallSimplifier::optimizeFFS(CallInst *CI, IRBuilder<> &B) {
- Function *Callee = CI->getCalledFunction();
- Value *Op = CI->getArgOperand(0);
-
- // Constant fold.
- if (ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
- if (CI->isZero()) // ffs(0) -> 0.
- return B.getInt32(0);
- // ffs(c) -> cttz(c)+1
- return B.getInt32(CI->getValue().countTrailingZeros() + 1);
- }
-
// ffs(x) -> x != 0 ? (i32)llvm.cttz(x)+1 : 0
+ Value *Op = CI->getArgOperand(0);
Type *ArgType = Op->getType();
- Value *F =
- Intrinsic::getDeclaration(Callee->getParent(), Intrinsic::cttz, ArgType);
+ Value *F = Intrinsic::getDeclaration(CI->getCalledFunction()->getParent(),
+ Intrinsic::cttz, ArgType);
Value *V = B.CreateCall(F, {Op, B.getTrue()}, "cttz");
V = B.CreateAdd(V, ConstantInt::get(V->getType(), 1));
V = B.CreateIntCast(V, B.getInt32Ty(), false);
@@ -1506,6 +1548,18 @@ Value *LibCallSimplifier::optimizeFFS(CallInst *CI, IRBuilder<> &B) {
return B.CreateSelect(Cond, V, B.getInt32(0));
}
+Value *LibCallSimplifier::optimizeFls(CallInst *CI, IRBuilder<> &B) {
+ // fls(x) -> (i32)(sizeInBits(x) - llvm.ctlz(x, false))
+ Value *Op = CI->getArgOperand(0);
+ Type *ArgType = Op->getType();
+ Value *F = Intrinsic::getDeclaration(CI->getCalledFunction()->getParent(),
+ Intrinsic::ctlz, ArgType);
+ Value *V = B.CreateCall(F, {Op, B.getFalse()}, "ctlz");
+ V = B.CreateSub(ConstantInt::get(V->getType(), ArgType->getIntegerBitWidth()),
+ V);
+ return B.CreateIntCast(V, CI->getType(), false);
+}
+
Value *LibCallSimplifier::optimizeAbs(CallInst *CI, IRBuilder<> &B) {
// abs(x) -> x >s -1 ? x : -x
Value *Op = CI->getArgOperand(0);
@@ -1891,7 +1945,7 @@ Value *LibCallSimplifier::optimizeStringMemoryLibCall(CallInst *CI,
if (TLI->getLibFunc(*Callee, Func) && TLI->has(Func)) {
// Make sure we never change the calling convention.
assert((ignoreCallingConv(Func) ||
- CI->getCallingConv() == llvm::CallingConv::C) &&
+ isCallingConvCCompatible(CI)) &&
"Optimizing string/memory libcall would change the calling convention");
switch (Func) {
case LibFunc::strcat:
@@ -1958,7 +2012,7 @@ Value *LibCallSimplifier::optimizeCall(CallInst *CI) {
SmallVector<OperandBundleDef, 2> OpBundles;
CI->getOperandBundlesAsDefs(OpBundles);
IRBuilder<> Builder(CI, /*FPMathTag=*/nullptr, OpBundles);
- bool isCallingConvC = CI->getCallingConv() == llvm::CallingConv::C;
+ bool isCallingConvC = isCallingConvCCompatible(CI);
// Command-line parameter overrides instruction attribute.
if (EnableUnsafeFPShrink.getNumOccurrences() > 0)
@@ -2042,6 +2096,10 @@ Value *LibCallSimplifier::optimizeCall(CallInst *CI) {
case LibFunc::ffsl:
case LibFunc::ffsll:
return optimizeFFS(CI, Builder);
+ case LibFunc::fls:
+ case LibFunc::flsl:
+ case LibFunc::flsll:
+ return optimizeFls(CI, Builder);
case LibFunc::abs:
case LibFunc::labs:
case LibFunc::llabs:
@@ -2314,7 +2372,7 @@ Value *FortifiedLibCallSimplifier::optimizeCall(CallInst *CI) {
SmallVector<OperandBundleDef, 2> OpBundles;
CI->getOperandBundlesAsDefs(OpBundles);
IRBuilder<> Builder(CI, /*FPMathTag=*/nullptr, OpBundles);
- bool isCallingConvC = CI->getCallingConv() == llvm::CallingConv::C;
+ bool isCallingConvC = isCallingConvCCompatible(CI);
// First, check that this is a known library functions and that the prototype
// is correct.
diff --git a/contrib/llvm/lib/Transforms/Utils/StripGCRelocates.cpp b/contrib/llvm/lib/Transforms/Utils/StripGCRelocates.cpp
new file mode 100644
index 0000000..f3d3fad
--- /dev/null
+++ b/contrib/llvm/lib/Transforms/Utils/StripGCRelocates.cpp
@@ -0,0 +1,80 @@
+//===- StripGCRelocates.cpp - Remove gc.relocates inserted by RewriteStatePoints===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a little utility pass that removes the gc.relocates inserted by
+// RewriteStatepointsForGC. Note that the generated IR is incorrect,
+// but this is useful as a single pass in itself, for analysis of IR, without
+// the GC.relocates. The statepoint and gc.result instrinsics would still be
+// present.
+//===----------------------------------------------------------------------===//
+
+#include "llvm/IR/Function.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Statepoint.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Pass.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+namespace {
+struct StripGCRelocates : public FunctionPass {
+ static char ID; // Pass identification, replacement for typeid
+ StripGCRelocates() : FunctionPass(ID) {
+ initializeStripGCRelocatesPass(*PassRegistry::getPassRegistry());
+ }
+
+ void getAnalysisUsage(AnalysisUsage &Info) const override {}
+
+ bool runOnFunction(Function &F) override;
+
+};
+char StripGCRelocates::ID = 0;
+}
+
+bool StripGCRelocates::runOnFunction(Function &F) {
+ // Nothing to do for declarations.
+ if (F.isDeclaration())
+ return false;
+ SmallVector<GCRelocateInst *, 20> GCRelocates;
+ // TODO: We currently do not handle gc.relocates that are in landing pads,
+ // i.e. not bound to a single statepoint token.
+ for (Instruction &I : instructions(F)) {
+ if (auto *GCR = dyn_cast<GCRelocateInst>(&I))
+ if (isStatepoint(GCR->getOperand(0)))
+ GCRelocates.push_back(GCR);
+ }
+ // All gc.relocates are bound to a single statepoint token. The order of
+ // visiting gc.relocates for deletion does not matter.
+ for (GCRelocateInst *GCRel : GCRelocates) {
+ Value *OrigPtr = GCRel->getDerivedPtr();
+ Value *ReplaceGCRel = OrigPtr;
+
+ // All gc_relocates are i8 addrspace(1)* typed, we need a bitcast from i8
+ // addrspace(1)* to the type of the OrigPtr, if the are not the same.
+ if (GCRel->getType() != OrigPtr->getType())
+ ReplaceGCRel = new BitCastInst(OrigPtr, GCRel->getType(), "cast", GCRel);
+
+ // Replace all uses of gc.relocate and delete the gc.relocate
+ // There maybe unncessary bitcasts back to the OrigPtr type, an instcombine
+ // pass would clear this up.
+ GCRel->replaceAllUsesWith(ReplaceGCRel);
+ GCRel->eraseFromParent();
+ }
+ return !GCRelocates.empty();
+}
+
+INITIALIZE_PASS(StripGCRelocates, "strip-gc-relocates",
+ "Strip gc.relocates inserted through RewriteStatepointsForGC",
+ true, false)
+FunctionPass *llvm::createStripGCRelocatesPass() {
+ return new StripGCRelocates();
+}
diff --git a/contrib/llvm/lib/Transforms/Utils/StripNonLineTableDebugInfo.cpp b/contrib/llvm/lib/Transforms/Utils/StripNonLineTableDebugInfo.cpp
new file mode 100644
index 0000000..66dbf33
--- /dev/null
+++ b/contrib/llvm/lib/Transforms/Utils/StripNonLineTableDebugInfo.cpp
@@ -0,0 +1,42 @@
+//===- StripNonLineTableDebugInfo.cpp -- Strip parts of Debug Info --------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/IPO.h"
+#include "llvm/IR/DebugInfo.h"
+#include "llvm/Pass.h"
+using namespace llvm;
+
+namespace {
+
+/// This pass strips all debug info that is not related line tables.
+/// The result will be the same as if the program where compiled with
+/// -gline-tables-only.
+struct StripNonLineTableDebugInfo : public ModulePass {
+ static char ID; // Pass identification, replacement for typeid
+ StripNonLineTableDebugInfo() : ModulePass(ID) {
+ initializeStripNonLineTableDebugInfoPass(*PassRegistry::getPassRegistry());
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesAll();
+ }
+
+ bool runOnModule(Module &M) override {
+ return llvm::stripNonLineTableDebugInfo(M);
+ }
+};
+}
+
+char StripNonLineTableDebugInfo::ID = 0;
+INITIALIZE_PASS(StripNonLineTableDebugInfo, "strip-nonlinetable-debuginfo",
+ "Strip all debug info except linetables", false, false)
+
+ModulePass *llvm::createStripNonLineTableDebugInfoPass() {
+ return new StripNonLineTableDebugInfo();
+}
diff --git a/contrib/llvm/lib/Transforms/Utils/SymbolRewriter.cpp b/contrib/llvm/lib/Transforms/Utils/SymbolRewriter.cpp
index 7523ca5..6d13663 100644
--- a/contrib/llvm/lib/Transforms/Utils/SymbolRewriter.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/SymbolRewriter.cpp
@@ -58,6 +58,7 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "symbol-rewriter"
+#include "llvm/Transforms/Utils/SymbolRewriter.h"
#include "llvm/Pass.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/IR/LegacyPassManager.h"
@@ -68,7 +69,6 @@
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/YAMLParser.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Transforms/Utils/SymbolRewriter.h"
using namespace llvm;
using namespace SymbolRewriter;
@@ -361,9 +361,11 @@ parseRewriteFunctionDescriptor(yaml::Stream &YS, yaml::ScalarNode *K,
// TODO see if there is a more elegant solution to selecting the rewrite
// descriptor type
if (!Target.empty())
- DL->push_back(new ExplicitRewriteFunctionDescriptor(Source, Target, Naked));
+ DL->push_back(llvm::make_unique<ExplicitRewriteFunctionDescriptor>(
+ Source, Target, Naked));
else
- DL->push_back(new PatternRewriteFunctionDescriptor(Source, Transform));
+ DL->push_back(
+ llvm::make_unique<PatternRewriteFunctionDescriptor>(Source, Transform));
return true;
}
@@ -421,11 +423,12 @@ parseRewriteGlobalVariableDescriptor(yaml::Stream &YS, yaml::ScalarNode *K,
}
if (!Target.empty())
- DL->push_back(new ExplicitRewriteGlobalVariableDescriptor(Source, Target,
- /*Naked*/false));
+ DL->push_back(llvm::make_unique<ExplicitRewriteGlobalVariableDescriptor>(
+ Source, Target,
+ /*Naked*/ false));
else
- DL->push_back(new PatternRewriteGlobalVariableDescriptor(Source,
- Transform));
+ DL->push_back(llvm::make_unique<PatternRewriteGlobalVariableDescriptor>(
+ Source, Transform));
return true;
}
@@ -483,67 +486,80 @@ parseRewriteGlobalAliasDescriptor(yaml::Stream &YS, yaml::ScalarNode *K,
}
if (!Target.empty())
- DL->push_back(new ExplicitRewriteNamedAliasDescriptor(Source, Target,
- /*Naked*/false));
+ DL->push_back(llvm::make_unique<ExplicitRewriteNamedAliasDescriptor>(
+ Source, Target,
+ /*Naked*/ false));
else
- DL->push_back(new PatternRewriteNamedAliasDescriptor(Source, Transform));
+ DL->push_back(llvm::make_unique<PatternRewriteNamedAliasDescriptor>(
+ Source, Transform));
return true;
}
namespace {
-class RewriteSymbols : public ModulePass {
+class RewriteSymbolsLegacyPass : public ModulePass {
public:
static char ID; // Pass identification, replacement for typeid
- RewriteSymbols();
- RewriteSymbols(SymbolRewriter::RewriteDescriptorList &DL);
+ RewriteSymbolsLegacyPass();
+ RewriteSymbolsLegacyPass(SymbolRewriter::RewriteDescriptorList &DL);
bool runOnModule(Module &M) override;
private:
- void loadAndParseMapFiles();
-
- SymbolRewriter::RewriteDescriptorList Descriptors;
+ RewriteSymbolPass Impl;
};
-char RewriteSymbols::ID = 0;
+char RewriteSymbolsLegacyPass::ID = 0;
-RewriteSymbols::RewriteSymbols() : ModulePass(ID) {
- initializeRewriteSymbolsPass(*PassRegistry::getPassRegistry());
- loadAndParseMapFiles();
+RewriteSymbolsLegacyPass::RewriteSymbolsLegacyPass() : ModulePass(ID), Impl() {
+ initializeRewriteSymbolsLegacyPassPass(*PassRegistry::getPassRegistry());
}
-RewriteSymbols::RewriteSymbols(SymbolRewriter::RewriteDescriptorList &DL)
- : ModulePass(ID) {
- Descriptors.splice(Descriptors.begin(), DL);
+RewriteSymbolsLegacyPass::RewriteSymbolsLegacyPass(
+ SymbolRewriter::RewriteDescriptorList &DL)
+ : ModulePass(ID), Impl(DL) {}
+
+bool RewriteSymbolsLegacyPass::runOnModule(Module &M) {
+ return Impl.runImpl(M);
+}
}
-bool RewriteSymbols::runOnModule(Module &M) {
+namespace llvm {
+PreservedAnalyses RewriteSymbolPass::run(Module &M, ModuleAnalysisManager &AM) {
+ if (!runImpl(M))
+ return PreservedAnalyses::all();
+
+ return PreservedAnalyses::none();
+}
+
+bool RewriteSymbolPass::runImpl(Module &M) {
bool Changed;
Changed = false;
for (auto &Descriptor : Descriptors)
- Changed |= Descriptor.performOnModule(M);
+ Changed |= Descriptor->performOnModule(M);
return Changed;
}
-void RewriteSymbols::loadAndParseMapFiles() {
+void RewriteSymbolPass::loadAndParseMapFiles() {
const std::vector<std::string> MapFiles(RewriteMapFiles);
- SymbolRewriter::RewriteMapParser parser;
+ SymbolRewriter::RewriteMapParser Parser;
for (const auto &MapFile : MapFiles)
- parser.parse(MapFile, &Descriptors);
+ Parser.parse(MapFile, &Descriptors);
}
}
-INITIALIZE_PASS(RewriteSymbols, "rewrite-symbols", "Rewrite Symbols", false,
- false)
+INITIALIZE_PASS(RewriteSymbolsLegacyPass, "rewrite-symbols", "Rewrite Symbols",
+ false, false)
-ModulePass *llvm::createRewriteSymbolsPass() { return new RewriteSymbols(); }
+ModulePass *llvm::createRewriteSymbolsPass() {
+ return new RewriteSymbolsLegacyPass();
+}
ModulePass *
llvm::createRewriteSymbolsPass(SymbolRewriter::RewriteDescriptorList &DL) {
- return new RewriteSymbols(DL);
+ return new RewriteSymbolsLegacyPass(DL);
}
diff --git a/contrib/llvm/lib/Transforms/Utils/Utils.cpp b/contrib/llvm/lib/Transforms/Utils/Utils.cpp
index 8f85f19..7b9de2e 100644
--- a/contrib/llvm/lib/Transforms/Utils/Utils.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/Utils.cpp
@@ -25,16 +25,19 @@ void llvm::initializeTransformUtils(PassRegistry &Registry) {
initializeBreakCriticalEdgesPass(Registry);
initializeInstNamerPass(Registry);
initializeLCSSAWrapperPassPass(Registry);
+ initializeLibCallsShrinkWrapLegacyPassPass(Registry);
initializeLoopSimplifyPass(Registry);
- initializeLowerInvokePass(Registry);
+ initializeLowerInvokeLegacyPassPass(Registry);
initializeLowerSwitchPass(Registry);
- initializeNameAnonFunctionPass(Registry);
+ initializeNameAnonGlobalLegacyPassPass(Registry);
initializePromoteLegacyPassPass(Registry);
+ initializeStripNonLineTableDebugInfoPass(Registry);
initializeUnifyFunctionExitNodesPass(Registry);
initializeInstSimplifierPass(Registry);
initializeMetaRenamerPass(Registry);
initializeMemorySSAWrapperPassPass(Registry);
initializeMemorySSAPrinterLegacyPassPass(Registry);
+ initializeStripGCRelocatesPass(Registry);
}
/// LLVMInitializeTransformUtils - C binding for initializeTransformUtilsPasses.
diff --git a/contrib/llvm/lib/Transforms/Utils/ValueMapper.cpp b/contrib/llvm/lib/Transforms/Utils/ValueMapper.cpp
index 2eade8c..0e9baaf 100644
--- a/contrib/llvm/lib/Transforms/Utils/ValueMapper.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/ValueMapper.cpp
@@ -38,15 +38,6 @@ struct DelayedBasicBlock {
BasicBlock *OldBB;
std::unique_ptr<BasicBlock> TempBB;
- // Explicit move for MSVC.
- DelayedBasicBlock(DelayedBasicBlock &&X)
- : OldBB(std::move(X.OldBB)), TempBB(std::move(X.TempBB)) {}
- DelayedBasicBlock &operator=(DelayedBasicBlock &&X) {
- OldBB = std::move(X.OldBB);
- TempBB = std::move(X.TempBB);
- return *this;
- }
-
DelayedBasicBlock(const BlockAddress &Old)
: OldBB(Old.getBasicBlock()),
TempBB(BasicBlock::Create(Old.getContext())) {}
@@ -184,17 +175,6 @@ class MDNodeMapper {
bool HasChanged = false;
unsigned ID = ~0u;
TempMDNode Placeholder;
-
- Data() {}
- Data(Data &&X)
- : HasChanged(std::move(X.HasChanged)), ID(std::move(X.ID)),
- Placeholder(std::move(X.Placeholder)) {}
- Data &operator=(Data &&X) {
- HasChanged = std::move(X.HasChanged);
- ID = std::move(X.ID);
- Placeholder = std::move(X.Placeholder);
- return *this;
- }
};
/// A graph of uniqued nodes.
@@ -671,7 +651,7 @@ void MDNodeMapper::UniquedGraph::propagateChanges() {
if (D.HasChanged)
continue;
- if (!llvm::any_of(N->operands(), [&](const Metadata *Op) {
+ if (none_of(N->operands(), [&](const Metadata *Op) {
auto Where = Info.find(Op);
return Where != Info.end() && Where->second.HasChanged;
}))
OpenPOWER on IntegriCloud