diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h index 304207779c0f1..4666d72f234ba 100644 --- a/clang/include/clang/Basic/Diagnostic.h +++ b/clang/include/clang/Basic/Diagnostic.h @@ -18,6 +18,7 @@ #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/Specifiers.h" +#include "clang/Basic/SyclOptReport.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" @@ -499,6 +500,8 @@ class DiagnosticsEngine : public RefCountedBase { DiagnosticsEngine &operator=(const DiagnosticsEngine &) = delete; ~DiagnosticsEngine(); + SyclOptReport SyclOptReportHandler; + LLVM_DUMP_METHOD void dump() const; LLVM_DUMP_METHOD void dump(StringRef DiagName) const; diff --git a/clang/include/clang/Basic/SyclOptReport.h b/clang/include/clang/Basic/SyclOptReport.h new file mode 100644 index 0000000000000..41b84c5d2f9cd --- /dev/null +++ b/clang/include/clang/Basic/SyclOptReport.h @@ -0,0 +1,53 @@ +//===---------------------- SyclOptReport.h ---------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Defines clang::SyclOptReport class. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_BASIC_SYCLOPTREPORT_H +#define LLVM_CLANG_BASIC_SYCLOPTREPORT_H + +#include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/DenseMap.h" + +namespace clang { + +class FunctionDecl; + +class SyclOptReport { + struct OptReportInfo { + StringRef KernelName; + StringRef KernelArg; + StringRef ArgType; + SourceLocation KernelArgLoc; + + OptReportInfo(StringRef KernelName, StringRef KernelArg, StringRef ArgType, + SourceLocation KernelArgLoc) + : KernelName(KernelName), KernelArg(KernelArg), ArgType(ArgType), + KernelArgLoc(KernelArgLoc) {} + }; + llvm::DenseMap> Map; + +public: + void AddKernelArg(const FunctionDecl *FD, StringRef KernelName, + StringRef KernelArg, StringRef ArgType, + SourceLocation KernelArgLoc) { + Map[FD].emplace_back(KernelName, KernelArg, ArgType, KernelArgLoc); + } + + SmallVector &getInfo(const FunctionDecl *FD) { + auto It = Map.find(FD); + return It->second; + } +}; + +} // namespace clang + +#endif diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 5c9f60ae5f0df..f6bd7eb14bd9b 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -33,6 +33,7 @@ #include "clang/Basic/TargetInfo.h" #include "clang/CodeGen/CGFunctionInfo.h" #include "clang/Frontend/FrontendDiagnostic.h" +#include "llvm/Analysis/OptimizationRemarkEmitter.h" #include "llvm/Frontend/OpenMP/OMPIRBuilder.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Dominators.h" @@ -1349,6 +1350,33 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, // Emit the standard function prologue. StartFunction(GD, ResTy, Fn, FnInfo, Args, Loc, BodyRange.getBegin()); + if (FD->hasAttr()) { + // Technically, we get most of the information required in the OptReport + // here (without the need for SyclOptReport class). The only information + // we do not have is source location because by this time we are dealing + // with compiler generated OpenCL kernel where there is no source location. + // In order to obtain source location for field corresponding to generated + // argument, I decided to use SyclOptReport class to collect all information + // about the parameter at the time of it's creation, including source + // locations. The commented code below was how I first accessed the kernel + // arguments need to emit in OptReport + /*for (auto KernelArg : Args) + QualType KernelArgType = KernelArg->getType();*/ + + // llvm::OptimizationRemarkEmitter ORE(Fn); + SyclOptReport &OptReportHandler = CGM.getDiags().SyclOptReportHandler; + for (auto &ORI : OptReportHandler.getInfo(FD)) { + StringRef KernelName = ORI.KernelName; + StringRef KernelArg = ORI.KernelArg; + StringRef ArgType = ORI.ArgType; + SourceLocation KernelArgLoc = ORI.KernelArgLoc; + llvm::DiagnosticLocation DL = SourceLocToDebugLoc(KernelArgLoc); + // StringRef RemarkName = "testthisstr"; + // llvm::OptimizationRemark R("SYCL", RemarkName, Fn); + // ORE.emit(R); + } + } + // Generate the body of the function. PGO.assignRegionCounters(GD, CurFn); if (isa(FD)) diff --git a/clang/lib/Sema/SemaSYCL.cpp b/clang/lib/Sema/SemaSYCL.cpp index f339c4a69b3be..03074761622e7 100644 --- a/clang/lib/Sema/SemaSYCL.cpp +++ b/clang/lib/Sema/SemaSYCL.cpp @@ -1348,12 +1348,18 @@ class SyclKernelDeclCreator : public SyclKernelFieldHandler { if (CAT) FieldTy = CAT->getElementType(); ParamDesc newParamDesc = makeParamDesc(FD, FieldTy); + SemaRef.getDiagnostics().SyclOptReportHandler.AddKernelArg( + KernelDecl, KernelDecl->getName(), FD->getName(), FieldTy.getAsString(), + FD->getLocation()); addParam(newParamDesc, FieldTy); } void addParam(const CXXBaseSpecifier &BS, QualType FieldTy) { ParamDesc newParamDesc = makeParamDesc(SemaRef.getASTContext(), BS, FieldTy); + SemaRef.getDiagnostics().SyclOptReportHandler.AddKernelArg( + KernelDecl, KernelDecl->getName(), "_arg__base", FieldTy.getAsString(), + BS.getBaseTypeLoc()); addParam(newParamDesc, FieldTy); }