瀏覽代碼

* fixed interprocedural gotos for llvm
o ensure that the label's local "jumpbuf" variable gets moved to the
parentfpstruct soon enough
o don't generate global symbols for interprocedural labels: they're not
necessary if they are only used via setjmp/longjmp (all references are
local in that case), and if they are referenced via an assembler block
then we'll have to handle them by passing a blockaddress() expression
as parameter to that assembler block (which does not require a global
symbol, but which is not yet implemented)

git-svn-id: trunk@34946 -

Jonas Maebe 8 年之前
父節點
當前提交
48ef33a8b3
共有 5 個文件被更改,包括 141 次插入4 次删除
  1. 2 0
      .gitattributes
  2. 2 2
      compiler/llvm/llvmnode.pas
  3. 67 0
      compiler/llvm/nllvmflw.pas
  4. 2 2
      compiler/ncgflw.pas
  5. 68 0
      compiler/ncgnstfl.pas

+ 2 - 0
.gitattributes

@@ -345,6 +345,7 @@ compiler/llvm/nllvmbas.pas svneol=native#text/plain
 compiler/llvm/nllvmcal.pas svneol=native#text/plain
 compiler/llvm/nllvmcnv.pas svneol=native#text/plain
 compiler/llvm/nllvmcon.pas svneol=native#text/plain
+compiler/llvm/nllvmflw.pas svneol=native#text/plain
 compiler/llvm/nllvminl.pas svneol=native#text/plain
 compiler/llvm/nllvmld.pas svneol=native#text/plain
 compiler/llvm/nllvmmat.pas svneol=native#text/plain
@@ -470,6 +471,7 @@ compiler/ncginl.pas svneol=native#text/plain
 compiler/ncgld.pas svneol=native#text/plain
 compiler/ncgmat.pas svneol=native#text/plain
 compiler/ncgmem.pas svneol=native#text/plain
+compiler/ncgnstfl.pas svneol=native#text/plain
 compiler/ncgnstld.pas svneol=native#text/plain
 compiler/ncgnstmm.pas svneol=native#text/plain
 compiler/ncgobjc.pas svneol=native#text/plain

+ 2 - 2
compiler/llvm/llvmnode.pas

@@ -37,8 +37,8 @@ implementation
     ncgbas,ncgflw,ncgcnv,ncgld,ncgmem,ncgcon,ncgset,
     ncgadd,ncgcal,ncgmat,ncginl,
     tgllvm,hlcgllvm,
-    nllvmadd,nllvmbas,nllvmcal,nllvmcnv,nllvmcon,nllvminl,nllvmld,nllvmmat,
-    nllvmmem,nllvmtcon,nllvmutil,
+    nllvmadd,nllvmbas,nllvmcal,nllvmcnv,nllvmcon,nllvmflw,nllvminl,nllvmld,
+    nllvmmat,nllvmmem,nllvmtcon,nllvmutil,
     llvmpara,
     symllvm;
 

+ 67 - 0
compiler/llvm/nllvmflw.pas

@@ -0,0 +1,67 @@
+{
+    Copyright (c) 2016 by Jonas Maebe
+
+    Generate assembler for nodes that influence the flow for llvm
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+unit nllvmflw;
+
+{$i fpcdefs.inc}
+
+interface
+
+    uses
+      aasmbase,
+      nflw, ncgflw, ncgnstfl;
+
+    type
+      tllvmlabelnode = class(tcglabelnode)
+        function getasmlabel: tasmlabel; override;
+      end;
+
+
+implementation
+
+{*****************************************************************************
+                             SecondLabel
+*****************************************************************************}
+
+    uses
+      aasmdata;
+
+
+    function tllvmlabelnode.getasmlabel: tasmlabel;
+      begin
+        { don't allocate global labels even if the label is accessed from
+          another routine: we always have to refer to such labels using the
+          blockaddress() construct, which works with local labels too.
+          Additionally, LLVM does not support defining global labels in the
+          middle of a routine -> jumping to such a label from assembler code
+          from another function will not work anyway (have to handle that by
+          passing a blockaddress as argument to an assembler block, although
+          "some targets may provide defined semantics when using the value as
+          the operand to an inline assembly") }
+        if not(assigned(asmlabel)) then
+          current_asmdata.getjumplabel(asmlabel);
+        result:=asmlabel
+      end;
+
+begin
+  clabelnode:=tllvmlabelnode;
+end.
+

+ 2 - 2
compiler/ncgflw.pas

@@ -62,10 +62,10 @@ interface
        end;
 
        tcglabelnode = class(tlabelnode)
-       private
+       protected
           asmlabel : tasmlabel;
        public
-          function getasmlabel : tasmlabel;
+          function getasmlabel : tasmlabel; virtual;
           procedure pass_generate_code;override;
        end;
 

+ 68 - 0
compiler/ncgnstfl.pas

@@ -0,0 +1,68 @@
+{
+    Copyright (c) 2016 by Jonas Maebe
+
+    Generate assembler for nodes that influence the flow
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+unit ncgnstfl;
+
+{$i fpcdefs.inc}
+
+interface
+
+    uses
+      node,
+      nflw, ncgflw;
+
+    type
+      tcgnestgotonode = class(tcggotonode)
+        function pass_typecheck: tnode; override;
+      end;
+
+implementation
+
+    uses
+      globtype,globals,
+      nld,
+      symdef,symsym,symcreat;
+
+
+    function tcgnestgotonode.pass_typecheck: tnode;
+      begin
+        result:=inherited;
+        if (m_non_local_goto in current_settings.modeswitches) and
+           assigned(labelsym.jumpbuf) then
+          begin
+            { we will access this jumpbuf local variable from a nested context,
+              but the loadnode to do so only gets created in pass_1. This is too
+              late for us to detect that it should have been added to the
+              parentfpstruct, so temporarily create and typecheckpass a load
+              node for the jumpbuf here (so that it can be added now) }
+            with cloadnode.create(labelsym.jumpbuf,labelsym.jumpbuf.Owner) do
+              begin
+                pass_typecheck;
+                free
+              end;
+          end;
+      end;
+
+
+begin
+  cgotonode:=tcgnestgotonode;
+end.
+