https://reviews.llvm.org/D115492 skips unreachable functions and potentially allows more static de-virtualizations. The motivation is to ignore virtual deleting destructor of abstract class (e.g., `Base::~Base()` in https://gcc.godbolt.org/z/dWMsdT9Kz). * Note WPD already handles most pure virtual functions (like `Base::x()` in the godbolt example above), which becomes a `__cxa_pure_virtual` in the vtable slot. This PR proposes to undo the change, because it turns out there are other unreachable functions that a general program wants to run and fail intentionally, with `LOG(FATAL)` or `CHECK` [1] for example. While many real-world applications are encouraged to check-fail sparingly, they are allowed to do so on critical errors (e.g., misconfiguration or bug is detected during server startup). * Implementation-wise, this PR keeps the one-bit 'unreachable' state in bitcode and updates WPD analysis. https://gcc.godbolt.org/z/T1aMhczYr is a minimum reproducible example extracted from unit test. `Base::func` is a one-liner of `LOG(FATAL) << "message"`, and lowered to one basic block ending with `unreachable`. A real-world program is _allowed_ to invoke Base::func to terminate the program as a way to report errors (in server initialization stage for example), even if errors on the serving path should be handled more gracefully. [1] https://abseil.io/docs/cpp/guides/logging#CHECK and https://abseil.io/docs/cpp/guides/logging#configuration-and-flags
101 KiB
101 KiB