Index: llvm/trunk/lib/Target/Mips/MipsRegisterBankInfo.h =================================================================== --- llvm/trunk/lib/Target/Mips/MipsRegisterBankInfo.h +++ llvm/trunk/lib/Target/Mips/MipsRegisterBankInfo.h @@ -73,6 +73,20 @@ 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 &getDefUses() { return DefUses; } Index: llvm/trunk/lib/Target/Mips/MipsRegisterBankInfo.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/MipsRegisterBankInfo.cpp +++ llvm/trunk/lib/Target/Mips/MipsRegisterBankInfo.cpp @@ -160,12 +160,14 @@ 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 @@ 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)); +} - UseDefs.push_back(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; +} + +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: llvm/trunk/test/CodeGen/Mips/GlobalISel/regbankselect/TypeInfoforMF_skipCopies.mir =================================================================== --- llvm/trunk/test/CodeGen/Mips/GlobalISel/regbankselect/TypeInfoforMF_skipCopies.mir +++ llvm/trunk/test/CodeGen/Mips/GlobalISel/regbankselect/TypeInfoforMF_skipCopies.mir @@ -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 + +...