-
Notifications
You must be signed in to change notification settings - Fork 154
[CIR][CodeGen][LowerToLLVM] Set calling convention for call ops #836
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -875,18 +875,24 @@ rewriteToCallOrInvoke(mlir::Operation *op, mlir::ValueRange callOperands, | |
mlir::Block *landingPadBlock = nullptr) { | ||
llvm::SmallVector<mlir::Type, 8> llvmResults; | ||
auto cirResults = op->getResultTypes(); | ||
auto callIf = cast<mlir::cir::CIRCallOpInterface>(op); | ||
|
||
if (converter->convertTypes(cirResults, llvmResults).failed()) | ||
return mlir::failure(); | ||
|
||
auto cconv = convertCallingConv(callIf.getCallingConv()); | ||
|
||
if (calleeAttr) { // direct call | ||
if (landingPadBlock) | ||
rewriter.replaceOpWithNewOp<mlir::LLVM::InvokeOp>( | ||
if (landingPadBlock) { | ||
auto newOp = rewriter.replaceOpWithNewOp<mlir::LLVM::InvokeOp>( | ||
op, llvmResults, calleeAttr, callOperands, continueBlock, | ||
mlir::ValueRange{}, landingPadBlock, mlir::ValueRange{}); | ||
else | ||
rewriter.replaceOpWithNewOp<mlir::LLVM::CallOp>(op, llvmResults, | ||
calleeAttr, callOperands); | ||
newOp.setCConv(cconv); | ||
Comment on lines
+887
to
+890
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't have an idea on how to avoid 4 dups of saving If we don't consider hacky There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wouldn't worry too much about this. Since we don't need the result for anything else (yet), my suggestion would be:
|
||
} else { | ||
auto newOp = rewriter.replaceOpWithNewOp<mlir::LLVM::CallOp>( | ||
op, llvmResults, calleeAttr, callOperands); | ||
newOp.setCConv(cconv); | ||
} | ||
} else { // indirect call | ||
assert(op->getOperands().size() && | ||
"operands list must no be empty for the indirect call"); | ||
|
@@ -899,14 +905,17 @@ rewriteToCallOrInvoke(mlir::Operation *op, mlir::ValueRange callOperands, | |
if (landingPadBlock) { | ||
auto llvmFnTy = | ||
dyn_cast<mlir::LLVM::LLVMFunctionType>(converter->convertType(ftyp)); | ||
rewriter.replaceOpWithNewOp<mlir::LLVM::InvokeOp>( | ||
auto newOp = rewriter.replaceOpWithNewOp<mlir::LLVM::InvokeOp>( | ||
op, llvmFnTy, mlir::FlatSymbolRefAttr{}, callOperands, continueBlock, | ||
mlir::ValueRange{}, landingPadBlock, mlir::ValueRange{}); | ||
} else | ||
rewriter.replaceOpWithNewOp<mlir::LLVM::CallOp>( | ||
newOp.setCConv(cconv); | ||
} else { | ||
auto newOp = rewriter.replaceOpWithNewOp<mlir::LLVM::CallOp>( | ||
op, | ||
dyn_cast<mlir::LLVM::LLVMFunctionType>(converter->convertType(ftyp)), | ||
callOperands); | ||
newOp.setCConv(cconv); | ||
} | ||
} | ||
return mlir::success(); | ||
} | ||
|
@@ -932,6 +941,10 @@ class CIRTryCallLowering | |
mlir::LogicalResult | ||
matchAndRewrite(mlir::cir::TryCallOp op, OpAdaptor adaptor, | ||
mlir::ConversionPatternRewriter &rewriter) const override { | ||
if (op.getCallingConv() != mlir::cir::CallingConv::C) { | ||
return op.emitError( | ||
"non-C calling convention is not implemented for try_call"); | ||
} | ||
return rewriteToCallOrInvoke( | ||
op.getOperation(), adaptor.getOperands(), rewriter, getTypeConverter(), | ||
op.getCalleeAttr(), op.getCont(), op.getLandingPad()); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// RUN: cir-translate -cir-to-llvmir %s -o %t.ll | ||
// RUN: FileCheck --input-file=%t.ll %s --check-prefix=LLVM | ||
|
||
!s32i = !cir.int<s, 32> | ||
!fnptr = !cir.ptr<!cir.func<!s32i (!s32i)>> | ||
|
||
module { | ||
cir.func private @my_add(%a: !s32i, %b: !s32i) -> !s32i cc(spir_function) | ||
|
||
cir.func @ind(%fnptr: !fnptr, %a : !s32i) { | ||
%1 = cir.call %fnptr(%a) : (!fnptr, !s32i) -> !s32i cc(spir_kernel) | ||
// LLVM: %{{[0-9]+}} = call spir_kernel i32 %{{[0-9]+}}(i32 %{{[0-9]+}}) | ||
|
||
%2 = cir.call %fnptr(%a) : (!fnptr, !s32i) -> !s32i cc(spir_function) | ||
// LLVM: %{{[0-9]+}} = call spir_func i32 %{{[0-9]+}}(i32 %{{[0-9]+}}) | ||
|
||
%3 = cir.call @my_add(%1, %2) : (!s32i, !s32i) -> !s32i cc(spir_function) | ||
// LLVM: %{{[0-9]+}} = call spir_func i32 @my_add(i32 %{{[0-9]+}}, i32 %{{[0-9]+}}) | ||
|
||
cir.return | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested by updated
spir-calling-conv.cl
.