1 //===- ReduceRegisterDefs.cpp - Specialized Delta Pass --------------------===//
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 file implements a function which calls the Generic Delta pass in order
10 // to reduce uninteresting register uses from the MachineFunction.
12 //===----------------------------------------------------------------------===//
14 #include "ReduceRegisterDefs.h"
15 #include "llvm/CodeGen/MachineFunction.h"
16 #include "llvm/CodeGen/MachineModuleInfo.h"
17 #include "llvm/CodeGen/MachineRegisterInfo.h"
18 #include "llvm/CodeGen/TargetInstrInfo.h"
22 static void removeDefsFromFunction(Oracle
&O
, MachineFunction
&MF
) {
23 MachineRegisterInfo
&MRI
= MF
.getRegInfo();
24 const TargetSubtargetInfo
&STI
= MF
.getSubtarget();
25 const TargetInstrInfo
*TII
= STI
.getInstrInfo();
27 DenseSet
<MachineOperand
*> KeepDefs
;
28 DenseSet
<TargetInstrInfo::RegSubRegPair
> DeleteDefs
;
30 for (MachineBasicBlock
&MBB
: MF
) {
31 for (MachineBasicBlock::iterator It
= MBB
.begin(),
32 E
= MBB
.getFirstTerminator();
34 MachineBasicBlock::iterator InsPt
= It
;
35 MachineInstr
&MI
= *It
;
41 int NumOperands
= MI
.getNumOperands();
42 int NumRequiredOps
= MI
.getNumExplicitOperands() +
43 MI
.getDesc().implicit_defs().size() +
44 MI
.getDesc().implicit_uses().size();
46 bool HaveDelete
= false;
47 // Do an initial scan in case the instruction defines the same register
49 for (int I
= NumOperands
- 1; I
>= 0; --I
) {
50 MachineOperand
&MO
= MI
.getOperand(I
);
51 if (!MO
.isReg() || !MO
.isDef())
54 TargetInstrInfo::RegSubRegPair
RegPair(MO
.getReg(), MO
.getSubReg());
55 if (!RegPair
.Reg
.isVirtual())
67 bool HaveKeptDef
= !KeepDefs
.empty();
68 for (int I
= NumOperands
- 1; I
>= 0; --I
) {
69 MachineOperand
&MO
= MI
.getOperand(I
);
70 if (!MO
.isReg() || !MO
.isDef())
73 if (KeepDefs
.count(&MO
))
76 TargetInstrInfo::RegSubRegPair
RegPair(MO
.getReg(), MO
.getSubReg());
77 if (!RegPair
.Reg
.isVirtual())
80 if (!DeleteDefs
.insert(RegPair
).second
)
83 if (MRI
.use_empty(RegPair
.Reg
)) {
84 if (I
>= NumRequiredOps
) {
85 // Delete implicit def operands that aren't part of the instruction
93 // If we aren't going to delete the instruction, replace it with a dead
96 MO
.setReg(MRI
.cloneVirtualRegister(MO
.getReg()));
98 bool IsGeneric
= MRI
.getRegClassOrNull(RegPair
.Reg
) == nullptr;
99 unsigned ImpDef
= IsGeneric
? TargetOpcode::G_IMPLICIT_DEF
100 : TargetOpcode::IMPLICIT_DEF
;
102 unsigned OpFlags
= getRegState(MO
) & ~RegState::Implicit
;
103 InsPt
= BuildMI(MBB
, InsPt
, DebugLoc(), TII
->get(ImpDef
))
104 .addReg(RegPair
.Reg
, OpFlags
, RegPair
.SubReg
);
108 MI
.eraseFromParent();
113 static void removeDefsFromModule(Oracle
&O
, ReducerWorkItem
&WorkItem
) {
114 for (const Function
&F
: WorkItem
.getModule()) {
115 if (auto *MF
= WorkItem
.MMI
->getMachineFunction(F
))
116 removeDefsFromFunction(O
, *MF
);
120 void llvm::reduceRegisterDefsMIRDeltaPass(TestRunner
&Test
) {
121 runDeltaPass(Test
, removeDefsFromModule
, "Reducing register defs");