Skip to content

Commit 29735a0

Browse files
committed
variableTypeChangesInLoop() -> variableTypeChangesInBranch()
1 parent 2c2bf75 commit 29735a0

File tree

4 files changed

+667
-131
lines changed

4 files changed

+667
-131
lines changed

src/engine/internal/llvm/llvmtypeanalyzer.cpp

Lines changed: 50 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Compiler::StaticType LLVMTypeAnalyzer::variableType(LLVMVariablePtr *varPtr, LLV
4040

4141
if (loopStart) {
4242
// Analyze the first loop that was found
43-
if (variableTypeChangesInLoop(varPtr, loopStart, previousType))
43+
if (variableTypeChangesInBranch(varPtr, loopStart, previousType))
4444
return write ? writeValueType(write) : Compiler::StaticType::Unknown;
4545
} else if (write) {
4646
// There wasn't any loop found, so we can just check the last write operation
@@ -51,65 +51,56 @@ Compiler::StaticType LLVMTypeAnalyzer::variableType(LLVMVariablePtr *varPtr, LLV
5151
return previousType;
5252
}
5353

54-
bool LLVMTypeAnalyzer::variableTypeChangesInLoop(LLVMVariablePtr *varPtr, LLVMInstruction *loopBody, Compiler::StaticType preLoopType) const
54+
bool LLVMTypeAnalyzer::variableTypeChangesInBranch(LLVMVariablePtr *varPtr, LLVMInstruction *loopBody, Compiler::StaticType preLoopType) const
5555
{
5656
if (!varPtr || !loopBody)
5757
return false;
5858

59-
// Find loop end
59+
assert(isLoopStart(loopBody) || isIfStart(loopBody) || isElse(loopBody));
60+
61+
// Find loop/if statement end or else branch
6062
LLVMInstruction *ins = loopBody->next;
61-
int loopLevel = 0;
62-
63-
while (ins && !(isLoopEnd(ins) && loopLevel == 0)) {
64-
if (isLoopStart(ins))
65-
loopLevel++;
66-
else if (isLoopEnd(ins)) {
67-
assert(loopLevel > 0);
68-
loopLevel--;
63+
int level = 0;
64+
65+
while (ins && !((isLoopEnd(ins) || isIfEnd(ins) || isElse(ins)) && level == 0)) {
66+
if (isLoopStart(ins) || isIfStart(ins))
67+
level++;
68+
else if (isLoopEnd(ins) || isIfEnd(ins)) {
69+
assert(level > 0);
70+
level--;
6971
}
7072

7173
ins = ins->next;
7274
}
7375

74-
// Loops must always have an end instruction
7576
if (!ins) {
7677
assert(false);
7778
return true;
7879
}
7980

80-
return variableTypeChangesInLoopFromEnd(varPtr, ins, preLoopType);
81+
// Process the branch from end
82+
return variableTypeChangesInBranchFromEnd(varPtr, ins, preLoopType);
8183
}
8284

83-
bool LLVMTypeAnalyzer::variableTypeChangesInLoopFromEnd(LLVMVariablePtr *varPtr, LLVMInstruction *loopEnd, Compiler::StaticType preLoopType) const
85+
bool LLVMTypeAnalyzer::variableTypeChangesInBranchFromEnd(LLVMVariablePtr *varPtr, LLVMInstruction *loopEnd, Compiler::StaticType preLoopType) const
8486
{
8587
// Find the last write instruction
8688
LLVMInstruction *ins = loopEnd->previous;
8789

88-
while (ins && !isLoopStart(ins)) {
90+
while (ins && !isLoopStart(ins) && !isIfStart(ins)) {
8991
if (isLoopEnd(ins) || isIfEnd(ins) || isElse(ins)) {
90-
// Nested loop or if statement
91-
if (variableTypeChangesInLoopFromEnd(varPtr, ins, preLoopType))
92+
// Process the nested loop or if statement
93+
if (variableTypeChangesInBranchFromEnd(varPtr, ins, preLoopType))
9294
return true;
9395

94-
// Skip the loop or if statement
95-
int level = 0;
96-
ins = ins->previous;
97-
98-
while (ins && !((isLoopStart(ins) || isIfStart(ins) || isElse(ins)) && level == 0)) {
99-
if (isLoopStart(ins) || isIfStart(ins)) {
100-
assert(level > 0);
101-
level--;
102-
}
96+
ins = skipBranch(ins);
10397

104-
if (isLoopEnd(ins) || isIfEnd(ins) || isElse(ins))
105-
level++;
98+
if (isElse(ins)) {
99+
// Process if branch (the else branch is already processed)
100+
if (variableTypeChangesInBranchFromEnd(varPtr, ins, preLoopType))
101+
return true;
106102

107-
ins = ins->previous;
108-
};
109-
110-
if (!ins) {
111-
assert(false);
112-
return true;
103+
ins = skipBranch(ins);
113104
}
114105
} else if (ins->type == LLVMInstruction::Type::WriteVariable && ins->workVariable == varPtr->var) {
115106
// Variable write instruction
@@ -122,6 +113,31 @@ bool LLVMTypeAnalyzer::variableTypeChangesInLoopFromEnd(LLVMVariablePtr *varPtr,
122113
return false;
123114
}
124115

116+
LLVMInstruction *LLVMTypeAnalyzer::skipBranch(LLVMInstruction *pos) const
117+
{
118+
int level = 0;
119+
pos = pos->previous;
120+
121+
while (pos && !((isLoopStart(pos) || isIfStart(pos)) && level == 0)) {
122+
if (isLoopStart(pos) || isIfStart(pos)) {
123+
assert(level > 0);
124+
level--;
125+
}
126+
127+
if (isLoopEnd(pos) || isIfEnd(pos) || isElse(pos)) {
128+
if (isElse(pos) && level == 0)
129+
break;
130+
131+
level++;
132+
}
133+
134+
pos = pos->previous;
135+
};
136+
137+
assert(pos);
138+
return pos;
139+
}
140+
125141
bool LLVMTypeAnalyzer::isLoopStart(LLVMInstruction *ins) const
126142
{
127143
return (BEGIN_LOOP_INSTRUCTIONS.find(ins->type) != BEGIN_LOOP_INSTRUCTIONS.cend());

src/engine/internal/llvm/llvmtypeanalyzer.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@ class LLVMTypeAnalyzer
1313
{
1414
public:
1515
Compiler::StaticType variableType(LLVMVariablePtr *varPtr, LLVMInstruction *pos, Compiler::StaticType previousType) const;
16-
bool variableTypeChangesInLoop(LLVMVariablePtr *varPtr, LLVMInstruction *loopBody, Compiler::StaticType preLoopType) const;
16+
bool variableTypeChangesInBranch(LLVMVariablePtr *varPtr, LLVMInstruction *loopBody, Compiler::StaticType preLoopType) const;
1717

1818
private:
19-
bool variableTypeChangesInLoopFromEnd(LLVMVariablePtr *varPtr, LLVMInstruction *loopEnd, Compiler::StaticType preLoopType) const;
19+
bool variableTypeChangesInBranchFromEnd(LLVMVariablePtr *varPtr, LLVMInstruction *loopEnd, Compiler::StaticType preLoopType) const;
20+
LLVMInstruction *skipBranch(LLVMInstruction *pos) const;
2021
bool isLoopStart(LLVMInstruction *ins) const;
2122
bool isLoopEnd(LLVMInstruction *ins) const;
2223
bool isIfStart(LLVMInstruction *ins) const;

test/llvm/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ add_executable(
2020
llvmexecutablecode_test.cpp
2121
llvmcodebuilder_test.cpp
2222
llvminstructionlist_test.cpp
23-
type_analyzer/variabletypechangesinloop_test.cpp
23+
type_analyzer/variabletypechangesinbranch_test.cpp
2424
type_analyzer/variabletype_test.cpp
2525
)
2626

0 commit comments

Comments
 (0)