Browse Source

+ -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 17 years ago
parent
commit
4a86e6b2fc
5 changed files with 29 additions and 7 deletions
  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;
        toptimizerswitches = set of toptimizerswitch;
 
 
        { whole program optimizer }
        { whole program optimizer }
-       twpoptimizerswitch = (cs_wpo_devirtualize_calls
+       twpoptimizerswitch = (
+         cs_wpo_devirtualize_calls,cs_wpo_optimize_vmts
        );
        );
        twpoptimizerswitches = set of twpoptimizerswitch;
        twpoptimizerswitches = set of twpoptimizerswitch;
 
 
@@ -200,7 +201,7 @@ interface
          'PEEPHOLE','ASMCSE','LOOPUNROLL','TAILREC','CSE','DFA','STRENGTH'
          'PEEPHOLE','ASMCSE','LOOPUNROLL','TAILREC','CSE','DFA','STRENGTH'
        );
        );
        WPOptimizerSwitchStr : array [twpoptimizerswitch] of string[11] = (
        WPOptimizerSwitchStr : array [twpoptimizerswitch] of string[11] = (
-         'DEVIRTCALLS'
+         'DEVIRTCALLS','OPTVMTS'
        );
        );
 
 
        DebugSwitchStr : array[tdebugswitch] of string[9] = ('',
        DebugSwitchStr : array[tdebugswitch] of string[9] = ('',

+ 3 - 2
compiler/nobj.pas

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

+ 7 - 2
compiler/optvirt.pas

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

+ 3 - 1
compiler/wpobase.pas

@@ -231,6 +231,8 @@ type
     { routines accessing the optimizer information }
     { routines accessing the optimizer information }
     { 1) devirtualization at the symbol name level }
     { 1) devirtualization at the symbol name level }
     function can_be_devirtualized(objdef, procdef: tdef; out name: shortstring): boolean; virtual; abstract;
     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;
     constructor create; reintroduce;
     destructor destroy; override;
     destructor destroy; override;
@@ -522,7 +524,7 @@ implementation
       { and for each specified optimization check whether the input feedback
       { and for each specified optimization check whether the input feedback
         file contained the necessary information
         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
          not assigned(wpoinfouse[wpo_devirtualization_context_insensitive]) then
         begin
         begin
           message1(wpo_not_enough_info,wpo2str[wpo_devirtualization_context_insensitive]);
           message1(wpo_not_enough_info,wpo2str[wpo_devirtualization_context_insensitive]);

+ 13 - 0
compiler/wpoinfo.pas

@@ -60,6 +60,7 @@ type
 
 
   twpoinfomanager = class(twpoinfomanagerbase)
   twpoinfomanager = class(twpoinfomanagerbase)
     function can_be_devirtualized(objdef, procdef: tdef; out name: shortstring): boolean; override;
     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;
   end;
 
 
 
 
@@ -190,6 +191,18 @@ implementation
     end;
     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;
   procedure InitWpo;
     begin
     begin
       { always create so we don't have to litter the source with if-tests }
       { always create so we don't have to litter the source with if-tests }