00001 /* -*-Mode: c++;-*- (Tell emacs to use c++ mode) */ 00002 00003 /* 00004 * Copyright (C) 2000-2003, Intel Corporation 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without modification, 00008 * are permitted provided that the following conditions are met: 00009 * 00010 * Redistributions of source code must retain the above copyright notice, this list 00011 * of conditions and the following disclaimer. 00012 * 00013 * Redistributions in binary form must reproduce the above copyright notice, this list 00014 * of conditions and the following disclaimer in the documentation and/or other materials 00015 * provided with the distribution. 00016 * 00017 * Neither the name of the owner nor the names of its contributors may be used to endorse or 00018 * promote products derived from this software without specific prior written permission. 00019 * 00020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 00021 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 00022 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR 00023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 00024 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 00025 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00026 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00027 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00028 * 00029 */ 00030 00031 #include "scheduler.h" 00032 #include "sched_spec_itf.h" 00033 00034 /* ====================================================================== 00035 * ====================================================================== 00036 * 00037 * Module sched_spec_itf.cxx 00038 * 00039 * $Revision: 1.1.1.1 $ 00040 * $Date: 2005/10/21 19:00:00 $ 00041 * $Author: marcel $ 00042 * 00043 * Description: 00044 * ============ 00045 * 00046 * This module serves as handshake between scheduler and speculation- 00047 * package src/osprey1.0/be/cg/orc_intel/{speculation.*,recovery.*} 00048 * 00049 * We centralize all workarounds to spec-package here to prevent it 00050 * from scattering anywhere in scheduling phase. 00051 * 00052 * ====================================================================== 00053 * ====================================================================== 00054 */ 00055 00056 00057 00058 /* ==================================================================== 00059 * 00060 * Change_Load_Spec_Form 00061 * 00062 * Change load to be speculative form IF NECESSARY. 00063 * This function do some ugly things for Commit_Schedule(), whichby 00064 * to keep Commit_Schedule() concise. 00065 * 00066 * 00067 * - return FALSE if <cand> remains unchanged, TRUE otherwise. 00068 * 00069 * - Insert_chk is set TRUE, if extra chk instruction is required. 00070 * We need not to point out which kind of chk is expected, 00071 * since spec-package is highly adaptive -- the author of 00072 * spec-package told me so, but I have not examine how it work. 00073 * 00074 * - ***** <cutting_set_size> **** 00075 * cutting_set_size = (the number of compensation blocks + 1). 00076 * Here, "1" corresponds to the target block(or,<_target_bb>) 00077 * 00078 * The seem-to-be-extraneous parameter is required by the 00079 * spec-package to determine the final form the load: if 00080 * cutting-set_size > 1, this function will uniformaly 00081 * change the <cand> to be the form of *.sa reguardless 00082 * the spec-type of <cand> is cntl-spec or data-spec unless 00083 * <IPFEC_Enable_Data_Speculation> is turned off. 00084 * 00085 * There are much painful experence of this little function which 00086 * serve as (a part of) handshake between scheduler and spec-package 00087 * (speculation.{cxx,h}, recovery.{cxx,h}). 00088 * 00089 * ==================================================================== 00090 */ 00091 BOOL 00092 SCHED_SPEC_HANDSHAKE :: Change_Load_Spec_Form 00093 (CANDIDATE* cand, INT32 cutting_set_size, 00094 BOOL* insert_chk, SCHEDULER* sched, 00095 ISA_ENUM_CLASS_VALUE* ldform, /* the form <cand> should be changed to*/ 00096 BOOL test /*if TRUE, don't do actual transform upon <cand>*/) { 00097 00098 *insert_chk = FALSE; 00099 if (ldform) {*ldform = ECV_UNDEFINED;}; 00100 00101 /* (a): rule out cases that need not transform 00102 */ 00103 OP* op = cand->Op (); 00104 if (!OP_load(op) || !cand->Is_Spec ()) { 00105 return FALSE; /* obviously */ 00106 } 00107 00108 // fix bug no. OSP_76 for implicit use of Actuals 00109 for (OP* prev_op = OP_prev(op); prev_op; prev_op = OP_prev(prev_op)){ 00110 if (!OP_Scheduled(prev_op) && OP_ANNOT_OP_Def_Actual_Para (prev_op)) 00111 return FALSE; 00112 } 00113 00114 /* ignore some speculation type since they do not entail transformation 00115 * up the given load. 00116 */ 00117 SPEC_TYPE spec_type = cand->Spec_Type(); 00118 if (OP_no_alias (op)) { 00119 spec_type = SPEC_TYPE(spec_type & ~SPEC_DATA); 00120 } 00121 if (SPEC_TYPE(spec_type & SPEC_CNTL) == SPEC_CNTL && 00122 Load_Has_Valid_Vaddr (op)) { 00123 spec_type = SPEC_TYPE(spec_type & ~SPEC_CNTL); 00124 } 00125 if (spec_type == SPEC_NONE) { 00126 return FALSE; 00127 } 00128 00129 Is_True (!OP_Can_not_be_Candidate (op, spec_type), 00130 ("Load cannot be further speculated due to some limitations")); 00131 00132 if (CGTARG_Is_OP_Speculative(op) || 00133 CGTARG_Is_OP_Advanced_Load (op) || 00134 CGTARG_Is_OP_Check_Load (op)) { 00135 /* OP_Can_not_be_Candidate () guarantees that 00136 * a cntl/data speculated but not data/cntl speculated load 00137 * cannot be further data/cntl speculated. and 00138 * a check load cannot be further speculatd. 00139 */ 00140 return FALSE; 00141 } 00142 00143 /* (b): tranform to .sa IF NECESSARY 00144 */ 00145 BOOL to_dot_sa_form = (spec_type == SPEC_COMB); 00146 00147 if (IPFEC_Enable_Data_Speculation && !OP_no_alias(op)) { 00148 /* In this case, a single load may be speculated to multiple 00149 * paths, causing a bunch of speculative loads. They share one 00150 * common check, either chk.s or chk.a. Once the spec_type is 00151 * fixed at a pure cntl_spec, we should insert a chk.s. According 00152 * to the reason described in line 109, we should gurantee those 00153 * control speculative load being not speculated across any store. 00154 * We can't make sure this and, further, we may lose many data 00155 * speculation opportunities. So, I decide to give them a cntl&data 00156 * speculative form. Hence, they can be speculated across "any" 00157 * instructions. 00158 */ 00159 if (cutting_set_size > 1) { 00160 to_dot_sa_form = TRUE; 00161 } 00162 } 00163 00164 if (to_dot_sa_form) { 00165 // need not insert check for a speculative load again. 00166 *insert_chk = TRUE; 00167 00168 if (ldform) { 00169 *ldform = OP_Is_Float_Mem(op) ? ECV_fldtype_sa: ECV_ldtype_sa; 00170 } 00171 00172 if (!test) { 00173 Change_ld_Form (op, OP_Is_Float_Mem(op) ? 00174 ECV_fldtype_sa: ECV_ldtype_sa); 00175 } 00176 return TRUE; 00177 } 00178 00179 Is_True (spec_type != SPEC_COMB, 00180 ("sepculation type can't be SPEC_COMB")); 00181 00182 /* (c): transform to .a IF NECESSARY 00183 */ 00184 if (spec_type & SPEC_DATA) { 00185 if (ldform) { 00186 *ldform = OP_Is_Float_Mem(op) ? ECV_fldtype_a: ECV_ldtype_a; 00187 } 00188 if (!test) { 00189 Change_ld_Form(op, OP_Is_Float_Mem(op) ? ECV_fldtype_a: ECV_ldtype_a); 00190 } 00191 return *insert_chk = TRUE; 00192 } 00193 00194 /* (d): transform to .s IF NECESSARY 00195 */ 00196 Is_True (spec_type & SPEC_CNTL, 00197 ("speculation type should be SPEC_CNTL")); 00198 00199 if (cutting_set_size == 1 && cand->Is_M_Ready () && 00200 Is_Control_Speculation_Gratuitous 00201 (op, sched->_target_bb, sched->_frontier_op)) { 00202 /* Why this condition? 00203 * ld ..=[r4] 00204 * ld.s ..=[r4] 00205 * the second load can be a safe load. 00206 */ 00207 return FALSE; 00208 } 00209 00210 if (ldform) *ldform = OP_Is_Float_Mem(op) ? ECV_fldtype_s : ECV_ldtype_s; 00211 if (!test) { 00212 Change_ld_Form(op, OP_Is_Float_Mem(op) ? ECV_fldtype_s : ECV_ldtype_s); 00213 } 00214 return *insert_chk = TRUE; 00215 } 00216 00217 /* ==================================================================== 00218 * 00219 * OP_Can_not_be_Candidate 00220 * 00221 * This function encapsulate the limitations of speculation supporting 00222 * routings for the scheduler. Currently, following scenarios are not 00223 * supported by speculation supporting routines. As GanGe told me, one 00224 * of the reasons is that it is hard to update the speculative chain. 00225 * The scenarios are: 00226 * 00227 * - a data speculated but not control speculated load is going to 00228 * be control speculated. 00229 * - a control speculated but not data speculatd load is going to be 00230 * data speculatd. 00231 * - a check-load cannot be further data or control speculated. 00232 * 00233 * This function return TRUE iff the one of above scenarios are met. 00234 * The input parameter <spec> specify how the load <op> is further 00235 * speculated. 00236 * 00237 * ==================================================================== 00238 */ 00239 BOOL 00240 SCHED_SPEC_HANDSHAKE :: OP_Can_not_be_Candidate (OP* op, SPEC_TYPE spec_type) { 00241 00242 if (!OP_load (op) || spec_type == SPEC_NONE) { 00243 return FALSE; 00244 } 00245 00246 /* Get load's current form */ 00247 BOOL in_cntl_spec_form = CGTARG_Is_OP_Speculative_Load(op); 00248 BOOL in_data_spec_form = CGTARG_Is_OP_Advanced_Load(op); 00249 BOOL is_check_ld = CGTARG_Is_OP_Check_Load(op); 00250 00251 if (!in_cntl_spec_form && !in_data_spec_form && !is_check_ld) { 00252 return FALSE; 00253 } 00254 00255 if (is_check_ld) { 00256 /* a check load cannot be further speculated */ 00257 return TRUE; 00258 } 00259 00260 /* ignore data or control specultion if it does not entail 00261 * transformation upon the load. 00262 */ 00263 if (OP_no_alias (op)) { 00264 spec_type = SPEC_TYPE(spec_type & ~SPEC_DATA); 00265 } 00266 00267 if (SPEC_TYPE(spec_type & SPEC_CNTL) == SPEC_CNTL && 00268 Load_Has_Valid_Vaddr (op)) { 00269 spec_type = SPEC_TYPE(spec_type & ~SPEC_CNTL); 00270 } 00271 00272 BOOL to_be_cntl_spec = (spec_type == SPEC_CNTL || 00273 spec_type == SPEC_COMB); 00274 BOOL to_be_data_spec = (spec_type == SPEC_DATA || 00275 spec_type == SPEC_COMB); 00276 00277 if (!in_cntl_spec_form && to_be_cntl_spec || 00278 !in_data_spec_form && to_be_data_spec) { 00279 return TRUE; 00280 } 00281 00282 return FALSE; 00283 }
1.5.6