From cbd7315745d098ea16c361883f586c76ba5bfc54 Mon Sep 17 00:00:00 2001 From: "Sergey V. Ignatov" Date: Wed, 29 Mar 2023 11:53:33 +0300 Subject: [PATCH] [Compiler] Renumbered stack slots Signed-off-by: Sergey V. Ignatov --- .../optimizer/analysis/reg_alloc_verifier.cpp | 58 ++++++++++++++----- .../optimizer/analysis/reg_alloc_verifier.h | 42 ++++++-------- 2 files changed, 62 insertions(+), 38 deletions(-) diff --git a/compiler/optimizer/analysis/reg_alloc_verifier.cpp b/compiler/optimizer/analysis/reg_alloc_verifier.cpp index ad3b01e5f..8b92ff38d 100644 --- a/compiler/optimizer/analysis/reg_alloc_verifier.cpp +++ b/compiler/optimizer/analysis/reg_alloc_verifier.cpp @@ -85,11 +85,23 @@ bool MergeImpl(const ArenaVector &from, ArenaVector &from, ArenaDeque *to) +{ + bool updated = false; + for (size_t offset = 0; offset < from.size(); ++offset) { + if (to->at(offset).ShouldSkip()) { + to->at(offset).SetSkip(false); + continue; + } + updated |= to->at(offset).Merge(from[offset]); + } + return updated; +} + class BlockStates { public: - BlockStates(size_t regs, size_t vregs, size_t stack_slots, size_t stack_params, ArenaAllocator *allocator) - : start_state_(regs, vregs, stack_slots, stack_params, allocator), - end_state_(regs, vregs, stack_slots, stack_params, allocator) + BlockStates(size_t regs, size_t vregs, size_t stack_slots, ArenaAllocator *allocator) + : start_state_(regs, vregs, stack_slots, allocator), end_state_(regs, vregs, stack_slots, allocator) { } ~BlockStates() = default; @@ -147,8 +159,8 @@ void InitStates(ArenaUnorderedMap *blocks, const Graph *g if (bb == nullptr) { continue; } - [[maybe_unused]] auto res = blocks->try_emplace(bb->GetId(), used_regs, used_vregs, MAX_NUM_STACK_SLOTS, - MAX_NUM_STACK_SLOTS, graph->GetLocalAllocator()); + [[maybe_unused]] auto res = + blocks->try_emplace(bb->GetId(), used_regs, used_vregs, MAX_NUM_STACK_SLOTS, graph->GetLocalAllocator()); ASSERT(res.second); } } @@ -201,17 +213,31 @@ bool LocationState::Merge(const LocationState &other) return false; } -BlockState::BlockState(size_t regs, size_t vregs, size_t stack_slots, size_t stack_params, ArenaAllocator *alloc) +BlockState::BlockState(size_t regs, size_t vregs, size_t stack_slots, ArenaAllocator *alloc) : regs_(regs, alloc->Adapter()), vregs_(vregs, alloc->Adapter()), stack_(stack_slots, alloc->Adapter()), - stack_param_(stack_params, alloc->Adapter()), - stack_arg_(0, alloc->Adapter()) + spill_size_(stack_slots) +{ +} +void BlockState::AdjustArgs(BlockState *state) { + if (state->spill_off_ > spill_off_) { + while (state->spill_off_ > spill_off_) { + stack_.push_front(LocationState()); + ++spill_off_; + } + } else { + while (state->spill_off_ < spill_off_) { + state->stack_.push_front(LocationState()); + ++state->spill_off_; + } + } + ASSERT(state->spill_off_ == spill_off_); } -bool BlockState::Merge(const BlockState &state, const PhiInstSafeIter &phis, BasicBlock *pred, +bool BlockState::Merge(BlockState &state, const PhiInstSafeIter &phis, BasicBlock *pred, const ArenaVector &immediates, const LivenessAnalyzer &la) { bool updated = false; @@ -243,9 +269,12 @@ bool BlockState::Merge(const BlockState &state, const PhiInstSafeIter &phis, Bas } updated |= MergeImpl(state.regs_, ®s_); updated |= MergeImpl(state.vregs_, &vregs_); + ASSERT(state.spill_size_ == spill_size_); + AdjustArgs(&state); + if (state.stack_.size() > stack_.size()) { + stack_.resize(state.stack_.size()); + } updated |= MergeImpl(state.stack_, &stack_); - updated |= MergeImpl(state.stack_param_, &stack_param_); - // note that stack_arg_ is not merged as it is only used during call handing return updated; } @@ -253,9 +282,12 @@ void BlockState::Copy(BlockState *state) { std::copy(state->regs_.begin(), state->regs_.end(), regs_.begin()); std::copy(state->vregs_.begin(), state->vregs_.end(), vregs_.begin()); + ASSERT(state->spill_size_ == spill_size_); + AdjustArgs(state); + if (state->stack_.size() > stack_.size()) { + stack_.resize(state->stack_.size()); + } std::copy(state->stack_.begin(), state->stack_.end(), stack_.begin()); - std::copy(state->stack_param_.begin(), state->stack_param_.end(), stack_param_.begin()); - // note that stack_arg_ is not merged as it is only used during call handing } RegAllocVerifier::RegAllocVerifier(Graph *graph, bool save_live_regs_on_call) diff --git a/compiler/optimizer/analysis/reg_alloc_verifier.h b/compiler/optimizer/analysis/reg_alloc_verifier.h index 6840f2edc..9d03d2ccb 100644 --- a/compiler/optimizer/analysis/reg_alloc_verifier.h +++ b/compiler/optimizer/analysis/reg_alloc_verifier.h @@ -163,7 +163,7 @@ private: class BlockState { public: - BlockState(size_t regs, size_t vregs, size_t stack_slots, size_t stack_params, ArenaAllocator *alloc); + BlockState(size_t regs, size_t vregs, size_t stack_slots, ArenaAllocator *alloc); ~BlockState() = default; NO_COPY_SEMANTIC(BlockState); NO_MOVE_SEMANTIC(BlockState); @@ -189,49 +189,41 @@ public: } const LocationState &GetStack(StackSlot slot) const { - ASSERT(slot < stack_.size()); - return stack_[slot]; + ASSERT(slot < spill_size_); + return stack_[spill_off_ + slot]; } LocationState &GetStack(StackSlot slot) { - ASSERT(slot < stack_.size()); - return stack_[slot]; - } - const LocationState &GetStackArg(StackSlot slot) const - { - ASSERT(slot < stack_arg_.size()); - return stack_arg_[slot]; + ASSERT(slot < spill_size_); + return stack_[spill_off_ + slot]; } LocationState &GetStackArg(StackSlot slot) { - if (slot >= stack_arg_.size()) { - stack_arg_.resize(slot + 1); + while (slot >= spill_off_) { + stack_.push_front(LocationState()); + ++spill_off_; } - return stack_arg_[slot]; - } - const LocationState &GetStackParam(StackSlot slot) const - { - ASSERT(slot < stack_param_.size()); - return stack_param_[slot]; + return stack_[spill_off_ - slot - 1]; } LocationState &GetStackParam(StackSlot slot) { - if (slot >= stack_param_.size()) { - stack_param_.resize(slot + 1); + while ((size_t)(slot + spill_size_ + spill_off_) >= stack_.size()) { + stack_.push_back(LocationState()); } - return stack_param_[slot]; + return stack_[slot + spill_size_ + spill_off_]; } - bool Merge(const BlockState &state, const PhiInstSafeIter &phis, BasicBlock *pred, + void AdjustArgs(BlockState *state); + bool Merge(BlockState &state, const PhiInstSafeIter &phis, BasicBlock *pred, const ArenaVector &immediates, const LivenessAnalyzer &la); void Copy(BlockState *state); private: ArenaVector regs_; ArenaVector vregs_; - ArenaVector stack_; - ArenaVector stack_param_; - ArenaVector stack_arg_; + ArenaDeque stack_; + uint16_t spill_off_ {0}; + uint16_t spill_size_ {0}; }; } // namespace panda::compiler -- Gitee