2
0
Эх сурвалжийг харах

* reorder processing of left/right for add nodes somewhat to make
it easier for the register allocator/optimizer to reduce the
number of intermediate stores to the stack

git-svn-id: branches/jvmbackend@18341 -

Jonas Maebe 14 жил өмнө
parent
commit
d3a4866cf5

+ 47 - 13
compiler/jvm/njvmadd.pas

@@ -31,7 +31,7 @@ interface
 
     type
 
-       { njvmadd }
+       { tjvmaddnode }
 
        tjvmaddnode = class(tcgaddnode)
        protected
@@ -41,6 +41,7 @@ interface
 
           procedure second_generic_compare;
 
+          procedure pass_left_right;override;
           procedure second_addfloat;override;
           procedure second_cmpfloat;override;
           procedure second_cmpboolean;override;
@@ -89,42 +90,53 @@ interface
 
 
     procedure tjvmaddnode.second_generic_compare;
+      var
+        cmpop: TOpCmp;
       begin
         pass_left_right;
-        if (nf_swapped in flags) then
+        { swap the operands to make it easier for the optimizer to optimize
+          the operand stack slot reloading in case both are in a register }
+        if (left.location.loc in [LOC_REGISTER,LOC_CREGISTER]) and
+           (right.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
           swapleftright;
+        cmpop:=cmpnode2signedtopcmp;
+        if (nf_swapped in flags) then
+          cmpop:=swap_opcmp(cmpop);
         location_reset(location,LOC_JUMP,OS_NO);
 
         if left.location.loc in [LOC_REGISTER,LOC_CREGISTER] then
-          hlcg.a_cmp_loc_reg_label(current_asmdata.CurrAsmList,left.resultdef,cmpnode2signedtopcmp,right.location,left.location.register,current_procinfo.CurrTrueLabel)
+          hlcg.a_cmp_loc_reg_label(current_asmdata.CurrAsmList,left.resultdef,cmpop,right.location,left.location.register,current_procinfo.CurrTrueLabel)
         else case right.location.loc of
           LOC_REGISTER,LOC_CREGISTER:
-            hlcg.a_cmp_reg_loc_label(current_asmdata.CurrAsmList,left.resultdef,cmpnode2signedtopcmp,right.location.register,left.location,current_procinfo.CurrTrueLabel);
+            hlcg.a_cmp_reg_loc_label(current_asmdata.CurrAsmList,left.resultdef,cmpop,right.location.register,left.location,current_procinfo.CurrTrueLabel);
           LOC_REFERENCE,LOC_CREFERENCE:
-            hlcg.a_cmp_ref_loc_label(current_asmdata.CurrAsmList,left.resultdef,cmpnode2signedtopcmp,right.location.reference,left.location,current_procinfo.CurrTrueLabel);
+            hlcg.a_cmp_ref_loc_label(current_asmdata.CurrAsmList,left.resultdef,cmpop,right.location.reference,left.location,current_procinfo.CurrTrueLabel);
           LOC_CONSTANT:
-            hlcg.a_cmp_const_loc_label(current_asmdata.CurrAsmList,left.resultdef,cmpnode2signedtopcmp,right.location.value,left.location,current_procinfo.CurrTrueLabel);
+            hlcg.a_cmp_const_loc_label(current_asmdata.CurrAsmList,left.resultdef,cmpop,right.location.value,left.location,current_procinfo.CurrTrueLabel);
           else
             internalerror(2011010413);
         end;
         hlcg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrFalseLabel);
       end;
 
+    procedure tjvmaddnode.pass_left_right;
+      begin
+        swapleftright;
+        inherited pass_left_right;
+      end;
+
 
     procedure tjvmaddnode.second_addfloat;
       var
         op : TAsmOp;
+        commutative : boolean;
       begin
         pass_left_right;
-        if (nf_swapped in flags) then
-          swapleftright;
-
-        thlcgjvm(hlcg).a_load_loc_stack(current_asmdata.CurrAsmList,left.resultdef,left.location);
-        thlcgjvm(hlcg).a_load_loc_stack(current_asmdata.CurrAsmList,right.resultdef,right.location);
 
         location_reset(location,LOC_FPUREGISTER,def_cgsize(resultdef));
         location.register:=hlcg.getfpuregister(current_asmdata.CurrAsmList,resultdef);
 
+        commutative:=false;
         case nodetype of
           addn :
             begin
@@ -132,6 +144,7 @@ interface
                 op:=a_dadd
               else
                 op:=a_fadd;
+              commutative:=true;
             end;
           muln :
             begin
@@ -139,6 +152,7 @@ interface
                 op:=a_dmul
               else
                 op:=a_fmul;
+              commutative:=true;
             end;
           subn :
             begin
@@ -158,6 +172,19 @@ interface
             internalerror(2011010402);
         end;
 
+        { swap the operands to make it easier for the optimizer to optimize
+          the operand stack slot reloading (non-commutative operations must
+          always be in the correct order though) }
+        if (commutative and
+            (left.location.loc in [LOC_FPUREGISTER,LOC_CFPUREGISTER]) and
+            (right.location.loc in [LOC_FPUREGISTER,LOC_CFPUREGISTER])) or
+           (not commutative and
+            (nf_swapped in flags)) then
+          swapleftright;
+
+        thlcgjvm(hlcg).a_load_loc_stack(current_asmdata.CurrAsmList,left.resultdef,left.location);
+        thlcgjvm(hlcg).a_load_loc_stack(current_asmdata.CurrAsmList,right.resultdef,right.location);
+
         current_asmdata.CurrAsmList.concat(taicpu.op_none(op));
         thlcgjvm(hlcg).decstack(current_asmdata.CurrAsmList,1+ord(location.size=OS_F64));
         { could be optimized in the future by keeping the results on the stack,
@@ -171,10 +198,17 @@ interface
     procedure tjvmaddnode.second_cmpfloat;
       var
         op : tasmop;
+        cmpop: TOpCmp;
       begin
         pass_left_right;
-        if (nf_swapped in flags) then
+        { swap the operands to make it easier for the optimizer to optimize
+          the operand stack slot reloading in case both are in a register }
+        if (left.location.loc in [LOC_FPUREGISTER,LOC_CFPUREGISTER]) and
+           (right.location.loc in [LOC_FPUREGISTER,LOC_CFPUREGISTER]) then
           swapleftright;
+        cmpop:=cmpnode2signedtopcmp;
+        if (nf_swapped in flags) then
+          cmpop:=swap_opcmp(cmpop);
         location_reset(location,LOC_JUMP,OS_NO);
 
         thlcgjvm(hlcg).a_load_loc_stack(current_asmdata.CurrAsmList,left.resultdef,left.location);
@@ -195,7 +229,7 @@ interface
         current_asmdata.CurrAsmList.concat(taicpu.op_none(op));
         thlcgjvm(hlcg).decstack(current_asmdata.CurrAsmList,(1+ord(left.location.size=OS_F64))*2-1);
 
-        current_asmdata.CurrAsmList.concat(taicpu.op_sym(opcmp2if[cmpnode2signedtopcmp],current_procinfo.CurrTrueLabel));
+        current_asmdata.CurrAsmList.concat(taicpu.op_sym(opcmp2if[cmpop],current_procinfo.CurrTrueLabel));
         thlcgjvm(hlcg).decstack(current_asmdata.CurrAsmList,1);
         hlcg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrFalseLabel);
       end;

+ 1 - 1
compiler/ncgadd.pas

@@ -34,7 +34,7 @@ interface
           procedure pass_generate_code;override;
          protected
           { call secondpass for both left and right }
-          procedure pass_left_right;
+          procedure pass_left_right; virtual;
           { set the register of the result location }
           procedure set_result_location_reg;
           { load left and right nodes into registers }