forked from OSchip/llvm-project
[WebAssembly] Avoid unused function imports in PIC mode
In PIC mode we import function address via `GOT.mem` imports but for direct function calls we still import the first class function. However, if the function is never directly called we can avoid the first class import completely. Differential Revision: https://reviews.llvm.org/D108345
This commit is contained in:
parent
a9095f005f
commit
e4888be74e
|
@ -167,10 +167,6 @@ get_local_func_address:
|
|||
# CHECK-NEXT: Kind: GLOBAL
|
||||
# CHECK-NEXT: GlobalType: I32
|
||||
# CHECK-NEXT: GlobalMutable: false
|
||||
# CHECK-NEXT: - Module: env
|
||||
# CHECK-NEXT: Field: func_external
|
||||
# CHECK-NEXT: Kind: FUNCTION
|
||||
# CHECK-NEXT: SigIndex: 1
|
||||
# CHECK-NEXT: - Module: GOT.mem
|
||||
# CHECK-NEXT: Field: indirect_func
|
||||
# CHECK-NEXT: Kind: GLOBAL
|
||||
|
@ -197,7 +193,7 @@ get_local_func_address:
|
|||
# CHECK-NEXT: Exports:
|
||||
# CHECK-NEXT: - Name: __wasm_call_ctors
|
||||
# CHECK-NEXT: Kind: FUNCTION
|
||||
# CHECK-NEXT: Index: 1
|
||||
# CHECK-NEXT: Index: 0
|
||||
|
||||
# check for elem segment initialized with __table_base global as offset
|
||||
|
||||
|
@ -206,17 +202,17 @@ get_local_func_address:
|
|||
# CHECK-NEXT: - Offset:
|
||||
# CHECK-NEXT: Opcode: GLOBAL_GET
|
||||
# CHECK-NEXT: Index: 2
|
||||
# CHECK-NEXT: Functions: [ 4, 3 ]
|
||||
# CHECK-NEXT: Functions: [ 3, 2 ]
|
||||
|
||||
# check the generated code in __wasm_call_ctors and __wasm_apply_data_relocs functions
|
||||
# TODO(sbc): Disassemble and verify instructions.
|
||||
|
||||
# CHECK: - Type: CODE
|
||||
# CHECK-NEXT: Functions:
|
||||
# CHECK-NEXT: - Index: 1
|
||||
# CHECK-NEXT: - Index: 0
|
||||
# CHECK-NEXT: Locals: []
|
||||
# CHECK-NEXT: Body: 10020B
|
||||
# CHECK-NEXT: - Index: 2
|
||||
# CHECK-NEXT: Body: 10010B
|
||||
# CHECK-NEXT: - Index: 1
|
||||
# CHECK-NEXT: Locals: []
|
||||
# CHECK-NEXT: Body: 230141046A2304360200230141086A230241016A3602002301410C6A230141006A360200230141106A2305360200230141146A230641046A3602000B
|
||||
|
||||
|
|
|
@ -174,10 +174,6 @@ get_local_func_address:
|
|||
# CHECK-NEXT: Kind: GLOBAL
|
||||
# CHECK-NEXT: GlobalType: I32
|
||||
# CHECK-NEXT: GlobalMutable: false
|
||||
# CHECK-NEXT: - Module: env
|
||||
# CHECK-NEXT: Field: func_external
|
||||
# CHECK-NEXT: Kind: FUNCTION
|
||||
# CHECK-NEXT: SigIndex: 1
|
||||
# CHECK-NEXT: - Module: GOT.mem
|
||||
# CHECK-NEXT: Field: indirect_func
|
||||
# CHECK-NEXT: Kind: GLOBAL
|
||||
|
@ -204,7 +200,7 @@ get_local_func_address:
|
|||
# CHECK-NEXT: Exports:
|
||||
# CHECK-NEXT: - Name: __wasm_call_ctors
|
||||
# CHECK-NEXT: Kind: FUNCTION
|
||||
# CHECK-NEXT: Index: 1
|
||||
# CHECK-NEXT: Index: 0
|
||||
|
||||
# check for elem segment initialized with __table_base global as offset
|
||||
|
||||
|
@ -213,17 +209,17 @@ get_local_func_address:
|
|||
# CHECK-NEXT: - Offset:
|
||||
# CHECK-NEXT: Opcode: GLOBAL_GET
|
||||
# CHECK-NEXT: Index: 3
|
||||
# CHECK-NEXT: Functions: [ 4, 3 ]
|
||||
# CHECK-NEXT: Functions: [ 3, 2 ]
|
||||
|
||||
# check the generated code in __wasm_call_ctors and __wasm_apply_data_relocs functions
|
||||
# TODO(sbc): Disassemble and verify instructions.
|
||||
|
||||
# CHECK: - Type: CODE
|
||||
# CHECK-NEXT: Functions:
|
||||
# CHECK-NEXT: - Index: 1
|
||||
# CHECK-NEXT: - Index: 0
|
||||
# CHECK-NEXT: Locals: []
|
||||
# CHECK-NEXT: Body: 10020B
|
||||
# CHECK-NEXT: - Index: 2
|
||||
# CHECK-NEXT: Body: 10010B
|
||||
# CHECK-NEXT: - Index: 1
|
||||
# CHECK-NEXT: Locals: []
|
||||
# CHECK-NEXT: Body: 230142047C23053702002301420C7C230242017C370200230142147C230141006A360200230142187C2306370200230142207C230741046A3602000B
|
||||
|
||||
|
|
|
@ -548,9 +548,12 @@ Symbol *SymbolTable::addUndefinedFunction(StringRef name,
|
|||
else if (getFunctionVariant(s, sig, file, &s))
|
||||
replaceSym();
|
||||
}
|
||||
if (existingUndefined)
|
||||
if (existingUndefined) {
|
||||
setImportAttributes(existingUndefined, importName, importModule, flags,
|
||||
file);
|
||||
if (isCalledDirectly)
|
||||
existingUndefined->isCalledDirectly = true;
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
|
|
|
@ -562,6 +562,14 @@ static bool shouldImport(Symbol *sym) {
|
|||
if (isa<DataSymbol>(sym))
|
||||
return false;
|
||||
|
||||
// In PIC mode we only need to import functions when they are called directly.
|
||||
// Indirect usage all goes via GOT imports.
|
||||
if (config->isPic) {
|
||||
if (auto *f = dyn_cast<UndefinedFunction>(sym))
|
||||
if (!f->isCalledDirectly)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (config->isPic || config->relocatable || config->importUndefined)
|
||||
return true;
|
||||
if (config->allowUndefinedSymbols.count(sym->getName()) != 0)
|
||||
|
|
Loading…
Reference in New Issue