Exemple #1
0
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;
}
Exemple #2
0
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;
}
Exemple #3
0
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;
}
Exemple #4
0
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;
}
Exemple #5
0
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;
}
Exemple #6
0
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;
}
Exemple #8
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;
}
Exemple #9
0
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;
}
Exemple #11
0
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;
}
Exemple #12
0
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);
	}
}
Exemple #13
0
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;
}
Exemple #14
0
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);
}
Exemple #15
0
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;
	}
}
Exemple #16
0
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();
	}
}
Exemple #17
0
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;
}
Exemple #18
0
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;
}
Exemple #23
0
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;
}
Exemple #24
0
void Lanes::setInitial() {

	int& t = typeVec[activeLane];
	if (!IS_NODE(t) && t != APPLIED)
		t = (boundary ? BOUNDARY : INITIAL);
}