diff options
-rw-r--r-- | CMakeLists.txt | 83 | ||||
-rwxr-xr-x | auto_update_tests.py | 4 | ||||
-rwxr-xr-x | check.py | 4 | ||||
-rw-r--r-- | scripts/fuzz_relooper.py | 2 | ||||
-rw-r--r-- | src/emscripten-optimizer/CMakeLists.txt | 6 | ||||
-rw-r--r-- | src/mixed_arena.h | 46 | ||||
-rw-r--r-- | src/passes/CMakeLists.txt | 17 | ||||
-rw-r--r-- | src/passes/pass.cpp (renamed from src/pass.cpp) | 0 | ||||
-rw-r--r-- | src/support/CMakeLists.txt | 10 | ||||
-rw-r--r-- | src/wasm.h | 2 |
10 files changed, 86 insertions, 88 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 126bf3a6d..2ecc51a9c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,6 +49,7 @@ IF(MSVC) ELSE() ADD_COMPILE_FLAG("/O2") ENDIF() + SET(all_passes passes) ELSE() SET(THREADS_PREFER_PTHREAD_FLAG ON) SET(CMAKE_THREAD_PREFER_PTHREAD ON) @@ -72,6 +73,11 @@ ELSE() ADD_COMPILE_FLAG("-O2") ADD_DEFINITIONS("-UNDEBUG") # Keep asserts. ENDIF() + if (CMAKE_SYSTEM_NAME STREQUAL "Darwin") + SET(all_passes "-force_load" passes) + ELSE() + SET(all_passes "-Wl,--whole-archive" passes "-Wl,-no-whole-archive") + ENDIF() ENDIF() # clang doesn't print colored diagnostics when invoked from Ninja @@ -83,141 +89,84 @@ ENDIF() # Static libraries ADD_SUBDIRECTORY(src/asmjs) +ADD_SUBDIRECTORY(src/emscripten-optimizer) +ADD_SUBDIRECTORY(src/passes) +ADD_SUBDIRECTORY(src/support) # Sources. -SET(support_SOURCES - src/support/archive.cpp - src/support/bits.cpp - src/support/colors.cpp - src/support/command-line.cpp - src/support/file.cpp - src/support/safe_integer.cpp - src/support/threads.cpp -) -ADD_LIBRARY(support STATIC ${support_SOURCES}) SET(binaryen_c_SOURCES src/binaryen-c.cpp src/cfg/Relooper.cpp - src/pass.cpp - src/passes/LowerIfElse.cpp - src/passes/MergeBlocks.cpp - src/passes/NameManager.cpp - src/passes/OptimizeInstructions.cpp - src/passes/PostEmscripten.cpp - src/passes/Print.cpp - src/passes/RemoveImports.cpp - src/passes/RemoveUnusedBrs.cpp - src/passes/RemoveUnusedNames.cpp - src/passes/SimplifyLocals.cpp - src/passes/ReorderLocals.cpp - src/passes/Vacuum.cpp - src/passes/Metrics.cpp src/wasm.cpp ) ADD_LIBRARY(binaryen-c SHARED ${binaryen_c_SOURCES}) -TARGET_LINK_LIBRARIES(binaryen-c asmjs support) +TARGET_LINK_LIBRARIES(binaryen-c asmjs ${all_passes} support) SET(binaryen-shell_SOURCES src/binaryen-shell.cpp - src/pass.cpp - src/passes/LowerIfElse.cpp - src/passes/MergeBlocks.cpp - src/passes/NameManager.cpp - src/passes/OptimizeInstructions.cpp - src/passes/PostEmscripten.cpp - src/passes/Print.cpp - src/passes/RemoveImports.cpp - src/passes/RemoveUnusedBrs.cpp - src/passes/RemoveUnusedNames.cpp - src/passes/SimplifyLocals.cpp - src/passes/ReorderLocals.cpp - src/passes/Vacuum.cpp - src/passes/Metrics.cpp src/wasm.cpp ) ADD_EXECUTABLE(binaryen-shell ${binaryen-shell_SOURCES}) -TARGET_LINK_LIBRARIES(binaryen-shell asmjs support) +TARGET_LINK_LIBRARIES(binaryen-shell asmjs emscripten-optimizer ${all_passes} support) SET_PROPERTY(TARGET binaryen-shell PROPERTY CXX_STANDARD 11) SET_PROPERTY(TARGET binaryen-shell PROPERTY CXX_STANDARD_REQUIRED ON) INSTALL(TARGETS binaryen-shell DESTINATION bin) SET(asm2wasm_SOURCES src/asm2wasm-main.cpp - src/pass.cpp - src/passes/MergeBlocks.cpp - src/passes/OptimizeInstructions.cpp - src/passes/PostEmscripten.cpp - src/passes/Print.cpp - src/passes/RemoveUnusedBrs.cpp - src/passes/RemoveUnusedNames.cpp - src/passes/SimplifyLocals.cpp - src/passes/ReorderLocals.cpp - src/passes/Vacuum.cpp - src/emscripten-optimizer/parser.cpp - src/emscripten-optimizer/simple_ast.cpp - src/emscripten-optimizer/optimizer-shared.cpp src/wasm.cpp ) ADD_EXECUTABLE(asm2wasm ${asm2wasm_SOURCES}) -TARGET_LINK_LIBRARIES(asm2wasm asmjs support) +TARGET_LINK_LIBRARIES(asm2wasm asmjs emscripten-optimizer ${all_passes} support) SET_PROPERTY(TARGET asm2wasm PROPERTY CXX_STANDARD 11) SET_PROPERTY(TARGET asm2wasm PROPERTY CXX_STANDARD_REQUIRED ON) INSTALL(TARGETS asm2wasm DESTINATION bin) SET(wasm2asm_SOURCES src/wasm2asm-main.cpp - src/emscripten-optimizer/parser.cpp - src/emscripten-optimizer/simple_ast.cpp - src/emscripten-optimizer/optimizer-shared.cpp src/wasm.cpp ) ADD_EXECUTABLE(wasm2asm ${wasm2asm_SOURCES}) -TARGET_LINK_LIBRARIES(wasm2asm asmjs support) +TARGET_LINK_LIBRARIES(wasm2asm asmjs emscripten-optimizer support) SET_PROPERTY(TARGET wasm2asm PROPERTY CXX_STANDARD 11) SET_PROPERTY(TARGET wasm2asm PROPERTY CXX_STANDARD_REQUIRED ON) INSTALL(TARGETS wasm2asm DESTINATION bin) SET(s2wasm_SOURCES - src/pass.cpp - src/passes/Print.cpp src/wasm-linker.cpp src/s2wasm-main.cpp src/wasm.cpp ) ADD_EXECUTABLE(s2wasm ${s2wasm_SOURCES}) -TARGET_LINK_LIBRARIES(s2wasm asmjs support) +TARGET_LINK_LIBRARIES(s2wasm asmjs passes support) SET_PROPERTY(TARGET s2wasm PROPERTY CXX_STANDARD 11) SET_PROPERTY(TARGET s2wasm PROPERTY CXX_STANDARD_REQUIRED ON) INSTALL(TARGETS s2wasm DESTINATION bin) SET(wasm_as_SOURCES - src/pass.cpp - src/passes/Print.cpp src/wasm-as.cpp src/wasm.cpp ) ADD_EXECUTABLE(wasm-as ${wasm_as_SOURCES}) -TARGET_LINK_LIBRARIES(wasm-as asmjs support) +TARGET_LINK_LIBRARIES(wasm-as asmjs passes support) SET_PROPERTY(TARGET wasm-as PROPERTY CXX_STANDARD 11) SET_PROPERTY(TARGET wasm-as PROPERTY CXX_STANDARD_REQUIRED ON) INSTALL(TARGETS wasm-as DESTINATION bin) SET(wasm_dis_SOURCES - src/pass.cpp - src/passes/Print.cpp src/wasm-dis.cpp src/wasm.cpp ) ADD_EXECUTABLE(wasm-dis ${wasm_dis_SOURCES}) -TARGET_LINK_LIBRARIES(wasm-dis support) +TARGET_LINK_LIBRARIES(wasm-dis passes support) SET_PROPERTY(TARGET wasm-dis PROPERTY CXX_STANDARD 11) SET_PROPERTY(TARGET wasm-dis PROPERTY CXX_STANDARD_REQUIRED ON) INSTALL(TARGETS wasm-dis DESTINATION bin) diff --git a/auto_update_tests.py b/auto_update_tests.py index 5380fc737..5fa106747 100755 --- a/auto_update_tests.py +++ b/auto_update_tests.py @@ -100,14 +100,14 @@ for t in sorted(os.listdir(os.path.join('test', 'example'))): cmd = ['-Isrc', '-g', '-lasmjs', '-lsupport', '-Llib/.', '-pthread', '-o', output_file] if t.endswith('.cpp'): cmd = [os.path.join('test', 'example', t), - os.path.join('src', 'pass.cpp'), + os.path.join('src', 'passes', 'pass.cpp'), os.path.join('src', 'wasm.cpp'), os.path.join('src', 'passes', 'Print.cpp')] + cmd elif t.endswith('.c'): # build the C file separately extra = [os.environ.get('CC') or 'gcc', os.path.join('test', 'example', t), '-c', '-o', 'example.o', - '-Isrc', '-g', '-lasmjs', '-lsupport', '-Llib/.', '-pthread'] + '-Isrc', '-g', '-Llib/.', '-pthread'] print ' '.join(extra) subprocess.check_call(extra) # Link against the binaryen C library DSO, using an executable-relative rpath @@ -599,14 +599,14 @@ for t in sorted(os.listdir(os.path.join('test', 'example'))): cmd = ['-Isrc', '-g', '-lasmjs', '-lsupport', '-Llib/.', '-pthread', '-o', output_file] if t.endswith('.cpp'): cmd = [os.path.join('test', 'example', t), - os.path.join('src', 'pass.cpp'), + os.path.join('src', 'passes', 'pass.cpp'), os.path.join('src', 'wasm.cpp'), os.path.join('src', 'passes', 'Print.cpp')] + cmd elif t.endswith('.c'): # build the C file separately extra = [os.environ.get('CC') or 'gcc', os.path.join('test', 'example', t), '-c', '-o', 'example.o', - '-Isrc', '-g', '-lasmjs', '-lsupport', '-Llib/.', '-pthread'] + '-Isrc', '-g', '-Llib/.', '-pthread'] print ' '.join(extra) subprocess.check_call(extra) # Link against the binaryen C library DSO, using an executable-relative rpath diff --git a/scripts/fuzz_relooper.py b/scripts/fuzz_relooper.py index 7a39147a5..e09f252b7 100644 --- a/scripts/fuzz_relooper.py +++ b/scripts/fuzz_relooper.py @@ -32,7 +32,7 @@ counter = 0 while True: # Random decisions - num = random.randint(2, 250) # TODO: 250+ + num = random.randint(2, 250) density = random.random() * random.random() decisions = [random.randint(1, num * 20) for x in range(num * 3)] branches = [0] * num diff --git a/src/emscripten-optimizer/CMakeLists.txt b/src/emscripten-optimizer/CMakeLists.txt new file mode 100644 index 000000000..6c302b991 --- /dev/null +++ b/src/emscripten-optimizer/CMakeLists.txt @@ -0,0 +1,6 @@ +SET(emscripten-optimizer_SOURCES + optimizer-shared.cpp + parser.cpp + simple_ast.cpp +) +ADD_LIBRARY(emscripten-optimizer STATIC ${emscripten-optimizer_SOURCES}) diff --git a/src/mixed_arena.h b/src/mixed_arena.h index 930bf3c0e..77aa052c1 100644 --- a/src/mixed_arena.h +++ b/src/mixed_arena.h @@ -61,32 +61,48 @@ struct MixedArena { size_t chunkSize = 32768; size_t index; // in last chunk + std::thread::id threadId; + // multithreaded allocation - each arena is valid on a specific thread. - // if we are on the wrong thread, we safely look in the linked + // if we are on the wrong thread, we atomically look in the linked // list of next, adding an allocator if necessary - // TODO: we don't really need locking here, atomics could suffice - std::thread::id threadId; - std::mutex mutex; - MixedArena* next; + std::atomic<MixedArena*> next; MixedArena() { threadId = std::this_thread::get_id(); - next = nullptr; + next.store(nullptr); } void* allocSpace(size_t size) { // the bump allocator data should not be modified by multiple threads at once. - if (std::this_thread::get_id() != threadId) { - // TODO use a fast double-checked locking pattern. - std::lock_guard<std::mutex> lock(mutex); + auto myId = std::this_thread::get_id(); + if (myId != threadId) { MixedArena* curr = this; - while (std::this_thread::get_id() != curr->threadId) { - if (curr->next) { - curr = curr->next; - } else { - curr->next = new MixedArena(); // will have our thread id + MixedArena* allocated = nullptr; + while (myId != curr->threadId) { + auto seen = curr->next.load(); + if (seen) { + curr = seen; + continue; + } + // there is a nullptr for next, so we may be able to place a new + // allocator for us there. but carefully, as others may do so as + // well. we may waste a few allocations here, but it doesn't matter + // as this can only happen as the chain is built up, i.e., + // O(# of cores) per allocator, and our allocatrs are long-lived. + if (!allocated) { + allocated = new MixedArena(); // has our thread id + } + if (curr->next.compare_exchange_weak(seen, allocated)) { + // we replaced it, so we are the next in the chain + // we can forget about allocated, it is owned by the chain now + allocated = nullptr; + break; } + // otherwise, the cmpxchg updated seen, and we continue to loop + curr = seen; } + if (allocated) delete allocated; return curr->allocSpace(size); } size = (size + 7) & (-8); // same alignment as malloc TODO optimize? @@ -120,7 +136,7 @@ struct MixedArena { ~MixedArena() { clear(); - if (next) delete next; + if (next.load()) delete next.load(); } }; diff --git a/src/passes/CMakeLists.txt b/src/passes/CMakeLists.txt new file mode 100644 index 000000000..460910978 --- /dev/null +++ b/src/passes/CMakeLists.txt @@ -0,0 +1,17 @@ +SET(passes_SOURCES + pass.cpp + LowerIfElse.cpp + MergeBlocks.cpp + Metrics.cpp + NameManager.cpp + OptimizeInstructions.cpp + PostEmscripten.cpp + Print.cpp + RemoveImports.cpp + RemoveUnusedBrs.cpp + RemoveUnusedNames.cpp + ReorderLocals.cpp + SimplifyLocals.cpp + Vacuum.cpp +) +ADD_LIBRARY(passes STATIC ${passes_SOURCES}) diff --git a/src/pass.cpp b/src/passes/pass.cpp index e4cc35554..e4cc35554 100644 --- a/src/pass.cpp +++ b/src/passes/pass.cpp diff --git a/src/support/CMakeLists.txt b/src/support/CMakeLists.txt new file mode 100644 index 000000000..08546e3ee --- /dev/null +++ b/src/support/CMakeLists.txt @@ -0,0 +1,10 @@ +SET(support_SOURCES + archive.cpp + bits.cpp + colors.cpp + command-line.cpp + file.cpp + safe_integer.cpp + threads.cpp +) +ADD_LIBRARY(support STATIC ${support_SOURCES}) diff --git a/src/wasm.h b/src/wasm.h index 049dc2e30..2e3a63105 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -913,7 +913,7 @@ public: // set the type of a block if you already know it void finalize(WasmType type_) { - type = type; + type = type_; } // set the type of a block based on its contents. this scans the block, so it is not fast |