Skip to content
8 changes: 7 additions & 1 deletion include/cudaq/Optimizer/Dialect/CC/CCTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,16 @@ inline bool SpanLikeType::classof(mlir::Type type) {
return mlir::isa<StdvecType, CharspanType>(type);
}

/// Return true if and only if \p ty has dynamic extent. This is a recursive
/// Returns true if and only if \p ty has dynamic extent. This is a recursive
/// test on composable types.
bool isDynamicType(mlir::Type ty);

/// Returns true if and only if the memory needed to store a value of type
/// \p ty is not known at compile time. This is a recursive test on composable
/// types. In contrast to `isDynamicType`, the size of the type is statically
/// known even if it contains pointers that may point to memory of dynamic size.
bool isDynamicallySizedType(mlir::Type ty);

/// Determine the number of hidden arguments, which is 0, 1, or 2.
inline unsigned numberOfHiddenArgs(bool thisPtr, bool sret) {
return (thisPtr ? 1 : 0) + (sret ? 1 : 0);
Expand Down
3 changes: 3 additions & 0 deletions lib/Frontend/nvqpp/ConvertStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,9 @@ bool QuakeBridgeVisitor::VisitReturnStmt(clang::ReturnStmt *x) {
if (!cudaq::cc::isDynamicType(eleTy))
tySize = irb.getByteSizeOfType(loc, eleTy);
if (!tySize) {
// TODO: we need to recursively create copies of all
// dynamic memory used within the type. See the
// implementation of `visit_Return` in the Python bridge.
TODO_x(toLocation(x), x, mangler, "unhandled vector element type");
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions lib/Optimizer/CodeGen/CCToLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -531,8 +531,8 @@ class SizeOfOpPattern : public ConvertOpToLLVMPattern<cudaq::cc::SizeOfOp> {
ConversionPatternRewriter &rewriter) const override {
auto inputTy = sizeOfOp.getInputType();
auto resultTy = sizeOfOp.getType();
if (quake::isQuakeType(inputTy) || cudaq::cc::isDynamicType(inputTy)) {
// Types that cannot be reified produce the poison op.
if (quake::isQuakeType(inputTy) ||
cudaq::cc::isDynamicallySizedType(inputTy)) {
rewriter.replaceOpWithNewOp<cudaq::cc::PoisonOp>(sizeOfOp, resultTy);
return success();
}
Expand Down
16 changes: 16 additions & 0 deletions lib/Optimizer/Dialect/CC/CCTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,22 @@ bool isDynamicType(Type ty) {
return false;
}

bool isDynamicallySizedType(Type ty) {
if (isa<SpanLikeType>(ty))
return false;
if (auto strTy = dyn_cast<StructType>(ty)) {
for (auto memTy : strTy.getMembers())
if (isDynamicallySizedType(memTy))
return true;
return false;
}
if (auto arrTy = dyn_cast<ArrayType>(ty))
return arrTy.isUnknownSize() ||
isDynamicallySizedType(arrTy.getElementType());
// Note: this isn't considering quake, builtin, etc. types.
return false;
}

void CCDialect::registerTypes() {
addTypes<ArrayType, CallableType, CharspanType, IndirectCallableType,
PointerType, StdvecType, StructType>();
Expand Down
Loading
Loading