<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
</head>
<body text="#000000" bgcolor="#FFFFFF">
This should be fully addressed in 254803 and 254795. 254795 papered
over the problem enough to pass valgrind (and cleaned up code in the
process), 254803 should cover the underlying problem. <br>
<br>
If you see further problems, feel free to revert all three changes.
<br>
<br>
Philip<br>
<br>
<div class="moz-cite-prefix">On 12/04/2015 01:37 PM, Mike Aizatsky
wrote:<br>
</div>
<blockquote
cite="mid:CAGq4m19GMojAekmHrKNU+gpMX4X6brCm-6VGPfobuBaz+2E4Zw@mail.gmail.com"
type="cite">
<div dir="ltr">The code seems to have a memory leak. Reported by
asan build:
<div><br>
</div>
<div><a moz-do-not-send="true"
href="http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/8348/steps/check-clang%20asan/logs/stdio">http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/8348/steps/check-clang%20asan/logs/stdio</a><br>
</div>
<div><br>
</div>
<div>
<pre style="font-family:'Courier New',courier,monotype,monospace;color:rgb(0,0,0);font-size:medium;line-height:normal"><span class="stdout">=================================================================
==17198==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 520 byte(s) in 1 object(s) allocated from:
#0 0x8514a8 in __interceptor_malloc /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:40
#1 0x3c428fd in llvm::SmallVectorBase::grow_pod(void*, unsigned long, unsigned long) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/lib/Support/SmallVector.cpp:28:15
#2 0x32771b2 in grow_pod /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/include/llvm/ADT/SmallVector.h:81:5
#3 0x32771b2 in grow /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/include/llvm/ADT/SmallVector.h:334
#4 0x32771b2 in operator= /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/include/llvm/ADT/SmallVector.h:771
#5 0x32771b2 in SmallVector /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/include/llvm/ADT/SmallVector.h:897
#6 0x32771b2 in AnalysisUsage /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/include/llvm/PassAnalysisSupport.h:37
#7 0x32771b2 in AUFoldingSetNode /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/include/llvm/IR/LegacyPassManagers.h:259
#8 0x32771b2 in llvm::PMTopLevelManager::findAnalysisUsage(llvm::Pass*) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/lib/IR/LegacyPassManager.cpp:592
#9 0x3278ed8 in llvm::PMTopLevelManager::schedulePass(llvm::Pass*) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/lib/IR/LegacyPassManager.cpp:623:28
#10 0x2ba9b0f in llvm::TargetPassConfig::addPass(llvm::Pass*, bool, bool) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/lib/CodeGen/Passes.cpp:327:5
#11 0x2bad50a in llvm::TargetPassConfig::addOptimizedRegAlloc(llvm::FunctionPass*) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/lib/CodeGen/Passes.cpp:759:5
#12 0x2babdd0 in llvm::TargetPassConfig::addMachinePasses() /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/lib/CodeGen/Passes.cpp:553:5
#13 0x298e905 in addPassesToGenerateCode(llvm::LLVMTargetMachine*, llvm::legacy::PassManagerBase&, bool, void const*, void const*, void const*, llvm::MachineFunctionInitializer*) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/lib/CodeGen/LLVMTargetMachine.cpp:138:3
#14 0x298d12e in llvm::LLVMTargetMachine::addPassesToEmitFile(llvm::legacy::PassManagerBase&, llvm::raw_pwrite_stream&, llvm::TargetMachine::CodeGenFileType, bool, void const*, void const*, void const*, llvm::MachineFunctionInitializer*) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/lib/CodeGen/LLVMTargetMachine.cpp:151:7
#15 0x4082655 in AddEmitPasses /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/CodeGen/BackendUtil.cpp:587:7
#16 0x4082655 in EmitAssembly /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/CodeGen/BackendUtil.cpp:627
#17 0x4082655 in clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::StringRef, llvm::Module*, clang::BackendAction, llvm::raw_pwrite_stream*) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/CodeGen/BackendUtil.cpp:666
#18 0x5329076 in clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/CodeGen/CodeGenAction.cpp:189:7
#19 0x5de04f4 in clang::ParseAST(clang::Sema&, bool, bool) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/Parse/ParseAST.cpp:168:3
#20 0x532541c in clang::CodeGenAction::ExecuteAction() /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/CodeGen/CodeGenAction.cpp:797:3
#21 0x4a2949b in clang::FrontendAction::Execute() /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/Frontend/FrontendAction.cpp:439:8
#22 0x498c2d4 in clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp:841:7
#23 0x4bd55ee in clang::ExecuteCompilerInvocation(clang::CompilerInstance*) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp:222:18
#24 0x89019a in cc1_main(llvm::ArrayRef<char const*>, char const*, void*) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/tools/driver/cc1_main.cpp:116:13
#25 0x88a5b2 in ExecuteCC1Tool /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/tools/driver/driver.cpp:301:12
#26 0x88a5b2 in main /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/tools/driver/driver.cpp:366
#27 0x7fdd62e94ec4 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)
SUMMARY: AddressSanitizer: 520 byte(s) leaked in 1 allocation(s).
</span></pre>
</div>
<div><span class="stdout"><br>
</span></div>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr">On Fri, Dec 4, 2015 at 12:08 PM Philip Reames via
llvm-commits <<a moz-do-not-send="true"
href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">Author:
reames<br>
Date: Fri Dec 4 14:05:04 2015<br>
New Revision: 254760<br>
<br>
URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project?rev=254760&view=rev"
rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=254760&view=rev</a><br>
Log:<br>
[LegacyPassManager] Reduce memory usage for AnalysisUsage<br>
<br>
The LegacyPassManager was storing an instance of AnalysisUsage
for each instance of each pass. In practice, most instances of
a single pass class share the same dependencies. We can't rely
on this because passes can (and some do) have dynamic
dependencies based on instance options.<br>
<br>
We can exploit the likely commonality by uniqueing the usage
information after querying the pass, but before storing it
into the pass manager. This greatly reduces memory consumption
by the AnalysisUsage objects. For a long pass pipeline, I
measured a decrease in memory consumption for this storage of
about 50%. I have not measured on the default O3 pipeline, but
I suspect it will see some benefit as well since many passes
are repeated (e.g. InstCombine).<br>
<br>
Differential Revision: <a moz-do-not-send="true"
href="http://reviews.llvm.org/D14677" rel="noreferrer"
target="_blank">http://reviews.llvm.org/D14677</a><br>
<br>
<br>
Modified:<br>
llvm/trunk/include/llvm/IR/LegacyPassManagers.h<br>
llvm/trunk/lib/IR/LegacyPassManager.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/IR/LegacyPassManagers.h<br>
URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/LegacyPassManagers.h?rev=254760&r1=254759&r2=254760&view=diff"
rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/LegacyPassManagers.h?rev=254760&r1=254759&r2=254760&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/IR/LegacyPassManagers.h (original)<br>
+++ llvm/trunk/include/llvm/IR/LegacyPassManagers.h Fri Dec 4
14:05:04 2015<br>
@@ -16,6 +16,7 @@<br>
<br>
#include "llvm/ADT/ArrayRef.h"<br>
#include "llvm/ADT/DenseMap.h"<br>
+#include "llvm/ADT/FoldingSet.h"<br>
#include "llvm/ADT/SmallPtrSet.h"<br>
#include "llvm/ADT/SmallVector.h"<br>
#include "llvm/Pass.h"<br>
@@ -250,7 +251,40 @@ private:<br>
/// Map from ID to immutable passes.<br>
SmallDenseMap<AnalysisID, ImmutablePass *, 8>
ImmutablePassMap;<br>
<br>
- DenseMap<Pass *, AnalysisUsage *> AnUsageMap;<br>
+<br>
+ /// A wrapper around AnalysisUsage for the purpose of
uniqueing. The wrapper<br>
+ /// is used to avoid needing to make AnalysisUsage itself a
folding set node.<br>
+ struct AUFoldingSetNode : public FoldingSetNode {<br>
+ AnalysisUsage AU;<br>
+ AUFoldingSetNode(const AnalysisUsage &AU) : AU(AU) {}<br>
+ void Profile(FoldingSetNodeID &ID) const {<br>
+ Profile(ID, AU);<br>
+ }<br>
+ static void Profile(FoldingSetNodeID &ID, const
AnalysisUsage &AU) {<br>
+ // TODO: We could consider sorting the dependency
arrays within the<br>
+ // AnalysisUsage (since they are conceptually
unordered).<br>
+ ID.AddBoolean(AU.getPreservesAll());<br>
+ for (auto &Vec : {AU.getRequiredSet(),
AU.getRequiredTransitiveSet(),<br>
+ AU.getPreservedSet(), AU.getUsedSet()}) {<br>
+ ID.AddInteger(Vec.size());<br>
+ for(AnalysisID AID : Vec)<br>
+ ID.AddPointer(AID);<br>
+ }<br>
+ }<br>
+ };<br>
+<br>
+ // Contains all of the unique combinations of
AnalysisUsage. This is helpful<br>
+ // when we have multiple instances of the same pass since
they'll usually<br>
+ // have the same analysis usage and can share storage.<br>
+ FoldingSet<AUFoldingSetNode> UniqueAnalysisUsages;<br>
+<br>
+ // Allocator used for allocating UAFoldingSetNodes. This
handles deletion of<br>
+ // all allocated nodes in one fell swoop.<br>
+ BumpPtrAllocator AUFoldingSetNodeAllocator;<br>
+<br>
+ // Maps from a pass to it's associated entry in
UniqueAnalysisUsages. Does<br>
+ // not own the storage associated with either key or
value..<br>
+ DenseMap<Pass *, AnalysisUsage*> AnUsageMap;<br>
<br>
/// Collection of PassInfo objects found via analysis IDs
and in this top<br>
/// level manager. This is used to memoize queries to the
pass registry.<br>
<br>
Modified: llvm/trunk/lib/IR/LegacyPassManager.cpp<br>
URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LegacyPassManager.cpp?rev=254760&r1=254759&r2=254760&view=diff"
rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LegacyPassManager.cpp?rev=254760&r1=254759&r2=254760&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/IR/LegacyPassManager.cpp (original)<br>
+++ llvm/trunk/lib/IR/LegacyPassManager.cpp Fri Dec 4
14:05:04 2015<br>
@@ -569,13 +569,33 @@ void PMTopLevelManager::collectLastUses(<br>
<br>
AnalysisUsage *PMTopLevelManager::findAnalysisUsage(Pass *P)
{<br>
AnalysisUsage *AnUsage = nullptr;<br>
- DenseMap<Pass *, AnalysisUsage *>::iterator DMI =
AnUsageMap.find(P);<br>
+ auto DMI = AnUsageMap.find(P);<br>
if (DMI != AnUsageMap.end())<br>
AnUsage = DMI->second;<br>
else {<br>
- AnUsage = new AnalysisUsage();<br>
- P->getAnalysisUsage(*AnUsage);<br>
- AnUsageMap[P] = AnUsage;<br>
+ // Look up the analysis usage from the pass instance
(different instances<br>
+ // of the same pass can produce different results), but
unique the<br>
+ // resulting object to reduce memory usage. This helps
to greatly reduce<br>
+ // memory usage when we have many instances of only a few
pass types<br>
+ // (e.g. instcombine, simplifycfg, etc...) which tend to
share a fixed set<br>
+ // of dependencies.<br>
+ AnalysisUsage AU;<br>
+ P->getAnalysisUsage(AU);<br>
+<br>
+ AUFoldingSetNode* Node = nullptr;<br>
+ FoldingSetNodeID ID;<br>
+ AUFoldingSetNode::Profile(ID, AU);<br>
+ void *IP = nullptr;<br>
+ if (auto *N =
UniqueAnalysisUsages.FindNodeOrInsertPos(ID, IP))<br>
+ Node = N;<br>
+ else {<br>
+ Node = new (AUFoldingSetNodeAllocator)
AUFoldingSetNode(AU);<br>
+ UniqueAnalysisUsages.InsertNode(Node, IP);<br>
+ }<br>
+ assert(Node && "cached analysis usage must be non
null");<br>
+<br>
+ AnUsageMap[P] = &Node->AU;<br>
+ AnUsage = &Node->AU;;<br>
}<br>
return AnUsage;<br>
}<br>
@@ -798,10 +818,6 @@ PMTopLevelManager::~PMTopLevelManager()<br>
for (SmallVectorImpl<ImmutablePass *>::iterator<br>
I = ImmutablePasses.begin(), E =
ImmutablePasses.end(); I != E; ++I)<br>
delete *I;<br>
-<br>
- for (DenseMap<Pass *, AnalysisUsage *>::iterator DMI
= AnUsageMap.begin(),<br>
- DME = AnUsageMap.end(); DMI != DME; ++DMI)<br>
- delete DMI->second;<br>
}<br>
<br>
//===----------------------------------------------------------------------===//<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a moz-do-not-send="true"
href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a moz-do-not-send="true"
href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits"
rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote>
</div>
</blockquote>
<br>
</body>
</html>