Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
symbol_table = _get_symbol_table(psyir_literal_parent)
if not symbol_table:
# No symbol table found. This should never happen in
# normal usage but could occur if a test constructs a
# PSyIR without a Schedule.
raise InternalError(
"Failed to find a symbol table to which to add the kind "
"symbol '{0}'.".format(precision_name))
# Lookup the precision symbol
try:
symbol = symbol_table.lookup(precision_name)
except KeyError:
# The symbol is not found so create a data
# symbol with deferred type and add it to the
# symbol table then return the symbol.
symbol = DataSymbol(precision_name, DeferredType(),
interface=UnresolvedInterface())
symbol_table.add(symbol)
return symbol
representing the symbol's array dimensions.
:param symbol: the symbol instance.
:type symbol: :py:class:`psyclone.psyir.symbols.DataSymbol`
:returns: the Fortran representation of the symbol's dimensions as \
a list.
:rtype: list of str
:raises NotImplementedError: if the format of the dimension is not \
supported.
'''
dims = []
for index in symbol.shape:
if isinstance(index, DataSymbol):
# references another symbol
dims.append(index.name)
elif isinstance(index, int):
# literal constant
dims.append(str(index))
elif isinstance(index, ArrayType.Extent):
# unknown extent
dims.append(":")
else:
raise NotImplementedError(
"unsupported gen_dims index '{0}'".format(str(index)))
return dims
valid_loop_types=["inner", "outer"])
self.loop_type = loop_type
if self._loop_type == "inner":
tag = "inner_loop_idx"
suggested_name = "i"
elif self.loop_type == "outer":
tag = "outer_loop_idx"
suggested_name = "j"
symtab = self.scope.symbol_table
try:
data_symbol = symtab.lookup_with_tag(tag)
except KeyError:
name = symtab.new_symbol_name(suggested_name)
data_symbol = DataSymbol(name, INTEGER_TYPE)
symtab.add(data_symbol, tag=tag)
self.variable = data_symbol
# Pre-initialise the Loop children # TODO: See issue #440
self.addchild(Literal("NOT_INITIALISED", INTEGER_TYPE,
parent=self)) # start
self.addchild(Literal("NOT_INITIALISED", INTEGER_TYPE,
parent=self)) # stop
self.addchild(Literal("1", INTEGER_TYPE, parent=self)) # step
self.addchild(Schedule(parent=self)) # loop body
def gen_code(self, parent):
''' Work out the appropriate loop bounds and then call the base
class to generate the code '''
self.start_expr = Literal("1", INTEGER_TYPE, parent=self)
if self._loop_type == "colours":
self.stop_expr = Reference(DataSymbol("ncolour", INTEGER_TYPE),
parent=self)
elif self._loop_type == "colour":
self.stop_expr = Array(DataSymbol("ncp_ncolour", INTEGER_TYPE),
parent=self)
self.stop_expr.addchild(
Reference(DataSymbol("colour", INTEGER_TYPE)),
parent=self.stop_expr)
else:
# This is a hack as the name is not a valid DataSymbol, it
# is a call to a type-bound function.
self.stop_expr = Reference(
DataSymbol(self.field_name+"%get_ncell()", INTEGER_TYPE),
parent=self)
Loop.gen_code(self, parent)
class to generate the code '''
self.start_expr = Literal("1", INTEGER_TYPE, parent=self)
if self._loop_type == "colours":
self.stop_expr = Reference(DataSymbol("ncolour", INTEGER_TYPE),
parent=self)
elif self._loop_type == "colour":
self.stop_expr = Array(DataSymbol("ncp_ncolour", INTEGER_TYPE),
parent=self)
self.stop_expr.addchild(
Reference(DataSymbol("colour", INTEGER_TYPE)),
parent=self.stop_expr)
else:
# This is a hack as the name is not a valid DataSymbol, it
# is a call to a type-bound function.
self.stop_expr = Reference(
DataSymbol(self.field_name+"%get_ncell()", INTEGER_TYPE),
parent=self)
Loop.gen_code(self, parent)
dim_var = DeclGen(parent, datatype="INTEGER",
entity_decls=[self.variable.name])
parent.add(dim_var)
# Update start loop bound
self.start_expr = Literal("1", INTEGER_TYPE, parent=self)
# Update stop loop bound
if self._loop_type == "inner":
index = "1"
elif self._loop_type == "outer":
index = "2"
self.stop_expr = BinaryOperation(BinaryOperation.Operator.SIZE,
parent=self)
self.stop_expr.addchild(
Reference(DataSymbol(self.field_name, INTEGER_TYPE),
parent=self.stop_expr))
self.stop_expr.addchild(Literal(index, INTEGER_TYPE,
parent=self.stop_expr))
else: # one of our spaces so use values provided by the infrastructure
# loop bounds
# TODO: Issue 440. Implement derive types in PSyIR
if self._loop_type == "inner":
self.start_expr = Reference(
self.field_space + "%istart", parent=self)
self.stop_expr = Reference(
self.field_space + "%istop", parent=self)
elif self._loop_type == "outer":
self.start_expr = Reference(
self.field_space + "%jstart", parent=self)
memento = Memento(schedule, self, [node, symbol_table])
oper_parent = node.parent
assignment = node.ancestor(Assignment)
# Create two temporary variables. There is an assumption here
# that the ABS Operator returns a PSyIR real type. This might
# not be what is wanted (e.g. the args might PSyIR integers),
# or there may be errors (arguments are of different types)
# but this can't be checked as we don't have access to a
# symbol table (see #500) and don't have the appropriate
# methods to query nodes (see #658).
res_var = symbol_table.new_symbol_name("res_abs")
symbol_res_var = DataSymbol(res_var, DataType.REAL)
symbol_table.add(symbol_res_var)
tmp_var = symbol_table.new_symbol_name("tmp_abs")
symbol_tmp_var = DataSymbol(tmp_var, DataType.REAL)
symbol_table.add(symbol_tmp_var)
# Replace operation with a temporary (res_X).
oper_parent.children[node.position] = Reference(symbol_res_var,
parent=oper_parent)
# tmp_var=X
lhs = Reference(symbol_tmp_var)
rhs = node.children[0]
new_assignment = Assignment.create(lhs, rhs)
new_assignment.parent = assignment.parent
assignment.parent.children.insert(assignment.position, new_assignment)
# if condition: tmp_var>0.0
lhs = Reference(symbol_tmp_var)
rhs = Literal("0.0", DataType.REAL)
def gen_code(self, parent):
''' Work out the appropriate loop bounds and then call the base
class to generate the code '''
self.start_expr = Literal("1", INTEGER_TYPE, parent=self)
if self._loop_type == "colours":
self.stop_expr = Reference(DataSymbol("ncolour", INTEGER_TYPE),
parent=self)
elif self._loop_type == "colour":
self.stop_expr = Array(DataSymbol("ncp_ncolour", INTEGER_TYPE),
parent=self)
self.stop_expr.addchild(
Reference(DataSymbol("colour", INTEGER_TYPE)),
parent=self.stop_expr)
else:
# This is a hack as the name is not a valid DataSymbol, it
# is a call to a type-bound function.
self.stop_expr = Reference(
DataSymbol(self.field_name+"%get_ncell()", INTEGER_TYPE),
parent=self)
Loop.gen_code(self, parent)
node must be an assignment. The rightmost range node in each array
within the assignment is replaced with a loop index and the
assignment is placed within a loop iterating over that
index. The bounds of the loop are determined from the bounds
of the array range on the left hand side of the assignment.
:param node: an Assignment node.
:type node: :py:class:`psyclone.psyir.nodes.Assignment`
'''
self.validate(node)
parent = node.parent
symbol_table = node.scope.symbol_table
loop_variable_name = symbol_table.new_symbol_name(root_name="idx")
loop_variable_symbol = DataSymbol(loop_variable_name, INTEGER_TYPE)
symbol_table.add(loop_variable_symbol)
# Replace the rightmost range found in all arrays with the
# iterator and use the range from the LHS range for the loop
# iteration space.
for array in node.walk(Array):
for idx, child in reversed(list(enumerate(array.children))):
if isinstance(child, Range):
if array is node.lhs:
# Save this range to determine indexing
lhs_range = child
array.children[idx] = Reference(
loop_variable_symbol, parent=array)
break
position = node.position
# Issue #806: If Loop bounds were a Range we would just