Skip to content

Commit

Permalink
Merge pull request #12126 from JosJuice/small-vector
Browse files Browse the repository at this point in the history
Move SmallVector to Common
  • Loading branch information
AdmiralCurtiss committed Aug 26, 2023
2 parents b149ea5 + 6e88c44 commit 5c4671f
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 51 deletions.
34 changes: 4 additions & 30 deletions Source/Core/Common/Arm64Emitter.cpp
Expand Up @@ -18,6 +18,7 @@
#include "Common/BitUtils.h"
#include "Common/CommonTypes.h"
#include "Common/MathUtil.h"
#include "Common/SmallVector.h"

#ifdef _WIN32
#include <Windows.h>
Expand Down Expand Up @@ -1794,33 +1795,6 @@ void ARM64XEmitter::ADRP(ARM64Reg Rd, s64 imm)
EncodeAddressInst(1, Rd, static_cast<s32>(imm >> 12));
}

template <typename T, size_t MaxSize>
class SmallVector final
{
public:
SmallVector() = default;
explicit SmallVector(size_t size) : m_size(size) {}

void push_back(const T& x) { m_array[m_size++] = x; }
void push_back(T&& x) { m_array[m_size++] = std::move(x); }

template <typename... Args>
T& emplace_back(Args&&... args)
{
return m_array[m_size++] = T{std::forward<Args>(args)...};
}

T& operator[](size_t i) { return m_array[i]; }
const T& operator[](size_t i) const { return m_array[i]; }

size_t size() const { return m_size; }
bool empty() const { return m_size == 0; }

private:
std::array<T, MaxSize> m_array{};
size_t m_size = 0;
};

template <typename T>
void ARM64XEmitter::MOVI2RImpl(ARM64Reg Rd, T imm)
{
Expand All @@ -1844,17 +1818,17 @@ void ARM64XEmitter::MOVI2RImpl(ARM64Reg Rd, T imm)

constexpr size_t max_parts = sizeof(T) / 2;

SmallVector<Part, max_parts> best_parts;
Common::SmallVector<Part, max_parts> best_parts;
Approach best_approach;
u64 best_base;

const auto instructions_required = [](const SmallVector<Part, max_parts>& parts,
const auto instructions_required = [](const Common::SmallVector<Part, max_parts>& parts,
Approach approach) {
return parts.size() + (approach > Approach::MOVNBase);
};

const auto try_base = [&](T base, Approach approach, bool first_time) {
SmallVector<Part, max_parts> parts;
Common::SmallVector<Part, max_parts> parts;

for (size_t i = 0; i < max_parts; ++i)
{
Expand Down
1 change: 1 addition & 0 deletions Source/Core/Common/CMakeLists.txt
Expand Up @@ -110,6 +110,7 @@ add_library(common
SettingsHandler.h
SFMLHelper.cpp
SFMLHelper.h
SmallVector.h
SocketContext.cpp
SocketContext.h
SPSCQueue.h
Expand Down
46 changes: 46 additions & 0 deletions Source/Core/Common/SmallVector.h
@@ -0,0 +1,46 @@
// SPDX-License-Identifier: CC0-1.0

#pragma once

#include <array>
#include <cstddef>
#include <utility>

namespace Common
{

// An std::vector-like container that uses no heap allocations but is limited to a maximum size.
template <typename T, size_t MaxSize>
class SmallVector final
{
public:
SmallVector() = default;
explicit SmallVector(size_t size) : m_size(size) {}

void push_back(const T& x) { m_array[m_size++] = x; }
void push_back(T&& x) { m_array[m_size++] = std::move(x); }

template <typename... Args>
T& emplace_back(Args&&... args)
{
return m_array[m_size++] = T{std::forward<Args>(args)...};
}

T& operator[](size_t i) { return m_array[i]; }
const T& operator[](size_t i) const { return m_array[i]; }

auto begin() { return m_array.begin(); }
auto end() { return m_array.begin() + m_size; }

auto begin() const { return m_array.begin(); }
auto end() const { return m_array.begin() + m_size; }

size_t size() const { return m_size; }
bool empty() const { return m_size == 0; }

private:
std::array<T, MaxSize> m_array{};
size_t m_size = 0;
};

} // namespace Common
1 change: 1 addition & 0 deletions Source/Core/DolphinLib.props
Expand Up @@ -143,6 +143,7 @@
<ClInclude Include="Common\Semaphore.h" />
<ClInclude Include="Common\SettingsHandler.h" />
<ClInclude Include="Common\SFMLHelper.h" />
<ClInclude Include="Common\SmallVector.h" />
<ClInclude Include="Common\SocketContext.h" />
<ClInclude Include="Common\SPSCQueue.h" />
<ClInclude Include="Common\StringLiteral.h" />
Expand Down
24 changes: 3 additions & 21 deletions Source/Core/VideoCommon/BPFunctions.cpp
Expand Up @@ -10,6 +10,7 @@
#include "Common/Assert.h"
#include "Common/CommonTypes.h"
#include "Common/Logging/Log.h"
#include "Common/SmallVector.h"

#include "VideoCommon/AbstractFramebuffer.h"
#include "VideoCommon/AbstractGfx.h"
Expand Down Expand Up @@ -76,26 +77,7 @@ bool ScissorResult::IsWorse(const ScissorRect& lhs, const ScissorRect& rhs) cons

namespace
{
// Dynamically sized small array of ScissorRanges (used as an heap-less alternative to std::vector
// to reduce allocation overhead)
struct RangeList
{
static constexpr u32 MAX_RANGES = 9;

u32 m_num_ranges = 0;
std::array<ScissorRange, MAX_RANGES> m_ranges{};

void AddRange(int offset, int start, int end)
{
DEBUG_ASSERT(m_num_ranges < MAX_RANGES);
m_ranges[m_num_ranges] = ScissorRange(offset, start, end);
m_num_ranges++;
}
auto begin() const { return m_ranges.begin(); }
auto end() const { return m_ranges.begin() + m_num_ranges; }

u32 size() { return m_num_ranges; }
};
using RangeList = Common::SmallVector<ScissorRange, 9>;

static RangeList ComputeScissorRanges(int start, int end, int offset, int efb_dim)
{
Expand All @@ -108,7 +90,7 @@ static RangeList ComputeScissorRanges(int start, int end, int offset, int efb_di
int new_end = std::clamp(end - new_off + 1, 0, efb_dim);
if (new_start < new_end)
{
ranges.AddRange(new_off, new_start, new_end);
ranges.emplace_back(new_off, new_start, new_end);
}
}

Expand Down

0 comments on commit 5c4671f

Please sign in to comment.