Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions DMCompiler/DM/Builders/DMASTFolder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,15 @@ private DMASTExpression FoldExpression(DMASTExpression? expression) {

break;
}
case DMASTLeftShift leftShift: {
if (leftShift is { LHS: DMASTConstantInteger lhsInt, RHS: DMASTConstantInteger rhsInt }) {
return new DMASTConstantInteger(expression.Location, lhsInt.Value << rhsInt.Value);
break;
case DMASTRightShift rightShift: {
if (rightShift is { LHS: DMASTConstantInteger lhsInt, RHS: DMASTConstantInteger rhsInt }) {
return new DMASTConstantInteger(expression.Location, lhsInt.Value >> rhsInt.Value);
break;
}
case DMASTBinaryAnd binaryAnd: {
if (binaryAnd is { LHS: DMASTConstantInteger lhsInt, RHS: DMASTConstantInteger rhsInt }) {
return new DMASTConstantInteger(expression.Location, lhsInt.Value & rhsInt.Value);
Expand Down
72 changes: 72 additions & 0 deletions DMCompiler/Optimizer/PeepholeOptimizations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,78 @@ public void Apply(List<IAnnotatedBytecode> input, int index) {
}

#region Constant Folding

// PushFloat [constant]
// BitNot
// -> PushFloat [result]
internal sealed class ConstFoldBitNot : IPeepholeOptimization {
public ReadOnlySpan<DreamProcOpcode> GetOpcodes() {
return [
DreamProcOpcode.PushFloat,
DreamProcOpcode.BitNot
];
}

public void Apply(List<IAnnotatedBytecode> input, int index) {
var firstInstruction = IPeepholeOptimization.GetInstructionAndValue(input[index], out var pushVal1);

var args = new List<IAnnotatedBytecode>(1) {new AnnotatedBytecodeFloat(((~(int)pushVal1) & 0xFFFFFF), firstInstruction.Location)};

IPeepholeOptimization.ReplaceInstructions(input, index, 2,
new AnnotatedBytecodeInstruction(DreamProcOpcode.PushFloat, 1, args));
}
}

// PushFloat [constant]
// PushFloat [constant]
// BitOr
// -> PushFloat [result]
internal sealed class ConstFoldBitOr : IPeepholeOptimization {
public ReadOnlySpan<DreamProcOpcode> GetOpcodes() {
return [
DreamProcOpcode.PushFloat,
DreamProcOpcode.PushFloat,
DreamProcOpcode.BitOr,
];
}

public void Apply(List<IAnnotatedBytecode> input, int index) {
var firstInstruction = IPeepholeOptimization.GetInstructionAndValue(input[index], out var pushVal1);

IPeepholeOptimization.GetInstructionAndValue(input[index + 1], out var pushVal2);

var args = new List<IAnnotatedBytecode>(1) {new AnnotatedBytecodeFloat(((int)pushVal1 | (int)pushVal2), firstInstruction.Location)};

IPeepholeOptimization.ReplaceInstructions(input, index, 3,
new AnnotatedBytecodeInstruction(DreamProcOpcode.PushFloat, 1, args));
}
}

// PushFloat [constant]
// PushFloat [constant]
// BitAnd
// -> PushFloat [result]
internal sealed class ConstFoldBitAnd : IPeepholeOptimization {
public ReadOnlySpan<DreamProcOpcode> GetOpcodes() {
return [
DreamProcOpcode.PushFloat,
DreamProcOpcode.PushFloat,
DreamProcOpcode.BitAnd,
];
}

public void Apply(List<IAnnotatedBytecode> input, int index) {
var firstInstruction = IPeepholeOptimization.GetInstructionAndValue(input[index], out var pushVal1);

IPeepholeOptimization.GetInstructionAndValue(input[index + 1], out var pushVal2);

var args = new List<IAnnotatedBytecode>(1) {new AnnotatedBytecodeFloat(((int)pushVal1 & (int)pushVal2), firstInstruction.Location)};

IPeepholeOptimization.ReplaceInstructions(input, index, 3,
new AnnotatedBytecodeInstruction(DreamProcOpcode.PushFloat, 1, args));
}
}

// PushFloat [constant]
// PushFloat [constant]
// Multiply
Expand Down