1cfca06d7SDimitry Andric //===- MachineStripDebug.cpp - Strip debug info ---------------------------===//
2cfca06d7SDimitry Andric //
3cfca06d7SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4cfca06d7SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5cfca06d7SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6cfca06d7SDimitry Andric //
7cfca06d7SDimitry Andric //===----------------------------------------------------------------------===//
8cfca06d7SDimitry Andric ///
9cfca06d7SDimitry Andric /// \file This removes debug info from everything. It can be used to ensure
10cfca06d7SDimitry Andric /// tests can be debugified without affecting the output MIR.
11cfca06d7SDimitry Andric //===----------------------------------------------------------------------===//
12cfca06d7SDimitry Andric
13145449b1SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
14145449b1SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
15cfca06d7SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h"
16cfca06d7SDimitry Andric #include "llvm/CodeGen/Passes.h"
17cfca06d7SDimitry Andric #include "llvm/InitializePasses.h"
18cfca06d7SDimitry Andric #include "llvm/Support/CommandLine.h"
19cfca06d7SDimitry Andric #include "llvm/Transforms/Utils/Debugify.h"
20cfca06d7SDimitry Andric
21cfca06d7SDimitry Andric #define DEBUG_TYPE "mir-strip-debug"
22cfca06d7SDimitry Andric
23cfca06d7SDimitry Andric using namespace llvm;
24cfca06d7SDimitry Andric
25cfca06d7SDimitry Andric namespace {
26cfca06d7SDimitry Andric cl::opt<bool>
27cfca06d7SDimitry Andric OnlyDebugifiedDefault("mir-strip-debugify-only",
28cfca06d7SDimitry Andric cl::desc("Should mir-strip-debug only strip debug "
29cfca06d7SDimitry Andric "info from debugified modules by default"),
30cfca06d7SDimitry Andric cl::init(true));
31cfca06d7SDimitry Andric
32cfca06d7SDimitry Andric struct StripDebugMachineModule : public ModulePass {
runOnModule__anon607f78770111::StripDebugMachineModule33cfca06d7SDimitry Andric bool runOnModule(Module &M) override {
34cfca06d7SDimitry Andric if (OnlyDebugified) {
35cfca06d7SDimitry Andric NamedMDNode *DebugifyMD = M.getNamedMetadata("llvm.debugify");
36cfca06d7SDimitry Andric if (!DebugifyMD) {
37cfca06d7SDimitry Andric LLVM_DEBUG(dbgs() << "Not stripping debug info"
38cfca06d7SDimitry Andric " (debugify metadata not found)?\n");
39cfca06d7SDimitry Andric return false;
40cfca06d7SDimitry Andric }
41cfca06d7SDimitry Andric }
42cfca06d7SDimitry Andric
43cfca06d7SDimitry Andric MachineModuleInfo &MMI =
44cfca06d7SDimitry Andric getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
45cfca06d7SDimitry Andric
46cfca06d7SDimitry Andric bool Changed = false;
47cfca06d7SDimitry Andric for (Function &F : M.functions()) {
48cfca06d7SDimitry Andric MachineFunction *MaybeMF = MMI.getMachineFunction(F);
49cfca06d7SDimitry Andric if (!MaybeMF)
50cfca06d7SDimitry Andric continue;
51cfca06d7SDimitry Andric MachineFunction &MF = *MaybeMF;
52cfca06d7SDimitry Andric for (MachineBasicBlock &MBB : MF) {
53c0981da4SDimitry Andric for (MachineInstr &MI : llvm::make_early_inc_range(MBB)) {
54c0981da4SDimitry Andric if (MI.isDebugInstr()) {
55cfca06d7SDimitry Andric // FIXME: We should remove all of them. However, AArch64 emits an
56cfca06d7SDimitry Andric // invalid `DBG_VALUE $lr` with only one operand instead of
57cfca06d7SDimitry Andric // the usual three and has a test that depends on it's
58cfca06d7SDimitry Andric // preservation. Preserve it for now.
59c0981da4SDimitry Andric if (MI.getNumOperands() > 1) {
60c0981da4SDimitry Andric LLVM_DEBUG(dbgs() << "Removing debug instruction " << MI);
61c0981da4SDimitry Andric MBB.erase(&MI);
62cfca06d7SDimitry Andric Changed |= true;
63cfca06d7SDimitry Andric continue;
64cfca06d7SDimitry Andric }
65cfca06d7SDimitry Andric }
66c0981da4SDimitry Andric if (MI.getDebugLoc()) {
67c0981da4SDimitry Andric LLVM_DEBUG(dbgs() << "Removing location " << MI);
68c0981da4SDimitry Andric MI.setDebugLoc(DebugLoc());
69cfca06d7SDimitry Andric Changed |= true;
70cfca06d7SDimitry Andric continue;
71cfca06d7SDimitry Andric }
72c0981da4SDimitry Andric LLVM_DEBUG(dbgs() << "Keeping " << MI);
73cfca06d7SDimitry Andric }
74cfca06d7SDimitry Andric }
75cfca06d7SDimitry Andric }
76cfca06d7SDimitry Andric
77cfca06d7SDimitry Andric Changed |= stripDebugifyMetadata(M);
78cfca06d7SDimitry Andric
79cfca06d7SDimitry Andric return Changed;
80cfca06d7SDimitry Andric }
81cfca06d7SDimitry Andric
StripDebugMachineModule__anon607f78770111::StripDebugMachineModule82cfca06d7SDimitry Andric StripDebugMachineModule() : StripDebugMachineModule(OnlyDebugifiedDefault) {}
StripDebugMachineModule__anon607f78770111::StripDebugMachineModule83cfca06d7SDimitry Andric StripDebugMachineModule(bool OnlyDebugified)
84cfca06d7SDimitry Andric : ModulePass(ID), OnlyDebugified(OnlyDebugified) {}
85cfca06d7SDimitry Andric
getAnalysisUsage__anon607f78770111::StripDebugMachineModule86cfca06d7SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override {
87cfca06d7SDimitry Andric AU.addRequired<MachineModuleInfoWrapperPass>();
88cfca06d7SDimitry Andric AU.addPreserved<MachineModuleInfoWrapperPass>();
89cfca06d7SDimitry Andric AU.setPreservesCFG();
90cfca06d7SDimitry Andric }
91cfca06d7SDimitry Andric
92cfca06d7SDimitry Andric static char ID; // Pass identification.
93cfca06d7SDimitry Andric
94cfca06d7SDimitry Andric protected:
95cfca06d7SDimitry Andric bool OnlyDebugified;
96cfca06d7SDimitry Andric };
97cfca06d7SDimitry Andric char StripDebugMachineModule::ID = 0;
98cfca06d7SDimitry Andric
99cfca06d7SDimitry Andric } // end anonymous namespace
100cfca06d7SDimitry Andric
101cfca06d7SDimitry Andric INITIALIZE_PASS_BEGIN(StripDebugMachineModule, DEBUG_TYPE,
102cfca06d7SDimitry Andric "Machine Strip Debug Module", false, false)
103cfca06d7SDimitry Andric INITIALIZE_PASS_END(StripDebugMachineModule, DEBUG_TYPE,
104cfca06d7SDimitry Andric "Machine Strip Debug Module", false, false)
105cfca06d7SDimitry Andric
createStripDebugMachineModulePass(bool OnlyDebugified)106cfca06d7SDimitry Andric ModulePass *llvm::createStripDebugMachineModulePass(bool OnlyDebugified) {
107cfca06d7SDimitry Andric return new StripDebugMachineModule(OnlyDebugified);
108cfca06d7SDimitry Andric }
109