Skip to content

Commit a9711a0

Browse files
[SYCL] Improve output emitted in opt-report (#3730)
This patch attempts to make the output generated in opt-report more user-friendly by adding a description for OpenCL kernel arguments. It also removes compiler generated names such as '__wrapper_class'. Signed-off-by: Elizabeth Andrews <[email protected]>
1 parent c252d7f commit a9711a0

File tree

4 files changed

+741
-97
lines changed

4 files changed

+741
-97
lines changed

clang/include/clang/Basic/SyclOptReportHandler.h

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,31 @@ class FunctionDecl;
2525
class SyclOptReportHandler {
2626
private:
2727
struct OptReportInfo {
28-
std::string KernelArgName;
28+
std::string KernelArgDescName; // Kernel argument name itself, or the name
29+
// of the parent class if the kernel argument
30+
// is a decomposed member.
2931
std::string KernelArgType;
3032
SourceLocation KernelArgLoc;
33+
unsigned KernelArgSize;
34+
std::string KernelArgDesc;
35+
std::string KernelArgDecomposedField;
3136

32-
OptReportInfo(std::string ArgName, std::string ArgType,
33-
SourceLocation ArgLoc)
34-
: KernelArgName(std::move(ArgName)), KernelArgType(std::move(ArgType)),
35-
KernelArgLoc(ArgLoc) {}
37+
OptReportInfo(std::string ArgDescName, std::string ArgType,
38+
SourceLocation ArgLoc, unsigned ArgSize, std::string ArgDesc,
39+
std::string ArgDecomposedField)
40+
: KernelArgDescName(std::move(ArgDescName)),
41+
KernelArgType(std::move(ArgType)), KernelArgLoc(ArgLoc),
42+
KernelArgSize(ArgSize), KernelArgDesc(std::move(ArgDesc)),
43+
KernelArgDecomposedField(std::move(ArgDecomposedField)) {}
3644
};
3745
llvm::DenseMap<const FunctionDecl *, SmallVector<OptReportInfo>> Map;
3846

3947
public:
40-
void AddKernelArgs(const FunctionDecl *FD, std::string ArgName,
41-
std::string ArgType, SourceLocation ArgLoc) {
42-
Map[FD].emplace_back(ArgName, ArgType, ArgLoc);
48+
void AddKernelArgs(const FunctionDecl *FD, StringRef ArgDescName,
49+
StringRef ArgType, SourceLocation ArgLoc, unsigned ArgSize,
50+
StringRef ArgDesc, StringRef ArgDecomposedField) {
51+
Map[FD].emplace_back(ArgDescName.data(), ArgType.data(), ArgLoc, ArgSize,
52+
ArgDesc.data(), ArgDecomposedField.data());
4353
}
4454
SmallVector<OptReportInfo> &GetInfo(const FunctionDecl *FD) {
4555
auto It = Map.find(FD);

clang/lib/CodeGen/CodeGenFunction.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1518,14 +1518,18 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
15181518
for (auto ORI : llvm::enumerate(OptReportHandler.GetInfo(FD))) {
15191519
llvm::DiagnosticLocation DL =
15201520
SourceLocToDebugLoc(ORI.value().KernelArgLoc);
1521-
std::string KAN = ORI.value().KernelArgName;
1521+
StringRef NameInDesc = ORI.value().KernelArgDescName;
1522+
StringRef ArgType = ORI.value().KernelArgType;
1523+
StringRef ArgDesc = ORI.value().KernelArgDesc;
1524+
unsigned ArgSize = ORI.value().KernelArgSize;
1525+
StringRef ArgDecomposedField = ORI.value().KernelArgDecomposedField;
1526+
15221527
llvm::OptimizationRemark Remark("sycl", "Region", DL,
15231528
&Fn->getEntryBlock());
1524-
Remark << "Argument " << llvm::ore::NV("Argument", ORI.index())
1525-
<< " for function kernel: "
1526-
<< llvm::ore::NV(KAN.empty() ? "&" : "") << " " << Fn->getName()
1527-
<< "." << llvm::ore::NV(KAN.empty() ? " " : KAN) << "("
1528-
<< ORI.value().KernelArgType << ")";
1529+
Remark << "Arg " << llvm::ore::NV("Argument", ORI.index()) << ":"
1530+
<< ArgDesc << NameInDesc << " (" << ArgDecomposedField
1531+
<< "Type:" << ArgType << ", "
1532+
<< "Size: " << llvm::ore::NV("Argument", ArgSize) << ")";
15291533
ORE.emit(Remark);
15301534
}
15311535
}

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 214 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1777,9 +1777,6 @@ class SyclKernelDeclCreator : public SyclKernelFieldHandler {
17771777

17781778
void addParam(const FieldDecl *FD, QualType FieldTy) {
17791779
ParamDesc newParamDesc = makeParamDesc(FD, FieldTy);
1780-
SemaRef.getDiagnostics().getSYCLOptReportHandler().AddKernelArgs(
1781-
KernelDecl, FD->getName().data(), FieldTy.getAsString(),
1782-
FD->getLocation());
17831780
addParam(newParamDesc, FieldTy);
17841781
}
17851782

@@ -1790,8 +1787,6 @@ class SyclKernelDeclCreator : public SyclKernelFieldHandler {
17901787
StringRef Name = "_arg__base";
17911788
ParamDesc newParamDesc =
17921789
makeParamDesc(SemaRef.getASTContext(), Name, FieldTy);
1793-
SemaRef.getDiagnostics().getSYCLOptReportHandler().AddKernelArgs(
1794-
KernelDecl, "", FieldTy.getAsString(), BS.getBaseTypeLoc());
17951790
addParam(newParamDesc, FieldTy);
17961791
}
17971792
// Add a parameter with specified name and type
@@ -2239,6 +2234,216 @@ class SyclKernelArgsSizeChecker : public SyclKernelFieldHandler {
22392234
using SyclKernelFieldHandler::handleSyclHalfType;
22402235
};
22412236

2237+
enum class KernelArgDescription {
2238+
BaseClass,
2239+
DecomposedMember,
2240+
WrappedPointer,
2241+
WrappedArray,
2242+
Accessor,
2243+
AccessorBase,
2244+
Sampler,
2245+
Stream,
2246+
KernelHandler,
2247+
None
2248+
};
2249+
2250+
StringRef getKernelArgDesc(KernelArgDescription Desc) {
2251+
switch (Desc) {
2252+
case KernelArgDescription::BaseClass:
2253+
return "Compiler generated argument for base class,";
2254+
case KernelArgDescription::DecomposedMember:
2255+
return "Compiler generated argument for decomposed struct/class,";
2256+
case KernelArgDescription::WrappedPointer:
2257+
return "Compiler generated argument for nested pointer,";
2258+
case KernelArgDescription::WrappedArray:
2259+
return "Compiler generated argument for array,";
2260+
case KernelArgDescription::Accessor:
2261+
return "Compiler generated argument for accessor,";
2262+
case KernelArgDescription::AccessorBase:
2263+
return "Compiler generated argument for accessor base class,";
2264+
case KernelArgDescription::Sampler:
2265+
return "Compiler generated argument for sampler,";
2266+
case KernelArgDescription::Stream:
2267+
return "Compiler generated argument for stream,";
2268+
case KernelArgDescription::KernelHandler:
2269+
return "Compiler generated argument for SYCL2020 specialization constant";
2270+
case KernelArgDescription::None:
2271+
return "";
2272+
}
2273+
llvm_unreachable(
2274+
"switch should cover all possible values for KernelArgDescription");
2275+
}
2276+
2277+
class SyclOptReportCreator : public SyclKernelFieldHandler {
2278+
SyclKernelDeclCreator &DC;
2279+
SourceLocation KernelInvocationLoc;
2280+
2281+
void addParam(const FieldDecl *KernelArg, QualType KernelArgType,
2282+
KernelArgDescription KernelArgDesc) {
2283+
StringRef NameToEmitInDescription = KernelArg->getName();
2284+
const RecordDecl *KernelArgParent = KernelArg->getParent();
2285+
if (KernelArgParent &&
2286+
KernelArgDesc == KernelArgDescription::DecomposedMember) {
2287+
NameToEmitInDescription = KernelArgParent->getName();
2288+
}
2289+
2290+
bool isWrappedField =
2291+
KernelArgDesc == KernelArgDescription::WrappedPointer ||
2292+
KernelArgDesc == KernelArgDescription::WrappedArray;
2293+
2294+
unsigned KernelArgSize =
2295+
SemaRef.getASTContext().getTypeSizeInChars(KernelArgType).getQuantity();
2296+
2297+
SemaRef.getDiagnostics().getSYCLOptReportHandler().AddKernelArgs(
2298+
DC.getKernelDecl(), NameToEmitInDescription,
2299+
isWrappedField ? "Compiler generated" : KernelArgType.getAsString(),
2300+
KernelInvocationLoc, KernelArgSize, getKernelArgDesc(KernelArgDesc),
2301+
(KernelArgDesc == KernelArgDescription::DecomposedMember)
2302+
? ("Field:" + KernelArg->getName().str() + ", ")
2303+
: "");
2304+
}
2305+
2306+
void addParam(const FieldDecl *FD, QualType FieldTy) {
2307+
KernelArgDescription Desc = KernelArgDescription::None;
2308+
const RecordDecl *RD = FD->getParent();
2309+
if (RD && RD->hasAttr<SYCLRequiresDecompositionAttr>())
2310+
Desc = KernelArgDescription::DecomposedMember;
2311+
2312+
addParam(FD, FieldTy, Desc);
2313+
}
2314+
2315+
// Handles base classes.
2316+
void addParam(const CXXBaseSpecifier &, QualType KernelArgType,
2317+
KernelArgDescription KernelArgDesc) {
2318+
unsigned KernelArgSize =
2319+
SemaRef.getASTContext().getTypeSizeInChars(KernelArgType).getQuantity();
2320+
SemaRef.getDiagnostics().getSYCLOptReportHandler().AddKernelArgs(
2321+
DC.getKernelDecl(), KernelArgType.getAsString(),
2322+
KernelArgType.getAsString(), KernelInvocationLoc, KernelArgSize,
2323+
getKernelArgDesc(KernelArgDesc), "");
2324+
}
2325+
2326+
// Handles specialization constants.
2327+
void addParam(QualType KernelArgType, KernelArgDescription KernelArgDesc) {
2328+
unsigned KernelArgSize =
2329+
SemaRef.getASTContext().getTypeSizeInChars(KernelArgType).getQuantity();
2330+
SemaRef.getDiagnostics().getSYCLOptReportHandler().AddKernelArgs(
2331+
DC.getKernelDecl(), "", KernelArgType.getAsString(),
2332+
KernelInvocationLoc, KernelArgSize, getKernelArgDesc(KernelArgDesc),
2333+
"");
2334+
}
2335+
2336+
// Handles SYCL special types (accessor, sampler and stream) and modified
2337+
// types (arrays and pointers)
2338+
bool handleSpecialType(const FieldDecl *FD, QualType FieldTy,
2339+
KernelArgDescription Desc) {
2340+
for (const auto *Param : DC.getParamVarDeclsForCurrentField())
2341+
addParam(FD, Param->getType(), Desc);
2342+
return true;
2343+
}
2344+
2345+
public:
2346+
static constexpr const bool VisitInsideSimpleContainers = false;
2347+
SyclOptReportCreator(Sema &S, SyclKernelDeclCreator &DC, SourceLocation Loc)
2348+
: SyclKernelFieldHandler(S), DC(DC), KernelInvocationLoc(Loc) {}
2349+
2350+
bool handleSyclAccessorType(FieldDecl *FD, QualType FieldTy) final {
2351+
return handleSpecialType(
2352+
FD, FieldTy, KernelArgDescription(KernelArgDescription::Accessor));
2353+
}
2354+
2355+
bool handleSyclAccessorType(const CXXRecordDecl *, const CXXBaseSpecifier &BS,
2356+
QualType FieldTy) final {
2357+
for (const auto *Param : DC.getParamVarDeclsForCurrentField()) {
2358+
QualType KernelArgType = Param->getType();
2359+
unsigned KernelArgSize = SemaRef.getASTContext()
2360+
.getTypeSizeInChars(KernelArgType)
2361+
.getQuantity();
2362+
SemaRef.getDiagnostics().getSYCLOptReportHandler().AddKernelArgs(
2363+
DC.getKernelDecl(), FieldTy.getAsString(),
2364+
KernelArgType.getAsString(), KernelInvocationLoc, KernelArgSize,
2365+
getKernelArgDesc(
2366+
KernelArgDescription(KernelArgDescription::AccessorBase)),
2367+
"");
2368+
}
2369+
return true;
2370+
}
2371+
2372+
bool handleSyclSamplerType(FieldDecl *FD, QualType FieldTy) final {
2373+
return handleSpecialType(
2374+
FD, FieldTy, KernelArgDescription(KernelArgDescription::Sampler));
2375+
}
2376+
2377+
bool handlePointerType(FieldDecl *FD, QualType FieldTy) final {
2378+
KernelArgDescription Desc = KernelArgDescription::None;
2379+
ParmVarDecl *KernelParameter = DC.getParamVarDeclsForCurrentField()[0];
2380+
// Compiler generated openCL kernel argument for current pointer field
2381+
// is not a pointer. This means we are processing a nested pointer and
2382+
// the openCL kernel argument is of type __wrapper_class.
2383+
if (!KernelParameter->getType()->isPointerType())
2384+
Desc = KernelArgDescription::WrappedPointer;
2385+
return handleSpecialType(FD, FieldTy, Desc);
2386+
}
2387+
2388+
bool handleScalarType(FieldDecl *FD, QualType FieldTy) final {
2389+
addParam(FD, FieldTy);
2390+
return true;
2391+
}
2392+
2393+
bool handleSimpleArrayType(FieldDecl *FD, QualType FieldTy) final {
2394+
// Simple arrays are always wrapped.
2395+
handleSpecialType(FD, FieldTy,
2396+
KernelArgDescription(KernelArgDescription::WrappedArray));
2397+
return true;
2398+
}
2399+
2400+
bool handleNonDecompStruct(const CXXRecordDecl *, FieldDecl *FD,
2401+
QualType Ty) final {
2402+
addParam(FD, Ty);
2403+
return true;
2404+
}
2405+
2406+
bool handleNonDecompStruct(const CXXRecordDecl *Base,
2407+
const CXXBaseSpecifier &BS, QualType Ty) final {
2408+
addParam(BS, Ty, KernelArgDescription(KernelArgDescription::BaseClass));
2409+
return true;
2410+
}
2411+
2412+
bool handleUnionType(FieldDecl *FD, QualType FieldTy) final {
2413+
return handleScalarType(FD, FieldTy);
2414+
}
2415+
2416+
bool handleSyclHalfType(FieldDecl *FD, QualType FieldTy) final {
2417+
addParam(FD, FieldTy);
2418+
return true;
2419+
}
2420+
2421+
bool handleSyclStreamType(FieldDecl *FD, QualType FieldTy) final {
2422+
// For the current implementation of stream class, the Visitor 'handles'
2423+
// stream argument and then visits each accessor field in stream. Therefore
2424+
// handleSpecialType in this case only adds a single argument for stream.
2425+
// The arguments corresponding to accessors in stream are handled in
2426+
// handleSyclAccessorType. The opt-report therefore does not diffrentiate
2427+
// between the accessors in streams and accessors captured by SYCL kernel.
2428+
// Once stream API is modified to use __init(), the visitor will no longer
2429+
// visit the stream object and opt-report output for stream class will be
2430+
// similar to that of other special types.
2431+
return handleSpecialType(
2432+
FD, FieldTy, KernelArgDescription(KernelArgDescription::Stream));
2433+
}
2434+
2435+
void handleSyclKernelHandlerType() {
2436+
ASTContext &Context = SemaRef.getASTContext();
2437+
if (isDefaultSPIRArch(Context))
2438+
return;
2439+
addParam(DC.getParamVarDeclsForCurrentField()[0]->getType(),
2440+
KernelArgDescription(KernelArgDescription::KernelHandler));
2441+
}
2442+
using SyclKernelFieldHandler::handleSyclHalfType;
2443+
using SyclKernelFieldHandler::handleSyclSamplerType;
2444+
using SyclKernelFieldHandler::handleSyclStreamType;
2445+
};
2446+
22422447
static CXXMethodDecl *getOperatorParens(const CXXRecordDecl *Rec) {
22432448
for (auto *MD : Rec->methods()) {
22442449
if (MD->getOverloadedOperator() == OO_Call)
@@ -3561,18 +3766,20 @@ void Sema::ConstructOpenCLKernel(FunctionDecl *KernelCallerFunc,
35613766
StableName, KernelCallerFunc);
35623767

35633768
SyclKernelIntFooterCreator int_footer(*this, getSyclIntegrationFooter());
3769+
SyclOptReportCreator opt_report(*this, kernel_decl, KernelObj->getLocation());
35643770

35653771
KernelObjVisitor Visitor{*this};
35663772
Visitor.VisitRecordBases(KernelObj, kernel_decl, kernel_body, int_header,
3567-
int_footer);
3773+
int_footer, opt_report);
35683774
Visitor.VisitRecordFields(KernelObj, kernel_decl, kernel_body, int_header,
3569-
int_footer);
3775+
int_footer, opt_report);
35703776

35713777
if (ParmVarDecl *KernelHandlerArg =
35723778
getSyclKernelHandlerArg(KernelCallerFunc)) {
35733779
kernel_decl.handleSyclKernelHandlerType();
35743780
kernel_body.handleSyclKernelHandlerType(KernelHandlerArg);
35753781
int_header.handleSyclKernelHandlerType(KernelHandlerArg->getType());
3782+
opt_report.handleSyclKernelHandlerType();
35763783
}
35773784
}
35783785

0 commit comments

Comments
 (0)