private bool OptimizeBlock(BaseBlock bblock, HashSet <String> active_vars) { bool ret = false; HashSet <String> living = new HashSet <string>(); for (int i = bblock.Code.Count - 1; i >= 0; --i) { var line = bblock.Code[i]; if (ThreeAddrOpType.IsDefinition(line.OpType) & line.OpType != ThreeAddrOpType.Read) { if (!living.Contains(line.Accum) && !active_vars.Contains(line.Accum)) { line.OpType = ThreeAddrOpType.Nop; ret = true; continue; } } if (line.RightOp != null && !ComputeHelper.IsConst(line.RightOp)) { living.Add(line.RightOp); } if (line.LeftOp != null && !ComputeHelper.IsConst(line.LeftOp)) { living.Add(line.LeftOp); } } return(ret); }
public override bool Optimize(List <BaseBlock> codeBlocks) { //var CFG = new ControlFlowGraph(codeBlocks); //неиспользую //var active = CFG.GenerateInputOutputActiveDefs(codeBlocks).Item1; //var active1 = CFG.GenerateInputOutputActiveDefs(codeBlocks).Item2; HashSet <String> bInit = new HashSet <String>(); HashSet <String> bNotInit = new HashSet <string>(); foreach (var l in BaseBlockHelper.JoinBaseBlocks(codeBlocks)) { if ((l.LeftOp != null) && (l.LeftOp.Contains("v")) && (!bInit.Contains(l.LeftOp))) { bNotInit.Add(l.LeftOp); } if ((l.RightOp != null) && (l.RightOp.Contains("v")) && (!bInit.Contains(l.RightOp))) { bNotInit.Add(l.RightOp); } if (ThreeAddrOpType.IsDefinition(l.OpType)) { bInit.Add(l.Accum); } } if (bNotInit.Count() > 0) { throw new NotInitVariableException(bNotInit.ToList(), "Ошибка"); } return(false); }
private bool TryOptimize(BaseBlock bblock, ExprSet input, IEnumerable <BaseBlock> prev) { for (int i = 0; i < bblock.Code.Count; ++i) { var line = bblock.Code[i]; if (ThreeAddrOpType.IsDefinition(line.OpType) && line.OpType != ThreeAddrOpType.Assign && line.OpType != ThreeAddrOpType.Read) { var expr = (line.LeftOp, line.OpType, line.RightOp); if (input.Contains(expr)) { if (TryExtract(prev, expr)) { line.RightOp = "tt" + _tempcount.ToString(); _tempcount++; line.OpType = ThreeAddrOpType.Assign; line.LeftOp = null; return(true); } } } input = TransferByLine(input, line); } return(false); }
public ControlFlowGraph(List <BaseBlock> baseBlocks) { Next = new Dictionary <int, List <int> >(); Prev = new Dictionary <int, List <int> >(); StartBlockId = baseBlocks[0].StartLabel; _bblocks = baseBlocks; _baseBlockByStart = new Dictionary <int, BaseBlock>(); _genByStart = new Dictionary <int, GenSet>(); _killByStart = new Dictionary <int, KillSet>(); _useByStart = new Dictionary <int, VarsSet>(); _defByStart = new Dictionary <int, VarsSet>(); _genExprByStart = new Dictionary <int, ExprSet>(); foreach (var bblock in baseBlocks) { _baseBlockByStart[bblock.StartLabel] = bblock; Prev[bblock.StartLabel] = new List <int>(); Next[bblock.StartLabel] = new List <int>(); } for (int i = 0; i < baseBlocks.Count; ++i) { var bblock = baseBlocks[i]; if (ThreeAddrOpType.IsGoto(bblock.LastLine.OpType)) { Next[bblock.StartLabel].Add(int.Parse(bblock.LastLine.RightOp)); if (bblock.LastLine.OpType == ThreeAddrOpType.Goto) { continue; } } if (i + 1 < baseBlocks.Count) { Next[bblock.StartLabel].Add(baseBlocks[i + 1].StartLabel); } } foreach (var vTo in Next) { foreach (var to in vTo.Value) { Prev[to].Add(vTo.Key); } } GenerateGenAndKillSets(); GenerateUseAndDefSets(); GenerateGenExprSets(); }
private bool Update(ThreeAddrLine line, ValueSet vals) { if (!ThreeAddrOpType.IsDefinition(line.OpType)) { return(false); } var ret = ReachingValues.Compute(line, vals); vals[line.Accum] = ret; bool ok = false; if (ComputeHelper.IsConst(ret)) { if (ThreeAddrOpType.Assign == line.OpType && line.RightOp == ret) { return(false); } line.OpType = ThreeAddrOpType.Assign; line.LeftOp = null; line.RightOp = ret; return(true); } if (line.LeftOp != null && vals.ContainsKey(line.LeftOp)) { if (vals[line.LeftOp] != "NAC") { line.LeftOp = vals[line.LeftOp]; ok = true; } } if (line.RightOp != null && vals.ContainsKey(line.RightOp)) { if (vals[line.RightOp] != "NAC") { line.RightOp = vals[line.RightOp]; ok = true; } } return(ok); }
private ValueSet GenFullValueSet(IEnumerable <ThreeAddrLine> lines) { ValueSet ret = new ValueSet(); foreach (var l in lines) { if (ThreeAddrOpType.IsDefinition(l.OpType)) { ret[l.Accum] = "NAC"; } } return(ret); }
public override bool Optimize(BaseBlock bblock) { bool answer = false; // Индикатор того, что хоть один раз, но оптимизация была выполнена. deathVariable.Clear(); liveVariable.Clear(); for (int i = bblock.Code.Count() - 1; i >= 0; --i) // Проход по всему базовому блоку. { if ((bblock.Code[i].OpType == ThreeAddrOpType.Write) && !IsConst(bblock.Code[i].RightOp)) { UpdateLive(bblock.Code[i].RightOp); continue; } if (bblock.Code[i].OpType == ThreeAddrOpType.Read) { UpdateDead(bblock.Code[i].Accum); continue; } if (ThreeAddrOpType.IsDefinition(bblock.Code[i].OpType)) { if (deathVariable.Contains(bblock.Code[i].Accum) || (bblock.Code[i].Accum.StartsWith("p") && !liveVariable.Contains(bblock.Code[i].Accum))) { bblock.Code[i].OpType = ThreeAddrOpType.Nop; answer = true; } else { UpdateDead(bblock.Code[i].Accum); if (!IsConst(bblock.Code[i].RightOp)) { UpdateLive(bblock.Code[i].RightOp); } if (bblock.Code[i].LeftOp != null && !IsConst(bblock.Code[i].LeftOp)) { UpdateLive(bblock.Code[i].LeftOp); } } continue; } if (bblock.Code[i].OpType == ThreeAddrOpType.IfGoto) { UpdateLive(bblock.Code[i].LeftOp); } } return(answer); }
public static GenSet GetGenSet(BaseBlock bblock) { var ret = new GenSet(); foreach (var line in bblock.Code.AsEnumerable().Reverse()) { if (ThreeAddrOpType.IsDefinition(line.OpType)) { if (!ret.ContainsKey(line.Accum)) { ret[line.Accum] = int.Parse(line.Label); } } } return(ret); }
public List <BaseBlock> GetAliveBlocks() { Queue <int> Q = new Queue <int>(); Q.Enqueue(StartBlockId); HashSet <int> visited = new HashSet <int>(); visited.Add(StartBlockId); while (Q.Count > 0) { var cur = Q.Dequeue(); foreach (var to in Next[cur]) { if (!visited.Contains(to)) { visited.Add(to); Q.Enqueue(to); } } } //Propagate empty blocks foreach (var k in visited) { var bblock = _baseBlockByStart[k]; if (ThreeAddrOpType.IsGoto(bblock.LastLine.OpType)) { int to = int.Parse(bblock.LastLine.RightOp); var tobl = _baseBlockByStart[to]; if (tobl.Code[0].OpType == ThreeAddrOpType.Goto) { bblock.LastLine.RightOp = tobl.Code[0].RightOp; } else if (tobl.Code.Count == 1 && tobl.Code[0].OpType == ThreeAddrOpType.Nop) { if (Next[to].Count == 1) { bblock.LastLine.RightOp = Next[to][0].ToString(); } } } } return(visited.OrderBy(x => x) .Select(x => _baseBlockByStart[x]).ToList()); }
public static ValueSet TransferByBBlock(ValueSet In, BaseBlock bblock) { ValueSet Out = new ValueSet(); foreach (var vk in In) { Out[vk.Key] = vk.Value; } foreach (var line in bblock.Code) { if (ThreeAddrOpType.IsDefinition(line.OpType)) { Out[line.Accum] = Compute(line, Out); } } return(Out); }
public override bool Optimize(BaseBlock bblock) { for (int i = 0; i < bblock.Code.Count; ++i) { var line = bblock.Code[i]; if (ThreeAddrOpType.IsDefinition(line.OpType) && line.Accum.StartsWith("p")) { bool ok = false; bool can_del = true; for (int j = i + 1; j < bblock.Code.Count; ++j) { var line_acc = bblock.Code[j]; if (line_acc.OpType == ThreeAddrOpType.Assign && line.Accum == line_acc.RightOp) { line_acc.OpType = line.OpType; line_acc.RightOp = line.RightOp; line_acc.LeftOp = line.LeftOp; ok = true; continue; } if (line.Accum == line_acc.RightOp || line.Accum == line_acc.LeftOp) { can_del = false; } } if (ok) { if (can_del) { line.OpType = ThreeAddrOpType.Nop; } return(true); } } } return(false); }
public override bool Optimize(BaseBlock bblock) { // Обход строк всех строк блока for (int i = 0; i < bblock.Code.Count; i++) { ThreeAddrLine line = bblock.Code[i]; string opType = line.OpType; // Яляется ли строка строкой вида: a = b op c if (ThreeAddrOpType.IsDefinition(opType) && opType != ThreeAddrOpType.Assign && opType != ThreeAddrOpType.Read) { string leftOp = line.LeftOp; string rightOp = line.RightOp; for (int j = i + 1; j < bblock.Code.Count; ++j) { ThreeAddrLine nextLine = bblock.Code[j]; if ((leftOp == nextLine.LeftOp) && (opType == nextLine.OpType) && (rightOp == nextLine.RightOp)) { nextLine.OpType = ThreeAddrOpType.Assign; nextLine.LeftOp = null; nextLine.RightOp = line.Accum; return(true); } if (nextLine.Accum == line.Accum || nextLine.Accum == rightOp || nextLine.Accum == leftOp) { break; } } } } return(false); }
public static VarsSet GetDefSet(BaseBlock bblock) { return(new VarsSet(bblock.Code .Where(l => ThreeAddrOpType.IsDefinition(l.OpType)) .Select(l => l.Accum))); }