diff options
| author | Jessica Paquette <jpaquette@apple.com> | 2017-09-27 20:47:39 +0000 |
|---|---|---|
| committer | Jessica Paquette <jpaquette@apple.com> | 2017-09-27 20:47:39 +0000 |
| commit | 4cf187b5b418e55c0cf8a662fd0fe48e1639f7b6 (patch) | |
| tree | 780ec8220057bdaef2c48de00696dee1a756ab85 /llvm/lib/Target/X86/X86InstrInfo.cpp | |
| parent | bd3a7633f19365cb7ac24d6bc646d5547b734fc0 (diff) | |
| download | bcm5719-llvm-4cf187b5b418e55c0cf8a662fd0fe48e1639f7b6.tar.gz bcm5719-llvm-4cf187b5b418e55c0cf8a662fd0fe48e1639f7b6.zip | |
[MachineOutliner] AArch64: Avoid saving + restoring LR if possible
This commit allows the outliner to avoid saving and restoring the link register
on AArch64 when it is dead within an entire class of candidates.
This introduces changes to the way the outliner interfaces with the target.
For example, the target now interfaces with the outliner using a
MachineOutlinerInfo struct rather than by using getOutliningCallOverhead and
getOutliningFrameOverhead.
This also improves several comments on the outliner's cost model.
https://reviews.llvm.org/D36721
llvm-svn: 314341
Diffstat (limited to 'llvm/lib/Target/X86/X86InstrInfo.cpp')
| -rw-r--r-- | llvm/lib/Target/X86/X86InstrInfo.cpp | 84 |
1 files changed, 54 insertions, 30 deletions
diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp index 0561bcd8d0a..6dcfa97b851 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.cpp +++ b/llvm/lib/Target/X86/X86InstrInfo.cpp @@ -10723,31 +10723,54 @@ char LDTLSCleanup::ID = 0; FunctionPass* llvm::createCleanupLocalDynamicTLSPass() { return new LDTLSCleanup(); } -// Constants defining how certain sequences should be outlined. -const unsigned MachineOutlinerDefaultFn = 0; -const unsigned MachineOutlinerTailCallFn = 1; - -std::pair<size_t, unsigned> X86InstrInfo::getOutliningCallOverhead( - MachineBasicBlock::iterator &StartIt, - MachineBasicBlock::iterator &EndIt) const { - - // Is this a tail call? If it is, make note of it. - if (EndIt->isTerminator()) - return std::make_pair(1, MachineOutlinerTailCallFn); - - return std::make_pair(1, MachineOutlinerDefaultFn); -} - -std::pair<size_t, unsigned> X86InstrInfo::getOutliningFrameOverhead( - std::vector<std::pair<MachineBasicBlock::iterator, - MachineBasicBlock::iterator>> &CandidateClass) const { - // Is this a tail-call? - // Is the last instruction in this class a terminator? - if (CandidateClass[0].second->isTerminator()) - return std::make_pair(0, MachineOutlinerTailCallFn); +/// Constants defining how certain sequences should be outlined. +/// +/// \p MachineOutlinerDefault implies that the function is called with a call +/// instruction, and a return must be emitted for the outlined function frame. +/// +/// That is, +/// +/// I1 OUTLINED_FUNCTION: +/// I2 --> call OUTLINED_FUNCTION I1 +/// I3 I2 +/// I3 +/// ret +/// +/// * Call construction overhead: 1 (call instruction) +/// * Frame construction overhead: 1 (return instruction) +/// +/// \p MachineOutlinerTailCall implies that the function is being tail called. +/// A jump is emitted instead of a call, and the return is already present in +/// the outlined sequence. That is, +/// +/// I1 OUTLINED_FUNCTION: +/// I2 --> jmp OUTLINED_FUNCTION I1 +/// ret I2 +/// ret +/// +/// * Call construction overhead: 1 (jump instruction) +/// * Frame construction overhead: 0 (don't need to return) +/// +enum MachineOutlinerClass { + MachineOutlinerDefault, + MachineOutlinerTailCall +}; - // No, so we have to add a return to the end. - return std::make_pair(1, MachineOutlinerDefaultFn); +X86GenInstrInfo::MachineOutlinerInfo +X86InstrInfo::getOutlininingCandidateInfo( + std::vector< + std::pair<MachineBasicBlock::iterator, MachineBasicBlock::iterator>> + &RepeatedSequenceLocs) const { + + if (RepeatedSequenceLocs[0].second->isTerminator()) + return MachineOutlinerInfo(1, // Number of instructions to emit call. + 0, // Number of instructions to emit frame. + MachineOutlinerTailCall, // Type of call. + MachineOutlinerTailCall // Type of frame. + ); + + return MachineOutlinerInfo(1, 1, MachineOutlinerDefault, + MachineOutlinerDefault); } bool X86InstrInfo::isFunctionSafeToOutlineFrom(MachineFunction &MF) const { @@ -10811,10 +10834,10 @@ X86InstrInfo::getOutliningType(MachineInstr &MI) const { void X86InstrInfo::insertOutlinerEpilogue(MachineBasicBlock &MBB, MachineFunction &MF, - unsigned FrameClass) const { - + const MachineOutlinerInfo &MInfo) + const { // If we're a tail call, we already have a return, so don't do anything. - if (FrameClass == MachineOutlinerTailCallFn) + if (MInfo.FrameConstructionID == MachineOutlinerTailCall) return; // We're a normal call, so our sequence doesn't have a return instruction. @@ -10825,15 +10848,16 @@ void X86InstrInfo::insertOutlinerEpilogue(MachineBasicBlock &MBB, void X86InstrInfo::insertOutlinerPrologue(MachineBasicBlock &MBB, MachineFunction &MF, - unsigned FrameClass) const {} + const MachineOutlinerInfo &MInfo) + const {} MachineBasicBlock::iterator X86InstrInfo::insertOutlinedCall(Module &M, MachineBasicBlock &MBB, MachineBasicBlock::iterator &It, MachineFunction &MF, - unsigned CallClass) const { + const MachineOutlinerInfo &MInfo) const { // Is it a tail call? - if (CallClass == MachineOutlinerTailCallFn) { + if (MInfo.CallConstructionID == MachineOutlinerTailCall) { // Yes, just insert a JMP. It = MBB.insert(It, BuildMI(MF, DebugLoc(), get(X86::JMP_1)) |

