30 #define DEBUG_TYPE "x86-fixup-LEAs"
32 STATISTIC(NumLEAs,
"Number of LEA instructions created");
36 enum RegUsageState { RU_NotUsed, RU_Write, RU_Read };
43 StringRef getPassName()
const override {
return "X86 LEA Fixup"; }
129 MFI->insert(MBBI, NewMI);
134 case X86::ADD64ri32_DB:
135 case X86::ADD64ri8_DB:
138 case X86::ADD32ri_DB:
139 case X86::ADD32ri8_DB:
142 case X86::ADD16ri_DB:
143 case X86::ADD16ri8_DB:
151 case X86::ADD16rr_DB:
159 return TII->convertToThreeAddress(MFI, MI,
nullptr);
173 if (!OptLEA && !OptIncDec)
178 DEBUG(
dbgs() <<
"Start X86FixupLEAs\n";);
181 processBasicBlock(Func,
I);
187 FixupLEAPass::RegUsageState
189 RegUsageState
RegUsage = RU_NotUsed;
209 if (I == MFI->begin()) {
210 if (MFI->isPredecessor(&*MFI)) {
223 int InstrDistance = 1;
225 static const int INSTR_DISTANCE_THRESHOLD = 5;
230 while (Found && I != CurInst) {
231 if (CurInst->isCall() || CurInst->isInlineAsm())
233 if (InstrDistance > INSTR_DISTANCE_THRESHOLD)
235 if (usesRegister(p, CurInst) == RU_Write) {
239 MF->getSubtarget().getInstrItineraryData(), *CurInst);
245 static inline bool isLEA(
const int opcode) {
246 return opcode == X86::LEA16r || opcode == X86::LEA32r ||
247 opcode == X86::LEA64r || opcode == X86::LEA64_32r;
257 return SrcReg == DstReg &&
277 NewOpcode = isINC ? X86::INC16r : X86::DEC16r;
281 NewOpcode = isINC ? X86::INC32r : X86::DEC32r;
284 NewOpcode = isINC ? X86::INC64r : X86::DEC64r;
305 if (AddrOffset >= 0) {
309 seekLEAFixup(p, I, MFI);
313 seekLEAFixup(q, I, MFI);
326 DEBUG(
dbgs() <<
"FixLEA: Candidate to replace:"; MBI->dump(););
332 processInstruction(J, MFI);
344 !
TII->isSafeToClobberEFLAGS(*MFI, I))
349 if ((SrcR1 == 0 || SrcR1 != DstR) && (SrcR2 == 0 || SrcR2 != DstR))
353 int addrr_opcode, addri_opcode;
358 addrr_opcode = X86::ADD16rr;
359 addri_opcode = X86::ADD16ri;
362 addrr_opcode = X86::ADD32rr;
363 addri_opcode = X86::ADD32ri;
367 addrr_opcode = X86::ADD64rr;
368 addri_opcode = X86::ADD64ri32;
371 DEBUG(
dbgs() <<
"FixLEA: Candidate to replace:"; I->dump(););
372 DEBUG(
dbgs() <<
"FixLEA: Replaced by: ";);
376 if (SrcR1 != 0 && SrcR2 != 0) {
383 MFI->insert(I, NewMI);
384 DEBUG(NewMI->dump(););
393 MFI->insert(I, NewMI);
394 DEBUG(NewMI->dump(););
407 if (fixupIncDec(I, MFI))
412 processInstructionForSLM(I, MFI);
414 processInstruction(I, MFI);
STATISTIC(NumFunctions,"Total number of functions")
static bool isLEASimpleIncOrDec(MachineInstr &LEA)
isLEASimpleIncOrDec - Does this LEA have one these forms: lea reg, 1(reg) lea reg, -1(reg)
const X86InstrInfo * getInstrInfo() const override
Describe properties that are true of each instruction in the target description file.
MachineInstrBuilder MachineInstrBuilder &DefMI const MCInstrDesc & Desc
static bool getPreviousInstr(MachineBasicBlock::iterator &I, MachineFunction::iterator MFI)
getPreviousInstr - Given a reference to an instruction in a basic block, return a reference to the pr...
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
MachineInstrBundleIterator< MachineInstr > iterator
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
bool optForMinSize() const
Optimize this function for minimum size (-Oz).
AddrSegmentReg - The operand # of the segment in the memory operand.
static MCDisassembler::DecodeStatus addOperand(MCInst &Inst, const MCOperand &Opnd)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
unsigned getNumOperands() const
Access to explicit operands of the instruction.
FunctionPass * createX86FixupLEAs()
Return a pass that selectively replaces certain instructions (like add, sub, inc, dec...
static bool isLEA(const int opcode)
unsigned getInstrLatency(const InstrItineraryData *ItinData, const MachineInstr &MI, unsigned *PredCost=nullptr) const override
Compute the instruction latency of a given instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
const MachineOperand & getOperand(unsigned i) const
FunctionPass class - This class is used to implement most global optimizations.
unsigned getOperandBias(const MCInstrDesc &Desc)
getOperandBias - compute any additional adjustment needed to the offset to the start of the memory op...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Iterator for intrusive lists based on ilist_node.
MachineOperand class - Representation of each machine instruction operand.
void dump(const TargetInstrInfo *TII=nullptr) const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
MachineFunctionProperties & set(Property P)
Representation of each machine instruction.
unsigned getReg() const
getReg - Returns the register number.
const MachineInstrBuilder & addOperand(const MachineOperand &MO) const
StringRef - Represent a constant reference to a string, i.e.
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Properties which a MachineFunction may have at a given point in time.
int getMemoryOperandNo(uint64_t TSFlags)
getMemoryOperandNo - The function returns the MCInst operand # for the first field of the memory oper...