Hi,
Magnus Lie Hetland wrote:
> Should I upload a patch to the tracker?
Sure, that will allow us to take a look at it and compare it to the
while-loop alternative. Just use "hg export" to keep the meta data.
> it occurred to me that it might be
> cleaner to just ditch the for loop than to undo its semantics. It
> won't help on the extra check needed to see if we assign to the loop
> variable at all (i.e., what I'm doing here), but by using a while-loop
> with the proper test, we should be able to avoid the spurious
> increment and the "undo" operation. Worth a shot?
That's my impression, too. I attached an old (incomplete) patch I had lying
around, don't know if it's still any good. Generating a straight
WhileStatNode instead might already do the right thing (and be less
invasive, given that we are nearing a release). See the methods of the
IterationTransform class in Optimize.py for that.
> Or do C compilers
> somehow rely on the use of for loops for some kind of optimization
> inference or something?
No idea. But I doubt that a while loop would be slower than the equivalent
for loop. Plus, we need to fix the semantics here, which is more important
than the last bit of performance.
> there also seemed to be a problem when running
> with the refnanny.
Could you be a bit more specific here? :)
> the tests work without the refnanny (except for
> the NumPy stuff, which all fails because I haven't properly installed
> NumPy at the moment;
It should actually check for numpy being installed and just skip the test
if not. At least, that's what it does here.
Stefan
diff -r 9234404eed45 Cython/Compiler/Nodes.py
--- a/Cython/Compiler/Nodes.py Tue Dec 23 10:42:06 2008 +0100
+++ b/Cython/Compiler/Nodes.py Tue Dec 23 15:03:35 2008 +0100
@@ -3619,7 +3619,80 @@ class LoopNode:
self.else_clause.analyse_control_flow(env)
env.finish_branching(self.end_pos())
-
+
+class GeneralLoopNode(LoopNode, StatNode):
+ # for-in or while loop
+ #
+ # This node is created by transforms. It is like a while-loop
+ # with 0-n preparation statements and 0-m conditions. If no
+ # condition is provided, it should have at least one break
+ # statement in its body.
+ #
+ # preparations StatNode or None
+ # while_conditions [ExprNode]
+ # body StatNode
+ # else_clause StatNode or None
+ # is_for_loop boolean (for code beauty only)
+
+ is_for_loop = False
+ preparations = []
+ conditions = []
+ child_attrs = ["preparations", "conditions", "body", "else_clause"]
+
+ def analyse_declarations(self, env):
+ for preparation in self.preparations:
+ preparation.analyse_declarations(env)
+ self.body.analyse_declarations(env)
+ if self.else_clause:
+ self.else_clause.analyse_declarations(env)
+
+ def analyse_expressions(self, env):
+ for preparation in self.preparations:
+ preparation.analyse_expressions(env)
+ conditions = []
+ for condition in self.while_conditions:
+ condition = condition.analyse_temp_boolean_expression(env)
+ condition.release_temp(env)
+ conditions.append(condition)
+ self.while_conditions = conditions
+ self.body.analyse_expressions(env)
+ if self.else_clause:
+ self.else_clause.analyse_expressions(env)
+
+ def generate_execution_code(self, code):
+ old_loop_labels = code.new_loop_labels()
+ for preparation in self.preparations:
+ preparation.generate_execution_code(code)
+ if self.is_for_loop:
+ code.putln("for (;;) {")
+ else:
+ code.putln("while (1) {")
+ for condition in self.while_conditions:
+ condition.generate_evaluation_code(code)
+ condition.generate_disposal_code(code)
+ code.putln(
+ "if (!%s) break;" %
+ condition.result())
+ condition.free_temps(code)
+ self.body.generate_execution_code(code)
+ code.put_label(code.continue_label)
+ code.putln("}")
+ break_label = code.break_label
+ code.set_loop_labels(old_loop_labels)
+ if self.else_clause:
+ code.putln("/*else*/ {")
+ self.else_clause.generate_execution_code(code)
+ code.putln("}")
+ code.put_label(break_label)
+
+ def annotate(self, code):
+ for condition in self.while_conditions:
+ condition.annotate(code)
+ self.body.annotate(code)
+ if self.else_clause:
+ self.else_clause.annotate(code)
+
+
class WhileStatNode(LoopNode, StatNode):
# while statement
#
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev