@@ -153,6 +153,178 @@ static gcp_map_type &getGCMap(void *&P) {
153
153
return *(gcp_map_type*)P;
154
154
}
155
155
156
+ namespace {
157
+ class AddrLabelMapCallbackPtr final : CallbackVH {
158
+ AddrLabelMap *Map = nullptr ;
159
+
160
+ public:
161
+ AddrLabelMapCallbackPtr () = default ;
162
+ AddrLabelMapCallbackPtr (Value *V) : CallbackVH(V) {}
163
+
164
+ void setPtr (BasicBlock *BB) {
165
+ ValueHandleBase::operator =(BB);
166
+ }
167
+
168
+ void setMap (AddrLabelMap *map) { Map = map; }
169
+
170
+ void deleted () override ;
171
+ void allUsesReplacedWith (Value *V2) override ;
172
+ };
173
+ } // namespace
174
+
175
+ class llvm ::AddrLabelMap {
176
+ MCContext &Context;
177
+ struct AddrLabelSymEntry {
178
+ // / The symbols for the label.
179
+ TinyPtrVector<MCSymbol *> Symbols;
180
+
181
+ Function *Fn; // The containing function of the BasicBlock.
182
+ unsigned Index; // The index in BBCallbacks for the BasicBlock.
183
+ };
184
+
185
+ DenseMap<AssertingVH<BasicBlock>, AddrLabelSymEntry> AddrLabelSymbols;
186
+
187
+ // / Callbacks for the BasicBlock's that we have entries for. We use this so
188
+ // / we get notified if a block is deleted or RAUWd.
189
+ std::vector<AddrLabelMapCallbackPtr> BBCallbacks;
190
+
191
+ // / This is a per-function list of symbols whose corresponding BasicBlock got
192
+ // / deleted. These symbols need to be emitted at some point in the file, so
193
+ // / AsmPrinter emits them after the function body.
194
+ DenseMap<AssertingVH<Function>, std::vector<MCSymbol *>>
195
+ DeletedAddrLabelsNeedingEmission;
196
+
197
+ public:
198
+ AddrLabelMap (MCContext &context) : Context(context) {}
199
+
200
+ ~AddrLabelMap () {
201
+ assert (DeletedAddrLabelsNeedingEmission.empty () &&
202
+ " Some labels for deleted blocks never got emitted" );
203
+ }
204
+
205
+ ArrayRef<MCSymbol *> getAddrLabelSymbolToEmit (BasicBlock *BB);
206
+
207
+ void takeDeletedSymbolsForFunction (Function *F,
208
+ std::vector<MCSymbol *> &Result);
209
+
210
+ void UpdateForDeletedBlock (BasicBlock *BB);
211
+ void UpdateForRAUWBlock (BasicBlock *Old, BasicBlock *New);
212
+ };
213
+
214
+ ArrayRef<MCSymbol *> AddrLabelMap::getAddrLabelSymbolToEmit (BasicBlock *BB) {
215
+ assert (BB->hasAddressTaken () &&
216
+ " Shouldn't get label for block without address taken" );
217
+ AddrLabelSymEntry &Entry = AddrLabelSymbols[BB];
218
+
219
+ // If we already had an entry for this block, just return it.
220
+ if (!Entry.Symbols .empty ()) {
221
+ assert (BB->getParent () == Entry.Fn && " Parent changed" );
222
+ return Entry.Symbols ;
223
+ }
224
+
225
+ // Otherwise, this is a new entry, create a new symbol for it and add an
226
+ // entry to BBCallbacks so we can be notified if the BB is deleted or RAUWd.
227
+ BBCallbacks.emplace_back (BB);
228
+ BBCallbacks.back ().setMap (this );
229
+ Entry.Index = BBCallbacks.size () - 1 ;
230
+ Entry.Fn = BB->getParent ();
231
+ MCSymbol *Sym = BB->hasAddressTaken () ? Context.createNamedTempSymbol ()
232
+ : Context.createTempSymbol ();
233
+ Entry.Symbols .push_back (Sym);
234
+ return Entry.Symbols ;
235
+ }
236
+
237
+ // / If we have any deleted symbols for F, return them.
238
+ void AddrLabelMap::takeDeletedSymbolsForFunction (
239
+ Function *F, std::vector<MCSymbol *> &Result) {
240
+ DenseMap<AssertingVH<Function>, std::vector<MCSymbol *>>::iterator I =
241
+ DeletedAddrLabelsNeedingEmission.find (F);
242
+
243
+ // If there are no entries for the function, just return.
244
+ if (I == DeletedAddrLabelsNeedingEmission.end ())
245
+ return ;
246
+
247
+ // Otherwise, take the list.
248
+ std::swap (Result, I->second );
249
+ DeletedAddrLabelsNeedingEmission.erase (I);
250
+ }
251
+
252
+ // ===- Address of Block Management ----------------------------------------===//
253
+
254
+ ArrayRef<MCSymbol *>
255
+ AsmPrinter::getAddrLabelSymbolToEmit (const BasicBlock *BB) {
256
+ // Lazily create AddrLabelSymbols.
257
+ if (!AddrLabelSymbols)
258
+ AddrLabelSymbols = std::make_unique<AddrLabelMap>(OutContext);
259
+ return AddrLabelSymbols->getAddrLabelSymbolToEmit (
260
+ const_cast <BasicBlock *>(BB));
261
+ }
262
+
263
+ void AsmPrinter::takeDeletedSymbolsForFunction (
264
+ const Function *F, std::vector<MCSymbol *> &Result) {
265
+ // If no blocks have had their addresses taken, we're done.
266
+ if (!AddrLabelSymbols)
267
+ return ;
268
+ return AddrLabelSymbols->takeDeletedSymbolsForFunction (
269
+ const_cast <Function *>(F), Result);
270
+ }
271
+
272
+ void AddrLabelMap::UpdateForDeletedBlock (BasicBlock *BB) {
273
+ // If the block got deleted, there is no need for the symbol. If the symbol
274
+ // was already emitted, we can just forget about it, otherwise we need to
275
+ // queue it up for later emission when the function is output.
276
+ AddrLabelSymEntry Entry = std::move (AddrLabelSymbols[BB]);
277
+ AddrLabelSymbols.erase (BB);
278
+ assert (!Entry.Symbols .empty () && " Didn't have a symbol, why a callback?" );
279
+ BBCallbacks[Entry.Index ] = nullptr ; // Clear the callback.
280
+
281
+ #if !LLVM_MEMORY_SANITIZER_BUILD
282
+ // BasicBlock is destroyed already, so this access is UB detectable by msan.
283
+ assert ((BB->getParent () == nullptr || BB->getParent () == Entry.Fn ) &&
284
+ " Block/parent mismatch" );
285
+ #endif
286
+
287
+ for (MCSymbol *Sym : Entry.Symbols ) {
288
+ if (Sym->isDefined ())
289
+ return ;
290
+
291
+ // If the block is not yet defined, we need to emit it at the end of the
292
+ // function. Add the symbol to the DeletedAddrLabelsNeedingEmission list
293
+ // for the containing Function. Since the block is being deleted, its
294
+ // parent may already be removed, we have to get the function from 'Entry'.
295
+ DeletedAddrLabelsNeedingEmission[Entry.Fn ].push_back (Sym);
296
+ }
297
+ }
298
+
299
+ void AddrLabelMap::UpdateForRAUWBlock (BasicBlock *Old, BasicBlock *New) {
300
+ // Get the entry for the RAUW'd block and remove it from our map.
301
+ AddrLabelSymEntry OldEntry = std::move (AddrLabelSymbols[Old]);
302
+ AddrLabelSymbols.erase (Old);
303
+ assert (!OldEntry.Symbols .empty () && " Didn't have a symbol, why a callback?" );
304
+
305
+ AddrLabelSymEntry &NewEntry = AddrLabelSymbols[New];
306
+
307
+ // If New is not address taken, just move our symbol over to it.
308
+ if (NewEntry.Symbols .empty ()) {
309
+ BBCallbacks[OldEntry.Index ].setPtr (New); // Update the callback.
310
+ NewEntry = std::move (OldEntry); // Set New's entry.
311
+ return ;
312
+ }
313
+
314
+ BBCallbacks[OldEntry.Index ] = nullptr ; // Update the callback.
315
+
316
+ // Otherwise, we need to add the old symbols to the new block's set.
317
+ llvm::append_range (NewEntry.Symbols , OldEntry.Symbols );
318
+ }
319
+
320
+ void AddrLabelMapCallbackPtr::deleted () {
321
+ Map->UpdateForDeletedBlock (cast<BasicBlock>(getValPtr ()));
322
+ }
323
+
324
+ void AddrLabelMapCallbackPtr::allUsesReplacedWith (Value *V2) {
325
+ Map->UpdateForRAUWBlock (cast<BasicBlock>(getValPtr ()), cast<BasicBlock>(V2));
326
+ }
327
+
156
328
// / getGVAlignment - Return the alignment to use for the specified global
157
329
// / value. This rounds up to the preferred alignment if possible and legal.
158
330
Align AsmPrinter::getGVAlignment (const GlobalObject *GV, const DataLayout &DL,
@@ -260,6 +432,8 @@ bool AsmPrinter::doInitialization(Module &M) {
260
432
HasSplitStack = false ;
261
433
HasNoSplitStack = false ;
262
434
435
+ AddrLabelSymbols = nullptr ;
436
+
263
437
// Initialize TargetLoweringObjectFile.
264
438
const_cast <TargetLoweringObjectFile&>(getObjFileLowering ())
265
439
.Initialize (OutContext, TM);
@@ -802,7 +976,7 @@ void AsmPrinter::emitFunctionHeader() {
802
976
// references to the dangling symbols. Emit them at the start of the function
803
977
// so that we don't get references to undefined symbols.
804
978
std::vector<MCSymbol*> DeadBlockSyms;
805
- MMI-> takeDeletedSymbolsForFunction (&F, DeadBlockSyms);
979
+ takeDeletedSymbolsForFunction (&F, DeadBlockSyms);
806
980
for (MCSymbol *DeadBlockSym : DeadBlockSyms) {
807
981
OutStreamer->AddComment (" Address taken block that was later removed" );
808
982
OutStreamer->emitLabel (DeadBlockSym);
@@ -1956,6 +2130,7 @@ bool AsmPrinter::doFinalization(Module &M) {
1956
2130
emitEndOfAsmFile (M);
1957
2131
1958
2132
MMI = nullptr ;
2133
+ AddrLabelSymbols = nullptr ;
1959
2134
1960
2135
OutStreamer->Finish ();
1961
2136
OutStreamer->reset ();
@@ -3140,11 +3315,12 @@ MCSymbol *AsmPrinter::createTempSymbol(const Twine &Name) const {
3140
3315
}
3141
3316
3142
3317
MCSymbol *AsmPrinter::GetBlockAddressSymbol (const BlockAddress *BA) const {
3143
- return MMI->getAddrLabelSymbol (BA->getBasicBlock ());
3318
+ return const_cast <AsmPrinter *>(this )->getAddrLabelSymbol (
3319
+ BA->getBasicBlock ());
3144
3320
}
3145
3321
3146
3322
MCSymbol *AsmPrinter::GetBlockAddressSymbol (const BasicBlock *BB) const {
3147
- return MMI ->getAddrLabelSymbol (BB);
3323
+ return const_cast <AsmPrinter *>( this ) ->getAddrLabelSymbol (BB);
3148
3324
}
3149
3325
3150
3326
// / GetCPISymbol - Return the symbol for the specified constant pool entry.
@@ -3303,7 +3479,7 @@ void AsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) {
3303
3479
// MBBs can have their address taken as part of CodeGen without having
3304
3480
// their corresponding BB's address taken in IR
3305
3481
if (BB && BB->hasAddressTaken ())
3306
- for (MCSymbol *Sym : MMI-> getAddrLabelSymbolToEmit (BB))
3482
+ for (MCSymbol *Sym : getAddrLabelSymbolToEmit (BB))
3307
3483
OutStreamer->emitLabel (Sym);
3308
3484
}
3309
3485
0 commit comments