diff options
-rw-r--r-- | llvm/include/llvm/Target/TargetInstrInfo.h | 9 | ||||
-rw-r--r-- | llvm/lib/CodeGen/BranchFolding.cpp | 15 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMBaseInstrInfo.h | 3 |
4 files changed, 18 insertions, 17 deletions
diff --git a/llvm/include/llvm/Target/TargetInstrInfo.h b/llvm/include/llvm/Target/TargetInstrInfo.h index 72ebe3cafac..8070d458588 100644 --- a/llvm/include/llvm/Target/TargetInstrInfo.h +++ b/llvm/include/llvm/Target/TargetInstrInfo.h @@ -544,12 +544,9 @@ public: virtual unsigned getInlineAsmLength(const char *Str, const MCAsmInfo &MAI) const; - /// TailDuplicationLimit - Returns the limit on the number of instructions - /// in basic block MBB beyond which it will not be tail-duplicated. - virtual unsigned TailDuplicationLimit(const MachineBasicBlock &MBB, - unsigned DefaultLimit) const { - return DefaultLimit; - } + /// isProfitableToDuplicateIndirectBranch - Returns true if tail duplication + /// is especially profitable for indirect branches. + virtual bool isProfitableToDuplicateIndirectBranch() const { return false; } }; /// TargetInstrInfoImpl - This is the default implementation of diff --git a/llvm/lib/CodeGen/BranchFolding.cpp b/llvm/lib/CodeGen/BranchFolding.cpp index f807e8fa261..0fd3c23085d 100644 --- a/llvm/lib/CodeGen/BranchFolding.cpp +++ b/llvm/lib/CodeGen/BranchFolding.cpp @@ -1043,9 +1043,18 @@ bool BranchFolder::TailDuplicate(MachineBasicBlock *TailBB, // of one less than the tail-merge threshold. When optimizing for size, // duplicate only one, because one branch instruction can be eliminated to // compensate for the duplication. - unsigned MaxDuplicateCount = - MF.getFunction()->hasFnAttr(Attribute::OptimizeForSize) ? - 1 : TII->TailDuplicationLimit(*TailBB, TailMergeSize - 1); + unsigned MaxDuplicateCount; + if (MF.getFunction()->hasFnAttr(Attribute::OptimizeForSize)) + MaxDuplicateCount = 1; + else if (TII->isProfitableToDuplicateIndirectBranch() && + !TailBB->empty() && TailBB->back().getDesc().isIndirectBranch()) + // If the target has hardware branch prediction that can handle indirect + // branches, duplicating them can often make them predictable when there + // are common paths through the code. The limit needs to be high enough + // to allow undoing the effects of tail merging. + MaxDuplicateCount = 20; + else + MaxDuplicateCount = TailMergeSize - 1; // Check the instructions in the block to determine whether tail-duplication // is invalid or unlikely to be profitable. diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp index c92ec368a79..705f97097c1 100644 --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -1027,14 +1027,10 @@ bool ARMBaseInstrInfo::isIdentical(const MachineInstr *MI0, return TargetInstrInfoImpl::isIdentical(MI0, MI1, MRI); } -unsigned ARMBaseInstrInfo::TailDuplicationLimit(const MachineBasicBlock &MBB, - unsigned DefaultLimit) const { +bool ARMBaseInstrInfo::isProfitableToDuplicateIndirectBranch() const { // If the target processor can predict indirect branches, it is highly // desirable to duplicate them, since it can often make them predictable. - if (!MBB.empty() && isIndirectBranchOpcode(MBB.back().getOpcode()) && - getSubtarget().hasBranchTargetBuffer()) - return DefaultLimit + 2; - return DefaultLimit; + return getSubtarget().hasBranchTargetBuffer(); } /// getInstrPredicate - If instruction is predicated, returns its predicate diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.h b/llvm/lib/Target/ARM/ARMBaseInstrInfo.h index dbd4f63619d..7944f354b9b 100644 --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.h +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.h @@ -291,8 +291,7 @@ public: virtual bool isIdentical(const MachineInstr *MI, const MachineInstr *Other, const MachineRegisterInfo *MRI) const; - virtual unsigned TailDuplicationLimit(const MachineBasicBlock &MBB, - unsigned DefaultLimit) const; + virtual bool isProfitableToDuplicateIndirectBranch() const; }; static inline |