Skip to content

Commit 0205667

Browse files
authored
[LTO] Add function alias as function instead of data (#112599)
On AIX, for undefined functions, only the dotnamed symbols (the address of the function) are generated after linking (i.e., no named function symbol is generated).   Currently, all alias symbols are added as defined data symbols when parsing symbols in LTOModule (the Link Time Optimization library used by linker to optimization code at link time). On AIX, if the function alias is used in the native object, and only its dotnamed symbol is generated, the linker will have problem to match the dotnamed symbol from the native object and the defined symbol marked as data from the bitcode at LTO linktime.   This patch is to add function alias as function instead of data.
1 parent 94643a4 commit 0205667

File tree

4 files changed

+93
-7
lines changed

4 files changed

+93
-7
lines changed

llvm/include/llvm/LTO/legacy/LTOModule.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ struct LTOModule {
195195

196196
/// Add a function symbol as defined to the list.
197197
void addDefinedFunctionSymbol(ModuleSymbolTable::Symbol Sym);
198-
void addDefinedFunctionSymbol(StringRef Name, const Function *F);
198+
void addDefinedFunctionSymbol(StringRef Name, const GlobalValue *F);
199199

200200
/// Add a global symbol from module-level ASM to the defined list.
201201
void addAsmGlobalSymbol(StringRef, lto_symbol_attributes scope);

llvm/lib/LTO/LTOModule.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -406,11 +406,16 @@ void LTOModule::addDefinedFunctionSymbol(ModuleSymbolTable::Symbol Sym) {
406406
Buffer.c_str();
407407
}
408408

409-
const Function *F = cast<Function>(cast<GlobalValue *>(Sym));
410-
addDefinedFunctionSymbol(Buffer, F);
409+
auto *GV = cast<GlobalValue *>(Sym);
410+
assert((isa<Function>(GV) ||
411+
(isa<GlobalAlias>(GV) &&
412+
isa<Function>(cast<GlobalAlias>(GV)->getAliasee()))) &&
413+
"Not function or function alias");
414+
415+
addDefinedFunctionSymbol(Buffer, GV);
411416
}
412417

413-
void LTOModule::addDefinedFunctionSymbol(StringRef Name, const Function *F) {
418+
void LTOModule::addDefinedFunctionSymbol(StringRef Name, const GlobalValue *F) {
414419
// add to list of defined symbols
415420
addDefinedSymbol(Name, F, true);
416421
}
@@ -611,7 +616,11 @@ void LTOModule::parseSymbols() {
611616
}
612617

613618
assert(isa<GlobalAlias>(GV));
614-
addDefinedDataSymbol(Sym);
619+
620+
if (isa<Function>(cast<GlobalAlias>(GV)->getAliasee()))
621+
addDefinedFunctionSymbol(Sym);
622+
else
623+
addDefinedDataSymbol(Sym);
615624
}
616625

617626
// make symbols for all undefines

llvm/test/LTO/PowerPC/list-symbol.ll

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
; RUN: llvm-as < %s > %t
2+
; RUN: llvm-lto -list-symbols-only %t | FileCheck %s
3+
; REQUIRES: default_triple
4+
5+
; CHECK-DAG: v { data defined default }
6+
; CHECK-DAG: va { data defined default alias }
7+
; CHECK-DAG: f { function defined default }
8+
; CHECK-DAG: fa { function defined default alias }
9+
10+
@v = global i32 0
11+
@va = alias i32, ptr @v
12+
@fa = alias void (ptr), ptr @f
13+
14+
define void @f() {
15+
ret void
16+
}

llvm/tools/llvm-lto/llvm-lto.cpp

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,64 @@ static void printIndexStats() {
407407
}
408408
}
409409

410+
/// Print the lto symbol attributes.
411+
static void printLTOSymbolAttributes(lto_symbol_attributes Attrs) {
412+
outs() << "{ ";
413+
unsigned Permission = Attrs & LTO_SYMBOL_PERMISSIONS_MASK;
414+
switch (Permission) {
415+
case LTO_SYMBOL_PERMISSIONS_CODE:
416+
outs() << "function ";
417+
break;
418+
case LTO_SYMBOL_PERMISSIONS_DATA:
419+
outs() << "data ";
420+
break;
421+
case LTO_SYMBOL_PERMISSIONS_RODATA:
422+
outs() << "constant ";
423+
break;
424+
}
425+
unsigned Definition = Attrs & LTO_SYMBOL_DEFINITION_MASK;
426+
switch (Definition) {
427+
case LTO_SYMBOL_DEFINITION_REGULAR:
428+
outs() << "defined ";
429+
break;
430+
case LTO_SYMBOL_DEFINITION_TENTATIVE:
431+
outs() << "common ";
432+
break;
433+
case LTO_SYMBOL_DEFINITION_WEAK:
434+
outs() << "weak ";
435+
break;
436+
case LTO_SYMBOL_DEFINITION_UNDEFINED:
437+
outs() << "extern ";
438+
break;
439+
case LTO_SYMBOL_DEFINITION_WEAKUNDEF:
440+
outs() << "extern-weak ";
441+
break;
442+
}
443+
unsigned Scope = Attrs & LTO_SYMBOL_SCOPE_MASK;
444+
switch (Scope) {
445+
case LTO_SYMBOL_SCOPE_INTERNAL:
446+
outs() << "internal ";
447+
break;
448+
case LTO_SYMBOL_SCOPE_HIDDEN:
449+
outs() << "hidden ";
450+
break;
451+
case LTO_SYMBOL_SCOPE_PROTECTED:
452+
outs() << "protected ";
453+
break;
454+
case LTO_SYMBOL_SCOPE_DEFAULT:
455+
outs() << "default ";
456+
break;
457+
case LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN:
458+
outs() << "omitted ";
459+
break;
460+
}
461+
if (Attrs & LTO_SYMBOL_COMDAT)
462+
outs() << "comdat ";
463+
if (Attrs & LTO_SYMBOL_ALIAS)
464+
outs() << "alias ";
465+
outs() << "}";
466+
}
467+
410468
/// Load each IR file and dump certain information based on active flags.
411469
///
412470
/// The main point here is to provide lit-testable coverage for the LTOModule
@@ -421,8 +479,11 @@ static void testLTOModule(const TargetOptions &Options) {
421479
if (ListSymbolsOnly) {
422480
// List the symbols.
423481
outs() << Filename << ":\n";
424-
for (int I = 0, E = Module->getSymbolCount(); I != E; ++I)
425-
outs() << Module->getSymbolName(I) << "\n";
482+
for (int I = 0, E = Module->getSymbolCount(); I != E; ++I) {
483+
outs() << Module->getSymbolName(I) << " ";
484+
printLTOSymbolAttributes(Module->getSymbolAttributes(I));
485+
outs() << "\n";
486+
}
426487
}
427488
if (QueryHasCtorDtor)
428489
outs() << Filename

0 commit comments

Comments
 (0)