@@ -54,7 +54,7 @@ void BoltAddressTranslation::writeEntriesForBB(
5454 // and this deleted block will both share the same output address (the same
5555 // key), and we need to map back. We choose here to privilege the successor by
5656 // allowing it to overwrite the previously inserted key in the map.
57- Map[ BBOutputOffset] = BBInputOffset << 1 ;
57+ Map. emplace ( BBOutputOffset, BBInputOffset << 1 ) ;
5858
5959 const auto &IOAddressMap =
6060 BB.getFunction ()->getBinaryContext ().getIOAddressMap ();
@@ -71,8 +71,7 @@ void BoltAddressTranslation::writeEntriesForBB(
7171
7272 LLVM_DEBUG (dbgs () << " Key: " << Twine::utohexstr (OutputOffset) << " Val: "
7373 << Twine::utohexstr (InputOffset) << " (branch)\n " );
74- Map.insert (std::pair<uint32_t , uint32_t >(OutputOffset,
75- (InputOffset << 1 ) | BRANCHENTRY));
74+ Map.emplace (OutputOffset, (InputOffset << 1 ) | BRANCHENTRY);
7675 }
7776}
7877
@@ -107,6 +106,19 @@ void BoltAddressTranslation::write(const BinaryContext &BC, raw_ostream &OS) {
107106 for (const BinaryBasicBlock *const BB :
108107 Function.getLayout ().getMainFragment ())
109108 writeEntriesForBB (Map, *BB, InputAddress, OutputAddress);
109+ // Add entries for deleted blocks. They are still required for correct BB
110+ // mapping of branches modified by SCTC. By convention, they would have the
111+ // end of the function as output address.
112+ const BBHashMapTy &BBHashMap = getBBHashMap (InputAddress);
113+ if (BBHashMap.size () != Function.size ()) {
114+ const uint64_t EndOffset = Function.getOutputSize ();
115+ std::unordered_set<uint32_t > MappedInputOffsets;
116+ for (const BinaryBasicBlock &BB : Function)
117+ MappedInputOffsets.emplace (BB.getInputOffset ());
118+ for (const auto &[InputOffset, _] : BBHashMap)
119+ if (!llvm::is_contained (MappedInputOffsets, InputOffset))
120+ Map.emplace (EndOffset, InputOffset << 1 );
121+ }
110122 Maps.emplace (Function.getOutputAddress (), std::move (Map));
111123 ReverseMap.emplace (OutputAddress, InputAddress);
112124
0 commit comments