mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-01 01:31:26 +00:00
[WebAssembly] Implement -print-gc-sections, to better test GC of globals
Differential Revision: https://reviews.llvm.org/D44311 llvm-svn: 330456
This commit is contained in:
parent
3a1b697d6e
commit
358af38d37
53
lld/test/wasm/Inputs/globals.yaml
Normal file
53
lld/test/wasm/Inputs/globals.yaml
Normal file
@ -0,0 +1,53 @@
|
||||
--- !WASM
|
||||
FileHeader:
|
||||
Version: 0x00000001
|
||||
Sections:
|
||||
- Type: TYPE
|
||||
Signatures:
|
||||
- Index: 0
|
||||
ReturnType: I64
|
||||
ParamTypes:
|
||||
- Type: FUNCTION
|
||||
FunctionTypes: [ 0 ]
|
||||
- Type: GLOBAL
|
||||
Globals:
|
||||
- Index: 0
|
||||
Type: I64
|
||||
Mutable: true
|
||||
InitExpr:
|
||||
Opcode: I64_CONST
|
||||
Value: 123
|
||||
- Index: 1
|
||||
Type: I64
|
||||
Mutable: true
|
||||
InitExpr:
|
||||
Opcode: I64_CONST
|
||||
Value: 456
|
||||
- Type: CODE
|
||||
Functions:
|
||||
- Index: 0
|
||||
Locals:
|
||||
Body: 2381808080000B
|
||||
Relocations:
|
||||
- Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB
|
||||
Index: 1
|
||||
Offset: 0x00000004
|
||||
- Type: CUSTOM
|
||||
Name: linking
|
||||
SymbolTable:
|
||||
- Index: 0
|
||||
Kind: GLOBAL
|
||||
Name: unused_global
|
||||
Flags: [ VISIBILITY_HIDDEN ]
|
||||
Global: 0
|
||||
- Index: 1
|
||||
Kind: GLOBAL
|
||||
Name: used_global
|
||||
Flags: [ VISIBILITY_HIDDEN ]
|
||||
Global: 1
|
||||
- Index: 2
|
||||
Kind: FUNCTION
|
||||
Name: use_global
|
||||
Flags: [ VISIBILITY_HIDDEN ]
|
||||
Function: 0
|
||||
...
|
@ -1,16 +1,20 @@
|
||||
; RUN: llc -filetype=obj %s -o %t.o
|
||||
; RUN: wasm-ld -print-gc-sections -o %t1.wasm %t.o | FileCheck %s -check-prefix=PRINT-GC
|
||||
; RUN: yaml2obj %S/Inputs/globals.yaml -o %t_globals.o
|
||||
; RUN: wasm-ld -print-gc-sections -o %t1.wasm %t.o %t_globals.o | \
|
||||
; RUN: FileCheck %s -check-prefix=PRINT-GC
|
||||
; PRINT-GC: removing unused section {{.*}}:(unused_function)
|
||||
; PRINT-GC-NOT: removing unused section {{.*}}:(used_function)
|
||||
; PRINT-GC: removing unused section {{.*}}:(.data.unused_data)
|
||||
; PRINT-GC-NOT: removing unused section {{.*}}:(.data.used_data)
|
||||
; PRINT-GC: removing unused section {{.*}}:(unused_global)
|
||||
; PRINT-GC-NOT: removing unused section {{.*}}:(used_global)
|
||||
|
||||
target triple = "wasm32-unknown-unknown-wasm"
|
||||
|
||||
@unused_data = hidden global i64 1, align 4
|
||||
@used_data = hidden global i32 2, align 4
|
||||
|
||||
define hidden i64 @unused_function() {
|
||||
define hidden i64 @unused_function(i64 %arg) {
|
||||
%1 = load i64, i64* @unused_data, align 4
|
||||
ret i64 %1
|
||||
}
|
||||
@ -20,24 +24,45 @@ define hidden i32 @used_function() {
|
||||
ret i32 %1
|
||||
}
|
||||
|
||||
declare i64 @use_global()
|
||||
|
||||
define hidden void @_start() {
|
||||
entry:
|
||||
call i32 @used_function()
|
||||
call i64 @use_global()
|
||||
ret void
|
||||
}
|
||||
|
||||
; RUN: obj2yaml %t1.wasm | FileCheck %s
|
||||
|
||||
; CHECK: - Type: TYPE
|
||||
; CHECK-NEXT: Signatures:
|
||||
; CHECK-NEXT: Signatures:
|
||||
; CHECK-NEXT: - Index: 0
|
||||
; CHECK-NEXT: ReturnType: NORESULT
|
||||
; CHECK-NEXT: ParamTypes:
|
||||
; CHECK-NEXT: ParamTypes:
|
||||
; CHECK-NEXT: - Index: 1
|
||||
; CHECK-NEXT: ReturnType: I32
|
||||
; CHECK-NEXT: ParamTypes:
|
||||
; CHECK-NEXT: ParamTypes:
|
||||
; CHECK-NEXT: - Index: 2
|
||||
; CHECK-NEXT: ReturnType: I64
|
||||
; CHECK-NEXT: ParamTypes:
|
||||
; CHECK-NEXT: - Type: FUNCTION
|
||||
|
||||
; CHECK: - Type: GLOBAL
|
||||
; CHECK-NEXT: Globals:
|
||||
; CHECK-NEXT: - Index: 0
|
||||
; CHECK-NEXT: Type: I32
|
||||
; CHECK-NEXT: Mutable: true
|
||||
; CHECK-NEXT: InitExpr:
|
||||
; CHECK-NEXT: Opcode: I32_CONST
|
||||
; CHECK-NEXT: Value: 66576
|
||||
; CHECK-NEXT: - Index: 1
|
||||
; CHECK-NEXT: Type: I64
|
||||
; CHECK-NEXT: Mutable: true
|
||||
; CHECK-NEXT: InitExpr:
|
||||
; CHECK-NEXT: Opcode: I64_CONST
|
||||
; CHECK-NEXT: Value: 456
|
||||
|
||||
; CHECK: - Type: DATA
|
||||
; CHECK-NEXT: Segments:
|
||||
; CHECK-NEXT: - SectionOffset: 7
|
||||
@ -55,24 +80,52 @@ entry:
|
||||
; CHECK-NEXT: Name: used_function
|
||||
; CHECK-NEXT: - Index: 2
|
||||
; CHECK-NEXT: Name: _start
|
||||
; CHECK-NEXT: - Index: 3
|
||||
; CHECK-NEXT: Name: use_global
|
||||
; CHECK-NEXT: ...
|
||||
|
||||
; RUN: wasm-ld -print-gc-sections --no-gc-sections -o %t1.no-gc.wasm %t.o
|
||||
; RUN: wasm-ld -print-gc-sections --no-gc-sections -o %t1.no-gc.wasm \
|
||||
; RUN: %t.o %t_globals.o
|
||||
; RUN: obj2yaml %t1.no-gc.wasm | FileCheck %s -check-prefix=NO-GC
|
||||
|
||||
; NO-GC: - Type: TYPE
|
||||
; NO-GC-NEXT: Signatures:
|
||||
; NO-GC-NEXT: Signatures:
|
||||
; NO-GC-NEXT: - Index: 0
|
||||
; NO-GC-NEXT: ReturnType: NORESULT
|
||||
; NO-GC-NEXT: ParamTypes:
|
||||
; NO-GC-NEXT: - Index: 1
|
||||
; NO-GC-NEXT: ReturnType: I64
|
||||
; NO-GC-NEXT: ParamTypes:
|
||||
; NO-GC-NEXT: ParamTypes:
|
||||
; NO-GC-NEXT: - I64
|
||||
; NO-GC-NEXT: - Index: 2
|
||||
; NO-GC-NEXT: ReturnType: I32
|
||||
; NO-GC-NEXT: ParamTypes:
|
||||
; NO-GC-NEXT: ParamTypes:
|
||||
; NO-GC-NEXT: - Index: 3
|
||||
; NO-GC-NEXT: ReturnType: I64
|
||||
; NO-GC-NEXT: ParamTypes:
|
||||
; NO-GC-NEXT: - Type: FUNCTION
|
||||
|
||||
; NO-GC: - Type: GLOBAL
|
||||
; NO-GC-NEXT: Globals:
|
||||
; NO-GC-NEXT: - Index: 0
|
||||
; NO-GC-NEXT: Type: I32
|
||||
; NO-GC-NEXT: Mutable: true
|
||||
; NO-GC-NEXT: InitExpr:
|
||||
; NO-GC-NEXT: Opcode: I32_CONST
|
||||
; NO-GC-NEXT: Value: 66576
|
||||
; NO-GC-NEXT: - Index: 1
|
||||
; NO-GC-NEXT: Type: I64
|
||||
; NO-GC-NEXT: Mutable: true
|
||||
; NO-GC-NEXT: InitExpr:
|
||||
; NO-GC-NEXT: Opcode: I64_CONST
|
||||
; NO-GC-NEXT: Value: 123
|
||||
; NO-GC-NEXT: - Index: 2
|
||||
; NO-GC-NEXT: Type: I64
|
||||
; NO-GC-NEXT: Mutable: true
|
||||
; NO-GC-NEXT: InitExpr:
|
||||
; NO-GC-NEXT: Opcode: I64_CONST
|
||||
; NO-GC-NEXT: Value: 456
|
||||
|
||||
; NO-GC: - Type: DATA
|
||||
; NO-GC-NEXT: Segments:
|
||||
; NO-GC-NEXT: - SectionOffset: 7
|
||||
@ -92,6 +145,8 @@ entry:
|
||||
; NO-GC-NEXT: Name: used_function
|
||||
; NO-GC-NEXT: - Index: 3
|
||||
; NO-GC-NEXT: Name: _start
|
||||
; NO-GC-NEXT: - Index: 4
|
||||
; NO-GC-NEXT: Name: use_global
|
||||
; NO-GC-NEXT: ...
|
||||
|
||||
; RUN: not wasm-ld --gc-sections --relocatable -o %t1.no-gc.wasm %t.o 2>&1 | FileCheck %s -check-prefix=CHECK-ERROR
|
||||
|
@ -340,7 +340,8 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
|
||||
Global.Type = {WASM_TYPE_I32, true};
|
||||
Global.InitExpr.Value.Int32 = 0;
|
||||
Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST;
|
||||
InputGlobal *StackPointer = make<InputGlobal>(Global);
|
||||
Global.SymbolName = "__stack_pointer";
|
||||
InputGlobal *StackPointer = make<InputGlobal>(Global, nullptr);
|
||||
StackPointer->Live = true;
|
||||
|
||||
static WasmSignature NullSignature = {{}, WASM_TYPE_NORESULT};
|
||||
|
@ -187,7 +187,7 @@ void ObjFile::parse() {
|
||||
|
||||
// Populate `Globals`.
|
||||
for (const WasmGlobal &G : WasmObj->globals())
|
||||
Globals.emplace_back(make<InputGlobal>(G));
|
||||
Globals.emplace_back(make<InputGlobal>(G, this));
|
||||
|
||||
// Populate `Symbols` based on the WasmSymbols in the object.
|
||||
Symbols.reserve(WasmObj->getNumberOfSymbols());
|
||||
|
@ -26,8 +26,10 @@ namespace wasm {
|
||||
// combined to form the final GLOBALS section.
|
||||
class InputGlobal {
|
||||
public:
|
||||
InputGlobal(const WasmGlobal &G) : Global(G) {}
|
||||
InputGlobal(const WasmGlobal &G, ObjFile *F)
|
||||
: File(F), Global(G), Live(!Config->GcSections) {}
|
||||
|
||||
StringRef getName() const { return Global.SymbolName; }
|
||||
const WasmGlobalType &getType() const { return Global.Type; }
|
||||
|
||||
uint32_t getGlobalIndex() const { return GlobalIndex.getValue(); }
|
||||
@ -37,16 +39,21 @@ public:
|
||||
GlobalIndex = Index;
|
||||
}
|
||||
|
||||
bool Live = false;
|
||||
|
||||
ObjFile *File;
|
||||
WasmGlobal Global;
|
||||
|
||||
bool Live = false;
|
||||
|
||||
protected:
|
||||
llvm::Optional<uint32_t> GlobalIndex;
|
||||
};
|
||||
|
||||
} // namespace wasm
|
||||
|
||||
inline std::string toString(const wasm::InputGlobal *G) {
|
||||
return (toString(G->File) + ":(" + G->getName() + ")").str();
|
||||
}
|
||||
|
||||
} // namespace lld
|
||||
|
||||
#endif // LLD_WASM_INPUT_GLOBAL_H
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "MarkLive.h"
|
||||
#include "Config.h"
|
||||
#include "InputChunks.h"
|
||||
#include "InputGlobal.h"
|
||||
#include "SymbolTable.h"
|
||||
#include "Symbols.h"
|
||||
|
||||
@ -102,9 +103,15 @@ void lld::wasm::markLive() {
|
||||
for (InputChunk *C : Obj->Segments)
|
||||
if (!C->Live)
|
||||
message("removing unused section " + toString(C));
|
||||
for (InputGlobal *G : Obj->Globals)
|
||||
if (!G->Live)
|
||||
message("removing unused section " + toString(G));
|
||||
}
|
||||
for (InputChunk *C : Symtab->SyntheticFunctions)
|
||||
if (!C->Live)
|
||||
message("removing unused section " + toString(C));
|
||||
for (InputGlobal *G : Symtab->SyntheticGlobals)
|
||||
if (!G->Live)
|
||||
message("removing unused section " + toString(G));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user