-
Notifications
You must be signed in to change notification settings - Fork 770
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
Changes from all commits
d99d3a7
4845eb1
8b5d07c
e69616e
5d12df4
c44d670
87ce263
232a8a9
4be5deb
978d6b8
1db1025
82cacc9
5254539
32454ac
d316062
95b6c9f
aeed807
1287604
8737bc1
c5d2ae3
6ce7268
f33353d
ddad6f9
0af4422
2c0a35c
f99e200
0937042
6a87209
eac6f25
c04374c
84a2cee
8efb79a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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" | ||
|
@@ -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()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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()) | ||
|
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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; | ||
} |
Uh oh!
There was an error while loading. Please reload this page.