Skip to content

Commit ccac403

Browse files
authored
[CIR][CodeGen][LowerToLLVM] Emit OpenCL version metadata for SPIR-V target (#773)
Similar to #767, this PR emit the module level OpenCL version metadata following the OG CodeGen skeleton. We use a full qualified `cir.cl.version` attribute on the module op to store the info in CIR.
1 parent 6d069d3 commit ccac403

File tree

5 files changed

+89
-0
lines changed

5 files changed

+89
-0
lines changed

clang/include/clang/CIR/Dialect/IR/CIROpenCLAttrs.td

+21
Original file line numberDiff line numberDiff line change
@@ -147,4 +147,25 @@ def OpenCLKernelArgMetadataAttr
147147
let genVerifyDecl = 1;
148148
}
149149

150+
//===----------------------------------------------------------------------===//
151+
// OpenCLVersionAttr
152+
//===----------------------------------------------------------------------===//
153+
154+
def OpenCLVersionAttr : CIR_Attr<"OpenCLVersion", "cl.version"> {
155+
let summary = "OpenCL version";
156+
let parameters = (ins "int32_t":$major, "int32_t":$minor);
157+
let description = [{
158+
Represents the version of OpenCL.
159+
160+
Example:
161+
```
162+
// Module compiled from OpenCL 1.2.
163+
module attributes {cir.cl.version = cir.cl.version<1, 2>} {}
164+
// Module compiled from OpenCL 3.0.
165+
module attributes {cir.cl.version = cir.cl.version<3, 0>} {}
166+
```
167+
}];
168+
let assemblyFormat = "`<` $major `,` $minor `>`";
169+
}
170+
150171
#endif // MLIR_CIR_DIALECT_CIR_OPENCL_ATTRS

clang/lib/CIR/CodeGen/CIRGenModule.cpp

+24
Original file line numberDiff line numberDiff line change
@@ -2767,6 +2767,16 @@ void CIRGenModule::Release() {
27672767
// TODO: buildModuleLinkOptions
27682768
}
27692769

2770+
// Emit OpenCL specific module metadata: OpenCL/SPIR version.
2771+
if (langOpts.CUDAIsDevice && getTriple().isSPIRV())
2772+
llvm_unreachable("CUDA SPIR-V NYI");
2773+
if (langOpts.OpenCL) {
2774+
buildOpenCLMetadata();
2775+
// Emit SPIR version.
2776+
if (getTriple().isSPIR())
2777+
llvm_unreachable("SPIR target NYI");
2778+
}
2779+
27702780
// TODO: FINISH THE REST OF THIS
27712781
}
27722782

@@ -3234,3 +3244,17 @@ void CIRGenModule::genKernelArgMetadata(mlir::cir::FuncOp Fn,
32343244
llvm_unreachable("NYI HIPSaveKernelArgName");
32353245
}
32363246
}
3247+
3248+
void CIRGenModule::buildOpenCLMetadata() {
3249+
// SPIR v2.0 s2.13 - The OpenCL version used by the module is stored in the
3250+
// opencl.ocl.version named metadata node.
3251+
// C++ for OpenCL has a distinct mapping for versions compatibile with OpenCL.
3252+
unsigned version = langOpts.getOpenCLCompatibleVersion();
3253+
unsigned major = version / 100;
3254+
unsigned minor = (version % 100) / 10;
3255+
3256+
auto clVersionAttr =
3257+
mlir::cir::OpenCLVersionAttr::get(builder.getContext(), major, minor);
3258+
3259+
theModule->setAttr("cir.cl.version", clVersionAttr);
3260+
}

clang/lib/CIR/CodeGen/CIRGenModule.h

+3
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,9 @@ class CIRGenModule : public CIRGenTypeCache {
702702
const FunctionDecl *FD = nullptr,
703703
CIRGenFunction *CGF = nullptr);
704704

705+
/// Emits OpenCL specific Metadata e.g. OpenCL version.
706+
void buildOpenCLMetadata();
707+
705708
private:
706709
// An ordered map of canonical GlobalDecls to their mangled names.
707710
llvm::MapVector<clang::GlobalDecl, llvm::StringRef> MangledDeclNames;

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVMIR.cpp

+25
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ class CIRDialectLLVMIRTranslationInterface
4141
mlir::LLVM::ModuleTranslation &moduleTranslation) const override {
4242
if (auto func = dyn_cast<mlir::LLVM::LLVMFuncOp>(op)) {
4343
amendFunction(func, instructions, attribute, moduleTranslation);
44+
} else if (auto mod = dyn_cast<mlir::ModuleOp>(op)) {
45+
amendModule(mod, attribute, moduleTranslation);
4446
}
4547
return mlir::success();
4648
}
@@ -60,6 +62,29 @@ class CIRDialectLLVMIRTranslationInterface
6062
}
6163

6264
private:
65+
// Translate CIR's module attributes to LLVM's module metadata
66+
void amendModule(mlir::ModuleOp module, mlir::NamedAttribute attribute,
67+
mlir::LLVM::ModuleTranslation &moduleTranslation) const {
68+
llvm::Module *llvmModule = moduleTranslation.getLLVMModule();
69+
llvm::LLVMContext &llvmContext = llvmModule->getContext();
70+
71+
if (auto openclVersionAttr = mlir::dyn_cast<mlir::cir::OpenCLVersionAttr>(
72+
attribute.getValue())) {
73+
auto *int32Ty = llvm::IntegerType::get(llvmContext, 32);
74+
llvm::Metadata *oclVerElts[] = {
75+
llvm::ConstantAsMetadata::get(
76+
llvm::ConstantInt::get(int32Ty, openclVersionAttr.getMajor())),
77+
llvm::ConstantAsMetadata::get(
78+
llvm::ConstantInt::get(int32Ty, openclVersionAttr.getMinor()))};
79+
llvm::NamedMDNode *oclVerMD =
80+
llvmModule->getOrInsertNamedMetadata("opencl.ocl.version");
81+
oclVerMD->addOperand(llvm::MDNode::get(llvmContext, oclVerElts));
82+
}
83+
84+
// Drop ammended CIR attribute from LLVM op.
85+
module->removeAttr(attribute.getName());
86+
}
87+
6388
// Translate CIR's extra function attributes to LLVM's function attributes.
6489
void amendFunction(mlir::LLVM::LLVMFuncOp func,
6590
llvm::ArrayRef<llvm::Instruction *> instructions,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %clang_cc1 -cl-std=CL3.0 -O0 -fclangir -emit-cir -triple spirv64-unknown-unknown %s -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR-CL30
3+
// RUN: %clang_cc1 -cl-std=CL3.0 -O0 -fclangir -emit-llvm -triple spirv64-unknown-unknown %s -o %t.ll
4+
// RUN: FileCheck --input-file=%t.ll %s --check-prefix=LLVM-CL30
5+
// RUN: %clang_cc1 -cl-std=CL1.2 -O0 -fclangir -emit-cir -triple spirv64-unknown-unknown %s -o %t.cir
6+
// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR-CL12
7+
// RUN: %clang_cc1 -cl-std=CL1.2 -O0 -fclangir -emit-llvm -triple spirv64-unknown-unknown %s -o %t.ll
8+
// RUN: FileCheck --input-file=%t.ll %s --check-prefix=LLVM-CL12
9+
10+
// CIR-CL30: module {{.*}} attributes {{{.*}}cir.cl.version = #cir.cl.version<3, 0>
11+
// LLVM-CL30: !opencl.ocl.version = !{![[MDCL30:[0-9]+]]}
12+
// LLVM-CL30: ![[MDCL30]] = !{i32 3, i32 0}
13+
14+
// CIR-CL12: module {{.*}} attributes {{{.*}}cir.cl.version = #cir.cl.version<1, 2>
15+
// LLVM-CL12: !opencl.ocl.version = !{![[MDCL12:[0-9]+]]}
16+
// LLVM-CL12: ![[MDCL12]] = !{i32 1, i32 2}

0 commit comments

Comments
 (0)