|
OpenADFortTk (basic)
|
00001 // -*-Mode: C++;-*- 00002 // $Header: /Volumes/cvsrep/developer/OpenADFortTk/src/xaif2whirl/XlateStmt.cxx,v 1.2 2006/05/12 16:12:24 utke Exp $ 00003 #include <stdlib.h> // ANSI: cstdlib // for strtol 00004 #include <string.h> // ANSI: cstring // for strcmp, etc. 00005 #include <iostream> 00006 00007 #include <xercesc/dom/DOMDocument.hpp> 00008 #include <xercesc/dom/DOMNode.hpp> 00009 #include <xercesc/dom/DOMElement.hpp> 00010 00011 #include "Open64IRInterface/Open64BasicTypes.h" 00012 #include "Open64IRInterface/Open64IRInterface.hpp" 00013 #include "Open64IRInterface/SymTab.h" 00014 #include "Open64IRInterface/wn_attr.h" 00015 #include "Open64IRInterface/stab_attr.h" 00016 00017 #include <WhirlIDMaps.h> 00018 #include <XAIFStrings.h> 00019 #include "Diagnostics.h" 00020 00021 #include "xaif2whirl.h" 00022 #include "XlateStmt.h" 00023 #include "XlateExpression.h" 00024 #include "XAIF_DOMFilters.h" 00025 #include "XercesStrX.h" 00026 00027 00028 namespace xaif2whirl { 00029 00030 WN* XlateStmt::translateStmt(const DOMElement* stmt, 00031 PUXlationContext& ctxt) { 00032 WN* wn = NULL; 00033 const XMLCh* name = stmt->getNodeName(); 00034 if (XMLString::equals(name, XAIFStrings.elem_Assign_x())) { 00035 wn = xlate_Assignment(stmt, ctxt); 00036 } 00037 else if (XMLString::equals(name, XAIFStrings.elem_LpInit_x()) || 00038 XMLString::equals(name, XAIFStrings.elem_LpUpdate_x())) { 00039 wn = translateAssignmentSimple(stmt, ctxt); 00040 } 00041 else if (XMLString::equals(name, XAIFStrings.elem_SubCall_x())) { 00042 wn = xlate_SubroutineCall(stmt, ctxt); 00043 } 00044 else if (XMLString::equals(name, XAIFStrings.elem_InlinableSubCall_x())) { 00045 wn = xlate_InlinableSubroutineCall(stmt, ctxt); 00046 } 00047 else if (XMLString::equals(name, XAIFStrings.elem_Marker_x())) { 00048 // nothing 00049 } 00050 else if (XMLString::equals(name, XAIFStrings.elem_DerivProp_x())) { 00051 wn = xlate_DerivativePropagator(stmt, ctxt); 00052 } 00053 else { 00054 FORTTK_DIE("Unknown XAIF statement:\n" << *stmt); 00055 } 00056 return wn; 00057 } 00058 00059 WN* XlateStmt::translateAssignmentSimple(const DOMElement* elem, 00060 PUXlationContext& ctxt) { 00061 DOMElement* lhs_elem = GetChildElement(elem, XAIFStrings.elem_AssignLHS_x()); 00062 DOMElement* rhs_elem = GetChildElement(elem, XAIFStrings.elem_AssignRHS_x()); 00063 DOMElement* lhsref = GetFirstChildElement(lhs_elem); 00064 std::pair<ST*, WN_OFFSET> lhspair = XlateExpression::translateVarRefSimple(lhsref, ctxt); 00065 ST* lhsst = lhspair.first; 00066 WN_OFFSET lhsoset = lhspair.second; 00067 ctxt.createXlationContext(XlationContext::EXPRSIMPLE); 00068 WN* rhs = xlate_AssignmentRHS(rhs_elem, ctxt); 00069 ctxt.deleteXlationContext(); 00070 WN* wn = createAssignment(lhsst, lhsoset, rhs); 00071 return wn; 00072 } 00073 00074 WN* XlateStmt::patchWNStmt(WN* wn, 00075 PUXlationContext& ctxt) { 00076 WN* patchedWN = NULL; 00077 OPERATOR opr = WN_operator(wn); 00078 if (opr == OPR_IO) { 00079 patchWN_IO(wn, ctxt); 00080 patchedWN = wn; 00081 } 00082 else if (OPERATOR_is_call(opr)) { 00083 // FIXME: for now, no need to do anything. all calls are active 00084 // and all arguments are variables 00085 } 00086 else if (OPERATOR_is_store(opr) && opr!=OPR_PSTORE && opr!=OPR_PSTID) { 00087 patchedWN = XlateExpression::patchWNExpr(wn, 0 /* kid */, ctxt); 00088 } 00089 return patchedWN; 00090 } 00091 00092 WN* XlateStmt::xlate_Assignment(const DOMElement* elem, 00093 PUXlationContext& ctxt) { 00094 DOMElement* lhs_elem = GetChildElement(elem, XAIFStrings.elem_AssignLHS_x()); 00095 DOMElement* rhs_elem = GetChildElement(elem, XAIFStrings.elem_AssignRHS_x()); 00096 ctxt.createXlationContext(XlationContext::NOFLAG); 00097 WN* lhs = xlate_AssignmentLHS(lhs_elem, ctxt); 00098 WN* rhs = xlate_AssignmentRHS(rhs_elem, ctxt); 00099 ctxt.deleteXlationContext(); 00100 // Special case to handle PREGS 00101 WN* wn = NULL; 00102 if (WN_operator(lhs) == OPR_LDID && ST_class(WN_st(lhs)) == CLASS_PREG) { 00103 wn = createAssignment(WN_st(lhs), WN_load_offset(lhs), rhs); 00104 WN_Delete(lhs); // not recursive 00105 } else { 00106 wn = createAssignment(lhs, rhs); 00107 } 00108 return wn; 00109 } 00110 00111 WN* XlateStmt::xlate_AssignmentLHS(const DOMElement* elem, 00112 PUXlationContext& ctxt) { 00113 // VariableReferenceType 00114 bool deriv = GetDerivAttr(elem); 00115 DOMElement* varref = GetFirstChildElement(elem); 00116 ctxt.createXlationContext((deriv) ? XlationContext::DERIVSELECTOR : XlationContext::VALUESELECTOR); 00117 ctxt.currentXlationContext().setFlag(XlationContext::LVALUE); 00118 WN* wn = XlateExpression::translateVarRef(varref, ctxt); 00119 ctxt.deleteXlationContext(); 00120 return wn; 00121 } 00122 00123 WN* XlateStmt::xlate_AssignmentRHS(const DOMElement* elem, 00124 PUXlationContext& ctxt) { 00125 // ExpressionType 00126 DOMElement* child = GetFirstChildElement(elem); 00127 ctxt.createXlationContext(XlationContext::NOFLAG); 00128 WN* wn = XlateExpression::translateExpression(child, ctxt); 00129 ctxt.deleteXlationContext(); 00130 return wn; 00131 } 00132 00133 WN* XlateStmt::xlate_SubroutineCall(const DOMElement* elem, 00134 PUXlationContext& ctxt) { 00135 // ------------------------------------------------------- 00136 // 1. Gather the arguments, sorted by "position" attribute and 00137 // translate them into a WHIRL expression tree. 00138 // ------------------------------------------------------- 00139 unsigned int numArgs = GetIntAttr(elem, XAIFStrings.attr_formalArgCount_x(), 0 /* default */); 00140 unsigned int numiArgs = 0; // implicit args 00141 std::vector<std::pair<WN*,fortTkSupport::SymId > > 00142 args_wn(numArgs, std::pair<WN*,fortTkSupport::SymId > (NULL,NULL)); 00143 for (DOMElement* arg = GetFirstChildElement(elem); (arg); 00144 arg = GetNextSiblingElement(arg)) { 00145 // VariableReferenceType 00146 const XMLCh* nmX = arg->getNodeName(); 00147 FORTTK_ASSERT(XMLString::equals(nmX, XAIFStrings.elem_Argument_x()), 00148 "Expected " << XAIFStrings.elem_Argument() << "; found:\n" 00149 << *arg); 00150 unsigned int pos = GetPositionAttr(arg); // 1-based 00151 FORTTK_ASSERT(1 <= pos && pos <= numArgs, 00152 "Unexpected position attribute value:\n" << *arg << " out of range [1," << numArgs << "]"); 00153 fortTkSupport::SymId symId = GetSymId(arg); 00154 if (symId) // non-zero for a keyword Argument 00155 args_wn[pos-1].second=symId; 00156 // Note: We do *not* check the deriv flag; any active variable 00157 // references should be passed as is. 00158 DOMElement* argExpr = GetFirstChildElement(arg); 00159 // this one can be a VariableReference or a Constant 00160 // figure out which it is: 00161 const XMLCh* nameArgExpr = argExpr->getNodeName(); 00162 if (XMLString::equals(nameArgExpr, XAIFStrings.elem_VarRef_x())) { 00163 DOMElement* varRef = GetFirstChildElement(argExpr); 00164 ctxt.createXlationContext(XlationContext::DERIVSELECTOR); 00165 WN* varRefWN = XlateExpression::translateVarRef(varRef, ctxt); 00166 ctxt.deleteXlationContext(); 00167 args_wn[pos - 1].first = varRefWN; 00168 // Determine whether WHIRL needs an implicit argument 00169 // (cf. WN2F_call() in wn2f_stmt.cxx) 00170 TY_IDX ty = WN_Tree_Type(varRefWN); 00171 if (TY_Is_Character_Reference(ty) || TY_Is_Chararray_Reference(ty)) { 00172 numiArgs++; 00173 } 00174 } 00175 else if (XMLString::equals(nameArgExpr, XAIFStrings.elem_Constant_x())) { 00176 ctxt.createXlationContext(XlationContext::DERIVSELECTOR); 00177 WN* constWN = XlateExpression::translateConstant(argExpr, ctxt); 00178 ctxt.deleteXlationContext(); 00179 args_wn[pos - 1].first = constWN; 00180 // Determine whether WHIRL needs an implicit argument 00181 // (cf. WN2F_call() in wn2f_stmt.cxx) 00182 TY_IDX ty = WN_Tree_Type(constWN); 00183 if (TY_Is_Character_Reference(ty) || TY_Is_Chararray_Reference(ty)) { 00184 numiArgs++; 00185 } 00186 } 00187 else { 00188 FORTTK_DIE("Unknown XAIF subroutine call argument:\n" << *argExpr); 00189 } 00190 } 00191 // ------------------------------------------------------- 00192 // 2. Gather WHIRL implicit arguments (e.g., for strings) 00193 // ------------------------------------------------------- 00194 std::vector<WN*> iargs_wn(numiArgs, NULL); 00195 for (unsigned i = 0; i < numiArgs; ++i) { 00196 // Create bogus values, knowing that we only want to unparse the WHIRL 00197 iargs_wn[i] = WN_CreateIntconst(OPC_I4INTCONST, 0); // a white lie 00198 } 00199 // ------------------------------------------------------- 00200 // 3. Create function call 00201 // ------------------------------------------------------- 00202 TYPE_ID rtype = MTYPE_V; // void type for subroutine call 00203 fortTkSupport::Symbol* sym = GetSymbol(elem, ctxt); 00204 WN* callWN = WN_Call(rtype, MTYPE_V, numArgs + numiArgs, sym->GetST()); 00205 WN_Set_Call_Default_Flags(callWN); // set conservative assumptions 00206 for (unsigned i = 0; i < numArgs; ++i) { 00207 if (args_wn[i].first) { 00208 // conservatively assume pass by reference 00209 WN_actual(callWN, i) = CreateParm(args_wn[i].first, WN_PARM_BY_REFERENCE); 00210 if (args_wn[i].second) { 00211 WN_actual(callWN, i)->u3.ty_fields.ty=args_wn[i].second; 00212 } 00213 } 00214 } 00215 for (unsigned i = 0, j = numArgs; i < numiArgs; ++i, ++j) { 00216 WN_actual(callWN, j) = CreateParm(iargs_wn[i], WN_PARM_BY_VALUE); 00217 } 00218 return callWN; 00219 } 00220 00221 WN* XlateStmt::xlate_InlinableSubroutineCall(const DOMElement* elem, 00222 PUXlationContext& ctxt) { 00223 // FIXME: abstract with above code 00224 // ------------------------------------------------------- 00225 // 1. Gather the arguments, sorted by "position" attribute and 00226 // translate them into a WHIRL expression tree. 00227 // ------------------------------------------------------- 00228 unsigned int numArgs = GetChildElementCount(elem); 00229 std::vector<WN*> args_wn(numArgs); 00230 for (DOMElement* arg = GetFirstChildElement(elem); (arg); 00231 arg = GetNextSiblingElement(arg) ) { 00232 // VariableReferenceType 00233 const XMLCh* nmX = arg->getNodeName(); 00234 FORTTK_ASSERT(XMLString::equals(nmX, XAIFStrings.elem_Argument_x()), 00235 "Expected " << XAIFStrings.elem_Argument() 00236 << "; found\n" << *arg); 00237 unsigned int pos = GetPositionAttr(arg); // 1-based 00238 FORTTK_ASSERT(1 <= pos, "Unexpected position attribute:\n" << *arg); 00239 if (pos > args_wn.size()) { args_wn.resize(pos); } // must resize 00240 // Note: We do *not* check the deriv flag; any active variable 00241 // references should be passed as is. 00242 DOMElement* argExpr = GetFirstChildElement(arg); 00243 // this one can be a VariableReference or a Constant 00244 // figure out which it is: 00245 const XMLCh* nameArgExpr = argExpr->getNodeName(); 00246 if (XMLString::equals(nameArgExpr, XAIFStrings.elem_VarRef_x())) { 00247 DOMElement* varRef = GetFirstChildElement(argExpr); 00248 ctxt.createXlationContext(XlationContext::DERIVSELECTOR); 00249 WN* varRefWN = XlateExpression::translateVarRef(varRef, ctxt); 00250 ctxt.deleteXlationContext(); 00251 args_wn[pos - 1] = varRefWN; 00252 } 00253 else if (XMLString::equals(nameArgExpr, XAIFStrings.elem_Constant_x())) { 00254 ctxt.createXlationContext(XlationContext::DERIVSELECTOR); 00255 WN* constWN = XlateExpression::translateConstant(argExpr, ctxt); 00256 ctxt.deleteXlationContext(); 00257 args_wn[pos - 1] = constWN; 00258 } 00259 else { 00260 FORTTK_DIE("Unknown XAIF subroutine call argument:\n" << *argExpr); 00261 } 00262 } 00263 // ------------------------------------------------------- 00264 // 2. Create block containing OpenAD pragma and call 00265 // ------------------------------------------------------- 00266 const XMLCh* subnameX = elem->getAttribute(XAIFStrings.attr_subname_x()); 00267 XercesStrX subname = XercesStrX(subnameX); 00268 // Create OpenAD pragma (locate before creating placeholder nodes!) 00269 WN* comWN = createOpenADInline(subname.c_str(), args_wn); 00270 // Create placeholder nodes for arguments not found above 00271 for (unsigned int i = 0; i < args_wn.size(); ++i) { 00272 if (!args_wn[i]) { 00273 fortTkSupport::Symbol* sym = GetOrCreateBogusTmpSymbol(ctxt); 00274 ST* st = sym->GetST(); 00275 TYPE_ID rty = ST_mtype(st), dty = ST_mtype(st); 00276 args_wn[i] = WN_CreateLdid(OPR_LDID, rty, dty, 0, st, ST_type(st), 0); 00277 } 00278 } 00279 // Create call (with placeholder nodes) 00280 TYPE_ID rtype = MTYPE_V; // void type for subroutine call 00281 WN* callWN = CreateCallToIntrin(rtype, subname.c_str(), args_wn); 00282 WN* blkWN = WN_CreateBlock(); 00283 WN_INSERT_BlockFirst(blkWN, comWN); 00284 WN_INSERT_BlockLast(blkWN, callWN); 00285 return blkWN; 00286 } 00287 00288 WN* XlateStmt::xlate_DerivativePropagator(const DOMElement* elem, 00289 PUXlationContext& ctxt) { 00290 WN* blckWN = WN_CreateBlock(); 00291 // Accumulate derivative propagator statements and add to block 00292 XAIF_DerivPropStmt filt; 00293 for (DOMElement* stmt = GetChildElement(elem, &filt); 00294 (stmt); stmt = GetNextSiblingElement(stmt, &filt)) { 00295 WN* wn = NULL; 00296 if (XAIF_DerivPropStmt::IsSetDeriv(stmt)) { 00297 wn = xlate_SetDeriv(stmt, ctxt); 00298 } 00299 else if (XAIF_DerivPropStmt::IsSetNegDeriv(stmt)) { 00300 wn = xlate_SetNegDeriv(stmt, ctxt); 00301 } 00302 else if (XAIF_DerivPropStmt::IsIncDeriv(stmt)) { 00303 wn = xlate_IncDeriv(stmt, ctxt); 00304 } 00305 else if (XAIF_DerivPropStmt::IsDecDeriv(stmt)) { 00306 wn = xlate_DecDeriv(stmt, ctxt); 00307 } 00308 else if (XAIF_DerivPropStmt::IsZeroDeriv(stmt) ) { 00309 wn = xlate_ZeroDeriv(stmt, ctxt); 00310 } 00311 else if (XAIF_DerivPropStmt::IsSax(stmt)) { 00312 wn = xlate_Saxpy(stmt, ctxt, false); 00313 } 00314 else if (XAIF_DerivPropStmt::IsSaxpy(stmt) ) { 00315 wn = xlate_Saxpy(stmt, ctxt, true); 00316 } 00317 else { 00318 FORTTK_DIE("Unknown XAIF derivative propagator statement:\n" << *stmt); 00319 } 00320 WN_INSERT_BlockLast(blckWN, wn); 00321 } 00322 // Do not return an empty block 00323 if (WN_first(blckWN) == NULL) { 00324 WN_Delete(blckWN); 00325 blckWN = NULL; 00326 } 00327 return blckWN; 00328 } 00329 00330 WN* XlateStmt::xlate_SetDeriv(const DOMElement* elem, 00331 PUXlationContext& ctxt) { 00332 DOMElement* tgt = GetChildElement(elem, XAIFStrings.elem_Tgt_x()); 00333 DOMElement* src = GetChildElement(elem, XAIFStrings.elem_Src_x()); 00334 // Note: This should always be DERIVSELECTOR (FIXME) 00335 bool deriv = GetDerivAttr(tgt); 00336 ctxt.createXlationContext((deriv) ? XlationContext::DERIVSELECTOR : XlationContext::VALUESELECTOR); 00337 WN* tgtWN = XlateExpression::translateVarRef(GetFirstChildElement(tgt), ctxt); 00338 ctxt.deleteXlationContext(); 00339 // Note: This should always be DERIVSELECTOR (FIXME) 00340 deriv = GetDerivAttr(src); 00341 ctxt.createXlationContext((deriv) ? XlationContext::DERIVSELECTOR : XlationContext::VALUESELECTOR); 00342 WN* srcWN = XlateExpression::translateVarRef(GetFirstChildElement(src), ctxt); 00343 ctxt.deleteXlationContext(); 00344 WN* callWN = CreateCallToIntrin(MTYPE_V, "setderiv", 2); 00345 WN_actual(callWN, 0) = CreateParm(tgtWN, WN_PARM_BY_REFERENCE); 00346 WN_actual(callWN, 1) = CreateParm(srcWN, WN_PARM_BY_VALUE); 00347 return callWN; 00348 } 00349 00350 WN* XlateStmt::xlate_SetNegDeriv(const DOMElement* elem, 00351 PUXlationContext& ctxt) { 00352 DOMElement* tgt = GetChildElement(elem, XAIFStrings.elem_Tgt_x()); 00353 DOMElement* src = GetChildElement(elem, XAIFStrings.elem_Src_x()); 00354 // Note: This should always be DERIVSELECTOR (FIXME) 00355 bool deriv = GetDerivAttr(tgt); 00356 ctxt.createXlationContext((deriv) ? XlationContext::DERIVSELECTOR : XlationContext::VALUESELECTOR); 00357 WN* tgtWN = XlateExpression::translateVarRef(GetFirstChildElement(tgt), ctxt); 00358 ctxt.deleteXlationContext(); 00359 // Note: This should always be DERIVSELECTOR (FIXME) 00360 deriv = GetDerivAttr(src); 00361 ctxt.createXlationContext((deriv) ? XlationContext::DERIVSELECTOR : XlationContext::VALUESELECTOR); 00362 WN* srcWN = XlateExpression::translateVarRef(GetFirstChildElement(src), ctxt); 00363 ctxt.deleteXlationContext(); 00364 WN* callWN = CreateCallToIntrin(MTYPE_V, "set_neg_deriv", 2); 00365 WN_actual(callWN, 0) = CreateParm(tgtWN, WN_PARM_BY_REFERENCE); 00366 WN_actual(callWN, 1) = CreateParm(srcWN, WN_PARM_BY_VALUE); 00367 return callWN; 00368 } 00369 00370 WN* XlateStmt::xlate_IncDeriv(const DOMElement* elem, 00371 PUXlationContext& ctxt) { 00372 DOMElement* tgt = GetChildElement(elem, XAIFStrings.elem_Tgt_x()); 00373 DOMElement* src = GetChildElement(elem, XAIFStrings.elem_Src_x()); 00374 // Note: This should always be DERIVSELECTOR (FIXME) 00375 bool deriv = GetDerivAttr(tgt); 00376 ctxt.createXlationContext((deriv) ? XlationContext::DERIVSELECTOR : XlationContext::VALUESELECTOR); 00377 WN* tgtWN = XlateExpression::translateVarRef(GetFirstChildElement(tgt), ctxt); 00378 ctxt.deleteXlationContext(); 00379 // Note: This should always be DERIVSELECTOR (FIXME) 00380 deriv = GetDerivAttr(src); 00381 ctxt.createXlationContext((deriv) ? XlationContext::DERIVSELECTOR : XlationContext::VALUESELECTOR); 00382 WN* srcWN = XlateExpression::translateVarRef(GetFirstChildElement(src), ctxt); 00383 ctxt.deleteXlationContext(); 00384 WN* callWN = CreateCallToIntrin(MTYPE_V, "inc_deriv", 2); 00385 WN_actual(callWN, 0) = CreateParm(tgtWN, WN_PARM_BY_REFERENCE); 00386 WN_actual(callWN, 1) = CreateParm(srcWN, WN_PARM_BY_VALUE); 00387 return callWN; 00388 } 00389 00390 WN* XlateStmt::xlate_DecDeriv(const DOMElement* elem, 00391 PUXlationContext& ctxt) { 00392 DOMElement* tgt = GetChildElement(elem, XAIFStrings.elem_Tgt_x()); 00393 DOMElement* src = GetChildElement(elem, XAIFStrings.elem_Src_x()); 00394 // Note: This should always be DERIVSELECTOR (FIXME) 00395 bool deriv = GetDerivAttr(tgt); 00396 ctxt.createXlationContext((deriv) ? XlationContext::DERIVSELECTOR : XlationContext::VALUESELECTOR); 00397 WN* tgtWN = XlateExpression::translateVarRef(GetFirstChildElement(tgt), ctxt); 00398 ctxt.deleteXlationContext(); 00399 // Note: This should always be DERIVSELECTOR (FIXME) 00400 deriv = GetDerivAttr(src); 00401 ctxt.createXlationContext((deriv) ? XlationContext::DERIVSELECTOR : XlationContext::VALUESELECTOR); 00402 WN* srcWN = XlateExpression::translateVarRef(GetFirstChildElement(src), ctxt); 00403 ctxt.deleteXlationContext(); 00404 WN* callWN = CreateCallToIntrin(MTYPE_V, "dec_deriv", 2); 00405 WN_actual(callWN, 0) = CreateParm(tgtWN, WN_PARM_BY_REFERENCE); 00406 WN_actual(callWN, 1) = CreateParm(srcWN, WN_PARM_BY_VALUE); 00407 return callWN; 00408 } 00409 00410 WN* XlateStmt::xlate_ZeroDeriv(const DOMElement* elem, 00411 PUXlationContext& ctxt) { 00412 WN* x = xlate_AssignmentLHS(elem, ctxt); // functionally equivalent 00413 WN* callWN = CreateCallToIntrin(MTYPE_V, "zero_deriv", 1); 00414 WN_actual(callWN, 0) = CreateParm(x, WN_PARM_BY_REFERENCE); 00415 return callWN; 00416 } 00417 00418 WN* XlateStmt::xlate_Saxpy(const DOMElement* elem, 00419 PUXlationContext& ctxt, 00420 bool saxpy) { 00421 // count the children 00422 int elemCount=GetChildElementCount(elem); 00423 // create a WHIRL call 00424 const char* fnm = (saxpy) ? "saxpy" : "sax"; 00425 MTYPE rtype = MTYPE_V; 00426 // one child element for 'y'; all other child elements are pairs of 'a' and 'x' 00427 WN* callWN = CreateCallToIntrin(rtype, fnm, 2*(elemCount-1)+1); 00428 int parameterPosition=0; 00429 // get the a/x pairs 00430 DOMElement* aChildElem(GetFirstChildElement(elem)); 00431 while (aChildElem) { 00432 if (XAIF_ElemFilter(XAIFStrings.elem_AX_x()).acceptNode(aChildElem) == DOMNodeFilter::FILTER_ACCEPT) { 00433 DOMElement* theA = GetChildElement(aChildElem, XAIFStrings.elem_A_x()); 00434 DOMElement* theX = GetChildElement(aChildElem, XAIFStrings.elem_X_x()); 00435 // A 00436 WN* a_wn = XlateExpression::translateExpression(GetFirstChildElement(theA), ctxt); 00437 // X 00438 bool deriv = GetDerivAttr(theX); 00439 ctxt.createXlationContext((deriv) ? XlationContext::DERIVSELECTOR : XlationContext::VALUESELECTOR); 00440 WN* x_wn = XlateExpression::translateVarRef(GetFirstChildElement(theX), ctxt); 00441 ctxt.deleteXlationContext(); 00442 // add the parameters 00443 WN_actual(callWN, parameterPosition++) = CreateParm(a_wn, WN_PARM_BY_VALUE); 00444 WN_actual(callWN, parameterPosition++) = CreateParm(x_wn, WN_PARM_BY_VALUE); 00445 } 00446 aChildElem=GetNextSiblingElement(aChildElem); 00447 } 00448 // Y 00449 DOMElement* Y = GetChildElement(elem, XAIFStrings.elem_Y_x()); 00450 bool deriv = GetDerivAttr(Y); 00451 ctxt.createXlationContext((deriv) ? XlationContext::DERIVSELECTOR : XlationContext::VALUESELECTOR); 00452 WN* y_wn = XlateExpression::translateVarRef(GetFirstChildElement(Y), ctxt); 00453 ctxt.deleteXlationContext(); 00454 WN_actual(callWN, parameterPosition) = CreateParm(y_wn, WN_PARM_BY_REFERENCE); 00455 return callWN; 00456 } 00457 00458 void XlateStmt::patchWN_IO(WN* wn, 00459 PUXlationContext& ctxt) { 00460 // FIXME: only handle cray read/write for now 00461 patchWN_IO_cray(wn, ctxt); 00462 } 00463 00464 void XlateStmt::patchWN_IO_cray(WN* wn, 00465 PUXlationContext& ctxt) { 00466 IOSTATEMENT iostmt = WN_io_statement(wn); 00467 FORTTK_ASSERT_WARN(iostmt == IOS_CR_FWF || iostmt == IOS_CR_FWU 00468 || iostmt == IOS_CR_FRF || iostmt == IOS_CR_FRU 00469 || iostmt == IOS_CR_OPEN || iostmt == IOS_CR_CLOSE 00470 || iostmt == IOS_INQUIRE || iostmt == IOS_CR_INQUIRE 00471 || iostmt == IOS_REWIND || iostmt == IOS_CR_REWIND, 00472 fortTkSupport::Diagnostics::UnexpectedInput << IOSTATEMENT_name(iostmt)); 00473 // Iterate over IO_ITEMs and translate IOLs (io lists) 00474 for (INT kidno = 0; kidno < WN_kid_count(wn); ++kidno) { 00475 WN* kid = WN_kid(wn, kidno); 00476 if (IS_IO_ITEM_IOL(kid)) { 00477 patchWN_IO_ITEM_list(kid, ctxt); 00478 } 00479 } 00480 } 00481 00482 void XlateStmt::patchWN_IO_ITEM_list(WN* wn, 00483 PUXlationContext& ctxt) { 00484 // cf. xlate_IO_ITEM_list 00485 IOITEM kind = WN_io_item(wn); 00486 switch (kind) { 00487 case IOL_VAR: 00488 case IOL_ARRAY: 00489 case IOL_RECORD: 00490 XlateExpression::patchWNExpr(wn, 0 /* kid */, ctxt); 00491 break; 00492 case IOL_CHAR_ARRAY: 00493 case IOL_CHAR: // skip 00494 break; 00495 case IOL_EXPR: // patch 00496 XlateExpression::patchWNExpr(wn, 0 /* kid */, ctxt); 00497 break; 00498 case IOL_IMPLIED_DO: // patch 00499 case IOL_IMPLIED_DO_1TRIP: 00500 XlateExpression::patchWNExpr(wn, 2 /* kid */, ctxt); 00501 for (int kid = 4; kid < WN_kid_count(wn); ++kid) { 00502 patchWN_IO_ITEM_list(WN_kid(wn, kid), ctxt); 00503 } 00504 break; 00505 case IOL_LOGICAL: // skip 00506 case IOL_DOPE: // skip 00507 break; 00508 default: 00509 FORTTK_DIE(fortTkSupport::Diagnostics::UnexpectedOpr << IOITEM_name(kind)); 00510 break; 00511 } 00512 } 00513 00514 WN* XlateStmt::createAssignment(WN* lhs, 00515 WN* rhs) { 00516 // We always use ISTORE (instead of e.g. STID) for generality. This 00517 // will not be an issue because the intension is for this WHIRL to 00518 // be translated to source code. 00519 TY_IDX ty = WN_Tree_Type(lhs); // should be a pointer type 00520 TY_IDX rhs_ty = WN_Tree_Type(rhs); 00521 if (TY_is_f90_pointer(rhs_ty) || TY_Is_Pointer(rhs_ty)) 00522 rhs_ty=TY_pointed(rhs_ty); 00523 if (TY_Is_Array(rhs_ty) || TY_Is_Pointer(rhs_ty)) 00524 rhs_ty=TY_etype(rhs_ty); 00525 TYPE_ID dtype = TY_mtype(rhs_ty); 00526 if (dtype == MTYPE_STR) { 00527 dtype = MTYPE_U1; 00528 } 00529 WN* wn = WN_Istore(dtype, 0, ty, lhs, rhs, 0); 00530 return wn; 00531 } 00532 00533 WN* XlateStmt::createAssignment(ST* lhs, 00534 WN_OFFSET oset, 00535 WN* rhs) { 00536 // A special version of the above for situations in which WHIRL 00537 // requires STID assignments (e.g. loop initialization and updates). 00538 TY_IDX ty = WN_Tree_Type(rhs); // referenced-obj = base-obj 00539 WN* wn = WN_Stid(TY_mtype(ty), oset, lhs, ty, rhs, 0); 00540 return wn; 00541 } 00542 00543 WN* XlateStmt::createZeroConst(TYPE_ID ty) { 00544 return Make_Const(Targ_Conv(ty, Host_To_Targ(MTYPE_I4, 0))); 00545 } 00546 00547 WN* XlateStmt::createOpenADInline(const char* fname, 00548 std::vector<WN*>& args) { 00549 // $OpenAD$ INLINE subname(argpos1, argpos2..) 00550 std::string com = "$OpenAD$ INLINE "; 00551 com.reserve(128); 00552 com += fname; 00553 com += "("; 00554 for (unsigned int i = 0; i < args.size(); ++i) { 00555 const char* argdesc = (args[i]) ? "subst" : "nosubst"; 00556 com += argdesc; 00557 if (i < (args.size() - 1)) { com += ","; } 00558 } 00559 com += ")"; 00560 WN* comWN = WN_CreateComment((char*)com.c_str()); 00561 return comWN; 00562 } 00563 }