Skip to content

Commit bef9536

Browse files
authored
Merge pull request #654 from scratchcpp/llvm_optimizations
LLVM optimizations
2 parents 3bcf4d9 + 33a6930 commit bef9536

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+2048
-473
lines changed

.github/workflows/utests-minimal.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
submodules: true
2020

2121
- name: Configure CMake
22-
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DLIBSCRATCHCPP_BUILD_UNIT_TESTS=ON -DLIBSCRATCHCPP_ENABLE_SANITIZER=ON -DLIBSCRATCHCPP_AUDIO_SUPPORT=OFF -DLIBSCRATCHCPP_NETWORK_SUPPORT=OFF
22+
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DLIBSCRATCHCPP_BUILD_UNIT_TESTS=ON -DLIBSCRATCHCPP_ENABLE_SANITIZER=ON -DLIBSCRATCHCPP_AUDIO_SUPPORT=OFF -DLIBSCRATCHCPP_NETWORK_SUPPORT=OFF -DLIBSCRATCHCPP_ENABLE_CODE_ANALYZER=OFF -DLIBSCRATCHCPP_LLVM_INTEGER_SUPPORT=OFF
2323

2424
- name: Build
2525
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j$(nproc --all)

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ option(LIBSCRATCHCPP_BUILD_UNIT_TESTS "Build unit tests" ON)
1010
option(LIBSCRATCHCPP_NETWORK_SUPPORT "Support for downloading projects" ON)
1111
option(LIBSCRATCHCPP_PRINT_LLVM_IR "Print LLVM IR of compiled Scratch scripts (for debugging)" OFF)
1212
option(LIBSCRATCHCPP_ENABLE_CODE_ANALYZER "Analyze Scratch scripts to enable various optimizations" ON)
13+
option(LIBSCRATCHCPP_LLVM_INTEGER_SUPPORT "Use integers when possible to enable various optimizations" ON)
1314
option(LIBSCRATCHCPP_ENABLE_SANITIZER "Enable sanitizer to detect memory issues" OFF)
1415

1516
if (LIBSCRATCHCPP_ENABLE_SANITIZER)
@@ -126,6 +127,10 @@ if(LIBSCRATCHCPP_ENABLE_CODE_ANALYZER)
126127
target_compile_definitions(scratchcpp PRIVATE ENABLE_CODE_ANALYZER)
127128
endif()
128129

130+
if(LIBSCRATCHCPP_LLVM_INTEGER_SUPPORT)
131+
target_compile_definitions(scratchcpp PRIVATE LLVM_INTEGER_SUPPORT)
132+
endif()
133+
129134
# Macros
130135
target_compile_definitions(scratchcpp PRIVATE LIBSCRATCHCPP_LIBRARY)
131136
target_compile_definitions(scratchcpp PRIVATE LIBSCRATCHCPP_VERSION="${PROJECT_VERSION}")

include/scratchcpp/compiler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ class LIBSCRATCHCPP_EXPORT Compiler
148148

149149
void createYield();
150150
void createStop();
151+
void createStopWithoutSync();
151152

152153
void createProcedureCall(BlockPrototype *prototype, const Compiler::Args &args);
153154

include/scratchcpp/value_functions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ extern "C"
8585
LIBSCRATCHCPP_EXPORT StringPtr *value_doubleToStringPtr(double v);
8686
LIBSCRATCHCPP_EXPORT const StringPtr *value_boolToStringPtr(bool v);
8787
LIBSCRATCHCPP_EXPORT double value_stringToDouble(const StringPtr *s);
88+
LIBSCRATCHCPP_EXPORT double value_stringToDoubleWithCheck(const StringPtr *s, bool *ok);
8889
LIBSCRATCHCPP_EXPORT bool value_stringToBool(const StringPtr *s);
8990

9091
LIBSCRATCHCPP_EXPORT void value_add(const ValueData *v1, const ValueData *v2, ValueData *dst);

src/blocks/controlblocks.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,10 @@ CompilerValue *ControlBlocks::compileCreateCloneOf(Compiler *compiler)
178178

179179
CompilerValue *ControlBlocks::compileDeleteThisClone(Compiler *compiler)
180180
{
181-
compiler->addTargetFunctionCall("control_delete_this_clone");
181+
CompilerValue *deleted = compiler->addTargetFunctionCall("control_delete_this_clone", Compiler::StaticType::Bool);
182+
compiler->beginIfStatement(deleted);
183+
compiler->createStopWithoutSync(); // sync happens before the function call
184+
compiler->endIf();
182185
return nullptr;
183186
}
184187

@@ -234,10 +237,17 @@ extern "C" void control_create_clone(ExecutionContext *ctx, const StringPtr *spr
234237
}
235238
}
236239

237-
extern "C" void control_delete_this_clone(Target *target)
240+
extern "C" bool control_delete_this_clone(Target *target)
238241
{
239242
if (!target->isStage()) {
240-
target->engine()->stopTarget(target, nullptr);
241-
static_cast<Sprite *>(target)->deleteClone();
243+
Sprite *sprite = static_cast<Sprite *>(target);
244+
245+
if (sprite->isClone()) {
246+
target->engine()->stopTarget(target, nullptr);
247+
sprite->deleteClone();
248+
return true;
249+
}
242250
}
251+
252+
return false;
243253
}

src/engine/compiler.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ void Compiler::preoptimize()
136136

137137
/*!
138138
* Adds a call to the given function.\n
139-
* For example: extern "C" bool some_block(double arg1, const char *arg2)
139+
* For example: extern "C" bool some_block(double arg1, const StringPtr *arg2)
140140
*/
141141
CompilerValue *Compiler::addFunctionCall(const std::string &functionName, StaticType returnType, const ArgTypes &argTypes, const Args &args)
142142
{
@@ -146,7 +146,7 @@ CompilerValue *Compiler::addFunctionCall(const std::string &functionName, Static
146146

147147
/*!
148148
* Adds a call to the given function with a target parameter.\n
149-
* For example: extern "C" bool some_block(Target *target, double arg1, const char *arg2)
149+
* For example: extern "C" bool some_block(Target *target, double arg1, const StringPtr *arg2)
150150
*/
151151
CompilerValue *Compiler::addTargetFunctionCall(const std::string &functionName, StaticType returnType, const ArgTypes &argTypes, const Args &args)
152152
{
@@ -156,7 +156,7 @@ CompilerValue *Compiler::addTargetFunctionCall(const std::string &functionName,
156156

157157
/*!
158158
* Adds a call to the given function with an execution context parameter.\n
159-
* For example: extern "C" bool some_block(ExecutionContext *ctx, double arg1, const char *arg2)
159+
* For example: extern "C" bool some_block(ExecutionContext *ctx, double arg1, const StringPtr *arg2)
160160
*/
161161
CompilerValue *Compiler::addFunctionCallWithCtx(const std::string &functionName, StaticType returnType, const ArgTypes &argTypes, const Args &args)
162162
{
@@ -705,6 +705,16 @@ void Compiler::createStop()
705705
impl->builder->createStop();
706706
}
707707

708+
/*!
709+
* Creates a stop script without synchronization instruction.\n
710+
* Use this if synchronization is not possible at the stop point.
711+
* \note Only use this when everything is synchronized, e. g. after a function call.
712+
*/
713+
void Compiler::createStopWithoutSync()
714+
{
715+
impl->builder->createStopWithoutSync();
716+
}
717+
708718
/*! Creates a call to the procedure with the given prototype. */
709719
void Compiler::createProcedureCall(BlockPrototype *prototype, const libscratchcpp::Compiler::Args &args)
710720
{

src/engine/internal/icodebuilder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ class ICodeBuilder
9999
virtual void yield() = 0;
100100

101101
virtual void createStop() = 0;
102+
virtual void createStopWithoutSync() = 0;
102103

103104
virtual void createProcedureCall(BlockPrototype *prototype, const Compiler::Args &args) = 0;
104105
};

src/engine/internal/llvm/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ target_sources(scratchcpp
1515
llvmloop.h
1616
llvmcoroutine.cpp
1717
llvmcoroutine.h
18+
llvmlocalvariableinfo.h
1819
llvmvariableptr.h
1920
llvmlistptr.h
2021
llvmtypes.cpp

src/engine/internal/llvm/instructions/control.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ ProcessResult Control::process(LLVMInstruction *ins)
6060
ret.next = buildStop(ins);
6161
break;
6262

63+
case LLVMInstruction::Type::StopWithoutSync:
64+
ret.next = buildStopWithoutSync(ins);
65+
break;
66+
6367
default:
6468
ret.match = false;
6569
break;
@@ -88,6 +92,8 @@ LLVMInstruction *Control::buildSelect(LLVMInstruction *ins)
8892
}
8993

9094
ins->functionReturnReg->value = m_builder.CreateSelect(cond, trueValue, falseValue);
95+
ins->functionReturnReg->isInt = m_builder.CreateSelect(cond, arg2.second->isInt, arg3.second->isInt);
96+
ins->functionReturnReg->intValue = m_builder.CreateSelect(cond, arg2.second->intValue, arg3.second->intValue);
9197
return ins->next;
9298
}
9399

@@ -241,6 +247,8 @@ LLVMInstruction *Control::buildLoopIndex(LLVMInstruction *ins)
241247
LLVMLoop &loop = m_utils.loops().back();
242248
llvm::Value *index = m_builder.CreateLoad(m_builder.getInt64Ty(), loop.index);
243249
ins->functionReturnReg->value = m_builder.CreateUIToFP(index, m_builder.getDoubleTy());
250+
ins->functionReturnReg->intValue = index;
251+
ins->functionReturnReg->isInt = m_builder.getInt1(true);
244252

245253
return ins->next;
246254
}
@@ -336,6 +344,12 @@ LLVMInstruction *Control::buildEndLoop(LLVMInstruction *ins)
336344
}
337345

338346
LLVMInstruction *Control::buildStop(LLVMInstruction *ins)
347+
{
348+
m_utils.syncVariables();
349+
return buildStopWithoutSync(ins);
350+
}
351+
352+
LLVMInstruction *Control::buildStopWithoutSync(LLVMInstruction *ins)
339353
{
340354
m_utils.freeScopeHeap();
341355
m_builder.CreateBr(m_utils.endBranch());

src/engine/internal/llvm/instructions/control.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class Control : public InstructionGroup
2727
LLVMInstruction *buildBeginLoopCondition(LLVMInstruction *ins);
2828
LLVMInstruction *buildEndLoop(LLVMInstruction *ins);
2929
LLVMInstruction *buildStop(LLVMInstruction *ins);
30+
LLVMInstruction *buildStopWithoutSync(LLVMInstruction *ins);
3031
};
3132

3233
} // namespace libscratchcpp::llvmins

0 commit comments

Comments
 (0)