| 
|   | STATISTIC (NumDevirtTargets, "Number of whole program devirtualization targets") | 
|   | STATISTIC (NumSingleImpl, "Number of single implementation devirtualizations") | 
|   | STATISTIC (NumBranchFunnel, "Number of branch funnels") | 
|   | STATISTIC (NumUniformRetVal, "Number of uniform return value optimizations") | 
|   | STATISTIC (NumUniqueRetVal, "Number of unique return value optimizations") | 
|   | STATISTIC (NumVirtConstProp1Bit, "Number of 1 bit virtual constant propagations") | 
|   | STATISTIC (NumVirtConstProp, "Number of virtual constant propagations") | 
| static bool  | mustBeUnreachableFunction (ValueInfo TheFnVI) | 
| static bool  | typeIDVisibleToRegularObj (StringRef TypeID, function_ref< bool(StringRef)> IsVisibleToRegularObj) | 
| static bool  | skipUpdateDueToValidation (GlobalVariable &GV, function_ref< bool(StringRef)> IsVisibleToRegularObj) | 
| static Error  | checkCombinedSummaryForTesting (ModuleSummaryIndex *Summary) | 
| static bool  | addCalls (VTableSlotInfo &SlotInfo, const ValueInfo &Callee) | 
 | 
| static cl::opt< PassSummaryAction >  | llvm::ClSummaryAction ("wholeprogramdevirt-summary-action", cl::desc("What to do with the summary when running this pass"), cl::values(clEnumValN(PassSummaryAction::None, "none", "Do nothing"), clEnumValN(PassSummaryAction::Import, "import", "Import typeid resolutions from summary and globals"), clEnumValN(PassSummaryAction::Export, "export", "Export typeid resolutions to summary and globals")), cl::Hidden) | 
| static cl::opt< std::string >  | llvm::ClReadSummary ("wholeprogramdevirt-read-summary", cl::desc("Read summary from given bitcode or YAML file before running pass"), cl::Hidden) | 
| static cl::opt< std::string >  | llvm::ClWriteSummary ("wholeprogramdevirt-write-summary", cl::desc("Write summary to given bitcode or YAML file after running pass. " "Output file format is deduced from extension: *.bc means writing " "bitcode, otherwise YAML"), cl::Hidden) | 
| static cl::opt< bool >  | llvm::ClDevirtualizeSpeculatively ("devirtualize-speculatively", cl::desc("Enable speculative devirtualization optimization"), cl::init(false)) | 
| static cl::opt< unsigned >  | llvm::ClThreshold ("wholeprogramdevirt-branch-funnel-threshold", cl::Hidden, cl::init(10), cl::desc("Maximum number of call targets per " "call site to enable branch funnels")) | 
| static cl::opt< bool >  | llvm::PrintSummaryDevirt ("wholeprogramdevirt-print-index-based", cl::Hidden, cl::desc("Print index-based devirtualization messages")) | 
| static cl::opt< bool >  | llvm::WholeProgramVisibility ("whole-program-visibility", cl::Hidden, cl::desc("Enable whole program visibility")) | 
|   | Provide a way to force enable whole program visibility in tests.  
  | 
| static cl::opt< bool >  | llvm::DisableWholeProgramVisibility ("disable-whole-program-visibility", cl::Hidden, cl::desc("Disable whole program visibility (overrides enabling options)")) | 
|   | Provide a way to force disable whole program for debugging or workarounds, when enabled via the linker.  
  | 
| static cl::list< std::string >  | llvm::SkipFunctionNames ("wholeprogramdevirt-skip", cl::desc("Prevent function(s) from being devirtualized"), cl::Hidden, cl::CommaSeparated) | 
|   | Provide way to prevent certain function from being devirtualized.  
  | 
| static cl::opt< bool >  | WholeProgramDevirtKeepUnreachableFunction ("wholeprogramdevirt-keep-unreachable-function", cl::desc("Regard unreachable functions as possible devirtualize targets."), cl::Hidden, cl::init(true)) | 
|   | With Clang, a pure virtual class's deleting destructor is emitted as a llvm.trap intrinsic followed by an unreachable IR instruction.  
  | 
| static cl::opt< unsigned >  | WholeProgramDevirtCutoff ("wholeprogramdevirt-cutoff", cl::desc("Max number of devirtualizations for devirt module pass"), cl::init(0)) | 
|   | If explicitly specified, the devirt module pass will stop transformation once the total number of devirtualizations reach the cutoff value.  
  | 
| static cl::opt< WPDCheckMode >  | DevirtCheckMode ("wholeprogramdevirt-check", cl::Hidden, cl::desc("Type of checking for incorrect devirtualizations"), cl::values(clEnumValN(WPDCheckMode::None, "none", "No checking"), clEnumValN(WPDCheckMode::Trap, "trap", "Trap when incorrect"), clEnumValN(WPDCheckMode::Fallback, "fallback", "Fallback to indirect when incorrect"))) | 
  
  
      
        
          | cl::opt< bool > WholeProgramDevirtKeepUnreachableFunction("wholeprogramdevirt-keep-unreachable-function", cl::desc("Regard unreachable functions as possible devirtualize targets."), cl::Hidden, cl::init(true))  | 
          ( | 
          "wholeprogramdevirt-keep-unreachable-function" |           ,  | 
         
        
           | 
           | 
          cl::desc("Regard unreachable functions as possible devirtualize targets.") |           ,  | 
         
        
           | 
           | 
          cl::Hidden |           ,  | 
         
        
           | 
           | 
          cl::init(true) |            ) | 
         
       
   | 
  
static   | 
  
 
With Clang, a pure virtual class's deleting destructor is emitted as a llvm.trap intrinsic followed by an unreachable IR instruction. 
In the context of whole program devirtualization, the deleting destructor of a pure virtual class won't be invoked by the source code so safe to skip as a devirtualize target.
However, not all unreachable functions are safe to skip. In some cases, the program intends to run such functions and terminate, for instance, a unit test may run a death test. A non-test program might (or allowed to) invoke such functions to report failures (whether/when it's a good practice or not is a different topic).
This option is enabled to keep an unreachable function as a possible devirtualize target to conservatively keep the program behavior.
TODO: Make a pure virtual class's deleting destructor precisely identifiable in Clang's codegen for more devirtualization in LLVM. 
Referenced by mustBeUnreachableFunction().