Index: llvm/trunk/include/llvm/Target/TargetInstrInfo.h =================================================================== --- llvm/trunk/include/llvm/Target/TargetInstrInfo.h +++ llvm/trunk/include/llvm/Target/TargetInstrInfo.h @@ -1235,6 +1235,14 @@ return false; } + /// \brief Return the value to use for the MachineCSE's LookAheadLimit, + /// which is a heuristic used for CSE'ing phys reg defs. + virtual unsigned getMachineCSELookAheadLimit () const { + // The default lookahead is small to prevent unprofitable quadratic + // behavior. + return 5; + } + private: int CallFrameSetupOpcode, CallFrameDestroyOpcode; }; Index: llvm/trunk/lib/CodeGen/MachineCSE.cpp =================================================================== --- llvm/trunk/lib/CodeGen/MachineCSE.cpp +++ llvm/trunk/lib/CodeGen/MachineCSE.cpp @@ -48,7 +48,7 @@ MachineRegisterInfo *MRI; public: static char ID; // Pass identification - MachineCSE() : MachineFunctionPass(ID), LookAheadLimit(5), CurrVN(0) { + MachineCSE() : MachineFunctionPass(ID), LookAheadLimit(0), CurrVN(0) { initializeMachineCSEPass(*PassRegistry::getPassRegistry()); } @@ -69,7 +69,7 @@ } private: - const unsigned LookAheadLimit; + unsigned LookAheadLimit; typedef RecyclingAllocator > AllocatorTy; typedef ScopedHashTable(); DT = &getAnalysis(); + LookAheadLimit = TII->getMachineCSELookAheadLimit(); return PerformCSE(DT->getRootNode()); } Index: llvm/trunk/lib/Target/R600/SIInstrInfo.h =================================================================== --- llvm/trunk/lib/Target/R600/SIInstrInfo.h +++ llvm/trunk/lib/Target/R600/SIInstrInfo.h @@ -142,6 +142,8 @@ bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI, unsigned Reg, MachineRegisterInfo *MRI) const final; + unsigned getMachineCSELookAheadLimit() const override { return 500; } + bool isSALU(uint16_t Opcode) const { return get(Opcode).TSFlags & SIInstrFlags::SALU; }