11
11
import re
12
12
import json
13
13
import shutil
14
- import logging
15
14
16
15
__rootpath__ = os .path .abspath (os .path .dirname (os .path .dirname (__file__ )))
17
16
sys .path .insert (1 , __rootpath__ )
@@ -35,9 +34,6 @@ def path_from_root(*pathelems):
35
34
return os .path .join (__rootpath__ , * pathelems )
36
35
37
36
38
- # Passes supported by the native optimizer
39
- NATIVE_PASSES = set (['asm' , 'asmPreciseF32' , 'receiveJSON' , 'emitJSON' , 'eliminate' , 'eliminateMemSafe' , 'simplifyExpressions' , 'simplifyIfs' , 'optimizeFrounds' , 'registerize' , 'registerizeHarder' , 'minifyNames' , 'minifyLocals' , 'minifyWhitespace' , 'cleanup' , 'asmLastOpts' , 'last' , 'noop' , 'closure' ])
40
-
41
37
JS_OPTIMIZER = path_from_root ('tools' , 'js-optimizer.js' )
42
38
43
39
NUM_CHUNKS_PER_CORE = 3
@@ -52,8 +48,6 @@ def path_from_root(*pathelems):
52
48
func_sig_json = re .compile (r'\["defun", ?"([_\w$]+)",' )
53
49
import_sig = re .compile (r'(var|const) ([_\w$]+ *=[^;]+);' )
54
50
55
- NATIVE_OPTIMIZER = os .environ .get ('EMCC_NATIVE_OPTIMIZER' ) or '2' # use optimized native optimizer by default (can also be '1' or 'g')
56
-
57
51
58
52
def split_funcs (js , just_split = False ):
59
53
if just_split :
@@ -74,137 +68,6 @@ def split_funcs(js, just_split=False):
74
68
return funcs
75
69
76
70
77
- def get_native_optimizer ():
78
- # Allow users to override the location of the optimizer executable by setting
79
- # an environment variable EMSCRIPTEN_NATIVE_OPTIMIZER=/path/to/optimizer(.exe)
80
- opt = os .environ .get ('EMSCRIPTEN_NATIVE_OPTIMIZER' )
81
- if opt :
82
- logging .debug ('env forcing native optimizer at ' + opt )
83
- return opt
84
- # Also, allow specifying the location of the optimizer in .emscripten
85
- # configuration file under EMSCRIPTEN_NATIVE_OPTIMIZER='/path/to/optimizer'
86
- opt = shared .EMSCRIPTEN_NATIVE_OPTIMIZER
87
- if opt :
88
- logging .debug ('config forcing native optimizer at ' + opt )
89
- return opt
90
-
91
- log_output = None if DEBUG else subprocess .PIPE
92
-
93
- def get_optimizer (name , args ):
94
- def create_optimizer_cmake ():
95
- shared .logging .debug ('building native optimizer via CMake: ' + name )
96
- output = shared .Cache .get_path (name )
97
- shared .try_delete (output )
98
-
99
- if NATIVE_OPTIMIZER == '1' :
100
- cmake_build_type = 'RelWithDebInfo'
101
- elif NATIVE_OPTIMIZER == '2' :
102
- cmake_build_type = 'Release'
103
- elif NATIVE_OPTIMIZER == 'g' :
104
- cmake_build_type = 'Debug'
105
-
106
- build_path = shared .Cache .get_path ('optimizer_build_' + cmake_build_type )
107
- shared .try_delete (os .path .join (build_path , 'CMakeCache.txt' ))
108
-
109
- if not os .path .exists (build_path ):
110
- os .mkdir (build_path )
111
-
112
- if WINDOWS :
113
- # Poor man's check for whether or not we should attempt 64 bit build
114
- if os .environ .get ('ProgramFiles(x86)' ):
115
- cmake_generators = [
116
- 'Visual Studio 15 2017 Win64' ,
117
- 'Visual Studio 15 2017' ,
118
- 'Visual Studio 14 2015 Win64' ,
119
- 'Visual Studio 14 2015' ,
120
- 'Visual Studio 12 Win64' , # The year component is omitted for compatibility with older CMake.
121
- 'Visual Studio 12' ,
122
- 'Visual Studio 11 Win64' ,
123
- 'Visual Studio 11' ,
124
- 'MinGW Makefiles' ,
125
- 'Unix Makefiles' ,
126
- ]
127
- else :
128
- cmake_generators = [
129
- 'Visual Studio 15 2017' ,
130
- 'Visual Studio 14 2015' ,
131
- 'Visual Studio 12' ,
132
- 'Visual Studio 11' ,
133
- 'MinGW Makefiles' ,
134
- 'Unix Makefiles' ,
135
- ]
136
- else :
137
- cmake_generators = ['Unix Makefiles' ]
138
-
139
- for cmake_generator in cmake_generators :
140
- # Delete CMakeCache.txt so that we can switch to a new CMake generator.
141
- shared .try_delete (os .path .join (build_path , 'CMakeCache.txt' ))
142
- proc = subprocess .Popen (['cmake' , '-G' , cmake_generator , '-DCMAKE_BUILD_TYPE=' + cmake_build_type , shared .path_from_root ('tools' , 'optimizer' )], cwd = build_path , stdin = log_output , stdout = log_output , stderr = log_output )
143
- proc .communicate ()
144
- if proc .returncode == 0 :
145
- make = ['cmake' , '--build' , build_path ]
146
- if 'Visual Studio' in cmake_generator :
147
- make += ['--config' , cmake_build_type , '--' , '/nologo' , '/verbosity:minimal' ]
148
-
149
- proc = subprocess .Popen (make , cwd = build_path , stdin = log_output , stdout = log_output , stderr = log_output )
150
- proc .communicate ()
151
- if proc .returncode == 0 :
152
- if WINDOWS and 'Visual Studio' in cmake_generator :
153
- shutil .copyfile (os .path .join (build_path , cmake_build_type , 'optimizer.exe' ), output )
154
- else :
155
- shutil .copyfile (os .path .join (build_path , 'optimizer' ), output )
156
- return output
157
-
158
- assert False
159
-
160
- def create_optimizer ():
161
- shared .logging .debug ('building native optimizer: ' + name )
162
- output = shared .Cache .get_path (name )
163
- shared .try_delete (output )
164
- for compiler in [shared .CLANG_CXX , 'g++' , 'clang++' ]: # try our clang first, otherwise hope for a system compiler in the path
165
- shared .logging .debug (' using ' + compiler )
166
- try :
167
- shared .run_process ([compiler ,
168
- shared .path_from_root ('tools' , 'optimizer' , 'parser.cpp' ),
169
- shared .path_from_root ('tools' , 'optimizer' , 'simple_ast.cpp' ),
170
- shared .path_from_root ('tools' , 'optimizer' , 'optimizer.cpp' ),
171
- shared .path_from_root ('tools' , 'optimizer' , 'optimizer-shared.cpp' ),
172
- shared .path_from_root ('tools' , 'optimizer' , 'optimizer-main.cpp' ),
173
- '-O3' , '-std=c++11' , '-fno-exceptions' , '-fno-rtti' , '-o' , output ] + args ,
174
- stdout = log_output , stderr = log_output )
175
- except Exception as e :
176
- logging .debug (str (e ))
177
- continue # perhaps the later compilers will succeed
178
- # success
179
- return output
180
- shared .exit_with_error ('Failed to build native optimizer' )
181
-
182
- use_cmake_to_configure = WINDOWS # Currently only Windows uses CMake to drive the optimizer build, but set this to True to use on other platforms as well.
183
- if use_cmake_to_configure :
184
- return shared .Cache .get (name , create_optimizer_cmake )
185
- else :
186
- return shared .Cache .get (name , create_optimizer )
187
-
188
- if NATIVE_OPTIMIZER == '1' :
189
- return get_optimizer ('optimizer.exe' , [])
190
- elif NATIVE_OPTIMIZER == '2' :
191
- return get_optimizer ('optimizer.2.exe' , ['-DNDEBUG' ])
192
- elif NATIVE_OPTIMIZER == 'g' :
193
- return get_optimizer ('optimizer.g.exe' , ['-O0' , '-g' , '-fno-omit-frame-pointer' ])
194
-
195
-
196
- # Check if we should run a pass or set of passes natively. if a set of passes,
197
- # they must all be valid to run in the native optimizer at once.
198
- def use_native (x , source_map = False ):
199
- if source_map :
200
- return False
201
- if not NATIVE_OPTIMIZER or NATIVE_OPTIMIZER == '0' :
202
- return False
203
- if isinstance (x , list ):
204
- return len (NATIVE_PASSES .intersection (x )) == len (x ) and 'asm' in x
205
- return x in NATIVE_PASSES
206
-
207
-
208
71
class Minifier (object ):
209
72
"""asm.js minification support. We calculate minification of
210
73
globals here, then pass that into the parallel js-optimizer.js runners which
@@ -445,15 +308,8 @@ def write_chunk(chunk, i):
445
308
446
309
with ToolchainProfiler .profile_block ('run_optimizer' ):
447
310
if len (filenames ):
448
- if not use_native (passes , source_map ):
449
- commands = [shared .NODE_JS + [JS_OPTIMIZER , f , 'noPrintMetadata' ] +
450
- (['--debug' ] if source_map else []) + passes for f in filenames ]
451
- else :
452
- # use the native optimizer
453
- shared .logging .debug ('js optimizer using native' )
454
- assert not source_map # XXX need to use js optimizer
455
- commands = [[get_native_optimizer (), f ] + passes for f in filenames ]
456
- # print [' '.join(command) for command in commands]
311
+ commands = [shared .NODE_JS + [JS_OPTIMIZER , f , 'noPrintMetadata' ] +
312
+ (['--debug' ] if source_map else []) + passes for f in filenames ]
457
313
458
314
cores = min (cores , len (filenames ))
459
315
if len (chunks ) > 1 and cores >= 2 :
0 commit comments