@@ -63,21 +63,28 @@ ProcessResult Lists::process(LLVMInstruction *ins)
6363
6464LLVMInstruction *Lists::buildClearList (LLVMInstruction *ins)
6565{
66- assert (ins->args .size () == 0 );
67- LLVMListPtr &listPtr = m_utils.listPtr (ins->workList );
68- m_builder.CreateCall (m_utils.functions ().resolve_list_clear (), listPtr.ptr );
66+ if (ins->targetType != Compiler::StaticType::Void) { // do not clear a list that is already empty
67+ assert (ins->args .size () == 0 );
68+ LLVMListPtr &listPtr = m_utils.listPtr (ins->targetList );
69+ m_builder.CreateCall (m_utils.functions ().resolve_list_clear (), listPtr.ptr );
70+ }
6971
7072 return ins->next ;
7173}
7274
7375LLVMInstruction *Lists::buildRemoveListItem (LLVMInstruction *ins)
7476{
77+ // No-op in empty lists
78+ if (ins->targetType == Compiler::StaticType::Void)
79+ return ins->next ;
80+
7581 llvm::LLVMContext &llvmCtx = m_utils.llvmCtx ();
7682 llvm::Function *function = m_utils.function ();
7783
7884 assert (ins->args .size () == 1 );
7985 const auto &arg = ins->args [0 ];
80- LLVMListPtr &listPtr = m_utils.listPtr (ins->workList );
86+
87+ LLVMListPtr &listPtr = m_utils.listPtr (ins->targetList );
8188
8289 // Range check
8390 llvm::Value *min = llvm::ConstantFP::get (llvmCtx, llvm::APFloat (0.0 ));
@@ -107,12 +114,7 @@ LLVMInstruction *Lists::buildAppendToList(LLVMInstruction *ins)
107114 assert (ins->args .size () == 1 );
108115 const auto &arg = ins->args [0 ];
109116 Compiler::StaticType type = m_utils.optimizeRegisterType (arg.second );
110- LLVMListPtr &listPtr = m_utils.listPtr (ins->workList );
111-
112- Compiler::StaticType listType = Compiler::StaticType::Unknown;
113-
114- if (m_utils.warp ())
115- listType = m_utils.typeAnalyzer ().listType (ins->workList , ins, Compiler::StaticType::Unknown, false );
117+ LLVMListPtr &listPtr = m_utils.listPtr (ins->targetList );
116118
117119 // Check if enough space is allocated
118120 llvm::Value *allocatedSize = m_builder.CreateLoad (m_builder.getInt64Ty (), listPtr.allocatedSizePtr );
@@ -126,14 +128,15 @@ LLVMInstruction *Lists::buildAppendToList(LLVMInstruction *ins)
126128 // If there's enough space, use the allocated memory
127129 m_builder.SetInsertPoint (ifBlock);
128130 llvm::Value *itemPtr = m_utils.getListItem (listPtr, size);
129- m_utils.createReusedValueStore (arg.second , itemPtr, type, listType );
131+ m_utils.createValueStore (arg.second , itemPtr, type);
130132 m_builder.CreateStore (m_builder.CreateAdd (size, m_builder.getInt64 (1 )), listPtr.sizePtr );
131133 m_builder.CreateBr (nextBlock);
132134
133135 // Otherwise call appendEmpty()
134136 m_builder.SetInsertPoint (elseBlock);
135137 itemPtr = m_builder.CreateCall (m_utils.functions ().resolve_list_append_empty (), listPtr.ptr );
136- m_utils.createReusedValueStore (arg.second , itemPtr, type, listType);
138+ // NOTE: Items created using appendEmpty() are always numbers
139+ m_utils.createValueStore (arg.second , itemPtr, Compiler::StaticType::Number, type);
137140 m_builder.CreateBr (nextBlock);
138141
139142 m_builder.SetInsertPoint (nextBlock);
@@ -149,12 +152,7 @@ LLVMInstruction *Lists::buildInsertToList(LLVMInstruction *ins)
149152 const auto &indexArg = ins->args [0 ];
150153 const auto &valueArg = ins->args [1 ];
151154 Compiler::StaticType type = m_utils.optimizeRegisterType (valueArg.second );
152- LLVMListPtr &listPtr = m_utils.listPtr (ins->workList );
153-
154- Compiler::StaticType listType = Compiler::StaticType::Unknown;
155-
156- if (m_utils.warp ())
157- listType = m_utils.typeAnalyzer ().listType (ins->workList , ins, Compiler::StaticType::Unknown, false );
155+ LLVMListPtr &listPtr = m_utils.listPtr (ins->targetList );
158156
159157 // Range check
160158 llvm::Value *size = m_builder.CreateLoad (m_builder.getInt64Ty (), listPtr.sizePtr );
@@ -170,7 +168,7 @@ LLVMInstruction *Lists::buildInsertToList(LLVMInstruction *ins)
170168 m_builder.SetInsertPoint (insertBlock);
171169 index = m_builder.CreateFPToUI (index, m_builder.getInt64Ty ());
172170 llvm::Value *itemPtr = m_builder.CreateCall (m_utils.functions ().resolve_list_insert_empty (), { listPtr.ptr , index });
173- m_utils.createReusedValueStore (valueArg.second , itemPtr, type, listType );
171+ m_utils.createValueStore (valueArg.second , itemPtr, type);
174172
175173 m_builder.CreateBr (nextBlock);
176174
@@ -180,19 +178,20 @@ LLVMInstruction *Lists::buildInsertToList(LLVMInstruction *ins)
180178
181179LLVMInstruction *Lists::buildListReplace (LLVMInstruction *ins)
182180{
181+ // No-op in empty lists
182+ if (ins->targetType == Compiler::StaticType::Void)
183+ return ins->next ;
184+
183185 llvm::LLVMContext &llvmCtx = m_utils.llvmCtx ();
184186 llvm::Function *function = m_utils.function ();
185187
186188 assert (ins->args .size () == 2 );
187189 const auto &indexArg = ins->args [0 ];
188190 const auto &valueArg = ins->args [1 ];
189191 Compiler::StaticType type = m_utils.optimizeRegisterType (valueArg.second );
190- LLVMListPtr &listPtr = m_utils.listPtr (ins->workList );
191-
192- Compiler::StaticType listType = Compiler::StaticType::Unknown;
192+ LLVMListPtr &listPtr = m_utils.listPtr (ins->targetList );
193193
194- if (m_utils.warp ())
195- listType = m_utils.typeAnalyzer ().listType (ins->workList , ins, Compiler::StaticType::Unknown, false );
194+ Compiler::StaticType listType = ins->targetType ;
196195
197196 // Range check
198197 llvm::Value *min = llvm::ConstantFP::get (llvmCtx, llvm::APFloat (0.0 ));
@@ -208,7 +207,7 @@ LLVMInstruction *Lists::buildListReplace(LLVMInstruction *ins)
208207 m_builder.SetInsertPoint (replaceBlock);
209208 index = m_builder.CreateFPToUI (index, m_builder.getInt64Ty ());
210209 llvm::Value *itemPtr = m_utils.getListItem (listPtr, index);
211- m_utils.createValueStore (valueArg.second , itemPtr, type, listType );
210+ m_utils.createValueStore (valueArg.second , itemPtr, listType, type );
212211 m_builder.CreateBr (nextBlock);
213212
214213 m_builder.SetInsertPoint (nextBlock);
@@ -218,7 +217,7 @@ LLVMInstruction *Lists::buildListReplace(LLVMInstruction *ins)
218217LLVMInstruction *Lists::buildGetListContents (LLVMInstruction *ins)
219218{
220219 assert (ins->args .size () == 0 );
221- const LLVMListPtr &listPtr = m_utils.listPtr (ins->workList );
220+ const LLVMListPtr &listPtr = m_utils.listPtr (ins->targetList );
222221 llvm::Value *ptr = m_builder.CreateCall (m_utils.functions ().resolve_list_to_string (), listPtr.ptr );
223222 m_utils.freeStringLater (ptr);
224223 ins->functionReturnReg ->value = ptr;
@@ -228,35 +227,38 @@ LLVMInstruction *Lists::buildGetListContents(LLVMInstruction *ins)
228227
229228LLVMInstruction *Lists::buildGetListItem (LLVMInstruction *ins)
230229{
230+ // Return empty string for empty lists
231+ if (ins->targetType == Compiler::StaticType::Void) {
232+ LLVMConstantRegister nullReg (Compiler::StaticType::String, " " );
233+ ins->functionReturnReg ->value = m_utils.createValue (static_cast <LLVMRegister *>(&nullReg));
234+ return ins->next ;
235+ }
236+
231237 assert (ins->args .size () == 1 );
232238 const auto &arg = ins->args [0 ];
233- LLVMListPtr &listPtr = m_utils.listPtr (ins->workList );
239+ LLVMListPtr &listPtr = m_utils.listPtr (ins->targetList );
234240
235- Compiler::StaticType listType = Compiler::StaticType::Unknown;
236-
237- if (m_utils.warp ())
238- listType = m_utils.typeAnalyzer ().listType (ins->workList , ins, Compiler::StaticType::Unknown, false );
241+ Compiler::StaticType listType = ins->functionReturnReg ->type ();
239242
240243 llvm::Value *min = llvm::ConstantFP::get (m_utils.llvmCtx (), llvm::APFloat (0.0 ));
241244 llvm::Value *size = m_builder.CreateLoad (m_builder.getInt64Ty (), listPtr.sizePtr );
242245 size = m_builder.CreateUIToFP (size, m_builder.getDoubleTy ());
243246 llvm::Value *index = m_utils.castValue (arg.second , arg.first );
244247 llvm::Value *inRange = m_builder.CreateAnd (m_builder.CreateFCmpOGE (index, min), m_builder.CreateFCmpOLT (index, size));
245248
246- LLVMConstantRegister nullReg (listType == Compiler::StaticType::Unknown ? Compiler::StaticType::Number : listType, Value () );
249+ LLVMConstantRegister nullReg (Compiler::StaticType::String, " " );
247250 llvm::Value *null = m_utils.createValue (static_cast <LLVMRegister *>(&nullReg));
248251
249252 index = m_builder.CreateFPToUI (index, m_builder.getInt64Ty ());
250253 ins->functionReturnReg ->value = m_builder.CreateSelect (inRange, m_utils.getListItem (listPtr, index), null);
251- ins->functionReturnReg ->setType (listType);
252254
253255 return ins->next ;
254256}
255257
256258LLVMInstruction *Lists::buildGetListSize (LLVMInstruction *ins)
257259{
258260 assert (ins->args .size () == 0 );
259- const LLVMListPtr &listPtr = m_utils.listPtr (ins->workList );
261+ const LLVMListPtr &listPtr = m_utils.listPtr (ins->targetList );
260262 llvm::Value *size = m_builder.CreateLoad (m_builder.getInt64Ty (), listPtr.sizePtr );
261263 ins->functionReturnReg ->value = m_builder.CreateUIToFP (size, m_builder.getDoubleTy ());
262264
@@ -267,12 +269,9 @@ LLVMInstruction *Lists::buildGetListItemIndex(LLVMInstruction *ins)
267269{
268270 assert (ins->args .size () == 1 );
269271 const auto &arg = ins->args [0 ];
270- LLVMListPtr &listPtr = m_utils.listPtr (ins->workList );
271-
272- Compiler::StaticType listType = Compiler::StaticType::Unknown;
272+ LLVMListPtr &listPtr = m_utils.listPtr (ins->targetList );
273273
274- if (m_utils.warp ())
275- listType = m_utils.typeAnalyzer ().listType (ins->workList , ins, Compiler::StaticType::Unknown, false );
274+ Compiler::StaticType listType = ins->targetType ;
276275
277276 ins->functionReturnReg ->value = m_builder.CreateSIToFP (m_utils.getListItemIndex (listPtr, listType, arg.second ), m_builder.getDoubleTy ());
278277 return ins->next ;
@@ -282,12 +281,9 @@ LLVMInstruction *Lists::buildListContainsItem(LLVMInstruction *ins)
282281{
283282 assert (ins->args .size () == 1 );
284283 const auto &arg = ins->args [0 ];
285- LLVMListPtr &listPtr = m_utils.listPtr (ins->workList );
286-
287- Compiler::StaticType listType = Compiler::StaticType::Unknown;
284+ LLVMListPtr &listPtr = m_utils.listPtr (ins->targetList );
288285
289- if (m_utils.warp ())
290- listType = m_utils.typeAnalyzer ().listType (ins->workList , ins, Compiler::StaticType::Unknown, false );
286+ Compiler::StaticType listType = ins->targetType ;
291287
292288 llvm::Value *index = m_utils.getListItemIndex (listPtr, listType, arg.second );
293289 ins->functionReturnReg ->value = m_builder.CreateICmpSGT (index, llvm::ConstantInt::get (m_builder.getInt64Ty (), -1 , true ));
0 commit comments