public BranchComparePodInstruction(CodeLocationTag codeLocation, HighSsaRegister regA, HighSsaRegister regB, HighCfgNodeHandle equalNode, HighCfgNodeHandle notEqualNode) : base(codeLocation) { m_regA = regA; m_regB = regB; m_equalNode = new HighCfgEdge(this, equalNode); m_notEqualNode = new HighCfgEdge(this, notEqualNode); }
public RloRoutedBranchInstruction(CodeLocationTag codeLocation, int routeID, HighCfgNode destination) : base(codeLocation) { m_routeID = routeID; m_destination = new HighCfgEdge(this, new HighCfgNodeHandle(destination)); }
public EdgedRouteTermination(int routeID, HighCfgEdge successor) { m_routeID = routeID; m_successor = successor; }
private void TranslateCfgEdge(ref HighCfgEdge cfgEdge) { cfgEdge = new HighCfgEdge(cfgEdge.Source, this.GetNode(cfgEdge.Dest.Value)); }
private void ProcessNode(HighCfgNode cfgNode) { HighCfgNode lastNode = cfgNode; HighInstruction lastInstr = cfgNode.Instructions[cfgNode.Instructions.Length - 1]; // Rebuild handles so they're definitely not shared, collect handles List<HighCfgNodeHandle> successorLinkHandles = new List<HighCfgNodeHandle>(); IBranchingInstruction brInstr = lastInstr as IBranchingInstruction; if (brInstr != null) { brInstr.VisitSuccessors(delegate (ref HighCfgEdge edge) { foreach (HighPhi phi in edge.Dest.Value.Phis) { HighPhiLink[] links = phi.Links; for (int i = 0; i < links.Length; i++) { if (links[i].Predecessor.Value == cfgNode) { HighCfgNodeHandle hdl = new HighCfgNodeHandle(cfgNode); links[i].Predecessor = hdl; successorLinkHandles.Add(hdl); } } } if (edge.Dest.Value.Instructions[0] is Rpa.Instructions.CatchInstruction) throw new RpaCompileException("Branch target is a catch instruction"); // Relink edges to their new sources edge = new HighCfgEdge(lastInstr, edge.Dest); QueueNode(edge.Dest.Value); }); } List<HighInstruction> newInstructions = new List<HighInstruction>(); HighInstruction[] originalInstructions = cfgNode.Instructions; foreach (HighInstruction instr in originalInstructions) { if (instr is Rpa.Instructions.ReturnValueInstruction) { if (m_regionStack != null) throw new RpaCompileException("ReturnValueInstruction in a protected region"); newInstructions.Add(instr); } else if (instr is Rpa.Instructions.ReturnInstruction) { if (m_regionStack != null) { if (m_finallyCleanupNode == null) throw new RpaCompileException("ReturnInstruction in a protected region doesn't exit a finally"); newInstructions.Add(new Rpa.Instructions.BranchInstruction(instr.CodeLocation, new HighCfgNodeHandle(m_finallyCleanupNode))); } else { if (!m_canReturnNothing) throw new RpaCompileException("ReturnInstruction in a function that returns a value"); newInstructions.Add(instr); } } else if (instr is Rpa.Instructions.LeaveRegionInstruction) { Rpa.Instructions.LeaveRegionInstruction tInstr = (Rpa.Instructions.LeaveRegionInstruction)instr; if (m_finallyCleanupNode != null && !m_isTry) throw new RpaCompileException("LeaveRegionInstruction isn't valid in a finally handler"); uint routeID = tInstr.RouteID; bool isRouted = false; HighCfgNode matchingNode = null; RegionStack stack = m_regionStack; while (stack != null) { if (stack.EHCluster.ProtectedRegion is HighTryFinallyRegion) { isRouted = true; matchingNode = stack.ExceptionHandler; break; } else { bool matched = false; foreach (HighEscapePathTerminator terminator in stack.EHCluster.EscapePathTerminators) { if (terminator.EscapePath == routeID) { matched = true; matchingNode = terminator.CfgNode.Value; break; } } if (matched) break; } stack = stack.Next; } if (matchingNode == null) throw new RpaCompileException("Unmatched exception escape route"); if (isRouted) newInstructions.Add(new Instructions.RloRoutedBranchInstruction(tInstr.CodeLocation, m_initPass.m_routeCompactionDict[routeID], matchingNode)); else newInstructions.Add(new Rpa.Instructions.BranchInstruction(tInstr.CodeLocation, new HighCfgNodeHandle(matchingNode))); } else if (instr is Rpa.Instructions.ThrowInstruction) { Rpa.Instructions.ThrowInstruction tInstr = (Rpa.Instructions.ThrowInstruction)instr; if (m_exceptionNode != null) tInstr.ExceptionEdge = new HighCfgEdge(tInstr, new HighCfgNodeHandle(m_exceptionNode)); newInstructions.Add(tInstr); } else if (instr is Rpa.Instructions.CatchInstruction) { throw new RpaCompileException("Invalid location of a catch instruction"); } else if (instr is Rpa.Instructions.EnterProtectedBlockInstruction) { Rpa.Instructions.EnterProtectedBlockInstruction tInstr = (Rpa.Instructions.EnterProtectedBlockInstruction)instr; HighEHCluster ehCluster = tInstr.EHCluster; HighProtectedRegion protRegion = ehCluster.ProtectedRegion; AddEscapePaths(ehCluster.EscapePathTerminators); HighCfgNode tryNode; if (protRegion is HighTryCatchRegion) { HighTryCatchRegion tProtRegion = (HighTryCatchRegion)protRegion; RegionStack regionStack = new RegionStack(m_regionStack, ehCluster, GenerateTryCatchHandler(tProtRegion)); tryNode = ProcessSubRegion(tProtRegion.TryRegion, regionStack, true); foreach (HighCatchHandler handler in tProtRegion.CatchHandlers) ProcessSubRegion(handler.Region, regionStack, false); } else if (protRegion is HighTryFaultRegion) { HighTryFaultRegion tProtRegion = (HighTryFaultRegion)protRegion; RegionStack regionStack = new RegionStack(m_regionStack, ehCluster, tProtRegion.FaultRegion.EntryNode.Value); tryNode = ProcessSubRegion(tProtRegion.TryRegion, regionStack, true); ProcessSubRegion(tProtRegion.FaultRegion, regionStack, false); } else if (protRegion is HighTryFinallyRegion) { HighTryFinallyRegion tProtRegion = (HighTryFinallyRegion)protRegion; HighCfgNode finallyInit = GenerateFinallyInit(tProtRegion.FinallyRegion.EntryNode.Value); RegionStack regionStack = new RegionStack(m_regionStack, ehCluster, finallyInit); tryNode = ProcessSubRegion(tProtRegion.TryRegion, regionStack, true); ProcessSubRegion(tProtRegion.FinallyRegion, regionStack, false); } else throw new Exception(); newInstructions.Add(new Rpa.Instructions.BranchInstruction(instr.CodeLocation, new HighCfgNodeHandle(tryNode))); } else { newInstructions.Add(instr); if (instr.MayThrow) { cfgNode.Instructions = newInstructions.ToArray(); HighCfgNode newNode = new HighCfgNode(new HighCfgNodeHandle[0], new HighPhi[0], null); HighCfgNodeHandle destHandle = new HighCfgNodeHandle(newNode); instr.ContinuationEdge = new HighCfgEdge(instr, destHandle); if (m_exceptionNode != null) instr.ExceptionEdge = new HighCfgEdge(instr, new HighCfgNodeHandle(m_exceptionNode)); cfgNode = newNode; newInstructions.Clear(); } } } if (newInstructions.Count == 0) throw new Exception(); cfgNode.Instructions = newInstructions.ToArray(); foreach (HighCfgNodeHandle linkHdl in successorLinkHandles) linkHdl.Value = cfgNode; }