brintos

brintos / llvm-project-archived public Read only

0
0
Text · 33.0 KiB · c0cf4ff Raw
1080 lines · cpp
1//===- unittests/CodeGen/DroppedVariableStatsMIRTest.cpp ------------------===//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/CodeGen/DroppedVariableStatsMIR.h"10#include "llvm/AsmParser/Parser.h"11#include "llvm/CodeGen/MIRParser/MIRParser.h"12#include "llvm/CodeGen/MachineModuleInfo.h"13#include "llvm/IR/Function.h"14#include "llvm/IR/LegacyPassManager.h"15#include "llvm/IR/Module.h"16#include "llvm/MC/TargetRegistry.h"17#include "llvm/Pass.h"18#include "llvm/Support/SourceMgr.h"19#include "llvm/Support/TargetSelect.h"20#include "llvm/Target/TargetMachine.h"21#include "gtest/gtest.h"22#include <llvm/ADT/SmallString.h>23#include <llvm/IR/LLVMContext.h>24#include <llvm/IR/PassInstrumentation.h>25#include <llvm/IR/PassManager.h>26#include <llvm/IR/PassTimingInfo.h>27#include <llvm/Support/raw_ostream.h>28 29using namespace llvm;30 31namespace {32 33std::unique_ptr<TargetMachine>34createTargetMachine(std::string TargetStr, StringRef CPU, StringRef FS) {35  std::string Error;36  Triple TT(TargetStr);37  const Target *T = TargetRegistry::lookupTarget(TT, Error);38  if (!T)39    return nullptr;40  TargetOptions Options;41  return std::unique_ptr<TargetMachine>(42      T->createTargetMachine(TT, CPU, FS, Options, std::nullopt, std::nullopt));43}44 45std::unique_ptr<Module> parseMIR(const TargetMachine &TM, StringRef MIRCode,46                                 MachineModuleInfo &MMI, LLVMContext *Context) {47  SMDiagnostic Diagnostic;48  std::unique_ptr<Module> M;49  std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRCode);50  auto MIR = createMIRParser(std::move(MBuffer), *Context);51  if (!MIR)52    return nullptr;53 54  std::unique_ptr<Module> Mod = MIR->parseIRModule();55  if (!Mod)56    return nullptr;57 58  Mod->setDataLayout(TM.createDataLayout());59 60  if (MIR->parseMachineFunctions(*Mod, MMI)) {61    M.reset();62    return nullptr;63  }64  return Mod;65}66// This test ensures that if a DBG_VALUE and an instruction that exists in the67// same scope as that DBG_VALUE are both deleted as a result of an optimization68// pass, debug information is considered not dropped.69TEST(DroppedVariableStatsMIR, BothDeleted) {70  InitializeAllTargetInfos();71  InitializeAllTargets();72  InitializeAllTargetMCs();73  PassInstrumentationCallbacks PIC;74  PassInstrumentation PI(&PIC);75 76  LLVMContext C;77 78  const char *MIR =79      R"(80--- |81  ; ModuleID = '/tmp/test.ll'82  source_filename = "/tmp/test.ll"83  target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"84  85  define noundef range(i32 -2147483647, -2147483648) i32 @_Z3fooi(i32 noundef %x) local_unnamed_addr !dbg !4 {86  entry:87      #dbg_value(i32 %x, !10, !DIExpression(), !11)88    %add = add nsw i32 %x, 1, !dbg !1289    ret i32 090  }91  92  !llvm.dbg.cu = !{!0}93  !llvm.module.flags = !{!2}94  !llvm.ident = !{!3}95  96  !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/")97  !1 = !DIFile(filename: "/tmp/code.cpp", directory: "/")98  !2 = !{i32 2, !"Debug Info Version", i32 3}99  !3 = !{!"clang"}100  !4 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !5, file: !5, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !9)101  !5 = !DIFile(filename: "/tmp/code.cpp", directory: "")102  !6 = !DISubroutineType(types: !7)103  !7 = !{!8, !8}104  !8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)105  !9 = !{!10}106  !10 = !DILocalVariable(name: "x", arg: 1, scope: !4, file: !5, line: 1, type: !8)107  !11 = !DILocation(line: 0, scope: !4)108  !12 = !DILocation(line: 2, column: 11, scope: !4)109 110...111---112name:            _Z3fooi113alignment:       4114exposesReturnsTwice: false115legalized:       false116regBankSelected: false117selected:        false118failedISel:      false119tracksRegLiveness: true120hasWinCFI:       false121noPhis:          false122isSSA:           true123noVRegs:         false124hasFakeUses:     false125callsEHReturn:   false126callsUnwindInit: false127hasEHContTarget: false128hasEHScopes:     false129hasEHFunclets:   false130isOutlined:      false131debugInstrRef:   false132failsVerification: false133tracksDebugUserValues: false134registers:135  - { id: 0, class: _, preferred-register: '', flags: [  ] }136  - { id: 1, class: _, preferred-register: '', flags: [  ] }137  - { id: 2, class: _, preferred-register: '', flags: [  ] }138  - { id: 3, class: _, preferred-register: '', flags: [  ] }139liveins:140  - { reg: '$w0', virtual-reg: '' }141frameInfo:142  isFrameAddressTaken: false143  isReturnAddressTaken: false144  hasStackMap:     false145  hasPatchPoint:   false146  stackSize:       0147  offsetAdjustment: 0148  maxAlignment:    1149  adjustsStack:    false150  hasCalls:        false151  stackProtector:  ''152  functionContext: ''153  maxCallFrameSize: 4294967295154  cvBytesOfCalleeSavedRegisters: 0155  hasOpaqueSPAdjustment: false156  hasVAStart:      false157  hasMustTailInVarArgFunc: false158  hasTailCall:     false159  isCalleeSavedInfoValid: false160  localFrameSize:  0161  savePoint:       []162  restorePoint:    []163fixedStack:      []164stack:           []165entry_values:    []166callSites:       []167debugValueSubstitutions: []168constants:       []169machineFunctionInfo: {}170body:             |171  bb.1.entry:172    liveins: $w0173  174    %0:_(s32) = COPY $w0175    %1:_(s32) = G_CONSTANT i32 1176    %3:_(s32) = G_CONSTANT i32 0177    DBG_VALUE %0(s32), $noreg, !10, !DIExpression(), debug-location !11178    %2:_(s32) = nsw G_ADD %0, %1, debug-location !12179    $w0 = COPY %3(s32)180    RET_ReallyLR implicit $w0181    )";182  auto TM = createTargetMachine(Triple::normalize("aarch64--"), "", "");183  if (!TM)184    return;185  MachineModuleInfo MMI(TM.get());186  std::unique_ptr<Module> M = parseMIR(*TM, MIR, MMI, &C);187  ASSERT_TRUE(M);188 189  DroppedVariableStatsMIR Stats;190  auto *MF = MMI.getMachineFunction(*M->getFunction("_Z3fooi"));191  Stats.runBeforePass("Test", MF);192 193  // This loop simulates an IR pass that drops debug information.194  for (auto &MBB : *MF) {195    for (auto &MI : MBB) {196      if (MI.isDebugValueLike()) {197        MI.eraseFromParent();198        break;199      }200    }201    for (auto &MI : MBB) {202      auto *DbgLoc = MI.getDebugLoc().get();203      if (DbgLoc) {204        MI.eraseFromParent();205        break;206      }207    }208    break;209  }210 211  Stats.runAfterPass("Test", MF);212  ASSERT_EQ(Stats.getPassDroppedVariables(), false);213}214 215// This test ensures that if a DBG_VALUE is dropped after an optimization pass,216// but an instruction that shares the same scope as the DBG_VALUE still exists,217// debug information is conisdered dropped.218TEST(DroppedVariableStatsMIR, DbgValLost) {219  InitializeAllTargetInfos();220  InitializeAllTargets();221  InitializeAllTargetMCs();222  PassInstrumentationCallbacks PIC;223  PassInstrumentation PI(&PIC);224 225  LLVMContext C;226 227  const char *MIR =228      R"(229--- |230  ; ModuleID = '/tmp/test.ll'231  source_filename = "/tmp/test.ll"232  target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"233  234  define noundef range(i32 -2147483647, -2147483648) i32 @_Z3fooi(i32 noundef %x) local_unnamed_addr !dbg !4 {235  entry:236      #dbg_value(i32 %x, !10, !DIExpression(), !11)237    %add = add nsw i32 %x, 1, !dbg !12238    ret i32 0239  }240  241  !llvm.dbg.cu = !{!0}242  !llvm.module.flags = !{!2}243  !llvm.ident = !{!3}244  245  !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/")246  !1 = !DIFile(filename: "/tmp/code.cpp", directory: "/")247  !2 = !{i32 2, !"Debug Info Version", i32 3}248  !3 = !{!"clang"}249  !4 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !5, file: !5, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !9)250  !5 = !DIFile(filename: "/tmp/code.cpp", directory: "")251  !6 = !DISubroutineType(types: !7)252  !7 = !{!8, !8}253  !8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)254  !9 = !{!10}255  !10 = !DILocalVariable(name: "x", arg: 1, scope: !4, file: !5, line: 1, type: !8)256  !11 = !DILocation(line: 0, scope: !4)257  !12 = !DILocation(line: 2, column: 11, scope: !4)258 259...260---261name:            _Z3fooi262alignment:       4263exposesReturnsTwice: false264legalized:       false265regBankSelected: false266selected:        false267failedISel:      false268tracksRegLiveness: true269hasWinCFI:       false270noPhis:          false271isSSA:           true272noVRegs:         false273hasFakeUses:     false274callsEHReturn:   false275callsUnwindInit: false276hasEHContTarget: false277hasEHScopes:     false278hasEHFunclets:   false279isOutlined:      false280debugInstrRef:   false281failsVerification: false282tracksDebugUserValues: false283registers:284  - { id: 0, class: _, preferred-register: '', flags: [  ] }285  - { id: 1, class: _, preferred-register: '', flags: [  ] }286  - { id: 2, class: _, preferred-register: '', flags: [  ] }287  - { id: 3, class: _, preferred-register: '', flags: [  ] }288liveins:289  - { reg: '$w0', virtual-reg: '' }290frameInfo:291  isFrameAddressTaken: false292  isReturnAddressTaken: false293  hasStackMap:     false294  hasPatchPoint:   false295  stackSize:       0296  offsetAdjustment: 0297  maxAlignment:    1298  adjustsStack:    false299  hasCalls:        false300  stackProtector:  ''301  functionContext: ''302  maxCallFrameSize: 4294967295303  cvBytesOfCalleeSavedRegisters: 0304  hasOpaqueSPAdjustment: false305  hasVAStart:      false306  hasMustTailInVarArgFunc: false307  hasTailCall:     false308  isCalleeSavedInfoValid: false309  localFrameSize:  0310  savePoint:       []311  restorePoint:    []312fixedStack:      []313stack:           []314entry_values:    []315callSites:       []316debugValueSubstitutions: []317constants:       []318machineFunctionInfo: {}319body:             |320  bb.1.entry:321    liveins: $w0322  323    %0:_(s32) = COPY $w0324    %1:_(s32) = G_CONSTANT i32 1325    %3:_(s32) = G_CONSTANT i32 0326    DBG_VALUE %0(s32), $noreg, !10, !DIExpression(), debug-location !11327    %2:_(s32) = nsw G_ADD %0, %1, debug-location !12328    $w0 = COPY %3(s32)329    RET_ReallyLR implicit $w0330    )";331  auto TM = createTargetMachine(Triple::normalize("aarch64--"), "", "");332  if (!TM)333    return;334  MachineModuleInfo MMI(TM.get());335  std::unique_ptr<Module> M = parseMIR(*TM, MIR, MMI, &C);336  ASSERT_TRUE(M);337 338  DroppedVariableStatsMIR Stats;339  auto *MF = MMI.getMachineFunction(*M->getFunction("_Z3fooi"));340  Stats.runBeforePass("Test", MF);341 342  // This loop simulates an IR pass that drops debug information.343  for (auto &MBB : *MF) {344    for (auto &MI : MBB) {345      if (MI.isDebugValueLike()) {346        MI.eraseFromParent();347        break;348      }349    }350    break;351  }352 353  Stats.runAfterPass("Test", MF);354  ASSERT_EQ(Stats.getPassDroppedVariables(), true);355}356 357// This test ensures that if a #dbg_value is dropped after an optimization pass,358// but an instruction that has an unrelated scope as the #dbg_value still359// exists, debug information is conisdered not dropped.360TEST(DroppedVariableStatsMIR, UnrelatedScopes) {361  InitializeAllTargetInfos();362  InitializeAllTargets();363  InitializeAllTargetMCs();364  PassInstrumentationCallbacks PIC;365  PassInstrumentation PI(&PIC);366 367  LLVMContext C;368 369  const char *MIR =370      R"(371--- |372  ; ModuleID = '/tmp/test.ll'373  source_filename = "/tmp/test.ll"374  target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"375  376  define noundef range(i32 -2147483647, -2147483648) i32 @_Z3fooi(i32 noundef %x) local_unnamed_addr !dbg !4 {377  entry:378      #dbg_value(i32 %x, !10, !DIExpression(), !11)379    %add = add nsw i32 %x, 1, !dbg !12380    ret i32 0381  }382  383  !llvm.dbg.cu = !{!0}384  !llvm.module.flags = !{!2}385  !llvm.ident = !{!3}386  387  !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/")388  !1 = !DIFile(filename: "/tmp/code.cpp", directory: "/")389  !2 = !{i32 2, !"Debug Info Version", i32 3}390  !3 = !{!"clang"}391  !4 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !5, file: !5, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !9)392  !5 = !DIFile(filename: "/tmp/code.cpp", directory: "")393  !6 = !DISubroutineType(types: !7)394  !7 = !{!8, !8}395  !8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)396  !9 = !{!10}397  !10 = !DILocalVariable(name: "x", arg: 1, scope: !4, file: !5, line: 1, type: !8)398  !11 = !DILocation(line: 0, scope: !4)399  !12 = !DILocation(line: 2, column: 11, scope: !13)400  !13 = distinct !DISubprogram(name: "bar", linkageName: "_Z3bari", scope: !5, file: !5, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !9)401 402...403---404name:            _Z3fooi405alignment:       4406exposesReturnsTwice: false407legalized:       false408regBankSelected: false409selected:        false410failedISel:      false411tracksRegLiveness: true412hasWinCFI:       false413noPhis:          false414isSSA:           true415noVRegs:         false416hasFakeUses:     false417callsEHReturn:   false418callsUnwindInit: false419hasEHContTarget: false420hasEHScopes:     false421hasEHFunclets:   false422isOutlined:      false423debugInstrRef:   false424failsVerification: false425tracksDebugUserValues: false426registers:427  - { id: 0, class: _, preferred-register: '', flags: [  ] }428  - { id: 1, class: _, preferred-register: '', flags: [  ] }429  - { id: 2, class: _, preferred-register: '', flags: [  ] }430  - { id: 3, class: _, preferred-register: '', flags: [  ] }431liveins:432  - { reg: '$w0', virtual-reg: '' }433frameInfo:434  isFrameAddressTaken: false435  isReturnAddressTaken: false436  hasStackMap:     false437  hasPatchPoint:   false438  stackSize:       0439  offsetAdjustment: 0440  maxAlignment:    1441  adjustsStack:    false442  hasCalls:        false443  stackProtector:  ''444  functionContext: ''445  maxCallFrameSize: 4294967295446  cvBytesOfCalleeSavedRegisters: 0447  hasOpaqueSPAdjustment: false448  hasVAStart:      false449  hasMustTailInVarArgFunc: false450  hasTailCall:     false451  isCalleeSavedInfoValid: false452  localFrameSize:  0453  savePoint:       []454  restorePoint:    []455fixedStack:      []456stack:           []457entry_values:    []458callSites:       []459debugValueSubstitutions: []460constants:       []461machineFunctionInfo: {}462body:             |463  bb.1.entry:464    liveins: $w0465  466    %0:_(s32) = COPY $w0467    %1:_(s32) = G_CONSTANT i32 1468    %3:_(s32) = G_CONSTANT i32 0469    DBG_VALUE %0(s32), $noreg, !10, !DIExpression(), debug-location !11470    %2:_(s32) = nsw G_ADD %0, %1, debug-location !12471    $w0 = COPY %3(s32)472    RET_ReallyLR implicit $w0473    )";474  auto TM = createTargetMachine(Triple::normalize("aarch64--"), "", "");475  if (!TM)476    return;477  MachineModuleInfo MMI(TM.get());478  std::unique_ptr<Module> M = parseMIR(*TM, MIR, MMI, &C);479  ASSERT_TRUE(M);480 481  DroppedVariableStatsMIR Stats;482  auto *MF = MMI.getMachineFunction(*M->getFunction("_Z3fooi"));483  Stats.runBeforePass("Test", MF);484 485  // This loop simulates an IR pass that drops debug information.486  for (auto &MBB : *MF) {487    for (auto &MI : MBB) {488      if (MI.isDebugValueLike()) {489        MI.eraseFromParent();490        break;491      }492    }493    break;494  }495 496  Stats.runAfterPass("Test", MF);497  ASSERT_EQ(Stats.getPassDroppedVariables(), false);498}499 500// This test ensures that if a #dbg_value is dropped after an optimization pass,501// but an instruction that has a scope which is a child of the #dbg_value scope502// still exists, debug information is conisdered dropped.503TEST(DroppedVariableStatsMIR, ChildScopes) {504  InitializeAllTargetInfos();505  InitializeAllTargets();506  InitializeAllTargetMCs();507  PassInstrumentationCallbacks PIC;508  PassInstrumentation PI(&PIC);509 510  LLVMContext C;511 512  const char *MIR =513      R"(514--- |515  ; ModuleID = '/tmp/test.ll'516  source_filename = "/tmp/test.ll"517  target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"518  519  define noundef range(i32 -2147483647, -2147483648) i32 @_Z3fooi(i32 noundef %x) local_unnamed_addr !dbg !4 {520  entry:521      #dbg_value(i32 %x, !10, !DIExpression(), !11)522    %add = add nsw i32 %x, 1, !dbg !12523    ret i32 0524  }525  526  !llvm.dbg.cu = !{!0}527  !llvm.module.flags = !{!2}528  !llvm.ident = !{!3}529  530  !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/")531  !1 = !DIFile(filename: "/tmp/code.cpp", directory: "/")532  !2 = !{i32 2, !"Debug Info Version", i32 3}533  !3 = !{!"clang"}534  !4 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !5, file: !5, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !9)535  !5 = !DIFile(filename: "/tmp/code.cpp", directory: "")536  !6 = !DISubroutineType(types: !7)537  !7 = !{!8, !8}538  !8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)539  !9 = !{!10}540  !10 = !DILocalVariable(name: "x", arg: 1, scope: !4, file: !5, line: 1, type: !8)541  !11 = !DILocation(line: 0, scope: !4)542  !12 = !DILocation(line: 2, column: 11, scope: !13)543  !13 = distinct !DILexicalBlock(scope: !4, file: !5, line: 10, column: 28)544 545...546---547name:            _Z3fooi548alignment:       4549exposesReturnsTwice: false550legalized:       false551regBankSelected: false552selected:        false553failedISel:      false554tracksRegLiveness: true555hasWinCFI:       false556noPhis:          false557isSSA:           true558noVRegs:         false559hasFakeUses:     false560callsEHReturn:   false561callsUnwindInit: false562hasEHContTarget: false563hasEHScopes:     false564hasEHFunclets:   false565isOutlined:      false566debugInstrRef:   false567failsVerification: false568tracksDebugUserValues: false569registers:570  - { id: 0, class: _, preferred-register: '', flags: [  ] }571  - { id: 1, class: _, preferred-register: '', flags: [  ] }572  - { id: 2, class: _, preferred-register: '', flags: [  ] }573  - { id: 3, class: _, preferred-register: '', flags: [  ] }574liveins:575  - { reg: '$w0', virtual-reg: '' }576frameInfo:577  isFrameAddressTaken: false578  isReturnAddressTaken: false579  hasStackMap:     false580  hasPatchPoint:   false581  stackSize:       0582  offsetAdjustment: 0583  maxAlignment:    1584  adjustsStack:    false585  hasCalls:        false586  stackProtector:  ''587  functionContext: ''588  maxCallFrameSize: 4294967295589  cvBytesOfCalleeSavedRegisters: 0590  hasOpaqueSPAdjustment: false591  hasVAStart:      false592  hasMustTailInVarArgFunc: false593  hasTailCall:     false594  isCalleeSavedInfoValid: false595  localFrameSize:  0596  savePoint:       []597  restorePoint:    []598fixedStack:      []599stack:           []600entry_values:    []601callSites:       []602debugValueSubstitutions: []603constants:       []604machineFunctionInfo: {}605body:             |606  bb.1.entry:607    liveins: $w0608  609    %0:_(s32) = COPY $w0610    %1:_(s32) = G_CONSTANT i32 1611    %3:_(s32) = G_CONSTANT i32 0612    DBG_VALUE %0(s32), $noreg, !10, !DIExpression(), debug-location !11613    %2:_(s32) = nsw G_ADD %0, %1, debug-location !12614    $w0 = COPY %3(s32)615    RET_ReallyLR implicit $w0616    )";617  auto TM = createTargetMachine(Triple::normalize("aarch64--"), "", "");618  if (!TM)619    return;620  MachineModuleInfo MMI(TM.get());621  std::unique_ptr<Module> M = parseMIR(*TM, MIR, MMI, &C);622  ASSERT_TRUE(M);623 624  DroppedVariableStatsMIR Stats;625  auto *MF = MMI.getMachineFunction(*M->getFunction("_Z3fooi"));626  Stats.runBeforePass("Test", MF);627 628  // This loop simulates an IR pass that drops debug information.629  for (auto &MBB : *MF) {630    for (auto &MI : MBB) {631      if (MI.isDebugValueLike()) {632        MI.eraseFromParent();633        break;634      }635    }636    break;637  }638 639  Stats.runAfterPass("Test", MF);640  ASSERT_EQ(Stats.getPassDroppedVariables(), true);641}642 643// This test ensures that if a DBG_VALUE is dropped after an optimization pass,644// but an instruction that has a scope which is a child of the DBG_VALUE scope645// still exists, and the DBG_VALUE is inlined at another location, debug646// information is conisdered not dropped.647TEST(DroppedVariableStatsMIR, InlinedAt) {648  InitializeAllTargetInfos();649  InitializeAllTargets();650  InitializeAllTargetMCs();651  PassInstrumentationCallbacks PIC;652  PassInstrumentation PI(&PIC);653 654  LLVMContext C;655 656  const char *MIR =657      R"(658--- |659  ; ModuleID = '/tmp/test.ll'660  source_filename = "/tmp/test.ll"661  target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"662  663  define noundef range(i32 -2147483647, -2147483648) i32 @_Z3fooi(i32 noundef %x) local_unnamed_addr !dbg !4 {664  entry:665      #dbg_value(i32 %x, !10, !DIExpression(), !11)666    %add = add nsw i32 %x, 1, !dbg !12667    ret i32 0668  }669  670  !llvm.dbg.cu = !{!0}671  !llvm.module.flags = !{!2}672  !llvm.ident = !{!3}673  674  !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/")675  !1 = !DIFile(filename: "/tmp/code.cpp", directory: "/")676  !2 = !{i32 2, !"Debug Info Version", i32 3}677  !3 = !{!"clang"}678  !4 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !5, file: !5, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !9)679  !5 = !DIFile(filename: "/tmp/code.cpp", directory: "")680  !6 = !DISubroutineType(types: !7)681  !7 = !{!8, !8}682  !8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)683  !9 = !{!10}684  !10 = !DILocalVariable(name: "x", arg: 1, scope: !4, file: !5, line: 1, type: !8)685  !11 = !DILocation(line: 0, scope: !4, inlinedAt: !14)686  !12 = !DILocation(line: 2, column: 11, scope: !13)687  !13 = distinct !DILexicalBlock(scope: !4, file: !5, line: 10, column: 28)688  !14 = !DILocation(line: 3, column: 2, scope: !4)689 690...691---692name:            _Z3fooi693alignment:       4694exposesReturnsTwice: false695legalized:       false696regBankSelected: false697selected:        false698failedISel:      false699tracksRegLiveness: true700hasWinCFI:       false701noPhis:          false702isSSA:           true703noVRegs:         false704hasFakeUses:     false705callsEHReturn:   false706callsUnwindInit: false707hasEHContTarget: false708hasEHScopes:     false709hasEHFunclets:   false710isOutlined:      false711debugInstrRef:   false712failsVerification: false713tracksDebugUserValues: false714registers:715  - { id: 0, class: _, preferred-register: '', flags: [  ] }716  - { id: 1, class: _, preferred-register: '', flags: [  ] }717  - { id: 2, class: _, preferred-register: '', flags: [  ] }718  - { id: 3, class: _, preferred-register: '', flags: [  ] }719liveins:720  - { reg: '$w0', virtual-reg: '' }721frameInfo:722  isFrameAddressTaken: false723  isReturnAddressTaken: false724  hasStackMap:     false725  hasPatchPoint:   false726  stackSize:       0727  offsetAdjustment: 0728  maxAlignment:    1729  adjustsStack:    false730  hasCalls:        false731  stackProtector:  ''732  functionContext: ''733  maxCallFrameSize: 4294967295734  cvBytesOfCalleeSavedRegisters: 0735  hasOpaqueSPAdjustment: false736  hasVAStart:      false737  hasMustTailInVarArgFunc: false738  hasTailCall:     false739  isCalleeSavedInfoValid: false740  localFrameSize:  0741  savePoint:       []742  restorePoint:    []743fixedStack:      []744stack:           []745entry_values:    []746callSites:       []747debugValueSubstitutions: []748constants:       []749machineFunctionInfo: {}750body:             |751  bb.1.entry:752    liveins: $w0753  754    %0:_(s32) = COPY $w0755    %1:_(s32) = G_CONSTANT i32 1756    %3:_(s32) = G_CONSTANT i32 0757    DBG_VALUE %0(s32), $noreg, !10, !DIExpression(), debug-location !11758    %2:_(s32) = nsw G_ADD %0, %1, debug-location !12759    $w0 = COPY %3(s32)760    RET_ReallyLR implicit $w0761    )";762  auto TM = createTargetMachine(Triple::normalize("aarch64--"), "", "");763  if (!TM)764    return;765  MachineModuleInfo MMI(TM.get());766  std::unique_ptr<Module> M = parseMIR(*TM, MIR, MMI, &C);767  ASSERT_TRUE(M);768 769  DroppedVariableStatsMIR Stats;770  auto *MF = MMI.getMachineFunction(*M->getFunction("_Z3fooi"));771  Stats.runBeforePass("Test", MF);772 773  // This loop simulates an IR pass that drops debug information.774  for (auto &MBB : *MF) {775    for (auto &MI : MBB) {776      if (MI.isDebugValueLike()) {777        MI.eraseFromParent();778        break;779      }780    }781    break;782  }783 784  Stats.runAfterPass("Test", MF);785  ASSERT_EQ(Stats.getPassDroppedVariables(), false);786}787 788// This test ensures that if a DBG_VALUE is dropped after an optimization pass,789// but an instruction that has a scope which is a child of the DBG_VALUE scope790// still exists, and the DBG_VALUE and the instruction are inlined at another791// location, debug information is conisdered dropped.792TEST(DroppedVariableStatsMIR, InlinedAtShared) {793  InitializeAllTargetInfos();794  InitializeAllTargets();795  InitializeAllTargetMCs();796  PassInstrumentationCallbacks PIC;797  PassInstrumentation PI(&PIC);798 799  LLVMContext C;800 801  const char *MIR =802      R"(803--- |804  ; ModuleID = '/tmp/test.ll'805  source_filename = "/tmp/test.ll"806  target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"807  808  define noundef range(i32 -2147483647, -2147483648) i32 @_Z3fooi(i32 noundef %x) local_unnamed_addr !dbg !4 {809  entry:810      #dbg_value(i32 %x, !10, !DIExpression(), !11)811    %add = add nsw i32 %x, 1, !dbg !12812    ret i32 0813  }814  815  !llvm.dbg.cu = !{!0}816  !llvm.module.flags = !{!2}817  !llvm.ident = !{!3}818  819  !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/")820  !1 = !DIFile(filename: "/tmp/code.cpp", directory: "/")821  !2 = !{i32 2, !"Debug Info Version", i32 3}822  !3 = !{!"clang"}823  !4 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !5, file: !5, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !9)824  !5 = !DIFile(filename: "/tmp/code.cpp", directory: "")825  !6 = !DISubroutineType(types: !7)826  !7 = !{!8, !8}827  !8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)828  !9 = !{!10}829  !10 = !DILocalVariable(name: "x", arg: 1, scope: !4, file: !5, line: 1, type: !8)830  !11 = !DILocation(line: 0, scope: !4, inlinedAt: !14)831  !12 = !DILocation(line: 2, column: 11, scope: !13, inlinedAt: !14)832  !13 = distinct !DILexicalBlock(scope: !4, file: !5, line: 10, column: 28)833  !14 = !DILocation(line: 3, column: 2, scope: !4)834 835...836---837name:            _Z3fooi838alignment:       4839exposesReturnsTwice: false840legalized:       false841regBankSelected: false842selected:        false843failedISel:      false844tracksRegLiveness: true845hasWinCFI:       false846noPhis:          false847isSSA:           true848noVRegs:         false849hasFakeUses:     false850callsEHReturn:   false851callsUnwindInit: false852hasEHContTarget: false853hasEHScopes:     false854hasEHFunclets:   false855isOutlined:      false856debugInstrRef:   false857failsVerification: false858tracksDebugUserValues: false859registers:860  - { id: 0, class: _, preferred-register: '', flags: [  ] }861  - { id: 1, class: _, preferred-register: '', flags: [  ] }862  - { id: 2, class: _, preferred-register: '', flags: [  ] }863  - { id: 3, class: _, preferred-register: '', flags: [  ] }864liveins:865  - { reg: '$w0', virtual-reg: '' }866frameInfo:867  isFrameAddressTaken: false868  isReturnAddressTaken: false869  hasStackMap:     false870  hasPatchPoint:   false871  stackSize:       0872  offsetAdjustment: 0873  maxAlignment:    1874  adjustsStack:    false875  hasCalls:        false876  stackProtector:  ''877  functionContext: ''878  maxCallFrameSize: 4294967295879  cvBytesOfCalleeSavedRegisters: 0880  hasOpaqueSPAdjustment: false881  hasVAStart:      false882  hasMustTailInVarArgFunc: false883  hasTailCall:     false884  isCalleeSavedInfoValid: false885  localFrameSize:  0886  savePoint:       []887  restorePoint:    []888fixedStack:      []889stack:           []890entry_values:    []891callSites:       []892debugValueSubstitutions: []893constants:       []894machineFunctionInfo: {}895body:             |896  bb.1.entry:897    liveins: $w0898  899    %0:_(s32) = COPY $w0900    %1:_(s32) = G_CONSTANT i32 1901    %3:_(s32) = G_CONSTANT i32 0902    DBG_VALUE %0(s32), $noreg, !10, !DIExpression(), debug-location !11903    %2:_(s32) = nsw G_ADD %0, %1, debug-location !12904    $w0 = COPY %3(s32)905    RET_ReallyLR implicit $w0906    )";907  auto TM = createTargetMachine(Triple::normalize("aarch64--"), "", "");908  if (!TM)909    return;910  MachineModuleInfo MMI(TM.get());911  std::unique_ptr<Module> M = parseMIR(*TM, MIR, MMI, &C);912  ASSERT_TRUE(M);913 914  DroppedVariableStatsMIR Stats;915  auto *MF = MMI.getMachineFunction(*M->getFunction("_Z3fooi"));916  Stats.runBeforePass("Test", MF);917 918  // This loop simulates an IR pass that drops debug information.919  for (auto &MBB : *MF) {920    for (auto &MI : MBB) {921      if (MI.isDebugValueLike()) {922        MI.eraseFromParent();923        break;924      }925    }926    break;927  }928 929  Stats.runAfterPass("Test", MF);930  ASSERT_EQ(Stats.getPassDroppedVariables(), true);931}932 933// This test ensures that if a DBG_VALUE is dropped after an optimization pass,934// but an instruction that has a scope which is a child of the DBG_VALUE scope935// still exists, and the instruction is inlined at a location that is the936// DBG_VALUE's inlined at location, debug information is conisdered dropped.937TEST(DroppedVariableStatsMIR, InlinedAtChild) {938  InitializeAllTargetInfos();939  InitializeAllTargets();940  InitializeAllTargetMCs();941  PassInstrumentationCallbacks PIC;942  PassInstrumentation PI(&PIC);943 944  LLVMContext C;945 946  const char *MIR =947      R"(948--- |949  ; ModuleID = '/tmp/test.ll'950  source_filename = "/tmp/test.ll"951  target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"952  953  define noundef range(i32 -2147483647, -2147483648) i32 @_Z3fooi(i32 noundef %x) local_unnamed_addr !dbg !4 {954  entry:955      #dbg_value(i32 %x, !10, !DIExpression(), !11)956    %add = add nsw i32 %x, 1, !dbg !12957    ret i32 0958  }959  960  !llvm.dbg.cu = !{!0}961  !llvm.module.flags = !{!2}962  !llvm.ident = !{!3}963  964  !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/")965  !1 = !DIFile(filename: "/tmp/code.cpp", directory: "/")966  !2 = !{i32 2, !"Debug Info Version", i32 3}967  !3 = !{!"clang"}968  !4 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !5, file: !5, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !9)969  !5 = !DIFile(filename: "/tmp/code.cpp", directory: "")970  !6 = !DISubroutineType(types: !7)971  !7 = !{!8, !8}972  !8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)973  !9 = !{!10}974  !10 = !DILocalVariable(name: "x", arg: 1, scope: !4, file: !5, line: 1, type: !8)975  !11 = !DILocation(line: 0, scope: !4, inlinedAt: !14)976  !12 = !DILocation(line: 2, column: 11, scope: !13, inlinedAt: !15)977  !13 = distinct !DILexicalBlock(scope: !4, file: !5, line: 10, column: 28)978  !14 = !DILocation(line: 3, column: 2, scope: !4)979  !15 = !DILocation(line: 4, column: 5, scope: !13, inlinedAt: !14)980 981...982---983name:            _Z3fooi984alignment:       4985exposesReturnsTwice: false986legalized:       false987regBankSelected: false988selected:        false989failedISel:      false990tracksRegLiveness: true991hasWinCFI:       false992noPhis:          false993isSSA:           true994noVRegs:         false995hasFakeUses:     false996callsEHReturn:   false997callsUnwindInit: false998hasEHContTarget: false999hasEHScopes:     false1000hasEHFunclets:   false1001isOutlined:      false1002debugInstrRef:   false1003failsVerification: false1004tracksDebugUserValues: false1005registers:1006  - { id: 0, class: _, preferred-register: '', flags: [  ] }1007  - { id: 1, class: _, preferred-register: '', flags: [  ] }1008  - { id: 2, class: _, preferred-register: '', flags: [  ] }1009  - { id: 3, class: _, preferred-register: '', flags: [  ] }1010liveins:1011  - { reg: '$w0', virtual-reg: '' }1012frameInfo:1013  isFrameAddressTaken: false1014  isReturnAddressTaken: false1015  hasStackMap:     false1016  hasPatchPoint:   false1017  stackSize:       01018  offsetAdjustment: 01019  maxAlignment:    11020  adjustsStack:    false1021  hasCalls:        false1022  stackProtector:  ''1023  functionContext: ''1024  maxCallFrameSize: 42949672951025  cvBytesOfCalleeSavedRegisters: 01026  hasOpaqueSPAdjustment: false1027  hasVAStart:      false1028  hasMustTailInVarArgFunc: false1029  hasTailCall:     false1030  isCalleeSavedInfoValid: false1031  localFrameSize:  01032  savePoint:       []1033  restorePoint:    []1034fixedStack:      []1035stack:           []1036entry_values:    []1037callSites:       []1038debugValueSubstitutions: []1039constants:       []1040machineFunctionInfo: {}1041body:             |1042  bb.1.entry:1043    liveins: $w01044  1045    %0:_(s32) = COPY $w01046    %1:_(s32) = G_CONSTANT i32 11047    %3:_(s32) = G_CONSTANT i32 01048    DBG_VALUE %0(s32), $noreg, !10, !DIExpression(), debug-location !111049    %2:_(s32) = nsw G_ADD %0, %1, debug-location !121050    $w0 = COPY %3(s32)1051    RET_ReallyLR implicit $w01052    )";1053  auto TM = createTargetMachine(Triple::normalize("aarch64--"), "", "");1054  if (!TM)1055    return;1056  MachineModuleInfo MMI(TM.get());1057  std::unique_ptr<Module> M = parseMIR(*TM, MIR, MMI, &C);1058  ASSERT_TRUE(M);1059 1060  DroppedVariableStatsMIR Stats;1061  auto *MF = MMI.getMachineFunction(*M->getFunction("_Z3fooi"));1062  Stats.runBeforePass("Test", MF);1063 1064  // This loop simulates an IR pass that drops debug information.1065  for (auto &MBB : *MF) {1066    for (auto &MI : MBB) {1067      if (MI.isDebugValueLike()) {1068        MI.eraseFromParent();1069        break;1070      }1071    }1072    break;1073  }1074 1075  Stats.runAfterPass("Test", MF);1076  ASSERT_EQ(Stats.getPassDroppedVariables(), true);1077}1078 1079} // end anonymous namespace1080