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

ir: proposal: typecheck more things #65

Open
2 of 7 tasks
pwaller opened this issue Feb 18, 2019 · 9 comments
Open
2 of 7 tasks

ir: proposal: typecheck more things #65

pwaller opened this issue Feb 18, 2019 · 9 comments

Comments

@pwaller
Copy link
Member

pwaller commented Feb 18, 2019

I occasionally get the order of params wrong to a store, passing the pointer in place of the value and vice versa. It would be neat if this panic'd.

Status: we agreed that typechecking is useful thing to do.
Progress: partially done, but only attacking things as they crop up. Feel free to comment to add to the list.

@mewmew
Copy link
Member

mewmew commented Feb 19, 2019

I understand that the arguments are easy to mix up, since they are in the reverse order of e.g. memcpy and friends. The rationale for the given order is to mimic the order of occurrence in the LLVM assembly. https://llvm.org/docs/LangRef.html#store-instruction

The proposed sanity check sounds good to me. Essentially it would check that src.Type() is equal to dst.Type().(*types.PointerType).Elem, and if not panic, preferably with a user friendly error message.

func NewStore(src, dst value.Value) *InstStore

@pwaller Care to prepare a PR?

@mewmew
Copy link
Member

mewmew commented Feb 19, 2019

Thinking a bit more about this, I remember earlier thoughts and design ideas to defer type checking to a dedicated semantic analysis stage.

We can add the proposed NewStore type check now, but it may go away in the future if we decide to implement sem.Verify.

The main rationale for separating IR construction and semantic analysis is that sometimes you may want to add an incomplete value as an argument to an instruction. The type of this incomplete value may not be readily available until later during IR construction, and forcing users to have it pre-computed, a-prior limits the use of the IR construction API.

To still provide the same safety guarantees, a later stage would then perform type checking and other semantic analysis and verification on the IR, once the users decides it is complete and ready for type checking (i.e. when the user decides to invoke sem.Verify.

// Package sem performs semantic analysis of LLVM IR modules.
package sem

// Verify performs type-checking and semantic analysis of the given module to
// verify consistency and correctness.
func Verify(m *ir.Module) error

I have run into this a few times in the past, and without that separation, you essentially run into a catch22 chicken or the egg problem. Which I had a more concrete example to provide, but it's just based on hours of struggling with these kind of issues in the past.

@pwaller
Copy link
Member Author

pwaller commented Feb 19, 2019

So, the reason I proposed NewStore to panic is:

  1. I want the code to panic at the point of the error, so that I can find the error early and easily.
  2. We do already have access to a functioning verifier (opt -verify).

With respect to incomplete types, I understand where you're coming from. I had particular fun implementing recursive types.

What about accepting some sort of wrapper or sentinel when you really want to defer the typing?

@mewmew
Copy link
Member

mewmew commented Feb 19, 2019

  • I want the code to panic at the point of the error, so that I can find the error early and easily.

Make sense. Feel free to add the panic. If we later discover that this is limiting IR construction too much, we can figure out specifics related to the wrapper/sentinel that you mentioned.

  • We do already have access to a functioning verifier (opt -verify).

Fair point.

@pwaller
Copy link
Member Author

pwaller commented Feb 20, 2019

I'm also finding it would be useful to check that the arguments to bitcast, inttoptr and ptrtoint have the right form.

@pwaller
Copy link
Member Author

pwaller commented Feb 23, 2019

I also added type checking of insertvalue. I am finding these really useful for catching bugs early. I figure if there are circumstances where it is useful to construct things with incomplete types, then those can be done by constructing the values of these directly rather than through their New* constructors. What do you think?

@mewmew
Copy link
Member

mewmew commented Feb 24, 2019

I figure if there are circumstances where it is useful to construct things with incomplete types, then those can be done by constructing the values of these directly rather than through their New* constructors. What do you think?

That's a good point! I agree.

pwaller added a commit that referenced this issue Feb 24, 2019
* Support vector and int typed arguments.
* Add a table driven test for the different cases.

I've tried my best to make the error messages informative and consistent
with other error messages, but further improvements are welcomed -
please also feel free to take ownership of the branch and tweak the
messages if appropriate.

Updates #65.

Subsumes part of PR #69.
pwaller added a commit that referenced this issue Feb 24, 2019
* Support vector and int typed arguments.
* Add a table driven test for the different cases.

I've tried my best to make the error messages informative and consistent
with other error messages, but further improvements are welcomed -
please also feel free to take ownership of the branch and tweak the
messages if appropriate.

Updates #65.

Subsumes part of PR #69.
@pwaller pwaller changed the title ir: proposal: typecheck NewStore arguments? ir: proposal: typecheck more things Feb 25, 2019
@mewmew mewmew added this to the future milestone Jun 30, 2019
@mewmew
Copy link
Member

mewmew commented Jun 30, 2019

Marking this as future milestone until we have a clear release target in mind.

@mewmew
Copy link
Member

mewmew commented Dec 5, 2019

re (#65 (comment)): inlineasm type parameter must be a func type (or pointer(?) depending on #74 discussion).

Pointer to function it is.

Resource located by @dannypsnl:

From https://stackoverflow.com/questions/29184031/how-to-get-llvm-inline-asm-operands-type:

In LLVM, InlineAsm is a subclass of Value, and the associated value is always of type pointer-to-function.

mewmew added a commit to mewpull/geode that referenced this issue Dec 30, 2019
There were two main changes of llir/llvm that required updates in Geode,
namely:

1) The sanity type-checks proposed in llir/llvm#65 and added in PR
   llir/llvm#72.
2) The API update of NewLoad, NewStore, NewGetElementPtr which added
   a elemType argument in preparation for opaque pointer types of the
   official LLVM project (see llir/llvm#112).

To resolve 1), an Equal method was added to StructType and SliceType of
gtypes.

To resolve 2) the element type was passed as the first argument to
NewLoad, NewStore and NewGetElementPtr.

Note, we've definitely noticed that working with user-defined types is
difficult and does not work well with the extensive type-switching used
in llir/llvm. The user-defined types (structs with names and slices) of
Geode have been very helpful to get a better understanding of this
limitation of llir/llvm. This has been outlined in llir/llvm#59 (comment)
and we hope to get a better design for sumtypes to allow user-defined
types, values, constants, instructions, etc.

One step at the time :)

I'm still very happy that you started the Geode project Nick as I've
learnt a lot from it and continue to learn more.

Wish you all the best and a most lovely start of the new year.

Cheers,
Robin
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants