Просмотр исходного кода

* moved execution weight calculation into a separate pass, so the info is available already available before the code generation pass if needed

git-svn-id: trunk@38717 -
florian 7 лет назад
Родитель
Сommit
f08d3fdf8f
7 измененных файлов с 62 добавлено и 28 удалено
  1. 1 1
      compiler/cgobj.pas
  2. 0 15
      compiler/ncgflw.pas
  3. 0 9
      compiler/ncgset.pas
  4. 2 0
      compiler/optbase.pas
  5. 49 1
      compiler/optutils.pas
  6. 6 1
      compiler/pass_2.pas
  7. 4 1
      compiler/psub.pas

+ 1 - 1
compiler/cgobj.pas

@@ -593,7 +593,7 @@ implementation
 {$endif cpu8bitalu or cpu16bitalu}
 {$endif cpu8bitalu or cpu16bitalu}
         fillchar(rg,sizeof(rg),0);
         fillchar(rg,sizeof(rg),0);
         add_reg_instruction_hook:=@add_reg_instruction;
         add_reg_instruction_hook:=@add_reg_instruction;
-        executionweight:=1;
+        executionweight:=100;
       end;
       end;
 
 
 
 

+ 0 - 15
compiler/ncgflw.pas

@@ -173,7 +173,6 @@ implementation
          oldclabel,oldblabel : tasmlabel;
          oldclabel,oldblabel : tasmlabel;
          truelabel,falselabel : tasmlabel;
          truelabel,falselabel : tasmlabel;
          oldflowcontrol : tflowcontrol;
          oldflowcontrol : tflowcontrol;
-         oldexecutionweight : longint;
       begin
       begin
          location_reset(location,LOC_VOID,OS_NO);
          location_reset(location,LOC_VOID,OS_NO);
 
 
@@ -205,10 +204,6 @@ implementation
          current_procinfo.CurrContinueLabel:=lcont;
          current_procinfo.CurrContinueLabel:=lcont;
          current_procinfo.CurrBreakLabel:=lbreak;
          current_procinfo.CurrBreakLabel:=lbreak;
 
 
-         { calc register weight }
-         oldexecutionweight:=cg.executionweight;
-         cg.executionweight:=max(cg.executionweight,1)*8;
-
          if assigned(right) then
          if assigned(right) then
            secondpass(right);
            secondpass(right);
 
 
@@ -230,7 +225,6 @@ implementation
          secondpass(left);
          secondpass(left);
 
 
          hlcg.maketojumpboollabels(current_asmdata.CurrAsmList,left,truelabel,falselabel);
          hlcg.maketojumpboollabels(current_asmdata.CurrAsmList,left,truelabel,falselabel);
-         cg.executionweight:=oldexecutionweight;
          hlcg.a_label(current_asmdata.CurrAsmList,lbreak);
          hlcg.a_label(current_asmdata.CurrAsmList,lbreak);
 
 
          sync_regvars(false);
          sync_regvars(false);
@@ -251,7 +245,6 @@ implementation
       var
       var
          hl : tasmlabel;
          hl : tasmlabel;
          oldflowcontrol: tflowcontrol;
          oldflowcontrol: tflowcontrol;
-         oldexecutionweight : longint;
 (*
 (*
          org_regvar_loaded_other,
          org_regvar_loaded_other,
          then_regvar_loaded_other,
          then_regvar_loaded_other,
@@ -290,12 +283,6 @@ implementation
              org_regvar_loaded_other := rg.regvar_loaded_other;
              org_regvar_loaded_other := rg.regvar_loaded_other;
            end;
            end;
 *)
 *)
-         { determines registers weigths }
-         oldexecutionweight:=cg.executionweight;
-         cg.executionweight:=cg.executionweight div 2;
-         if cg.executionweight<1 then
-           cg.executionweight:=1;
-
          if assigned(right) then
          if assigned(right) then
            begin
            begin
               hlcg.a_label(current_asmdata.CurrAsmList,left.location.truelabel);
               hlcg.a_label(current_asmdata.CurrAsmList,left.location.truelabel);
@@ -403,8 +390,6 @@ implementation
            end;
            end;
 *)
 *)
 
 
-         cg.executionweight:=oldexecutionweight;
-
          flowcontrol := oldflowcontrol + (flowcontrol - [fc_inflowcontrol]);
          flowcontrol := oldflowcontrol + (flowcontrol - [fc_inflowcontrol]);
       end;
       end;
 
 

+ 0 - 9
compiler/ncgset.pas

@@ -1051,7 +1051,6 @@ implementation
          labelcnt : tcgint;
          labelcnt : tcgint;
          max_linear_list : aint;
          max_linear_list : aint;
          max_dist : aword;
          max_dist : aword;
-         oldexecutionweight : longint;
       begin
       begin
          location_reset(location,LOC_VOID,OS_NO);
          location_reset(location,LOC_VOID,OS_NO);
 
 
@@ -1186,12 +1185,6 @@ implementation
                 genlinearlist(labels);
                 genlinearlist(labels);
            end;
            end;
 
 
-         { estimates the repeat of each instruction }
-         oldexecutionweight:=cg.executionweight;
-         cg.executionweight:=cg.executionweight div case_count_labels(labels);
-         if cg.executionweight<1 then
-           cg.executionweight:=1;
-
          { generate the instruction blocks }
          { generate the instruction blocks }
          for i:=0 to blocks.count-1 do
          for i:=0 to blocks.count-1 do
            begin
            begin
@@ -1216,8 +1209,6 @@ implementation
 {$endif OLDREGVARS}
 {$endif OLDREGVARS}
            end;
            end;
 
 
-         cg.executionweight:=oldexecutionweight;
-
          current_asmdata.CurrAsmList.concat(cai_align.create(current_settings.alignment.jumpalign));
          current_asmdata.CurrAsmList.concat(cai_align.create(current_settings.alignment.jumpalign));
          hlcg.a_label(current_asmdata.CurrAsmList,endlabel);
          hlcg.a_label(current_asmdata.CurrAsmList,endlabel);
 
 

+ 2 - 0
compiler/optbase.pas

@@ -43,6 +43,8 @@ unit optbase;
         life : tdfaset;
         life : tdfaset;
         defsum : tdfaset;
         defsum : tdfaset;
         avail : tdfaset;
         avail : tdfaset;
+        { estimation, how often the node is executed per subroutine call times 100, calculated by optutils.CalcExecutionWeight }
+        executionweight : aword;
       end;
       end;
 
 
       poptinfo = ^toptinfo;
       poptinfo = ^toptinfo;

+ 49 - 1
compiler/optutils.pas

@@ -27,7 +27,8 @@ unit optutils;
 
 
     uses
     uses
       cclasses,
       cclasses,
-      node;
+      node,
+      globtype;
 
 
     type
     type
       { this implementation should be really improved,
       { this implementation should be really improved,
@@ -47,12 +48,16 @@ unit optutils;
     }
     }
     procedure CalcDefSum(p : tnode);
     procedure CalcDefSum(p : tnode);
 
 
+    { calculates/estimates the field execution weight of optinfo }
+    procedure CalcExecutionWeights(p : tnode;Initial : AWord = 100);
+
     { returns true, if n is a valid node and has life info }
     { returns true, if n is a valid node and has life info }
     function has_life_info(n : tnode) : boolean;
     function has_life_info(n : tnode) : boolean;
 
 
   implementation
   implementation
 
 
     uses
     uses
+      cutils,
       verbose,
       verbose,
       optbase,
       optbase,
       ncal,nbas,nflw,nutils,nset,ncon;
       ncal,nbas,nflw,nutils,nset,ncon;
@@ -352,6 +357,49 @@ unit optutils;
       end;
       end;
 
 
 
 
+    function SetExecutionWeight(var n: tnode; arg: pointer): foreachnoderesult;
+      var
+        Weight : AWord absolute arg;
+        i : Integer;
+      begin
+        Result:=fen_false;
+        n.allocoptinfo;
+        case n.nodetype of
+          casen:
+            begin
+              CalcExecutionWeights(tcasenode(n).left,Weight);
+              for i:=0 to tcasenode(n).blocks.count-1 do
+                CalcExecutionWeights(pcaseblock(tcasenode(n).blocks[i])^.statement,max(1,Weight div case_count_labels(tcasenode(n).labels)));
+
+              CalcExecutionWeights(tcasenode(n).elseblock,max(1,Weight div case_count_labels(tcasenode(n).labels)));
+              Result:=fen_norecurse_false;
+            end;
+          whilerepeatn:
+            begin
+              CalcExecutionWeights(twhilerepeatnode(n).right,max(Weight,1)*8);
+              CalcExecutionWeights(twhilerepeatnode(n).left,max(Weight,1)*8);
+              Result:=fen_norecurse_false;
+            end;
+          ifn:
+            begin
+              CalcExecutionWeights(tifnode(n).left,Weight);
+              CalcExecutionWeights(tifnode(n).right,max(Weight div 2,1));
+              CalcExecutionWeights(tifnode(n).t1,max(Weight div 2,1));
+              Result:=fen_norecurse_false;
+            end;
+          else
+            n.optinfo^.executionweight:=AWord(arg);
+        end;
+      end;
+
+
+    procedure CalcExecutionWeights(p : tnode;Initial : AWord = 100);
+      begin
+        if assigned(p) then
+          foreachnodestatic(pm_postprocess,p,@SetExecutionWeight,Pointer(Initial));
+      end;
+
+
     function has_life_info(n : tnode) : boolean;
     function has_life_info(n : tnode) : boolean;
       begin
       begin
         result:=assigned(n) and assigned(n.optinfo) and
         result:=assigned(n) and assigned(n.optinfo) and

+ 6 - 1
compiler/pass_2.pas

@@ -63,7 +63,8 @@ implementation
 {$endif}
 {$endif}
      globtype,verbose,
      globtype,verbose,
      globals,
      globals,
-     aasmdata
+     aasmdata,
+     cgobj
 {$ifdef EXTDEBUG}
 {$ifdef EXTDEBUG}
      ,cgbase
      ,cgbase
      ,aasmtai
      ,aasmtai
@@ -192,6 +193,10 @@ implementation
             current_filepos:=p.fileinfo;
             current_filepos:=p.fileinfo;
             current_settings.localswitches:=p.localswitches;
             current_settings.localswitches:=p.localswitches;
             codegenerror:=false;
             codegenerror:=false;
+            if assigned(p.optinfo) then
+              cg.executionweight:=p.optinfo^.executionweight
+            else
+              cg.executionweight:=100;
 {$ifdef EXTDEBUG}
 {$ifdef EXTDEBUG}
             if (p.expectloc=LOC_INVALID) then
             if (p.expectloc=LOC_INVALID) then
               Comment(V_Warning,'ExpectLoc is not set before secondpass: '+nodetype2str[p.nodetype]);
               Comment(V_Warning,'ExpectLoc is not set before secondpass: '+nodetype2str[p.nodetype]);

+ 4 - 1
compiler/psub.pas

@@ -127,7 +127,8 @@ implementation
        optloop,
        optloop,
        optconstprop,
        optconstprop,
        optdeadstore,
        optdeadstore,
-       optloadmodifystore
+       optloadmodifystore,
+       optutils
 {$if defined(arm)}
 {$if defined(arm)}
        ,cpuinfo
        ,cpuinfo
 {$endif arm}
 {$endif arm}
@@ -1478,6 +1479,8 @@ implementation
               code of the ppc (and possibly other processors)               }
               code of the ppc (and possibly other processors)               }
             procdef.init_paraloc_info(callerside);
             procdef.init_paraloc_info(callerside);
 
 
+            CalcExecutionWeights(code);
+
             { Print the node to tree.log }
             { Print the node to tree.log }
             if paraprintnodetree=1 then
             if paraprintnodetree=1 then
               printproc( 'right before code generation');
               printproc( 'right before code generation');