Skip to content

(Towards #3325) Improving .datatype to return size intrinsics instead of DEFERRED#3336

Open
LonelyCat124 wants to merge 9 commits intomasterfrom
3325_datatype_enhancement
Open

(Towards #3325) Improving .datatype to return size intrinsics instead of DEFERRED#3336
LonelyCat124 wants to merge 9 commits intomasterfrom
3325_datatype_enhancement

Conversation

@LonelyCat124
Copy link
Collaborator

Still in progress, this so far changes the arrayreference datatype to never give shapes with ArrayType.Extent in the result if we can resolve the shape.

I want to look at binaryoperation and how it chooses what result to use next, as I think we can do better than the current resul.

@LonelyCat124 LonelyCat124 marked this pull request as ready for review February 18, 2026 11:49
@LonelyCat124
Copy link
Collaborator Author

Waiting on coverage to come back, but if its ok this is ready for a first look.

I'm not totally convinced by the choice I make in BinaryOperation, so if the reviewer has a better strategy I'm happy to change it.

StructureReference already did output sizes better than ArrayReference, so from my experiment I didn't think that needed to be updated.

@sergisiso
Copy link
Collaborator

I am happy to review this, as I have been thinking what I need to redo WHEREs and it will be something similar. (I will wait for test/coverage to be reported before starting)

@codecov
Copy link

codecov bot commented Feb 18, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.95%. Comparing base (b703387) to head (e4fb575).

❌ Your project check has failed because you have indirect coverage changes. Learn more about Unexpected Coverage Changes and reasons for indirect coverage changes.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #3336      +/-   ##
==========================================
- Coverage   99.95%   99.95%   -0.01%     
==========================================
  Files         384      384              
  Lines       54225    54232       +7     
==========================================
+ Hits        54203    54208       +5     
- Misses         22       24       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Collaborator

@sergisiso sergisiso left a comment

Choose a reason for hiding this comment

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

Looks good @LonelyCat124 (although I am not convinced about the new special case - see inline)

I see this is a towards, is the goal of that issue to make "the datatype method should not propagate the DEFERRED attribute when constructing the datatype of an expression". Where are we on this?

@sergisiso
Copy link
Collaborator

Oh and I forgot about the Coverage indirect changes. It seems they are related to WHEREs, so I would address that comment first and see if they are still there.

@LonelyCat124
Copy link
Collaborator Author

@sergisiso Ready for another look now I've updated the array_mixin stuff.

Copy link
Collaborator

@sergisiso sergisiso left a comment

Choose a reason for hiding this comment

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

Thanks for improving the array_mixin._extent behaviour @LonelyCat124 . I still have some questions about the behaviour of the datatype method that probably means we are missing some tests.

Comment on lines +611 to +612
if (isinstance(start, Literal) and start.value_as_python == 1 and
isinstance(step, Literal) and step.value_as_python == 1):
Copy link
Collaborator

Choose a reason for hiding this comment

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

Just for me to understand, what is the difference here? Is that now the precision doesn't matter in the comparison?

Also, I find the "value_as_python" slightly odd, for me it should be the other way around: "as_python_value" or even excluding the python and just being "as_value"

:param argtypes: the types of the two operands.
:type argtypes: list[:py:class:`psyclone.psyir.symbols.DataType`,
:param optypes: the types of the two operands.
:type optypes: list[:py:class:`psyclone.psyir.symbols.DataType`,
Copy link
Collaborator

Choose a reason for hiding this comment

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

typehint, maybe Iterable[DataType]?

b(widx1) = a(widx1)
end if
enddo'''
print(out)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Delete

IntrinsicCall.Intrinsic.SIZE,
[Reference(sym2)])
)])
print("------------")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Remove

[Reference(sym2)])
)])
print("------------")
binop7 = BinaryOperation.create(oper, ref7.copy(), ref6.copy())
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you also do another BinOp with the operands switched? I think you are trying to check that the "datatype" prefers the type without the SIZE intrinsic (add a comment saying that this is the purpose), but in this case its the first operand which would also be chosen by default.

Comment on lines 176 to 178
# TODO #1857 - passing base_type as an instance of ArrayType
# only works because the ArrayType constructor just pulls out
# the intrinsic and precision properties of the type.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this the reason the method have the desirable property that "the datatype method should not propagate the DEFERRED attribute when constructing the datatype of an expression". In this case this should not be a TODO, just a comment. And it will be good to add tests with Extent.ATTRIBUTE and Extent.DEFERRED in src/psyclone/tests/psyir/nodes/array_reference_test.py which are the moment there is none.

Also if the above is true can you update the docstring to say:

def datatype(self) -> Datatype:
''' Note that if the resulting datatype is an ArrayType,
this will convert Extent attributes to the appropriate inquiry intrinsic,
which is convenient to directly use the resulting expression as executable
code. Use `node.symbol.datatype` to obtain the type declaration of the
array symbol (with its Extent attributes).

:returns: the resulting datatype of the array access expression.
'''

(We may want the first sentence to be in each node.datatype docstring, as it is true by extension. E.g. operation.datatype must also have this property)

Copy link
Collaborator

Choose a reason for hiding this comment

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

By the way, if you extend the src/psyclone/tests/psyir/nodes/array_reference_test.py::test_array_datatype I would prefer to have it with a fortran_writer and a bunch of fortran declaration and array_references. I find it much easier to quickly verify it than reading the constructed PSyIR.

all(self.is_full_range(idx) for idx in range(len(shape)))
and all(isinstance(idx, ArrayType.ArrayBounds) for idx in
orig_shape)):
return self.symbol.datatype
Copy link
Collaborator

Choose a reason for hiding this comment

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

I am still usure about this:

  • Are not all shapes ArrayType.ArrayBounds?, what is the new condition checking?
  • What happens if there is a DEFERRED array bounds e.g. real, dimension(3:) :: a. There is no tests for this.
  • Wouldn't we want the same behaviour if it is not the full range, for instance in . real, dimension(100,100) :: a and a(:,1), the resulting shape should preferable be [100] and not SIZE(a, 1).

binop7 = BinaryOperation.create(oper, ref7.copy(), ref6.copy())
dtype6 = binop7.datatype
assert dtype6.shape[0].lower.value == "1"
assert dtype6.shape[0].upper.debug_string() == "5"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Another case we could implement/test is UnresolvedType/UnknwonType + ArrayType

In fortran the operand of an ArrayType can only be an array of the same rank or an scalar. But both will always results as an array of the exact same shape than the ArrayType of the known operand.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants