[pypy-commit] pypy s390x-backend: label now loads the constant pool when it is entered. the jump back within the same loop (peeled loop does not reload the literal pool, because it is not changed)

plan_rich noreply at buildbot.pypy.org
Wed Nov 11 09:46:01 EST 2015


Author: Richard Plangger <planrichi at gmail.com>
Branch: s390x-backend
Changeset: r80631:45f50d672a78
Date: 2015-11-09 12:07 +0100
http://bitbucket.org/pypy/pypy/changeset/45f50d672a78/

Log:	label now loads the constant pool when it is entered. the jump back
	within the same loop (peeled loop does not reload the literal pool,
	because it is not changed)

diff --git a/rpython/jit/backend/zarch/assembler.py b/rpython/jit/backend/zarch/assembler.py
--- a/rpython/jit/backend/zarch/assembler.py
+++ b/rpython/jit/backend/zarch/assembler.py
@@ -245,11 +245,13 @@
 
         regalloc = Regalloc(assembler=self)
         #
+        self.pool.pre_assemble(self, operations)
+        entrypos = self.mc.get_relative_pos()
+        self.mc.LARL(r.POOL, l.halfword(self.pool.pool_start - entrypos))
         self._call_header_with_stack_check()
         operations = regalloc.prepare_loop(inputargs, operations,
                                            looptoken, clt.allgcrefs)
         looppos = self.mc.get_relative_pos()
-        self.pool.pre_assemble(self, operations)
         frame_depth_no_fixed_size = self._assemble(regalloc, inputargs,
                                                    operations)
         self.update_frame_depth(frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE)
@@ -278,7 +280,7 @@
             looptoken._zarch_rawstart = rawstart
             looptoken._zarch_fullsize = full_size
             looptoken._zarch_ops_offset = ops_offset
-        looptoken._ll_function_addr = rawstart
+        looptoken._ll_function_addr = rawstart + entrypos
         if logger:
             logger.log_loop(inputargs, operations, 0, "rewritten",
                             name=loopname, ops_offset=ops_offset)
@@ -308,13 +310,14 @@
 
         arglocs = self.rebuild_faillocs_from_descr(faildescr, inputargs)
         regalloc = Regalloc(assembler=self)
+        self.pool.pre_assemble(self, operations, bridge=True)
         startpos = self.mc.get_relative_pos()
+        self.mc.LARL(r.POOL, l.halfword(self.pool.pool_start - startpos))
         operations = regalloc.prepare_bridge(inputargs, arglocs,
                                              operations,
                                              self.current_clt.allgcrefs,
                                              self.current_clt.frame_info)
         self._check_frame_depth(self.mc, regalloc.get_gcmap())
-        self.pool.pre_assemble(self, operations, bridge=True)
         frame_depth_no_fixed_size = self._assemble(regalloc, inputargs, operations)
         codeendpos = self.mc.get_relative_pos()
         self.pool.post_assemble(self)
@@ -326,7 +329,7 @@
         debug_bridge(descr_number, rawstart, codeendpos)
         self.patch_pending_failure_recoveries(rawstart)
         # patch the jump from original guard
-        self.patch_jump_for_descr(faildescr, rawstart)
+        self.patch_jump_for_descr(faildescr, rawstart + startpos)
         ops_offset = self.mc.ops_offset
         frame_depth = max(self.current_clt.frame_info.jfi_frame_depth,
                           frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE)
@@ -345,7 +348,6 @@
         # Updates the pool address
         mc = InstrBuilder()
         mc.write_i64(adr_new_target)
-        print "addr is", hex(adr_new_target), "writing to", hex(faildescr.adr_jump_offset)
         mc.copy_to_raw_memory(faildescr.adr_jump_offset)
         assert faildescr.adr_jump_offset != 0
         faildescr.adr_jump_offset = 0    # means "patched"
@@ -353,7 +355,6 @@
     def fixup_target_tokens(self, rawstart):
         for targettoken in self.target_tokens_currently_compiling:
             targettoken._ll_loop_code += rawstart
-            targettoken._ll_loop_pool += rawstart
         self.target_tokens_currently_compiling = None
 
     def _assemble(self, regalloc, inputargs, operations):
@@ -561,7 +562,9 @@
         pass # TODO
 
     def emit_label(self, op, arglocs, regalloc):
-        pass
+        offset = self.pool.pool_start - self.mc.get_relative_pos()
+        # load the pool address at each label
+        self.mc.LARL(r.POOL, l.halfword(offset))
 
     def emit_jump(self, op, arglocs, regalloc):
         # The backend's logic assumes that the target code is in a piece of
@@ -576,19 +579,18 @@
         assert my_nbargs == target_nbargs
 
         if descr in self.target_tokens_currently_compiling:
-            self.mc.b_offset(descr._ll_loop_code)
+            # a label has a LARL instruction that does not need
+            # to be executed, thus remove the first opcode
+            self.mc.b_offset(descr._ll_loop_code + self.mc.LARL_byte_count)
         else:
             # restore the pool address
             offset = self.pool.get_descr_offset(descr) + \
                      JUMPABS_TARGET_ADDR__POOL_OFFSET
             offset_pool = offset + JUMPABS_POOL_ADDR_POOL_OFFSET
             self.mc.LG(r.SCRATCH, l.pool(offset))
-            # the pool address of the target is saved in the bridge's pool
-            self.mc.LG(r.POOL, l.pool(offset_pool))
             self.mc.BCR(c.ANY, r.SCRATCH)
 
             self.pool.overwrite_64(self.mc, offset, descr._ll_loop_code)
-            self.pool.overwrite_64(self.mc, offset_pool, descr._ll_loop_pool)
 
 
     def emit_finish(self, op, arglocs, regalloc):
diff --git a/rpython/jit/backend/zarch/instruction_builder.py b/rpython/jit/backend/zarch/instruction_builder.py
--- a/rpython/jit/backend/zarch/instruction_builder.py
+++ b/rpython/jit/backend/zarch/instruction_builder.py
@@ -9,6 +9,8 @@
         return 0
     if arg.startswith('i') or arg.startswith('u'):
         return 0
+    if arg.startswith('h'):
+        return 0
     return loc.addr(0)
 
 class builder(object):
@@ -31,6 +33,7 @@
         bidl   - index base displacement (20 bit)
         l4bd   - length base displacement (4 bit)
         l8bd   - length base displacement (8 bit)
+        h32    - halfwords 32 bit (e.g. LARL, or other relative instr.)
 
         note that a suffix 'l' means long, and a prefix length
         """
@@ -174,9 +177,9 @@
     func._arguments_[1] = 'u16'
     return func
 
-def build_ril(mnemonic, (opcode,halfopcode)):
+def build_ril(mnemonic, (opcode,halfopcode), args='r/m,i32'):
     br = is_branch_relative(mnemonic)
-    @builder.arguments('r/m,i32')
+    @builder.arguments(args)
     def encode_ri(self, reg_or_mask, imm32):
         self.writechar(opcode)
         byte = (reg_or_mask & 0xf) << 4 | (ord(halfopcode) & 0xf)
@@ -348,7 +351,7 @@
                 newargs[i] = 0
             elif arg == 'r' or arg == 'r/m' or arg == 'f':
                 newargs[i] = args[i].value
-            elif arg.startswith('i') or arg.startswith('u'):
+            elif arg.startswith('i') or arg.startswith('u') or arg.startswith('h'):
                 newargs[i] = args[i].value
             else:
                 newargs[i] = args[i]
diff --git a/rpython/jit/backend/zarch/instructions.py b/rpython/jit/backend/zarch/instructions.py
--- a/rpython/jit/backend/zarch/instructions.py
+++ b/rpython/jit/backend/zarch/instructions.py
@@ -87,6 +87,7 @@
     'LR':      ('rr',    ['\x18']),
     'LGR':     ('rre',   ['\xB9','\x04']),
     'LG':      ('rxy',   ['\xE3','\x04']),
+    'LARL':    ('ril',   ['\xC0','\x00'], 'r/m,h32'),
 
     # store memory
     'STMG':    ('rsy',   ['\xEB','\x24']),
diff --git a/rpython/jit/backend/zarch/locations.py b/rpython/jit/backend/zarch/locations.py
--- a/rpython/jit/backend/zarch/locations.py
+++ b/rpython/jit/backend/zarch/locations.py
@@ -217,9 +217,11 @@
     return ImmLocation(i)
 
 def pool(off, float=False):
-    print "loading pool", off
     return PoolLoc(off, float)
 
+def halfword(value):
+    return ImmLocation(value//2)
+
 def get_fp_offset(base_ofs, position):
     from rpython.jit.backend.zarch.registers import JITFRAME_FIXED_SIZE
     return base_ofs + WORD * (position + JITFRAME_FIXED_SIZE)
diff --git a/rpython/jit/backend/zarch/pool.py b/rpython/jit/backend/zarch/pool.py
--- a/rpython/jit/backend/zarch/pool.py
+++ b/rpython/jit/backend/zarch/pool.py
@@ -27,7 +27,7 @@
             if descr not in asm.target_tokens_currently_compiling:
                 # this is a 'long' jump instead of a relative jump
                 self.offset_map[descr] = self.size
-                self.reserve_literal(16)
+                self.reserve_literal(8)
         elif op.getopnum() == rop.LABEL:
             descr = op.getdescr()
             descr._ll_loop_pool = self.pool_start
@@ -68,8 +68,7 @@
         # the current solution (gcc does the same), use a literal pool
         # located at register r13. This one can easily offset with 20
         # bit signed values (should be enough)
-        self.pool_start = asm.mc.get_relative_pos() + \
-                          asm.mc.BRAS_byte_count
+        self.pool_start = asm.mc.get_relative_pos()
         for op in operations:
             self.ensure_can_hold_constants(asm, op)
         if self.size == 0:
@@ -78,9 +77,6 @@
         assert self.size % 2 == 0
         #if self.size % 2 == 1:
         #    self.size += 1
-        jump_offset = self.size+asm.mc.BRAS_byte_count
-        assert jump_offset < 2**15-1
-        asm.mc.BRAS(r.POOL, l.imm(jump_offset))
         asm.mc.write('\xFF' * self.size)
         print "pool with %d quad words" % (self.size // 8)
 


More information about the pypy-commit mailing list