From 270232e8d6ac32fb41bdc95b17b95b6e35df4b22 Mon Sep 17 00:00:00 2001 From: crueter Date: Tue, 24 Feb 2026 19:34:34 +0100 Subject: [PATCH] [dynarmic] Revert "Transition IR::Block to use stable_vector, remove inline pool + pooled vector, remove unused mutable get/set block functors (#3543)" (#3625) This reverts commit d64f7dfe5c3f727939b36d92600fe04f11b0f4d0. Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3625 --- .../src/dynarmic/backend/arm64/emit_arm64.cpp | 4 +- .../dynarmic/backend/riscv64/emit_riscv64.cpp | 2 +- .../src/dynarmic/backend/x64/a32_emit_x64.cpp | 4 +- .../src/dynarmic/backend/x64/a64_emit_x64.cpp | 2 +- .../A32/translate/conditional_state.cpp | 4 +- .../frontend/A32/translate/translate_arm.cpp | 4 +- .../A32/translate/translate_thumb.cpp | 4 +- .../frontend/A64/translate/a64_translate.cpp | 4 +- .../frontend/A64/translate/impl/system.cpp | 2 +- src/dynarmic/src/dynarmic/ir/basic_block.cpp | 32 +++++++++---- src/dynarmic/src/dynarmic/ir/basic_block.h | 47 +++++++++++++++++-- src/dynarmic/src/dynarmic/ir/ir_emitter.h | 17 ++++--- .../src/dynarmic/ir/microinstruction.h | 6 ++- src/dynarmic/src/dynarmic/ir/opt_passes.cpp | 27 ++++++----- 14 files changed, 108 insertions(+), 51 deletions(-) diff --git a/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64.cpp b/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64.cpp index e4958eb67f..104d0a452c 100644 --- a/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64.cpp +++ b/src/dynarmic/src/dynarmic/backend/arm64/emit_arm64.cpp @@ -212,7 +212,7 @@ EmittedBlockInfo EmitArm64(oaknut::CodeGenerator& code, IR::Block block, const E oaknut::Label pass; pass = conf.emit_cond(code, ctx, ctx.block.GetCondition()); - EmitAddCycles(code, ctx, ctx.block.cond_failed_cycle_count); + EmitAddCycles(code, ctx, ctx.block.ConditionFailedCycleCount()); conf.emit_condition_failed_terminal(code, ctx); code.l(pass); @@ -254,7 +254,7 @@ EmittedBlockInfo EmitArm64(oaknut::CodeGenerator& code, IR::Block block, const E reg_alloc.AssertNoMoreUses(); - EmitAddCycles(code, ctx, block.cycle_count); + EmitAddCycles(code, ctx, block.CycleCount()); conf.emit_terminal(code, ctx); code.BRK(0); diff --git a/src/dynarmic/src/dynarmic/backend/riscv64/emit_riscv64.cpp b/src/dynarmic/src/dynarmic/backend/riscv64/emit_riscv64.cpp index 32a26de781..50cbaf9526 100644 --- a/src/dynarmic/src/dynarmic/backend/riscv64/emit_riscv64.cpp +++ b/src/dynarmic/src/dynarmic/backend/riscv64/emit_riscv64.cpp @@ -151,7 +151,7 @@ EmittedBlockInfo EmitRV64(biscuit::Assembler& as, IR::Block block, const EmitCon reg_alloc.AssertNoMoreUses(); if (emit_conf.enable_cycle_counting) { - const size_t cycles_to_add = block.cycle_count; + const size_t cycles_to_add = block.CycleCount(); as.LD(Xscratch0, offsetof(StackLayout, cycles_remaining), sp); if (mcl::bit::sign_extend<12>(-cycles_to_add) == -cycles_to_add) { as.ADDI(Xscratch0, Xscratch0, -cycles_to_add); diff --git a/src/dynarmic/src/dynarmic/backend/x64/a32_emit_x64.cpp b/src/dynarmic/src/dynarmic/backend/x64/a32_emit_x64.cpp index 59d0bc13c4..38cec7c750 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/a32_emit_x64.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/a32_emit_x64.cpp @@ -148,7 +148,7 @@ A32EmitX64::BlockDescriptor A32EmitX64::Emit(IR::Block& block) { reg_alloc.AssertNoMoreUses(); if (conf.enable_cycle_counting) { - EmitAddCycles(block.cycle_count); + EmitAddCycles(block.CycleCount()); } EmitTerminal(block.GetTerminal(), ctx.Location().SetSingleStepping(false), ctx.IsSingleStep()); code.int3(); @@ -192,7 +192,7 @@ void A32EmitX64::EmitCondPrelude(const A32EmitContext& ctx) { Xbyak::Label pass = EmitCond(ctx.block.GetCondition()); if (conf.enable_cycle_counting) { - EmitAddCycles(ctx.block.cond_failed_cycle_count); + EmitAddCycles(ctx.block.ConditionFailedCycleCount()); } EmitTerminal(IR::Term::LinkBlock{ctx.block.ConditionFailedLocation()}, ctx.Location().SetSingleStepping(false), ctx.IsSingleStep()); code.L(pass); diff --git a/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp b/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp index 825ff6f9cf..ff82d8b05c 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp @@ -142,7 +142,7 @@ finish_this_inst: reg_alloc.AssertNoMoreUses(); if (conf.enable_cycle_counting) { - EmitAddCycles(block.cycle_count); + EmitAddCycles(block.CycleCount()); } EmitTerminal(block.GetTerminal(), ctx.Location().SetSingleStepping(false), ctx.IsSingleStep()); code.int3(); diff --git a/src/dynarmic/src/dynarmic/frontend/A32/translate/conditional_state.cpp b/src/dynarmic/src/dynarmic/frontend/A32/translate/conditional_state.cpp index 6f6d2d7b68..8c55588a28 100644 --- a/src/dynarmic/src/dynarmic/frontend/A32/translate/conditional_state.cpp +++ b/src/dynarmic/src/dynarmic/frontend/A32/translate/conditional_state.cpp @@ -48,7 +48,7 @@ bool IsConditionPassed(TranslatorVisitor& v, IR::Cond cond) { } else { if (cond == v.ir.block.GetCondition()) { v.ir.block.SetConditionFailedLocation(v.ir.current_location.AdvancePC(static_cast(v.current_instruction_size)).AdvanceIT()); - v.ir.block.cond_failed_cycle_count++; + v.ir.block.ConditionFailedCycleCount()++; return true; } @@ -79,7 +79,7 @@ bool IsConditionPassed(TranslatorVisitor& v, IR::Cond cond) { v.cond_state = ConditionalState::Translating; v.ir.block.SetCondition(cond); v.ir.block.SetConditionFailedLocation(v.ir.current_location.AdvancePC(static_cast(v.current_instruction_size)).AdvanceIT()); - v.ir.block.cond_failed_cycle_count = v.ir.block.cycle_count + 1; + v.ir.block.ConditionFailedCycleCount() = v.ir.block.CycleCount() + 1; return true; } diff --git a/src/dynarmic/src/dynarmic/frontend/A32/translate/translate_arm.cpp b/src/dynarmic/src/dynarmic/frontend/A32/translate/translate_arm.cpp index 320046ffc1..5cc9ef3893 100644 --- a/src/dynarmic/src/dynarmic/frontend/A32/translate/translate_arm.cpp +++ b/src/dynarmic/src/dynarmic/frontend/A32/translate/translate_arm.cpp @@ -61,7 +61,7 @@ void TranslateArm(IR::Block& block, LocationDescriptor descriptor, TranslateCall } visitor.ir.current_location = visitor.ir.current_location.AdvancePC(4); - block.cycle_count += ticks_for_instruction; + block.CycleCount() += ticks_for_instruction; } while (should_continue && CondCanContinue(visitor.cond_state, visitor.ir) && !single_step); if (visitor.cond_state == ConditionalState::Translating || visitor.cond_state == ConditionalState::Trailing || single_step) { @@ -101,7 +101,7 @@ bool TranslateSingleArmInstruction(IR::Block& block, LocationDescriptor descript // TODO: Feedback resulting cond status to caller somehow. visitor.ir.current_location = visitor.ir.current_location.AdvancePC(4); - block.cycle_count += ticks_for_instruction; + block.CycleCount() += ticks_for_instruction; block.SetEndLocation(visitor.ir.current_location); diff --git a/src/dynarmic/src/dynarmic/frontend/A32/translate/translate_thumb.cpp b/src/dynarmic/src/dynarmic/frontend/A32/translate/translate_thumb.cpp index a043c3f543..e0333e487d 100644 --- a/src/dynarmic/src/dynarmic/frontend/A32/translate/translate_thumb.cpp +++ b/src/dynarmic/src/dynarmic/frontend/A32/translate/translate_thumb.cpp @@ -161,7 +161,7 @@ void TranslateThumb(IR::Block& block, LocationDescriptor descriptor, TranslateCa } visitor.ir.current_location = visitor.ir.current_location.AdvancePC(static_cast(visitor.current_instruction_size)).AdvanceIT(); - block.cycle_count += ticks_for_instruction; + block.CycleCount() += ticks_for_instruction; } while (should_continue && CondCanContinue(visitor.cond_state, visitor.ir) && !single_step); if (visitor.cond_state == ConditionalState::Translating || visitor.cond_state == ConditionalState::Trailing || single_step) { @@ -214,7 +214,7 @@ bool TranslateSingleThumbInstruction(IR::Block& block, LocationDescriptor descri const s32 advance_pc = is_thumb_16 ? 2 : 4; visitor.ir.current_location = visitor.ir.current_location.AdvancePC(advance_pc); - block.cycle_count += ticks_for_instruction; + block.CycleCount() += ticks_for_instruction; block.SetEndLocation(visitor.ir.current_location); diff --git a/src/dynarmic/src/dynarmic/frontend/A64/translate/a64_translate.cpp b/src/dynarmic/src/dynarmic/frontend/A64/translate/a64_translate.cpp index fc6841e082..6778d13890 100644 --- a/src/dynarmic/src/dynarmic/frontend/A64/translate/a64_translate.cpp +++ b/src/dynarmic/src/dynarmic/frontend/A64/translate/a64_translate.cpp @@ -30,7 +30,7 @@ void Translate(IR::Block& block, LocationDescriptor descriptor, MemoryReadCodeFu should_continue = visitor.RaiseException(Exception::NoExecuteFault); } visitor.ir.current_location = visitor.ir.current_location->AdvancePC(4); - block.cycle_count++; + block.CycleCount()++; } while (should_continue && !single_step); if (single_step && should_continue) { @@ -48,7 +48,7 @@ bool TranslateSingleInstruction(IR::Block& block, LocationDescriptor descriptor, should_continue = decoder.get().call(visitor, instruction); visitor.ir.current_location = visitor.ir.current_location->AdvancePC(4); - block.cycle_count++; + block.CycleCount()++; block.SetEndLocation(*visitor.ir.current_location); diff --git a/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/system.cpp b/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/system.cpp index 61d5c065f4..c60fdc3ae0 100644 --- a/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/system.cpp +++ b/src/dynarmic/src/dynarmic/frontend/A64/translate/impl/system.cpp @@ -130,7 +130,7 @@ bool TranslatorVisitor::MRS(Imm<1> o0, Imm<3> op1, Imm<4> CRn, Imm<4> CRm, Imm<3 case SystemRegisterEncoding::CNTPCT_EL0: // HACK: Ensure that this is the first instruction in the block it's emitted in, so the cycle count is most up-to-date. if (!ir.block.instructions.empty() && !options.wall_clock_cntpct) { - ir.block.cycle_count--; + ir.block.CycleCount()--; ir.SetTerm(IR::Term::LinkBlock{*ir.current_location}); return false; } diff --git a/src/dynarmic/src/dynarmic/ir/basic_block.cpp b/src/dynarmic/src/dynarmic/ir/basic_block.cpp index 8417661c42..ac0f03d76a 100644 --- a/src/dynarmic/src/dynarmic/ir/basic_block.cpp +++ b/src/dynarmic/src/dynarmic/ir/basic_block.cpp @@ -30,26 +30,38 @@ Block::Block(LocationDescriptor location) noexcept /// Prepends a new instruction to this basic block before the insertion point, /// handling any allocations necessary to do so. /// @param insertion_point Where to insert the new instruction. -/// @param op Opcode representing the instruction to add. -/// @param args A sequence of Value instances used as arguments for the instruction. +/// @param op Opcode representing the instruction to add. +/// @param args A sequence of Value instances used as arguments for the instruction. /// @returns Iterator to the newly created instruction. -Block::iterator Block::PrependNewInst(Block::const_iterator insertion_point, Opcode opcode, std::initializer_list args) noexcept { +Block::iterator Block::PrependNewInst(iterator insertion_point, Opcode opcode, std::initializer_list args) noexcept { // First try using the "inline" buffer, otherwise fallback to a slower slab-like allocation scheme // purpouse is to avoid many calls to new/delete which invoke malloc which invokes mmap // just pool it!!! - reason why there is an inline buffer is because many small blocks are created // with few instructions due to subpar optimisations on other passes... plus branch-heavy code will // hugely benefit from the coherency of faster allocations... - auto it = instructions.insert(insertion_point, Inst(opcode)); - DEBUG_ASSERT(args.size() == it->NumArgs()); - std::for_each(args.begin(), args.end(), [&it, index = size_t(0)](const auto& arg) mutable { - it->SetArg(index, arg); + IR::Inst* inst; + if (inlined_inst.size() < inlined_inst.max_size()) { + inlined_inst.emplace_back(opcode); + inst = &inlined_inst[inlined_inst.size() - 1]; + } else { + if (pooled_inst.empty() || pooled_inst.back().size() == pooled_inst.back().max_size()) + pooled_inst.emplace_back(); + pooled_inst.back().emplace_back(opcode); + inst = &pooled_inst.back()[pooled_inst.back().size() - 1]; + } + DEBUG_ASSERT(args.size() == inst->NumArgs()); + std::for_each(args.begin(), args.end(), [&inst, index = size_t(0)](const auto& arg) mutable { + inst->SetArg(index, arg); index++; }); - return it; + return instructions.insert_before(insertion_point, inst); } void Block::Reset(LocationDescriptor location_) noexcept { - instructions.clear(); + mcl::intrusive_list tmp = {}; + instructions.swap(tmp); + inlined_inst.clear(); + pooled_inst.clear(); cond_failed.reset(); location = location_; end_location = location_; @@ -95,7 +107,7 @@ static std::string TerminalToString(const Terminal& terminal_variant) noexcept { std::string DumpBlock(const IR::Block& block) noexcept { std::string ret = fmt::format("Block: location={}-{}\n", block.Location(), block.EndLocation()) - + fmt::format("cycles={}", block.cycle_count) + + fmt::format("cycles={}", block.CycleCount()) + fmt::format(", entry_cond={}", A64::CondToString(block.GetCondition())); if (block.GetCondition() != Cond::AL) ret += fmt::format(", cond_fail={}", block.ConditionFailedLocation()); diff --git a/src/dynarmic/src/dynarmic/ir/basic_block.h b/src/dynarmic/src/dynarmic/ir/basic_block.h index db9ac7bd12..4044005bd0 100644 --- a/src/dynarmic/src/dynarmic/ir/basic_block.h +++ b/src/dynarmic/src/dynarmic/ir/basic_block.h @@ -16,6 +16,7 @@ #include #include #include +#include #include "dynarmic/common/common_types.h" #include "dynarmic/ir/location_descriptor.h" @@ -32,10 +33,10 @@ enum class Opcode; /// Note that this is a linear IR and not a pure tree-based IR: i.e.: there is an ordering to /// the microinstructions. This only matters before chaining is done in order to correctly /// order memory accesses. -class Block final { +class alignas(4096) Block final { public: //using instruction_list_type = dense_list; - using instruction_list_type = boost::container::stable_vector; + using instruction_list_type = mcl::intrusive_list; using size_type = instruction_list_type::size_type; using iterator = instruction_list_type::iterator; using const_iterator = instruction_list_type::const_iterator; @@ -49,9 +50,25 @@ public: Block(Block&&) = default; Block& operator=(Block&&) = default; - iterator PrependNewInst(const_iterator insertion_point, Opcode op, std::initializer_list args) noexcept; + /// Appends a new instruction to the end of this basic block, + /// handling any allocations necessary to do so. + /// @param op Opcode representing the instruction to add. + /// @param args A sequence of Value instances used as arguments for the instruction. + inline iterator AppendNewInst(const Opcode opcode, const std::initializer_list args) noexcept { + return PrependNewInst(instructions.end(), opcode, args); + } + iterator PrependNewInst(iterator insertion_point, Opcode op, std::initializer_list args) noexcept; void Reset(LocationDescriptor location_) noexcept; + /// Gets a mutable reference to the instruction list for this basic block. + inline instruction_list_type& Instructions() noexcept { + return instructions; + } + /// Gets an immutable reference to the instruction list for this basic block. + inline const instruction_list_type& Instructions() const noexcept { + return instructions; + } + /// Gets the starting location for this basic block. inline LocationDescriptor Location() const noexcept { return location; @@ -87,6 +104,15 @@ public: return cond_failed.has_value(); } + /// Gets a mutable reference to the condition failed cycle count. + inline size_t& ConditionFailedCycleCount() noexcept { + return cond_failed_cycle_count; + } + /// Gets an immutable reference to the condition failed cycle count. + inline const size_t& ConditionFailedCycleCount() const noexcept { + return cond_failed_cycle_count; + } + /// Gets the terminal instruction for this basic block. inline Terminal GetTerminal() const noexcept { return terminal; @@ -106,8 +132,21 @@ public: return terminal.which() != 0; } + /// Gets a mutable reference to the cycle count for this basic block. + inline size_t& CycleCount() noexcept { + return cycle_count; + } + /// Gets an immutable reference to the cycle count for this basic block. + inline const size_t& CycleCount() const noexcept { + return cycle_count; + } + + /// "Hot cache" for small blocks so we don't call global allocator + boost::container::static_vector inlined_inst; /// List of instructions in this block. instruction_list_type instructions; + /// "Long/far" memory pool + boost::container::stable_vector> pooled_inst; /// Block to execute next if `cond` did not pass. std::optional cond_failed = {}; /// Description of the starting location of this block @@ -123,7 +162,7 @@ public: /// Number of cycles this block takes to execute. size_t cycle_count = 0; }; -//static_assert(sizeof(Block) == 120); +static_assert(sizeof(Block) == 4096); /// Returns a string representation of the contents of block. Intended for debugging. std::string DumpBlock(const IR::Block& block) noexcept; diff --git a/src/dynarmic/src/dynarmic/ir/ir_emitter.h b/src/dynarmic/src/dynarmic/ir/ir_emitter.h index becbbf92c7..2b5c7d5cdd 100644 --- a/src/dynarmic/src/dynarmic/ir/ir_emitter.h +++ b/src/dynarmic/src/dynarmic/ir/ir_emitter.h @@ -70,10 +70,7 @@ enum class MemOp { /// The user of this class updates `current_location` as appropriate. class IREmitter { public: - explicit IREmitter(Block& block) noexcept - : block(block) - , insertion_point(block.instructions.end()) - {} + explicit IREmitter(Block& block) : block(block), insertion_point(block.instructions.end()) {} Block& block; @@ -2950,10 +2947,19 @@ public: block.SetTerminal(terminal); } + void SetInsertionPointBefore(IR::Inst* new_insertion_point) { + insertion_point = IR::Block::iterator{*new_insertion_point}; + } + void SetInsertionPointBefore(IR::Block::iterator new_insertion_point) { insertion_point = new_insertion_point; } + void SetInsertionPointAfter(IR::Inst* new_insertion_point) { + insertion_point = IR::Block::iterator{*new_insertion_point}; + ++insertion_point; + } + void SetInsertionPointAfter(IR::Block::iterator new_insertion_point) { insertion_point = new_insertion_point; ++insertion_point; @@ -2964,10 +2970,7 @@ protected: template T Inst(Opcode op, Args... args) { - auto const offset = std::distance(block.instructions.begin(), insertion_point); - auto const at_end = block.instructions.end() == insertion_point; auto iter = block.PrependNewInst(insertion_point, op, {Value(args)...}); - insertion_point = at_end ? block.instructions.end() : block.instructions.begin() + (offset + 1); return T(Value(&*iter)); } }; diff --git a/src/dynarmic/src/dynarmic/ir/microinstruction.h b/src/dynarmic/src/dynarmic/ir/microinstruction.h index d1fea62e04..843b4cdf18 100644 --- a/src/dynarmic/src/dynarmic/ir/microinstruction.h +++ b/src/dynarmic/src/dynarmic/ir/microinstruction.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later /* This file is part of the dynarmic project. @@ -10,7 +10,9 @@ #include +#include #include "dynarmic/common/common_types.h" + #include "dynarmic/ir/value.h" #include "dynarmic/ir/opcodes.h" @@ -24,7 +26,7 @@ constexpr size_t max_arg_count = 4; /// A representation of a microinstruction. A single ARM/Thumb instruction may be /// converted into zero or more microinstructions. //class Inst final { -class Inst final { +class Inst final : public mcl::intrusive_list_node { public: explicit Inst(Opcode op) : op(op) {} diff --git a/src/dynarmic/src/dynarmic/ir/opt_passes.cpp b/src/dynarmic/src/dynarmic/ir/opt_passes.cpp index 1a6670fcca..f22e8aaa69 100644 --- a/src/dynarmic/src/dynarmic/ir/opt_passes.cpp +++ b/src/dynarmic/src/dynarmic/ir/opt_passes.cpp @@ -86,10 +86,12 @@ static void ConstantMemoryReads(IR::Block& block, A32::UserCallbacks* cb) { } static void FlagsPass(IR::Block& block) { + using Iterator = typename std::reverse_iterator; + struct FlagInfo { bool set_not_required = false; bool has_value_request = false; - IR::Block::reverse_iterator value_request = {}; + Iterator value_request = {}; }; struct ValuelessFlagInfo { bool set_not_required = false; @@ -100,7 +102,7 @@ static void FlagsPass(IR::Block& block) { FlagInfo c_flag; FlagInfo ge; - auto do_set = [&](FlagInfo& info, IR::Value value, IR::Block::reverse_iterator inst) { + auto do_set = [&](FlagInfo& info, IR::Value value, Iterator inst) { if (info.has_value_request) { info.value_request->ReplaceUsesWith(value); } @@ -112,14 +114,14 @@ static void FlagsPass(IR::Block& block) { info.set_not_required = true; }; - auto do_set_valueless = [](ValuelessFlagInfo& info, IR::Block::reverse_iterator inst) { + auto do_set_valueless = [&](ValuelessFlagInfo& info, Iterator inst) { if (info.set_not_required) { inst->Invalidate(); } info.set_not_required = true; }; - auto do_get = [](FlagInfo& info, IR::Block::reverse_iterator inst) { + auto do_get = [](FlagInfo& info, Iterator inst) { if (info.has_value_request) { info.value_request->ReplaceUsesWith(IR::Value{&*inst}); } @@ -446,8 +448,7 @@ static void A64CallbackConfigPass(IR::Block& block, const A64::UserConfig& conf) return; } - for (auto it = block.instructions.begin(); it != block.instructions.end(); it++) { - auto& inst = *it; + for (auto& inst : block.instructions) { if (inst.GetOpcode() != IR::Opcode::A64DataCacheOperationRaised) { continue; } @@ -456,7 +457,7 @@ static void A64CallbackConfigPass(IR::Block& block, const A64::UserConfig& conf) if (op == A64::DataCacheOperation::ZeroByVA) { A64::IREmitter ir{block}; ir.current_location = A64::LocationDescriptor{IR::LocationDescriptor{inst.GetArg(0).GetU64()}}; - ir.SetInsertionPointBefore(it); + ir.SetInsertionPointBefore(&inst); size_t bytes = 4 << static_cast(conf.dczid_el0 & 0b1111); IR::U64 addr{inst.GetArg(2)}; @@ -521,7 +522,7 @@ static void A64GetSetElimination(IR::Block& block) { const auto do_set = [&block](RegisterInfo& info, IR::Value value, Iterator set_inst, TrackingType tracking_type) { if (info.set_instruction_present) { info.last_set_instruction->Invalidate(); - block.instructions.erase(info.last_set_instruction); + block.Instructions().erase(info.last_set_instruction); } info.register_value = value; info.tracking_type = tracking_type; @@ -540,7 +541,7 @@ static void A64GetSetElimination(IR::Block& block) { ReplaceUsesWith(*get_inst, true, u32(info.register_value.GetImmediateAsU64())); } else { A64::IREmitter ir{block}; - ir.SetInsertionPointBefore(get_inst); + ir.SetInsertionPointBefore(&*get_inst); get_inst->ReplaceUsesWith(ir.LeastSignificantWord(IR::U64{info.register_value})); } } else { @@ -1209,7 +1210,7 @@ static void IdentityRemovalPass(IR::Block& block) { } if (it->GetOpcode() == IR::Opcode::Identity || it->GetOpcode() == IR::Opcode::Void) { to_invalidate.push_back(&*it); - it = block.instructions.erase(it); + it = block.Instructions().erase(it); } else { ++it; } @@ -1369,9 +1370,9 @@ static void PolyfillPass(IR::Block& block, const PolyfillOptions& polyfill) { IR::IREmitter ir{block}; - for (auto it = block.instructions.begin(); it != block.instructions.end(); it++) { - auto& inst = *it; - ir.SetInsertionPointBefore(it); + for (auto& inst : block.instructions) { + ir.SetInsertionPointBefore(&inst); + switch (inst.GetOpcode()) { case IR::Opcode::SHA256MessageSchedule0: if (polyfill.sha256) {