-
Notifications
You must be signed in to change notification settings - Fork 171
[ASR/LLVM]: Implement Tuple/List Compare #1342
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
Conversation
This PR adds to the ASR front end. We need to figure out how to handle it in the LLVM backend. |
9118f10
to
14c0c9d
Compare
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.
Please implement the support for both these nodes in LLVM. I will approve and merge then.
Yes, I'm planning to add a pass to handle the tuple/list comparison. |
This PR needs #1349 to be merged |
|
||
def f(): | ||
a11: tuple[i32, i32] | ||
b11: tuple[i32, i32] |
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.
Test for nested tuples as well with mixed types like, tuple[i32, tuple[i64, f32], str]
.
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 case (see #1342 (comment)) is not yet covered in the tests. Please test for this first.
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 case is not yet covered in the tests. Please test for this first.
I avoided using f32
because of precision issues in comparison. I added a test for the mixed types:
a: tuple[tuple[i32, i32], str, bool]
b: tuple[tuple[i32, i32], str, bool]
a = (a11, 'ok', True)
b = (b11, 'ok', True)
assert a == b
b = (b11, 'notok', True)
assert a != b
using ASR::down_cast; | ||
|
||
/* | ||
* This ASR pass handles TupleCompare. |
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.
Can you put an example here what is an example input and example output of this pass?
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, I will document once I complete adding the ListCompare
pass.
This adds a pass in the LLVM backend. What exactly does the pass do? Please document in the docstring, see my comment above. Is this just an optional pass that we currently run to simplify the backend, but it is not needed to run in theory? Or is this pass required to always be run due to a deficiency in our ASR design? If the latter, then we need to improve ASR, so that one can generate code from it without requiring any passes. |
IMHO, we don't need a pass here at all (at least for tuples). The backend should be able to do this. Comparing tuples is fairly simple in LLVM. Just generate code according to the type of the elements (they are fixed in number as tuples are fixed size types, we specify everything in the tuple type itself). Calling function for simple comparison of tuples is not worth it I think. Comparing lists though does require generating a loop but I think for generating low level code like LLVM, x86 the loop should be inlined. For C we can add function on our own. Pass might not be needed. |
The reason for adding a pass to compare complex data types like lists, tuples is that it will make the LLVM backend less complex. The current approach recursively compares each element for a tuple, list, etc, and altogether is implemented under one class. The other benefit is that if we make this pass re-usable to any other backend will reduce the effort to write the same recursive algorithm in each backend.
We need |
The problem is LLVM already has the infrastructure to generate code for Tuple comparisons. Extending it for List comparisons is easy. We need it to implement Let's do the following,
lpython/src/libasr/codegen/llvm_utils.cpp Lines 234 to 235 in 81cf7de
Extend it. Re-use it. Modify it. It will generate inlined code so no overhead of function calls.
|
Sure, that sounds like a good idea. I can add a pass for both the compares in this PR and open a new PR for the LLVM backend as a follow-up. |
@certik @czgdp1807 I have added a pass for both |
I don't like the pass for LLVM backend but I will approve this PR. Please add it immediately after this PR is merged. |
|
||
def f(): | ||
a11: tuple[i32, i32] | ||
b11: tuple[i32, i32] |
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 case (see #1342 (comment)) is not yet covered in the tests. Please test for this first.
Ahh, this was working all good before rebasing but now fails with this: this->visit_stmt(*x.m_body[i]);
File "../libasr/asr.h", line 4217
File "../libasr/asr.h", line 3983
File "/Users/thebigbool/repos/lpython/src/libasr/codegen/asr_to_llvm.cpp", line 4007
LFORTRAN_ASSERT(finder != nested_globals.end());
AssertFailed: finder != nested_globals.end() |
#1245