[PATCH] D19556: [ThinLTO] Emit individual index files for distributed backends

Teresa Johnson via llvm-commits llvm-commits at lists.llvm.org
Fri May 6 17:11:08 PDT 2016


tejohnson added a comment.

I'm at a loss as to what is going on with the msan failures. Maybe it will be obvious to someone else, so posting what I found so far here.

Unfortunately, I can make the msan failure go away any number of ways (including building at a lower level of optimization or adding any print statements, which is making debugging challenging). I also put a log from a debugging session below to show what info I can get.

With my own msan built compiler, I can reproduce most but not all of the failures from the bot. The case I have been looking at is with the distributed_indexes.ll test added with this patch. In that case when we create the IndexBitcodeWriter we have a non-null ModuleToSummariesForIndex pointer, so we don't initialize the IndexSummaries* pointers. When I step through in the debugger, the range based for loop in the IndexBitcodeWriter constructor executes the expected paths in the begin() and end() iterator constructors (not shown in the below trace). After the first for loop body executes, I can see where we execute the iterator's operator++() and operator==() paths for the expected ModuleToSummariesForIndex!=null case. But then oddly we seem to jump back to operator++() handling on the wrong path (that we would execute if ModuleToSummariesForIndex==null), and is where we attempt to access and get the msan error on the IndexSummaries* iterator accesses.

A few things that make it go away, but I don't understand why (may be luck):

1. Initializing the IndexSummariesBack and IndexSummariesIter unconditionally in the constructor (we can do this safely since the Index is always passed in).
2. Re-initializing IndexSummariesBack in the operator++() code right before we access it (although that access shouldn't happen as noted above).

For both 1) and 2) I don't understand why these would help except luck, since we shouldn't be executing the path that accesses these iterators. Is there something about the way they are declared that would make the compiler think it can hoist the accesses so that they are unconditionally executed?

3. Change the range based for loop to be a non-range for loop: for (IndexBitcodeWriter::iterator I = begin(); I != end(); ++I) GUIDToValueIdMap[(*I).first] = ++GlobalValueId;
4. Change the range based for loop to make a copy of the value instead of assigning to a const reference: for (auto I : *this) GUIDToValueIdMap[I.first] = ++GlobalValueId;

For both 3) and 4) this avoids binding the return of the iterator::operator* (which is a std::pair) to a const reference. However, looking at operator* which invokes make_pair on a GUID and summary pointer to create the return value, I think the const reference should extend the lifetime of the returned temporary through the loop body shouldn't it? In any case, this doesn't explain why I am seeing the wrong path of the operator++() being executed after we appear to already have done the operator++ and operator==.

Here's the debugging log, with some comments sprinkled in:

Starting program: /usr/local/google/home/tejohnson/llvm/llvm_msan/bin/llvm-lto -thinlto-action=distributedindexes -thinlto-index /usr/local/google/home/tejohnson/llvm/llvm_msan/test/ThinLTO/X86/Output/distributed_indexes.ll.tmp.index.bc /usr/local/google/home/tejohnson/llvm/llvm_msan/test/ThinLTO/X86/Output/distributed_indexes.ll.tmp1.bc /usr/local/google/home/tejohnson/llvm/llvm_msan/test/ThinLTO/X86/Output/distributed_indexes.ll.tmp2.bc

Breakpoint 3, IndexBitcodeWriter () at llvm/lib/Bitcode/Writer/BitcodeWriter.cpp:285
285	      : BitcodeWriter(Buffer), Index(Index),

// entered the IndexBitcodeWriter constructor, use next to get to the body of the first iteration:

(gdb) n
286	        ModuleToSummariesForIndex(ModuleToSummariesForIndex) {
(gdb) 
285	      : BitcodeWriter(Buffer), Index(Index),
(gdb) 
286	        ModuleToSummariesForIndex(ModuleToSummariesForIndex) {
(gdb) 
281	  IndexBitcodeWriter(SmallVectorImpl<char> &Buffer,
(gdb) 
275	  unsigned GlobalValueId = 0;
(gdb) 
291	    for (const auto &I : *this)
(gdb) 
292	      GUIDToValueIdMap[I.first] = ++GlobalValueId;

// single step from here. First set of instructions are the emplace into map from line 292:

(gdb) s
operator[] () at llvm/lib/Bitcode/Writer/BitcodeWriter.cpp:292
292	      GUIDToValueIdMap[I.first] = ++GlobalValueId;
(gdb) 
__emplace_unique_key_args<unsigned long, const std::__1::piecewise_construct_t &, std::__1::tuple<const unsigned long &>, std::__1::tuple<> > () at llvm/lib/Bitcode/Writer/BitcodeWriter.cpp:292
292	      GUIDToValueIdMap[I.first] = ++GlobalValueId;
(gdb) 
__insert_node_at () at llvm/lib/Bitcode/Writer/BitcodeWriter.cpp:292
292	      GUIDToValueIdMap[I.first] = ++GlobalValueId;
(gdb) 
size () at llvm/lib/Bitcode/Writer/BitcodeWriter.cpp:292
292	      GUIDToValueIdMap[I.first] = ++GlobalValueId;
(gdb) 
first () at llvm/lib/Bitcode/Writer/BitcodeWriter.cpp:292
292	      GUIDToValueIdMap[I.first] = ++GlobalValueId;
(gdb) 
first () at /usr/local/google/home/tejohnson/llvm/llvm_msan/build-libcxx-msan/include/c++/v1/memory:2312
2312	    _LIBCPP_INLINE_VISIBILITY _T1_reference       first() _NOEXCEPT       {return __first_;}
(gdb) 
__emplace_unique_key_args<unsigned long, const std::__1::piecewise_construct_t &, std::__1::tuple<const unsigned long &>, std::__1::tuple<> > () at /usr/local/google/home/tejohnson/llvm/llvm_msan/build-libcxx-msan/include/c++/v1/__tree:2013
2013	    __node_base_pointer& __child = __find_equal(__parent, __k);
(gdb) 
__find_equal<unsigned long> () at /usr/local/google/home/tejohnson/llvm/llvm_msan/build-libcxx-msan/include/c++/v1/__tree:1887
1887	    if (__nd != nullptr)
(gdb) 
__emplace_unique_key_args<unsigned long, const std::__1::piecewise_construct_t &, std::__1::tuple<const unsigned long &>, std::__1::tuple<> > () at /usr/local/google/home/tejohnson/llvm/llvm_msan/build-libcxx-msan/include/c++/v1/__tree:2023
2023	        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
(gdb) 
__insert_node_at () at /usr/local/google/home/tejohnson/llvm/llvm_msan/build-libcxx-msan/include/c++/v1/__tree:1997
1997	    ++size();

// Now enter the operator++() in the range for loop, executes the Writer.ModuleToSummariesForIndex!=null case as expected:

(gdb) 
357	        if (ModuleGVSummariesIter == ModuleSummariesIter->second.end() &&
(gdb) list
352	      // First the inner iterator is incremented, then if it is at the end
353	      // and there are more outer iterations to go, the inner is reset to
354	      // the start of the next inner list.
355	      if (Writer.ModuleToSummariesForIndex) {
356	        ++ModuleGVSummariesIter;
357	        if (ModuleGVSummariesIter == ModuleSummariesIter->second.end() &&
358	            ModuleSummariesIter != ModuleSummariesBack) {
359	          ++ModuleSummariesIter;
360	          ModuleGVSummariesIter = ModuleSummariesIter->second.begin();
361	        }
(gdb) up
#1  IndexBitcodeWriter () at llvm/lib/Bitcode/Writer/BitcodeWriter.cpp:291
291	    for (const auto &I : *this)
(gdb) down
#0  operator++ () at llvm/lib/Bitcode/Writer/BitcodeWriter.cpp:357
357	        if (ModuleGVSummariesIter == ModuleSummariesIter->second.end() &&
(gdb) s
end () at llvm/lib/Bitcode/Writer/BitcodeWriter.cpp:357
357	        if (ModuleGVSummariesIter == ModuleSummariesIter->second.end() &&
(gdb) 
end () at llvm/lib/Bitcode/Writer/BitcodeWriter.cpp:357
357	        if (ModuleGVSummariesIter == ModuleSummariesIter->second.end() &&
(gdb) 
__end_node () at llvm/lib/Bitcode/Writer/BitcodeWriter.cpp:357
357	        if (ModuleGVSummariesIter == ModuleSummariesIter->second.end() &&
(gdb) 
first () at llvm/lib/Bitcode/Writer/BitcodeWriter.cpp:357
357	        if (ModuleGVSummariesIter == ModuleSummariesIter->second.end() &&
(gdb) 
first () at /usr/local/google/home/tejohnson/llvm/llvm_msan/build-libcxx-msan/include/c++/v1/memory:2312
2312	    _LIBCPP_INLINE_VISIBILITY _T1_reference       first() _NOEXCEPT       {return __first_;}
(gdb) 
operator++ () at llvm/lib/Bitcode/Writer/BitcodeWriter.cpp:358
358	            ModuleSummariesIter != ModuleSummariesBack) {
(gdb) s
operator!= () at llvm/lib/Bitcode/Writer/BitcodeWriter.cpp:358
358	            ModuleSummariesIter != ModuleSummariesBack) {
(gdb) s
operator!= () at /usr/local/google/home/tejohnson/llvm/llvm_msan/build-libcxx-msan/include/c++/v1/__tree:810
810	        {return !(__x == __y);}
(gdb) 
operator++ () at llvm/lib/Bitcode/Writer/BitcodeWriter.cpp:357
357	        if (ModuleGVSummariesIter == ModuleSummariesIter->second.end() &&
(gdb) 
IndexBitcodeWriter () at llvm/lib/Bitcode/Writer/BitcodeWriter.cpp:291
291	    for (const auto &I : *this)

// Next we execute the operator!= to check if for loop at end():

(gdb) s
operator!= () at llvm/lib/Bitcode/Writer/BitcodeWriter.cpp:291
291	    for (const auto &I : *this)
(gdb) 
operator== () at llvm/lib/Bitcode/Writer/BitcodeWriter.cpp:291
291	    for (const auto &I : *this)
(gdb) up
#1  operator!= () at llvm/include/llvm/ADT/iterator.h:97
97	    return !static_cast<const DerivedT *>(this)->operator==(RHS);
(gdb) up
#2  IndexBitcodeWriter () at llvm/lib/Bitcode/Writer/BitcodeWriter.cpp:291
291	    for (const auto &I : *this)
(gdb) down
#1  operator!= () at llvm/include/llvm/ADT/iterator.h:97
97	    return !static_cast<const DerivedT *>(this)->operator==(RHS);
(gdb) down
#0  operator== () at llvm/lib/Bitcode/Writer/BitcodeWriter.cpp:291
291	    for (const auto &I : *this)
(gdb) s
operator== () at llvm/lib/Bitcode/Writer/BitcodeWriter.cpp:291
291	    for (const auto &I : *this)

// This is the Writer.ModuleToSummariesForIndex!=null case of operator==() as expected:

(gdb) up
#1  operator== () at llvm/lib/Bitcode/Writer/BitcodeWriter.cpp:395
395	        return ModuleGVSummariesIter == RHS.ModuleGVSummariesIter;
(gdb) s
operator== () at /usr/local/google/home/tejohnson/llvm/llvm_msan/build-libcxx-msan/include/c++/v1/__tree:807
807	        {return __x.__ptr_ == __y.__ptr_;}
(gdb) s
IndexBitcodeWriter () at llvm/lib/Bitcode/Writer/BitcodeWriter.cpp:291
291	    for (const auto &I : *this)

// Here's where things go weird. This is the Writer.ModuleToSummariesForIndex==null case of operator++():

(gdb) s
operator++ () at llvm/lib/Bitcode/Writer/BitcodeWriter.cpp:364
364	        if (IndexGVSummariesIter == IndexSummariesIter->second.end() &&
(gdb) up
#1  IndexBitcodeWriter () at llvm/lib/Bitcode/Writer/BitcodeWriter.cpp:291
291	    for (const auto &I : *this)
(gdb) down
#0  operator++ () at llvm/lib/Bitcode/Writer/BitcodeWriter.cpp:364
364	        if (IndexGVSummariesIter == IndexSummariesIter->second.end() &&
(gdb) s
365	            IndexSummariesIter != IndexSummariesBack) {
(gdb) s
operator!= () at llvm/lib/Bitcode/Writer/BitcodeWriter.cpp:365
365	            IndexSummariesIter != IndexSummariesBack) {
(gdb) s
operator!= () at /usr/local/google/home/tejohnson/llvm/llvm_msan/build-libcxx-msan/include/c++/v1/__tree:886
886	        {return !(__x == __y);}
(gdb) up
#1  operator!= () at /usr/local/google/home/tejohnson/llvm/llvm_msan/build-libcxx-msan/include/c++/v1/map:798
798	        {return __x.__i_ != __y.__i_;}
(gdb) up
#2  operator++ () at llvm/lib/Bitcode/Writer/BitcodeWriter.cpp:365
365	            IndexSummariesIter != IndexSummariesBack) {
(gdb) down   
#1  operator!= () at /usr/local/google/home/tejohnson/llvm/llvm_msan/build-libcxx-msan/include/c++/v1/map:798
798	        {return __x.__i_ != __y.__i_;}
(gdb) down
#0  operator!= () at /usr/local/google/home/tejohnson/llvm/llvm_msan/build-libcxx-msan/include/c++/v1/__tree:886
886	        {return !(__x == __y);}
(gdb) s
operator++ () at llvm/lib/Bitcode/Writer/BitcodeWriter.cpp:364
364	        if (IndexGVSummariesIter == IndexSummariesIter->second.end() &&
(gdb) s

Breakpoint 2, __msan_warning_noreturn ()

  at /usr/local/google/home/tejohnson/llvm/llvm_msan/llvm/projects/compiler-rt/lib/msan/msan.cc:362

362	void __msan_warning_noreturn() {


Repository:
  rL LLVM

http://reviews.llvm.org/D19556





More information about the llvm-commits mailing list