private static void RunOptimizationPasses(BasicBlock[] blocks) { bool modified; do { modified = false; for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++) { BasicBlock block = blocks[blkIndex]; LinkedListNode <INode> node = block.Operations.First; while (node != null) { LinkedListNode <INode> nextNode = node.Next; bool isUnused = IsUnused(node.Value); if (!(node.Value is Operation operation) || isUnused) { if (node.Value is PhiNode phi && !isUnused) { isUnused = PropagatePhi(phi); } if (isUnused) { RemoveNode(block, node); modified = true; } node = nextNode; continue; } ConstantFolding.RunPass(operation); Simplification.RunPass(operation); if (DestIsLocalVar(operation)) { if (operation.Inst == Instruction.Copy) { PropagateCopy(operation); RemoveNode(block, node); modified = true; } else if ((operation.Inst == Instruction.PackHalf2x16 && PropagatePack(operation)) || (operation.Inst == Instruction.ShuffleXor && MatchDdxOrDdy(operation))) { if (DestHasNoUses(operation)) { RemoveNode(block, node); } modified = true; } } node = nextNode; } if (BranchElimination.RunPass(block)) { RemoveNode(block, block.Operations.Last); modified = true; } } }while (modified); }
public static void RunPass(BasicBlock[] blocks, ShaderConfig config) { for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++) { GlobalToStorage.RunPass(blocks[blkIndex], config); } bool modified; do { modified = false; for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++) { BasicBlock block = blocks[blkIndex]; LinkedListNode <INode> node = block.Operations.First; while (node != null) { LinkedListNode <INode> nextNode = node.Next; bool isUnused = IsUnused(node.Value); if (!(node.Value is Operation operation) || isUnused) { if (isUnused) { RemoveNode(block, node); modified = true; } node = nextNode; continue; } ConstantFolding.RunPass(operation); Simplification.RunPass(operation); if (DestIsLocalVar(operation)) { if (operation.Inst == Instruction.Copy) { PropagateCopy(operation); RemoveNode(block, node); modified = true; } else if ((operation.Inst == Instruction.PackHalf2x16 && PropagatePack(operation)) || (operation.Inst == Instruction.ShuffleXor && MatchDdxOrDdy(operation))) { if (operation.Dest.UseOps.Count == 0) { RemoveNode(block, node); } modified = true; } } node = nextNode; } if (BranchElimination.RunPass(block)) { RemoveNode(block, block.Operations.Last); modified = true; } } }while (modified); for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++) { BindlessToIndexed.RunPass(blocks[blkIndex]); BindlessElimination.RunPass(blocks[blkIndex], config); // Try to eliminate any operations that are now unused. LinkedListNode <INode> node = blocks[blkIndex].Operations.First; while (node != null) { LinkedListNode <INode> nextNode = node.Next; if (IsUnused(node.Value)) { RemoveNode(blocks[blkIndex], node); } node = nextNode; } } }