Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CIR] Remove also the !cir.void return type from the textual IR #1249

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions clang/include/clang/CIR/Dialect/IR/CIRTypes.td
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ def CIR_FuncType : CIR_Type<"Func", "func"> {

```mlir
!cir.func<!bool ()>
!cir.func<!cir.void ()>
!cir.func<(!s8i, !s8i)>
!cir.func<!s32i (!s8i, !s8i)>
!cir.func<!s32i (!s32i, ...)>
```
Expand All @@ -388,7 +388,7 @@ def CIR_FuncType : CIR_Type<"Func", "func"> {
let parameters = (ins ArrayRefParameter<"mlir::Type">:$inputs, ArrayRefParameter<"mlir::Type">:$returnTypes,
"bool":$varArg);
let assemblyFormat = [{
`<` custom<FuncType>($returnTypes, $inputs, $varArg) `>`
`<` $returnTypes ` ` `(` custom<FuncTypeArgs>($inputs, $varArg) `>`
}];

let builders = [
Expand Down
25 changes: 3 additions & 22 deletions clang/lib/CIR/Dialect/IR/CIRDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2224,26 +2224,6 @@ void cir::FuncOp::build(OpBuilder &builder, OperationState &result,
getResAttrsAttrName(result.name));
}

// A specific version of function_interface_impl::parseFunctionSignature able to
// handle the "-> !void" special fake return type.
static ParseResult
parseFunctionSignature(OpAsmParser &parser, bool allowVariadic,
SmallVectorImpl<OpAsmParser::Argument> &arguments,
bool &isVariadic, SmallVectorImpl<Type> &resultTypes,
SmallVectorImpl<DictionaryAttr> &resultAttrs) {
if (function_interface_impl::parseFunctionArgumentList(parser, allowVariadic,
arguments, isVariadic))
return failure();
if (succeeded(parser.parseOptionalArrow())) {
if (parser.parseOptionalExclamationKeyword("!void").succeeded())
// This is just an empty return type and attribute.
return success();
return function_interface_impl::parseFunctionResultList(parser, resultTypes,
resultAttrs);
}
return success();
}

ParseResult cir::FuncOp::parse(OpAsmParser &parser, OperationState &state) {
llvm::SMLoc loc = parser.getCurrentLocation();

Expand Down Expand Up @@ -2304,8 +2284,9 @@ ParseResult cir::FuncOp::parse(OpAsmParser &parser, OperationState &state) {

// Parse the function signature.
bool isVariadic = false;
if (parseFunctionSignature(parser, /*allowVariadic=*/true, arguments,
isVariadic, resultTypes, resultAttrs))
if (function_interface_impl::parseFunctionSignature(
parser, /*allowVariadic=*/true, arguments, isVariadic, resultTypes,
resultAttrs))
return failure();

for (auto &arg : arguments)
Expand Down
75 changes: 9 additions & 66 deletions clang/lib/CIR/Dialect/IR/CIRTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,13 @@ using cir::MissingFeatures;
//===----------------------------------------------------------------------===//

static mlir::ParseResult
parseFuncType(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> &returnTypes,
llvm::SmallVector<mlir::Type> &params, bool &isVarArg);

static void printFuncType(mlir::AsmPrinter &p,
mlir::ArrayRef<mlir::Type> returnTypes,
mlir::ArrayRef<mlir::Type> params, bool isVarArg);
parseFuncTypeArgs(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> &params,
bool &isVarArg);
static void printFuncTypeArgs(mlir::AsmPrinter &p,
mlir::ArrayRef<mlir::Type> params, bool isVarArg);

static mlir::ParseResult parsePointerAddrSpace(mlir::AsmParser &p,
mlir::Attribute &addrSpaceAttr);

static void printPointerAddrSpace(mlir::AsmPrinter &p,
mlir::Attribute addrSpaceAttr);

Expand Down Expand Up @@ -917,46 +914,9 @@ FuncType FuncType::clone(TypeRange inputs, TypeRange results) const {
return get(llvm::to_vector(inputs), results[0], isVarArg());
}

// A special parser is needed for function returning void to consume the "!void"
// returned type in the case there is no alias defined.
static mlir::ParseResult
parseFuncTypeReturn(mlir::AsmParser &p,
llvm::SmallVector<mlir::Type> &returnTypes) {
if (p.parseOptionalExclamationKeyword("!void").succeeded())
// !void means no return type.
return p.parseLParen();
if (succeeded(p.parseOptionalLParen()))
// If we have already a '(', the function has no return type
return mlir::success();

mlir::Type type;
auto result = p.parseOptionalType(type);
if (!result.has_value())
return mlir::failure();
if (failed(*result) || isa<cir::VoidType>(type))
// No return type specified.
return p.parseLParen();
// Otherwise use the actual type.
returnTypes.push_back(type);
return p.parseLParen();
}

// A special pretty-printer for function returning void to emit a "!void"
// returned type. Note that there is no real type used here since it does not
// appear in the IR and thus the alias might not be defined and cannot be
// referred to. This is why this is a pure syntactic-sugar string which is used.
static void printFuncTypeReturn(mlir::AsmPrinter &p,
mlir::ArrayRef<mlir::Type> returnTypes) {
if (returnTypes.empty())
// Pretty-print no return type as "!void"
p << "!void ";
else
p << returnTypes << ' ';
}

static mlir::ParseResult
parseFuncTypeArgs(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> &params,
bool &isVarArg) {
mlir::ParseResult parseFuncTypeArgs(mlir::AsmParser &p,
llvm::SmallVector<mlir::Type> &params,
bool &isVarArg) {
isVarArg = false;
// `(` `)`
if (succeeded(p.parseOptionalRParen()))
Expand Down Expand Up @@ -986,10 +946,8 @@ parseFuncTypeArgs(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> &params,
return p.parseRParen();
}

static void printFuncTypeArgs(mlir::AsmPrinter &p,
mlir::ArrayRef<mlir::Type> params,
bool isVarArg) {
p << '(';
void printFuncTypeArgs(mlir::AsmPrinter &p, mlir::ArrayRef<mlir::Type> params,
bool isVarArg) {
llvm::interleaveComma(params, p,
[&p](mlir::Type type) { p.printType(type); });
if (isVarArg) {
Expand All @@ -1000,21 +958,6 @@ static void printFuncTypeArgs(mlir::AsmPrinter &p,
p << ')';
}

static mlir::ParseResult
parseFuncType(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> &returnTypes,
llvm::SmallVector<mlir::Type> &params, bool &isVarArg) {
if (failed(parseFuncTypeReturn(p, returnTypes)))
return failure();
return parseFuncTypeArgs(p, params, isVarArg);
}

static void printFuncType(mlir::AsmPrinter &p,
mlir::ArrayRef<mlir::Type> returnTypes,
mlir::ArrayRef<mlir::Type> params, bool isVarArg) {
printFuncTypeReturn(p, returnTypes);
printFuncTypeArgs(p, params, isVarArg);
}

// Return the actual return type or an explicit !cir.void if the function does
// not return anything
mlir::Type FuncType::getReturnType() const {
Expand Down
23 changes: 1 addition & 22 deletions clang/test/CIR/IR/being_and_nothingness.cir
Original file line number Diff line number Diff line change
@@ -1,31 +1,10 @@
// RUN: cir-opt %s | FileCheck %s
// Exercise different ways to encode a function returning void
!s32i = !cir.int<s, 32>
!fnptr1 = !cir.ptr<!cir.func<!cir.void(!s32i)>>
// Note there is no !void alias defined
!fnptr2 = !cir.ptr<!cir.func<!void(!s32i)>>
!fnptr3 = !cir.ptr<!cir.func<(!s32i)>>
module {
cir.func @ind1(%fnptr: !fnptr1, %a : !s32i) {
// CHECK: cir.func @ind1(%arg0: !cir.ptr<!cir.func<!void (!s32i)>>, %arg1: !s32i) {
cir.return
}

cir.func @ind2(%fnptr: !fnptr2, %a : !s32i) {
// CHECK: cir.func @ind2(%arg0: !cir.ptr<!cir.func<!void (!s32i)>>, %arg1: !s32i) {
cir.return
}
cir.func @ind3(%fnptr: !fnptr3, %a : !s32i) {
// CHECK: cir.func @ind3(%arg0: !cir.ptr<!cir.func<!void (!s32i)>>, %arg1: !s32i) {
cir.return
}
cir.func @f1() -> !cir.void {
// CHECK: cir.func @f1() {
cir.return
}
// Note there is no !void alias defined
cir.func @f2() -> !void {
// CHECK: cir.func @f2() {
// CHECK: cir.func @ind3(%arg0: !cir.ptr<!cir.func<(!s32i)>>, %arg1: !s32i) {
cir.return
}
cir.func @f3() {
Expand Down
3 changes: 0 additions & 3 deletions mlir/include/mlir/IR/OpImplementation.h
Original file line number Diff line number Diff line change
Expand Up @@ -922,9 +922,6 @@ class AsmParser {
/// Parse an optional keyword or string.
virtual ParseResult parseOptionalKeywordOrString(std::string *result) = 0;

/// Parse the given exclamation-prefixed keyword if present.
virtual ParseResult parseOptionalExclamationKeyword(StringRef keyword) = 0;

//===--------------------------------------------------------------------===//
// Attribute/Type Parsing
//===--------------------------------------------------------------------===//
Expand Down
22 changes: 0 additions & 22 deletions mlir/include/mlir/Interfaces/FunctionImplementation.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,28 +64,6 @@ parseFunctionSignature(OpAsmParser &parser, bool allowVariadic,
bool &isVariadic, SmallVectorImpl<Type> &resultTypes,
SmallVectorImpl<DictionaryAttr> &resultAttrs);

/// Parse a function argument list using `parser`. The `allowVariadic` argument
/// indicates whether functions with variadic arguments are supported. The
/// trailing arguments are populated by this function with names, types,
/// attributes and locations of the arguments.
ParseResult
parseFunctionArgumentList(OpAsmParser &parser, bool allowVariadic,
SmallVectorImpl<OpAsmParser::Argument> &arguments,
bool &isVariadic);

/// Parse a function result list using `parser`.
///
/// function-result-list ::= function-result-list-parens
/// | non-function-type
/// function-result-list-parens ::= `(` `)`
/// | `(` function-result-list-no-parens `)`
/// function-result-list-no-parens ::= function-result (`,` function-result)*
/// function-result ::= type attribute-dict?
///
ParseResult
parseFunctionResultList(OpAsmParser &parser, SmallVectorImpl<Type> &resultTypes,
SmallVectorImpl<DictionaryAttr> &resultAttrs);

/// Parser implementation for function-like operations. Uses
/// `funcTypeBuilder` to construct the custom function type given lists of
/// input and output types. The parser sets the `typeAttrName` attribute to the
Expand Down
13 changes: 0 additions & 13 deletions mlir/lib/AsmParser/AsmParserImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -396,19 +396,6 @@ class AsmParserImpl : public BaseT {
return parseOptionalString(result);
}

/// Parse the given exclamation-prefixed keyword if present.
ParseResult parseOptionalExclamationKeyword(StringRef keyword) override {
if (parser.getToken().isCodeCompletion())
return parser.codeCompleteOptionalTokens(keyword);

// Check that the current token has the same spelling.
if (!parser.getToken().is(Token::Kind::exclamation_identifier) ||
parser.getTokenSpelling() != keyword)
return failure();
parser.consumeToken();
return success();
}

//===--------------------------------------------------------------------===//
// Attribute Parsing
//===--------------------------------------------------------------------===//
Expand Down
13 changes: 7 additions & 6 deletions mlir/lib/Interfaces/FunctionImplementation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@

using namespace mlir;

ParseResult function_interface_impl::parseFunctionArgumentList(
OpAsmParser &parser, bool allowVariadic,
SmallVectorImpl<OpAsmParser::Argument> &arguments, bool &isVariadic) {
static ParseResult
parseFunctionArgumentList(OpAsmParser &parser, bool allowVariadic,
SmallVectorImpl<OpAsmParser::Argument> &arguments,
bool &isVariadic) {

// Parse the function arguments. The argument list either has to consistently
// have ssa-id's followed by types, or just be a type list. It isn't ok to
Expand Down Expand Up @@ -78,9 +79,9 @@ ParseResult function_interface_impl::parseFunctionArgumentList(
/// function-result-list-no-parens ::= function-result (`,` function-result)*
/// function-result ::= type attribute-dict?
///
ParseResult function_interface_impl::parseFunctionResultList(
OpAsmParser &parser, SmallVectorImpl<Type> &resultTypes,
SmallVectorImpl<DictionaryAttr> &resultAttrs) {
static ParseResult
parseFunctionResultList(OpAsmParser &parser, SmallVectorImpl<Type> &resultTypes,
SmallVectorImpl<DictionaryAttr> &resultAttrs) {
if (failed(parser.parseOptionalLParen())) {
// We already know that there is no `(`, so parse a type.
// Because there is no `(`, it cannot be a function type.
Expand Down
Loading