1 //=== LoongArchDeadRegisterDefinitions.cpp - Replace dead defs w/ zero reg ===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===---------------------------------------------------------------------===//
9 // This pass rewrites Rd to r0 for instrs whose return values are unused.
11 //===---------------------------------------------------------------------===//
13 #include "LoongArch.h"
14 #include "LoongArchSubtarget.h"
15 #include "llvm/ADT/Statistic.h"
16 #include "llvm/CodeGen/LiveDebugVariables.h"
17 #include "llvm/CodeGen/LiveIntervals.h"
18 #include "llvm/CodeGen/LiveStacks.h"
19 #include "llvm/CodeGen/MachineFunctionPass.h"
22 #define DEBUG_TYPE "loongarch-dead-defs"
23 #define LoongArch_DEAD_REG_DEF_NAME "LoongArch Dead register definitions"
25 STATISTIC(NumDeadDefsReplaced
, "Number of dead definitions replaced");
28 class LoongArchDeadRegisterDefinitions
: public MachineFunctionPass
{
32 LoongArchDeadRegisterDefinitions() : MachineFunctionPass(ID
) {}
33 bool runOnMachineFunction(MachineFunction
&MF
) override
;
34 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
36 AU
.addRequired
<LiveIntervalsWrapperPass
>();
37 AU
.addPreserved
<LiveIntervalsWrapperPass
>();
38 AU
.addRequired
<LiveIntervalsWrapperPass
>();
39 AU
.addPreserved
<SlotIndexesWrapperPass
>();
40 AU
.addPreserved
<LiveDebugVariables
>();
41 AU
.addPreserved
<LiveStacks
>();
42 MachineFunctionPass::getAnalysisUsage(AU
);
45 StringRef
getPassName() const override
{ return LoongArch_DEAD_REG_DEF_NAME
; }
47 } // end anonymous namespace
49 char LoongArchDeadRegisterDefinitions::ID
= 0;
50 INITIALIZE_PASS(LoongArchDeadRegisterDefinitions
, DEBUG_TYPE
,
51 LoongArch_DEAD_REG_DEF_NAME
, false, false)
53 FunctionPass
*llvm::createLoongArchDeadRegisterDefinitionsPass() {
54 return new LoongArchDeadRegisterDefinitions();
57 bool LoongArchDeadRegisterDefinitions::runOnMachineFunction(
58 MachineFunction
&MF
) {
59 if (skipFunction(MF
.getFunction()))
62 const TargetInstrInfo
*TII
= MF
.getSubtarget().getInstrInfo();
63 const TargetRegisterInfo
*TRI
= MF
.getSubtarget().getRegisterInfo();
64 LiveIntervals
&LIS
= getAnalysis
<LiveIntervalsWrapperPass
>().getLIS();
65 LLVM_DEBUG(dbgs() << "***** LoongArchDeadRegisterDefinitions *****\n");
67 bool MadeChange
= false;
68 for (MachineBasicBlock
&MBB
: MF
) {
69 for (MachineInstr
&MI
: MBB
) {
70 // We only handle non-computational instructions.
71 const MCInstrDesc
&Desc
= MI
.getDesc();
72 if (!Desc
.mayLoad() && !Desc
.mayStore() &&
73 !Desc
.hasUnmodeledSideEffects())
75 for (int I
= 0, E
= Desc
.getNumDefs(); I
!= E
; ++I
) {
76 MachineOperand
&MO
= MI
.getOperand(I
);
77 if (!MO
.isReg() || !MO
.isDef() || MO
.isEarlyClobber())
79 // Be careful not to change the register if it's a tied operand.
80 if (MI
.isRegTiedToUseOperand(I
)) {
81 LLVM_DEBUG(dbgs() << " Ignoring, def is tied operand.\n");
84 Register Reg
= MO
.getReg();
85 if (!Reg
.isVirtual() || !MO
.isDead())
87 LLVM_DEBUG(dbgs() << " Dead def operand #" << I
<< " in:\n ";
89 const TargetRegisterClass
*RC
= TII
->getRegClass(Desc
, I
, TRI
, MF
);
90 if (!(RC
&& RC
->contains(LoongArch::R0
))) {
91 LLVM_DEBUG(dbgs() << " Ignoring, register is not a GPR.\n");
94 assert(LIS
.hasInterval(Reg
));
95 LIS
.removeInterval(Reg
);
96 MO
.setReg(LoongArch::R0
);
97 LLVM_DEBUG(dbgs() << " Replacing with zero register. New:\n ";
99 ++NumDeadDefsReplaced
;