LLVM: lib/Target/X86/X86CmovConversion.cpp File Reference (original) (raw)

This file implements a pass that converts X86 cmov instructions into branches when profitable. More...

Go to the source code of this file.

Macros
#define DEBUG_TYPE "x86-cmov-conversion"
Functions
STATISTIC (NumOfSkippedCmovGroups, "Number of unsupported CMOV-groups")
STATISTIC (NumOfCmovGroupCandidate, "Number of CMOV-group candidates")
STATISTIC (NumOfLoopCandidate, "Number of CMOV-conversion profitable loops")
STATISTIC (NumOfOptimizedCmovGroups, "Number of optimized CMOV-groups")
static unsigned getDepthOfOptCmov (unsigned TrueOpDepth, unsigned FalseOpDepth)
static bool checkEFLAGSLive (MachineInstr *MI)
static void packCmovGroup (MachineInstr *First, MachineInstr *Last)
Given /p First CMOV instruction and /p Last CMOV instruction representing a group of CMOV instructions, which may contain debug instructions in between, move all debug instructions to after the last CMOV instruction, making the CMOV group consecutive.
INITIALIZE_PASS_BEGIN (X86CmovConverterPass, DEBUG_TYPE, "X86 cmov Conversion", false, false) INITIALIZE_PASS_END(X86CmovConverterPass
Variables
static cl::opt< bool > EnableCmovConverter ("x86-cmov-converter", cl::desc("Enable the X86 cmov-to-branch optimization."), cl::init(true), cl::Hidden)
static cl::opt< unsigned > GainCycleThreshold ("x86-cmov-converter-threshold", cl::desc("Minimum gain per loop (in cycles) threshold."), cl::init(4), cl::Hidden)
static cl::opt< bool > ForceMemOperand ("x86-cmov-converter-force-mem-operand", cl::desc("Convert cmovs to branches whenever they have memory operands."), cl::init(true), cl::Hidden)
static cl::opt< bool > ForceAll ("x86-cmov-converter-force-all", cl::desc("Convert all cmovs to branches."), cl::init(false), cl::Hidden)
DEBUG_TYPE
X86 cmov Conversion
X86 cmov false

This file implements a pass that converts X86 cmov instructions into branches when profitable.

This pass is conservative. It transforms if and only if it can guarantee a gain with high confidence.

Thus, the optimization applies under the following conditions:

  1. Consider as candidates only CMOVs in innermost loops (assume that most hotspots are represented by these loops).
  2. Given a group of CMOV instructions that are using the same EFLAGS def instruction: a. Consider them as candidates only if all have the same code condition or the opposite one to prevent generating more than one conditional jump per EFLAGS def instruction. b. Consider them as candidates only if all are profitable to be converted (assume that one bad conversion may cause a degradation).
  3. Apply conversion only for loops that are found profitable and only for CMOV candidates that were found profitable. a. A loop is considered profitable only if conversion will reduce its depth cost by some threshold. b. CMOV is considered profitable if the cost of its condition is higher than the average cost of its true-value and false-value by 25% of branch-misprediction-penalty. This assures no degradation even with 25% branch misprediction.

Note: This pass is assumed to run on SSA machine code.

Definition in file X86CmovConversion.cpp.

DEBUG_TYPE

#define DEBUG_TYPE "x86-cmov-conversion"

checkEFLAGSLive()

getDepthOfOptCmov()

Returns

Depth of CMOV instruction as if it was converted into branch.

Parameters

TrueOpDepth depth cost of CMOV true value operand.
FalseOpDepth depth cost of CMOV false value operand.

Definition at line 382 of file X86CmovConversion.cpp.

References llvm::divideCeil().

INITIALIZE_PASS_BEGIN()

INITIALIZE_PASS_BEGIN ( X86CmovConverterPass ,
DEBUG_TYPE ,
"X86 cmov Conversion" ,
false ,
false )

packCmovGroup()

Given /p First CMOV instruction and /p Last CMOV instruction representing a group of CMOV instructions, which may contain debug instructions in between, move all debug instructions to after the last CMOV instruction, making the CMOV group consecutive.

Definition at line 610 of file X86CmovConversion.cpp.

References assert(), llvm::X86::COND_INVALID, E(), llvm::First, llvm::X86::getCondFromCMov(), I, llvm::Last, MBB, MI, and llvm::SmallVectorTemplateBase< T, bool >::push_back().

STATISTIC() [1/4]

STATISTIC ( NumOfCmovGroupCandidate ,
"Number of CMOV-group candidates" )

STATISTIC() [2/4]

STATISTIC ( NumOfLoopCandidate ,
"Number of CMOV-conversion profitable loops" )

STATISTIC() [3/4]

STATISTIC ( NumOfOptimizedCmovGroups ,
"Number of optimized CMOV-groups" )

STATISTIC() [4/4]

STATISTIC ( NumOfSkippedCmovGroups ,
"Number of unsupported CMOV-groups" )

Conversion

DEBUG_TYPE

EnableCmovConverter

cl::opt< bool > EnableCmovConverter("x86-cmov-converter", cl::desc("Enable the X86 cmov-to-branch optimization."), cl::init(true), cl::Hidden) ( "x86-cmov-converter" , cl::desc("Enable the X86 cmov-to-branch optimization.") , cl::init(true) , cl::Hidden ) static

false

ForceAll

cl::opt< bool > ForceAll("x86-cmov-converter-force-all", cl::desc("Convert all cmovs to branches."), cl::init(false), cl::Hidden) ( "x86-cmov-converter-force-all" , cl::desc("Convert all cmovs to branches.") , cl::init(false) , cl::Hidden ) static

ForceMemOperand

cl::opt< bool > ForceMemOperand("x86-cmov-converter-force-mem-operand", cl::desc("Convert cmovs to branches whenever they have memory operands."), cl::init(true), cl::Hidden) ( "x86-cmov-converter-force-mem-operand" , cl::desc("Convert cmovs to branches whenever they have memory operands.") , cl::init(true) , cl::Hidden ) static

GainCycleThreshold

cl::opt< unsigned > GainCycleThreshold("x86-cmov-converter-threshold", cl::desc("Minimum gain per loop (in cycles) threshold."), cl::init(4), cl::Hidden) ( "x86-cmov-converter-threshold" , cl::desc("Minimum gain per loop (in cycles) threshold.") , cl::init(4) , cl::Hidden ) static