Browse Source

[PATCH 45/83] updating flow control changed while repeat loop structure to block-loop-block changed boolean expression valuation - avoiding use of labels

From 2682c3e197242edfed382e3d9701687b0f27d74e Mon Sep 17 00:00:00 2001
From: Dmitry Boyarintsev <[email protected]>
Date: Thu, 19 Sep 2019 16:09:15 -0400

git-svn-id: branches/wasm@45922 -
nickysn 5 years ago
parent
commit
7e8b442c5c
3 changed files with 72 additions and 79 deletions
  1. 5 3
      compiler/wasm/hlcgcpu.pas
  2. 53 71
      compiler/wasm/nwasmadd.pas
  3. 14 5
      compiler/wasm/nwasmflw.pas

+ 5 - 3
compiler/wasm/hlcgcpu.pas

@@ -1345,12 +1345,14 @@ implementation
       if l = current_procinfo.CurrBreakLabel then begin
         // todo: this should be moved to node generator pass2
         list.concat(taicpu.op_const(a_i32_const, 0));
-        list.concat(taicpu.op_const(a_br,1))
+        list.concat(taicpu.op_const(a_br,2+blocks))
       end else if l = current_procinfo.CurrContinueLabel then begin
         list.concat(taicpu.op_const(a_i32_const, 0));
-        list.concat(taicpu.op_const(a_br,0))
-      end else
+        list.concat(taicpu.op_const(a_br,1+blocks))
+      end else begin
         //Internalerror(2019091806); // unexpected jump
+        Internalerror(2019091806); // unexpected jump
+      end;
     end;
 
   procedure thlcgwasm.concatcopy_normal_array(list: TAsmList; size: tdef; const source, dest: treference);

+ 53 - 71
compiler/wasm/nwasmadd.pas

@@ -27,7 +27,7 @@ interface
 
     uses
        cgbase,
-       node,ncgadd,cpubase;
+       node,ncgadd,cpubase, globals, pass_2;
 
     type
 
@@ -38,12 +38,16 @@ interface
           procedure second_generic_compare(unsigned: boolean);
 
           procedure pass_left_right;override;
-          procedure second_addfloat;override;
+          //procedure second_addfloat;override;
           procedure second_cmpfloat;override;
           procedure second_cmpboolean;override;
           procedure second_cmp64bit;override;
           procedure second_add64bit; override;
           procedure second_cmpordinal;override;
+
+          // special treatement for short-boolean expressions
+          // using IF block, instead of direct labels
+          procedure second_addboolean; override;
        end;
 
   implementation
@@ -73,75 +77,6 @@ interface
       end;
 
 
-    procedure twasmaddnode.second_addfloat;
-      //var
-      //  op : TAsmOp;
-      //  commutative : boolean;
-      begin
-        //pass_left_right;
-        //
-        //location_reset(location,LOC_FPUREGISTER,def_cgsize(resultdef));
-        //location.register:=hlcg.getfpuregister(current_asmdata.CurrAsmList,resultdef);
-        //
-        //commutative:=false;
-        //case nodetype of
-        //  addn :
-        //    begin
-        //      if location.size=OS_F64 then
-        //        op:=a_dadd
-        //      else
-        //        op:=a_fadd;
-        //      commutative:=true;
-        //    end;
-        //  muln :
-        //    begin
-        //      if location.size=OS_F64 then
-        //        op:=a_dmul
-        //      else
-        //        op:=a_fmul;
-        //      commutative:=true;
-        //    end;
-        //  subn :
-        //    begin
-        //      if location.size=OS_F64 then
-        //        op:=a_dsub
-        //      else
-        //        op:=a_fsub;
-        //    end;
-        //  slashn :
-        //    begin
-        //      if location.size=OS_F64 then
-        //        op:=a_ddiv
-        //      else
-        //        op:=a_fdiv;
-        //    end;
-        //  else
-        //    internalerror(2011010402);
-        //end;
-        //
-        //{ swap the operands to make it easier for the optimizer to optimize
-        //  the operand stack slot reloading (non-commutative operations must
-        //  always be in the correct order though) }
-        //if (commutative and
-        //    (left.location.loc in [LOC_FPUREGISTER,LOC_CFPUREGISTER]) and
-        //    (right.location.loc in [LOC_FPUREGISTER,LOC_CFPUREGISTER])) or
-        //   (not commutative and
-        //    (nf_swapped in flags)) then
-        //  swapleftright;
-        //
-        //thlcgjvm(hlcg).a_load_loc_stack(current_asmdata.CurrAsmList,left.resultdef,left.location);
-        //thlcgjvm(hlcg).a_load_loc_stack(current_asmdata.CurrAsmList,right.resultdef,right.location);
-        //
-        //current_asmdata.CurrAsmList.concat(taicpu.op_none(op));
-        //thlcgjvm(hlcg).decstack(current_asmdata.CurrAsmList,1+ord(location.size=OS_F64));
-        //{ could be optimized in the future by keeping the results on the stack,
-        //  if we add code to swap the operands when necessary (a_swap for
-        //  singles, store/load/load for doubles since there is no swap for
-        //  2-slot elements -- also adjust expectloc in that case! }
-        //thlcgjvm(hlcg).a_load_stack_reg(current_asmdata.CurrAsmList,resultdef,location.register);
-      end;
-
-
     procedure twasmaddnode.second_cmpfloat;
       //var
       //  truelabel,
@@ -212,6 +147,53 @@ interface
         second_generic_compare(not is_signed(left.resultdef));
       end;
 
+    procedure twasmaddnode.second_addboolean;
+      begin
+        if (nodetype in [orn,andn]) and
+           (not(cs_full_boolean_eval in current_settings.localswitches) or
+            (nf_short_bool in flags)) then
+        begin
+          secondpass(left);
+          current_asmdata.CurrAsmList.Concat( taicpu.op_none(a_if) );
+
+          case nodetype of
+              andn :
+                begin
+                   // inside of IF (the condition evaluated as true)
+                   // for "and" must evaluate the right section
+                   secondpass(right);
+
+                   current_asmdata.CurrAsmList.Concat( taicpu.op_none(a_else) );
+
+                   // inside of ELSE (the condition evaluated as false)
+                   // for "and" must end evaluation immediately
+                   current_asmdata.CurrAsmList.Concat( taicpu.op_const(a_i32_const, 0) );
+                   current_asmdata.CurrAsmList.Concat( taicpu.op_none(a_end) );
+                end;
+              orn :
+                begin
+                   // inside of IF (the condition evaluated as true)
+                   // for "or" must end evalaution immediately - satified!
+                   current_asmdata.CurrAsmList.Concat( taicpu.op_const(a_i32_const, 1) );
+
+                   current_asmdata.CurrAsmList.Concat( taicpu.op_none(a_else) );
+                   // inside of ELSE (the condition evaluated as false)
+                   // for "or" must evaluate the right part
+                   secondpass(right);
+                   // inside of ELSE (the condition evaluated as false)
+                   // for "and" must end evaluation immediately
+                   current_asmdata.CurrAsmList.Concat( taicpu.op_none(a_end) );
+                end;
+              else
+                Internalerror(2019091902);
+              end;
+          // todo: need to reset location to the stack?
+
+          //Internalerror(2019091901);
+        end else
+          inherited;
+      end;
+
     procedure twasmaddnode.second_generic_compare(unsigned: boolean);
       var
         truelabel,

+ 14 - 5
compiler/wasm/nwasmflw.pas

@@ -24,7 +24,7 @@ unit nwasmflw;
 interface
 
 uses
-  aasmbase,node,nflw,ncgflw;
+  aasmbase,node,nflw,ncgflw, cutils;
 
 type
 
@@ -101,15 +101,22 @@ begin
   if lnf_testatbegin in loopflags then
     pass_generate_code_condition;
 
+  current_asmdata.CurrAsmList.concat(taicpu.op_none(a_block));
+
   current_procinfo.CurrContinueLabel:=lcont;
   current_procinfo.CurrBreakLabel:=lbreak;
 
   secondpass(right);
 
-  if not (lnf_testatbegin in loopflags) then
-    pass_generate_code_condition;
+  if (lnf_testatbegin in loopflags) then
+    current_asmdata.CurrAsmList.concat(taicpu.op_const(a_br,1) ); // jump back to the external loop
 
-  current_asmdata.CurrAsmList.concat(taicpu.op_const(a_br,0) );
+  current_asmdata.CurrAsmList.concat(tai_comment.create(strpnew('end of internal loop block')));
+  current_asmdata.CurrAsmList.concat(taicpu.op_none(a_end));
+  if not (lnf_testatbegin in loopflags) then begin
+    pass_generate_code_condition;
+  end;
+  current_asmdata.CurrAsmList.concat(taicpu.op_const(a_br,0) ); // jump back to loop
 
   current_asmdata.CurrAsmList.concat(taicpu.op_none(a_end));
   current_asmdata.CurrAsmList.concat(taicpu.op_none(a_end));
@@ -136,13 +143,14 @@ begin
   secondpass(left); // condition exprssions
 
   current_asmdata.CurrAsmList.concat(taicpu.op_none(a_if)); // IF
+  thlcgwasm(hlcg).incblock;
 
   secondpass(right); // then branchs
 
   if Assigned(t1) then // else branch
     begin
       // 0 const on stack if used to return IF value
-      current_asmdata.CurrAsmList.concat(taicpu.op_const(a_i32_const, 0));
+      current_asmdata.CurrAsmList.concat(taicpu.op_const(a_i32_const, 1));
       current_asmdata.CurrAsmList.concat(taicpu.op_none(a_else));
       secondpass(t1);
     end
@@ -158,6 +166,7 @@ begin
   // 0 const on stack if used to return IF value
   current_asmdata.CurrAsmList.concat(taicpu.op_const(a_i32_const, 0));
   current_asmdata.CurrAsmList.concat(taicpu.op_none(a_end));
+  thlcgwasm(hlcg).decblock;
 
   // clearing IF return value
   current_asmdata.CurrAsmList.concat(taicpu.op_none(a_drop));