@@ -352,6 +352,27 @@ 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+ GV->eraseFromParent ();
365+ auto NonFuncBegin =
366+ std::stable_partition (Vec.begin (), Vec.end (), [](GlobalValue *GV) {
367+ return isa<Function>(GV);
368+ });
369+ if (CompilerUsed)
370+ appendToCompilerUsed (M, {NonFuncBegin, Vec.end ()});
371+ else
372+ appendToUsed (M, {NonFuncBegin, Vec.end ()});
373+ Vec.resize (NonFuncBegin - Vec.begin ());
374+ }
375+
355376 ScopedSaveAliaseesAndUsed (Module &M) : M(M) {
356377 // The users of this class want to replace all function references except
357378 // for aliases and llvm.used/llvm.compiler.used with references to a jump
@@ -365,10 +386,8 @@ struct ScopedSaveAliaseesAndUsed {
365386 // llvm.used/llvm.compiler.used and aliases, erase the used lists, let RAUW
366387 // replace the aliasees and then set them back to their original values at
367388 // the end.
368- if (GlobalVariable *GV = collectUsedGlobalVariables (M, Used, false ))
369- GV->eraseFromParent ();
370- if (GlobalVariable *GV = collectUsedGlobalVariables (M, CompilerUsed, true ))
371- GV->eraseFromParent ();
389+ collectAndEraseUsedFunctions (M, Used, false );
390+ collectAndEraseUsedFunctions (M, CompilerUsed, true );
372391
373392 for (auto &GA : M.aliases ()) {
374393 // FIXME: This should look past all aliases not just interposable ones,
@@ -1669,61 +1688,55 @@ void LowerTypeTestsModule::buildBitSetsFromFunctionsNative(
16691688
16701689 lowerTypeTestCalls (TypeIds, JumpTable, GlobalLayout);
16711690
1672- {
1673- ScopedSaveAliaseesAndUsed S (M);
1691+ // Build aliases pointing to offsets into the jump table, and replace
1692+ // references to the original functions with references to the aliases.
1693+ for (unsigned I = 0 ; I != Functions.size (); ++I) {
1694+ Function *F = cast<Function>(Functions[I]->getGlobal ());
1695+ bool IsJumpTableCanonical = Functions[I]->isJumpTableCanonical ();
16741696
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- }
1697+ Constant *CombinedGlobalElemPtr = ConstantExpr::getInBoundsGetElementPtr (
1698+ JumpTableType, JumpTable,
1699+ ArrayRef<Constant *>{ConstantInt::get (IntPtrTy, 0 ),
1700+ ConstantInt::get (IntPtrTy, I)});
1701+
1702+ const bool IsExported = Functions[I]->isExported ();
1703+ if (!IsJumpTableCanonical) {
1704+ GlobalValue::LinkageTypes LT = IsExported ? GlobalValue::ExternalLinkage
1705+ : GlobalValue::InternalLinkage;
1706+ GlobalAlias *JtAlias = GlobalAlias::create (F->getValueType (), 0 , LT,
1707+ F->getName () + " .cfi_jt" ,
1708+ CombinedGlobalElemPtr, &M);
1709+ if (IsExported)
1710+ JtAlias->setVisibility (GlobalValue::HiddenVisibility);
1711+ else
1712+ appendToUsed (M, {JtAlias});
1713+ }
16991714
1700- if (IsExported) {
1701- if (IsJumpTableCanonical)
1702- ExportSummary->cfiFunctionDefs ().emplace (F->getName ());
1703- else
1704- ExportSummary->cfiFunctionDecls ().emplace (F->getName ());
1705- }
1715+ if (IsExported) {
1716+ if (IsJumpTableCanonical)
1717+ ExportSummary->cfiFunctionDefs ().emplace (F->getName ());
1718+ else
1719+ ExportSummary->cfiFunctionDecls ().emplace (F->getName ());
1720+ }
17061721
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- }
1722+ if (!IsJumpTableCanonical) {
1723+ if (F->hasExternalWeakLinkage ())
1724+ replaceWeakDeclarationWithJumpTablePtr (F, CombinedGlobalElemPtr,
1725+ IsJumpTableCanonical);
1726+ else
1727+ replaceCfiUses (F, CombinedGlobalElemPtr, IsJumpTableCanonical);
1728+ } else {
1729+ assert (F->getType ()->getAddressSpace () == 0 );
1730+
1731+ GlobalAlias *FAlias = GlobalAlias::create (
1732+ F->getValueType (), 0 , F->getLinkage (), " " , CombinedGlobalElemPtr, &M);
1733+ FAlias->setVisibility (F->getVisibility ());
1734+ FAlias->takeName (F);
1735+ if (FAlias->hasName ())
1736+ F->setName (FAlias->getName () + " .cfi" );
1737+ replaceCfiUses (F, FAlias, IsJumpTableCanonical);
1738+ if (!F->hasLocalLinkage ())
1739+ F->setVisibility (GlobalVariable::HiddenVisibility);
17271740 }
17281741 }
17291742
@@ -2339,39 +2352,43 @@ bool LowerTypeTestsModule::lower() {
23392352 if (GlobalClasses.empty ())
23402353 return false ;
23412354
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- });
2355+ {
2356+ ScopedSaveAliaseesAndUsed S (M);
2357+ // For each disjoint set we found...
2358+ for (const auto &C : GlobalClasses) {
2359+ if (!C->isLeader ())
2360+ continue ;
23662361
2367- // Same for the branch funnels.
2368- llvm::sort (ICallBranchFunnels,
2369- [&](ICallBranchFunnel *F1, ICallBranchFunnel *F2) {
2370- return F1->UniqueId < F2->UniqueId ;
2371- });
2362+ ++NumTypeIdDisjointSets;
2363+ // Build the list of type identifiers in this disjoint set.
2364+ std::vector<Metadata *> TypeIds;
2365+ std::vector<GlobalTypeMember *> Globals;
2366+ std::vector<ICallBranchFunnel *> ICallBranchFunnels;
2367+ for (auto M : GlobalClasses.members (*C)) {
2368+ if (isa<Metadata *>(M))
2369+ TypeIds.push_back (cast<Metadata *>(M));
2370+ else if (isa<GlobalTypeMember *>(M))
2371+ Globals.push_back (cast<GlobalTypeMember *>(M));
2372+ else
2373+ ICallBranchFunnels.push_back (cast<ICallBranchFunnel *>(M));
2374+ }
23722375
2373- // Build bitsets for this disjoint set.
2374- buildBitSetsFromDisjointSet (TypeIds, Globals, ICallBranchFunnels);
2376+ // Order type identifiers by unique ID for determinism. This ordering is
2377+ // stable as there is a one-to-one mapping between metadata and unique
2378+ // IDs.
2379+ llvm::sort (TypeIds, [&](Metadata *M1, Metadata *M2) {
2380+ return TypeIdInfo[M1].UniqueId < TypeIdInfo[M2].UniqueId ;
2381+ });
2382+
2383+ // Same for the branch funnels.
2384+ llvm::sort (ICallBranchFunnels,
2385+ [&](ICallBranchFunnel *F1, ICallBranchFunnel *F2) {
2386+ return F1->UniqueId < F2->UniqueId ;
2387+ });
2388+
2389+ // Build bitsets for this disjoint set.
2390+ buildBitSetsFromDisjointSet (TypeIds, Globals, ICallBranchFunnels);
2391+ }
23752392 }
23762393
23772394 allocateByteArrays ();
0 commit comments