<html><head><style type='text/css'>p { margin: 0; }</style></head><body><div style='font-family: arial,helvetica,sans-serif; font-size: 10pt; color: #000000'><br><hr id="zwchr"><blockquote style="border-left: 2px solid rgb(16, 16, 255); margin-left: 5px; padding-left: 5px; color: rgb(0, 0, 0); font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;"><b>From: </b>"Zvi Rackover" <zvi.rackover@intel.com><br><b>To: </b>"Hal Finkel" <hfinkel@anl.gov>, "Gadi Haber" <gadi.haber@intel.com><br><b>Cc: </b>llvm-dev@lists.llvm.org<br><b>Sent: </b>Monday, November 28, 2016 8:50:15 AM<br><b>Subject: </b>RE: [llvm-dev] RFC: code size reduction in X86 by replacing EVEX with        VEX encoding<br><br>


<style><!--

@font-face
        {font-family:Helvetica;
        panose-1:2 11 6 4 2 2 2 2 2 4;}
@font-face
        {font-family:Wingdings;
        panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Consolas;
        panose-1:2 11 6 9 2 2 4 3 2 4;}

p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:#0563C1;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:#954F72;
        text-decoration:underline;}
p
        {mso-style-priority:99;
        margin:0cm;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman",serif;}
pre
        {mso-style-priority:99;
        mso-style-link:"HTML Preformatted Char";
        margin:0cm;
        margin-bottom:.0001pt;
        font-size:10.0pt;
        font-family:"Courier New";}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
        {mso-style-priority:34;
        margin-top:0cm;
        margin-right:0cm;
        margin-bottom:0cm;
        margin-left:36.0pt;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
span.HTMLPreformattedChar
        {mso-style-name:"HTML Preformatted Char";
        mso-style-priority:99;
        mso-style-link:"HTML Preformatted";
        font-family:"Courier New";}
span.EmailStyle20
        {mso-style-type:personal;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
span.EmailStyle21
        {mso-style-type:personal;
        font-family:"Calibri",sans-serif;
        color:#1F497D;}
span.EmailStyle22
        {mso-style-type:personal;
        font-family:"Calibri",sans-serif;
        color:#1F497D;}
span.EmailStyle23
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 90.0pt 72.0pt 90.0pt;}
div.WordSection1
        {page:WordSection1;}

@list l0
        {mso-list-id:1255554927;
        mso-list-type:hybrid;
        mso-list-template-ids:1879840464 588819812 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;}
@list l0:level1
        {mso-level-start-at:0;
        mso-level-number-format:bullet;
        mso-level-text:-;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:"Calibri",sans-serif;
        mso-fareast-font-family:Calibri;
        mso-bidi-font-family:Arial;}
@list l0:level2
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:"Courier New";}
@list l0:level3
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Wingdings;}
@list l0:level4
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Symbol;}
@list l0:level5
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:"Courier New";}
@list l0:level6
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Wingdings;}
@list l0:level7
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Symbol;}
@list l0:level8
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:"Courier New";}
@list l0:level9
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Wingdings;}
ol
        {margin-bottom:0cm;}
ul
        {margin-bottom:0cm;}
--></style>

<div class="WordSection1">
<p class="MsoNormal"><span style="color: rgb(31, 73, 125);">Hal, that’s a good point. There are more manually-maintained tables in the X86 backend that should probably be tablegened: the memory-folding tables and ReplaceableInstrs, to name a couple.</span></p>
<p class="MsoNormal"><span id="DWT2516" style="color: rgb(31, 73, 125);">If you have ideas on how to get these auto-generated, please let us know.</span></p></div></blockquote>I'm going to use  ReplaceableInstrs as an example.  ReplaceableInstrs is more complicated than some of the other mappings because, as you'll see below, there are multiple possible "key" instructions for each generated row of the table (i.e. we need to be able to look up a row in the table by any of the columns). The EVEX -> VEX mapping seems potentially simpler because it lacks this requirement. Nevertheless, hopefully this is useful. Generically, however, I agree with you that we should try to move a number of these manually-maintained tables in the X86 backend over to TableGen. Also, I'm writing this up without trying it, so please excuse any mistakes...<br><br>There are a few ReplaceableInstrs tables in X86InstrInfo.cpp (used by getExecutionDomain/setExecutionDomain) that look like this:<br><br>static const uint16_t ReplaceableInstrs[][3] = {<br>  //PackedSingle     PackedDouble    PackedInt<br>  { X86::MOVAPSmr,   X86::MOVAPDmr,  X86::MOVDQAmr  },<br>  { X86::MOVAPSrm,   X86::MOVAPDrm,  X86::MOVDQArm  },<br>  { X86::MOVAPSrr,   X86::MOVAPDrr,  X86::MOVDQArr  },<br><br>The idea being that, given some instruction, we want to know:<br><br>  1. If it is in the table (in any column)<br>  2. The corresponding instruction in some other domain<br><br>Here's how you might replace this manually-maintained table with a TableGen-generated table using the InstrMapping feature:<br><br>1. In X86InstrInfo.cpp add the line:<br><br>#define GET_INSTRMAP_INFO<br><br>before X86GenInstrInfo.inc is included.<br><br>2. Establish a key field in the instruction class use to establish the relationship between the instructions in each row of the table. You might add to X86Inst something like this:<br><br>  // Key used to relate replaceable instructions.<br>  string ReplaceableInstrKey = "";<br><br>3. Establish some field to act as the column identifier:<br>  string ReplaceableInstrDomain = "";<br><br>in practice, for this case, I assume that we'd want to reuse the existing ExeDomain class to set the value; I think that we can get the name of the class directly like this:<br><br>  string ReplaceableInstrDomain = !cast<string>(d);<br><br>where d is the class parameter used to initialize the ExeDomain field.<br><br>4. For each instruction, set the ReplaceableInstrKey to some unique name for each row; for example, for MOVAPS, MOVAPD, MOVDQA add:<br><br>  let ReplaceableInstrKey = "MOVA" in<br><br>before the associated metaclass instantiations (or use any other of several ways TableGen has to set the field value).<br><br>5. Add a "filter class" definition to X86.td (or where ever else we'd like) like this:<br><br>  // A filter class for the ReplaceableInstrs mapping.<br>  class ReplaceableInstr;<br><br>and make sure that all instructions that will participate in the mapping also derive from this class:<br><br>  defm MOVAPS : foo<bar, ...>, ReplaceableInstr;<br><br>In practice, you might want to combine this step with the previous one (i.e. have the ReplaceableInstr class take a parameter which sets the key field name).<br><br>6. Add the definition of some mappings:<br><br>  def getReplaceableSSEPackedSingleInstr : InstrMapping {<br>    let FilterClass = "ReplaceableInstr";<br>    let RowFields = [ "ReplaceableInstrKey", "FormBits" ];<br>    let ColFields = [ "ReplaceableInstrDomain" ];<br>    let KeyCol = ["SSEPackedSingle"];<br>    let ValueCols = [["SSEPackedSingle"], ["SSEPackedDouble"], ["SSEPackedInt"]];<br>  }<br><br>  def getReplaceableSSEPackedDoubleInstr : InstrMapping {<br>
    let FilterClass = "ReplaceableInstr";<br>
    let RowFields = [ "ReplaceableInstrKey", "FormBits" ];<br>
    let ColFields = [ "ReplaceableInstrDomain" ];<br>
    let KeyCol = ["SSEPackedDouble"];<br>
    let ValueCols = [["SSEPackedSingle"], ["SSEPackedDouble"], ["SSEPackedInt"]];<br>
  }<br><br>  def getReplaceableSSEPackedIntInstr : InstrMapping {<br>
    let FilterClass = "ReplaceableInstr";<br>
    let RowFields = [ "ReplaceableInstrKey", "FormBits" ];<br>
    let ColFields = [ "ReplaceableInstrDomain" ];<br>
    let KeyCol = ["SSEPackedInt"];<br>
    let ValueCols = [["SSEPackedSingle"], ["SSEPackedDouble"], ["SSEPackedInt"]];<br>
  }<br><br>Note that my use of FormBits above is probably not right. I'm trying to make each row identified by the value of ReplaceableInstrKey in addition to the operand types (rr, rm, mr, etc.). I'll also note that it would be nice not to have to define three separate mappings here, but I think that changing that will require some (likely welcome) enhancement to the existing infrastructure.<br><br>7. The code in X86InstrInfo.cpp would then be changed to use the generated mapping lookup functions, perhaps using some utility functions like this:<br><br>static bool isReplaceableInstr(const MachineInstr &MI) {<br>  uint16_t domain = (MI.getDesc().TSFlags >> X86II::SSEDomainShift) & 3;<br>  unsigned opcode = MI.getOpcode();<br>  switch (domain) {<br>  case 1:<br>    return X86::getReplaceableSSEPackedSingleInstr(opcode, X86::ReplaceableInstrDomain_SSEPackedSingle) >= 0;<br>  case 2:<br>     return X86::getReplaceableSSEPackedDoubleInstr(opcode, X86::ReplaceableInstrDomain_SSEPackedDouble) >= 0;<br>  case 3:<br>     return X86::getReplaceableSSEPackedIntInstr(opcode, X86::ReplaceableInstrDomain_SSEPackedInt) >= 0;<br>  }<br>}<br><br>static unsigned getReplacementInstrInDomain(const MachineInstr &MI, unsigned newDomain) {<br>  uint16_t domain = (MI.getDesc().TSFlags >> X86II::SSEDomainShift) & 3;<br>
  unsigned opcode = MI.getOpcode();<br><br>  unsigned newDomainKey;<br>  switch (newDomain) {<br>  case 1: newDomainKey = X86::ReplaceableInstrDomain_SSEPackedSingle; break;<br>  case 2: newDomainKey = X86::ReplaceableInstrDomain_SSEPackedDouble; break;<br>  case 3; newDomainKey = X86::ReplaceableInstrDomain_SSEPackedInt; break;<br>  }<br><br>
  switch (domain) {<br>
  case 1:<br>
    return X86::getReplaceableSSEPackedSingleInstr(opcode, newDomainKey);<br>
  case 2:<br>
     return X86::getReplaceableSSEPackedDoubleInstr(opcode, newDomainKey);<br>
  case 3:<br>
     return X86::getReplaceableSSEPackedIntInstr(opcode, newDomainKey);<br>
  }<br>}<br><br> -Hal<br><blockquote style="border-left: 2px solid rgb(16, 16, 255); margin-left: 5px; padding-left: 5px; color: rgb(0, 0, 0); font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;"><div class="WordSection1"><p class="MsoNormal"><span style="color: rgb(31, 73, 125);"></span></p>
<p class="MsoNormal"><a name="_MailEndCompose"><span style="color: rgb(31, 73, 125);"> </span></a></p>
<div>
<div style="border-width: 1pt medium medium; border-style: solid none none; border-color: rgb(225, 225, 225) -moz-use-text-color -moz-use-text-color; padding: 3pt 0cm 0cm;">
<p class="MsoNormal"><a name="_____replyseparator"></a><b>From:</b> llvm-dev [mailto:llvm-dev-bounces@lists.llvm.org]
<b>On Behalf Of </b>Hal Finkel via llvm-dev<br>
<b>Sent:</b> Wednesday, November 23, 2016 15:01<br>
<b>To:</b> Haber, Gadi <gadi.haber@intel.com><br>
<b>Cc:</b> llvm-dev@lists.llvm.org<br>
<b>Subject:</b> Re: [llvm-dev] RFC: code size reduction in X86 by replacing EVEX with VEX encoding</p>
</div>
</div>
<p class="MsoNormal"> </p>
<div>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: "Arial",sans-serif; color: black;"> </span></p>
<div class="MsoNormal" style="text-align: center;" align="center"><span style="font-size: 10pt; font-family: "Arial",sans-serif; color: black;">
<hr id="zwchr" align="center" size="2" width="100%">
</span></div>
<blockquote style="border-width: medium medium medium 1.5pt; border-style: none none none solid; border-color: -moz-use-text-color -moz-use-text-color -moz-use-text-color rgb(16, 16, 255); padding: 0cm 0cm 0cm 4pt; margin-left: 3.75pt; margin-top: 5pt; margin-bottom: 5pt;">
<p class="MsoNormal" style="margin-bottom: 12pt;"><b><span style="font-family: "Helvetica",sans-serif; color: black;">From:
</span></b><span style="font-family: "Helvetica",sans-serif; color: black;">"Gadi via llvm-dev Haber" <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>><br>
<b>To: </b><a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<b>Sent: </b>Wednesday, November 23, 2016 5:50:42 AM<br>
<b>Subject: </b>[llvm-dev] RFC: code size reduction in X86 by replacing EVEX with        VEX encoding</span><span style="font-size: 12pt; font-family: "Helvetica",sans-serif; color: black;"></span></p>
<p class="MsoNormal"><span style="color: black;">Hi All.</span></p>
<p class="MsoNormal"><span style="color: black;"> </span></p>
<p class="MsoNormal"><span style="color: black;">This is an RFC for a proposed target specific X86 optimization for reducing code size in the encoding of AVX-512 instructions when possible.</span></p>
<p class="MsoNormal"><span style="color: black;"> </span></p>
<p class="MsoNormal"><span style="color: black;">When the AVX512F instruction set was introduced in X86 it included additional 32 registers of 512bit size each ZMM0 - ZMM31, as well as additional 16 XMM registers XMM16-XMM31 and 16 YMM registers YMM16-YMM31.</span></p>
<p class="MsoNormal"><span style="color: black;">In order to encode the new registers of 16-31 and the additional instructions, a new encoding prefix called EVEX</span><span style="color: rgb(31, 73, 125);">,</span><span style="color: black;"> which extends the existing VEX
 encoding</span><span style="color: rgb(31, 73, 125);">,</span><span style="color: black;"> was introduced as shown below:</span></p>
<p class="MsoNormal"><span style="color: rgb(31, 73, 125);"> </span><span style="color: black;"></span></p>
<p class="MsoNormal"><span style="font-size: 9.5pt; font-family: Consolas; color: black;">The EVEX encoding format:</span><span style="color: black;"></span></p>
<p class="MsoNormal"><span style="font-size: 9.5pt; font-family: Consolas; color: black;">            EVEX Opcode ModR/M [SIB] [Disp32] / [Disp8*N] [Immediate]</span><span style="color: black;"></span></p>
<p class="MsoNormal"><span style="font-size: 9.5pt; font-family: Consolas; color: black;"># of bytes: 4    1      1      1      4       / 1         1</span><span style="color: black;"></span></p>
<p class="MsoNormal"><span style="color: black;"> </span></p>
<p class="MsoNormal"><span style="color: black;">The existing VEX encoding format:</span></p>
<p class="MsoNormal"><span style="font-size: 9.5pt; font-family: Consolas; color: black;">            [VEX]   OPCODE ModR/M [SIB] [DISP]   [IMM]</span><span style="color: black;"></span></p>
<p class="MsoNormal"><span style="font-size: 9.5pt; font-family: Consolas; color: black;"># of bytes: 0,2,3   1      1      0,1   0,1,2,4  0,1</span><span style="color: black;"></span></p>
<p class="MsoNormal"><span style="font-size: 9.5pt; font-family: Consolas; color: green;"> </span><span style="color: black;"></span></p>
<p class="MsoNormal"><span style="color: black;">Note that the EVEX prefix requires 4 bytes whereas the VEX prefix can take only up to 3 bytes.</span></p>
<p class="MsoNormal"><span style="color: black;">Consequently, for the SKX architecture, many instructions that use only the lower registers of XMM0-XMM15 or YMM0-YMM15, can be encoded by either the EVEX or the VEX format. For such cases, using the VEX encoding
 results in a code size reduction of ~2 bytes even though it is compiled with the AVX512F/AVX512VL features enabled.</span></p>
<p class="MsoNormal"><span style="color: black;"> </span></p>
<p class="MsoNormal"><span style="color: black;">For example: “vmovss  %xmm0, 32(%rsp,%rax,4)“, has the following 2 possible encodings:</span></p>
<p class="MsoNormal"><span style="color: black;"> </span></p>
<p class="MsoNormal"><span style="color: black;">EVEX encoding (8 bytes long):</span></p>
<p class="MsoNormal"><span style="color: black;">            62 f1 7e 08 11 44 84 08         vmovss  %xmm0, 32(%rsp,%rax,4)</span></p>
<p class="MsoNormal"><span style="color: black;"> </span></p>
<p class="MsoNormal"><span style="color: black;">VEX encoding (6 bytes long):</span></p>
<p class="MsoNormal"><span style="color: black;">           c5 fa 11 44 84 20                      vmovss  %xmm0, 32(%rsp,%rax,4)</span></p>
<p class="MsoNormal"><span style="color: black;"> </span></p>
<p class="MsoNormal"><span style="color: black;">See reported Bugzilla bugs about this proposed optimization:</span></p>
<p class="MsoNormal"><span style="color: rgb(31, 73, 125);"><a href="https://llvm.org/bugs/show_bug.cgi?id=23376" target="_blank">https://llvm.org/bugs/show_bug.cgi?id=23376</a></span><span style="color: black;"></span></p>
<p class="MsoNormal"><span style="color: black;"><a href="https://llvm.org/bugs/show_bug.cgi?id=29162" target="_blank">https://llvm.org/bugs/show_bug.cgi?id=29162</a></span></p>
<p class="MsoNormal"><span style="color: black;"> </span></p>
<p class="MsoNormal"><span style="color: black;">The proposed optimization implementation is to add a table of all EVEX opcodes that can be encoded via VEX in a new header file placed under lib/Target/X86.</span></p>
<p class="MsoNormal"><span style="color: black;">A new pass is to be added at the pre-emit stage</span><span style="color: rgb(31, 73, 125);">.</span><span style="color: black;"></span></p>
</blockquote>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: "Arial",sans-serif; color: black;">It might be better to have TableGen generate the mapping table for you instead of manually making a table yourself. TableGen has a feature that is specifically designed
 to make mapping tables like this. For examples, grep for InstrMapping in:<br>
<br>
lib/Target/Hexagon/Hexagon.td<br>
lib/Target/Mips/MipsDSPInstrFormats.td<br>
lib/Target/Mips/MipsInstrFormats.td<br>
lib/Target/Mips/Mips32r6InstrFormats.td<br>
lib/Target/PowerPC/PPC.td<br>
lib/Target/AMDGPU/SIInstrInfo.td<br>
lib/Target/AMDGPU/R600Instructions.td<br>
lib/Target/SystemZ/SystemZInstrFormats.td<br>
lib/Target/Lanai/LanaiInstrInfo.td<br>
<br>
I've used this feature a few times in the PowerPC backend, and it's quite convenient.<br>
<br>
 -Hal</span></p>
<blockquote style="border-width: medium medium medium 1.5pt; border-style: none none none solid; border-color: -moz-use-text-color -moz-use-text-color -moz-use-text-color rgb(16, 16, 255); padding: 0cm 0cm 0cm 4pt; margin-left: 3.75pt; margin-top: 5pt; margin-bottom: 5pt;">
<p class="MsoNormal"><span style="color: black;">No need for special Opt flags, as it is always better to use the reduced VEX encoding when possible.</span></p>
<p class="MsoNormal"><span style="color: black;"> </span></p>
<p class="MsoNormal"><span style="color: black;">Thank you for any comments or questions that you may have.</span></p>
<p class="MsoNormal"><span style="color: rgb(31, 73, 125);"> </span><span style="color: black;"></span></p>
<p class="MsoNormal"><span style="color: black;">Sincerely, </span></p>
<p class="MsoNormal"><span style="color: rgb(31, 73, 125);"> </span><span style="color: black;"></span></p>
<p class="MsoNormal"><span style="color: black;">Gadi. </span></p>
<p class="MsoNormal"><span style="color: black;"> </span></p>
<p><span style="font-family: "Helvetica",sans-serif; color: black;">---------------------------------------------------------------------<br>
Intel Israel (74) Limited</span></p>
<p><span style="font-family: "Helvetica",sans-serif; color: black;">This e-mail and any attachments may contain confidential material for<br>
the sole use of the intended recipient(s). Any review or distribution<br>
by others is strictly prohibited. If you are not the intended<br>
recipient, please contact the sender and delete all copies.</span></p>
<p class="MsoNormal"><span style="font-size: 12pt; font-family: "Helvetica",sans-serif; color: black;"><br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a></span></p>
</blockquote>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: "Arial",sans-serif; color: black;"><br>
<br>
<br>
-- </span></p>
<div>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: "Arial",sans-serif; color: black;">Hal Finkel<br>
Lead, Compiler Technology and Programming Languages<br>
Leadership Computing Facility<br>
Argonne National Laboratory</span></p>
</div>
</div>
</div>
<p>---------------------------------------------------------------------<br>
Intel Israel (74) Limited</p>

<p>This e-mail and any attachments may contain confidential material for<br>
the sole use of the intended recipient(s). Any review or distribution<br>
by others is strictly prohibited. If you are not the intended<br>
recipient, please contact the sender and delete all copies.</p></blockquote><br><br><br>-- <br><div><span></span>Hal Finkel<br>Lead, Compiler Technology and Programming Languages<br>Leadership Computing Facility<br>Argonne National Laboratory<span></span><br></div></div></body></html>