mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-20 18:09:08 +02:00
* Adapted from patch node-dump-pass-1.patch submitted by J. Gareth Moreton from bug report 38156.
This patch extends the DEBUG_NODE_XML debug feature by also outputting, to the *-node-dump.xml files, the node tree as it appears after the first pass, since it often contains many more internal nodes like temporary allocations that may need to be evaluated for debugging and development purposes, or node-level optimisation opportunities. git-svn-id: trunk@47709 -
This commit is contained in:
parent
54627fe1e7
commit
a7232669ff
@ -86,7 +86,7 @@ interface
|
|||||||
function has_assembler_child : boolean;
|
function has_assembler_child : boolean;
|
||||||
procedure set_eh_info; override;
|
procedure set_eh_info; override;
|
||||||
{$ifdef DEBUG_NODE_XML}
|
{$ifdef DEBUG_NODE_XML}
|
||||||
procedure XMLPrintProc;
|
procedure XMLPrintProc(FirstHalf: Boolean);
|
||||||
{$endif DEBUG_NODE_XML}
|
{$endif DEBUG_NODE_XML}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1437,14 +1437,18 @@ implementation
|
|||||||
|
|
||||||
|
|
||||||
{$ifdef DEBUG_NODE_XML}
|
{$ifdef DEBUG_NODE_XML}
|
||||||
procedure tcgprocinfo.XMLPrintProc;
|
procedure tcgprocinfo.XMLPrintProc(FirstHalf: Boolean);
|
||||||
var
|
var
|
||||||
T: Text;
|
T: Text;
|
||||||
W: Word;
|
W: Word;
|
||||||
syssym: tsyssym;
|
syssym: tsyssym;
|
||||||
|
separate : boolean;
|
||||||
|
|
||||||
procedure PrintType(Flag: string);
|
procedure PrintType(Flag: string);
|
||||||
begin
|
begin
|
||||||
|
if df_generic in procdef.defoptions then
|
||||||
|
Write(T, ' type="generic ', Flag, '"')
|
||||||
|
else
|
||||||
Write(T, ' type="', Flag, '"');
|
Write(T, ' type="', Flag, '"');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1467,8 +1471,13 @@ implementation
|
|||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
{$pop}
|
{$pop}
|
||||||
Write(T, PrintNodeIndention, '<subroutine');
|
|
||||||
|
|
||||||
|
separate := (df_generic in procdef.defoptions);
|
||||||
|
|
||||||
|
{ First half prints the header and the nodes as a "code" tag }
|
||||||
|
if FirstHalf or separate then
|
||||||
|
begin
|
||||||
|
Write(T, PrintNodeIndention, '<subroutine');
|
||||||
{ Check to see if the procedure is a class or object method }
|
{ Check to see if the procedure is a class or object method }
|
||||||
if Assigned(procdef.struct) then
|
if Assigned(procdef.struct) then
|
||||||
begin
|
begin
|
||||||
@ -1477,10 +1486,9 @@ implementation
|
|||||||
else
|
else
|
||||||
Write(T, ' struct="<NULL>"');
|
Write(T, ' struct="<NULL>"');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
case procdef.proctypeoption of
|
case procdef.proctypeoption of
|
||||||
potype_none: { Do nothing };
|
potype_none:
|
||||||
|
{ Do nothing - should this be an internal error though? };
|
||||||
potype_procedure,
|
potype_procedure,
|
||||||
potype_function:
|
potype_function:
|
||||||
if po_classmethod in procdef.procoptions then
|
if po_classmethod in procdef.procoptions then
|
||||||
@ -1489,9 +1497,9 @@ implementation
|
|||||||
PrintType('static class method')
|
PrintType('static class method')
|
||||||
else
|
else
|
||||||
PrintType('class method');
|
PrintType('class method');
|
||||||
end;
|
end
|
||||||
{ Do nothing otherwise }
|
else if df_generic in procdef.defoptions then
|
||||||
|
Write(T, ' type="generic"');
|
||||||
potype_proginit,
|
potype_proginit,
|
||||||
potype_unitinit:
|
potype_unitinit:
|
||||||
PrintType('initialization');
|
PrintType('initialization');
|
||||||
@ -1522,10 +1530,8 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
Write(T, ' name="', SanitiseXMLString(procdef.customprocname([pno_showhidden, pno_noclassmarker])), '"');
|
Write(T, ' name="', SanitiseXMLString(procdef.customprocname([pno_showhidden, pno_noclassmarker])), '"');
|
||||||
|
|
||||||
if po_hascallingconvention in procdef.procoptions then
|
if po_hascallingconvention in procdef.procoptions then
|
||||||
Write(T, ' convention="', proccalloptionStr[procdef.proccalloption], '"');
|
Write(T, ' convention="', proccalloptionStr[procdef.proccalloption], '"');
|
||||||
|
|
||||||
WriteLn(T, '>');
|
WriteLn(T, '>');
|
||||||
|
|
||||||
PrintNodeIndent;
|
PrintNodeIndent;
|
||||||
@ -1555,21 +1561,42 @@ implementation
|
|||||||
PrintOption('noreturn');
|
PrintOption('noreturn');
|
||||||
if po_noinline in procdef.procoptions then
|
if po_noinline in procdef.procoptions then
|
||||||
PrintOption('noinline');
|
PrintOption('noinline');
|
||||||
|
end;
|
||||||
|
|
||||||
if Assigned(Code) then
|
if Assigned(Code) then
|
||||||
begin
|
begin
|
||||||
WriteLn(T, PrintNodeIndention, '<code>');
|
if FirstHalf then
|
||||||
|
WriteLn(T, PrintNodeIndention, '<code>')
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
WriteLn(T); { Line for spacing }
|
||||||
|
WriteLn(T, PrintNodeIndention, '<firstpass>');
|
||||||
|
end;
|
||||||
|
|
||||||
PrintNodeIndent;
|
PrintNodeIndent;
|
||||||
XMLPrintNode(T, Code);
|
XMLPrintNode(T, Code);
|
||||||
PrintNodeUnindent;
|
PrintNodeUnindent;
|
||||||
WriteLn(T, PrintNodeIndention, '</code>');
|
|
||||||
end
|
|
||||||
else
|
|
||||||
WriteLn(T, PrintNodeIndention, '<code />');
|
|
||||||
|
|
||||||
|
if FirstHalf then
|
||||||
|
WriteLn(T, PrintNodeIndention, '</code>')
|
||||||
|
else
|
||||||
|
WriteLn(T, PrintNodeIndention, '</firstpass>');
|
||||||
|
end
|
||||||
|
else { Code=Nil }
|
||||||
|
begin
|
||||||
|
{ Don't print anything for second half - if there's no code, there's no firstpass }
|
||||||
|
if FirstHalf then
|
||||||
|
WriteLn(T, PrintNodeIndention, '<code />');
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Print footer only for second half }
|
||||||
|
if (not FirstHalf) or separate then
|
||||||
|
begin
|
||||||
PrintNodeUnindent;
|
PrintNodeUnindent;
|
||||||
WriteLn(T, PrintNodeIndention, '</subroutine>');
|
WriteLn(T, PrintNodeIndention, '</subroutine>');
|
||||||
WriteLn(T); { Line for spacing }
|
WriteLn(T); { Line for spacing }
|
||||||
|
end;
|
||||||
|
|
||||||
Close(T);
|
Close(T);
|
||||||
end;
|
end;
|
||||||
{$endif DEBUG_NODE_XML}
|
{$endif DEBUG_NODE_XML}
|
||||||
@ -1789,7 +1816,14 @@ implementation
|
|||||||
don't need to generate anything. When it was an empty
|
don't need to generate anything. When it was an empty
|
||||||
procedure there would be at least a blocknode }
|
procedure there would be at least a blocknode }
|
||||||
if not assigned(code) then
|
if not assigned(code) then
|
||||||
|
begin
|
||||||
|
{$ifdef DEBUG_NODE_XML}
|
||||||
|
{ Print out nodes as they appear after the first pass }
|
||||||
|
XMLPrintProc(True);
|
||||||
|
XMLPrintProc(False);
|
||||||
|
{$endif DEBUG_NODE_XML}
|
||||||
exit;
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
{ We need valid code }
|
{ We need valid code }
|
||||||
if Errorcount<>0 then
|
if Errorcount<>0 then
|
||||||
@ -1883,6 +1917,10 @@ implementation
|
|||||||
(procdef.proccalloption=pocall_safecall) then
|
(procdef.proccalloption=pocall_safecall) then
|
||||||
include(flags, pi_needs_implicit_finally);
|
include(flags, pi_needs_implicit_finally);
|
||||||
{$endif}
|
{$endif}
|
||||||
|
{$ifdef DEBUG_NODE_XML}
|
||||||
|
{ Print out nodes as they appear after the first pass }
|
||||||
|
XMLPrintProc(True);
|
||||||
|
{$endif DEBUG_NODE_XML}
|
||||||
{ firstpass everything }
|
{ firstpass everything }
|
||||||
flowcontrol:=[];
|
flowcontrol:=[];
|
||||||
do_firstpass(code);
|
do_firstpass(code);
|
||||||
@ -1912,7 +1950,14 @@ implementation
|
|||||||
do_optloadmodifystore(code);
|
do_optloadmodifystore(code);
|
||||||
|
|
||||||
{ only do secondpass if there are no errors }
|
{ only do secondpass if there are no errors }
|
||||||
if (ErrorCount=0) then
|
if (ErrorCount<>0) then
|
||||||
|
begin
|
||||||
|
{$ifdef DEBUG_NODE_XML}
|
||||||
|
{ Print out nodes as they appear after the first pass }
|
||||||
|
XMLPrintProc(False);
|
||||||
|
{$endif DEBUG_NODE_XML}
|
||||||
|
end
|
||||||
|
else
|
||||||
begin
|
begin
|
||||||
create_hlcodegen;
|
create_hlcodegen;
|
||||||
|
|
||||||
@ -1962,6 +2007,11 @@ implementation
|
|||||||
if paraprintnodetree <> 0 then
|
if paraprintnodetree <> 0 then
|
||||||
printproc( 'right before code generation');
|
printproc( 'right before code generation');
|
||||||
|
|
||||||
|
{$ifdef DEBUG_NODE_XML}
|
||||||
|
{ Print out nodes as they appear after the first pass }
|
||||||
|
XMLPrintProc(False);
|
||||||
|
{$endif DEBUG_NODE_XML}
|
||||||
|
|
||||||
{ generate code for the node tree }
|
{ generate code for the node tree }
|
||||||
do_secondpass(code);
|
do_secondpass(code);
|
||||||
aktproccode.concatlist(current_asmdata.CurrAsmList);
|
aktproccode.concatlist(current_asmdata.CurrAsmList);
|
||||||
@ -2470,7 +2520,10 @@ implementation
|
|||||||
printproc( 'after parsing');
|
printproc( 'after parsing');
|
||||||
|
|
||||||
{$ifdef DEBUG_NODE_XML}
|
{$ifdef DEBUG_NODE_XML}
|
||||||
XMLPrintProc;
|
{ Methods of generic classes don't get any code generated, so output
|
||||||
|
the node tree here }
|
||||||
|
if (df_generic in procdef.defoptions) then
|
||||||
|
XMLPrintProc(True);
|
||||||
{$endif DEBUG_NODE_XML}
|
{$endif DEBUG_NODE_XML}
|
||||||
|
|
||||||
{ ... remove symbol tables }
|
{ ... remove symbol tables }
|
||||||
|
Loading…
Reference in New Issue
Block a user