Skip to content

Commit 4480f8b

Browse files
authored
[SYCLLowerIR] Add support for FPGA latency control extension (#8705)
This PR adds support to lower compile time properties and generate llvm pointer annotations ready to be consumed by SPIR-V gen. The compile-time properties lowered are latency-anchor-id and latency-constraint. Thanks --------- Signed-off-by: Arvind Sudarsanam <[email protected]>
1 parent ad66442 commit 4480f8b

File tree

3 files changed

+116
-26
lines changed

3 files changed

+116
-26
lines changed

llvm/lib/SYCLLowerIR/CompileTimeProperties.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,5 @@ SYCL_COMPILE_TIME_PROPERTY("sycl-alignment", 44, DecorValueTy::uint32)
3131
SYCL_COMPILE_TIME_PROPERTY("sycl-wait-request", 6182, DecorValueTy::uint32)
3232
SYCL_COMPILE_TIME_PROPERTY("sycl-stable", 6183, DecorValueTy::boolean)
3333
SYCL_COMPILE_TIME_PROPERTY("sycl-strict", 19, DecorValueTy::boolean)
34+
SYCL_COMPILE_TIME_PROPERTY("sycl-latency-anchor-id", 6172, DecorValueTy::string)
35+
SYCL_COMPILE_TIME_PROPERTY("sycl-latency-constraint", 6173, DecorValueTy::string)

llvm/lib/SYCLLowerIR/CompileTimePropertiesPass.cpp

Lines changed: 53 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ constexpr uint32_t SPIRV_PIPELINE_ENABLE_DECOR = 5919;
4242
enum class DecorValueTy {
4343
uint32,
4444
boolean,
45+
string,
4546
none,
4647
};
4748

@@ -78,6 +79,27 @@ MDNode *buildSpirvDecorMetadata(LLVMContext &Ctx, uint32_t OpCode,
7879
return MDNode::get(Ctx, MD);
7980
}
8081

82+
/// Builds a metadata node for a SPIR-V decoration (decoration code
83+
/// is \c uint32_t integer and value is a string).
84+
///
85+
/// @param Ctx [in] the LLVM Context.
86+
/// @param OpCode [in] the SPIR-V OpCode code.
87+
/// @param Value [in] the SPIR-V decoration value.
88+
///
89+
/// @returns a pointer to the metadata node created for the required decoration
90+
/// and its value.
91+
MDNode *buildSpirvDecorMetadata(LLVMContext &Ctx, uint32_t OpCode,
92+
StringRef Value) {
93+
auto *Ty = Type::getInt32Ty(Ctx);
94+
SmallVector<Metadata *, 2> MD;
95+
MD.push_back(ConstantAsMetadata::get(
96+
Constant::getIntegerValue(Ty, APInt(32, OpCode))));
97+
MD.push_back(
98+
ConstantAsMetadata::get(ConstantDataArray::getString(Ctx, Value,
99+
/*AddNull=*/true)));
100+
return MDNode::get(Ctx, MD);
101+
}
102+
81103
/// Builds a metadata node for a SPIR-V decoration (both decoration code
82104
/// and value are \c uint32_t integers, and the secondary extra operand is a
83105
/// string).
@@ -143,6 +165,8 @@ MDNode *attributeToDecorateMetadata(LLVMContext &Ctx, const Attribute &Attr) {
143165
getAttributeAsInteger<uint32_t>(Attr));
144166
case DecorValueTy::boolean:
145167
return buildSpirvDecorMetadata(Ctx, DecorCode, hasProperty(Attr));
168+
case DecorValueTy::string:
169+
return buildSpirvDecorMetadata(Ctx, DecorCode, Attr.getValueAsString());
146170
default:
147171
llvm_unreachable("Unhandled decorator type.");
148172
}
@@ -251,29 +275,31 @@ parseSYCLPropertiesString(Module &M, IntrinsicInst *IntrInst) {
251275
SmallVector<std::pair<std::optional<StringRef>, std::optional<StringRef>>, 8>
252276
result;
253277

254-
if (const auto *Cast =
255-
dyn_cast<BitCastOperator>(IntrInst->getArgOperand(4))) {
256-
if (const auto *AnnotValsGV =
257-
dyn_cast<GlobalVariable>(Cast->getOperand(0))) {
258-
if (const auto *AnnotValsAggr =
259-
dyn_cast<ConstantAggregate>(AnnotValsGV->getInitializer())) {
260-
assert(
261-
(AnnotValsAggr->getNumOperands() & 1) == 0 &&
262-
"sycl-properties annotation must have an even number of annotation "
263-
"values.");
264-
265-
// Iterate over the pairs of property meta-names and meta-values.
266-
for (size_t I = 0; I < AnnotValsAggr->getNumOperands(); I += 2) {
267-
std::optional<StringRef> PropMetaName =
268-
getGlobalVariableString(AnnotValsAggr->getOperand(I));
269-
std::optional<StringRef> PropMetaValue =
270-
getGlobalVariableString(AnnotValsAggr->getOperand(I + 1));
271-
272-
assert(PropMetaName &&
273-
"Unexpected format for property name in annotation.");
274-
275-
result.push_back(std::make_pair(PropMetaName, PropMetaValue));
276-
}
278+
auto AnnotValsIntrOpd = IntrInst->getArgOperand(4);
279+
const GlobalVariable *AnnotValsGV = nullptr;
280+
if (AnnotValsIntrOpd->getType()->isOpaquePointerTy())
281+
AnnotValsGV = dyn_cast<GlobalVariable>(AnnotValsIntrOpd);
282+
else if (const auto *Cast = dyn_cast<BitCastOperator>(AnnotValsIntrOpd))
283+
AnnotValsGV = dyn_cast<GlobalVariable>(Cast->getOperand(0));
284+
if (AnnotValsGV) {
285+
if (const auto *AnnotValsAggr =
286+
dyn_cast<ConstantAggregate>(AnnotValsGV->getInitializer())) {
287+
assert(
288+
(AnnotValsAggr->getNumOperands() & 1) == 0 &&
289+
"sycl-properties annotation must have an even number of annotation "
290+
"values.");
291+
292+
// Iterate over the pairs of property meta-names and meta-values.
293+
for (size_t I = 0; I < AnnotValsAggr->getNumOperands(); I += 2) {
294+
std::optional<StringRef> PropMetaName =
295+
getGlobalVariableString(AnnotValsAggr->getOperand(I));
296+
std::optional<StringRef> PropMetaValue =
297+
getGlobalVariableString(AnnotValsAggr->getOperand(I + 1));
298+
299+
assert(PropMetaName &&
300+
"Unexpected format for property name in annotation.");
301+
302+
result.push_back(std::make_pair(PropMetaName, PropMetaValue));
277303
}
278304
}
279305
}
@@ -510,9 +536,10 @@ bool CompileTimePropertiesPass::transformSYCLPropertiesAnnotation(
510536
// Get the global variable with the annotation string.
511537
const GlobalVariable *AnnotStrArgGV = nullptr;
512538
const Value *IntrAnnotStringArg = IntrInst->getArgOperand(1);
513-
if (auto *GEP = dyn_cast<GEPOperator>(IntrAnnotStringArg))
514-
if (auto *C = dyn_cast<Constant>(GEP->getOperand(0)))
515-
AnnotStrArgGV = dyn_cast<GlobalVariable>(C);
539+
if (IntrAnnotStringArg->getType()->isOpaquePointerTy())
540+
AnnotStrArgGV = dyn_cast<GlobalVariable>(IntrAnnotStringArg);
541+
else if (auto *GEP = dyn_cast<GEPOperator>(IntrAnnotStringArg))
542+
AnnotStrArgGV = dyn_cast<GlobalVariable>(GEP->getOperand(0));
516543
if (!AnnotStrArgGV)
517544
return false;
518545

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
; RUN: opt -passes=compile-time-properties %s -S | FileCheck %s
2+
3+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64"
4+
target triple = "spir64-unknown-unknown"
5+
6+
%struct.__spirv_Something = type { i32, i32 }
7+
8+
$_ZTSZ4fooEUlvE_ = comdat any
9+
10+
@.str = private unnamed_addr constant [16 x i8] c"sycl-properties\00", section "llvm.metadata"
11+
@.str.1 = private unnamed_addr constant [19 x i8] c"inc/fpga_utils.hpp\00", section "llvm.metadata"
12+
@.str.2 = private unnamed_addr constant [23 x i8] c"sycl-latency-anchor-id\00", section "llvm.metadata"
13+
@.str.3 = private unnamed_addr constant [2 x i8] c"0\00", section "llvm.metadata"
14+
@.args = private unnamed_addr constant { ptr , ptr } { ptr @.str.2, ptr @.str.3 }, section "llvm.metadata"
15+
@.str.6 = private unnamed_addr constant [2 x i8] c"1\00", section "llvm.metadata"
16+
@.str.7 = private unnamed_addr constant [24 x i8] c"sycl-latency-constraint\00", section "llvm.metadata"
17+
@.str.8 = private unnamed_addr constant [6 x i8] c"0,1,5\00", section "llvm.metadata"
18+
@.args.9 = private unnamed_addr constant { ptr , ptr , ptr , ptr } { ptr @.str.2, ptr @.str.6, ptr @.str.7, ptr @.str.8 }, section "llvm.metadata"
19+
20+
;CHECK: @[[NewAnnotStr1:.*]] = private unnamed_addr constant [11 x i8] c"{6172:\220\22}\00"
21+
;CHECK: @[[NewAnnotStr2:.*]] = private unnamed_addr constant [25 x i8] c"{6172:\221\22}{6173:\220,1,5\22}\00"
22+
23+
; Function Attrs: mustprogress norecurse
24+
define weak_odr dso_local spir_kernel void @_ZTSZ4fooEUlvE_(ptr %0) local_unnamed_addr #0 comdat !kernel_arg_buffer_location !5 !sycl_kernel_omit_args !5 {
25+
entry:
26+
%1 = alloca ptr , align 8
27+
store ptr %0, ptr %1, align 8
28+
%2 = load ptr , ptr %1, align 8
29+
%3 = getelementptr inbounds %struct.__spirv_Something, ptr %2, i32 0, i32 0
30+
%4 = bitcast ptr %3 to ptr
31+
%5 = call ptr @llvm.ptr.annotation.p0.p0(ptr %4, ptr @.str, ptr @.str.1, i32 5, ptr @.args)
32+
; CHECK: %{{.*}} = call ptr @llvm.ptr.annotation.p0.p0(ptr %[[#]], ptr @[[NewAnnotStr1]], ptr @.str.1, i32 5, ptr null)
33+
%6 = bitcast ptr %5 to ptr
34+
%7 = load i32, ptr %6, align 8
35+
%8 = load ptr , ptr %1, align 8
36+
%9 = getelementptr inbounds %struct.__spirv_Something, ptr %8, i32 0, i32 1
37+
%10 = bitcast ptr %9 to ptr
38+
%11 = call ptr @llvm.ptr.annotation.p0.p0(ptr %10, ptr @.str, ptr @.str.1, i32 5, ptr @.args.9)
39+
; CHECK: %{{.*}} = call ptr @llvm.ptr.annotation.p0.p0(ptr %[[#]], ptr @[[NewAnnotStr2]], ptr @.str.1, i32 5, ptr null)
40+
%12 = bitcast ptr %11 to ptr
41+
%13 = load i32, ptr %12, align 8
42+
ret void
43+
}
44+
45+
; Function Attrs: nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)
46+
declare ptr @llvm.ptr.annotation.p0.p0(ptr , ptr , ptr , i32, ptr ) #1
47+
48+
attributes #0 = { mustprogress norecurse "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "sycl-module-id"="sycl-properties-ptr-annotations.cpp" "uniform-work-group-size"="true" }
49+
attributes #1 = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) }
50+
51+
!opencl.spir.version = !{!0, !0, !0, !0, !0, !0}
52+
!spirv.Source = !{!1, !1, !1, !1, !1, !1}
53+
!llvm.ident = !{!2, !2, !2, !2, !2, !2}
54+
!llvm.module.flags = !{!3, !4}
55+
56+
!0 = !{i32 1, i32 2}
57+
!1 = !{i32 4, i32 100000}
58+
!2 = !{!"clang version 15.0.0"}
59+
!3 = !{i32 1, !"wchar_size", i32 4}
60+
!4 = !{i32 7, !"frame-pointer", i32 2}
61+
!5 = !{}

0 commit comments

Comments
 (0)