Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
serge-sans-paille committed Sep 1, 2024
1 parent 2b7c76f commit 265178f
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 6 deletions.
2 changes: 1 addition & 1 deletion pythran/analyses/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import analyses.Foo
"""

from .aliases import Aliases, StrictAliases
from .aliases import Aliases, StrictAliases, InterproceduralAliases
from .ancestors import Ancestors, AncestorsWithBody
from .argument_effects import ArgumentEffects
from .argument_read_once import ArgumentReadOnce
Expand Down
40 changes: 38 additions & 2 deletions pythran/analyses/aliases.py
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,11 @@ def visit_DictComp(self, node):

# aliasing created by statements

def init_function_alias(self, node):
"each argument is bound to a different identifier"
self.aliases.update((arg.id, {arg})
for arg in node.args.args)

def visit_FunctionDef(self, node):
'''
Initialise aliasing default value before visiting.
Expand All @@ -558,8 +563,7 @@ def visit_FunctionDef(self, node):
self.aliases.update((k, {v})
for k, v in self.global_declarations.items())

self.aliases.update((arg.id, {arg})
for arg in node.args.args)
self.init_function_alias(node)

self.generic_visit(node)
if Aliases.RetId in self.aliases:
Expand Down Expand Up @@ -612,6 +616,27 @@ def merge_return_aliases(args):

node.return_alias = merge_return_aliases

def visit_Assert(self, node):
self.generic_visit(node)

if not isinstance(node.test, ast.Compare):
return
if len(node.test.ops) != 1:
return
op = node.test.ops[0]
comparator = node.test.comparators[0]

if not isinstance(node.test.left, ast.Name):
return
if not isinstance(comparator, ast.Name):
return

if isinstance(op, ast.IsNot):
left_aliases = self.aliases[node.test.left.id]
right_aliases = self.aliases[comparator.id]
self.aliases[node.test.left.id] = self.aliases[node.test.left.id].difference(right_aliases)
right_aliases.difference_update(left_aliases)

def visit_Assign(self, node):
r'''
Assignment creates aliasing between lhs and rhs
Expand Down Expand Up @@ -786,3 +811,14 @@ class StrictAliases(Aliases):

def get_unbound_value_set(self):
return set()


class InterproceduralAliases(Aliases):
"""
Gather aliases while assuming two different parameters can point to the same
value
"""

def init_function_alias(self, node):
self.aliases.update((arg.id, set(node.args.args))
for arg in node.args.args)
6 changes: 3 additions & 3 deletions pythran/optimizations/fast_gexpr.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
""" Optimize a[...] = b[...] + c when we have no conflicting aliasing """

from pythran.analyses import Aliases
from pythran.analyses import InterproceduralAliases
from pythran.passmanager import Transformation

import gast as ast
Expand All @@ -10,7 +10,7 @@ class FastGExpr(Transformation):

def __init__(self):
self.update = False
super(FastGExpr, self).__init__(Aliases)
super(FastGExpr, self).__init__(InterproceduralAliases)

def as_gexpr(self, node):
if not isinstance(node, ast.Subscript):
Expand Down Expand Up @@ -39,7 +39,7 @@ def may_alias(self, gexpr, value):
if isinstance(value, ast.Subscript):
if not isinstance(value.value, ast.Name):
return True
return gexpr[0] in self.aliases[value.value]
return not self.interprocedural_aliases[gexpr[0]].isdisjoint(self.interprocedural_aliases[value.value])

return True

Expand Down

0 comments on commit 265178f

Please sign in to comment.