Index: lib/Target/SystemZ/SystemZRegisterInfo.h =================================================================== --- lib/Target/SystemZ/SystemZRegisterInfo.h +++ lib/Target/SystemZ/SystemZRegisterInfo.h @@ -42,6 +42,13 @@ return &SystemZ::ADDR64BitRegClass; } + void getRegAllocationHints(unsigned VirtReg, + ArrayRef Order, + SmallVectorImpl &Hints, + const MachineFunction &MF, + const VirtRegMap *VRM, + const LiveRegMatrix *Matrix) const override; + // Override TargetRegisterInfo.h. bool requiresRegisterScavenging(const MachineFunction &MF) const override { return true; Index: lib/Target/SystemZ/SystemZRegisterInfo.cpp =================================================================== --- lib/Target/SystemZ/SystemZRegisterInfo.cpp +++ lib/Target/SystemZ/SystemZRegisterInfo.cpp @@ -22,6 +22,59 @@ SystemZRegisterInfo::SystemZRegisterInfo() : SystemZGenRegisterInfo(SystemZ::R14D) {} +void +SystemZRegisterInfo::getRegAllocationHints(unsigned VirtReg, + ArrayRef Order, + SmallVectorImpl &Hints, + const MachineFunction &MF, + const VirtRegMap *VRM, + const LiveRegMatrix *Matrix) const { + const MachineRegisterInfo *MRI = &MF.getRegInfo(); + const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); + + // Hint all physregs that are connected with VirtReg via COPYs. + const TargetRegisterClass *RC = MRI->getRegClass(VirtReg); + for (auto &Use : MRI->use_instructions(VirtReg)) { + if (Use.isCopy()) { + unsigned PhysReg = 0; + MachineOperand &DstMO = Use.getOperand(0); + MachineOperand &SrcMO = Use.getOperand(1); + MachineOperand *VirtRegMO = nullptr; + // Get the connected physreg, if any. + if (TRI->isPhysicalRegister(DstMO.getReg())) { + PhysReg = DstMO.getReg(); + if (DstMO.getSubReg()) + PhysReg = TRI->getSubReg(PhysReg, DstMO.getSubReg()); + VirtRegMO = &SrcMO; + } else if (TRI->isPhysicalRegister(SrcMO.getReg())) { + PhysReg = SrcMO.getReg(); + if (SrcMO.getSubReg()) + PhysReg = TRI->getSubReg(PhysReg, SrcMO.getSubReg()); + VirtRegMO = &DstMO; + } + if (!PhysReg) + continue; + + if (RC->contains(PhysReg)) { + if (!MRI->isReserved(PhysReg)) + Hints.push_back(PhysReg); + continue; + } + + // Check if the subreg index match so that a super register of PhysReg + // could be hinted. + if (VirtRegMO->getSubReg() != SystemZ::NoSubRegister) { + if (unsigned SuperReg = + TRI->getMatchingSuperReg(PhysReg, VirtRegMO->getSubReg(), RC)) + if (!MRI->isReserved(SuperReg)) + Hints.push_back(SuperReg); + } + } + } + + TargetRegisterInfo::getRegAllocationHints(VirtReg, Order, Hints, MF, VRM); +} + const MCPhysReg * SystemZRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { if (MF->getSubtarget().getTargetLowering()->supportSwiftError() && Index: test/CodeGen/SystemZ/call-args-coalesce.mir =================================================================== --- /dev/null +++ test/CodeGen/SystemZ/call-args-coalesce.mir @@ -0,0 +1,45 @@ +# RUN: llc -mtriple=s390x-linux-gnu -start-before=greedy %s -o - | FileCheck %s +# Test that %r2d is copied directly to %r1d + +--- | + + define void @f5(void (i32, i32, i32, i32)* %foo) { + tail call void %foo(i32 1, i32 2, i32 3, i32 4) + ret void + } + + ; Function Attrs: nounwind + declare void @llvm.stackprotector(i8*, i8**) #0 + + attributes #0 = { nounwind } + +... + +# CHECK: lgr %r1, %r2 +# CHECK-NOT: lgr + +--- +name: f5 +alignment: 2 +tracksRegLiveness: true +registers: + - { id: 0, class: gr64bit } + - { id: 1, class: gr32bit } + - { id: 2, class: gr32bit } + - { id: 3, class: gr32bit } + - { id: 4, class: gr32bit } +liveins: + - { reg: '%r2d', virtual-reg: '%0' } +body: | + bb.0 (%ir-block.0): + liveins: %r2d + + %0 = COPY %r2d + %r2l = LHI 1 + %r3l = LHI 2 + %r4l = LHI 3 + %r5l = LHI 4 + %r1d = COPY %0 + CallBR csr_systemz, implicit %r1d, implicit %r2l, implicit killed %r3l, implicit killed %r4l, implicit killed %r5l + +...