Fix cbuilder CDefinition specialization design and magic

This commit is contained in:
Mark Florisson 2012-10-29 14:16:13 +00:00
commit bd377de198

View file

@ -709,24 +709,6 @@ class CBuilder(object):
md = lc.MetaData.get(self.function.module, [const_one]) md = lc.MetaData.get(self.function.module, [const_one])
ldst.set_metadata('nontemporal', md) ldst.set_metadata('nontemporal', md)
class _DeclareCDef(object):
'''create a function a CDefinition to use with `CBuilder.depends`
An instance of this class is created by the constructor of CDefinition.
Do not use directly.
'''
def __init__(self, cdef):
self.cdef = cdef
def __str__(self):
return self.cdef._name_
def __call__(self, module):
try:
func = self.cdef.define(module)
except FunctionAlreadyExists as e:
(func,) = e
return func
class CFuncRef(object): class CFuncRef(object):
'''create a function reference to use with `CBuilder.depends` '''create a function reference to use with `CBuilder.depends`
@ -766,7 +748,8 @@ class CFuncRef(object):
def __str__(self): def __str__(self):
return self._name return self._name
class CDefinition(CBuilder):
class CDefinition(object):
'''represents function definition '''represents function definition
Inherit from this class to create a new function definition. Inherit from this class to create a new function definition.
@ -782,31 +765,33 @@ class CDefinition(CBuilder):
_retty_ = types.void # return type; can overide in subclass _retty_ = types.void # return type; can overide in subclass
_argtys_ = [] # a list of tuple(name, type, [attributes]); can overide in subclass _argtys_ = [] # a list of tuple(name, type, [attributes]); can overide in subclass
def __new__(cls, *args, **kws): def __init__(self, *args, **kwargs):
if cls.is_generic(): self.specialize(*args, **kwargs)
# Call specialize if it is defined. self.cbuilder = None
cls = type('%s_Specialized' % cls.__name__, (cls,), {})
cls.specialize(*args, **kws)
obj = object.__new__(_DeclareCDef) def specialize(self, *args, **kwargs):
obj.__init__(cls) """
return obj Override in subclasses
"""
@classmethod def specialize_name(self):
def is_generic(cls): """
'''Is this a generic definition? Specialize the class name to enable multiple function definitions
''' """
return hasattr(cls, 'specialize') cls = type(self)
@classmethod counter = getattr(cls, 'counter', 0)
def define(cls, module): cls._name_ = "%s_%d" % (cls._name_, counter)
cls.counter = counter + 1
def define(self, module):
'''define the function in the module. '''define the function in the module.
Raises NameError if a function of the same name has already been Raises NameError if a function of the same name has already been
defined. defined.
''' '''
functype = lc.Type.function(cls._retty_, [arg[1] for arg in cls._argtys_]) functype = lc.Type.function(self._retty_, [arg[1] for arg in self._argtys_])
name = cls._name_ name = self._name_
if not name: if not name:
raise AttributeError("Function name cannot be empty.") raise AttributeError("Function name cannot be empty.")
@ -816,17 +801,17 @@ class CDefinition(CBuilder):
raise FunctionAlreadyExists(func) raise FunctionAlreadyExists(func)
# Name all arguments # Name all arguments
for i, arginfo in enumerate(cls._argtys_): for i, arginfo in enumerate(self._argtys_):
name = arginfo[0] name = arginfo[0]
func.args[i].name = name func.args[i].name = name
if len(arginfo) > 2: if len(arginfo) > 2:
for attr in arginfo[2]: for attr in arginfo[2]:
func.args[i].add_attribute(attr) func.args[i].add_attribute(attr)
# Create builder and populate body # Create builder and populate body
cbuilder = object.__new__(cls) self.cbuilder = CBuilder(func)
cbuilder.__init__(func) self.body(*self.cbuilder.args)
cbuilder.body(*cbuilder.args) self.cbuilder.close()
cbuilder.close()
# optimize # optimize
fpm = lp.FunctionPassManager.new(module) fpm = lp.FunctionPassManager.new(module)
@ -837,11 +822,24 @@ class CDefinition(CBuilder):
fpm.run(func) fpm.run(func)
return func return func
def __call__(self, module):
# We don't really have to overload __call__ to do things like
# defining functions...
try:
func = self.define(module)
except FunctionAlreadyExists as e:
(func,) = e
return func
def __getattr__(self, attr):
return getattr(self.cbuilder, attr)
def body(self): def body(self):
'''overide this function to define the body. '''overide this function to define the body.
''' '''
raise NotImplementedError raise NotImplementedError
class CValue(object): class CValue(object):
def __init__(self, parent, handle): def __init__(self, parent, handle):
self.__parent = parent self.__parent = parent