Skip to content

Commit 9065472

Browse files
committed
Added support for SPV_INTEL_fpga_dsp_control
1 parent 22d10f0 commit 9065472

File tree

6 files changed

+214
-4
lines changed

6 files changed

+214
-4
lines changed

llvm/docs/SPIRVUsage.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,9 @@ list of supported SPIR-V extensions, sorted alphabetically by their extension na
212212
* - ``SPV_INTEL_ternary_bitwise_function``
213213
- Adds a bitwise instruction on three operands and a look-up table index for specifying the bitwise operation to perform.
214214
* - ``SPV_INTEL_subgroup_matrix_multiply_accumulate``
215-
- Adds an instruction to compute the matrix product of an M x K matrix with a K x N matrix and then add an M x N matrix.
215+
- Adds an instruction to compute the matrix product of an M x K matrix with a K x N matrix and then add an M x N matrix.
216+
* - ``SPV_INTEL_fpga_dsp_control``
217+
- Enables control over whether certain floating-point operations should be implemented using DSP blocks or logic elements on FPGA hardware, allowing fine-tuned optimization of resource usage and performance.
216218

217219
To enable multiple extensions, list them separated by comma. For example, to enable support for atomic operations on floating-point numbers and arbitrary precision integers, use:
218220

llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ static const std::map<std::string, SPIRV::Extension::Extension, std::less<>>
8787
SPIRV::Extension::Extension::SPV_KHR_shader_clock},
8888
{"SPV_KHR_cooperative_matrix",
8989
SPIRV::Extension::Extension::SPV_KHR_cooperative_matrix},
90+
{"SPV_INTEL_fpga_dsp_control",
91+
SPIRV::Extension::Extension::SPV_INTEL_fpga_dsp_control},
9092
{"SPV_KHR_non_semantic_info",
9193
SPIRV::Extension::Extension::SPV_KHR_non_semantic_info},
9294
{"SPV_INTEL_long_composites",

llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,8 @@ static void addOpDecorateReqs(const MachineInstr &MI, unsigned DecIndex,
920920
} else if (Dec == SPIRV::Decoration::FPMaxErrorDecorationINTEL) {
921921
Reqs.addRequirements(SPIRV::Capability::FPMaxErrorINTEL);
922922
Reqs.addExtension(SPIRV::Extension::SPV_INTEL_fp_max_error);
923+
} else if (Dec == SPIRV::Decoration::MathOpDSPModeINTEL) {
924+
Reqs.addExtension(SPIRV::Extension::Extension::SPV_INTEL_fpga_dsp_control);
923925
}
924926
}
925927

@@ -1976,17 +1978,63 @@ static void handleMIFlagDecoration(MachineInstr &I, const SPIRVSubtarget &ST,
19761978
buildOpDecorate(DstReg, I, TII, SPIRV::Decoration::FPFastMathMode, {FMFlags});
19771979
}
19781980

1979-
// Walk all functions and add decorations related to MI flags.
1981+
static std::vector<uint32_t>
1982+
getMetaDataValues(std::vector<llvm::MDNode *> &MetaDataList) {
1983+
std::vector<uint32_t> res;
1984+
for (auto metaDataNode : MetaDataList) {
1985+
if (metaDataNode->getNumOperands() > 0) {
1986+
if (auto *CMD = llvm::dyn_cast<llvm::ConstantAsMetadata>(
1987+
metaDataNode->getOperand(0))) {
1988+
if (auto *CI = llvm::dyn_cast<llvm::ConstantInt>(CMD->getValue())) {
1989+
APInt val = CI->getValue();
1990+
int64_t decVal = val.getZExtValue();
1991+
res.push_back(decVal);
1992+
}
1993+
}
1994+
}
1995+
}
1996+
return res;
1997+
}
1998+
1999+
static void handleFunctionDecoration(llvm::Module::const_iterator F,
2000+
const SPIRVInstrInfo &TII,
2001+
MachineModuleInfo *MMI,
2002+
const SPIRVSubtarget &ST,
2003+
MachineInstr &MI) {
2004+
Register Des = MI.getOperand(0).getReg();
2005+
MachineInstr *curr = &MI;
2006+
// dsp controll
2007+
if (llvm::MDNode *Node = F->getMetadata("prefer_dsp")) {
2008+
std::vector<llvm::MDNode *> MetaDataList;
2009+
MetaDataList.push_back(Node);
2010+
if (llvm::MDNode *Node = F->getMetadata("propagate_dsp_preference"))
2011+
MetaDataList.push_back(Node);
2012+
if (ST.canUseExtension(
2013+
SPIRV::Extension::Extension::SPV_INTEL_fpga_dsp_control)) {
2014+
std::vector<uint32_t> params = getMetaDataValues(MetaDataList);
2015+
if (params.size() == 1)
2016+
params.push_back(0);
2017+
buildOpDecorate(Des, *curr, TII, SPIRV::Decoration::MathOpDSPModeINTEL,
2018+
params);
2019+
}
2020+
}
2021+
}
2022+
2023+
// Walk all functions and add decorations related to MI flags and function metadata.
19802024
static void addDecorations(const Module &M, const SPIRVInstrInfo &TII,
19812025
MachineModuleInfo *MMI, const SPIRVSubtarget &ST,
19822026
SPIRV::ModuleAnalysisInfo &MAI) {
19832027
for (auto F = M.begin(), E = M.end(); F != E; ++F) {
19842028
MachineFunction *MF = MMI->getMachineFunction(*F);
19852029
if (!MF)
19862030
continue;
1987-
for (auto &MBB : *MF)
1988-
for (auto &MI : MBB)
2031+
for (auto &MBB : *MF) {
2032+
for (auto &MI : MBB) {
2033+
if (MI.getOpcode() == SPIRV::OpFunction)
2034+
handleFunctionDecoration(F, TII, MMI, ST, MI);
19892035
handleMIFlagDecoration(MI, ST, TII, MAI.Reqs);
2036+
}
2037+
}
19902038
}
19912039
}
19922040

llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,7 @@ defm MemoryAccessAliasingINTEL : CapabilityOperand<5910, 0, 0, [SPV_INTEL_memory
517517
defm FPMaxErrorINTEL : CapabilityOperand<6169, 0, 0, [SPV_INTEL_fp_max_error], []>;
518518
defm TernaryBitwiseFunctionINTEL : CapabilityOperand<6241, 0, 0, [SPV_INTEL_ternary_bitwise_function], []>;
519519
defm SubgroupMatrixMultiplyAccumulateINTEL : CapabilityOperand<6236, 0, 0, [SPV_INTEL_subgroup_matrix_multiply_accumulate], []>;
520+
defm FPGADSPControlINTEL : CapabilityOperand<5908, 0, 0, [SPV_INTEL_fpga_dsp_control], []>;
520521

521522
//===----------------------------------------------------------------------===//
522523
// Multiclass used to define SourceLanguage enum values and at the same time
@@ -1268,6 +1269,7 @@ defm FunctionFloatingPointModeINTEL : DecorationOperand<6080, 0, 0, [], [Functio
12681269
defm AliasScopeINTEL : DecorationOperand<5914, 0, 0, [], [MemoryAccessAliasingINTEL]>;
12691270
defm NoAliasINTEL : DecorationOperand<5915, 0, 0, [], [MemoryAccessAliasingINTEL]>;
12701271
defm FPMaxErrorDecorationINTEL : DecorationOperand<6170, 0, 0, [], [FPMaxErrorINTEL]>;
1272+
defm MathOpDSPModeINTEL : DecorationOperand<5909, 0, 0, [], [FPGADSPControlINTEL]>;
12711273

12721274
//===----------------------------------------------------------------------===//
12731275
// Multiclass used to define BuiltIn enum values and at the same time
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
; template<typename Function>
2+
; [[intel::prefer_dsp]]
3+
; void math_prefer_dsp_propagate(Function f)
4+
; {
5+
; f();
6+
; }
7+
8+
; int main() {
9+
; math_prefer_dsp_propagate([]() {
10+
; int a = 0;
11+
; a += 1;
12+
; });
13+
14+
; return 0;
15+
; }
16+
17+
18+
; RUN: llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_fpga_dsp_control %s -o - | FileCheck %s --check-prefixes=CHECK-SPIRV
19+
20+
21+
; CHECK-SPIRV: OpCapability FPGADSPControlINTEL
22+
; CHECK-SPIRV: OpExtension "SPV_INTEL_fpga_dsp_control"
23+
; CHECK-SPIRV: OpName %[[#FuncNameId:]] "_Z25math_prefer_dsp_propagateIZ4mainE3$_0EvT_"
24+
; CHECK-SPIRV: OpDecorate %[[#FuncNameId]] MathOpDSPModeINTEL 1 0
25+
26+
27+
; ModuleID = 'prefer_dsp.cpp'
28+
source_filename = "prefer_dsp.cpp"
29+
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"
30+
target triple = "spir64-unknown-unknown"
31+
32+
%class.anon = type { i8 }
33+
34+
; Function Attrs: noinline norecurse optnone mustprogress
35+
define dso_local i32 @main() #0 {
36+
entry:
37+
%retval = alloca i32, align 4
38+
%agg.tmp = alloca %class.anon, align 1
39+
store i32 0, ptr %retval, align 4
40+
call spir_func void @"_Z25math_prefer_dsp_propagateIZ4mainE3$_0EvT_"(ptr byval(%class.anon) align 1 %agg.tmp)
41+
ret i32 0
42+
}
43+
44+
; Function Attrs: noinline optnone mustprogress
45+
define internal spir_func void @"_Z25math_prefer_dsp_propagateIZ4mainE3$_0EvT_"(ptr byval(%class.anon) align 1 %f) #1 !prefer_dsp !3 {
46+
entry:
47+
call spir_func void @"_ZZ4mainENK3$_0clEv"(ptr nonnull dereferenceable(1) %f)
48+
ret void
49+
}
50+
51+
; Function Attrs: noinline nounwind optnone mustprogress
52+
define internal spir_func void @"_ZZ4mainENK3$_0clEv"(ptr nonnull dereferenceable(1) %this) #2 align 2 {
53+
entry:
54+
%this.addr = alloca ptr, align 8
55+
%a = alloca i32, align 4
56+
store ptr %this, ptr %this.addr, align 8
57+
%this1 = load ptr, ptr %this.addr, align 8
58+
store i32 0, ptr %a, align 4
59+
%0 = load i32, ptr %a, align 4
60+
%add = add nsw i32 %0, 1
61+
store i32 %add, ptr %a, align 4
62+
ret void
63+
}
64+
65+
attributes #0 = { noinline norecurse optnone mustprogress "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
66+
attributes #1 = { noinline optnone mustprogress "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
67+
attributes #2 = { noinline nounwind optnone mustprogress "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
68+
69+
!llvm.module.flags = !{!0}
70+
!opencl.used.extensions = !{!1}
71+
!opencl.used.optional.core.features = !{!1}
72+
!opencl.compiler.options = !{!1}
73+
!llvm.ident = !{!2}
74+
75+
!0 = !{i32 1, !"wchar_size", i32 4}
76+
!1 = !{}
77+
!2 = !{!"clang version 13.0.0 (https://github.com/llvm/llvm-project.git 7d09e1d7cf27ce781e83f9d388a7a3e1e6487ead)"}
78+
!3 = !{i32 1}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
; template<typename Function>
2+
; [[intel::prefer_dsp]]
3+
; [[intel::propagate_dsp_preference]]
4+
; void math_prefer_dsp_propagate(Function f)
5+
; {
6+
; f();
7+
; }
8+
9+
; int main() {
10+
; math_prefer_dsp_propagate([]() {
11+
; int a = 0;
12+
; a += 1;
13+
; });
14+
15+
; return 0;
16+
; }
17+
18+
; RUN: llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_fpga_dsp_control %s -o - | FileCheck %s --check-prefixes=CHECK-SPIRV
19+
20+
21+
; CHECK-SPIRV: OpCapability FPGADSPControlINTEL
22+
; CHECK-SPIRV: OpExtension "SPV_INTEL_fpga_dsp_control"
23+
; CHECK-SPIRV: OpName %[[#FuncNameId:]] "_Z25math_prefer_dsp_propagateIZ4mainE3$_0EvT_"
24+
; CHECK-SPIRV: OpDecorate %[[#FuncNameId]] MathOpDSPModeINTEL 1 1
25+
26+
27+
; ModuleID = 'prefer_dsp_propagate.cpp'
28+
source_filename = "prefer_dsp_propagate.cpp"
29+
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"
30+
target triple = "spir64-unknown-unknown"
31+
32+
%class.anon = type { i8 }
33+
34+
; Function Attrs: noinline norecurse optnone mustprogress
35+
define dso_local i32 @main() #0 {
36+
entry:
37+
%retval = alloca i32, align 4
38+
%agg.tmp = alloca %class.anon, align 1
39+
store i32 0, ptr %retval, align 4
40+
call spir_func void @"_Z25math_prefer_dsp_propagateIZ4mainE3$_0EvT_"(ptr byval(%class.anon) align 1 %agg.tmp)
41+
ret i32 0
42+
}
43+
44+
; Function Attrs: noinline optnone mustprogress
45+
define internal spir_func void @"_Z25math_prefer_dsp_propagateIZ4mainE3$_0EvT_"(ptr byval(%class.anon) align 1 %f) #1 !prefer_dsp !3 !propagate_dsp_preference !3 {
46+
entry:
47+
call spir_func void @"_ZZ4mainENK3$_0clEv"(ptr nonnull dereferenceable(1) %f)
48+
ret void
49+
}
50+
51+
; Function Attrs: noinline nounwind optnone mustprogress
52+
define internal spir_func void @"_ZZ4mainENK3$_0clEv"(ptr nonnull dereferenceable(1) %this) #2 align 2 {
53+
entry:
54+
%this.addr = alloca ptr, align 8
55+
%a = alloca i32, align 4
56+
store ptr %this, ptr %this.addr, align 8
57+
%this1 = load ptr, ptr %this.addr, align 8
58+
store i32 0, ptr %a, align 4
59+
%0 = load i32, ptr %a, align 4
60+
%add = add nsw i32 %0, 1
61+
store i32 %add, ptr %a, align 4
62+
ret void
63+
}
64+
65+
attributes #0 = { noinline norecurse optnone mustprogress "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
66+
attributes #1 = { noinline optnone mustprogress "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
67+
attributes #2 = { noinline nounwind optnone mustprogress "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
68+
69+
!llvm.module.flags = !{!0}
70+
!opencl.used.extensions = !{!1}
71+
!opencl.used.optional.core.features = !{!1}
72+
!opencl.compiler.options = !{!1}
73+
!llvm.ident = !{!2}
74+
75+
!0 = !{i32 1, !"wchar_size", i32 4}
76+
!1 = !{}
77+
!2 = !{!"clang version 13.0.0 (https://github.com/llvm/llvm-project.git 7d09e1d7cf27ce781e83f9d388a7a3e1e6487ead)"}
78+
!3 = !{i32 1}

0 commit comments

Comments
 (0)