@@ -715,13 +715,78 @@ unsigned cir::CallOp::getNumArgOperands() {
715715 return this ->getOperation ()->getNumOperands ();
716716}
717717
718+ static mlir::ParseResult
719+ parseTryCallBranches (mlir::OpAsmParser &parser, mlir::OperationState &result,
720+ llvm::SmallVectorImpl<mlir::OpAsmParser::UnresolvedOperand>
721+ &continueOperands,
722+ llvm::SmallVectorImpl<mlir::OpAsmParser::UnresolvedOperand>
723+ &landingPadOperands,
724+ llvm::SmallVectorImpl<mlir::Type> &continueTypes,
725+ llvm::SmallVectorImpl<mlir::Type> &landingPadTypes,
726+ llvm::SMLoc &continueOperandsLoc,
727+ llvm::SMLoc &landingPadOperandsLoc) {
728+ mlir::Block *continueSuccessor = nullptr ;
729+ mlir::Block *landingPadSuccessor = nullptr ;
730+
731+ if (parser.parseSuccessor (continueSuccessor))
732+ return mlir::failure ();
733+
734+ if (mlir::succeeded (parser.parseOptionalLParen ())) {
735+ continueOperandsLoc = parser.getCurrentLocation ();
736+ if (parser.parseOperandList (continueOperands))
737+ return mlir::failure ();
738+ if (parser.parseColon ())
739+ return mlir::failure ();
740+
741+ if (parser.parseTypeList (continueTypes))
742+ return mlir::failure ();
743+ if (parser.parseRParen ())
744+ return mlir::failure ();
745+ }
746+
747+ if (parser.parseComma ())
748+ return mlir::failure ();
749+
750+ if (parser.parseSuccessor (landingPadSuccessor))
751+ return mlir::failure ();
752+
753+ if (mlir::succeeded (parser.parseOptionalLParen ())) {
754+ landingPadOperandsLoc = parser.getCurrentLocation ();
755+ if (parser.parseOperandList (landingPadOperands))
756+ return mlir::failure ();
757+ if (parser.parseColon ())
758+ return mlir::failure ();
759+
760+ if (parser.parseTypeList (landingPadTypes))
761+ return mlir::failure ();
762+ if (parser.parseRParen ())
763+ return mlir::failure ();
764+ }
765+
766+ if (parser.parseOptionalAttrDict (result.attributes ))
767+ return mlir::failure ();
768+
769+ result.addSuccessors (continueSuccessor);
770+ result.addSuccessors (landingPadSuccessor);
771+ return mlir::success ();
772+ }
773+
718774static mlir::ParseResult parseCallCommon (mlir::OpAsmParser &parser,
719- mlir::OperationState &result) {
775+ mlir::OperationState &result,
776+ bool hasDestinationBlocks = false ) {
720777 llvm::SmallVector<mlir::OpAsmParser::UnresolvedOperand, 4 > ops;
721778 llvm::SMLoc opsLoc;
722779 mlir::FlatSymbolRefAttr calleeAttr;
723780 llvm::ArrayRef<mlir::Type> allResultTypes;
724781
782+ // TryCall control flow related
783+ llvm::SmallVector<mlir::OpAsmParser::UnresolvedOperand, 4 > continueOperands;
784+ llvm::SMLoc continueOperandsLoc;
785+ llvm::SmallVector<mlir::Type, 1 > continueTypes;
786+ llvm::SmallVector<mlir::OpAsmParser::UnresolvedOperand, 4 > landingPadOperands;
787+ llvm::SMLoc landingPadOperandsLoc;
788+ llvm::SmallVector<mlir::Type, 1 > landingPadTypes;
789+
725790 // If we cannot parse a string callee, it means this is an indirect call.
726791 if (!parser
727792 .parseOptionalAttribute (calleeAttr, CIRDialect::getCalleeAttrName (),
@@ -743,6 +808,14 @@ static mlir::ParseResult parseCallCommon(mlir::OpAsmParser &parser,
743808 if (parser.parseRParen ())
744809 return mlir::failure ();
745810
811+ if (hasDestinationBlocks &&
812+ parseTryCallBranches (parser, result, continueOperands, landingPadOperands,
813+ continueTypes, landingPadTypes, continueOperandsLoc,
814+ landingPadOperandsLoc)
815+ .failed ()) {
816+ return ::mlir::failure ();
817+ }
818+
746819 if (parser.parseOptionalKeyword (" nothrow" ).succeeded ())
747820 result.addAttribute (CIRDialect::getNoThrowAttrName (),
748821 mlir::UnitAttr::get (parser.getContext ()));
@@ -775,14 +848,34 @@ static mlir::ParseResult parseCallCommon(mlir::OpAsmParser &parser,
775848 if (parser.resolveOperands (ops, opsFnTy.getInputs (), opsLoc, result.operands ))
776849 return mlir::failure ();
777850
851+ if (hasDestinationBlocks) {
852+ // The TryCall ODS layout is: cont, landing_pad, operands.
853+ llvm::copy (::llvm::ArrayRef<int32_t >(
854+ {static_cast <int32_t >(continueOperands.size ()),
855+ static_cast <int32_t >(landingPadOperands.size ()),
856+ static_cast <int32_t >(ops.size ())}),
857+ result.getOrAddProperties <cir::TryCallOp::Properties>()
858+ .operandSegmentSizes .begin ());
859+
860+ if (parser.resolveOperands (continueOperands, continueTypes,
861+ continueOperandsLoc, result.operands ))
862+ return ::mlir::failure ();
863+
864+ if (parser.resolveOperands (landingPadOperands, landingPadTypes,
865+ landingPadOperandsLoc, result.operands ))
866+ return ::mlir::failure ();
867+ }
868+
778869 return mlir::success ();
779870}
780871
781872static void printCallCommon (mlir::Operation *op,
782873 mlir::FlatSymbolRefAttr calleeSym,
783874 mlir::Value indirectCallee,
784875 mlir::OpAsmPrinter &printer, bool isNothrow,
785- cir::SideEffect sideEffect) {
876+ cir::SideEffect sideEffect,
877+ mlir::Block *cont = nullptr ,
878+ mlir::Block *landingPad = nullptr ) {
786879 printer << ' ' ;
787880
788881 auto callLikeOp = mlir::cast<cir::CIRCallOpInterface>(op);
@@ -796,8 +889,35 @@ static void printCallCommon(mlir::Operation *op,
796889 assert (indirectCallee);
797890 printer << indirectCallee;
798891 }
892+
799893 printer << " (" << ops << " )" ;
800894
895+ if (cont) {
896+ assert (landingPad && " expected two successors" );
897+ auto tryCall = dyn_cast<cir::TryCallOp>(op);
898+ assert (tryCall && " regular calls do not branch" );
899+ printer << ' ' << tryCall.getCont ();
900+ if (!tryCall.getContOperands ().empty ()) {
901+ printer << " (" ;
902+ printer << tryCall.getContOperands ();
903+ printer << ' ' << " :" ;
904+ printer << ' ' ;
905+ printer << tryCall.getContOperands ().getTypes ();
906+ printer << " )" ;
907+ }
908+ printer << " ," ;
909+ printer << ' ' ;
910+ printer << tryCall.getLandingPad ();
911+ if (!tryCall.getLandingPadOperands ().empty ()) {
912+ printer << " (" ;
913+ printer << tryCall.getLandingPadOperands ();
914+ printer << ' ' << " :" ;
915+ printer << ' ' ;
916+ printer << tryCall.getLandingPadOperands ().getTypes ();
917+ printer << " )" ;
918+ }
919+ }
920+
801921 if (isNothrow)
802922 printer << " nothrow" ;
803923
@@ -807,10 +927,11 @@ static void printCallCommon(mlir::Operation *op,
807927 printer << " )" ;
808928 }
809929
810- printer.printOptionalAttrDict (op->getAttrs (),
811- {CIRDialect::getCalleeAttrName (),
812- CIRDialect::getNoThrowAttrName (),
813- CIRDialect::getSideEffectAttrName ()});
930+ llvm::SmallVector<::llvm::StringRef, 4 > elidedAttrs = {
931+ CIRDialect::getCalleeAttrName (), CIRDialect::getNoThrowAttrName (),
932+ CIRDialect::getSideEffectAttrName (),
933+ CIRDialect::getOperandSegmentSizesAttrName ()};
934+ printer.printOptionalAttrDict (op->getAttrs (), elidedAttrs);
814935
815936 printer << " : " ;
816937 printer.printFunctionalType (op->getOperands ().getTypes (),
@@ -892,6 +1013,70 @@ cir::CallOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
8921013 return verifyCallCommInSymbolUses (*this , symbolTable);
8931014}
8941015
1016+ // ===----------------------------------------------------------------------===//
1017+ // TryCallOp
1018+ // ===----------------------------------------------------------------------===//
1019+
1020+ mlir::OperandRange cir::TryCallOp::getArgOperands () {
1021+ if (isIndirect ())
1022+ return getArgs ().drop_front (1 );
1023+ return getArgs ();
1024+ }
1025+
1026+ mlir::MutableOperandRange cir::TryCallOp::getArgOperandsMutable () {
1027+ mlir::MutableOperandRange args = getArgsMutable ();
1028+ if (isIndirect ())
1029+ return args.slice (1 , args.size () - 1 );
1030+ return args;
1031+ }
1032+
1033+ mlir::Value cir::TryCallOp::getIndirectCall () {
1034+ assert (isIndirect ());
1035+ return getOperand (0 );
1036+ }
1037+
1038+ // / Return the operand at index 'i'.
1039+ Value cir::TryCallOp::getArgOperand (unsigned i) {
1040+ if (isIndirect ())
1041+ ++i;
1042+ return getOperand (i);
1043+ }
1044+
1045+ // / Return the number of operands.
1046+ unsigned cir::TryCallOp::getNumArgOperands () {
1047+ if (isIndirect ())
1048+ return this ->getOperation ()->getNumOperands () - 1 ;
1049+ return this ->getOperation ()->getNumOperands ();
1050+ }
1051+
1052+ LogicalResult
1053+ cir::TryCallOp::verifySymbolUses (SymbolTableCollection &symbolTable) {
1054+ return verifyCallCommInSymbolUses (*this , symbolTable);
1055+ }
1056+
1057+ mlir::ParseResult cir::TryCallOp::parse (mlir::OpAsmParser &parser,
1058+ mlir::OperationState &result) {
1059+ return parseCallCommon (parser, result, /* hasDestinationBlocks=*/ true );
1060+ }
1061+
1062+ void cir::TryCallOp::print (::mlir::OpAsmPrinter &p) {
1063+ mlir::Value indirectCallee = isIndirect () ? getIndirectCall () : nullptr ;
1064+ cir::SideEffect sideEffect = getSideEffect ();
1065+ printCallCommon (*this , getCalleeAttr (), indirectCallee, p, getNothrow (),
1066+ sideEffect, getCont (), getLandingPad ());
1067+ }
1068+
1069+ mlir::SuccessorOperands cir::TryCallOp::getSuccessorOperands (unsigned index) {
1070+ assert (index < getNumSuccessors () && " invalid successor index" );
1071+ if (index == 0 )
1072+ return SuccessorOperands (getContOperandsMutable ());
1073+ if (index == 1 )
1074+ return SuccessorOperands (getLandingPadOperandsMutable ());
1075+
1076+ // index == 2
1077+ return SuccessorOperands (getArgOperandsMutable ());
1078+ }
1079+
8951080// ===----------------------------------------------------------------------===//
8961081// ReturnOp
8971082// ===----------------------------------------------------------------------===//
0 commit comments