1 //===- MachineStripDebug.cpp - Strip debug info ---------------------------===//
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 This removes debug info from everything. It can be used to ensure
10 /// tests can be debugified without affecting the output MIR.
11 //===----------------------------------------------------------------------===//
12 
13 #include "llvm/CodeGen/MachineFunctionPass.h"
14 #include "llvm/CodeGen/MachineModuleInfo.h"
15 #include "llvm/CodeGen/Passes.h"
16 #include "llvm/IR/DebugInfo.h"
17 #include "llvm/InitializePasses.h"
18 
19 #define DEBUG_TYPE "mir-strip-debug"
20 
21 using namespace llvm;
22 
23 namespace {
24 
25 struct StripDebugMachineModule : public ModulePass {
26   bool runOnModule(Module &M) override {
27     MachineModuleInfo &MMI =
28         getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
29 
30     bool Changed = false;
31     for (Function &F : M.functions()) {
32       MachineFunction &MF = MMI.getOrCreateMachineFunction(F);
33       for (MachineBasicBlock &MBB : MF) {
34         for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
35              I != E;) {
36           if (I->isDebugInstr()) {
37             // FIXME: We should remove all of them. However, AArch64 emits an
38             //        invalid `DBG_VALUE $lr` with only one operand instead of
39             //        the usual three and has a test that depends on it's
40             //        preservation. Preserve it for now.
41             if (I->getNumOperands() > 1) {
42               LLVM_DEBUG(dbgs() << "Removing debug instruction " << *I);
43               I = MBB.erase(I);
44               Changed |= true;
45               continue;
46             }
47           }
48           if (I->getDebugLoc()) {
49             LLVM_DEBUG(dbgs() << "Removing location " << *I);
50             I->setDebugLoc(DebugLoc());
51             Changed |= true;
52             ++I;
53             continue;
54           }
55           LLVM_DEBUG(dbgs() << "Keeping " << *I);
56           ++I;
57         }
58       }
59     }
60 
61     Changed |= StripDebugInfo(M);
62 
63     NamedMDNode *NMD = M.getNamedMetadata("llvm.debugify");
64     if (NMD) {
65       NMD->eraseFromParent();
66       Changed |= true;
67     }
68 
69     NMD = M.getModuleFlagsMetadata();
70     if (NMD) {
71       // There must be an easier way to remove an operand from a NamedMDNode.
72       SmallVector<MDNode *, 4> Flags;
73       for (MDNode *Flag : NMD->operands())
74         Flags.push_back(Flag);
75       NMD->clearOperands();
76       for (MDNode *Flag : Flags) {
77         MDString *Key = dyn_cast_or_null<MDString>(Flag->getOperand(1));
78         if (Key->getString() == "Debug Info Version") {
79           Changed |= true;
80           continue;
81         }
82         NMD->addOperand(Flag);
83       }
84       // If we left it empty we might as well remove it.
85       if (NMD->getNumOperands() == 0)
86         NMD->eraseFromParent();
87     }
88 
89     return Changed;
90   }
91 
92   StripDebugMachineModule() : ModulePass(ID) {}
93 
94   void getAnalysisUsage(AnalysisUsage &AU) const override {
95     AU.addRequired<MachineModuleInfoWrapperPass>();
96     AU.addPreserved<MachineModuleInfoWrapperPass>();
97   }
98 
99   static char ID; // Pass identification.
100 };
101 char StripDebugMachineModule::ID = 0;
102 
103 } // end anonymous namespace
104 
105 INITIALIZE_PASS_BEGIN(StripDebugMachineModule, DEBUG_TYPE,
106                       "Machine Strip Debug Module", false, false)
107 INITIALIZE_PASS_END(StripDebugMachineModule, DEBUG_TYPE,
108                     "Machine Strip Debug Module", false, false)
109 
110 ModulePass *createStripDebugMachineModulePass() {
111   return new StripDebugMachineModule();
112 }
113