Forráskód Böngészése

* 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 éve
szülő
commit
f08d3fdf8f

+ 1 - 1
compiler/cgobj.pas

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

+ 0 - 15
compiler/ncgflw.pas

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

+ 0 - 9
compiler/ncgset.pas

@@ -1051,7 +1051,6 @@ implementation
          labelcnt : tcgint;
          max_linear_list : aint;
          max_dist : aword;
-         oldexecutionweight : longint;
       begin
          location_reset(location,LOC_VOID,OS_NO);
 
@@ -1186,12 +1185,6 @@ implementation
                 genlinearlist(labels);
            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 }
          for i:=0 to blocks.count-1 do
            begin
@@ -1216,8 +1209,6 @@ implementation
 {$endif OLDREGVARS}
            end;
 
-         cg.executionweight:=oldexecutionweight;
-
          current_asmdata.CurrAsmList.concat(cai_align.create(current_settings.alignment.jumpalign));
          hlcg.a_label(current_asmdata.CurrAsmList,endlabel);
 

+ 2 - 0
compiler/optbase.pas

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

+ 49 - 1
compiler/optutils.pas

@@ -27,7 +27,8 @@ unit optutils;
 
     uses
       cclasses,
-      node;
+      node,
+      globtype;
 
     type
       { this implementation should be really improved,
@@ -47,12 +48,16 @@ unit optutils;
     }
     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 }
     function has_life_info(n : tnode) : boolean;
 
   implementation
 
     uses
+      cutils,
       verbose,
       optbase,
       ncal,nbas,nflw,nutils,nset,ncon;
@@ -352,6 +357,49 @@ unit optutils;
       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;
       begin
         result:=assigned(n) and assigned(n.optinfo) and

+ 6 - 1
compiler/pass_2.pas

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

+ 4 - 1
compiler/psub.pas

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