]> granicus.if.org Git - llvm/commitdiff
[MIPS GlobalISel] Skip copies in addUseDef and addDefUses
authorPetar Avramovic <Petar.Avramovic@rt-rk.com>
Thu, 11 Jul 2019 09:28:34 +0000 (09:28 +0000)
committerPetar Avramovic <Petar.Avramovic@rt-rk.com>
Thu, 11 Jul 2019 09:28:34 +0000 (09:28 +0000)
Skip copies between virtual registers during search for UseDefs
and DefUses.
Since each operand has one def search for UseDefs is straightforward.
But since operand can have many uses, we have to check all uses of
each copy we traverse during search for DefUses.

Differential Revision: https://reviews.llvm.org/D64486

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@365744 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/MipsRegisterBankInfo.cpp
lib/Target/Mips/MipsRegisterBankInfo.h
test/CodeGen/Mips/GlobalISel/regbankselect/TypeInfoforMF_skipCopies.mir [new file with mode: 0644]

index 63cb66416f3997396e4090dbe8668a4700afc17f..d8bcf16afd5035eb0727e41a688f29338cd5eb2d 100644 (file)
@@ -160,12 +160,14 @@ void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addDefUses(
   assert(!MRI.getType(Reg).isPointer() &&
          "Pointers are gprb, they should not be considered as ambiguous.\n");
   for (MachineInstr &UseMI : MRI.use_instructions(Reg)) {
-    if (UseMI.getOpcode() == TargetOpcode::COPY &&
-        !TargetRegisterInfo::isPhysicalRegister(UseMI.getOperand(0).getReg()))
-      // Copies of non-physical registers are not supported
-      return;
-
-    DefUses.push_back(&UseMI);
+    MachineInstr *NonCopyInstr = skipCopiesOutgoing(&UseMI);
+    // Copy with many uses.
+    if (NonCopyInstr->getOpcode() == TargetOpcode::COPY &&
+        !TargetRegisterInfo::isPhysicalRegister(
+            NonCopyInstr->getOperand(0).getReg()))
+      addDefUses(NonCopyInstr->getOperand(0).getReg(), MRI);
+    else
+      DefUses.push_back(skipCopiesOutgoing(&UseMI));
   }
 }
 
@@ -174,12 +176,33 @@ void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addUseDef(
   assert(!MRI.getType(Reg).isPointer() &&
          "Pointers are gprb, they should not be considered as ambiguous.\n");
   MachineInstr *DefMI = MRI.getVRegDef(Reg);
-  if (DefMI->getOpcode() == TargetOpcode::COPY &&
-      !TargetRegisterInfo::isPhysicalRegister(DefMI->getOperand(1).getReg()))
-    // Copies from non-physical registers are not supported.
-    return;
+  UseDefs.push_back(skipCopiesIncoming(DefMI));
+}
+
+MachineInstr *
+MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesOutgoing(
+    MachineInstr *MI) const {
+  const MachineFunction &MF = *MI->getParent()->getParent();
+  const MachineRegisterInfo &MRI = MF.getRegInfo();
+  MachineInstr *Ret = MI;
+  while (Ret->getOpcode() == TargetOpcode::COPY &&
+         !TargetRegisterInfo::isPhysicalRegister(Ret->getOperand(0).getReg()) &&
+         MRI.hasOneUse(Ret->getOperand(0).getReg())) {
+    Ret = &(*MRI.use_instr_begin(Ret->getOperand(0).getReg()));
+  }
+  return Ret;
+}
 
-  UseDefs.push_back(DefMI);
+MachineInstr *
+MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesIncoming(
+    MachineInstr *MI) const {
+  const MachineFunction &MF = *MI->getParent()->getParent();
+  const MachineRegisterInfo &MRI = MF.getRegInfo();
+  MachineInstr *Ret = MI;
+  while (Ret->getOpcode() == TargetOpcode::COPY &&
+         !TargetRegisterInfo::isPhysicalRegister(Ret->getOperand(1).getReg()))
+    Ret = MRI.getVRegDef(Ret->getOperand(1).getReg());
+  return Ret;
 }
 
 MipsRegisterBankInfo::AmbiguousRegDefUseContainer::AmbiguousRegDefUseContainer(
index 704d40a6b1010bf5f1b5b738938617218f2ce47a..176813c031ed09551dd97a958d6e7d17564ff8e4 100644 (file)
@@ -73,6 +73,20 @@ private:
     void addDefUses(Register Reg, const MachineRegisterInfo &MRI);
     void addUseDef(Register Reg, const MachineRegisterInfo &MRI);
 
+    /// Skip copy instructions until we get to a non-copy instruction or to a
+    /// copy with phys register as def. Used during search for DefUses.
+    /// MI :  %5 = COPY %4
+    ///       %6 = COPY %5
+    ///       $v0 = COPY %6 <- we want this one.
+    MachineInstr *skipCopiesOutgoing(MachineInstr *MI) const;
+
+    /// Skip copy instructions until we get to a non-copy instruction or to a
+    /// copy with phys register as use. Used during search for UseDefs.
+    ///       %1 = COPY $a1 <- we want this one.
+    ///       %2 = COPY %1
+    /// MI =  %3 = COPY %2
+    MachineInstr *skipCopiesIncoming(MachineInstr *MI) const;
+
   public:
     AmbiguousRegDefUseContainer(const MachineInstr *MI);
     SmallVectorImpl<MachineInstr *> &getDefUses() { return DefUses; }
diff --git a/test/CodeGen/Mips/GlobalISel/regbankselect/TypeInfoforMF_skipCopies.mir b/test/CodeGen/Mips/GlobalISel/regbankselect/TypeInfoforMF_skipCopies.mir
new file mode 100644 (file)
index 0000000..284cf74
--- /dev/null
@@ -0,0 +1,82 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -O0 -mtriple=mipsel-linux-gnu -run-pass=regbankselect -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32
+--- |
+
+  define void @skipCopiesOutgoing(float* %ptr_a, float* %ptr_b, float* %ptr_c) {entry: ret void}
+  define void @skipCopiesIncoming(float* %float_ptr) {entry: ret void}
+
+...
+---
+name:            skipCopiesOutgoing
+alignment:       2
+legalized:       true
+tracksRegLiveness: true
+body:             |
+  bb.1.entry:
+    liveins: $a0, $a1, $a2
+
+    ; MIPS32-LABEL: name: skipCopiesOutgoing
+    ; MIPS32: liveins: $a0, $a1, $a2
+    ; MIPS32: [[COPY:%[0-9]+]]:gprb(p0) = COPY $a0
+    ; MIPS32: [[COPY1:%[0-9]+]]:gprb(p0) = COPY $a1
+    ; MIPS32: [[COPY2:%[0-9]+]]:gprb(p0) = COPY $a2
+    ; MIPS32: [[LOAD:%[0-9]+]]:fprb(s32) = G_LOAD [[COPY]](p0) :: (load 4 from %ir.ptr_a)
+    ; MIPS32: [[COPY3:%[0-9]+]]:fprb(s32) = COPY [[LOAD]](s32)
+    ; MIPS32: G_STORE [[COPY3]](s32), [[COPY1]](p0) :: (store 4 into %ir.ptr_b)
+    ; MIPS32: [[COPY4:%[0-9]+]]:fprb(s32) = COPY [[COPY3]](s32)
+    ; MIPS32: G_STORE [[COPY4]](s32), [[COPY2]](p0) :: (store 4 into %ir.ptr_c)
+    ; MIPS32: $f0 = COPY [[COPY4]](s32)
+    ; MIPS32: RetRA implicit $f0
+    %0:_(p0) = COPY $a0
+    %1:_(p0) = COPY $a1
+    %2:_(p0) = COPY $a2
+    %3:_(s32) = G_LOAD %0(p0) :: (load 4 from %ir.ptr_a)
+    %4:_(s32) = COPY %3(s32)
+    G_STORE %4(s32), %1(p0) :: (store 4 into %ir.ptr_b)
+    %5:_(s32) = COPY %4(s32)
+    G_STORE %5(s32), %2(p0) :: (store 4 into %ir.ptr_c)
+    $f0 = COPY %5(s32)
+    RetRA implicit $f0
+
+...
+---
+name:            skipCopiesIncoming
+alignment:       2
+legalized:       true
+tracksRegLiveness: true
+body:             |
+  bb.1.entry:
+    liveins: $a2, $a3, $f12, $f14
+
+    ; MIPS32-LABEL: name: skipCopiesIncoming
+    ; MIPS32: liveins: $a2, $a3, $f12, $f14
+    ; MIPS32: [[COPY:%[0-9]+]]:fprb(s32) = COPY $f12
+    ; MIPS32: [[COPY1:%[0-9]+]]:fprb(s32) = COPY $f14
+    ; MIPS32: [[COPY2:%[0-9]+]]:gprb(p0) = COPY $a2
+    ; MIPS32: [[COPY3:%[0-9]+]]:gprb(s32) = COPY $a3
+    ; MIPS32: [[LOAD:%[0-9]+]]:fprb(s32) = G_LOAD [[COPY2]](p0) :: (load 4 from %ir.float_ptr)
+    ; MIPS32: [[FADD:%[0-9]+]]:fprb(s32) = G_FADD [[COPY1]], [[COPY]]
+    ; MIPS32: [[COPY4:%[0-9]+]]:fprb(s32) = COPY [[FADD]](s32)
+    ; MIPS32: [[C:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 1
+    ; MIPS32: [[COPY5:%[0-9]+]]:gprb(s32) = COPY [[COPY3]](s32)
+    ; MIPS32: [[AND:%[0-9]+]]:gprb(s32) = G_AND [[COPY5]], [[C]]
+    ; MIPS32: [[COPY6:%[0-9]+]]:fprb(s32) = COPY [[COPY4]](s32)
+    ; MIPS32: [[SELECT:%[0-9]+]]:fprb(s32) = G_SELECT [[AND]](s32), [[LOAD]], [[COPY6]]
+    ; MIPS32: $f0 = COPY [[SELECT]](s32)
+    ; MIPS32: RetRA implicit $f0
+    %0:_(s32) = COPY $f12
+    %1:_(s32) = COPY $f14
+    %2:_(p0) = COPY $a2
+    %4:_(s32) = COPY $a3
+    %5:_(s32) = G_LOAD %2(p0) :: (load 4 from %ir.float_ptr)
+    %6:_(s32) = G_FADD %1, %0
+    %11:_(s32) = COPY %6(s32)
+    %9:_(s32) = G_CONSTANT i32 1
+    %10:_(s32) = COPY %4(s32)
+    %8:_(s32) = G_AND %10, %9
+    %12:_(s32) = COPY %11(s32)
+    %7:_(s32) = G_SELECT %8(s32), %5, %12
+    $f0 = COPY %7(s32)
+    RetRA implicit $f0
+
+...