浏览代码

+ redirect calls to empty virtual methods to FPC_EMPTYMETHOD
* do empty subroutine/method optimization only for O2 and higer

git-svn-id: trunk@23276 -

florian 12 年之前
父节点
当前提交
24f518f232
共有 4 个文件被更改,包括 37 次插入1 次删除
  1. 2 1
      compiler/ncal.pas
  2. 29 0
      compiler/nobj.pas
  3. 5 0
      rtl/inc/system.inc
  4. 1 0
      rtl/inc/systemh.inc

+ 2 - 1
compiler/ncal.pas

@@ -3423,7 +3423,8 @@ implementation
          result:=nil;
 
          { can we get rid of the call? }
-         if not(cnf_return_value_used in callnodeflags) and
+         if (cs_opt_level2 in current_settings.optimizerswitches) and
+            not(cnf_return_value_used in callnodeflags) and
            (procdefinition.typ=procdef) and
            tprocdef(procdefinition).isempty and
            { allow only certain proc options }

+ 29 - 0
compiler/nobj.pas

@@ -71,6 +71,7 @@ interface
         procedure insertmsgstr(p:TObject;arg:pointer);
         procedure insertint(p : pprocdeftree;var at : pprocdeftree;var count:longint);
         procedure insertstr(p : pprocdeftree;var at : pprocdeftree;var count:longint);
+        function RedirectToEmpty(procdef: tprocdef): boolean;
         procedure writenames(list : TAsmList;p : pprocdeftree);
         procedure writeintentry(list : TAsmList;p : pprocdeftree);
         procedure writestrentry(list : TAsmList;p : pprocdeftree);
@@ -113,6 +114,7 @@ implementation
        globals,verbose,systems,
        node,procinfo,
        symbase,symtable,symconst,symtype,defcmp,
+       cgbase,parabase,
        dbgbase,
        ncgrtti,
        wpobase
@@ -1532,6 +1534,31 @@ implementation
     end;
 
 
+    function TVMTWriter.RedirectToEmpty(procdef : tprocdef) : boolean;
+      var
+        i : longint;
+        hp : PCGParaLocation;
+      begin
+        result:=false;
+        if procdef.isempty then
+          begin
+            procdef.init_paraloc_info(calleeside);
+            { we can redirect the call if no memory parameter is passed }
+            for i:=0 to procdef.paras.count-1 do
+              begin
+                hp:=tparavarsym(procdef.paras[i]).paraloc[callerside].Location;
+                while assigned(hp) do
+                  begin
+                    if not(hp^.Loc in [LOC_REGISTER,LOC_MMREGISTER,LOC_FPUREGISTER]) then
+                      exit;
+                    hp:=hp^.Next;
+                  end;
+              end;
+            result:=true;
+          end;
+      end;
+
+
     procedure TVMTWriter.writevirtualmethods(List:TAsmList);
       var
          vmtpd : tprocdef;
@@ -1555,6 +1582,8 @@ implementation
              internalerror(200611083);
            if (po_abstractmethod in vmtpd.procoptions) then
              procname:='FPC_ABSTRACTERROR'
+           else if (cs_opt_level2 in current_settings.optimizerswitches) and RedirectToEmpty(vmtpd) then
+             procname:='FPC_EMPTYMETHOD'
            else if not wpoinfomanager.optimized_name_for_vmt(_class,vmtpd,procname) then
              procname:=vmtpd.mangledname;
            List.concat(Tai_const.createname(procname,0));

+ 5 - 0
rtl/inc/system.inc

@@ -1312,6 +1312,11 @@ end;
                           Abstract/Assert support.
 *****************************************************************************}
 
+procedure fpc_emptymethod;[public,alias : 'FPC_EMPTYMETHOD'];
+begin
+end;
+
+
 procedure fpc_AbstractErrorIntern;compilerproc;[public,alias : 'FPC_ABSTRACTERROR'];
 begin
   If pointer(AbstractErrorProc)<>nil then

+ 1 - 0
rtl/inc/systemh.inc

@@ -1227,6 +1227,7 @@ Function StringToPPChar(S: PChar;ReserveEntries:integer):ppchar;
 
 
 procedure AbstractError;external name 'FPC_ABSTRACTERROR';
+procedure EmptyMethod;external name 'FPC_AEMPTYMETHOD';
 Function  SysBackTraceStr(Addr:Pointer): ShortString;
 Procedure SysAssert(const Msg,FName:ShortString;LineNo:Longint;ErrorAddr:Pointer);
 (* Supposed to return address of previous CtrlBreakHandler *)