* 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:
pierre 2020-12-07 07:28:04 +00:00
parent 54627fe1e7
commit a7232669ff

View File

@ -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="&lt;NULL&gt;"'); Write(T, ' struct="&lt;NULL&gt;"');
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 }