* use temp-reference nodes rather than addrnodes to create references to

complex parameters passed to inlined routines on the JVM target, because
    it is not possible to take the address of any kind of node on the JVM
    target (temp-reference nodes work for any kind of LOC_(C)REFERENCE, but
    are currently only implemented for the JVM platform)

git-svn-id: branches/jvmbackend@18905 -
This commit is contained in:
Jonas Maebe 2011-08-29 22:58:55 +00:00
parent 49817c9a0e
commit 6a7ff1cf75
2 changed files with 46 additions and 17 deletions

View File

@ -28,7 +28,7 @@ interface
uses uses
cgbase, cgbase,
symtype,symdef, symtype,symdef,
node,ncgcal; node,ncal,ncgcal;
type type
tjvmcallparanode = class(tcgcallparanode) tjvmcallparanode = class(tcgcallparanode)
@ -43,6 +43,7 @@ interface
tjvmcallnode = class(tcgcallnode) tjvmcallnode = class(tcgcallnode)
protected protected
procedure wrapcomplexinlinepara(para: tcallparanode); override;
procedure extra_pre_call_code; override; procedure extra_pre_call_code; override;
procedure set_result_location(realresdef: tstoreddef); override; procedure set_result_location(realresdef: tstoreddef); override;
procedure do_release_unused_return_value;override; procedure do_release_unused_return_value;override;
@ -59,7 +60,6 @@ implementation
uses uses
verbose,globtype,constexp,cutils, verbose,globtype,constexp,cutils,
symconst,symtable,symsym,defutil, symconst,symtable,symsym,defutil,
ncal,
cgutils,tgobj,procinfo,htypechk, cgutils,tgobj,procinfo,htypechk,
cpubase,aasmdata,aasmcpu, cpubase,aasmdata,aasmcpu,
hlcgobj,hlcgcpu, hlcgobj,hlcgcpu,
@ -311,6 +311,26 @@ implementation
TJVMCALLNODE TJVMCALLNODE
*****************************************************************************} *****************************************************************************}
procedure tjvmcallnode.wrapcomplexinlinepara(para: tcallparanode);
var
tempnode: ttempcreatenode;
begin
{ don't use caddrnodes for the JVM target, because we can't take the
address of every kind of type (e.g., of ansistrings). A temp-reference
node does work for any kind of memory reference (and the expectloc
is LOC_(C)REFERENCE when this routine is called), but is not (yet)
supported for other targets }
tempnode:=ctempcreatenode.create_reference(para.parasym.vardef,para.parasym.vardef.size,
tt_persistent,tparavarsym(para.parasym).is_regvar(false),para.left,false);
addstatement(inlineinitstatement,tempnode);
addstatement(inlinecleanupstatement,ctempdeletenode.create(tempnode));
para.left:=ctemprefnode.create(tempnode);
{ inherit addr_taken flag }
if (tabstractvarsym(para.parasym).addr_taken) then
include(tempnode.tempinfo^.flags,ti_addr_taken);
end;
procedure tjvmcallnode.extra_pre_call_code; procedure tjvmcallnode.extra_pre_call_code;
begin begin
{ when calling a constructor, first create a new instance, except { when calling a constructor, first create a new instance, except

View File

@ -80,12 +80,13 @@ interface
protected protected
procedure objc_convert_to_message_send;virtual; procedure objc_convert_to_message_send;virtual;
private protected
{ inlining support } { inlining support }
inlinelocals : TFPObjectList; inlinelocals : TFPObjectList;
inlineinitstatement, inlineinitstatement,
inlinecleanupstatement : tstatementnode; inlinecleanupstatement : tstatementnode;
procedure createinlineparas; procedure createinlineparas;
procedure wrapcomplexinlinepara(para: tcallparanode); virtual;
function replaceparaload(var n: tnode; arg: pointer): foreachnoderesult; function replaceparaload(var n: tnode; arg: pointer): foreachnoderesult;
procedure createlocaltemps(p:TObject;arg:pointer); procedure createlocaltemps(p:TObject;arg:pointer);
function optimize_funcret_assignment(inlineblock: tblocknode): tnode; function optimize_funcret_assignment(inlineblock: tblocknode): tnode;
@ -3667,8 +3668,6 @@ implementation
para: tcallparanode; para: tcallparanode;
tempnode: ttempcreatenode; tempnode: ttempcreatenode;
n: tnode; n: tnode;
paraaddr: taddrnode;
ptrtype: tpointerdef;
paracomplexity: longint; paracomplexity: longint;
pushconstaddr: boolean; pushconstaddr: boolean;
begin begin
@ -3802,18 +3801,7 @@ implementation
{ temp } { temp }
else if (paracomplexity > 1) then else if (paracomplexity > 1) then
begin begin
ptrtype:=getpointerdef(para.left.resultdef); wrapcomplexinlinepara(para);
tempnode := ctempcreatenode.create(ptrtype,ptrtype.size,tt_persistent,tparavarsym(para.parasym).is_regvar(true));
addstatement(inlineinitstatement,tempnode);
addstatement(inlinecleanupstatement,ctempdeletenode.create(tempnode));
{ inherit addr_taken flag }
if (tabstractvarsym(para.parasym).addr_taken) then
include(tempnode.tempinfo^.flags,ti_addr_taken);
paraaddr:=caddrnode.create_internal(para.left);
include(paraaddr.flags,nf_typedaddr);
addstatement(inlineinitstatement,cassignmentnode.create(ctemprefnode.create(tempnode),
paraaddr));
para.left:=cderefnode.create(ctemprefnode.create(tempnode));
end; end;
end; end;
para := tcallparanode(para.right); para := tcallparanode(para.right);
@ -3827,6 +3815,27 @@ implementation
end; end;
procedure tcallnode.wrapcomplexinlinepara(para: tcallparanode);
var
ptrtype: tdef;
tempnode: ttempcreatenode;
paraaddr: taddrnode;
begin
ptrtype:=getpointerdef(para.left.resultdef);
tempnode := ctempcreatenode.create(ptrtype,ptrtype.size,tt_persistent,tparavarsym(para.parasym).is_regvar(true));
addstatement(inlineinitstatement,tempnode);
addstatement(inlinecleanupstatement,ctempdeletenode.create(tempnode));
{ inherit addr_taken flag }
if (tabstractvarsym(para.parasym).addr_taken) then
include(tempnode.tempinfo^.flags,ti_addr_taken);
paraaddr:=caddrnode.create_internal(para.left);
include(paraaddr.flags,nf_typedaddr);
addstatement(inlineinitstatement,cassignmentnode.create(ctemprefnode.create(tempnode),
paraaddr));
para.left:=cderefnode.create(ctemprefnode.create(tempnode));
end;
function tcallnode.optimize_funcret_assignment(inlineblock: tblocknode): tnode; function tcallnode.optimize_funcret_assignment(inlineblock: tblocknode): tnode;
var var
hp : tstatementnode; hp : tstatementnode;