@@ -27,61 +27,8 @@ Compiler::StaticType LLVMTypeAnalyzer::listTypeAfterBranch(List *list, LLVMInstr
2727 if (!list || !start)
2828 return previousType;
2929
30- assert (isLoopStart (start) || isIfStart (start) || isElse (start));
31-
32- InstructionSet visitedInstructions; // TODO: Handle cross-variable/list dependencies
33-
34- LLVMInstruction *ins = start->next ;
35- LLVMInstruction *lastWrite = nullptr ;
36- Compiler::StaticType lastWriteType = Compiler::StaticType::Unknown;
37- int level = 0 ;
38-
39- while (ins && !((isLoopEnd (ins) || isIfEnd (ins) || isElse (ins)) && level == 0 )) {
40- if (isLoopStart (ins) || isIfStart (ins))
41- level++;
42- else if (isLoopEnd (ins) || isIfEnd (ins)) {
43- assert (level > 0 );
44- level--;
45- } else if (isListWrite (ins, list)) {
46- // List write instruction
47- Compiler::StaticType writeType = writeValueType (ins, visitedInstructions);
48-
49- // For non-empty lists, we can just check the write type
50- if (!isEmpty && !typesMatch (writeType, previousType)) {
51- return Compiler::StaticType::Unknown;
52- }
53-
54- // In empty lists, writes of the same type determine the final type
55- if (isEmpty) {
56- if (lastWrite) {
57- // There was a write before which means it might determine the final type
58- if (!typesMatch (writeType, lastWriteType))
59- return Compiler::StaticType::Unknown;
60- } else {
61- // This is the first write found, it might determine the final type
62- lastWrite = ins;
63- lastWriteType = writeType;
64- }
65- }
66- }
67-
68- ins = ins->next ;
69- }
70-
71- assert (ins);
72-
73- if (isEmpty) {
74- if (lastWrite) {
75- // Only writes of the same type modify the list
76- return lastWriteType;
77- } else {
78- // No writes to empty list found, keep the previous type
79- return previousType;
80- }
81- } else {
82- // No type conflicts found for non-empty list
83- return previousType;
84- }
30+ bool write = false ; // only used internally (the compiler doesn't need this)
31+ return listTypeAfterBranch (list, start, previousType, isEmpty, write);
8532}
8633
8734Compiler::StaticType LLVMTypeAnalyzer::variableType (Variable *var, LLVMInstruction *pos, Compiler::StaticType previousType, InstructionSet &visitedInstructions) const
@@ -234,6 +181,61 @@ Compiler::StaticType LLVMTypeAnalyzer::variableTypeAfterBranchFromEnd(Variable *
234181 return previousType;
235182}
236183
184+ Compiler::StaticType LLVMTypeAnalyzer::listTypeAfterBranch (List *list, LLVMInstruction *start, Compiler::StaticType previousType, bool isEmpty, bool &write) const
185+ {
186+ assert (isLoopStart (start) || isIfStart (start) || isElse (start));
187+
188+ InstructionSet visitedInstructions; // TODO: Handle cross-variable/list dependencies
189+
190+ LLVMInstruction *ins = start->next ;
191+ write = false ;
192+
193+ while (ins && !(isLoopEnd (ins) || isIfEnd (ins) || isElse (ins))) {
194+ if (isLoopStart (ins) || isIfStart (ins)) {
195+ do {
196+ Compiler::StaticType type = listTypeAfterBranch (list, ins, previousType, isEmpty, write);
197+
198+ // If there was a write, the list is no longer empty
199+ if (write) {
200+ isEmpty = false ;
201+
202+ // The write could change the type
203+ if (!typesMatch (type, previousType))
204+ return Compiler::StaticType::Unknown;
205+ }
206+
207+ // Skip the branch
208+ ins = branchEnd (ins);
209+ } while (isElse (ins)); // handle else branch
210+ } else if (isListWrite (ins, list)) {
211+ // List write instruction
212+ Compiler::StaticType writeType = writeValueType (ins, visitedInstructions);
213+ write = true ;
214+
215+ if (isEmpty) {
216+ // In empty lists, writes of the same type determine the final type
217+ // This is the first write found, it might determine the final type
218+ previousType = writeType;
219+
220+ // The list is no longer empty
221+ isEmpty = false ;
222+ } else if (!typesMatch (writeType, previousType)) {
223+ // For non-empty lists, we can just check the write type
224+ return Compiler::StaticType::Unknown;
225+ }
226+ } else if (ins->type == LLVMInstruction::Type::ClearList && ins->workList == list) {
227+ // The list is now empty
228+ isEmpty = true ;
229+ write = false ; // the write variable is only used to check if the list is still empty
230+ }
231+
232+ ins = ins->next ;
233+ }
234+
235+ assert (ins);
236+ return previousType;
237+ }
238+
237239LLVMInstruction *LLVMTypeAnalyzer::branchEnd (LLVMInstruction *start) const
238240{
239241 assert (start);
0 commit comments