Esempio n. 1
0
 def render(self, generator, op):
     assert cmpopcodes.can_branch_directly(op.opname)
     truelbl = generator.unique_label('load_comparision_result_true')
     endlbl = generator.unique_label('load_comparision_result_end')
     cmpopcodes.branch_if(generator, op.opname, truelbl)
     generator.emit(jvm.ICONST, 0)
     generator.goto(endlbl)
     generator.mark(truelbl)
     generator.emit(jvm.ICONST, 1)
     generator.mark(endlbl)
Esempio n. 2
0
File: metavm.py Progetto: ieure/pypy
 def render(self, generator, op):
     assert cmpopcodes.can_branch_directly(op.opname)
     truelbl = generator.unique_label('load_comparision_result_true')
     endlbl = generator.unique_label('load_comparision_result_end')
     cmpopcodes.branch_if(generator, op.opname, truelbl)
     generator.emit(jvm.ICONST, 0)
     generator.goto(endlbl)
     generator.mark(truelbl)
     generator.emit(jvm.ICONST, 1)
     generator.mark(endlbl)
Esempio n. 3
0
    def render_normal_block(self, block):
        """
        Overload OOFunction.render_normal_block: we intercept blocks where the
        exitcase tests a bool variable with one use so as to generate more
        efficient code.  For example, the naive code generation for a test
        like 'if x < y' yields something like:
        
           push x
           push y
           jump_if_less_than true
        false:
           push 0
           jump done
        true:
           push 1
        done:
           store_into_local_var
           load_from_local_var
           jump_if_true true_destination
           jump false_destination

        when it could (should) be

           push x
           push y
           jump_if_less_than true_destination
           jump false_destination
        """
        def not_in_link_args(v):
            for link in block.exits:
                if v in link.args: return False
            return True

        def true_false_exits():
            if block.exits[0].exitcase:
                return block.exits[0], block.exits[1]
            return block.exits[1], block.exits[0]

        if block.operations:
            # Look for a case where the block switches on a bool variable
            # which is produced by the last operation and not used
            # anywhere else, and where the last operation is a comparison.

            # Watch out for a last operation like:
            #   v1 = same_as([int_lt(i, j)])
            last_op = block.operations[-1]
            while (last_op.opname == "same_as"
                   and isinstance(last_op.args[0], SubOperation)):
                last_op = last_op.args[0].op

            if (block.exitswitch is not None
                    and block.exitswitch.concretetype is ootype.Bool
                    and block.operations[-1].result is block.exitswitch
                    and can_branch_directly(last_op.opname)
                    and not_in_link_args(block.exitswitch)):

                self.generator.add_comment(
                    "short-circuit final comparison on %s, block has %d ops" %
                    (block.exitswitch, len(block.operations)))

                for op in block.operations[:-1]:
                    self._render_op(op)

                self.generator.add_comment(
                    "inlining comparison: %r" % (last_op), )
                for arg in last_op.args:
                    self.ilasm.load(arg)
                truelink, falselink = true_false_exits()
                true_label = self.next_label('link_true')
                branch_if(self.ilasm, last_op.opname, true_label)
                self._follow_link(falselink)
                self.set_label(true_label)
                self._follow_link(truelink)
                return

        return OOFunction.render_normal_block(self, block)
Esempio n. 4
0
    def render_normal_block(self, block):
        """
        Overload OOFunction.render_normal_block: we intercept blocks where the
        exitcase tests a bool variable with one use so as to generate more
        efficient code.  For example, the naive code generation for a test
        like 'if x < y' yields something like:
        
           push x
           push y
           jump_if_less_than true
        false:
           push 0
           jump done
        true:
           push 1
        done:
           store_into_local_var
           load_from_local_var
           jump_if_true true_destination
           jump false_destination

        when it could (should) be

           push x
           push y
           jump_if_less_than true_destination
           jump false_destination
        """

        def not_in_link_args(v):
            for link in block.exits:
                if v in link.args: return False
            return True

        def true_false_exits():
            if block.exits[0].exitcase:
                return block.exits[0], block.exits[1]
            return block.exits[1], block.exits[0]

        if block.operations:
            # Look for a case where the block switches on a bool variable
            # which is produced by the last operation and not used
            # anywhere else, and where the last operation is a comparison.

            # Watch out for a last operation like:
            #   v1 = same_as([int_lt(i, j)])
            last_op = block.operations[-1]
            while (last_op.opname == "same_as" and
                   isinstance(last_op.args[0], SubOperation)):
                last_op = last_op.args[0].op
            
            if (block.exitswitch is not None and
                block.exitswitch.concretetype is ootype.Bool and
                block.operations[-1].result is block.exitswitch and
                can_branch_directly(last_op.opname) and
                not_in_link_args(block.exitswitch)):

                self.generator.add_comment(
                    "short-circuit final comparison on %s, block has %d ops" % (
                    block.exitswitch, len(block.operations)))

                for op in block.operations[:-1]:
                    self._render_op(op)
                    
                self.generator.add_comment(
                    "inlining comparison: %r" % (last_op),)
                for arg in last_op.args:
                    self.ilasm.load(arg)
                truelink, falselink = true_false_exits()
                true_label = self.next_label('link_true')
                branch_if(self.ilasm, last_op.opname, true_label)
                self._follow_link(falselink)
                self.set_label(true_label)
                self._follow_link(truelink)
                return

        return OOFunction.render_normal_block(self, block)