@@ -167,6 +167,18 @@ static cl::list<std::string>
167167 cl::desc (" Prevent function(s) from being devirtualized" ),
168168 cl::Hidden, cl::CommaSeparated);
169169
170+ // / A function is unreachable if its entry block ends with 'unreachable' IR
171+ // / instruction. In some cases, the program intends to run such functions and
172+ // / terminate, for instance, a unit test may run a death test. A non-test
173+ // / program might (or allowed to) invoke such functions to report failures
174+ // / (whether/when it's a good practice or not is a different topic). Regard
175+ // / unreachable function as possible devirtualize targets to keep the program
176+ // / behavior.
177+ static cl::opt<bool > WholeProgramDevirtKeepUnreachableFunction (
178+ " wholeprogramdevirt-keep-unreachable-function" ,
179+ cl::desc (" Regard unreachable functions as possible devirtualize targets." ),
180+ cl::Hidden, cl::init(true ));
181+
170182// / If explicitly specified, the devirt module pass will stop transformation
171183// / once the total number of devirtualizations reach the cutoff value. Setting
172184// / this option to 0 explicitly will do 0 devirtualization.
@@ -386,6 +398,9 @@ template <> struct DenseMapInfo<VTableSlotSummary> {
386398// 2) All function summaries indicate it's unreachable
387399// 3) There is no non-function with the same GUID (which is rare)
388400static bool mustBeUnreachableFunction (ValueInfo TheFnVI) {
401+ if (WholeProgramDevirtKeepUnreachableFunction)
402+ return false ;
403+
389404 if ((!TheFnVI) || TheFnVI.getSummaryList ().empty ()) {
390405 // Returns false if ValueInfo is absent, or the summary list is empty
391406 // (e.g., function declarations).
@@ -2241,6 +2256,8 @@ DevirtModule::lookUpFunctionValueInfo(Function *TheFn,
22412256
22422257bool DevirtModule::mustBeUnreachableFunction (
22432258 Function *const F, ModuleSummaryIndex *ExportSummary) {
2259+ if (WholeProgramDevirtKeepUnreachableFunction)
2260+ return false ;
22442261 // First, learn unreachability by analyzing function IR.
22452262 if (!F->isDeclaration ()) {
22462263 // A function must be unreachable if its entry block ends with an
0 commit comments