Skip to content

Commit aceb0b0

Browse files
committed
Revert "[CIR] Remove the !cir.void return type for functions returning void (llvm#1203)"
This reverts commit 568b515.
1 parent 25b269e commit aceb0b0

File tree

11 files changed

+43
-211
lines changed

11 files changed

+43
-211
lines changed

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

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3474,6 +3474,8 @@ def FuncOp : CIR_Op<"func", [
34743474
/// Returns the results types that the callable region produces when
34753475
/// executed.
34763476
llvm::ArrayRef<mlir::Type> getCallableResults() {
3477+
if (::llvm::isa<cir::VoidType>(getFunctionType().getReturnType()))
3478+
return {};
34773479
return getFunctionType().getReturnTypes();
34783480
}
34793481

@@ -3490,15 +3492,10 @@ def FuncOp : CIR_Op<"func", [
34903492
}
34913493

34923494
/// Returns the argument types of this function.
3493-
llvm::ArrayRef<mlir::Type> getArgumentTypes() {
3494-
return getFunctionType().getInputs();
3495-
}
3495+
llvm::ArrayRef<mlir::Type> getArgumentTypes() { return getFunctionType().getInputs(); }
34963496

3497-
/// Returns 0 or 1 result type of this function (0 in the case of a function
3498-
/// returing void)
3499-
llvm::ArrayRef<mlir::Type> getResultTypes() {
3500-
return getFunctionType().getReturnTypes();
3501-
}
3497+
/// Returns the result types of this function.
3498+
llvm::ArrayRef<mlir::Type> getResultTypes() { return getFunctionType().getReturnTypes(); }
35023499

35033500
/// Hook for OpTrait::FunctionOpInterfaceTrait, called after verifying that
35043501
/// the 'type' attribute is present and checks if it holds a function type.

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

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -379,27 +379,22 @@ def CIR_FuncType : CIR_Type<"Func", "func"> {
379379

380380
```mlir
381381
!cir.func<!bool ()>
382-
!cir.func<!cir.void ()>
383382
!cir.func<!s32i (!s8i, !s8i)>
384383
!cir.func<!s32i (!s32i, ...)>
385384
```
386385
}];
387386

388-
let parameters = (ins ArrayRefParameter<"mlir::Type">:$inputs, ArrayRefParameter<"mlir::Type">:$returnTypes,
387+
let parameters = (ins ArrayRefParameter<"mlir::Type">:$inputs, "mlir::Type":$returnType,
389388
"bool":$varArg);
390389
let assemblyFormat = [{
391-
`<` custom<FuncType>($returnTypes, $inputs, $varArg) `>`
390+
`<` $returnType ` ` `(` custom<FuncTypeArgs>($inputs, $varArg) `>`
392391
}];
393392

394393
let builders = [
395-
// Construct with an actual return type or explicit !cir.void
396394
TypeBuilderWithInferredContext<(ins
397395
"llvm::ArrayRef<mlir::Type>":$inputs, "mlir::Type":$returnType,
398396
CArg<"bool", "false">:$isVarArg), [{
399-
return $_get(returnType.getContext(), inputs,
400-
::mlir::isa<::cir::VoidType>(returnType) ? llvm::ArrayRef<mlir::Type>{}
401-
: llvm::ArrayRef{returnType},
402-
isVarArg);
397+
return $_get(returnType.getContext(), inputs, returnType, isVarArg);
403398
}]>
404399
];
405400

@@ -413,11 +408,11 @@ def CIR_FuncType : CIR_Type<"Func", "func"> {
413408
/// Returns the number of arguments to the function.
414409
unsigned getNumInputs() const { return getInputs().size(); }
415410

416-
/// Returns the result type of the function as an actual return type or
417-
/// explicit !cir.void
418-
mlir::Type getReturnType() const;
411+
/// Returns the result type of the function as an ArrayRef, enabling better
412+
/// integration with generic MLIR utilities.
413+
llvm::ArrayRef<mlir::Type> getReturnTypes() const;
419414

420-
/// Returns whether the function returns void.
415+
/// Returns whether the function is returns void.
421416
bool isVoid() const;
422417

423418
/// Returns a clone of this function type with the given argument

clang/lib/CIR/CodeGen/CIRGenTypes.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ mlir::Type CIRGenTypes::ConvertFunctionTypeInternal(QualType QFT) {
271271
assert(QFT.isCanonical());
272272
const Type *Ty = QFT.getTypePtr();
273273
const FunctionType *FT = cast<FunctionType>(QFT.getTypePtr());
274-
// First, check whether we can build the full function type. If the function
274+
// First, check whether we can build the full fucntion type. If the function
275275
// type depends on an incomplete type (e.g. a struct or enum), we cannot lower
276276
// the function type.
277277
assert(isFuncTypeConvertible(FT) && "NYI");

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

Lines changed: 10 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2224,26 +2224,6 @@ void cir::FuncOp::build(OpBuilder &builder, OperationState &result,
22242224
getResAttrsAttrName(result.name));
22252225
}
22262226

2227-
// A specific version of function_interface_impl::parseFunctionSignature able to
2228-
// handle the "-> !void" special fake return type.
2229-
static ParseResult
2230-
parseFunctionSignature(OpAsmParser &parser, bool allowVariadic,
2231-
SmallVectorImpl<OpAsmParser::Argument> &arguments,
2232-
bool &isVariadic, SmallVectorImpl<Type> &resultTypes,
2233-
SmallVectorImpl<DictionaryAttr> &resultAttrs) {
2234-
if (function_interface_impl::parseFunctionArgumentList(parser, allowVariadic,
2235-
arguments, isVariadic))
2236-
return failure();
2237-
if (succeeded(parser.parseOptionalArrow())) {
2238-
if (parser.parseOptionalExclamationKeyword("!void").succeeded())
2239-
// This is just an empty return type and attribute.
2240-
return success();
2241-
return function_interface_impl::parseFunctionResultList(parser, resultTypes,
2242-
resultAttrs);
2243-
}
2244-
return success();
2245-
}
2246-
22472227
ParseResult cir::FuncOp::parse(OpAsmParser &parser, OperationState &state) {
22482228
llvm::SMLoc loc = parser.getCurrentLocation();
22492229

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

23052285
// Parse the function signature.
23062286
bool isVariadic = false;
2307-
if (parseFunctionSignature(parser, /*allowVariadic=*/true, arguments,
2308-
isVariadic, resultTypes, resultAttrs))
2287+
if (function_interface_impl::parseFunctionSignature(
2288+
parser, /*allowVariadic=*/true, arguments, isVariadic, resultTypes,
2289+
resultAttrs))
23092290
return failure();
23102291

23112292
for (auto &arg : arguments)
@@ -2508,8 +2489,13 @@ void cir::FuncOp::print(OpAsmPrinter &p) {
25082489
p.printSymbolName(getSymName());
25092490
auto fnType = getFunctionType();
25102491
llvm::SmallVector<Type, 1> resultTypes;
2511-
function_interface_impl::printFunctionSignature(
2512-
p, *this, fnType.getInputs(), fnType.isVarArg(), fnType.getReturnTypes());
2492+
if (!fnType.isVoid())
2493+
function_interface_impl::printFunctionSignature(
2494+
p, *this, fnType.getInputs(), fnType.isVarArg(),
2495+
fnType.getReturnTypes());
2496+
else
2497+
function_interface_impl::printFunctionSignature(
2498+
p, *this, fnType.getInputs(), fnType.isVarArg(), {});
25132499

25142500
if (mlir::ArrayAttr annotations = getAnnotationsAttr()) {
25152501
p << ' ';
@@ -2578,11 +2564,6 @@ LogicalResult cir::FuncOp::verifyType() {
25782564
if (!getNoProto() && type.isVarArg() && type.getNumInputs() == 0)
25792565
return emitError()
25802566
<< "prototyped function must have at least one non-variadic input";
2581-
if (auto rt = type.getReturnTypes();
2582-
!rt.empty() && mlir::isa<cir::VoidType>(rt.front()))
2583-
return emitOpError("The return type for a function returning void should "
2584-
"be empty instead of an explicit !cir.void");
2585-
25862567
return success();
25872568
}
25882569

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

Lines changed: 12 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
#include "llvm/ADT/TypeSwitch.h"
3434
#include "llvm/Support/ErrorHandling.h"
3535
#include "llvm/Support/MathExtras.h"
36-
#include <cassert>
3736
#include <optional>
3837

3938
using cir::MissingFeatures;
@@ -43,16 +42,13 @@ using cir::MissingFeatures;
4342
//===----------------------------------------------------------------------===//
4443

4544
static mlir::ParseResult
46-
parseFuncType(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> &returnTypes,
47-
llvm::SmallVector<mlir::Type> &params, bool &isVarArg);
48-
49-
static void printFuncType(mlir::AsmPrinter &p,
50-
mlir::ArrayRef<mlir::Type> returnTypes,
51-
mlir::ArrayRef<mlir::Type> params, bool isVarArg);
45+
parseFuncTypeArgs(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> &params,
46+
bool &isVarArg);
47+
static void printFuncTypeArgs(mlir::AsmPrinter &p,
48+
mlir::ArrayRef<mlir::Type> params, bool isVarArg);
5249

5350
static mlir::ParseResult parsePointerAddrSpace(mlir::AsmParser &p,
5451
mlir::Attribute &addrSpaceAttr);
55-
5652
static void printPointerAddrSpace(mlir::AsmPrinter &p,
5753
mlir::Attribute addrSpaceAttr);
5854

@@ -917,46 +913,9 @@ FuncType FuncType::clone(TypeRange inputs, TypeRange results) const {
917913
return get(llvm::to_vector(inputs), results[0], isVarArg());
918914
}
919915

920-
// A special parser is needed for function returning void to consume the "!void"
921-
// returned type in the case there is no alias defined.
922-
static mlir::ParseResult
923-
parseFuncTypeReturn(mlir::AsmParser &p,
924-
llvm::SmallVector<mlir::Type> &returnTypes) {
925-
if (p.parseOptionalExclamationKeyword("!void").succeeded())
926-
// !void means no return type.
927-
return p.parseLParen();
928-
if (succeeded(p.parseOptionalLParen()))
929-
// If we have already a '(', the function has no return type
930-
return mlir::success();
931-
932-
mlir::Type type;
933-
auto result = p.parseOptionalType(type);
934-
if (!result.has_value())
935-
return mlir::failure();
936-
if (failed(*result) || isa<cir::VoidType>(type))
937-
// No return type specified.
938-
return p.parseLParen();
939-
// Otherwise use the actual type.
940-
returnTypes.push_back(type);
941-
return p.parseLParen();
942-
}
943-
944-
// A special pretty-printer for function returning void to emit a "!void"
945-
// returned type. Note that there is no real type used here since it does not
946-
// appear in the IR and thus the alias might not be defined and cannot be
947-
// referred to. This is why this is a pure syntactic-sugar string which is used.
948-
static void printFuncTypeReturn(mlir::AsmPrinter &p,
949-
mlir::ArrayRef<mlir::Type> returnTypes) {
950-
if (returnTypes.empty())
951-
// Pretty-print no return type as "!void"
952-
p << "!void ";
953-
else
954-
p << returnTypes << ' ';
955-
}
956-
957-
static mlir::ParseResult
958-
parseFuncTypeArgs(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> &params,
959-
bool &isVarArg) {
916+
mlir::ParseResult parseFuncTypeArgs(mlir::AsmParser &p,
917+
llvm::SmallVector<mlir::Type> &params,
918+
bool &isVarArg) {
960919
isVarArg = false;
961920
// `(` `)`
962921
if (succeeded(p.parseOptionalRParen()))
@@ -986,10 +945,8 @@ parseFuncTypeArgs(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> &params,
986945
return p.parseRParen();
987946
}
988947

989-
static void printFuncTypeArgs(mlir::AsmPrinter &p,
990-
mlir::ArrayRef<mlir::Type> params,
991-
bool isVarArg) {
992-
p << '(';
948+
void printFuncTypeArgs(mlir::AsmPrinter &p, mlir::ArrayRef<mlir::Type> params,
949+
bool isVarArg) {
993950
llvm::interleaveComma(params, p,
994951
[&p](mlir::Type type) { p.printType(type); });
995952
if (isVarArg) {
@@ -1000,37 +957,11 @@ static void printFuncTypeArgs(mlir::AsmPrinter &p,
1000957
p << ')';
1001958
}
1002959

1003-
static mlir::ParseResult
1004-
parseFuncType(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> &returnTypes,
1005-
llvm::SmallVector<mlir::Type> &params, bool &isVarArg) {
1006-
if (failed(parseFuncTypeReturn(p, returnTypes)))
1007-
return failure();
1008-
return parseFuncTypeArgs(p, params, isVarArg);
1009-
}
1010-
1011-
static void printFuncType(mlir::AsmPrinter &p,
1012-
mlir::ArrayRef<mlir::Type> returnTypes,
1013-
mlir::ArrayRef<mlir::Type> params, bool isVarArg) {
1014-
printFuncTypeReturn(p, returnTypes);
1015-
printFuncTypeArgs(p, params, isVarArg);
960+
llvm::ArrayRef<mlir::Type> FuncType::getReturnTypes() const {
961+
return static_cast<detail::FuncTypeStorage *>(getImpl())->returnType;
1016962
}
1017963

1018-
// Return the actual return type or an explicit !cir.void if the function does
1019-
// not return anything
1020-
mlir::Type FuncType::getReturnType() const {
1021-
if (isVoid())
1022-
return cir::VoidType::get(getContext());
1023-
return static_cast<detail::FuncTypeStorage *>(getImpl())->returnTypes.front();
1024-
}
1025-
1026-
bool FuncType::isVoid() const {
1027-
auto rt = static_cast<detail::FuncTypeStorage *>(getImpl())->returnTypes;
1028-
assert(rt.empty() ||
1029-
!mlir::isa<cir::VoidType>(rt.front()) &&
1030-
"The return type for a function returning void should be empty "
1031-
"instead of a real !cir.void");
1032-
return rt.empty();
1033-
}
964+
bool FuncType::isVoid() const { return mlir::isa<VoidType>(getReturnType()); }
1034965

1035966
//===----------------------------------------------------------------------===//
1036967
// MethodType Definitions

clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerTypes.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ FuncType LowerTypes::getFunctionType(const LowerFunctionInfo &FI) {
109109
}
110110
}
111111

112-
return FuncType::get(ArgTypes, resultType, FI.isVariadic());
112+
return FuncType::get(getMLIRContext(), ArgTypes, resultType, FI.isVariadic());
113113
}
114114

115115
/// Convert a CIR type to its ABI-specific default form.

clang/test/CIR/IR/being_and_nothingness.cir

Lines changed: 0 additions & 35 deletions
This file was deleted.

mlir/include/mlir/IR/OpImplementation.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -922,9 +922,6 @@ class AsmParser {
922922
/// Parse an optional keyword or string.
923923
virtual ParseResult parseOptionalKeywordOrString(std::string *result) = 0;
924924

925-
/// Parse the given exclamation-prefixed keyword if present.
926-
virtual ParseResult parseOptionalExclamationKeyword(StringRef keyword) = 0;
927-
928925
//===--------------------------------------------------------------------===//
929926
// Attribute/Type Parsing
930927
//===--------------------------------------------------------------------===//

mlir/include/mlir/Interfaces/FunctionImplementation.h

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -64,28 +64,6 @@ parseFunctionSignature(OpAsmParser &parser, bool allowVariadic,
6464
bool &isVariadic, SmallVectorImpl<Type> &resultTypes,
6565
SmallVectorImpl<DictionaryAttr> &resultAttrs);
6666

67-
/// Parse a function argument list using `parser`. The `allowVariadic` argument
68-
/// indicates whether functions with variadic arguments are supported. The
69-
/// trailing arguments are populated by this function with names, types,
70-
/// attributes and locations of the arguments.
71-
ParseResult
72-
parseFunctionArgumentList(OpAsmParser &parser, bool allowVariadic,
73-
SmallVectorImpl<OpAsmParser::Argument> &arguments,
74-
bool &isVariadic);
75-
76-
/// Parse a function result list using `parser`.
77-
///
78-
/// function-result-list ::= function-result-list-parens
79-
/// | non-function-type
80-
/// function-result-list-parens ::= `(` `)`
81-
/// | `(` function-result-list-no-parens `)`
82-
/// function-result-list-no-parens ::= function-result (`,` function-result)*
83-
/// function-result ::= type attribute-dict?
84-
///
85-
ParseResult
86-
parseFunctionResultList(OpAsmParser &parser, SmallVectorImpl<Type> &resultTypes,
87-
SmallVectorImpl<DictionaryAttr> &resultAttrs);
88-
8967
/// Parser implementation for function-like operations. Uses
9068
/// `funcTypeBuilder` to construct the custom function type given lists of
9169
/// input and output types. The parser sets the `typeAttrName` attribute to the

mlir/lib/AsmParser/AsmParserImpl.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -396,19 +396,6 @@ class AsmParserImpl : public BaseT {
396396
return parseOptionalString(result);
397397
}
398398

399-
/// Parse the given exclamation-prefixed keyword if present.
400-
ParseResult parseOptionalExclamationKeyword(StringRef keyword) override {
401-
if (parser.getToken().isCodeCompletion())
402-
return parser.codeCompleteOptionalTokens(keyword);
403-
404-
// Check that the current token has the same spelling.
405-
if (!parser.getToken().is(Token::Kind::exclamation_identifier) ||
406-
parser.getTokenSpelling() != keyword)
407-
return failure();
408-
parser.consumeToken();
409-
return success();
410-
}
411-
412399
//===--------------------------------------------------------------------===//
413400
// Attribute Parsing
414401
//===--------------------------------------------------------------------===//

0 commit comments

Comments
 (0)