<div dir="ltr">Here's an example using the gcc toolchain for embedded 32 bit RISC-V (my HiFive1 board):<div><br></div><div><div>#include <stdio.h></div><div><br></div><div>int foo(int i){</div><div>    if (i < 100){</div><div>        printf("%d\n", i);</div><div>    }</div><div>    return i;</div><div>}</div><div><br></div><div>int main(){</div><div>    foo(10);</div><div>    return 0;</div><div>}</div></div><div><br></div><div>After compiling to a .o with -O2 -march=RV32IC we get (just looking at foo)</div><div><br></div><div><div>00000000 <foo>:</div><div>   0:<span style="white-space:pre">     </span>1141                <span style="white-space:pre"> </span>addi<span style="white-space:pre"> </span>sp,sp,-16</div><div>   2:<span style="white-space:pre">      </span>c422                <span style="white-space:pre"> </span>sw<span style="white-space:pre">   </span>s0,8(sp)</div><div>   4:<span style="white-space:pre">       </span>c606                <span style="white-space:pre"> </span>sw<span style="white-space:pre">   </span>ra,12(sp)</div><div>   6:<span style="white-space:pre">      </span>06300793          <span style="white-space:pre">      </span>li<span style="white-space:pre">   </span>a5,99</div><div>   a:<span style="white-space:pre">  </span>842a                <span style="white-space:pre"> </span>mv<span style="white-space:pre">   </span>s0,a0</div><div>   c:<span style="white-space:pre">  </span>00a7cb63          <span style="white-space:pre">      </span>blt<span style="white-space:pre">  </span>a5,a0,22 <.L2></div><div>  10:<span style="white-space:pre">    </span>85aa                <span style="white-space:pre"> </span>mv<span style="white-space:pre">   </span>a1,a0</div><div>  12:<span style="white-space:pre">   </span>00000537          <span style="white-space:pre">      </span>lui<span style="white-space:pre">  </span>a0,0x0</div><div>  16:<span style="white-space:pre">  </span>00050513          <span style="white-space:pre">      </span>mv<span style="white-space:pre">   </span>a0,a0</div><div>  1a:<span style="white-space:pre">   </span>00000317          <span style="white-space:pre">      </span>auipc<span style="white-space:pre">        </span>t1,0x0</div><div>  1e:<span style="white-space:pre">  </span>000300e7          <span style="white-space:pre">      </span>jalr<span style="white-space:pre"> </span>t1</div><div><br></div><div>00000022 <.L2>:</div><div>  22:<span style="white-space:pre"> </span>40b2                <span style="white-space:pre"> </span>lw<span style="white-space:pre">   </span>ra,12(sp)</div><div>  24:<span style="white-space:pre">       </span>8522                <span style="white-space:pre"> </span>mv<span style="white-space:pre">   </span>a0,s0</div><div>  26:<span style="white-space:pre">   </span>4422                <span style="white-space:pre"> </span>lw<span style="white-space:pre">   </span>s0,8(sp)</div><div>  28:<span style="white-space:pre">        </span>0141                <span style="white-space:pre"> </span>addi<span style="white-space:pre"> </span>sp,sp,16</div><div>  2a:<span style="white-space:pre">        </span>8082                <span style="white-space:pre"> </span>ret</div></div><div><br></div><div>And after linking:</div><div><br></div><div><div>00010164 <foo>:</div><div>   10164:       1141                    addi    sp,sp,-16</div><div>   10166:       c422                    sw      s0,8(sp)</div><div>   10168:       c606                    sw      ra,12(sp)</div><div>   1016a:       06300793                li      a5,99</div><div>   1016e:       842a                    mv      s0,a0</div><div>   10170:       00a7c863                blt     a5,a0,10180 <foo+0x1c></div><div>   10174:       85aa                    mv      a1,a0</div><div>   10176:       0001a537                lui     a0,0x1a</div><div>   1017a:       6a050513                addi    a0,a0,1696 # 1a6a0 <__clz_tab+0x100></div><div>   1017e:       2a69                    jal     10318 <printf></div><div>   10180:       40b2                    lw      ra,12(sp)</div><div>   10182:       8522                    mv      a0,s0</div><div>   10184:       4422                    lw      s0,8(sp)</div><div>   10186:       0141                    addi    sp,sp,16</div><div>   10188:       8082                    ret</div></div><div><br></div><div>The linker has done quite a lot!</div><div><br></div><div>1) the format string address generation has had the LUI (Load Upper Immediate)<br></div><div>changed from 0x0 to 0x1a (the literal is in flash memory). If it had stayed at</div><div>0x0 it would have been removed by the linker. The mv a0,a0 (which is really</div><div>addi a0,a0,#0) has had the real immediate filled in.</div><div><br></div><div>2) the call of printf had the general call-anywhere-in-the-address-space auipc</div><div>(Add Upper Immediate to PC); jalr (Jump And Link to address in Register (plus</div><div>offset)) sequence replaced by a simple jal (Jump And Link, with PC +/- 1 MB range)</div><div><br></div><div>3) as the jal offset was in fact less than +/- 2 KB, the 32 bit jal was replaced by a</div><div>16 bit jal instruction.</div><div><br></div><div>4) the conditional branch has been shortened from 18 bytes to 12 bytes due to</div><div>the other changes.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jul 11, 2017 at 1:59 PM, Peter Smith via llvm-dev <span dir="ltr"><<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello,<br>
<br>
To the best of my knowledge I think the closest analogue is something<br>
like the Synthetic EHFrame and MergeInputSections, not strictly code<br>
relaxation, but these do involve changes in size of sections.<br>
<br>
Can I ask you a quick question?  In many architectures not all<br>
pc-relative offsets are exposed to the linker as relocations so it<br>
isn't safe to change the sizes of sections in arbitrary places [*];<br>
does the RiscV ABI have restrictions on code-generation to allow a<br>
linker to reduce the code-size of a code-sequence within a Section? If<br>
there are constraints on the relaxations it might help us make a<br>
suggestion.<br>
<br>
I'm assuming that if you are doing some kind of range based relaxation<br>
you'll need something like range extension thunks (I'm working on<br>
these right now) this means you'll probably have to do your<br>
calculations on what you can relax in finalizeSections() at a similar<br>
point to createThunks(), or perhaps the mechanisms would need to be<br>
merged as I think they'll need to converge on a point when no more<br>
relaxations are possible and no more thunks can be added.<br>
<br>
Writing out the relaxed sections will be interesting as you won't want<br>
all of the InputSectionContents. I suggest looking at EHFrame and<br>
MergeInputSections for ideas.<br>
<br>
Hope that is of some use<br>
<br>
Peter<br>
<br>
[*] For example in pseudo ARM<br>
<br>
    ldr r0, [pc, offset] ; where pc + offset == label<br>
    ...<br>
    relaxable sequence such as an indirect jump via a register<br>
    ...<br>
label: .word foo<br>
<br>
If the compiler/assembler has pre-computed the offset to label then<br>
changing the size of the relaxable sequence without also updating the<br>
offset will break the program.<br>
<div class="HOEnZb"><div class="h5"><br>
<br>
<br>
On 11 July 2017 at 11:09, PkmX via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>> wrote:<br>
> Hi,<br>
><br>
> Does lld support linker relaxation that may shrink code size? As far<br>
> as I see lld seems to assume that the content of input sections to be<br>
> fixed other than patching up relocations, but I believe some targets<br>
> may benefit the extra optimization opportunity with relaxation.<br>
> Specifically, I'm currently working on adding support for RISC-V in<br>
> lld, and RISC-V heavily relies on linker relaxation to remove<br>
> extraneous code and to handle alignment. Since linker relaxation may<br>
> be of interest to other targets as well, I'm wondering what would be a<br>
> good way to modify lld to support that. Thanks.<br>
><br>
> --<br>
> Chih-Mao Chen (PkmX)<br>
> Software R&D, Andes Technology<br>
> ______________________________<wbr>_________________<br>
> LLVM Developers mailing list<br>
> <a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-dev</a><br>
______________________________<wbr>_________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-dev</a><br>
</div></div></blockquote></div><br></div>