* make actualtargetnode a normal procedure using pointers to node so it can be used also when replacing nodes

+ replacenode to replace nodes inline

git-svn-id: trunk@25013 -
This commit is contained in:
florian 2013-06-29 22:20:30 +00:00
parent 7e70a5f763
commit be2ab84474
6 changed files with 56 additions and 45 deletions

View File

@ -2307,7 +2307,7 @@ implementation
exit;
{ remove possible typecasts }
realassignmenttarget:=aktassignmentnode.left.actualtargetnode;
realassignmenttarget:=actualtargetnode(@aktassignmentnode.left)^;
{ when it is not passed in a parameter it will only be used after the
function call }
@ -2327,7 +2327,7 @@ implementation
point
}
if assigned(methodpointer) and
realassignmenttarget.isequal(methodpointer.actualtargetnode) then
realassignmenttarget.isequal(actualtargetnode(@methodpointer)^) then
exit;
{ when we substitute a function result inside an inlined function,
@ -3169,7 +3169,7 @@ implementation
{ skip (absolute and other simple) type conversions -- only now,
because the checks above have to take type conversions into
e.g. class reference types account }
hpt:=hpt.actualtargetnode;
hpt:=actualtargetnode(@hpt)^;
{ R.Init then R will be initialized by the constructor,
Also allow it for simple loads }

View File

@ -803,7 +803,7 @@ implementation
var
offsetdec,
extraoffset : aint;
t : tnode;
rightp : pnode;
otl,ofl : tasmlabel;
newsize : tcgsize;
mulsize,
@ -981,34 +981,26 @@ implementation
not is_packed_array(left.resultdef) then
begin
extraoffset:=0;
if (right.nodetype=addn) then
rightp:=actualtargetnode(@right);
if rightp^.nodetype=addn then
begin
if taddnode(right).right.nodetype=ordconstn then
if taddnode(rightp^).right.nodetype=ordconstn then
begin
extraoffset:=tordconstnode(taddnode(right).right).value.svalue;
t:=taddnode(right).left;
taddnode(right).left:=nil;
right.free;
right:=t;
extraoffset:=tordconstnode(taddnode(rightp^).right).value.svalue;
replacenode(rightp^,taddnode(rightp^).left);
end
else if taddnode(right).left.nodetype=ordconstn then
else if taddnode(rightp^).left.nodetype=ordconstn then
begin
extraoffset:=tordconstnode(taddnode(right).left).value.svalue;
t:=taddnode(right).right;
taddnode(right).right:=nil;
right.free;
right:=t;
extraoffset:=tordconstnode(taddnode(rightp^).left).value.svalue;
replacenode(rightp^,taddnode(rightp^).right);
end;
end
else if (right.nodetype=subn) then
else if rightp^.nodetype=subn then
begin
if taddnode(right).right.nodetype=ordconstn then
if taddnode(rightp^).right.nodetype=ordconstn then
begin
extraoffset:=-tordconstnode(taddnode(right).right).value.svalue;
t:=taddnode(right).left;
taddnode(right).left:=nil;
right.free;
right:=t;
extraoffset:=-tordconstnode(taddnode(rightp^).right).value.svalue;
replacenode(rightp^,taddnode(rightp^).left);
end;
end;
inc(location.reference.offset,

View File

@ -48,7 +48,6 @@ interface
procedure buildderefimpl;override;
procedure derefimpl;override;
function dogetcopy : tnode;override;
function actualtargetnode: tnode;override;
procedure printnodeinfo(var t : text);override;
function pass_1 : tnode;override;
function pass_typecheck:tnode;override;
@ -2101,15 +2100,6 @@ implementation
end;
function ttypeconvnode.actualtargetnode: tnode;
begin
result:=self;
while (result.nodetype=typeconvn) and
ttypeconvnode(result).retains_value_location do
result:=ttypeconvnode(result).left;
end;
function ttypeconvnode.pass_typecheck:tnode;
var

View File

@ -367,10 +367,6 @@ interface
{ does the real copying of a node }
function dogetcopy : tnode;virtual;
{ returns the real loadn/temprefn a node refers to,
skipping (absolute) equal type conversions }
function actualtargetnode: tnode;virtual;
procedure insertintolist(l : tnodelist);virtual;
{ writes a node for debugging purpose, shouldn't be called }
{ direct, because there is no test for nil, use printnode }
@ -952,12 +948,6 @@ implementation
end;
function tnode.actualtargetnode: tnode;
begin
result:=self;
end;
procedure tnode.insertintolist(l : tnodelist);
begin
end;

View File

@ -82,6 +82,7 @@ interface
{ tries to simplify the given node after inlining }
procedure doinlinesimplify(var n : tnode);
{ creates an ordinal constant, optionally based on the result from a
simplify operation: normally the type is the smallest integer type
that can hold the value, but when inlining the "def" will be used instead,
@ -122,6 +123,18 @@ interface
if no dirty tricks like buffer overflows or pointer magic are used }
function is_const(node : tnode) : boolean;
{ returns a pointer to the real node a node refers to,
skipping (absolute) equal type conversions. Returning
a pointer allows the caller to move/remove/replace this
node
}
function actualtargetnode(n : pnode) : pnode;
{ moves src into dest, before doing so, right is set to nil and dest is freed.
Because dest and src are var parameters, this can be done inline in an existing
node tree }
procedure replacenode(var dest,src : tnode);
implementation
uses
@ -1144,4 +1157,30 @@ implementation
result:=(node.nodetype=temprefn) and (ti_const in ttemprefnode(node).tempinfo^.flags)
end;
function actualtargetnode(n : pnode) : pnode;
begin
result:=n;
case n^.nodetype of
typeconvn:
if ttypeconvnode(n^).retains_value_location then
result:=actualtargetnode(@ttypeconvnode(n^).left);
end;
end;
procedure replacenode(var dest,src : tnode);
var
t : tnode;
begin
t:=src;
{ set src nil before free'ing dest because
src could be part of dest }
src:=nil;
dest.Free;
dest:=t;
end;
end.

View File

@ -151,7 +151,7 @@ unit optcse;
assigned(n.resultdef) and
(
{ regable expressions }
(n.actualtargetnode.flags*[nf_write,nf_modify]=[]) and
(actualtargetnode(@n)^.flags*[nf_write,nf_modify]=[]) and
((tstoreddef(n.resultdef).is_intregable or tstoreddef(n.resultdef).is_fpuregable) and
{ is_int/fpuregable allows arrays and records to be in registers, cse cannot handle this }
(not(n.resultdef.typ in [arraydef,recorddef])) and