Skip to content

Conversation

MathiasVP
Copy link
Contributor

This PR fixes two classes of bugs related to computing the type of a DataFlow::Node:

  • The type of Operands and Instructions weren't using the dataflow specific way to get the type of those entities. In certain cases the IR assigns some instructions an Unknown type (for soundness reasons, I guess?) whereas there's a more intuitive type to assign to the instruction for dataflow-purposes. We were already doing the correct thing for SSA, but we weren't doing so in the dataflow files.
  • The type of an InitialGlobalValue node's at indirection index 0 was (e.g.) int instead of int*. It should be int* because its the InitialGlobalValue at indirection index 1 that represents the value pointed to by the global variable.

The first commit adds a new test that reveals these problems. The second commits fixes the issues, and the third commit accepts the test changes (which are all good 🎉).

@MathiasVP MathiasVP requested a review from a team as a code owner February 14, 2023 09:08
@github-actions github-actions bot added the C++ label Feb 14, 2023
@MathiasVP MathiasVP added the no-change-note-required This PR does not need a change note label Feb 14, 2023
Comment on lines 604 to 606
if this.isGLValue()
then result = globalDef.getUnspecifiedType()
else result = getTypeImpl(type.getUnspecifiedType(), globalDef.getIndirectionIndex() - 1)
Copy link
Contributor

Choose a reason for hiding this comment

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

Since we have type = globalDef.getUnspecifiedType(), I think the following should do.

Suggested change
if this.isGLValue()
then result = globalDef.getUnspecifiedType()
else result = getTypeImpl(type.getUnspecifiedType(), globalDef.getIndirectionIndex() - 1)
if this.isGLValue()
then result = type
else result = getTypeImpl(type, globalDef.getIndirectionIndex() - 1)

Copy link
Contributor

Choose a reason for hiding this comment

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

What I don't understand is why here we do not recurse in the case of a glvalue, while in the two case below we do.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since we have type = globalDef.getUnspecifiedType(), I think the following should do.

Agreed. Thanks for that!

Copy link
Contributor

Choose a reason for hiding this comment

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

What I don't understand is why here we do not recurse in the case of a glvalue, while in the two case below we do.

This is still unanswered 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep. I'm trying to formulate a good response to this right now 😂.

Copy link
Contributor

@jketema jketema Feb 14, 2023

Choose a reason for hiding this comment

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

Take your time. I thought it might have slipped through, but apparently it didn't.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What I don't understand is why here we do not recurse in the case of a glvalue, while in the two case below we do.

Yeah, that's a bit unfortunate. I couldn't quite make it fit the pattern as the other cases. The reason is that, the other cases (i.e., IndirectOperand and IndirectInstruction) are defined with indirection indices in the range 1 to some max number.

However, the GlobalDef that defined an InitialGlobalValue has an index that's in the range 0 to some max number. And that discrepancy between the ranges meant I couldn't figure out how to write it in the same style as the other two cases 😕.

It may be that the real fix is to modify the indices of InitialGlobalValue so that its indirection index range starts 1 instead of 0 🤔. However, I'd like to delay such a larger change to another PR if you're okay with it. I can also add a version of the above explanation to a comment in this predicate if you think that's a good idea.

Copy link
Contributor

Choose a reason for hiding this comment

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

So, isGLValue can only be true is the index has the minimum value?

Copy link
Contributor Author

@MathiasVP MathiasVP Feb 14, 2023

Choose a reason for hiding this comment

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

Short answer: Yes.

Longer answer:
Note that isGLValue is only implemented for InstructionNodes, OperandNodes and InitialGlobalValue.InstructionNode and OperandNode (which intuitively can be seen as IndirectInstructionNodes and IndirectOperandNodes with indirection index 0) implement the predicate by checking if the underlying operand or instruction is a glvalue. Similarly, InitialGlobalValue implements the glvalue check by checking if the indirection index is 0.

Does that make sense? I'd be happy to do a Zoom chat about it if that's any easier.

MathiasVP and others added 2 commits February 14, 2023 09:49
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
@MathiasVP
Copy link
Contributor Author

DCA is uneventful (as expected).

Copy link
Contributor

@jketema jketema left a comment

Choose a reason for hiding this comment

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

LGTM

@MathiasVP MathiasVP merged commit 2591460 into github:mathiasvp/replace-ast-with-ir-use-usedataflow Feb 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C++ no-change-note-required This PR does not need a change note
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants