LLVM  6.0.0svn
Macros | Functions | Variables
X86FixupBWInsts.cpp File Reference

This file defines the pass that looks through the machine instructions late in the compilation, and finds byte or word instructions that can be profitably replaced with 32 bit instructions that give equivalent results for the bits of the results that are used. More...

#include "X86.h"
#include "X86InstrInfo.h"
#include "X86Subtarget.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/LivePhysRegs.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h"
Include dependency graph for X86FixupBWInsts.cpp:

Go to the source code of this file.

Macros

#define FIXUPBW_DESC   "X86 Byte/Word Instruction Fixup"
 
#define FIXUPBW_NAME   "x86-fixup-bw-insts"
 
#define DEBUG_TYPE   FIXUPBW_NAME
 

Functions

static bool isLive (const MachineInstr &MI, const LivePhysRegs &LiveRegs, const TargetRegisterInfo *TRI, unsigned Reg)
 Check if register Reg is live after the MI. More...
 

Variables

static cl::opt< boolFixupBWInsts ("fixup-byte-word-insts", cl::desc("Change byte and word instructions to larger sizes"), cl::init(true), cl::Hidden)
 

Detailed Description

This file defines the pass that looks through the machine instructions late in the compilation, and finds byte or word instructions that can be profitably replaced with 32 bit instructions that give equivalent results for the bits of the results that are used.

There are two possible reasons to do this.

One reason is to avoid false-dependences on the upper portions of the registers. Only instructions that have a destination register which is not in any of the source registers can be affected by this. Any instruction where one of the source registers is also the destination register is unaffected, because it has a true dependence on the source register already. So, this consideration primarily affects load instructions and register-to-register moves. It would seem like cmov(s) would also be affected, but because of the way cmov is really implemented by most machines as reading both the destination and and source registers, and then "merging" the two based on a condition, it really already should be considered as having a true dependence on the destination register as well.

The other reason to do this is for potential code size savings. Word operations need an extra override byte compared to their 32 bit versions. So this can convert many word operations to their larger size, saving a byte in encoding. This could introduce partial register dependences where none existed however. As an example take: orw ax, $0x1000 addw ax, $3 now if this were to get transformed into orw ax, $1000 addl eax, $3 because the addl encodes shorter than the addw, this would introduce a use of a register that was only partially written earlier. On older Intel processors this can be quite a performance penalty, so this should probably only be done when it can be proven that a new partial dependence wouldn't be created, or when your know a newer processor is being targeted, or when optimizing for minimum code size.

Definition in file X86FixupBWInsts.cpp.

Macro Definition Documentation

◆ DEBUG_TYPE

#define DEBUG_TYPE   FIXUPBW_NAME

Definition at line 66 of file X86FixupBWInsts.cpp.

◆ FIXUPBW_DESC

#define FIXUPBW_DESC   "X86 Byte/Word Instruction Fixup"

Definition at line 63 of file X86FixupBWInsts.cpp.

◆ FIXUPBW_NAME

#define FIXUPBW_NAME   "x86-fixup-bw-insts"

Definition at line 64 of file X86FixupBWInsts.cpp.

Function Documentation

◆ isLive()

static bool isLive ( const MachineInstr MI,
const LivePhysRegs LiveRegs,
const TargetRegisterInfo TRI,
unsigned  Reg 
)
static

Check if register Reg is live after the MI.

LiveRegs should be in a state describing liveness information in that exact place as this function tries to precise analysis made by LiveRegs by exploiting the information about particular instruction MI. MI is expected to be one of the MOVs handled by the x86FixupBWInsts pass. Note: similar to LivePhysRegs::contains this would state that super-register is not used if only some part of it is used.

X86 backend does not have subregister liveness tracking enabled, so liveness information might be overly conservative. However, for some specific instructions (this pass only cares about MOVs) we can produce more precise results by analysing that MOV's operands.

Indeed, if super-register is not live before the mov it means that it was originally <read-undef> and so we are free to modify these undef upper bits. That may happen in case where the use is in another MBB and the vreg/physreg corresponding to the move has higher width than necessary (e.g. due to register coalescing with a "truncate" copy). So, it handles pattern like this:

BB#2: derived from LLVM BB if.then Live Ins: RDI Predecessors according to CFG: BB#0 AX<def> = MOV16rm RDI<kill>, 1, noreg, 0, noreg, EAX<imp-def>; mem:LD2[p] No EAX<imp-use> Successors according to CFG: BB#3(?%)

BB#3: derived from LLVM BB if.end Live Ins: EAX Only AX is actually live Predecessors according to CFG: BB#2 BB#1 AX<def> = KILL AX, EAX<imp-use,kill> RET 0, AX

Definition at line 203 of file X86FixupBWInsts.cpp.

References llvm::MachineInstrBuilder::add(), llvm::MachineInstrBuilder::addReg(), assert(), llvm::SmallVectorTemplateCommon< T >::back(), llvm::BuildMI(), llvm::SmallVectorImpl< T >::clear(), llvm::LivePhysRegs::contains(), llvm::SmallVectorBase::empty(), llvm::MachineBasicBlock::erase(), llvm::MachineInstr::getDebugLoc(), llvm::MachineInstr::getNumExplicitOperands(), llvm::MachineInstr::getNumOperands(), llvm::MachineInstr::getOpcode(), llvm::MachineInstr::getOperand(), llvm::MachineOperand::getReg(), llvm::getX86SubSuperRegister(), I, llvm::RegState::Implicit, llvm::MachineInstr::implicit_operands(), llvm::MachineBasicBlock::insert(), llvm::MCRegisterInfo::DiffListIterator::isValid(), llvm::MachineInstr::memoperands_begin(), llvm::MachineInstr::memoperands_end(), MI, llvm::SmallVectorTemplateBase< T, isPodLike< T >::value >::pop_back(), llvm::SmallVectorTemplateBase< T, isPodLike< T >::value >::push_back(), llvm::MachineBasicBlock::rbegin(), llvm::MachineBasicBlock::rend(), llvm::MachineInstr::setMemRefs(), TII, and llvm::RegState::Undef.

Referenced by getFPReg(), llvm::GlobalValueSummary::GVFlags::GVFlags(), and isUnconditionalBranch().

Variable Documentation

◆ FixupBWInsts

cl::opt<bool> FixupBWInsts("fixup-byte-word-insts", cl::desc("Change byte and word instructions to larger sizes"), cl::init(true), cl::Hidden)
static