diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-02-10 17:28:20 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-02-11 14:54:56 -0800 |
commit | 79db56a186db69c6617b0670e4675c9f321bee7d (patch) | |
tree | e81dbcbc7e571c4a9e0a9a060d26c711dc236d91 | |
parent | 8c69b59fcd8bdc560bceba221496ad271f4a35d3 (diff) |
remove variable eliminator in analyzer; we do that in the eliminator in -O1 and above anyhow
-rw-r--r-- | src/analyzer.js | 28 | ||||
-rw-r--r-- | tests/cases/lifetime.ll | 42 | ||||
-rw-r--r-- | tests/cases/lifetime.py | 6 | ||||
-rw-r--r-- | tests/lifetime.ll | 37 | ||||
-rwxr-xr-x | tests/runner.py | 22 |
5 files changed, 56 insertions, 79 deletions
diff --git a/src/analyzer.js b/src/analyzer.js index bb9ab27d..bba617a7 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -820,33 +820,7 @@ function analyzer(data, sidePass) { //if (dcheck('vars')) dprint('analyzed variables: ' + dump(func.variables)); } - // Filter out no longer used variables, collapsing more as we go - while (true) { - analyzeVariableUses(); - - var recalc = false; - - keys(func.variables).forEach(function(vname) { - var variable = func.variables[vname]; - if (variable.uses == 0 && variable.origin != 'funcparam') { - // Eliminate this variable if we can - var sideEffects = false; - walkInterdata(func.lines[variable.rawLinesIndex], function(item) { - if (item.intertype in SIDE_EFFECT_CAUSERS) sideEffects = true; - }); - if (!sideEffects) { - dprint('vars', 'Eliminating ' + vname); - func.lines[variable.rawLinesIndex].intertype = 'noop'; - func.lines[variable.rawLinesIndex].assignTo = null; - // in theory we can also null out some fields here to save memory - delete func.variables[vname]; - recalc = true; - } - } - }); - - if (!recalc) break; - } + analyzeVariableUses(); // Decision time diff --git a/tests/cases/lifetime.ll b/tests/cases/lifetime.ll deleted file mode 100644 index dc6d471d..00000000 --- a/tests/cases/lifetime.ll +++ /dev/null @@ -1,42 +0,0 @@ -; ModuleID = '/tmp/emscripten/tmp/src.cpp.o' -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32" -target triple = "i386-pc-linux-gnu" - -%struct.vec2 = type { float, float } - -@.str = private unnamed_addr constant [15 x i8] c"hello, world!\0A\00" ; [#uses=1] - -; [#uses=1] -declare i32 @printf(i8* noalias, ...) - -define linkonce_odr float @vec2Length(%struct.vec2* %this) nounwind align 2 { -entry: - %__first.addr.i = alloca %struct.b2Pair.5*, align 4 ; [#uses=3 type=%struct.b2Pair.5**] - %__last.addr.i = alloca %struct.b2Pair.5*, align 4 ; [#uses=3 type=%struct.b2Pair.5**] - %__comp.addr.i = alloca %struct.b2Pair.5*, align 4 ; [#uses=2 type=%struct.b2Pair.5**] - %13 = bitcast %struct.vec2** %__first.addr.i to i8* ; [#uses=1 type=i8*] - call void @llvm.lifetime.start(i64 -1, i8* %13) - %14 = bitcast %struct.vec2** %__last.addr.i to i8* ; [#uses=1 type=i8*] - call void @llvm.lifetime.start(i64 -1, i8* %14) - %15 = bitcast i1 (%struct.vec2*, %struct.vec2*)** %__comp.addr.i to i8* ; [#uses=1 type=i8*] - call void @llvm.lifetime.start(i64 -1, i8* %15) - store %struct.vec2* %10, %struct.vec2** %__first.addr.i, align 4 - store %struct.vec2* %add.ptr, %struct.vec2** %__last.addr.i, align 4 - %18 = bitcast %struct.vec2** %__first.addr.i to i8* ; [#uses=1 type=i8*] - call void @llvm.lifetime.end(i64 -1, i8* %18) - %19 = bitcast %struct.vec2** %__last.addr.i to i8* ; [#uses=1 type=i8*] - call void @llvm.lifetime.end(i64 -1, i8* %19) - %20 = bitcast i1 (%struct.vec2*, %struct.vec2*)** %__comp.addr.i to i8* ; [#uses=1 type=i8*] - call void @llvm.lifetime.end(i64 -1, i8* %20) -} - -define i32 @main() { -entry: - %retval = alloca i32, align 4 ; [#uses=1] - store i32 0, i32* %retval - %b = getelementptr inbounds i32* %retval, i32 0, i32 1 ; [#uses=1] ; force __stackBase__ to appear! - %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str, i32 0, i32 0)) ; [#uses=0] - call i32 (i32)* @nonexistant(i32 %b) ; keep %b alive - ret i32 0 -} - diff --git a/tests/cases/lifetime.py b/tests/cases/lifetime.py deleted file mode 100644 index 3bb9cbac..00000000 --- a/tests/cases/lifetime.py +++ /dev/null @@ -1,6 +0,0 @@ -if Settings.MICRO_OPTS: - assert '__stackBase__' in generated, 'There should be some stack activity (without which, we cannot do the next checks)' - assert '__stackBase__+4' not in generated, 'All variables should have been nativized' - assert '__stackBase__+8' not in generated, 'All variables should have been nativized' - assert 'comp_addr' not in generated, 'This variable should have been eliminated during analysis' - diff --git a/tests/lifetime.ll b/tests/lifetime.ll new file mode 100644 index 00000000..058d6b4a --- /dev/null +++ b/tests/lifetime.ll @@ -0,0 +1,37 @@ +; ModuleID = '/tmp/emscripten/tmp/src.cpp.o' +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32" +target triple = "i386-pc-linux-gnu" + +%struct.vec2 = type { float, float } + +@.str = private unnamed_addr constant [15 x i8] c"hello, world!\0A\00" ; [#uses=1] + +; [#uses=1] +declare i32 @printf(i8* noalias, ...) + +define linkonce_odr i32 @vec2Length(%struct.vec2* %this) nounwind align 2 { +entry: + %__first.addr.i = alloca %struct.vec2*, align 4 ; [#uses=3 type=%struct.vec2**] + %__last.addr.i = alloca %struct.vec2*, align 4 ; [#uses=3 type=%struct.vec2**] + %__comp.addr.i = alloca %struct.vec2*, align 4 ; [#uses=2 type=%struct.vec2**] + %a13 = bitcast %struct.vec2** %__first.addr.i to i8* ; [#uses=1 type=i8*] + call void @llvm.lifetime.start(i64 -1, i8* %a13) + %a14 = bitcast %struct.vec2** %__last.addr.i to i8* ; [#uses=1 type=i8*] + call void @llvm.lifetime.start(i64 -1, i8* %a14) + %a18 = bitcast %struct.vec2** %__first.addr.i to i8* ; [#uses=1 type=i8*] + call void @llvm.lifetime.end(i64 -1, i8* %a18) + %a19 = bitcast %struct.vec2** %__last.addr.i to i8* ; [#uses=1 type=i8*] + call void @llvm.lifetime.end(i64 -1, i8* %a19) + ret i32 0 +} + +define i32 @main() { +entry: + %retval = alloca i32, align 4 ; [#uses=1] + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str, i32 0, i32 0)) ; [#uses=0] + ret i32 0 +} + +declare void @llvm.lifetime.start(i64, i8*) +declare void @llvm.lifetime.end(i64, i8*) + diff --git a/tests/runner.py b/tests/runner.py index fd447863..b27d2837 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -4653,17 +4653,31 @@ def process(filename): 'hello python world!\n[0, 2, 4, 6]\n5\n22\n5.470000', args=['-S', '-c' '''print "hello python world!"; print [x*2 for x in range(4)]; t=2; print 10-3-t; print (lambda x: x*2)(11); print '%f' % 5.47''']) + def test_lifetime(self): + if self.emcc_args is None: return self.skip('test relies on emcc opts') + + try: + os.environ['EMCC_LEAVE_INPUTS_RAW'] = '1' + + self.do_ll_run(path_from_root('tests', 'lifetime.ll'), 'hello, world!\n') + if '-O1' in self.emcc_args or '-O2' in self.emcc_args: + assert 'a18' not in open(os.path.join(self.get_dir(), 'src.cpp.o.js')).read(), 'lifetime stuff and their vars must be culled' + else: + assert 'a18' in open(os.path.join(self.get_dir(), 'src.cpp.o.js')).read(), "without opts, it's there" + + finally: + del os.environ['EMCC_LEAVE_INPUTS_RAW'] + # Test cases in separate files. Note that these files may contain invalid .ll! # They are only valid enough for us to read for test purposes, not for llvm-as # to process. def test_cases(self): - try: - self.banned_js_engines = [NODE_JS] # node issue 1669, exception causes stdout not to be flushed + if Building.LLVM_OPTS: return self.skip("Our code is not exactly 'normal' llvm assembly") + try: os.environ['EMCC_LEAVE_INPUTS_RAW'] = '1' - + self.banned_js_engines = [NODE_JS] # node issue 1669, exception causes stdout not to be flushed Settings.CHECK_OVERFLOWS = 0 - if Building.LLVM_OPTS: return self.skip("Our code is not exactly 'normal' llvm assembly") for name in glob.glob(path_from_root('tests', 'cases', '*.ll')): shortname = name.replace('.ll', '') |