Ver Fonte

+ -Owoptvmts whole program optimisation which replaces vmt entries
with method names of child classes in case the current class'
method can never be called (e.g., because this class is never
instantiated). As a result, such methods can then be removed
by dead code removal/smart linking (not much effect for either
the compiler, lazarus or a trivial lazarus app though).

git-svn-id: branches/wpo@11882 -

Jonas Maebe há 17 anos atrás
pai
commit
4a86e6b2fc
5 ficheiros alterados com 29 adições e 7 exclusões
  1. 3 2
      compiler/globtype.pas
  2. 3 2
      compiler/nobj.pas
  3. 7 2
      compiler/optvirt.pas
  4. 3 1
      compiler/wpobase.pas
  5. 13 0
      compiler/wpoinfo.pas

+ 3 - 2
compiler/globtype.pas

@@ -188,7 +188,8 @@ interface
        toptimizerswitches = set of toptimizerswitch;
 
        { whole program optimizer }
-       twpoptimizerswitch = (cs_wpo_devirtualize_calls
+       twpoptimizerswitch = (
+         cs_wpo_devirtualize_calls,cs_wpo_optimize_vmts
        );
        twpoptimizerswitches = set of twpoptimizerswitch;
 
@@ -200,7 +201,7 @@ interface
          'PEEPHOLE','ASMCSE','LOOPUNROLL','TAILREC','CSE','DFA','STRENGTH'
        );
        WPOptimizerSwitchStr : array [twpoptimizerswitch] of string[11] = (
-         'DEVIRTCALLS'
+         'DEVIRTCALLS','OPTVMTS'
        );
 
        DebugSwitchStr : array[tdebugswitch] of string[9] = ('',

+ 3 - 2
compiler/nobj.pas

@@ -131,7 +131,8 @@ implementation
        node,
        symbase,symtable,symconst,symtype,defcmp,
        dbgbase,
-       ncgrtti
+       ncgrtti,
+       wpobase
        ;
 
 
@@ -1317,7 +1318,7 @@ implementation
              internalerror(200611083);
            if (po_abstractmethod in pd.procoptions) then
              procname:='FPC_ABSTRACTERROR'
-           else
+           else if not wpoinfomanager.optimized_name_for_vmt(_class,pd,procname) then
              procname:=pd.mangledname;
            List.concat(Tai_const.createname(procname,0));
 {$ifdef vtentry}

+ 7 - 2
compiler/optvirt.pas

@@ -630,30 +630,35 @@ unit optvirt;
             end;
       end;
 
+
     constructor tprogdevirtinfo.create;
       begin
         inherited create;
       end;
 
+
     destructor tprogdevirtinfo.destroy;
       begin
         funits.free;
         inherited destroy;
       end;
 
+
     class function tprogdevirtinfo.getwpotype: twpotype;
       begin
         result:=wpo_devirtualization_context_insensitive;
       end;
 
+
     class function tprogdevirtinfo.generatesinfoforwposwitches: twpoptimizerswitches;
       begin
-        result:=[cs_wpo_devirtualize_calls];
+        result:=[cs_wpo_devirtualize_calls,cs_wpo_optimize_vmts];
       end;
 
+
     class function tprogdevirtinfo.performswpoforswitches: twpoptimizerswitches;
       begin
-        result:=[cs_wpo_devirtualize_calls];
+        result:=[cs_wpo_devirtualize_calls,cs_wpo_optimize_vmts];
       end;
 
 

+ 3 - 1
compiler/wpobase.pas

@@ -231,6 +231,8 @@ type
     { routines accessing the optimizer information }
     { 1) devirtualization at the symbol name level }
     function can_be_devirtualized(objdef, procdef: tdef; out name: shortstring): boolean; virtual; abstract;
+    { 2) optimal replacement method name in vmt }
+    function optimized_name_for_vmt(objdef, procdef: tdef; out name: shortstring): boolean; virtual; abstract;
 
     constructor create; reintroduce;
     destructor destroy; override;
@@ -522,7 +524,7 @@ implementation
       { and for each specified optimization check whether the input feedback
         file contained the necessary information
       }
-      if (cs_wpo_devirtualize_calls in init_settings.dowpoptimizerswitches) and
+      if (([cs_wpo_devirtualize_calls,cs_wpo_optimize_vmts] * init_settings.dowpoptimizerswitches) <> []) and
          not assigned(wpoinfouse[wpo_devirtualization_context_insensitive]) then
         begin
           message1(wpo_not_enough_info,wpo2str[wpo_devirtualization_context_insensitive]);

+ 13 - 0
compiler/wpoinfo.pas

@@ -60,6 +60,7 @@ type
 
   twpoinfomanager = class(twpoinfomanagerbase)
     function can_be_devirtualized(objdef, procdef: tdef; out name: shortstring): boolean; override;
+    function optimized_name_for_vmt(objdef, procdef: tdef; out name: shortstring): boolean; override;
   end;
 
 
@@ -190,6 +191,18 @@ implementation
     end;
 
 
+  function twpoinfomanager.optimized_name_for_vmt(objdef, procdef: tdef; out name: shortstring): boolean;
+    begin
+      if not assigned(wpoinfouse[wpo_devirtualization_context_insensitive]) or
+         not(cs_wpo_optimize_vmts in current_settings.dowpoptimizerswitches) then
+        begin
+          result:=false;
+          exit;
+        end;
+      result:=twpodevirtualisationhandler(wpoinfouse[wpo_devirtualization_context_insensitive]).staticnameforvirtualmethod(objdef,procdef,name);
+    end;
+
+
   procedure InitWpo;
     begin
       { always create so we don't have to litter the source with if-tests }