@@ -92,9 +92,6 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
92
92
varPtr.onStack = false ; // use heap before the first assignment
93
93
}
94
94
95
- m_scopeVariables.clear ();
96
- m_scopeVariables.push_back ({});
97
-
98
95
// Create list pointers
99
96
for (auto &[list, listPtr] : m_listPtrs) {
100
97
listPtr.ptr = getListPtr (targetLists, list);
@@ -109,6 +106,10 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
109
106
m_builder.CreateStore (m_builder.getInt1 (false ), listPtr.dataPtrDirty );
110
107
}
111
108
109
+ m_scopeVariables.clear ();
110
+ m_scopeLists.clear ();
111
+ pushScopeLevel ();
112
+
112
113
// Execute recorded steps
113
114
for (const LLVMInstruction &step : m_instructions) {
114
115
switch (step.type ) {
@@ -498,6 +499,8 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
498
499
llvm::Value *dataPtrDirty = m_builder.CreateLoad (m_builder.getInt1Ty (), listPtr.dataPtrDirty );
499
500
llvm::Value *allocatedSize = m_builder.CreateLoad (m_builder.getInt64Ty (), listPtr.allocatedSizePtr );
500
501
m_builder.CreateStore (m_builder.CreateOr (dataPtrDirty, m_builder.CreateICmpNE (allocatedSize, oldAllocatedSize)), listPtr.dataPtrDirty );
502
+
503
+ m_scopeLists.back ().erase (&listPtr);
501
504
break ;
502
505
}
503
506
@@ -515,7 +518,7 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
515
518
assert (step.args .size () == 1 );
516
519
const auto &arg = step.args [0 ];
517
520
Compiler::StaticType type = optimizeRegisterType (arg.second );
518
- const LLVMListPtr &listPtr = m_listPtrs[step.workList ];
521
+ LLVMListPtr &listPtr = m_listPtrs[step.workList ];
519
522
520
523
// Check if enough space is allocated
521
524
llvm::Value *allocatedSize = m_builder.CreateLoad (m_builder.getInt64Ty (), listPtr.allocatedSizePtr );
@@ -541,7 +544,16 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
541
544
m_builder.CreateBr (nextBlock);
542
545
543
546
m_builder.SetInsertPoint (nextBlock);
544
- // TODO: Implement list type prediction
547
+ auto &typeMap = m_scopeLists.back ();
548
+
549
+ if (typeMap.find (&listPtr) == typeMap.cend ()) {
550
+ listPtr.type = type;
551
+ typeMap[&listPtr] = listPtr.type ;
552
+ } else if (listPtr.type != type) {
553
+ listPtr.type = Compiler::StaticType::Unknown;
554
+ typeMap[&listPtr] = listPtr.type ;
555
+ }
556
+
545
557
break ;
546
558
}
547
559
@@ -550,7 +562,7 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
550
562
const auto &indexArg = step.args [0 ];
551
563
const auto &valueArg = step.args [1 ];
552
564
Compiler::StaticType type = optimizeRegisterType (valueArg.second );
553
- const LLVMListPtr &listPtr = m_listPtrs[step.workList ];
565
+ LLVMListPtr &listPtr = m_listPtrs[step.workList ];
554
566
555
567
// dataPtrDirty
556
568
llvm::Value *dataPtrDirty = m_builder.CreateLoad (m_builder.getInt1Ty (), listPtr.dataPtrDirty );
@@ -561,8 +573,18 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
561
573
// Insert
562
574
llvm::Value *index = m_builder.CreateFPToUI (castValue (indexArg.second , indexArg.first ), m_builder.getInt64Ty ());
563
575
llvm::Value *itemPtr = m_builder.CreateCall (resolve_list_insert_empty (), { listPtr.ptr , index });
564
- // TODO: Implement list type prediction
565
576
createReusedValueStore (valueArg.second , itemPtr, type);
577
+
578
+ auto &typeMap = m_scopeLists.back ();
579
+
580
+ if (typeMap.find (&listPtr) == typeMap.cend ()) {
581
+ listPtr.type = type;
582
+ typeMap[&listPtr] = listPtr.type ;
583
+ } else if (listPtr.type != type) {
584
+ listPtr.type = Compiler::StaticType::Unknown;
585
+ typeMap[&listPtr] = listPtr.type ;
586
+ }
587
+
566
588
break ;
567
589
}
568
590
@@ -571,11 +593,21 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
571
593
const auto &indexArg = step.args [0 ];
572
594
const auto &valueArg = step.args [1 ];
573
595
Compiler::StaticType type = optimizeRegisterType (valueArg.second );
574
- const LLVMListPtr &listPtr = m_listPtrs[step.workList ];
596
+ LLVMListPtr &listPtr = m_listPtrs[step.workList ];
575
597
llvm::Value *index = m_builder.CreateFPToUI (castValue (indexArg.second , indexArg.first ), m_builder.getInt64Ty ());
576
598
llvm::Value *itemPtr = getListItem (listPtr, index , func);
577
599
createValueStore (valueArg.second , itemPtr, type, listPtr.type );
578
- // TODO: Implement list type prediction
600
+
601
+ auto &typeMap = m_scopeLists.back ();
602
+
603
+ if (typeMap.find (&listPtr) == typeMap.cend ()) {
604
+ listPtr.type = type;
605
+ typeMap[&listPtr] = listPtr.type ;
606
+ } else if (listPtr.type != type) {
607
+ listPtr.type = Compiler::StaticType::Unknown;
608
+ typeMap[&listPtr] = listPtr.type ;
609
+ }
610
+
579
611
break ;
580
612
}
581
613
@@ -618,9 +650,9 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
618
650
if (!m_warp) {
619
651
freeHeap ();
620
652
syncVariables (targetVariables);
621
- reloadLists ();
622
653
coro->createSuspend ();
623
654
reloadVariables (targetVariables);
655
+ reloadLists ();
624
656
}
625
657
626
658
break ;
@@ -1285,6 +1317,16 @@ void LLVMCodeBuilder::createListMap()
1285
1317
void LLVMCodeBuilder::pushScopeLevel ()
1286
1318
{
1287
1319
m_scopeVariables.push_back ({});
1320
+
1321
+ if (m_scopeLists.empty ()) {
1322
+ std::unordered_map<LLVMListPtr *, Compiler::StaticType> listTypes;
1323
+
1324
+ for (auto &[list, listPtr] : m_listPtrs)
1325
+ listTypes[&listPtr] = Compiler::StaticType::Unknown;
1326
+
1327
+ m_scopeLists.push_back (listTypes);
1328
+ } else
1329
+ m_scopeLists.push_back (m_scopeLists.back ());
1288
1330
}
1289
1331
1290
1332
void LLVMCodeBuilder::popScopeLevel ()
@@ -1297,6 +1339,15 @@ void LLVMCodeBuilder::popScopeLevel()
1297
1339
}
1298
1340
1299
1341
m_scopeVariables.pop_back ();
1342
+
1343
+ for (size_t i = 0 ; i < m_scopeLists.size () - 1 ; i++) {
1344
+ for (auto &[ptr, type] : m_scopeLists[i]) {
1345
+ if (ptr->type != type)
1346
+ ptr->type = Compiler::StaticType::Unknown;
1347
+ }
1348
+ }
1349
+
1350
+ m_scopeLists.pop_back ();
1300
1351
}
1301
1352
1302
1353
void LLVMCodeBuilder::verifyFunction (llvm::Function *func)
@@ -1605,9 +1656,14 @@ void LLVMCodeBuilder::reloadVariables(llvm::Value *targetVariables)
1605
1656
1606
1657
void LLVMCodeBuilder::reloadLists ()
1607
1658
{
1608
- // Reload list data pointers
1609
- for (auto &[list, listPtr] : m_listPtrs)
1610
- m_builder.CreateStore (m_builder.CreateCall (resolve_list_data (), listPtr.ptr ), listPtr.dataPtr );
1659
+ // Reset list data dirty and list types
1660
+ auto &typeMap = m_scopeLists.back ();
1661
+
1662
+ for (auto &[list, listPtr] : m_listPtrs) {
1663
+ m_builder.CreateStore (m_builder.getInt1 (true ), listPtr.dataPtrDirty );
1664
+ listPtr.type = Compiler::StaticType::Unknown;
1665
+ typeMap[&listPtr] = listPtr.type ;
1666
+ }
1611
1667
}
1612
1668
1613
1669
void LLVMCodeBuilder::updateListDataPtr (const LLVMListPtr &listPtr, llvm::Function *func)
@@ -1733,25 +1789,20 @@ void LLVMCodeBuilder::createValueStore(LLVMRegisterPtr reg, llvm::Value *targetP
1733
1789
}
1734
1790
}
1735
1791
1736
- void LLVMCodeBuilder::createInitialValueStore (LLVMRegisterPtr reg, llvm::Value *targetPtr, Compiler::StaticType sourceType)
1792
+ void LLVMCodeBuilder::createReusedValueStore (LLVMRegisterPtr reg, llvm::Value *targetPtr, Compiler::StaticType sourceType)
1737
1793
{
1738
1794
llvm::Value *converted = nullptr ;
1739
1795
1740
1796
if (sourceType != Compiler::StaticType::Unknown)
1741
1797
converted = castValue (reg, sourceType);
1742
1798
1743
- auto it = std::find_if (TYPE_MAP.begin (), TYPE_MAP.end (), [sourceType](const std::pair<ValueType, Compiler::StaticType> &pair) { return pair.second == sourceType; });
1744
- const ValueType mappedType = it == TYPE_MAP.cend () ? ValueType::Number : it->first ; // unknown type can be ignored
1745
-
1746
- llvm::Value *valuePtr = m_builder.CreateStructGEP (m_valueDataType, targetPtr, 0 );
1747
- llvm::Value *typePtr = m_builder.CreateStructGEP (m_valueDataType, targetPtr, 1 );
1748
- m_builder.CreateStore (m_builder.getInt32 (static_cast <uint32_t >(mappedType)), typePtr);
1749
-
1750
1799
switch (sourceType) {
1751
1800
case Compiler::StaticType::Number:
1801
+ m_builder.CreateCall (resolve_value_assign_double (), { targetPtr, converted });
1802
+ break ;
1803
+
1752
1804
case Compiler::StaticType::Bool:
1753
- // Write number/bool directly
1754
- m_builder.CreateStore (converted, valuePtr);
1805
+ m_builder.CreateCall (resolve_value_assign_bool (), { targetPtr, converted });
1755
1806
break ;
1756
1807
1757
1808
case Compiler::StaticType::String:
0 commit comments