X86FixupLEAs.cpp revision 7813a2fe9dff1d30efaaf84bec8eb02f8b78bd06
1d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd//===-- X86FixupLEAs.cpp - use or replace LEA instructions -----------===// 2d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd// 3d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd// The LLVM Compiler Infrastructure 4d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd// 5d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd// This file is distributed under the University of Illinois Open Source 6d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd// License. See LICENSE.TXT for details. 7d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd// 8d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd//===----------------------------------------------------------------------===// 9d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd// 10d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd// This file defines the pass which will find instructions which 11d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd// can be re-written as LEA instructions in order to reduce pipeline 12d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd// delays for some models of the Intel Atom family. 13d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd// 14d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd//===----------------------------------------------------------------------===// 15d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd 16d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd#define DEBUG_TYPE "x86-fixup-LEAs" 17d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd#include "X86.h" 18d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd#include "X86InstrInfo.h" 19d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd#include "X86Subtarget.h" 20d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd#include "llvm/ADT/Statistic.h" 21d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd#include "llvm/CodeGen/LiveVariables.h" 22d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd#include "llvm/CodeGen/MachineFunctionPass.h" 23d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd#include "llvm/CodeGen/MachineInstrBuilder.h" 24d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd#include "llvm/CodeGen/MachineRegisterInfo.h" 25d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd#include "llvm/CodeGen/Passes.h" 26d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd#include "llvm/Support/Debug.h" 27d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd#include "llvm/Support/raw_ostream.h" 28d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd#include "llvm/Target/TargetInstrInfo.h" 29d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurdusing namespace llvm; 30d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd 31d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston GurdSTATISTIC(NumLEAs, "Number of LEA instructions created"); 32d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd 33d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurdnamespace { 34d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd class FixupLEAPass : public MachineFunctionPass { 35d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd enum RegUsageState { RU_NotUsed, RU_Write, RU_Read }; 36d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd static char ID; 377f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd /// \brief Loop over all of the instructions in the basic block 387f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd /// replacing applicable instructions with LEA instructions, 397f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd /// where appropriate. 40d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd bool processBasicBlock(MachineFunction &MF, MachineFunction::iterator MFI); 41d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd 42d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd virtual const char *getPassName() const { return "X86 Atom LEA Fixup";} 437f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd 447f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd /// \brief Given a machine register, look for the instruction 457f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd /// which writes it in the current basic block. If found, 467f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd /// try to replace it with an equivalent LEA instruction. 477f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd /// If replacement succeeds, then also process the the newly created 487f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd /// instruction. 49d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd void seekLEAFixup(MachineOperand& p, MachineBasicBlock::iterator& I, 50d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd MachineFunction::iterator MFI); 517f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd 527f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd /// \brief Given a memory access or LEA instruction 537f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd /// whose address mode uses a base and/or index register, look for 547f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd /// an opportunity to replace the instruction which sets the base or index 557f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd /// register with an equivalent LEA instruction. 56d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd void processInstruction(MachineBasicBlock::iterator& I, 57d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd MachineFunction::iterator MFI); 587f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd 597f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd /// \brief Determine if an instruction references a machine register 607f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd /// and, if so, whether it reads or writes the register. 61d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd RegUsageState usesRegister(MachineOperand& p, 62d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd MachineBasicBlock::iterator I); 637f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd 647f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd /// \brief Step backwards through a basic block, looking 657f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd /// for an instruction which writes a register within 667f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd /// a maximum of INSTR_DISTANCE_THRESHOLD instruction latency cycles. 67d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd MachineBasicBlock::iterator searchBackwards(MachineOperand& p, 68d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd MachineBasicBlock::iterator& I, 69d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd MachineFunction::iterator MFI); 707f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd 717f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd /// \brief if an instruction can be converted to an 727f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd /// equivalent LEA, insert the new instruction into the basic block 737f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd /// and return a pointer to it. Otherwise, return zero. 74d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd MachineInstr* postRAConvertToLEA(MachineFunction::iterator &MFI, 757f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd MachineBasicBlock::iterator &MBBI) const; 76d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd 77d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd public: 78d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd FixupLEAPass() : MachineFunctionPass(ID) {} 79d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd 807f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd /// \brief Loop over all of the basic blocks, 817f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd /// replacing instructions by equivalent LEA instructions 827f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd /// if needed and when possible. 83d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd virtual bool runOnMachineFunction(MachineFunction &MF); 84d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd 85d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd private: 86d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd MachineFunction *MF; 87d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd const TargetMachine *TM; 88d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd const TargetInstrInfo *TII; // Machine instruction info. 89d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd 90d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd }; 91d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd char FixupLEAPass::ID = 0; 92d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd} 93d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd 94d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston GurdMachineInstr * 95d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston GurdFixupLEAPass::postRAConvertToLEA(MachineFunction::iterator &MFI, 967f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd MachineBasicBlock::iterator &MBBI) const { 97d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd MachineInstr* MI = MBBI; 98d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd MachineInstr* NewMI; 99d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd switch (MI->getOpcode()) { 100d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd case X86::MOV32rr: 101d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd case X86::MOV64rr: { 102d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd const MachineOperand& Src = MI->getOperand(1); 103d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd const MachineOperand& Dest = MI->getOperand(0); 104d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd NewMI = BuildMI(*MF, MI->getDebugLoc(), 105d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd TII->get( MI->getOpcode() == X86::MOV32rr ? X86::LEA32r : X86::LEA64r)) 106d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd .addOperand(Dest) 107d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd .addOperand(Src).addImm(1).addReg(0).addImm(0).addReg(0); 108d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd MFI->insert(MBBI, NewMI); // Insert the new inst 109d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd return NewMI; 110d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd } 111d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd case X86::ADD64ri32: 112d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd case X86::ADD64ri8: 113d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd case X86::ADD64ri32_DB: 114d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd case X86::ADD64ri8_DB: 115d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd case X86::ADD32ri: 116d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd case X86::ADD32ri8: 117d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd case X86::ADD32ri_DB: 118d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd case X86::ADD32ri8_DB: 119d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd case X86::ADD16ri: 120d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd case X86::ADD16ri8: 121d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd case X86::ADD16ri_DB: 122d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd case X86::ADD16ri8_DB: 123d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd if (!MI->getOperand(2).isImm()) { 124d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd // convertToThreeAddress will call getImm() 125d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd // which requires isImm() to be true 126d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd return 0; 127d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd } 1287813a2fe9dff1d30efaaf84bec8eb02f8b78bd06Preston Gurd break; 1292967a804126c6081a18d8b75adf2d9fd5a3c096ePreston Gurd case X86::ADD16rr: 1302967a804126c6081a18d8b75adf2d9fd5a3c096ePreston Gurd case X86::ADD16rr_DB: 1312967a804126c6081a18d8b75adf2d9fd5a3c096ePreston Gurd if (MI->getOperand(1).getReg() != MI->getOperand(2).getReg()) { 1322967a804126c6081a18d8b75adf2d9fd5a3c096ePreston Gurd // if src1 != src2, then convertToThreeAddress will 1332967a804126c6081a18d8b75adf2d9fd5a3c096ePreston Gurd // need to create a Virtual register, which we cannot do 1342967a804126c6081a18d8b75adf2d9fd5a3c096ePreston Gurd // after register allocation. 1352967a804126c6081a18d8b75adf2d9fd5a3c096ePreston Gurd return 0; 1362967a804126c6081a18d8b75adf2d9fd5a3c096ePreston Gurd } 137d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd } 1387f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd return TII->convertToThreeAddress(MFI, MBBI, 0); 139d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd} 140d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd 141d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston GurdFunctionPass *llvm::createX86FixupLEAs() { 142d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd return new FixupLEAPass(); 143d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd} 144d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd 145d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurdbool FixupLEAPass::runOnMachineFunction(MachineFunction &Func) { 146d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd MF = &Func; 147d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd TM = &MF->getTarget(); 148a5e5ba611f787f518fd3f7349343f8c4ae863fc2Bill Wendling TII = TM->getInstrInfo(); 149d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd 150d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd DEBUG(dbgs() << "Start X86FixupLEAs\n";); 151d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd // Process all basic blocks. 152d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd for (MachineFunction::iterator I = Func.begin(), E = Func.end(); I != E; ++I) 153d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd processBasicBlock(Func, I); 154d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd DEBUG(dbgs() << "End X86FixupLEAs\n";); 155d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd 156d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd return true; 157d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd} 158d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd 159d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston GurdFixupLEAPass::RegUsageState FixupLEAPass::usesRegister(MachineOperand& p, 160d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd MachineBasicBlock::iterator I) { 161d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd RegUsageState RegUsage = RU_NotUsed; 162d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd MachineInstr* MI = I; 163d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd 164d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd for (unsigned int i = 0; i < MI->getNumOperands(); ++i) { 165d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd MachineOperand& opnd = MI->getOperand(i); 166d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd if (opnd.isReg() && opnd.getReg() == p.getReg()){ 167d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd if (opnd.isDef()) 168d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd return RU_Write; 169d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd RegUsage = RU_Read; 170d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd } 171d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd } 172d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd return RegUsage; 173d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd} 174d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd 175d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd/// getPreviousInstr - Given a reference to an instruction in a basic 176d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd/// block, return a reference to the previous instruction in the block, 177d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd/// wrapping around to the last instruction of the block if the block 178d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd/// branches to itself. 179d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurdstatic inline bool getPreviousInstr(MachineBasicBlock::iterator& I, 180d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd MachineFunction::iterator MFI) { 181d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd if (I == MFI->begin()) { 182d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd if (MFI->isPredecessor(MFI)) { 183d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd I = --MFI->end(); 184d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd return true; 185d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd } 186d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd else 187d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd return false; 188d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd } 189d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd --I; 190d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd return true; 191d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd} 192d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd 193d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston GurdMachineBasicBlock::iterator FixupLEAPass::searchBackwards(MachineOperand& p, 194d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd MachineBasicBlock::iterator& I, 195d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd MachineFunction::iterator MFI) { 196d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd int InstrDistance = 1; 197d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd MachineBasicBlock::iterator CurInst; 198d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd static const int INSTR_DISTANCE_THRESHOLD = 5; 199d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd 200d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd CurInst = I; 201d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd bool Found; 202d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd Found = getPreviousInstr(CurInst, MFI); 203d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd while( Found && I != CurInst) { 204d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd if (CurInst->isCall() || CurInst->isInlineAsm()) 205d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd break; 206d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd if (InstrDistance > INSTR_DISTANCE_THRESHOLD) 207d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd break; // too far back to make a difference 208d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd if (usesRegister(p, CurInst) == RU_Write){ 209d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd return CurInst; 210d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd } 211d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd InstrDistance += TII->getInstrLatency(TM->getInstrItineraryData(), CurInst); 212d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd Found = getPreviousInstr(CurInst, MFI); 213d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd } 214d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd return 0; 215d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd} 216d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd 217d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurdvoid FixupLEAPass::processInstruction(MachineBasicBlock::iterator& I, 218d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd MachineFunction::iterator MFI) { 219d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd // Process a load, store, or LEA instruction. 220d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd MachineInstr *MI = I; 221d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd int opcode = MI->getOpcode(); 222d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd const MCInstrDesc& Desc = MI->getDesc(); 223d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd int AddrOffset = X86II::getMemoryOperandNo(Desc.TSFlags, opcode); 224d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd if (AddrOffset >= 0) { 225d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd AddrOffset += X86II::getOperandBias(Desc); 226d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd MachineOperand& p = MI->getOperand(AddrOffset + X86::AddrBaseReg); 227d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd if (p.isReg() && p.getReg() != X86::ESP) { 228d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd seekLEAFixup(p, I, MFI); 229d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd } 230d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd MachineOperand& q = MI->getOperand(AddrOffset + X86::AddrIndexReg); 231d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd if (q.isReg() && q.getReg() != X86::ESP) { 232d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd seekLEAFixup(q, I, MFI); 233d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd } 234d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd } 235d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd} 236d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd 237d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurdvoid FixupLEAPass::seekLEAFixup(MachineOperand& p, 238d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd MachineBasicBlock::iterator& I, 239d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd MachineFunction::iterator MFI) { 240d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd MachineBasicBlock::iterator MBI = searchBackwards(p, I, MFI); 241d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd if (MBI) { 2427f8300b8f3f35167ce78628bc14d50beec203b8fPreston Gurd MachineInstr* NewMI = postRAConvertToLEA(MFI, MBI); 243d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd if (NewMI) { 244d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd ++NumLEAs; 245d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd DEBUG(dbgs() << "Candidate to replace:"; MBI->dump();); 246d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd // now to replace with an equivalent LEA... 247d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd DEBUG(dbgs() << "Replaced by: "; NewMI->dump();); 248d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd MFI->erase(MBI); 249d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd MachineBasicBlock::iterator J = 250d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd static_cast<MachineBasicBlock::iterator> (NewMI); 251d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd processInstruction(J, MFI); 252d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd } 253d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd } 254d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd} 255d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd 256d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurdbool FixupLEAPass::processBasicBlock(MachineFunction &MF, 257d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd MachineFunction::iterator MFI) { 258d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd 259d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd for (MachineBasicBlock::iterator I = MFI->begin(); I != MFI->end(); ++I) 260d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd processInstruction(I, MFI); 261d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd return false; 262d6ac8e9a03d8fa7115079d86192bc4529e8281aaPreston Gurd} 263