Browse Source

* convert if structured instructions to br_if + labels

Nikolay Nikolov 1 year ago
parent
commit
0f07c966b6
2 changed files with 79 additions and 24 deletions
  1. 63 21
      compiler/wasm32/aasmcpu.pas
  2. 16 3
      compiler/wasm32/cpupi.pas

+ 63 - 21
compiler/wasm32/aasmcpu.pas

@@ -42,7 +42,14 @@ uses
 
     type
       twasmstruc_stack = class;
-      TAsmMapFunc = function(ai: tai; blockstack: twasmstruc_stack): tai of object;
+      TAsmMapFuncResultType = (amfrtNoChange, amfrtNewAi, amfrtNewList);
+      TAsmMapFuncResult = record
+        case typ: TAsmMapFuncResultType of
+          amfrtNoChange: ();
+          amfrtNewAi: (newai: tai);
+          amfrtNewList: (newlist: TAsmList);
+      end;
+      TAsmMapFunc = function(ai: tai; blockstack: twasmstruc_stack): TAsmMapFuncResult of object;
       TWasmLocalAllocator = function(wbt: TWasmBasicType): Integer of object;
 
       { taicpu }
@@ -516,12 +523,12 @@ uses
         if assigned(else_asmlist) then
           list.concatList(else_asmlist);
         SaveResults;
-        list.concat(taicpu.op_sym(a_br, FLabel));
+        list.concat(taicpu.op_sym(a_br, GetLabel));
         list.concat(tai_label.create(then_label));
         RestoreParams;
         list.concatList(then_asmlist);
         SaveResults;
-        list.concat(tai_label.create(FLabel));
+        list.concat(tai_label.create(GetLabel));
         RestoreResults;
       end;
 
@@ -2848,6 +2855,7 @@ uses
     procedure map_structured_asmlist_inner(l: TAsmList; f: TAsmMapFunc; blockstack: twasmstruc_stack);
       var
         p, q: tai;
+        mapres: TAsmMapFuncResult;
       begin
         if not assigned(l) then
           exit;
@@ -2856,27 +2864,61 @@ uses
           begin
             if p.typ=ait_wasm_structured_instruction then
               begin
-                q:=f(p,blockstack);
-                if q<>p then
-                  begin
-                    l.InsertAfter(q,p);
-                    l.Remove(p);
-                    p:=q;
-                  end;
-                taicpu_wasm_structured_instruction(p).Map(f,blockstack);
-                p:=tai(p.next);
+                mapres:=f(p,blockstack);
+                case mapres.typ of
+                  amfrtNoChange:
+                    begin
+                      taicpu_wasm_structured_instruction(p).Map(f,blockstack);
+                      p:=tai(p.next);
+                    end;
+                  amfrtNewAi:
+                    begin
+                      q:=mapres.newai;
+                      if q<>p then
+                        begin
+                          l.InsertAfter(q,p);
+                          l.Remove(p);
+                          p:=q;
+                        end;
+                      p:=tai(p.next);
+                    end;
+                  amfrtNewList:
+                    begin
+                      q:=tai(mapres.newlist.First);
+                      l.insertListAfter(p,mapres.newlist);
+                      mapres.newlist.free;
+                      l.Remove(p);
+                      p:=q;
+                    end;
+                end;
               end
             else
               begin
-                q:=f(p,blockstack);
-                if q<>p then
-                  begin
-                    l.InsertAfter(q,p);
-                    l.Remove(p);
-                    p:=tai(q.next);
-                  end
-                else
-                  p:=tai(p.next);
+                mapres:=f(p,blockstack);
+                case mapres.typ of
+                  amfrtNoChange:
+                    p:=tai(p.next);
+                  amfrtNewAi:
+                    begin
+                      q:=mapres.newai;
+                      if q<>p then
+                        begin
+                          l.InsertAfter(q,p);
+                          l.Remove(p);
+                          p:=tai(q.next);
+                        end
+                      else
+                        p:=tai(p.next);
+                    end;
+                  amfrtNewList:
+                    begin
+                      q:=tai(mapres.newlist.First);
+                      l.insertListAfter(p,mapres.newlist);
+                      mapres.newlist.free;
+                      l.Remove(p);
+                      p:=q;
+                    end;
+                end;
               end;
           end;
       end;

+ 16 - 3
compiler/wasm32/cpupi.pas

@@ -39,7 +39,8 @@ interface
       FFirstFreeLocal: Integer;
       FAllocatedLocals: array of TWasmBasicType;
 
-      function ConvertBranchTargetNumbersToLabels(ai: tai; blockstack: twasmstruc_stack): tai;
+      function ConvertBranchTargetNumbersToLabels(ai: tai; blockstack: twasmstruc_stack): TAsmMapFuncResult;
+      function ConvertIfToBrIf(ai: tai; blockstack: twasmstruc_stack): TAsmMapFuncResult;
 
       { used for allocating locals during the postprocess_code stage (i.e. after register allocation) }
       function AllocWasmLocal(wbt: TWasmBasicType): Integer;
@@ -356,13 +357,13 @@ implementation
                            tcpuprocinfo
 *****************************************************************************}
 
-    function tcpuprocinfo.ConvertBranchTargetNumbersToLabels(ai: tai; blockstack: twasmstruc_stack): tai;
+    function tcpuprocinfo.ConvertBranchTargetNumbersToLabels(ai: tai; blockstack: twasmstruc_stack): TAsmMapFuncResult;
       var
         instr: taicpu;
         bl: taicpu_wasm_structured_instruction;
         l: TAsmLabel;
       begin
-        result:=ai;
+        result.typ:=amfrtNoChange;
         if ai.typ<>ait_instruction then
           exit;
         instr:=taicpu(ai);
@@ -377,6 +378,17 @@ implementation
         instr.loadsymbol(0,l,0);
       end;
 
+    function tcpuprocinfo.ConvertIfToBrIf(ai: tai; blockstack: twasmstruc_stack): TAsmMapFuncResult;
+      begin
+        result.typ:=amfrtNoChange;
+        if (ai.typ=ait_wasm_structured_instruction) and (ai is tai_wasmstruc_if) then
+          begin
+            result.typ:=amfrtNewList;
+            result.newlist:=TAsmList.Create;
+            tai_wasmstruc_if(ai).ConvertToBrIf(result.newlist,@AllocWasmLocal);
+          end;
+      end;
+
     function tcpuprocinfo.AllocWasmLocal(wbt: TWasmBasicType): Integer;
       begin
         SetLength(FAllocatedLocals,Length(FAllocatedLocals)+1);
@@ -643,6 +655,7 @@ implementation
           asmlist:=l2;
 
           map_structured_asmlist(asmlist,@ConvertBranchTargetNumbersToLabels);
+          map_structured_asmlist(asmlist,@ConvertIfToBrIf);
 
           l2:=TAsmList.Create;
           wasm_convert_to_flat_asmlist(asmlist,l2);