mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-21 15:49:26 +02:00
+ no stackframe is generated for i386 if possible
git-svn-id: trunk@2162 -
This commit is contained in:
parent
a85bb43749
commit
f7d2c47f73
@ -240,7 +240,9 @@ than 255 characters. That's why using Ansi Strings}
|
||||
pi_needs_got,
|
||||
{ references var/proc/type/const in static symtable,
|
||||
i.e. not allowed for inlining from other units }
|
||||
pi_uses_static_symtable
|
||||
pi_uses_static_symtable,
|
||||
{ set if the procedure has to push parameters onto the stack }
|
||||
pi_has_stackparameter
|
||||
);
|
||||
tprocinfoflags=set of tprocinfoflag;
|
||||
|
||||
|
@ -264,7 +264,7 @@ unit cgcpu;
|
||||
end
|
||||
else
|
||||
list.concat(Taicpu.op_none(A_LEAVE,S_NO));
|
||||
list.concat(tai_regalloc.dealloc(NR_FRAME_POINTER_REG,nil));
|
||||
list.concat(tai_regalloc.dealloc(current_procinfo.framepointer,nil));
|
||||
end;
|
||||
|
||||
{ return from proc }
|
||||
|
@ -130,6 +130,9 @@ interface
|
||||
procedure printnodedata(var t:text);override;
|
||||
function para_count:longint;
|
||||
function get_load_methodpointer:tnode;
|
||||
{ checks if there are any parameters which end up at the stack, i.e.
|
||||
which have LOC_REFERENCE and set pi_has_stackparameter if this applies }
|
||||
procedure check_stack_parameters;
|
||||
private
|
||||
AbstractMethodsList : TStringList;
|
||||
end;
|
||||
@ -2333,6 +2336,22 @@ type
|
||||
end;
|
||||
|
||||
|
||||
procedure tcallnode.check_stack_parameters;
|
||||
var
|
||||
hp : tcallparanode;
|
||||
begin
|
||||
hp:=tcallparanode(left);
|
||||
while assigned(hp) do
|
||||
begin
|
||||
if assigned(hp.parasym) and
|
||||
assigned(hp.parasym.paraloc[callerside].location) and
|
||||
(hp.parasym.paraloc[callerside].location^.loc=LOC_REFERENCE) then
|
||||
include(current_procinfo.flags,pi_has_stackparameter);
|
||||
hp:=tcallparanode(hp.right);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
function tcallnode.pass_1 : tnode;
|
||||
var
|
||||
st : tsymtable;
|
||||
@ -2378,7 +2397,16 @@ type
|
||||
|
||||
{ work trough all parameters to get the register requirements }
|
||||
if assigned(left) then
|
||||
tcallparanode(left).det_registers;
|
||||
begin
|
||||
tcallparanode(left).det_registers;
|
||||
|
||||
if cs_optimize in aktglobalswitches then
|
||||
begin
|
||||
{ check for stacked parameters }
|
||||
check_stack_parameters;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
{ order parameters }
|
||||
order_parameters;
|
||||
|
@ -54,6 +54,8 @@ interface
|
||||
procedure add_to_symtablestack;
|
||||
procedure remove_from_symtablestack;
|
||||
procedure parse_body;
|
||||
|
||||
function stack_tainting_parameter : boolean;
|
||||
end;
|
||||
|
||||
|
||||
@ -96,7 +98,7 @@ implementation
|
||||
scanner,import,gendef,
|
||||
pbase,pstatmnt,pdecl,pdecsub,pexports,
|
||||
{ codegen }
|
||||
tgobj,cgobj,dbgbase,
|
||||
tgobj,cgbase,cgobj,dbgbase,
|
||||
ncgutil,regvars
|
||||
{$if defined(arm) or defined(powerpc) or defined(powerpc64)}
|
||||
,aasmcpu
|
||||
@ -604,6 +606,29 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure check_for_stack(p : tnamedindexitem;arg:pointer);
|
||||
begin
|
||||
if tsym(p).typ=paravarsym then
|
||||
begin
|
||||
{ check if there no parameter of the current procedure is stack dependend }
|
||||
if is_open_array(tparavarsym(p).vartype.def) or
|
||||
is_array_of_const(tparavarsym(p).vartype.def) then
|
||||
pboolean(arg)^:=true;
|
||||
if assigned(p) and
|
||||
assigned(tparavarsym(p).paraloc[calleeside].location) and
|
||||
(tparavarsym(p).paraloc[calleeside].location^.loc=LOC_REFERENCE) then
|
||||
pboolean(arg)^:=true;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
function tcgprocinfo.stack_tainting_parameter : boolean;
|
||||
begin
|
||||
result:=false;
|
||||
procdef.parast.foreach_static(@check_for_stack,@result);
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgprocinfo.generate_code;
|
||||
var
|
||||
oldprocinfo : tprocinfo;
|
||||
@ -680,6 +705,38 @@ implementation
|
||||
{ set the start offset to the start of the temp area in the stack }
|
||||
tg:=ttgobj.create;
|
||||
|
||||
{$ifdef i386}
|
||||
{ try to strip the stack frame }
|
||||
{ set the framepointer to esp if:
|
||||
- no assembler directive, those are handled elsewhere
|
||||
- no exceptions are used
|
||||
- no debug info
|
||||
- no pushes are used/esp modifications, could be:
|
||||
* outgoing parameters on the stack
|
||||
* incoming parameters on the stack
|
||||
* open arrays
|
||||
- no inline assembler
|
||||
}
|
||||
if (cs_optimize in aktglobalswitches) and
|
||||
not(po_assembler in procdef.procoptions) and
|
||||
((flags*[pi_has_assembler_block,pi_uses_exceptions,pi_is_assembler,
|
||||
pi_needs_implicit_finally,pi_has_implicit_finally,pi_has_stackparameter])=[]) then
|
||||
begin
|
||||
{ we need the parameter info here to determine if the procedure gets
|
||||
parameters on the stack
|
||||
|
||||
calling generate_parameter_info doesn't hurt but it costs time
|
||||
}
|
||||
generate_parameter_info;
|
||||
if not(stack_tainting_parameter) then
|
||||
begin
|
||||
{ Only need to set the framepointer }
|
||||
framepointer:=NR_STACK_POINTER_REG;
|
||||
tg.direction:=1;
|
||||
end;
|
||||
end;
|
||||
{$endif i386}
|
||||
|
||||
{ Create register allocator }
|
||||
cg.init_register_allocators;
|
||||
|
||||
@ -713,6 +770,7 @@ implementation
|
||||
procdef.has_paraloc_info:=true;
|
||||
end;
|
||||
|
||||
|
||||
{ generate code for the node tree }
|
||||
do_secondpass(code);
|
||||
aktproccode.concatlist(exprasmlist);
|
||||
|
@ -1839,11 +1839,12 @@ unit cgx86;
|
||||
{ save old framepointer }
|
||||
if not nostackframe then
|
||||
begin
|
||||
list.concat(tai_regalloc.alloc(current_procinfo.framepointer,nil));
|
||||
if (current_procinfo.framepointer=NR_STACK_POINTER_REG) then
|
||||
CGmessage(cg_d_stackframe_omited)
|
||||
else
|
||||
begin
|
||||
list.concat(tai_regalloc.alloc(NR_FRAME_POINTER_REG,nil));
|
||||
|
||||
include(rg[R_INTREGISTER].preserved_by_proc,RS_FRAME_POINTER_REG);
|
||||
list.concat(Taicpu.op_reg(A_PUSH,tcgsize2opsize[OS_ADDR],NR_FRAME_POINTER_REG));
|
||||
{ Return address and FP are both on stack }
|
||||
|
Loading…
Reference in New Issue
Block a user