+/**
+ * (Re-)compute the type for a Proj(Cond).
+ *
+ * @param node the node
+ * @param cond the predecessor Cond node
+ */
+static void compute_Proj_Cond(node_t *node, ir_node *cond) {
+ ir_node *proj = node->node;
+ long pnc = get_Proj_proj(proj);
+ ir_node *sel = get_Cond_selector(cond);
+ node_t *selector = get_irn_node(sel);
+
+ if (get_irn_mode(sel) == mode_b) {
+ /* an IF */
+ if (pnc == pn_Cond_true) {
+ if (selector->type.tv == tarval_b_false) {
+ node->type.tv = tarval_U;
+ } else if (selector->type.tv == tarval_b_true) {
+ node->type.tv = tarval_R;
+ } else if (selector->type.tv == tarval_bottom) {
+ node->type.tv = tarval_R;
+ } else {
+ assert(selector->type.tv == tarval_top);
+ node->type.tv = tarval_U;
+ }
+ } else {
+ assert(pnc == pn_Cond_false);
+
+ if (selector->type.tv == tarval_b_false) {
+ node->type.tv = tarval_R;
+ } else if (selector->type.tv == tarval_b_true) {
+ node->type.tv = tarval_U;
+ } else if (selector->type.tv == tarval_bottom) {
+ node->type.tv = tarval_R;
+ } else {
+ assert(selector->type.tv == tarval_top);
+ node->type.tv = tarval_U;
+ }
+ }
+ } else {
+ /* an SWITCH */
+ if (selector->type.tv == tarval_bottom) {
+ node->type.tv = tarval_R;
+ } else if (selector->type.tv == tarval_top) {
+ node->type.tv = tarval_U;
+ } else {
+ long value = get_tarval_long(selector->type.tv);
+ if (pnc == get_Cond_defaultProj(cond)) {
+ /* default switch, have to check ALL other cases */
+ int i;
+
+ for (i = get_irn_n_outs(cond) - 1; i >= 0; --i) {
+ ir_node *succ = get_irn_out(cond, i);
+
+ if (succ == proj)
+ continue;
+ if (value == get_Proj_proj(succ)) {
+ /* we found a match, will NOT take the default case */
+ node->type.tv = tarval_U;
+ return;
+ }
+ }
+ /* all cases checked, no match, will take default case */
+ node->type.tv = tarval_R;
+ } else {
+ /* normal case */
+ node->type.tv = value == pnc ? tarval_R : tarval_U;
+ }
+ }
+ }
+} /* compute_Proj_Cond */
+