Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/asmjit/asmjit.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/asmjit/core/raassignment_p.h')
-rw-r--r--src/asmjit/core/raassignment_p.h132
1 files changed, 57 insertions, 75 deletions
diff --git a/src/asmjit/core/raassignment_p.h b/src/asmjit/core/raassignment_p.h
index 6b5df54..22a97e2 100644
--- a/src/asmjit/core/raassignment_p.h
+++ b/src/asmjit/core/raassignment_p.h
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#ifndef ASMJIT_CORE_RAASSIGNMENT_P_H_INCLUDED
#define ASMJIT_CORE_RAASSIGNMENT_P_H_INCLUDED
@@ -35,10 +17,12 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_ra
//! \{
-// ============================================================================
-// [asmjit::RAAssignment]
-// ============================================================================
-
+//! Holds the current register assignment.
+//!
+//! Has two purposes:
+//!
+//! 1. Holds register assignment of a local register allocator (see \ref RALocalAllocator).
+//! 2. Holds register assignment of the entry of basic blocks (see \ref RABlock).
class RAAssignment {
public:
ASMJIT_NONCOPYABLE(RAAssignment)
@@ -120,6 +104,9 @@ public:
}
};
+ //! \name Members
+ //! \{
+
//! Physical registers layout.
Layout _layout;
//! WorkReg to PhysReg mapping.
@@ -127,7 +114,9 @@ public:
//! PhysReg to WorkReg mapping and assigned/dirty bits.
PhysToWorkMap* _physToWorkMap;
//! Optimization to translate PhysRegs to WorkRegs faster.
- uint32_t* _physToWorkIds[BaseReg::kGroupVirt];
+ Support::Array<uint32_t*, Globals::kNumVirtGroups> _physToWorkIds;
+
+ //! \}
//! \name Construction & Destruction
//! \{
@@ -137,31 +126,30 @@ public:
resetMaps();
}
- inline void initLayout(const RARegCount& physCount, const RAWorkRegs& workRegs) noexcept {
+ ASMJIT_FORCE_INLINE void initLayout(const RARegCount& physCount, const RAWorkRegs& workRegs) noexcept {
// Layout must be initialized before data.
ASMJIT_ASSERT(_physToWorkMap == nullptr);
ASMJIT_ASSERT(_workToPhysMap == nullptr);
_layout.physIndex.buildIndexes(physCount);
_layout.physCount = physCount;
- _layout.physTotal = uint32_t(_layout.physIndex[BaseReg::kGroupVirt - 1]) +
- uint32_t(_layout.physCount[BaseReg::kGroupVirt - 1]) ;
+ _layout.physTotal = uint32_t(_layout.physIndex[RegGroup::kMaxVirt]) +
+ uint32_t(_layout.physCount[RegGroup::kMaxVirt]) ;
_layout.workCount = workRegs.size();
_layout.workRegs = &workRegs;
}
- inline void initMaps(PhysToWorkMap* physToWorkMap, WorkToPhysMap* workToPhysMap) noexcept {
+ ASMJIT_FORCE_INLINE void initMaps(PhysToWorkMap* physToWorkMap, WorkToPhysMap* workToPhysMap) noexcept {
_physToWorkMap = physToWorkMap;
_workToPhysMap = workToPhysMap;
- for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++)
+ for (RegGroup group : RegGroupVirtValues{})
_physToWorkIds[group] = physToWorkMap->workIds + _layout.physIndex.get(group);
}
- inline void resetMaps() noexcept {
+ ASMJIT_FORCE_INLINE void resetMaps() noexcept {
_physToWorkMap = nullptr;
_workToPhysMap = nullptr;
- for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++)
- _physToWorkIds[group] = nullptr;
+ _physToWorkIds.fill(nullptr);
}
//! \}
@@ -174,30 +162,30 @@ public:
inline RARegMask& assigned() noexcept { return _physToWorkMap->assigned; }
inline const RARegMask& assigned() const noexcept { return _physToWorkMap->assigned; }
- inline uint32_t assigned(uint32_t group) const noexcept { return _physToWorkMap->assigned[group]; }
+ inline uint32_t assigned(RegGroup group) const noexcept { return _physToWorkMap->assigned[group]; }
inline RARegMask& dirty() noexcept { return _physToWorkMap->dirty; }
inline const RARegMask& dirty() const noexcept { return _physToWorkMap->dirty; }
- inline uint32_t dirty(uint32_t group) const noexcept { return _physToWorkMap->dirty[group]; }
+ inline RegMask dirty(RegGroup group) const noexcept { return _physToWorkMap->dirty[group]; }
- inline uint32_t workToPhysId(uint32_t group, uint32_t workId) const noexcept {
+ inline uint32_t workToPhysId(RegGroup group, uint32_t workId) const noexcept {
DebugUtils::unused(group);
ASMJIT_ASSERT(workId != kWorkNone);
ASMJIT_ASSERT(workId < _layout.workCount);
return _workToPhysMap->physIds[workId];
}
- inline uint32_t physToWorkId(uint32_t group, uint32_t physId) const noexcept {
+ inline uint32_t physToWorkId(RegGroup group, uint32_t physId) const noexcept {
ASMJIT_ASSERT(physId < Globals::kMaxPhysRegs);
return _physToWorkIds[group][physId];
}
- inline bool isPhysAssigned(uint32_t group, uint32_t physId) const noexcept {
+ inline bool isPhysAssigned(RegGroup group, uint32_t physId) const noexcept {
ASMJIT_ASSERT(physId < Globals::kMaxPhysRegs);
return Support::bitTest(_physToWorkMap->assigned[group], physId);
}
- inline bool isPhysDirty(uint32_t group, uint32_t physId) const noexcept {
+ inline bool isPhysDirty(RegGroup group, uint32_t physId) const noexcept {
ASMJIT_ASSERT(physId < Globals::kMaxPhysRegs);
return Support::bitTest(_physToWorkMap->dirty[group], physId);
}
@@ -205,15 +193,15 @@ public:
//! \}
//! \name Assignment
+ //!
+ //! These are low-level allocation helpers that are used to update the current mappings between physical and
+ //! virt/work registers and also to update masks that represent allocated and dirty registers. These functions
+ //! don't emit any code; they are only used to update and keep all mappings in sync.
+ //!
//! \{
- // These are low-level allocation helpers that are used to update the current
- // mappings between physical and virt/work registers and also to update masks
- // that represent allocated and dirty registers. These functions don't emit
- // any code; they are only used to update and keep all mappings in sync.
-
//! Assign [VirtReg/WorkReg] to a physical register.
- ASMJIT_INLINE void assign(uint32_t group, uint32_t workId, uint32_t physId, uint32_t dirty) noexcept {
+ inline void assign(RegGroup group, uint32_t workId, uint32_t physId, bool dirty) noexcept {
ASMJIT_ASSERT(workToPhysId(group, workId) == kPhysNone);
ASMJIT_ASSERT(physToWorkId(group, physId) == kWorkNone);
ASMJIT_ASSERT(!isPhysAssigned(group, physId));
@@ -222,15 +210,15 @@ public:
_workToPhysMap->physIds[workId] = uint8_t(physId);
_physToWorkIds[group][physId] = workId;
- uint32_t regMask = Support::bitMask(physId);
+ RegMask regMask = Support::bitMask(physId);
_physToWorkMap->assigned[group] |= regMask;
- _physToWorkMap->dirty[group] |= regMask & Support::bitMaskFromBool<uint32_t>(dirty);
+ _physToWorkMap->dirty[group] |= regMask & Support::bitMaskFromBool<RegMask>(dirty);
verify();
}
//! Reassign [VirtReg/WorkReg] to `dstPhysId` from `srcPhysId`.
- ASMJIT_INLINE void reassign(uint32_t group, uint32_t workId, uint32_t dstPhysId, uint32_t srcPhysId) noexcept {
+ inline void reassign(RegGroup group, uint32_t workId, uint32_t dstPhysId, uint32_t srcPhysId) noexcept {
ASMJIT_ASSERT(dstPhysId != srcPhysId);
ASMJIT_ASSERT(workToPhysId(group, workId) == srcPhysId);
ASMJIT_ASSERT(physToWorkId(group, srcPhysId) == workId);
@@ -241,19 +229,19 @@ public:
_physToWorkIds[group][srcPhysId] = kWorkNone;
_physToWorkIds[group][dstPhysId] = workId;
- uint32_t srcMask = Support::bitMask(srcPhysId);
- uint32_t dstMask = Support::bitMask(dstPhysId);
+ RegMask srcMask = Support::bitMask(srcPhysId);
+ RegMask dstMask = Support::bitMask(dstPhysId);
- uint32_t dirty = (_physToWorkMap->dirty[group] & srcMask) != 0;
- uint32_t regMask = dstMask | srcMask;
+ bool dirty = (_physToWorkMap->dirty[group] & srcMask) != 0;
+ RegMask regMask = dstMask | srcMask;
_physToWorkMap->assigned[group] ^= regMask;
- _physToWorkMap->dirty[group] ^= regMask & Support::bitMaskFromBool<uint32_t>(dirty);
+ _physToWorkMap->dirty[group] ^= regMask & Support::bitMaskFromBool<RegMask>(dirty);
verify();
}
- ASMJIT_INLINE void swap(uint32_t group, uint32_t aWorkId, uint32_t aPhysId, uint32_t bWorkId, uint32_t bPhysId) noexcept {
+ inline void swap(RegGroup group, uint32_t aWorkId, uint32_t aPhysId, uint32_t bWorkId, uint32_t bPhysId) noexcept {
ASMJIT_ASSERT(aPhysId != bPhysId);
ASMJIT_ASSERT(workToPhysId(group, aWorkId) == aPhysId);
ASMJIT_ASSERT(workToPhysId(group, bWorkId) == bPhysId);
@@ -267,21 +255,17 @@ public:
_physToWorkIds[group][aPhysId] = bWorkId;
_physToWorkIds[group][bPhysId] = aWorkId;
- uint32_t aMask = Support::bitMask(aPhysId);
- uint32_t bMask = Support::bitMask(bPhysId);
-
- uint32_t flipMask = Support::bitMaskFromBool<uint32_t>(
- ((_physToWorkMap->dirty[group] & aMask) != 0) ^
- ((_physToWorkMap->dirty[group] & bMask) != 0));
-
- uint32_t regMask = aMask | bMask;
+ RegMask aMask = Support::bitMask(aPhysId);
+ RegMask bMask = Support::bitMask(bPhysId);
+ RegMask flipMask = Support::bitMaskFromBool<RegMask>(((_physToWorkMap->dirty[group] & aMask) != 0) ^ ((_physToWorkMap->dirty[group] & bMask) != 0));
+ RegMask regMask = aMask | bMask;
_physToWorkMap->dirty[group] ^= regMask & flipMask;
verify();
}
//! Unassign [VirtReg/WorkReg] from a physical register.
- ASMJIT_INLINE void unassign(uint32_t group, uint32_t workId, uint32_t physId) noexcept {
+ inline void unassign(RegGroup group, uint32_t workId, uint32_t physId) noexcept {
ASMJIT_ASSERT(physId < Globals::kMaxPhysRegs);
ASMJIT_ASSERT(workToPhysId(group, workId) == physId);
ASMJIT_ASSERT(physToWorkId(group, physId) == workId);
@@ -290,22 +274,22 @@ public:
_workToPhysMap->physIds[workId] = kPhysNone;
_physToWorkIds[group][physId] = kWorkNone;
- uint32_t regMask = Support::bitMask(physId);
+ RegMask regMask = Support::bitMask(physId);
_physToWorkMap->assigned[group] &= ~regMask;
_physToWorkMap->dirty[group] &= ~regMask;
verify();
}
- inline void makeClean(uint32_t group, uint32_t workId, uint32_t physId) noexcept {
+ inline void makeClean(RegGroup group, uint32_t workId, uint32_t physId) noexcept {
DebugUtils::unused(workId);
- uint32_t regMask = Support::bitMask(physId);
+ RegMask regMask = Support::bitMask(physId);
_physToWorkMap->dirty[group] &= ~regMask;
}
- inline void makeDirty(uint32_t group, uint32_t workId, uint32_t physId) noexcept {
+ inline void makeDirty(RegGroup group, uint32_t workId, uint32_t physId) noexcept {
DebugUtils::unused(workId);
- uint32_t regMask = Support::bitMask(physId);
+ RegMask regMask = Support::bitMask(physId);
_physToWorkMap->dirty[group] |= regMask;
}
@@ -314,12 +298,10 @@ public:
//! \name Utilities
//! \{
- inline void swap(RAAssignment& other) noexcept {
+ ASMJIT_FORCE_INLINE void swap(RAAssignment& other) noexcept {
std::swap(_workToPhysMap, other._workToPhysMap);
std::swap(_physToWorkMap, other._physToWorkMap);
-
- for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++)
- std::swap(_physToWorkIds[group], other._physToWorkIds[group]);
+ _physToWorkIds.swap(other._physToWorkIds);
}
inline void copyFrom(const PhysToWorkMap* physToWorkMap, const WorkToPhysMap* workToPhysMap) noexcept {
@@ -373,7 +355,7 @@ public:
uint32_t physId = _workToPhysMap->physIds[workId];
if (physId != kPhysNone) {
const RAWorkReg* workReg = _layout.workRegs->at(workId);
- uint32_t group = workReg->group();
+ RegGroup group = workReg->group();
ASMJIT_ASSERT(_physToWorkIds[group][physId] == workId);
}
}
@@ -381,7 +363,7 @@ public:
// Verify PhysToWorkMap.
{
- for (uint32_t group = 0; group < BaseReg::kGroupVirt; group++) {
+ for (RegGroup group : RegGroupVirtValues{}) {
uint32_t physCount = _layout.physCount[group];
for (uint32_t physId = 0; physId < physCount; physId++) {
uint32_t workId = _physToWorkIds[group][physId];