Sfoglia il codice sorgente

* updates for inlining

peter 22 anni fa
parent
commit
22158bfb99
4 ha cambiato i file con 159 aggiunte e 59 eliminazioni
  1. 75 7
      compiler/i386/cpupara.pas
  2. 41 40
      compiler/ncgcal.pas
  3. 9 3
      compiler/ncgutil.pas
  4. 34 9
      compiler/paramgr.pas

+ 75 - 7
compiler/i386/cpupara.pas

@@ -51,6 +51,7 @@ unit cpupara;
        private
           procedure create_funcret_paraloc_info(p : tabstractprocdef; side: tcallercallee);
           function create_stdcall_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
+          function create_inline_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
           function create_register_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
        end;
 
@@ -359,16 +360,80 @@ unit cpupara;
       end;
 
 
+    function ti386paramanager.create_inline_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
+      var
+        hp : tparaitem;
+        paraloc : tparalocation;
+        l,
+        varalign,
+        parasize : longint;
+      begin
+        parasize:=0;
+        hp:=tparaitem(p.para.first);
+        while assigned(hp) do
+          begin
+            if push_addr_param(hp.paratyp,hp.paratype.def,p.proccalloption) then
+              paraloc.size:=OS_ADDR
+            else
+              paraloc.size:=def_cgsize(hp.paratype.def);
+            if paraloc.size=OS_NO then
+              internalerror(200309301);
+            { Indicate parameter is loaded in register, the register
+              will be allocated when the allocpara is called }
+            paraloc.loc:=LOC_REGISTER;
+            paraloc.register:=NR_NO;
+(*
+                paraloc.loc:=LOC_REFERENCE;
+                if assigned(current_procinfo) then
+                  paraloc.reference.index:=current_procinfo.framepointer
+                else
+                  paraloc.reference.index:=NR_FRAME_POINTER_REG;
+                l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
+                varalign:=size_2_align(l);
+                paraloc.reference.offset:=parasize+target_info.first_parm_offset;
+                varalign:=used_align(varalign,p.paraalign,p.paraalign);
+                parasize:=align(parasize+l,varalign);
+*)
+            hp.paraloc[side]:=paraloc;
+            hp:=tparaitem(hp.next);
+          end;
+        { We need to return the size allocated }
+        result:=parasize;
+      end;
+
+
     procedure ti386paramanager.create_paraloc_info(p : tabstractprocdef; side: tcallercallee);
       var
         l : longint;
       begin
-        if (p.proccalloption=pocall_register) or
-           ((pocall_default=pocall_register) and
-            (p.proccalloption in [pocall_compilerproc,pocall_internproc])) then
-          l:=create_register_paraloc_info(p,side)
-        else
-          l:=create_stdcall_paraloc_info(p,side);
+        case p.proccalloption of
+          pocall_register :
+            l:=create_register_paraloc_info(p,side);
+          pocall_inline :
+            begin
+              if inlining_procedure then
+                l:=create_inline_paraloc_info(p,side)
+              else
+                begin
+                  { Use default calling }
+                  if (pocall_default=pocall_register) then
+                    l:=create_register_paraloc_info(p,side)
+                  else
+                    l:=create_stdcall_paraloc_info(p,side);
+                end;
+            end;
+          pocall_compilerproc,
+          pocall_internproc :
+            begin
+              { Use default calling }
+              if (pocall_default=pocall_register) then
+                l:=create_register_paraloc_info(p,side)
+              else
+                l:=create_stdcall_paraloc_info(p,side);
+            end;
+          else
+            l:=create_stdcall_paraloc_info(p,side);
+        end;
         create_funcret_paraloc_info(p,side);
         { Store the size of the parameters on the stack }
         if (side=calleeside) then
@@ -381,7 +446,10 @@ begin
 end.
 {
   $Log$
-  Revision 1.33  2003-09-28 17:55:04  peter
+  Revision 1.34  2003-09-30 21:02:37  peter
+    * updates for inlining
+
+  Revision 1.33  2003/09/28 17:55:04  peter
     * parent framepointer changed to hidden parameter
     * tloadparentfpnode added
 

+ 41 - 40
compiler/ncgcal.pas

@@ -977,7 +977,6 @@ implementation
          pushedother : tpushedsavedother;
          oldpushedparasize : longint;
          oldaktcallnode : tcallnode;
-         oldprocdef : tprocdef;
          i : longint;
          oldprocinfo : tprocinfo;
          oldinlining_procedure : boolean;
@@ -998,23 +997,19 @@ implementation
 {$warning TODO Fix inlining}
          internalerror(200309211);
 
-(*
          if not(assigned(procdefinition) and (procdefinition.deftype=procdef)) then
            internalerror(200305262);
 
          oldinlining_procedure:=inlining_procedure;
-         oldprocdef:=current_procinfo.procdef;
          oldprocinfo:=current_procinfo;
          { we're inlining a procedure }
          inlining_procedure:=true;
 
-         { calculate the parameter info for the procdef }
-         if not procdefinition.has_paraloc_info then
-           begin
-             paramanager.create_paraloc_info(procdefinition,callerside);
-             procdefinition.has_paraloc_info:=true;
-           end;
+         { calculate registers to pass the parameters }
+         paramanager.create_paraloc_info(procdefinition,callerside);
+         paramanager.create_paraloc_info(procdefinition,calleeside);
 
+(*
          { deallocate the registers used for the current procedure's regvars }
          if assigned(current_procinfo.procdef.regvarinfo) then
            begin
@@ -1038,11 +1033,13 @@ implementation
                        internalerror(200301232);
                      end;
            end;
+*)
 
          { create temp procinfo }
          current_procinfo:=cprocinfo.create(nil);
          current_procinfo.procdef:=tprocdef(procdefinition);
 
+(*
          { Localsymtable }
          current_procinfo.procdef.localst.symtablelevel:=oldprocdef.localst.symtablelevel;
          if current_procinfo.procdef.localst.datasize>0 then
@@ -1073,34 +1070,42 @@ implementation
                'inlined para symtable ('+tostr(current_procinfo.procdef.parast.datasize)+' bytes) is at offset '+tostr(current_procinfo.procdef.parast.address_fixup))));
 {$endif extdebug}
            end;
+*)
 
+         { Add inling start }
          exprasmList.concat(Tai_Marker.Create(InlineStart));
 {$ifdef extdebug}
          exprasmList.concat(tai_comment.Create(strpnew('Start of inlined proc')));
 {$endif extdebug}
+
+         { Allocate parameters and locals }
+         gen_alloc_parast(exprasmlist,tparasymtable(current_procinfo.procdef.parast));
+         if current_procinfo.procdef.localst.symtabletype=localsymtable then
+           gen_alloc_localst(exprasmlist,tlocalsymtable(current_procinfo.procdef.localst));
+
 {$ifdef GDB}
          if (cs_debuginfo in aktmoduleswitches) then
            begin
              objectlibrary.getaddrlabel(startlabel);
              objectlibrary.getaddrlabel(endlabel);
              cg.a_label(exprasmlist,startlabel);
-             tprocdef(procdefinition).localst.symtabletype:=inlinelocalsymtable;
-             procdefinition.parast.symtabletype:=inlineparasymtable;
+//             tprocdef(procdefinition).localst.symtabletype:=inlinelocalsymtable;
+//             procdefinition.parast.symtabletype:=inlineparasymtable;
 
              { Here we must include the para and local symtable info }
              procdefinition.concatstabto(withdebuglist);
 
              { set it back for safety }
-             tprocdef(procdefinition).localst.symtabletype:=localsymtable;
-             procdefinition.parast.symtabletype:=parasymtable;
+//             tprocdef(procdefinition).localst.symtabletype:=localsymtable;
+//             procdefinition.parast.symtabletype:=parasymtable;
 
-             mangled_length:=length(oldprocdef.mangledname);
+             mangled_length:=length(oldprocinfo.procdef.mangledname);
              getmem(pp,mangled_length+50);
              strpcopy(pp,'192,0,0,'+startlabel.name);
              if (target_info.use_function_relative_addresses) then
                begin
                  strpcopy(strend(pp),'-');
-                 strpcopy(strend(pp),oldprocdef.mangledname);
+                 strpcopy(strend(pp),oldprocinfo.procdef.mangledname);
                end;
              withdebugList.concat(Tai_stabn.Create(strnew(pp)));
            end;
@@ -1121,6 +1126,7 @@ implementation
              cg.g_decrrefcount(exprasmlist,resulttype.def,refcountedtemp,false);
            end;
 
+(*
          { save all used registers and possible registers
            used for the return value }
          regs_to_push_int:=paramanager.get_volatile_registers_int(procdefinition.proccalloption);
@@ -1144,26 +1150,20 @@ implementation
            end;
 
          rg.saveusedotherregisters(exprasmlist,pushedother,regs_to_push_other);
+*)
 
          { Initialize for pushing the parameters }
-         oldpushedparasize:=pushedparasize;
-         pushedparasize:=0;
+//         oldpushedparasize:=pushedparasize;
+//         pushedparasize:=0;
 
          { Push parameters }
          oldaktcallnode:=aktcallnode;
          aktcallnode:=self;
-
          if assigned(left) then
-           begin
-              { we push from right to left, so start with parameters at the end of
-                the parameter block }
-              tcallparanode(left).secondcallparan(
-                  (procdefinition.proccalloption in pushleftright_pocalls),procdefinition.proccalloption,
-                  0,procdefinition.parast.address_fixup+procdefinition.parast.datasize);
-           end;
+           tcallparanode(left).secondcallparan(procdefinition.proccalloption,0);
          aktcallnode:=oldaktcallnode;
 
-         rg.saveotherregvars(exprasmlist,regs_to_push_other);
+//         rg.saveotherregvars(exprasmlist,regs_to_push_other);
 
          { takes care of local data initialization }
          inlineentrycode:=TAAsmoutput.Create;
@@ -1178,20 +1178,17 @@ implementation
          secondpass(inlinecode);
 
          { Reserve space for storing parameters that will be pushed }
-         current_procinfo.allocate_push_parasize(pushedparasize);
+//         current_procinfo.allocate_push_parasize(pushedparasize);
 
          { Restore }
-         pushedparasize:=oldpushedparasize;
-         rg.restoreunusedstate(unusedstate);
-{$ifdef TEMPREGDEBUG}
-         testregisters32;
-{$endif TEMPREGDEBUG}
+//         pushedparasize:=oldpushedparasize;
+//         rg.restoreunusedstate(unusedstate);
 
          gen_finalize_code(inlineexitcode,true);
          gen_load_return_value(inlineexitcode,usesacc,usesacchi,usesfpu);
          if po_assembler in current_procinfo.procdef.procoptions then
            inlineexitcode.concat(Tai_marker.Create(asmblockend));
-         exprasmList.concatlist(inlineexitcode);
+         exprasmlist.concatlist(inlineexitcode);
 
          inlineentrycode.free;
          inlineexitcode.free;
@@ -1200,6 +1197,7 @@ implementation
 {$endif extdebug}
          exprasmList.concat(Tai_Marker.Create(InlineEnd));
 
+(*
          {we can free the local data now, reset also the fixup address }
          if current_procinfo.procdef.localst.datasize>0 then
            begin
@@ -1212,6 +1210,7 @@ implementation
              tg.UnGetTemp(exprasmlist,pararef);
              current_procinfo.procdef.parast.address_fixup:=old_para_fixup;
            end;
+*)
 
          { handle function results }
          if (not is_void(resulttype.def)) then
@@ -1233,7 +1232,7 @@ implementation
            end;
 
          { restore registers }
-         rg.restoreusedotherregisters(exprasmlist,pushedother);
+//         rg.restoreusedotherregisters(exprasmlist,pushedother);
 
          { release temps of paras }
          release_para_temps;
@@ -1275,7 +1274,7 @@ implementation
             if (target_info.use_function_relative_addresses) then
               begin
                 strpcopy(strend(pp),'-');
-                strpcopy(strend(pp),oldprocdef.mangledname);
+                strpcopy(strend(pp),oldprocinfo.procdef.mangledname);
               end;
              withdebugList.concat(Tai_stabn.Create(strnew(pp)));
              freemem(pp,mangled_length+50);
@@ -1283,15 +1282,14 @@ implementation
 {$endif GDB}
 
          { restore }
-         current_procinfo.procdef:=oldprocdef;
+         current_procinfo:=oldprocinfo;
          inlining_procedure:=oldinlining_procedure;
 
          { reallocate the registers used for the current procedure's regvars, }
          { since they may have been used and then deallocated in the inlined  }
          { procedure (JM)                                                     }
-         if assigned(current_procinfo.procdef.regvarinfo) then
-           rg.restoreStateAfterInline(oldregstate);
-*)
+//         if assigned(current_procinfo.procdef.regvarinfo) then
+//           rg.restoreStateAfterInline(oldregstate);
       end;
 
 
@@ -1310,7 +1308,10 @@ begin
 end.
 {
   $Log$
-  Revision 1.121  2003-09-30 19:55:19  peter
+  Revision 1.122  2003-09-30 21:02:37  peter
+    * updates for inlining
+
+  Revision 1.121  2003/09/30 19:55:19  peter
     * remove abt reg for vmtreg
 
   Revision 1.120  2003/09/29 20:58:55  peter

+ 9 - 3
compiler/ncgutil.pas

@@ -1786,8 +1786,11 @@ implementation
               begin
                 with tvarsym(sym) do
                   begin
-                    { Allocate imaginary register for register parameters }
-                    if paraitem.paraloc[calleeside].loc=LOC_REGISTER then
+                    { Allocate imaginary register for register parameters,
+                      this is not required when the parameter is already an
+                      imaginary register }
+                    if (paraitem.paraloc[calleeside].loc=LOC_REGISTER) and
+                       (getsupreg(paraitem.paraloc[calleeside].register)<first_int_imreg) then
                       begin
                         (*
 {$warning TODO Allocate register paras}
@@ -1856,7 +1859,10 @@ implementation
 end.
 {
   $Log$
-  Revision 1.152  2003-09-29 20:58:56  peter
+  Revision 1.153  2003-09-30 21:02:37  peter
+    * updates for inlining
+
+  Revision 1.152  2003/09/29 20:58:56  peter
     * optimized releasing of registers
 
   Revision 1.151  2003/09/28 21:47:18  peter

+ 34 - 9
compiler/paramgr.pas

@@ -79,7 +79,7 @@ unit paramgr;
             @param(list Current assembler list)
             @param(loc Parameter location)
           }
-          procedure allocparaloc(list: taasmoutput; const loc: tparalocation); virtual;
+          procedure allocparaloc(list: taasmoutput; var loc: tparalocation); virtual;
 
           {# free a parameter location allocated with allocparaloc
 
@@ -253,23 +253,45 @@ implementation
       end;
 
 
-    procedure tparamanager.allocparaloc(list: taasmoutput; const loc: tparalocation);
+    procedure tparamanager.allocparaloc(list: taasmoutput; var loc: tparalocation);
       begin
         case loc.loc of
           LOC_REGISTER, LOC_CREGISTER:
             begin
-{$ifndef cpu64bit}
-              if (loc.size in [OS_64,OS_S64,OS_F64]) then
+              { NR_NO means we need to allocate imaginary registers.
+                This is used for inlining parameters (PFV) }
+              if loc.register=NR_NO then
                 begin
-                  rg.getexplicitregisterint(list,loc.registerhigh);
-                  rg.getexplicitregisterint(list,loc.registerlow);
+{$ifndef cpu64bit}
+                  if (loc.size in [OS_64,OS_S64,OS_F64]) then
+                    begin
+                      loc.registerhigh:=rg.getregisterint(list,OS_32);
+                      loc.registerlow:=rg.getregisterint(list,OS_32);
+                    end
+                  else
+{$endif cpu64bit}
+                    loc.register:=rg.getregisterint(list,loc.size);
                 end
               else
+                begin
+{$ifndef cpu64bit}
+                  if (loc.size in [OS_64,OS_S64,OS_F64]) then
+                    begin
+                      rg.getexplicitregisterint(list,loc.registerhigh);
+                      rg.getexplicitregisterint(list,loc.registerlow);
+                    end
+                  else
 {$endif cpu64bit}
-                rg.getexplicitregisterint(list,loc.register);
+                    rg.getexplicitregisterint(list,loc.register);
+                end;
             end;
           LOC_FPUREGISTER, LOC_CFPUREGISTER:
-            rg.getexplicitregisterfpu(list,loc.register);
+            begin
+              if loc.register=NR_NO then
+                loc.register:=rg.getregisterfpu(list,loc.size)
+              else
+                rg.getexplicitregisterfpu(list,loc.register);
+            end;
           LOC_REFERENCE,LOC_CREFERENCE:
             { do nothing by default, most of the time it's the framepointer }
           else
@@ -358,7 +380,10 @@ end.
 
 {
    $Log$
-   Revision 1.56  2003-09-23 17:56:05  peter
+   Revision 1.57  2003-09-30 21:02:37  peter
+     * updates for inlining
+
+   Revision 1.56  2003/09/23 17:56:05  peter
      * locals and paras are allocated in the code generation
      * tvarsym.localloc contains the location of para/local when
        generating code for the current procedure