Skip to content

Commit

Permalink
Actually memoize previous_part and next_part.
Browse files Browse the repository at this point in the history
This improves performance further and doesn't really affect peak memory
consumption.

Because of eng/libadalang/langkit#710, overriden properties lose their
memoization attribute. So, this change inlines the logic of the
overriding properties inside the base properties to make sure
memoization is applied.
  • Loading branch information
Roldak committed Oct 19, 2023
1 parent 407e244 commit 05d5cd6
Showing 1 changed file with 19 additions and 21 deletions.
40 changes: 19 additions & 21 deletions ada/ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -6921,12 +6921,18 @@ def previous_part(go_to_incomplete=(Bool, True)):
"""
Returns the previous part for this type decl.
"""
return If(
return Cond(
Self.is_generic_formal,

# A generic formal type never has a previous part
No(T.BaseTypeDecl.entity),

Self.is_a(ClasswideTypeDecl),
Entity.cast(ClasswideTypeDecl).type_decl
.previous_part(go_to_incomplete).then(
lambda pp: pp.classwide_type
),

# Otherwise look for the previous part in the immediate enclosing
# declarative region.
Self.name.then(
Expand Down Expand Up @@ -6976,6 +6982,18 @@ def next_part():
)
)),

lambda cwt=T.ClasswideTypeDecl: Let(
lambda td=cwt.type_decl: td.next_part.then(
# Sometimes `next_part` returns Entity itself, so check
# that to avoid an infinite loop.
lambda np: If(
td == np,
cwt,
np.classwide_type
)
)
),

lambda _: If(
Entity.is_private
& Not(Entity.is_generic_formal),
Expand Down Expand Up @@ -7384,26 +7402,6 @@ def discriminants_list(
):
return Entity.type_decl.discriminants_list(stop_recurse_at)

@langkit_property(public=True, return_type=T.BaseTypeDecl.entity,
memoized=True)
def previous_part(go_to_incomplete=(Bool, True)):
return Entity.type_decl.previous_part(go_to_incomplete).then(
lambda pp: pp.classwide_type
)

@langkit_property()
def next_part():
td = Var(Entity.type_decl)
return td.next_part.then(
# Sometimes `next_part` returns Entity itself, so check that
# to avoid an infinite loop.
lambda np: If(
td == np,
Entity,
np.classwide_type
)
)

canonical_type = Property(Entity.type_decl.canonical_type.then(
# The canonical type should be classwide whenever it makes sense (e.g.
# if the canonical type is a tagged record type.) Otherwise return
Expand Down

0 comments on commit 05d5cd6

Please sign in to comment.