void ArrayAssignmentStatementTransformation::processArrayRefExp(SgVarRefExp* varRefExp, int dimension) { string variableName = varRefExp->get_symbol()->get_declaration()->get_name().str(); #if DEBUG cout << " Variable Name " << variableName << endl; #endif SgScopeStatement* scope = getScope(varRefExp); //SgVarRefExp* replaceVarRefExp = buildVarRefExp(variableName, getScope(varRefExp)); SgVarRefExp* newVarRefExp = buildVarRefExp("_" + variableName + "_pointer", scope); ROSE_ASSERT(newVarRefExp != NULL); string functionName = "SC_" + variableName; if (varRefExp->get_parent() != NULL) { SgFunctionCallExp* functionCallExpression = isSgFunctionCallExp(varRefExp->get_parent()->get_parent()); if (functionCallExpression != NULL) { string operatorName = TransformationSupport::getFunctionName(functionCallExpression); #if DEBUG cout << " Operator Name: " << operatorName << endl; #endif if (operatorName == "operator()") { // Create a copy since the original might be deleted during replacement SgExprListExp* functionExprList = isSgExprListExp(copyExpression(functionCallExpression->get_args())); substituteIndexes(functionExprList, scope); SgFunctionCallExp* functionCallExp = buildFunctionCallExp(functionName, buildIntType(), functionExprList, scope); SgPntrArrRefExp* pntrArrRefExp = buildPntrArrRefExp(newVarRefExp, functionCallExp); cout << " PntrArrayReference replacement: " << pntrArrRefExp->unparseToString() << endl; replaceExpression(functionCallExpression, pntrArrRefExp, false); } else { SgPntrArrRefExp* pntrRefExp = buildArrayRefExp(newVarRefExp, dimension, functionName, scope); replaceExpression(varRefExp, pntrRefExp); } } else { // Added to support simple cases like A = A+B where there is dependence SgPntrArrRefExp* pntrRefExp = buildArrayRefExp(newVarRefExp, dimension, functionName, scope); replaceExpression(varRefExp, pntrRefExp); } } }
// Constructs _A_pointer[SC_A(_1,_2)] SgPntrArrRefExp* buildAPPArrayRef(SgNode* astNode, ArrayAssignmentStatementQueryInheritedAttributeType & arrayAssignmentStatementQueryInheritedData, OperandDataBaseType & operandDataBase, SgScopeStatement* scope, SgExprListExp* parameterExpList) { #if DEBUG printf("Contructing A++ array reference object \n"); #endif string returnString; SgVarRefExp* varRefExp = isSgVarRefExp(astNode); ROSE_ASSERT(varRefExp != NULL); SgVariableSymbol* variableSymbol = varRefExp->get_symbol(); ROSE_ASSERT(variableSymbol != NULL); SgInitializedName* initializedName = variableSymbol->get_declaration(); ROSE_ASSERT(initializedName != NULL); SgName variableName = initializedName->get_name(); vector<SgExpression*> parameters; // Figure out the dimensionality of the statement globally int maxNumberOfIndexOffsets = 6; // default value for A++/P++ arrays ROSE_ASSERT(arrayAssignmentStatementQueryInheritedData.arrayStatementDimensionDefined == TRUE); if (arrayAssignmentStatementQueryInheritedData.arrayStatementDimensionDefined == TRUE) { // The the globally computed array dimension from the arrayAssignmentStatementQueryInheritedData maxNumberOfIndexOffsets = arrayAssignmentStatementQueryInheritedData.arrayStatementDimension; } // Then we want the minimum of all the dimensions accesses (or is it the maximum?) for (int n = 0; n < maxNumberOfIndexOffsets; n++) { parameters.push_back(buildVarRefExp("_" + StringUtility::numberToString(n + 1), scope)); } // Make a reference to the global operand database //OperandDataBaseType & operandDataBase = accumulatorValue.operandDataBase; SgType* type = variableSymbol->get_type(); ROSE_ASSERT(type != NULL); string typeName = TransformationSupport::getTypeName(type); ROSE_ASSERT(typeName.c_str() != NULL); // Copy the string from the SgName object to a string object string variableNameString = variableName.str(); // Setup an intry in the synthesized attribute data base for this variable any // future results from analysis could be place there at this point as well // record the name in the synthesized attribute ROSE_ASSERT(operandDataBase.transformationOption > ArrayTransformationSupport::UnknownIndexingAccess); ArrayOperandDataBase arrayOperandDB = operandDataBase.setVariableName(variableNameString); // We could have specified in the inherited attribute that this array variable was // index and if so leave the value of $IDENTIFIER_STRING to be modified later in // the assembly of the operator() and if not do the string replacement on // $IDENTIFIER_STRING here (right now). returnString = string("$IDENTIFIER_STRING") + string("_pointer[SC") + string("$MACRO_NAME_SUBSTRING") + string("(") + string("$OFFSET") + string(")]"); string functionSuffix = ""; SgPntrArrRefExp* pntrRefExp; cout << " arrayAssignmentStatementQueryInheritedData.getIsIndexedArrayOperand() " << arrayAssignmentStatementQueryInheritedData.getIsIndexedArrayOperand() << endl; // The inherited attribute mechanism is not yet implimented if (arrayAssignmentStatementQueryInheritedData.getIsIndexedArrayOperand() == FALSE) //if(true) { // do the substitution of $OFFSET here since it our last chance // (offsetString is the list of index values "index1,index2,...,indexn") //returnString = StringUtility::copyEdit(returnString,"$OFFSET",offsetString); string operandIdentifier = arrayOperandDB.generateIdentifierString(); // do the substitution of $IDENTIFIER_STRING here since it our last chance // if variable name is "A", generate: A_pointer[SC_A(index1,...)] // returnString = StringUtility::copyEdit (returnString,"$IDENTIFIER_STRING",variableNameString); ROSE_ASSERT(arrayOperandDB.indexingAccessCode > ArrayTransformationSupport::UnknownIndexingAccess); // Edit into place the name of the data pointer returnString = StringUtility::copyEdit(returnString, "$IDENTIFIER_STRING", operandIdentifier); // Optimize the case of uniform or unit indexing to generate a single subscript macro definition if ((arrayOperandDB.indexingAccessCode == ArrayTransformationSupport::UniformSizeUnitStride) || (arrayOperandDB.indexingAccessCode == ArrayTransformationSupport::UniformSizeUniformStride)) returnString = StringUtility::copyEdit(returnString, "$MACRO_NAME_SUBSTRING", ""); else { returnString = StringUtility::copyEdit(returnString, "$MACRO_NAME_SUBSTRING", operandIdentifier); functionSuffix = operandIdentifier; } /* * Create SgPntrArrRefExp lhs is VarRefExp and rhs is SgFunctionCallExp */ SgVarRefExp* newVarRefExp = buildVarRefExp(operandIdentifier + "_pointer", scope); string functionName = "SC" + functionSuffix; SgFunctionCallExp* functionCallExp; if (parameterExpList == NULL) functionCallExp = buildFunctionCallExp(functionName, buildIntType(), buildExprListExp(parameters), scope); else functionCallExp = buildFunctionCallExp(functionName, buildIntType(), parameterExpList, scope); pntrRefExp = buildPntrArrRefExp(newVarRefExp, functionCallExp); #if DEBUG cout << " pntrArrRefExp = " << pntrRefExp->unparseToString() << endl; #endif } return pntrRefExp; }