| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- using Ryujinx.Graphics.Shader.IntermediateRepresentation;
- using System.Collections.Generic;
- namespace Ryujinx.Graphics.Shader.Translation
- {
- static class ControlFlowGraph
- {
- public static BasicBlock[] MakeCfg(Operation[] operations)
- {
- Dictionary<Operand, BasicBlock> labels = new Dictionary<Operand, BasicBlock>();
- List<BasicBlock> blocks = new List<BasicBlock>();
- BasicBlock currentBlock = null;
- void NextBlock(BasicBlock nextBlock)
- {
- if (currentBlock != null && !EndsWithUnconditionalInst(currentBlock.GetLastOp()))
- {
- currentBlock.Next = nextBlock;
- }
- currentBlock = nextBlock;
- }
- void NewNextBlock()
- {
- BasicBlock block = new BasicBlock(blocks.Count);
- blocks.Add(block);
- NextBlock(block);
- }
- bool needsNewBlock = true;
- for (int index = 0; index < operations.Length; index++)
- {
- Operation operation = operations[index];
- if (operation.Inst == Instruction.MarkLabel)
- {
- Operand label = operation.Dest;
- if (labels.TryGetValue(label, out BasicBlock nextBlock))
- {
- nextBlock.Index = blocks.Count;
- blocks.Add(nextBlock);
- NextBlock(nextBlock);
- }
- else
- {
- NewNextBlock();
- labels.Add(label, currentBlock);
- }
- }
- else
- {
- if (needsNewBlock)
- {
- NewNextBlock();
- }
- currentBlock.Operations.AddLast(operation);
- }
- needsNewBlock = operation.Inst == Instruction.Branch ||
- operation.Inst == Instruction.BranchIfTrue ||
- operation.Inst == Instruction.BranchIfFalse;
- if (needsNewBlock)
- {
- Operand label = operation.Dest;
- if (!labels.TryGetValue(label, out BasicBlock branchBlock))
- {
- branchBlock = new BasicBlock();
- labels.Add(label, branchBlock);
- }
- currentBlock.Branch = branchBlock;
- }
- }
- return blocks.ToArray();
- }
- private static bool EndsWithUnconditionalInst(INode node)
- {
- if (node is Operation operation)
- {
- switch (operation.Inst)
- {
- case Instruction.Branch:
- case Instruction.Discard:
- case Instruction.Return:
- return true;
- }
- }
- return false;
- }
- }
- }
|