Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def visit_If(self, node):
self.generic_visit(node)
try:
if ast.literal_eval(node.test):
if not metadata.get(node, OMPDirective):
self.update = True
return node.body
else:
if not metadata.get(node, OMPDirective):
self.update = True
return node.orelse
except ValueError:
# not a constant expression
pass
have_body = any(not isinstance(x, ast.Pass) for x in node.body)
have_else = any(not isinstance(x, ast.Pass) for x in node.orelse)
# If the "body" is empty but "else content" is useful, switch branches
# and remove else content
if not have_body and have_else:
test = ast.UnaryOp(op=ast.Not(), operand=node.test)
self.update = True
return ast.If(test=test, body=node.orelse, orelse=list())
# if neither "if" and "else" are useful, keep test if it is not pure
elif not have_body:
def visit(self, node):
old_omp = self.in_omp
omp_nodes = md.get(node, openmp.OMPDirective)
if omp_nodes:
self.in_omp = set(self.name_count.keys())
super(LazynessAnalysis, self).visit(node)
if omp_nodes:
new_nodes = set(self.name_count).difference(self.in_omp)
for omp_node in omp_nodes:
for n in omp_node.deps:
if isinstance(n, ast.Name):
self.result[n.id] = LazynessAnalysis.INF
self.dead.update(new_nodes)
self.in_omp = old_omp
def visit(self, node):
""" Add OMPDirective from the old node to the new one. """
old_omp = metadata.get(node, OMPDirective)
node = super(DeadCodeElimination, self).visit(node)
if not metadata.get(node, OMPDirective):
for omp_directive in old_omp:
metadata.add(node, omp_directive)
return node
def visit_For(self, node):
# if the user added some OpenMP directive, trust him and no unroll
if metadata.get(node, OMPDirective):
return node # don't visit children because of collapse
# first unroll children if needed or possible
self.generic_visit(node)
# a break or continue in the loop prevents unrolling too
has_break = any(self.gather(HasBreak, n)
for n in node.body)
has_cont = any(self.gather(HasContinue, n)
for n in node.body)
if has_break or has_cont:
return node
# do not unroll too much to prevent code growth
node_count = self.gather(NodeCount, node)
def process_omp_attachements(self, node, stmt, index=None):
"""
Add OpenMP pragma on the correct stmt in the correct order.
stmt may be a list. On this case, index have to be specify to add
OpenMP on the correct statement.
"""
omp_directives = metadata.get(node, OMPDirective)
if omp_directives:
directives = list()
for directive in omp_directives:
directive.deps = [self.visit(dep) for dep in directive.deps]
directives.append(directive)
if index is None:
stmt = AnnotatedStatement(stmt, directives)
else:
stmt[index] = AnnotatedStatement(stmt[index], directives)
return stmt
if self.current:
for curr in self.current:
md = OMPDirective(curr)
metadata.add(node, md)
self.current = list()
# add a Pass to hold some directives
for field_name, field in ast.iter_fields(node):
if field_name in GatherOMPData.statement_lists:
if(field and
isinstance(field[-1], ast.Expr) and
self.isompdirective(field[-1].value)):
field.append(ast.Pass())
self.generic_visit(node)
# add an If to hold scoping OpenMP directives
directives = metadata.get(node, OMPDirective)
field_names = {n for n, _ in ast.iter_fields(node)}
has_no_scope = field_names.isdisjoint(GatherOMPData.statement_lists)
if directives and has_no_scope:
# some directives create a scope, but the holding stmt may not
# artificially create one here if needed
sdirective = ''.join(d.s for d in directives)
scoping = ('parallel', 'task', 'section')
if any(s in sdirective for s in scoping):
metadata.clear(node, OMPDirective)
node = ast.If(ast.Constant(1, None), [node], [])
for directive in directives:
metadata.add(node, directive)
return node
def check_global(self, node, arg):
if not isinstance(arg, ast.Call):
return
try:
aliases = self.strict_aliases[arg.func]
except KeyError:
return
for alias in aliases:
if not isinstance(alias, ast.FunctionDef):
continue
if metadata.get(alias.body[0], metadata.StaticReturn):
raise PythranSyntaxError(
("Cannot modify '{}': global variables are constant "
"in pythran.").format(alias.name),
node)
def dispatch(self, tree):
"""Dispatcher function, dispatching tree type T to method _T."""
# display omp directive in python dump
for omp in metadata.get(tree, openmp.OMPDirective):
deps = list()
for dep in omp.deps:
old_file = self.f
self.f = io.StringIO()
self.dispatch(dep)
deps.append(self.f.getvalue())
self.f = old_file
directive = omp.s.format(*deps)
self._Expr(ast.Expr(ast.Constant(directive, None)))
if isinstance(tree, list):
for t in tree:
self.dispatch(t)
return
meth = getattr(self, "_" + tree.__class__.__name__)
meth(tree)
def visit_Pass(self, node):
ancestor = self.ancestors[node][-1]
if getattr(ancestor, 'body', ()) == [node]:
return node
if getattr(ancestor, 'orelse', ()) == [node]:
return node
if metadata.get(node, OMPDirective):
return node
return None