Skip to content

Generate an opt report of kernel arguments. #3492

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 32 commits into from
Apr 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
d99d3a7
Implementing opt-report
zahiraam Mar 31, 2021
4845eb1
Merge remote-tracking branch 'remote/sycl' into opt-report
zahiraam Mar 31, 2021
8b5d07c
OptReport for kernel arguments.
zahiraam Apr 2, 2021
e69616e
Improve the output.
zahiraam Apr 5, 2021
5d12df4
Merge remote-tracking branch 'remote/sycl' into opt-report
zahiraam Apr 5, 2021
c44d670
cleanup
zahiraam Apr 5, 2021
87ce263
Put back the indentation as it was
zahiraam Apr 5, 2021
232a8a9
Put back the indentation as it was
zahiraam Apr 5, 2021
4be5deb
Addding test case
zahiraam Apr 8, 2021
978d6b8
Addding test case
zahiraam Apr 8, 2021
1db1025
Merge remote-tracking branch 'remote/sycl' into opt-report
zahiraam Apr 12, 2021
82cacc9
Merge remote-tracking branch 'remote/sycl' into opt-report
zahiraam Apr 14, 2021
5254539
Merge branch 'opt-report' of https://github.com/zahiraam/llvm-1 into …
zahiraam Apr 14, 2021
32454ac
Formatting
zahiraam Apr 15, 2021
d316062
Formatting
zahiraam Apr 15, 2021
95b6c9f
Merge remote-tracking branch 'remote/sycl' into opt-report
zahiraam Apr 15, 2021
aeed807
After review fixes
zahiraam Apr 15, 2021
1287604
Merge remote-tracking branch 'remote/sycl' into opt-report
zahiraam Apr 16, 2021
8737bc1
Merge remote-tracking branch 'remote/sycl' into opt-report
zahiraam Apr 19, 2021
c5d2ae3
Merge remote-tracking branch 'remote/sycl' into opt-report
zahiraam Apr 20, 2021
6ce7268
Review comments fixes
zahiraam Apr 20, 2021
f33353d
Merge remote-tracking branch 'remote/sycl' into opt-report
zahiraam Apr 21, 2021
ddad6f9
Review comments fixes
zahiraam Apr 21, 2021
0af4422
Review comments fixes
zahiraam Apr 21, 2021
2c0a35c
Merge remote-tracking branch 'remote/sycl' into opt-report
zahiraam Apr 22, 2021
f99e200
Review comments fixes
zahiraam Apr 22, 2021
0937042
Merge remote-tracking branch 'remote/sycl' into opt-report
zahiraam Apr 22, 2021
6a87209
Review comments fixes
zahiraam Apr 22, 2021
eac6f25
Review comments fixes
zahiraam Apr 22, 2021
c04374c
Merge remote-tracking branch 'remote/sycl' into opt-report
zahiraam Apr 23, 2021
84a2cee
Review comments fixes
zahiraam Apr 23, 2021
8efb79a
Review comments fixes
zahiraam Apr 23, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions clang/include/clang/Basic/Diagnostic.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/SyclOptReportHandler.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
Expand Down Expand Up @@ -294,6 +295,7 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
DiagnosticConsumer *Client = nullptr;
std::unique_ptr<DiagnosticConsumer> Owner;
SourceManager *SourceMgr = nullptr;
SyclOptReportHandler OptReportHandler;

/// Mapping information for diagnostics.
///
Expand Down Expand Up @@ -547,6 +549,12 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
LLVM_DUMP_METHOD void dump() const;
LLVM_DUMP_METHOD void dump(StringRef DiagName) const;

/// Retrieve the report SyclOptReport info.
SyclOptReportHandler &getSYCLOptReportHandler() { return OptReportHandler; }
const SyclOptReportHandler &getSYCLOptReportHandler() const {
return OptReportHandler;
}

const IntrusiveRefCntPtr<DiagnosticIDs> &getDiagnosticIDs() const {
return Diags;
}
Expand Down
57 changes: 57 additions & 0 deletions clang/include/clang/Basic/SyclOptReportHandler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//===---------------------- SyclOptReportHandler.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::SyclOptReportHandler class.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_BASIC_SYCLOPTREPORTHANDLER_H
#define LLVM_CLANG_BASIC_SYCLOPTREPORTHANDLER_H

#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringRef.h"

namespace clang {

class FunctionDecl;

class SyclOptReportHandler {
private:
struct OptReportInfo {
std::string KernelArgName;
std::string KernelArgType;
SourceLocation KernelArgLoc;

OptReportInfo(std::string ArgName, std::string ArgType,
SourceLocation ArgLoc)
: KernelArgName(std::move(ArgName)), KernelArgType(std::move(ArgType)),
KernelArgLoc(ArgLoc) {}
};
llvm::DenseMap<const FunctionDecl *, SmallVector<OptReportInfo>> Map;

public:
void AddKernelArgs(const FunctionDecl *FD, std::string ArgName,
std::string ArgType, SourceLocation ArgLoc) {
Map[FD].emplace_back(ArgName, ArgType, ArgLoc);
}
SmallVector<OptReportInfo> &GetInfo(const FunctionDecl *FD) {
auto It = Map.find(FD);
assert(It != Map.end());
return It->second;
}

bool HasOptReportInfo(const FunctionDecl *FD) const {
return Map.find(FD) != Map.end();
}
};

} // namespace clang

#endif // LLVM_CLANG_BASIC_SYCLOPTREPORTHANDLER_H
2 changes: 2 additions & 0 deletions clang/lib/CodeGen/CGSYCLRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#include "CodeGenFunction.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/IR/Instructions.h"
#include <assert.h>

Expand Down
66 changes: 45 additions & 21 deletions clang/lib/CodeGen/CodeGenAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,28 +304,12 @@ namespace clang {
return;

LLVMContext &Ctx = getModule()->getContext();

std::unique_ptr<DiagnosticHandler> OldDiagnosticHandler =
Ctx.getDiagnosticHandler();
Ctx.setDiagnosticHandler(std::make_unique<ClangDiagnosticHandler>(
CodeGenOpts, this));

Expected<std::unique_ptr<llvm::ToolOutputFile>> OptRecordFileOrErr =
setupLLVMOptimizationRemarks(
Ctx, CodeGenOpts.OptRecordFile, CodeGenOpts.OptRecordPasses,
CodeGenOpts.OptRecordFormat, CodeGenOpts.DiagnosticsWithHotness,
CodeGenOpts.DiagnosticsHotnessThreshold);

if (Error E = OptRecordFileOrErr.takeError()) {
reportOptRecordError(std::move(E), Diags, CodeGenOpts);
return;
}

std::unique_ptr<llvm::ToolOutputFile> OptRecordFile =
std::move(*OptRecordFileOrErr);

if (OptRecordFile &&
CodeGenOpts.getProfileUse() != CodeGenOptions::ProfileNone)
Ctx.setDiagnosticsHotnessRequested(true);
// The diagnostic handler is now processed in OptRecordFileRAII.

// The parallel_for_work_group legalization pass can emit calls to
// builtins function. Definitions of those builtins can be provided in
Expand All @@ -349,9 +333,6 @@ namespace clang {
getModule(), Action, std::move(AsmOutStream));

Ctx.setDiagnosticHandler(std::move(OldDiagnosticHandler));

if (OptRecordFile)
OptRecordFile->keep();
}

void HandleTagDeclDefinition(TagDecl *D) override {
Expand Down Expand Up @@ -1046,8 +1027,51 @@ CodeGenAction::loadModule(MemoryBufferRef MBRef) {
return {};
}

namespace {
// Handles the initialization and cleanup of the OptRecordFile. This
// customization allows initialization before the clang codegen runs
// so it can also emit to the opt report.
struct OptRecordFileRAII {
std::unique_ptr<llvm::ToolOutputFile> OptRecordFile;
std::unique_ptr<DiagnosticHandler> OldDiagnosticHandler;
llvm::LLVMContext &Ctx;

OptRecordFileRAII(CodeGenAction &CGA, llvm::LLVMContext &Ctx,
BackendConsumer &BC)
: Ctx(Ctx), OldDiagnosticHandler(Ctx.getDiagnosticHandler()) {

CompilerInstance &CI = CGA.getCompilerInstance();
CodeGenOptions &CodeGenOpts = CI.getCodeGenOpts();

Ctx.setDiagnosticHandler(
std::make_unique<ClangDiagnosticHandler>(CodeGenOpts, &BC));

Expected<std::unique_ptr<llvm::ToolOutputFile>> OptRecordFileOrErr =
setupLLVMOptimizationRemarks(
Ctx, CodeGenOpts.OptRecordFile, CodeGenOpts.OptRecordPasses,
CodeGenOpts.OptRecordFormat, CodeGenOpts.DiagnosticsWithHotness,
CodeGenOpts.DiagnosticsHotnessThreshold);

if (Error E = OptRecordFileOrErr.takeError())
reportOptRecordError(std::move(E), CI.getDiagnostics(), CodeGenOpts);
else
OptRecordFile = std::move(*OptRecordFileOrErr);

if (OptRecordFile &&
CodeGenOpts.getProfileUse() != CodeGenOptions::ProfileNone)
Ctx.setDiagnosticsHotnessRequested(true);
}
~OptRecordFileRAII() {
Ctx.setDiagnosticHandler(std::move(OldDiagnosticHandler));
if (OptRecordFile)
OptRecordFile->keep();
}
};
} // namespace

void CodeGenAction::ExecuteAction() {
if (getCurrentFileKind().getLanguage() != Language::LLVM_IR) {
OptRecordFileRAII ORF(*this, *VMContext, *BEConsumer);
this->ASTFrontendAction::ExecuteAction();
return;
}
Expand Down
20 changes: 20 additions & 0 deletions clang/lib/CodeGen/CodeGenFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "clang/CodeGen/CGFunctionInfo.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Dominators.h"
Expand Down Expand Up @@ -1521,6 +1522,25 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
// Emit the standard function prologue.
StartFunction(GD, ResTy, Fn, FnInfo, Args, Loc, BodyRange.getBegin());

SyclOptReportHandler &OptReportHandler =
CGM.getDiags().getSYCLOptReportHandler();
if (OptReportHandler.HasOptReportInfo(FD)) {
llvm::OptimizationRemarkEmitter ORE(Fn);
for (auto ORI : llvm::enumerate(OptReportHandler.GetInfo(FD))) {
llvm::DiagnosticLocation DL =
SourceLocToDebugLoc(ORI.value().KernelArgLoc);
std::string KAN = ORI.value().KernelArgName;
llvm::OptimizationRemark Remark("sycl", "Region", DL,
&Fn->getEntryBlock());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We seem to calling ORI.value() multiple times below; perhaps save ORI.value().KernelArgName in a variable here and the reuse that?

Remark << "Argument " << llvm::ore::NV("Argument", ORI.index())
<< " for function kernel: "
<< llvm::ore::NV(KAN.empty() ? "&" : "") << " " << Fn->getName()
<< "." << llvm::ore::NV(KAN.empty() ? " " : KAN) << "("
<< ORI.value().KernelArgType << ")";
ORE.emit(Remark);
}
}

// Save parameters for coroutine function.
if (Body && isa_and_nonnull<CoroutineBodyStmt>(Body))
for (const auto *ParamDecl : FD->parameters())
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/Sema/SemaSYCL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1768,6 +1768,9 @@ class SyclKernelDeclCreator : public SyclKernelFieldHandler {

void addParam(const FieldDecl *FD, QualType FieldTy) {
ParamDesc newParamDesc = makeParamDesc(FD, FieldTy);
SemaRef.getDiagnostics().getSYCLOptReportHandler().AddKernelArgs(
KernelDecl, FD->getName().data(), FieldTy.getAsString(),
FD->getLocation());
addParam(newParamDesc, FieldTy);
}

Expand All @@ -1778,6 +1781,8 @@ class SyclKernelDeclCreator : public SyclKernelFieldHandler {
StringRef Name = "_arg__base";
ParamDesc newParamDesc =
makeParamDesc(SemaRef.getASTContext(), Name, FieldTy);
SemaRef.getDiagnostics().getSYCLOptReportHandler().AddKernelArgs(
KernelDecl, "", FieldTy.getAsString(), BS.getBaseTypeLoc());
addParam(newParamDesc, FieldTy);
}
// Add a parameter with specified name and type
Expand Down
101 changes: 101 additions & 0 deletions clang/test/SemaSYCL/kernel-arg-opt-report.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// RUN: %clang_cc1 -triple spir64-unknown-unknown-sycldevice -fsycl-is-device \
// RUN: -Wno-sycl-2017-compat -emit-llvm-bc %s -o %t-host.bc -opt-record-file %t-host.yaml
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you expand this test to check for basic things in the opt-report file? I would like to see that to understand the changes in CodeGenFunction better.

// RUN: FileCheck -check-prefix=CHECK --input-file %t-host.yaml %s
// The test generates remarks about the kernel argument, their location and type
// in the resulting yaml file.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also add a comment here describing what the test is testing for.

#include "Inputs/sycl.hpp"

class second_base {
public:
int *e;
};

class InnerFieldBase {
public:
int d;
};
class InnerField : public InnerFieldBase {
int c;
};

struct base {
public:
int b;
InnerField obj;
};

//CHECK: --- !Passed
//CHECK: Pass:{{.*}}sycl
//CHECK: Name:{{.*}}Region
//CHECK: DebugLoc:{{.*}} { File: '{{.*}}kernel-arg-opt-report.cpp',
//CHECK: Line: 85, Column: 18 }
//CHECK: Function: _ZTS7derived
//CHECK: Args:
//CHECK-NEXT: String: 'Argument '
//CHECK-NEXT: Argument: '0'
//CHECK-NEXT: String: ' for function kernel: '
//CHECK-NEXT: String: '&'
//CHECK-NEXT: String: ' '
//CHECK-NEXT: String: _ZTS7derived
//CHECK-NEXT: String: .
//CHECK-NEXT: String: ' '
//CHECK-NEXT: String: '('
//CHECK-NEXT: String: struct base
//CHECK-NEXT: String: ')'

//CHECK: --- !Passed
//CHECK: Pass:{{.*}}sycl
//CHECK: Name:{{.*}}Region
//CHECK: DebugLoc:{{.*}} { File: '{{.*}}kernel-arg-opt-report.cpp',
//CHECK: Line: 11, Column: 8 }
//CHECK: Function: _ZTS7derived
//CHECK: Args:
//CHECK-NEXT: String: 'Argument '
//CHECK-NEXT: Argument: '1'
//CHECK-NEXT: String: ' for function kernel: '
//CHECK-NEXT: String: ''
//CHECK-NEXT: String: ' '
//CHECK-NEXT: String: _ZTS7derived
//CHECK-NEXT: String: .
//CHECK-NEXT: String: e
//CHECK-NEXT: String: '('
//CHECK-NEXT: String: struct __wrapper_class
//CHECK-NEXT: String: ')'

//CHECK: --- !Passed
//CHECK: Pass:{{.*}}sycl
//CHECK: Name:{{.*}}Region
//CHECK: DebugLoc:{{.*}} { File: '{{.*}}kernel-arg-opt-report.cpp',
//CHECK: Line: 86, Column: 7 }
//CHECK: Function: _ZTS7derived
//CHECK: Args:
//CHECK-NEXT: String: 'Argument '
//CHECK-NEXT: Argument: '2'
//CHECK-NEXT: String: ' for function kernel: '
//CHECK-NEXT: String: ''
//CHECK-NEXT: String: ' '
//CHECK-NEXT: String: _ZTS7derived
//CHECK-NEXT: String: .
//CHECK-NEXT: String: a
//CHECK-NEXT: String: '('
//CHECK-NEXT: String: int
//CHECK-NEXT: String: ')'

struct derived : base, second_base {
int a;

void operator()() const {
}
};

int main() {
sycl::queue q;

q.submit([&](cl::sycl::handler &cgh) {
derived f{};
cgh.single_task(f);
});

return 0;
}