rustwasm / team

A point of coordination for all things Rust and WebAssembly
MIT License
1.45k stars 59 forks source link

BSS values are explicitly generated #248

Closed pepyakin closed 5 years ago

pepyakin commented 5 years ago

This Rust code

#![no_std]

use core::panic::PanicInfo;

#[panic_handler]
fn panic_handler(_: &PanicInfo) -> ! {
    loop { }
}

static mut BUF: [u8; 32] = [0; 32];

#[no_mangle]
pub unsafe extern "C" fn add(idx: usize) -> u8 {
    match BUF.get_mut(idx) {
        Some(v) => {
            *v = v.wrapping_add(1);
            *v
        }
        None => 0,
    }
}

generates the following wasm

(module
  (type (;0;) (func))
  (type (;1;) (func (param i32) (result i32)))
  (func $__wasm_call_ctors (type 0))
  (func $add (type 1) (param i32) (result i32)
    (local i32)
    (set_local 1
      (i32.const 0))
    (block  ;; label = @1
      (br_if 0 (;@1;)
        (i32.gt_u
          (get_local 0)
          (i32.const 31)))
      (i32.store8
        (tee_local 0
          (i32.add
            (get_local 0)
            (i32.const 1048576)))
        (tee_local 1
          (i32.add
            (i32.load8_u
              (get_local 0))
            (i32.const 1)))))
    (i32.and
      (get_local 1)
      (i32.const 255)))
  (table (;0;) 1 1 anyfunc)
  (memory (;0;) 17)
  (global (;0;) (mut i32) (i32.const 1048576))
  (global (;1;) i32 (i32.const 1048608))
  (global (;2;) i32 (i32.const 1048608))
  (export "memory" (memory 0))
  (export "__indirect_function_table" (table 0))
  (export "__heap_base" (global 1))
  (export "__data_end" (global 2))
  (export "add" (func $add))
  (data (;0;) (i32.const 1048576) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00"))

note that on the last line there is a data segment declaration which initializes memory starting from 1048576 to zeroes. This is redundant since memory instance is already initialized to zeroes.

alexcrichton commented 5 years ago

I believe this is a case of a missing optimization in LLD itself. If you run this through wasm-opt it'll remove the bss, but LLD has yet to be taught about that afaik.

pepyakin commented 5 years ago

Hm actually the presented binary already after wasm-opt. I should have mentioned this earlier but this is how I build this binary:

rustc +nightly --target wasm32-unknown-unknown -Copt-level=3 -Clto --crate-type=cdylib bss.rs
wasm-opt bss.wasm
wasm2wat -f bss.wasm > bss.wat
alexcrichton commented 5 years ago

Oh I think this may require the -Os flag perhaps?

pepyakin commented 5 years ago

It worked when I tried it and rebuilt my wasm-opt (not sure what helped though)!

alexcrichton commented 5 years ago

Ok I'm going to close this as it was solved locally, and otherwise I think this is a bug for upstream LLD