summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2014-08-16 01:54:37 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2014-08-16 01:54:37 +0000
commit5a5fd7b1b33be5f6c83bf5eda08e0d053805c7da (patch)
treefe562eb63f89242c2f46a3efb8fbd574f6d83a31 /llvm/lib/Bitcode/Reader/BitcodeReader.cpp
parent1318364e3e95a0df24c607b478fab7034580618c (diff)
downloadbcm5719-llvm-5a5fd7b1b33be5f6c83bf5eda08e0d053805c7da.tar.gz
bcm5719-llvm-5a5fd7b1b33be5f6c83bf5eda08e0d053805c7da.zip
BitcodeReader: Only create one basic block for each blockaddress
Block address forward-references are implemented by creating a `BasicBlock` ahead of time that gets inserted in the `Function` when it's eventually encountered. However, if the same blockaddress was used in two separate functions that were parsed *before* the referenced function (and the blockaddress was never used at global scope), two separate basic blocks would get created, one of which would be forgotten creating invalid IR. This commit changes the forward-reference logic to create only one basic block (and always return the same blockaddress). llvm-svn: 215805
Diffstat (limited to 'llvm/lib/Bitcode/Reader/BitcodeReader.cpp')
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp32
1 files changed, 15 insertions, 17 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 66426c83c66..e5dfa723b04 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -1635,11 +1635,14 @@ std::error_code BitcodeReader::ParseConstants() {
} else {
// Otherwise insert a placeholder and remember it so it can be inserted
// when the function is parsed.
- BB = BasicBlock::Create(Context);
auto &FwdBBs = BasicBlockFwdRefs[Fn];
if (FwdBBs.empty())
BasicBlockFwdRefQueue.push_back(Fn);
- FwdBBs.emplace_back(BBID, BB);
+ if (FwdBBs.size() < BBID + 1)
+ FwdBBs.resize(BBID + 1);
+ if (!FwdBBs[BBID])
+ FwdBBs[BBID] = BasicBlock::Create(Context);
+ BB = FwdBBs[BBID];
}
V = BlockAddress::get(Fn, BB);
break;
@@ -2392,24 +2395,19 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
FunctionBBs[i] = BasicBlock::Create(Context, "", F);
} else {
auto &BBRefs = BBFRI->second;
- std::sort(BBRefs.begin(), BBRefs.end(),
- [](const std::pair<unsigned, BasicBlock *> &LHS,
- const std::pair<unsigned, BasicBlock *> &RHS) {
- return LHS.first < RHS.first;
- });
- unsigned R = 0, RE = BBRefs.size();
- for (unsigned I = 0, E = FunctionBBs.size(); I != E; ++I)
- if (R != RE && BBRefs[R].first == I) {
- assert(I != 0 && "Invalid reference to entry block");
- BasicBlock *BB = BBRefs[R++].second;
- BB->insertInto(F);
- FunctionBBs[I] = BB;
+ // Check for invalid basic block references.
+ if (BBRefs.size() > FunctionBBs.size())
+ return Error(BitcodeError::InvalidID);
+ assert(!BBRefs.empty() && "Unexpected empty array");
+ assert(!BBRefs.front() && "Invalid reference to entry block");
+ for (unsigned I = 0, E = FunctionBBs.size(), RE = BBRefs.size(); I != E;
+ ++I)
+ if (I < RE && BBRefs[I]) {
+ BBRefs[I]->insertInto(F);
+ FunctionBBs[I] = BBRefs[I];
} else {
FunctionBBs[I] = BasicBlock::Create(Context, "", F);
}
- // Check for invalid basic block references.
- if (R != RE)
- return Error(BitcodeError::InvalidID);
// Erase from the table.
BasicBlockFwdRefs.erase(BBFRI);
OpenPOWER on IntegriCloud