Skip to content

Commit 3555003

Browse files
committed
Update kill of individual instructions
1 parent e2763e3 commit 3555003

File tree

3 files changed

+90
-10
lines changed

3 files changed

+90
-10
lines changed

llvm/lib/Target/RISCV/RISCV.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ void initializeRISCVLoadStoreOptPass(PassRegistry &);
9797
FunctionPass *createRISCVZacasABIFixPass();
9898
void initializeRISCVZacasABIFixPass(PassRegistry &);
9999

100-
FunctionPass *createRISCVLiveVariablesPass();
100+
FunctionPass *createRISCVLiveVariablesPass(bool PreRegAlloc);
101101
void initializeRISCVLiveVariablesPass(PassRegistry &);
102102

103103
InstructionSelector *

llvm/lib/Target/RISCV/RISCVLiveVariables.cpp

Lines changed: 86 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "RISCV.h"
2222
#include "RISCVInstrInfo.h"
2323
#include "RISCVSubtarget.h"
24+
#include "llvm/ADT/BitVector.h"
2425
#include "llvm/ADT/DenseMap.h"
2526
#include "llvm/ADT/PostOrderIterator.h"
2627
#include "llvm/ADT/Statistic.h"
@@ -33,6 +34,8 @@
3334
#include "llvm/Support/Debug.h"
3435
#include "llvm/Support/ErrorHandling.h"
3536
#include "llvm/Support/raw_ostream.h"
37+
38+
#include <unordered_map>
3639
#include <set>
3740

3841
using namespace llvm;
@@ -43,6 +46,10 @@ using namespace llvm;
4346
STATISTIC(NumLiveRegsAtEntry, "Number of registers live at function entry");
4447
STATISTIC(NumLiveRegsTotal, "Total number of live registers across all blocks");
4548

49+
static cl::opt<bool> UpdateKills("riscv-liveness-update-kills",
50+
cl::desc("Update kill flags"), cl::init(false),
51+
cl::Hidden);
52+
4653
namespace {
4754

4855
/// LivenessInfo - Stores liveness information for a basic block
@@ -67,14 +74,14 @@ class RISCVLiveVariables : public MachineFunctionPass {
6774
public:
6875
static char ID;
6976

70-
RISCVLiveVariables() : MachineFunctionPass(ID) {
77+
RISCVLiveVariables(bool PreRegAlloc)
78+
: MachineFunctionPass(ID), PreRegAlloc(PreRegAlloc) {
7179
initializeRISCVLiveVariablesPass(*PassRegistry::getPassRegistry());
7280
}
7381

7482
bool runOnMachineFunction(MachineFunction &MF) override;
7583

7684
void getAnalysisUsage(AnalysisUsage &AU) const override {
77-
AU.setPreservesAll();
7885
MachineFunctionPass::getAnalysisUsage(AU);
7986
}
8087

@@ -102,6 +109,9 @@ class RISCVLiveVariables : public MachineFunctionPass {
102109

103110
void verifyLiveness(MachineFunction &MF) const;
104111

112+
/// Mark operands that kill a register
113+
void markKills(MachineFunction &MF);
114+
105115
private:
106116
/// Compute local liveness information (Use and Def sets) for each block
107117
void computeLocalLiveness(MachineFunction &MF);
@@ -117,6 +127,13 @@ class RISCVLiveVariables : public MachineFunctionPass {
117127
bool isTrackableRegister(Register Reg, const TargetRegisterInfo *TRI,
118128
const MachineRegisterInfo *MRI) const;
119129

130+
bool PreRegAlloc;
131+
unsigned RegCounter = 0;
132+
133+
// PreRA can have large number of registers and basic block
134+
// level liveness may be expensive without a bitvector representation.
135+
std::unordered_map<unsigned, unsigned> TrackedRegisters;
136+
120137
/// Liveness information for each basic block
121138
DenseMap<const MachineBasicBlock *, LivenessInfo> BlockLiveness;
122139

@@ -134,8 +151,8 @@ char RISCVLiveVariables::ID = 0;
134151
INITIALIZE_PASS(RISCVLiveVariables, DEBUG_TYPE, RISCV_LIVE_VARIABLES_NAME,
135152
false, true)
136153

137-
FunctionPass *llvm::createRISCVLiveVariablesPass() {
138-
return new RISCVLiveVariables();
154+
FunctionPass *llvm::createRISCVLiveVariablesPass(bool PreRegAlloc) {
155+
return new RISCVLiveVariables(PreRegAlloc);
139156
}
140157

141158
bool RISCVLiveVariables::isTrackableRegister(
@@ -170,6 +187,8 @@ void RISCVLiveVariables::processInstruction(const MachineInstr &MI,
170187

171188
Register Reg = MO.getReg();
172189

190+
TrackedRegisters.insert(std::pair(Reg, RegCounter++));
191+
173192
// Skip non-trackable registers
174193
if (!isTrackableRegister(Reg, TRI, MRI))
175194
continue;
@@ -277,10 +296,7 @@ void RISCVLiveVariables::computeGlobalLiveness(MachineFunction &MF) {
277296
Changed = false;
278297
++Iterations;
279298

280-
// Process blocks in **post-order** for better convergence
281-
ReversePostOrderTraversal<MachineFunction *> RPOT(&MF);
282-
283-
for (MachineBasicBlock *MBB : RPOT) {
299+
for (MachineBasicBlock *MBB : post_order(&MF)) {
284300
LivenessInfo &Info = BlockLiveness[MBB];
285301
std::set<Register> OldLiveIn = Info.LiveIn;
286302
std::set<Register> NewLiveOut;
@@ -368,6 +384,62 @@ void RISCVLiveVariables::verifyLiveness(MachineFunction &MF) const {
368384
}
369385
}
370386

387+
void RISCVLiveVariables::markKills(MachineFunction &MF) {
388+
auto KillSetSize = PreRegAlloc ? RegCounter : TRI->getNumRegs();
389+
for (MachineBasicBlock *MBB : post_order(&MF)) {
390+
// Set all the registers that are not live-out of the block.
391+
// Since the global liveness is available (even though a bit conservative),
392+
// this initialization is safe.
393+
llvm::BitVector KillSet(KillSetSize, true);
394+
LivenessInfo &Info = BlockLiveness[MBB];
395+
396+
for (Register Reg : Info.LiveOut) {
397+
auto RegIdx = PreRegAlloc ? TrackedRegisters[Reg] : Reg.asMCReg().id();
398+
KillSet.reset(RegIdx);
399+
}
400+
401+
for (MachineInstr &MI : reverse(*MBB)) {
402+
for (MachineOperand &MO : MI.operands()) {
403+
if (!MO.isReg())
404+
continue;
405+
406+
Register Reg = MO.getReg();
407+
// Does not track physical registers pre-regalloc.
408+
if ((PreRegAlloc && Reg.isPhysical()) || !isTrackableRegister(Reg, TRI, MRI))
409+
continue;
410+
411+
assert(TrackedRegisters.find(Reg) != TrackedRegisters.end() &&
412+
"Register not tracked");
413+
auto RegIdx = PreRegAlloc ? TrackedRegisters[Reg] : Reg.asMCReg().id();
414+
415+
if (MO.isDef()) {
416+
KillSet.set(RegIdx);
417+
418+
// Also handle sub-registers for physical registers
419+
if (!PreRegAlloc && Reg.isPhysical()) {
420+
for (MCRegAliasIterator RA(Reg, TRI, true); RA.isValid(); ++RA)
421+
KillSet.set(*RA);
422+
}
423+
continue;
424+
}
425+
426+
// Use.
427+
if (KillSet[RegIdx]) {
428+
if (!MO.isKill() && !MI.isPHI() && !MI.isCall())
429+
MO.setIsKill(true);
430+
LLVM_DEBUG(dbgs() << "Marking kill of " << printReg(Reg, TRI)
431+
<< " at instruction: " << MI);
432+
KillSet.reset(RegIdx);
433+
if (Reg.isPhysical()) {
434+
for (MCRegAliasIterator RA(Reg, TRI, true); RA.isValid(); ++RA)
435+
KillSet.reset(*RA);
436+
}
437+
}
438+
}
439+
}
440+
}
441+
}
442+
371443
bool RISCVLiveVariables::runOnMachineFunction(MachineFunction &MF) {
372444
if (skipFunction(MF.getFunction()) || MF.empty())
373445
return false;
@@ -396,6 +468,12 @@ bool RISCVLiveVariables::runOnMachineFunction(MachineFunction &MF) {
396468
// Step 2: Compute global liveness (LiveIn and LiveOut sets)
397469
computeGlobalLiveness(MF);
398470

471+
// TODO: Update live-in/live-out sets of MBBs
472+
473+
// Step 3: Mark kill flags on operands
474+
if (UpdateKills)
475+
markKills(MF);
476+
399477
LLVM_DEBUG({
400478
dbgs() << "\n***** Final Liveness Information *****\n";
401479
print(dbgs());

llvm/lib/Target/RISCV/RISCVTargetMachine.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,8 @@ void RISCVPassConfig::addPreEmitPass2() {
589589
void RISCVPassConfig::addMachineSSAOptimization() {
590590
addPass(createRISCVVectorPeepholePass());
591591
addPass(createRISCVFoldMemOffsetPass());
592+
if (EnableRISCVLiveVariables)
593+
addPass(createRISCVLiveVariablesPass(true));
592594

593595
TargetPassConfig::addMachineSSAOptimization();
594596

@@ -626,7 +628,7 @@ void RISCVPassConfig::addPostRegAlloc() {
626628
addPass(createRISCVRedundantCopyEliminationPass());
627629

628630
if (EnableRISCVLiveVariables)
629-
addPass(createRISCVLiveVariablesPass());
631+
addPass(createRISCVLiveVariablesPass(false));
630632
}
631633

632634
bool RISCVPassConfig::addILPOpts() {

0 commit comments

Comments
 (0)