Skip to content

Commit 4a21df8

Browse files
committed
Add Compare Instruction Matching
1 parent b5fc68d commit 4a21df8

3 files changed

Lines changed: 118 additions & 9 deletions

File tree

src/DistIL/IR/DSL/InstructionPattern.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
using PatternArguments;
77
using Utils.Parser;
88

9-
internal record InstructionPattern(Opcode Operation, List<IInstructionPatternArgument> Arguments)
9+
internal record InstructionPattern(Opcode OpCode, List<IInstructionPatternArgument> Arguments)
1010
: IInstructionPatternArgument
1111
{
1212
public static InstructionPattern? Parse(ReadOnlySpan<char> pattern)
@@ -25,8 +25,9 @@ internal record InstructionPattern(Opcode Operation, List<IInstructionPatternArg
2525

2626
// Split the operation from its arguments
2727
int spaceIndex = pattern.IndexOf(' ');
28-
if (spaceIndex == -1)
29-
throw new ArgumentException("Invalid pattern format.");
28+
if (spaceIndex == -1) {
29+
spaceIndex = pattern.Length;
30+
}
3031

3132
var operation = Opcodes.TryParse(pattern[..spaceIndex].ToString()); // TryParse does not support span yet
3233
var argsString = pattern[spaceIndex..].Trim();

src/DistIL/IR/MatchExtensions.cs

Lines changed: 106 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,90 @@ public static bool Match(this Instruction instruction, string pattern)
2222

2323
private static bool MatchInstruction(Instruction instruction, InstructionPattern instrPattern, OutputPattern outputs)
2424
{
25-
if (instrPattern.Arguments.Count == 2 && instruction is BinaryInst bin) {
25+
if (instruction is BinaryInst bin) {
2626
return MatchBinary(bin, instrPattern, outputs);
2727
}
28+
if (instruction is CompareInst comp) {
29+
return MatchCompare(comp, instrPattern, outputs);
30+
}
31+
else if (instruction is UnaryInst un) {
32+
return MatchUnary(un, instrPattern, outputs);
33+
}
2834

29-
return false;
35+
return MatchOtherInstruction(instruction, instrPattern, outputs);
36+
}
37+
38+
private static bool MatchOtherInstruction(Instruction instruction, InstructionPattern pattern, OutputPattern outputs)
39+
{
40+
var op = pattern.OpCode;
41+
var ops = MatchOpCode(op, instruction);
42+
43+
return MatchOperands(instruction, pattern, outputs);
44+
}
45+
46+
private static bool MatchOpCode(Opcode op, Instruction instruction)
47+
{
48+
return op switch {
49+
Opcode.Unknown => false,
50+
/* Opcode.Goto => expr,
51+
Opcode.Switch => expr,
52+
Opcode.Ret => expr,
53+
Opcode.Phi => expr,
54+
Opcode.Call => expr,
55+
Opcode.CallVirt => expr,
56+
Opcode.NewObj => expr,
57+
Opcode.Intrinsic => expr,
58+
Opcode.Select => expr,
59+
Opcode.Lea => expr,
60+
Opcode.Getfld => expr,
61+
Opcode.Setfld => expr,
62+
Opcode.ArrAddr => expr,
63+
Opcode.FldAddr => expr,
64+
Opcode.Load => expr,
65+
Opcode.Store => expr,
66+
Opcode.Conv => expr,
67+
Opcode._Cmp_First => expr,
68+
Opcode.Cmp_Eq => expr,
69+
Opcode.Cmp_Ne => expr,
70+
Opcode.Cmp_Slt => expr,
71+
Opcode.Cmp_Sgt => expr,
72+
Opcode.Cmp_Sle => expr,
73+
Opcode.Cmp_Sge => expr,
74+
Opcode.Cmp_Ult => expr,
75+
Opcode.Cmp_Ugt => expr,
76+
Opcode.Cmp_Ule => expr,
77+
Opcode.Cmp_Uge => expr,
78+
Opcode.Cmp_FOlt => expr,
79+
Opcode.Cmp_FOgt => expr,
80+
Opcode.Cmp_FOle => expr,
81+
Opcode.Cmp_FOge => expr,
82+
Opcode.Cmp_FOeq => expr,
83+
Opcode.Cmp_FOne => expr,
84+
Opcode.Cmp_FUlt => expr,
85+
Opcode.Cmp_FUgt => expr,
86+
Opcode.Cmp_FUle => expr,
87+
Opcode.Cmp_FUge => expr,
88+
Opcode.Cmp_FUeq => expr,
89+
Opcode.Cmp_FUne => expr,
90+
Opcode._Cmp_Last => expr,*/
91+
_ => throw new ArgumentOutOfRangeException(nameof(op), op, null)
92+
};
93+
}
94+
95+
private static bool MatchOperands(Instruction instruction, InstructionPattern pattern, OutputPattern outputs)
96+
{
97+
bool matched = true;
98+
99+
if (pattern.Arguments.Count > instruction.Operands.Length) {
100+
return false;
101+
}
102+
103+
for (int index = 0; index < pattern.Arguments.Count; index++) {
104+
Value? operand = instruction.Operands[index];
105+
matched &= MatchValue(operand, pattern.Arguments[index], outputs);
106+
}
107+
108+
return matched;
30109
}
31110

32111
private static bool MatchArgument(Value value, IInstructionPatternArgument argument, OutputPattern outputs)
@@ -167,16 +246,37 @@ private static bool MatchStringArg(StringArgument strArg, ConstString constant)
167246

168247
private static bool MatchBinary(BinaryInst bin, InstructionPattern pattern, OutputPattern outputs)
169248
{
170-
var operation = pattern.Operation;
249+
var operation = pattern.OpCode;
171250
var op = (BinaryOp)(operation - (Opcode._Bin_First + 1));
172251

173252
if (bin.Op != op) {
174253
return false;
175254
}
176255

177-
bool left = MatchValue(bin.Left, pattern.Arguments[0], outputs);
178-
bool right = MatchValue(bin.Right, pattern.Arguments[1], outputs);
256+
return MatchOperands(bin, pattern, outputs);
257+
}
258+
259+
private static bool MatchCompare(CompareInst comp, InstructionPattern pattern, OutputPattern outputs)
260+
{
261+
var operation = pattern.OpCode;
262+
var op = (CompareOp)(operation - (Opcode._Cmp_First + 1));
263+
264+
if (comp.Op != op) {
265+
return false;
266+
}
267+
268+
return MatchOperands(comp, pattern, outputs);
269+
}
270+
271+
private static bool MatchUnary(UnaryInst un, InstructionPattern pattern, OutputPattern outputs)
272+
{
273+
var operation = pattern.OpCode;
274+
var op = (UnaryOp)(operation - (Opcode._Bin_First + 1));
275+
276+
if (un.Op != op) {
277+
return false;
278+
}
179279

180-
return left && right;
280+
return MatchOperands(un, pattern, outputs);;
181281
}
182282
}

tests/DistIL.Tests/IR/MatchingTests.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,14 @@ public void TestReturn()
6767
Assert.True(inst.Match("(ret _)"));
6868
}
6969

70+
[Fact]
71+
public void TestCompare()
72+
{
73+
var inst = new CompareInst(CompareOp.Eq, ConstInt.CreateI(1), ConstInt.CreateI(3));
74+
75+
Assert.True(inst.Match("(cmp.eq)"));
76+
}
77+
7078
[Fact]
7179
public void TestUnary()
7280
{

0 commit comments

Comments
 (0)