summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/ShrinkWrap.cpp
diff options
context:
space:
mode:
authorQuentin Colombet <qcolombet@apple.com>2015-11-06 21:00:13 +0000
committerQuentin Colombet <qcolombet@apple.com>2015-11-06 21:00:13 +0000
commit9a8efc08d366526e1b4f964409b64b1068fb475c (patch)
treee04a1352b6f64b4bfb8b68a804c30ac6202df8b8 /llvm/lib/CodeGen/ShrinkWrap.cpp
parent9198c671e883fa579fa7b00cd86a2568d2cd3304 (diff)
downloadbcm5719-llvm-9a8efc08d366526e1b4f964409b64b1068fb475c.tar.gz
bcm5719-llvm-9a8efc08d366526e1b4f964409b64b1068fb475c.zip
[ShrinkWrapping] Teach shrink-wrapping how to analyze RegMask.
Previously we were conservatively assuming that RegMask operands clobber callee saved registers. llvm-svn: 252341
Diffstat (limited to 'llvm/lib/CodeGen/ShrinkWrap.cpp')
-rw-r--r--llvm/lib/CodeGen/ShrinkWrap.cpp46
1 files changed, 38 insertions, 8 deletions
diff --git a/llvm/lib/CodeGen/ShrinkWrap.cpp b/llvm/lib/CodeGen/ShrinkWrap.cpp
index dff0973c924..8261caa4f84 100644
--- a/llvm/lib/CodeGen/ShrinkWrap.cpp
+++ b/llvm/lib/CodeGen/ShrinkWrap.cpp
@@ -43,9 +43,11 @@
// points must be in the same loop.
// Property #3 is ensured via the MachineBlockFrequencyInfo.
//
-// If this pass found points matching all this properties, then
+// If this pass found points matching all these properties, then
// MachineFrameInfo is updated this that information.
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/Statistic.h"
// To check for profitability.
#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
@@ -117,12 +119,32 @@ class ShrinkWrap : public MachineFunctionPass {
unsigned FrameDestroyOpcode;
/// Entry block.
const MachineBasicBlock *Entry;
+ typedef SmallSetVector<unsigned, 16> SetOfRegs;
+ /// Registers that need to be saved for the current function.
+ mutable SetOfRegs CurrentCSRs;
+ /// Current MachineFunction.
+ MachineFunction *MachineFunc;
/// \brief Check if \p MI uses or defines a callee-saved register or
/// a frame index. If this is the case, this means \p MI must happen
/// after Save and before Restore.
bool useOrDefCSROrFI(const MachineInstr &MI) const;
+ const SetOfRegs &getCurrentCSRs() const {
+ if (CurrentCSRs.empty()) {
+ BitVector SavedRegs;
+ const TargetFrameLowering *TFI =
+ MachineFunc->getSubtarget().getFrameLowering();
+
+ TFI->determineCalleeSaves(*MachineFunc, SavedRegs, nullptr);
+
+ for (int Reg = SavedRegs.find_first(); Reg != -1;
+ Reg = SavedRegs.find_next(Reg))
+ CurrentCSRs.insert((unsigned)Reg);
+ }
+ return CurrentCSRs;
+ }
+
/// \brief Update the Save and Restore points such that \p MBB is in
/// the region that is dominated by Save and post-dominated by Restore
/// and Save and Restore still match the safe point definition.
@@ -144,6 +166,8 @@ class ShrinkWrap : public MachineFunctionPass {
FrameSetupOpcode = TII.getCallFrameSetupOpcode();
FrameDestroyOpcode = TII.getCallFrameDestroyOpcode();
Entry = &MF.front();
+ CurrentCSRs.clear();
+ MachineFunc = &MF;
++NumFunc;
}
@@ -199,20 +223,26 @@ bool ShrinkWrap::useOrDefCSROrFI(const MachineInstr &MI) const {
return true;
}
for (const MachineOperand &MO : MI.operands()) {
- bool UseCSR = false;
+ bool UseOrDefCSR = false;
if (MO.isReg()) {
unsigned PhysReg = MO.getReg();
if (!PhysReg)
continue;
assert(TargetRegisterInfo::isPhysicalRegister(PhysReg) &&
"Unallocated register?!");
- UseCSR = RCI.getLastCalleeSavedAlias(PhysReg);
+ UseOrDefCSR = RCI.getLastCalleeSavedAlias(PhysReg);
+ } else if (MO.isRegMask()) {
+ // Check if this regmask clobbers any of the CSRs.
+ for (unsigned Reg : getCurrentCSRs()) {
+ if (MO.clobbersPhysReg(Reg)) {
+ UseOrDefCSR = true;
+ break;
+ }
+ }
}
- // TODO: Handle regmask more accurately.
- // For now, be conservative about them.
- if (UseCSR || MO.isFI() || MO.isRegMask()) {
- DEBUG(dbgs() << "Use or define CSR(" << UseCSR << ") or FI(" << MO.isFI()
- << "): " << MI << '\n');
+ if (UseOrDefCSR || MO.isFI()) {
+ DEBUG(dbgs() << "Use or define CSR(" << UseOrDefCSR << ") or FI("
+ << MO.isFI() << "): " << MI << '\n');
return true;
}
}
OpenPOWER on IntegriCloud