Home | History | Annotate | Line # | Download | only in CodeGen
      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 #include "llvm/Support/CommandLine.h"
     19 #include "llvm/Transforms/Utils/Debugify.h"
     20 
     21 #define DEBUG_TYPE "mir-strip-debug"
     22 
     23 using namespace llvm;
     24 
     25 namespace {
     26 cl::opt<bool>
     27     OnlyDebugifiedDefault("mir-strip-debugify-only",
     28                           cl::desc("Should mir-strip-debug only strip debug "
     29                                    "info from debugified modules by default"),
     30                           cl::init(true));
     31 
     32 struct StripDebugMachineModule : public ModulePass {
     33   bool runOnModule(Module &M) override {
     34     if (OnlyDebugified) {
     35       NamedMDNode *DebugifyMD = M.getNamedMetadata("llvm.debugify");
     36       if (!DebugifyMD) {
     37         LLVM_DEBUG(dbgs() << "Not stripping debug info"
     38                              " (debugify metadata not found)?\n");
     39         return false;
     40       }
     41     }
     42 
     43     MachineModuleInfo &MMI =
     44         getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
     45 
     46     bool Changed = false;
     47     for (Function &F : M.functions()) {
     48       MachineFunction *MaybeMF = MMI.getMachineFunction(F);
     49       if (!MaybeMF)
     50         continue;
     51       MachineFunction &MF = *MaybeMF;
     52       for (MachineBasicBlock &MBB : MF) {
     53         for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
     54              I != E;) {
     55           if (I->isDebugInstr()) {
     56             // FIXME: We should remove all of them. However, AArch64 emits an
     57             //        invalid `DBG_VALUE $lr` with only one operand instead of
     58             //        the usual three and has a test that depends on it's
     59             //        preservation. Preserve it for now.
     60             if (I->getNumOperands() > 1) {
     61               LLVM_DEBUG(dbgs() << "Removing debug instruction " << *I);
     62               I = MBB.erase(I);
     63               Changed |= true;
     64               continue;
     65             }
     66           }
     67           if (I->getDebugLoc()) {
     68             LLVM_DEBUG(dbgs() << "Removing location " << *I);
     69             I->setDebugLoc(DebugLoc());
     70             Changed |= true;
     71             ++I;
     72             continue;
     73           }
     74           LLVM_DEBUG(dbgs() << "Keeping " << *I);
     75           ++I;
     76         }
     77       }
     78     }
     79 
     80     Changed |= stripDebugifyMetadata(M);
     81 
     82     return Changed;
     83   }
     84 
     85   StripDebugMachineModule() : StripDebugMachineModule(OnlyDebugifiedDefault) {}
     86   StripDebugMachineModule(bool OnlyDebugified)
     87       : ModulePass(ID), OnlyDebugified(OnlyDebugified) {}
     88 
     89   void getAnalysisUsage(AnalysisUsage &AU) const override {
     90     AU.addRequired<MachineModuleInfoWrapperPass>();
     91     AU.addPreserved<MachineModuleInfoWrapperPass>();
     92     AU.setPreservesCFG();
     93   }
     94 
     95   static char ID; // Pass identification.
     96 
     97 protected:
     98   bool OnlyDebugified;
     99 };
    100 char StripDebugMachineModule::ID = 0;
    101 
    102 } // end anonymous namespace
    103 
    104 INITIALIZE_PASS_BEGIN(StripDebugMachineModule, DEBUG_TYPE,
    105                       "Machine Strip Debug Module", false, false)
    106 INITIALIZE_PASS_END(StripDebugMachineModule, DEBUG_TYPE,
    107                     "Machine Strip Debug Module", false, false)
    108 
    109 ModulePass *llvm::createStripDebugMachineModulePass(bool OnlyDebugified) {
    110   return new StripDebugMachineModule(OnlyDebugified);
    111 }
    112