|
| 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 > | 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 > | ClReadSummary ("wholeprogramdevirt-read-summary", cl::desc("Read summary from given bitcode or YAML file before running pass"), cl::Hidden) |
|
static cl::opt< std::string > | 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< unsigned > | 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 > | PrintSummaryDevirt ("wholeprogramdevirt-print-index-based", cl::Hidden, cl::desc("Print index-based devirtualization messages")) |
|
static cl::opt< bool > | 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 > | 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 > | 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().