diff options
Diffstat (limited to 'lib')
37 files changed, 2017 insertions, 12093 deletions
diff --git a/lib/CodeGen/DFAPacketizer.cpp b/lib/CodeGen/DFAPacketizer.cpp index bfbe779099..5ff641c7c8 100644 --- a/lib/CodeGen/DFAPacketizer.cpp +++ b/lib/CodeGen/DFAPacketizer.cpp @@ -23,10 +23,10 @@ // //===----------------------------------------------------------------------===// -#include "llvm/CodeGen/ScheduleDAGInstrs.h" #include "llvm/CodeGen/DFAPacketizer.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBundle.h" +#include "llvm/CodeGen/ScheduleDAGInstrs.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/MC/MCInstrItineraries.h" using namespace llvm; @@ -100,17 +100,17 @@ void DFAPacketizer::reserveResources(llvm::MachineInstr *MI) { reserveResources(&MID); } -namespace llvm { +namespace { // DefaultVLIWScheduler - This class extends ScheduleDAGInstrs and overrides // Schedule method to build the dependence graph. class DefaultVLIWScheduler : public ScheduleDAGInstrs { public: DefaultVLIWScheduler(MachineFunction &MF, MachineLoopInfo &MLI, - MachineDominatorTree &MDT, bool IsPostRA); + MachineDominatorTree &MDT, bool IsPostRA); // Schedule - Actual scheduling work. void schedule(); }; -} +} // end anonymous namespace DefaultVLIWScheduler::DefaultVLIWScheduler( MachineFunction &MF, MachineLoopInfo &MLI, MachineDominatorTree &MDT, @@ -129,25 +129,49 @@ VLIWPacketizerList::VLIWPacketizerList( bool IsPostRA) : TM(MF.getTarget()), MF(MF) { TII = TM.getInstrInfo(); ResourceTracker = TII->CreateTargetScheduleState(&TM, 0); - VLIWScheduler = new DefaultVLIWScheduler(MF, MLI, MDT, IsPostRA); + SchedulerImpl = new DefaultVLIWScheduler(MF, MLI, MDT, IsPostRA); } // VLIWPacketizerList Dtor VLIWPacketizerList::~VLIWPacketizerList() { - if (VLIWScheduler) - delete VLIWScheduler; + delete SchedulerImpl; + delete ResourceTracker; +} + +// ignorePseudoInstruction - ignore pseudo instructions. +bool VLIWPacketizerList::ignorePseudoInstruction(MachineInstr *MI, + MachineBasicBlock *MBB) { + if (MI->isDebugValue()) + return true; + + if (TII->isSchedulingBoundary(MI, MBB, MF)) + return true; + + return false; +} + +// isSoloInstruction - return true if instruction I must end previous +// packet. +bool VLIWPacketizerList::isSoloInstruction(MachineInstr *I) { + if (I->isInlineAsm()) + return true; + + return false; +} - if (ResourceTracker) - delete ResourceTracker; +// addToPacket - Add I to the current packet and reserve resource. +void VLIWPacketizerList::addToPacket(MachineInstr *MI) { + CurrentPacketMIs.push_back(MI); + ResourceTracker->reserveResources(MI); } // endPacket - End the current packet, bundle packet instructions and reset // DFA state. void VLIWPacketizerList::endPacket(MachineBasicBlock *MBB, - MachineInstr *MI) { + MachineInstr *I) { if (CurrentPacketMIs.size() > 1) { MachineInstr *MIFirst = CurrentPacketMIs.front(); - finalizeBundle(*MBB, MIFirst, MI); + finalizeBundle(*MBB, MIFirst, I); } CurrentPacketMIs.clear(); ResourceTracker->clearResources(); @@ -157,36 +181,31 @@ void VLIWPacketizerList::endPacket(MachineBasicBlock *MBB, void VLIWPacketizerList::PacketizeMIs(MachineBasicBlock *MBB, MachineBasicBlock::iterator BeginItr, MachineBasicBlock::iterator EndItr) { - assert(VLIWScheduler && "VLIW Scheduler is not initialized!"); - VLIWScheduler->enterRegion(MBB, BeginItr, EndItr, MBB->size()); - VLIWScheduler->schedule(); - VLIWScheduler->exitRegion(); - - // Generate MI -> SU map. - //std::map <MachineInstr*, SUnit*> MIToSUnit; - MIToSUnit.clear(); - for (unsigned i = 0, e = VLIWScheduler->SUnits.size(); i != e; ++i) { - SUnit *SU = &VLIWScheduler->SUnits[i]; - MIToSUnit[SU->getInstr()] = SU; - } + assert(MBB->end() == EndItr && "Bad EndIndex"); + + SchedulerImpl->enterRegion(MBB, BeginItr, EndItr, MBB->size()); + + // Build the DAG without reordering instructions. + SchedulerImpl->schedule(); + + // Remember scheduling units. + SUnits = SchedulerImpl->SUnits; // The main packetizer loop. for (; BeginItr != EndItr; ++BeginItr) { MachineInstr *MI = BeginItr; - this->initPacketizerState(); + // Ignore pseudo instructions. + if (ignorePseudoInstruction(MI, MBB)) + continue; // End the current packet if needed. - if (this->isSoloInstruction(MI)) { + if (isSoloInstruction(MI)) { endPacket(MBB, MI); continue; } - // Ignore pseudo instructions. - if (this->ignorePseudoInstruction(MI, MBB)) - continue; - - SUnit *SUI = MIToSUnit[MI]; + SUnit *SUI = SchedulerImpl->getSUnit(MI); assert(SUI && "Missing SUnit Info!"); // Ask DFA if machine resource is available for MI. @@ -196,13 +215,13 @@ void VLIWPacketizerList::PacketizeMIs(MachineBasicBlock *MBB, for (std::vector<MachineInstr*>::iterator VI = CurrentPacketMIs.begin(), VE = CurrentPacketMIs.end(); VI != VE; ++VI) { MachineInstr *MJ = *VI; - SUnit *SUJ = MIToSUnit[MJ]; + SUnit *SUJ = SchedulerImpl->getSUnit(MJ); assert(SUJ && "Missing SUnit Info!"); // Is it legal to packetize SUI and SUJ together. - if (!this->isLegalToPacketizeTogether(SUI, SUJ)) { + if (!isLegalToPacketizeTogether(SUI, SUJ)) { // Allow packetization if dependency can be pruned. - if (!this->isLegalToPruneDependencies(SUI, SUJ)) { + if (!isLegalToPruneDependencies(SUI, SUJ)) { // End the packet if dependency cannot be pruned. endPacket(MBB, MI); break; @@ -215,9 +234,11 @@ void VLIWPacketizerList::PacketizeMIs(MachineBasicBlock *MBB, } // Add MI to the current packet. - BeginItr = this->addToPacket(MI); + addToPacket(MI); } // For all instructions in BB. // End any packet left behind. endPacket(MBB, EndItr); + + SchedulerImpl->exitRegion(); } diff --git a/lib/Target/Hexagon/CMakeLists.txt b/lib/Target/Hexagon/CMakeLists.txt index 7f4192c0dd..af9e8136bf 100644 --- a/lib/Target/Hexagon/CMakeLists.txt +++ b/lib/Target/Hexagon/CMakeLists.txt @@ -11,15 +11,15 @@ add_public_tablegen_target(HexagonCommonTableGen) add_llvm_target(HexagonCodeGen HexagonAsmPrinter.cpp - HexagonCFGOptimizer.cpp HexagonCallingConvLower.cpp + HexagonCFGOptimizer.cpp HexagonExpandPredSpillCode.cpp HexagonFrameLowering.cpp HexagonHardwareLoops.cpp + HexagonMCInstLower.cpp + HexagonInstrInfo.cpp HexagonISelDAGToDAG.cpp HexagonISelLowering.cpp - HexagonInstrInfo.cpp - HexagonMCInstLower.cpp HexagonPeephole.cpp HexagonRegisterInfo.cpp HexagonRemoveSZExtArgs.cpp @@ -28,9 +28,6 @@ add_llvm_target(HexagonCodeGen HexagonSubtarget.cpp HexagonTargetMachine.cpp HexagonTargetObjectFile.cpp - HexagonVLIWPacketizer.cpp - HexagonNewValueJump.cpp - HexagonCopyToCombine.cpp ) add_subdirectory(TargetInfo) diff --git a/lib/Target/Hexagon/Hexagon.h b/lib/Target/Hexagon/Hexagon.h index 2738df3717..0808323336 100644 --- a/lib/Target/Hexagon/Hexagon.h +++ b/lib/Target/Hexagon/Hexagon.h @@ -40,9 +40,6 @@ namespace llvm { FunctionPass *createHexagonHardwareLoops(); FunctionPass *createHexagonPeephole(); FunctionPass *createHexagonFixupHwLoops(); - FunctionPass *createHexagonNewValueJump(); - FunctionPass *createHexagonCopyToCombine(); - FunctionPass *createHexagonPacketizer(); /* TODO: object output. MCCodeEmitter *createHexagonMCCodeEmitter(const Target &, diff --git a/lib/Target/Hexagon/HexagonAsmPrinter.cpp b/lib/Target/Hexagon/HexagonAsmPrinter.cpp index 2cc8b814a0..39bf45d2d7 100644 --- a/lib/Target/Hexagon/HexagonAsmPrinter.cpp +++ b/lib/Target/Hexagon/HexagonAsmPrinter.cpp @@ -13,11 +13,11 @@ // //===----------------------------------------------------------------------===// + #define DEBUG_TYPE "asm-printer" #include "Hexagon.h" #include "HexagonAsmPrinter.h" #include "HexagonMachineFunctionInfo.h" -#include "HexagonMCInst.h" #include "HexagonTargetMachine.h" #include "HexagonSubtarget.h" #include "InstPrinter/HexagonInstPrinter.h" @@ -54,7 +54,6 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" -#include <map> using namespace llvm; @@ -78,7 +77,8 @@ void HexagonAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, const MachineOperand &MO = MI->getOperand(OpNo); switch (MO.getType()) { - default: llvm_unreachable("<unknown operand type>"); + default: + assert(0 && "<unknown operand type>"); case MachineOperand::MO_Register: O << HexagonInstPrinter::getRegisterName(MO.getReg()); return; @@ -196,45 +196,10 @@ void HexagonAsmPrinter::printPredicateOperand(const MachineInstr *MI, /// the current output stream. /// void HexagonAsmPrinter::EmitInstruction(const MachineInstr *MI) { - if (MI->isBundle()) { - std::vector<const MachineInstr*> BundleMIs; - - const MachineBasicBlock *MBB = MI->getParent(); - MachineBasicBlock::const_instr_iterator MII = MI; - ++MII; - unsigned int IgnoreCount = 0; - while (MII != MBB->end() && MII->isInsideBundle()) { - const MachineInstr *MInst = MII; - if (MInst->getOpcode() == TargetOpcode::DBG_VALUE || - MInst->getOpcode() == TargetOpcode::IMPLICIT_DEF) { - IgnoreCount++; - ++MII; - continue; - } - //BundleMIs.push_back(&*MII); - BundleMIs.push_back(MInst); - ++MII; - } - unsigned Size = BundleMIs.size(); - assert((Size+IgnoreCount) == MI->getBundleSize() && "Corrupt Bundle!"); - for (unsigned Index = 0; Index < Size; Index++) { - HexagonMCInst MCI; - MCI.setStartPacket(Index == 0); - MCI.setEndPacket(Index == (Size-1)); - - HexagonLowerToMC(BundleMIs[Index], MCI, *this); - OutStreamer.EmitInstruction(MCI); - } - } - else { - HexagonMCInst MCI; - if (MI->getOpcode() == Hexagon::ENDLOOP0) { - MCI.setStartPacket(true); - MCI.setEndPacket(true); - } - HexagonLowerToMC(MI, MCI, *this); - OutStreamer.EmitInstruction(MCI); - } + MCInst MCI; + + HexagonLowerToMC(MI, MCI, *this); + OutStreamer.EmitInstruction(MCI); return; } @@ -277,17 +242,17 @@ void HexagonAsmPrinter::printJumpTable(const MachineInstr *MI, int OpNo, raw_ostream &O) { const MachineOperand &MO = MI->getOperand(OpNo); assert( (MO.getType() == MachineOperand::MO_JumpTableIndex) && - "Expecting jump table index"); + "Expecting jump table index"); // Hexagon_TODO: Do we need name mangling? O << *GetJTISymbol(MO.getIndex()); } void HexagonAsmPrinter::printConstantPool(const MachineInstr *MI, int OpNo, - raw_ostream &O) { + raw_ostream &O) { const MachineOperand &MO = MI->getOperand(OpNo); assert( (MO.getType() == MachineOperand::MO_ConstantPoolIndex) && - "Expecting constant pool index"); + "Expecting constant pool index"); // Hexagon_TODO: Do we need name mangling? O << *GetCPISymbol(MO.getIndex()); diff --git a/lib/Target/Hexagon/HexagonCallingConv.td b/lib/Target/Hexagon/HexagonCallingConv.td index e61b2a7a58..bd9608bdb0 100644 --- a/lib/Target/Hexagon/HexagonCallingConv.td +++ b/lib/Target/Hexagon/HexagonCallingConv.td @@ -17,8 +17,8 @@ // Hexagon 32-bit C return-value convention. def RetCC_Hexagon32 : CallingConv<[ - CCIfType<[i32, f32], CCAssignToReg<[R0, R1, R2, R3, R4, R5]>>, - CCIfType<[i64, f64], CCAssignToReg<[D0, D1, D2]>>, + CCIfType<[i32], CCAssignToReg<[R0, R1, R2, R3, R4, R5]>>, + CCIfType<[i64], CCAssignToReg<[D0, D1, D2]>>, // Alternatively, they are assigned to the stack in 4-byte aligned units. CCAssignToStack<4, 4> @@ -27,8 +27,8 @@ def RetCC_Hexagon32 : CallingConv<[ // Hexagon 32-bit C Calling convention. def CC_Hexagon32 : CallingConv<[ // All arguments get passed in integer registers if there is space. - CCIfType<[f32, i32, i16, i8], CCAssignToReg<[R0, R1, R2, R3, R4, R5]>>, - CCIfType<[f64, i64], CCAssignToReg<[D0, D1, D2]>>, + CCIfType<[i32, i16, i8], CCAssignToReg<[R0, R1, R2, R3, R4, R5]>>, + CCIfType<[i64], CCAssignToReg<[D0, D1, D2]>>, // Alternatively, they are assigned to the stack in 4-byte aligned units. CCAssignToStack<4, 4> diff --git a/lib/Target/Hexagon/HexagonCopyToCombine.cpp b/lib/Target/Hexagon/HexagonCopyToCombine.cpp deleted file mode 100644 index e93d278c82..0000000000 --- a/lib/Target/Hexagon/HexagonCopyToCombine.cpp +++ /dev/null @@ -1,475 +0,0 @@ -//===------- HexagonCopyToCombine.cpp - Hexagon Copy-To-Combine Pass ------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// This pass replaces transfer instructions by combine instructions. -// We walk along a basic block and look for two combinable instructions and try -// to move them together. If we can move them next to each other we do so and -// replace them with a combine instruction. -//===----------------------------------------------------------------------===// -#define DEBUG_TYPE "hexagon-copy-combine" - -#include "llvm/PassSupport.h" -#include "llvm/CodeGen/Passes.h" -#include "llvm/CodeGen/MachineBasicBlock.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineInstr.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/raw_ostream.h" - -#include "Hexagon.h" -#include "HexagonInstrInfo.h" -#include "HexagonRegisterInfo.h" -#include "HexagonSubtarget.h" -#include "HexagonTargetMachine.h" -#include "HexagonMachineFunctionInfo.h" - -using namespace llvm; - -static -cl::opt<bool> IsCombinesDisabled("disable-merge-into-combines", - cl::Hidden, cl::ZeroOrMore, - cl::init(false), - cl::desc("Disable merging into combines")); - -namespace { - -class HexagonCopyToCombine : public MachineFunctionPass { - const HexagonInstrInfo *TII; - const TargetRegisterInfo *TRI; -public: - static char ID; - - HexagonCopyToCombine() : MachineFunctionPass(ID) { } - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - MachineFunctionPass::getAnalysisUsage(AU); - } - - const char *getPassName() const { - return "Hexagon Copy-To-Combine Pass"; - } - - virtual bool runOnMachineFunction(MachineFunction &Fn); - -private: - MachineInstr *findPairable(MachineInstr *I1, bool &DoInsertAtI1); - - void combine(MachineInstr *I1, MachineInstr *I2, - MachineBasicBlock::iterator &MI, bool DoInsertAtI1); - - bool isSafeToMoveTogether(MachineInstr *I1, MachineInstr *I2, - unsigned I1DestReg, unsigned I2DestReg, - bool &DoInsertAtI1); - - void emitCombineRR(MachineBasicBlock::iterator &Before, unsigned DestReg, - MachineOperand &HiOperand, MachineOperand &LoOperand); - - void emitCombineRI(MachineBasicBlock::iterator &Before, unsigned DestReg, - MachineOperand &HiOperand, MachineOperand &LoOperand); - - void emitCombineIR(MachineBasicBlock::iterator &Before, unsigned DestReg, - MachineOperand &HiOperand, MachineOperand &LoOperand); - - void emitCombineII(MachineBasicBlock::iterator &Before, unsigned DestReg, - MachineOperand &HiOperand, MachineOperand &LoOperand); -}; - -} // End anonymous namespace. - -char HexagonCopyToCombine::ID = 0; - -static bool isCombinableInstType(MachineInstr *MI, - const HexagonInstrInfo *TII) { - switch(MI->getOpcode()) { - case Hexagon::TFR: { - // A COPY instruction can be combined if its arguments are IntRegs (32bit). - assert(MI->getOperand(0).isReg() && MI->getOperand(1).isReg()); - - unsigned DestReg = MI->getOperand(0).getReg(); - unsigned SrcReg = MI->getOperand(1).getReg(); - return Hexagon::IntRegsRegClass.contains(DestReg) && - Hexagon::IntRegsRegClass.contains(SrcReg); - } - - case Hexagon::TFRI: { - // A transfer-immediate can be combined if its argument is a signed 8bit - // value. - assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm()); - unsigned DestReg = MI->getOperand(0).getReg(); - return Hexagon::IntRegsRegClass.contains(DestReg) && - isInt<8>(MI->getOperand(1).getImm()); - } - default: - break; - } - - return false; -} - - -/// areCombinableOperations - Returns true if the two instruction can be merge -/// into a combine (ignoring register constraints). -static bool areCombinableOperations(const TargetRegisterInfo *TRI, - MachineInstr *I1, MachineInstr *I2) { - assert((I1->getOpcode() == Hexagon::TFR || - I1->getOpcode() == Hexagon::TFRI) && - (I2->getOpcode() == Hexagon::TFR || - I2->getOpcode() == Hexagon::TFRI) && - "Assume individual instructions are of a combinable type"); - - const HexagonRegisterInfo *QRI = - static_cast<const HexagonRegisterInfo *>(TRI); - - // V4 added some combine variations (mixed immediate and register source - // operands), if we are on < V4 we can only combine 2 register-to-register - // moves and 2 immediate-to-register moves. - if (QRI->Subtarget.getHexagonArchVersion() < HexagonSubtarget::V4) - return I1->getOpcode() == I2->getOpcode(); - - return true; -} - -static bool isEvenReg(unsigned Reg) { - assert(TargetRegisterInfo::isPhysicalRegister(Reg) && - Hexagon::IntRegsRegClass.contains(Reg)); - return (Reg - Hexagon::R0) % 2 == 0; -} - -static void removeKillInfo(MachineInstr *MI, unsigned RegNotKilled) { - for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) { - MachineOperand &Op = MI->getOperand(I); - if (!Op.isReg() || Op.getReg() != RegNotKilled || !Op.isKill()) - continue; - Op.setIsKill(false); - } -} - -/// isUnsafeToMoveAccross - Returns true if it is unsafe to move a copy -/// instruction from \p UseReg to \p DestReg over the instruction \p I. -bool isUnsafeToMoveAccross(MachineInstr *I, unsigned UseReg, unsigned DestReg, - const TargetRegisterInfo *TRI) { - return (UseReg && (I->modifiesRegister(UseReg, TRI))) || - I->modifiesRegister(DestReg, TRI) || - I->readsRegister(DestReg, TRI) || - I->hasUnmodeledSideEffects() || - I->isInlineAsm() || I->isDebugValue(); -} - -/// isSafeToMoveTogether - Returns true if it is safe to move I1 next to I2 such -/// that the two instructions can be paired in a combine. -bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr *I1, - MachineInstr *I2, - unsigned I1DestReg, - unsigned I2DestReg, - bool &DoInsertAtI1) { - bool isSafe = true; - - // First try to move I2 towards I1. - { - // A reverse_iterator instantiated like below starts before I2, and I1 - // respectively. - // Look at instructions I in between I2 and (including) I1. - MachineBasicBlock::reverse_iterator I(I2), - End = MachineBasicBlock::reverse_iterator(I1); - bool IsImmUseReg = I2->getOperand(1).isImm(); - unsigned I2UseReg = IsImmUseReg ? 0 : I2->getOperand(1).getReg(); - - // If I2 kills its operand and we move I2 over an instruction that also - // uses I2's use reg we need to modify that (first) instruction to now kill - // this reg. - unsigned KilledOperand = 0; - if (I2->killsRegister(I2UseReg)) - KilledOperand = I2UseReg; - MachineInstr *KillingInstr = 0; - - for (; I != End; ++I) { - // If the intervening instruction I: - // * modifies I2's use reg - // * modifies I2's def reg - // * reads I2's def reg - // * or has unmodelled side effects - // we can't move I2 across it. - if (isUnsafeToMoveAccross(&*I, I2UseReg, I2DestReg, TRI)) { - isSafe = false; - break; - } - - // Update first use of the killed operand. - if (!KillingInstr && KilledOperand && - I->readsRegister(KilledOperand, TRI)) - KillingInstr = &*I; - } - if (isSafe) { - // Update the intermediate instruction to with the kill flag. - if (KillingInstr) { - bool Added = KillingInstr->addRegisterKilled(KilledOperand, TRI, true); - assert(Added && "Must successfully update kill flag"); - (void)Added; - removeKillInfo(I2, KilledOperand); - } - DoInsertAtI1 = true; - return true; - } - } - - // Try to move I1 towards I2. - { - // Look at instructions I in between I1 and (including) I2. - MachineBasicBlock::iterator I(I1), - End(llvm::next(MachineBasicBlock::iterator(I2))); - bool IsImmUseReg = I1->getOperand(1).isImm(); - unsigned I1UseReg = IsImmUseReg ? 0 : I1->getOperand(1).getReg(); - // Track killed operands. If we move accross an instruction that kills our - // operand, we need to update the kill information on the moved I1. It kills - // the operand now. - MachineInstr *KillingInstr = 0; - unsigned KilledOperand = 0; - - while(++I != End) { - // If the intervening instruction I: - // * modifies I1's use reg - // * modifies I1's def reg - // * reads I1's def reg - // * or has unmodelled side effects - // We introduce this special case because llvm has no api to remove a - // kill flag for a register (a removeRegisterKilled() analogous to - // addRegisterKilled) that handles aliased register correctly. - // * or has a killed aliased register use of I1's use reg - // %D4<def> = TFRI64 16 - // %R6<def> = TFR %R9 - // %R8<def> = KILL %R8, %D4<imp-use,kill> - // If we want to move R6 = across the KILL instruction we would have - // to remove the %D4<imp-use,kill> operand. For now, we are - // conservative and disallow the move. - // we can't move I1 across it. - if (isUnsafeToMoveAccross(I, I1UseReg, I1DestReg, TRI) || - // Check for an aliased register kill. Bail out if we see one. - (!I->killsRegister(I1UseReg) && I->killsRegister(I1UseReg, TRI))) - return false; - - // Check for an exact kill (registers match). - if (I1UseReg && I->killsRegister(I1UseReg)) { - assert(KillingInstr == 0 && "Should only see one killing instruction"); - KilledOperand = I1UseReg; - KillingInstr = &*I; - } - } - if (KillingInstr) { - removeKillInfo(KillingInstr, KilledOperand); - // Update I1 to set the kill flag. This flag will later be picked up by - // the new COMBINE instruction. - bool Added = I1->addRegisterKilled(KilledOperand, TRI); - assert(Added && "Must successfully update kill flag"); - (void)Added; - } - DoInsertAtI1 = false; - } - - return true; -} - -bool HexagonCopyToCombine::runOnMachineFunction(MachineFunction &MF) { - - if (IsCombinesDisabled) return false; - - bool HasChanged = false; - - // Get target info. - TRI = MF.getTarget().getRegisterInfo(); - TII = static_cast<const HexagonInstrInfo *>(MF.getTarget().getInstrInfo()); - - // Traverse basic blocks. - for (MachineFunction::iterator BI = MF.begin(), BE = MF.end(); BI != BE; - ++BI) { - // Traverse instructions in basic block. - for(MachineBasicBlock::iterator MI = BI->begin(), End = BI->end(); - MI != End;) { - MachineInstr *I1 = MI++; - - // Ignore instructions that are not combinable. - if (!isCombinableInstType(I1, TII)) - continue; - - // Find a second instruction that can be merged into a combine - // instruction. - bool DoInsertAtI1 = false; - MachineInstr *I2 = findPairable(I1, DoInsertAtI1); - if (I2) { - HasChanged = true; - combine(I1, I2, MI, DoInsertAtI1); - } - } - } - - return HasChanged; -} - -/// findPairable - Returns an instruction that can be merged with \p I1 into a -/// COMBINE instruction or 0 if no such instruction can be found. Returns true -/// in \p DoInsertAtI1 if the combine must be inserted at instruction \p I1 -/// false if the combine must be inserted at the returned instruction. -MachineInstr *HexagonCopyToCombine::findPairable(MachineInstr *I1, - bool &DoInsertAtI1) { - MachineBasicBlock::iterator I2 = llvm::next(MachineBasicBlock::iterator(I1)); - unsigned I1DestReg = I1->getOperand(0).getReg(); - - for (MachineBasicBlock::iterator End = I1->getParent()->end(); I2 != End; - ++I2) { - // Bail out early if we see a second definition of I1DestReg. - if (I2->modifiesRegister(I1DestReg, TRI)) - break; - - // Ignore non-combinable instructions. - if (!isCombinableInstTy |