From 51ae50fd0898123e3f3efe2c10239a220fd4613c Mon Sep 17 00:00:00 2001 From: Ivan Krasin Date: Fri, 5 Aug 2016 19:45:16 +0000 Subject: [PATCH] WholeProgramDevirt: print remarks with devirtualized method names. Summary: Chrome on Linux uses WholeProgramDevirt for speed ups, and it's important to detect regressions on both sides: the toolchain, if fewer methods get devirtualized after an update, and Chrome, if an innocently looking change caused many hot methods become virtual again. The need to track devirtualized methods is not Chrome-specific, but it's probably the only user of the pass at this time. Reviewers: kcc Differential Revision: https://reviews.llvm.org/D23219 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@277856 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/IPO/WholeProgramDevirt.cpp | 20 ++++++++++++++++++-- .../WholeProgramDevirt/devirt-single-impl.ll | 6 +++++- .../WholeProgramDevirt/virtual-const-prop-check.ll | 12 ++++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/lib/Transforms/IPO/WholeProgramDevirt.cpp b/lib/Transforms/IPO/WholeProgramDevirt.cpp index 53eb4e2c907..b14bfa36f41 100644 --- a/lib/Transforms/IPO/WholeProgramDevirt.cpp +++ b/lib/Transforms/IPO/WholeProgramDevirt.cpp @@ -35,6 +35,7 @@ #include "llvm/IR/CallSite.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Instructions.h" @@ -610,6 +611,16 @@ bool DevirtModule::tryVirtualConstProp( return true; } +static void emitTargetsRemarks(const std::vector &TargetsForSlot) { + for (const VirtualCallTarget &Target : TargetsForSlot) { + Function *F = Target.Fn; + DISubprogram *SP = F->getSubprogram(); + DebugLoc DL = SP ? DebugLoc::get(SP->getScopeLine(), 0, SP) : DebugLoc(); + emitOptimizationRemark(F->getContext(), DEBUG_TYPE, *F, DL, + std::string("devirtualized ") + F->getName().str()); + } +} + void DevirtModule::rebuildGlobal(VTableBits &B) { if (B.Before.Bytes.empty() && B.After.Bytes.empty()) return; @@ -815,10 +826,15 @@ bool DevirtModule::run() { S.first.ByteOffset)) continue; - if (trySingleImplDevirt(TargetsForSlot, S.second)) + if (trySingleImplDevirt(TargetsForSlot, S.second)) { + emitTargetsRemarks(TargetsForSlot); continue; + } - DidVirtualConstProp |= tryVirtualConstProp(TargetsForSlot, S.second); + if (tryVirtualConstProp(TargetsForSlot, S.second)) { + emitTargetsRemarks(TargetsForSlot); + DidVirtualConstProp = true; + } } // If we were able to eliminate all unsafe uses for a type checked load, diff --git a/test/Transforms/WholeProgramDevirt/devirt-single-impl.ll b/test/Transforms/WholeProgramDevirt/devirt-single-impl.ll index 7d665f534a5..ea5247ab636 100644 --- a/test/Transforms/WholeProgramDevirt/devirt-single-impl.ll +++ b/test/Transforms/WholeProgramDevirt/devirt-single-impl.ll @@ -1,8 +1,12 @@ -; RUN: opt -S -wholeprogramdevirt %s | FileCheck %s +; RUN: opt -S -wholeprogramdevirt -pass-remarks=wholeprogramdevirt %s 2>&1 | FileCheck %s target datalayout = "e-p:64:64" target triple = "x86_64-unknown-linux-gnu" +; CHECK: remark: :0:0: devirtualized call +; CHECK: remark: :0:0: devirtualized vf +; CHECK: remark: :0:0: devirtualized vf + @vt1 = constant [1 x i8*] [i8* bitcast (void (i8*)* @vf to i8*)], !type !0 @vt2 = constant [1 x i8*] [i8* bitcast (void (i8*)* @vf to i8*)], !type !0 diff --git a/test/Transforms/WholeProgramDevirt/virtual-const-prop-check.ll b/test/Transforms/WholeProgramDevirt/virtual-const-prop-check.ll index d2eff163a84..66db3576cb4 100644 --- a/test/Transforms/WholeProgramDevirt/virtual-const-prop-check.ll +++ b/test/Transforms/WholeProgramDevirt/virtual-const-prop-check.ll @@ -4,8 +4,20 @@ target datalayout = "e-p:64:64" target triple = "x86_64-unknown-linux-gnu" ; CHECK: remark: :0:0: devirtualized call +; CHECK: remark: :0:0: devirtualized vf1i32 +; CHECK: remark: :0:0: devirtualized vf2i32 +; CHECK: remark: :0:0: devirtualized vf3i32 +; CHECK: remark: :0:0: devirtualized vf4i32 ; CHECK: remark: :0:0: devirtualized call +; CHECK: remark: :0:0: devirtualized vf1i1 +; CHECK: remark: :0:0: devirtualized vf0i1 +; CHECK: remark: :0:0: devirtualized vf1i1 +; CHECK: remark: :0:0: devirtualized vf0i1 ; CHECK: remark: :0:0: devirtualized call +; CHECK: remark: :0:0: devirtualized vf0i1 +; CHECK: remark: :0:0: devirtualized vf1i1 +; CHECK: remark: :0:0: devirtualized vf0i1 +; CHECK: remark: :0:0: devirtualized vf1i1 ; CHECK-NOT: devirtualized call ; CHECK: [[VT1DATA:@[^ ]*]] = private constant { [8 x i8], [3 x i8*], [0 x i8] } { [8 x i8] c"\00\00\00\01\01\00\00\00", [3 x i8*] [i8* bitcast (i1 (i8*)* @vf0i1 to i8*), i8* bitcast (i1 (i8*)* @vf1i1 to i8*), i8* bitcast (i32 (i8*)* @vf1i32 to i8*)], [0 x i8] zeroinitializer }, section "vt1sec", !type [[T8:![0-9]+]] -- 2.11.0