From 82d9c0a3fabda486a646a4749c6534790d970ca6 Mon Sep 17 00:00:00 2001 From: Jessica Paquette Date: Mon, 12 Nov 2018 23:51:32 +0000 Subject: [PATCH] [MachineOutliner][NFC] Change getMachineOutlinerMBBFlags to isMBBSafeToOutlineFrom Instead of returning Flags, return true if the MBB is safe to outline from. This lets us check for unsafe situations, like say, in AArch64, X17 is live across a MBB without being defined in that MBB. In that case, there's no point in performing an instruction mapping. llvm-svn: 346718 --- llvm/include/llvm/CodeGen/TargetInstrInfo.h | 9 ++-- llvm/lib/CodeGen/MachineOutliner.cpp | 7 ++- llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 49 +++++++++++++------- llvm/lib/Target/AArch64/AArch64InstrInfo.h | 3 +- 4 files changed, 45 insertions(+), 23 deletions(-) diff --git a/llvm/include/llvm/CodeGen/TargetInstrInfo.h b/llvm/include/llvm/CodeGen/TargetInstrInfo.h index 1fa3de421eac..39146b575011 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 143310ea16f8..e6f30663dced 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 bcf278e78881..71cbffdff482 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; +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 ModifiedRegUnits(getRegisterInfo()); + LiveRegUnits UsedRegUnits(getRegisterInfo()); + ModifiedRegUnits.addLiveOuts(MBB); + UsedRegUnits.addLiveOuts(MBB); + const TargetRegisterInfo *TRI = &getRegisterInfo(); + + 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; + // 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; - // 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); + if (!ModifiedRegUnits.available(AArch64::LR) || + !UsedRegUnits.available(AArch64::LR)) + Flags |= MachineOutlinerMBBFlags::LRUnavailableSomewhere; - std::for_each(MBB.rbegin(), - MBB.rend(), - [&LRU](MachineInstr &MI) { LRU.accumulate(MI); }); - - if (!LRU.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 43011dd4c3e5..404d632b13c3 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.h +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.h @@ -246,7 +246,8 @@ public: std::vector &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