Example #1
0
  def is_loop_invariant(self, node, loop_node):
    node_dependency_set = self.get_node_dependencies(node)
#     print "is loop invariant node:", node
#     for x in node_dependency_set:
#       print "  dep:", x
    # find dependencies within the loop node but outside the node we're checking
    node_dependency_set_except_node_tree = node_dependency_set - set(flatten_tree(node))
    dependencies_within_loop = set(flatten_tree(loop_node)).intersection(
      node_dependency_set_except_node_tree)
    depends_on_loop_variants = bool(loop_node.loop_variant_set.intersection(
      node_dependency_set))

	# TODO: Disabling warnings for now. They are useless witout
	# filenames. Also need to make sure all these cases are valid.

#     if not depends_on_loop_variants and dependencies_within_loop:
#       # we can't assume this is invariant because it depends on other
#       # nodes inside the loop. eventually we should hoist out both the
#       # node and its dependencies.
#       dependency_nodes = '\n'.join('  %s' % node.parent for node in dependencies_within_loop)
#       logging.warning("Cannot hoist possible loop invariant: %s.", node)
#       logging.warning("Please move following dependencies out of the loop:\n%s",
#         dependency_nodes)

    return not depends_on_loop_variants and not dependencies_within_loop
Example #2
0
  def get_node_dependencies(self, node):
    node_dependency_set = set(flatten_tree(node))
    parent_block = self.get_parent_block(node)

    for n in list(node_dependency_set):
      # when this is an identifier, you need to check all of the potential
      # the dependencies for that symbol, which means doing some crawling
      if isinstance(n, IdentifierNode):
        identifier = n
        parent_block_to_check = parent_block
        while parent_block_to_check:
          for block_node in parent_block_to_check.child_nodes:
            if isinstance(block_node, AssignNode):
              if block_node.left == identifier:
                node_dependency_set.update(
                  self.get_node_dependencies(block_node.right))
                parent_block_to_check = None
                break
            elif isinstance(block_node, IfNode):
              # if you encounter a conditional in your chain, you depend on any
              # dependencies of the condition itself
              # FIXME: calling get_node_dependencies(block_node.test_expression)
              # causes an infinite loop, but that is probably the correct way
              # forward to address the dependency chain
              node_dependency_set.update(
                flatten_tree(block_node.test_expression))
          else:
            parent_block_to_check = self.get_parent_block(
              parent_block_to_check)
      #elif isinstance(n, (GetUDNNode, FilterNode)):
      #  node_dependency_set.update(
      #    self.get_node_dependencies(node.expression))
    #print "get_node_dependencies", node
    #print "  deps:", node_dependency_set
    return node_dependency_set
Example #3
0
def _get_identifiers_from_expression(node):
  """Find the IdentifierNodes present in an expression.

  This function searches through the nodes of an expression and returns a set
  of the IdentiferNodes that are present. This function doesn't traverse
  ast.GetAttrNode or any LiteralNodes such as ListLiteral or DictLiteral nodes.
  """
  return set([n for n in walker.flatten_tree(node) if isinstance(n, ast.IdentifierNode)])