xref: /llvm-project/llvm/tools/llvm-reduce/deltas/ReduceRegisterDefs.cpp (revision 073401e59c8c0e03e06be1d516fe8ea821146d2f)
1e24b390dSMatt Arsenault //===- ReduceRegisterDefs.cpp - Specialized Delta Pass --------------------===//
2e24b390dSMatt Arsenault //
3e24b390dSMatt Arsenault // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e24b390dSMatt Arsenault // See https://llvm.org/LICENSE.txt for license information.
5e24b390dSMatt Arsenault // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e24b390dSMatt Arsenault //
7e24b390dSMatt Arsenault //===----------------------------------------------------------------------===//
8e24b390dSMatt Arsenault //
9e24b390dSMatt Arsenault // This file implements a function which calls the Generic Delta pass in order
10e24b390dSMatt Arsenault // to reduce uninteresting register uses from the MachineFunction.
11e24b390dSMatt Arsenault //
12e24b390dSMatt Arsenault //===----------------------------------------------------------------------===//
13e24b390dSMatt Arsenault 
14e24b390dSMatt Arsenault #include "ReduceRegisterDefs.h"
15e24b390dSMatt Arsenault #include "llvm/CodeGen/MachineFunction.h"
16333ffafbSMatt Arsenault #include "llvm/CodeGen/MachineModuleInfo.h"
17e24b390dSMatt Arsenault #include "llvm/CodeGen/MachineRegisterInfo.h"
18e24b390dSMatt Arsenault #include "llvm/CodeGen/TargetInstrInfo.h"
19e24b390dSMatt Arsenault 
20e24b390dSMatt Arsenault using namespace llvm;
21e24b390dSMatt Arsenault 
removeDefsFromFunction(Oracle & O,MachineFunction & MF)22e24b390dSMatt Arsenault static void removeDefsFromFunction(Oracle &O, MachineFunction &MF) {
23e24b390dSMatt Arsenault   MachineRegisterInfo &MRI = MF.getRegInfo();
24e24b390dSMatt Arsenault   const TargetSubtargetInfo &STI = MF.getSubtarget();
25e24b390dSMatt Arsenault   const TargetInstrInfo *TII = STI.getInstrInfo();
26e24b390dSMatt Arsenault 
27e24b390dSMatt Arsenault   DenseSet<MachineOperand *> KeepDefs;
28e24b390dSMatt Arsenault   DenseSet<TargetInstrInfo::RegSubRegPair> DeleteDefs;
29e24b390dSMatt Arsenault 
30e24b390dSMatt Arsenault   for (MachineBasicBlock &MBB : MF) {
31e24b390dSMatt Arsenault     for (MachineBasicBlock::iterator It = MBB.begin(),
32e24b390dSMatt Arsenault                                      E = MBB.getFirstTerminator();
33e24b390dSMatt Arsenault          It != E;) {
34e24b390dSMatt Arsenault       MachineBasicBlock::iterator InsPt = It;
35e24b390dSMatt Arsenault       MachineInstr &MI = *It;
36e24b390dSMatt Arsenault       ++It;
37e24b390dSMatt Arsenault 
38e24b390dSMatt Arsenault       KeepDefs.clear();
39e24b390dSMatt Arsenault       DeleteDefs.clear();
40e24b390dSMatt Arsenault 
41e24b390dSMatt Arsenault       int NumOperands = MI.getNumOperands();
42e24b390dSMatt Arsenault       int NumRequiredOps = MI.getNumExplicitOperands() +
43*073401e5SJay Foad                            MI.getDesc().implicit_defs().size() +
44*073401e5SJay Foad                            MI.getDesc().implicit_uses().size();
45e24b390dSMatt Arsenault 
46e24b390dSMatt Arsenault       bool HaveDelete = false;
47e24b390dSMatt Arsenault       // Do an initial scan in case the instruction defines the same register
48e24b390dSMatt Arsenault       // multiple times.
49e24b390dSMatt Arsenault       for (int I = NumOperands - 1; I >= 0; --I) {
50e24b390dSMatt Arsenault         MachineOperand &MO = MI.getOperand(I);
51e24b390dSMatt Arsenault         if (!MO.isReg() || !MO.isDef())
52e24b390dSMatt Arsenault           continue;
53e24b390dSMatt Arsenault 
54e24b390dSMatt Arsenault         TargetInstrInfo::RegSubRegPair RegPair(MO.getReg(), MO.getSubReg());
55e24b390dSMatt Arsenault         if (!RegPair.Reg.isVirtual())
56e24b390dSMatt Arsenault           continue;
57e24b390dSMatt Arsenault 
58e24b390dSMatt Arsenault         if (O.shouldKeep())
59e24b390dSMatt Arsenault           KeepDefs.insert(&MO);
60e24b390dSMatt Arsenault         else
61e24b390dSMatt Arsenault           HaveDelete = true;
62e24b390dSMatt Arsenault       }
63e24b390dSMatt Arsenault 
64e24b390dSMatt Arsenault       if (!HaveDelete)
65e24b390dSMatt Arsenault         continue;
66e24b390dSMatt Arsenault 
67e24b390dSMatt Arsenault       bool HaveKeptDef = !KeepDefs.empty();
68e24b390dSMatt Arsenault       for (int I = NumOperands - 1; I >= 0; --I) {
69e24b390dSMatt Arsenault         MachineOperand &MO = MI.getOperand(I);
70e24b390dSMatt Arsenault         if (!MO.isReg() || !MO.isDef())
71e24b390dSMatt Arsenault           continue;
72e24b390dSMatt Arsenault 
73e24b390dSMatt Arsenault         if (KeepDefs.count(&MO))
74e24b390dSMatt Arsenault           continue;
75e24b390dSMatt Arsenault 
76e24b390dSMatt Arsenault         TargetInstrInfo::RegSubRegPair RegPair(MO.getReg(), MO.getSubReg());
77e24b390dSMatt Arsenault         if (!RegPair.Reg.isVirtual())
78e24b390dSMatt Arsenault           continue;
79e24b390dSMatt Arsenault 
80e24b390dSMatt Arsenault         if (!DeleteDefs.insert(RegPair).second)
81e24b390dSMatt Arsenault           continue;
82e24b390dSMatt Arsenault 
83e24b390dSMatt Arsenault         if (MRI.use_empty(RegPair.Reg)) {
84e24b390dSMatt Arsenault           if (I >= NumRequiredOps) {
85e24b390dSMatt Arsenault             // Delete implicit def operands that aren't part of the instruction
86e24b390dSMatt Arsenault             // definition
87e24b390dSMatt Arsenault             MI.removeOperand(I);
88e24b390dSMatt Arsenault           }
89e24b390dSMatt Arsenault 
90e24b390dSMatt Arsenault           continue;
91e24b390dSMatt Arsenault         }
92e24b390dSMatt Arsenault 
93e24b390dSMatt Arsenault         // If we aren't going to delete the instruction, replace it with a dead
94e24b390dSMatt Arsenault         // def.
95e24b390dSMatt Arsenault         if (HaveKeptDef)
96e24b390dSMatt Arsenault           MO.setReg(MRI.cloneVirtualRegister(MO.getReg()));
97e24b390dSMatt Arsenault 
98e24b390dSMatt Arsenault         bool IsGeneric = MRI.getRegClassOrNull(RegPair.Reg) == nullptr;
99e24b390dSMatt Arsenault         unsigned ImpDef = IsGeneric ? TargetOpcode::G_IMPLICIT_DEF
100e24b390dSMatt Arsenault                                     : TargetOpcode::IMPLICIT_DEF;
101e24b390dSMatt Arsenault 
102e24b390dSMatt Arsenault         unsigned OpFlags = getRegState(MO) & ~RegState::Implicit;
103e24b390dSMatt Arsenault         InsPt = BuildMI(MBB, InsPt, DebugLoc(), TII->get(ImpDef))
104e24b390dSMatt Arsenault           .addReg(RegPair.Reg, OpFlags, RegPair.SubReg);
105e24b390dSMatt Arsenault       }
106e24b390dSMatt Arsenault 
107e24b390dSMatt Arsenault       if (!HaveKeptDef)
108e24b390dSMatt Arsenault         MI.eraseFromParent();
109e24b390dSMatt Arsenault     }
110e24b390dSMatt Arsenault   }
111e24b390dSMatt Arsenault }
112e24b390dSMatt Arsenault 
removeDefsFromModule(Oracle & O,ReducerWorkItem & WorkItem)113e24b390dSMatt Arsenault static void removeDefsFromModule(Oracle &O, ReducerWorkItem &WorkItem) {
114e24b390dSMatt Arsenault   for (const Function &F : WorkItem.getModule()) {
115e24b390dSMatt Arsenault     if (auto *MF = WorkItem.MMI->getMachineFunction(F))
116e24b390dSMatt Arsenault       removeDefsFromFunction(O, *MF);
117e24b390dSMatt Arsenault   }
118e24b390dSMatt Arsenault }
119e24b390dSMatt Arsenault 
reduceRegisterDefsMIRDeltaPass(TestRunner & Test)120e24b390dSMatt Arsenault void llvm::reduceRegisterDefsMIRDeltaPass(TestRunner &Test) {
1212592ccdeSArthur Eubanks   runDeltaPass(Test, removeDefsFromModule, "Reducing register defs");
122e24b390dSMatt Arsenault }
123