* 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 -
This commit is contained in:
Jonas Maebe 2016-11-21 07:39:13 +00:00
parent ade45eb31a
commit 48ef33a8b3
5 changed files with 141 additions and 4 deletions

2
.gitattributes vendored
View File

@ -345,6 +345,7 @@ compiler/llvm/nllvmbas.pas svneol=native#text/plain
compiler/llvm/nllvmcal.pas svneol=native#text/plain compiler/llvm/nllvmcal.pas svneol=native#text/plain
compiler/llvm/nllvmcnv.pas svneol=native#text/plain compiler/llvm/nllvmcnv.pas svneol=native#text/plain
compiler/llvm/nllvmcon.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/nllvminl.pas svneol=native#text/plain
compiler/llvm/nllvmld.pas svneol=native#text/plain compiler/llvm/nllvmld.pas svneol=native#text/plain
compiler/llvm/nllvmmat.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/ncgld.pas svneol=native#text/plain
compiler/ncgmat.pas svneol=native#text/plain compiler/ncgmat.pas svneol=native#text/plain
compiler/ncgmem.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/ncgnstld.pas svneol=native#text/plain
compiler/ncgnstmm.pas svneol=native#text/plain compiler/ncgnstmm.pas svneol=native#text/plain
compiler/ncgobjc.pas svneol=native#text/plain compiler/ncgobjc.pas svneol=native#text/plain

View File

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

View File

@ -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.

View File

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

68
compiler/ncgnstfl.pas Normal file
View File

@ -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.