diff --git a/DMCompiler/DM/Builders/DMASTFolder.cs b/DMCompiler/DM/Builders/DMASTFolder.cs index ef41916191..c117824b65 100644 --- a/DMCompiler/DM/Builders/DMASTFolder.cs +++ b/DMCompiler/DM/Builders/DMASTFolder.cs @@ -254,13 +254,6 @@ private DMASTExpression FoldExpression(DMASTExpression? expression) { break; } - case DMASTAdd add: { - DMASTConstantString? lhsString = add.LHS as DMASTConstantString; - DMASTConstantString? rhsString = add.RHS as DMASTConstantString; - if (lhsString != null && rhsString != null) return new DMASTConstantString(expression.Location, lhsString.Value + rhsString.Value); - - break; - } #endregion Math diff --git a/DMCompiler/Optimizer/AnnotatedBytecode.cs b/DMCompiler/Optimizer/AnnotatedBytecode.cs index b84a212c93..f931b84b72 100644 --- a/DMCompiler/Optimizer/AnnotatedBytecode.cs +++ b/DMCompiler/Optimizer/AnnotatedBytecode.cs @@ -249,6 +249,10 @@ public void SetLocation(Location loc) { public Location GetLocation() { return Location; } + + public string ResolveString() { + return DMObjectTree.StringTable[Id]; + } } internal sealed class AnnotatedBytecodeArgumentType : IAnnotatedBytecode { diff --git a/DMCompiler/Optimizer/PeepholeOptimizations.cs b/DMCompiler/Optimizer/PeepholeOptimizations.cs index ad82b829a4..ef8b6592e2 100644 --- a/DMCompiler/Optimizer/PeepholeOptimizations.cs +++ b/DMCompiler/Optimizer/PeepholeOptimizations.cs @@ -1,4 +1,5 @@ using DMCompiler.Bytecode; +using DMCompiler.DM; namespace DMCompiler.Optimizer; @@ -678,6 +679,33 @@ public void Apply(List input, int index) { } } +// PushString [constant] +// PushString [constant] +// Add +// -> PushString [result] +internal sealed class ConstFoldAddStrings : IPeepholeOptimization { + public ReadOnlySpan GetOpcodes() { + return [ + DreamProcOpcode.PushString, + DreamProcOpcode.PushString, + DreamProcOpcode.Add, + ]; + } + + public void Apply(List input, int index) { + var firstInstruction = (AnnotatedBytecodeInstruction)input[index]; + var firstString = firstInstruction.GetArg(0); + var secondString = ((AnnotatedBytecodeInstruction)input[index+1]).GetArg(0); + + var combinedId = DMObjectTree.AddString(firstString.ResolveString() + secondString.ResolveString()); + + var args = new List(1) {new AnnotatedBytecodeString(combinedId, firstInstruction.Location)}; + + IPeepholeOptimization.ReplaceInstructions(input, index, 3, + new AnnotatedBytecodeInstruction(DreamProcOpcode.PushString, 1, args)); + } +} + // PushFloat [constant] // PushFloat [constant] // Subtract