diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp --- a/clang/lib/CodeGen/CodeGenAction.cpp +++ b/clang/lib/CodeGen/CodeGenAction.cpp @@ -151,6 +151,29 @@ FrontendTimesIsEnabled = TimePasses; llvm::TimePassesIsEnabled = TimePasses; } + + // This constructor is used in installing an empty BackendConsumer + // to use the clang diagnostic handler for IR input files. It avoids + // initializing the OS field. + BackendConsumer(BackendAction Action, DiagnosticsEngine &Diags, + const HeaderSearchOptions &HeaderSearchOpts, + const PreprocessorOptions &PPOpts, + const CodeGenOptions &CodeGenOpts, + const TargetOptions &TargetOpts, + const LangOptions &LangOpts, bool TimePasses, + SmallVector LinkModules, LLVMContext &C, + CoverageSourceInfo *CoverageInfo = nullptr) + : Diags(Diags), Action(Action), HeaderSearchOpts(HeaderSearchOpts), + CodeGenOpts(CodeGenOpts), TargetOpts(TargetOpts), LangOpts(LangOpts), + Context(nullptr), + LLVMIRGeneration("irgen", "LLVM IR Generation Time"), + LLVMIRGenerationRefCount(0), + Gen(CreateLLVMCodeGen(Diags, "", HeaderSearchOpts, PPOpts, + CodeGenOpts, C, CoverageInfo)), + LinkModules(std::move(LinkModules)) { + FrontendTimesIsEnabled = TimePasses; + llvm::TimePassesIsEnabled = TimePasses; + } llvm::Module *getModule() const { return Gen->GetModule(); } std::unique_ptr takeModule() { return std::unique_ptr(Gen->ReleaseModule()); @@ -616,10 +639,20 @@ StringRef Filename; unsigned Line, Column; bool BadDebugInfo = false; - FullSourceLoc Loc = - getBestLocationFromDebugLoc(D, BadDebugInfo, Filename, Line, Column); + FullSourceLoc Loc; + std::string Msg; + raw_string_ostream MsgStream(Msg); - Diags.Report(Loc, diag::err_fe_backend_unsupported) << D.getMessage().str(); + // Context will be nullptr for IR input files, we will construct the diag + // message from llvm::DiagnosticInfoUnsupported. + if (Context != nullptr) { + Loc = getBestLocationFromDebugLoc(D, BadDebugInfo, Filename, Line, Column); + MsgStream << D.getMessage(); + } else { + DiagnosticPrinterRawOStream DP(MsgStream); + D.print(DP); + } + Diags.Report(Loc, diag::err_fe_backend_unsupported) << MsgStream.str(); if (BadDebugInfo) // If we were not able to translate the file:line:col information @@ -635,10 +668,21 @@ StringRef Filename; unsigned Line, Column; bool BadDebugInfo = false; - FullSourceLoc Loc = - getBestLocationFromDebugLoc(D, BadDebugInfo, Filename, Line, Column); + FullSourceLoc Loc; + std::string Msg; + raw_string_ostream MsgStream(Msg); + DiagnosticPrinterRawOStream DP(MsgStream); - Diags.Report(Loc, diag::warn_profile_data_misexpect) << D.getMsg().str(); + // Context will be nullptr for IR input files, we will construct the diag + // message from llvm::DiagnosticInfoMisExpect. + if (Context != nullptr) { + Loc = getBestLocationFromDebugLoc(D, BadDebugInfo, Filename, Line, Column); + MsgStream << D.getMsg(); + } else { + DiagnosticPrinterRawOStream DP(MsgStream); + D.print(DP); + } + Diags.Report(Loc, diag::warn_profile_data_misexpect) << MsgStream.str(); if (BadDebugInfo) // If we were not able to translate the file:line:col information @@ -658,12 +702,19 @@ StringRef Filename; unsigned Line, Column; bool BadDebugInfo = false; - FullSourceLoc Loc = - getBestLocationFromDebugLoc(D, BadDebugInfo, Filename, Line, Column); - + FullSourceLoc Loc; std::string Msg; raw_string_ostream MsgStream(Msg); - MsgStream << D.getMsg(); + + // Context will be nullptr for IR input files, we will construct the remark + // message from llvm::DiagnosticInfoOptimizationBase. + if (Context != nullptr) { + Loc = getBestLocationFromDebugLoc(D, BadDebugInfo, Filename, Line, Column); + MsgStream << D.getMsg(); + } else { + DiagnosticPrinterRawOStream DP(MsgStream); + D.print(DP); + } if (D.getHotness()) MsgStream << " (hotness: " << *D.getHotness() << ")"; @@ -1088,12 +1139,20 @@ Ctx.setInlineAsmDiagnosticHandler(BitcodeInlineAsmDiagHandler, &Diagnostics); + // Set clang diagnostic handler. To do this we need to create a fake + // BackendConsumer. + BackendConsumer Result(BA, CI.getDiagnostics(), CI.getHeaderSearchOpts(), + CI.getPreprocessorOpts(), CI.getCodeGenOpts(), + CI.getTargetOpts(), CI.getLangOpts(), + CI.getFrontendOpts().ShowTimers, + std::move(LinkModules), *VMContext, nullptr); + Ctx.setDiagnosticHandler( + std::make_unique(CodeGenOpts, &Result)); + Expected> OptRecordFileOrErr = setupOptimizationRemarks( - Ctx, CodeGenOpts.OptRecordFile, - CodeGenOpts.OptRecordPasses, - CodeGenOpts.OptRecordFormat, - CodeGenOpts.DiagnosticsWithHotness, + Ctx, CodeGenOpts.OptRecordFile, CodeGenOpts.OptRecordPasses, + CodeGenOpts.OptRecordFormat, CodeGenOpts.DiagnosticsWithHotness, CodeGenOpts.DiagnosticsHotnessThreshold); if (Error E = OptRecordFileOrErr.takeError()) { @@ -1101,10 +1160,10 @@ return; } std::unique_ptr OptRecordFile = - std::move(*OptRecordFileOrErr); + std::move(*OptRecordFileOrErr); - EmitBackendOutput(Diagnostics, CI.getHeaderSearchOpts(), - CodeGenOpts, TargetOpts, CI.getLangOpts(), + EmitBackendOutput(Diagnostics, CI.getHeaderSearchOpts(), CodeGenOpts, + TargetOpts, CI.getLangOpts(), CI.getTarget().getDataLayout(), TheModule.get(), BA, std::move(OS)); diff --git a/clang/test/CodeGen/Inputs/thinlto_expect1.proftext b/clang/test/CodeGen/Inputs/thinlto_expect1.proftext new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/Inputs/thinlto_expect1.proftext @@ -0,0 +1,11 @@ +# IR level Instrumentation Flag +:ir +foo +# Func Hash: +25571299074 +# Num Counters: +2 +# Counter Values: +12 +24 + diff --git a/clang/test/CodeGen/Inputs/thinlto_expect2.proftext b/clang/test/CodeGen/Inputs/thinlto_expect2.proftext new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/Inputs/thinlto_expect2.proftext @@ -0,0 +1,20 @@ +# CSIR level Instrumentation Flag +:csir +foo +# Func Hash: +25571299074 +# Num Counters: +2 +# Counter Values: +12 +24 + +foo +# Func Hash: +1152921530178146050 +# Num Counters: +2 +# Counter Values: +24 +12 + diff --git a/clang/test/CodeGen/thinlto-clang-diagnostic-handler-in-be.c b/clang/test/CodeGen/thinlto-clang-diagnostic-handler-in-be.c new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/thinlto-clang-diagnostic-handler-in-be.c @@ -0,0 +1,24 @@ +// Test clang diagnositic handler works in IR file compilation. + +// REQUIRES: x86-registered-target + +// RUN: llvm-profdata merge -o %t1.profdata %S/Inputs/thinlto_expect1.proftext +// RUN: %clang -O2 -fexperimental-new-pass-manager -flto=thin -g -fprofile-use=%t1.profdata -c -o %t1.bo %s +// RUN: llvm-lto -thinlto -o %t %t1.bo +// RUN: %clang -cc1 -O2 -fexperimental-new-pass-manager -x ir %t1.bo -fthinlto-index=%t.thinlto.bc -emit-obj -Rpass-analysis=info 2>&1 | FileCheck %s -check-prefix=CHECK-REMARK +// RUN: llvm-profdata merge -o %t2.profdata %S/Inputs/thinlto_expect2.proftext +// RUN: %clang -cc1 -O2 -fexperimental-new-pass-manager -x ir %t1.bo -fthinlto-index=%t.thinlto.bc -fprofile-instrument-use-path=%t2.profdata -emit-obj -Wmisexpect 2>&1 | FileCheck %s -check-prefix=CHECK-WARNING +// RUN: %clang -cc1 -O2 -fexperimental-new-pass-manager -x ir %t1.bo -fthinlto-index=%t.thinlto.bc -fprofile-instrument-use-path=%t2.profdata -emit-obj 2>&1 | FileCheck %s -allow-empty -check-prefix=CHECK-NOWARNING + +int sum; +__attribute__((noinline)) void bar() { + sum = 1234; +} + +__attribute__((noinline)) void foo(int m) { + if (__builtin_expect(m > 9, 1)) + bar(); +} +// CHECK-REMARK: remark: {{.*}}.c: +// CHECK-WARNING: warning: Potential performance regression from use of __builtin_expect(): Annotation was correct on {{.*}}.c:{{[0-9]*}}:26: 50.00% (12 / 24) of profiled executions. +// CHECK-NOWARNING-NOT: warning: {{.*}}.c:{{[0-9]*}}:26: 50.00% (12 / 24) diff --git a/clang/test/CodeGen/thinlto-diagnostic-handler-remarks-with-hotness.ll b/clang/test/CodeGen/thinlto-diagnostic-handler-remarks-with-hotness.ll --- a/clang/test/CodeGen/thinlto-diagnostic-handler-remarks-with-hotness.ll +++ b/clang/test/CodeGen/thinlto-diagnostic-handler-remarks-with-hotness.ll @@ -28,7 +28,7 @@ ; YAML-NEXT: ... ; Next try with pass remarks to stderr -; RUN: %clang -target x86_64-scei-ps4 -O2 -x ir %t.o -fthinlto-index=%t.thinlto.bc -mllvm -pass-remarks=inline -fdiagnostics-show-hotness -o %t2.o -c 2>&1 | FileCheck %s +; RUN: %clang -target x86_64-scei-ps4 -O2 -x ir %t.o -fthinlto-index=%t.thinlto.bc -Rpass=inline -fdiagnostics-show-hotness -o %t2.o -c 2>&1 | FileCheck %s ; CHECK: tinkywinky inlined into main with (cost=0, threshold=337) (hotness: 300)