Skip to content

Commit 10ee161

Browse files
committed
[𝘀𝗽𝗿] initial version
Created using spr 1.3.6-beta.1
1 parent 20a7902 commit 10ee161

File tree

7 files changed

+156
-102
lines changed

7 files changed

+156
-102
lines changed

llvm/include/llvm/LTO/LTO.h

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -541,20 +541,21 @@ class LTO {
541541
void addModuleToGlobalRes(ArrayRef<InputFile::Symbol> Syms,
542542
ArrayRef<SymbolResolution> Res, unsigned Partition,
543543
bool InSummary);
544-
545-
// These functions take a range of symbol resolutions [ResI, ResE) and consume
546-
// the resolutions used by a single input module by incrementing ResI. After
547-
// these functions return, [ResI, ResE) will refer to the resolution range for
548-
// the remaining modules in the InputFile.
549544
Error addModule(InputFile &Input, unsigned ModI,
550-
const SymbolResolution *&ResI, const SymbolResolution *ResE);
545+
const SymbolResolution *&ResI,
546+
ArrayRef<SymbolResolution> Res);
551547

552548
Expected<RegularLTOState::AddedModule>
553-
addRegularLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms,
554-
const SymbolResolution *&ResI, const SymbolResolution *ResE);
549+
addRegularLTO(InputFile &Input, BitcodeModule BM,
550+
ArrayRef<InputFile::Symbol> Syms, const SymbolResolution *&ResI,
551+
ArrayRef<SymbolResolution> Res);
555552
Error linkRegularLTO(RegularLTOState::AddedModule Mod,
556553
bool LivenessFromIndex);
557554

555+
// This function takes a range of symbol resolutions [ResI, ResE) and consume
556+
// the resolutions used by a single input module by incrementing ResI. After
557+
// these functions return, [ResI, ResE) will refer to the resolution range for
558+
// the remaining modules in the InputFile.
558559
Error addThinLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms,
559560
const SymbolResolution *&ResI, const SymbolResolution *ResE);
560561

llvm/lib/LTO/LTO.cpp

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -744,7 +744,7 @@ Error LTO::add(std::unique_ptr<InputFile> Input,
744744

745745
const SymbolResolution *ResI = Res.begin();
746746
for (unsigned I = 0; I != Input->Mods.size(); ++I)
747-
if (Error Err = addModule(*Input, I, ResI, Res.end()))
747+
if (Error Err = addModule(*Input, I, ResI, Res))
748748
return Err;
749749

750750
assert(ResI == Res.end());
@@ -753,7 +753,7 @@ Error LTO::add(std::unique_ptr<InputFile> Input,
753753

754754
Error LTO::addModule(InputFile &Input, unsigned ModI,
755755
const SymbolResolution *&ResI,
756-
const SymbolResolution *ResE) {
756+
ArrayRef<SymbolResolution> Res) {
757757
Expected<BitcodeLTOInfo> LTOInfo = Input.Mods[ModI].getLTOInfo();
758758
if (!LTOInfo)
759759
return LTOInfo.takeError();
@@ -782,16 +782,16 @@ Error LTO::addModule(InputFile &Input, unsigned ModI,
782782
bool IsThinLTO = LTOInfo->IsThinLTO && (LTOMode != LTOK_UnifiedRegular);
783783

784784
auto ModSyms = Input.module_symbols(ModI);
785-
addModuleToGlobalRes(ModSyms, {ResI, ResE},
785+
addModuleToGlobalRes(ModSyms, {ResI, Res.end()},
786786
IsThinLTO ? ThinLTO.ModuleMap.size() + 1 : 0,
787787
LTOInfo->HasSummary);
788788

789789
if (IsThinLTO)
790-
return addThinLTO(BM, ModSyms, ResI, ResE);
790+
return addThinLTO(BM, ModSyms, ResI, Res.end());
791791

792792
RegularLTO.EmptyCombinedModule = false;
793793
Expected<RegularLTOState::AddedModule> ModOrErr =
794-
addRegularLTO(BM, ModSyms, ResI, ResE);
794+
addRegularLTO(Input, BM, ModSyms, ResI, Res);
795795
if (!ModOrErr)
796796
return ModOrErr.takeError();
797797

@@ -839,10 +839,9 @@ handleNonPrevailingComdat(GlobalValue &GV,
839839
// Add a regular LTO object to the link.
840840
// The resulting module needs to be linked into the combined LTO module with
841841
// linkRegularLTO.
842-
Expected<LTO::RegularLTOState::AddedModule>
843-
LTO::addRegularLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms,
844-
const SymbolResolution *&ResI,
845-
const SymbolResolution *ResE) {
842+
Expected<LTO::RegularLTOState::AddedModule> LTO::addRegularLTO(
843+
InputFile &Input, BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms,
844+
const SymbolResolution *&ResI, ArrayRef<SymbolResolution> Res) {
846845
RegularLTOState::AddedModule Mod;
847846
Expected<std::unique_ptr<Module>> MOrErr =
848847
BM.getLazyModule(RegularLTO.Ctx, /*ShouldLazyLoadMetadata*/ true,
@@ -855,13 +854,34 @@ LTO::addRegularLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms,
855854
if (Error Err = M.materializeMetadata())
856855
return std::move(Err);
857856

858-
// If cfi.functions is present and we are in regular LTO mode, LowerTypeTests
859-
// will rename local functions in the merged module as "<function name>.1".
860-
// This causes linking errors, since other parts of the module expect the
861-
// original function name.
862-
if (LTOMode == LTOK_UnifiedRegular)
857+
if (LTOMode == LTOK_UnifiedRegular) {
858+
// cfi.functions metadata is intended to be used with ThinLTO and may
859+
// trigger invalid IR transformations if they are present when doing regular
860+
// LTO, so delete it.
863861
if (NamedMDNode *CfiFunctionsMD = M.getNamedMetadata("cfi.functions"))
864862
M.eraseNamedMetadata(CfiFunctionsMD);
863+
} else if (NamedMDNode *AliasesMD = M.getNamedMetadata("aliases")) {
864+
// Delete aliases entries for non-prevailing symbols on the ThinLTO side of
865+
// this input file.
866+
std::set<StringRef> Prevailing;
867+
for (auto P : zip(Input.symbols(), Res))
868+
if (std::get<1>(P).Prevailing && !std::get<0>(P).getIRName().empty())
869+
Prevailing.insert(std::get<0>(P).getIRName());
870+
std::vector<MDNode *> AliasGroups;
871+
for (MDNode *AliasGroup : AliasesMD->operands()) {
872+
std::vector<Metadata *> Aliases;
873+
for (Metadata *Alias : AliasGroup->operands()) {
874+
if (isa<MDString>(Alias) &&
875+
Prevailing.count(cast<MDString>(Alias)->getString()))
876+
Aliases.push_back(Alias);
877+
}
878+
if (Aliases.size() > 1)
879+
AliasGroups.push_back(MDTuple::get(RegularLTO.Ctx, Aliases));
880+
}
881+
AliasesMD->clearOperands();
882+
for (MDNode *G : AliasGroups)
883+
AliasesMD->addOperand(G);
884+
}
865885

866886
UpgradeDebugInfo(M);
867887

@@ -899,7 +919,7 @@ LTO::addRegularLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms,
899919
std::set<const Comdat *> NonPrevailingComdats;
900920
SmallSet<StringRef, 2> NonPrevailingAsmSymbols;
901921
for (const InputFile::Symbol &Sym : Syms) {
902-
assert(ResI != ResE);
922+
assert(ResI != Res.end());
903923
SymbolResolution Res = *ResI++;
904924

905925
assert(MsymI != MsymE);

llvm/lib/Transforms/IPO/LowerTypeTests.cpp

Lines changed: 71 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ struct ICallBranchFunnel final
349349

350350
struct ScopedSaveAliaseesAndUsed {
351351
Module &M;
352+
std::set<GlobalAlias *> *ExcludedAliases;
352353
SmallVector<GlobalValue *, 4> Used, CompilerUsed;
353354
std::vector<std::pair<GlobalAlias *, Function *>> FunctionAliases;
354355
std::vector<std::pair<GlobalIFunc *, Function *>> ResolverIFuncs;
@@ -377,7 +378,9 @@ struct ScopedSaveAliaseesAndUsed {
377378
Vec.resize(NonFuncBegin - Vec.begin());
378379
}
379380

380-
ScopedSaveAliaseesAndUsed(Module &M) : M(M) {
381+
ScopedSaveAliaseesAndUsed(Module &M,
382+
std::set<GlobalAlias *> *ExcludedAliases = nullptr)
383+
: M(M), ExcludedAliases(ExcludedAliases) {
381384
// The users of this class want to replace all function references except
382385
// for aliases and llvm.used/llvm.compiler.used with references to a jump
383386
// table. We avoid replacing aliases in order to avoid introducing a double
@@ -396,8 +399,9 @@ struct ScopedSaveAliaseesAndUsed {
396399
for (auto &GA : M.aliases()) {
397400
// FIXME: This should look past all aliases not just interposable ones,
398401
// see discussion on D65118.
399-
if (auto *F = dyn_cast<Function>(GA.getAliasee()->stripPointerCasts()))
400-
FunctionAliases.push_back({&GA, F});
402+
if (!ExcludedAliases || !ExcludedAliases->count(&GA))
403+
if (auto *F = dyn_cast<Function>(GA.getAliasee()->stripPointerCasts()))
404+
FunctionAliases.push_back({&GA, F});
401405
}
402406

403407
for (auto &GI : M.ifuncs())
@@ -2137,6 +2141,18 @@ bool LowerTypeTestsModule::lower() {
21372141
if (auto Alias = dyn_cast<AliasSummary>(RefGVS.get()))
21382142
AddressTaken.insert(Alias->getAliaseeGUID());
21392143
}
2144+
auto IsAddressTaken = [&](GlobalValue::GUID GUID) {
2145+
if (AddressTaken.count(GUID))
2146+
return true;
2147+
auto VI = ExportSummary->getValueInfo(GUID);
2148+
if (!VI)
2149+
return false;
2150+
for (auto &I : VI.getSummaryList())
2151+
if (auto Alias = dyn_cast<AliasSummary>(I.get()))
2152+
if (AddressTaken.count(Alias->getAliaseeGUID()))
2153+
return true;
2154+
return false;
2155+
};
21402156
for (auto *FuncMD : CfiFunctionsMD->operands()) {
21412157
assert(FuncMD->getNumOperands() >= 2);
21422158
StringRef FunctionName =
@@ -2153,7 +2169,7 @@ bool LowerTypeTestsModule::lower() {
21532169
// have no live references (and are not exported with cross-DSO CFI.)
21542170
if (!ExportSummary->isGUIDLive(GUID))
21552171
continue;
2156-
if (!AddressTaken.count(GUID)) {
2172+
if (!IsAddressTaken(GUID)) {
21572173
if (!CrossDsoCfi || Linkage != CFL_Definition)
21582174
continue;
21592175

@@ -2227,6 +2243,44 @@ bool LowerTypeTestsModule::lower() {
22272243
}
22282244
}
22292245

2246+
struct AliasToCreate {
2247+
Function *Alias;
2248+
std::string TargetName;
2249+
};
2250+
std::vector<AliasToCreate> AliasesToCreate;
2251+
2252+
// Parse alias data to replace stand-in function declarations for aliases
2253+
// with an alias to the intended target.
2254+
std::set<GlobalAlias *> ExcludedAliases;
2255+
if (ExportSummary) {
2256+
if (NamedMDNode *AliasesMD = M.getNamedMetadata("aliases")) {
2257+
for (auto *AliasMD : AliasesMD->operands()) {
2258+
std::vector<Function *> Aliases;
2259+
for (Metadata *MD : AliasMD->operands()) {
2260+
auto *MDS = dyn_cast<MDString>(MD);
2261+
if (!MDS)
2262+
continue;
2263+
StringRef AliasName = MDS->getString();
2264+
if (!ExportedFunctions.count(AliasName))
2265+
continue;
2266+
auto *AliasF = M.getFunction(AliasName);
2267+
if (AliasF)
2268+
Aliases.push_back(AliasF);
2269+
}
2270+
2271+
if (Aliases.empty())
2272+
continue;
2273+
2274+
for (unsigned I = 1; I != Aliases.size(); ++I) {
2275+
auto *AliasF = Aliases[I];
2276+
ExportedFunctions.erase(AliasF->getName());
2277+
AliasesToCreate.push_back(
2278+
{AliasF, std::string(Aliases[0]->getName())});
2279+
}
2280+
}
2281+
}
2282+
}
2283+
22302284
DenseMap<GlobalObject *, GlobalTypeMember *> GlobalTypeMembers;
22312285
for (GlobalObject &GO : M.global_objects()) {
22322286
if (isa<GlobalVariable>(GO) && GO.isDeclarationForLinker())
@@ -2374,7 +2428,7 @@ bool LowerTypeTestsModule::lower() {
23742428
return false;
23752429

23762430
{
2377-
ScopedSaveAliaseesAndUsed S(M);
2431+
ScopedSaveAliaseesAndUsed S(M, &ExcludedAliases);
23782432
// For each disjoint set we found...
23792433
for (const auto &C : GlobalClasses) {
23802434
if (!C->isLeader())
@@ -2414,49 +2468,18 @@ bool LowerTypeTestsModule::lower() {
24142468

24152469
allocateByteArrays();
24162470

2417-
// Parse alias data to replace stand-in function declarations for aliases
2418-
// with an alias to the intended target.
2419-
if (ExportSummary) {
2420-
if (NamedMDNode *AliasesMD = M.getNamedMetadata("aliases")) {
2421-
for (auto *AliasMD : AliasesMD->operands()) {
2422-
assert(AliasMD->getNumOperands() >= 4);
2423-
StringRef AliasName =
2424-
cast<MDString>(AliasMD->getOperand(0))->getString();
2425-
StringRef Aliasee = cast<MDString>(AliasMD->getOperand(1))->getString();
2426-
2427-
if (auto It = ExportedFunctions.find(Aliasee);
2428-
It == ExportedFunctions.end() ||
2429-
It->second.Linkage != CFL_Definition || !M.getNamedAlias(Aliasee))
2430-
continue;
2431-
2432-
GlobalValue::VisibilityTypes Visibility =
2433-
static_cast<GlobalValue::VisibilityTypes>(
2434-
cast<ConstantAsMetadata>(AliasMD->getOperand(2))
2435-
->getValue()
2436-
->getUniqueInteger()
2437-
.getZExtValue());
2438-
bool Weak =
2439-
static_cast<bool>(cast<ConstantAsMetadata>(AliasMD->getOperand(3))
2440-
->getValue()
2441-
->getUniqueInteger()
2442-
.getZExtValue());
2443-
2444-
auto *Alias = GlobalAlias::create("", M.getNamedAlias(Aliasee));
2445-
Alias->setVisibility(Visibility);
2446-
if (Weak)
2447-
Alias->setLinkage(GlobalValue::WeakAnyLinkage);
2448-
2449-
if (auto *F = M.getFunction(AliasName)) {
2450-
Alias->takeName(F);
2451-
F->replaceAllUsesWith(Alias);
2452-
F->eraseFromParent();
2453-
} else {
2454-
Alias->setName(AliasName);
2455-
}
2456-
}
2457-
}
2458-
}
2459-
2471+
for (auto A : AliasesToCreate) {
2472+
auto *Target = M.getNamedValue(A.TargetName);
2473+
if (!isa<GlobalAlias>(Target))
2474+
continue;
2475+
auto *AliasGA = GlobalAlias::create("", Target);
2476+
AliasGA->setVisibility(A.Alias->getVisibility());
2477+
AliasGA->setLinkage(A.Alias->getLinkage());
2478+
AliasGA->takeName(A.Alias);
2479+
A.Alias->replaceAllUsesWith(AliasGA);
2480+
A.Alias->eraseFromParent();
2481+
}
2482+
24602483
// Emit .symver directives for exported functions, if they exist.
24612484
if (ExportSummary) {
24622485
if (NamedMDNode *SymversMD = M.getNamedMetadata("symvers")) {

llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,10 @@ void splitAndWriteThinLTOBitcode(
384384
for (auto &F : M)
385385
if ((!F.hasLocalLinkage() || F.hasAddressTaken()) && HasTypeMetadata(&F))
386386
CfiFunctions.insert(&F);
387+
for (auto &A : M.aliases())
388+
if (auto *F = dyn_cast<Function>(A.getAliasee()))
389+
if (HasTypeMetadata(F))
390+
CfiFunctions.insert(&A);
387391

388392
// Remove all globals with type metadata, globals with comdats that live in
389393
// MergedM, and aliases pointing to such globals from the thin LTO module.
@@ -403,12 +407,12 @@ void splitAndWriteThinLTOBitcode(
403407
auto &Ctx = MergedM->getContext();
404408
SmallVector<MDNode *, 8> CfiFunctionMDs;
405409
for (auto *V : CfiFunctions) {
406-
Function &F = *cast<Function>(V);
410+
Function &F = *cast<Function>(V->getAliaseeObject());
407411
SmallVector<MDNode *, 2> Types;
408412
F.getMetadata(LLVMContext::MD_type, Types);
409413

410414
SmallVector<Metadata *, 4> Elts;
411-
Elts.push_back(MDString::get(Ctx, F.getName()));
415+
Elts.push_back(MDString::get(Ctx, V->getName()));
412416
CfiFunctionLinkage Linkage;
413417
if (lowertypetests::isJumpTableCanonical(&F))
414418
Linkage = CFL_Definition;
@@ -428,29 +432,24 @@ void splitAndWriteThinLTOBitcode(
428432
NMD->addOperand(MD);
429433
}
430434

431-
SmallVector<MDNode *, 8> FunctionAliases;
435+
MapVector<Function *, std::vector<GlobalAlias *>> FunctionAliases;
432436
for (auto &A : M.aliases()) {
433437
if (!isa<Function>(A.getAliasee()))
434438
continue;
435439

436440
auto *F = cast<Function>(A.getAliasee());
437-
438-
Metadata *Elts[] = {
439-
MDString::get(Ctx, A.getName()),
440-
MDString::get(Ctx, F->getName()),
441-
ConstantAsMetadata::get(
442-
ConstantInt::get(Type::getInt8Ty(Ctx), A.getVisibility())),
443-
ConstantAsMetadata::get(
444-
ConstantInt::get(Type::getInt8Ty(Ctx), A.isWeakForLinker())),
445-
};
446-
447-
FunctionAliases.push_back(MDTuple::get(Ctx, Elts));
441+
FunctionAliases[F].push_back(&A);
448442
}
449443

450444
if (!FunctionAliases.empty()) {
451445
NamedMDNode *NMD = MergedM->getOrInsertNamedMetadata("aliases");
452-
for (auto *MD : FunctionAliases)
453-
NMD->addOperand(MD);
446+
for (auto &Alias : FunctionAliases) {
447+
std::vector<Metadata *> Elts;
448+
Elts.push_back(MDString::get(Ctx, Alias.first->getName()));
449+
for (auto *A : Alias.second)
450+
Elts.push_back(MDString::get(Ctx, A->getName()));
451+
NMD->addOperand(MDTuple::get(Ctx, Elts));
452+
}
454453
}
455454

456455
SmallVector<MDNode *, 8> Symvers;

llvm/test/Transforms/LowerTypeTests/Inputs/exported-funcs.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,12 @@ GlobalValueMap:
1919
15859245615183425489: # guid("internal")
2020
- Linkage: 7 # internal
2121
Live: true
22+
1062103744896965210: # guid("alias1")
23+
- Linkage: 4 # weak
24+
Live: true
25+
Aliasee: 16594175687743574550 # guid("external_addrtaken")
26+
2510616090736846890: # guid("alias2")
27+
- Linkage: 0 # weak
28+
Live: true
29+
Aliasee: 16594175687743574550 # guid("external_addrtaken")
2230
...

0 commit comments

Comments
 (0)