<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 14 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:Wingdings;
panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
{font-family:Wingdings;
panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
{font-family:Tahoma;
panose-1:2 11 6 4 3 5 4 4 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
margin-bottom:.0001pt;
font-size:12.0pt;
font-family:"Times New Roman","serif";}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:purple;
text-decoration:underline;}
span.EmailStyle17
{mso-style-type:personal-reply;
font-family:"Calibri","sans-serif";
color:#1F497D;}
.MsoChpDefault
{mso-style-type:export-only;
font-family:"Calibri","sans-serif";}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal" style="margin-left:.5in">I think that would be a mistake - the way that DW_AT_specification is …<span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p></o:p></span></p>
<p class="MsoNormal"><a name="_MailEndCompose"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></a></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">DW_AT_specification says the completing declaration "does not need to duplicate information" which is way weaker than requiring redundant attributes to be omitted.
So "mistake" seems a bit strong here.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in">I imagine you have a specific problem, though, with the PS4 debugger not being able to cope with this?<span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">Honestly I have no idea what our debugger would do with this; our merge-and-test cycle is nowhere near that fast, you just committed this yesterday.
</span><span style="font-size:11.0pt;font-family:Wingdings;color:#1F497D">J</span><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"> Being legal syntactically, I'd expect we would cope just fine, however.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">No, my suggestion is just because it looked weird to me, and as a human reading a dwarfdump it would be a double-take. But if you feel that strongly about
it, well, okay.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">--paulr<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt">
<div>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">From:</span></b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif""> David Blaikie [mailto:dblaikie@gmail.com]
<br>
<b>Sent:</b> Wednesday, October 07, 2015 9:26 AM<br>
<b>To:</b> Robinson, Paul<br>
<b>Cc:</b> llvm-commits@lists.llvm.org; Eric Christopher<br>
<b>Subject:</b> Re: [llvm] r249487 - DebugInfo: Include the decl_line/decl_file in subprogram definitions if they differ from those in the declaration<o:p></o:p></span></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal">On Wed, Oct 7, 2015 at 9:17 AM, David Blaikie <<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>> wrote:<o:p></o:p></p>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div>
<div>
<p class="MsoNormal">On Wed, Oct 7, 2015 at 9:07 AM, Robinson, Paul <<a href="mailto:Paul_Robinson@playstation.sony.com" target="_blank">Paul_Robinson@playstation.sony.com</a>> wrote:<o:p></o:p></p>
<p class="MsoNormal">Resending because reply-all didn't cc llvm-commits...<br>
<br>
> -----Original Message-----<br>
> From: llvm-commits [mailto:<a href="mailto:llvm-commits-bounces@lists.llvm.org" target="_blank">llvm-commits-bounces@lists.llvm.org</a>] On Behalf<br>
> Of David Blaikie via llvm-commits<br>
> Sent: Tuesday, October 06, 2015 5:04 PM<br>
> To: <a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><o:p></o:p></p>
<div>
<div>
<p class="MsoNormal">> Subject: [llvm] r249487 - DebugInfo: Include the decl_line/decl_file in<br>
> subprogram definitions if they differ from those in the declaration<br>
><br>
> Author: dblaikie<br>
> Date: Tue Oct 6 19:04:16 2015<br>
> New Revision: 249487<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=249487&view=rev" target="_blank">
http://llvm.org/viewvc/llvm-project?rev=249487&view=rev</a><br>
> Log:<br>
> DebugInfo: Include the decl_line/decl_file in subprogram definitions if<br>
> they differ from those in the declaration<br>
><br>
> This is handy for some AutoFDO stuff, and seems like a minor improvement<br>
> to correctness (otherwise a debug info consumer might think the decl<br>
> line/file of the def was the same as that of the declaration - though<br>
> what a consumer might use that for, I'm not sure - maybe "list <func>"<br>
> would've misbehaved with the old behavior?) and at a minor cost (in my<br>
> experiment, with fission, without type units, without compression, 0.01%<br>
> growth in debug info in the executable/objects, 0.02% growth in the .dwo<br>
> files).<br>
><br>
> Added:<br>
> llvm/trunk/test/DebugInfo/Generic/def-line.ll<br>
> Modified:<br>
> llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp<br>
> llvm/trunk/test/DebugInfo/X86/concrete_out_of_line.ll<br>
> llvm/trunk/test/DebugInfo/X86/dwarf-public-names.ll<br>
><br>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal">> URL: <a href="http://llvm.org/viewvc/llvm-" target="_blank">
http://llvm.org/viewvc/llvm-</a><br>
> project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp?rev=249487&r1=2494<br>
> 86&r2=249487&view=diff<br>
> ==========================================================================<br>
> ====<br>
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp (original)<br>
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp Tue Oct 6 19:04:16<br>
> 2015<br>
> @@ -1151,6 +1151,14 @@ bool DwarfUnit::applySubprogramDefinitio<br>
> "definition DIE was created in "<br>
> "getOrCreateSubprogramDIE");<br>
> DeclLinkageName = SPDecl->getLinkageName();<br>
> + unsigned DeclID =<br>
> + getOrCreateSourceID(SPDecl->getFilename(), SPDecl-<br>
> >getDirectory());<br>
> + unsigned DefID = getOrCreateSourceID(SP->getFilename(), SP-<br>
> >getDirectory());<br>
> + if (DeclID != DefID)<br>
> + addUInt(SPDie, dwarf::DW_AT_decl_file, None, DefID);<br>
> +<br>
> + if (SP->getLine() != SPDecl->getLine())<br>
> + addUInt(SPDie, dwarf::DW_AT_decl_line, None, SP->getLine());<br>
<br>
Please emit both together, not potentially just one or the other.<br>
(Based on the Principle of Least Surprise; these attributes are<br>
commonly considered a pair, even if it is syntactically legal to<br>
provide only one or the other.)<o:p></o:p></p>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</div>
</div>
<div>
<p class="MsoNormal">I think that would be a mistake - the way that DW_AT_specification is specified is similar to entities with DW_AT_abstract_origin - the idea being that most attributes are inherited from the declaration to the definition, except where the
definition overrides them. (the wording is a bit vague about which things should be considered inherited and which should not - it provides some examples of obvious things not to inherit, and then basically leaves it up to the implementation, it seems)<o:p></o:p></p>
</div>
</div>
</div>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Oh, and GCC already does this (not sure for how long it's been doing it - I imagine for a while, given the way one might implement it to naturally collapse matching attribute values between decl and def) so there's some precedent for consumers
being able to cope with it.<br>
<br>
I imagine you have a specific problem, though, with the PS4 debugger not being able to cope with this?<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"> <o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<div>
<div>
<p class="MsoNormal"><br>
Again, it's not a huge size growth, and including both or neither might reduce the abbrev growth slightly (less variety in abbrevs) so it's not a technical difficulty, just a philosophical one.<br>
<br>
- Dave<o:p></o:p></p>
</div>
<div>
<div>
<div>
<p class="MsoNormal"> <o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<p class="MsoNormal">--paulr<br>
<br>
> }<br>
><o:p></o:p></p>
<div>
<div>
<p class="MsoNormal">> // Add function template parameters.<br>
><br>
> Added: llvm/trunk/test/DebugInfo/Generic/def-line.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-" target="_blank">http://llvm.org/viewvc/llvm-</a><br>
> project/llvm/trunk/test/DebugInfo/Generic/def-line.ll?rev=249487&view=auto<br>
> ==========================================================================<br>
> ====<br>
> --- llvm/trunk/test/DebugInfo/Generic/def-line.ll (added)<br>
> +++ llvm/trunk/test/DebugInfo/Generic/def-line.ll Tue Oct 6 19:04:16 2015<br>
> @@ -0,0 +1,95 @@<br>
> +; REQUIRES: object-emission<br>
> +<br>
> +; RUN: %llc_dwarf < %s -filetype=obj | llvm-dwarfdump -debug-dump=info -<br>
> | FileCheck %s<br>
> +<br>
> +; Given the following source, ensure that the decl_line/file is correctly<br>
> +; emitted and omitted on definitions if it mismatches/matches the<br>
> declaration<br>
> +<br>
> +; struct foo {<br>
> +; static void f1() {<br>
> +; }<br>
> +; static void f2();<br>
> +; static void f3();<br>
> +; };<br>
> +; void foo::f2() {<br>
> +; f1(); // just to ensure f1 is emitted<br>
> +; }<br>
> +; #line 1 "bar.cpp"<br>
> +; void foo::f3() {<br>
> +; }<br>
> +<br>
> +; Skip the declarations<br>
> +; CHECK: DW_TAG_subprogram<br>
> +; CHECK: DW_TAG_subprogram<br>
> +; CHECK: DW_TAG_subprogram<br>
> +<br>
> +; CHECK: DW_TAG_subprogram<br>
> +; CHECK-NOT: {{DW_TAG|NULL|DW_AT_decl_file}}<br>
> +; CHECK: DW_AT_decl_line {{.*}}7<br>
> +; CHECK-NOT: {{DW_TAG|NULL|DW_AT_decl_file}}<br>
> +; CHECK: DW_AT_specification {{.*}}f2<br>
> +; CHECK-NOT: {{DW_TAG|NULL|DW_AT_decl_file}}<br>
> +<br>
> +; CHECK: DW_TAG_subprogram<br>
> +; CHECK-NOT: {{DW_TAG|NULL|DW_AT_decl_line|DW_AT_decl_file}}<br>
> +; CHECK: DW_AT_specification {{.*}}f1<br>
> +<br>
> +; CHECK: DW_TAG_subprogram<br>
> +; CHECK-NOT: {{DW_TAG|NULL}}<br>
> +; CHECK: DW_AT_decl_file {{.*}}bar.cpp<br>
> +; CHECK-NOT: {{DW_TAG|NULL}}<br>
> +; CHECK: DW_AT_decl_line {{.*}}1<br>
> +; CHECK-NOT: {{DW_TAG|NULL}}<br>
> +; CHECK: DW_AT_specification {{.*}}f3<br>
> +<br>
> +$_ZN3foo2f1Ev = comdat any<br>
> +<br>
> +; Function Attrs: uwtable<br>
> +define void @_ZN3foo2f2Ev() #0 align 2 {<br>
> +entry:<br>
> + call void @_ZN3foo2f1Ev(), !dbg !19<br>
> + ret void, !dbg !20<br>
> +}<br>
> +<br>
> +; Function Attrs: nounwind uwtable<br>
> +define linkonce_odr void @_ZN3foo2f1Ev() #1 comdat align 2 {<br>
> +entry:<br>
> + ret void, !dbg !21<br>
> +}<br>
> +<br>
> +; Function Attrs: nounwind uwtable<br>
> +define void @_ZN3foo2f3Ev() #1 align 2 {<br>
> +entry:<br>
> + ret void, !dbg !22<br>
> +}<br>
> +<br>
> +attributes #0 = { uwtable "disable-tail-calls"="false" "less-precise-<br>
> fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-<br>
> leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-<br>
> protector-buffer-size"="8" "target-cpu"="x86-64" "target-<br>
> features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }<br>
> +attributes #1 = { nounwind uwtable "disable-tail-calls"="false" "less-<br>
> precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-<br>
> elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-<br>
> protector-buffer-size"="8" "target-cpu"="x86-64" "target-<o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal">> features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }<br>
> +<br>
> +!<a href="http://llvm.dbg.cu" target="_blank">llvm.dbg.cu</a> = !{!0}<br>
> +!llvm.module.flags = !{!16, !17}<br>
> +!llvm.ident = !{!18}<br>
> +<br>
> +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1,<br>
> producer: "clang version 3.8.0 (trunk 249440) (llvm/trunk 249465)",<br>
> isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2,<br>
> retainedTypes: !3, subprograms: !11)<br>
> +!1 = !DIFile(filename: "def-line.cpp", directory: "/tmp/dbginfo")<br>
> +!2 = !{}<br>
> +!3 = !{!4}<br>
> +!4 = !DICompositeType(tag: DW_TAG_structure_type, name: "foo", file: !1,<br>
> line: 1, size: 8, align: 8, elements: !5, identifier: "_ZTS3foo")<br>
> +!5 = !{!6, !9, !10}<br>
> +!6 = !DISubprogram(name: "f1", linkageName: "_ZN3foo2f1Ev", scope:<br>
> !"_ZTS3foo", file: !1, line: 2, type: !7, isLocal: false, isDefinition:<br>
> false, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: false)<br>
> +!7 = !DISubroutineType(types: !8)<br>
> +!8 = !{null}<br>
> +!9 = !DISubprogram(name: "f2", linkageName: "_ZN3foo2f2Ev", scope:<br>
> !"_ZTS3foo", file: !1, line: 4, type: !7, isLocal: false, isDefinition:<br>
> false, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: false)<br>
> +!10 = !DISubprogram(name: "f3", linkageName: "_ZN3foo2f3Ev", scope:<br>
> !"_ZTS3foo", file: !1, line: 5, type: !7, isLocal: false, isDefinition:<br>
> false, scopeLine: 5, flags: DIFlagPrototyped, isOptimized: false)<br>
> +!11 = !{!12, !13, !15}<br>
> +!12 = distinct !DISubprogram(name: "f2", linkageName: "_ZN3foo2f2Ev",<br>
> scope: !"_ZTS3foo", file: !1, line: 7, type: !7, isLocal: false,<br>
> isDefinition: true, scopeLine: 7, flags: DIFlagPrototyped, isOptimized:<br>
> false, function: void ()* @_ZN3foo2f2Ev, declaration: !9, variables: !2)<br>
> +!13 = distinct !DISubprogram(name: "f3", linkageName: "_ZN3foo2f3Ev",<br>
> scope: !"_ZTS3foo", file: !14, line: 1, type: !7, isLocal: false,<br>
> isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized:<br>
> false, function: void ()* @_ZN3foo2f3Ev, declaration: !10, variables: !2)<br>
> +!14 = !DIFile(filename: "bar.cpp", directory: "/tmp/dbginfo")<br>
> +!15 = distinct !DISubprogram(name: "f1", linkageName: "_ZN3foo2f1Ev",<br>
> scope: !"_ZTS3foo", file: !1, line: 2, type: !7, isLocal: false,<br>
> isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized:<br>
> false, function: void ()* @_ZN3foo2f1Ev, declaration: !6, variables: !2)<br>
> +!16 = !{i32 2, !"Dwarf Version", i32 4}<br>
> +!17 = !{i32 2, !"Debug Info Version", i32 3}<br>
> +!18 = !{!"clang version 3.8.0 (trunk 249440) (llvm/trunk 249465)"}<br>
> +!19 = !DILocation(line: 8, column: 3, scope: !12)<br>
> +!20 = !DILocation(line: 9, column: 1, scope: !12)<br>
> +!21 = !DILocation(line: 3, column: 3, scope: !15)<br>
> +!22 = !DILocation(line: 2, column: 1, scope: !13)<br>
><br>
> Modified: llvm/trunk/test/DebugInfo/X86/concrete_out_of_line.ll<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal">> URL: <a href="http://llvm.org/viewvc/llvm-" target="_blank">
http://llvm.org/viewvc/llvm-</a><br>
> project/llvm/trunk/test/DebugInfo/X86/concrete_out_of_line.ll?rev=249487&r<br>
> 1=249486&r2=249487&view=diff<br>
> ==========================================================================<br>
> ====<br>
> --- llvm/trunk/test/DebugInfo/X86/concrete_out_of_line.ll (original)<br>
> +++ llvm/trunk/test/DebugInfo/X86/concrete_out_of_line.ll Tue Oct 6<br>
> 19:04:16 2015<br>
> @@ -18,12 +18,14 @@<br>
> ; CHECK: DW_AT_name {{.*}} "~nsAutoRefCnt"<br>
><br>
> ; CHECK: DW_TAG_subprogram<br>
> +; CHECK-NEXT: DW_AT_decl_line {{.*}}18<br>
> ; CHECK-NEXT: DW_AT_{{.*}}linkage_name {{.*}}D2<br>
> ; CHECK-NEXT: DW_AT_specification {{.*}} "~nsAutoRefCnt"<br>
> ; CHECK-NEXT: DW_AT_inline<br>
> ; CHECK-NOT: DW_AT<br>
> ; CHECK: DW_TAG<br>
> ; CHECK: DW_TAG_subprogram<br>
> +; CHECK-NEXT: DW_AT_decl_line {{.*}}18<br>
> ; CHECK-NEXT: DW_AT_{{.*}}linkage_name {{.*}}D1<br>
> ; CHECK-NEXT: DW_AT_specification {{.*}} "~nsAutoRefCnt"<br>
> ; CHECK-NEXT: DW_AT_inline<br>
><br>
> Modified: llvm/trunk/test/DebugInfo/X86/dwarf-public-names.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-" target="_blank">http://llvm.org/viewvc/llvm-</a><br>
> project/llvm/trunk/test/DebugInfo/X86/dwarf-public-<br>
> names.ll?rev=249487&r1=249486&r2=249487&view=diff<br>
> ==========================================================================<br>
> ====<o:p></o:p></p>
<div>
<div>
<p class="MsoNormal">> --- llvm/trunk/test/DebugInfo/X86/dwarf-public-names.ll (original)<br>
> +++ llvm/trunk/test/DebugInfo/X86/dwarf-public-names.ll Tue Oct 6<br>
> 19:04:16 2015<br>
> @@ -43,7 +43,7 @@<br>
><br>
> ; Skip the output to the header of the pubnames section.<br>
> ; LINUX: debug_pubnames<br>
> -; LINUX-NEXT: unit_size = 0x00000128<br>
> +; LINUX-NEXT: unit_size = 0x0000012a<br>
><br>
> ; Check for each name in the output.<br>
> ; LINUX-DAG: "ns"<br>
><br>
><br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" target="_blank">
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><o:p></o:p></p>
</div>
</div>
</blockquote>
</div>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</div>
</blockquote>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</div>
</div>
</div>
</body>
</html>