mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-22 17:49:27 +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;
|
exit;
|
||||||
|
|
||||||
{ remove possible typecasts }
|
{ 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
|
{ when it is not passed in a parameter it will only be used after the
|
||||||
function call }
|
function call }
|
||||||
@ -2327,7 +2327,7 @@ implementation
|
|||||||
point
|
point
|
||||||
}
|
}
|
||||||
if assigned(methodpointer) and
|
if assigned(methodpointer) and
|
||||||
realassignmenttarget.isequal(methodpointer.actualtargetnode) then
|
realassignmenttarget.isequal(actualtargetnode(@methodpointer)^) then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
{ when we substitute a function result inside an inlined function,
|
{ when we substitute a function result inside an inlined function,
|
||||||
@ -3169,7 +3169,7 @@ implementation
|
|||||||
{ skip (absolute and other simple) type conversions -- only now,
|
{ skip (absolute and other simple) type conversions -- only now,
|
||||||
because the checks above have to take type conversions into
|
because the checks above have to take type conversions into
|
||||||
e.g. class reference types account }
|
e.g. class reference types account }
|
||||||
hpt:=hpt.actualtargetnode;
|
hpt:=actualtargetnode(@hpt)^;
|
||||||
|
|
||||||
{ R.Init then R will be initialized by the constructor,
|
{ R.Init then R will be initialized by the constructor,
|
||||||
Also allow it for simple loads }
|
Also allow it for simple loads }
|
||||||
|
@ -803,7 +803,7 @@ implementation
|
|||||||
var
|
var
|
||||||
offsetdec,
|
offsetdec,
|
||||||
extraoffset : aint;
|
extraoffset : aint;
|
||||||
t : tnode;
|
rightp : pnode;
|
||||||
otl,ofl : tasmlabel;
|
otl,ofl : tasmlabel;
|
||||||
newsize : tcgsize;
|
newsize : tcgsize;
|
||||||
mulsize,
|
mulsize,
|
||||||
@ -981,34 +981,26 @@ implementation
|
|||||||
not is_packed_array(left.resultdef) then
|
not is_packed_array(left.resultdef) then
|
||||||
begin
|
begin
|
||||||
extraoffset:=0;
|
extraoffset:=0;
|
||||||
if (right.nodetype=addn) then
|
rightp:=actualtargetnode(@right);
|
||||||
|
if rightp^.nodetype=addn then
|
||||||
begin
|
begin
|
||||||
if taddnode(right).right.nodetype=ordconstn then
|
if taddnode(rightp^).right.nodetype=ordconstn then
|
||||||
begin
|
begin
|
||||||
extraoffset:=tordconstnode(taddnode(right).right).value.svalue;
|
extraoffset:=tordconstnode(taddnode(rightp^).right).value.svalue;
|
||||||
t:=taddnode(right).left;
|
replacenode(rightp^,taddnode(rightp^).left);
|
||||||
taddnode(right).left:=nil;
|
|
||||||
right.free;
|
|
||||||
right:=t;
|
|
||||||
end
|
end
|
||||||
else if taddnode(right).left.nodetype=ordconstn then
|
else if taddnode(rightp^).left.nodetype=ordconstn then
|
||||||
begin
|
begin
|
||||||
extraoffset:=tordconstnode(taddnode(right).left).value.svalue;
|
extraoffset:=tordconstnode(taddnode(rightp^).left).value.svalue;
|
||||||
t:=taddnode(right).right;
|
replacenode(rightp^,taddnode(rightp^).right);
|
||||||
taddnode(right).right:=nil;
|
|
||||||
right.free;
|
|
||||||
right:=t;
|
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
else if (right.nodetype=subn) then
|
else if rightp^.nodetype=subn then
|
||||||
begin
|
begin
|
||||||
if taddnode(right).right.nodetype=ordconstn then
|
if taddnode(rightp^).right.nodetype=ordconstn then
|
||||||
begin
|
begin
|
||||||
extraoffset:=-tordconstnode(taddnode(right).right).value.svalue;
|
extraoffset:=-tordconstnode(taddnode(rightp^).right).value.svalue;
|
||||||
t:=taddnode(right).left;
|
replacenode(rightp^,taddnode(rightp^).left);
|
||||||
taddnode(right).left:=nil;
|
|
||||||
right.free;
|
|
||||||
right:=t;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
inc(location.reference.offset,
|
inc(location.reference.offset,
|
||||||
|
@ -48,7 +48,6 @@ interface
|
|||||||
procedure buildderefimpl;override;
|
procedure buildderefimpl;override;
|
||||||
procedure derefimpl;override;
|
procedure derefimpl;override;
|
||||||
function dogetcopy : tnode;override;
|
function dogetcopy : tnode;override;
|
||||||
function actualtargetnode: tnode;override;
|
|
||||||
procedure printnodeinfo(var t : text);override;
|
procedure printnodeinfo(var t : text);override;
|
||||||
function pass_1 : tnode;override;
|
function pass_1 : tnode;override;
|
||||||
function pass_typecheck:tnode;override;
|
function pass_typecheck:tnode;override;
|
||||||
@ -2101,15 +2100,6 @@ implementation
|
|||||||
end;
|
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;
|
function ttypeconvnode.pass_typecheck:tnode;
|
||||||
|
|
||||||
var
|
var
|
||||||
|
@ -367,10 +367,6 @@ interface
|
|||||||
{ does the real copying of a node }
|
{ does the real copying of a node }
|
||||||
function dogetcopy : tnode;virtual;
|
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;
|
procedure insertintolist(l : tnodelist);virtual;
|
||||||
{ writes a node for debugging purpose, shouldn't be called }
|
{ writes a node for debugging purpose, shouldn't be called }
|
||||||
{ direct, because there is no test for nil, use printnode }
|
{ direct, because there is no test for nil, use printnode }
|
||||||
@ -952,12 +948,6 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function tnode.actualtargetnode: tnode;
|
|
||||||
begin
|
|
||||||
result:=self;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure tnode.insertintolist(l : tnodelist);
|
procedure tnode.insertintolist(l : tnodelist);
|
||||||
begin
|
begin
|
||||||
end;
|
end;
|
||||||
|
@ -82,6 +82,7 @@ interface
|
|||||||
|
|
||||||
{ tries to simplify the given node after inlining }
|
{ tries to simplify the given node after inlining }
|
||||||
procedure doinlinesimplify(var n : tnode);
|
procedure doinlinesimplify(var n : tnode);
|
||||||
|
|
||||||
{ creates an ordinal constant, optionally based on the result from a
|
{ creates an ordinal constant, optionally based on the result from a
|
||||||
simplify operation: normally the type is the smallest integer type
|
simplify operation: normally the type is the smallest integer type
|
||||||
that can hold the value, but when inlining the "def" will be used instead,
|
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 }
|
if no dirty tricks like buffer overflows or pointer magic are used }
|
||||||
function is_const(node : tnode) : boolean;
|
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
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
@ -1144,4 +1157,30 @@ implementation
|
|||||||
result:=(node.nodetype=temprefn) and (ti_const in ttemprefnode(node).tempinfo^.flags)
|
result:=(node.nodetype=temprefn) and (ti_const in ttemprefnode(node).tempinfo^.flags)
|
||||||
end;
|
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.
|
end.
|
||||||
|
@ -151,7 +151,7 @@ unit optcse;
|
|||||||
assigned(n.resultdef) and
|
assigned(n.resultdef) and
|
||||||
(
|
(
|
||||||
{ regable expressions }
|
{ 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
|
((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 }
|
{ is_int/fpuregable allows arrays and records to be in registers, cse cannot handle this }
|
||||||
(not(n.resultdef.typ in [arraydef,recorddef])) and
|
(not(n.resultdef.typ in [arraydef,recorddef])) and
|
||||||
|
Loading…
Reference in New Issue
Block a user