+ no stackframe is generated for i386 if possible

git-svn-id: trunk@2162 -
This commit is contained in:
florian 2006-01-04 19:19:06 +00:00
parent a85bb43749
commit f7d2c47f73
5 changed files with 94 additions and 5 deletions

View File

@ -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;

View File

@ -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 }

View File

@ -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;

View File

@ -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);

View File

@ -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 }