summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Braun <matze@braunis.de>2016-07-06 21:31:27 +0000
committerMatthias Braun <matze@braunis.de>2016-07-06 21:31:27 +0000
commit332bb5c2364d2d213f768948acbe25b35474cd53 (patch)
treee758a68f04a99da32f2fe35bae78cafeea2ec635
parentf296a7eeae5e850b2460513cac4ebc13e7240788 (diff)
downloadbcm5719-llvm-332bb5c2364d2d213f768948acbe25b35474cd53.tar.gz
bcm5719-llvm-332bb5c2364d2d213f768948acbe25b35474cd53.zip
AArch64: Replace a RegScavenger instance with LivePhysRegs
findScratchNonCalleeSaveRegister() just needs a simple liveness analysis, use LivePhysRegs for that as it is simpler and does not depend on the kill flags. This commit adds a convenience function available() to LivePhysRegs: This function returns true if the given register is not reserved and neither the register nor any of its aliases are alive. Differential Revision: http://reviews.llvm.org/D21865 llvm-svn: 274685
-rw-r--r--llvm/include/llvm/CodeGen/LivePhysRegs.h9
-rw-r--r--llvm/lib/CodeGen/LivePhysRegs.cpp14
-rw-r--r--llvm/lib/Target/AArch64/AArch64FrameLowering.cpp28
3 files changed, 35 insertions, 16 deletions
diff --git a/llvm/include/llvm/CodeGen/LivePhysRegs.h b/llvm/include/llvm/CodeGen/LivePhysRegs.h
index 56999f13191..1cea9d5b90d 100644
--- a/llvm/include/llvm/CodeGen/LivePhysRegs.h
+++ b/llvm/include/llvm/CodeGen/LivePhysRegs.h
@@ -93,10 +93,15 @@ public:
SmallVectorImpl<std::pair<unsigned, const MachineOperand*>> *Clobbers);
/// \brief Returns true if register @p Reg is contained in the set. This also
- /// works if only the super register of @p Reg has been defined, because we
- /// always add also all sub-registers to the set.
+ /// works if only the super register of @p Reg has been defined, because
+ /// addReg() always adds all sub-registers to the set as well.
+ /// Note: Returns false if just some sub registers are live, use available()
+ /// when searching a free register.
bool contains(unsigned Reg) const { return LiveRegs.count(Reg); }
+ /// Returns true if register \p Reg and no aliasing register is in the set.
+ bool available(const MachineRegisterInfo &MRI, unsigned Reg) const;
+
/// \brief Simulates liveness when stepping backwards over an
/// instruction(bundle): Remove Defs, add uses. This is the recommended way of
/// calculating liveness.
diff --git a/llvm/lib/CodeGen/LivePhysRegs.cpp b/llvm/lib/CodeGen/LivePhysRegs.cpp
index eb2955045fd..57faef3c297 100644
--- a/llvm/lib/CodeGen/LivePhysRegs.cpp
+++ b/llvm/lib/CodeGen/LivePhysRegs.cpp
@@ -17,6 +17,7 @@
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBundle.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
@@ -126,6 +127,19 @@ LLVM_DUMP_METHOD void LivePhysRegs::dump() const {
#endif
}
+bool LivePhysRegs::available(const MachineRegisterInfo &MRI,
+ unsigned Reg) const {
+ if (LiveRegs.count(Reg))
+ return false;
+ if (MRI.isReserved(Reg))
+ return false;
+ for (MCRegAliasIterator R(Reg, TRI, false); R.isValid(); ++R) {
+ if (LiveRegs.count(*R))
+ return false;
+ }
+ return true;
+}
+
/// Add live-in registers of basic block \p MBB to \p LiveRegs.
static void addLiveIns(LivePhysRegs &LiveRegs, const MachineBasicBlock &MBB) {
for (const auto &LI : MBB.liveins())
diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
index 48d4e113fd7..5fbec7e49ad 100644
--- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -93,6 +93,7 @@
#include "AArch64Subtarget.h"
#include "AArch64TargetMachine.h"
#include "llvm/ADT/Statistic.h"
+#include "llvm/CodeGen/LivePhysRegs.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
@@ -244,27 +245,26 @@ static unsigned findScratchNonCalleeSaveRegister(MachineBasicBlock *MBB) {
if (&MF->front() == MBB)
return AArch64::X9;
- RegScavenger RS;
- RS.enterBasicBlock(*MBB);
+ const TargetRegisterInfo &TRI = *MF->getSubtarget().getRegisterInfo();
+ LivePhysRegs LiveRegs(&TRI);
+ LiveRegs.addLiveIns(*MBB);
- // Prefer X9 since it was historically used for the prologue scratch reg.
- if (!RS.isRegUsed(AArch64::X9))
- return AArch64::X9;
-
- // Find a free non callee-save reg.
+ // Mark callee saved registers as used so we will not choose them.
const AArch64Subtarget &Subtarget = MF->getSubtarget<AArch64Subtarget>();
const AArch64RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
const MCPhysReg *CSRegs = RegInfo->getCalleeSavedRegs(MF);
- BitVector CalleeSaveRegs(RegInfo->getNumRegs());
for (unsigned i = 0; CSRegs[i]; ++i)
- CalleeSaveRegs.set(CSRegs[i]);
+ LiveRegs.addReg(CSRegs[i]);
- BitVector Available = RS.getRegsAvailable(&AArch64::GPR64RegClass);
- for (int AvailReg = Available.find_first(); AvailReg != -1;
- AvailReg = Available.find_next(AvailReg))
- if (!CalleeSaveRegs.test(AvailReg))
- return AvailReg;
+ // Prefer X9 since it was historically used for the prologue scratch reg.
+ const MachineRegisterInfo &MRI = MF->getRegInfo();
+ if (LiveRegs.available(MRI, AArch64::X9))
+ return AArch64::X9;
+ for (unsigned Reg : AArch64::GPR64RegClass) {
+ if (LiveRegs.available(MRI, Reg))
+ return Reg;
+ }
return AArch64::NoRegister;
}
OpenPOWER on IntegriCloud