
Debugging the dropped variable statistics for large LLVM IR files can be made easier if the functions called before an optimization pass is run includes the PassID of the pass that will be run after statistics metrics are collected. This patch adds that support.
432 lines
18 KiB
C++
432 lines
18 KiB
C++
//===- unittests/IR/DroppedVariableStatsIRTest.cpp ------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/AsmParser/Parser.h"
|
|
#include "llvm/IR/Function.h"
|
|
#include "llvm/IR/InstIterator.h"
|
|
#include "llvm/IR/LegacyPassManager.h"
|
|
#include "llvm/IR/Module.h"
|
|
#include "llvm/Pass.h"
|
|
#include "llvm/PassRegistry.h"
|
|
#include "llvm/Passes/StandardInstrumentations.h"
|
|
#include "llvm/Support/SourceMgr.h"
|
|
#include "gtest/gtest.h"
|
|
#include <gtest/gtest.h>
|
|
#include <llvm/ADT/SmallString.h>
|
|
#include <llvm/IR/LLVMContext.h>
|
|
#include <llvm/IR/Module.h>
|
|
#include <llvm/IR/PassInstrumentation.h>
|
|
#include <llvm/IR/PassManager.h>
|
|
#include <llvm/IR/PassTimingInfo.h>
|
|
#include <llvm/Support/raw_ostream.h>
|
|
|
|
using namespace llvm;
|
|
namespace llvm {
|
|
void initializePassTest1Pass(PassRegistry &);
|
|
|
|
static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
|
|
SMDiagnostic Err;
|
|
std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);
|
|
if (!Mod)
|
|
Err.print("AbstractCallSiteTests", errs());
|
|
return Mod;
|
|
}
|
|
} // namespace llvm
|
|
|
|
namespace {
|
|
|
|
// This test ensures that if a #dbg_value and an instruction that exists in the
|
|
// same scope as that #dbg_value are both deleted as a result of an optimization
|
|
// pass, debug information is considered not dropped.
|
|
TEST(DroppedVariableStatsIR, BothDeleted) {
|
|
PassInstrumentationCallbacks PIC;
|
|
PassInstrumentation PI(&PIC);
|
|
|
|
LLVMContext C;
|
|
|
|
const char *IR =
|
|
R"(
|
|
; Function Attrs: mustprogress nounwind ssp uwtable(sync)
|
|
define noundef range(i32 -2147483647, -2147483648) i32 @_Z3fooi(i32 noundef %x) local_unnamed_addr #0 !dbg !9 {
|
|
entry:
|
|
#dbg_value(i32 %x, !15, !DIExpression(), !16)
|
|
%add = add nsw i32 %x, 1, !dbg !17
|
|
ret i32 0
|
|
}
|
|
!llvm.dbg.cu = !{!0}
|
|
!llvm.module.flags = !{!3}
|
|
!llvm.ident = !{!8}
|
|
!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: "/")
|
|
!1 = !DIFile(filename: "/tmp/code.cpp", directory: "/")
|
|
!3 = !{i32 2, !"Debug Info Version", i32 3}
|
|
!8 = !{!"clang"}
|
|
!9 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !10, file: !10, line: 1, type: !11, scopeLine: 1, unit: !0, retainedNodes: !14)
|
|
!10 = !DIFile(filename: "/tmp/code.cpp", directory: "")
|
|
!11 = !DISubroutineType(types: !12)
|
|
!12 = !{!13, !13}
|
|
!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
|
!14 = !{!15}
|
|
!15 = !DILocalVariable(name: "x", arg: 1, scope: !9, file: !10, line: 1, type: !13)
|
|
!16 = !DILocation(line: 0, scope: !9)
|
|
!17 = !DILocation(line: 2, column: 11, scope: !9))";
|
|
|
|
std::unique_ptr<llvm::Module> M = parseIR(C, IR);
|
|
ASSERT_TRUE(M);
|
|
|
|
DroppedVariableStatsIR Stats(true);
|
|
Stats.runBeforePass("", llvm::Any(const_cast<const llvm::Module *>(M.get())));
|
|
|
|
// This loop simulates an IR pass that drops debug information.
|
|
for (auto &F : *M) {
|
|
for (auto &I : instructions(&F)) {
|
|
I.dropDbgRecords();
|
|
I.eraseFromParent();
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
Stats.runAfterPass("Test",
|
|
llvm::Any(const_cast<const llvm::Module *>(M.get())));
|
|
ASSERT_EQ(Stats.getPassDroppedVariables(), false);
|
|
}
|
|
|
|
// This test ensures that if a #dbg_value is dropped after an optimization pass,
|
|
// but an instruction that shares the same scope as the #dbg_value still exists,
|
|
// debug information is conisdered dropped.
|
|
TEST(DroppedVariableStatsIR, DbgValLost) {
|
|
PassInstrumentationCallbacks PIC;
|
|
PassInstrumentation PI(&PIC);
|
|
|
|
LLVMContext C;
|
|
|
|
const char *IR =
|
|
R"(
|
|
; Function Attrs: mustprogress nounwind ssp uwtable(sync)
|
|
define noundef range(i32 -2147483647, -2147483648) i32 @_Z3fooi(i32 noundef %x) local_unnamed_addr #0 !dbg !9 {
|
|
entry:
|
|
#dbg_value(i32 %x, !15, !DIExpression(), !16)
|
|
%add = add nsw i32 %x, 1, !dbg !17
|
|
ret i32 0
|
|
}
|
|
!llvm.dbg.cu = !{!0}
|
|
!llvm.module.flags = !{!3}
|
|
!llvm.ident = !{!8}
|
|
!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: "/")
|
|
!1 = !DIFile(filename: "/tmp/code.cpp", directory: "/")
|
|
!3 = !{i32 2, !"Debug Info Version", i32 3}
|
|
!8 = !{!"clang"}
|
|
!9 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !10, file: !10, line: 1, type: !11, scopeLine: 1, unit: !0, retainedNodes: !14)
|
|
!10 = !DIFile(filename: "/tmp/code.cpp", directory: "")
|
|
!11 = !DISubroutineType(types: !12)
|
|
!12 = !{!13, !13}
|
|
!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
|
!14 = !{!15}
|
|
!15 = !DILocalVariable(name: "x", arg: 1, scope: !9, file: !10, line: 1, type: !13)
|
|
!16 = !DILocation(line: 0, scope: !9)
|
|
!17 = !DILocation(line: 2, column: 11, scope: !9))";
|
|
|
|
std::unique_ptr<llvm::Module> M = parseIR(C, IR);
|
|
ASSERT_TRUE(M);
|
|
|
|
DroppedVariableStatsIR Stats(true);
|
|
Stats.runBeforePass("", llvm::Any(const_cast<const llvm::Module *>(M.get())));
|
|
|
|
// This loop simulates an IR pass that drops debug information.
|
|
for (auto &F : *M) {
|
|
for (auto &I : instructions(&F)) {
|
|
I.dropDbgRecords();
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
Stats.runAfterPass("Test",
|
|
llvm::Any(const_cast<const llvm::Module *>(M.get())));
|
|
ASSERT_EQ(Stats.getPassDroppedVariables(), true);
|
|
}
|
|
|
|
// This test ensures that if a #dbg_value is dropped after an optimization pass,
|
|
// but an instruction that has an unrelated scope as the #dbg_value still
|
|
// exists, debug information is conisdered not dropped.
|
|
TEST(DroppedVariableStatsIR, UnrelatedScopes) {
|
|
PassInstrumentationCallbacks PIC;
|
|
PassInstrumentation PI(&PIC);
|
|
|
|
LLVMContext C;
|
|
|
|
const char *IR =
|
|
R"(
|
|
; Function Attrs: mustprogress nounwind ssp uwtable(sync)
|
|
define noundef range(i32 -2147483647, -2147483648) i32 @_Z3fooi(i32 noundef %x) local_unnamed_addr #0 !dbg !9 {
|
|
entry:
|
|
#dbg_value(i32 %x, !15, !DIExpression(), !16)
|
|
%add = add nsw i32 %x, 1, !dbg !17
|
|
ret i32 0
|
|
}
|
|
!llvm.dbg.cu = !{!0}
|
|
!llvm.module.flags = !{!3}
|
|
!llvm.ident = !{!8}
|
|
!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: "/")
|
|
!1 = !DIFile(filename: "/tmp/code.cpp", directory: "/")
|
|
!3 = !{i32 2, !"Debug Info Version", i32 3}
|
|
!8 = !{!"clang"}
|
|
!9 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !10, file: !10, line: 1, type: !11, scopeLine: 1, unit: !0, retainedNodes: !14)
|
|
!10 = !DIFile(filename: "/tmp/code.cpp", directory: "")
|
|
!11 = !DISubroutineType(types: !12)
|
|
!12 = !{!13, !13}
|
|
!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
|
!14 = !{!15}
|
|
!15 = !DILocalVariable(name: "x", arg: 1, scope: !9, file: !10, line: 1, type: !13)
|
|
!16 = !DILocation(line: 0, scope: !9)
|
|
!17 = !DILocation(line: 2, column: 11, scope: !18)
|
|
!18 = distinct !DISubprogram(name: "bar", linkageName: "_Z3bari", scope: !10, file: !10, line: 11, type: !11, scopeLine: 1, unit: !0, retainedNodes: !14))";
|
|
|
|
std::unique_ptr<llvm::Module> M = parseIR(C, IR);
|
|
ASSERT_TRUE(M);
|
|
|
|
DroppedVariableStatsIR Stats(true);
|
|
Stats.runBeforePass("", llvm::Any(const_cast<const llvm::Module *>(M.get())));
|
|
|
|
// This loop simulates an IR pass that drops debug information.
|
|
for (auto &F : *M) {
|
|
for (auto &I : instructions(&F)) {
|
|
I.dropDbgRecords();
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
Stats.runAfterPass("Test",
|
|
llvm::Any(const_cast<const llvm::Module *>(M.get())));
|
|
ASSERT_EQ(Stats.getPassDroppedVariables(), false);
|
|
}
|
|
|
|
// This test ensures that if a #dbg_value is dropped after an optimization pass,
|
|
// but an instruction that has a scope which is a child of the #dbg_value scope
|
|
// still exists, debug information is conisdered dropped.
|
|
TEST(DroppedVariableStatsIR, ChildScopes) {
|
|
PassInstrumentationCallbacks PIC;
|
|
PassInstrumentation PI(&PIC);
|
|
|
|
LLVMContext C;
|
|
|
|
const char *IR =
|
|
R"(
|
|
; Function Attrs: mustprogress nounwind ssp uwtable(sync)
|
|
define noundef range(i32 -2147483647, -2147483648) i32 @_Z3fooi(i32 noundef %x) local_unnamed_addr #0 !dbg !9 {
|
|
entry:
|
|
#dbg_value(i32 %x, !15, !DIExpression(), !16)
|
|
%add = add nsw i32 %x, 1, !dbg !17
|
|
ret i32 0
|
|
}
|
|
!llvm.dbg.cu = !{!0}
|
|
!llvm.module.flags = !{!3}
|
|
!llvm.ident = !{!8}
|
|
!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: "/")
|
|
!1 = !DIFile(filename: "/tmp/code.cpp", directory: "/")
|
|
!3 = !{i32 2, !"Debug Info Version", i32 3}
|
|
!8 = !{!"clang"}
|
|
!9 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !10, file: !10, line: 1, type: !11, scopeLine: 1, unit: !0, retainedNodes: !14)
|
|
!10 = !DIFile(filename: "/tmp/code.cpp", directory: "")
|
|
!11 = !DISubroutineType(types: !12)
|
|
!12 = !{!13, !13}
|
|
!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
|
!14 = !{!15}
|
|
!15 = !DILocalVariable(name: "x", arg: 1, scope: !9, file: !10, line: 1, type: !13)
|
|
!16 = !DILocation(line: 0, scope: !9)
|
|
!17 = !DILocation(line: 2, column: 11, scope: !18)
|
|
!18 = distinct !DILexicalBlock(scope: !9, file: !10, line: 10, column: 28))";
|
|
|
|
std::unique_ptr<llvm::Module> M = parseIR(C, IR);
|
|
ASSERT_TRUE(M);
|
|
|
|
DroppedVariableStatsIR Stats(true);
|
|
Stats.runBeforePass("", llvm::Any(const_cast<const llvm::Module *>(M.get())));
|
|
|
|
// This loop simulates an IR pass that drops debug information.
|
|
for (auto &F : *M) {
|
|
for (auto &I : instructions(&F)) {
|
|
I.dropDbgRecords();
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
Stats.runAfterPass("Test",
|
|
llvm::Any(const_cast<const llvm::Module *>(M.get())));
|
|
ASSERT_EQ(Stats.getPassDroppedVariables(), true);
|
|
}
|
|
|
|
// This test ensures that if a #dbg_value is dropped after an optimization pass,
|
|
// but an instruction that has a scope which is a child of the #dbg_value scope
|
|
// still exists, and the #dbg_value is inlined at another location, debug
|
|
// information is conisdered not dropped.
|
|
TEST(DroppedVariableStatsIR, InlinedAt) {
|
|
PassInstrumentationCallbacks PIC;
|
|
PassInstrumentation PI(&PIC);
|
|
|
|
LLVMContext C;
|
|
|
|
const char *IR =
|
|
R"(; Function Attrs: mustprogress nounwind ssp uwtable(sync)
|
|
define noundef range(i32 -2147483647, -2147483648) i32 @_Z3fooi(i32 noundef %x) local_unnamed_addr #0 !dbg !9 {
|
|
entry:
|
|
#dbg_value(i32 %x, !15, !DIExpression(), !16)
|
|
%add = add nsw i32 %x, 1, !dbg !17
|
|
ret i32 0
|
|
}
|
|
!llvm.dbg.cu = !{!0}
|
|
!llvm.module.flags = !{!3}
|
|
!llvm.ident = !{!8}
|
|
!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: "/")
|
|
!1 = !DIFile(filename: "/tmp/code.cpp", directory: "/")
|
|
!3 = !{i32 2, !"Debug Info Version", i32 3}
|
|
!8 = !{!"clang"}
|
|
!9 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !10, file: !10, line: 1, type: !11, scopeLine: 1, unit: !0, retainedNodes: !14)
|
|
!10 = !DIFile(filename: "/tmp/code.cpp", directory: "")
|
|
!11 = !DISubroutineType(types: !12)
|
|
!12 = !{!13, !13}
|
|
!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
|
!14 = !{!15}
|
|
!15 = !DILocalVariable(name: "x", arg: 1, scope: !9, file: !10, line: 1, type: !13)
|
|
!16 = !DILocation(line: 0, scope: !9, inlinedAt: !19)
|
|
!17 = !DILocation(line: 2, column: 11, scope: !18)
|
|
!18 = distinct !DILexicalBlock(scope: !9, file: !10, line: 10, column: 28)
|
|
!19 = !DILocation(line: 3, column: 2, scope: !9))";
|
|
|
|
std::unique_ptr<llvm::Module> M = parseIR(C, IR);
|
|
ASSERT_TRUE(M);
|
|
|
|
DroppedVariableStatsIR Stats(true);
|
|
Stats.runBeforePass("", llvm::Any(const_cast<const llvm::Module *>(M.get())));
|
|
|
|
// This loop simulates an IR pass that drops debug information.
|
|
for (auto &F : *M) {
|
|
for (auto &I : instructions(&F)) {
|
|
I.dropDbgRecords();
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
Stats.runAfterPass("Test",
|
|
llvm::Any(const_cast<const llvm::Module *>(M.get())));
|
|
ASSERT_EQ(Stats.getPassDroppedVariables(), false);
|
|
}
|
|
|
|
// This test ensures that if a #dbg_value is dropped after an optimization pass,
|
|
// but an instruction that has a scope which is a child of the #dbg_value scope
|
|
// still exists, and the #dbg_value and the instruction are inlined at another
|
|
// location, debug information is conisdered dropped.
|
|
TEST(DroppedVariableStatsIR, InlinedAtShared) {
|
|
PassInstrumentationCallbacks PIC;
|
|
PassInstrumentation PI(&PIC);
|
|
|
|
LLVMContext C;
|
|
|
|
const char *IR =
|
|
R"(; Function Attrs: mustprogress nounwind ssp uwtable(sync)
|
|
define noundef range(i32 -2147483647, -2147483648) i32 @_Z3fooi(i32 noundef %x) local_unnamed_addr #0 !dbg !9 {
|
|
entry:
|
|
#dbg_value(i32 %x, !15, !DIExpression(), !16)
|
|
%add = add nsw i32 %x, 1, !dbg !17
|
|
ret i32 0
|
|
}
|
|
!llvm.dbg.cu = !{!0}
|
|
!llvm.module.flags = !{!3}
|
|
!llvm.ident = !{!8}
|
|
!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: "/")
|
|
!1 = !DIFile(filename: "/tmp/code.cpp", directory: "/")
|
|
!3 = !{i32 2, !"Debug Info Version", i32 3}
|
|
!8 = !{!"clang"}
|
|
!9 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !10, file: !10, line: 1, type: !11, scopeLine: 1, unit: !0, retainedNodes: !14)
|
|
!10 = !DIFile(filename: "/tmp/code.cpp", directory: "")
|
|
!11 = !DISubroutineType(types: !12)
|
|
!12 = !{!13, !13}
|
|
!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
|
!14 = !{!15}
|
|
!15 = !DILocalVariable(name: "x", arg: 1, scope: !9, file: !10, line: 1, type: !13)
|
|
!16 = !DILocation(line: 0, scope: !9, inlinedAt: !19)
|
|
!17 = !DILocation(line: 2, column: 11, scope: !18, inlinedAt: !19)
|
|
!18 = distinct !DILexicalBlock(scope: !9, file: !10, line: 10, column: 28)
|
|
!19 = !DILocation(line: 3, column: 2, scope: !9))";
|
|
|
|
std::unique_ptr<llvm::Module> M = parseIR(C, IR);
|
|
ASSERT_TRUE(M);
|
|
|
|
DroppedVariableStatsIR Stats(true);
|
|
Stats.runBeforePass("", llvm::Any(const_cast<const llvm::Module *>(M.get())));
|
|
|
|
// This loop simulates an IR pass that drops debug information.
|
|
for (auto &F : *M) {
|
|
for (auto &I : instructions(&F)) {
|
|
I.dropDbgRecords();
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
Stats.runAfterPass("Test",
|
|
llvm::Any(const_cast<const llvm::Module *>(M.get())));
|
|
ASSERT_EQ(Stats.getPassDroppedVariables(), true);
|
|
}
|
|
|
|
// This test ensures that if a #dbg_value is dropped after an optimization pass,
|
|
// but an instruction that has a scope which is a child of the #dbg_value scope
|
|
// still exists, and the instruction is inlined at a location that is the
|
|
// #dbg_value's inlined at location, debug information is conisdered dropped.
|
|
TEST(DroppedVariableStatsIR, InlinedAtChild) {
|
|
PassInstrumentationCallbacks PIC;
|
|
PassInstrumentation PI(&PIC);
|
|
|
|
LLVMContext C;
|
|
|
|
const char *IR =
|
|
R"(; Function Attrs: mustprogress nounwind ssp uwtable(sync)
|
|
define noundef range(i32 -2147483647, -2147483648) i32 @_Z3fooi(i32 noundef %x) local_unnamed_addr #0 !dbg !9 {
|
|
entry:
|
|
#dbg_value(i32 %x, !15, !DIExpression(), !16)
|
|
%add = add nsw i32 %x, 1, !dbg !17
|
|
ret i32 0
|
|
}
|
|
!llvm.dbg.cu = !{!0}
|
|
!llvm.module.flags = !{!3}
|
|
!llvm.ident = !{!8}
|
|
!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: "/")
|
|
!1 = !DIFile(filename: "/tmp/code.cpp", directory: "/")
|
|
!3 = !{i32 2, !"Debug Info Version", i32 3}
|
|
!8 = !{!"clang"}
|
|
!9 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !10, file: !10, line: 1, type: !11, scopeLine: 1, unit: !0, retainedNodes: !14)
|
|
!10 = !DIFile(filename: "/tmp/code.cpp", directory: "")
|
|
!11 = !DISubroutineType(types: !12)
|
|
!12 = !{!13, !13}
|
|
!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
|
!14 = !{!15}
|
|
!15 = !DILocalVariable(name: "x", arg: 1, scope: !9, file: !10, line: 1, type: !13)
|
|
!16 = !DILocation(line: 0, scope: !9, inlinedAt: !19)
|
|
!17 = !DILocation(line: 2, column: 11, scope: !18, inlinedAt: !20)
|
|
!18 = distinct !DILexicalBlock(scope: !9, file: !10, line: 10, column: 28)
|
|
!19 = !DILocation(line: 3, column: 2, scope: !9);
|
|
!20 = !DILocation(line: 4, column: 5, scope: !18, inlinedAt: !19))";
|
|
|
|
std::unique_ptr<llvm::Module> M = parseIR(C, IR);
|
|
ASSERT_TRUE(M);
|
|
|
|
DroppedVariableStatsIR Stats(true);
|
|
Stats.runBeforePass("", llvm::Any(const_cast<const llvm::Module *>(M.get())));
|
|
|
|
// This loop simulates an IR pass that drops debug information.
|
|
for (auto &F : *M) {
|
|
for (auto &I : instructions(&F)) {
|
|
I.dropDbgRecords();
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
Stats.runAfterPass("Test",
|
|
llvm::Any(const_cast<const llvm::Module *>(M.get())));
|
|
ASSERT_EQ(Stats.getPassDroppedVariables(), true);
|
|
}
|
|
|
|
} // end anonymous namespace
|