using System.Collections.Generic; namespace Ryujinx.Graphics.Shader.IntermediateRepresentation { class BasicBlock { public int Index { get; set; } public LinkedList Operations { get; } private BasicBlock _next; private BasicBlock _branch; public BasicBlock Next { get => _next; set => _next = AddSuccessor(_next, value); } public BasicBlock Branch { get => _branch; set => _branch = AddSuccessor(_branch, value); } public bool HasBranch => _branch != null; public bool Reachable => Index == 0 || Predecessors.Count != 0; public List Predecessors { get; } public HashSet DominanceFrontiers { get; } public BasicBlock ImmediateDominator { get; set; } public BasicBlock() { Operations = new LinkedList(); Predecessors = new List(); DominanceFrontiers = new HashSet(); } public BasicBlock(int index) : this() { Index = index; } private BasicBlock AddSuccessor(BasicBlock oldBlock, BasicBlock newBlock) { oldBlock?.Predecessors.Remove(this); newBlock?.Predecessors.Add(this); return newBlock; } public INode GetLastOp() { return Operations.Last?.Value; } public void Append(INode node) { INode lastOp = GetLastOp(); if (lastOp is Operation operation && IsControlFlowInst(operation.Inst)) { Operations.AddBefore(Operations.Last, node); } else { Operations.AddLast(node); } } private static bool IsControlFlowInst(Instruction inst) { switch (inst) { case Instruction.Branch: case Instruction.BranchIfFalse: case Instruction.BranchIfTrue: case Instruction.Discard: case Instruction.Return: return true; } return false; } } }