Ejemplo n.º 1
0
size_t schedule_chain::find_unit(const schedule_unit *unit) const
{
    size_t i = 0;
    while(i < get_unit_count())
    {
        if(get_unit_at(i) == unit)
            break;
        i++;
    }
    return i;
}
Ejemplo n.º 2
0
size_t schedule_chain::compute_rp_against_dag(const schedule_dag& dag, bool ignore_external_reg) const
{
    std::map< schedule_dep::reg_t, size_t > nb_use_left;
    size_t rp = 0;

    /* if the chain is only a subgraph of the DAG, handle it */
    if(get_unit_count() < dag.get_units().size() && ignore_external_reg)
    {
        schedule_dag *cpy = dag.dup();
        for(size_t u = 0; u < dag.get_units().size(); u++)
        {
            bool ok = false;
            for(size_t i = 0; i < get_unit_count(); i++)
                ok = ok || get_unit_at(i) == dag.get_units()[u];
            if(!ok)
                cpy->remove_unit(dag.get_units()[u]);
        }

        size_t rp = compute_rp_against_dag(*cpy);
        delete cpy;
        return rp;
    }

    for(size_t i = 0; i < get_unit_count(); i++)
    {
        const schedule_unit *unit = get_unit_at(i);
        /* use & destroy regs */
        std::set< schedule_dep::reg_t > set;
        std::set< schedule_dep::reg_t >::iterator it;

        set = dag.get_reg_use(unit);
        for(it = set.begin(); it != set.end(); ++it)
        {
            assert(nb_use_left.find(*it) != nb_use_left.end() && "Used variable is not alive !");
            assert(nb_use_left[*it] > 0 && "Variable is use more times than expected !");

            nb_use_left[*it]--;
            if(nb_use_left[*it] == 0)
                nb_use_left.erase(*it);
        }
        /* update RP */
        rp = std::max(rp, nb_use_left.size() + unit->internal_register_pressure());
        /* create regs */
        set = dag.get_reg_create(unit);
        for(it = set.begin(); it != set.end(); ++it)
        {
            assert(nb_use_left.find(*it) == nb_use_left.end() &&
                   "Created variable is already alive ! Either this is wrong or f****d up with physical registers, "
                   "check with schedule_chain::check_against_dag");

            nb_use_left[*it] = 0;
            for(size_t i = 0; i < dag.get_succs(unit).size(); i++)
            {
                const schedule_dep& dep = dag.get_succs(unit)[i];
                if(dep.is_data() && dep.reg() == *it)
                    nb_use_left[*it]++;
            }
        }
        /* update RP */
        rp = std::max(rp, nb_use_left.size());
    }

    if(ignore_external_reg)
    {
        assert(nb_use_left.size() == 0 && "Variables still alive at end of schedule !");
    }
    else
    {
        rp = std::max(rp, nb_use_left.size());
    }

    return rp;
}
Ejemplo n.º 3
0
bool schedule_chain::check_against_dag(const schedule_dag& dag) const
{
#if 1
#define fail(msg) return false
#else
#define fail(msg) std::runtime_error(msg)
#endif
    /* trivial check */
    if(dag.get_units().size() != get_unit_count())
        fail("schedule_chain::check_against_dag detected a unit count mismatch");
    /* first build a map of positions */
    std::map< const schedule_unit *, size_t > pos;

    for(size_t i = 0; i < get_unit_count(); i++)
        pos[get_unit_at(i)] = i;

    /* then check each dependency is satisfied */
    for(size_t i = 0; i < dag.get_deps().size(); i++)
    {
        const schedule_dep& d = dag.get_deps()[i];
        if(pos.find(d.from()) == pos.end() ||
                pos.find(d.to()) == pos.end())
            fail("schedule_chain::check_against_dag detected unscheduled unit");
        if(pos[d.from()] >= pos[d.to()])
            fail("schedule_chain::check_against_dag detected unsatisfied dependency");
    }

    /* then check that the same physical register is not alive twice at the same time */
    std::map< schedule_dep::reg_t, size_t > phys_reg_uses;
    for(size_t i = 0; i < get_unit_count(); i++)
    {
        const schedule_unit *unit = get_unit_at(i);
        /* destroy physical registers if any */
        for(size_t j = 0; j < dag.get_preds(unit).size(); j++)
        {
            const schedule_dep& dep = dag.get_preds(unit)[j];
            if(!dep.is_phys())
                continue;
            assert(phys_reg_uses.find(dep.reg()) != phys_reg_uses.end() && "inconsistent phys reg uses map");
            /* remove this unit from the use count of the physical register */
            if((--phys_reg_uses[dep.reg()]) == 0)
                /* if the set is now empty, remove entry */
                phys_reg_uses.erase(dep.reg());
        }
        /* create physical registers if any */
        for(size_t j = 0; j < dag.get_succs(unit).size(); j++)
        {
            const schedule_dep& dep = dag.get_succs(unit)[j];
            if(!dep.is_phys())
                continue;
            /* if the physical register is already alive, then the schedule is not valid */
            if(phys_reg_uses.find(dep.reg()) != phys_reg_uses.end())
                fail("schedule_chain::check_against_dag detected that the same physical register is alive at the same point"
                     "but with different creators, this will result in miscompilation!");
        }
        for(size_t j = 0; j < dag.get_succs(unit).size(); j++)
        {
            const schedule_dep& dep = dag.get_succs(unit)[j];
            if(!dep.is_phys())
                continue;
            phys_reg_uses[dep.reg()]++;
        }
    }

    assert(phys_reg_uses.size() == 0 && "not all physical register have been destroyed: partial dag ?");

    return true;
}
Ejemplo n.º 4
0
void user_daemon_t::handle_parameters(int argc, char *argv[])
{
	bool_t instance_specified, unit_specified;
	co_command_line_params_t cmdline;
	co_rc_t rc;

	rc = co_cmdline_params_alloc(&argv[1], argc-1, &cmdline);
	if (!CO_OK(rc)) {
		log("error parsing arguments\n");
		throw user_daemon_exception_t(rc);
	}
	
	try {
	
		rc = co_cmdline_params_one_arugment_int_parameter(cmdline, "-i", 
								  &instance_specified, (int *)&param_instance);
	
		if (!CO_OK(rc)) {
			syntax();
			throw user_daemon_exception_t(rc);
		}

		rc = co_cmdline_params_one_arugment_int_parameter(cmdline, "-u", 
								  &unit_specified, &param_index);

		if (!CO_OK(rc)) {
			syntax();
			throw user_daemon_exception_t(rc);
		}

		handle_extended_parameters(cmdline);
	
		rc = co_cmdline_params_check_for_no_unparsed_parameters(cmdline, PTRUE);
		if (!CO_OK(rc)) {
			syntax();
			throw user_daemon_exception_t(rc);
		}

		if (!instance_specified  &&  !unit_specified) {
			rc = CO_RC(OK);
			syntax();
			throw user_daemon_exception_t(rc);
		}
	
		verify_parameters();

		if ((param_index < 0) || (param_index >= get_unit_count()))
		{
			syntax();
			log("invalid unit index: %d\n", param_index);
			throw user_daemon_exception_t(rc);
		}

		if (!instance_specified) {
			syntax();
			log("coLinux instance not specificed\n");
			throw user_daemon_exception_t(rc);
		}

	} catch(...) {
		co_cmdline_params_free(cmdline);
		throw;
	}
}