Index: lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h =================================================================== --- lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h +++ lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h @@ -35,7 +35,7 @@ size_t SetRegisterInfo(const lldb_private::StructuredData::Dictionary &dict, const lldb_private::ArchSpec &arch); - void AddRegister(lldb_private::RegisterInfo ®_info, + void AddRegister(lldb_private::RegisterInfo reg_info, lldb_private::ConstString &set_name); void Finalize(const lldb_private::ArchSpec &arch); Index: lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp =================================================================== --- lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp +++ lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp @@ -395,20 +395,58 @@ return m_regs.size(); } -void DynamicRegisterInfo::AddRegister(RegisterInfo ®_info, +void DynamicRegisterInfo::AddRegister(RegisterInfo reg_info, ConstString &set_name) { assert(!m_finalized); const uint32_t reg_num = m_regs.size(); assert(reg_info.name); uint32_t i; if (reg_info.value_regs) { - for (i = 0; reg_info.value_regs[i] != LLDB_INVALID_REGNUM; ++i) - m_value_regs_map[reg_num].push_back(reg_info.value_regs[i]); + reg_num_collection &value_regs = m_value_regs_map[reg_num]; + + // copy value_regs into the collection + for (i = 0;; ++i) { + value_regs.push_back(reg_info.value_regs[i]); + if (reg_info.value_regs[i] == LLDB_INVALID_REGNUM) + break; + } + + // sort and unique them + if (value_regs.size() > 1) { + llvm::sort(value_regs.begin(), value_regs.end()); + reg_num_collection::iterator unique_end = + std::unique(value_regs.begin(), value_regs.end()); + if (unique_end != value_regs.end()) + value_regs.erase(unique_end, value_regs.end()); + } + assert(!value_regs.empty()); + + reg_info.value_regs = value_regs.data(); } + if (reg_info.invalidate_regs) { - for (i = 0; reg_info.invalidate_regs[i] != LLDB_INVALID_REGNUM; ++i) - m_invalidate_regs_map[reg_num].push_back(reg_info.invalidate_regs[i]); + reg_num_collection &invalidate_regs = m_invalidate_regs_map[reg_num]; + + // copy invalidate regs into the collection + for (i = 0;; ++i) { + invalidate_regs.push_back(reg_info.invalidate_regs[i]); + if (reg_info.invalidate_regs[i] == LLDB_INVALID_REGNUM) + break; + } + + // sort and unique them + if (invalidate_regs.size() > 1) { + llvm::sort(invalidate_regs.begin(), invalidate_regs.end()); + reg_num_collection::iterator unique_end = + std::unique(invalidate_regs.begin(), invalidate_regs.end()); + if (unique_end != invalidate_regs.end()) + invalidate_regs.erase(unique_end, invalidate_regs.end()); + } + assert(!invalidate_regs.empty()); + + reg_info.invalidate_regs = invalidate_regs.data(); } + if (reg_info.dynamic_size_dwarf_expr_bytes) { for (i = 0; i < reg_info.dynamic_size_dwarf_len; ++i) m_dynamic_reg_size_map[reg_num].push_back( @@ -438,33 +476,6 @@ m_sets[set].registers = m_set_reg_nums[set].data(); } - // sort and unique all value registers and make sure each is terminated with - // LLDB_INVALID_REGNUM - - for (reg_to_regs_map::iterator pos = m_value_regs_map.begin(), - end = m_value_regs_map.end(); - pos != end; ++pos) { - if (pos->second.size() > 1) { - llvm::sort(pos->second.begin(), pos->second.end()); - reg_num_collection::iterator unique_end = - std::unique(pos->second.begin(), pos->second.end()); - if (unique_end != pos->second.end()) - pos->second.erase(unique_end, pos->second.end()); - } - assert(!pos->second.empty()); - if (pos->second.back() != LLDB_INVALID_REGNUM) - pos->second.push_back(LLDB_INVALID_REGNUM); - } - - // Now update all value_regs with each register info as needed - const size_t num_regs = m_regs.size(); - for (size_t i = 0; i < num_regs; ++i) { - if (m_value_regs_map.find(i) != m_value_regs_map.end()) - m_regs[i].value_regs = m_value_regs_map[i].data(); - else - m_regs[i].value_regs = nullptr; - } - // Expand all invalidation dependencies for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(), end = m_invalidate_regs_map.end(); @@ -484,34 +495,18 @@ } } } - pos->second.insert(pos->second.end(), extra_invalid_regs.begin(), - extra_invalid_regs.end()); - } - } - // sort and unique all invalidate registers and make sure each is terminated - // with LLDB_INVALID_REGNUM - for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(), - end = m_invalidate_regs_map.end(); - pos != end; ++pos) { - if (pos->second.size() > 1) { - llvm::sort(pos->second.begin(), pos->second.end()); - reg_num_collection::iterator unique_end = - std::unique(pos->second.begin(), pos->second.end()); - if (unique_end != pos->second.end()) - pos->second.erase(unique_end, pos->second.end()); - } - assert(!pos->second.empty()); - if (pos->second.back() != LLDB_INVALID_REGNUM) - pos->second.push_back(LLDB_INVALID_REGNUM); - } + // Insert additional regnums sorted, if they are not in the list + // already. + for (uint32_t insert_reg_num : extra_invalid_regs) { + reg_num_collection::iterator it = llvm::lower_bound(pos->second, insert_reg_num); + if (it != pos->second.end() && *it != insert_reg_num) + pos->second.insert(it, insert_reg_num); + } - // Now update all invalidate_regs with each register info as needed - for (size_t i = 0; i < num_regs; ++i) { - if (m_invalidate_regs_map.find(i) != m_invalidate_regs_map.end()) - m_regs[i].invalidate_regs = m_invalidate_regs_map[i].data(); - else - m_regs[i].invalidate_regs = nullptr; + // Update the pointer in case it changed. + m_regs[reg_num].invalidate_regs = pos->second.data(); + } } // Check if we need to automatically set the generic registers in case they Index: lldb/unittests/Process/Utility/DynamicRegisterInfoTest.cpp =================================================================== --- lldb/unittests/Process/Utility/DynamicRegisterInfoTest.cpp +++ lldb/unittests/Process/Utility/DynamicRegisterInfoTest.cpp @@ -43,6 +43,44 @@ return regnum++; } +TEST(DynamicRegisterInfoTest, add_regs) { + DynamicRegisterInfo info; + + // Add regular registers + uint32_t b1 = AddRegister(info, "b1", 8); + uint32_t b2 = AddRegister(info, "b2", 8); + + // Add a few sub-registers + AddRegister(info, "s1", 4, {b1}); + AddRegister(info, "s2", 4, {b2}); + + // Add a register with invalidate_regs + uint32_t i1 = AddRegister(info, "i1", 8, {}, {b1}); + + // Add a register with indirect invalidate regs to be expanded + AddRegister(info, "i2", 4, {b2}, {i1}); + + const RegisterInfo *added_reg = info.GetRegisterInfoAtIndex(2); + ASSERT_NE(added_reg, nullptr); + EXPECT_EQ(added_reg->value_regs[0], b1); + EXPECT_EQ(added_reg->value_regs[1], LLDB_INVALID_REGNUM); + + added_reg = info.GetRegisterInfoAtIndex(3); + ASSERT_NE(added_reg, nullptr); + EXPECT_EQ(added_reg->value_regs[0], b2); + EXPECT_EQ(added_reg->value_regs[1], LLDB_INVALID_REGNUM); + + added_reg = info.GetRegisterInfoAtIndex(4); + ASSERT_NE(added_reg, nullptr); + EXPECT_EQ(added_reg->invalidate_regs[0], b1); + EXPECT_EQ(added_reg->invalidate_regs[1], LLDB_INVALID_REGNUM); + + added_reg = info.GetRegisterInfoAtIndex(5); + ASSERT_NE(added_reg, nullptr); + EXPECT_EQ(added_reg->invalidate_regs[0], i1); + EXPECT_EQ(added_reg->invalidate_regs[1], LLDB_INVALID_REGNUM); +} + TEST(DynamicRegisterInfoTest, finalize_regs) { DynamicRegisterInfo info;