diff options
| -rw-r--r-- | llvm/include/llvm/CodeGen/TargetInstrInfo.h | 9 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/MachineOutliner.cpp | 7 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 47 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64InstrInfo.h | 3 |
4 files changed, 44 insertions, 22 deletions
diff --git a/llvm/include/llvm/CodeGen/TargetInstrInfo.h b/llvm/include/llvm/CodeGen/TargetInstrInfo.h index 1fa3de421ea..39146b57501 100644 --- a/llvm/include/llvm/CodeGen/TargetInstrInfo.h +++ b/llvm/include/llvm/CodeGen/TargetInstrInfo.h @@ -1635,10 +1635,11 @@ public: "Target didn't implement TargetInstrInfo::getOutliningType!"); } - /// Returns target-defined flags defining properties of the MBB for - /// the outliner. - virtual unsigned getMachineOutlinerMBBFlags(MachineBasicBlock &MBB) const { - return 0x0; + /// Optional target hook that returns true if \p MBB is safe to outline from, + /// and returns any target-specific information in \p Flags. + virtual bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB, + unsigned &Flags) const { + return true; } /// Insert a custom frame for outlined functions. diff --git a/llvm/lib/CodeGen/MachineOutliner.cpp b/llvm/lib/CodeGen/MachineOutliner.cpp index 143310ea16f..e6f30663dce 100644 --- a/llvm/lib/CodeGen/MachineOutliner.cpp +++ b/llvm/lib/CodeGen/MachineOutliner.cpp @@ -742,7 +742,12 @@ struct InstructionMapper { /// \param TII \p TargetInstrInfo for the function. void convertToUnsignedVec(MachineBasicBlock &MBB, const TargetInstrInfo &TII) { - unsigned Flags = TII.getMachineOutlinerMBBFlags(MBB); + unsigned Flags; + + // Don't even map in this case. + if (!TII.isMBBSafeToOutlineFrom(MBB, Flags)) + return; + MachineBasicBlock::iterator It = MBB.begin(); // The number of instructions in this block that will be considered for diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp index bcf278e7888..71cbffdff48 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -5286,29 +5286,44 @@ bool AArch64InstrInfo::isFunctionSafeToOutlineFrom( return true; } -unsigned -AArch64InstrInfo::getMachineOutlinerMBBFlags(MachineBasicBlock &MBB) const { - unsigned Flags = 0x0; - // Check if there's a call inside this MachineBasicBlock. If there is, then - // set a flag. - if (any_of(MBB, [](MachineInstr &MI) { return MI.isCall(); })) - Flags |= MachineOutlinerMBBFlags::HasCalls; - +bool AArch64InstrInfo::isMBBSafeToOutlineFrom(MachineBasicBlock &MBB, + unsigned &Flags) const { // Check if LR is available through all of the MBB. If it's not, then set // a flag. assert(MBB.getParent()->getRegInfo().tracksLiveness() && "Suitable Machine Function for outlining must track liveness"); - LiveRegUnits LRU(getRegisterInfo()); - LRU.addLiveOuts(MBB); + LiveRegUnits ModifiedRegUnits(getRegisterInfo()); + LiveRegUnits UsedRegUnits(getRegisterInfo()); + ModifiedRegUnits.addLiveOuts(MBB); + UsedRegUnits.addLiveOuts(MBB); + const TargetRegisterInfo *TRI = &getRegisterInfo(); - std::for_each(MBB.rbegin(), - MBB.rend(), - [&LRU](MachineInstr &MI) { LRU.accumulate(MI); }); + std::for_each(MBB.rbegin(), MBB.rend(), + [&ModifiedRegUnits, &UsedRegUnits, &TRI](MachineInstr &MI) { + LiveRegUnits::accumulateUsedDefed(MI, ModifiedRegUnits, + UsedRegUnits, TRI); + }); + + // If one of these registers is live out of the MBB, but not modified in the + // MBB, then we can't outline. + if ((ModifiedRegUnits.available(AArch64::W16) && + !UsedRegUnits.available(AArch64::W16)) || + (ModifiedRegUnits.available(AArch64::W17) && + !UsedRegUnits.available(AArch64::W17)) || + (ModifiedRegUnits.available(AArch64::NZCV) && + !UsedRegUnits.available(AArch64::NZCV))) + return false; - if (!LRU.available(AArch64::LR)) - Flags |= MachineOutlinerMBBFlags::LRUnavailableSomewhere; + // Check if there's a call inside this MachineBasicBlock. If there is, then + // set a flag. + if (any_of(MBB, [](MachineInstr &MI) { return MI.isCall(); })) + Flags |= MachineOutlinerMBBFlags::HasCalls; + + if (!ModifiedRegUnits.available(AArch64::LR) || + !UsedRegUnits.available(AArch64::LR)) + Flags |= MachineOutlinerMBBFlags::LRUnavailableSomewhere; - return Flags; + return true; } outliner::InstrType diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.h b/llvm/lib/Target/AArch64/AArch64InstrInfo.h index 43011dd4c3e..404d632b13c 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.h +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.h @@ -246,7 +246,8 @@ public: std::vector<outliner::Candidate> &RepeatedSequenceLocs) const override; outliner::InstrType getOutliningType(MachineBasicBlock::iterator &MIT, unsigned Flags) const override; - unsigned getMachineOutlinerMBBFlags(MachineBasicBlock &MBB) const override; + bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB, + unsigned &Flags) const override; void buildOutlinedFrame(MachineBasicBlock &MBB, MachineFunction &MF, const outliner::OutlinedFunction &OF) const override; MachineBasicBlock::iterator |

