Skip to content

Commit

Permalink
Fix #1392: "synthesis" of callables
Browse files Browse the repository at this point in the history
Change the catch-all for structs to NOT raise an error for callables and
empty structs (which are more than likely callable classes).
  • Loading branch information
schweitzpgi committed Mar 14, 2024
1 parent 30e1d3b commit 0b92381
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 6 deletions.
2 changes: 2 additions & 0 deletions include/cudaq/Frontend/nvqpp/ASTBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,8 @@ class QuakeBridgeVisitor
bool isItaniumCXXABI();

private:
static bool isSubscriptOperator(clang::OverloadedOperatorKind kind);

/// Map the block arguments to the names of the function parameters.
void addArgumentSymbols(mlir::Block *entryBlock,
mlir::ArrayRef<clang::ParmVarDecl *> parameters);
Expand Down
13 changes: 8 additions & 5 deletions lib/Frontend/nvqpp/ConvertExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,11 +204,6 @@ bool isOperatorKind(T kindValue) {
return kindValue == KindConst;
}

/// Is \p kind the `operator[]` function?
static bool isSubscriptOperator(clang::OverloadedOperatorKind kind) {
return isOperatorKind<clang::OverloadedOperatorKind::OO_Subscript>(kind);
}

/// Is \p kind the `operator==` function?
static bool isCompareEqualOperator(clang::OverloadedOperatorKind kind) {
return isOperatorKind<clang::OverloadedOperatorKind::OO_EqualEqual>(kind);
Expand Down Expand Up @@ -1113,6 +1108,12 @@ bool QuakeBridgeVisitor::VisitMemberExpr(clang::MemberExpr *x) {
return true;
}

/// Is \p kind the `operator[]` function?
bool QuakeBridgeVisitor::isSubscriptOperator(
clang::OverloadedOperatorKind kind) {
return isOperatorKind<clang::OverloadedOperatorKind::OO_Subscript>(kind);
}

bool QuakeBridgeVisitor::VisitCallExpr(clang::CallExpr *x) {
auto loc = toLocation(x->getSourceRange());
// The called function is reified as a Value in the IR.
Expand Down Expand Up @@ -1952,6 +1953,8 @@ bool QuakeBridgeVisitor::WalkUpFromCXXOperatorCallExpr(
bool QuakeBridgeVisitor::VisitCXXOperatorCallExpr(
clang::CXXOperatorCallExpr *x) {
auto loc = toLocation(x->getSourceRange());

// Helper to replace the operator[] function name with the value, v.
auto replaceTOSValue = [&](Value v) {
[[maybe_unused]] auto funcVal = popValue();
assert(funcVal.getDefiningOp<func::ConstantOp>());
Expand Down
13 changes: 13 additions & 0 deletions lib/Frontend/nvqpp/ConvertStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,19 @@ bool QuakeBridgeVisitor::TraverseIfStmt(clang::IfStmt *x,
// If there is no initialization expression, skip creating an `if` scope.
if (!TraverseStmt(cond))
return false;

// For something like an `operator[]` the TOS value (likely) is a
// pointer to the indexed element in a vector. Since there may not be a cast
// node in the AST to make that a RHS value, we must explicitly check here
// and add the required a load and cast.
if (auto ptrTy = dyn_cast<cc::PointerType>(peekValue().getType())) {
Value v = popValue();
pushValue(builder.create<cc::LoadOp>(loc, v));
if (ptrTy != builder.getI1Type()) {
reportClangError(x, mangler,
"expression in condition not yet supported");
}
}
if (x->getElse())
builder.create<cc::IfOp>(loc, TypeRange{}, popValue(),
stmtBuilder(x->getThen()),
Expand Down
11 changes: 10 additions & 1 deletion lib/Optimizer/Transforms/QuakeSynthesizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -448,9 +448,18 @@ class QuakeSynthesizer
continue;
}

if (isa<cudaq::cc::CallableType>(type)) {
// TODO: for now we ignore the passing of callable arguments.
continue;
}

// The struct type ends up as a i64 in the thunk kernel args pointer, so
// just skip ahead. TODO: add support for struct types!
if (isa<cudaq::cc::StructType, cudaq::cc::CallableType>(type)) {
if (auto structTy = dyn_cast<cudaq::cc::StructType>(type)) {
if (structTy.isEmpty()) {
// TODO: for now we can ignore empty struct types.
continue;
}
char *ptrToSizeInBuffer = static_cast<char *>(args) + offset;
auto rawSize = *reinterpret_cast<std::uint64_t *>(ptrToSizeInBuffer);
stdVecInfo.emplace_back(argNum, Type{}, rawSize);
Expand Down

0 comments on commit 0b92381

Please sign in to comment.