Extended semantics of Cond node. There are two flavors now.
[libfirm] / ir / ir / irnode.c
index 701de9e..c414299 100644 (file)
@@ -146,7 +146,7 @@ ir_node_print (XP_PAR1, const xprintf_info *info ATTRIBUTE((unused)), XP_PARN)
     XPF1 ("%I", get_irn_mode(np)->name);
     XPC  (" ");
     XP   (symconst_name_arr[get_irn_symconst_attr(np).num]);
-    XPF1 (" %#N", get_class_ident((type_class *)get_SymConst_type(np)));
+    XPF1 (" %#N", get_type_nameid(get_SymConst_type(np)));
     break;
   case iro_Start:              /* don't dump mode of these */
   case iro_Cond:
@@ -163,7 +163,6 @@ ir_node_print (XP_PAR1, const xprintf_info *info ATTRIBUTE((unused)), XP_PARN)
   return printed;
 }
 
-
 /** getting some parameters from ir_nodes **/
 
 /* returns the number of predecessors without the block predecessor. */
@@ -335,7 +334,7 @@ get_irn_symconst_attr (ir_node *node)
   return node->attr.i;
 }
 
-inline type_method *
+inline type *
 get_irn_call_attr (ir_node *node)
 {
   assert (node->op == op_Call);
@@ -449,7 +448,37 @@ set_Block_graph_arr (ir_node *node, int pos, ir_node *value) {
   assert (node->op == op_Block);
   node->attr.block.graph_arr[pos+1] = value;
 }
-
+/*
+> Implementing the case construct (which is where the constant Proj node is
+> important) involves far more than simply determining the constant values.
+> We could argue that this is more properly a function of the translator from
+> Firm to the target machine.  That could be done if there was some way of
+> projecting "default" out of the Cond node.
+I know it's complicated.
+Basically there are two proglems:
+ - determining the gaps between the projs
+ - determining the biggest case constant to konw the proj number for
+   the default node.
+I see several solutions:
+1. Introduce a ProjDefault node.  Solves both problems.
+   This means to extend all optimizations executed during construction.
+2. Give the Cond node for switch two flavors:
+   a) there are no gaps in the projs  (existing flavor)
+   b) gaps may exist, default proj is still the Proj with the largest
+      projection number.  This covers also the gaps.
+3. Fix the semantic of the Cond to that of 2b)
+
+Solution 2 seems to be the best:
+Computing the gaps in the Firm representation is not too hard, i.e.,
+libfirm can implement a routine that transforms betweeen the two
+flavours.  This is also possible for 1) but 2) does not require to
+change any existing optimization.
+Further it should be far simpler to determine the biggest constant than
+to compute all gaps.
+I don't want to choose 3) as 2a) seems to have advantages for
+dataflow analysis and 3) does not allow to convert the representation to
+2a).
+*/
 inline ir_node *
 get_Cond_selector (ir_node *node) {
   assert (node->op == op_Cond);
@@ -462,6 +491,18 @@ set_Cond_selector (ir_node *node, ir_node *selector) {
   set_irn_n(node, 0, selector);
 }
 
+inline cond_kind
+get_Cond_kind (ir_node *node) {
+  assert (node->op == op_Cond);
+  return node->attr.c;
+}
+
+inline void
+set_Cond_kind (ir_node *node, cond_kind kind) {
+  assert (node->op == op_Cond);
+  node->attr.c = kind;
+}
+
 inline ir_node *
 get_Return_mem (ir_node *node) {
   assert (node->op == op_Return);
@@ -741,15 +782,16 @@ set_Call_param (ir_node *node, int pos, ir_node *param) {
   set_irn_n(node, pos + CALL_PARAM_OFFSET, param);
 }
 
-inline type_method *
+inline type *
 get_Call_type (ir_node *node) {
   assert (node->op == op_Call);
   return node->attr.call;
 }
 
 inline void
-set_Call_type (ir_node *node, type_method *type) {
+set_Call_type (ir_node *node, type *type) {
   assert (node->op == op_Call);
+  assert (is_method_type(type));
   node->attr.call = type;
 }