Skip to content

Commit b4f1a34

Browse files
author
Mahmood Yassin
committed
Support general and minimal ocl opaque type
1 parent f3a8198 commit b4f1a34

File tree

11 files changed

+141
-22
lines changed

11 files changed

+141
-22
lines changed

clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,10 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
168168
return cir::ZeroAttr::get(RecordTy);
169169
if (auto methodTy = mlir::dyn_cast<cir::MethodType>(ty))
170170
return getNullMethodAttr(methodTy);
171-
if (mlir::isa<cir::BoolType>(ty)) {
171+
if (mlir::isa<cir::BoolType>(ty))
172172
return getFalseAttr();
173-
}
173+
if (mlir::isa<cir::OpaqueType>(ty))
174+
return cir::ZeroAttr::get(ty);
174175
llvm_unreachable("Zero initializer for given type is NYI");
175176
}
176177

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

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,48 @@ def CIR_RecordType : CIR_Type<"Record", "record", [
752752
def CIRRecordType : Type<
753753
CPred<"::mlir::isa<::cir::RecordType>($_self)">, "CIR record type">;
754754

755+
//===----------------------------------------------------------------------===//
756+
// Minimal opaque type (used for OpenCL opaque builtin types)
757+
//===----------------------------------------------------------------------===//
758+
759+
def CIR_OCLOpaqueType : CIR_Type<"Opaque", "opaque"> {
760+
let summary = "Named opaque type for OpenCL-style builtin opaque objects";
761+
762+
let description = [{
763+
Represents a target-independent opaque type used for OpenCL opaque
764+
builtin types such as `event_t`, `sampler_t`, `clk_event_t` and `queue_t`.
765+
766+
The type has no defined size or layout. CIR carries it through
767+
lowering and delegates the final representation to the target codegen
768+
(e.g. SPIR/SPIR-V lowering), which maps the logical opaque kind to
769+
the correct LLVM type.
770+
771+
The `tag` attribute identifies the opaque category (e.g. `"event"`).
772+
Values of this type typically appear only through pointer types.
773+
774+
Example:
775+
!cir.ptr<!cir.opaque<"event">, addrspace(1)>
776+
}];
777+
778+
let parameters = (ins "mlir::StringAttr":$tag);
779+
780+
let builders = [
781+
TypeBuilder<(ins "mlir::StringAttr":$tag), [{
782+
return $_get($_ctxt, tag);
783+
}]>
784+
];
785+
786+
let extraClassDeclaration = [{
787+
static llvm::StringRef getEventTag() { return "event"; }
788+
}];
789+
790+
let assemblyFormat = [{
791+
`<` $tag `>`
792+
}];
793+
794+
let skipDefaultBuilders = 1;
795+
}
796+
755797
//===----------------------------------------------------------------------===//
756798
// Global type constraints
757799
//===----------------------------------------------------------------------===//
@@ -760,7 +802,7 @@ def CIR_AnyType : AnyTypeOf<[
760802
CIR_IntType, CIR_PointerType, CIR_DataMemberType, CIR_MethodType,
761803
CIR_BoolType, CIR_ArrayType, CIR_VectorType, CIR_FuncType, CIR_VoidType,
762804
CIR_RecordType, CIR_ExceptionType, CIR_AnyFloatType, CIR_ComplexType,
763-
CIR_VPtrType
805+
CIR_VPtrType, CIR_OCLOpaqueType
764806
]>;
765807

766808
#endif // MLIR_CIR_DIALECT_CIR_TYPES

clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2123,18 +2123,11 @@ mlir::Value ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
21232123
return emitComplexToScalarConversion(CGF.getLoc(CE->getExprLoc()), V, Kind,
21242124
DestTy);
21252125
}
2126-
case CK_ZeroToOCLOpaqueType: {
2126+
case CK_ZeroToOCLOpaqueType:
21272127
// OpenCL: event_t e = async_work_group_copy(..., 0);
21282128
// The source is an integer constant zero; the destination is an OpenCL
21292129
// opaque type
2130-
mlir::Type destTy = CGF.convertType(DestTy);
2131-
auto PtrTy =
2132-
cir::PointerType::get(destTy, cir::AddressSpace::OffloadPrivate);
2133-
auto constNullPtrAttr = Builder.getConstNullPtrAttr(PtrTy);
2134-
auto nullVal =
2135-
Builder.getConstant(CGF.getLoc(E->getExprLoc()), constNullPtrAttr);
2136-
return nullVal;
2137-
}
2130+
return emitNullValue(DestTy, CGF.getLoc(E->getExprLoc()));
21382131
case CK_IntToOCLSampler:
21392132
llvm_unreachable("NYI");
21402133

clang/lib/CIR/CodeGen/CIRGenTypes.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -512,18 +512,23 @@ mlir::Type CIRGenTypes::convertType(QualType T) {
512512
#include "clang/Basic/OpenCLImageTypes.def"
513513
#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) case BuiltinType::Id:
514514
#include "clang/Basic/OpenCLExtensionTypes.def"
515-
case BuiltinType::OCLSampler:
516515
case BuiltinType::OCLEvent:
516+
ResultType = cir::OpaqueType::get(
517+
Builder.getContext(),
518+
mlir::StringAttr::get(Builder.getContext(),
519+
cir::OpaqueType::getEventTag()));
520+
break;
521+
case BuiltinType::OCLSampler:
517522
case BuiltinType::OCLClkEvent:
518523
case BuiltinType::OCLQueue:
519-
ResultType = Builder.getVoidPtrTy();
524+
llvm_unreachable("NYI");
520525
break;
521526
case BuiltinType::OCLReserveID:
522527
ResultType = cir::RecordType::get(
523528
&getMLIRContext(), {},
524529
mlir::StringAttr::get(&getMLIRContext(), "ocl_reserve_id"), false,
525530
false, cir::RecordType::Struct);
526-
break;
531+
527532
case BuiltinType::SveInt8:
528533
case BuiltinType::SveUint8:
529534
case BuiltinType::SveInt8x2:

clang/lib/CIR/Dialect/IR/CIRDialect.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ static LogicalResult checkConstantTypes(mlir::Operation *op, mlir::Type opType,
439439

440440
if (isa<cir::ZeroAttr>(attrType)) {
441441
if (::mlir::isa<cir::RecordType, cir::ArrayType, cir::ComplexType,
442-
cir::VectorType>(opType))
442+
cir::VectorType, cir::OpaqueType>(opType))
443443
return success();
444444
return op->emitOpError("zero expects record or array type");
445445
}

clang/lib/CIR/Dialect/Transforms/TargetLowering/TargetLoweringInfo.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ class TargetLoweringInfo {
3535

3636
virtual unsigned
3737
getTargetAddrSpaceFromCIRAddrSpace(cir::LangAddressSpace addrSpace) const = 0;
38+
39+
virtual mlir::Type getOpaqueType(cir::OpaqueType type) const {
40+
llvm_unreachable("NYI");
41+
}
3842
};
3943

4044
} // namespace cir

clang/lib/CIR/Dialect/Transforms/TargetLowering/Targets/AMDGPU.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "clang/CIR/MissingFeatures.h"
1818
#include "llvm/Support/Casting.h"
1919
#include "llvm/Support/ErrorHandling.h"
20+
#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
2021

2122
using ABIArgInfo = cir::ABIArgInfo;
2223
using MissingFeature = cir::MissingFeatures;
@@ -61,6 +62,11 @@ class AMDGPUTargetLoweringInfo : public TargetLoweringInfo {
6162
cir_cconv_unreachable("Unknown CIR address space for this target");
6263
}
6364
}
65+
66+
mlir::Type getOpaqueType(cir::OpaqueType type) const override {
67+
assert(!cir::MissingFeatures::addressSpace());
68+
return mlir::LLVM::LLVMPointerType::get(type.getContext());
69+
}
6470
};
6571

6672
} // namespace

clang/lib/CIR/Dialect/Transforms/TargetLowering/Targets/SPIR.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
#include "TargetLoweringInfo.h"
1414
#include "clang/CIR/ABIArgInfo.h"
1515
#include "clang/CIR/Dialect/IR/CIROpsEnums.h"
16+
#include "clang/CIR/Dialect/IR/CIRTypes.h"
1617
#include "clang/CIR/MissingFeatures.h"
1718
#include "llvm/Support/ErrorHandling.h"
19+
#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
1820

1921
using ABIArgInfo = cir::ABIArgInfo;
2022
using MissingFeature = cir::MissingFeatures;
@@ -59,6 +61,16 @@ class SPIRVTargetLoweringInfo : public TargetLoweringInfo {
5961
cir_cconv_unreachable("Unknown CIR address space for this target");
6062
}
6163
}
64+
65+
mlir::Type getOpaqueType(cir::OpaqueType type) const override {
66+
if (type.getTag() != cir::OpaqueType::getEventTag())
67+
llvm_unreachable("NYI");
68+
69+
return mlir::LLVM::LLVMTargetExtType::get(type.getContext(),
70+
/*extTypeName=*/"spirv.Event",
71+
/*typeParams=*/{},
72+
/*intParams=*/{});
73+
}
6274
};
6375

6476
} // namespace

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

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2136,6 +2136,45 @@ mlir::LogicalResult CIRToLLVMConstantOpLowering::matchAndRewrite(
21362136
rewriter.replaceOp(op, lowerCirAttrAsValue(op, op.getValue(), rewriter,
21372137
getTypeConverter(), dataLayout));
21382138
return mlir::success();
2139+
} else if (mlir::isa<cir::OpaqueType>(op.getType())) {
2140+
mlir::Attribute valAttr = op.getValue();
2141+
mlir::Type llvmTy = getTypeConverter()->convertType(op.getType());
2142+
// If the attribute is ZeroAttr or UndefAttr, handle it:
2143+
if (mlir::isa<cir::ZeroAttr, cir::UndefAttr>(valAttr)) {
2144+
// Handle target-ext type
2145+
if (auto tgtExtTy =
2146+
llvm::dyn_cast_or_null<mlir::LLVM::LLVMTargetExtType>(llvmTy)) {
2147+
// Produce a real zero constant if the target-ext type allows it
2148+
if (tgtExtTy.hasProperty(mlir::LLVM::LLVMTargetExtType::HasZeroInit)) {
2149+
if (mlir::isa<cir::ZeroAttr>(valAttr)) {
2150+
auto zero =
2151+
mlir::LLVM::ZeroOp::create(rewriter, op.getLoc(), llvmTy);
2152+
rewriter.replaceOp(op, zero.getResult());
2153+
return mlir::success();
2154+
}
2155+
// Fallback: emit an undef of that exact llvm type so users have
2156+
// matching types.
2157+
auto undef =
2158+
mlir::LLVM::UndefOp::create(rewriter, op.getLoc(), llvmTy);
2159+
rewriter.replaceOp(op, undef.getResult());
2160+
return mlir::success();
2161+
}
2162+
} else {
2163+
// Target ext type does not support zero init — use `ptr null` of
2164+
// the target-ext type (so users still have the expected type).
2165+
auto ptrTy = mlir::LLVM::LLVMPointerType::get(getContext());
2166+
auto nullPtr = mlir::LLVM::ZeroOp::create(rewriter, op.getLoc(), ptrTy);
2167+
2168+
rewriter.replaceOp(op, nullPtr.getResult());
2169+
return mlir::success();
2170+
}
2171+
}
2172+
2173+
// If the attr is a non-zero concrete value, we must decide if the target
2174+
// expects an encoded representation. Most target-ext types for OpenCL
2175+
// do not accept arbitrary non-zero constants; reject them.
2176+
return op.emitError() << "non-zero constant for target extension type "
2177+
<< llvmTy << " is unsupported";
21392178
} else
21402179
return op.emitError() << "unsupported constant type " << op.getType();
21412180

@@ -5190,6 +5229,11 @@ void prepareTypeConverter(mlir::LLVMTypeConverter &converter,
51905229
converter.addConversion([&](cir::VoidType type) -> mlir::Type {
51915230
return mlir::LLVM::LLVMVoidType::get(type.getContext());
51925231
});
5232+
5233+
converter.addConversion([&, lowerModule](cir::OpaqueType type) -> mlir::Type {
5234+
assert(lowerModule && "LowerModule is not available");
5235+
return lowerModule->getTargetLoweringInfo().getOpaqueType(type);
5236+
});
51935237
}
51945238

51955239
void buildCtorDtorList(

clang/lib/CIR/Lowering/ThroughMLIR/LowerCIRToMLIR.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1861,6 +1861,9 @@ static mlir::TypeConverter prepareTypeConverter() {
18611861
return nullptr;
18621862
return mlir::VectorType::get(2, elemTy);
18631863
});
1864+
converter.addConversion([&](cir::OpaqueType type) -> mlir::Type {
1865+
llvm_unreachable("NYI");
1866+
});
18641867
return converter;
18651868
}
18661869

0 commit comments

Comments
 (0)