brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.7 KiB · 1daf381 Raw
260 lines · cpp
1//===- DebugifyTest.cpp - Debugify unit tests -----------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/ADT/SmallVector.h"10#include "llvm/AsmParser/Parser.h"11#include "llvm/IR/DebugInfoMetadata.h"12#include "llvm/IR/IntrinsicInst.h"13#include "llvm/IR/LegacyPassManager.h"14#include "llvm/Support/SourceMgr.h"15#include "llvm/Transforms/Utils/Debugify.h"16#include "gtest/gtest.h"17 18using namespace llvm;19 20static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {21  SMDiagnostic Err;22  std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);23  if (!Mod)24    Err.print("DebugifyTest", errs());25  return Mod;26}27 28namespace llvm {29void initializeDebugInfoDropPass(PassRegistry &);30void initializeDebugInfoDummyAnalysisPass(PassRegistry &);31 32namespace {33struct DebugInfoDrop : public FunctionPass {34  static char ID;35  bool runOnFunction(Function &F) override {36    // Drop DISubprogram.37    F.setSubprogram(nullptr);38    for (BasicBlock &BB : F) {39      // Remove debug locations.40      for (Instruction &I : BB)41        I.setDebugLoc(DebugLoc());42    }43 44    return false;45  }46 47  void getAnalysisUsage(AnalysisUsage &AU) const override {48    AU.setPreservesCFG();49  }50 51  DebugInfoDrop() : FunctionPass(ID) {}52};53 54struct DebugValueDrop : public FunctionPass {55  static char ID;56  bool runOnFunction(Function &F) override {57    for (BasicBlock &BB : F) {58      for (Instruction &I : BB) {59        // If there are any debug records, drop them.60        I.dropDbgRecords();61      }62    }63 64    return true;65  }66 67  void getAnalysisUsage(AnalysisUsage &AU) const override {68    AU.setPreservesCFG();69  }70 71  DebugValueDrop() : FunctionPass(ID) {}72};73 74struct DebugInfoDummyAnalysis : public FunctionPass {75  static char ID;76  bool runOnFunction(Function &F) override {77    // Do nothing, so debug info stays untouched.78    return false;79  }80  void getAnalysisUsage(AnalysisUsage &AU) const override {81    AU.setPreservesAll();82  }83 84  DebugInfoDummyAnalysis() : FunctionPass(ID) {}85};86}87 88char DebugInfoDrop::ID = 0;89char DebugValueDrop::ID = 0;90char DebugInfoDummyAnalysis::ID = 0;91 92TEST(DebugInfoDrop, DropOriginalDebugInfo) {93  LLVMContext C;94  std::unique_ptr<Module> M = parseIR(C, R"(95    define i16 @f(i16 %a) !dbg !6 {96      %b = add i16 %a, 1, !dbg !1197      call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !1198      ret i16 0, !dbg !1199    }100    declare void @llvm.dbg.value(metadata, metadata, metadata)101 102    !llvm.dbg.cu = !{!0}103    !llvm.module.flags = !{!5}104 105    !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)106    !1 = !DIFile(filename: "t.ll", directory: "/")107    !2 = !{}108    !5 = !{i32 2, !"Debug Info Version", i32 3}109    !6 = distinct !DISubprogram(name: "f", linkageName: "f", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)110    !7 = !DISubroutineType(types: !2)111    !8 = !{!9}112    !9 = !DILocalVariable(name: "b", scope: !6, file: !1, line: 1, type: !10)113    !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned)114    !11 = !DILocation(line: 1, column: 1, scope: !6)115  )");116 117  DebugInfoDrop *P = new DebugInfoDrop();118 119  DebugInfoPerPass DIBeforePass;120  DebugifyCustomPassManager Passes;121  Passes.setDebugInfoBeforePass(DIBeforePass);122  Passes.add(createDebugifyModulePass(DebugifyMode::OriginalDebugInfo, "",123                                      &(Passes.getDebugInfoPerPass())));124  Passes.add(P);125  Passes.add(createCheckDebugifyModulePass(false, "", nullptr,126                                           DebugifyMode::OriginalDebugInfo,127                                           &(Passes.getDebugInfoPerPass())));128 129  testing::internal::CaptureStderr();130  Passes.run(*M);131 132  std::string StdOut = testing::internal::GetCapturedStderr();133 134  std::string ErrorForSP = "ERROR:  dropped DISubprogram of";135  std::string WarningForLoc = "WARNING:  dropped DILocation of";136  std::string FinalResult = "CheckModuleDebugify (original debuginfo): FAIL";137 138  EXPECT_TRUE(StdOut.find(ErrorForSP) != std::string::npos);139  EXPECT_TRUE(StdOut.find(WarningForLoc) != std::string::npos);140  EXPECT_TRUE(StdOut.find(FinalResult) != std::string::npos);141}142 143TEST(DebugValueDrop, DropOriginalDebugValues) {144  LLVMContext C;145  std::unique_ptr<Module> M = parseIR(C, R"(146    define i16 @f(i16 %a) !dbg !6 {147      %b = add i16 %a, 1, !dbg !11148      call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11149      ret i16 0, !dbg !11150    }151    declare void @llvm.dbg.value(metadata, metadata, metadata)152 153    !llvm.dbg.cu = !{!0}154    !llvm.module.flags = !{!5}155 156    !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)157    !1 = !DIFile(filename: "t.ll", directory: "/")158    !2 = !{}159    !5 = !{i32 2, !"Debug Info Version", i32 3}160    !6 = distinct !DISubprogram(name: "f", linkageName: "f", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)161    !7 = !DISubroutineType(types: !2)162    !8 = !{!9}163    !9 = !DILocalVariable(name: "b", scope: !6, file: !1, line: 1, type: !10)164    !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned)165    !11 = !DILocation(line: 1, column: 1, scope: !6)166  )");167 168  DebugValueDrop *P = new DebugValueDrop();169 170  DebugInfoPerPass DIBeforePass;171  DebugifyCustomPassManager Passes;172  Passes.setDebugInfoBeforePass(DIBeforePass);173  Passes.add(createDebugifyModulePass(DebugifyMode::OriginalDebugInfo, "",174                                      &(Passes.getDebugInfoPerPass())));175  Passes.add(P);176  Passes.add(createCheckDebugifyModulePass(false, "", nullptr,177                                           DebugifyMode::OriginalDebugInfo,178                                           &(Passes.getDebugInfoPerPass())));179 180  testing::internal::CaptureStderr();181  Passes.run(*M);182 183  std::string StdOut = testing::internal::GetCapturedStderr();184 185  std::string ErrorForSP = "ERROR:  dropped DISubprogram of";186  std::string WarningForLoc = "WARNING:  dropped DILocation of";187  std::string WarningForVars = "WARNING:  drops dbg.value()/dbg.declare() for";188  std::string FinalResult = "CheckModuleDebugify (original debuginfo): FAIL";189 190  EXPECT_TRUE(StdOut.find(ErrorForSP) == std::string::npos);191  EXPECT_TRUE(StdOut.find(WarningForLoc) == std::string::npos);192  EXPECT_TRUE(StdOut.find(WarningForVars) != std::string::npos);193  EXPECT_TRUE(StdOut.find(FinalResult) != std::string::npos);194}195 196TEST(DebugInfoDummyAnalysis, PreserveOriginalDebugInfo) {197  LLVMContext C;198  std::unique_ptr<Module> M = parseIR(C, R"(199    define i32 @g(i32 %b) !dbg !6 {200      %c = add i32 %b, 1, !dbg !11201      call void @llvm.dbg.value(metadata i32 %c, metadata !9, metadata !DIExpression()), !dbg !11202      ret i32 1, !dbg !11203    }204    declare void @llvm.dbg.value(metadata, metadata, metadata)205 206    !llvm.dbg.cu = !{!0}207    !llvm.module.flags = !{!5}208 209    !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)210    !1 = !DIFile(filename: "test.ll", directory: "/")211    !2 = !{}212    !5 = !{i32 2, !"Debug Info Version", i32 3}213    !6 = distinct !DISubprogram(name: "f", linkageName: "f", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)214    !7 = !DISubroutineType(types: !2)215    !8 = !{!9}216    !9 = !DILocalVariable(name: "c", scope: !6, file: !1, line: 1, type: !10)217    !10 = !DIBasicType(name: "ty32", size: 32, encoding: DW_ATE_unsigned)218    !11 = !DILocation(line: 1, column: 1, scope: !6)219  )");220 221  DebugInfoDummyAnalysis *P = new DebugInfoDummyAnalysis();222 223  DebugInfoPerPass DIBeforePass;224  DebugifyCustomPassManager Passes;225  Passes.setDebugInfoBeforePass(DIBeforePass);226  Passes.add(createDebugifyModulePass(DebugifyMode::OriginalDebugInfo, "",227                                      &(Passes.getDebugInfoPerPass())));228  Passes.add(P);229  Passes.add(createCheckDebugifyModulePass(false, "", nullptr,230                                           DebugifyMode::OriginalDebugInfo,231                                           &(Passes.getDebugInfoPerPass())));232 233  testing::internal::CaptureStderr();234  Passes.run(*M);235 236  std::string StdOut = testing::internal::GetCapturedStderr();237 238  std::string ErrorForSP = "ERROR:  dropped DISubprogram of";239  std::string WarningForLoc = "WARNING:  dropped DILocation of";240  std::string WarningForVars = "WARNING:  drops dbg.value()/dbg.declare() for";241  std::string FinalResult = "CheckModuleDebugify (original debuginfo): PASS";242 243  EXPECT_TRUE(StdOut.find(ErrorForSP) == std::string::npos);244  EXPECT_TRUE(StdOut.find(WarningForLoc) == std::string::npos);245  EXPECT_TRUE(StdOut.find(WarningForVars) == std::string::npos);246  EXPECT_TRUE(StdOut.find(FinalResult) != std::string::npos);247}248 249} // end namespace llvm250 251INITIALIZE_PASS_BEGIN(DebugInfoDrop, "debuginfodroppass", "debuginfodroppass",252                      false, false)253INITIALIZE_PASS_END(DebugInfoDrop, "debuginfodroppass", "debuginfodroppass", false,254                    false)255 256INITIALIZE_PASS_BEGIN(DebugInfoDummyAnalysis, "debuginfodummyanalysispass",257                      "debuginfodummyanalysispass", false, false)258INITIALIZE_PASS_END(DebugInfoDummyAnalysis, "debuginfodummyanalysispass",259                    "debuginfodummyanalysispass", false, false)260