@@ -2581,22 +2581,69 @@ void createLLVMFuncOpIfNotExist(mlir::ConversionPatternRewriter &rewriter,
25812581mlir::LogicalResult CIRToLLVMThrowOpLowering::matchAndRewrite (
25822582 cir::ThrowOp op, OpAdaptor adaptor,
25832583 mlir::ConversionPatternRewriter &rewriter) const {
2584- if (op.rethrows ()) {
2585- auto voidTy = mlir::LLVM::LLVMVoidType::get (getContext ());
2586- auto funcTy =
2587- mlir::LLVM::LLVMFunctionType::get (getContext (), voidTy, {}, false );
2584+ mlir::Location loc = op.getLoc ();
2585+ auto voidTy = mlir::LLVM::LLVMVoidType::get (getContext ());
25882586
2589- auto mlirModule = op-> getParentOfType <mlir::ModuleOp>();
2590- rewriter. setInsertionPointToStart (&mlirModule. getBodyRegion (). front () );
2587+ if (op. rethrows ()) {
2588+ auto funcTy = mlir::LLVM::LLVMFunctionType::get (voidTy, {} );
25912589
2590+ // Get or create `declare void @__cxa_rethrow()`
25922591 const llvm::StringRef functionName = " __cxa_rethrow" ;
25932592 createLLVMFuncOpIfNotExist (rewriter, op, functionName, funcTy);
25942593
2595- rewriter.setInsertionPointAfter (op.getOperation ());
2596- rewriter.replaceOpWithNewOp <mlir::LLVM::CallOp>(
2597- op, mlir::TypeRange{}, functionName, mlir::ValueRange{});
2594+ auto cxaRethrow = mlir::LLVM::CallOp::create (
2595+ rewriter, loc, mlir::TypeRange{}, functionName);
2596+
2597+ rewriter.replaceOp (op, cxaRethrow);
2598+ return mlir::success ();
25982599 }
25992600
2601+ auto llvmPtrTy = mlir::LLVM::LLVMPointerType::get (rewriter.getContext ());
2602+ auto fnTy = mlir::LLVM::LLVMFunctionType::get (
2603+ voidTy, {llvmPtrTy, llvmPtrTy, llvmPtrTy});
2604+
2605+ // Get or create `declare void @__cxa_throw(ptr, ptr, ptr)`
2606+ const llvm::StringRef fnName = " __cxa_throw" ;
2607+ createLLVMFuncOpIfNotExist (rewriter, op, fnName, fnTy);
2608+
2609+ mlir::Value typeInfo = mlir::LLVM::AddressOfOp::create (
2610+ rewriter, loc, mlir::LLVM::LLVMPointerType::get (rewriter.getContext ()),
2611+ adaptor.getTypeInfoAttr ());
2612+
2613+ mlir::Value dtor;
2614+ if (op.getDtor ()) {
2615+ dtor = mlir::LLVM::AddressOfOp::create (rewriter, loc, llvmPtrTy,
2616+ adaptor.getDtorAttr ());
2617+ } else {
2618+ dtor = mlir::LLVM::ZeroOp::create (rewriter, loc, llvmPtrTy);
2619+ }
2620+
2621+ auto cxaThrowCall = mlir::LLVM::CallOp::create (
2622+ rewriter, loc, mlir::TypeRange{}, fnName,
2623+ mlir::ValueRange{adaptor.getExceptionPtr (), typeInfo, dtor});
2624+
2625+ rewriter.replaceOp (op, cxaThrowCall);
2626+ return mlir::success ();
2627+ }
2628+
2629+ mlir::LogicalResult CIRToLLVMAllocExceptionOpLowering::matchAndRewrite (
2630+ cir::AllocExceptionOp op, OpAdaptor adaptor,
2631+ mlir::ConversionPatternRewriter &rewriter) const {
2632+ // Get or create `declare ptr @__cxa_allocate_exception(i64)`
2633+ StringRef fnName = " __cxa_allocate_exception" ;
2634+ auto llvmPtrTy = mlir::LLVM::LLVMPointerType::get (rewriter.getContext ());
2635+ auto int64Ty = mlir::IntegerType::get (rewriter.getContext (), 64 );
2636+ auto fnTy = mlir::LLVM::LLVMFunctionType::get (llvmPtrTy, {int64Ty});
2637+
2638+ createLLVMFuncOpIfNotExist (rewriter, op, fnName, fnTy);
2639+ auto exceptionSize = mlir::LLVM::ConstantOp::create (rewriter, op.getLoc (),
2640+ adaptor.getSizeAttr ());
2641+
2642+ auto allocaExceptionCall = mlir::LLVM::CallOp::create (
2643+ rewriter, op.getLoc (), mlir::TypeRange{llvmPtrTy}, fnName,
2644+ mlir::ValueRange{exceptionSize});
2645+
2646+ rewriter.replaceOp (op, allocaExceptionCall);
26002647 return mlir::success ();
26012648}
26022649
0 commit comments