summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/AArch64/AArch64InstrInfo.cpp')
-rw-r--r--llvm/lib/Target/AArch64/AArch64InstrInfo.cpp47
1 files changed, 31 insertions, 16 deletions
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
OpenPOWER on IntegriCloud