public override Node Visit(AssignmentExpression assignmentExpression) { var variable = GetUniform(assignmentExpression.Target); bool isMemberExpression = assignmentExpression.Target is MemberReferenceExpression; if (variable != null) { // Default == operator is the only write only operators if (assignmentExpression.Operator == AssignmentOperator.Default && !uniformReadList.Contains(variable) && !this.UniformUsedWriteFirstList.Contains(variable)) { // Handle the case where the assignment operator is partial like vect.xy = 5; and later vect.zw += 6; // In this case, the variable is considered as read and write (and not only write first) if (isMemberExpression) { var variableType = variable.Type.ResolveType(); if (variableType is VectorType || variableType is MatrixType) { var dim = Math.Max(TypeBase.GetDimensionSize(variableType, 0), TypeBase.GetDimensionSize(variableType, 1)); var memberRef = assignmentExpression.Target as MemberReferenceExpression; var numberOfMembers = memberRef.Member.Text.Length; // If the variable is a global uniform, non static/const and is not already in the list used then if (numberOfMembers < dim) { if (!uniformReadList.Contains(variable)) { uniformReadList.Add(variable); } } else { UniformUsedWriteFirstList.Add(variable); } } } else { UniformUsedWriteFirstList.Add(variable); } } if (assignmentExpression.Operator != AssignmentOperator.Default) { if (!UniformReadWriteList.Contains(variable)) { UniformReadWriteList.Add(variable); } } } return(assignmentExpression); }
protected override void ProcessMethodInvocation(MethodInvocationExpression invoke, MethodDefinition method) { // Handle the case where a parameter can be out // If this is the case, we need to check that for (int i = 0; i < invoke.Arguments.Count; i++) { var arg = invoke.Arguments[i]; var variable = this.GetUniform(arg); var parameter = method.Parameters[i]; if (variable != null && parameter.Qualifiers.Contains(ParameterQualifier.Out)) { bool isUniformWasAlreadyUsedAsRead = false; for (int j = 0; j < countReadBeforeInvoke; j++) { if (ReferenceEquals(uniformReadList[i], variable)) { isUniformWasAlreadyUsedAsRead = true; break; } } // If this is a out parameter, and the variable was not already used as a read, then // we can remove it from the uniform read list if (!isUniformWasAlreadyUsedAsRead) { uniformReadList.Remove(variable); if (!UniformUsedWriteFirstList.Contains(variable)) { UniformUsedWriteFirstList.Add(variable); } } } } this.VisitDynamic(method); }
public bool IsVariableAsGlobalTemporary(Variable variable) { return(UniformUsedWriteFirstList.Contains(variable)); }