diff options
author | Roman Artemev <roman.artemev@syntacore.com> | 2024-04-18 13:40:13 +0300 |
---|---|---|
committer | VladimĂr Marko <vmarko@google.com> | 2024-04-18 14:55:03 +0000 |
commit | b1eb2853b3e6349bac4f2cd5c2ee47458198399d (patch) | |
tree | eb16c165abb4b9fe3de78f9c57d748c60159bc6d | |
parent | c7bc9f58348dff223807c4828f99b6930b07ad3c (diff) | |
download | art-b1eb2853b3e6349bac4f2cd5c2ee47458198399d.tar.gz |
riscv64: Reorganize list of branches bound to the same label
Move next link from code buffer to branch object
This change is required to properly support compressed branches
Test: m test-art-host-gtest
Test: run-gtests.sh
Test: testrunner.py --target --optimizing
Bug: 328561342
Change-Id: Icbf61e9ec758b0116358c29bf93d27878a9c7753
-rw-r--r-- | compiler/utils/riscv64/assembler_riscv64.cc | 36 | ||||
-rw-r--r-- | compiler/utils/riscv64/assembler_riscv64.h | 10 |
2 files changed, 30 insertions, 16 deletions
diff --git a/compiler/utils/riscv64/assembler_riscv64.cc b/compiler/utils/riscv64/assembler_riscv64.cc index a2df6d287d..9cd4a45f0c 100644 --- a/compiler/utils/riscv64/assembler_riscv64.cc +++ b/compiler/utils/riscv64/assembler_riscv64.cc @@ -6680,7 +6680,8 @@ Riscv64Assembler::Branch::Branch(uint32_t location, uint32_t target, XRegister r lhs_reg_(rd), rhs_reg_(Zero), freg_(kNoFRegister), - condition_(kUncond) { + condition_(kUncond), + next_branch_id_(0u) { InitializeType( (rd != Zero ? (is_bare ? kBareCall : kCall) : (is_bare ? kBareUncondBranch : kUncondBranch))); } @@ -6697,7 +6698,8 @@ Riscv64Assembler::Branch::Branch(uint32_t location, lhs_reg_(lhs_reg), rhs_reg_(rhs_reg), freg_(kNoFRegister), - condition_(condition) { + condition_(condition), + next_branch_id_(0u) { DCHECK_NE(condition, kUncond); DCHECK(!IsNop(condition, lhs_reg, rhs_reg)); DCHECK(!IsUncond(condition, lhs_reg, rhs_reg)); @@ -6714,7 +6716,8 @@ Riscv64Assembler::Branch::Branch(uint32_t location, lhs_reg_(rd), rhs_reg_(Zero), freg_(kNoFRegister), - condition_(kUncond) { + condition_(kUncond), + next_branch_id_(0u) { CHECK_NE(rd , Zero); InitializeType(label_or_literal_type); } @@ -6729,7 +6732,8 @@ Riscv64Assembler::Branch::Branch(uint32_t location, lhs_reg_(Zero), rhs_reg_(Zero), freg_(rd), - condition_(kUncond) { + condition_(kUncond), + next_branch_id_(0u) { InitializeType(literal_type); } @@ -6790,6 +6794,8 @@ uint32_t Riscv64Assembler::Branch::GetOldEndLocation() const { return GetOldLocation() + GetOldLength(); } +uint32_t Riscv64Assembler::Branch::NextBranchId() const { return next_branch_id_; } + bool Riscv64Assembler::Branch::IsBare() const { switch (type_) { case kBareUncondBranch: @@ -6904,6 +6910,10 @@ int32_t Riscv64Assembler::Branch::GetOffset() const { return offset; } +void Riscv64Assembler::Branch::LinkToList(uint32_t next_branch_id) { + next_branch_id_ = next_branch_id; +} + void Riscv64Assembler::EmitBcond(BranchCondition cond, XRegister rs, XRegister rt, @@ -7023,16 +7033,16 @@ void Riscv64Assembler::EmitBranches() { } void Riscv64Assembler::FinalizeLabeledBranch(Riscv64Label* label) { - DCHECK_ALIGNED(branches_.back().GetLength(), sizeof(uint32_t)); - uint32_t length = branches_.back().GetLength() / sizeof(uint32_t); + Branch& this_branch = branches_.back(); + DCHECK_ALIGNED(this_branch.GetLength(), sizeof(uint32_t)); + uint32_t length = this_branch.GetLength() / sizeof(uint32_t); ScopedNoCInstructions no_compression(this); if (!label->IsBound()) { // Branch forward (to a following label), distance is unknown. // The first branch forward will contain 0, serving as the terminator of // the list of forward-reaching branches. - Emit32(label->position_); - length--; + this_branch.LinkToList(label->position_); // Now make the label object point to this branch // (this forms a linked list of branches preceding this label). uint32_t branch_id = branches_.size() - 1; @@ -7097,14 +7107,8 @@ void Riscv64Assembler::Bind(Riscv64Label* label) { uint32_t branch_id = label->Position(); Branch* branch = GetBranch(branch_id); branch->Resolve(bound_pc); - - uint32_t branch_location = branch->GetLocation(); - // Extract the location of the previous branch in the list (walking the list backwards; - // the previous branch ID was stored in the space reserved for this branch). - uint32_t prev = buffer_.Load<uint32_t>(branch_location); - - // On to the previous branch in the list... - label->position_ = prev; + // On to the next branch in the list... + label->position_ = branch->NextBranchId(); } // Now make the label object contain its own location (relative to the end of the preceding diff --git a/compiler/utils/riscv64/assembler_riscv64.h b/compiler/utils/riscv64/assembler_riscv64.h index fc5d3f0684..4f561dc1a6 100644 --- a/compiler/utils/riscv64/assembler_riscv64.h +++ b/compiler/utils/riscv64/assembler_riscv64.h @@ -2030,6 +2030,8 @@ class Riscv64Assembler final : public Assembler { bool IsBare() const; bool IsResolved() const; + uint32_t NextBranchId() const; + // Returns the bit size of the signed offset that the branch instruction can handle. OffsetBits GetOffsetSize() const; @@ -2057,6 +2059,9 @@ class Riscv64Assembler final : public Assembler { // Calculates and returns the offset ready for encoding in the branch instruction(s). int32_t GetOffset() const; + // Link with the next branch + void LinkToList(uint32_t next_branch_id); + private: // Completes branch construction by determining and recording its type. void InitializeType(Type initial_type); @@ -2075,6 +2080,11 @@ class Riscv64Assembler final : public Assembler { Type type_; // Current type of the branch. Type old_type_; // Initial type of the branch. + + // Id of the next branch bound to the same label in singly-linked zero-terminated list + // NOTE: encoded the same way as a position in a linked Label (id + sizeof(void*)) + // Label itself is used to hold the 'head' of this list + uint32_t next_branch_id_; }; // Branch and literal fixup. |