Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
herobuxx committed Nov 2, 2024
2 parents ab4ee06 + 7603fea commit eb66d7e
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,81 @@ static_assert(!CanEmplace<Map, Emplaceable>);
static_assert(!CanEmplace<Map, int, double>);

template <class KeyContainer, class ValueContainer>
void test_simple() {
void test() {
using Key = typename KeyContainer::value_type;
using Value = typename ValueContainer::value_type;
using M = std::flat_map<Key, Value, std::less<Key>, KeyContainer, ValueContainer>;
using R = std::pair<typename M::iterator, bool>;
M m;
ASSERT_SAME_TYPE(decltype(m.emplace()), R);
R r = m.emplace(typename M::value_type(2, 3.5));
assert(r.second);
assert(r.first == m.begin());
assert(m.size() == 1);
assert(m.begin()->first == 2);
assert(m.begin()->second == 3.5);
{
// was empty
M m;
std::same_as<R> decltype(auto) r = m.emplace(typename M::value_type(2, 3.5));
assert(r.second);
assert(r.first == m.begin());
assert(m.size() == 1);
assert(r.first->first == 2);
assert(r.first->second == 3.5);
}
{
// key does not exist and inserted at the begin
M m = {{3, 4.0}, {5, 3.0}, {6, 1.0}, {7, 0.0}};
std::same_as<R> decltype(auto) r = m.emplace(typename M::value_type(2, 2.0));
assert(r.second);
assert(r.first == m.begin());
assert(m.size() == 5);
assert(r.first->first == 2);
assert(r.first->second == 2.0);
}
{
// key does not exist and inserted in the middle
M m = {{0, 4.0}, {1, 3.0}, {3, 1.0}, {4, 0.0}};
std::same_as<R> decltype(auto) r = m.emplace(typename M::value_type(2, 2.0));
assert(r.second);
assert(r.first == m.begin() + 2);
assert(m.size() == 5);
assert(r.first->first == 2);
assert(r.first->second == 2.0);
}
{
// key does not exist and inserted at the end
M m = {{0, 4.0}, {1, 3.0}};
std::same_as<R> decltype(auto) r = m.emplace(typename M::value_type(2, 2.0));
assert(r.second);
assert(r.first == m.begin() + 2);
assert(m.size() == 3);
assert(r.first->first == 2);
assert(r.first->second == 2.0);
}
{
// key already exists and original at the begin
M m = {{2, 4.0}, {3, 3.0}, {5, 1.0}, {6, 0.0}};
std::same_as<R> decltype(auto) r = m.emplace(typename M::value_type(2, 2.0));
assert(!r.second);
assert(r.first == m.begin());
assert(m.size() == 4);
assert(r.first->first == 2);
assert(r.first->second == 4.0);
}
{
// key already exists and original in the middle
M m = {{0, 4.0}, {2, 3.0}, {3, 1.0}, {4, 0.0}};
std::same_as<R> decltype(auto) r = m.emplace(typename M::value_type(2, 2.0));
assert(!r.second);
assert(r.first == m.begin() + 1);
assert(m.size() == 4);
assert(r.first->first == 2);
assert(r.first->second == 3.0);
}
{
// key already exists and original at the end
M m = {{0, 4.0}, {1, 3.0}, {2, 1.0}};
std::same_as<R> decltype(auto) r = m.emplace(typename M::value_type(2, 2.0));
assert(!r.second);
assert(r.first == m.begin() + 2);
assert(m.size() == 3);
assert(r.first->first == 2);
assert(r.first->second == 1.0);
}
}

template <class KeyContainer, class ValueContainer>
Expand Down Expand Up @@ -82,10 +144,10 @@ void test_emplaceable() {
}

int main(int, char**) {
test_simple<std::vector<int>, std::vector<double>>();
test_simple<std::deque<int>, std::vector<double>>();
test_simple<MinSequenceContainer<int>, MinSequenceContainer<double>>();
test_simple<std::vector<int, min_allocator<int>>, std::vector<double, min_allocator<double>>>();
test<std::vector<int>, std::vector<double>>();
test<std::deque<int>, std::vector<double>>();
test<MinSequenceContainer<int>, MinSequenceContainer<double>>();
test<std::vector<int, min_allocator<int>>, std::vector<double, min_allocator<double>>>();

test_emplaceable<std::vector<int>, std::vector<Emplaceable>>();
test_emplaceable<std::deque<int>, std::vector<Emplaceable>>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,100 @@ static_assert(!CanEmplaceHint<Map, int, double>);
#endif

template <class KeyContainer, class ValueContainer>
void test_simple() {
void test() {
using Key = typename KeyContainer::value_type;
using Value = typename ValueContainer::value_type;
using M = std::flat_map<Key, Value, std::less<Key>, KeyContainer, ValueContainer>;
using R = M::iterator;
M m;
ASSERT_SAME_TYPE(decltype(m.emplace_hint(m.cbegin())), R);
R r = m.emplace_hint(m.end(), typename M::value_type(2, 3.5));
assert(r == m.begin());
assert(m.size() == 1);
assert(m.begin()->first == 2);
assert(m.begin()->second == 3.5);
{
// was empty
M m;
std::same_as<R> decltype(auto) r = m.emplace_hint(m.end(), typename M::value_type(2, 3.5));
assert(r == m.begin());
assert(m.size() == 1);
assert(r->first == 2);
assert(r->second == 3.5);
}
{
// hints correct at the begin
M m = {{3, 3.0}, {4, 4.0}};
auto hint = m.begin();
std::same_as<R> decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2, 2.0));
assert(r == m.begin());
assert(m.size() == 3);
assert(r->first == 2);
assert(r->second == 2.0);
}
{
// hints correct in the middle
M m = {{0, 0.0}, {1, 1.0}, {3, 3.0}, {4, 4.0}};
auto hint = m.begin() + 2;
std::same_as<R> decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2, 2.0));
assert(r == m.begin() + 2);
assert(m.size() == 5);
assert(r->first == 2);
assert(r->second == 2.0);
}
{
// hints correct at the end
M m = {{0, 0.0}, {1, 1.0}};
auto hint = m.end();
std::same_as<R> decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2, 2.0));
assert(r == m.begin() + 2);
assert(m.size() == 3);
assert(r->first == 2);
assert(r->second == 2.0);
}
{
// hints correct but key already exists
M m = {{0, 0.0}, {1, 1.0}, {2, 1.9}, {3, 3.0}, {4, 4.0}};
auto hint = m.begin() + 2;
std::same_as<R> decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2, 2.0));
assert(r == m.begin() + 2);
assert(m.size() == 5);
assert(r->first == 2);
assert(r->second == 1.9);
}
{
// hints incorrectly at the begin
M m = {{1, 1.0}, {4, 4.0}};
auto hint = m.begin();
std::same_as<R> decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2, 2.0));
assert(r == m.begin() + 1);
assert(m.size() == 3);
assert(r->first == 2);
assert(r->second == 2.0);
}
{
// hints incorrectly in the middle
M m = {{0, 0.0}, {1, 1.0}, {3, 3.0}, {4, 4.0}};
auto hint = m.begin() + 1;
std::same_as<R> decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2, 2.0));
assert(r == m.begin() + 2);
assert(m.size() == 5);
assert(r->first == 2);
assert(r->second == 2.0);
}
{
// hints incorrectly at the end
M m = {{0, 0.0}, {3, 3.0}};
auto hint = m.end();
std::same_as<R> decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2, 2.0));
assert(r == m.begin() + 1);
assert(m.size() == 3);
assert(r->first == 2);
assert(r->second == 2.0);
}
{
// hints incorrect and key already exists
M m = {{0, 0.0}, {1, 1.0}, {2, 1.9}, {3, 3.0}, {4, 4.0}};
auto hint = m.begin();
std::same_as<R> decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2, 2.0));
assert(r == m.begin() + 2);
assert(m.size() == 5);
assert(r->first == 2);
assert(r->second == 1.9);
}
}

template <class KeyContainer, class ValueContainer>
Expand Down Expand Up @@ -81,10 +163,10 @@ void test_emplaceable() {
}

int main(int, char**) {
test_simple<std::vector<int>, std::vector<double>>();
test_simple<std::deque<int>, std::vector<double>>();
test_simple<MinSequenceContainer<int>, MinSequenceContainer<double>>();
test_simple<std::vector<int, min_allocator<int>>, std::vector<double, min_allocator<double>>>();
test<std::vector<int>, std::vector<double>>();
test<std::deque<int>, std::vector<double>>();
test<MinSequenceContainer<int>, MinSequenceContainer<double>>();
test<std::vector<int, min_allocator<int>>, std::vector<double, min_allocator<double>>>();

test_emplaceable<std::vector<int>, std::vector<Emplaceable>>();
test_emplaceable<std::deque<int>, std::vector<Emplaceable>>();
Expand Down
14 changes: 8 additions & 6 deletions llvm/docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1161,15 +1161,16 @@ parameters of a function. Parameter attributes are considered to be part
of the function, not of the function type, so functions with different
parameter attributes can have the same function type.

Parameter attributes are simple keywords that follow the type specified.
If multiple parameter attributes are needed, they are space separated.
For example:
Parameter attributes are either simple keywords or strings that follow the
specified type. Multiple parameter attributes, when required, are separated by
spaces. For example:

.. code-block:: llvm

declare i32 @printf(ptr noalias nocapture, ...)
declare i32 @atoi(i8 zeroext)
declare signext i8 @returns_signed_char()
define void @baz(i32 "amdgpu-flat-work-group-size"="1,256" %x)

Note that any attributes for the function result (``nonnull``,
``signext``) come before the result type.
Expand Down Expand Up @@ -1843,16 +1844,17 @@ a function. Function attributes are considered to be part of the
function, not of the function type, so functions with different function
attributes can have the same function type.

Function attributes are simple keywords that follow the type specified.
If multiple attributes are needed, they are space separated. For
example:
Function attributes are simple keywords or strings that follow the specified
type. Multiple attributes, when required, are separated by spaces.
For example:

.. code-block:: llvm

define void @f() noinline { ... }
define void @f() alwaysinline { ... }
define void @f() alwaysinline optsize { ... }
define void @f() optsize { ... }
define void @f() "no-sse" { ... }

``alignstack(<n>)``
This attribute indicates that, when emitting the prologue and
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/X86/X86RegisterInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -432,11 +432,11 @@ def TMM4: X86Reg<"tmm4", 4>;
def TMM5: X86Reg<"tmm5", 5>;
def TMM6: X86Reg<"tmm6", 6>;
def TMM7: X86Reg<"tmm7", 7>;
}
// TMM register pairs
def TPAIRS : RegisterTuples<[sub_t0, sub_t1],
[(add TMM0, TMM2, TMM4, TMM6),
(add TMM1, TMM3, TMM5, TMM7)]>;
}

// Floating point stack registers. These don't map one-to-one to the FP
// pseudo registers, but we still mark them as aliasing FP registers. That
Expand Down

0 comments on commit eb66d7e

Please sign in to comment.