forked from OSchip/llvm-project
Refactor target hook for tail duplication as requested by Chris.
Make tail duplication of indirect branches much more aggressive (for targets that indicate that it is profitable), based on further experience with this transformation. I compiled 3 large applications with and without this more aggressive tail duplication and measured minimal changes in code size. ("size" on Darwin seems to round the text size up to the nearest page boundary, so I can only say that any code size increase was less than one 4k page.) Radar 7421267. llvm-svn: 89814
This commit is contained in:
parent
5ece8f0a20
commit
d4d40670e8
|
@ -544,12 +544,9 @@ public:
|
||||||
virtual unsigned getInlineAsmLength(const char *Str,
|
virtual unsigned getInlineAsmLength(const char *Str,
|
||||||
const MCAsmInfo &MAI) const;
|
const MCAsmInfo &MAI) const;
|
||||||
|
|
||||||
/// TailDuplicationLimit - Returns the limit on the number of instructions
|
/// isProfitableToDuplicateIndirectBranch - Returns true if tail duplication
|
||||||
/// in basic block MBB beyond which it will not be tail-duplicated.
|
/// is especially profitable for indirect branches.
|
||||||
virtual unsigned TailDuplicationLimit(const MachineBasicBlock &MBB,
|
virtual bool isProfitableToDuplicateIndirectBranch() const { return false; }
|
||||||
unsigned DefaultLimit) const {
|
|
||||||
return DefaultLimit;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// TargetInstrInfoImpl - This is the default implementation of
|
/// TargetInstrInfoImpl - This is the default implementation of
|
||||||
|
|
|
@ -1043,9 +1043,18 @@ bool BranchFolder::TailDuplicate(MachineBasicBlock *TailBB,
|
||||||
// of one less than the tail-merge threshold. When optimizing for size,
|
// of one less than the tail-merge threshold. When optimizing for size,
|
||||||
// duplicate only one, because one branch instruction can be eliminated to
|
// duplicate only one, because one branch instruction can be eliminated to
|
||||||
// compensate for the duplication.
|
// compensate for the duplication.
|
||||||
unsigned MaxDuplicateCount =
|
unsigned MaxDuplicateCount;
|
||||||
MF.getFunction()->hasFnAttr(Attribute::OptimizeForSize) ?
|
if (MF.getFunction()->hasFnAttr(Attribute::OptimizeForSize))
|
||||||
1 : TII->TailDuplicationLimit(*TailBB, TailMergeSize - 1);
|
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
|
// Check the instructions in the block to determine whether tail-duplication
|
||||||
// is invalid or unlikely to be profitable.
|
// is invalid or unlikely to be profitable.
|
||||||
|
|
|
@ -1027,14 +1027,10 @@ bool ARMBaseInstrInfo::isIdentical(const MachineInstr *MI0,
|
||||||
return TargetInstrInfoImpl::isIdentical(MI0, MI1, MRI);
|
return TargetInstrInfoImpl::isIdentical(MI0, MI1, MRI);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned ARMBaseInstrInfo::TailDuplicationLimit(const MachineBasicBlock &MBB,
|
bool ARMBaseInstrInfo::isProfitableToDuplicateIndirectBranch() const {
|
||||||
unsigned DefaultLimit) const {
|
|
||||||
// If the target processor can predict indirect branches, it is highly
|
// If the target processor can predict indirect branches, it is highly
|
||||||
// desirable to duplicate them, since it can often make them predictable.
|
// desirable to duplicate them, since it can often make them predictable.
|
||||||
if (!MBB.empty() && isIndirectBranchOpcode(MBB.back().getOpcode()) &&
|
return getSubtarget().hasBranchTargetBuffer();
|
||||||
getSubtarget().hasBranchTargetBuffer())
|
|
||||||
return DefaultLimit + 2;
|
|
||||||
return DefaultLimit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// getInstrPredicate - If instruction is predicated, returns its predicate
|
/// getInstrPredicate - If instruction is predicated, returns its predicate
|
||||||
|
|
|
@ -291,8 +291,7 @@ public:
|
||||||
virtual bool isIdentical(const MachineInstr *MI, const MachineInstr *Other,
|
virtual bool isIdentical(const MachineInstr *MI, const MachineInstr *Other,
|
||||||
const MachineRegisterInfo *MRI) const;
|
const MachineRegisterInfo *MRI) const;
|
||||||
|
|
||||||
virtual unsigned TailDuplicationLimit(const MachineBasicBlock &MBB,
|
virtual bool isProfitableToDuplicateIndirectBranch() const;
|
||||||
unsigned DefaultLimit) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
|
|
Loading…
Reference in New Issue