clang 23.0.0git
CIRTransformUtils.cpp
Go to the documentation of this file.
1//===- CIRTransformUtils.cpp - Shared helpers for CIR transforms ----------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "CIRTransformUtils.h"
10
12
13mlir::Block *cir::replaceCallWithTryCall(cir::CallOp callOp,
14 mlir::Block *unwindDest,
15 mlir::Location loc,
16 mlir::RewriterBase &rewriter) {
17 mlir::Block *callBlock = callOp->getBlock();
18
19 assert(!callOp.getNothrow() && "call is not expected to throw");
20
21 // Split the block after the call - remaining ops become the normal
22 // destination.
23 mlir::Block *normalDest =
24 rewriter.splitBlock(callBlock, std::next(callOp->getIterator()));
25
26 // Build the try_call to replace the original call.
27 rewriter.setInsertionPoint(callOp);
28 cir::TryCallOp tryCallOp;
29 if (callOp.isIndirect()) {
30 mlir::Value indTarget = callOp.getIndirectCall();
31 auto ptrTy = mlir::cast<cir::PointerType>(indTarget.getType());
32 auto resTy = mlir::cast<cir::FuncType>(ptrTy.getPointee());
33 tryCallOp =
34 cir::TryCallOp::create(rewriter, loc, indTarget, resTy, normalDest,
35 unwindDest, callOp.getArgOperands());
36 } else {
37 mlir::Type resType = callOp->getNumResults() > 0
38 ? callOp->getResult(0).getType()
39 : mlir::Type();
40 tryCallOp =
41 cir::TryCallOp::create(rewriter, loc, callOp.getCalleeAttr(), resType,
42 normalDest, unwindDest, callOp.getArgOperands());
43 }
44
45 // Copy all attributes from the original call except those already set by
46 // TryCallOp::create or that are operation-specific and should not be copied.
47 llvm::StringRef excludedAttrs[] = {
48 cir::CIRDialect::getCalleeAttrName(), // Set by create()
49 cir::CIRDialect::getOperandSegmentSizesAttrName(),
50 };
51 for (mlir::NamedAttribute attr : callOp->getAttrs()) {
52 if (llvm::is_contained(excludedAttrs, attr.getName()))
53 continue;
54 assert(!llvm::is_contained(
55 {
56 cir::CIRDialect::getNoThrowAttrName(),
57 cir::CIRDialect::getNoUnwindAttrName(),
58 },
59 attr.getName()) &&
60 "unexpected attribute on converted call");
61 tryCallOp->setAttr(attr.getName(), attr.getValue());
62 }
63
64 // Replace uses of the call result with the try_call result. Use the
65 // rewriter API so any listener (e.g. the pattern rewriter in
66 // FlattenCFG) is notified of the in-place modifications to each user.
67 if (callOp->getNumResults() > 0)
68 rewriter.replaceAllUsesWith(callOp->getResult(0), tryCallOp.getResult());
69
70 rewriter.eraseOp(callOp);
71 return normalDest;
72}
mlir::Block * replaceCallWithTryCall(cir::CallOp callOp, mlir::Block *unwindDest, mlir::Location loc, mlir::RewriterBase &rewriter)
Replace a cir::CallOp with a cir::TryCallOp whose unwind destination is unwindDest.