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