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;
            }