@@ -220,10 +220,19 @@ static void addIntrinsicToSummary(
220
220
}
221
221
}
222
222
223
- static void computeFunctionSummary (
224
- ModuleSummaryIndex &Index, const Module &M, const Function &F,
225
- BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI, DominatorTree &DT,
226
- bool HasLocalsInUsedOrAsm, DenseSet<GlobalValue::GUID> &CantBePromoted) {
223
+ static bool isNonVolatileLoad (const Instruction *I) {
224
+ if (const auto *LI = dyn_cast<LoadInst>(I))
225
+ return !LI->isVolatile ();
226
+
227
+ return false ;
228
+ }
229
+
230
+ static void computeFunctionSummary (ModuleSummaryIndex &Index, const Module &M,
231
+ const Function &F, BlockFrequencyInfo *BFI,
232
+ ProfileSummaryInfo *PSI, DominatorTree &DT,
233
+ bool HasLocalsInUsedOrAsm,
234
+ DenseSet<GlobalValue::GUID> &CantBePromoted,
235
+ bool IsThinLTO) {
227
236
// Summary not currently supported for anonymous functions, they should
228
237
// have been named.
229
238
assert (F.hasName ());
@@ -244,13 +253,21 @@ static void computeFunctionSummary(
244
253
// Add personality function, prefix data and prologue data to function's ref
245
254
// list.
246
255
findRefEdges (Index, &F, RefEdges, Visited);
256
+ std::vector<const Instruction *> NonVolatileLoads;
247
257
248
258
bool HasInlineAsmMaybeReferencingInternal = false ;
249
259
for (const BasicBlock &BB : F)
250
260
for (const Instruction &I : BB) {
251
261
if (isa<DbgInfoIntrinsic>(I))
252
262
continue ;
253
263
++NumInsts;
264
+ if (isNonVolatileLoad (&I)) {
265
+ // Postpone processing of non-volatile load instructions
266
+ // See comments below
267
+ Visited.insert (&I);
268
+ NonVolatileLoads.push_back (&I);
269
+ continue ;
270
+ }
254
271
findRefEdges (Index, &I, RefEdges, Visited);
255
272
auto CS = ImmutableCallSite (&I);
256
273
if (!CS)
@@ -340,6 +357,24 @@ static void computeFunctionSummary(
340
357
}
341
358
}
342
359
360
+ // By now we processed all instructions in a function, except
361
+ // non-volatile loads. All new refs we add in a loop below
362
+ // are obviously constant. All constant refs are grouped in the
363
+ // end of RefEdges vector, so we can use a single integer value
364
+ // to identify them.
365
+ unsigned RefCnt = RefEdges.size ();
366
+ for (const Instruction *I : NonVolatileLoads) {
367
+ Visited.erase (I);
368
+ findRefEdges (Index, I, RefEdges, Visited);
369
+ }
370
+ std::vector<ValueInfo> Refs = RefEdges.takeVector ();
371
+ // Regular LTO module doesn't participate in ThinLTO import,
372
+ // so no reference from it can be readonly, since this would
373
+ // require importing variable as local copy
374
+ if (IsThinLTO)
375
+ for (; RefCnt < Refs.size (); ++RefCnt)
376
+ Refs[RefCnt].setReadOnly ();
377
+
343
378
// Explicit add hot edges to enforce importing for designated GUIDs for
344
379
// sample PGO, to enable the same inlines as the profiled optimized binary.
345
380
for (auto &I : F.getImportGUIDs ())
@@ -363,9 +398,9 @@ static void computeFunctionSummary(
363
398
// Don't try to import functions with noinline attribute.
364
399
F.getAttributes ().hasFnAttribute (Attribute::NoInline)};
365
400
auto FuncSummary = llvm::make_unique<FunctionSummary>(
366
- Flags, NumInsts, FunFlags, RefEdges .takeVector (),
367
- CallGraphEdges .takeVector (), TypeTests .takeVector (),
368
- TypeTestAssumeVCalls. takeVector (), TypeCheckedLoadVCalls.takeVector (),
401
+ Flags, NumInsts, FunFlags, std::move (Refs), CallGraphEdges .takeVector (),
402
+ TypeTests .takeVector (), TypeTestAssumeVCalls .takeVector (),
403
+ TypeCheckedLoadVCalls.takeVector (),
369
404
TypeTestAssumeConstVCalls.takeVector (),
370
405
TypeCheckedLoadConstVCalls.takeVector ());
371
406
if (NonRenamableLocal)
@@ -382,8 +417,13 @@ computeVariableSummary(ModuleSummaryIndex &Index, const GlobalVariable &V,
382
417
bool NonRenamableLocal = isNonRenamableLocal (V);
383
418
GlobalValueSummary::GVFlags Flags (V.getLinkage (), NonRenamableLocal,
384
419
/* Live = */ false , V.isDSOLocal ());
385
- auto GVarSummary =
386
- llvm::make_unique<GlobalVarSummary>(Flags, RefEdges.takeVector ());
420
+
421
+ // Don't mark variables we won't be able to internalize as read-only.
422
+ GlobalVarSummary::GVarFlags VarFlags (
423
+ !V.hasComdat () && !V.hasAppendingLinkage () && !V.isInterposable () &&
424
+ !V.hasAvailableExternallyLinkage () && !V.hasDLLExportStorageClass ());
425
+ auto GVarSummary = llvm::make_unique<GlobalVarSummary>(Flags, VarFlags,
426
+ RefEdges.takeVector ());
387
427
if (NonRenamableLocal)
388
428
CantBePromoted.insert (V.getGUID ());
389
429
if (HasBlockAddress)
@@ -487,13 +527,19 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex(
487
527
Index.addGlobalValueSummary (*GV, std::move (Summary));
488
528
} else {
489
529
std::unique_ptr<GlobalVarSummary> Summary =
490
- llvm::make_unique<GlobalVarSummary>(GVFlags,
491
- ArrayRef<ValueInfo>{});
530
+ llvm::make_unique<GlobalVarSummary>(
531
+ GVFlags, GlobalVarSummary::GVarFlags (),
532
+ ArrayRef<ValueInfo>{});
492
533
Index.addGlobalValueSummary (*GV, std::move (Summary));
493
534
}
494
535
});
495
536
}
496
537
538
+ bool IsThinLTO = true ;
539
+ if (auto *MD =
540
+ mdconst::extract_or_null<ConstantInt>(M.getModuleFlag (" ThinLTO" )))
541
+ IsThinLTO = MD->getZExtValue ();
542
+
497
543
// Compute summaries for all functions defined in module, and save in the
498
544
// index.
499
545
for (auto &F : M) {
@@ -514,7 +560,7 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex(
514
560
515
561
computeFunctionSummary (Index, M, F, BFI, PSI, DT,
516
562
!LocalsUsed.empty () || HasLocalInlineAsmSymbol,
517
- CantBePromoted);
563
+ CantBePromoted, IsThinLTO );
518
564
}
519
565
520
566
// Compute summaries for all variables defined in module, and save in the
@@ -545,11 +591,6 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex(
545
591
setLiveRoot (Index, " llvm.global_dtors" );
546
592
setLiveRoot (Index, " llvm.global.annotations" );
547
593
548
- bool IsThinLTO = true ;
549
- if (auto *MD =
550
- mdconst::extract_or_null<ConstantInt>(M.getModuleFlag (" ThinLTO" )))
551
- IsThinLTO = MD->getZExtValue ();
552
-
553
594
for (auto &GlobalList : Index) {
554
595
// Ignore entries for references that are undefined in the current module.
555
596
if (GlobalList.second .SummaryList .empty ())
0 commit comments