[lld] e4888be - [WebAssembly] Avoid unused function imports in PIC mode

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 18 19:31:18 PDT 2021


Author: Sam Clegg
Date: 2021-08-18T22:31:04-04:00
New Revision: e4888be74e342840cc1d9e42c9f42938169ae96b

URL: https://github.com/llvm/llvm-project/commit/e4888be74e342840cc1d9e42c9f42938169ae96b
DIFF: https://github.com/llvm/llvm-project/commit/e4888be74e342840cc1d9e42c9f42938169ae96b.diff

LOG: [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

Added: 
    

Modified: 
    lld/test/wasm/shared.s
    lld/test/wasm/shared64.s
    lld/wasm/SymbolTable.cpp
    lld/wasm/Writer.cpp

Removed: 
    


################################################################################
diff  --git a/lld/test/wasm/shared.s b/lld/test/wasm/shared.s
index 3299d844c2b3e..29cf8f6f996c5 100644
--- a/lld/test/wasm/shared.s
+++ b/lld/test/wasm/shared.s
@@ -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
 

diff  --git a/lld/test/wasm/shared64.s b/lld/test/wasm/shared64.s
index 36528e1031a65..d441dd363cdb2 100644
--- a/lld/test/wasm/shared64.s
+++ b/lld/test/wasm/shared64.s
@@ -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
 

diff  --git a/lld/wasm/SymbolTable.cpp b/lld/wasm/SymbolTable.cpp
index 1a5213347ba3d..89fb481d72ceb 100644
--- a/lld/wasm/SymbolTable.cpp
+++ b/lld/wasm/SymbolTable.cpp
@@ -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;

diff  --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp
index cf9356ba18a36..efe64e6ab616a 100644
--- a/lld/wasm/Writer.cpp
+++ b/lld/wasm/Writer.cpp
@@ -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)


        


More information about the llvm-commits mailing list