public BBLoop(BasicBlock head, BasicBlock tail, IMSet<BasicBlock> body, JST.Identifier label) { Head = head; Tail = tail; Body = body; Label = label; var headEscapes = false; var headbranchbb = head as BranchBasicBlock; foreach (var t in head.Targets) { if (!body.Contains(t)) headEscapes = true; } var tailEscapes = false; var tailbranchbb = tail as BranchBasicBlock; foreach (var t in tail.Targets) { if (!body.Contains(t)) tailEscapes = true; } if (!headEscapes && tailEscapes && tailbranchbb != null) { if (tailbranchbb.Target.Equals(head)) Flavor = LoopFlavor.DoWhile; else if (tailbranchbb.Fallthrough.Equals(head)) Flavor = LoopFlavor.FlippedDoWhile; else throw new InvalidOperationException("invalid loop"); } else if (headEscapes && !tailEscapes && headbranchbb != null) { if (body.Contains(headbranchbb.Target)) Flavor = LoopFlavor.WhileDo; else if (body.Contains(headbranchbb.Fallthrough)) Flavor = LoopFlavor.FlippedWhileDo; else throw new InvalidOperationException("invalid loop"); } else if (!headEscapes && !tailEscapes) Flavor = LoopFlavor.Loop; else if (headEscapes && tailEscapes && headbranchbb != null && tailbranchbb != null) { // Could encode as do-while with a break at start, or while-do with a break at end. if (body.Contains(headbranchbb.Target)) Flavor = LoopFlavor.WhileDo; else if (body.Contains(headbranchbb.Fallthrough)) Flavor = LoopFlavor.FlippedWhileDo; else throw new InvalidOperationException("invalid loop"); } else Flavor = LoopFlavor.Unknown; }
public override void AccumLeaveTrys(IMSet <BasicBlock> visited, ISeq <LeaveTryBasicBlock> acc, int depth) { if (!visited.Contains(this)) { visited.Add(this); Target.AccumLeaveTrys(visited, acc, depth); } }
public override void AccumLeaveTrys(IMSet <BasicBlock> visited, ISeq <LeaveTryBasicBlock> acc, int depth) { if (!visited.Contains(this)) { visited.Add(this); // Remember, this basic block is for 'leaves' which don't acutally leave any try context, // in other words are just a fancy way of emptying the stack. Target.AccumLeaveTrys(visited, acc, depth); } }
public override void AccumLeaveTrys(IMSet <BasicBlock> visited, ISeq <LeaveTryBasicBlock> acc, int depth) { if (!visited.Contains(this)) { visited.Add(this); foreach (var bb in CaseTargets) { bb.AccumLeaveTrys(visited, acc, depth); } Fallthrough.AccumLeaveTrys(visited, acc, depth); } }
public override void AccumLeaveTrys(IMSet <BasicBlock> visited, ISeq <LeaveTryBasicBlock> acc, int depth) { if (!visited.Contains(this)) { visited.Add(this); depth -= HandlerPopCount; if (depth >= 0) { Target.AccumLeaveTrys(visited, acc, depth); } } }
public override void AccumLeaveTrys(IMSet <BasicBlock> visited, ISeq <LeaveTryBasicBlock> acc, int depth) { if (!visited.Contains(this)) { visited.Add(this); Body.AccumLeaveTrys(visited, acc, depth + 1); foreach (var h in Handlers) { h.AccumLeaveTrys(visited, acc, depth + 1); } } }
public override void AccumLeaveTrys(IMSet <BasicBlock> visited, ISeq <LeaveTryBasicBlock> acc, int depth) { if (!visited.Contains(this)) { visited.Add(this); if (depth == 0) { // Only include leave's from the try we started from, not inner trys acc.Add(this); } else { depth -= HandlerPopCount; if (depth >= 0) { Target.AccumLeaveTrys(visited, acc, depth); } } } }
public BBLoop(BasicBlock head, BasicBlock tail, IMSet <BasicBlock> body, JST.Identifier label) { Head = head; Tail = tail; Body = body; Label = label; var headEscapes = false; var headbranchbb = head as BranchBasicBlock; foreach (var t in head.Targets) { if (!body.Contains(t)) { headEscapes = true; } } var tailEscapes = false; var tailbranchbb = tail as BranchBasicBlock; foreach (var t in tail.Targets) { if (!body.Contains(t)) { tailEscapes = true; } } if (!headEscapes && tailEscapes && tailbranchbb != null) { if (tailbranchbb.Target.Equals(head)) { Flavor = LoopFlavor.DoWhile; } else if (tailbranchbb.Fallthrough.Equals(head)) { Flavor = LoopFlavor.FlippedDoWhile; } else { throw new InvalidOperationException("invalid loop"); } } else if (headEscapes && !tailEscapes && headbranchbb != null) { if (body.Contains(headbranchbb.Target)) { Flavor = LoopFlavor.WhileDo; } else if (body.Contains(headbranchbb.Fallthrough)) { Flavor = LoopFlavor.FlippedWhileDo; } else { throw new InvalidOperationException("invalid loop"); } } else if (!headEscapes && !tailEscapes) { Flavor = LoopFlavor.Loop; } else if (headEscapes && tailEscapes && headbranchbb != null && tailbranchbb != null) { // Could encode as do-while with a break at start, or while-do with a break at end. if (body.Contains(headbranchbb.Target)) { Flavor = LoopFlavor.WhileDo; } else if (body.Contains(headbranchbb.Fallthrough)) { Flavor = LoopFlavor.FlippedWhileDo; } else { throw new InvalidOperationException("invalid loop"); } } else { Flavor = LoopFlavor.Unknown; } }