void AnalyzeNode(ILNode node) { ILExpression expr = node as ILExpression; if (expr != null) { ILVariable locVar = expr.Operand as ILVariable; if (locVar != null) { if (expr.Code == ILCode.Stloc) { numStloc[locVar] = numStloc.GetOrDefault(locVar) + 1; } else if (expr.Code == ILCode.Ldloc) { numLdloc[locVar] = numLdloc.GetOrDefault(locVar) + 1; } else if (expr.Code == ILCode.Ldloca) { numLdloca[locVar] = numLdloca.GetOrDefault(locVar) + 1; } else { throw new NotSupportedException(expr.Code.ToString()); } } foreach (ILExpression child in expr.Arguments) AnalyzeNode(child); } else { var catchBlock = node as ILTryCatchBlock.CatchBlock; if (catchBlock != null && catchBlock.ExceptionVariable != null) { numStloc[catchBlock.ExceptionVariable] = numStloc.GetOrDefault(catchBlock.ExceptionVariable) + 1; } foreach (ILNode child in node.GetChildren()) AnalyzeNode(child); } }
void InferTypes(ILNode node) { ILCondition cond = node as ILCondition; if (cond != null) { InferTypeForExpression(cond.Condition, typeSystem.Boolean, false); } ILWhileLoop loop = node as ILWhileLoop; if (loop != null && loop.Condition != null) { InferTypeForExpression(loop.Condition, typeSystem.Boolean, false); } ILExpression expr = node as ILExpression; if (expr != null) { ILVariable v = expr.Operand as ILVariable; if (v != null && v.IsGenerated && v.Type == null && expr.Code == ILCode.Stloc && !inferredVariables.Contains(v) && HasSingleLoad(v)) { // Don't deal with this node or its children yet, // wait for the expected type to be inferred first. // This happens with the arg_... variables introduced by the ILAst - we skip inferring the whole statement, // and first infer the statement that reads from the arg_... variable. // The ldloc inference will write the expected type to the variable, and the next InferRemainingStores() pass // will then infer this statement with the correct expected type. storedToGeneratedVariables.Add(expr); return; } bool anyArgumentIsMissingType = expr.Arguments.Any(a => a.InferredType == null); if (expr.InferredType == null || anyArgumentIsMissingType) expr.InferredType = InferTypeForExpression(expr, expr.ExpectedType, forceInferChildren: anyArgumentIsMissingType); } foreach (ILNode child in node.GetChildren()) { InferTypes(child); } }
void FlattenBasicBlocks(ILNode node) { ILBlock block = node as ILBlock; if (block != null) { List <ILNode> flatBody = new List <ILNode>(); foreach (ILNode child in block.GetChildren()) { FlattenBasicBlocks(child); ILBasicBlock childAsBB = child as ILBasicBlock; if (childAsBB != null) { if (!(childAsBB.Body.FirstOrDefault() is ILLabel)) { throw new Exception("Basic block has to start with a label. \n" + childAsBB.ToString()); } if (childAsBB.Body.LastOrDefault() is ILExpression && !childAsBB.Body.LastOrDefault().IsUnconditionalControlFlow()) { throw new Exception("Basci block has to end with unconditional control flow. \n" + childAsBB.ToString()); } flatBody.AddRange(childAsBB.GetChildren()); } else { flatBody.Add(child); } } block.EntryGoto = null; block.Body = flatBody; } else if (node is ILExpression) { // Optimization - no need to check expressions } else if (node != null) { // Recursively find all ILBlocks foreach (ILNode child in node.GetChildren()) { FlattenBasicBlocks(child); } } }
// stelem.any(T, ldloc(array), ldloc(pos), <OP>(ldelem.any(T, ldloc(array), ldloc(pos)), <RIGHT>)) // or // stobj(T, ldloc(ptr), <OP>(ldobj(T, ldloc(ptr)), <RIGHT>)) private void PreprocessorRemoveCompoundAssignment(ILNode node) { ILExpression e = node as ILExpression; if ((e != null) && (e.Code == ILCode.CompoundAssignment)) { ILExpression op = e.Arguments[0]; e.Arguments.Clear(); ILExpression loadExp = op.Arguments[0]; e.Code = LoadVarInvert[loadExp.Code]; e.Operand = loadExp.Operand; e.Arguments.AddRange(loadExp.Arguments); e.Arguments.Add(op); } foreach (ILNode n in node.GetChildren()) { PreprocessorRemoveCompoundAssignment(n); } }
/// <summary> /// Creates the "ExpressionToInfer" instances (=nodes in dependency graph) /// </summary> /// <remarks> /// We are using a dependency graph to ensure that expressions are analyzed in the correct order. /// </remarks> void CreateDependencyGraph(ILNode node) { ILCondition cond = node as ILCondition; if (cond != null) { cond.Condition.ExpectedType = typeSystem.Boolean; } ILWhileLoop loop = node as ILWhileLoop; if (loop != null && loop.Condition != null) { loop.Condition.ExpectedType = typeSystem.Boolean; } ILTryCatchBlock.CatchBlock catchBlock = node as ILTryCatchBlock.CatchBlock; if (catchBlock != null && catchBlock.ExceptionVariable != null && catchBlock.ExceptionType != null && catchBlock.ExceptionVariable.Type == null) { catchBlock.ExceptionVariable.Type = catchBlock.ExceptionType; } ILExpression expr = node as ILExpression; if (expr != null) { ExpressionToInfer expressionToInfer = new ExpressionToInfer(); expressionToInfer.Expression = expr; allExpressions.Add(expressionToInfer); FindNestedAssignments(expr, expressionToInfer); if (expr.Code == ILCode.Stloc && ((ILVariable)expr.Operand).Type == null) assignmentExpressions[(ILVariable)expr.Operand].Add(expressionToInfer); return; } foreach (ILNode child in node.GetChildren()) { CreateDependencyGraph(child); } }
/// <summary> /// Flattens all nested movable blocks, except the the top level 'node' argument /// </summary> void FlattenNestedMovableBlocks(ILNode node) { ILBlock block = node as ILBlock; if (block != null) { List<ILNode> flatBody = new List<ILNode>(); if (block.EntryPoint != null) { flatBody.Add(new ILExpression(OpCodes.Br, block.EntryPoint)); block.EntryPoint = null; } foreach (ILNode child in block.Body) { FlattenNestedMovableBlocks(child); if (child is ILMoveableBlock) { flatBody.AddRange(((ILMoveableBlock)child).Body); } else { flatBody.Add(child); } } block.Body = flatBody; } else if (node is ILExpression) { // Optimization - no need to check expressions } else if (node != null) { // Recursively find all ILBlocks foreach(ILNode child in node.GetChildren()) { FlattenNestedMovableBlocks(child); } } }
/// <summary> /// Flattens all nested basic blocks, except the the top level 'node' argument /// </summary> void FlattenBasicBlocks(ILNode node) { ILBlock block = node as ILBlock; if (block != null) { List<ILNode> flatBody = new List<ILNode>(); foreach (ILNode child in block.GetChildren()) { FlattenBasicBlocks(child); if (child is ILBasicBlock) { flatBody.AddRange(child.GetChildren()); } else { flatBody.Add(child); } } block.EntryGoto = null; block.Body = flatBody; } else if (node is ILExpression) { // Optimization - no need to check expressions } else if (node != null) { // Recursively find all ILBlocks foreach(ILNode child in node.GetChildren()) { FlattenBasicBlocks(child); } } }