Skip to content

Commit 26b2f6d

Browse files
committed
LLVMTypeAnalyzer: Implement variableType() for basic cases
1 parent 2d6dc53 commit 26b2f6d

File tree

4 files changed

+1038
-0
lines changed

4 files changed

+1038
-0
lines changed

src/engine/internal/llvm/llvmtypeanalyzer.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,48 @@ using namespace libscratchcpp;
99
static const std::unordered_set<LLVMInstruction::Type>
1010
BEGIN_LOOP_INSTRUCTIONS = { LLVMInstruction::Type::BeginRepeatLoop, LLVMInstruction::Type::BeginWhileLoop, LLVMInstruction::Type::BeginRepeatUntilLoop };
1111

12+
Compiler::StaticType LLVMTypeAnalyzer::variableType(LLVMVariablePtr *varPtr, LLVMInstruction *pos, Compiler::StaticType previousType) const
13+
{
14+
if (!varPtr || !pos)
15+
return Compiler::StaticType::Unknown;
16+
17+
// Check the last write operation before the instruction
18+
LLVMInstruction *ins = pos;
19+
LLVMInstruction *write = nullptr;
20+
LLVMInstruction *loopStart = nullptr;
21+
int level = 0;
22+
23+
while (ins) {
24+
if (isLoopEnd(ins))
25+
level++;
26+
else if (isLoopStart(ins)) {
27+
level--;
28+
29+
if (!loopStart)
30+
loopStart = ins;
31+
} else if (ins->type == LLVMInstruction::Type::WriteVariable && ins->workVariable == varPtr->var) {
32+
if (level <= 0) { // ignore nested loops (they're handled later)
33+
write = ins;
34+
break;
35+
}
36+
}
37+
38+
ins = ins->previous;
39+
}
40+
41+
if (loopStart) {
42+
// Analyze the first loop that was found
43+
if (variableTypeChangesInLoop(varPtr, loopStart, previousType))
44+
return write ? writeValueType(write) : Compiler::StaticType::Unknown;
45+
} else if (write) {
46+
// There wasn't any loop found, so we can just check the last write operation
47+
return writeValueType(write);
48+
}
49+
50+
// No write operation found
51+
return previousType;
52+
}
53+
1254
bool LLVMTypeAnalyzer::variableTypeChangesInLoop(LLVMVariablePtr *varPtr, LLVMInstruction *loopBody, Compiler::StaticType preLoopType) const
1355
{
1456
if (!varPtr || !loopBody)

src/engine/internal/llvm/llvmtypeanalyzer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ struct LLVMRegister;
1212
class LLVMTypeAnalyzer
1313
{
1414
public:
15+
Compiler::StaticType variableType(LLVMVariablePtr *varPtr, LLVMInstruction *pos, Compiler::StaticType previousType) const;
1516
bool variableTypeChangesInLoop(LLVMVariablePtr *varPtr, LLVMInstruction *loopBody, Compiler::StaticType preLoopType) const;
1617

1718
private:

test/llvm/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ add_executable(
2121
llvmcodebuilder_test.cpp
2222
llvminstructionlist_test.cpp
2323
type_analyzer/variabletypechangesinloop_test.cpp
24+
type_analyzer/variabletype_test.cpp
2425
)
2526

2627
target_link_libraries(

0 commit comments

Comments
 (0)