-
Notifications
You must be signed in to change notification settings - Fork 180
[CIR] Add support for AliasOp #1925
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
base: main
Are you sure you want to change the base?
Conversation
Closes llvm#1367 --------- Co-authored-by: Sirui Mu <msrlancern@gmail.com> Co-authored-by: Amr Hesham <amr96@programmer.net> Co-authored-by: Chibuoyim (Wilson) Ogbonna <ogbonnachibuoyim12@gmail.com> Co-authored-by: Yue Huang <30948580+AdUhTkJm@users.noreply.github.com> Co-authored-by: Morris Hafner <mmha@users.noreply.github.com> Co-authored-by: Morris Hafner <mhafner@nvidia.com> Co-authored-by: Sharp-Edged <48861530+Sharp-Edged@users.noreply.github.com> Co-authored-by: Bruno Cardoso Lopes <bruno.cardoso@gmail.com> Co-authored-by: Letu Ren <fantasquex@gmail.com>
…ity and maintainability (llvm#1525) As noted in [this comment](llvm#1442 (comment)), the nested if-arms in `GlobalOpLowering` are somewhat confusing and error-prone. This PR simplifies the logic into more straightforward components. Since LLVM's GlobalOp accepts two types of initializers (either an initializer value or an initializer region), we've extracted the decision logic into a separate function called `lowerInitializer`. This function takes two inout arguments: `mlir::Attribute &init` (for the attribute value) and `bool useInitializerRegion` (as the decision indicator). All code paths then converge at a common epilogue that handles the operation rewriting. The previous implementation for lowering `DataMemberAttr` initializers relied on recursion between MLIR rewrite calls, which made the control flow somewhat opaque. The new version makes this explicit by using a clear self-recursive pattern within `lowerInitializer`.
Fix llvm#1371. Not sure about whether we could remove `convertTypeForMem` completely. Let's fix the doc first.
This change moves all declarations of emit* functions in CIRGenFunction.h into a common location and sorts them alphabetically. The goal of this change is to make it easier to keep upstream and incubator code in a consistent location, making functions easier to find for upstreaming and minimizing conflicts in the incubator when rebasing. I did most of this sort manually, and I've probably been inconsistent in how I treat sorting of uppercase versus lowercase. I made no attempt to provide a rule for ordering different declarations of functions with the same name. We can improve on that over time if anyone feels the need. I tried very hard not to drop comments (one of the reasons I had to do this manually), but I may have lost a few. This change loses the grouping of some declarations that were co-located by common purpose, but most of the declarations lacked a coherent ordering, so I think this is a step forward overall.
This is a rebased version of the inactive PR llvm#1380. --------- Co-authored-by: koparasy <parasyris1@llnl.gov>
Adds implementation for ATanOp's lowering ThroughMLIR.
Lower `vabds_f32` and `vabdd_f64`
Adds implementation for ACosOp's lowering ThroughMLIR.
Lower vmaxv_s32
Adds implementation for ASinOp's lowering ThroughMLIR.
Lower vmaxv_u32
Lower vmaxvq_f64
Lower vmaxnmvq f32 and f64
In the review for upstreaming unary operation support (llvm/llvm-project#131369), it was suggested that the VisitPlus and VisitMinus functions should be combined. This is a backport of that refactoring.
This also removes some unused `#include`s. I choose to allow lowering to LLVM dialect when we're lowering CIR to MLIR core dialects, because some operations don't have their counterparts in these dialects (for example, `UnreachableOp -> llvm.unreachable` and `LLVMIntrinsicCallOp -> cir.llvm.intr.xxx`). I don't think we can delay them to the MLIR->LLVM pass as it seems we assume all CIR operations have been lowered after CIR->MLIR conversion. Co-authored-by: Yue Huang <yh548@cam.ac.uk>
Lower vmaxnmv_f32
Update getZeroInitAttr to cover more FP types, Backport from (llvm/llvm-project#133100)
Adds implementation for TanOp's lowering via ThroughMLIR.
Upstream commit changed behavior llvm/llvm-project@ff585fe I tested in original clang and it produced the same IR with clangir. Related: llvm#1497
…nmvq_f32 (llvm#1546) ower vminnmv_f32, vminnmvq_f64 and vminnmvq_f32
…llvm#1547) When a pointer variable is initialized with a null pointer, the AST contains a NullToPointer cast. If we just emit a null pointer of the correct type, we will miss any side effects that occur in the initializer. This change adds code to emit the initializer expression if it is not a simple constant. This results in an extra null pointer constant being emitted when the expression has side effects, but the constant emitted while visiting the expression does not have the correct type, so the alternative would be to capture the emitted constant and bitcast it to the correct type. An extra constant seems less intrusive than an unnecessary bitcast.
Lower vminv_s32
Lower vminv_u32
llvm#1552) These entries exist in OG but are not present in CIR codegen.
Added: - `cos` - `floor` - `round` - `rint` - `nearbyint` - `sin` - `sqrt` - `tan` - `trunc`
Failure: ``` calling convention does not permit calls call spir_kernel void @bar(ptr addrspace(1) %10) fatal error: error in backend: Lowering from LLVMIR dialect to llvm IR failed! ```
This makes it on par with OG but does not add anything just yet (same NYI asserts should fail).
This will enable handling for records (coming next)
bcardosolopes
left a comment
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.
Thanks for the PR, besides comments, this also needs testcases and LLVM lowering support.
| mlir::OpBuilder::InsertionGuard guard(builder); | ||
|
|
||
| // Some global emissions are triggered while emitting a function, e.g. | ||
| // void s() { x.method() } |
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.
This doesn't seem to apply here.
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.
i think i need some help and explanation on this comment in the OG createCIRFunction to understand more why it's not applicable.
| // Be sure to insert a new function before a current one. | ||
| auto *curCGF = getCurrCIRGenFun(); | ||
| if (curCGF) | ||
| builder.setInsertionPoint(curCGF->CurFn); |
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.
is this ever the case? I can't see how one might want to insert an alias op outside the module level scope
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.
i'm not quite sure what you mean here? don't we want to reset the insertion point if we're inside a function?
| >; | ||
|
|
||
| def CIR_AliasOp : CIR_Op<"alias", [AutomaticAllocationScope, CallableOpInterface, | ||
| FunctionOpInterface, IsolatedFromAbove]> { |
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.
You need to add a description, examples, etc, see others for inspiration
| /// Returns the region on the current operation that is callable. This may | ||
| /// return null in the case of an external callable object, e.g. an external | ||
| /// function. | ||
| ::mlir::Region *getCallableRegion() { |
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.
Will this operation also be used for global variable aliases?
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.
hi Andy, I want to have a simple lowering to LLVM_AliasOp but not sure how messy if the same op has two different functionalities. I want to try using 1 op first. I can change the comments
I've refactored the code to use CIRCallableOpInterface instead of FuncOp now but was wondering if it is ergonomic to do so. Right now if some person wants to use some methods that exists in FunctionOpInterface, they need to search up the return type and the argument type and add it to the CIRCallableOpInterface first, if they dont want to cast it to FunctionOpInterface. It stinks a bit but on top of my mind i can't see another cleaner way to do this. Only test case that doesn't pass is the test case that both requires alias as well as lowering to llvm. will handle that soon |
|
This is changing too much, and became way harder to review. What I was trying to suggest is that we shouldn't be duplicating code that can be covered with interfaces, meaning that if you are free to create a new one if it makes more sense, I'm basically alluding to the existing ones, it doesn't mean they have to be used. In LLVM, there are two cases for alias, function aliases and global aliases. I suggest you start a new PR looking at C/C++ examples that create aliases for both globals and function, and find out via that what it's the abstraction you really need. Right now, as you noticed, we have clunky support for alias functions in CIR, because LLVM dialect didn't have AliasOp until I added it some months ago, so you'd need to think about the design here. |
8acaf96 to
58135ea
Compare
Related to #1913.
Added alias op and verifier for call op. Failing two tests related to constructor and destructor aliases
Right now
cir::FuncOp CIRGenModule::GetOrCreateCIRFunctionis being used in a lot of place where if we switch to using Alias in emitAliasForGlobal, we'll hit cast type error. I'm not quite sure if i should change the function result type to be mlir::Operation* or something that encompasses both function and alias or notPilot test case