1//===---- RemoveLoadsIntoFakeUses.cpp - Remove loads with no real uses ----===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// The FAKE_USE instruction is used to preserve certain values through
11/// optimizations for the sake of debugging. This may result in spilled values
12/// being loaded into registers that are only used by FAKE_USEs; this is not
13/// necessary for debugging purposes, because at that point the value must be on
14/// the stack and hence available for debugging. Therefore, this pass removes
15/// loads that are only used by FAKE_USEs.
16///
17/// This pass should run very late, to ensure that we don't inadvertently
18/// shorten stack lifetimes by removing these loads, since the FAKE_USEs will
19/// also no longer be in effect. Running immediately before LiveDebugValues
20/// ensures that LDV will have accurate information of the machine location of
21/// debug values.
22///
23//===----------------------------------------------------------------------===//
24
25#include "llvm/CodeGen/RemoveLoadsIntoFakeUses.h"
26#include "llvm/ADT/PostOrderIterator.h"
27#include "llvm/ADT/Statistic.h"
28#include "llvm/CodeGen/LiveRegUnits.h"
29#include "llvm/CodeGen/MachineFunction.h"
30#include "llvm/CodeGen/MachineFunctionPass.h"
31#include "llvm/CodeGen/MachinePassManager.h"
32#include "llvm/CodeGen/MachineRegisterInfo.h"
33#include "llvm/CodeGen/TargetSubtargetInfo.h"
34#include "llvm/IR/Function.h"
35#include "llvm/InitializePasses.h"
36#include "llvm/Support/Debug.h"
37#include "llvm/Target/TargetMachine.h"
38
39using namespace llvm;
40
41#define DEBUG_TYPE "remove-loads-into-fake-uses"
42
43STATISTIC(NumLoadsDeleted, "Number of dead load instructions deleted");
44STATISTIC(NumFakeUsesDeleted, "Number of FAKE_USE instructions deleted");
45
46class RemoveLoadsIntoFakeUsesLegacy : public MachineFunctionPass {
47public:
48 static char ID;
49
50 RemoveLoadsIntoFakeUsesLegacy() : MachineFunctionPass(ID) {}
51
52 void getAnalysisUsage(AnalysisUsage &AU) const override {
53 AU.setPreservesCFG();
54 MachineFunctionPass::getAnalysisUsage(AU);
55 }
56
57 MachineFunctionProperties getRequiredProperties() const override {
58 return MachineFunctionProperties().setNoVRegs();
59 }
60
61 StringRef getPassName() const override {
62 return "Remove Loads Into Fake Uses";
63 }
64
65 bool runOnMachineFunction(MachineFunction &MF) override;
66};
67
68struct RemoveLoadsIntoFakeUses {
69 bool run(MachineFunction &MF);
70};
71
72char RemoveLoadsIntoFakeUsesLegacy::ID = 0;
73char &llvm::RemoveLoadsIntoFakeUsesID = RemoveLoadsIntoFakeUsesLegacy::ID;
74
75INITIALIZE_PASS_BEGIN(RemoveLoadsIntoFakeUsesLegacy, DEBUG_TYPE,
76 "Remove Loads Into Fake Uses", false, false)
77INITIALIZE_PASS_END(RemoveLoadsIntoFakeUsesLegacy, DEBUG_TYPE,
78 "Remove Loads Into Fake Uses", false, false)
79
80bool RemoveLoadsIntoFakeUsesLegacy::runOnMachineFunction(MachineFunction &MF) {
81 if (skipFunction(F: MF.getFunction()))
82 return false;
83
84 return RemoveLoadsIntoFakeUses().run(MF);
85}
86
87PreservedAnalyses
88RemoveLoadsIntoFakeUsesPass::run(MachineFunction &MF,
89 MachineFunctionAnalysisManager &MFAM) {
90 MFPropsModifier _(*this, MF);
91
92 if (!RemoveLoadsIntoFakeUses().run(MF))
93 return PreservedAnalyses::all();
94
95 auto PA = getMachineFunctionPassPreservedAnalyses();
96 PA.preserveSet<CFGAnalyses>();
97 return PA;
98}
99
100bool RemoveLoadsIntoFakeUses::run(MachineFunction &MF) {
101 // Skip this pass if we would use VarLoc-based LDV, as there may be DBG_VALUE
102 // instructions of the restored values that would become invalid.
103 if (!MF.useDebugInstrRef())
104 return false;
105 // Only run this for functions that have fake uses.
106 if (!MF.hasFakeUses())
107 return false;
108
109 bool AnyChanges = false;
110
111 LiveRegUnits LivePhysRegs;
112 const MachineRegisterInfo *MRI = &MF.getRegInfo();
113 const TargetSubtargetInfo &ST = MF.getSubtarget();
114 const TargetInstrInfo *TII = ST.getInstrInfo();
115 const TargetRegisterInfo *TRI = ST.getRegisterInfo();
116
117 SmallVector<MachineInstr *> RegFakeUses;
118 LivePhysRegs.init(TRI: *TRI);
119 for (MachineBasicBlock *MBB : post_order(G: &MF)) {
120 RegFakeUses.clear();
121 LivePhysRegs.addLiveOuts(MBB: *MBB);
122
123 for (MachineInstr &MI : make_early_inc_range(Range: reverse(C&: *MBB))) {
124 if (MI.isFakeUse()) {
125 if (MI.getNumOperands() == 0 || !MI.getOperand(i: 0).isReg())
126 continue;
127 // Track the Fake Uses that use these register units so that we can
128 // delete them if we delete the corresponding load.
129 RegFakeUses.push_back(Elt: &MI);
130 // Do not record FAKE_USE uses in LivePhysRegs so that we can recognize
131 // otherwise-unused loads.
132 continue;
133 }
134
135 // If the restore size is not std::nullopt then we are dealing with a
136 // reload of a spilled register.
137 if (MI.getRestoreSize(TII)) {
138 Register Reg = MI.getOperand(i: 0).getReg();
139 // Don't delete live physreg defs, or any reserved register defs.
140 if (!LivePhysRegs.available(Reg) || MRI->isReserved(PhysReg: Reg))
141 continue;
142 // There should typically be an exact match between the loaded register
143 // and the FAKE_USE, but sometimes regalloc will choose to load a larger
144 // value than is needed. Therefore, as long as the load isn't used by
145 // anything except at least one FAKE_USE, we will delete it. If it isn't
146 // used by any fake uses, it should still be safe to delete but we
147 // choose to ignore it so that this pass has no side effects unrelated
148 // to fake uses.
149 SmallDenseSet<MachineInstr *> FakeUsesToDelete;
150 for (MachineInstr *&FakeUse : reverse(C&: RegFakeUses)) {
151 if (FakeUse->readsRegister(Reg, TRI)) {
152 FakeUsesToDelete.insert(V: FakeUse);
153 RegFakeUses.erase(CI: &FakeUse);
154 }
155 }
156 if (!FakeUsesToDelete.empty()) {
157 LLVM_DEBUG(dbgs() << "RemoveLoadsIntoFakeUses: DELETING: " << MI);
158 // Since this load only exists to restore a spilled register and we
159 // haven't, run LiveDebugValues yet, there shouldn't be any DBG_VALUEs
160 // for this load; otherwise, deleting this would be incorrect.
161 MI.eraseFromParent();
162 AnyChanges = true;
163 ++NumLoadsDeleted;
164 for (MachineInstr *FakeUse : FakeUsesToDelete) {
165 LLVM_DEBUG(dbgs()
166 << "RemoveLoadsIntoFakeUses: DELETING: " << *FakeUse);
167 FakeUse->eraseFromParent();
168 }
169 NumFakeUsesDeleted += FakeUsesToDelete.size();
170 }
171 continue;
172 }
173
174 // In addition to tracking LivePhysRegs, we need to clear RegFakeUses each
175 // time a register is defined, as existing FAKE_USEs no longer apply to
176 // that register.
177 if (!RegFakeUses.empty()) {
178 for (const MachineOperand &MO : MI.operands()) {
179 if (!MO.isReg())
180 continue;
181 Register Reg = MO.getReg();
182 // We clear RegFakeUses for this register and all subregisters,
183 // because any such FAKE_USE encountered prior is no longer relevant
184 // for later encountered loads.
185 for (MachineInstr *&FakeUse : reverse(C&: RegFakeUses))
186 if (FakeUse->readsRegister(Reg, TRI))
187 RegFakeUses.erase(CI: &FakeUse);
188 }
189 }
190 LivePhysRegs.stepBackward(MI);
191 }
192 }
193
194 return AnyChanges;
195}
196