Use a tri-state enum to represent shouldUseFramePointer() and
shouldUseLeafFramePointer().
This simplifies the logic and fixes PR9825:
-fno-omit-frame-pointer doesn't imply -mno-omit-leaf-frame-pointer.
and PR24003:
/Oy- /O2 should not omit leaf frame pointer: this matches MSVC x86-32. (/Oy- is a no-op on MSVC x86-64.)
and:
when CC1 option -mdisable-fp-elim if absent, -momit-leaf-frame-pointer can also be omitted.
The new behavior matches GCC:
-fomit-frame-pointer wins over -mno-omit-leaf-frame-pointer -fno-omit-frame-pointer loses out to -momit-leaf-frame-pointer
The behavior makes lots of sense. We have 4 states:
- 00) leaf retained, non-leaf retained
- 01) leaf retained, non-leaf omitted (this is invalid)
- 10) leaf omitted, non-leaf retained (what -momit-leaf-frame-pointer was designed for)
- 11) leaf omitted, non-leaf omitted
"omit" options taking precedence over "no-omit" options is the only way
to make 3 valid states representable with -f(no-)?omit-frame-pointer and
-m(no-)?omit-leaf-pointer.
It looks better if frame_pointer is represented using tri-state. Something like this?
It would be great to have comments for conditions that are not obvious such as the overriding rules.