diff options
author | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2014-08-05 17:49:48 +0000 |
---|---|---|
committer | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2014-08-05 17:49:48 +0000 |
commit | 5a511b59c5571097e9cec617873168f55a8f2e0c (patch) | |
tree | 08755bde5a2c4060314b11d5580280dfa13d0ffa /llvm/lib/Bitcode/Reader/BitcodeReader.cpp | |
parent | 00c9b6461f65380deed20676147083a6e8c66c3e (diff) | |
download | llvm-5a511b59c5571097e9cec617873168f55a8f2e0c.zip llvm-5a511b59c5571097e9cec617873168f55a8f2e0c.tar.gz llvm-5a511b59c5571097e9cec617873168f55a8f2e0c.tar.bz2 |
BitcodeReader: Fix non-determinism in use-list order
`BasicBlockFwdRefs` (and `BlockAddrFwdRefs` before it) was being emptied
in a non-deterministic order. When predicting use-list order I've
worked around this another way, but even when parsing lazily (and we
can't recreate use-list order) use-lists should be deterministic.
Make them so by using a side-queue of functions with forward-referenced
blocks that gets visited in order.
llvm-svn: 214899
Diffstat (limited to 'llvm/lib/Bitcode/Reader/BitcodeReader.cpp')
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 85dde39..7908524 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -38,9 +38,14 @@ std::error_code BitcodeReader::materializeForwardReferencedFunctions() { // Prevent recursion. WillMaterializeAllForwardRefs = true; - while (!BasicBlockFwdRefs.empty()) { - Function *F = BasicBlockFwdRefs.begin()->first; + while (!BasicBlockFwdRefQueue.empty()) { + Function *F = BasicBlockFwdRefQueue.front(); + BasicBlockFwdRefQueue.pop_front(); assert(F && "Expected valid function"); + if (!BasicBlockFwdRefs.count(F)) + // Already materialized. + continue; + // Check for a function that isn't materializable to prevent an infinite // loop. When parsing a blockaddress stored in a global variable, there // isn't a trivial way to check if a function will have a body without a @@ -52,6 +57,7 @@ std::error_code BitcodeReader::materializeForwardReferencedFunctions() { if (std::error_code EC = Materialize(F)) return EC; } + assert(BasicBlockFwdRefs.empty() && "Function missing from queue"); // Reset state. WillMaterializeAllForwardRefs = false; @@ -72,6 +78,7 @@ void BitcodeReader::FreeState() { MDKindMap.clear(); assert(BasicBlockFwdRefs.empty() && "Unresolved blockaddress fwd references"); + BasicBlockFwdRefQueue.clear(); } //===----------------------------------------------------------------------===// @@ -1629,7 +1636,10 @@ std::error_code BitcodeReader::ParseConstants() { // Otherwise insert a placeholder and remember it so it can be inserted // when the function is parsed. BB = BasicBlock::Create(Context); - BasicBlockFwdRefs[Fn].emplace_back(BBID, BB); + auto &FwdBBs = BasicBlockFwdRefs[Fn]; + if (FwdBBs.empty()) + BasicBlockFwdRefQueue.push_back(Fn); + FwdBBs.emplace_back(BBID, BB); } V = BlockAddress::get(Fn, BB); break; |