BasicBlock.cs
1 using System.Collections.Generic; 2 3 namespace Ryujinx.Graphics.Shader.IntermediateRepresentation 4 { 5 class BasicBlock 6 { 7 public int Index { get; set; } 8 9 public LinkedList<INode> Operations { get; } 10 11 private BasicBlock _next; 12 private BasicBlock _branch; 13 14 public BasicBlock Next 15 { 16 get => _next; 17 set => _next = AddSuccessor(_next, value); 18 } 19 20 public BasicBlock Branch 21 { 22 get => _branch; 23 set => _branch = AddSuccessor(_branch, value); 24 } 25 26 public bool HasBranch => _branch != null; 27 public bool Reachable => Index == 0 || Predecessors.Count != 0; 28 29 public List<BasicBlock> Predecessors { get; } 30 31 public HashSet<BasicBlock> DominanceFrontiers { get; } 32 33 public BasicBlock ImmediateDominator { get; set; } 34 35 public BasicBlock() 36 { 37 Operations = new LinkedList<INode>(); 38 39 Predecessors = new List<BasicBlock>(); 40 41 DominanceFrontiers = new HashSet<BasicBlock>(); 42 } 43 44 public BasicBlock(int index) : this() 45 { 46 Index = index; 47 } 48 49 private BasicBlock AddSuccessor(BasicBlock oldBlock, BasicBlock newBlock) 50 { 51 oldBlock?.Predecessors.Remove(this); 52 newBlock?.Predecessors.Add(this); 53 54 return newBlock; 55 } 56 57 public INode GetLastOp() 58 { 59 return Operations.Last?.Value; 60 } 61 62 public void Append(INode node) 63 { 64 INode lastOp = GetLastOp(); 65 66 if (lastOp is Operation operation && IsControlFlowInst(operation.Inst)) 67 { 68 Operations.AddBefore(Operations.Last, node); 69 } 70 else 71 { 72 Operations.AddLast(node); 73 } 74 } 75 76 private static bool IsControlFlowInst(Instruction inst) 77 { 78 switch (inst) 79 { 80 case Instruction.Branch: 81 case Instruction.BranchIfFalse: 82 case Instruction.BranchIfTrue: 83 case Instruction.Discard: 84 case Instruction.Return: 85 return true; 86 default: 87 return false; 88 } 89 } 90 } 91 }