gint node_remove_wire (Node *node, Wire *wire) { gboolean dot; g_return_val_if_fail (node != NULL, FALSE); g_return_val_if_fail (IS_NODE (node), FALSE); g_return_val_if_fail (wire != NULL, FALSE); g_return_val_if_fail (IS_WIRE (wire), FALSE); if (node->wire_count == 0) return FALSE; if (!g_slist_find (node->wires, wire)) { NG_DEBUG ("node_remove_wire: not there.\n"); return FALSE; } dot = node_needs_dot (node); node->wires = g_slist_remove (node->wires, wire); node->wire_count--; if (dot && (!node_needs_dot (node))) g_signal_emit_by_name (G_OBJECT (node), "node_dot_removed", &node->key); return TRUE; }
nodeid fs_ptree_new_node(fs_ptree *pt) { if (pt->header->node_free != FS_PTREE_NULL_NODE) { nodeid n = pt->header->node_free; if (!IS_NODE(n)) { fs_error(LOG_ERR, "got free'd node (%08x) that is actually a leaf", n); } else { node *nr = NODE_REF(pt, n); pt->header->node_free = nr->branch[0]; for (int i=0; i<FS_PTREE_BRANCHES; i++) { nr->branch[i] = FS_PTREE_NULL_NODE; } return n; } } if (pt->header->node_base == pt->header->node_size) { fs_ptree_grow_nodes(pt); } nodeid n = pt->header->node_base | 0x80000000; pt->header->node_base++; pt->header->node_count++; node *nn = NODE_REF(pt, n); for (int i=0; i<FS_PTREE_BRANCHES; i++) { nn->branch[i] = FS_PTREE_NULL_NODE; } return n; }
gint node_add_wire (Node *node, Wire *wire) { gboolean dot; g_return_val_if_fail (node != NULL, FALSE); g_return_val_if_fail (IS_NODE (node), FALSE); g_return_val_if_fail (wire != NULL, FALSE); g_return_val_if_fail (IS_WIRE (wire), FALSE); if (g_slist_find (node->wires, wire)) { NG_DEBUG ("node_add_wire: wire already there.\n"); return FALSE; } dot = node_needs_dot (node); node->wires = g_slist_prepend (node->wires, wire); node->wire_count++; if (!dot && node_needs_dot (node)) g_signal_emit_by_name (G_OBJECT (node), "node_dot_added", &node->key); return TRUE; }
FeriteAMTTree *ferite_amt_compressed_dup( FeriteScript *script, FeriteAMTTree *tree, void*(*dup)(FeriteScript*,void*,void*), void *extra ) { FeriteAMTTree *newTree = fmalloc(sizeof(FeriteAMTTree)); memset(newTree, 0, sizeof(FeriteAMTTree)); newTree->map = tree->map; newTree->index_type = tree->index_type; newTree->base_size = tree->base_size; newTree->base = ferite_amt_create_base( script, newTree->base_size ); if( newTree->map ) { int i = 0; FeriteAMTNode *node = NULL; for( i = 0; i < newTree->base_size; i++ ) { if( (node = tree->base[i]) != NULL ) { newTree->base[i] = fmalloc(sizeof(FeriteAMTNode)); memset(newTree->base[i], 0, sizeof(FeriteAMTNode)); newTree->base[i]->type = node->type; if( IS_NODE(node) ) { newTree->base[i]->u.value.id = node->u.value.id; newTree->base[i]->u.value.data = (dup ? (dup)( script, node->u.value.data, extra ) : node->u.value.data); newTree->base[i]->u.value.key = NULL; if( node->u.value.key ) { newTree->base[i]->u.value.key = fstrdup(node->u.value.key); } } else if( node->type == FeriteAMTType_Tree ) { newTree->base[i]->u.tree = __ferite_amt_tree_dup( script, node->u.tree, dup, extra ); } } } } return newTree; }
void node_set_visited (Node *node, gboolean is_visited) { g_return_if_fail (node != NULL); g_return_if_fail (IS_NODE (node)); node->visited = is_visited; }
gint node_is_visited (Node *node) { g_return_val_if_fail (node != NULL, FALSE); g_return_val_if_fail (IS_NODE (node), FALSE); return node->visited; }
int reset_pnodes(int curr, int pnode) { struct msm_bus_inode_info *info; struct msm_bus_fabric_device *fabdev; int index, next_pnode; fabdev = msm_bus_get_fabric_device(GET_FABID(curr)); if (!fabdev) { MSM_BUS_ERR("Fabric not found for: %d\n", (GET_FABID(curr))); return -ENXIO; } index = GET_INDEX(pnode); info = fabdev->algo->find_node(fabdev, curr); if (!info) { MSM_BUS_ERR("Cannot find node info!\n"); return -ENXIO; } MSM_BUS_DBG("Starting the loop--remove\n"); do { struct msm_bus_inode_info *hop; fabdev = msm_bus_get_fabric_device(GET_FABID(curr)); if (!fabdev) { MSM_BUS_ERR("Fabric not found\n"); return -ENXIO; } next_pnode = info->pnode[index].next; info->pnode[index].next = -2; curr = GET_NODE(next_pnode); index = GET_INDEX(next_pnode); if (IS_NODE(curr)) hop = fabdev->algo->find_node(fabdev, curr); else hop = fabdev->algo->find_gw_node(fabdev, curr); if (!hop) { MSM_BUS_ERR("Null Info found for hop\n"); return -ENXIO; } MSM_BUS_DBG("%d[%d] = %d\n", info->node_info->priv_id, index, info->pnode[index].next); MSM_BUS_DBG("num_pnodes: %d: %d\n", info->node_info->priv_id, info->num_pnodes); info = hop; } while (GET_NODE(info->pnode[index].next) != info->node_info->priv_id); info->pnode[index].next = -2; MSM_BUS_DBG("%d[%d] = %d\n", info->node_info->priv_id, index, info->pnode[index].next); MSM_BUS_DBG("num_pnodes: %d: %d\n", info->node_info->priv_id, info->num_pnodes); return 0; }
gint node_is_empty (Node *node) { g_return_val_if_fail (node != NULL, FALSE); g_return_val_if_fail (IS_NODE (node), FALSE); if ((node->wire_count == 0) && (node->pin_count == 0)) return TRUE; return FALSE; }
void fs_ptree_free_leaf(fs_ptree *pt, nodeid n) { if (IS_NODE(n)) { fs_error(LOG_ERR, "tried to free node as leaf"); return; } leaf *lr = LEAF_REF(pt, n); lr->block = pt->header->leaf_free; pt->header->leaf_free = n; }
void* cgfunc_store_nodes(callsite_t *site, int level, int flags, void *ptr) { if( flags==VISIT_BACKTRACK ) return ptr; if( IS_NODE(site) ) { (*((void**)ptr))=site; return ((char*)ptr)+sizeof(void*); } return ptr; }
parse_node_t *optimize_loop_test P1(parse_node_t *, pn) { parse_node_t *ret; if (IS_NODE(pn, NODE_BINARY_OP, F_LT) && IS_NODE(pn->l.expr, NODE_OPCODE_1, F_LOCAL)) { if (IS_NODE(pn->r.expr, NODE_OPCODE_1, F_LOCAL)) { CREATE_OPCODE_2(ret, F_LOOP_COND_LOCAL, 0, pn->l.expr->l.number, pn->r.expr->l.number); } else if (pn->r.expr->kind == NODE_NUMBER) { CREATE_OPCODE_2(ret, F_LOOP_COND_NUMBER, 0, pn->l.expr->l.number, pn->r.expr->v.number); } else ret = pn; } else if (IS_NODE(pn, NODE_UNARY_OP, F_POST_DEC) && IS_NODE(pn->r.expr, NODE_OPCODE_1, F_LOCAL_LVALUE)) { int lvar = pn->r.expr->l.number; CREATE_OPCODE_1(ret, F_WHILE_DEC, 0, lvar); } else ret = pn; return ret; }
static void node_traverse (Node *node) { GSList *iter; g_return_if_fail (node != NULL); g_return_if_fail (IS_NODE (node)); if (node_is_visited (node)) return; node_set_visited (node, TRUE); for (iter = node->wires; iter; iter = iter->next) { Wire *wire = iter->data; wire_traverse (wire); } }
gint wire_add_node (Wire *wire, Node *node) { WirePriv *priv; g_return_val_if_fail (wire != NULL, FALSE); g_return_val_if_fail (IS_WIRE (wire), FALSE); g_return_val_if_fail (node != NULL, FALSE); g_return_val_if_fail (IS_NODE (node), FALSE); priv = wire->priv; if (g_slist_find (priv->nodes, node)) { return FALSE; } priv->nodes = g_slist_prepend (priv->nodes, node); return TRUE; }
static void node_traverse (Node *node) { GSList *wires; g_return_if_fail (node != NULL); g_return_if_fail (IS_NODE (node)); if (node_is_visited (node)) return; node_set_visited (node, TRUE); for (wires = node->wires; wires; wires = wires->next) { Wire *wire = wires->data; wire_traverse (wire); } g_slist_free_full (wires, g_object_unref); }
void Lanes::afterMerge() { if (boundary) return; // will be reset by changeActiveLane() for (unsigned int i = 0; i < typeVec.size(); ++i) { int& t = typeVec[i]; if (isHead(t) || isJoin(t) || t == CROSS) t = NOT_ACTIVE; else if (t == CROSS_EMPTY) t = EMPTY; else if (IS_NODE(t)) t = ACTIVE; } }
void Lanes::afterFork() { for (unsigned int i = 0; i < typeVec.size(); ++i) { int& t = typeVec[i]; if (t == CROSS) t = NOT_ACTIVE; else if (isTail(t) || t == CROSS_EMPTY) t = EMPTY; if (!boundary && IS_NODE(t)) t = ACTIVE; // boundary will be reset by changeActiveLane() } while (typeVec.back() == EMPTY) { typeVec.pop_back(); nextShaVec.pop_back(); } }
gint node_remove_pin (Node *node, Pin *pin) { gboolean dot; g_return_val_if_fail (node != NULL, FALSE); g_return_val_if_fail (IS_NODE (node), FALSE); g_return_val_if_fail (pin != NULL, FALSE); if (node->pin_count == 0) return FALSE; dot = node_needs_dot (node); node->pins = g_slist_remove (node->pins, pin); node->pin_count--; if (dot && !node_needs_dot (node)) g_signal_emit_by_name (G_OBJECT (node), "node_dot_removed", &node->key); return TRUE; }
gint node_add_pin (Node *node, Pin *pin) { gboolean dot; g_return_val_if_fail (node != NULL, FALSE); g_return_val_if_fail (IS_NODE (node), FALSE); g_return_val_if_fail (pin != NULL, FALSE); if (g_slist_find (node->pins, pin)) { NG_DEBUG ("node_add_pin: pin already there.\n"); return FALSE; } dot = node_needs_dot (node); node->pins = g_slist_prepend (node->pins, pin); node->pin_count++; if (!dot && node_needs_dot (node)) g_signal_emit_by_name (G_OBJECT (node), "node_dot_added", &node->key); return TRUE; }
/** * update_path() - Update the path with the bandwidth and clock values, as * requested by the client. * * @curr: Current source node, as specified in the client vector (master) * @pnode: The first-hop node on the path, stored in the internal client struct * @req_clk: Requested clock value from the vector * @req_bw: Requested bandwidth value from the vector * @curr_clk: Current clock frequency * @curr_bw: Currently allocated bandwidth * * This function updates the nodes on the path calculated using getpath(), with * clock and bandwidth values. The sum of bandwidths, and the max of clock * frequencies is calculated at each node on the path. Commit data to be sent * to RPM for each master and slave is also calculated here. */ static int update_path(int curr, int pnode, unsigned long req_clk, unsigned long req_bw, unsigned long curr_clk, unsigned long curr_bw, unsigned int ctx, unsigned int cl_active_flag) { int index, ret = 0; struct msm_bus_inode_info *info; int next_pnode; long int add_bw = req_bw - curr_bw; unsigned bwsum = 0; unsigned req_clk_hz, curr_clk_hz, bwsum_hz; int *master_tiers; struct msm_bus_fabric_device *fabdev = msm_bus_get_fabric_device (GET_FABID(curr)); MSM_BUS_DBG("args: %d %d %d %lu %lu %lu %lu %u\n", curr, GET_NODE(pnode), GET_INDEX(pnode), req_clk, req_bw, curr_clk, curr_bw, ctx); index = GET_INDEX(pnode); MSM_BUS_DBG("Client passed index :%d\n", index); info = fabdev->algo->find_node(fabdev, curr); if (!info) { MSM_BUS_ERR("Cannot find node info!\n"); return -ENXIO; } info->link_info.sel_bw = &info->link_info.bw[ctx]; info->link_info.sel_clk = &info->link_info.clk[ctx]; *info->link_info.sel_bw += add_bw; info->pnode[index].sel_bw = &info->pnode[index].bw[ctx]; /** * To select the right clock, AND the context with * client active flag. */ info->pnode[index].sel_clk = &info->pnode[index].clk[ctx & cl_active_flag]; *info->pnode[index].sel_bw += add_bw; info->link_info.num_tiers = info->node_info->num_tiers; info->link_info.tier = info->node_info->tier; master_tiers = info->node_info->tier; do { struct msm_bus_inode_info *hop; fabdev = msm_bus_get_fabric_device(GET_FABID(curr)); if (!fabdev) { MSM_BUS_ERR("Fabric not found\n"); return -ENXIO; } MSM_BUS_DBG("id: %d\n", info->node_info->priv_id); /* find next node and index */ next_pnode = info->pnode[index].next; curr = GET_NODE(next_pnode); index = GET_INDEX(next_pnode); MSM_BUS_DBG("id:%d, next: %d\n", info-> node_info->priv_id, curr); /* Get hop */ /* check if we are here as gateway, or does the hop belong to * this fabric */ if (IS_NODE(curr)) hop = fabdev->algo->find_node(fabdev, curr); else hop = fabdev->algo->find_gw_node(fabdev, curr); if (!hop) { MSM_BUS_ERR("Null Info found for hop\n"); return -ENXIO; } hop->link_info.sel_bw = &hop->link_info.bw[ctx]; hop->link_info.sel_clk = &hop->link_info.clk[ctx]; *hop->link_info.sel_bw += add_bw; hop->pnode[index].sel_bw = &hop->pnode[index].bw[ctx]; hop->pnode[index].sel_clk = &hop->pnode[index].clk[ctx & cl_active_flag]; if (!hop->node_info->buswidth) { MSM_BUS_WARN("No bus width found. Using default\n"); hop->node_info->buswidth = 8; } *hop->pnode[index].sel_clk = BW_TO_CLK_FREQ_HZ(hop->node_info-> buswidth, req_clk); *hop->pnode[index].sel_bw += add_bw; MSM_BUS_DBG("fabric: %d slave: %d, slave-width: %d info: %d\n", fabdev->id, hop->node_info->priv_id, hop->node_info-> buswidth, info->node_info->priv_id); /* Update Bandwidth */ fabdev->algo->update_bw(fabdev, hop, info, add_bw, master_tiers, ctx); bwsum = (uint16_t)*hop->link_info.sel_bw; /* Update Fabric clocks */ curr_clk_hz = BW_TO_CLK_FREQ_HZ(hop->node_info->buswidth, curr_clk); req_clk_hz = BW_TO_CLK_FREQ_HZ(hop->node_info->buswidth, req_clk); bwsum_hz = BW_TO_CLK_FREQ_HZ(hop->node_info->buswidth, bwsum); MSM_BUS_DBG("Calling update-clks: curr_hz: %lu, req_hz: %lu," " bw_hz %u\n", curr_clk, req_clk, bwsum_hz); ret = fabdev->algo->update_clks(fabdev, hop, index, curr_clk_hz, req_clk_hz, bwsum_hz, SEL_FAB_CLK, ctx, cl_active_flag); if (ret) MSM_BUS_WARN("Failed to update clk\n"); info = hop; } while (GET_NODE(info->pnode[index].next) != info->node_info->priv_id); /* Update BW, clk after exiting the loop for the last one */ if (!info) { MSM_BUS_ERR("Cannot find node info!\n"); return -ENXIO; } /* Update slave clocks */ ret = fabdev->algo->update_clks(fabdev, info, index, curr_clk_hz, req_clk_hz, bwsum_hz, SEL_SLAVE_CLK, ctx, cl_active_flag); if (ret) MSM_BUS_ERR("Failed to update clk\n"); return ret; }
/** * getpath() - Finds the path from the topology between src and dest * @src: Source. This is the master from which the request originates * @dest: Destination. This is the slave to which we're trying to reach * * Function returns: next_pnode_id. The higher 16 bits of the next_pnode_id * represent the src id of the next node on path. The lower 16 bits of the * next_pnode_id represent the "index", which is the next entry in the array * of pnodes for that node to fill in clk and bw values. This is created using * CREATE_PNODE_ID. The return value is stored in ret_pnode, and this is added * to the list of path nodes. * * This function recursively finds the path by updating the src to the * closest possible node to dest. */ static int getpath(int src, int dest) { int pnode_num = -1, i; struct msm_bus_fabnodeinfo *fabnodeinfo; struct msm_bus_fabric_device *fabdev; int next_pnode_id = -1; struct msm_bus_inode_info *info = NULL; int _src = src/FABRIC_ID_KEY; int _dst = dest/FABRIC_ID_KEY; int ret_pnode = -1; int fabid = GET_FABID(src); /* Find the location of fabric for the src */ MSM_BUS_DBG("%d --> %d\n", src, dest); fabdev = msm_bus_get_fabric_device(fabid); if (!fabdev) { MSM_BUS_WARN("Fabric Not yet registered. Try again\n"); return -ENXIO; } /* Are we there yet? */ if (src == dest) { info = fabdev->algo->find_node(fabdev, src); if (ZERO_OR_NULL_PTR(info)) { MSM_BUS_ERR("Node %d not found\n", dest); return -ENXIO; } for (i = 0; i <= info->num_pnodes; i++) { if (info->pnode[i].next == -2) { MSM_BUS_DBG("src = dst Reusing pnode for" " info: %d at index: %d\n", info->node_info->priv_id, i); next_pnode_id = CREATE_PNODE_ID(src, i); info->pnode[i].clk[DUAL_CTX] = 0; info->pnode[i].bw[DUAL_CTX] = 0; info->pnode[i].next = next_pnode_id; MSM_BUS_DBG("returning: %d, %d\n", GET_NODE (next_pnode_id), GET_INDEX(next_pnode_id)); return next_pnode_id; } } next_pnode_id = CREATE_PNODE_ID(src, (info->num_pnodes + 1)); pnode_num = add_path_node(info, next_pnode_id); if (pnode_num < 0) { MSM_BUS_ERR("Error adding path node\n"); return -ENXIO; } MSM_BUS_DBG("returning: %d, %d\n", GET_NODE(next_pnode_id), GET_INDEX(next_pnode_id)); return next_pnode_id; } else if (_src == _dst) { /* * src and dest belong to same fabric, find the destination * from the radix tree */ info = fabdev->algo->find_node(fabdev, dest); if (ZERO_OR_NULL_PTR(info)) { MSM_BUS_ERR("Node %d not found\n", dest); return -ENXIO; } ret_pnode = getpath(info->node_info->priv_id, dest); next_pnode_id = ret_pnode; } else { /* find the dest fabric */ int trynextgw = true; struct list_head *gateways = fabdev->algo->get_gw_list(fabdev); list_for_each_entry(fabnodeinfo, gateways, list) { /* see if the destination is at a connected fabric */ if (_dst == (fabnodeinfo->info->node_info->priv_id / FABRIC_ID_KEY)) { /* Found the fab on which the device exists */ info = fabnodeinfo->info; trynextgw = false; ret_pnode = getpath(info->node_info->priv_id, dest); pnode_num = add_path_node(info, ret_pnode); if (pnode_num < 0) { MSM_BUS_ERR("Error adding path node\n"); return -ENXIO; } next_pnode_id = CREATE_PNODE_ID( info->node_info->priv_id, pnode_num); break; } } /* find the gateway */ if (trynextgw) { gateways = fabdev->algo->get_gw_list(fabdev); list_for_each_entry(fabnodeinfo, gateways, list) { struct msm_bus_fabric_device *gwfab = msm_bus_get_fabric_device(fabnodeinfo-> info->node_info->priv_id); if (!gwfab->visited) { MSM_BUS_DBG("VISITED ID: %d\n", gwfab->id); gwfab->visited = true; info = fabnodeinfo->info; ret_pnode = getpath(info-> node_info->priv_id, dest); pnode_num = add_path_node(info, ret_pnode); if (pnode_num < 0) { MSM_BUS_ERR("Malloc failure in" " adding path node\n"); return -ENXIO; } next_pnode_id = CREATE_PNODE_ID( info->node_info->priv_id, pnode_num); break; } } if (next_pnode_id < 0) return -ENXIO; } } if (!IS_NODE(src)) { MSM_BUS_DBG("Returning next_pnode_id:%d[%d]\n", GET_NODE( next_pnode_id), GET_INDEX(next_pnode_id)); return next_pnode_id; } info = fabdev->algo->find_node(fabdev, src); if (!info) { MSM_BUS_ERR("Node info not found.\n"); return -ENXIO; } pnode_num = add_path_node(info, next_pnode_id); MSM_BUS_DBG(" Last: %d[%d] = (%d, %d)\n", src, info->num_pnodes, GET_NODE(next_pnode_id), GET_INDEX(next_pnode_id)); MSM_BUS_DBG("returning: %d, %d\n", src, pnode_num); return CREATE_PNODE_ID(src, pnode_num); }
optimize P1(parse_node_t *, expr) { if (!expr) return 0; switch (expr->kind) { case NODE_TERNARY_OP: OPT(expr->l.expr); OPT(expr->r.expr->l.expr); OPT(expr->r.expr->r.expr); break; case NODE_BINARY_OP: OPT(expr->l.expr); if (expr->v.number == F_ASSIGN) { if (IS_NODE(expr->r.expr, NODE_OPCODE_1, F_LOCAL_LVALUE)) { if (!optimizer_state) { int x = expr->r.expr->l.number; if (last_local_refs[x]) { last_local_refs[x]->v.number = F_TRANSFER_LOCAL; last_local_refs[x] = 0; } } } } OPT(expr->r.expr); break; case NODE_UNARY_OP: OPT(expr->r.expr); break; case NODE_OPCODE: break; case NODE_TERNARY_OP_1: OPT(expr->l.expr); OPT(expr->r.expr->l.expr); OPT(expr->r.expr->r.expr); break; case NODE_BINARY_OP_1: OPT(expr->l.expr); OPT(expr->r.expr); break; case NODE_UNARY_OP_1: OPT(expr->r.expr); if (expr->v.number == F_VOID_ASSIGN_LOCAL) { if (last_local_refs[expr->l.number] && !optimizer_state) { last_local_refs[expr->l.number]->v.number = F_TRANSFER_LOCAL; last_local_refs[expr->l.number] = 0; } } break; case NODE_OPCODE_1: if (expr->v.number == F_LOCAL || expr->v.number == F_LOCAL_LVALUE) { if (expr->v.number == F_LOCAL) { if(!optimizer_state) { last_local_refs[expr->l.number] = expr; break; } } last_local_refs[expr->l.number] = 0; } break; case NODE_OPCODE_2: break; case NODE_RETURN: OPT(expr->r.expr); break; case NODE_STRING: case NODE_REAL: case NODE_NUMBER: break; case NODE_LAND_LOR: case NODE_BRANCH_LINK: OPT(expr->l.expr); OPT(expr->r.expr); break; case NODE_CALL_2: case NODE_CALL_1: case NODE_CALL: optimize_expr_list(expr->r.expr); break; case NODE_TWO_VALUES: OPT(expr->l.expr); OPT(expr->r.expr); break; case NODE_CONTROL_JUMP: case NODE_PARAMETER: case NODE_PARAMETER_LVALUE: break; case NODE_IF: { int in_cond; OPT(expr->v.expr); in_cond = (optimizer_state & OPTIMIZER_IN_COND); optimizer_state |= OPTIMIZER_IN_COND; OPT(expr->l.expr); OPT(expr->r.expr); optimizer_state &= ~OPTIMIZER_IN_COND; optimizer_state |= in_cond; break; } case NODE_LOOP: { int in_loop = (optimizer_state & OPTIMIZER_IN_LOOP); optimizer_state |= OPTIMIZER_IN_LOOP; OPT(expr->v.expr); OPT(expr->l.expr); OPT(expr->r.expr); optimizer_state &= ~OPTIMIZER_IN_LOOP; optimizer_state |= in_loop; break; } case NODE_FOREACH: OPT(expr->l.expr); OPT(expr->r.expr); OPT(expr->v.expr); break; case NODE_CASE_NUMBER: case NODE_CASE_STRING: case NODE_DEFAULT: break; case NODE_SWITCH_STRINGS: case NODE_SWITCH_NUMBERS: case NODE_SWITCH_DIRECT: case NODE_SWITCH_RANGES: { int in_cond; OPT(expr->l.expr); in_cond = (optimizer_state & OPTIMIZER_IN_COND); optimizer_state |= OPTIMIZER_IN_COND; OPT(expr->r.expr); optimizer_state &= ~OPTIMIZER_IN_COND; optimizer_state |= in_cond; break; } case NODE_CATCH: OPT(expr->r.expr); break; case NODE_LVALUE_EFUN: OPT(expr->l.expr); optimize_lvalue_list(expr->r.expr); break; case NODE_FUNCTION_CONSTRUCTOR: /* Don't optimize inside of these; we'll get confused by local vars * since it's a separate frame, etc * * OPT(expr->r.expr); * * BUT make sure to optimize the things which AREN'T part of that * frame, namely, the arguments, otherwise we will screw up: * * use(local); return (: foo, local :); // local evaluated at * use(local); return (: ... $(local) ... :); // construction time */ if (expr->r.expr) optimize_expr_list(expr->r.expr); /* arguments */ break; case NODE_ANON_FUNC: break; case NODE_EFUN: optimize_expr_list(expr->r.expr); break; default: break; } return expr; }
/** * update_path() - Update the path with the bandwidth and clock values, as * requested by the client. * * @curr: Current source node, as specified in the client vector (master) * @pnode: The first-hop node on the path, stored in the internal client struct * @req_clk: Requested clock value from the vector * @req_bw: Requested bandwidth value from the vector * @curr_clk: Current clock frequency * @curr_bw: Currently allocated bandwidth * * This function updates the nodes on the path calculated using getpath(), with * clock and bandwidth values. The sum of bandwidths, and the max of clock * frequencies is calculated at each node on the path. Commit data to be sent * to RPM for each master and slave is also calculated here. */ static int update_path(int curr, int pnode, uint64_t req_clk, uint64_t req_bw, uint64_t curr_clk, uint64_t curr_bw, unsigned int ctx, unsigned int cl_active_flag) { int index, ret = 0; struct msm_bus_inode_info *info; int next_pnode; int64_t add_bw = req_bw - curr_bw; uint64_t bwsum = 0; uint64_t req_clk_hz, curr_clk_hz, bwsum_hz; int *master_tiers; struct msm_bus_fabric_device *fabdev = msm_bus_get_fabric_device (GET_FABID(curr)); if (!fabdev) { MSM_BUS_ERR("Bus device for bus ID: %d not found!\n", GET_FABID(curr)); return -ENXIO; } MSM_BUS_DBG("args: %d %d %d %llu %llu %llu %llu %u\n", curr, GET_NODE(pnode), GET_INDEX(pnode), req_clk, req_bw, curr_clk, curr_bw, ctx); index = GET_INDEX(pnode); MSM_BUS_DBG("Client passed index :%d\n", index); info = fabdev->algo->find_node(fabdev, curr); if (!info) { MSM_BUS_ERR("Cannot find node info!\n"); return -ENXIO; } #ifndef CONFIG_BW_LIMITER_FIX /** * If master supports dual configuration, check if * the configuration needs to be changed based on * incoming requests */ if (info->node_info->dual_conf) fabdev->algo->config_master(fabdev, info, req_clk, req_bw); #endif info->link_info.sel_bw = &info->link_info.bw[ctx]; info->link_info.sel_clk = &info->link_info.clk[ctx]; *info->link_info.sel_bw += add_bw; info->pnode[index].sel_bw = &info->pnode[index].bw[ctx]; /** * To select the right clock, AND the context with * client active flag. */ info->pnode[index].sel_clk = &info->pnode[index].clk[ctx & cl_active_flag]; *info->pnode[index].sel_bw += add_bw; #ifdef CONFIG_BW_LIMITER_FIX *info->pnode[index].sel_clk = req_clk; /** * If master supports dual configuration, check if * the configuration needs to be changed based on * incoming requests */ if (info->node_info->dual_conf) { uint64_t node_maxib = 0; node_maxib = get_node_maxib(info); fabdev->algo->config_master(fabdev, info, node_maxib, req_bw); } #endif info->link_info.num_tiers = info->node_info->num_tiers; info->link_info.tier = info->node_info->tier; master_tiers = info->node_info->tier; do { struct msm_bus_inode_info *hop; fabdev = msm_bus_get_fabric_device(GET_FABID(curr)); if (!fabdev) { MSM_BUS_ERR("Fabric not found\n"); return -ENXIO; } MSM_BUS_DBG("id: %d\n", info->node_info->priv_id); /* find next node and index */ next_pnode = info->pnode[index].next; curr = GET_NODE(next_pnode); index = GET_INDEX(next_pnode); MSM_BUS_DBG("id:%d, next: %d\n", info-> node_info->priv_id, curr); /* Get hop */ /* check if we are here as gateway, or does the hop belong to * this fabric */ if (IS_NODE(curr)) hop = fabdev->algo->find_node(fabdev, curr); else hop = fabdev->algo->find_gw_node(fabdev, curr); if (!hop) { MSM_BUS_ERR("Null Info found for hop\n"); return -ENXIO; } hop->link_info.sel_bw = &hop->link_info.bw[ctx]; hop->link_info.sel_clk = &hop->link_info.clk[ctx]; *hop->link_info.sel_bw += add_bw; hop->pnode[index].sel_bw = &hop->pnode[index].bw[ctx]; hop->pnode[index].sel_clk = &hop->pnode[index].clk[ctx & cl_active_flag]; if (!hop->node_info->buswidth) { MSM_BUS_WARN("No bus width found. Using default\n"); hop->node_info->buswidth = 8; } *hop->pnode[index].sel_clk = BW_TO_CLK_FREQ_HZ(hop->node_info-> buswidth, req_clk); *hop->pnode[index].sel_bw += add_bw; MSM_BUS_DBG("fabric: %d slave: %d, slave-width: %d info: %d\n", fabdev->id, hop->node_info->priv_id, hop->node_info-> buswidth, info->node_info->priv_id); /* Update Bandwidth */ fabdev->algo->update_bw(fabdev, hop, info, add_bw, master_tiers, ctx); bwsum = *hop->link_info.sel_bw; /* Update Fabric clocks */ curr_clk_hz = BW_TO_CLK_FREQ_HZ(hop->node_info->buswidth, curr_clk); req_clk_hz = BW_TO_CLK_FREQ_HZ(hop->node_info->buswidth, req_clk); bwsum_hz = BW_TO_CLK_FREQ_HZ(hop->node_info->buswidth, bwsum); /* Account for multiple channels if any */ if (hop->node_info->num_sports > 1) bwsum_hz = msm_bus_div64(hop->node_info->num_sports, bwsum_hz); MSM_BUS_DBG("AXI: Hop: %d, ports: %d, bwsum_hz: %llu\n", hop->node_info->id, hop->node_info->num_sports, bwsum_hz); MSM_BUS_DBG("up-clk: curr_hz: %llu, req_hz: %llu, bw_hz %llu\n", curr_clk, req_clk, bwsum_hz); ret = fabdev->algo->update_clks(fabdev, hop, index, curr_clk_hz, req_clk_hz, bwsum_hz, SEL_FAB_CLK, ctx, cl_active_flag); if (ret) MSM_BUS_WARN("Failed to update clk\n"); info = hop; } while (GET_NODE(info->pnode[index].next) != info->node_info->priv_id); /* Update BW, clk after exiting the loop for the last one */ if (!info) { MSM_BUS_ERR("Cannot find node info!\n"); return -ENXIO; } /* Update slave clocks */ ret = fabdev->algo->update_clks(fabdev, info, index, curr_clk_hz, req_clk_hz, bwsum_hz, SEL_SLAVE_CLK, ctx, cl_active_flag); if (ret) MSM_BUS_ERR("Failed to update clk\n"); return ret; }
parse_node_t *insert_pop_value P1(parse_node_t *, expr) { parse_node_t *replacement; if (!expr) return 0; if (expr->type == TYPE_NOVALUE) { expr->type = TYPE_VOID; return expr; } switch (expr->kind) { case NODE_EFUN: if (expr->v.number & NOVALUE_USED_FLAG) { expr->v.number &= ~NOVALUE_USED_FLAG; return expr; } break; case NODE_TWO_VALUES: /* (two-values expr1 expr2) where expr1 is already popped. * * instead of: (pop (two-values expr1 expr2)) * generated: (two-values expr (pop expr2)) * * both of which generate the same code, but the second optimizes * better in cases like: i++, j++ * * we get: (two-values (inc i) (post-inc j)) * first: (pop (two-values (inc i) (post-inc j))) * -> INC i; POST_INC j; POP * second: (two-values (inc i) (inc j)) * -> INC i; INC j */ if ((expr->r.expr = insert_pop_value(expr->r.expr))) return expr; return expr->l.expr; case NODE_IF: /* a NODE_IF that gets popped is a (x ? y : z); * propagate the pop in order to produce the same code as * if (x) y; else z; */ expr->l.expr = insert_pop_value(expr->l.expr); expr->r.expr = insert_pop_value(expr->r.expr); if (!expr->l.expr && !expr->r.expr) { /* if both branches do nothing, don't bother with the test ... */ return insert_pop_value(expr->v.expr); } return expr; case NODE_TERNARY_OP: switch (expr->r.expr->v.number) { case F_NN_RANGE: case F_RN_RANGE: case F_RR_RANGE: case F_NR_RANGE: expr->kind = NODE_TWO_VALUES; expr->l.expr = insert_pop_value(expr->l.expr); expr->r.expr->kind = NODE_TWO_VALUES; expr->r.expr->l.expr = insert_pop_value(expr->r.expr->l.expr); expr->r.expr->r.expr = insert_pop_value(expr->r.expr->r.expr); if (!expr->l.expr) { expr = expr->r.expr; if (!expr->l.expr) return expr->r.expr; if (!expr->r.expr) return expr->l.expr; } else { if (!expr->r.expr->l.expr) { expr->r.expr = expr->r.expr->r.expr; if (!expr->r.expr) return expr->l.expr; } else { if (!expr->r.expr->r.expr) expr->r.expr = expr->r.expr->l.expr; } } return expr; } break; /* take advantage of the fact that opcodes don't clash */ case NODE_CALL: case NODE_BINARY_OP: case NODE_UNARY_OP_1: case NODE_UNARY_OP: case NODE_OPCODE_1: switch (expr->v.number) { case F_AGGREGATE_ASSOC: /* This has to be done specially b/c of the way mapping constants are stored */ return throw_away_mapping(expr); case F_AGGREGATE: return throw_away_call(expr); case F_PRE_INC: case F_POST_INC: expr->v.number = F_INC; return expr; case F_PRE_DEC: case F_POST_DEC: expr->v.number = F_DEC; return expr; case F_NOT: case F_COMPL: case F_NEGATE: expr = insert_pop_value(expr->r.expr); return expr; case F_MEMBER: expr = insert_pop_value(expr->r.expr); return expr; case F_LOCAL: case F_GLOBAL: return 0; case F_EQ: case F_NE: case F_GT: case F_GE: case F_LT: case F_LE: yywarn("Value of conditional expression is unused"); /* FALLTHRU */ case F_OR: case F_XOR: case F_AND: case F_LSH: case F_RSH: case F_ADD: case F_SUBTRACT: case F_MULTIPLY: case F_DIVIDE: case F_MOD: case F_RE_RANGE: case F_NE_RANGE: case F_RINDEX: case F_INDEX: expr->kind = NODE_TWO_VALUES; if ((expr->l.expr = insert_pop_value(expr->l.expr))) { if ((expr->r.expr = insert_pop_value(expr->r.expr))) return expr; else return expr->l.expr; } else return insert_pop_value(expr->r.expr); break; case F_ASSIGN: if (IS_NODE(expr->r.expr, NODE_OPCODE_1, F_LOCAL_LVALUE)) { int tmp = expr->r.expr->l.number; expr->kind = NODE_UNARY_OP_1; expr->r.expr = expr->l.expr; expr->v.number = F_VOID_ASSIGN_LOCAL; expr->l.number = tmp; } else expr->v.number = F_VOID_ASSIGN; return expr; case F_ADD_EQ: expr->v.number = F_VOID_ADD_EQ; return expr; } break; case NODE_PARAMETER: case NODE_ANON_FUNC: /* some dweeb threw away one? */ case NODE_FUNCTION_CONSTRUCTOR: return 0; case NODE_NUMBER: case NODE_STRING: case NODE_REAL: return 0; } CREATE_UNARY_OP(replacement, F_POP_VALUE, 0, expr); return replacement; }
void Lanes::setInitial() { int& t = typeVec[activeLane]; if (!IS_NODE(t) && t != APPLIED) t = (boundary ? BOUNDARY : INITIAL); }