Skip to content

Commit 3e2a5ba

Browse files
committed
[𝘀𝗽𝗿] initial version
Created using spr 1.3.6-beta.1
1 parent 58c3fba commit 3e2a5ba

File tree

1 file changed

+104
-87
lines changed

1 file changed

+104
-87
lines changed

llvm/lib/Transforms/IPO/LowerTypeTests.cpp

Lines changed: 104 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)