/// <summary> /// Evaluate the type of a phi node. /// </summary> /// <param name="phi"></param> internal static void EvaluatePhiType(Phi phi) { int allUnreached = 0; Type typeSoFar = null; bool first = true; if (phi.Operands.Length == 0 || phi.DefinedBlock == null) { return; } foreach (var operand in phi.Operands) { var operandDetails = InternalVariablesDictionary[operand.Name]; if (operandDetails.Type == typeof(Undetermined)) { typeSoFar = typeof(Undetermined); break; } else { if (first) { first = false; typeSoFar = operandDetails.Type; if (typeSoFar == typeof(Unreached)) { allUnreached += 1; } } else { if (operandDetails.Type == typeof(Unreached)) { allUnreached += 1; } else if (typeSoFar != operandDetails.Type) { typeSoFar = typeof(Undetermined); break; } } } } if (allUnreached == phi.Operands.Length) { typeSoFar = typeof(Unreached); } InternalVariablesDictionary[phi.Name].Type = typeSoFar; return; }
/// <summary> /// Evaluate the constant value at a phi node /// </summary> /// <param name="phi"></param> internal static void EvaluatePhiConstant(Phi phi) { int allUnreached = 0; object constantSoFar = null; bool first = true; if (phi.Operands.Length == 0 || phi.DefinedBlock == null) { return; } foreach (var operand in phi.Operands) { var operandDetails = InternalVariablesDictionary[operand.Name]; if (operandDetails.Constant == Undetermined.UndeterminedConstant) { constantSoFar = Undetermined.UndeterminedConstant; break; } else { if (first) { first = false; constantSoFar = operandDetails.Constant; if (constantSoFar == Unreached.UnreachedConstant) { allUnreached += 1; } } else { if (operandDetails.Constant == Unreached.UnreachedConstant) { allUnreached += 1; } else if ((operandDetails.Constant == null && operandDetails.Constant != constantSoFar) || (operandDetails.Constant != null && !operandDetails.Constant.Equals(constantSoFar))) { constantSoFar = Undetermined.UndeterminedConstant; break; } } } } if (allUnreached == phi.Operands.Length) { constantSoFar = Unreached.UnreachedConstant; } InternalVariablesDictionary[phi.Name].Constant = constantSoFar; return; }