summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/Target/TargetInstrInfo.h9
-rw-r--r--llvm/lib/CodeGen/BranchFolding.cpp15
-rw-r--r--llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp8
-rw-r--r--llvm/lib/Target/ARM/ARMBaseInstrInfo.h3
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
OpenPOWER on IntegriCloud