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 #include "cgtarget.h" 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 $ 00040 * $Date: 2005/12/30 01:50:23 $ 00041 * $Author: weitang $ 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 * Change_Load_Spec_Form 00060 * 00061 * Change load to be speculative form IF NECESSARY. 00062 * This function do some ugly things for Commit_Schedule(), whichby 00063 * to keep Commit_Schedule() concise. 00064 * 00065 * 00066 * - return FALSE if <cand> remains unchanged, TRUE otherwise. 00067 * 00068 * - Insert_chk is set TRUE, if extra chk instruction is required. 00069 * We need not to point out which kind of chk is expected, 00070 * since spec-package is highly adaptive -- the author of 00071 * spec-package told me so, but I have not examine how it work. 00072 * 00073 * - ***** <cutting_set_size> **** 00074 * cutting_set_size = (the number of compensation blocks + 1). 00075 * Here, "1" corresponds to the target block(or,<_target_bb>) 00076 * 00077 * The seem-to-be-extraneous parameter is required by the 00078 * spec-package to determine the final form the load: if 00079 * cutting-set_size > 1, this function will uniformaly 00080 * change the <cand> to be the form of *.sa reguardless 00081 * the spec-type of <cand> is cntl-spec or data-spec unless 00082 * <IPFEC_Enable_Data_Speculation> is turned off. 00083 * 00084 * There are much painful experence of this little function which 00085 * serve as (a part of) handshake between scheduler and spec-package 00086 * (speculation.{cxx,h}, recovery.{cxx,h}). It has ever create 00087 * 10**10000 bugs. change that number if you ever encounter one. 00088 * 10**10000++, 5/20/2003 00089 * 00090 * ==================================================================== 00091 */ 00092 BOOL 00093 SCHED_SPEC_HANDSHAKE :: Change_Load_Spec_Form 00094 (CANDIDATE* cand, INT32 cutting_set_size, 00095 BOOL* insert_chk, SCHEDULER* sched) { 00096 00097 #if !defined(TARG_IA64) 00098 *insert_chk = FALSE; 00099 00100 /* suppress compilation complain */ 00101 cand = cand; 00102 cutting_set_size = cutting_set_size; 00103 sched = sched; 00104 return FALSE; 00105 #else 00106 *insert_chk = FALSE; 00107 00108 /* (a): rule out cases that need not transform 00109 */ 00110 OP* op = cand->Op (); 00111 if (!OP_load(op) || !cand->Is_Spec ()) { 00112 return FALSE; /* obviously */ 00113 } 00114 00115 if (CGTARG_Is_OP_Speculative_Load(op)) { 00116 /* What about ld.s => ld.sa ? 00117 * 00118 * For ld.s: we can not 00119 * if you have a ld.s, you should have a chk.s and 00120 * a speculative chain between them. if you want to change 00121 * ld.s to ld.sa, you should change chk.s to chk.a at the 00122 * same time. This may not be difficult. But how about the 00123 * speculative chain? It is not easy to despeculate all 00124 * OPs on the speculative chain and control-speculate 00125 * them again. 00126 * 00127 * For ld.sa: we need not 00128 * need not transform a ld.sa 00129 */ 00130 return FALSE; 00131 } 00132 00133 if (CGTARG_Is_OP_Check_Load(op)) { 00134 /* What about ld.a => ld.sa ? 00135 * Can never meet ld.c here. 00136 */ 00137 return FALSE; 00138 } 00139 00140 SPEC_TYPE spec_type = cand->Spec_Type (); 00141 if ((spec_type & SPEC_DATA) && OP_no_alias(op)) { 00142 DevWarn ("data speculate no_alias OP[%d] of BB:%d", 00143 OP_map_idx(op), BB_id(OP_bb(op))); 00144 spec_type = SPEC_TYPE(spec_type & SPEC_CNTL); /* remove SPEC_DATA */ 00145 } 00146 00147 00148 if (Load_Has_Valid_Vaddr (op) && !(spec_type & SPEC_DATA)) { 00149 /* load always has valid virtual address and it 00150 * does not being moved beyond any aliasing stores. 00151 * 00152 * NOTE: Load_Has_Valid_Vaddr () does not imply that no OPs 00153 * alias with this op. 00154 */ 00155 return FALSE; 00156 } 00157 00158 /* (b): tranform to .sa IF NECESSARY 00159 */ 00160 BOOL to_dot_sa_form = (spec_type == SPEC_COMB); 00161 00162 if (IPFEC_Enable_Data_Speculation && !OP_no_alias(op)) { 00163 /* In this case, a single load may be speculated to multiple 00164 * paths, causing a bunch of speculative loads. They share one 00165 * common check, either chk.s or chk.a. Once the spec_type is 00166 * fixed at a pure cntl_spec, we should insert a chk.s. According 00167 * to the reason described in line 109, we should gurantee those 00168 * control speculative load being not speculated across any store. 00169 * We can't make sure this and, further, we may lose many data 00170 * speculation opportunities. So, I decide to give them a cntl&data 00171 * speculative form. Hence, they can be speculated across "any" 00172 * instructions. 00173 */ 00174 if (cutting_set_size > 1) { 00175 to_dot_sa_form = TRUE; 00176 } 00177 } 00178 00179 if (to_dot_sa_form) { 00180 // need not insert check for a speculative load again. 00181 if (!CGTARG_Is_OP_Speculative(op)) { 00182 *insert_chk = TRUE; 00183 } 00184 Change_ld_Form(op, ECV_ldtype_sa); 00185 return TRUE; 00186 } 00187 00188 Is_True (spec_type != SPEC_COMB, 00189 ("sepculation type can't be SPEC_COMB")); 00190 00191 /* (c): transform to .a IF NECESSARY 00192 */ 00193 if (spec_type & SPEC_DATA) { 00194 if (!CGTARG_Is_OP_Advanced_Load(op)) { 00195 Change_ld_Form(op, ECV_ldtype_a); 00196 return *insert_chk = TRUE; 00197 } else { 00198 /* already in *.a form */ 00199 return FALSE; 00200 } 00201 } 00202 00203 /* (d): transform to .s IF NECESSARY 00204 */ 00205 Is_True (spec_type & SPEC_CNTL, 00206 ("speculation type should be SPEC_CNTL")); 00207 00208 if (CGTARG_Is_OP_Speculative (op)) { 00209 /* already in .s form */ 00210 return FALSE; 00211 } 00212 00213 if (cutting_set_size == 1 && cand->Is_M_Ready () && 00214 Is_Control_Speculation_Gratuitous 00215 (op, sched->_target_bb, sched->_frontier_op)) { 00216 /* Why this condition? 00217 * ld ..=[r4] 00218 * ld.s ..=[r4] 00219 * the second load can be a safe load. 00220 */ 00221 return FALSE; 00222 } 00223 00224 Change_ld_Form(op, ECV_ldtype_s); 00225 return *insert_chk = TRUE; 00226 #endif 00227 } 00228 00229 BOOL 00230 SCHED_SPEC_HANDSHAKE :: OP_Can_not_be_Candidate 00231 (OP* op, SPEC_TYPE spec_ty) { 00232 #ifdef TARG_IA64 00233 if ((spec_ty & SPEC_DATA) && OP_load(op) && 00234 CGTARG_Is_OP_Speculative_Load (op) && 00235 !CGTARG_Is_OP_Advanced_Load (op)) { 00236 return TRUE; 00237 } 00238 return FALSE; 00239 #else 00240 if (spec_ty & SPEC_DATA || 00241 (spec_ty & SPEC_CNTL) && CGTARG_Can_Be_Speculative(op)) { 00242 return TRUE; 00243 } 00244 00245 return FALSE; 00246 #endif 00247 }
1.5.6