[phc-internals] [phc commit] r1252 - trunk/src/hir_to_mir
codesite-noreply at google.com
codesite-noreply at google.com
Sat May 24 12:33:12 IST 2008
Author: paul.biggar
Date: Sat May 24 04:32:15 2008
New Revision: 1252
Modified:
trunk/src/hir_to_mir/Lower_control_flow.cpp
Log:
Slightly simplify the foreach lowering by putting in the gotos
explicitly, instead of using a loop, and then lowering the loop.
Modified: trunk/src/hir_to_mir/Lower_control_flow.cpp
==============================================================================
--- trunk/src/hir_to_mir/Lower_control_flow.cpp (original)
+++ trunk/src/hir_to_mir/Lower_control_flow.cpp Sat May 24 04:32:15 2008
@@ -146,9 +146,8 @@
* ...;
* }
* into
- * foreach_reset ($arr, iter);
- * loop()
- * {
+ * foreach_reset ($arr, iter);
+ * L0:
* $T = foreach_has_key ($arr, iter);
* if ($T) goto L1; else goto L2;
* L1:
@@ -156,9 +155,9 @@
* $val = foreach_get_val ($arr, iter); // optional
* ....
* foreach_next ($arr, iter);
- * }
+ * goto L0:
* L2:
- * foreach_end ($arr, iter);
+ * foreach_end ($arr, iter);
*/
void Lower_control_flow::lower_foreach (Foreach* in, List<Statement*>* out)
@@ -170,13 +169,14 @@
out->push_back (new Foreach_reset (array_name->clone (), iter));
- // loop ()
- Loop* loop = new Loop (new List<Statement*>);
+ // L0:
+ Label* l0 = fresh_label ();
+ out->push_back (new Label (l0->label_name));
// $T = foreach_has_key ($arr, iter);
VARIABLE_NAME* has_key = fresh_var_name ("THK");
- loop->statements->push_back (
+ out->push_back (
new Eval_expr (
new Assignment (
new Variable (has_key),
@@ -189,11 +189,11 @@
// if ($T) goto L1; else goto L2;
Label* l1 = fresh_label ();
Label* l2 = fresh_label ();
- loop->statements->push_back (new Branch (has_key->clone (),
l1->label_name->clone (), l2->label_name->clone ()));
+ out->push_back (new Branch (has_key->clone (), l1->label_name->clone
(), l2->label_name->clone ()));
// L1:
- loop->statements->push_back (l1);
+ out->push_back (l1);
// $key = foreach_get_key ($arr, iter);
@@ -210,7 +210,7 @@
assert (key->is_simple_variable ());
- loop->statements->push_back (new Eval_expr (
+ out->push_back (new Eval_expr (
new Assignment (
key,
false,
@@ -218,7 +218,7 @@
// $val = foreach_get_val ($arr, $get_key, iter);
- loop->statements->push_back (new Eval_expr (
+ out->push_back (new Eval_expr (
new Assignment (
in->val->clone (),
in->is_ref,
@@ -229,16 +229,17 @@
// ....
- loop->statements->push_back_all (in->statements);
+ out->push_back_all (in->statements);
// foreach_next ($arr, iter);
- loop->statements->push_back (
+ out->push_back (
new Foreach_next (
array_name->clone (),
iter->clone ()));
- lower_loop(loop, out);
+ // goto L0:
+ out->push_back (new Goto (l0->label_name->clone ()));
// L2:
@@ -254,252 +255,6 @@
// wrap it in a PHP script to call visit
(new PHP_script (out))->visit (new Clone_blank_mixins<Node, Visitor>
(in, new List<Node*>)); // TODO we should have nodes here
}
-
-/* Convert
- * foreach ($array as $key => $value)
- * {
- * ...;
- * }
- * into
- * if ($array->refcount)
- * $temp_array = $array; // copy by val
- * else
- * $temp_array =& $array; // copy by ref
- *
- * // (if array is an expression, use former form)
- *
- * unset ($value);
- * while (list ($Tkey, ) = each ($temp_array))
- * {
- * $key =& $Tkey;
- * $value = $temp_array [$Tkey]; // use =& form for an array reference
- * ...
- * }
- *
- * This saves from messing about with locks, and such, which I
- * believe are just refcounts anyway.
- */
-
-#if 0
-void Lower_control_flow::lower_foreach (Foreach* in, List<Statement*>* out)
-{
- Variable* temp_array = fresh_var ("LCF_ARRAY_");
-
- // we need a temporary even if the key is provided
- Variable* Tkey = fresh_var ("LCF_KEY_");
-
- // If the expression is a varaible then we may want to use a
- // reference. Otherwise, we just use a copy.
- // $temp_array =& $array
-// bool array_ref = (dynamic_cast<Variable*>(in->expr) != NULL);
- Eval_expr* array_copy = new Eval_expr (
- new Assignment (temp_array, in->is_ref, in->expr));
-
- Eval_expr* reset = NULL;
- if (in->is_ref)
- {
- // reset ($temp_array);
- reset = new Eval_expr (
- new Method_invocation (
- NULL,
- new METHOD_NAME (new String ("reset")),
- new List<Actual_parameter*> (
- new Actual_parameter (false, temp_array->clone ())
- )
- )
- );
- }
-
- // unset ($value);
-/* List<Actual_parameter*> *unset_params = new List<Actual_parameter*> ();
- unset_params->push_back (new Actual_parameter (false, in->val));
- Eval_expr* unset = new Eval_expr (
- new Method_invocation (NULL,
- new METHOD_NAME (new String ("unset")),
- unset_params)
- );
-*/
-
- // list ($Tkey, ) = each ($temp_array);
- List_assignment *assign = new List_assignment (
- new List<List_element*> (Tkey),
- new Method_invocation (
- NULL,
- new METHOD_NAME (new String ("each")),
- new List<Actual_parameter*> (
- new Actual_parameter (false, temp_array->clone ())
- )
- )
- );
-
- // $key &= $Tkey;
- if (in->key)
- in->statements->push_front (
- new Eval_expr (
- new Assignment (
- in->key,
- false,
- Tkey->clone ())));
-
-
- // $value = $temp_array [$Tkey]
- // or
- // $value =& $temp_array [$Tkey]
- in->statements->push_front (
- new Eval_expr (
- new Assignment (
- in->val,
- in->is_ref,
- new Variable (
- NULL,
- temp_array->variable_name->clone (),
- new List<Expr*> (Tkey->clone ())))
- )
- );
-
- // while (list ($key, ) = each ($temp_array))
- Loop* while_stmt = new Loop (assign, in->statements);
-
- // A continue in a for loop lands just before the increment
- add_label<Continue> (in, while_stmt->statements);
-
- // push it all back
- out->push_back (array_copy);
- if (reset) out->push_back (reset);
-// out->push_back (unset);
- lower_loop (while_stmt, out);
-}
-
-void Lower_control_flow::lower_foreach (Foreach* in, List<Statement*>* out)
-{
- // use the same lock variable throughout the program
- static Variable* locks = fresh_var ("LCF_LOCK_");
-
- Variable* temp_array = fresh_var ("LCF_ARRAY_");
-
- // if no key is provided, use a temporary
- Variable* Tkey;
- if (in->key) Tkey = in->key;
- else Tkey = fresh_var ("LCF_KEY_");
-
- // If the expression is a varaible then we may want to use a
- // reference. Otherwise, we just use a copy.
- bool array_ref = (dynamic_cast<Variable*>(in->expr) != NULL);
- Eval_expr* copy = new Eval_expr (
- new Assignment (temp_array, array_ref, in->expr));
-
- List <Statement*>* lock_check = new List<Statement*> ();
- Variable* lock_created;
- // if ($locks[$x]) {
- if (array_ref)
- {
-
- lock_created = fresh_var ("LCF_LOCK_CREATED_");
-
- // $tmp = $x;
- List<Statement*>* by_copy = new List<Statement*> ();
- by_copy->push_back (new Eval_expr (
- new Assignment (temp_array->clone (), true, in->expr)));
- // lock_created = false;
- by_copy->push_back (new Eval_expr (
- new Assignment (lock_created->clone (), false, new BOOL (false))));
-
-
- // else
- // {
- // $tmp =& $x;
- List<Statement*>* by_ref = new List<Statement*> ();
- by_ref->push_back (new Eval_expr (
- new Assignment (temp_array->clone (), false, in->expr)));
- // lock_created = true;
- by_ref->push_back (new Eval_expr (
- new Assignment (lock_created->clone (), false, new BOOL (false))));
-
- // $locks[$x] = true;
- // }
- by_ref->push_back (new Eval_expr (
- new Assignment (get_lock_access (in->expr), true, in->expr)));
-
- // Finally create the if
- lock_check->push_back (new If (get_lock_access (in->expr), by_ref, by_copy));
-
- }
-
- // reset ($temp_array);
-/* List<Actual_parameter*> *reset_params
- = new List<Actual_parameter*> ();
- reset_params->push_back (new Actual_parameter (false, temp_array));
- Eval_expr* reset = new Eval_expr (
- new Method_invocation (NULL,
- new METHOD_NAME (new String ("reset")),
- reset_params)
- );
-*/
- // unset ($value);
-/* List<Actual_parameter*> *unset_params = new List<Actual_parameter*> ();
- unset_params->push_back (new Actual_parameter (false, in->val));
- Eval_expr* unset = new Eval_expr (
- new Method_invocation (NULL,
- new METHOD_NAME (new String ("unset")),
- unset_params)
- );
-*/
-
- // each ($temp_array)
- List<Actual_parameter*> *each_params
- = new List<Actual_parameter*> ();
- each_params->push_back (new Actual_parameter (false, temp_array));
- Method_invocation *each = new Method_invocation (NULL,
- new METHOD_NAME (new String ("each")),
- each_params);
-
- // list ($key, ) = each ($temp_array);
- List<List_element*> *lhss = new List< List_element*> ();
- lhss->push_back (Tkey);
- List_assignment *assign = new List_assignment (lhss, each);
-
- // $value = $temp_array [$Tkey]
- // or
- // $value =& $temp_array [$Tkey]
- List<Expr*> *indices = new List<Expr*> ();
- indices->push_back (Tkey);
- Variable *val = new Variable (NULL, temp_array->variable_name, indices);
- Assignment *fetch_val = new Assignment (in->val, in->is_ref, val);
- in->statements->push_front (new Eval_expr (fetch_val));
-
- // while (list ($key, ) = each ($temp_array))
- Loop* while_stmt = new Loop (assign, in->statements);
-
- // A continue in a for loop lands just before the increment
- add_label<Continue> (in, while_stmt->statements);
-
- // reset the lock
- Statement* lock_unset;
- if (array_ref)
- {
- // if (lock_created);
- lock_unset = If (new Eval_expr (lock_created->clone ()));
-
-
- // unset ($lock [$asrray]);
- List<Actual_parameter*> *unset_params = new List<Actual_parameter*> ();
- unset_params->push_back (new Actual_parameter (false,
get_lock_access (in->expr)));
- lock_unset->iftrue->push_back (new Eval_expr (
- new Method_invocation (NULL,
- new METHOD_NAME (new String ("unset")),
- unset_params)
- ));
- }
-
-
- // push it all back
- out->push_back (copy);
- if (array_ref) lower_if (check_lock, out);
-// if (reset) out->push_back (reset);
- lower_loop (while_stmt, out);
- if (array_ref) out->push_back (lock_unset);
-}
-#endif
void Lower_control_flow::post_foreach(Foreach* in, List<Statement*>* out)
{
More information about the phc-internals
mailing list