INT TI_RES_RES_Resources_Length( TI_RES_RES *res, TOP opcode ) { return SI_RR_Length(TSI_Resource_Requirement(opcode)); }
/* ==================================================================== * * TI_RES_RES_Resource_Grainy * * See interface description * * ==================================================================== */ BOOL TI_RES_RES_Resources_Grainy( TI_RES_RES *res, TOP opcode ) { INT i; const INT32 length = TI_RES_RES_length(res); SI_RESOURCE_ID_SET *uncommon_res_ids = TI_RES_RES_uncommon_res_ids(res); UINT min_rr_length = TI_RES_RES_min_rr_length(res); const SI_RESOURCE_ID_SET* res_used = TSI_II_Cycle_Resource_Ids_Used(opcode,length); INT res_used_length = SI_RR_Length(TSI_II_Resource_Requirement(opcode,length)); if ( min_rr_length < res_used_length ) return TRUE; for ( i = 0; i < min_rr_length; ++i ) { if ( SI_RESOURCE_ID_SET_Intersection_Non_Empty(res_used[i], uncommon_res_ids[i]) ) { return TRUE; } } return FALSE; }
static void Check_Reserve_Loop_Control_For_Alternative_Res( TI_RES_RES *res, TOP opcode, INT cycle, SI_RR *rr, INT *length1, INT *length2, INT *cycle_mod_ii ) { INT32 rr_length; INT32 length = TI_RES_RES_length(res); if ( TI_RES_RES_cyclic(res) ) { *rr = TSI_II_Resource_Requirement(opcode,length); } else { *rr = TSI_Alternative_Resource_Requirement(opcode); } *cycle_mod_ii = Cycle_Mod_II(cycle,length); rr_length = SI_RR_Length(*rr); if ( *cycle_mod_ii + rr_length <= length ) { *length1 = rr_length; *length2 = 0; } else { *length1 = length - *cycle_mod_ii; *length2 = rr_length - *length1; } }
/* ==================================================================== * * TI_RES_RES_Resources_Equivalent * * See interface description * * ==================================================================== */ BOOL TI_RES_RES_Resources_Equivalent( TI_RES_RES *res, TOP opcode1, TOP opcode2 ) { INT i; const INT32 length = TI_RES_RES_length(res); SI_RR rr1 = TSI_II_Resource_Requirement(opcode1,length); SI_RR rr2 = TSI_II_Resource_Requirement(opcode2,length); if ( rr1 == rr2 ) return TRUE; if ( SI_RR_Length(rr1) != SI_RR_Length(rr2) ) return FALSE; for (i = 0; i < SI_RR_Length(rr1); ++i) { if ( SI_RR_Cycle_RRW(rr1,i) != SI_RR_Cycle_RRW(rr2,i) ) return FALSE; } return TRUE; }
/* ==================================================================== * * TI_RES_Can_Dual_Issue * * See interface description * * ==================================================================== */ BOOL TI_RES_Can_Dual_Issue( TOP opcode1, TOP opcode2 ) { INT min_length, i; SI_RR rr1, rr2; /* Quick check to see if we could ever dual issue something. */ if (!PROC_has_same_cycle_branch_shadow()) return FALSE; /* Resource requirements for each. */ rr1 = TSI_Resource_Requirement(opcode1); rr2 = TSI_Resource_Requirement(opcode2); /* We only have to check up to the end of the shorter of the two resource * requests. */ if ( SI_RR_Length(rr1) < SI_RR_Length(rr2) ) min_length = SI_RR_Length(rr1); else min_length = SI_RR_Length(rr2); /* Check each cycle. */ for ( i = 0; i < min_length; ++i ) { SI_RRW rrw = SI_RRW_Initial(); rrw = SI_RRW_Reserve(rrw,SI_RR_Cycle_RRW(rr1,i)); rrw = SI_RRW_Reserve(rrw,SI_RR_Cycle_RRW(rr2,i)); if ( SI_RRW_Has_Overuse(rrw) ) return FALSE; } return TRUE; }
/* ==================================================================== * * TI_RES_RES_Has_TOP * * See interface description * * ==================================================================== */ void TI_RES_RES_Has_TOP( TI_RES_RES *res, TOP opcode ) { if ( !BS_MemberP(TI_RES_RES_si_ids(res), TSI_Id(opcode) ) ) { UINT rr_length; TI_RES_RES_si_ids(res) = BS_Union1D(TI_RES_RES_si_ids(res), TSI_Id(opcode), TI_RES_RES_pool(res)); TI_RES_RES_bad_iis(res) = SI_BAD_II_SET_Union(TI_RES_RES_bad_iis(res), TSI_Bad_IIs(opcode)); rr_length = SI_RR_Length(TSI_Resource_Requirement(opcode)); if ( rr_length < TI_RES_RES_min_rr_length(res) ) { TI_RES_RES_min_rr_length(res) = rr_length; } } }
/* ==================================================================== * * TI_RES_RES_Resources_Relevant * * See interface description * * ==================================================================== */ BOOL TI_RES_RES_Resources_Relevant( TI_RES_RES *res, TOP opcode1, TOP opcode2, INT offset ) { INT length1, length2, i; const INT32 length = TI_RES_RES_length(res); const SI_RESOURCE_ID_SET *const res_ids1 = TSI_II_Cycle_Resource_Ids_Used(opcode1,length); const SI_RESOURCE_ID_SET *const res_ids2 = TSI_II_Cycle_Resource_Ids_Used(opcode2,length); const INT rr1_length = SI_RR_Length(TSI_II_Resource_Requirement(opcode1,length)); const INT rr2_length = SI_RR_Length(TSI_II_Resource_Requirement(opcode2,length)); const INT offset_mod_ii = Cycle_Mod_II(offset,length); const SI_RESOURCE_ID_SET *const uncommon_res_ids = TI_RES_RES_uncommon_res_ids(res); FmtAssert (TI_RES_RES_cyclic(res), ("TI_RES_RES_Resources_Relevant not applicable to non-cyclic schedules")); /* Check from the start of rr2 until either the end of rr2 or the end of * rr1 + offset (which cannot be greater than II-1.) */ length1 = rr1_length - offset_mod_ii; if ( rr2_length < length1 ) length1 = rr2_length; for ( i = 0; i < length1; ++i ) { if ( SI_RESOURCE_ID_SET_Intersection4_Non_Empty( res_ids1[i + offset_mod_ii], uncommon_res_ids[i + offset_mod_ii], res_ids2[i], uncommon_res_ids[i] ) ) { return TRUE; } } /* The resource requirements for opcode1 (rr1) and opcode2 (rr2) * are already modulo the II. But we are comparing rr2 at an offset * from rr1, therefore we may have some cycles and the end of rr2 * that wrap around to the beginning of rr1. If that is the case, * check those cycles. Note that rr2 can only wrap once (because * we have use the offset mod II), and some cycles in the middle * of rr2 may not need to be checked against rr1 (because rr1 might * consume no resource in those cycles). */ length2 = (rr2_length + offset_mod_ii) - length; if ( length > 0 ) { if ( rr1_length < length2 ) length2 = rr1_length; for ( i = 0; i < length2; ++i ) { if ( SI_RESOURCE_ID_SET_Intersection4_Non_Empty( res_ids1[i], uncommon_res_ids[i], res_ids2[i + length - offset_mod_ii], uncommon_res_ids[i + length - offset_mod_ii] ) ) { return TRUE; } } } return FALSE; }