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

Implement ListInsert in the LLVM Backend #932

Merged
merged 5 commits into from
Aug 7, 2022

Conversation

Thirumalai-Shaktivel
Copy link
Collaborator

No description provided.

@Thirumalai-Shaktivel Thirumalai-Shaktivel added the llvm LLVM related changes label Aug 6, 2022
@Thirumalai-Shaktivel
Copy link
Collaborator Author

@czgdp1807
I'm planning to implement in this way:

int main() {
  int a[] = {1, 3, 4, 0};
  for (int i = 3; i > 1; i--) {
    a[i] = a[i-1];
  }
  a[1] = 2;
  for (int i = 0; i <=3; i ++) {
    std::cout << a[i] << " ";
  }
  return 0;
}

@Thirumalai-Shaktivel
Copy link
Collaborator Author

Thirumalai-Shaktivel commented Aug 6, 2022

Can you please provide some explanation:

  • What does get_pointer_to_current_end_point work? (How does it actually calculate the value?)
  • How to get the List size?
llvm::Value* arg_size = builder->CreateMul(llvm::ConstantInt::get(context, llvm::APInt(32, type_size)), src_capacity);

Does this work as intended?

  • The following retrieves the value at the specific pos in the list, right?
    llvm_utils->create_gep(list, pos)

@czgdp1807
Copy link
Collaborator

Well, it needs the following steps IMO,

  1. First resize if needed. Since, n is always pointing to the index of the next incoming element you can simply call LLVMList::resize_if_needed.
  2. Now start shifting element to the right by one step (you need to generate loop in LLVM for that) starting from the n - 1 position till pos.
  3. Now call LLVMList::write_item with list, pos and value.

That should be it.

@Thirumalai-Shaktivel
Copy link
Collaborator Author

Yup, I had the same thought!

@czgdp1807
Copy link
Collaborator

czgdp1807 commented Aug 6, 2022

What does get_pointer_to_current_end_point do? (How does it actually calculate the value?)

It points to the index of the next incoming element. Say you have 4 elements in the list then its value will be 4 (0, 1, 2, 3 will be the indices of the already existing elements and 4 will be the index of the next incoming list).

How to get the List size?

If you are planning to use size for resizing for inserting the new element then you don't need it. resize_if_needed already does that. capacity is the maximum element of elements a list can accommodate before next doubling + 1, and n (current end point) is the number of elements currently in the list.

@Thirumalai-Shaktivel
Copy link
Collaborator Author

Thank you, I got it!

@czgdp1807
Copy link
Collaborator

czgdp1807 commented Aug 6, 2022

Well doing the second step in #932 (comment) from n - 1 to pos (in reverse direction) might not be cache efficient. Starting from pos should be better. You just need to store pos + 1's value in a temporary variable. Something like the following,

tmp1 = l[pos]
for i in range(pos, n):
    tmp2 = l[i + 1]
    l[i + 1] = tmp1
    tmp1 = tmp2

I tested the above approach but not so sure. You can see the code here and try it out for yourself before implementing the same logic in LPython (https://ideone.com/JSDhuh, -100 acts like a garbage value).

@Thirumalai-Shaktivel
Copy link
Collaborator Author

Thirumalai-Shaktivel commented Aug 6, 2022

I have implemented it as mentioned, but I got stuck in handling the loop, Can you please review and help debug the issue here? The while loop goes to an infinite loop!

@Thirumalai-Shaktivel
Copy link
Collaborator Author

@czgdp1807, this PR is ready, Can you please review it?

@czgdp1807
Copy link
Collaborator

Will review tomorrow.

@Thirumalai-Shaktivel
Copy link
Collaborator Author

Thank you very much for your guidance and review.

Copy link
Contributor

@certik certik left a comment

Choose a reason for hiding this comment

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

Fine to merge.

We can create some nicer API to create loops in LLVM in some easier way.

@certik certik merged commit 2082224 into lcompilers:main Aug 7, 2022
@Thirumalai-Shaktivel Thirumalai-Shaktivel deleted the list_insert branch August 8, 2022 02:37
@Thirumalai-Shaktivel
Copy link
Collaborator Author

Thank you!

@Thirumalai-Shaktivel
Copy link
Collaborator Author

Fine to merge.

We can create some nicer API to create loops in LLVM in some easier way.

How do I implement API for loops, or if possible, if statements?

@certik
Copy link
Contributor

certik commented Aug 8, 2022

You implement some nice C++ utility classes or functions, that make using loops/if statements in LLVM easier.

Perhaps something with C++ lambda functions: if(<lambda condition>, <lamba then>, optional <lambda else>), and you just fill in the condition and then / else, and the if function generates the correct boilerplate.

I created a new issue #938 to discuss further.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
llvm LLVM related changes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants