Skip to content

Commit 9baa20a

Browse files
committed
Check if the string is same when optimizing numeric strings
1 parent 6eafec6 commit 9baa20a

File tree

3 files changed

+64
-2
lines changed

3 files changed

+64
-2
lines changed

src/engine/internal/llvm/llvmbuildutils.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -434,8 +434,15 @@ Compiler::StaticType LLVMBuildUtils::optimizeRegisterType(const LLVMRegister *re
434434
Compiler::StaticType ret = reg->type();
435435

436436
// Optimize string constants that represent numbers
437-
if (reg->isConst() && reg->type() == Compiler::StaticType::String && reg->constValue().isValidNumber())
438-
ret = Compiler::StaticType::Number;
437+
if (reg->isConst() && reg->type() == Compiler::StaticType::String) {
438+
const Value &value = reg->constValue();
439+
Value numberValue(value.toDouble());
440+
441+
// Apply this optimization only if the number matches the string
442+
// TODO: Exclude unsafe constants
443+
if (value.isValidNumber() && numberValue.toString() == value.toString())
444+
ret = Compiler::StaticType::Number;
445+
}
439446

440447
return ret;
441448
}

test/llvm/code_analyzer/list_type_analysis.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,36 @@ TEST(LLVMCodeAnalyzer_ListTypeAnalysis, StringOptimization_AfterClear)
152152
ASSERT_EQ(appendList2->targetType, Compiler::StaticType::Number);
153153
}
154154

155+
TEST(LLVMCodeAnalyzer_ListTypeAnalysis, StringOptimization_AfterClear_DifferentString)
156+
{
157+
LLVMCodeAnalyzer analyzer;
158+
LLVMInstructionList list;
159+
List targetList("", "");
160+
161+
auto clearList = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::ClearList, false);
162+
clearList->targetList = &targetList;
163+
list.addInstruction(clearList);
164+
165+
auto appendList1 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::AppendToList, false);
166+
LLVMConstantRegister value1(Compiler::StaticType::String, "1.0");
167+
appendList1->targetList = &targetList;
168+
appendList1->args.push_back({ Compiler::StaticType::Unknown, &value1 });
169+
list.addInstruction(appendList1);
170+
171+
auto appendList2 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::AppendToList, false);
172+
LLVMConstantRegister value2(Compiler::StaticType::Bool, true);
173+
appendList2->targetList = &targetList;
174+
appendList2->args.push_back({ Compiler::StaticType::Unknown, &value2 });
175+
list.addInstruction(appendList2);
176+
177+
analyzer.analyzeScript(list);
178+
179+
ASSERT_EQ(appendList1->targetType, Compiler::StaticType::Void);
180+
181+
// String "1.0" does NOT get optimized to Number because it would convert to "1"
182+
ASSERT_EQ(appendList2->targetType, Compiler::StaticType::String);
183+
}
184+
155185
TEST(LLVMCodeAnalyzer_ListTypeAnalysis, ClearListOperation)
156186
{
157187
LLVMCodeAnalyzer analyzer;

test/llvm/code_analyzer/variable_type_analysis.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,31 @@ TEST(LLVMCodeAnalyzer_VariableTypeAnalysis, StringOptimization)
107107
ASSERT_EQ(setVar2->targetType, Compiler::StaticType::Number);
108108
}
109109

110+
TEST(LLVMCodeAnalyzer_VariableTypeAnalysis, StringOptimization_DifferentString)
111+
{
112+
LLVMCodeAnalyzer analyzer;
113+
LLVMInstructionList list;
114+
Variable var("", "");
115+
116+
auto setVar1 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::WriteVariable, false);
117+
LLVMConstantRegister value1(Compiler::StaticType::String, "1.0");
118+
setVar1->targetVariable = &var;
119+
setVar1->args.push_back({ Compiler::StaticType::Unknown, &value1 });
120+
list.addInstruction(setVar1);
121+
122+
auto setVar2 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::WriteVariable, false);
123+
LLVMConstantRegister value2(Compiler::StaticType::Bool, true);
124+
setVar2->targetVariable = &var;
125+
setVar2->args.push_back({ Compiler::StaticType::Unknown, &value2 });
126+
list.addInstruction(setVar2);
127+
128+
analyzer.analyzeScript(list);
129+
130+
ASSERT_EQ(setVar1->targetType, Compiler::StaticType::Unknown);
131+
// String "1.0" does NOT get optimized to Number because it would convert to "1"
132+
ASSERT_EQ(setVar2->targetType, Compiler::StaticType::String);
133+
}
134+
110135
TEST(LLVMCodeAnalyzer_VariableTypeAnalysis, LoopSingleWrite)
111136
{
112137
LLVMCodeAnalyzer analyzer;

0 commit comments

Comments
 (0)