This is an archive of the discontinued LLVM Phabricator instance.

[libunwind][ARM] Improve unwinder stack usage on baremetal targets - part 1
AbandonedPublic

Authored by rmaprath on May 4 2016, 7:32 AM.

Details

Reviewers
jroelofs
Summary

Currently, unw_context_t and unw_cursor_t are sized to allow the virtual register set of any target architecuture supported by libunwind. This does not work well for baremetal ARM targets (where memory is at a premium).

This patch makes unw_context_t and unw_cursor_t use just enough space to hold the ARM virtual register set on baremetal arm targets.

The various Registers_xxx definitions (and their dependencies) had to be conditionally compiled out in order to allow each of the targets to perform size checks independently.

This change saves about 1500 bytes of stack on ARM v7 (similar amount on AArch32).

Diff Detail

Event Timeline

rmaprath updated this revision to Diff 56146.May 4 2016, 7:32 AM
rmaprath retitled this revision from to [libunwind][ARM] Improve unwinder stack usage on baremetal targets - part 1.
rmaprath updated this object.
rmaprath added a reviewer: jroelofs.
rmaprath added a subscriber: cfe-commits.
rmaprath updated this object.May 4 2016, 7:44 AM

I think it would be better to use a generic method so the size is minimal everywhere rather than making ARM a special case. Possibly move the #define bits from libunwind.cpp to __libunwind_config.h and use REGISTER_KIND to declare unw_context_t?

src/CompactUnwinder.hpp
490

__aarch64__ is defined for iOS too, so no need for both.

jroelofs edited edge metadata.May 4 2016, 7:49 AM

Wouldn't this break cross unwinding?

I agree with Tim, I think this should be more generic.

I think it would be better to use a generic method so the size is minimal everywhere rather than making ARM a special case. Possibly move the #define bits from libunwind.cpp to __libunwind_config.h and use REGISTER_KIND to declare unw_context_t?

Wouldn't this make libunwind.h depend on Registers_xxx types? I thought the whole idea of statically allocated buffers was to keep these two separate. I may be wrong though, pretty new to unwinder.

Thanks.

/ Asiri

Wouldn't this break cross unwinding?

I wasn't aware of cross unwinding, I think you are referring to [1]. Thanks for the pointer.

Would it make sense to support a libunwind build that only supports native unwinding? For baremetal (embedded) applications, I don't think cross unwinding (if I understand it correctly) makes a lot of sense.

Thanks!

/ Asiri

[1] http://www.nongnu.org/libunwind/man/libunwind(3).html#section_4

Wouldn't this break cross unwinding?

I wasn't aware of cross unwinding, I think you are referring to [1]. Thanks for the pointer.

Would it make sense to support a libunwind build that only supports native unwinding? For baremetal (embedded) applications, I don't think cross unwinding (if I understand it correctly) makes a lot of sense.

Thanks!

/ Asiri

[1] http://www.nongnu.org/libunwind/man/libunwind(3).html#section_4

Yeah, that's what I'm referring to. I have no idea if it's currently working or not, but *adding* a build mode that only supports native unwinding sounds like a good idea.

Wouldn't this break cross unwinding?

I wasn't aware of cross unwinding, I think you are referring to [1]. Thanks for the pointer.

Would it make sense to support a libunwind build that only supports native unwinding? For baremetal (embedded) applications, I don't think cross unwinding (if I understand it correctly) makes a lot of sense.

Thanks!

/ Asiri

[1] http://www.nongnu.org/libunwind/man/libunwind(3).html#section_4

Yeah, that's what I'm referring to. I have no idea if it's currently working or not, but *adding* a build mode that only supports native unwinding sounds like a good idea.

Makes sense. I will update the patch to hide behind a build option.

@rengolin, @t.p.northover: From what I gathered so far, libunwind.h is supposed to be platform independent, so we cannot make the size computation generic as suggested (without tying up libunwind.h into library sources).

We could, on the other hand, do this tightening for all the supported architectures (for the new, native-only libunwind build suggested by @jroelofs) with appropriate asserts in place so that we maintain these tight bounds as we move forward. Not sure if that effort would be worth though, given that for most non-ARM targets, unwinder stack usage is not a huge concern.

Cheers,

/ Asiri

bcraig added a subscriber: bcraig.May 4 2016, 8:56 AM

We could, on the other hand, do this tightening for all the supported architectures (for the new, native-only libunwind build suggested by @jroelofs) with appropriate asserts in place so that we maintain these tight bounds as we move forward. Not sure if that effort would be worth though, given that for most non-ARM targets, unwinder stack usage is not a huge concern.

libunwind doesn't currently support Hexagon, but it has been investigated some there. Hexagon would care about stack usage as well. I wouldn't be surprised if some embedded MIPS and Power targets also cared. I don't think any of those targets come close to using 1K for their unwind context.

We could, on the other hand, do this tightening for all the supported architectures (for the new, native-only libunwind build suggested by @jroelofs) with appropriate asserts in place so that we maintain these tight bounds as we move forward. Not sure if that effort would be worth though, given that for most non-ARM targets, unwinder stack usage is not a huge concern.

libunwind doesn't currently support Hexagon, but it has been investigated some there. Hexagon would care about stack usage as well. I wouldn't be surprised if some embedded MIPS and Power targets also cared. I don't think any of those targets come close to using 1K for their unwind context.

Right, in that case, I will do the tightening for all the existing architectures. Will add a comment explaining the expected behaviour for future changes as well.

Thanks.

/ Asiri

rmaprath abandoned this revision.May 10 2016, 11:13 AM

Superseded by D20119.