<div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Dec 13, 2019 at 7:27 AM Robinson, Paul via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">> I am looking at obtaining smaller code sizes for ARM cores. So far, I am<br>
> trying a  genetic algorithm to find the best option for the opt passes  and<br>
> clang/ llc flags.<br>
<br>
Nice.<br>
<br>
> I am looking at what flags and passes -Oz and the other optimization levels<br>
> enable and use. Having done something similar for gcc, I was looking for a<br>
> similar approach.<br>
> However, I was not able to find many optimization flags for clang or llc,<br>
> which made me think that in clang/llvm the optimization changes are done<br>
> mostly by selecting/removing the opt passes(flags).<br></blockquote><div><br></div><div>Most passes exposes some flags affecting their cost modeling and other heuristics. These are not intended to be exposed to clang users but you can play with them in `opt`, and a genetic algorithm would likely try to select these as well. For example here is one such option: <a href="https://github.com/llvm/llvm-project/blob/master/llvm/lib/Transforms/Scalar/LoopRotation.cpp#L32">https://github.com/llvm/llvm-project/blob/master/llvm/lib/Transforms/Scalar/LoopRotation.cpp#L32</a></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<br>
I'm unfamiliar with how gcc is structured; clang does not actually<br>
run `opt` or `llc`.  These three tools are all independent clients<br>
of the optimization and code-generation libraries.  Clang builds <br>
its pipelines with comparatively little control from the command <br>
line; opt and llc, which are intended to be testing tools for LLVM <br>
developers, provide more control.<br>
<br>
As a rule of thumb, `opt` runs IR optimization passes (aka the <br>
"middle end"), while `llc` primarily runs lower-level "machine" <br>
oriented passes (aka the "back end").  Both opt and llc will run <br>
both target-independent and target-specific passes, so the set of <br>
passes you will be looking at will be at least somewhat influenced <br>
by which target you select.<br>
<br>
> In order to run what opt passes I select, I split the compilation process<br>
> in:<br>
><br>
> clang  CLANG_FLAGS -emit-llvm  mysource1.c  -c -o mysource1.bc<br>
> opt  OPT_FLAGS  mysource1.bc -o mysource1.ll<br>
> llc LLC_FLAGS mysource1.ll -filetype=obj -o mysource1.o<br>
<br>
That looks quite reasonable.  In order to have Clang produce IR <br>
that is optimizable, without running any optimizations itself, you<br>
would want CLANG_FLAGS to include the following:<br>
    -Xclang -disable-llvm-passes -Xclang -disable-O0-optnone<br>
and then opt and llc can operate on the IR files as you would like.<br></blockquote><div><br></div><div>Actually I would likely replace `-Xclang -disable-O0-optnone` with `-Oz`: clang will insert an attribute on functions that will impact some pass heuristics to optimize for size.</div><div>(it is possible that -Oz for invoking `llc` will also change some heuristics in the backend)</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<br>
> I have also seen that for -Oz for example, the Pass Arguments appears<br>
> multiple time, does this mean that opt is run multiple times with different<br>
> passes options?<br>
<br>
I'm not clear what you are asking about here.  Note that clang does<br>
not run opt, are you getting some kind of dump output from clang?</blockquote><div><br></div><div>It may refer to the fact that there are two pass pipelines created by the PassManagerBuilder in Clang, so the debug output prints two invocations.</div><div>And `opt` does the same when used with the -Ox levels: <a href="https://github.com/llvm/llvm-project/blob/master/llvm/tools/opt/opt.cpp#L437-L438" style="font-family:-webkit-standard">https://github.com/llvm/llvm-project/blob/master/llvm/tools/opt/opt.cpp#L437-L438</a></div><div><br></div><div>-- </div><div>Mehdi</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<br>
> Now, my general direction questions are:<br>
><br>
> Am I on the right track with this?<br>
> Do you have any pointers or advice on this?<br>
<br>
Well, what you're doing (with the tweaks mentioned above) is<br>
probably how I would go about doing the same thing.  Once you<br>
have determined what a good -Oz pipeline looks like for your<br>
examples and target, you could bring that back to the list as a<br>
proposal for how Clang should build its -Oz pipeline.  I'm sure<br>
you will get plenty of feedback on the exact set of passes!<br>
<br>
--paulr<br>
<br>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</blockquote></div></div></div></div></div>