@@ -352,6 +352,30 @@ struct ScopedSaveAliaseesAndUsed {
352352 std::vector<std::pair<GlobalAlias *, Function *>> FunctionAliases;
353353 std::vector<std::pair<GlobalIFunc *, Function *>> ResolverIFuncs;
354354
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+
355379 ScopedSaveAliaseesAndUsed (Module &M) : M(M) {
356380 // The users of this class want to replace all function references except
357381 // for aliases and llvm.used/llvm.compiler.used with references to a jump
@@ -365,10 +389,8 @@ struct ScopedSaveAliaseesAndUsed {
365389 // llvm.used/llvm.compiler.used and aliases, erase the used lists, let RAUW
366390 // replace the aliasees and then set them back to their original values at
367391 // 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 );
372394
373395 for (auto &GA : M.aliases ()) {
374396 // FIXME: This should look past all aliases not just interposable ones,
@@ -1669,61 +1691,55 @@ void LowerTypeTestsModule::buildBitSetsFromFunctionsNative(
16691691
16701692 lowerTypeTestCalls (TypeIds, JumpTable, GlobalLayout);
16711693
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 ();
16741699
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+ }
16991717
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+ }
17061724
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);
17271743 }
17281744 }
17291745
@@ -2339,39 +2355,43 @@ bool LowerTypeTestsModule::lower() {
23392355 if (GlobalClasses.empty ())
23402356 return false ;
23412357
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 ;
23662364
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+ }
23722378
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+ }
23752395 }
23762396
23772397 allocateByteArrays ();
0 commit comments