<div dir="ltr"><div>Hello, LLVM.</div><div><br></div><div>We'd like to start a discussion about what would be the best way of</div><div>supporting target-specific defaults for options in the LLVM tools.</div><div><br></div><div>Problem description</div><div>-------------------</div><div><br></div><div>LLVM strives to be a generic compiler and it has a lot of code generation</div><div>options which are (rightly) not linked to the target triple.</div><div>However, some target triples do impose hard requirements for such options. For</div><div>example, PS4 requires the relocation model to be PIC. Cross-compilers for</div><div>specific target systems are likely to have similar restrictions.</div><div><br></div><div>One very effective way to ensure that users of Clang/LLVM don't misuse the</div><div>tools by passing the wrong options is to set the default values for those</div><div>options in the cross-compiler once the target triple is known. This has the</div><div>following rationale:</div><div><br></div><div>- Correctness: the user must be able to generate correct code for the target</div><div>  in the default workflow (with or without optimizations).</div><div>- Performance: the user should be able to generate good code for the target</div><div>  in the default workflow with optimizations enabled.</div><div>- Usability: although the default workflow could potentially be defined as</div><div>  "sorry, but you must pass options X, Y and Z to the tools", obviously it would</div><div>  be easier if it did not require such esoteric options.</div><div><br></div><div>And of course, from a company's point of view:</div><div><br></div><div>- Commercial reasons: if a tool is released commercially, the user expects such</div><div>  commercial product to work "out of the box" for the target system.</div><div><br></div><div>This is very easy to do in Clang, as the driver does the job of "dispatching"</div><div>the correct command line options to subsequent invocations of tools. Because of</div><div>the driver being the "middle man", it can parse the options, understand what the</div><div>target triple is, and invoke other tools accordingly (i.e. actively adding an</div><div>option, or erroring out upon encountering an invalid set of options).</div><div><br></div><div>A vendor can set the default target triple for Clang even at build time, and</div><div>this approach seems to not cause any trouble in the Clang tests (which don't get</div><div>as far as checking the output assembly). So for Clang the problem is solved to a</div><div>certain degree.</div><div><br></div><div>However, issues start to pop up when we consider all the other tools (opt, llc,</div><div>and so on) and the complications of having for example a "cross-llc". Usage of</div><div>such tools is becoming increasingly likely thanks to the existence of other</div><div>tools and frontends which can generate LLVM IR. Some crazy people might even try</div><div>to write IR instead of C++! :-)</div><div><br></div><div>First of all, overriding the defaults based on the triple is harder in LLVM</div><div>tools, because of how the cl::opt options work. If you consider llc, it</div><div>determines the triple in this sequence:</div><div><br></div><div>- Parse the IR and extract the triple if present.</div><div>- If there's a triple on the command line, override the IR triple.</div><div>- If no triple was found by either method, use the default triple.</div><div><br></div><div>This process is performed in the compileModule() function, which happens way</div><div>after the cl::init initializers for the cl::opt option defaults, and shortly</div><div>after the cl::ParseCommandLineOptions() call. If the value of some option needs</div><div>to be changed _after_ the triple has been determined, additional work has to be</div><div>performed to tweak the cl::opt options on the fly, but only if they had not</div><div>already been set on the command line (which would mean the user explicitly</div><div>wanted a non-default value). It would be quite ugly, although doable.</div><div><br></div><div>The real problem, however, is that tools are used not only by the end user, but</div><div>also extensively by the LLVM tests that check the output assembly.</div><div>Currently, there is a non-trivial number of LLVM tests that do not set the full</div><div>triple, but only parts of it, and then rely on specific default code generation</div><div>options. In the past, some defaults have been locked down as opposed to being</div><div>auto-detected (for example, -mcpu=generic) specifically for the purpose of</div><div>making tests stable and correct for cross-compilers.</div><div><br></div><div>Changing the code to override the defaults for opt, llc, and so on based on the</div><div>target triple can make some tests fail, because it would reinstate the same</div><div>problems we had before locking down such defaults. Of course, such a change</div><div>could be kept private and out of the open-source tree, and the tests could be</div><div>modified accordingly. However, it is clear that it could become a large burden</div><div>to support these private changes when new tests are constantly added to the</div><div>codebase.</div><div><br></div><div>We would like to start a discussion with the community about how best to support</div><div>the use case of "target-specific defaults for LLVM tools", especially in the</div><div>case of cross-compiling tools. Maybe somebody else is running into our same</div><div>use-case.</div><div>And this could even prove to be tied to the cl::opt reworking that was going on</div><div>a while ago, so new requirements / limitations / ideas might emerge.</div><div><br></div><div>We have identified a few approaches that could serve as the starting point of a</div><div>discussion. I will briefly outline them below. We don't want to push for any of</div><div>them, we just want to discuss them. There could even be more effective ways of</div><div>solving the problem, which is why we are interested in having this discussion</div><div>here.</div><div><br></div><div><br></div><div>A - Fixed option defaults, irrelevant default triple logic</div><div>----------------------------------------------------------</div><div><br></div><div>I believe this is the current situation, possibly caused by how cl::opt works.</div><div>This alternative assumes that:</div><div><br></div><div>- There is no functionality in the open-source tree to change the defaults based</div><div>  on the target triple.</div><div>- Vendors may or may not change the default triple in their cross-compilers.</div><div><br></div><div>If a vendor wants to both change a tool to have a specific default triple, and</div><div>cause option defaults to depend on the triple, it is the vendor's responsibility</div><div>to adapt failing tests, and changes will have to be kept private. If a vendor</div><div>tried to push them onto the community ("yes, this -mcpu=generic in the test is</div><div>totally unnecessary, but can we have it in tree?"), such a change would never</div><div>pass a review.</div><div><br></div><div>If this approach is chosen, then vendors will have to maintain private changes,</div><div>but the state of the LLVM tests in the open-source tree will be consistent and</div><div>there will be no target-specific code to override option defaults.</div><div><br></div><div><br></div><div>B - Triple-based option defaults, variable default triple logic</div><div>---------------------------------------------------------------</div><div><br></div><div>This alternative is at the other end of the spectrum and it assumes that:</div><div><br></div><div>- There is some functionality (a new API in llvm::cl?) in the open-source tree</div><div>  to override the defaults based on the target triple.</div><div>- The default target triple can be freely changed in cross-compilers, with</div><div>  impunity.</div><div><br></div><div>As described above, this would cause problems to some existing tests. It could</div><div>be argued though that, if a test is unstable with respect to code generation</div><div>options, then it should specify all options that it actually requires in order</div><div>to run properly.</div><div>This would mean that tests must specify a target triple in the RUN lines or in</div><div>the IR, otherwise they cannot assume that the code will be generated as</div><div>expected.</div><div><br></div><div>This puts a burden on the test implementors, but could it be argued that this is</div><div>technically correct? Shouldn't tests be robust? On the other hand, if tests had</div><div>to specify a target triple, wouldn't this reduce coverage (as they'd be testing</div><div>a single target as opposed to many)?</div><div><br></div><div>If this approach was chosen, then a good number of LLVM tests in the open-source</div><div>tree would need to be adapted, but vendors could be free to implement their own</div><div>defaults and set the default triple without significant consequences.</div><div><br></div><div><br></div><div>C - Triple-based option defaults, fixed default triple logic</div><div>------------------------------------------------------------</div><div><br></div><div>This alternative assumes that:</div><div><br></div><div>- There is some functionality (a new API in llvm::cl?) in the open-source tree</div><div>  to override the defaults based on the target triple.</div><div>- Vendors are NOT free to change the logic determining the default triple.</div><div>- The default triple is inferred by some fixed logic, which is test-friendly.</div><div><br></div><div>There is code in the Clang driver that parses the program name to identify a</div><div>prefix that is used to determine the target triple. For example, I seem to</div><div>understand that "x86_64-scei-ps4-clang" would indicate a Clang which has a PS4</div><div>target triple by default.</div><div>Opt, llc, and similar tools do not support anything of the sort, so at the</div><div>moment the default target triple cannot be selected with the same approach.</div><div><br></div><div>Anyway, consider the case where option defaults are set based on the target</div><div>triple, but the default triple can be inferred from the name prefix, just as</div><div>Clang does; if no such prefix is found, the defaulting falls back to what we do</div><div>currently. This allows tests with RUN lines running "llc" to just use the triple</div><div>that we currently use, and therefore all existing open-source tests will</div><div>continue to work.</div><div><br></div><div>At the same time, a vendor could release a tool with a name prefix and reap the</div><div>benefits of having the desired defaults; and to make it convenient for the user,</div><div>a symlink (or something more complex on Windows) could easily be used.</div><div><br></div><div>If this approach was chosen, vendor-specific tests which expect the vendor</div><div>defaults would have to somehow rename the tool on the fly before running it; or</div><div>maybe they could change the build process to produce both an "llc" and a</div><div>"<triple>-llc" executables. Also vendors would need to release the renamed</div><div>tools, but this often happens anyway with cross-compilers. This pushes some</div><div>burden on the vendor, but it is much less than maintaining a lot of private</div><div>changes to the open-source code and tests.</div><div><br></div><div>What does the community think?</div><div>Discuss. :-)</div><div><br></div><div>Cheers,</div><div>    Dario Domizioli</div><div>    SN Systems - Sony Computer Entertainment Group</div><div><br></div><div><br></div></div>