diff options
-rw-r--r-- | llvm/lib/CodeGen/LivePhysRegs.cpp | 79 | ||||
-rw-r--r-- | llvm/test/CodeGen/PowerPC/livephysregs.mir | 52 |
2 files changed, 100 insertions, 31 deletions
diff --git a/llvm/lib/CodeGen/LivePhysRegs.cpp b/llvm/lib/CodeGen/LivePhysRegs.cpp index 012ba6cd1a4..317e38ded07 100644 --- a/llvm/lib/CodeGen/LivePhysRegs.cpp +++ b/llvm/lib/CodeGen/LivePhysRegs.cpp @@ -142,61 +142,78 @@ bool LivePhysRegs::available(const MachineRegisterInfo &MRI, /// Add live-in registers of basic block \p MBB to \p LiveRegs. void LivePhysRegs::addBlockLiveIns(const MachineBasicBlock &MBB) { for (const auto &LI : MBB.liveins()) { - MCSubRegIndexIterator S(LI.PhysReg, TRI); - if (LI.LaneMask.all() || (LI.LaneMask.any() && !S.isValid())) { - addReg(LI.PhysReg); + unsigned Reg = LI.PhysReg; + LaneBitmask Mask = LI.LaneMask; + MCSubRegIndexIterator S(Reg, TRI); + assert(Mask.any() && "Invalid livein mask"); + if (Mask.all() || !S.isValid()) { + addReg(Reg); continue; } for (; S.isValid(); ++S) { unsigned SI = S.getSubRegIndex(); - if ((LI.LaneMask & TRI->getSubRegIndexLaneMask(SI)).any()) + if ((Mask & TRI->getSubRegIndexLaneMask(SI)).any()) addReg(S.getSubReg()); } } } -/// Add pristine registers to the given \p LiveRegs. This function removes -/// actually saved callee save registers when \p InPrologueEpilogue is false. -static void addPristines(LivePhysRegs &LiveRegs, const MachineFunction &MF, - const MachineFrameInfo &MFI, - const TargetRegisterInfo &TRI) { +/// Adds all callee saved registers to \p LiveRegs. +static void addCalleeSavedRegs(LivePhysRegs &LiveRegs, + const MachineFunction &MF) { const MachineRegisterInfo &MRI = MF.getRegInfo(); - for (const MCPhysReg *CSR = MRI.getCalleeSavedRegs(); CSR && *CSR; - ++CSR) + for (const MCPhysReg *CSR = MRI.getCalleeSavedRegs(); CSR && *CSR; ++CSR) LiveRegs.addReg(*CSR); +} + +/// Adds pristine registers to the given \p LiveRegs. Pristine registers are +/// callee saved registers that are unused in the function. +static void addPristines(LivePhysRegs &LiveRegs, const MachineFunction &MF) { + const MachineFrameInfo &MFI = MF.getFrameInfo(); + if (!MFI.isCalleeSavedInfoValid()) + return; + /// Add all callee saved regs, then remove the ones that are saved+restored. + addCalleeSavedRegs(LiveRegs, MF); + /// Remove the ones that are not saved/restored; they are pristine. for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo()) LiveRegs.removeReg(Info.getReg()); } void LivePhysRegs::addLiveOutsNoPristines(const MachineBasicBlock &MBB) { - // To get the live-outs we simply merge the live-ins of all successors. - for (const MachineBasicBlock *Succ : MBB.successors()) - addBlockLiveIns(*Succ); + if (!MBB.succ_empty()) { + // To get the live-outs we simply merge the live-ins of all successors. + for (const MachineBasicBlock *Succ : MBB.successors()) + addBlockLiveIns(*Succ); + } else if (MBB.isReturnBlock()) { + // For the return block: Add all callee saved registers that are saved and + // restored (somewhere); This does not include callee saved registers that + // are unused and hence not saved and restored; they are called pristine. + const MachineFunction &MF = *MBB.getParent(); + const MachineFrameInfo &MFI = MF.getFrameInfo(); + if (MFI.isCalleeSavedInfoValid()) { + for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo()) + addReg(Info.getReg()); + } + } } void LivePhysRegs::addLiveOuts(const MachineBasicBlock &MBB) { - const MachineFunction &MF = *MBB.getParent(); - const MachineFrameInfo &MFI = MF.getFrameInfo(); - if (MFI.isCalleeSavedInfoValid()) { - if (MBB.isReturnBlock()) { - // The return block has no successors whose live-ins we could merge - // below. So instead we add the callee saved registers manually. - const MachineRegisterInfo &MRI = MF.getRegInfo(); - for (const MCPhysReg *I = MRI.getCalleeSavedRegs(); *I; ++I) - addReg(*I); - } else { - addPristines(*this, MF, MFI, *TRI); - } + if (!MBB.succ_empty()) { + const MachineFunction &MF = *MBB.getParent(); + addPristines(*this, MF); + addLiveOutsNoPristines(MBB); + } else if (MBB.isReturnBlock()) { + // For the return block: Add all callee saved registers. + const MachineFunction &MF = *MBB.getParent(); + const MachineFrameInfo &MFI = MF.getFrameInfo(); + if (MFI.isCalleeSavedInfoValid()) + addCalleeSavedRegs(*this, MF); } - - addLiveOutsNoPristines(MBB); } void LivePhysRegs::addLiveIns(const MachineBasicBlock &MBB) { const MachineFunction &MF = *MBB.getParent(); - const MachineFrameInfo &MFI = MF.getFrameInfo(); - if (MFI.isCalleeSavedInfoValid()) - addPristines(*this, MF, MFI, *TRI); + addPristines(*this, MF); addBlockLiveIns(MBB); } diff --git a/llvm/test/CodeGen/PowerPC/livephysregs.mir b/llvm/test/CodeGen/PowerPC/livephysregs.mir new file mode 100644 index 00000000000..6b6268778e9 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/livephysregs.mir @@ -0,0 +1,52 @@ +# RUN: llc -o - %s -mtriple=powerpc64le--linux-gnu -run-pass=branch-folder | FileCheck %s +# The branch-folder should merge bb.1 and bb.5 below and therefore recalculate +# the liveins list of the merged block. This test is checking whether this +# recalculated list if okay and contains all the non-saved and saved CSRs. +# CHECK-LABEL: name: func +# CHECK: bb.3: +# CHECK-NEXT: liveins: %x30, %x29, %x3, %x6 +# CHECK: %x4 = RLDICR killed %x6, 16, 47 +# CHECK: %x3 = OR8 killed %x4, killed %x3 +# CHECK: BLR8 implicit %lr8, implicit %rm, implicit %x3 +--- +name: func +tracksRegLiveness: true +fixedStack: + - { id: 0, type: spill-slot, offset: -16, size: 8, alignment: 16, callee-saved-register: '%x30' } + - { id: 1, type: spill-slot, offset: -24, size: 8, alignment: 8, callee-saved-register: '%x29' } + - { id: 2, offset: -8, size: 8, alignment: 8, isImmutable: true, isAliased: false } +body: | + bb.0: + liveins: %x3, %x5, %x29, %x30 + + %x6 = RLWINM8 %x3, 16, 16, 31 + %x3 = RLDICL killed %x3, 0, 48 + BC undef %cr5lt, %bb.3 + + bb.1: + liveins: %x3, %x6, %x29, %x30 + + %x4 = RLDICR killed %x6, 16, 47 + %x3 = OR8 killed %x4, killed %x3 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + + bb.3: + liveins: %x3, %x5, %x6, %x29, %x30 + + dead %x5 = ADD8 %x5, %x6 + BC undef %cr5lt, %bb.1 + + bb.6: + liveins: %x3, %x6, %x29, %x30 + STD killed %x29, -24, %x1 :: (store 8 into %fixed-stack.1) + STD killed %x30, -16, %x1 :: (store 8 into %fixed-stack.0, align 16) + NOP implicit-def dead %x29 + NOP implicit-def dead %x30 + + %x30 = LD -16, %x1 :: (load 8 from %fixed-stack.0, align 16) + %x29 = LD -24, %x1 :: (load 8 from %fixed-stack.1) + + %x4 = RLDICR killed %x6, 16, 47 + %x3 = OR8 killed %x4, killed %x3 + BLR8 implicit %lr8, implicit %rm, implicit %x3 +... |