Selaa lähdekoodia

* fixed code generation for -Og switch
* copied createtempparaloc() method from i386 parameter manager to avoid copying for larger value parameters (see 2692)
* do not copy memory if references are equal in g_concatcopy()
* do not emit some strings used for debugging into assembly file in g_concatcopy by default anymore
* simplification of boolean expression in calc_stackframe_size()

git-svn-id: trunk@2694 -

tom_at_work 19 vuotta sitten
vanhempi
commit
b309574e22
3 muutettua tiedostoa jossa 43 lisäystä ja 15 poistoa
  1. 25 13
      compiler/powerpc64/cgcpu.pas
  2. 15 0
      compiler/powerpc64/cpupara.pas
  3. 3 2
      compiler/powerpc64/cpupi.pas

+ 25 - 13
compiler/powerpc64/cgcpu.pas

@@ -154,7 +154,14 @@ type
     immediate as required by some PowerPC instructions }
     function hasLargeOffset(const ref : TReference) : Boolean; inline;
 
-    procedure a_call_name_direct(list: taasmoutput; s: string; prependDot : boolean; addNOP : boolean);
+    { generates code to call a method with the given string name. The boolean options
+     control code generation. If prependDot is true, a single dot character is prepended to
+     the string, if addNOP is true a single NOP instruction is added after the call, and
+     if includeCall is true, the method is marked as having a call, not if false. This
+     option is particularly useful to prevent generation of a larger stack frame for the 
+     register save and restore helper functions. }
+    procedure a_call_name_direct(list: taasmoutput; s: string; prependDot : boolean; 
+      addNOP : boolean; includeCall : boolean = true);
 
     { emits code to store the given value a into the TOC (if not already in there), and load it from there
      as well }
@@ -552,7 +559,7 @@ begin
     a_call_name_direct(list, s, true, true);
 end;
 
-procedure tcgppc.a_call_name_direct(list: taasmoutput; s: string; prependDot : boolean; addNOP : boolean);
+procedure tcgppc.a_call_name_direct(list: taasmoutput; s: string; prependDot : boolean; addNOP : boolean; includeCall : boolean);
 begin
   if (prependDot) then
     s := '.' + s;
@@ -560,9 +567,9 @@ begin
     AT_FUNCTION)));
   if (addNOP) then
     list.concat(taicpu.op_none(A_NOP));
-  { the compiler does not properly set this flag anymore in pass 1, and
-   for now we only need it after pass 2 (I hope) (JM) }
-  include(current_procinfo.flags, pi_do_call);
+
+  if (includeCall) then
+    include(current_procinfo.flags, pi_do_call);
 end;
 
 
@@ -1326,12 +1333,12 @@ var
       mayNeedLRStore := false;
       if ((fprcount > 0) and (gprcount > 0)) then begin
         a_op_const_reg_reg(list, OP_SUB, OS_INT, 8 * fprcount, NR_R1, NR_R12);
-        a_call_name_direct(list, '_savegpr1_' + intToStr(32-gprcount), false, false);
-        a_call_name_direct(list, '_savefpr_' + intToStr(32-fprcount), false, false);
+        a_call_name_direct(list, '_savegpr1_' + intToStr(32-gprcount), false, false, false);
+        a_call_name_direct(list, '_savefpr_' + intToStr(32-fprcount), false, false, false);
       end else if (gprcount > 0) then
-        a_call_name_direct(list, '_savegpr0_' + intToStr(32-gprcount), false, false)
+        a_call_name_direct(list, '_savegpr0_' + intToStr(32-gprcount), false, false, false)
       else if (fprcount > 0) then
-        a_call_name_direct(list, '_savefpr_' + intToStr(32-fprcount), false, false)
+        a_call_name_direct(list, '_savefpr_' + intToStr(32-fprcount), false, false, false)
       else
         mayNeedLRStore := true;
     end else begin
@@ -1461,7 +1468,7 @@ var
       needsExitCode := false;
       if ((fprcount > 0) and (gprcount > 0)) then begin
         a_op_const_reg_reg(list, OP_SUB, OS_INT, 8 * fprcount, NR_R1, NR_R12);
-        a_call_name_direct(list, '_restgpr1_' + intToStr(32-gprcount), false, false);
+        a_call_name_direct(list, '_restgpr1_' + intToStr(32-gprcount), false, false, false);
         a_jmp_name(list, '_restfpr_' + intToStr(32-fprcount));
       end else if (gprcount > 0) then
         a_jmp_name(list, '_restgpr0_' + intToStr(32-gprcount))
@@ -1520,7 +1527,6 @@ begin
   { calculate stack frame }
   localsize := tppcprocinfo(current_procinfo).calc_stackframe_size(
     gprcount, fprcount);
-
   { CR register not supported }
 
   { restore stack pointer }
@@ -1656,15 +1662,21 @@ begin
     internalerror(2002072704);
   list.concat(tai_comment.create(strpnew('g_concatcopy1 ' + inttostr(len) + ' bytes left ')));
 {$ENDIF extdebug}
+  { if the references are equal, exit, there is no need to copy anything } 
+  if (references_equal(source, dest)) then
+    exit;
+
   { make sure short loads are handled as optimally as possible;
    note that the data here never overlaps, so we can do a forward
    copy at all times.
    NOTE: maybe use some scratch registers to pair load/store instructions
   }
-
+  
   if (len <= maxmoveunit) then begin
     src := source; dst := dest;
+    {$IFDEF extdebug}
     list.concat(tai_comment.create(strpnew('g_concatcopy3 ' + inttostr(src.offset) + ' ' + inttostr(dst.offset))));
+    {$ENDIF extdebug}
     while (len <> 0) do begin
       if (len = 8) then begin
         a_load_ref_ref(list, OS_64, OS_64, src, dst);    
@@ -2167,7 +2179,7 @@ begin
   ref.refaddr := addr_pic;
 
   {$IFDEF EXTDEBUG}
-  list.concat(tai_comment.create(strpnew('loading value from TOC reference for ' + symbol)));
+  list.concat(tai_comment.create(strpnew('loading value from TOC reference for ' + symname)));
   {$ENDIF EXTDEBUG}
   cg.a_load_ref_reg(list, OS_INT, OS_INT, ref, reg);
 end;

+ 15 - 0
compiler/powerpc64/cpupara.pas

@@ -47,6 +47,7 @@ type
       tvarargsparalist): longint; override;
     procedure create_funcretloc_info(p: tabstractprocdef; side: tcallercallee);
 
+    procedure createtempparaloc(list: taasmoutput;calloption : tproccalloption;parasym : tparavarsym;var cgpara:TCGPara);
   private
     procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister;
       var cur_stack_offset: aword);
@@ -487,6 +488,20 @@ begin
   result := true;
 end;
 
+procedure tppcparamanager.createtempparaloc(list: taasmoutput;calloption : tproccalloption;parasym : tparavarsym;var cgpara:TCGPara);
+var
+  paraloc : pcgparalocation;
+begin
+  paraloc:=parasym.paraloc[callerside].location;
+  { Do not create a temporary if the value is pushed }
+  if assigned(paraloc) and
+    (paraloc^.loc=LOC_REFERENCE) and
+    (paraloc^.reference.index=NR_STACK_POINTER_REG) then
+    duplicateparaloc(list,calloption,parasym,cgpara)
+  else
+    inherited createtempparaloc(list,calloption,parasym,cgpara);
+end;
+
 begin
   paramanager := tppcparamanager.create;
 end.

+ 3 - 2
compiler/powerpc64/cpupi.pas

@@ -106,9 +106,10 @@ begin
     result := align(numgpr * tcgsize2size[OS_INT] +
         numfpr * tcgsize2size[OS_FLOAT], ELF_STACK_ALIGN);
 
-    if not ((not (pi_do_call in flags)) and (tg.lasttemp = tg.firsttemp) and
-      (result <= RED_ZONE_SIZE)) then
+    if (pi_do_call in flags) or (tg.lasttemp <> tg.firsttemp) or
+      (result > RED_ZONE_SIZE) then begin
       result := align(result + tg.lasttemp, ELF_STACK_ALIGN);
+    end;
   end else
     result := align(tg.lasttemp, ELF_STACK_ALIGN);
 end;