Do not pre-allocate for registers which form a REG_SEQUENCE.
authorEvan Cheng <evan.cheng@apple.com>
Tue, 4 May 2010 20:38:12 +0000 (20:38 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Tue, 4 May 2010 20:38:12 +0000 (20:38 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103041 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/NEONPreAllocPass.cpp

index 7334259bf574e015fb6a4ce67e9c2825dee8b9d4..ef6bf3a132bbb37cf5e875e4fdafba6c869e25d0 100644 (file)
 #include "ARMInstrInfo.h"
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 using namespace llvm;
 
 namespace {
   class NEONPreAllocPass : public MachineFunctionPass {
     const TargetInstrInfo *TII;
+    MachineRegisterInfo *MRI;
 
   public:
     static char ID;
@@ -30,6 +32,8 @@ namespace {
     }
 
   private:
+    bool FormsRegSequence(MachineInstr *MI,
+                          unsigned FirstOpnd, unsigned NumRegs);
     bool PreAllocNEONRegisters(MachineBasicBlock &MBB);
   };
 
@@ -334,6 +338,27 @@ static bool isNEONMultiRegOp(int Opcode, unsigned &FirstOpnd, unsigned &NumRegs,
   return false;
 }
 
+bool NEONPreAllocPass::FormsRegSequence(MachineInstr *MI,
+                                        unsigned FirstOpnd, unsigned NumRegs) {
+  MachineInstr *RegSeq = 0;
+  for (unsigned R = 0; R < NumRegs; ++R) {
+    MachineOperand &MO = MI->getOperand(FirstOpnd + R);
+    assert(MO.isReg() && MO.getSubReg() == 0 && "unexpected operand");
+    unsigned VirtReg = MO.getReg();
+    assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
+           "expected a virtual register");
+    if (!MRI->hasOneNonDBGUse(VirtReg))
+      return false;
+    MachineInstr *UseMI = &*MRI->use_nodbg_begin(VirtReg);
+    if (UseMI->getOpcode() != TargetOpcode::REG_SEQUENCE)
+      return false;
+    if (RegSeq && RegSeq != UseMI)
+      return false;
+    RegSeq = UseMI;
+  }
+  return true;
+}
+
 bool NEONPreAllocPass::PreAllocNEONRegisters(MachineBasicBlock &MBB) {
   bool Modified = false;
 
@@ -343,6 +368,8 @@ bool NEONPreAllocPass::PreAllocNEONRegisters(MachineBasicBlock &MBB) {
     unsigned FirstOpnd, NumRegs, Offset, Stride;
     if (!isNEONMultiRegOp(MI->getOpcode(), FirstOpnd, NumRegs, Offset, Stride))
       continue;
+    if (FormsRegSequence(MI, FirstOpnd, NumRegs))
+      continue;
 
     MachineBasicBlock::iterator NextI = llvm::next(MBBI);
     for (unsigned R = 0; R < NumRegs; ++R) {
@@ -382,6 +409,7 @@ bool NEONPreAllocPass::PreAllocNEONRegisters(MachineBasicBlock &MBB) {
 
 bool NEONPreAllocPass::runOnMachineFunction(MachineFunction &MF) {
   TII = MF.getTarget().getInstrInfo();
+  MRI = &MF.getRegInfo();
 
   bool Modified = false;
   for (MachineFunction::iterator MFI = MF.begin(), E = MF.end(); MFI != E;