xref: /freebsd/contrib/llvm-project/llvm/lib/CodeGen/RemoveLoadsIntoFakeUses.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
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 
39 using namespace llvm;
40 
41 #define DEBUG_TYPE "remove-loads-into-fake-uses"
42 
43 STATISTIC(NumLoadsDeleted, "Number of dead load instructions deleted");
44 STATISTIC(NumFakeUsesDeleted, "Number of FAKE_USE instructions deleted");
45 
46 class RemoveLoadsIntoFakeUsesLegacy : public MachineFunctionPass {
47 public:
48   static char ID;
49 
RemoveLoadsIntoFakeUsesLegacy()50   RemoveLoadsIntoFakeUsesLegacy() : MachineFunctionPass(ID) {
51     initializeRemoveLoadsIntoFakeUsesLegacyPass(
52         *PassRegistry::getPassRegistry());
53   }
54 
getAnalysisUsage(AnalysisUsage & AU) const55   void getAnalysisUsage(AnalysisUsage &AU) const override {
56     AU.setPreservesCFG();
57     MachineFunctionPass::getAnalysisUsage(AU);
58   }
59 
getRequiredProperties() const60   MachineFunctionProperties getRequiredProperties() const override {
61     return MachineFunctionProperties().setNoVRegs();
62   }
63 
getPassName() const64   StringRef getPassName() const override {
65     return "Remove Loads Into Fake Uses";
66   }
67 
68   bool runOnMachineFunction(MachineFunction &MF) override;
69 };
70 
71 struct RemoveLoadsIntoFakeUses {
72   bool run(MachineFunction &MF);
73 };
74 
75 char RemoveLoadsIntoFakeUsesLegacy::ID = 0;
76 char &llvm::RemoveLoadsIntoFakeUsesID = RemoveLoadsIntoFakeUsesLegacy::ID;
77 
78 INITIALIZE_PASS_BEGIN(RemoveLoadsIntoFakeUsesLegacy, DEBUG_TYPE,
79                       "Remove Loads Into Fake Uses", false, false)
80 INITIALIZE_PASS_END(RemoveLoadsIntoFakeUsesLegacy, DEBUG_TYPE,
81                     "Remove Loads Into Fake Uses", false, false)
82 
runOnMachineFunction(MachineFunction & MF)83 bool RemoveLoadsIntoFakeUsesLegacy::runOnMachineFunction(MachineFunction &MF) {
84   if (skipFunction(MF.getFunction()))
85     return false;
86 
87   return RemoveLoadsIntoFakeUses().run(MF);
88 }
89 
90 PreservedAnalyses
run(MachineFunction & MF,MachineFunctionAnalysisManager & MFAM)91 RemoveLoadsIntoFakeUsesPass::run(MachineFunction &MF,
92                                  MachineFunctionAnalysisManager &MFAM) {
93   MFPropsModifier _(*this, MF);
94 
95   if (!RemoveLoadsIntoFakeUses().run(MF))
96     return PreservedAnalyses::all();
97 
98   auto PA = getMachineFunctionPassPreservedAnalyses();
99   PA.preserveSet<CFGAnalyses>();
100   return PA;
101 }
102 
run(MachineFunction & MF)103 bool RemoveLoadsIntoFakeUses::run(MachineFunction &MF) {
104   // Skip this pass if we would use VarLoc-based LDV, as there may be DBG_VALUE
105   // instructions of the restored values that would become invalid.
106   if (!MF.useDebugInstrRef())
107     return false;
108   // Only run this for functions that have fake uses.
109   if (!MF.hasFakeUses())
110     return false;
111 
112   bool AnyChanges = false;
113 
114   LiveRegUnits LivePhysRegs;
115   const MachineRegisterInfo *MRI = &MF.getRegInfo();
116   const TargetSubtargetInfo &ST = MF.getSubtarget();
117   const TargetInstrInfo *TII = ST.getInstrInfo();
118   const TargetRegisterInfo *TRI = ST.getRegisterInfo();
119 
120   SmallVector<MachineInstr *> RegFakeUses;
121   LivePhysRegs.init(*TRI);
122   for (MachineBasicBlock *MBB : post_order(&MF)) {
123     RegFakeUses.clear();
124     LivePhysRegs.addLiveOuts(*MBB);
125 
126     for (MachineInstr &MI : make_early_inc_range(reverse(*MBB))) {
127       if (MI.isFakeUse()) {
128         if (MI.getNumOperands() == 0 || !MI.getOperand(0).isReg())
129           continue;
130         // Track the Fake Uses that use these register units so that we can
131         // delete them if we delete the corresponding load.
132         RegFakeUses.push_back(&MI);
133         // Do not record FAKE_USE uses in LivePhysRegs so that we can recognize
134         // otherwise-unused loads.
135         continue;
136       }
137 
138       // If the restore size is not std::nullopt then we are dealing with a
139       // reload of a spilled register.
140       if (MI.getRestoreSize(TII)) {
141         Register Reg = MI.getOperand(0).getReg();
142         // Don't delete live physreg defs, or any reserved register defs.
143         if (!LivePhysRegs.available(Reg) || MRI->isReserved(Reg))
144           continue;
145         // There should typically be an exact match between the loaded register
146         // and the FAKE_USE, but sometimes regalloc will choose to load a larger
147         // value than is needed. Therefore, as long as the load isn't used by
148         // anything except at least one FAKE_USE, we will delete it. If it isn't
149         // used by any fake uses, it should still be safe to delete but we
150         // choose to ignore it so that this pass has no side effects unrelated
151         // to fake uses.
152         SmallDenseSet<MachineInstr *> FakeUsesToDelete;
153         for (MachineInstr *&FakeUse : reverse(RegFakeUses)) {
154           if (FakeUse->readsRegister(Reg, TRI)) {
155             FakeUsesToDelete.insert(FakeUse);
156             RegFakeUses.erase(&FakeUse);
157           }
158         }
159         if (!FakeUsesToDelete.empty()) {
160           LLVM_DEBUG(dbgs() << "RemoveLoadsIntoFakeUses: DELETING: " << MI);
161           // Since this load only exists to restore a spilled register and we
162           // haven't, run LiveDebugValues yet, there shouldn't be any DBG_VALUEs
163           // for this load; otherwise, deleting this would be incorrect.
164           MI.eraseFromParent();
165           AnyChanges = true;
166           ++NumLoadsDeleted;
167           for (MachineInstr *FakeUse : FakeUsesToDelete) {
168             LLVM_DEBUG(dbgs()
169                        << "RemoveLoadsIntoFakeUses: DELETING: " << *FakeUse);
170             FakeUse->eraseFromParent();
171           }
172           NumFakeUsesDeleted += FakeUsesToDelete.size();
173         }
174         continue;
175       }
176 
177       // In addition to tracking LivePhysRegs, we need to clear RegFakeUses each
178       // time a register is defined, as existing FAKE_USEs no longer apply to
179       // that register.
180       if (!RegFakeUses.empty()) {
181         for (const MachineOperand &MO : MI.operands()) {
182           if (!MO.isReg())
183             continue;
184           Register Reg = MO.getReg();
185           // We clear RegFakeUses for this register and all subregisters,
186           // because any such FAKE_USE encountered prior is no longer relevant
187           // for later encountered loads.
188           for (MachineInstr *&FakeUse : reverse(RegFakeUses))
189             if (FakeUse->readsRegister(Reg, TRI))
190               RegFakeUses.erase(&FakeUse);
191         }
192       }
193       LivePhysRegs.stepBackward(MI);
194     }
195   }
196 
197   return AnyChanges;
198 }
199