@@ -352,6 +352,30 @@ struct ScopedSaveAliaseesAndUsed {
352
352
std::vector<std::pair<GlobalAlias *, Function *>> FunctionAliases;
353
353
std::vector<std::pair<GlobalIFunc *, Function *>> ResolverIFuncs;
354
354
355
+ // This function only removes functions from llvm.used and llvm.compiler.used.
356
+ // We cannot remove global variables because they need to follow RAUW, as
357
+ // they may be deleted by buildBitSetsFromGlobalVariables.
358
+ void collectAndEraseUsedFunctions (Module &M,
359
+ SmallVectorImpl<GlobalValue *> &Vec,
360
+ bool CompilerUsed) {
361
+ auto *GV = collectUsedGlobalVariables (M, Vec, CompilerUsed);
362
+ if (!GV)
363
+ return ;
364
+ // There's no API to only remove certain array elements from
365
+ // llvm.used/llvm.compiler.used, so we remove all of them and add back only
366
+ // the non-functions.
367
+ GV->eraseFromParent ();
368
+ auto NonFuncBegin =
369
+ std::stable_partition (Vec.begin (), Vec.end (), [](GlobalValue *GV) {
370
+ return isa<Function>(GV);
371
+ });
372
+ if (CompilerUsed)
373
+ appendToCompilerUsed (M, {NonFuncBegin, Vec.end ()});
374
+ else
375
+ appendToUsed (M, {NonFuncBegin, Vec.end ()});
376
+ Vec.resize (NonFuncBegin - Vec.begin ());
377
+ }
378
+
355
379
ScopedSaveAliaseesAndUsed (Module &M) : M(M) {
356
380
// The users of this class want to replace all function references except
357
381
// for aliases and llvm.used/llvm.compiler.used with references to a jump
@@ -365,10 +389,8 @@ struct ScopedSaveAliaseesAndUsed {
365
389
// llvm.used/llvm.compiler.used and aliases, erase the used lists, let RAUW
366
390
// replace the aliasees and then set them back to their original values at
367
391
// the end.
368
- if (GlobalVariable *GV = collectUsedGlobalVariables (M, Used, false ))
369
- GV->eraseFromParent ();
370
- if (GlobalVariable *GV = collectUsedGlobalVariables (M, CompilerUsed, true ))
371
- GV->eraseFromParent ();
392
+ collectAndEraseUsedFunctions (M, Used, false );
393
+ collectAndEraseUsedFunctions (M, CompilerUsed, true );
372
394
373
395
for (auto &GA : M.aliases ()) {
374
396
// FIXME: This should look past all aliases not just interposable ones,
@@ -1669,61 +1691,55 @@ void LowerTypeTestsModule::buildBitSetsFromFunctionsNative(
1669
1691
1670
1692
lowerTypeTestCalls (TypeIds, JumpTable, GlobalLayout);
1671
1693
1672
- {
1673
- ScopedSaveAliaseesAndUsed S (M);
1694
+ // Build aliases pointing to offsets into the jump table, and replace
1695
+ // references to the original functions with references to the aliases.
1696
+ for (unsigned I = 0 ; I != Functions.size (); ++I) {
1697
+ Function *F = cast<Function>(Functions[I]->getGlobal ());
1698
+ bool IsJumpTableCanonical = Functions[I]->isJumpTableCanonical ();
1674
1699
1675
- // Build aliases pointing to offsets into the jump table, and replace
1676
- // references to the original functions with references to the aliases.
1677
- for (unsigned I = 0 ; I != Functions.size (); ++I) {
1678
- Function *F = cast<Function>(Functions[I]->getGlobal ());
1679
- bool IsJumpTableCanonical = Functions[I]->isJumpTableCanonical ();
1680
-
1681
- Constant *CombinedGlobalElemPtr = ConstantExpr::getInBoundsGetElementPtr (
1682
- JumpTableType, JumpTable,
1683
- ArrayRef<Constant *>{ConstantInt::get (IntPtrTy, 0 ),
1684
- ConstantInt::get (IntPtrTy, I)});
1685
-
1686
- const bool IsExported = Functions[I]->isExported ();
1687
- if (!IsJumpTableCanonical) {
1688
- GlobalValue::LinkageTypes LT = IsExported
1689
- ? GlobalValue::ExternalLinkage
1690
- : GlobalValue::InternalLinkage;
1691
- GlobalAlias *JtAlias = GlobalAlias::create (F->getValueType (), 0 , LT,
1692
- F->getName () + " .cfi_jt" ,
1693
- CombinedGlobalElemPtr, &M);
1694
- if (IsExported)
1695
- JtAlias->setVisibility (GlobalValue::HiddenVisibility);
1696
- else
1697
- appendToUsed (M, {JtAlias});
1698
- }
1700
+ Constant *CombinedGlobalElemPtr = ConstantExpr::getInBoundsGetElementPtr (
1701
+ JumpTableType, JumpTable,
1702
+ ArrayRef<Constant *>{ConstantInt::get (IntPtrTy, 0 ),
1703
+ ConstantInt::get (IntPtrTy, I)});
1704
+
1705
+ const bool IsExported = Functions[I]->isExported ();
1706
+ if (!IsJumpTableCanonical) {
1707
+ GlobalValue::LinkageTypes LT = IsExported ? GlobalValue::ExternalLinkage
1708
+ : GlobalValue::InternalLinkage;
1709
+ GlobalAlias *JtAlias = GlobalAlias::create (F->getValueType (), 0 , LT,
1710
+ F->getName () + " .cfi_jt" ,
1711
+ CombinedGlobalElemPtr, &M);
1712
+ if (IsExported)
1713
+ JtAlias->setVisibility (GlobalValue::HiddenVisibility);
1714
+ else
1715
+ appendToUsed (M, {JtAlias});
1716
+ }
1699
1717
1700
- if (IsExported) {
1701
- if (IsJumpTableCanonical)
1702
- ExportSummary->cfiFunctionDefs ().emplace (F->getName ());
1703
- else
1704
- ExportSummary->cfiFunctionDecls ().emplace (F->getName ());
1705
- }
1718
+ if (IsExported) {
1719
+ if (IsJumpTableCanonical)
1720
+ ExportSummary->cfiFunctionDefs ().emplace (F->getName ());
1721
+ else
1722
+ ExportSummary->cfiFunctionDecls ().emplace (F->getName ());
1723
+ }
1706
1724
1707
- if (!IsJumpTableCanonical) {
1708
- if (F->hasExternalWeakLinkage ())
1709
- replaceWeakDeclarationWithJumpTablePtr (F, CombinedGlobalElemPtr,
1710
- IsJumpTableCanonical);
1711
- else
1712
- replaceCfiUses (F, CombinedGlobalElemPtr, IsJumpTableCanonical);
1713
- } else {
1714
- assert (F->getType ()->getAddressSpace () == 0 );
1715
-
1716
- GlobalAlias *FAlias =
1717
- GlobalAlias::create (F->getValueType (), 0 , F->getLinkage (), " " ,
1718
- CombinedGlobalElemPtr, &M);
1719
- FAlias->setVisibility (F->getVisibility ());
1720
- FAlias->takeName (F);
1721
- if (FAlias->hasName ())
1722
- F->setName (FAlias->getName () + " .cfi" );
1723
- replaceCfiUses (F, FAlias, IsJumpTableCanonical);
1724
- if (!F->hasLocalLinkage ())
1725
- F->setVisibility (GlobalVariable::HiddenVisibility);
1726
- }
1725
+ if (!IsJumpTableCanonical) {
1726
+ if (F->hasExternalWeakLinkage ())
1727
+ replaceWeakDeclarationWithJumpTablePtr (F, CombinedGlobalElemPtr,
1728
+ IsJumpTableCanonical);
1729
+ else
1730
+ replaceCfiUses (F, CombinedGlobalElemPtr, IsJumpTableCanonical);
1731
+ } else {
1732
+ assert (F->getType ()->getAddressSpace () == 0 );
1733
+
1734
+ GlobalAlias *FAlias = GlobalAlias::create (
1735
+ F->getValueType (), 0 , F->getLinkage (), " " , CombinedGlobalElemPtr, &M);
1736
+ FAlias->setVisibility (F->getVisibility ());
1737
+ FAlias->takeName (F);
1738
+ if (FAlias->hasName ())
1739
+ F->setName (FAlias->getName () + " .cfi" );
1740
+ replaceCfiUses (F, FAlias, IsJumpTableCanonical);
1741
+ if (!F->hasLocalLinkage ())
1742
+ F->setVisibility (GlobalVariable::HiddenVisibility);
1727
1743
}
1728
1744
}
1729
1745
@@ -2339,39 +2355,43 @@ bool LowerTypeTestsModule::lower() {
2339
2355
if (GlobalClasses.empty ())
2340
2356
return false ;
2341
2357
2342
- // For each disjoint set we found...
2343
- for (const auto &C : GlobalClasses) {
2344
- if (!C->isLeader ())
2345
- continue ;
2346
-
2347
- ++NumTypeIdDisjointSets;
2348
- // Build the list of type identifiers in this disjoint set.
2349
- std::vector<Metadata *> TypeIds;
2350
- std::vector<GlobalTypeMember *> Globals;
2351
- std::vector<ICallBranchFunnel *> ICallBranchFunnels;
2352
- for (auto M : GlobalClasses.members (*C)) {
2353
- if (isa<Metadata *>(M))
2354
- TypeIds.push_back (cast<Metadata *>(M));
2355
- else if (isa<GlobalTypeMember *>(M))
2356
- Globals.push_back (cast<GlobalTypeMember *>(M));
2357
- else
2358
- ICallBranchFunnels.push_back (cast<ICallBranchFunnel *>(M));
2359
- }
2360
-
2361
- // Order type identifiers by unique ID for determinism. This ordering is
2362
- // stable as there is a one-to-one mapping between metadata and unique IDs.
2363
- llvm::sort (TypeIds, [&](Metadata *M1, Metadata *M2) {
2364
- return TypeIdInfo[M1].UniqueId < TypeIdInfo[M2].UniqueId ;
2365
- });
2358
+ {
2359
+ ScopedSaveAliaseesAndUsed S (M);
2360
+ // For each disjoint set we found...
2361
+ for (const auto &C : GlobalClasses) {
2362
+ if (!C->isLeader ())
2363
+ continue ;
2366
2364
2367
- // Same for the branch funnels.
2368
- llvm::sort (ICallBranchFunnels,
2369
- [&](ICallBranchFunnel *F1, ICallBranchFunnel *F2) {
2370
- return F1->UniqueId < F2->UniqueId ;
2371
- });
2365
+ ++NumTypeIdDisjointSets;
2366
+ // Build the list of type identifiers in this disjoint set.
2367
+ std::vector<Metadata *> TypeIds;
2368
+ std::vector<GlobalTypeMember *> Globals;
2369
+ std::vector<ICallBranchFunnel *> ICallBranchFunnels;
2370
+ for (auto M : GlobalClasses.members (*C)) {
2371
+ if (isa<Metadata *>(M))
2372
+ TypeIds.push_back (cast<Metadata *>(M));
2373
+ else if (isa<GlobalTypeMember *>(M))
2374
+ Globals.push_back (cast<GlobalTypeMember *>(M));
2375
+ else
2376
+ ICallBranchFunnels.push_back (cast<ICallBranchFunnel *>(M));
2377
+ }
2372
2378
2373
- // Build bitsets for this disjoint set.
2374
- buildBitSetsFromDisjointSet (TypeIds, Globals, ICallBranchFunnels);
2379
+ // Order type identifiers by unique ID for determinism. This ordering is
2380
+ // stable as there is a one-to-one mapping between metadata and unique
2381
+ // IDs.
2382
+ llvm::sort (TypeIds, [&](Metadata *M1, Metadata *M2) {
2383
+ return TypeIdInfo[M1].UniqueId < TypeIdInfo[M2].UniqueId ;
2384
+ });
2385
+
2386
+ // Same for the branch funnels.
2387
+ llvm::sort (ICallBranchFunnels,
2388
+ [&](ICallBranchFunnel *F1, ICallBranchFunnel *F2) {
2389
+ return F1->UniqueId < F2->UniqueId ;
2390
+ });
2391
+
2392
+ // Build bitsets for this disjoint set.
2393
+ buildBitSetsFromDisjointSet (TypeIds, Globals, ICallBranchFunnels);
2394
+ }
2375
2395
}
2376
2396
2377
2397
allocateByteArrays ();
0 commit comments