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  }