Skip to content

Commit 9f18821

Browse files
author
Mahmood Yassin
committed
Support general and minimal ocl opaque type
1 parent 0eb9550 commit 9f18821

File tree

11 files changed

+140
-22
lines changed

11 files changed

+140
-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
@@ -155,9 +155,10 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
155155
return cir::ZeroAttr::get(RecordTy);
156156
if (auto methodTy = mlir::dyn_cast<cir::MethodType>(ty))
157157
return getNullMethodAttr(methodTy);
158-
if (mlir::isa<cir::BoolType>(ty)) {
158+
if (mlir::isa<cir::BoolType>(ty))
159159
return getFalseAttr();
160-
}
160+
if (mlir::isa<cir::OpaqueType>(ty))
161+
return cir::ZeroAttr::get(ty);
161162
llvm_unreachable("Zero initializer for given type is NYI");
162163
}
163164

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

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

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

765807
#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
@@ -1945,18 +1945,11 @@ mlir::Value ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
19451945
return emitComplexToScalarConversion(CGF.getLoc(CE->getExprLoc()), V, Kind,
19461946
DestTy);
19471947
}
1948-
case CK_ZeroToOCLOpaqueType: {
1948+
case CK_ZeroToOCLOpaqueType:
19491949
// OpenCL: event_t e = async_work_group_copy(..., 0);
19501950
// The source is an integer constant zero; the destination is an OpenCL
19511951
// opaque type
1952-
mlir::Type destTy = CGF.convertType(DestTy);
1953-
auto PtrTy =
1954-
cir::PointerType::get(destTy, cir::AddressSpace::OffloadPrivate);
1955-
auto constNullPtrAttr = Builder.getConstNullPtrAttr(PtrTy);
1956-
auto nullVal =
1957-
Builder.getConstant(CGF.getLoc(E->getExprLoc()), constNullPtrAttr);
1958-
return nullVal;
1959-
}
1952+
return emitNullValue(DestTy, CGF.getLoc(E->getExprLoc()));
19601953
case CK_IntToOCLSampler:
19611954
llvm_unreachable("NYI");
19621955

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
@@ -392,7 +392,7 @@ static LogicalResult checkConstantTypes(mlir::Operation *op, mlir::Type opType,
392392

393393
if (isa<cir::ZeroAttr>(attrType)) {
394394
if (::mlir::isa<cir::RecordType, cir::ArrayType, cir::ComplexType,
395-
cir::VectorType>(opType))
395+
cir::VectorType, cir::OpaqueType>(opType))
396396
return success();
397397
return op->emitOpError("zero expects record or array type");
398398
}

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

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

3535
virtual unsigned
3636
getTargetAddrSpaceFromCIRAddrSpace(cir::AddressSpace addrSpace) const = 0;
37+
38+
virtual mlir::Type getOpaqueType(cir::OpaqueType type) const {
39+
llvm_unreachable("NYI");
40+
}
3741
};
3842

3943
} // 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
@@ -16,6 +16,7 @@
1616
#include "clang/CIR/MissingFeatures.h"
1717
#include "llvm/Support/Casting.h"
1818
#include "llvm/Support/ErrorHandling.h"
19+
#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
1920

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

6571
} // namespace

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
#include "TargetInfo.h"
1313
#include "TargetLoweringInfo.h"
1414
#include "clang/CIR/ABIArgInfo.h"
15+
#include "clang/CIR/Dialect/IR/CIRTypes.h"
1516
#include "clang/CIR/MissingFeatures.h"
1617
#include "llvm/Support/ErrorHandling.h"
18+
#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
1719

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

6375
} // namespace

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

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

@@ -5138,6 +5177,10 @@ void prepareTypeConverter(mlir::LLVMTypeConverter &converter,
51385177
converter.addConversion([&](cir::VoidType type) -> mlir::Type {
51395178
return mlir::LLVM::LLVMVoidType::get(type.getContext());
51405179
});
5180+
5181+
converter.addConversion([&](cir::OpaqueType type) -> mlir::Type {
5182+
return lowerModule->getTargetLoweringInfo().getOpaqueType(type);
5183+
});
51415184
}
51425185

51435186
void buildCtorDtorList(

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1767,6 +1767,9 @@ static mlir::TypeConverter prepareTypeConverter() {
17671767
return nullptr;
17681768
return mlir::VectorType::get(2, elemTy);
17691769
});
1770+
converter.addConversion([&](cir::OpaqueType type) -> mlir::Type {
1771+
llvm_unreachable("NYI");
1772+
});
17701773
return converter;
17711774
}
17721775

0 commit comments

Comments
 (0)