Explorar o código

* the optimization of converting a multiplication with a power of two to
a shl is moved from n386add/secondpass to nadd/resulttypepass

Jonas Maebe %!s(int64=23) %!d(string=hai) anos
pai
achega
ed2bdb31a6
Modificáronse 2 ficheiros con 82 adicións e 73 borrados
  1. 54 72
      compiler/i386/n386add.pas
  2. 28 1
      compiler/nadd.pas

+ 54 - 72
compiler/i386/n386add.pas

@@ -1443,77 +1443,55 @@ interface
                { the location.register will be filled in later (JM) }
                location_reset(location,LOC_REGISTER,OS_INT);
 
-{$IfNDef NoShlMul}
-               if right.nodetype=ordconstn then
-                swapleftright;
-               If (left.nodetype = ordconstn) and
-                  ispowerof2(tordconstnode(left).value, power) and
-                  not(cs_check_overflow in aktlocalswitches) then
-                 Begin
-                   { This release will be moved after the next }
-                   { instruction by the optimizer. No need to  }
-                   { release left.location, since it's a   }
-                   { constant (JM)                             }
-                   location_release(exprasmlist,right.location);
-                   location.register:=rg.getregisterint(exprasmlist);
-                   cg.a_load_loc_reg(exprasmlist,right.location,location.register);
-                   cg.a_op_const_reg(exprasmlist,OP_SHL,power,location.register);
-                 End
-               Else
-                Begin
-{$EndIf NoShlMul}
-                  regstopush := all_registers;
-                  remove_non_regvars_from_loc(right.location,regstopush);
-                  remove_non_regvars_from_loc(left.location,regstopush);
-                  { now, regstopush does NOT contain EAX and/or EDX if they are }
-                  { used in either the left or the right location, excepts if   }
-                  {they are regvars. It DOES contain them if they are used in   }
-                  { another location (JM)                                       }
-                  if not(R_EAX in rg.unusedregsint) and
-                     (R_EAX in regstopush) then
-                   begin
-                     emit_reg(A_PUSH,S_L,R_EAX);
-                     popeax:=true;
-                   end;
-                  if not(R_EDX in rg.unusedregsint) and
-                     (R_EDX in regstopush) then
-                   begin
-                     emit_reg(A_PUSH,S_L,R_EDX);
-                     popedx:=true;
-                   end;
-                  { left.location can be R_EAX !!! }
-                  rg.getexplicitregisterint(exprasmlist,R_EDI);
-                  { load the left value }
-                  cg.a_load_loc_reg(exprasmlist,left.location,R_EDI);
-                  location_release(exprasmlist,left.location);
-                  { allocate EAX }
-                  if R_EAX in rg.unusedregsint then
-                    exprasmList.concat(tai_regalloc.Alloc(R_EAX));
-                  { load he right value }
-                  cg.a_load_loc_reg(exprasmlist,right.location,R_EAX);
-                  location_release(exprasmlist,right.location);
-                  { allocate EAX if it isn't yet allocated (JM) }
-                  if (R_EAX in rg.unusedregsint) then
-                    exprasmList.concat(tai_regalloc.Alloc(R_EAX));
-                  { also allocate EDX, since it is also modified by }
-                  { a mul (JM)                                      }
-                  if R_EDX in rg.unusedregsint then
-                    exprasmList.concat(tai_regalloc.Alloc(R_EDX));
-                  emit_reg(A_MUL,S_L,R_EDI);
-                  rg.ungetregisterint(exprasmlist,R_EDI);
-                  if R_EDX in rg.unusedregsint then
-                    exprasmList.concat(tai_regalloc.DeAlloc(R_EDX));
-                  if R_EAX in rg.unusedregsint then
-                    exprasmList.concat(tai_regalloc.DeAlloc(R_EAX));
-                  location.register:=rg.getregisterint(exprasmlist);
-                  emit_reg_reg(A_MOV,S_L,R_EAX,location.register);
-                  if popedx then
-                   emit_reg(A_POP,S_L,R_EDX);
-                  if popeax then
-                   emit_reg(A_POP,S_L,R_EAX);
-{$IfNDef NoShlMul}
-                End;
-{$endif NoShlMul}
+               regstopush := all_registers;
+               remove_non_regvars_from_loc(right.location,regstopush);
+               remove_non_regvars_from_loc(left.location,regstopush);
+               { now, regstopush does NOT contain EAX and/or EDX if they are }
+               { used in either the left or the right location, excepts if   }
+               {they are regvars. It DOES contain them if they are used in   }
+               { another location (JM)                                       }
+               if not(R_EAX in rg.unusedregsint) and
+                  (R_EAX in regstopush) then
+                 begin
+                   emit_reg(A_PUSH,S_L,R_EAX);
+                   popeax:=true;
+                 end;
+               if not(R_EDX in rg.unusedregsint) and
+                   (R_EDX in regstopush) then
+                 begin
+                   emit_reg(A_PUSH,S_L,R_EDX);
+                   popedx:=true;
+                 end;
+               { left.location can be R_EAX !!! }
+               rg.getexplicitregisterint(exprasmlist,R_EDI);
+               { load the left value }
+               cg.a_load_loc_reg(exprasmlist,left.location,R_EDI);
+               location_release(exprasmlist,left.location);
+               { allocate EAX }
+               if R_EAX in rg.unusedregsint then
+                 exprasmList.concat(tai_regalloc.Alloc(R_EAX));
+               { load he right value }
+               cg.a_load_loc_reg(exprasmlist,right.location,R_EAX);
+               location_release(exprasmlist,right.location);
+               { allocate EAX if it isn't yet allocated (JM) }
+               if (R_EAX in rg.unusedregsint) then
+                 exprasmList.concat(tai_regalloc.Alloc(R_EAX));
+               { also allocate EDX, since it is also modified by }
+               { a mul (JM)                                      }
+               if R_EDX in rg.unusedregsint then
+                 exprasmList.concat(tai_regalloc.Alloc(R_EDX));
+               emit_reg(A_MUL,S_L,R_EDI);
+               rg.ungetregisterint(exprasmlist,R_EDI);
+               if R_EDX in rg.unusedregsint then
+                 exprasmList.concat(tai_regalloc.DeAlloc(R_EDX));
+               if R_EAX in rg.unusedregsint then
+                 exprasmList.concat(tai_regalloc.DeAlloc(R_EAX));
+               location.register:=rg.getregisterint(exprasmlist);
+               emit_reg_reg(A_MOV,S_L,R_EAX,location.register);
+               if popedx then
+                 emit_reg(A_POP,S_L,R_EDX);
+               if popeax then
+                 emit_reg(A_POP,S_L,R_EAX);
                location_freetemp(exprasmlist,left.location);
                location_freetemp(exprasmlist,right.location);
                exit;
@@ -1573,7 +1551,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.44  2002-07-20 11:58:00  florian
+  Revision 1.45  2002-07-26 11:17:52  jonas
+    * the optimization of converting a multiplication with a power of two to
+      a shl is moved from n386add/secondpass to nadd/resulttypepass
+
+  Revision 1.44  2002/07/20 11:58:00  florian
     * types.pas renamed to defbase.pas because D6 contains a types
       unit so this would conflicts if D6 programms are compiled
     + Willamette/SSE2 instructions to assembler added

+ 28 - 1
compiler/nadd.pas

@@ -605,6 +605,29 @@ implementation
          { if both are orddefs then check sub types }
          else if (ld.deftype=orddef) and (rd.deftype=orddef) then
            begin
+             { optimize multiplacation by a power of 2 }
+             if not(cs_check_overflow in aktlocalswitches) and
+                (nodetype = muln) and
+                (((left.nodetype = ordconstn) and
+                  ispowerof2(tordconstnode(left).value,i)) or
+                 ((right.nodetype = ordconstn) and
+                  ispowerof2(tordconstnode(right).value,i))) then
+               begin
+                 if left.nodetype = ordconstn then
+                   begin
+                     tordconstnode(left).value := i;
+                     result := cshlshrnode.create(shln,right,left);
+                   end
+                 else
+                   begin
+                     tordconstnode(right).value := i;
+                     result := cshlshrnode.create(shln,left,right);
+                   end;
+                 left := nil;
+                 right := nil;
+                 exit;
+               end;
+
              { 2 booleans? Make them equal to the largest boolean }
              if is_boolean(ld) and is_boolean(rd) then
               begin
@@ -1708,7 +1731,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.57  2002-07-23 13:08:16  jonas
+  Revision 1.58  2002-07-26 11:17:52  jonas
+    * the optimization of converting a multiplication with a power of two to
+      a shl is moved from n386add/secondpass to nadd/resulttypepass
+
+  Revision 1.57  2002/07/23 13:08:16  jonas
     * fixed constant set evaluation of new set handling for non-commutative
       operators