Mechanism to add runtime checking of devirtualization decisions, optionally trapping or falling back to indirect call on any that are not correct. More...
Functions
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")
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)
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)
ClThreshold ("wholeprogramdevirt-branch-funnel-threshold", cl::Hidden, cl::init(10), cl::desc("Maximum number of call targets per " "call site to enable branch funnels"))
Mechanism to add runtime checking of devirtualization decisions, optionally trapping or falling back to indirect call on any that are not correct.
Trapping mode is useful for debugging undefined behavior leading to failures with WPD. Fallback mode is useful for ensuring safety when whole program visibility may be compromised.
cl::opt< std::string > ClReadSummary("wholeprogramdevirt-read-summary", cl::desc( "Read summary from given bitcode or YAML file before running pass"), cl::Hidden) ( "wholeprogramdevirt-read-summary" , cl::desc( "Read summary from given bitcode or YAML file before running pass") , cl::Hidden )
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) ( "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 )
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")) ( "wholeprogramdevirt-branch-funnel-threshold" , cl::Hidden , cl::init(10) , cl::desc("Maximum number of call targets per " "call site to enable branch funnels") )
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) ( "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 )
cl::opt< unsigned > WholeProgramDevirtCutoff("wholeprogramdevirt-cutoff", cl::desc("Max number of devirtualizations for devirt module pass"), cl::init(0)) ( "wholeprogramdevirt-cutoff" , cl::desc("Max number of devirtualizations for devirt module pass") , cl::init(0) )
static
If explicitly specified, the devirt module pass will stop transformation once the total number of devirtualizations reach the cutoff value.
Setting this option to 0 explicitly will do 0 devirtualization.
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.
cl::opt< bool > WholeProgramVisibility("whole-program-visibility", cl::Hidden, cl::desc("Enable whole program visibility")) ( "whole-program-visibility" , cl::Hidden , cl::desc("Enable whole program visibility") )
static
Provide a way to force enable whole program visibility in tests.
This is needed to support legacy tests that don't contain !vcall_visibility metadata (the mere presense of type tests previously implied hidden visibility).