Skip to content

Commit 710a4c1

Browse files
committedJan 20, 2017
CodeGen: Add/Factor out LiveRegUnits class; NFCI
This is a set of register units intended to track register liveness, it is similar in spirit to LivePhysRegs. You can also think of this as the liveness tracking parts of the RegisterScavenger factored out into an own class. This was proposed in http://llvm.org/PR27609 Differential Revision: http://reviews.llvm.org/D21916 llvm-svn: 292542
1 parent d1e211a commit 710a4c1

File tree

5 files changed

+228
-67
lines changed

5 files changed

+228
-67
lines changed
 
+116
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
//===- llvm/CodeGen/LiveRegUnits.h - Register Unit Set ----------*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
//
10+
/// \file
11+
/// A set of register units. It is intended for register liveness tracking.
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
#ifndef LLVM_CODEGEN_LIVEREGUNITS_H
16+
#define LLVM_CODEGEN_LIVEREGUNITS_H
17+
18+
#include "llvm/ADT/BitVector.h"
19+
#include "llvm/Target/TargetRegisterInfo.h"
20+
21+
namespace llvm {
22+
23+
class MachineInstr;
24+
class MachineBasicBlock;
25+
26+
/// A set of register units used to track register liveness.
27+
class LiveRegUnits {
28+
const TargetRegisterInfo *TRI;
29+
BitVector Units;
30+
31+
public:
32+
/// Constructs a new empty LiveRegUnits set.
33+
LiveRegUnits() : TRI(nullptr) {}
34+
35+
/// Constructs and initialize an empty LiveRegUnits set.
36+
LiveRegUnits(const TargetRegisterInfo &TRI) {
37+
init(TRI);
38+
}
39+
40+
/// Initialize and clear the set.
41+
void init(const TargetRegisterInfo &TRI) {
42+
this->TRI = &TRI;
43+
Units.reset();
44+
Units.resize(TRI.getNumRegUnits());
45+
}
46+
47+
/// Clears the set.
48+
void clear() { Units.reset(); }
49+
50+
/// Returns true if the set is empty.
51+
bool empty() const { return Units.empty(); }
52+
53+
/// Adds register units covered by physical register \p Reg.
54+
void addReg(unsigned Reg) {
55+
for (MCRegUnitIterator Unit(Reg, TRI); Unit.isValid(); ++Unit)
56+
Units.set(*Unit);
57+
}
58+
59+
/// \brief Adds register units covered by physical register \p Reg that are
60+
/// part of the lanemask \p Mask.
61+
void addRegMasked(unsigned Reg, LaneBitmask Mask) {
62+
for (MCRegUnitMaskIterator Unit(Reg, TRI); Unit.isValid(); ++Unit) {
63+
LaneBitmask UnitMask = (*Unit).second;
64+
if (UnitMask.none() || (UnitMask & Mask).any())
65+
Units.set((*Unit).first);
66+
}
67+
}
68+
69+
/// Removes all register units covered by physical register \p Reg.
70+
void removeReg(unsigned Reg) {
71+
for (MCRegUnitIterator Unit(Reg, TRI); Unit.isValid(); ++Unit)
72+
Units.reset(*Unit);
73+
}
74+
75+
/// Removes register units not preserved by the regmask \p RegMask.
76+
/// The regmask has the same format as the one in the RegMask machine operand.
77+
void removeRegsNotPreserved(const uint32_t *RegMask);
78+
79+
/// Returns true if no part of physical register \p Reg is live.
80+
bool available(unsigned Reg) const {
81+
for (MCRegUnitIterator Unit(Reg, TRI); Unit.isValid(); ++Unit) {
82+
if (Units.test(*Unit))
83+
return false;
84+
}
85+
return true;
86+
}
87+
88+
/// Updates liveness when stepping backwards over the instruction \p MI.
89+
void stepBackward(const MachineInstr &MI);
90+
91+
/// Adds registers living out of block \p MBB.
92+
/// Live out registers are the union of the live-in registers of the successor
93+
/// blocks and pristine registers. Live out registers of the end block are the
94+
/// callee saved registers.
95+
void addLiveOuts(const MachineBasicBlock &MBB);
96+
97+
/// Adds registers living into block \p MBB.
98+
void addLiveIns(const MachineBasicBlock &MBB);
99+
100+
/// Adds all register units marked in the bitvector \p RegUnits.
101+
void addUnits(const BitVector &RegUnits) {
102+
Units |= RegUnits;
103+
}
104+
/// Removes all register units marked in the bitvector \p RegUnits.
105+
void removeUnits(const BitVector &RegUnits) {
106+
Units.reset(RegUnits);
107+
}
108+
/// Return the internal bitvector representation of the set.
109+
const BitVector &getBitVector() const {
110+
return Units;
111+
}
112+
};
113+
114+
} // namespace llvm
115+
116+
#endif

‎llvm/include/llvm/CodeGen/RegisterScavenging.h

+6-8
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#define LLVM_CODEGEN_REGISTERSCAVENGING_H
2020

2121
#include "llvm/ADT/BitVector.h"
22+
#include "llvm/CodeGen/LiveRegUnits.h"
2223
#include "llvm/CodeGen/MachineBasicBlock.h"
2324
#include "llvm/CodeGen/MachineRegisterInfo.h"
2425

@@ -58,10 +59,7 @@ class RegScavenger {
5859
/// A vector of information on scavenged registers.
5960
SmallVector<ScavengedInfo, 2> Scavenged;
6061

61-
/// The current state of each reg unit immediately before MBBI.
62-
/// One bit per register unit. If bit is not set it means any
63-
/// register containing that register unit is currently being used.
64-
BitVector RegUnitsAvailable;
62+
LiveRegUnits LiveUnits;
6563

6664
// These BitVectors are only used internally to forward(). They are members
6765
// to avoid frequent reallocations.
@@ -171,11 +169,11 @@ class RegScavenger {
171169

172170
/// setUsed / setUnused - Mark the state of one or a number of register units.
173171
///
174-
void setUsed(BitVector &RegUnits) {
175-
RegUnitsAvailable.reset(RegUnits);
172+
void setUsed(const BitVector &RegUnits) {
173+
LiveUnits.addUnits(RegUnits);
176174
}
177-
void setUnused(BitVector &RegUnits) {
178-
RegUnitsAvailable |= RegUnits;
175+
void setUnused(const BitVector &RegUnits) {
176+
LiveUnits.removeUnits(RegUnits);
179177
}
180178

181179
/// Processes the current instruction and fill the KillRegUnits and

‎llvm/lib/CodeGen/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ add_llvm_library(LLVMCodeGen
4646
LiveRangeCalc.cpp
4747
LiveRangeEdit.cpp
4848
LiveRegMatrix.cpp
49+
LiveRegUnits.cpp
4950
LiveStackAnalysis.cpp
5051
LiveVariables.cpp
5152
LLVMTargetMachine.cpp

‎llvm/lib/CodeGen/LiveRegUnits.cpp

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
//===--- LiveRegUnits.cpp - Register Unit Set -----------------------------===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
//
10+
/// \file This file imlements the LiveRegUnits set.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#include "llvm/CodeGen/LiveRegUnits.h"
15+
#include "llvm/CodeGen/MachineFrameInfo.h"
16+
#include "llvm/CodeGen/MachineFunction.h"
17+
#include "llvm/CodeGen/MachineInstrBundle.h"
18+
using namespace llvm;
19+
20+
void LiveRegUnits::removeRegsNotPreserved(const uint32_t *RegMask) {
21+
for (unsigned U = 0, E = TRI->getNumRegUnits(); U != E; ++U) {
22+
for (MCRegUnitRootIterator RootReg(U, TRI); RootReg.isValid(); ++RootReg) {
23+
if (MachineOperand::clobbersPhysReg(RegMask, *RootReg))
24+
Units.reset(U);
25+
}
26+
}
27+
}
28+
29+
void LiveRegUnits::stepBackward(const MachineInstr &MI) {
30+
// Remove defined registers and regmask kills from the set.
31+
for (ConstMIBundleOperands O(MI); O.isValid(); ++O) {
32+
if (O->isReg()) {
33+
if (!O->isDef())
34+
continue;
35+
unsigned Reg = O->getReg();
36+
if (!TargetRegisterInfo::isPhysicalRegister(Reg))
37+
continue;
38+
removeReg(Reg);
39+
} else if (O->isRegMask())
40+
removeRegsNotPreserved(O->getRegMask());
41+
}
42+
43+
// Add uses to the set.
44+
for (ConstMIBundleOperands O(MI); O.isValid(); ++O) {
45+
if (!O->isReg() || !O->readsReg())
46+
continue;
47+
unsigned Reg = O->getReg();
48+
if (!TargetRegisterInfo::isPhysicalRegister(Reg))
49+
continue;
50+
addReg(Reg);
51+
}
52+
}
53+
54+
/// Add live-in registers of basic block \p MBB to \p LiveUnits.
55+
static void addLiveIns(LiveRegUnits &LiveUnits, const MachineBasicBlock &MBB) {
56+
for (const auto &LI : MBB.liveins())
57+
LiveUnits.addRegMasked(LI.PhysReg, LI.LaneMask);
58+
}
59+
60+
static void addLiveOuts(LiveRegUnits &LiveUnits, const MachineBasicBlock &MBB) {
61+
// To get the live-outs we simply merge the live-ins of all successors.
62+
for (const MachineBasicBlock *Succ : MBB.successors())
63+
addLiveIns(LiveUnits, *Succ);
64+
}
65+
66+
/// Add pristine registers to the given \p LiveUnits. This function removes
67+
/// actually saved callee save registers when \p InPrologueEpilogue is false.
68+
static void removeSavedRegs(LiveRegUnits &LiveUnits, const MachineFunction &MF,
69+
const MachineFrameInfo &MFI,
70+
const TargetRegisterInfo &TRI) {
71+
for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo())
72+
LiveUnits.removeReg(Info.getReg());
73+
}
74+
75+
void LiveRegUnits::addLiveOuts(const MachineBasicBlock &MBB) {
76+
const MachineFunction &MF = *MBB.getParent();
77+
const MachineFrameInfo &MFI = MF.getFrameInfo();
78+
if (MFI.isCalleeSavedInfoValid()) {
79+
for (const MCPhysReg *I = TRI->getCalleeSavedRegs(&MF); *I; ++I)
80+
addReg(*I);
81+
if (!MBB.isReturnBlock())
82+
removeSavedRegs(*this, MF, MFI, *TRI);
83+
}
84+
::addLiveOuts(*this, MBB);
85+
}
86+
87+
void LiveRegUnits::addLiveIns(const MachineBasicBlock &MBB) {
88+
const MachineFunction &MF = *MBB.getParent();
89+
const MachineFrameInfo &MFI = MF.getFrameInfo();
90+
if (MFI.isCalleeSavedInfoValid()) {
91+
for (const MCPhysReg *I = TRI->getCalleeSavedRegs(&MF); *I; ++I)
92+
addReg(*I);
93+
if (&MBB != &MF.front())
94+
removeSavedRegs(*this, MF, MFI, *TRI);
95+
}
96+
::addLiveIns(*this, MBB);
97+
}

‎llvm/lib/CodeGen/RegisterScavenging.cpp

+8-59
Original file line numberDiff line numberDiff line change
@@ -32,26 +32,22 @@ using namespace llvm;
3232
#define DEBUG_TYPE "reg-scavenging"
3333

3434
void RegScavenger::setRegUsed(unsigned Reg, LaneBitmask LaneMask) {
35-
for (MCRegUnitMaskIterator RUI(Reg, TRI); RUI.isValid(); ++RUI) {
36-
LaneBitmask UnitMask = (*RUI).second;
37-
if (UnitMask.none() || (LaneMask & UnitMask).any())
38-
RegUnitsAvailable.reset((*RUI).first);
39-
}
35+
LiveUnits.addRegMasked(Reg, LaneMask);
4036
}
4137

4238
void RegScavenger::init(MachineBasicBlock &MBB) {
4339
MachineFunction &MF = *MBB.getParent();
4440
TII = MF.getSubtarget().getInstrInfo();
4541
TRI = MF.getSubtarget().getRegisterInfo();
4642
MRI = &MF.getRegInfo();
43+
LiveUnits.init(*TRI);
4744

4845
assert((NumRegUnits == 0 || NumRegUnits == TRI->getNumRegUnits()) &&
4946
"Target changed?");
5047

5148
// Self-initialize.
5249
if (!this->MBB) {
5350
NumRegUnits = TRI->getNumRegUnits();
54-
RegUnitsAvailable.resize(NumRegUnits);
5551
KillRegUnits.resize(NumRegUnits);
5652
DefRegUnits.resize(NumRegUnits);
5753
TmpRegUnits.resize(NumRegUnits);
@@ -64,32 +60,17 @@ void RegScavenger::init(MachineBasicBlock &MBB) {
6460
I->Restore = nullptr;
6561
}
6662

67-
// All register units start out unused.
68-
RegUnitsAvailable.set();
69-
70-
// Pristine CSRs are not available.
71-
BitVector PR = MF.getFrameInfo().getPristineRegs(MF);
72-
for (int I = PR.find_first(); I>0; I = PR.find_next(I))
73-
setRegUsed(I);
74-
7563
Tracking = false;
7664
}
7765

78-
void RegScavenger::setLiveInsUsed(const MachineBasicBlock &MBB) {
79-
for (const auto &LI : MBB.liveins())
80-
setRegUsed(LI.PhysReg, LI.LaneMask);
81-
}
82-
8366
void RegScavenger::enterBasicBlock(MachineBasicBlock &MBB) {
8467
init(MBB);
85-
setLiveInsUsed(MBB);
68+
LiveUnits.addLiveIns(MBB);
8669
}
8770

8871
void RegScavenger::enterBasicBlockEnd(MachineBasicBlock &MBB) {
8972
init(MBB);
90-
// Merge live-ins of successors to get live-outs.
91-
for (const MachineBasicBlock *Succ : MBB.successors())
92-
setLiveInsUsed(*Succ);
73+
LiveUnits.addLiveOuts(MBB);
9374

9475
// Move internal iterator at the last instruction of the block.
9576
if (MBB.begin() != MBB.end()) {
@@ -263,36 +244,7 @@ void RegScavenger::backward() {
263244
assert(Tracking && "Must be tracking to determine kills and defs");
264245

265246
const MachineInstr &MI = *MBBI;
266-
// Defined or clobbered registers are available now.
267-
for (const MachineOperand &MO : MI.operands()) {
268-
if (MO.isRegMask()) {
269-
for (unsigned RU = 0, RUEnd = TRI->getNumRegUnits(); RU != RUEnd;
270-
++RU) {
271-
for (MCRegUnitRootIterator RURI(RU, TRI); RURI.isValid(); ++RURI) {
272-
if (MO.clobbersPhysReg(*RURI)) {
273-
RegUnitsAvailable.set(RU);
274-
break;
275-
}
276-
}
277-
}
278-
} else if (MO.isReg() && MO.isDef()) {
279-
unsigned Reg = MO.getReg();
280-
if (!Reg || TargetRegisterInfo::isVirtualRegister(Reg) ||
281-
isReserved(Reg))
282-
continue;
283-
addRegUnits(RegUnitsAvailable, Reg);
284-
}
285-
}
286-
// Mark read registers as unavailable.
287-
for (const MachineOperand &MO : MI.uses()) {
288-
if (MO.isReg() && MO.readsReg()) {
289-
unsigned Reg = MO.getReg();
290-
if (!Reg || TargetRegisterInfo::isVirtualRegister(Reg) ||
291-
isReserved(Reg))
292-
continue;
293-
removeRegUnits(RegUnitsAvailable, Reg);
294-
}
295-
}
247+
LiveUnits.stepBackward(MI);
296248

297249
if (MBBI == MBB->begin()) {
298250
MBBI = MachineBasicBlock::iterator(nullptr);
@@ -302,12 +254,9 @@ void RegScavenger::backward() {
302254
}
303255

304256
bool RegScavenger::isRegUsed(unsigned Reg, bool includeReserved) const {
305-
if (includeReserved && isReserved(Reg))
306-
return true;
307-
for (MCRegUnitIterator RUI(Reg, TRI); RUI.isValid(); ++RUI)
308-
if (!RegUnitsAvailable.test(*RUI))
309-
return true;
310-
return false;
257+
if (isReserved(Reg))
258+
return includeReserved;
259+
return !LiveUnits.available(Reg);
311260
}
312261

313262
unsigned RegScavenger::FindUnusedReg(const TargetRegisterClass *RC) const {

0 commit comments

Comments
 (0)
Please sign in to comment.