UseListOrder: Fix blockaddress use-list order

`parseBitcodeFile()` uses the generic `getLazyBitcodeFile()` function as
a helper.  Since `parseBitcodeFile()` isn't actually lazy -- it calls
`MaterializeAllPermanently()` -- bypass the unnecessary call to
`materializeForwardReferencedFunctions()` by extracting out a common
helper function.  This removes the last of the use-list churn caused by
blockaddresses.

This highlights that we can't reproduce use-list order of globals and
constants when parsing lazily -- but that's necessarily out of scope.
When we're parsing lazily, we never have all the functions in memory, so
the use-lists of globals (and constants that reference globals) are
always incomplete.

This is part of PR5680.

llvm-svn: 214581
This commit is contained in:
Duncan P. N. Exon Smith 2014-08-01 22:27:19 +00:00
parent 3516669a50
commit 6e1009b65e
3 changed files with 56 additions and 6 deletions

View File

@ -3503,10 +3503,17 @@ const std::error_category &llvm::BitcodeErrorCategory() {
// External interface
//===----------------------------------------------------------------------===//
/// getLazyBitcodeModule - lazy function-at-a-time loading from a file.
/// \brief Get a lazy one-at-time loading module from bitcode.
///
ErrorOr<Module *> llvm::getLazyBitcodeModule(MemoryBuffer *Buffer,
LLVMContext &Context) {
/// This isn't always used in a lazy context. In particular, it's also used by
/// \a parseBitcodeFile(). If this is truly lazy, then we need to eagerly pull
/// in forward-referenced functions from block address references.
///
/// \param[in] WillMaterializeAll Set to \c true if the caller promises to
/// materialize everything -- in particular, if this isn't truly lazy.
static ErrorOr<Module *> getLazyBitcodeModuleImpl(MemoryBuffer *Buffer,
LLVMContext &Context,
bool WillMaterializeAll) {
Module *M = new Module(Buffer->getBufferIdentifier(), Context);
BitcodeReader *R = new BitcodeReader(Buffer, Context);
M->setMaterializer(R);
@ -3520,12 +3527,18 @@ ErrorOr<Module *> llvm::getLazyBitcodeModule(MemoryBuffer *Buffer,
if (std::error_code EC = R->ParseBitcodeInto(M))
return cleanupOnError(EC);
if (std::error_code EC = R->materializeForwardReferencedFunctions())
return cleanupOnError(EC);
if (!WillMaterializeAll)
// Resolve forward references from blockaddresses.
if (std::error_code EC = R->materializeForwardReferencedFunctions())
return cleanupOnError(EC);
return M;
}
ErrorOr<Module *> llvm::getLazyBitcodeModule(MemoryBuffer *Buffer,
LLVMContext &Context) {
return getLazyBitcodeModuleImpl(Buffer, Context, false);
}
Module *llvm::getStreamedBitcodeModule(const std::string &name,
DataStreamer *streamer,
@ -3545,7 +3558,8 @@ Module *llvm::getStreamedBitcodeModule(const std::string &name,
ErrorOr<Module *> llvm::parseBitcodeFile(MemoryBuffer *Buffer,
LLVMContext &Context) {
ErrorOr<Module *> ModuleOrErr = getLazyBitcodeModule(Buffer, Context);
ErrorOr<Module *> ModuleOrErr =
getLazyBitcodeModuleImpl(Buffer, Context, true);
if (!ModuleOrErr)
return ModuleOrErr;
Module *M = ModuleOrErr.get();

View File

@ -1,4 +1,5 @@
; RUN: llvm-as < %s | llvm-dis | FileCheck %s
; RUN: verify-uselistorder < %s -preserve-bc-use-list-order
; PR9857
define void @f(i8** nocapture %ptr1) {

View File

@ -131,3 +131,38 @@ loop2:
%var = phi i32 [ %var, %loop1 ], [ %var, %loop2 ]
br label %loop1
}
; Check that block addresses work.
@ba1 = constant i8* blockaddress (@bafunc1, %bb)
@ba2 = constant i8* getelementptr (i8* blockaddress (@bafunc2, %bb), i61 0)
@ba3 = constant i8* getelementptr (i8* blockaddress (@bafunc2, %bb), i61 0)
define i8* @babefore() {
ret i8* getelementptr (i8* blockaddress (@bafunc2, %bb), i61 0)
bb1:
ret i8* blockaddress (@bafunc1, %bb)
bb2:
ret i8* blockaddress (@bafunc3, %bb)
}
define void @bafunc1() {
unreachable
bb:
unreachable
}
define void @bafunc2() {
unreachable
bb:
unreachable
}
define void @bafunc3() {
unreachable
bb:
unreachable
}
define i8* @baafter() {
ret i8* blockaddress (@bafunc2, %bb)
bb1:
ret i8* blockaddress (@bafunc1, %bb)
bb2:
ret i8* blockaddress (@bafunc3, %bb)
}