LTO API: lto_codegen_optimize and lto_codegen_compile_optimized
Nick Kledzik
kledzik at apple.com
Fri Jan 30 13:26:45 PST 2015
On Jan 30, 2015, at 12:58 PM, Duncan P. N. Exon Smith <dexonsmith at apple.com> wrote:
>
>
>> On Jan 30, 2015, at 12:01 PM, Manman Ren <mren at apple.com> wrote:
>>
>> We currently have lto_codegen_compile that runs IR passes and codegen passes. If we dump the bitcode file after lto_codegen_compile, codegen passes can modify IR (one example is StackProtector pass).
>> If we run “llc lto.opt.bc”, we will get assertion failure because llc runs StackProtector pass again.
>>
>> To enable dumping bitcode file right before running the codegen passes, this patch splits lto_codegen_compile in 2
>> lto_codegen_optimize
>> lto_codegen_compile_optimize
>>
>> Linker can choose to dump the bitcode file before calling lto_codegen_compile_optimize and we can debug the codegen passes from the dumped bitcode file.
>>
>> I initially had a different proposal, thanks to Rafael for suggesting this solution!
>>
>> Cheers,
>> Manman
>>
>> <lto.patch>
>
> +kledzik (see discussion about lto_codegen_optimize() below).
See if I understand this. Instead of calling lto_codegen_compile() the linker would call lto_codegen_optimize() then lto_codegen_compile_optimized(). But the linker only needs to use the two new calls if it plans to write out the bitcode (-r or -save-temps) via lto_codegen_write_merged_modules().
If that is the only usage, why not combine the three into one function:
extern const void*
lto_codegen_compile_and_write_bitcode(lto_code_gen_t cg, const char *path, size_t* length);
>
>>
>> +/**
>> + * Runs optimization for the merged module. Returns true on error.
>> + *
>> + * \since LTO_API_VERSION=12
>> + */
>> +extern lto_bool_t
>> +lto_codegen_optimize(lto_code_gen_t cg);
>
> It's not clear to me how the linker can determine at runtime whether
> this function is available in the `dlopen()`'ed libLTO.dylib.
>
> IIRC, the ld64 checks for runtime-availability of the new API by calling
> the function, and assuming it doesn't exist if the function returns NULL
> (the return value of functions that don't exist at runtime). Usually
> the flow is something like:
>
> Result = nullptr;
> #ifdef LTO_API_VERSION >= XYZ
> Result = lto_new_api(...);
> if (!Result)
> #else
> Result = lto_old_api(...)
> #endif
> // deal with Result
>
> That scheme doesn't work for functions that can return 0 as a valid
> result.
>
> Simply switching the error condition (0 on failure) won't work either,
> since then on error with the new API, you'd run the old API.
>
> I can see two possibilities:
>
> 1. Change `lto_codegen_optimize()` to return `1` on success and `2` on
> failure. Then `0` will mark that the API isn't available.
>
> 2. Add an `lto_api_version()` function that returns the runtime API
> version.
>
> The latter option seems cleaner to me.
>
> @Nick: any thoughts on this?
>
> Then the linker code would look something like this:
>
> Result = nullptr;
> #ifdef LTO_API_VERSION >= XYZ
> if (lto_api_version() >= XYZ)
> Result = lto_new_api(...);
> else
> #else
> Result = lto_old_api(...)
> #endif
> // deal with Result
If we needed to support functions that return 0 as a valid result, then yes, we’d need something like this.
-Nick
More information about the llvm-commits
mailing list