ExprSynAttr *examineExpr(SgExpression *expr, ostream &out) { stringstream ss1; stringstream ss2; stringstream ss3; SgExpression *e1; SgExpression *e2; SgBinaryOp *binop; SgUnaryOp *unaryop; SgType *type; ExprSynAttr *ret; ExprSynAttr *attr1, *attr2; string tmp_name; string tmp_type; string tmp2_name; string tmp2_type; if (expr == NULL) return NULL; ret = new ExprSynAttr(); attr1 = NULL; attr2 = NULL; switch(expr->variantT()) { /* Begin UnaryOp */ case V_SgMinusOp: out << "(-"; unaryop = isSgUnaryOp(expr); e1 = unaryop->get_operand(); attr1 = examineExpr(e1, out); out << ")"; ret->type = attr1->type; ret->sgtype = attr1->sgtype; ret->new_tmp_name(); ret->add_new_tmp_decl(ret->type, ret->result_var); ret->union_tmp_decls(attr1); ret->code << attr1->code.str(); ret->code << ret->result_var << "= -" << attr1->result_var; ret->code << ";" << endl; break; case V_SgUnaryAddOp: out << "(+"; unaryop = isSgUnaryOp(expr); e1 = unaryop->get_operand(); attr1 = examineExpr(e1, out); out << ")"; ret->type = attr1->type; ret->sgtype = attr1->sgtype; ret->new_tmp_name(); ret->add_new_tmp_decl(ret->type, ret->result_var); ret->union_tmp_decls(attr1); ret->code << attr1->code.str(); ret->code << ret->result_var << "= +" << attr1->result_var; ret->code << ";" << endl; break; case V_SgNotOp: out << "(!"; unaryop = isSgUnaryOp(expr); e1 = unaryop->get_operand(); attr1 = examineExpr(e1, out); out << ")"; ret->type = "int"; ret->sgtype = attr1->sgtype; ret->new_tmp_name(); ret->add_new_tmp_decl(ret->type, ret->result_var); ret->union_tmp_decls(attr1); ret->code << attr1->code.str(); ret->code << ret->result_var << "= (int)!" << attr1->result_var; ret->code << ";" << endl; break; case V_SgPointerDerefExp: out << "(*"; unaryop = isSgUnaryOp(expr); e1 = unaryop->get_operand(); attr1 = examineExpr(e1, out); out << ")"; ret->basetype(attr1); ret->new_tmp_name(); ret->add_new_tmp_decl(ret->type, ret->result_var); ret->union_tmp_decls(attr1); ret->code << attr1->code.str(); ret->code << ret->result_var << "= *" << attr1->result_var; ret->code << ";" << endl; break; case V_SgAddressOfOp: out << "(&"; unaryop = isSgUnaryOp(expr); e1 = unaryop->get_operand(); attr1 = examineExpr(e1, out); out << ")"; ret->type = attr1->type + "*"; /* FIXME ret->sgtype */ ret->new_tmp_name(); ret->add_new_tmp_decl(ret->type, ret->result_var); ret->union_tmp_decls(attr1); ret->code << attr1->code.str(); ret->code << ret->result_var << "= &" << attr1->result_var; ret->code << ";" << endl; break; case V_SgMinusMinusOp: unaryop = isSgUnaryOp(expr); if (unaryop->get_mode()) { out << "("; e1 = unaryop->get_operand(); attr1 = examineExpr(e1, out); out << "--)"; ret->type = attr1->type; ret->sgtype = attr1->sgtype; ret->new_tmp_name(); ret->add_new_tmp_decl(ret->type, ret->result_var); ret->union_tmp_decls(attr1); ret->code << attr1->code.str(); ret->code << ret->result_var << "=" << attr1->result_var << ";" << endl; ret->code << attr1->result_var << "=" << attr1->result_var << "-1;" << endl; } else { out << "(--"; e1 = unaryop->get_operand(); attr1 = examineExpr(e1, out); out << ")"; ret->type = attr1->type; ret->sgtype = attr1->sgtype; ret->result_var = attr1->result_var; ret->union_tmp_decls(attr1); ret->code << attr1->code.str(); ret->code << ret->result_var << "=" << attr1->result_var << "-1;" << endl; } break; case V_SgPlusPlusOp: unaryop = isSgUnaryOp(expr); if (unaryop->get_mode()) { out << "("; e1 = unaryop->get_operand(); attr1 = examineExpr(e1, out); out << "++)"; ret->type = attr1->type; ret->sgtype = attr1->sgtype; ret->new_tmp_name(); ret->add_new_tmp_decl(ret->type, ret->result_var); ret->union_tmp_decls(attr1); ret->code << attr1->code.str(); ret->code << ret->result_var << "=" << attr1->result_var << ";" << endl; ret->code << attr1->result_var << "=" << attr1->result_var << "+1;" << endl; } else { out << "(++"; e1 = unaryop->get_operand(); attr1 = examineExpr(e1, out); out << ")"; ret->type = attr1->type; ret->sgtype = attr1->sgtype; ret->result_var = attr1->result_var; ret->union_tmp_decls(attr1); ret->code << attr1->code.str(); ret->code << ret->result_var << "=" << attr1->result_var << "+1;" << endl; } break; case V_SgBitComplementOp: out << "(~"; unaryop = isSgUnaryOp(expr); e1 = unaryop->get_operand(); attr1 = examineExpr(e1, out); out << ")"; ret->type = attr1->type; ret->sgtype = attr1->sgtype; ret->new_tmp_name(); ret->add_new_tmp_decl(ret->type, ret->result_var); ret->union_tmp_decls(attr1); ret->code << attr1->code.str(); ret->code << ret->result_var << "= ~" << attr1->result_var; ret->code << ";" << endl; break; case V_SgCastExp: { out << "("; SgCastExp *castexp = isSgCastExp(expr); e1 = castexp->get_operand(); type = castexp->get_type(); examineType(type, out); out << ")"; attr1 = examineExpr(e1, out); stringstream casts; examineType(type, casts); ret->type = casts.str(); ret->sgtype = type; ret->new_tmp_name(tmp_name); ret->union_tmp_decls(attr1, NULL); ret->add_new_tmp_decl(ret->type, tmp_name); ret->result_var = tmp_name; ret->code << attr1->code.str() << tmp_name; ret->code << "=(" << ret->type << ")" << attr1->result_var; ret->code << ";" << endl; break; } /* End UnaryOp */ /* Begin BinaryOp */ case V_SgEqualityOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "=="; attr2 = examineExpr(e2, out); out << ")"; ret->type = "int"; ret->sgtype = attr1->sgtype; binop_noassign(ret, attr1, attr2, "=="); break; case V_SgLessThanOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "<"; attr2 = examineExpr(e2, out); out << ")"; ret->type = "int"; ret->sgtype = attr1->sgtype; binop_noassign(ret, attr1, attr2, "<"); break; case V_SgGreaterThanOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << ">"; attr2 = examineExpr(e2, out); out << ")"; ret->type = "int"; ret->sgtype = attr1->sgtype; binop_noassign(ret, attr1, attr2, ">"); break; case V_SgNotEqualOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "!="; attr2 = examineExpr(e2, out); out << ")"; ret->type = "int"; ret->sgtype = attr1->sgtype; binop_noassign(ret, attr1, attr2, "!="); break; case V_SgLessOrEqualOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "<="; attr2 = examineExpr(e2, out); out << ")"; ret->type = "int"; ret->sgtype = attr1->sgtype; binop_noassign(ret, attr1, attr2, "<="); break; case V_SgGreaterOrEqualOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << ">="; attr2 = examineExpr(e2, out); out << ")"; ret->type = "int"; ret->sgtype = attr1->sgtype; binop_noassign(ret, attr1, attr2, ">="); break; case V_SgAddOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "+"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, "+"); break; case V_SgSubtractOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "-"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, "-"); break; case V_SgMultiplyOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "*"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, "*"); break; case V_SgDivideOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "/"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, "/"); break; case V_SgIntegerDivideOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "/"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, "/"); break; case V_SgModOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "%"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, "%"); break; case V_SgAndOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "&&"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); ret->type = "int"; binop_noassign(ret, attr1, attr2, "&&"); break; case V_SgOrOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "||"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); ret->type = "int"; binop_noassign(ret, attr1, attr2, "||"); break; case V_SgBitXorOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "^"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, "^"); break; case V_SgBitAndOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "&"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, "&"); break; case V_SgBitOrOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "|"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, "|"); break; case V_SgCommaOpExp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << ","; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, ","); break; case V_SgLshiftOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "<<"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, "<<"); break; case V_SgRshiftOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << ">>"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, ">>"); break; case V_SgAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret->union_tmp_decls(attr1, attr2); ret->result_var = attr1->result_var; ret->code << attr2->code.str() << attr1->code.str() << ret->result_var; ret->code << "=" << attr2->result_var; ret->code << ";" << endl; break; case V_SgPlusAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "+="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret = binop_assign(ret, attr1, attr2, "+"); break; case V_SgMinusAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "-="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret = binop_assign(ret, attr1, attr2, "-"); break; case V_SgAndAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "&="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret = binop_assign(ret, attr1, attr2, "&"); break; case V_SgIorAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "|="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret = binop_assign(ret, attr1, attr2, "|"); break; case V_SgMultAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "*="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret = binop_assign(ret, attr1, attr2, "*"); break; case V_SgDivAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "/="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret = binop_assign(ret, attr1, attr2, "/"); break; case V_SgModAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "%="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret = binop_assign(ret, attr1, attr2, "%"); break; case V_SgXorAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "^="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret = binop_assign(ret, attr1, attr2, "^"); break; case V_SgLshiftAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "<<="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret = binop_assign(ret, attr1, attr2, "<<"); break; case V_SgRshiftAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << ">>="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret = binop_assign(ret, attr1, attr2, ">>"); break; case V_SgExponentiationOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "ExpUnknown"; attr2 = examineExpr(e2, out); out << ")"; break; case V_SgConcatenationOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "CatUnknown"; attr2 = examineExpr(e2, out); out << ")"; break; case V_SgPntrArrRefExp: { binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "["; attr2 = examineExpr(e2, out); out << "]"; ret->basetype(attr1); ret->union_tmp_decls(attr1, attr2); ret->result_var = attr1->result_var + "[" + attr2->result_var + "]"; ret->code << attr1->code.str() << attr2->code.str(); break; } /* End BinaryOp */ /* Begin variables */ case V_SgVarRefExp: { stringstream casts; SgVarRefExp *varref = isSgVarRefExp(expr); if (NULL == varref) return NULL; SgVariableSymbol *svsym = varref->get_symbol(); if (NULL == svsym) return NULL; out << svsym->get_name().getString(); ret->result_var = svsym->get_name().getString(); examineType(svsym->get_type(), casts); ret->type = casts.str(); ret->sgtype = svsym->get_type(); /* ret->new_tmp_name(); examineType(svsym->get_type(), casts); ret->type = casts.str(); ret->sgtype = svsym->get_type(); ret->add_new_tmp_decl(ret->type, ret->result_var); ret->code << ret->result_var << " = " << svsym->get_name().getString(); ret->code << ";" << endl; */ break; } case V_SgLabelRefExp: SgLabelRefExp *labref = isSgLabelRefExp(expr); out << labref->get_name().getString(); break; /* Begin Constants */ case V_SgIntVal: { stringstream casts; SgIntVal *intval = isSgIntVal(expr); out << intval->get_value(); casts << intval->get_value(); ret->result_var = casts.str(); ret->type = "int"; ret->sgtype = intval->get_type(); break; } case V_SgLongIntVal: { stringstream casts; SgLongIntVal *longval = isSgLongIntVal(expr); out << longval->get_value() << "L"; casts << longval->get_value() << "L"; ret->result_var = casts.str(); ret->type = "long"; ret->sgtype = longval->get_type(); break; } case V_SgUnsignedIntVal: { stringstream casts; SgUnsignedIntVal *uintval = isSgUnsignedIntVal(expr); out << uintval->get_value() << "U"; casts << uintval->get_value() << "U"; ret->result_var = casts.str(); ret->type = "unsigned"; ret->sgtype = uintval->get_type(); break; } case V_SgUnsignedLongVal: { stringstream casts; SgUnsignedLongVal *ulongval = isSgUnsignedLongVal(expr); out << ulongval->get_value() << "UL"; casts << ulongval->get_value() << "UL"; ret->result_var = casts.str(); ret->type = "unsigned long"; ret->sgtype = ulongval->get_type(); break; } case V_SgDoubleVal: { stringstream casts; SgDoubleVal *doubleval = isSgDoubleVal(expr); out << doubleval->get_value(); casts << doubleval->get_value(); ret->result_var = casts.str(); ret->type = "double"; ret->sgtype = doubleval->get_type(); break; } case V_SgFloatVal: { stringstream casts; SgFloatVal *floatval = isSgFloatVal(expr); out << floatval->get_value(); casts << floatval->get_value(); ret->result_var = casts.str(); ret->type = "float"; ret->sgtype = floatval->get_type(); break; } default: out << "/* UNKNOWN EXPR[" << expr->class_name() << "](" << expr->variantT() << ") " << expr->unparseToString() << " */" << endl; cerr << "UNKNOWN EXPR[" << expr->class_name() << "] " << expr->unparseToString() << endl; break; } if (NULL != attr1) delete attr1; if (NULL != attr2) delete attr2; return ret; }
StencilEvaluation_InheritedAttribute StencilEvaluationTraversal::evaluateInheritedAttribute (SgNode* astNode, StencilEvaluation_InheritedAttribute inheritedAttribute ) { #if 0 printf ("In evaluateInheritedAttribute(): astNode = %p = %s \n",astNode,astNode->class_name().c_str()); #endif bool foundPairShiftDoubleConstructor = false; // This is for stencil specifications using vectors of points to represent offsets (not finished). // bool foundVariableDeclarationForStencilInput = false; double stencilCoeficientValue = 0.0; // StencilOffsetFSM offset; StencilOffsetFSM* stencilOffsetFSM = NULL; // We want to interogate the SgAssignInitializer, but we need to generality in the refactored function to use any SgInitializer (e.g. SgConstructorInitializer, etc.). SgInitializedName* initializedName = detectVariableDeclarationOfSpecificType (astNode,"Point"); if (initializedName != NULL) { // This is the code that is specific to the DSL (e.g. the semantics of getZeros() and getUnitv() functions). // So this may be the limit of what can be refactored to common DSL support code. // Or I can maybe do a second pass at atempting to refactor more code later. string name = initializedName->get_name(); SgInitializer* initializer = initializedName->get_initptr(); SgAssignInitializer* assignInitializer = isSgAssignInitializer(initializer); if (assignInitializer != NULL) { SgExpression* exp = assignInitializer->get_operand(); ROSE_ASSERT(exp != NULL); SgFunctionCallExp* functionCallExp = isSgFunctionCallExp(exp); if (functionCallExp != NULL) { SgFunctionRefExp* functionRefExp = isSgFunctionRefExp(functionCallExp->get_function()); if (functionRefExp != NULL) { SgFunctionSymbol* functionSymbol = functionRefExp->get_symbol(); ROSE_ASSERT(functionSymbol != NULL); string functionName = functionSymbol->get_name(); #if 0 printf ("functionName = %s \n",functionName.c_str()); #endif if (functionName == "getZeros") { // We leverage the semantics of known functions used to initialize "Point" objects ("getZeros" initialized the Point object to be all zeros). // In a stencil this will be the center point from which all other points will have non-zero offsets. // For a common centered difference discretization this will be the center point of the stencil. #if 0 printf ("Identified and interpreting the semantics of getZeros() function \n"); #endif stencilOffsetFSM = new StencilOffsetFSM(0,0,0); ROSE_ASSERT(stencilOffsetFSM != NULL); } if (functionName == "getUnitv") { // We leverage the semantics of known functions used to initialize "Point" objects // ("getUnitv" initializes the Point object to be a unit vector for a specific input dimention). // In a stencil this will be an ofset from the center point. #if 0 printf ("Identified and interpreting the semantics of getUnitv() function \n"); #endif // Need to get the dimention argument. SgExprListExp* argumentList = functionCallExp->get_args(); ROSE_ASSERT(argumentList != NULL); // This function has a single argument. ROSE_ASSERT(argumentList->get_expressions().size() == 1); SgExpression* functionArg = argumentList->get_expressions()[0]; ROSE_ASSERT(functionArg != NULL); SgIntVal* intVal = isSgIntVal(functionArg); // ROSE_ASSERT(intVal != NULL); if (intVal != NULL) { int value = intVal->get_value(); #if 0 printf ("value = %d \n",value); #endif switch(value) { case 0: stencilOffsetFSM = new StencilOffsetFSM(1,0,0); break; case 1: stencilOffsetFSM = new StencilOffsetFSM(0,1,0); break; case 2: stencilOffsetFSM = new StencilOffsetFSM(0,0,1); break; default: { printf ("Error: default reached in switch: value = %d (for be value of 0, 1, or 2) \n",value); ROSE_ASSERT(false); } } ROSE_ASSERT(stencilOffsetFSM != NULL); // End of test for intVal != NULL } else { #if 0 printf ("functionArg = %p = %s \n",functionArg,functionArg->class_name().c_str()); #endif } } // ROSE_ASSERT(stencilOffsetFSM != NULL); } } } if (stencilOffsetFSM != NULL) { // Put the FSM into the map. #if 0 printf ("Put the stencilOffsetFSM = %p into the StencilOffsetMap using key = %s \n",stencilOffsetFSM,name.c_str()); #endif ROSE_ASSERT(StencilOffsetMap.find(name) == StencilOffsetMap.end()); // We have a choice of syntax to add the element to the map. // StencilOffsetMap.insert(pair<string,StencilOffsetFSM*>(name,stencilOffsetFSM)); StencilOffsetMap[name] = stencilOffsetFSM; } // new StencilOffsetFSM(); #if 0 printf ("Exiting as a test! \n"); ROSE_ASSERT(false); #endif } // Recognize member function calls on "Point" objects so that we can trigger events on those associated finite state machines. bool isTemplateClass = false; bool isTemplateFunctionInstantiation = false; SgInitializedName* initializedNameUsedToCallMemberFunction = NULL; SgFunctionCallExp* functionCallExp = detectMemberFunctionOfSpecificClassType(astNode,initializedNameUsedToCallMemberFunction,"Point",isTemplateClass,"operator*=",isTemplateFunctionInstantiation); if (functionCallExp != NULL) { // This is the DSL specific part (capturing the semantics of operator*= with specific integer values). // The name of the variable off of which the member function is called (variable has type "Point"). ROSE_ASSERT(initializedNameUsedToCallMemberFunction != NULL); string name = initializedNameUsedToCallMemberFunction->get_name(); // Need to get the dimention argument. SgExprListExp* argumentList = functionCallExp->get_args(); ROSE_ASSERT(argumentList != NULL); // This function has a single argument. ROSE_ASSERT(argumentList->get_expressions().size() == 1); SgExpression* functionArg = argumentList->get_expressions()[0]; ROSE_ASSERT(functionArg != NULL); SgIntVal* intVal = isSgIntVal(functionArg); bool usingUnaryMinus = false; if (intVal == NULL) { SgMinusOp* minusOp = isSgMinusOp(functionArg); if (minusOp != NULL) { #if 0 printf ("Using SgMinusOp on stencil constant \n"); #endif usingUnaryMinus = true; intVal = isSgIntVal(minusOp->get_operand()); } } ROSE_ASSERT(intVal != NULL); int value = intVal->get_value(); if (usingUnaryMinus == true) { value *= -1; } #if 0 printf ("value = %d \n",value); #endif // Look up the stencil offset finite state machine ROSE_ASSERT(StencilOffsetMap.find(name) != StencilOffsetMap.end()); StencilOffsetFSM* stencilOffsetFSM = StencilOffsetMap[name]; ROSE_ASSERT(stencilOffsetFSM != NULL); #if 0 printf ("We have found the StencilOffsetFSM associated with the StencilOffset named %s \n",name.c_str()); #endif #if 0 stencilOffsetFSM->display("before multiply event"); #endif if (value == -1) { // Execute the event on the finte state machine to accumulate the state. stencilOffsetFSM->operator*=(-1); } else { printf ("Error: constant value other than -1 are not supported \n"); ROSE_ASSERT(false); } #if 0 stencilOffsetFSM->display("after multiply event"); #endif } // Detection of "pair<Shift,double>(xdir,ident)" defined as an event in the stencil finite machine model. // Actually, it is the Stencil that is create using the "pair<Shift,double>(xdir,ident)" that should be the // event so we first detect the SgConstructorInitializer. There is not other code similar to this which // has to test for the template arguments, so this has not yet refactored into the dslSupport.C file. // I will do this later since this is general support that could be resused in other DSL compilers. SgConstructorInitializer* constructorInitializer = isSgConstructorInitializer(astNode); if (constructorInitializer != NULL) { // DQ (10/20/2014): This can sometimes be NULL. // ROSE_ASSERT(constructorInitializer->get_class_decl() != NULL); SgClassDeclaration* classDeclaration = constructorInitializer->get_class_decl(); // ROSE_ASSERT(classDeclaration != NULL); if (classDeclaration != NULL) { #if 0 printf ("constructorInitializer = %p class name = %s \n",constructorInitializer,classDeclaration->get_name().str()); #endif SgTemplateInstantiationDecl* templateInstantiationDecl = isSgTemplateInstantiationDecl(classDeclaration); // ROSE_ASSERT(templateInstantiationDecl != NULL); #if 0 if (templateInstantiationDecl != NULL) { printf ("constructorInitializer = %p name = %s template name = %s \n",constructorInitializer,templateInstantiationDecl->get_name().str(),templateInstantiationDecl->get_templateName().str()); } #endif // if (classDeclaration->get_name() == "pair") if (templateInstantiationDecl != NULL && templateInstantiationDecl->get_templateName() == "pair") { // Look at the template parameters. #if 0 printf ("Found template instantiation for pair \n"); #endif SgTemplateArgumentPtrList & templateArgs = templateInstantiationDecl->get_templateArguments(); if (templateArgs.size() == 2) { // Now look at the template arguments and check that they represent the pattern that we are looking for in the AST. // It is not clear now flexible we should be, at present shift/coeficent pairs must be specified exactly one way. SgType* type_0 = templateArgs[0]->get_type(); SgType* type_1 = templateArgs[1]->get_type(); if ( type_0 != NULL && type_1 != NULL) { SgClassType* classType_0 = isSgClassType(type_0); // ROSE_ASSERT(classType_0 != NULL); if (classType_0 != NULL) { SgClassDeclaration* classDeclarationType_0 = isSgClassDeclaration(classType_0->get_declaration()); ROSE_ASSERT(classDeclarationType_0 != NULL); #if 0 printf ("templateArgs[0]->get_name() = %s \n",classDeclarationType_0->get_name().str()); printf ("templateArgs[1]->get_type()->class_name() = %s \n",type_1->class_name().c_str()); #endif bool foundShiftExpression = false; bool foundStencilCoeficient = false; // We might want to be more flexiable about the type of the 2nd parameter (allow SgTypeFloat, SgTypeComplex, etc.). if (classDeclarationType_0->get_name() == "Shift" && type_1->variant() == V_SgTypeDouble) { // Found a pair<Shift,double> input for a stencil. #if 0 printf ("##### Found a pair<Shift,double>() input for a stencil input \n"); #endif // ***************************************************************************************************** // Look at the first parameter to the pair<Shift,double>() constructor. // ***************************************************************************************************** SgExpression* stencilOffset = constructorInitializer->get_args()->get_expressions()[0]; ROSE_ASSERT(stencilOffset != NULL); #if 0 printf ("stencilOffset = %p = %s \n",stencilOffset,stencilOffset->class_name().c_str()); #endif SgConstructorInitializer* stencilOffsetConstructorInitializer = isSgConstructorInitializer(stencilOffset); if (stencilOffsetConstructorInitializer != NULL) { // This is the case of a Shift being constructed implicitly from a Point (doing so more directly would be easier to make sense of in the AST). #if 0 printf ("!!!!! Looking for the stencil offset \n"); #endif ROSE_ASSERT(stencilOffsetConstructorInitializer->get_class_decl() != NULL); SgClassDeclaration* stencilOffsetClassDeclaration = stencilOffsetConstructorInitializer->get_class_decl(); ROSE_ASSERT(stencilOffsetClassDeclaration != NULL); #if 0 printf ("stencilOffsetConstructorInitializer = %p class name = %s \n",stencilOffsetConstructorInitializer,stencilOffsetClassDeclaration->get_name().str()); printf ("stencilOffsetConstructorInitializer = %p class = %p = %s \n",stencilOffsetConstructorInitializer,stencilOffsetClassDeclaration,stencilOffsetClassDeclaration->class_name().c_str()); #endif // This should not be a template instantiation (the Shift is defined to be a noo-template class declaration, not a template class declaration). SgTemplateInstantiationDecl* stencilOffsetTemplateInstantiationDecl = isSgTemplateInstantiationDecl(stencilOffsetClassDeclaration); ROSE_ASSERT(stencilOffsetTemplateInstantiationDecl == NULL); if (stencilOffsetClassDeclaration != NULL && stencilOffsetClassDeclaration->get_name() == "Shift") { // Now we know that the type associated with the first template parameter is associated with the class "Shift". // But we need so also now what the first parametr is associate with the constructor initializer, since it will // be the name of the variable used to interprete the stencil offset (and the name of the variable will be the // key into the map of finite machine models used to accumulate the state of the stencil offsets that we accumulate // to build the stencil. // Now we need the value of the input (computed using it's fine state machine). SgExpression* inputToShiftConstructor = stencilOffsetConstructorInitializer->get_args()->get_expressions()[0]; ROSE_ASSERT(inputToShiftConstructor != NULL); SgConstructorInitializer* inputToShiftConstructorInitializer = isSgConstructorInitializer(inputToShiftConstructor); if (stencilOffsetConstructorInitializer != NULL) { SgExpression* inputToPointConstructor = inputToShiftConstructorInitializer->get_args()->get_expressions()[0]; ROSE_ASSERT(inputToPointConstructor != NULL); // This should be a SgVarRefExp (if we strictly follow the stencil specification rules (which are not written down yet). SgVarRefExp* inputToPointVarRefExp = isSgVarRefExp(inputToPointConstructor); if (inputToPointVarRefExp != NULL) { #if 0 printf ("Found varRefExp in bottom of chain of constructors \n"); #endif SgVariableSymbol* variableSymbolForOffset = isSgVariableSymbol(inputToPointVarRefExp->get_symbol()); ROSE_ASSERT(variableSymbolForOffset != NULL); SgInitializedName* initializedNameForOffset = variableSymbolForOffset->get_declaration(); ROSE_ASSERT(initializedNameForOffset != NULL); SgInitializer* initializer = initializedNameForOffset->get_initptr(); ROSE_ASSERT(initializer != NULL); #if 0 printf ("Found initializedName: name = %s in bottom of chain of constructors: initializer = %p = %s \n",initializedNameForOffset->get_name().str(),initializer,initializer->class_name().c_str()); #endif // Record the name to be used as a key into the map of "StencilOffset" finite state machines. SgAssignInitializer* assignInitializer = isSgAssignInitializer(initializer); ROSE_ASSERT(assignInitializer != NULL); string name = initializedNameForOffset->get_name(); // Look up the current state in the finite state machine for the "Point". // Check that this is a previously defined stencil offset. ROSE_ASSERT(StencilOffsetMap.find(name) != StencilOffsetMap.end()); // StencilOffsetFSM* stencilOffsetFSM = StencilOffsetMap[name]; stencilOffsetFSM = StencilOffsetMap[name]; ROSE_ASSERT(stencilOffsetFSM != NULL); #if 0 printf ("We have found the StencilOffsetFSM associated with the StencilOffset named %s \n",name.c_str()); #endif #if 0 printf ("Exiting as a test! \n"); ROSE_ASSERT(false); #endif } else { printf ("What is this expression: inputToPointConstructor = %p = %s \n",inputToPointConstructor,inputToPointConstructor->class_name().c_str()); ROSE_ASSERT(false); } } #if 0 printf ("Found Shift type \n"); #endif foundShiftExpression = true; } #if 0 printf ("Exiting as a test! \n"); ROSE_ASSERT(false); #endif } else { // This case for the specification of a Shift in the first argument is not yet supported (need an example of this). printf ("This case of using a shift is not a part of what is supported \n"); } // ***************************************************************************************************** // Look at the second parameter to the pair<Shift,double>(first_parameter,second_parameter) constructor. // ***************************************************************************************************** SgExpression* stencilCoeficent = constructorInitializer->get_args()->get_expressions()[1]; ROSE_ASSERT(stencilCoeficent != NULL); SgVarRefExp* stencilCoeficentVarRefExp = isSgVarRefExp(stencilCoeficent); if (stencilCoeficentVarRefExp != NULL) { // Handle the case where this is a constant SgVarRefExp and the value is available in the declaration. SgVariableSymbol* variableSymbolForConstant = isSgVariableSymbol(stencilCoeficentVarRefExp->get_symbol()); ROSE_ASSERT(variableSymbolForConstant != NULL); SgInitializedName* initializedNameForConstant = variableSymbolForConstant->get_declaration(); ROSE_ASSERT(initializedNameForConstant != NULL); SgInitializer* initializer = initializedNameForConstant->get_initptr(); ROSE_ASSERT(initializer != NULL); SgAssignInitializer* assignInitializer = isSgAssignInitializer(initializer); ROSE_ASSERT(assignInitializer != NULL); SgValueExp* valueExp = isSgValueExp(assignInitializer->get_operand()); bool usingUnaryMinus = false; // ROSE_ASSERT(valueExp != NULL); if (valueExp == NULL) { SgExpression* operand = assignInitializer->get_operand(); SgMinusOp* minusOp = isSgMinusOp(operand); if (minusOp != NULL) { #if 0 printf ("Using SgMinusOp on stencil constant \n"); #endif usingUnaryMinus = true; valueExp = isSgValueExp(minusOp->get_operand()); } } SgDoubleVal* doubleVal = isSgDoubleVal(valueExp); // ROSE_ASSERT(doubleVal != NULL); double value = 0.0; if (doubleVal == NULL) { // Call JP's function to evaluate the constant expression. ROSE_ASSERT(valueExp == NULL); ROSE_ASSERT(stencilCoeficent != NULL); DSL_Support::const_numeric_expr_t const_expression = DSL_Support::evaluateConstNumericExpression(stencilCoeficent); if (const_expression.hasValue_ == true) { ROSE_ASSERT(const_expression.isIntOnly_ == false); value = const_expression.value_; printf ("const expression evaluated to value = %4.2f \n",value); } else { printf ("constnat value expression could not be evaluated to a constant \n"); ROSE_ASSERT(false); } } else { #if 1 printf ("SgDoubleVal value = %f \n",doubleVal->get_value()); #endif value = (usingUnaryMinus == false) ? doubleVal->get_value() : -(doubleVal->get_value()); } #if 1 printf ("Stencil coeficient = %f \n",value); #endif foundStencilCoeficient = true; stencilCoeficientValue = value; } else { // When we turn on constant folding in the frontend we eveluate directly to a SgDoubleVal. SgDoubleVal* doubleVal = isSgDoubleVal(stencilCoeficent); if (doubleVal != NULL) { ROSE_ASSERT(doubleVal != NULL); #if 0 printf ("SgDoubleVal value = %f \n",doubleVal->get_value()); #endif double value = doubleVal->get_value(); #if 0 printf ("Stencil coeficient = %f \n",value); #endif foundStencilCoeficient = true; stencilCoeficientValue = value; } else { printf ("Error: second parameter in pair for stencil is not a SgVarRefExp (might be explicit value not yet supported) \n"); printf (" --- stencilCoeficent = %p = %s \n",stencilCoeficent,stencilCoeficent->class_name().c_str()); ROSE_ASSERT(false); } } } #if 0 printf ("foundShiftExpression = %s \n",foundShiftExpression ? "true" : "false"); printf ("foundStencilCoeficient = %s \n",foundStencilCoeficient ? "true" : "false"); #endif if (foundShiftExpression == true && foundStencilCoeficient == true) { #if 0 printf ("Found pair<Shift,double>() constructor expression! \n"); #endif foundPairShiftDoubleConstructor = true; } // End of test for classType_0 != NULL } } } } else { #if 0 printf ("This is not a SgConstructorInitializer for the pair templated class \n"); #endif } // End of test for classDeclaration != NULL } } #if 0 printf ("foundPairShiftDoubleConstructor = %s \n",foundPairShiftDoubleConstructor ? "true" : "false"); #endif if (foundPairShiftDoubleConstructor == true) { // This is the recognition of an event for one of the finite state machines we implement to evaluate the stencil at compile time. #if 0 printf ("In evaluateInheritedAttribute(): found pair<Shift,double>() constructor expression! \n"); printf (" --- stencilOffsetFSM = %p \n",stencilOffsetFSM); printf (" --- stencilCoeficientValue = %f \n",stencilCoeficientValue); #endif ROSE_ASSERT(stencilOffsetFSM != NULL); inheritedAttribute.stencilOffsetFSM = stencilOffsetFSM; inheritedAttribute.stencilCoeficientValue = stencilCoeficientValue; #if 0 printf ("Exiting as a test! \n"); ROSE_ASSERT(false); #endif } // Construct the return attribute from the modified input attribute. return StencilEvaluation_InheritedAttribute(inheritedAttribute); }
void TransformationSupport::getTransformationOptionsFromVariableDeclarationConstructorArguments ( SgVariableDeclaration* variableDeclaration, list<OptionDeclaration> & returnEnumValueList ) { ROSE_ASSERT (variableDeclaration != NULL); SgInitializedNamePtrList & variableList = variableDeclaration->get_variables(); printf ("Inside of getTransformationOptionsFromVariableDeclarationConstructorArguments() \n"); for (SgInitializedNamePtrList::iterator i = variableList.begin(); i != variableList.end(); i++) { // We don't care about the name // SgName & name = (*i).get_name(); ROSE_ASSERT ((*i) != NULL); // QY 11/10/04 removed named_item in SgInitializedName // printf ("Processing a variable in the list \n"); // if ((*i)->get_named_item() != NULL) // { // ROSE_ASSERT ((*i)->get_named_item() != NULL); // SgInitializer *initializerOther = (*i)->get_named_item()->get_initializer(); SgInitializer *initializerOther = (*i)->get_initializer(); // This is not always a valid pointer // ROSE_ASSERT (initializerOther != NULL); // printf ("Test for initialized in variable \n"); if (initializerOther != NULL) { // There are other things we could ask of the initializer ROSE_ASSERT (initializerOther != NULL); // printf ("Found a valid initialized in variable \n"); SgConstructorInitializer* constructorInitializer = isSgConstructorInitializer(initializerOther); ROSE_ASSERT (constructorInitializer != NULL); SgExprListExp* argumentList = constructorInitializer->get_args(); ROSE_ASSERT (argumentList != NULL); SgExpressionPtrList & expressionPtrList = argumentList->get_expressions(); ROSE_ASSERT(expressionPtrList.empty() == false); SgExpressionPtrList::iterator i = expressionPtrList.begin(); ROSE_ASSERT (*i != NULL); // First value is a char* identifying the option SgStringVal* charString = isSgStringVal(*i); ROSE_ASSERT (charString != NULL); #if 1 string optionString; string valueString; int counter = 0; while (i != expressionPtrList.end()) { // printf ("Expression List Element #%d of %d (total) (*i)->sage_class_name() = %s \n", // counter,expressionPtrList.size(),(*i)->sage_class_name()); switch ( (*i)->variant() ) { case ENUM_VAL: { SgEnumVal* enumVal = isSgEnumVal(*i); ROSE_ASSERT (enumVal != NULL); // int enumValue = enumVal->get_value(); SgName enumName = enumVal->get_name(); // printf ("Name = %s value = %d \n",enumName.str(),enumValue); // printf ("Name = %s \n",enumName.str()); string name = enumName.str(); // char* name = rose::stringDuplicate( enumName.str() ); // Put the value at the start of the list so that the list can be processed in // consecutive order to establish options for consecutive scopes (root to // child scope). Order is not important if we are only ORing the operands! // returnEnumValueList.push_front (name); // returnEnumValueList.push_front (enumValue); ROSE_ASSERT (counter == 0); break; } case STRING_VAL: { // ROSE_ASSERT (counter == 1); // printf ("Found a SgStringVal expression! \n"); SgStringVal* stringVal = isSgStringVal(*i); ROSE_ASSERT (stringVal != NULL); if (counter == 0) { optionString = stringVal->get_value(); valueString = ""; // printf ("optionString = %s \n",optionString); } if (counter == 1) { valueString = stringVal->get_value(); // printf ("valueString = %s \n",valueString); } break; } case DOUBLE_VAL: { ROSE_ASSERT (counter == 1); // printf ("Found a SgStringVal expression! \n"); SgDoubleVal* doubleVal = isSgDoubleVal(*i); ROSE_ASSERT (doubleVal != NULL); valueString = StringUtility::numberToString(doubleVal->get_value()).c_str(); // printf ("valueString = %s \n",valueString); break; } default: { printf ("Default reached in switch in getTransformationOptionsFromVariableDeclarationConstructorArguments() (*i)->sage_class_name() = %s \n",(*i)->sage_class_name()); ROSE_ABORT(); break; } } i++; counter++; } // printf ("optionString = %s valueString = %s \n",optionString,valueString); OptionDeclaration optionSpecification(optionString.c_str(),valueString.c_str()); returnEnumValueList.push_front (optionSpecification); #endif } else { // printf ("Valid initializer not found in variable \n"); } /* } else { // printf ("Warning: In getTransformationOptionsFromVariableDeclarationConstructorArguments(): (*i).get_named_item() = NULL \n"); } */ } }