Skip to content

Commit

Permalink
Expand IR for integer operations with constant operands
Browse files Browse the repository at this point in the history
  • Loading branch information
Viir committed Jan 6, 2025
1 parent 4696d06 commit 5182ae2
Show file tree
Hide file tree
Showing 4 changed files with 193 additions and 4 deletions.
49 changes: 45 additions & 4 deletions implement/pine/Pine/PineVM/PineVM.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1352,14 +1352,14 @@ static ExecutionErrorReport buildErrorReport(StackFrame stackFrame)
var right = currentInstruction.Literal
??
throw new Exception("Invalid operation form: Missing literal value");

var left = currentFrame.PopTopmostFromStack();

var areEqual = left == right;

currentFrame.PushInstructionResult(
areEqual ? PineVMValues.FalseValue : PineVMValues.TrueValue);

continue;
}

Expand Down Expand Up @@ -1629,6 +1629,27 @@ static ExecutionErrorReport buildErrorReport(StackFrame stackFrame)
continue;
}

case StackInstructionKind.Int_Add_Const:
{
var rightInt =
currentInstruction.IntegerLiteral
??
throw new Exception("Invalid operation form: Missing literal value");

var leftValue = currentFrame.PopTopmostFromStack();

PineValue resultValue = PineValue.EmptyList;

if (KernelFunction.SignedIntegerFromValueRelaxed(leftValue) is { } leftInt)
{
resultValue = PineValueAsInteger.ValueFromSignedInteger(leftInt + rightInt);
}

currentFrame.PushInstructionResult(resultValue);

continue;
}

case StackInstructionKind.Int_Sub_Binary:
{
var right = currentFrame.PopTopmostFromStack();
Expand Down Expand Up @@ -1665,6 +1686,26 @@ static ExecutionErrorReport buildErrorReport(StackFrame stackFrame)
continue;
}

case StackInstructionKind.Int_Mul_Const:
{
var right = currentInstruction.IntegerLiteral
??
throw new Exception("Invalid operation form: Missing literal value");

var left = currentFrame.PopTopmostFromStack();

PineValue resultValue = PineValue.EmptyList;

if (KernelFunction.SignedIntegerFromValueRelaxed(left) is { } leftInt)
{
resultValue = PineValueAsInteger.ValueFromSignedInteger(leftInt * right);
}

currentFrame.PushInstructionResult(resultValue);

continue;
}

case StackInstructionKind.Int_Less_Than_Binary:
{
var right = currentFrame.PopTopmostFromStack();
Expand Down
73 changes: 73 additions & 0 deletions implement/pine/PineVM/PineIRCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -869,6 +869,42 @@ public static NodeCompilationResult CompileKernelApplication_Int_Add(
Literal: PineValueAsInteger.ValueFromSignedInteger(0)));
}

if (listExpr.items.Count is 2)
{
if (listExpr.items[0] is Expression.Literal leftLiteralExpr &&
KernelFunction.SignedIntegerFromValueRelaxed(leftLiteralExpr.Value) is { } leftInt)
{
var afterRight =
CompileExpressionTransitive(
listExpr.items[1],
copyToLocal,
prior);

return
afterRight
.AppendInstruction(
new StackInstruction(
StackInstructionKind.Int_Add_Const,
IntegerLiteral: leftInt));
}

if (listExpr.items[1] is Expression.Literal rightLiteralExpr &&
KernelFunction.SignedIntegerFromValueRelaxed(rightLiteralExpr.Value) is { } rightInt)
{
var afterLeft =
CompileExpressionTransitive(
listExpr.items[0],
copyToLocal,
prior);
return
afterLeft
.AppendInstruction(
new StackInstruction(
StackInstructionKind.Int_Add_Const,
IntegerLiteral: rightInt));
}
}

var addOps = prior;

for (var i = 0; i < listExpr.items.Count; ++i)
Expand Down Expand Up @@ -941,6 +977,43 @@ public static NodeCompilationResult CompileKernelApplication_Int_Mul(
Literal: PineValueAsInteger.ValueFromSignedInteger(1)));
}

if (listExpr.items.Count is 2)
{
if (listExpr.items[0] is Expression.Literal leftLiteralExpr &&
KernelFunction.SignedIntegerFromValueRelaxed(leftLiteralExpr.Value) is { } leftInt)
{
var afterRight =
CompileExpressionTransitive(
listExpr.items[1],
copyToLocal,
prior);

return
afterRight
.AppendInstruction(
new StackInstruction(
StackInstructionKind.Int_Mul_Const,
IntegerLiteral: leftInt));
}

if (listExpr.items[1] is Expression.Literal rightLiteralExpr &&
KernelFunction.SignedIntegerFromValueRelaxed(rightLiteralExpr.Value) is { } rightInt)
{
var afterLeft =
CompileExpressionTransitive(
listExpr.items[0],
copyToLocal,
prior);

return
afterLeft
.AppendInstruction(
new StackInstruction(
StackInstructionKind.Int_Mul_Const,
IntegerLiteral: rightInt));
}
}

var mulOps = prior;

for (var i = 0; i < listExpr.items.Count; ++i)
Expand Down
12 changes: 12 additions & 0 deletions implement/pine/PineVM/StackInstruction.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Pine.Core;
using System.Numerics;

namespace Pine.PineVM;

Expand Down Expand Up @@ -154,6 +155,11 @@ public enum StackInstructionKind
/// </summary>
Int_Add_Binary,

/// <summary>
/// Add the integer literal from <see cref="StackInstruction.IntegerLiteral"/>.
/// </summary>
Int_Add_Const,

/// <summary>
/// Add all items in the list from the top value from the stack.
/// </summary>
Expand All @@ -169,6 +175,11 @@ public enum StackInstructionKind
/// </summary>
Int_Mul_Binary,

/// <summary>
/// Multiply the top value on the stack with the integer literal from <see cref="StackInstruction.IntegerLiteral"/>.
/// </summary>
Int_Mul_Const,

/// <summary>
/// Multiply all items in the list from the top value from the stack.
/// </summary>
Expand Down Expand Up @@ -226,6 +237,7 @@ public enum StackInstructionKind
public record StackInstruction(
StackInstructionKind Kind,
PineValue? Literal = null,
BigInteger? IntegerLiteral = null,
int? LocalIndex = null,
int? SkipCount = null,
int? TakeCount = null,
Expand Down
63 changes: 63 additions & 0 deletions implement/test-elm-time/PineVMTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1485,6 +1485,69 @@ public void Compile_stack_frame_instructions()
StackInstruction.Return,
])
},

new
{
expression =
(Expression)
new Expression.KernelApplication(
function: "int_add",
input:
Expression.ListInstance(
[
new Expression.KernelApplication(
function: "head",
input: Expression.EnvironmentInstance),

Expression.LiteralInstance(PineValueAsInteger.ValueFromSignedInteger(13)),
])),

expected =
new PineVM.StackFrameInstructions(
[
new StackInstruction(StackInstructionKind.Push_Environment),

new StackInstruction(StackInstructionKind.Head_Generic),

new StackInstruction(
StackInstructionKind.Int_Add_Const,
IntegerLiteral: 13),

StackInstruction.Return,
])
},

new
{
expression =
(Expression)
new Expression.KernelApplication(
function: "int_mul",
input:
Expression.ListInstance(
[
new Expression.KernelApplication(
function: "head",
input: Expression.EnvironmentInstance),

Expression.LiteralInstance(PineValueAsInteger.ValueFromSignedInteger(17)),
])),

expected =
new PineVM.StackFrameInstructions(
[
new StackInstruction(StackInstructionKind.Push_Environment),

new StackInstruction(StackInstructionKind.Head_Generic),

new StackInstruction(
StackInstructionKind.Int_Mul_Const,
IntegerLiteral: 17),

StackInstruction.Return,
])
},

};

var parseCache = new PineVMParseCache();
Expand Down

0 comments on commit 5182ae2

Please sign in to comment.