1 //===- ReduceInstructionsMIR.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 MachineInstr from the MachineFunction.
12 //===----------------------------------------------------------------------===//
14 #include "ReduceInstructionsMIR.h"
17 #include "llvm/ADT/SetVector.h"
18 #include "llvm/CodeGen/MachineDominators.h"
19 #include "llvm/CodeGen/MachineFunction.h"
20 #include "llvm/CodeGen/MachineFunctionPass.h"
21 #include "llvm/CodeGen/MachineModuleInfo.h"
22 #include "llvm/CodeGen/MachineRegisterInfo.h"
23 #include "llvm/CodeGen/TargetInstrInfo.h"
27 static Register
getPrevDefOfRCInMBB(MachineBasicBlock
&MBB
,
28 MachineBasicBlock::reverse_iterator
&RI
,
29 const RegClassOrRegBank
&RC
, LLT Ty
,
30 SetVector
<MachineInstr
*> &ExcludeMIs
) {
31 auto MRI
= &MBB
.getParent()->getRegInfo();
32 for (MachineBasicBlock::reverse_instr_iterator E
= MBB
.instr_rend(); RI
!= E
;
35 // All Def operands explicit and implicit.
36 for (auto &MO
: MI
.operands()) {
37 if (!MO
.isReg() || !MO
.isDef() || MO
.isDead())
39 auto Reg
= MO
.getReg();
43 if (MRI
->getRegClassOrRegBank(Reg
) == RC
&& MRI
->getType(Reg
) == Ty
&&
44 !ExcludeMIs
.count(MO
.getParent()))
51 static bool shouldNotRemoveInstruction(const TargetInstrInfo
&TII
,
52 const MachineInstr
&MI
) {
53 if (MI
.isTerminator())
56 // The MIR is almost certainly going to be invalid if frame instructions are
57 // deleted individually since they need to come in balanced pairs, so don't
58 // try to delete them.
59 if (MI
.getOpcode() == TII
.getCallFrameSetupOpcode() ||
60 MI
.getOpcode() == TII
.getCallFrameDestroyOpcode())
66 static void extractInstrFromFunction(Oracle
&O
, MachineFunction
&MF
) {
67 MachineDominatorTree MDT
;
68 MDT
.runOnMachineFunction(MF
);
70 auto MRI
= &MF
.getRegInfo();
71 SetVector
<MachineInstr
*> ToDelete
;
73 const TargetSubtargetInfo
&STI
= MF
.getSubtarget();
74 const TargetInstrInfo
*TII
= STI
.getInstrInfo();
75 MachineBasicBlock
*EntryMBB
= &*MF
.begin();
76 MachineBasicBlock::iterator EntryInsPt
=
77 EntryMBB
->SkipPHIsLabelsAndDebug(EntryMBB
->begin());
79 // Mark MIs for deletion according to some criteria.
80 for (auto &MBB
: MF
) {
81 for (auto &MI
: MBB
) {
82 if (shouldNotRemoveInstruction(*TII
, MI
))
89 // For each MI to be deleted update users of regs defined by that MI to use
90 // some other dominating definition (that is not to be deleted).
91 for (auto *MI
: ToDelete
) {
92 for (auto &MO
: MI
->operands()) {
93 if (!MO
.isReg() || !MO
.isDef() || MO
.isDead())
95 auto Reg
= MO
.getReg();
98 auto UI
= MRI
->use_begin(Reg
);
99 auto UE
= MRI
->use_end();
101 const auto &RegRC
= MRI
->getRegClassOrRegBank(Reg
);
102 LLT RegTy
= MRI
->getType(Reg
);
105 // If this is not a physical register and there are some uses.
107 MachineBasicBlock::reverse_iterator
RI(*MI
);
108 MachineBasicBlock
*BB
= MI
->getParent();
111 if (MDT
.isReachableFromEntry(BB
)) {
112 while (NewReg
== 0 && BB
) {
113 NewReg
= getPrevDefOfRCInMBB(*BB
, RI
, RegRC
, RegTy
, ToDelete
);
114 // Prepare for idom(BB).
115 if (auto *IDM
= MDT
.getNode(BB
)->getIDom()) {
116 BB
= IDM
->getBlock();
125 // If no dominating definition was found then add an implicit def to the
126 // top of the entry block.
128 NewReg
= MRI
->cloneVirtualRegister(Reg
);
129 bool IsGeneric
= MRI
->getRegClassOrNull(Reg
) == nullptr;
130 unsigned ImpDef
= IsGeneric
? TargetOpcode::G_IMPLICIT_DEF
131 : TargetOpcode::IMPLICIT_DEF
;
133 unsigned State
= getRegState(MO
);
135 State
|= RegState::Undef
;
137 BuildMI(*EntryMBB
, EntryInsPt
, DebugLoc(), TII
->get(ImpDef
))
138 .addReg(NewReg
, State
, MO
.getSubReg());
149 // Finally delete the MIs.
150 for (auto *MI
: ToDelete
)
151 MI
->eraseFromParent();
154 static void extractInstrFromModule(Oracle
&O
, ReducerWorkItem
&WorkItem
) {
155 for (const Function
&F
: WorkItem
.getModule()) {
156 if (MachineFunction
*MF
= WorkItem
.MMI
->getMachineFunction(F
))
157 extractInstrFromFunction(O
, *MF
);
161 void llvm::reduceInstructionsMIRDeltaPass(TestRunner
&Test
) {
162 runDeltaPass(Test
, extractInstrFromModule
, "Reducing Instructions");