Commit f51ac43e authored by Dag Sverre Seljebotn's avatar Dag Sverre Seljebotn

In the middle of a buffer refactor (nonworking; done indexing)

parent 8fd5165e
This diff is collapsed.
...@@ -893,6 +893,10 @@ class NameNode(AtomicExprNode): ...@@ -893,6 +893,10 @@ class NameNode(AtomicExprNode):
% self.name) % self.name)
self.type = PyrexTypes.error_type self.type = PyrexTypes.error_type
self.entry.used = 1 self.entry.used = 1
if self.entry.type.is_buffer:
# Need some temps
print self.dump()
def analyse_rvalue_entry(self, env): def analyse_rvalue_entry(self, env):
#print "NameNode.analyse_rvalue_entry:", self.name ### #print "NameNode.analyse_rvalue_entry:", self.name ###
...@@ -1311,6 +1315,9 @@ class IndexNode(ExprNode): ...@@ -1311,6 +1315,9 @@ class IndexNode(ExprNode):
self.analyse_base_and_index_types(env, setting = 1) self.analyse_base_and_index_types(env, setting = 1)
def analyse_base_and_index_types(self, env, getting = 0, setting = 0): def analyse_base_and_index_types(self, env, getting = 0, setting = 0):
# Note: This might be cleaned up by having IndexNode
# parsed in a saner way and only construct the tuple if
# needed.
self.is_buffer_access = False self.is_buffer_access = False
self.base.analyse_types(env) self.base.analyse_types(env)
...@@ -1318,6 +1325,7 @@ class IndexNode(ExprNode): ...@@ -1318,6 +1325,7 @@ class IndexNode(ExprNode):
skip_child_analysis = False skip_child_analysis = False
buffer_access = False buffer_access = False
if self.base.type.is_buffer: if self.base.type.is_buffer:
assert isinstance(self.base, NameNode)
if isinstance(self.index, TupleNode): if isinstance(self.index, TupleNode):
indices = self.index.args indices = self.index.args
else: else:
...@@ -1329,21 +1337,19 @@ class IndexNode(ExprNode): ...@@ -1329,21 +1337,19 @@ class IndexNode(ExprNode):
x.analyse_types(env) x.analyse_types(env)
if not x.type.is_int: if not x.type.is_int:
buffer_access = False buffer_access = False
if buffer_access:
# self.indices = [
# x.coerce_to(PyrexTypes.c_py_ssize_t_type, env).coerce_to_simple(env)
# for x in indices]
self.indices = indices
self.index = None
self.type = self.base.type.dtype
self.is_temp = 1
self.is_buffer_access = True
# Note: This might be cleaned up by having IndexNode
# parsed in a saner way and only construct the tuple if
# needed.
if not buffer_access: if buffer_access:
self.indices = indices
self.index = None
self.type = self.base.type.dtype
self.is_buffer_access = True
self.index_temps = [Symtab.new_temp(i.type) for i in indices]
self.temps = self.index_temps
if getting:
# we only need a temp because result_code isn't refactored to
# generation time, but this seems an ok shortcut to take
self.is_temp = True
else:
if isinstance(self.index, TupleNode): if isinstance(self.index, TupleNode):
self.index.analyse_types(env, skip_children=skip_child_analysis) self.index.analyse_types(env, skip_children=skip_child_analysis)
elif not skip_child_analysis: elif not skip_child_analysis:
...@@ -1388,7 +1394,7 @@ class IndexNode(ExprNode): ...@@ -1388,7 +1394,7 @@ class IndexNode(ExprNode):
def calculate_result_code(self): def calculate_result_code(self):
if self.is_buffer_access: if self.is_buffer_access:
return "<not needed>" return "<not used>"
else: else:
return "(%s[%s])" % ( return "(%s[%s])" % (
self.base.result_code, self.index.result_code) self.base.result_code, self.index.result_code)
...@@ -1407,7 +1413,8 @@ class IndexNode(ExprNode): ...@@ -1407,7 +1413,8 @@ class IndexNode(ExprNode):
if self.index is not None: if self.index is not None:
self.index.generate_evaluation_code(code) self.index.generate_evaluation_code(code)
else: else:
for i in self.indices: i.generate_evaluation_code(code) for i in self.indices:
i.generate_evaluation_code(code)
def generate_subexpr_disposal_code(self, code): def generate_subexpr_disposal_code(self, code):
self.base.generate_disposal_code(code) self.base.generate_disposal_code(code)
...@@ -1417,7 +1424,10 @@ class IndexNode(ExprNode): ...@@ -1417,7 +1424,10 @@ class IndexNode(ExprNode):
for i in self.indices: i.generate_disposal_code(code) for i in self.indices: i.generate_disposal_code(code)
def generate_result_code(self, code): def generate_result_code(self, code):
if self.type.is_pyobject: if self.is_buffer_access:
valuecode = self.buffer_access_code(code)
code.putln("%s = %s;" % (self.result_code, valuecode))
elif self.type.is_pyobject:
if self.index.type.is_int: if self.index.type.is_int:
function = "__Pyx_GetItemInt" function = "__Pyx_GetItemInt"
index_code = self.index.result_code index_code = self.index.result_code
...@@ -1453,7 +1463,10 @@ class IndexNode(ExprNode): ...@@ -1453,7 +1463,10 @@ class IndexNode(ExprNode):
def generate_assignment_code(self, rhs, code): def generate_assignment_code(self, rhs, code):
self.generate_subexpr_evaluation_code(code) self.generate_subexpr_evaluation_code(code)
if self.type.is_pyobject: if self.is_buffer_access:
valuecode = self.buffer_access_code(code)
code.putln("%s = %s;" % (valuecode, rhs.result_code))
elif self.type.is_pyobject:
self.generate_setitem_code(rhs.py_result(), code) self.generate_setitem_code(rhs.py_result(), code)
else: else:
code.putln( code.putln(
...@@ -1479,6 +1492,23 @@ class IndexNode(ExprNode): ...@@ -1479,6 +1492,23 @@ class IndexNode(ExprNode):
code.error_goto(self.pos))) code.error_goto(self.pos)))
self.generate_subexpr_disposal_code(code) self.generate_subexpr_disposal_code(code)
def buffer_access_code(self, code):
# 1. Assign indices to temps
for temp, index in zip(self.index_temps, self.indices):
code.putln("%s = %s;" % (temp.cname, index.result_code))
# 2. Output code to do bounds checking on these
# 3. Return a code fragment string which does buffer
# lookup, which can be used on lhs or rhs of an assignment
# in the caller depending on the scenario.
bufaux = self.base.entry.buffer_aux
offset = " + ".join(["%s * %s" % (idx.cname, stride.cname)
for idx, stride in
zip(self.index_temps, bufaux.stridevars)])
ptrcode = "(%s.buf + %s)" % (bufaux.buffer_info_var.cname, offset)
valuecode = "*%s" % self.base.type.buffer_ptr_type.cast_code(ptrcode)
return valuecode
class SliceIndexNode(ExprNode): class SliceIndexNode(ExprNode):
# 2-element slice indexing # 2-element slice indexing
......
...@@ -361,23 +361,25 @@ def create_default_pipeline(context, options, result): ...@@ -361,23 +361,25 @@ def create_default_pipeline(context, options, result):
from ParseTreeTransforms import CreateClosureClasses, MarkClosureVisitor, DecoratorTransform from ParseTreeTransforms import CreateClosureClasses, MarkClosureVisitor, DecoratorTransform
from Optimize import FlattenInListTransform, SwitchTransform, OptimizeRefcounting from Optimize import FlattenInListTransform, SwitchTransform, OptimizeRefcounting
from CodeGeneration import AnchorTemps from CodeGeneration import AnchorTemps
from Buffer import BufferTransform from Buffer import BufferTransform, IntroduceBufferAuxiliaryVars
from ModuleNode import check_c_classes from ModuleNode import check_c_classes
def printit(x): print x.dump()
return [ return [
create_parse(context), create_parse(context),
# printit,
NormalizeTree(context), NormalizeTree(context),
PostParse(context), PostParse(context),
FlattenInListTransform(), FlattenInListTransform(),
WithTransform(context), WithTransform(context),
DecoratorTransform(context), DecoratorTransform(context),
AnalyseDeclarationsTransform(context), AnalyseDeclarationsTransform(context),
IntroduceBufferAuxiliaryVars(context),
check_c_classes, check_c_classes,
AnalyseExpressionsTransform(context), AnalyseExpressionsTransform(context),
BufferTransform(context), # BufferTransform(context),
SwitchTransform(), SwitchTransform(),
OptimizeRefcounting(context), OptimizeRefcounting(context),
# AnchorTemps(context), AnchorTemps(context),
# CreateClosureClasses(context), # CreateClosureClasses(context),
create_generate_code(context, options, result) create_generate_code(context, options, result)
] ]
......
...@@ -203,6 +203,7 @@ class BufferType(BaseType): ...@@ -203,6 +203,7 @@ class BufferType(BaseType):
self.base = base self.base = base
self.dtype = dtype self.dtype = dtype
self.ndim = ndim self.ndim = ndim
self.buffer_ptr_type = CPtrType(dtype)
def as_argument_type(self): def as_argument_type(self):
return self return self
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment