Skip to content
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

[CIR][CodeGen][LowerToLLVM] Set calling convention for call ops #836

Merged
merged 1 commit into from
Sep 13, 2024

Conversation

seven-mile
Copy link
Collaborator

This PR implements the CIRGen and Lowering part of calling convention attribute of cir.call-like operations. Here we have 4 kinds of operations: (direct or indirect) x (call or try_call).

According to our need and feasibility of constructing a test case, this PR includes:

  • For CIRGen, only direct call. Until now, the only extra calling conventions are SPIR ones, which cannot be set from source code manually using attributes. Meanwhile, OpenCL C does not allow function pointers or exceptions, therefore the only case remaining is direct call.
  • For Lowering, direct and indirect call, but not any try_call. Although it's possible to write all 4 kinds of calls with calling convention in ClangIR assembly, exceptions is quite hard to write and read. I prefer source-code-level test for it when it's available in the future. For example, possibly C++ thiscall with exceptions.
  • Extra: the verification of calling convention consistency for direct call and direct try_call.

All unsupported cases are guarded by assertions or MLIR diags.

Comment on lines +887 to +890
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);
Copy link
Collaborator Author

@seven-mile seven-mile Sep 13, 2024

Choose a reason for hiding this comment

The 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 newOp and setting CConv. Different from CIRCallOpInterface, LLVM uses CallOpInterface from MLIR std, which is not aware of calling convention.

If we don't consider hacky op->setAttr('calling_conv', ...), it seems we have to do a dynamic dispatch of at least size 2 (invoke + call) after rewriting. I chose to just leave it clear. It might be more appropriate to refactor this part after we have more similar logic like setCConv.

Copy link
Member

Choose a reason for hiding this comment

The 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:

rewriter.replaceOpWithNewOp<mlir::LLVM::InvokeOp>(
          op, llvmResults, calleeAttr, callOperands, continueBlock,
          mlir::ValueRange{}, landingPadBlock, mlir::ValueRange{}).setCConv(cconv);

return builder.createCallOp(callLoc, directFuncOp, CIRCallArgs,
mlir::cir::CallingConv::C, extraFnAttrs);
}
return builder.createCallOp(callLoc, directFuncOp, CIRCallArgs, callingConv,
Copy link
Collaborator Author

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.

Copy link
Member

@bcardosolopes bcardosolopes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, minor suggestion inline, but feel free to apply it in another PR, gonna go ahead and merge this!

Comment on lines +887 to +890
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);
Copy link
Member

Choose a reason for hiding this comment

The 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:

rewriter.replaceOpWithNewOp<mlir::LLVM::InvokeOp>(
          op, llvmResults, calleeAttr, callOperands, continueBlock,
          mlir::ValueRange{}, landingPadBlock, mlir::ValueRange{}).setCConv(cconv);

@bcardosolopes bcardosolopes merged commit 62bfcde into llvm:main Sep 13, 2024
7 checks passed
Hugobros3 pushed a commit to shady-gang/clangir that referenced this pull request Oct 2, 2024
…#836)

This PR implements the CIRGen and Lowering part of calling convention
attribute of `cir.call`-like operations. Here we have **4 kinds of
operations**: (direct or indirect) x (`call` or `try_call`).

According to our need and feasibility of constructing a test case, this
PR includes:

* For CIRGen, only direct `call`. Until now, the only extra calling
conventions are SPIR ones, which cannot be set from source code manually
using attributes. Meanwhile, OpenCL C *does not allow* function pointers
or exceptions, therefore the only case remaining is direct call.
* For Lowering, direct and indirect `call`, but not any `try_call`.
Although it's possible to write all 4 kinds of calls with calling
convention in ClangIR assembly, exceptions is quite hard to write and
read. I prefer source-code-level test for it when it's available in the
future. For example, possibly C++ `thiscall` with exceptions.
* Extra: the verification of calling convention consistency for direct
`call` and direct `try_call`.

All unsupported cases are guarded by assertions or MLIR diags.
smeenai pushed a commit to smeenai/clangir that referenced this pull request Oct 9, 2024
…#836)

This PR implements the CIRGen and Lowering part of calling convention
attribute of `cir.call`-like operations. Here we have **4 kinds of
operations**: (direct or indirect) x (`call` or `try_call`).

According to our need and feasibility of constructing a test case, this
PR includes:

* For CIRGen, only direct `call`. Until now, the only extra calling
conventions are SPIR ones, which cannot be set from source code manually
using attributes. Meanwhile, OpenCL C *does not allow* function pointers
or exceptions, therefore the only case remaining is direct call.
* For Lowering, direct and indirect `call`, but not any `try_call`.
Although it's possible to write all 4 kinds of calls with calling
convention in ClangIR assembly, exceptions is quite hard to write and
read. I prefer source-code-level test for it when it's available in the
future. For example, possibly C++ `thiscall` with exceptions.
* Extra: the verification of calling convention consistency for direct
`call` and direct `try_call`.

All unsupported cases are guarded by assertions or MLIR diags.
smeenai pushed a commit to smeenai/clangir that referenced this pull request Oct 9, 2024
…#836)

This PR implements the CIRGen and Lowering part of calling convention
attribute of `cir.call`-like operations. Here we have **4 kinds of
operations**: (direct or indirect) x (`call` or `try_call`).

According to our need and feasibility of constructing a test case, this
PR includes:

* For CIRGen, only direct `call`. Until now, the only extra calling
conventions are SPIR ones, which cannot be set from source code manually
using attributes. Meanwhile, OpenCL C *does not allow* function pointers
or exceptions, therefore the only case remaining is direct call.
* For Lowering, direct and indirect `call`, but not any `try_call`.
Although it's possible to write all 4 kinds of calls with calling
convention in ClangIR assembly, exceptions is quite hard to write and
read. I prefer source-code-level test for it when it's available in the
future. For example, possibly C++ `thiscall` with exceptions.
* Extra: the verification of calling convention consistency for direct
`call` and direct `try_call`.

All unsupported cases are guarded by assertions or MLIR diags.
keryell pushed a commit to keryell/clangir that referenced this pull request Oct 19, 2024
…#836)

This PR implements the CIRGen and Lowering part of calling convention
attribute of `cir.call`-like operations. Here we have **4 kinds of
operations**: (direct or indirect) x (`call` or `try_call`).

According to our need and feasibility of constructing a test case, this
PR includes:

* For CIRGen, only direct `call`. Until now, the only extra calling
conventions are SPIR ones, which cannot be set from source code manually
using attributes. Meanwhile, OpenCL C *does not allow* function pointers
or exceptions, therefore the only case remaining is direct call.
* For Lowering, direct and indirect `call`, but not any `try_call`.
Although it's possible to write all 4 kinds of calls with calling
convention in ClangIR assembly, exceptions is quite hard to write and
read. I prefer source-code-level test for it when it's available in the
future. For example, possibly C++ `thiscall` with exceptions.
* Extra: the verification of calling convention consistency for direct
`call` and direct `try_call`.

All unsupported cases are guarded by assertions or MLIR diags.
lanza pushed a commit that referenced this pull request Nov 5, 2024
This PR implements the CIRGen and Lowering part of calling convention
attribute of `cir.call`-like operations. Here we have **4 kinds of
operations**: (direct or indirect) x (`call` or `try_call`).

According to our need and feasibility of constructing a test case, this
PR includes:

* For CIRGen, only direct `call`. Until now, the only extra calling
conventions are SPIR ones, which cannot be set from source code manually
using attributes. Meanwhile, OpenCL C *does not allow* function pointers
or exceptions, therefore the only case remaining is direct call.
* For Lowering, direct and indirect `call`, but not any `try_call`.
Although it's possible to write all 4 kinds of calls with calling
convention in ClangIR assembly, exceptions is quite hard to write and
read. I prefer source-code-level test for it when it's available in the
future. For example, possibly C++ `thiscall` with exceptions.
* Extra: the verification of calling convention consistency for direct
`call` and direct `try_call`.

All unsupported cases are guarded by assertions or MLIR diags.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants