From ae9665238615f49704290d948560e61259856d19 Mon Sep 17 00:00:00 2001
From: atrexus <110138304+atrexus@users.noreply.github.com>
Date: Tue, 13 Aug 2024 14:54:58 -0400
Subject: [PATCH] Clean up control flow generation
---
.../IR/ProtoTypes/ControlFlow/BasicBlock.cs | 6 ++--
src/Unluau/IR/ProtoTypes/ControlFlow/Graph.cs | 29 +++++++++----------
src/Unluau/IR/Writers/DotWriter.cs | 6 ++--
3 files changed, 21 insertions(+), 20 deletions(-)
diff --git a/src/Unluau/IR/ProtoTypes/ControlFlow/BasicBlock.cs b/src/Unluau/IR/ProtoTypes/ControlFlow/BasicBlock.cs
index 6fa9d3b..9f2bbcf 100644
--- a/src/Unluau/IR/ProtoTypes/ControlFlow/BasicBlock.cs
+++ b/src/Unluau/IR/ProtoTypes/ControlFlow/BasicBlock.cs
@@ -20,7 +20,7 @@ public enum BranchType
///
/// This block never branches.
///
- Never
+ Never,
}
///
@@ -31,7 +31,7 @@ public class BasicBlock : Node
///
/// The kind of branch that is taken.
///
- public BranchType Branch { get; set; } = BranchType.Always;
+ public BranchType? Branch { get; set; }
///
/// The list of instructions in the basic block.
@@ -45,6 +45,8 @@ public class BasicBlock : Node
public void AddEdge(BasicBlock target) => OutgoingEdges.Add(new Edge(this, target));
+ public bool IsDead => OutgoingEdges.Count == 0 && Branch == null;
+
///
public override void Accept(Visitor visitor)
{
diff --git a/src/Unluau/IR/ProtoTypes/ControlFlow/Graph.cs b/src/Unluau/IR/ProtoTypes/ControlFlow/Graph.cs
index fb8a758..afab6ae 100644
--- a/src/Unluau/IR/ProtoTypes/ControlFlow/Graph.cs
+++ b/src/Unluau/IR/ProtoTypes/ControlFlow/Graph.cs
@@ -48,7 +48,7 @@ private void AddInstruction(Instruction instruction)
if (instruction.Context.Pc == pc + 1)
{
- if (_currentBlock == oldBlock)
+ if (_currentBlock == oldBlock && _currentBlock.Instructions.Count > 0)
_currentBlock = new();
block.AddEdge(_currentBlock);
@@ -59,6 +59,9 @@ private void AddInstruction(Instruction instruction)
_currentBlock.Instructions.Add(instruction);
+ if (_currentBlock != oldBlock && oldBlock.IsDead)
+ oldBlock.AddEdge(_currentBlock);
+
switch (instruction.Code)
{
case OpCode.JumpX:
@@ -68,8 +71,6 @@ private void AddInstruction(Instruction instruction)
}
case OpCode.LoadB:
{
- var branchType = instruction.C > 0 ? BranchType.Always : BranchType.Never;
-
AddEdge(instruction.C, instruction.Context.Pc, _currentBlock, BranchType.Always);
break;
}
@@ -79,21 +80,25 @@ private void AddInstruction(Instruction instruction)
AddEdge(instruction.D, instruction.Context.Pc, _currentBlock, BranchType.Always);
break;
}
+ case OpCode.ForNPrep:
+ {
+ AddEdge(0, instruction.Context.Pc, _currentBlock, BranchType.Always);
+ break;
+ }
case OpCode.Return:
{
AddEdge(0, instruction.Context.Pc, _currentBlock, BranchType.Never);
- goto default;
+ break;
}
case OpCode.JumpXEqKNil:
case OpCode.JumpXEqKB:
case OpCode.JumpXEqKN:
case OpCode.JumpXEqKS:
{
- var branchType = instruction.D > 0 ? BranchType.Can : BranchType.Never;
-
- AddEdge(instruction.D == 1 ? 0 : instruction.D, instruction.Context.Pc, _currentBlock, branchType);
+ AddEdge(instruction.D == 1 ? 0 : instruction.D, instruction.Context.Pc, _currentBlock, BranchType.Can);
break;
}
+ case OpCode.ForNLoop:
case OpCode.JumpIf:
case OpCode.JumpIfNot:
case OpCode.JumpIfEq:
@@ -103,15 +108,7 @@ private void AddInstruction(Instruction instruction)
case OpCode.JumpIfLt:
case OpCode.JumpIfNotLt:
{
- var branchType = instruction.D > 0 ? BranchType.Can : BranchType.Never;
-
- AddEdge(instruction.D, instruction.Context.Pc, _currentBlock, branchType);
- break;
- }
- default:
- {
- if (_currentBlock != oldBlock)
- oldBlock.AddEdge(_currentBlock);
+ AddEdge(instruction.D, instruction.Context.Pc, _currentBlock, BranchType.Can);
break;
}
}
diff --git a/src/Unluau/IR/Writers/DotWriter.cs b/src/Unluau/IR/Writers/DotWriter.cs
index 35f41b7..0d4e833 100644
--- a/src/Unluau/IR/Writers/DotWriter.cs
+++ b/src/Unluau/IR/Writers/DotWriter.cs
@@ -73,7 +73,7 @@ public override bool Visit(ProtoType protoType)
_graph!.Add(_protoSubGraph);
// Visit all basic blocks in the control flow graph.
- protoType.ControlFlow.Accept(this);
+ protoType.ControlFlow!.Accept(this);
return false;
}
@@ -144,7 +144,9 @@ public override bool Visit(Edge edge)
.From($"block_{edge.Source.GetHashCode()}").To($"block_{edge.Target.GetHashCode()}")
.WithArrowHead(DotEdgeArrowType.Vee)
.WithArrowTail(DotEdgeArrowType.None)
- .WithAttribute("fontname", "Helvetica");
+ .WithAttribute("fontname", "Helvetica")
+ .WithAttribute("headport", "n")
+ .WithAttribute("tailport", "s");
if (_edgeName != null)
myEdge = myEdge.WithLabel(_edgeName);