Skip to content

Commit

Permalink
Squashed commit of the sql branch
Browse files Browse the repository at this point in the history
  • Loading branch information
bdcht committed Sep 19, 2016
1 parent 4fedf42 commit c482432
Show file tree
Hide file tree
Showing 42 changed files with 2,289 additions and 2,120 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -2,7 +2,9 @@ tags
*.pyc
*.swp
build/
doc/_build
dist/
*.egg-info
tests/priv
tests/.cache
.tox/
1,299 changes: 23 additions & 1,276 deletions README.rst

Large diffs are not rendered by default.

269 changes: 162 additions & 107 deletions amoco/arch/core.py

Large diffs are not rendered by default.

13 changes: 10 additions & 3 deletions amoco/cas/expressions.py
Expand Up @@ -670,15 +670,15 @@ def stub(cls,ref):
return (lambda env,**kargs:None)

def call(self,env,**kargs):
logger.info('stub %s called'%self.ref)
logger.info('stub %s explicit call'%self.ref)
if not 'size' in kargs: kargs.update(size=self.size)
res = self.stub(self.ref)(env,**kargs)
if res is None: return top(self.size)
return res[0:self.size]

# used when the expression is a target used to build a block
def __call__(self,env):
logger.info('stub %s called'%self.ref)
logger.info('stub %s implicit call'%self.ref)
self.stub(self.ref)(env,**self._subrefs)
##

Expand Down Expand Up @@ -929,6 +929,10 @@ def eval(self,env):

def simplify(self):
self.a.simplify()
if self.a.base._is_vec:
seg,disp = self.a.seg,self.a.disp
v = vec([mem(a,self.size,seg,disp,mods=self.mods) for a in self.a.base.l])
return v if self.a.base._is_def else vecw(v)
return self

def addr(self,env):
Expand Down Expand Up @@ -1084,12 +1088,15 @@ def simplify(self):
if rst==0:
a = ptr(self.x.a.base,self.x.a.seg,self.x.a.disp+off)
return mem(a,self.size)
if self.x._is_eqn and self.x.op.type==2:
if self.x._is_eqn and (self.x.op.type==2 or
(self.x.op.symbol in '+-' and self.pos==0)):
r = self.x.r[self.pos:self.pos+self.size]
if self.x.op.unary:
return self.x.op(r)
l = self.x.l[self.pos:self.pos+self.size]
return self.x.op(l,r)
if self.x._is_vec:
return vec([x[self.pos:self.pos+self.size] for x in self.x.l])
else:
return self

Expand Down
20 changes: 11 additions & 9 deletions amoco/cas/mapper.py
Expand Up @@ -65,23 +65,24 @@ def pp(self,**kargs):
if t.colsize[1]>58: t.colsize[1]=58
return str(t)

def __getstate__(self):
return (self.__map,self.csi)
def __setstate__(self,state):
self.__map,self.csi = state
self.__Mem = MemoryMap()
for loc,v in self:
if loc._is_ptr: self._Mem_write(loc,v)

# list antecedent locations (used in the mapping)
def inputs(self):
return sum(map(locations_of,self.__map.itervalues()),[])
r = []
for l,v in self.__map.iteritems():
for lv in locations_of(v):
if lv._is_reg and l._is_reg:
if (lv == l) or (lv.type==l.type==regtype.FLAGS):
continue
r.append(lv)
return r

# list image locations (modified in the mapping)
def outputs(self):
L = []
for l in sum(map(locations_of,self.__map.iterkeys()),[]):
if l._is_reg and l.type in (regtype.PC,regtype.FLAGS): continue
if l._is_ptr: l = mem(l,self.__map[l].size)
if self.__map[l]==l: continue
L.append(l)
return L

Expand All @@ -103,6 +104,7 @@ def rw(self):
def clear(self):
self.__map.clear()
self.__Mem = MemoryMap()
self.conds = []

def memory(self):
return self.__Mem
Expand Down
198 changes: 177 additions & 21 deletions amoco/cfg.py
Expand Up @@ -4,7 +4,16 @@
# Copyright (C) 2006-2011 Axel Tillequin (bdcht3@gmail.com)
# published under GPLv2 license

# we wrap the grandalf classes here
"""
cfg.py
======
This module provides elements to define *control flow graphs* (CFG).
It is based essentially on classes provided by the `grandalf`_ package.
.. _grandalf: https://grandalf.readthedocs.io/
"""

from amoco.logger import Log
logger = Log(__name__)
Expand All @@ -14,16 +23,58 @@
from amoco.system.core import MemoryZone

#------------------------------------------------------------------------------
# node class is a graph vertex that embeds a block instance and inherits its
# name (default to the address of the block). It extends the Vertex class by
# overloading the __hash__ method in order to test membership based on the data
# rather than on the Vertex instance.
class node(Vertex):
# protect from None data node:
"""A node is a graph vertex that embeds a :mod:`code` object.
It extends the :ref:`Vertex <grandalf:Vertex>` class in order to compare
nodes by their data blocks rather than their id.
Args:
acode : an instance of :class:`block`, :class:`func` or :class:`xfunc`.
Attributes:
data : the reference to the ``acode`` argument above.
e (list[link]): inherited from `grandalf`_, the list of edges with this
node. In amoco, edges and vertices are called links and nodes.
c (graph_core): reference to the connected component that contains this
node.
Methods:
deg(): returns the *degree* of this node (number of its links).
N(dir=0): provides a list of *neighbor* nodes, all if *dir* parameter is 0,
parent nodes if *dir<0*, children nodes if *dir>0*.
e_dir(dir=0): provides a list of *links*, all if *dir* parameter is 0,
incoming links if *dir<0*, outgoing links if *dir>0*.
e_in(): a shortcut for ``e_dir(-1)``.
e_out(): a shortcut for ``e_dir(+1)``.
e_with(v): provides a *link* to or from v. Should be used with caution: if there is
several links between current node and v this method gives the first one
listed only, independently of the direction.
e_to(v): provides the *link* from current node to node v.
e_from(v): provides the *link* to current node from node v.
"""

def __init__(self,acode):
Vertex.__init__(self,data=acode)
self.name = self.data.name
self.view = self.data.view

@property
def name(self):
"""name (str): name property of the node's code object.
"""
return self.data.name

@property
def view(self):
"""view : view property of the node's code object.
"""
return self.data.view

def __repr__(self):
return '<%s [%s] at 0x%x>'%(self.__class__.__name__,self.name,id(self))
Expand All @@ -41,11 +92,43 @@ def __getitem__(self,i):
res = node(self.data.__getitem__(i))
return res

def __getstate__(self):
return (self.index,self.data)

def __setstate__(self,state):
self.__index,self.data = state
self.c = None
self.e = []

#------------------------------------------------------------------------------
# link is a direct graph edge between two nodes. It extends the Edge class by
# overloading the __hash__ method in order to test membership based on the data
# rather than on the Edge instance.
class link(Edge):
"""A directed edge between two nodes. It extends :ref:`Edge <grandalf:Edge>`
class in order to compare edges based on their data rather than id.
Args:
x (node) : the source node.
y (node) : the destination node.
w (int) : an optional weight value, default 1.
data : a list of conditional expressions associated with the link.
connect : a flag to indicate that a new node should be automatically
added to the connected component of its parent/child if it
is defined (default False).
Attributes:
name : the name property returns the string composed of source and
destination node's *addresses*.
deg (int): 1 if source and destination are the same node, 0 otherwise.
v (tuple[node]): inherited from `grandalf`_, the 2-tuple (source,dest)
nodes of the link.
feedback: a flag indicating that this link is involved in a loop,
used internally by `grandalf`_ layout algorithm.
Methods:
attach(): add current link to its :attr:`node.e` attribute list.
detach(): remove current link from its :attr:`node.e` attribute list.
"""

def __str__(self):
n0 = self.v[0].name
Expand All @@ -58,8 +141,8 @@ def __repr__(self):

@property
def name(self):
n0 = self.v[0].name
n1 = self.v[1].name
n0 = self.v[0].data.address
n1 = self.v[1].data.address
return "%s -> %s"%(n0,n1)

def __cmp__(self,e):
Expand All @@ -68,21 +151,86 @@ def __cmp__(self,e):
def __hash__(self):
return hash(self.name)

def __getstate__(self):
xi,yi = (self.v[0].index,self.v[1].index)
return (xi,yi,self.w,self.data,self.feedback)

def __setstate__(self,state):
xi,yi,self.w,self.data,self.feedback = state
self._v = [xi,yi]
self.deg = 0 if xi==yi else 1

#------------------------------------------------------------------------------
# graph is a Graph that represents a set of functions as individual components
class graph(Graph):
"""a :ref:`<grandalf:Graph>` that represents a set of functions as its
individual components.
Args:
V (iterable[node]) : the set of (possibly detached) nodes.
E (iterable[link]) : the set of links of this graph.
Attributes:
C : the list of :class:`graph_core <grandalf:graph_core>` connected
components of the graph.
support (:class:`~system.core.MemoryZone`): the abstract memory zone
holding all nodes contained in this graph.
overlay : defaults to None, another instance of MemoryZone
with nodes of the graph that overlap other nodes already mapped
in :attr:`support`.
Methods:
get_by_name(name): get the node with the given name (as string).
get_with_address(vaddr): get the node that contains the given *vaddr*
:class:`~cas.expressions.cst` expression.
signature(): returns the full signature string of all connected
components.
add_vertex(v,[support=None]): add node v to the graph and declare
node support in the default MemoryZone or the overlay zone if
provided as support argument. This method deals with a node v
that cuts or swallows a previously added node.
remove_vertex(v): remove node v from the graph.
add_edge(e): add link to the graph as well as possible new nodes.
remove_edge(e): remove the provided link.
get_vertices_count(): a synonym for :meth:`order`.
V(): generator of all nodes of the graph.
E(): generator of all links of the graph.
N(v,f_io=0): returns the neighbors of node v in direction f_io.
path(x,y,f_io=0,hook=None):
order(): number of nodes in the graph.
norm(): number of links in the graph.
deg_min(): minimum degree of nodes.
deg_max(): maximum degree of nodes.
deg_avg(): average degree of nodes.
eps(): ratio of links over nodes (norm/order).
connected(): boolean flag indicating that the graph as
only one connected component.
components(): synonym for attribute :attr:`C`.
"""
def __init__(self,*args,**kargs):
self.support = MemoryZone()
self.overlay = None
super(graph,self).__init__(*args,**kargs)

def spool(self,n=None):
L = []
for v in self.V():
if len(v.e_out())==0: L.append(v)
return L

def __cut_add_vertex(self,v,mz,vaddr,mo):
oldnode = mo.data.val
if oldnode==v: return oldnode
Expand Down Expand Up @@ -160,12 +308,20 @@ def get_with_address(self,vaddr):
def signature(self):
return ''.join([signature(g) for g in self.C])

#------------------------------------------------------------------------------

def signature(g):
"""compute the signature of a :ref:`graph_core <grandalf:graph_core>` component
based on :meth:`block.sig` value of nodes in every partion of the graph.
Returns:
str: the signature string.
"""
P = g.partition()
S = []
for p in P:
s = []
for n in p:
s.append(n.data.sig())
S.append(''.join(s))
return '{[%s]}'%']['.join(S)
return '{[%s]}'%'] ['.join(S)

0 comments on commit c482432

Please sign in to comment.