icode: fix slot locality for params and return
authorJean Privat <jean@pryen.org>
Tue, 11 Aug 2009 05:28:11 +0000 (01:28 -0400)
committerJean Privat <jean@pryen.org>
Mon, 17 Aug 2009 18:56:53 +0000 (14:56 -0400)
Signed-off-by: Jean Privat <jean@pryen.org>

src/analysis/allocate_iregister_slots.nit
tests/base_closure_single_return.nit [new file with mode: 0644]
tests/sav/base_closure_single_return.sav [new file with mode: 0644]

index dc454a2..0558cb4 100644 (file)
@@ -33,17 +33,23 @@ special ICodeVisitor
        # Second pass is used to assign an effective slot to iregsiters
        var _pass: Int = 0
 
+       # Update locality information of r according to the current iroutine
+       fun mark_locality(r: IRegister)
+       do
+               if r._is_local and r._local_iroutine != _current_ir then
+                       if r._local_iroutine == null then
+                               r._local_iroutine = _current_ir
+                       else
+                               r._is_local = false
+                       end
+               end
+       end
+
        redef fun visit_iregister_read(ic: ICode, r: IRegister)
        do
                var pass = _pass
                if pass == 0 then
-                       if r._is_local and r._local_iroutine != _current_ir then
-                               if r._local_iroutine == null then
-                                       r._local_iroutine = _current_ir
-                               else
-                                       r._is_local = false
-                               end
-                       end
+                       mark_locality(r)
                        _lasts[r] = ic
                        r._slot_index = null
                else if pass == 1 and _lasts.has_key(r) and _lasts[r] == ic then
@@ -55,14 +61,7 @@ special ICodeVisitor
        do
                var pass = _pass
                if pass == 0 then
-                       # Process locality
-                       if r._is_local and r._local_iroutine != _current_ir then
-                               if r._local_iroutine == null then
-                                       r._local_iroutine = _current_ir
-                               else
-                                       r._is_local = false
-                               end
-                       end
+                       mark_locality(r)
                        r._slot_index = null
                        # The first write make it live
                        if not _firsts.has_key(r) then _firsts[r] = ic
@@ -143,10 +142,12 @@ special ICodeVisitor
                        _current_ir = ir
                        for r in ir.params do
                                _firsts[r] = self
+                               mark_locality(r)
                        end
                        super
                        if res != null then
                                _lasts[res] = self
+                               mark_locality(res)
                        end
                        _current_ir = old_ir
                else
diff --git a/tests/base_closure_single_return.nit b/tests/base_closure_single_return.nit
new file mode 100644 (file)
index 0000000..b451b34
--- /dev/null
@@ -0,0 +1,35 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Copyright 2009 Jean Privat <jean@pryen.org>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import kernel
+
+fun foo
+       !f
+do
+       f
+end
+
+fun test: Int
+do
+       var i = 1
+       i.output
+       foo !f do
+               return 2
+       end
+       abort
+end
+
+test.output
diff --git a/tests/sav/base_closure_single_return.sav b/tests/sav/base_closure_single_return.sav
new file mode 100644 (file)
index 0000000..1191247
--- /dev/null
@@ -0,0 +1,2 @@
+1
+2