ilinpv added inline comments.

================
Comment at: compiler-rt/lib/builtins/cpu_model.c:1382
+    return;
+#if defined(__ANDROID__)
+  // ifunc resolvers don't have hwcaps in arguments on Android API lower
----------------
enh wrote:
> rprichard wrote:
> > enh wrote:
> > > srhines wrote:
> > > > MaskRay wrote:
> > > > > enh wrote:
> > > > > > ilinpv wrote:
> > > > > > > MaskRay wrote:
> > > > > > > > I am unfamiliar with how Android ndk builds compiler-rt.
> > > > > > > > 
> > > > > > > > If `__ANDROID_API__ >= 30`, shall we use the regular Linux code 
> > > > > > > > path?
> > > > > > > I think that leads to shipping different compile-rt libraries 
> > > > > > > depend on ANDROID_API. If this is an option to consider than 
> > > > > > > runtime check android_get_device_api_level() < 30 can be replaced 
> > > > > > > by `__ANDROID_API__ < 30`
> > > > > > depends what you mean... in 10 years or so, yes, no-one is likely 
> > > > > > to still care about the older API levels and we can just delete 
> > > > > > this. but until then, no, there's _one_ copy of compiler-rt that 
> > > > > > everyone uses, and although _OS developers_ don't need to support 
> > > > > > anything more than a couple of years old, most app developers are 
> > > > > > targeting far lower API levels than that (to maximize the number of 
> > > > > > possible customers).
> > > > > > 
> > > > > > TL;DR: "you could add that condition to the `#if`, but no-one would 
> > > > > > use it for a decade". (and i think the comment and `if` below 
> > > > > > should make it clear enough to future archeologists when this code 
> > > > > > block can be removed :-) )
> > > > > My thought was that people build Android with a specific 
> > > > > `__ANDROID_API__`, and only systems >= this level are supported.
> > > > > ```
> > > > > #If __ANDROID_API__ < 30
> > > > > ...
> > > > > #endif
> > > > > ```
> > > > > 
> > > > > This code has a greater chance to be removed when it becomes 
> > > > > obsoleted. The argument is similar to how we find obsoleted GCC 
> > > > > workarounds.
> > > > Yes, the NDK currently just ships the oldest supported target API level 
> > > > for compiler-rt, while the Android platform build does have access to 
> > > > both the oldest supported target API level + the most recent target API 
> > > > level, so that we can make better use of features there.
> > > > 
> > > > Maybe I'm missing something, but it's feeling like the NDK users won't 
> > > > be able to make great use of FMV without us either bumping the minimum 
> > > > level or shipping multiple runtimes (and then using the #ifdefs 
> > > > properly here).
> > > > Maybe I'm missing something, but it's feeling like the NDK users won't 
> > > > be able to make great use of FMV without us either bumping the minimum 
> > > > level or shipping multiple runtimes (and then using the #ifdefs 
> > > > properly here).
> > > 
> > > yeah, that's the point of this code --- it's a runtime check so the NDK 
> > > "just works".
> > > 
> > > but if people want the `__ANDROID_API__` `#if` too, that's fine. (and, 
> > > like you say, the platform's two variants mean that we'll be testing both 
> > > code paths, so i'm not worried about "one of these is the only one that 
> > > anyone's actually building" problem.)
> > > 
> > > i have no opinion on whether anyone llvm is more/less likely to 
> > > understand if/when `if (android_get_device_api_level() < 30)` versus `#if 
> > > __ANDROID_API__ < 30` can be deleted.
> > > 
> > > i think the best argument for leaving this change as-is would be "anyone 
> > > building their own is less likely to screw up" (since developers struggle 
> > > all the time with the difference between "target" and "min" api, because 
> > > the ndk terminology is different to the AndroidManifest.xml stuff that 
> > > developers are more familiar with, which causes confusion). so if this 
> > > was in libc++ (where i know people do build their own), i'd argue for the 
> > > code as-is. but since it's compiler-rt (and i'm not aware that anyone's 
> > > building that themselves) i don't think it matters either way?
> > > 
> > > to be clear, i'm imagining:
> > > ```
> > > #if __ANDROID_API__ < 30
> > >   if (android_get_device_api_level() < 30) {
> > >     setCPUFeature(FEAT_MAX);
> > >     return;
> > >   }
> > > #endif
> > > ```
> > > (which brings us back to the "this is confusing" --- _just_ having the 
> > > `#if` would be subtly different, which is why if i'd written this, i'd 
> > > have written it as-is too!)
> > Unless I'm missing something, calling android_get_device_api_level doesn't 
> > work, because (a) the loader hasn't performed the necessary relocations and 
> > (b) that API reads system properties, which haven't been initialized yet.
> > 
> > Maybe the device API could/should be exported to a /dev file, which is how 
> > we exported the CPU variant to ifunc resolvers.
> > 
> > We could redesign Bionic so that an ifunc resolver can call 
> > android_get_device_api_level: e.g:
> >  - Relocate objects in bottom-up order.
> >  - Collect ifunc relocations and defer them until after non-ifunc 
> > relocations.
> >  - Have android_get_device_api_level in libc.so call into the loader, which 
> > has already initialized its copy of the system properties code.
> > 
> > However, with that approach, we can't call android_get_device_api_level 
> > unless `__ANDROID_API__` is new enough to have the loader enhancements, in 
> > which case, we can just use `__ANDROID_API__`.
> > 
> > Using the macro isn't great for the NDK because the NDK only distributes 
> > the builtins built for the oldest supported API level. I suspect most apps 
> > are the same way. Even the platform builtins are built for the oldest API. 
> > toolchain/llvm_android/builders.py:
> > ```
> > class BuiltinsBuilder(base_builders.LLVMRuntimeBuilder):
> >     ...
> >     # Only target the NDK, not the platform. The NDK copy is sufficient for 
> > the
> >     # platform builders, and both NDK+platform builders use the same 
> > toolchain,
> >     # which can only have a single copy installed into its resource 
> > directory.
> > ```
> > 
> > If we really want to make this info available to NDK apps, there's probably 
> > some way to detect a new-enough version of libc.so -- e.g. I think a weak 
> > symbol reference could detect V and later.
> > 
> > Unless I'm missing something, calling android_get_device_api_level doesn't 
> > work, because (a) the loader hasn't performed the necessary relocations and 
> > (b) that API reads system properties, which haven't been initialized yet.
> 
> i don't think (b) is a problem because this is for apps, so you're being 
> loaded into a zygote clone anyway. but, yes, (a) is the fundamental problem 
> here.
> 
> > We could redesign Bionic so that an ifunc resolver...
> 
> that doesn't solve the problem here, which is backwards compatibility. we can 
> already only target api >= 30 and use what the ifunc resolver passes us. the 
> question is how to fix this for apis 21-29.
> 
> > If we really want to make this info available to NDK apps, there's probably 
> > some way to detect a new-enough version of libc.so -- e.g. I think a weak 
> > symbol reference could detect V and later.
> 
> well, it's 30 rather than 35, but, yeah --- we have a bunch of stuff that was 
> new in 30 that we could look for:
> ```
> LIBC_R { # introduced=R
>   global:
>     __mempcpy_chk;
>     __tls_get_addr; # arm64
>     call_once;
>     cnd_broadcast;
>     cnd_destroy;
>     cnd_init;
>     cnd_signal;
>     cnd_timedwait;
>     cnd_wait;
>     memfd_create;
>     mlock2;
>     mtx_destroy;
>     mtx_init;
>     mtx_lock;
>     mtx_timedlock;
>     mtx_trylock;
>     mtx_unlock;
>     pthread_cond_clockwait;
>     pthread_mutex_clocklock;
>     pthread_rwlock_clockrdlock;
>     pthread_rwlock_clockwrlock;
>     renameat2;
>     sem_clockwait;
>     statx;
>     thrd_create;
>     thrd_current;
>     thrd_detach;
>     thrd_equal;
>     thrd_exit;
>     thrd_join;
>     thrd_sleep;
>     thrd_yield;
>     tss_create;
>     tss_delete;
>     tss_get;
>     tss_set;
> ```
Thanks for the idea! We'll test that and update the patch.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D158641/new/

https://reviews.llvm.org/D158641

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to