Skip to content

Commit d73a1da

Browse files
committed
second stage of implementation
Signed-off-by: Arvind Sudarsanam <[email protected]>
1 parent 4d58f01 commit d73a1da

File tree

14 files changed

+231
-254
lines changed

14 files changed

+231
-254
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,12 +1309,12 @@ def SYCLType: InheritableAttr {
13091309
"specialization_id", "kernel_handler", "buffer_location",
13101310
"no_alias", "accessor_property_list", "group",
13111311
"private_memory", "aspect", "annotated_ptr", "annotated_arg",
1312-
"compile_options", "stream", "sampler"],
1312+
"stream", "sampler"],
13131313
["accessor", "local_accessor", "spec_constant",
13141314
"specialization_id", "kernel_handler", "buffer_location",
13151315
"no_alias", "accessor_property_list", "group",
13161316
"private_memory", "aspect", "annotated_ptr", "annotated_arg",
1317-
"compile_options", "stream", "sampler"]>];
1317+
"stream", "sampler"]>];
13181318
// Only used internally by SYCL implementation
13191319
let Documentation = [InternalOnly];
13201320
}
@@ -1328,15 +1328,6 @@ def SYCLDeviceHas : InheritableAttr {
13281328
let SupportsNonconformingLambdaSyntax = 1;
13291329
}
13301330

1331-
def SYCLDeviceCompileOptions : InheritableAttr {
1332-
let Spellings = [CXX11<"sycl", "device_compile_options">];
1333-
let Subjects = SubjectList<[Function], ErrorDiag>;
1334-
let Args = [VariadicExprArgument<"DeviceCompileOptions">];
1335-
let LangOpts = [SYCLIsDevice, SilentlyIgnoreSYCLIsHost];
1336-
// Only used internally by SYCL implementation
1337-
let Documentation = [InternalOnly];
1338-
}
1339-
13401331
def SYCLUsesAspects : InheritableAttr {
13411332
let Spellings = [CXX11<"__sycl_detail__", "__uses_aspects__">];
13421333
let Subjects = SubjectList<[CXXRecord, Function], ErrorDiag>;

clang/lib/CodeGen/CodeGenFunction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,7 @@ void CodeGenFunction::EmitKernelMetadata(const FunctionDecl *FD,
587587
// TODO Module identifier is not reliable for this purpose since two modules
588588
// can have the same ID, needs improvement
589589
Fn->addFnAttr("sycl-module-id", Fn->getParent()->getModuleIdentifier());
590-
int SYCLDeviceCompileOptLevel;
590+
int SYCLDeviceCompileOptLevel = 2;
591591
switch (CGM.getCodeGenOpts().OptimizationLevel) {
592592
default:
593593
llvm_unreachable("Invalid optimization level!");

llvm/tools/sycl-post-link/CompileTimePropertiesPass.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -208,10 +208,6 @@ attributeToExecModeMetadata(Module &M, const Attribute &Attr) {
208208
MDNode::get(Ctx, MD));
209209
}
210210

211-
if (AttrKindStr == "sycl-device-compile-options") {
212-
auto Opt = Attr.getValueAsString();
213-
llvm::errs() << "ARV: Opt is -O" << Opt << "\n";
214-
}
215211
return None;
216212
}
217213

llvm/tools/sycl-post-link/ModuleSplitter.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ constexpr char ESIMD_MARKER_MD[] = "sycl_explicit_simd";
4343

4444
constexpr char ATTR_SYCL_MODULE_ID[] = "sycl-module-id";
4545

46+
// Similar copy in sycl-post-link.cpp
47+
constexpr char ATTR_OPT_LEVEL[] = "sycl-device-compile-optlevel";
48+
4649
bool hasIndirectFunctionsOrCalls(const Module &M) {
4750
for (const auto &F : M.functions()) {
4851
// There are functions marked with [[intel::device_indirectly_callable]]
@@ -299,6 +302,44 @@ groupEntryPointsByAttribute(ModuleDesc &MD, StringRef AttrName,
299302
return EntryPointGroups;
300303
}
301304

305+
template <class EntryPoinGroupFunc>
306+
EntryPointGroupVec
307+
groupEntryPointsByOptLevel(ModuleDesc &MD, StringRef AttrName,
308+
bool EmitOnlyKernelsAsEntryPoints,
309+
EntryPoinGroupFunc F) {
310+
EntryPointGroupVec EntryPointGroups{};
311+
std::map<StringRef, EntryPointSet> EntryPointMap;
312+
Module &M = MD.getModule();
313+
314+
// Only process module entry points:
315+
for (auto &F : M.functions()) {
316+
if (!isEntryPoint(F, EmitOnlyKernelsAsEntryPoints) ||
317+
!MD.isEntryPointCandidate(F)) {
318+
continue;
319+
}
320+
if (F.hasFnAttribute(AttrName)) {
321+
SmallString<16> stringConstName;
322+
StringRef OptLevelStr = F.getFnAttribute(AttrName).getValueAsString();
323+
EntryPointMap[OptLevelStr].insert(&F);
324+
} else {
325+
EntryPointMap["2"].insert(&F);
326+
}
327+
}
328+
if (!EntryPointMap.empty()) {
329+
EntryPointGroups.reserve(EntryPointMap.size());
330+
for (auto &EPG : EntryPointMap) {
331+
EntryPointGroups.emplace_back(EntryPointGroup{
332+
EPG.first, std::move(EPG.second), MD.getEntryPointGroup().Props});
333+
F(EntryPointGroups.back());
334+
}
335+
} else {
336+
// No entry points met, record this.
337+
EntryPointGroups.push_back({GLOBAL_SCOPE_NAME, {}});
338+
F(EntryPointGroups.back());
339+
}
340+
return EntryPointGroups;
341+
}
342+
302343
// Represents a call graph between functions in a module. Nodes are functions,
303344
// edges are "calls" relation.
304345
class CallGraph {
@@ -761,5 +802,28 @@ getLargeGRFSplitter(ModuleDesc &&MD, bool EmitOnlyKernelsAsEntryPoints) {
761802
return std::make_unique<ModuleCopier>(std::move(MD), std::move(Groups));
762803
}
763804

805+
std::unique_ptr<ModuleSplitterBase>
806+
getOptLevelSplitter(ModuleDesc &&MD, bool EmitOnlyKernelsAsEntryPoints) {
807+
EntryPointGroupVec Groups = groupEntryPointsByOptLevel(
808+
MD, ATTR_OPT_LEVEL, EmitOnlyKernelsAsEntryPoints,
809+
[](EntryPointGroup &G) {
810+
if (G.GroupId == "3")
811+
G.Props.OptLevel = 3;
812+
else if (G.GroupId == "2")
813+
G.Props.OptLevel = 2;
814+
else if (G.GroupId == "1")
815+
G.Props.OptLevel = 1;
816+
else if (G.GroupId == "0")
817+
G.Props.OptLevel = 0;
818+
});
819+
assert(!Groups.empty() && "At least one group is expected");
820+
assert(Groups.size() <= 2 && "At most 2 groups are expected");
821+
822+
if (Groups.size() > 1)
823+
return std::make_unique<ModuleSplitter>(std::move(MD), std::move(Groups));
824+
else
825+
return std::make_unique<ModuleCopier>(std::move(MD), std::move(Groups));
826+
}
827+
764828
} // namespace module_split
765829
} // namespace llvm

llvm/tools/sycl-post-link/ModuleSplitter.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,16 @@ struct EntryPointGroup {
6060
// Scope represented by EPs in a group
6161
EntryPointsGroupScope Scope = Scope_Global;
6262

63+
// opt level
64+
unsigned OptLevel = 2;
65+
6366
Properties merge(const Properties &Other) const {
6467
Properties Res;
6568
Res.HasESIMD = HasESIMD == Other.HasESIMD
6669
? HasESIMD
6770
: SyclEsimdSplitStatus::SYCL_AND_ESIMD;
6871
Res.UsesLargeGRF = UsesLargeGRF || Other.UsesLargeGRF;
72+
// Opt Level remains at '2'
6973
// Scope remains global
7074
return Res;
7175
}
@@ -93,6 +97,9 @@ struct EntryPointGroup {
9397
// Tells if some entry points use large GRF mode.
9498
bool isLargeGRF() const { return Props.UsesLargeGRF; }
9599

100+
// Get opt level.
101+
uint32_t getOptLevel() const { return Props.OptLevel; }
102+
96103
void saveNames(std::vector<std::string> &Dest) const;
97104
void rebuildFromNames(const std::vector<std::string> &Names, const Module &M);
98105
void rebuild(const Module &M);
@@ -147,6 +154,7 @@ class ModuleDesc {
147154
bool isESIMD() const { return EntryPoints.isEsimd(); }
148155
bool isSYCL() const { return EntryPoints.isSycl(); }
149156
bool isLargeGRF() const { return EntryPoints.isLargeGRF(); }
157+
uint32_t getOptLevel() const { return EntryPoints.getOptLevel(); }
150158

151159
const EntryPointSet &entries() const { return EntryPoints.Functions; }
152160
const EntryPointGroup &getEntryPointGroup() const { return EntryPoints; }
@@ -253,6 +261,9 @@ getSplitterByMode(ModuleDesc &&MD, IRSplitMode Mode,
253261
std::unique_ptr<ModuleSplitterBase>
254262
getLargeGRFSplitter(ModuleDesc &&MD, bool EmitOnlyKernelsAsEntryPoints);
255263

264+
std::unique_ptr<ModuleSplitterBase>
265+
getOptLevelSplitter(ModuleDesc &&MD, bool EmitOnlyKernelsAsEntryPoints);
266+
256267
#ifndef NDEBUG
257268
void dumpEntryPoints(const EntryPointSet &C, const char *msg = "", int Tab = 0);
258269
void dumpEntryPoints(const Module &M, bool OnlyKernelsAreEntryPoints = false,

0 commit comments

Comments
 (0)