private static bool InlineCalls <TScopeProvider>( Method.Builder builder, Landscape.Entry caller, TScopeProvider scopeProvider, ref BasicBlock currentBlock) where TScopeProvider : IScopeProvider { foreach (var valueEntry in currentBlock) { if (!(valueEntry.Value is MethodCall call)) { continue; } if (call.Target.HasFlags(MethodFlags.Inline)) { var targetScope = scopeProvider[call.Target]; var blockBuilder = builder[currentBlock]; var tempBlock = blockBuilder.SpecializeCall(call, targetScope); // We can continue our search in the temp block currentBlock = tempBlock.BasicBlock; return(true); } } return(false); }
/// <summary cref="OrderedTransformation.PerformTransformation{TScopeProvider}(Method.Builder, Landscape, Landscape{object}.Entry, TScopeProvider)"/> protected override bool PerformTransformation <TScopeProvider>( Method.Builder builder, Landscape landscape, Landscape.Entry current, TScopeProvider scopeProvider) { var processed = new HashSet <BasicBlock>(); var toProcess = new Stack <BasicBlock>(); bool result = false; var currentBlock = current.Scope.EntryBlock; while (true) { if (processed.Add(currentBlock)) { if (result = InlineCalls( builder, current, scopeProvider, ref currentBlock)) { result = true; continue; } var successors = currentBlock.Successors; if (successors.Length > 0) { currentBlock = successors[0]; for (int i = 1, e = successors.Length; i < e; ++i) { toProcess.Push(successors[1]); } continue; } } if (toProcess.Count < 1) { break; } currentBlock = toProcess.Pop(); } return(result); }
/// <summary> /// Applies the inlining transformation. /// </summary> protected override bool PerformTransformation( IRContext context, Method.Builder builder, Landscape landscape, Landscape.Entry current) { var processed = builder.SourceBlocks.CreateSet(); var toProcess = new Stack <BasicBlock>(); bool result = false; var currentBlock = builder.EntryBlock; while (true) { if (processed.Add(currentBlock)) { if (result = InlineCalls(builder, ref currentBlock)) { result = true; continue; } var successors = currentBlock.Terminator.Targets; if (successors.Length > 0) { currentBlock = successors[0]; for (int i = 1, e = successors.Length; i < e; ++i) { toProcess.Push(successors[1]); } continue; } } if (toProcess.Count < 1) { break; } currentBlock = toProcess.Pop(); } return(result); }