Преглед изворни кода

+ introduce cnf_call_never_returns to signal the dfa if a call node never returns
* get rid of tcgraisenode.pass_generate_code, it is replaced by compiler proc. call nodes generated in pass_1

git-svn-id: branches/i8086@24288 -

florian пре 12 година
родитељ
комит
709ba5e053
5 измењених фајлова са 54 додато и 162 уклоњено
  1. 2 1
      compiler/ncal.pas
  2. 0 122
      compiler/ncgflw.pas
  3. 47 18
      compiler/nflw.pas
  4. 2 19
      compiler/optdfa.pas
  5. 3 2
      compiler/optutils.pas

+ 2 - 1
compiler/ncal.pas

@@ -51,7 +51,8 @@ interface
          cnf_create_failed,      { exception thrown in constructor -> don't call beforedestruction }
          cnf_objc_processed,     { the procedure name has been set to the appropriate objc_msgSend* variant -> don't process again }
          cnf_objc_id_call,       { the procedure is a member call via id -> any ObjC method of any ObjC type in scope is fair game }
-         cnf_unit_specified      { the unit in which the procedure has to be searched has been specified }
+         cnf_unit_specified,     { the unit in which the procedure has to be searched has been specified }
+         cnf_call_never_returns  { information for the dfa that a subroutine never returns }
        );
        tcallnodeflags = set of tcallnodeflag;
 

+ 0 - 122
compiler/ncgflw.pas

@@ -72,10 +72,6 @@ interface
           procedure pass_generate_code;override;
        end;
 
-       tcgraisenode = class(traisenode)
-          procedure pass_generate_code;override;
-       end;
-
        tcgtryexceptnode = class(ttryexceptnode)
           procedure pass_generate_code;override;
        end;
@@ -949,122 +945,6 @@ implementation
       end;
 
 
-{*****************************************************************************
-                             SecondRaise
-*****************************************************************************}
-
-    procedure tcgraisenode.pass_generate_code;
-
-      var
-         a : tasmlabel;
-         href2: treference;
-         paraloc1,paraloc2,paraloc3 : tcgpara;
-         pd : tprocdef;
-      begin
-         location_reset(location,LOC_VOID,OS_NO);
-
-         if assigned(left) then
-           begin
-              pd:=search_system_proc('fpc_raiseexception');
-              paraloc1.init;
-              paraloc2.init;
-              paraloc3.init;
-              paramanager.getintparaloc(pd,1,paraloc1);
-              paramanager.getintparaloc(pd,2,paraloc2);
-              paramanager.getintparaloc(pd,3,paraloc3);
-
-              { multiple parameters? }
-              if assigned(right) then
-                begin
-                  { frame tree }
-                  if assigned(third) then
-                    secondpass(third);
-                  secondpass(right);
-                end;
-              secondpass(left);
-              if codegenerror then
-                exit;
-
-              { Push parameters }
-              { ugly code repetition follows for left to right and right to left calling conventions }
-              { TODO: refactor this somehow }
-              if pd.is_pushleftright then
-                begin
-                  cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,left.location,paraloc1);
-                   if assigned(right) then
-                     begin
-                       { push address }
-                       cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,right.location,paraloc2);
-                       { frame tree }
-                       if assigned(third) then
-                         cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,third.location,paraloc3)
-                       else
-                         cg.a_load_const_cgpara(current_asmdata.CurrAsmList,OS_ADDR,0,paraloc3);
-                     end
-                   else
-                     begin
-                        { get current address }
-                        current_asmdata.getaddrlabel(a);
-                        cg.a_label(current_asmdata.CurrAsmList,a);
-                        reference_reset_symbol(href2,a,0,1);
-                        { push current address }
-                        if target_info.system <> system_powerpc_macos then
-                          cg.a_loadaddr_ref_cgpara(current_asmdata.CurrAsmList,href2,paraloc2)
-                        else
-                          cg.a_load_const_cgpara(current_asmdata.CurrAsmList,OS_ADDR,0,paraloc2);
-                        { push current frame }
-                        cg.a_load_reg_cgpara(current_asmdata.CurrAsmList,OS_ADDR,NR_FRAME_POINTER_REG,paraloc3);
-                     end;
-                end
-              else
-                begin
-                  if assigned(right) then
-                    begin
-                      { frame tree }
-                      if assigned(third) then
-                        cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,third.location,paraloc3)
-                      else
-                        cg.a_load_const_cgpara(current_asmdata.CurrAsmList,OS_ADDR,0,paraloc3);
-                      { push address }
-                      cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,right.location,paraloc2);
-                    end
-                  else
-                    begin
-                       { get current address }
-                       current_asmdata.getaddrlabel(a);
-                       cg.a_label(current_asmdata.CurrAsmList,a);
-                       reference_reset_symbol(href2,a,0,1);
-                       { push current frame }
-                       cg.a_load_reg_cgpara(current_asmdata.CurrAsmList,OS_ADDR,NR_FRAME_POINTER_REG,paraloc3);
-                       { push current address }
-                       if target_info.system <> system_powerpc_macos then
-                         cg.a_loadaddr_ref_cgpara(current_asmdata.CurrAsmList,href2,paraloc2)
-                       else
-                         cg.a_load_const_cgpara(current_asmdata.CurrAsmList,OS_ADDR,0,paraloc2);
-                    end;
-                  cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,left.location,paraloc1);
-                end;
-              paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc1);
-              paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc2);
-              paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc3);
-              cg.allocallcpuregisters(current_asmdata.CurrAsmList);
-              cg.a_call_name(current_asmdata.CurrAsmList,'FPC_RAISEEXCEPTION',false);
-              cg.deallocallcpuregisters(current_asmdata.CurrAsmList);
-
-              paraloc1.done;
-              paraloc2.done;
-              paraloc3.done;
-           end
-         else
-           begin
-              cg.allocallcpuregisters(current_asmdata.CurrAsmList);
-              cg.a_call_name(current_asmdata.CurrAsmList,'FPC_POPADDRSTACK',false);
-              cg.a_call_name(current_asmdata.CurrAsmList,'FPC_RERAISE',false);
-              cg.deallocallcpuregisters(current_asmdata.CurrAsmList);
-           end;
-       end;
-
-
 {*****************************************************************************
                              SecondTryExcept
 *****************************************************************************}
@@ -1072,7 +952,6 @@ implementation
     var
        endexceptlabel : tasmlabel;
 
-
     { does the necessary things to clean up the object stack }
     { in the except block                                    }
     procedure cleanupobjectstack;
@@ -1693,7 +1572,6 @@ begin
    ccontinuenode:=tcgcontinuenode;
    cgotonode:=tcggotonode;
    clabelnode:=tcglabelnode;
-   craisenode:=tcgraisenode;
    ctryexceptnode:=tcgtryexceptnode;
    ctryfinallynode:=tcgtryfinallynode;
    connode:=tcgonnode;

+ 47 - 18
compiler/nflw.pas

@@ -1937,26 +1937,55 @@ implementation
 
 
     function traisenode.pass_1 : tnode;
+      var
+        statements : tstatementnode;
+        current_addr : tlabelnode;
+        raisenode : tcallnode;
       begin
-         result:=nil;
-         include(current_procinfo.flags,pi_do_call);
-         expectloc:=LOC_VOID;
-         if assigned(left) then
-           begin
-              { first para must be a _class_ }
-              firstpass(left);
-              { insert needed typeconvs for addr,frame }
-              if assigned(right) then
-               begin
-                 { addr }
-                 firstpass(right);
-                 { frame }
-                 if assigned(third) then
-                  firstpass(third);
-               end;
-           end;
-      end;
+        result:=internalstatements(statements);
 
+        if assigned(left) then
+          begin
+            { first para must be a class }
+            firstpass(left);
+            { insert needed typeconvs for addr,frame }
+            if assigned(right) then
+              begin
+                { addr }
+                firstpass(right);
+                { frame }
+                if assigned(third) then
+                  firstpass(third)
+                else
+                  third:=cpointerconstnode.Create(0,voidpointertype);
+              end
+            else
+              begin
+                right:=cloadparentfpnode.create(current_procinfo.procdef);
+                current_addr:=clabelnode.create(cnothingnode.create,tlabelsym.create('$raiseaddr'));
+                addstatement(statements,current_addr);
+                third:=caddrnode.create(cloadnode.create(current_addr.labsym,current_addr.labsym.owner));
+              end;
+
+            raisenode:=ccallnode.createintern('fpc_raiseexception',
+              ccallparanode.create(third,
+              ccallparanode.create(right,
+              ccallparanode.create(left,nil)))
+              );
+            include(raisenode.callnodeflags,cnf_call_never_returns);
+            addstatement(statements,raisenode);
+          end
+        else
+          begin
+            addstatement(statements,ccallnode.createintern('fpc_popaddrstack',nil));
+            raisenode:=ccallnode.createintern('fpc_reraise',nil);
+            include(raisenode.callnodeflags,cnf_call_never_returns);
+            addstatement(statements,raisenode);
+          end;
+        left:=nil;
+        right:=nil;
+        third:=nil;
+      end;
 
 {*****************************************************************************
                              TTRYEXCEPTNODE

+ 2 - 19
compiler/optdfa.pas

@@ -222,7 +222,8 @@ unit optdfa;
               begin
                 { last node, not exit or raise node and function? }
                 if assigned(resultnode) and
-                  not(node.nodetype in [raisen,exitn]) then
+                  not(node.nodetype=exitn) and
+                  not((node.nodetype=calln) and (cnf_call_never_returns in tcallnode(node).callnodeflags)) then
                   begin
                     { if yes, result lifes }
                     DFASetDiff(l,resultnode.optinfo^.life,n.optinfo^.def);
@@ -499,24 +500,6 @@ unit optdfa;
                   end;
               end;
 
-            raisen:
-              begin
-                if not(assigned(node.optinfo^.life)) then
-                  begin
-                    dfainfo.use:[email protected]^.use;
-                    dfainfo.def:[email protected]^.def;
-                    dfainfo.map:=map;
-                    foreachnodestatic(pm_postprocess,traisenode(node).left,@AddDefUse,@dfainfo);
-                    foreachnodestatic(pm_postprocess,traisenode(node).right,@AddDefUse,@dfainfo);
-                    foreachnodestatic(pm_postprocess,traisenode(node).third,@AddDefUse,@dfainfo);
-                    { update node }
-                    l:=node.optinfo^.life;
-                    DFASetIncludeSet(l,node.optinfo^.use);
-                    UpdateLifeInfo(node,l);
-                    printdfainfo(output,node);
-                  end;
-              end;
-
             calln:
               begin
                 if not(assigned(node.optinfo^.def)) and

+ 3 - 2
compiler/optutils.pas

@@ -52,7 +52,7 @@ unit optutils;
     uses
       verbose,
       optbase,
-      nbas,nflw,nutils,nset;
+      ncal,nbas,nflw,nutils,nset;
 
     function TIndexedNodeSet.Add(node : tnode) : boolean;
       var
@@ -264,7 +264,8 @@ unit optutils;
               begin
                 { not sure if this is enough (FK) }
                 result:=p;
-                p.successor:=succ;
+                if not(cnf_call_never_returns in tcallnode(p).callnodeflags) then
+                  p.successor:=succ;
               end;
             inlinen:
               begin