예제 #1
0
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);
		}
	}

}
예제 #2
0
// 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;
}