mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-09 21:48:35 +02:00
* 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:
parent
7e70a5f763
commit
be2ab84474
@ -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 }
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user