00001
00002
00003 #include "defs.h"
00004 #include "tracing.h"
00005 #include "ipfec_defs.h"
00006 #include "ipfec_options.h"
00007
00008 #include "sched_util.h"
00009 #include "sched_res_aware.h"
00010
00011
00012 #define ALAT_ENTRY_NUM (28)
00013
00014 void
00015 BB_VIGILANT_PNT_MGR::Init (void) {
00016 OP* op;
00017 FOR_ALL_BB_OPs (_bb, op) {
00018 if (VIGILANT_PNT::Candidate (op)) {
00019 Add_Vigilant_Point (op);
00020 }
00021 }
00022 }
00023
00024 void
00025 BB_VIGILANT_PNT_MGR::Update_Vp_For_Compensation_Code
00026 (OP* bookeeping) {
00027
00028 if (!VIGILANT_PNT::Candidate (bookeeping)) {
00029 return;
00030 }
00031
00032 VIGILANT_PNT* vp = CXX_NEW(VIGILANT_PNT(bookeeping), _mp);
00033 _vigilant_pnt_list.push_back (vp);
00034 if (CGTARG_Is_OP_Advanced_Load (bookeeping)) {
00035 _exit_vp.Inc_Pending_Adv_Ld ();
00036 } else if (OP_chk_a (bookeeping)) {
00037 _exit_vp.Dec_Pending_Adv_Ld ();
00038 }
00039
00040 vp->Set_Pending_Adv_Ld (_exit_vp.Pending_Adv_Ld ());
00041 }
00042
00043 DATA_SPEC_RES_CONSTRAIT_MGR::DATA_SPEC_RES_CONSTRAIT_MGR
00044 (MEM_POOL* mp) : _mp(mp) {
00045
00046 for (INT i = 0; i < sizeof(_buckets)/sizeof(_buckets[0]); i++) {
00047 _buckets[i] = CXX_NEW(BB_VIGILANT_PNT_MGR_LIST(_mp), _mp);
00048 }
00049 _rgn = NULL;
00050 }
00051
00052 void
00053 DATA_SPEC_RES_CONSTRAIT_MGR::Init (REGION* gscope) {
00054 _rgn = gscope;
00055 for (SEQ_REGIONAL_CFG_ITER iter(gscope->Regional_Cfg());
00056 iter != 0;++iter) {
00057 REGIONAL_CFG_NODE *n = *iter;
00058 if (!n->Is_Region ()) {
00059 BB* blk = n->BB_Node ();
00060 INT idx = hash_idx (blk);
00061 BB_VIGILANT_PNT_MGR* vpmgr =
00062 CXX_NEW(BB_VIGILANT_PNT_MGR(_mp, blk), _mp);
00063 vpmgr->Init ();
00064 _buckets[idx]->push_back (vpmgr);
00065 }
00066 }
00067 }
00068
00069 void
00070 DATA_SPEC_RES_CONSTRAIT_MGR::Init (BB* lscope) {
00071 INT idx = hash_idx (lscope);
00072 BB_VIGILANT_PNT_MGR* vpmgr =
00073 CXX_NEW(BB_VIGILANT_PNT_MGR(_mp, lscope), _mp);
00074 vpmgr->Init ();
00075 _buckets[idx]->push_back (vpmgr);
00076 }
00077
00078 BOOL
00079 DATA_SPEC_RES_CONSTRAIT_MGR::There_Exist_Misc_Dep_Arc (OP* pred, OP* succ) {
00080
00081 for (ARC_LIST* arcs = OP_succs(pred); arcs != NULL;
00082 arcs = ARC_LIST_rest(arcs)) {
00083
00084 ARC *arc = ARC_LIST_first(arcs) ;
00085 if (ARC_kind(arc) == CG_DEP_MISC && ARC_succ(arc) == succ) {
00086 return TRUE;
00087 }
00088 }
00089 return FALSE;
00090 }
00091
00092 BOOL
00093 DATA_SPEC_RES_CONSTRAIT_MGR::Check_Res_Constraint_Helper
00094 (BB* bb, OP* predbound, OP* succbound, OP* op) {
00095
00096 BB_VIGILANT_PNT_MGR* vpmgr = Find (bb);
00097 Is_True (vpmgr != NULL,
00098 ("BB_VIGILANT_PNT_MGR corresponding to BB:%d does not exist",
00099 BB_id(bb)));
00100
00101 VIGILANT_PNT_LIST& vps = vpmgr->Vigilant_point_list ();
00102 for (VIGILANT_PNT_LIST_ITER iter = vps.begin ();
00103 iter != vps.end (); iter++) {
00104 VIGILANT_PNT* vp = *iter;
00105 OP* vpop = vp->Op ();
00106 if (predbound && OP_Precedes(vpop, predbound) ||
00107 succbound && OP_Follows(vpop, succbound) ||
00108 OP_Scheduled (vpop)) {
00109 continue;
00110 }
00111
00112 if (OP_bb(op) == OP_bb(vpop) && !OP_Precedes (vpop, op)) {
00113 continue;
00114 }
00115
00116 if (OP_load(vpop) && !CGTARG_Is_OP_Advanced_Load(vpop)) {
00117 continue;
00118 }
00119
00120 if (vp->Pending_Adv_Ld () >= ALAT_ENTRY_NUM) {
00121 if (OP_like_store(vpop) && OP_load(op) &&
00122 !CGTARG_Is_OP_Advanced_Load(op) &&
00123 !There_Exist_Misc_Dep_Arc (vpop,op)) {
00124 continue;
00125 }
00126
00127 if (!There_Exist_Misc_Dep_Arc (vpop, op)) {
00128 new_arc_with_latency (CG_DEP_MISC, vpop, op, 0, 0, 0, TRUE);
00129 }
00130 return FALSE;
00131 }
00132 }
00133
00134 if (bb != OP_bb(op) && succbound) {
00135 VIGILANT_PNT& vp = vpmgr->Vp_for_Exit();
00136 if (vp.Pending_Adv_Ld () >= ALAT_ENTRY_NUM) {
00137 return FALSE;
00138 }
00139 }
00140
00141 return TRUE;
00142 }
00143
00144 BOOL
00145 DATA_SPEC_RES_CONSTRAIT_MGR::Check_Res_Constraint
00146 (BB* bb, OP* op) {
00147 return Check_Res_Constraint_Helper (bb, NULL, NULL, op);
00148 }
00149
00150 BOOL
00151 DATA_SPEC_RES_CONSTRAIT_MGR::Check_Res_Constraint
00152 (REGION* rgn, OP* op, SRC_BB_INFO* src_info) {
00153
00154 BB* blk = src_info->Target_BB ();
00155 if (!Check_Res_Constraint_Helper (blk, NULL, NULL, op)) {
00156 return FALSE;
00157 }
00158
00159 BB_VECTOR* bbv = src_info->Move_Across_Or_Around_BBs ();
00160 for (BB_VECTOR_ITER iter = bbv->begin ();
00161 iter != bbv->end ();
00162 iter ++) {
00163 if (!Check_Res_Constraint_Helper (*iter, NULL, NULL, op)) {
00164 return FALSE;
00165 }
00166 }
00167
00168 blk = src_info->Source_BB ();
00169 if (BB_first_op (blk) != op) {
00170 if (!Check_Res_Constraint_Helper (blk, NULL, OP_prev(op), op)) {
00171 return FALSE;
00172 }
00173 }
00174 return TRUE;
00175 }
00176
00177
00178
00179
00180
00181
00182
00183 void
00184 DATA_SPEC_RES_CONSTRAIT_MGR::Update_Pending_Adv_Ld_Info
00185 (BB* blk, OP* upperbound, OP* lowerbound, OP* sched_op) {
00186
00187 BB_VIGILANT_PNT_MGR* vpmgr = Find (blk);
00188 Is_True (vpmgr != NULL,
00189 ("BB_VIGILANT_PNT_MGR corresponding to BB:%d does not exist",
00190 BB_id(blk)));
00191
00192 VIGILANT_PNT_LIST& vps = vpmgr->Vigilant_point_list ();
00193
00194 BOOL inc = OP_chk(sched_op) ? FALSE: TRUE;
00195 for (VIGILANT_PNT_LIST_ITER iter = vps.begin ();
00196 iter != vps.end (); iter++) {
00197 VIGILANT_PNT* vp = *iter;
00198 OP* vpop = vp->Op ();
00199 if (upperbound && OP_Precedes(vpop, upperbound) ||
00200 lowerbound && OP_Follows(vpop, lowerbound) ||
00201 OP_Scheduled (vpop)) {
00202 continue;
00203 }
00204
00205 if (OP_bb(sched_op) == blk && !OP_Precedes(vpop, sched_op))
00206 continue;
00207
00208 if (inc) {
00209 vp->Inc_Pending_Adv_Ld ();
00210 } else if (vp->Pending_Adv_Ld() > 0) {
00211 vp->Dec_Pending_Adv_Ld ();
00212 }
00213 }
00214
00215 if (!lowerbound) {
00216 vpmgr->Vp_for_Exit().Inc_Pending_Adv_Ld ();
00217 }
00218 }
00219
00220 void
00221 DATA_SPEC_RES_CONSTRAIT_MGR::Update_Pending_Adv_Ld_Info
00222 (SRC_BB_INFO* srcinfo, OP* sched_op) {
00223
00224 Is_True (OP_bb(sched_op) == srcinfo->Source_BB () &&
00225 !OP_Scheduled(sched_op),
00226 ("We require that this function should be "
00227 "called before the OP is physically moved"));
00228
00229
00230
00231
00232 BB* blk = srcinfo->Target_BB ();
00233 if (OP_bb(sched_op) != blk) {
00234 Update_Pending_Adv_Ld_Info (blk, NULL, NULL, sched_op);
00235 } else if (BB_first_op(blk) != sched_op) {
00236 Update_Pending_Adv_Ld_Info (blk, NULL, OP_prev(sched_op), sched_op);
00237 }
00238
00239
00240
00241
00242 blk = srcinfo->Target_BB ();
00243
00244 blk = srcinfo->Source_BB ();
00245 if (blk != srcinfo->Target_BB () && OP_prev(sched_op)) {
00246 Update_Pending_Adv_Ld_Info (blk, NULL, OP_prev(sched_op), sched_op);
00247 }
00248
00249
00250
00251
00252 BB_VECTOR* bbv = srcinfo->Move_Across_Or_Around_BBs ();
00253 for (BB_VECTOR_ITER iter = bbv->begin ();
00254 iter != bbv->end ();
00255 iter ++) {
00256 Update_Pending_Adv_Ld_Info (*iter, NULL, NULL, sched_op);
00257 }
00258 }
00259
00260
00261 void
00262 DATA_SPEC_RES_CONSTRAIT_MGR::Update_Vp_For_Compensation_Code
00263 (OP* bookeeping, BB* compensation_blk) {
00264
00265 Is_True (OP_bb(bookeeping) == compensation_blk,
00266 ("Update_Vp_For_Compensation_Code () should be called "
00267 "after compensation code is really generated since "
00268 "the initial value of the number-of-pending-advanced-ld "
00269 "is derived from the info recorded in dummy vigilant point"));
00270
00271 if (!VIGILANT_PNT::Candidate (bookeeping)) {
00272 return;
00273 }
00274
00275 BB_VIGILANT_PNT_MGR* vpmgr = Find (OP_bb(bookeeping));
00276 vpmgr->Update_Vp_For_Compensation_Code (bookeeping);
00277 }