| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using ILRuntime.Mono.Cecil;
- using ILRuntime.Mono.Cecil.Cil;
- using ILRuntime.CLR.TypeSystem;
- using ILRuntime.CLR.Method;
- using ILRuntime.Runtime.Intepreter.OpCodes;
- namespace ILRuntime.Runtime.Intepreter.RegisterVM
- {
- partial class Optimizer
- {
- public static void ForwardCopyPropagation(List<CodeBasicBlock> blocks, bool hasReturn,short stackRegisterBegin)
- {
- foreach (var b in blocks)
- {
- var lst = b.FinalInstructions;
- HashSet<int> canRemove = b.CanRemove;
- HashSet<int> pendingFCP = b.PendingCP;
- bool isInline = false;
- for (int i = 0; i < lst.Count; i++)
- {
- if (canRemove.Contains(i))
- continue;
- OpCodeR X = lst[i];
- if(X.Code == OpCodeREnum.InlineStart)
- {
- isInline = true;
- continue;
- }
- if (X.Code == OpCodeREnum.InlineEnd)
- {
- isInline = false;
- continue;
- }
- //if (isInline)
- // continue;
- if (X.Code == OpCodeREnum.Nop || X.Code == OpCodeREnum.Castclass || X.Code == OpCodeREnum.Readonly || X.Code == OpCodeREnum.Volatile)
- {
- canRemove.Add(i);
- continue;
- }
- if (X.Code == OpCodeREnum.Move)
- {
- short xSrc, xSrc2, xSrc3, xDst;
- GetOpcodeSourceRegister(ref X, hasReturn, out xSrc, out xSrc2, out xSrc3);
- GetOpcodeDestRegister(ref X, out xDst);
- if (xDst == xSrc)
- {
- canRemove.Add(i);
- continue;
- }
- //Only deal with local->stack, local->local, stack->stack
- if (xSrc >= stackRegisterBegin && xDst < stackRegisterBegin || isInline)
- continue;
- bool postPropagation = false;
- bool ended = false;
- bool propagationInline = false;
- for (int j = i + 1; j < lst.Count; j++)
- {
- OpCodeR Y = lst[j];
- if (Y.Code == OpCodeREnum.InlineStart)
- propagationInline = true;
- else if (Y.Code == OpCodeREnum.InlineEnd)
- {
- propagationInline = false;
- }
- short ySrc, ySrc2, ySrc3;
- if (GetOpcodeSourceRegister(ref Y, hasReturn, out ySrc, out ySrc2, out ySrc3))
- {
- bool replaced = false;
- if (ySrc >= 0 && ySrc == xDst)
- {
- if (postPropagation)
- {
- postPropagation = false;
- ended = true;
- break;
- }
- if(propagationInline)
- {
- ended = true;
- break;
- }
- ReplaceOpcodeSource(ref Y, 0, xSrc);
- replaced = true;
- }
- if (ySrc2 >= 0 && ySrc2 == xDst)
- {
- if (postPropagation)
- {
- postPropagation = false;
- ended = true;
- break;
- }
- if (propagationInline)
- {
- ended = true;
- break;
- }
- ReplaceOpcodeSource(ref Y, 1, xSrc);
- replaced = true;
- }
- if (ySrc3 >= 0 && ySrc3 == xDst)
- {
- if (postPropagation)
- {
- postPropagation = false;
- ended = true;
- break;
- }
- if (propagationInline)
- {
- ended = true;
- break;
- }
- ReplaceOpcodeSource(ref Y, 2, xSrc);
- replaced = true;
- }
- if (replaced)
- lst[j] = Y;
- }
- short yDst;
- if (GetOpcodeDestRegister(ref Y, out yDst))
- {
- if (xSrc == yDst)
- {
- postPropagation = true;
- }
- if (xDst == yDst)
- {
- postPropagation = false;
- ended = true;
- if (!propagationInline)
- canRemove.Add(i);
- break;
- }
- }
- if(Y.Code == OpCodeREnum.Ret && !propagationInline)
- {
- postPropagation = false;
- canRemove.Add(i);
- ended = true;
- break;
- }
- }
- if (postPropagation || !ended)
- {
- if (xDst >= stackRegisterBegin)
- pendingFCP.Add(i);
- }
- }
- }
- }
- foreach(var b in blocks)
- {
- var pendingFCP = b.PendingCP;
- if (pendingFCP.Count > 0)
- {
- var originBlock = b;
- HashSet<CodeBasicBlock> processedBlocks = new HashSet<CodeBasicBlock>();
- Queue<CodeBasicBlock> pendingBlocks = new Queue<CodeBasicBlock>();
- foreach (var idx in pendingFCP)
- {
- var X = originBlock.FinalInstructions[idx];
- short xDst, xSrc, xSrc2, xSrc3;
- GetOpcodeDestRegister(ref X, out xDst);
- GetOpcodeSourceRegister(ref X, hasReturn, out xSrc, out xSrc2, out xSrc3);
- pendingBlocks.Clear();
- bool cannotRemove = false;
- bool isAbort = false;
- processedBlocks.Clear();
- foreach (var nb in originBlock.NextBlocks)
- pendingBlocks.Enqueue(nb);
- processedBlocks.Add(originBlock);
- while (pendingBlocks.Count > 0)
- {
- var cur = pendingBlocks.Dequeue();
- var ins = cur.FinalInstructions;
- bool propagationInline = false;
- for (int j = 0; j < ins.Count; j++)
- {
- if(cur == originBlock && j == idx)
- {
- isAbort = true;
- break;
- }
- var Y = ins[j];
- if (Y.Code == OpCodeREnum.InlineStart)
- propagationInline = true;
- else if (Y.Code == OpCodeREnum.InlineEnd)
- {
- propagationInline = false;
- }
- short ySrc, ySrc2, ySrc3, yDst;
- if (GetOpcodeSourceRegister(ref Y, hasReturn, out ySrc, out ySrc2, out ySrc3))
- {
- bool replaced = false;
- if (ySrc == xDst)
- {
- if (propagationInline || cur.PreviousBlocks.Count > 1)
- {
- cannotRemove = true;
- break;
- }
- replaced = true;
- ReplaceOpcodeSource(ref Y, 0, xSrc);
- }
- if (ySrc2 == xDst)
- {
- if (propagationInline || cur.PreviousBlocks.Count > 1)
- {
- cannotRemove = true;
- break;
- }
- replaced = true;
- ReplaceOpcodeSource(ref Y, 1, xSrc);
- }
- if (ySrc3 == xDst)
- {
- if (propagationInline || cur.PreviousBlocks.Count > 1)
- {
- cannotRemove = true;
- break;
- }
- replaced = true;
- ReplaceOpcodeSource(ref Y, 2, xSrc);
- }
- if (replaced)
- ins[j] = Y;
- }
- if(GetOpcodeDestRegister(ref Y, out yDst))
- {
- if(yDst == xDst)
- {
- isAbort = true;
- break;
- }
- }
- if(Y.Code == OpCodeREnum.Ret && !propagationInline)
- {
- isAbort = true;
- break;
- }
- }
- if (cannotRemove)
- break;
- processedBlocks.Add(cur);
- if (!isAbort)
- {
- foreach (var nb in cur.NextBlocks)
- {
- if (!processedBlocks.Contains(nb))
- pendingBlocks.Enqueue(nb);
- }
- }
- }
- if(!cannotRemove)
- {
- originBlock.CanRemove.Add(idx);
- }
- }
- pendingFCP.Clear();
- }
- }
- }
-
- }
- }
|