diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -5200,8 +5200,9 @@ auto Remark = [&](OptimizationRemarkMissed ORM) { return ORM << "Could not move globalized variable to the stack. " << "Variable is potentially " - << ((!NoCaptureAA.isAssumedNoCapture()) ? "captured." - : "freed."); + << (!NoCaptureAA.isAssumedNoCapture() ? "captured. " + : "freed. ") + << "Mark as noescape to override."; }; LibFunc IsAllocShared; diff --git a/llvm/lib/Transforms/IPO/OpenMPOpt.cpp b/llvm/lib/Transforms/IPO/OpenMPOpt.cpp --- a/llvm/lib/Transforms/IPO/OpenMPOpt.cpp +++ b/llvm/lib/Transforms/IPO/OpenMPOpt.cpp @@ -2634,6 +2634,8 @@ if (DisableOpenMPOptimizations) return PreservedAnalyses::all(); + FunctionAnalysisManager &FAM = + AM.getResult(M).getManager(); KernelSet Kernels = getDeviceKernels(M); auto IsCalled = [&](Function &F) { @@ -2645,14 +2647,27 @@ return false; }; + auto EmitRemark = [&](Function &F) { + auto &ORE = FAM.getResult(F); + ORE.emit([&]() { + OptimizationRemarkMissed ORM(DEBUG_TYPE, "InternalizationFailure", &F); + return ORM << "Could not internalize function. " + << "Some optimizations may not be possible."; + }); + }; + // Create internal copies of each function if this is a kernel Module. This // allows iterprocedural passes to see every call edge. DenseSet InternalizedFuncs; if (isOpenMPDevice(M)) for (Function &F : M) - if (!F.isDeclaration() && !Kernels.contains(&F) && IsCalled(F)) - if (Attributor::internalizeFunction(F, /* Force */ true)) + if (!F.isDeclaration() && !Kernels.contains(&F) && IsCalled(F)) { + if (Attributor::internalizeFunction(F, /* Force */ true)) { InternalizedFuncs.insert(&F); + } else if (!F.hasLocalLinkage()) { + EmitRemark(F); + } + } // Look at every function in the Module unless it was internalized. SmallVector SCC; @@ -2663,9 +2678,6 @@ if (SCC.empty()) return PreservedAnalyses::all(); - FunctionAnalysisManager &FAM = - AM.getResult(M).getManager(); - AnalysisGetter AG(FAM); auto OREGetter = [&FAM](Function *F) -> OptimizationRemarkEmitter & { diff --git a/llvm/test/Transforms/OpenMP/remove_globalization.ll b/llvm/test/Transforms/OpenMP/remove_globalization.ll --- a/llvm/test/Transforms/OpenMP/remove_globalization.ll +++ b/llvm/test/Transforms/OpenMP/remove_globalization.ll @@ -4,7 +4,7 @@ target datalayout = "e-i64:64-i128:128-v16:16-v32:32-n16:32:64" target triple = "nvptx64" -; CHECK-REMARKS: remark: remove_globalization.c:4:2: Could not move globalized variable to the stack. Variable is potentially captured. +; CHECK-REMARKS: remark: remove_globalization.c:4:2: Could not move globalized variable to the stack. Variable is potentially captured. Mark as noescape to override. ; CHECK-REMARKS: remark: remove_globalization.c:2:2: Moving globalized variable to the stack. ; CHECK-REMARKS: remark: remove_globalization.c:6:2: Moving globalized variable to the stack. diff --git a/llvm/test/Transforms/OpenMP/single_threaded_execution.ll b/llvm/test/Transforms/OpenMP/single_threaded_execution.ll --- a/llvm/test/Transforms/OpenMP/single_threaded_execution.ll +++ b/llvm/test/Transforms/OpenMP/single_threaded_execution.ll @@ -1,4 +1,5 @@ ; RUN: opt -passes=openmp-opt -debug-only=openmp-opt -disable-output < %s 2>&1 | FileCheck %s +; RUN: opt -passes=openmp-opt -pass-remarks-missed=openmp-opt -disable-output < %s 2>&1 | FileCheck %s --check-prefix=REMARKS ; REQUIRES: asserts ; ModuleID = 'single_threaded_exeuction.c' @@ -9,6 +10,8 @@ ret void } +; REMARKS: remark: single_threaded_execution.c:1:0: Could not internalize function. Some optimizations may not be possible. + ; CHECK-NOT: [openmp-opt] Basic block @nvptx entry is executed by a single thread. ; CHECK: [openmp-opt] Basic block @nvptx if.then is executed by a single thread. ; CHECK-NOT: [openmp-opt] Basic block @nvptx if.end is executed by a single thread. @@ -22,6 +25,7 @@ if.then: call void @foo() call void @bar() + call void @baz() br label %if.end if.end: @@ -41,6 +45,7 @@ if.then: call void @foo() call void @bar() + call void @baz() br label %if.end if.end: @@ -61,6 +66,13 @@ ret void } +; CHECK-NOT: [openmp-opt] Basic block @baz entry is executed by a single thread. +; Function Attrs: noinline +define weak void @baz() !dbg !8 { +entry: + ret void +} + declare i32 @llvm.nvvm.read.ptx.sreg.tid.x() declare i32 @llvm.amdgcn.workitem.id.x() @@ -80,3 +92,6 @@ !5 = !{i32 7, !"openmp", i32 50} !6 = !{i32 7, !"openmp-device", i32 50} !7 = !{void ()* @kernel, !"kernel", i32 1} +!8 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 8, type: !9, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2) +!9 = !DISubroutineType(types: !2) +!10 = !DILocation(line: 5, column: 7, scope: !8)