18 changes: 18 additions & 0 deletions flang/test/Lower/CUDA/cuda-data-transfer.cuf
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,21 @@ end subroutine
! CHECK: fir.cuda_kernel<<<*, *>>>
! CHECK-NOT: fir.cuda_data_transfer
! CHECK: hlfir.assign

attributes(global) subroutine sub5(a)
integer, device :: a
integer :: i
a = i
end subroutine

! CHECK-LABEL: func.func @_QPsub5
! CHECK-NOT: fir.cuda_data_transfer

attributes(host,device) subroutine sub6(a)
integer, device :: a
integer :: i
a = i
end subroutine

! CHECK-LABEL: func.func @_QPsub6
! CHECK: fir.cuda_data_transfer
11 changes: 11 additions & 0 deletions flang/test/Lower/OpenMP/default-clause-implied-do-fix.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s

!CHECK: @_QPsb
subroutine sb(a)
integer :: a(:)
!CHECK: omp.parallel
!$omp parallel default(private)
!CHECK: hlfir.elemental
if (any(a/=(/(100,i=1,5)/))) print *, "OK"
!$omp end parallel
end subroutine
2 changes: 1 addition & 1 deletion libcxx/docs/Status/Cxx2cIssues.csv
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"`3919 <https://wg21.link/LWG3919>`__","``enumerate_view`` may invoke UB for sized common non-forward underlying ranges","Tokyo March 2024","","","|ranges|"
"`3950 <https://wg21.link/LWG3950>`__","``std::basic_string_view`` comparison operators are overspecified","Tokyo March 2024","|Complete|","18.0",""
"`3975 <https://wg21.link/LWG3975>`__","Specializations of ``basic_format_context`` should not be permitted","Tokyo March 2024","|Nothing To Do|","","|format|"
"`3984 <https://wg21.link/LWG3984>`__","``ranges::to``'s recursion branch may be ill-formed","Tokyo March 2024","","","|ranges|"
"`3984 <https://wg21.link/LWG3984>`__","``ranges::to``'s recursion branch may be ill-formed","Tokyo March 2024","|Complete|","19.0","|ranges|"
"`4011 <https://wg21.link/LWG4011>`__","``""Effects: Equivalent to return""`` in ``[span.elem]``","Tokyo March 2024","|Nothing To Do|","",""
"`4012 <https://wg21.link/LWG4012>`__","``common_view::begin/end`` are missing the ``simple-view`` check","Tokyo March 2024","","","|ranges|"
"`4013 <https://wg21.link/LWG4013>`__","``lazy_split_view::outer-iterator::value_type`` should not provide default constructor","Tokyo March 2024","","","|ranges|"
Expand Down
20 changes: 9 additions & 11 deletions libcxx/include/__algorithm/find.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
// generic implementation
template <class _Iter, class _Sent, class _Tp, class _Proj>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter
__find_impl(_Iter __first, _Sent __last, const _Tp& __value, _Proj& __proj) {
__find(_Iter __first, _Sent __last, const _Tp& __value, _Proj& __proj) {
for (; __first != __last; ++__first)
if (std::__invoke(__proj, *__first) == __value)
break;
Expand All @@ -57,8 +57,7 @@ template <class _Tp,
__enable_if_t<__is_identity<_Proj>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value &&
sizeof(_Tp) == 1,
int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp*
__find_impl(_Tp* __first, _Tp* __last, const _Up& __value, _Proj&) {
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __find(_Tp* __first, _Tp* __last, const _Up& __value, _Proj&) {
if (auto __ret = std::__constexpr_memchr(__first, __value, __last - __first))
return __ret;
return __last;
Expand All @@ -71,8 +70,7 @@ template <class _Tp,
__enable_if_t<__is_identity<_Proj>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value &&
sizeof(_Tp) == sizeof(wchar_t) && _LIBCPP_ALIGNOF(_Tp) >= _LIBCPP_ALIGNOF(wchar_t),
int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp*
__find_impl(_Tp* __first, _Tp* __last, const _Up& __value, _Proj&) {
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __find(_Tp* __first, _Tp* __last, const _Up& __value, _Proj&) {
if (auto __ret = std::__constexpr_wmemchr(__first, __value, __last - __first))
return __ret;
return __last;
Expand All @@ -89,10 +87,10 @@ template <class _Tp,
is_signed<_Tp>::value == is_signed<_Up>::value,
int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp*
__find_impl(_Tp* __first, _Tp* __last, const _Up& __value, _Proj& __proj) {
__find(_Tp* __first, _Tp* __last, const _Up& __value, _Proj& __proj) {
if (__value < numeric_limits<_Tp>::min() || __value > numeric_limits<_Tp>::max())
return __last;
return std::__find_impl(__first, __last, _Tp(__value), __proj);
return std::__find(__first, __last, _Tp(__value), __proj);
}

// __bit_iterator implementation
Expand Down Expand Up @@ -134,7 +132,7 @@ __find_bool(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)

template <class _Cp, bool _IsConst, class _Tp, class _Proj, __enable_if_t<__is_identity<_Proj>::value, int> = 0>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, _IsConst>
__find_impl(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value, _Proj&) {
__find(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value, _Proj&) {
if (static_cast<bool>(__value))
return std::__find_bool<true>(__first, static_cast<typename _Cp::size_type>(__last - __first));
return std::__find_bool<false>(__first, static_cast<typename _Cp::size_type>(__last - __first));
Expand All @@ -150,7 +148,7 @@ template <class _SegmentedIterator,
class _Proj,
__enable_if_t<__is_segmented_iterator<_SegmentedIterator>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _SegmentedIterator
__find_impl(_SegmentedIterator __first, _SegmentedIterator __last, const _Tp& __value, _Proj& __proj) {
__find(_SegmentedIterator __first, _SegmentedIterator __last, const _Tp& __value, _Proj& __proj) {
return std::__find_segment_if(std::move(__first), std::move(__last), __find_segment<_Tp>(__value), __proj);
}

Expand All @@ -163,7 +161,7 @@ struct __find_segment {
template <class _InputIterator, class _Proj>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _InputIterator
operator()(_InputIterator __first, _InputIterator __last, _Proj& __proj) const {
return std::__find_impl(__first, __last, __value_, __proj);
return std::__find(__first, __last, __value_, __proj);
}
};

Expand All @@ -173,7 +171,7 @@ _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _In
find(_InputIterator __first, _InputIterator __last, const _Tp& __value) {
__identity __proj;
return std::__rewrap_iter(
__first, std::__find_impl(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __value, __proj));
__first, std::__find(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __value, __proj));
}

_LIBCPP_END_NAMESPACE_STD
Expand Down
4 changes: 2 additions & 2 deletions libcxx/include/__algorithm/ranges_find.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ struct __fn {
if constexpr (forward_iterator<_Iter>) {
auto [__first_un, __last_un] = std::__unwrap_range(__first, std::move(__last));
return std::__rewrap_range<_Sent>(
std::move(__first), std::__find_impl(std::move(__first_un), std::move(__last_un), __value, __proj));
std::move(__first), std::__find(std::move(__first_un), std::move(__last_un), __value, __proj));
} else {
return std::__find_impl(std::move(__first), std::move(__last), __value, __proj);
return std::__find(std::move(__first), std::move(__last), __value, __proj);
}
}

Expand Down
3 changes: 2 additions & 1 deletion libcxx/include/__ranges/to.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <__ranges/concepts.h>
#include <__ranges/from_range.h>
#include <__ranges/range_adaptor.h>
#include <__ranges/ref_view.h>
#include <__ranges/size.h>
#include <__ranges/transform_view.h>
#include <__type_traits/add_pointer.h>
Expand Down Expand Up @@ -129,7 +130,7 @@ template <class _Container, input_range _Range, class... _Args>
// Try the recursive case.
} else if constexpr (input_range<range_reference_t<_Range>>) {
return ranges::to<_Container>(
__range | views::transform([](auto&& __elem) {
ref_view(__range) | views::transform([](auto&& __elem) {
return ranges::to<range_value_t<_Container>>(std::forward<decltype(__elem)>(__elem));
}),
std::forward<_Args>(__args)...);
Expand Down
4 changes: 2 additions & 2 deletions libcxx/include/__string/char_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t> {
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX17 const char_type*
find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT {
__identity __proj;
const char_type* __match = std::__find_impl(__s, __s + __n, __a, __proj);
const char_type* __match = std::__find(__s, __s + __n, __a, __proj);
if (__match == __s + __n)
return nullptr;
return __match;
Expand Down Expand Up @@ -430,7 +430,7 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t> {
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX17 const char_type*
find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT {
__identity __proj;
const char_type* __match = std::__find_impl(__s, __s + __n, __a, __proj);
const char_type* __match = std::__find(__s, __s + __n, __a, __proj);
if (__match == __s + __n)
return nullptr;
return __match;
Expand Down
29 changes: 10 additions & 19 deletions libcxx/include/__utility/no_destroy.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <__config>
#include <__type_traits/is_constant_evaluated.h>
#include <__utility/forward.h>
#include <new>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
Expand All @@ -29,33 +30,23 @@ struct __uninitialized_tag {};
// initialization using __emplace.
template <class _Tp>
struct __no_destroy {
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI explicit __no_destroy(__uninitialized_tag) : __dummy_() {
if (__libcpp_is_constant_evaluated()) {
__dummy_ = char();
}
}
_LIBCPP_HIDE_FROM_ABI ~__no_destroy() {
// nothing
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __no_destroy(__uninitialized_tag) : __obj_() {}

template <class... _Args>
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI explicit __no_destroy(_Args&&... __args)
: __obj_(std::forward<_Args>(__args)...) {}
_LIBCPP_HIDE_FROM_ABI explicit __no_destroy(_Args&&... __args) {
::new ((void*)__obj_) _Tp(std::forward<_Args>(__args)...);
}

template <class... _Args>
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp& __emplace(_Args&&... __args) {
new (&__obj_) _Tp(std::forward<_Args>(__args)...);
return __obj_;
_LIBCPP_HIDE_FROM_ABI _Tp& __emplace(_Args&&... __args) {
return *(::new ((void*)__obj_) _Tp(std::forward<_Args>(__args)...));
}

_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp& __get() { return __obj_; }
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp const& __get() const { return __obj_; }
_LIBCPP_HIDE_FROM_ABI _Tp& __get() { return *reinterpret_cast<_Tp*>(__obj_); }
_LIBCPP_HIDE_FROM_ABI _Tp const& __get() const { return *reinterpret_cast<const _Tp*>(__obj_); }

private:
union {
_Tp __obj_;
char __dummy_; // so we can initialize a member even with __uninitialized_tag for constexpr-friendliness
};
_ALIGNAS_TYPE(_Tp) char __obj_[sizeof(_Tp)];
};

_LIBCPP_END_NAMESPACE_STD
Expand Down
11 changes: 11 additions & 0 deletions libcxx/modules/std/ranges.inc
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,17 @@ export namespace std {
#if _LIBCPP_STD_VER >= 23
// [range.adaptor.object], range adaptor objects
using std::ranges::range_adaptor_closure;
// Note: This declaration not in the synopsis or explicitly in the wording.
// However it is needed for the range adaptors.
// [range.adaptor.object]/3
// The template parameter D for range_adaptor_closure may be an
// incomplete type. If an expression of type cv D is used as an operand
// to the | operator, D shall be complete and model
// derived_from<range_adaptor_closure<D>>. The behavior of an expression
// involving an object of type cv D as an operand to the | operator is
// undefined if overload resolution selects a program-defined operator|
// function.
using std::ranges::operator|;
#endif

// [range.all], all view
Expand Down
1 change: 1 addition & 0 deletions libcxx/test/libcxx/transitive_includes/cxx20.csv
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ chrono cwchar
chrono forward_list
chrono limits
chrono locale
chrono new
chrono optional
chrono ostream
chrono ratio
Expand Down
31 changes: 31 additions & 0 deletions libcxx/test/libcxx/utilities/no_destroy.pass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include <__utility/no_destroy.h>
#include <cassert>

#include "test_macros.h"

#if TEST_STD_VER > 17
// Test constexpr-constructibility.
constinit std::__no_destroy<int> nd_int_const(std::__uninitialized_tag{});
#endif

struct DestroyLast {
~DestroyLast() { assert(*ptr == 5); }

int* ptr;
} last;

static std::__no_destroy<int> nd_int(5);

int main(int, char**) {
last.ptr = &nd_int.__get();

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14
// XFAIL: (clang || apple-clang) && stdlib=libc++
// UNSUPPORTED: (clang || apple-clang) && stdlib=libc++

#include <new>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,11 @@ constexpr void test_recursive() {
}

assert((in | std::ranges::to<C4>()) == result);

// LWG3984: ranges::to's recursion branch may be ill-formed
auto in_owning_view = std::views::all(std::move(in));
static_assert(!std::ranges::viewable_range<decltype((in_owning_view))>);
assert(std::ranges::to<C4>(in_owning_view) == result);
}

constexpr bool test() {
Expand Down
67 changes: 2 additions & 65 deletions lld/ELF/Arch/RISCV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1057,7 +1057,7 @@ class RISCVAttributesSection final : public SyntheticSection {
};
} // namespace

static void mergeArch(RISCVISAInfo::OrderedExtensionMap &mergedExts,
static void mergeArch(RISCVISAUtils::OrderedExtensionMap &mergedExts,
unsigned &mergedXlen, const InputSectionBase *sec,
StringRef s) {
auto maybeInfo = RISCVISAInfo::parseNormalizedArchString(s);
Expand All @@ -1084,62 +1084,10 @@ static void mergeArch(RISCVISAInfo::OrderedExtensionMap &mergedExts,
}
}

static void mergeAtomic(DenseMap<unsigned, unsigned>::iterator it,
const InputSectionBase *oldSection,
const InputSectionBase *newSection, unsigned int oldTag,
unsigned int newTag) {
using RISCVAttrs::RISCVAtomicAbiTag::AtomicABI;
// Same tags stay the same, and UNKNOWN is compatible with anything
if (oldTag == newTag || newTag == AtomicABI::UNKNOWN)
return;

switch (oldTag) {
case AtomicABI::UNKNOWN:
it->getSecond() = newTag;
return;
case AtomicABI::A6C:
switch (newTag) {
case AtomicABI::A6S:
it->getSecond() = AtomicABI::A6C;
return;
case AtomicABI::A7:
error(toString(oldSection) + " has atomic_abi=" + Twine(oldTag) +
" but " + toString(newSection) +
" has atomic_abi=" + Twine(newTag));
return;
};

case AtomicABI::A6S:
switch (newTag) {
case AtomicABI::A6C:
it->getSecond() = AtomicABI::A6C;
return;
case AtomicABI::A7:
it->getSecond() = AtomicABI::A7;
return;
};

case AtomicABI::A7:
switch (newTag) {
case AtomicABI::A6S:
it->getSecond() = AtomicABI::A7;
return;
case AtomicABI::A6C:
error(toString(oldSection) + " has atomic_abi=" + Twine(oldTag) +
" but " + toString(newSection) +
" has atomic_abi=" + Twine(newTag));
return;
};
default:
llvm_unreachable("unknown AtomicABI");
};
}

static RISCVAttributesSection *
mergeAttributesSection(const SmallVector<InputSectionBase *, 0> &sections) {
RISCVISAInfo::OrderedExtensionMap exts;
RISCVISAUtils::OrderedExtensionMap exts;
const InputSectionBase *firstStackAlign = nullptr;
const InputSectionBase *firstAtomicAbi = nullptr;
unsigned firstStackAlignValue = 0, xlen = 0;
bool hasArch = false;

Expand Down Expand Up @@ -1186,17 +1134,6 @@ mergeAttributesSection(const SmallVector<InputSectionBase *, 0> &sections) {
case RISCVAttrs::PRIV_SPEC_MINOR:
case RISCVAttrs::PRIV_SPEC_REVISION:
break;

case llvm::RISCVAttrs::AttrType::ATOMIC_ABI:
if (auto i = parser.getAttributeValue(tag.attr)) {
auto r = merged.intAttr.try_emplace(tag.attr, *i);
if (r.second) {
firstAtomicAbi = sec;
} else {
mergeAtomic(r.first, firstAtomicAbi, sec, r.first->getSecond(), *i);
}
}
continue;
}

// Fallback for deprecated priv_spec* and other unknown attributes: retain
Expand Down
4 changes: 2 additions & 2 deletions lld/test/ELF/mips-eh_frame-pic.s
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@
# RELOCS: .rel{{a?}}.eh_frame {
# ABS32-RELOCS-NEXT: 0x1C R_MIPS_32 .text
# ABS64-RELOCS-NEXT: 0x1C R_MIPS_64/R_MIPS_NONE/R_MIPS_NONE .text
# PIC64-RELOCS-NEXT: 0x1C R_MIPS_PC32/R_MIPS_NONE/R_MIPS_NONE <null>
# PIC32-RELOCS-NEXT: 0x1C R_MIPS_PC32 <null>
# PIC64-RELOCS-NEXT: 0x1C R_MIPS_PC32/R_MIPS_NONE/R_MIPS_NONE .L0
# PIC32-RELOCS-NEXT: 0x1C R_MIPS_PC32 .L0
# RELOCS-NEXT: }

# ABS64-EH-FRAME: Augmentation data: 0C
Expand Down
202 changes: 0 additions & 202 deletions lld/test/ELF/riscv-attributes.s
Original file line number Diff line number Diff line change
Expand Up @@ -44,39 +44,6 @@
# RUN: not ld.lld a.o b.o c.o diff_stack_align.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=STACK_ALIGN --implicit-check-not=error:
# STACK_ALIGN: error: diff_stack_align.o:(.riscv.attributes) has stack_align=32 but a.o:(.riscv.attributes) has stack_align=16

## merging atomic_abi values for A6C and A7 lead to an error.
# RUN: llvm-mc -filetype=obj -triple=riscv64 atomic_abi_A6C.s -o atomic_abi_A6C.o
# RUN: llvm-mc -filetype=obj -triple=riscv64 atomic_abi_A7.s -o atomic_abi_A7.o
# RUN: not ld.lld atomic_abi_A6C.o atomic_abi_A7.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=ATOMIC_ABI_ERROR --implicit-check-not=error:
# ATOMIC_ABI_ERROR: error: atomic_abi_A6C.o:(.riscv.attributes) has atomic_abi=1 but atomic_abi_A7.o:(.riscv.attributes) has atomic_abi=3


# RUN: llvm-mc -filetype=obj -triple=riscv64 atomic_abi_A6S.s -o atomic_abi_A6S.o
# RUN: ld.lld atomic_abi_A6S.o atomic_abi_A6C.o -o atomic_abi_A6C_A6S
# RUN: llvm-readobj -A atomic_abi_A6C_A6S | FileCheck %s --check-prefix=A6C_A6S

# RUN: ld.lld atomic_abi_A6S.o atomic_abi_A7.o -o atomic_abi_A6S_A7
# RUN: llvm-readobj -A atomic_abi_A6S_A7 | FileCheck %s --check-prefix=A6S_A7

# RUN: llvm-mc -filetype=obj -triple=riscv64 atomic_abi_unknown.s -o atomic_abi_unknown.o
# RUN: ld.lld atomic_abi_unknown.o atomic_abi_A6C.o -o atomic_abi_A6C_unknown
# RUN: llvm-readobj -A atomic_abi_A6C_unknown | FileCheck %s --check-prefixes=UNKNOWN_A6C

# RUN: ld.lld atomic_abi_unknown.o diff_stack_align.o -o atomic_abi_none_unknown
# RUN: llvm-readobj -A atomic_abi_none_unknown | FileCheck %s --check-prefixes=UNKNOWN_NONE

# RUN: ld.lld diff_stack_align.o atomic_abi_A6C.o -o atomic_abi_A6C_none
# RUN: llvm-readobj -A atomic_abi_A6C_none | FileCheck %s --check-prefixes=NONE_A6C

# RUN: ld.lld atomic_abi_unknown.o atomic_abi_A6S.o -o atomic_abi_A6S_unknown
# RUN: llvm-readobj -A atomic_abi_A6S_unknown | FileCheck %s --check-prefix=UNKNOWN_A6S

# RUN: ld.lld atomic_abi_unknown.o atomic_abi_A7.o -o atomic_abi_A7_unknown
# RUN: llvm-readobj -A atomic_abi_A7_unknown | FileCheck %s --check-prefix=UNKNOWN_A7

# RUN: ld.lld diff_stack_align.o atomic_abi_A7.o -o atomic_abi_A7_none
# RUN: llvm-readobj -A atomic_abi_A7_none | FileCheck %s --check-prefix=NONE_A7

## The deprecated priv_spec is not handled as GNU ld does.
## Differing priv_spec attributes lead to an absent attribute.
# RUN: llvm-mc -filetype=obj -triple=riscv64 diff_priv_spec.s -o diff_priv_spec.o
Expand Down Expand Up @@ -319,175 +286,6 @@
.attribute priv_spec, 3
.attribute priv_spec_minor, 3

#--- atomic_abi_unknown.s
.attribute atomic_abi, 0

#--- atomic_abi_A6C.s
.attribute atomic_abi, 1

#--- atomic_abi_A6S.s
.attribute atomic_abi, 2

#--- atomic_abi_A7.s
.attribute atomic_abi, 3

# UNKNOWN_NONE: BuildAttributes {
# UNKNOWN_NONE-NEXT: FormatVersion: 0x41
# UNKNOWN_NONE-NEXT: Section 1 {
# UNKNOWN_NONE-NEXT: SectionLength: 17
# UNKNOWN_NONE-NEXT: Vendor: riscv
# UNKNOWN_NONE-NEXT: Tag: Tag_File (0x1)
# UNKNOWN_NONE-NEXT: Size: 7
# UNKNOWN_NONE-NEXT: FileAttributes {
# UNKNOWN_NONE-NEXT: Attribute {
# UNKNOWN_NONE-NEXT: Tag: 4
# UNKNOWN_NONE-NEXT: Value: 32
# UNKNOWN_NONE-NEXT: TagName: stack_align
# UNKNOWN_NONE-NEXT: Description: Stack alignment is 32-bytes
# UNKNOWN_NONE-NEXT: }
# UNKNOWN_NONE-NEXT: }
# UNKNOWN_NONE-NEXT: }
# UNKNOWN_NONE-NEXT: }

# NONE_A6C: BuildAttributes {
# NONE_A6C-NEXT: FormatVersion: 0x41
# NONE_A6C-NEXT: Section 1 {
# NONE_A6C-NEXT: SectionLength: 19
# NONE_A6C-NEXT: Vendor: riscv
# NONE_A6C-NEXT: Tag: Tag_File (0x1)
# NONE_A6C-NEXT: Size: 9
# NONE_A6C-NEXT: FileAttributes {
# NONE_A6C-NEXT: Attribute {
# NONE_A6C-NEXT: Tag: 14
# NONE_A6C-NEXT: Value: 1
# NONE_A6C-NEXT: TagName: atomic_abi
# NONE_A6C-NEXT: Description: Atomic ABI is 1
# NONE_A6C-NEXT: }
# NONE_A6C-NEXT: Attribute {
# NONE_A6C-NEXT: Tag: 4
# NONE_A6C-NEXT: Value: 32
# NONE_A6C-NEXT: TagName: stack_align
# NONE_A6C-NEXT: Description: Stack alignment is 32-bytes
# NONE_A6C-NEXT: }
# NONE_A6C-NEXT: }
# NONE_A6C-NEXT: }
# NONE_A6C-NEXT: }

# UNKNOWN_A6C: BuildAttributes {
# UNKNOWN_A6C-NEXT: FormatVersion: 0x41
# UNKNOWN_A6C-NEXT: Section 1 {
# UNKNOWN_A6C-NEXT: SectionLength: 17
# UNKNOWN_A6C-NEXT: Vendor: riscv
# UNKNOWN_A6C-NEXT: Tag: Tag_File (0x1)
# UNKNOWN_A6C-NEXT: Size: 7
# UNKNOWN_A6C-NEXT: FileAttributes {
# UNKNOWN_A6C-NEXT: Attribute {
# UNKNOWN_A6C-NEXT: Tag: 14
# UNKNOWN_A6C-NEXT: Value: 1
# UNKNOWN_A6C-NEXT: TagName: atomic_abi
# UNKNOWN_A6C-NEXT: Description: Atomic ABI is 1
# UNKNOWN_A6C-NEXT: }
# UNKNOWN_A6C-NEXT: }
# UNKNOWN_A6C-NEXT: }
# UNKNOWN_A6C-NEXT: }

# UNKNOWN_A6S: BuildAttributes {
# UNKNOWN_A6S-NEXT: FormatVersion: 0x41
# UNKNOWN_A6S-NEXT: Section 1 {
# UNKNOWN_A6S-NEXT: SectionLength:
# UNKNOWN_A6S-NEXT: Vendor: riscv
# UNKNOWN_A6S-NEXT: Tag: Tag_File (0x1)
# UNKNOWN_A6S-NEXT: Size: 7
# UNKNOWN_A6S-NEXT: FileAttributes {
# UNKNOWN_A6S-NEXT: Attribute {
# UNKNOWN_A6S-NEXT: Tag: 14
# UNKNOWN_A6S-NEXT: Value: 2
# UNKNOWN_A6S-NEXT: TagName: atomic_abi
# UNKNOWN_A6S-NEXT: Description: Atomic ABI is 2
# UNKNOWN_A6S-NEXT: }
# UNKNOWN_A6S-NEXT: }
# UNKNOWN_A6S-NEXT: }
# UNKNOWN_A6S-NEXT: }

# NONE_A7: BuildAttributes {
# NONE_A7-NEXT: FormatVersion: 0x41
# NONE_A7-NEXT: Section 1 {
# NONE_A7-NEXT: SectionLength: 19
# NONE_A7-NEXT: Vendor: riscv
# NONE_A7-NEXT: Tag: Tag_File (0x1)
# NONE_A7-NEXT: Size: 9
# NONE_A7-NEXT: FileAttributes {
# NONE_A7-NEXT: Attribute {
# NONE_A7-NEXT: Tag: 14
# NONE_A7-NEXT: Value: 3
# NONE_A7-NEXT: TagName: atomic_abi
# NONE_A7-NEXT: Description: Atomic ABI is 3
# NONE_A7-NEXT: }
# NONE_A7-NEXT: Attribute {
# NONE_A7-NEXT: Tag: 4
# NONE_A7-NEXT: Value: 32
# NONE_A7-NEXT: TagName: stack_align
# NONE_A7-NEXT: Description: Stack alignment is 32-bytes
# NONE_A7-NEXT: }
# NONE_A7-NEXT: }
# NONE_A7-NEXT: }
# NONE_A7-NEXT: }


# UNKNOWN_A7: BuildAttributes {
# UNKNOWN_A7-NEXT: FormatVersion: 0x41
# UNKNOWN_A7-NEXT: Section 1 {
# UNKNOWN_A7-NEXT: SectionLength: 17
# UNKNOWN_A7-NEXT: Vendor: riscv
# UNKNOWN_A7-NEXT: Tag: Tag_File (0x1)
# UNKNOWN_A7-NEXT: Size: 7
# UNKNOWN_A7-NEXT: FileAttributes {
# UNKNOWN_A7-NEXT: Attribute {
# UNKNOWN_A7-NEXT: Tag: 14
# UNKNOWN_A7-NEXT: Value: 3
# UNKNOWN_A7-NEXT: TagName: atomic_abi
# UNKNOWN_A7-NEXT: Description: Atomic ABI is 3
# UNKNOWN_A7-NEXT: }
# UNKNOWN_A7-NEXT: }
# UNKNOWN_A7-NEXT: }
# UNKNOWN_A7-NEXT: }

# A6C_A6S: BuildAttributes {
# A6C_A6S-NEXT: FormatVersion: 0x41
# A6C_A6S-NEXT: Section 1 {
# A6C_A6S-NEXT: SectionLength: 17
# A6C_A6S-NEXT: Vendor: riscv
# A6C_A6S-NEXT: Tag: Tag_File (0x1)
# A6C_A6S-NEXT: Size: 7
# A6C_A6S-NEXT: FileAttributes {
# A6C_A6S-NEXT: Attribute {
# A6C_A6S-NEXT: Tag: 14
# A6C_A6S-NEXT: Value: 1
# A6C_A6S-NEXT: TagName: atomic_abi
# A6C_A6S-NEXT: Description: Atomic ABI is 1
# A6C_A6S-NEXT: }
# A6C_A6S-NEXT: }
# A6C_A6S-NEXT: }
# A6C_A6S-NEXT: }

# A6S_A7: BuildAttributes {
# A6S_A7-NEXT: FormatVersion: 0x41
# A6S_A7-NEXT: Section 1 {
# A6S_A7-NEXT: SectionLength: 17
# A6S_A7-NEXT: Vendor: riscv
# A6S_A7-NEXT: Tag: Tag_File (0x1)
# A6S_A7-NEXT: Size: 7
# A6S_A7-NEXT: FileAttributes {
# A6S_A7-NEXT: Attribute {
# A6S_A7-NEXT: Tag: 14
# A6S_A7-NEXT: Value: 3
# A6S_A7-NEXT: TagName: atomic_abi
# A6S_A7-NEXT: Description: Atomic ABI is 3
# A6S_A7-NEXT: }
# A6S_A7-NEXT: }
# A6S_A7-NEXT: }
# A6S_A7-NEXT: }

#--- unknown13.s
.attribute 13, "0"
#--- unknown13a.s
Expand Down
16 changes: 8 additions & 8 deletions lld/test/ELF/riscv-branch.s
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@
# RUN: ld.lld %t.rv64.o --defsym foo=_start+4 --defsym bar=_start -o %t.rv64
# RUN: llvm-objdump -d %t.rv32 | FileCheck %s --check-prefix=CHECK-32
# RUN: llvm-objdump -d %t.rv64 | FileCheck %s --check-prefix=CHECK-64
# CHECK-32: 63 02 00 00 beqz zero, 0x110b8
# CHECK-32: e3 1e 00 fe bnez zero, 0x110b4
# CHECK-64: 63 02 00 00 beqz zero, 0x11124
# CHECK-64: e3 1e 00 fe bnez zero, 0x11120
# CHECK-32: 00000263 beqz zero, 0x110b8
# CHECK-32: fe001ee3 bnez zero, 0x110b4
# CHECK-64: 00000263 beqz zero, 0x11124
# CHECK-64: fe001ee3 bnez zero, 0x11120
#
# RUN: ld.lld %t.rv32.o --defsym foo=_start+0xffe --defsym bar=_start+4-0x1000 -o %t.rv32.limits
# RUN: ld.lld %t.rv64.o --defsym foo=_start+0xffe --defsym bar=_start+4-0x1000 -o %t.rv64.limits
# RUN: llvm-objdump -d %t.rv32.limits | FileCheck --check-prefix=LIMITS-32 %s
# RUN: llvm-objdump -d %t.rv64.limits | FileCheck --check-prefix=LIMITS-64 %s
# LIMITS-32: e3 0f 00 7e beqz zero, 0x120b2
# LIMITS-32-NEXT: 63 10 00 80 bnez zero, 0x100b8
# LIMITS-64: e3 0f 00 7e beqz zero, 0x1211e
# LIMITS-64-NEXT: 63 10 00 80 bnez zero, 0x10124
# LIMITS-32: 7e000fe3 beqz zero, 0x120b2
# LIMITS-32-NEXT: 80001063 bnez zero, 0x100b8
# LIMITS-64: 7e000fe3 beqz zero, 0x1211e
# LIMITS-64-NEXT: 80001063 bnez zero, 0x10124

# RUN: not ld.lld %t.rv32.o --defsym foo=_start+0x1000 --defsym bar=_start+4-0x1002 -o /dev/null 2>&1 | FileCheck --check-prefix=ERROR-RANGE %s
# RUN: not ld.lld %t.rv64.o --defsym foo=_start+0x1000 --defsym bar=_start+4-0x1002 -o /dev/null 2>&1 | FileCheck --check-prefix=ERROR-RANGE %s
Expand Down
16 changes: 8 additions & 8 deletions lld/test/ELF/riscv-call.s
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@
# RUN: ld.lld %t.rv64.o --defsym foo=_start+8 --defsym bar=_start -o %t.rv64
# RUN: llvm-objdump -d %t.rv32 | FileCheck %s
# RUN: llvm-objdump -d %t.rv64 | FileCheck %s
# CHECK: 97 00 00 00 auipc ra, 0x0
# CHECK-NEXT: e7 80 80 00 jalr 0x8(ra)
# CHECK: 97 00 00 00 auipc ra, 0x0
# CHECK-NEXT: e7 80 80 ff jalr -0x8(ra)
# CHECK: 00000097 auipc ra, 0x0
# CHECK-NEXT: 008080e7 jalr 0x8(ra)
# CHECK: 00000097 auipc ra, 0x0
# CHECK-NEXT: ff8080e7 jalr -0x8(ra)

# RUN: ld.lld %t.rv32.o --defsym foo=_start+0x7ffff7ff --defsym bar=_start+8-0x80000800 -o %t.rv32.limits
# RUN: ld.lld %t.rv64.o --defsym foo=_start+0x7ffff7ff --defsym bar=_start+8-0x80000800 -o %t.rv64.limits
# RUN: llvm-objdump -d %t.rv32.limits | FileCheck --check-prefix=LIMITS %s
# RUN: llvm-objdump -d %t.rv64.limits | FileCheck --check-prefix=LIMITS %s
# LIMITS: 97 f0 ff 7f auipc ra, 0x7ffff
# LIMITS-NEXT: e7 80 f0 7f jalr 0x7ff(ra)
# LIMITS-NEXT: 97 00 00 80 auipc ra, 0x80000
# LIMITS-NEXT: e7 80 00 80 jalr -0x800(ra)
# LIMITS: 7ffff097 auipc ra, 0x7ffff
# LIMITS-NEXT: 7ff080e7 jalr 0x7ff(ra)
# LIMITS-NEXT: 80000097 auipc ra, 0x80000
# LIMITS-NEXT: 800080e7 jalr -0x800(ra)

# RUN: ld.lld %t.rv32.o --defsym foo=_start+0x7ffff800 --defsym bar=_start+8-0x80000801 -o %t
# RUN: not ld.lld %t.rv64.o --defsym foo=_start+0x7ffff800 --defsym bar=_start+8-0x80000801 -o /dev/null 2>&1 | \
Expand Down
24 changes: 12 additions & 12 deletions lld/test/ELF/riscv-hi20-lo12.s
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,23 @@
# RUN: ld.lld %t.rv64.o --defsym foo=0 --defsym bar=42 -o %t.rv64
# RUN: llvm-objdump -d %t.rv32 | FileCheck %s
# RUN: llvm-objdump -d %t.rv64 | FileCheck %s
# CHECK: 37 05 00 00 lui a0, 0x0
# CHECK-NEXT: 13 05 05 00 mv a0, a0
# CHECK-NEXT: 23 20 a5 00 sw a0, 0x0(a0)
# CHECK-NEXT: b7 05 00 00 lui a1, 0x0
# CHECK-NEXT: 93 85 a5 02 addi a1, a1, 0x2a
# CHECK-NEXT: 23 a5 b5 02 sw a1, 0x2a(a1)
# CHECK: 00000537 lui a0, 0x0
# CHECK-NEXT: 00050513 mv a0, a0
# CHECK-NEXT: 00a52023 sw a0, 0x0(a0)
# CHECK-NEXT: 000005b7 lui a1, 0x0
# CHECK-NEXT: 02a58593 addi a1, a1, 0x2a
# CHECK-NEXT: 02b5a523 sw a1, 0x2a(a1)

# RUN: ld.lld %t.rv32.o --defsym foo=0x7ffff7ff --defsym bar=0x7ffff800 -o %t.rv32.limits
# RUN: ld.lld %t.rv64.o --defsym foo=0x7ffff7ff --defsym bar=0xffffffff7ffff800 -o %t.rv64.limits
# RUN: llvm-objdump -d %t.rv32.limits | FileCheck --check-prefix=LIMITS %s
# RUN: llvm-objdump -d %t.rv64.limits | FileCheck --check-prefix=LIMITS %s
# LIMITS: 37 f5 ff 7f lui a0, 0x7ffff
# LIMITS-NEXT: 13 05 f5 7f addi a0, a0, 0x7ff
# LIMITS-NEXT: a3 2f a5 7e sw a0, 0x7ff(a0)
# LIMITS-NEXT: b7 05 00 80 lui a1, 0x80000
# LIMITS-NEXT: 93 85 05 80 addi a1, a1, -0x800
# LIMITS-NEXT: 23 a0 b5 80 sw a1, -0x800(a1)
# LIMITS: 7ffff537 lui a0, 0x7ffff
# LIMITS-NEXT: 7ff50513 addi a0, a0, 0x7ff
# LIMITS-NEXT: 7ea52fa3 sw a0, 0x7ff(a0)
# LIMITS-NEXT: 800005b7 lui a1, 0x80000
# LIMITS-NEXT: 80058593 addi a1, a1, -0x800
# LIMITS-NEXT: 80b5a023 sw a1, -0x800(a1)

# RUN: not ld.lld %t.rv64.o --defsym foo=0x7ffff800 --defsym bar=0xffffffff7ffff7ff -o /dev/null 2>&1 | FileCheck --check-prefix ERROR %s
# ERROR: relocation R_RISCV_HI20 out of range: 524288 is not in [-524288, 524287]; references 'foo'
Expand Down
16 changes: 8 additions & 8 deletions lld/test/ELF/riscv-jal.s
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@
# RUN: ld.lld %t.rv64.o --defsym foo=_start+4 --defsym bar=_start -o %t.rv64
# RUN: llvm-objdump -d %t.rv32 | FileCheck %s --check-prefix=CHECK-32
# RUN: llvm-objdump -d %t.rv64 | FileCheck %s --check-prefix=CHECK-64
# CHECK-32: 6f 00 40 00 j 0x110b8
# CHECK-32: ef f0 df ff jal 0x110b4
# CHECK-64: 6f 00 40 00 j 0x11124
# CHECK-64: ef f0 df ff jal 0x11120
# CHECK-32: 0040006f j 0x110b8
# CHECK-32: ffdff0ef jal 0x110b4
# CHECK-64: 0040006f j 0x11124
# CHECK-64: ffdff0ef jal 0x11120

# RUN: ld.lld %t.rv32.o --defsym foo=_start+0xffffe --defsym bar=_start+4-0x100000 -o %t.rv32.limits
# RUN: ld.lld %t.rv64.o --defsym foo=_start+0xffffe --defsym bar=_start+4-0x100000 -o %t.rv64.limits
# RUN: llvm-objdump -d %t.rv32.limits | FileCheck --check-prefix=LIMITS-32 %s
# RUN: llvm-objdump -d %t.rv64.limits | FileCheck --check-prefix=LIMITS-64 %s
# LIMITS-32: 6f f0 ff 7f j 0x1110b2
# LIMITS-32-NEXT: ef 00 00 80 jal 0xfff110b8
# LIMITS-64: 6f f0 ff 7f j 0x11111e
# LIMITS-64-NEXT: ef 00 00 80 jal 0xfffffffffff11124
# LIMITS-32: 7ffff06f j 0x1110b2
# LIMITS-32-NEXT: 800000ef jal 0xfff110b8
# LIMITS-64: 7ffff06f j 0x11111e
# LIMITS-64-NEXT: 800000ef jal 0xfffffffffff11124

# RUN: not ld.lld %t.rv32.o --defsym foo=_start+0x100000 --defsym bar=_start+4-0x100002 -o /dev/null 2>&1 | FileCheck --check-prefix=ERROR-RANGE %s
# RUN: not ld.lld %t.rv64.o --defsym foo=_start+0x100000 --defsym bar=_start+4-0x100002 -o /dev/null 2>&1 | FileCheck --check-prefix=ERROR-RANGE %s
Expand Down
2 changes: 1 addition & 1 deletion lld/test/wasm/init-fini.ll
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ entry:
; CHECK-NEXT: Body: 10041005100A100F1012100F10141004100C100F10161002100E0B
; CHECK: - Index: 22
; CHECK-NEXT: Locals:
; CHECK-NEXT: Body: 02404186808080004100418088808000108080808000450D0000000B0B
; CHECK-NEXT: Body: 02404186808080004100418088808000108080808000450D00000B0B
; CHECK-NEXT: - Type: CUSTOM
; CHECK-NEXT: Name: name
; CHECK-NEXT: FunctionNames:
Expand Down
269 changes: 268 additions & 1 deletion lldb/docs/resources/lldbgdbremote.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,21 @@ The above packet helps when you have remote debugging abilities where you
could launch a process on a remote host, this isn't needed for bare board
debugging.

## qLaunchSuccess

### Brief

Check whether launching a process with the `A` packet succeeded.

### Description

Returns the status of the last attempt to launch a process.
Either `OK` if no error ocurred, or `E` followed by a string
describing the error.

### Priority To Implement

High, launching processes is a key part of LLDB's platform mode.

## QEnvironment:NAME=VALUE

Expand Down Expand Up @@ -263,6 +278,20 @@ QSetWorkingDir:<ascii-hex-path>
```
This packet must be sent _prior_ to sending a "A" packet.

## qGetWorkingDir

### Brief

Get the current working directory of the platform stub in
ASCII hex encoding.

### Example

```
receive: qGetWorkingDir
send: 2f4170706c65496e7465726e616c2f6c6c64622f73657474696e67732f342f5465737453657474696e67732e746573745f646973617373656d626c65725f73657474696e6773
```

## QSetDisableASLR:\<bool\>

### Brief
Expand Down Expand Up @@ -1029,13 +1058,17 @@ a remote host.
Request: `qPlatform_mkdir:<hex-file-mode>,<ascii-hex-path>`
The request packet has the fields:
1. mode bits in base 16
2. file path in ascii-hex encoding
Reply:
* `F<mkdir-return-code>`
(mkdir called successfully and returned with the given return code)
* `Exx` (An error occurred)
## qPlatform_chmod
## vFile:chmod / qPlatform_chmod
### Brief
Expand Down Expand Up @@ -1900,6 +1933,43 @@ send packet: $qsProcessInfo#00
read packet: $E04#00
```
## qPathComplete (Platform Extension)
### Brief
Get a list of matched disk files/directories by passing a boolean flag
and a partial path.
### Example
```
receive: qPathComplete:0,6d61696e
send: M6d61696e2e637070
receive: qPathComplete:1,746573
send: M746573742f,74657374732f
```
If the first argument is zero, the result should contain all
files (including directories) starting with the given path. If the
argument is one, the result should contain only directories.
The result should be a comma-separated list of hex-encoded paths.
Paths denoting a directory should end with a directory separator (`/` or `\`.
## qKillSpawnedProcess (Platform Extension)
### Brief
Kill a process running on the target system.
### Example
```
receive: qKillSpawnedProcess:1337
send: OK
```
The request packet has the process ID in base 10.
## qLaunchGDBServer (Platform Extension)
### Brief
Expand Down Expand Up @@ -2397,3 +2467,200 @@ STUB REPLIES: {"process_state_value":48,"process_state string":"dyld_process_sta
Low. This packet is needed to prevent lldb's utility functions for
scanning the Objective-C class list from running very early in
process startup.
## vFile Packets
Though some of these may match the ones described in GDB's protocol
documentation, we include our own expectations here in case of
mismatches or extensions.
### vFile:size
#### Brief
Get the size of a file on the target system, filename in ASCII hex.
#### Example
```
receive: vFile:size:2f746d702f61
send: Fc008
```
response is `F` followed by the file size in base 16.
`F-1,errno` with the errno if an error occurs, base 16.
### vFile:mode
#### Brief
Get the mode bits of a file on the target system, filename in ASCII hex.
#### Example
```
receive: vFile:mode:2f746d702f61
send: F1ed
```
response is `F` followed by the mode bits in base 16, this `0x1ed` would
correspond to `0755` in octal.
`F-1,errno` with the errno if an error occurs, base 16.
### vFile:unlink
#### Brief
Remove a file on the target system.
#### Example
```
receive: vFile:unlink:2f746d702f61
send: F0
```
Argument is a file path in ascii-hex encoding.
Response is `F` plus the return value of `unlink()`, base 16 encoding.
Return value may optionally be followed by a comma and the base16
value of errno if unlink failed.
### vFile:symlink
#### Brief
Create a symbolic link (symlink, soft-link) on the target system.
#### Example
```
receive: vFile:symlink:<SRC-FILE>,<DST-NAME>
send: F0,0
```
Argument file paths are in ascii-hex encoding.
Response is `F` plus the return value of `symlink()`, base 16 encoding,
optionally followed by the value of errno if it failed, also base 16.
### vFile:open
#### Brief
Open a file on the remote system and return the file descriptor of it.
#### Example
```
receive: vFile:open:2f746d702f61,00000001,00000180
send: F8
```
request packet has the fields:
1. ASCII hex encoded filename
2. Flags passed to the open call, base 16.
Note that these are not the `oflags` that `open(2)` takes, but
are the constant values in `enum OpenOptions` from LLDB's
[`File.h`](https://github.com/llvm/llvm-project/blob/main/lldb/include/lldb/Host/File.h).
3. Mode bits, base 16
response is `F` followed by the opened file descriptor in base 16.
`F-1,errno` with the errno if an error occurs, base 16.
### vFile:close
#### Brief
Close a previously opened file descriptor.
#### Example
```
receive: vFile:close:7
send: F0
```
File descriptor is in base 16. `F-1,errno` with the errno if an error occurs,
errno is base 16.
### vFile:pread
#### Brief
Read data from an opened file descriptor.
#### Example
```
receive: vFile:pread:7,1024,0
send: F4;a'b\00
```
Request packet has the fields:
1. File descriptor, base 16
2. Number of bytes to be read, base 16
3. Offset into file to start from, base 16
Response is `F`, followed by the number of bytes read (base 16), a
semicolon, followed by the data in the binary-escaped-data encoding.
### vFile:pwrite
#### Brief
Write data to a previously opened file descriptor.
#### Example
```
receive: vFile:pwrite:8,0,\cf\fa\ed\fe\0c\00\00
send: F1024
```
Request packet has the fields:
1. File descriptor, base 16
2. Offset into file to start from, base 16
3. binary-escaped-data to be written
Response is `F`, followed by the number of bytes written (base 16).
### vFile:MD5
#### Brief
Generate an MD5 hash of the file at the given path.
#### Example
```
receive: vFile:MD5:2f746d702f61
send (success): F,00000000000000001111111111111111
send (failure): F,x
```
Request packet contains the ASCII hex encoded filename.
If the hash succeeded, the response is `F,` followed by the low 64
bits of the result, and finally the high 64 bits of the result. Both are in
hex format without a prefix.
The response is `F,`, followed by `x` if the file did not exist
or failed to hash.
### vFile:exists
#### Brief
Check whether the file at the given path exists.
#### Example
```
receive: vFile:exists:2f746d702f61
send (exists): F,1
send (does not exist): F,0
```
Request packet contains the ASCII hex encoded filename.
The response is a return code where 1 means the file exists
and 0 means it does not.
513 changes: 39 additions & 474 deletions lldb/docs/resources/lldbplatformpackets.md

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions lldb/include/lldb/API/SBDebugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ class LLDB_API SBInputReader {

class LLDB_API SBDebugger {
public:
FLAGS_ANONYMOUS_ENUM(){
eBroadcastBitProgress = lldb::DebuggerBroadcastBit::eBroadcastBitProgress,
eBroadcastBitWarning = lldb::DebuggerBroadcastBit::eBroadcastBitWarning,
eBroadcastBitError = lldb::DebuggerBroadcastBit::eBroadcastBitError,
eBroadcastBitProgressCategory =
lldb::DebuggerBroadcastBit::eBroadcastBitProgressCategory,
};
SBDebugger();

SBDebugger(const lldb::SBDebugger &rhs);
Expand Down
2 changes: 1 addition & 1 deletion lldb/include/lldb/Utility/ProcessInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ class ProcessInstanceInfo : public ProcessInfo {

bool CumulativeSystemTimeIsValid() const {
return m_cumulative_system_time.tv_sec > 0 ||
m_cumulative_system_time.tv_sec > 0;
m_cumulative_system_time.tv_usec > 0;
}

void Dump(Stream &s, UserIDResolver &resolver) const;
Expand Down
2 changes: 1 addition & 1 deletion lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class DWARFCompileUnit : public DWARFUnit {

private:
DWARFCompileUnit(SymbolFileDWARF &dwarf, lldb::user_id_t uid,
const DWARFUnitHeader &header,
const llvm::DWARFUnitHeader &header,
const llvm::DWARFAbbreviationDeclarationSet &abbrevs,
DIERef::Section section, bool is_dwo)
: DWARFUnit(dwarf, uid, header, abbrevs, section, is_dwo) {}
Expand Down
6 changes: 3 additions & 3 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ class DWARFTypeUnit : public DWARFUnit {

void Dump(Stream *s) const override;

uint64_t GetTypeHash() { return m_header.GetTypeHash(); }
uint64_t GetTypeHash() { return m_header.getTypeHash(); }

dw_offset_t GetTypeOffset() { return GetOffset() + m_header.GetTypeOffset(); }
dw_offset_t GetTypeOffset() { return GetOffset() + m_header.getTypeOffset(); }

static bool classof(const DWARFUnit *unit) { return unit->IsTypeUnit(); }

private:
DWARFTypeUnit(SymbolFileDWARF &dwarf, lldb::user_id_t uid,
const DWARFUnitHeader &header,
const llvm::DWARFUnitHeader &header,
const llvm::DWARFAbbreviationDeclarationSet &abbrevs,
DIERef::Section section, bool is_dwo)
: DWARFUnit(dwarf, uid, header, abbrevs, section, is_dwo) {}
Expand Down
137 changes: 34 additions & 103 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ using namespace lldb_private::plugin::dwarf;
extern int g_verbose;

DWARFUnit::DWARFUnit(SymbolFileDWARF &dwarf, lldb::user_id_t uid,
const DWARFUnitHeader &header,
const llvm::DWARFUnitHeader &header,
const llvm::DWARFAbbreviationDeclarationSet &abbrevs,
DIERef::Section section, bool is_dwo)
: UserID(uid), m_dwarf(dwarf), m_header(header), m_abbrevs(&abbrevs),
m_cancel_scopes(false), m_section(section), m_is_dwo(is_dwo),
m_has_parsed_non_skeleton_unit(false), m_dwo_id(header.GetDWOId()) {}
m_has_parsed_non_skeleton_unit(false), m_dwo_id(header.getDWOId()) {}

DWARFUnit::~DWARFUnit() = default;

Expand Down Expand Up @@ -345,7 +345,7 @@ void DWARFUnit::ExtractDIEsRWLocked() {
void DWARFUnit::SetDwoStrOffsetsBase() {
lldb::offset_t baseOffset = 0;

if (const llvm::DWARFUnitIndex::Entry *entry = m_header.GetIndexEntry()) {
if (const llvm::DWARFUnitIndex::Entry *entry = m_header.getIndexEntry()) {
if (const auto *contribution =
entry->getContribution(llvm::DW_SECT_STR_OFFSETS))
baseOffset = contribution->getOffset();
Expand Down Expand Up @@ -489,7 +489,7 @@ ParseListTableHeader(const llvm::DWARFDataExtractor &data, uint64_t offset,

void DWARFUnit::SetLoclistsBase(dw_addr_t loclists_base) {
uint64_t offset = 0;
if (const llvm::DWARFUnitIndex::Entry *entry = m_header.GetIndexEntry()) {
if (const llvm::DWARFUnitIndex::Entry *entry = m_header.getIndexEntry()) {
const auto *contribution = entry->getContribution(llvm::DW_SECT_LOCLISTS);
if (!contribution) {
GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
Expand Down Expand Up @@ -533,7 +533,7 @@ DWARFDataExtractor DWARFUnit::GetLocationData() const {
DWARFContext &Ctx = GetSymbolFileDWARF().GetDWARFContext();
const DWARFDataExtractor &data =
GetVersion() >= 5 ? Ctx.getOrLoadLocListsData() : Ctx.getOrLoadLocData();
if (const llvm::DWARFUnitIndex::Entry *entry = m_header.GetIndexEntry()) {
if (const llvm::DWARFUnitIndex::Entry *entry = m_header.getIndexEntry()) {
if (const auto *contribution = entry->getContribution(
GetVersion() >= 5 ? llvm::DW_SECT_LOCLISTS : llvm::DW_SECT_EXT_LOC))
return DWARFDataExtractor(data, contribution->getOffset(),
Expand All @@ -546,7 +546,7 @@ DWARFDataExtractor DWARFUnit::GetLocationData() const {
DWARFDataExtractor DWARFUnit::GetRnglistData() const {
DWARFContext &Ctx = GetSymbolFileDWARF().GetDWARFContext();
const DWARFDataExtractor &data = Ctx.getOrLoadRngListsData();
if (const llvm::DWARFUnitIndex::Entry *entry = m_header.GetIndexEntry()) {
if (const llvm::DWARFUnitIndex::Entry *entry = m_header.getIndexEntry()) {
if (const auto *contribution =
entry->getContribution(llvm::DW_SECT_RNGLISTS))
return DWARFDataExtractor(data, contribution->getOffset(),
Expand Down Expand Up @@ -924,111 +924,42 @@ const DWARFDebugAranges &DWARFUnit::GetFunctionAranges() {
return *m_func_aranges_up;
}

llvm::Error DWARFUnitHeader::ApplyIndexEntry(
const llvm::DWARFUnitIndex::Entry *index_entry) {
// We should only be calling this function when the index entry is not set and
// we have a valid one to set it to.
assert(index_entry);
assert(!m_index_entry);

if (m_abbr_offset)
return llvm::createStringError(
llvm::inconvertibleErrorCode(),
"Package unit with a non-zero abbreviation offset");

auto *unit_contrib = index_entry->getContribution();
if (!unit_contrib || unit_contrib->getLength32() != m_length + 4)
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"Inconsistent DWARF package unit index");

auto *abbr_entry = index_entry->getContribution(llvm::DW_SECT_ABBREV);
if (!abbr_entry)
return llvm::createStringError(
llvm::inconvertibleErrorCode(),
"DWARF package index missing abbreviation column");

m_abbr_offset = abbr_entry->getOffset();
m_index_entry = index_entry;
return llvm::Error::success();
}

llvm::Expected<DWARFUnitHeader>
DWARFUnitHeader::extract(const DWARFDataExtractor &data,
DIERef::Section section, DWARFContext &context,
lldb::offset_t *offset_ptr) {
DWARFUnitHeader header;
header.m_offset = *offset_ptr;
header.m_length = data.GetDWARFInitialLength(offset_ptr);
header.m_version = data.GetU16(offset_ptr);
if (header.m_version == 5) {
header.m_unit_type = data.GetU8(offset_ptr);
header.m_addr_size = data.GetU8(offset_ptr);
header.m_abbr_offset = data.GetDWARFOffset(offset_ptr);
if (header.m_unit_type == llvm::dwarf::DW_UT_skeleton ||
header.m_unit_type == llvm::dwarf::DW_UT_split_compile)
header.m_dwo_id = data.GetU64(offset_ptr);
} else {
header.m_abbr_offset = data.GetDWARFOffset(offset_ptr);
header.m_addr_size = data.GetU8(offset_ptr);
header.m_unit_type =
section == DIERef::Section::DebugTypes ? DW_UT_type : DW_UT_compile;
}

if (header.IsTypeUnit()) {
header.m_type_hash = data.GetU64(offset_ptr);
header.m_type_offset = data.GetDWARFOffset(offset_ptr);
}

bool length_OK = data.ValidOffset(header.GetNextUnitOffset() - 1);
bool version_OK = SymbolFileDWARF::SupportedVersion(header.m_version);
bool addr_size_OK = (header.m_addr_size == 2) || (header.m_addr_size == 4) ||
(header.m_addr_size == 8);
bool type_offset_OK =
!header.IsTypeUnit() || (header.m_type_offset <= header.GetLength());

if (!length_OK)
return llvm::make_error<llvm::object::GenericBinaryError>(
"Invalid unit length");
if (!version_OK)
return llvm::make_error<llvm::object::GenericBinaryError>(
"Unsupported unit version");
if (!addr_size_OK)
return llvm::make_error<llvm::object::GenericBinaryError>(
"Invalid unit address size");
if (!type_offset_OK)
return llvm::make_error<llvm::object::GenericBinaryError>(
"Type offset out of range");

return header;
}

llvm::Expected<DWARFUnitSP>
DWARFUnit::extract(SymbolFileDWARF &dwarf, user_id_t uid,
const DWARFDataExtractor &debug_info,
DIERef::Section section, lldb::offset_t *offset_ptr) {
assert(debug_info.ValidOffset(*offset_ptr));

DWARFContext &context = dwarf.GetDWARFContext();
auto expected_header =
DWARFUnitHeader::extract(debug_info, section, context, offset_ptr);
if (!expected_header)
return expected_header.takeError();

// FIXME: Either properly map between DIERef::Section and
// llvm::DWARFSectionKind or switch to llvm's definition entirely.
llvm::DWARFSectionKind section_kind_llvm =
section == DIERef::Section::DebugInfo
? llvm::DWARFSectionKind::DW_SECT_INFO
: llvm::DWARFSectionKind::DW_SECT_EXT_TYPES;

llvm::DWARFDataExtractor debug_info_llvm = debug_info.GetAsLLVMDWARF();
llvm::DWARFUnitHeader header;
if (llvm::Error extract_err = header.extract(
context.GetAsLLVM(), debug_info_llvm, offset_ptr, section_kind_llvm))
return std::move(extract_err);

if (context.isDwo()) {
const llvm::DWARFUnitIndex::Entry *entry = nullptr;
const llvm::DWARFUnitIndex &index = expected_header->IsTypeUnit()
const llvm::DWARFUnitIndex &index = header.isTypeUnit()
? context.GetAsLLVM().getTUIndex()
: context.GetAsLLVM().getCUIndex();
if (index) {
if (expected_header->IsTypeUnit())
entry = index.getFromHash(expected_header->GetTypeHash());
else if (auto dwo_id = expected_header->GetDWOId())
if (header.isTypeUnit())
entry = index.getFromHash(header.getTypeHash());
else if (auto dwo_id = header.getDWOId())
entry = index.getFromHash(*dwo_id);
}
if (!entry)
entry = index.getFromOffset(expected_header->GetOffset());
entry = index.getFromOffset(header.getOffset());
if (entry)
if (llvm::Error err = expected_header->ApplyIndexEntry(entry))
if (llvm::Error err = header.applyIndexEntry(entry))
return std::move(err);
}

Expand All @@ -1039,13 +970,13 @@ DWARFUnit::extract(SymbolFileDWARF &dwarf, user_id_t uid,

bool abbr_offset_OK =
dwarf.GetDWARFContext().getOrLoadAbbrevData().ValidOffset(
expected_header->GetAbbrOffset());
header.getAbbrOffset());
if (!abbr_offset_OK)
return llvm::make_error<llvm::object::GenericBinaryError>(
"Abbreviation offset for unit is not valid");

llvm::Expected<const llvm::DWARFAbbreviationDeclarationSet *> abbrevs_or_err =
abbr->getAbbreviationDeclarationSet(expected_header->GetAbbrOffset());
abbr->getAbbreviationDeclarationSet(header.getAbbrOffset());
if (!abbrevs_or_err)
return abbrevs_or_err.takeError();

Expand All @@ -1055,11 +986,11 @@ DWARFUnit::extract(SymbolFileDWARF &dwarf, user_id_t uid,
"No abbrev exists at the specified offset.");

bool is_dwo = dwarf.GetDWARFContext().isDwo();
if (expected_header->IsTypeUnit())
return DWARFUnitSP(new DWARFTypeUnit(dwarf, uid, *expected_header, *abbrevs,
section, is_dwo));
return DWARFUnitSP(new DWARFCompileUnit(dwarf, uid, *expected_header,
*abbrevs, section, is_dwo));
if (header.isTypeUnit())
return DWARFUnitSP(
new DWARFTypeUnit(dwarf, uid, header, *abbrevs, section, is_dwo));
return DWARFUnitSP(
new DWARFCompileUnit(dwarf, uid, header, *abbrevs, section, is_dwo));
}

const lldb_private::DWARFDataExtractor &DWARFUnit::GetData() const {
Expand All @@ -1069,7 +1000,7 @@ const lldb_private::DWARFDataExtractor &DWARFUnit::GetData() const {
}

uint32_t DWARFUnit::GetHeaderByteSize() const {
switch (m_header.GetUnitType()) {
switch (m_header.getUnitType()) {
case llvm::dwarf::DW_UT_compile:
case llvm::dwarf::DW_UT_partial:
return GetVersion() < 5 ? 11 : 12;
Expand Down Expand Up @@ -1106,7 +1037,7 @@ DWARFUnit::FindRnglistFromOffset(dw_offset_t offset) {
llvm::DWARFDataExtractor data = GetRnglistData().GetAsLLVMDWARF();

// As DW_AT_rnglists_base may be missing we need to call setAddressSize.
data.setAddressSize(m_header.GetAddressByteSize());
data.setAddressSize(m_header.getAddressByteSize());
auto range_list_or_error = GetRnglistTable()->findList(data, offset);
if (!range_list_or_error)
return range_list_or_error.takeError();
Expand Down
68 changes: 10 additions & 58 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,54 +38,6 @@ enum DWARFProducer {
eProducerOther
};

/// Base class describing the header of any kind of "unit." Some information
/// is specific to certain unit types. We separate this class out so we can
/// parse the header before deciding what specific kind of unit to construct.
class DWARFUnitHeader {
dw_offset_t m_offset = 0;
dw_offset_t m_length = 0;
uint16_t m_version = 0;
dw_offset_t m_abbr_offset = 0;

const llvm::DWARFUnitIndex::Entry *m_index_entry = nullptr;

uint8_t m_unit_type = 0;
uint8_t m_addr_size = 0;

uint64_t m_type_hash = 0;
uint32_t m_type_offset = 0;

std::optional<uint64_t> m_dwo_id;

DWARFUnitHeader() = default;

public:
dw_offset_t GetOffset() const { return m_offset; }
uint16_t GetVersion() const { return m_version; }
uint16_t GetAddressByteSize() const { return m_addr_size; }
dw_offset_t GetLength() const { return m_length; }
dw_offset_t GetAbbrOffset() const { return m_abbr_offset; }
uint8_t GetUnitType() const { return m_unit_type; }
const llvm::DWARFUnitIndex::Entry *GetIndexEntry() const {
return m_index_entry;
}
uint64_t GetTypeHash() const { return m_type_hash; }
dw_offset_t GetTypeOffset() const { return m_type_offset; }
std::optional<uint64_t> GetDWOId() const { return m_dwo_id; }
bool IsTypeUnit() const {
return m_unit_type == llvm::dwarf::DW_UT_type ||
m_unit_type == llvm::dwarf::DW_UT_split_type;
}
dw_offset_t GetNextUnitOffset() const { return m_offset + m_length + 4; }

llvm::Error ApplyIndexEntry(const llvm::DWARFUnitIndex::Entry *index_entry);

static llvm::Expected<DWARFUnitHeader> extract(const DWARFDataExtractor &data,
DIERef::Section section,
DWARFContext &dwarf_context,
lldb::offset_t *offset_ptr);
};

class DWARFUnit : public UserID {
using die_iterator_range =
llvm::iterator_range<DWARFDebugInfoEntry::collection::iterator>;
Expand All @@ -105,7 +57,7 @@ class DWARFUnit : public UserID {
/// the DWO ID in the compile unit header and we sometimes only want to access
/// this cheap value without causing the more expensive attribute fetches that
/// GetDWOId() uses.
std::optional<uint64_t> GetHeaderDWOId() { return m_header.GetDWOId(); }
std::optional<uint64_t> GetHeaderDWOId() { return m_header.getDWOId(); }
void ExtractUnitDIEIfNeeded();
void ExtractUnitDIENoDwoIfNeeded();
void ExtractDIEsIfNeeded();
Expand Down Expand Up @@ -143,7 +95,7 @@ class DWARFUnit : public UserID {
uint32_t GetHeaderByteSize() const;

// Offset of the initial length field.
dw_offset_t GetOffset() const { return m_header.GetOffset(); }
dw_offset_t GetOffset() const { return m_header.getOffset(); }
/// Get the size in bytes of the length field in the header.
///
/// In DWARF32 this is just 4 bytes
Expand All @@ -159,15 +111,15 @@ class DWARFUnit : public UserID {
dw_offset_t GetFirstDIEOffset() const {
return GetOffset() + GetHeaderByteSize();
}
dw_offset_t GetNextUnitOffset() const { return m_header.GetNextUnitOffset(); }
dw_offset_t GetNextUnitOffset() const { return m_header.getNextUnitOffset(); }
// Size of the CU data (without initial length and without header).
size_t GetDebugInfoSize() const;
// Size of the CU data incl. header but without initial length.
dw_offset_t GetLength() const { return m_header.GetLength(); }
uint16_t GetVersion() const { return m_header.GetVersion(); }
dw_offset_t GetLength() const { return m_header.getLength(); }
uint16_t GetVersion() const { return m_header.getVersion(); }
const llvm::DWARFAbbreviationDeclarationSet *GetAbbreviations() const;
dw_offset_t GetAbbrevOffset() const;
uint8_t GetAddressByteSize() const { return m_header.GetAddressByteSize(); }
uint8_t GetAddressByteSize() const { return m_header.getAddressByteSize(); }
dw_addr_t GetAddrBase() const { return m_addr_base.value_or(0); }
dw_addr_t GetBaseAddress() const { return m_base_addr; }
dw_offset_t GetLineTableOffset();
Expand Down Expand Up @@ -250,8 +202,8 @@ class DWARFUnit : public UserID {

DIERef::Section GetDebugSection() const { return m_section; }

uint8_t GetUnitType() const { return m_header.GetUnitType(); }
bool IsTypeUnit() const { return m_header.IsTypeUnit(); }
uint8_t GetUnitType() const { return m_header.getUnitType(); }
bool IsTypeUnit() const { return m_header.isTypeUnit(); }
/// Note that this check only works for DWARF5+.
bool IsSkeletonUnit() const {
return GetUnitType() == llvm::dwarf::DW_UT_skeleton;
Expand Down Expand Up @@ -320,7 +272,7 @@ class DWARFUnit : public UserID {

protected:
DWARFUnit(SymbolFileDWARF &dwarf, lldb::user_id_t uid,
const DWARFUnitHeader &header,
const llvm::DWARFUnitHeader &header,
const llvm::DWARFAbbreviationDeclarationSet &abbrevs,
DIERef::Section section, bool is_dwo);

Expand Down Expand Up @@ -352,7 +304,7 @@ class DWARFUnit : public UserID {

SymbolFileDWARF &m_dwarf;
std::shared_ptr<DWARFUnit> m_dwo;
DWARFUnitHeader m_header;
llvm::DWARFUnitHeader m_header;
const llvm::DWARFAbbreviationDeclarationSet *m_abbrevs = nullptr;
lldb_private::CompileUnit *m_lldb_cu = nullptr;
// If this is a DWO file, we have a backlink to our skeleton compile unit.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def setUp(self):
self.broadcaster = self.dbg.GetBroadcaster()
self.listener = lldbutil.start_listening_from(
self.broadcaster,
lldb.eBroadcastBitWarning | lldb.eBroadcastBitError,
lldb.SBDebugger.eBroadcastBitWarning | lldb.SBDebugger.eBroadcastBitError,
)

def test_dwarf_symbol_loading_diagnostic_report(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def setUp(self):
TestBase.setUp(self)
self.broadcaster = self.dbg.GetBroadcaster()
self.listener = lldbutil.start_listening_from(
self.broadcaster, lldb.eBroadcastBitProgress
self.broadcaster, lldb.SBDebugger.eBroadcastBitProgress
)

def test_dwarf_symbol_loading_progress_report(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def test_clang_module_build_progress_report(self):
# other unrelated progress events.
broadcaster = self.dbg.GetBroadcaster()
listener = lldbutil.start_listening_from(
broadcaster, lldb.eBroadcastBitProgress
broadcaster, lldb.SBDebugger.eBroadcastBitProgress
)

# Trigger module builds.
Expand Down
2 changes: 1 addition & 1 deletion lldb/test/API/macosx/rosetta/TestRosetta.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def test_rosetta(self):
if rosetta_debugserver_installed():
broadcaster = self.dbg.GetBroadcaster()
listener = lldbutil.start_listening_from(
broadcaster, lldb.eBroadcastBitWarning
broadcaster, lldb.SBDebugger.eBroadcastBitWarning
)

target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
Expand Down
4 changes: 2 additions & 2 deletions lldb/tools/lldb-dap/lldb-dap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -421,8 +421,8 @@ void SendStdOutStdErr(lldb::SBProcess &process) {

void ProgressEventThreadFunction() {
lldb::SBListener listener("lldb-dap.progress.listener");
g_dap.debugger.GetBroadcaster().AddListener(listener,
lldb::eBroadcastBitProgress);
g_dap.debugger.GetBroadcaster().AddListener(
listener, lldb::SBDebugger::eBroadcastBitProgress);
g_dap.broadcaster.AddListener(listener, eBroadcastBitStopProgressThread);
lldb::SBEvent event;
bool done = false;
Expand Down
21 changes: 21 additions & 0 deletions lldb/unittests/Host/HostTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//

#include "lldb/Host/Host.h"
#include "lldb/Utility/ProcessInfo.h"
#include "gtest/gtest.h"

using namespace lldb_private;
Expand All @@ -25,3 +26,23 @@ TEST(Host, GetEnvironment) {
ASSERT_EQ("Host::GetEnvironment",
Host::GetEnvironment().lookup("LLDB_TEST_ENVIRONMENT_VAR"));
}

TEST(Host, ProcessInstanceInfoCumulativeUserTimeIsValid) {
ProcessInstanceInfo info;
info.SetCumulativeUserTime(ProcessInstanceInfo::timespec{0, 0});
EXPECT_FALSE(info.CumulativeUserTimeIsValid());
info.SetCumulativeUserTime(ProcessInstanceInfo::timespec{0, 1});
EXPECT_TRUE(info.CumulativeUserTimeIsValid());
info.SetCumulativeUserTime(ProcessInstanceInfo::timespec{1, 0});
EXPECT_TRUE(info.CumulativeUserTimeIsValid());
}

TEST(Host, ProcessInstanceInfoCumulativeSystemTimeIsValid) {
ProcessInstanceInfo info;
info.SetCumulativeSystemTime(ProcessInstanceInfo::timespec{0, 0});
EXPECT_FALSE(info.CumulativeSystemTimeIsValid());
info.SetCumulativeSystemTime(ProcessInstanceInfo::timespec{0, 1});
EXPECT_TRUE(info.CumulativeSystemTimeIsValid());
info.SetCumulativeSystemTime(ProcessInstanceInfo::timespec{1, 0});
EXPECT_TRUE(info.CumulativeSystemTimeIsValid());
}
6 changes: 3 additions & 3 deletions llvm/docs/CommandGuide/llvm-objcopy.rst
Original file line number Diff line number Diff line change
Expand Up @@ -366,12 +366,12 @@ them.

.. option:: --keep-global-symbol <symbol>, -G

Make all symbols local in the output, except for symbols with the name
Mark all symbols local in the output, except for symbols with the name
``<symbol>``. Can be specified multiple times to ignore multiple symbols.

.. option:: --keep-global-symbols <filename>

Make all symbols local in the output, except for symbols named in the file
Mark all symbols local in the output, except for symbols named in the file
``<filename>``. In the file, each line represents a single symbol, with leading
and trailing whitespace ignored, as is anything following a '#'. Can be
specified multiple times to read names from multiple files.
Expand All @@ -395,7 +395,7 @@ them.

.. option:: --localize-hidden

Make all symbols with hidden or internal visibility local in the output.
Mark all symbols with hidden or internal visibility local in the output.

.. option:: --localize-symbol <symbol>, -L

Expand Down
10 changes: 4 additions & 6 deletions llvm/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ Changes to Interprocedural Optimizations
Changes to the AArch64 Backend
------------------------------

* Added support for Cortex-A78AE, Cortex-A520AE and Cortex-A720AE CPUs.
* Added support for Cortex-A78AE, Cortex-A520AE, Cortex-A720AE,
Neoverse-N3, Neoverse-V3 and Neoverse-V3AE CPUs.

Changes to the AMDGPU Backend
-----------------------------
Expand Down Expand Up @@ -112,11 +113,8 @@ Changes to the RISC-V Backend
* The experimental Ssqosid extension is supported.
* Zacas is no longer experimental.
* Added the CSR names from the Resumable Non-Maskable Interrupts (Smrnmi) extension.
* The default atomics mapping was changed to emit an additional trailing fence
for sequentially consistent stores, offering compatibility with a future
mapping using load-acquire and store-release instructions while remaining
fully compatible with objects produced prior to this change. The mapping
(ABI) used is recorded as an ELF attribute.
* llvm-objdump now prints disassembled opcode bytes in groups of 2 or 4 bytes to
match GNU objdump. The bytes within the groups are in big endian order.

Changes to the WebAssembly Backend
----------------------------------
Expand Down
13 changes: 13 additions & 0 deletions llvm/include/llvm-c/DebugInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,20 @@ typedef enum {
LLVMDWARFSourceLanguageFortran18,
LLVMDWARFSourceLanguageAda2005,
LLVMDWARFSourceLanguageAda2012,
LLVMDWARFSourceLanguageHIP,
LLVMDWARFSourceLanguageAssembly,
LLVMDWARFSourceLanguageC_sharp,
LLVMDWARFSourceLanguageMojo,
LLVMDWARFSourceLanguageGLSL,
LLVMDWARFSourceLanguageGLSL_ES,
LLVMDWARFSourceLanguageHLSL,
LLVMDWARFSourceLanguageOpenCL_CPP,
LLVMDWARFSourceLanguageCPP_for_OpenCL,
LLVMDWARFSourceLanguageSYCL,
LLVMDWARFSourceLanguageRuby,
LLVMDWARFSourceLanguageMove,
LLVMDWARFSourceLanguageHylo,

// Vendor extensions:
LLVMDWARFSourceLanguageMips_Assembler,
LLVMDWARFSourceLanguageGOOGLE_RenderScript,
Expand Down
6 changes: 6 additions & 0 deletions llvm/include/llvm/ADT/StringRef.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,9 @@ namespace llvm {
return Length >= Prefix.Length &&
compareMemory(Data, Prefix.Data, Prefix.Length) == 0;
}
[[nodiscard]] bool starts_with(char Prefix) const {
return !empty() && front() == Prefix;
}

/// Check if this string starts with the given \p Prefix, ignoring case.
[[nodiscard]] bool starts_with_insensitive(StringRef Prefix) const;
Expand All @@ -268,6 +271,9 @@ namespace llvm {
compareMemory(end() - Suffix.Length, Suffix.Data, Suffix.Length) ==
0;
}
[[nodiscard]] bool ends_with(char Suffix) const {
return !empty() && back() == Suffix;
}

/// Check if this string ends with the given \p Suffix, ignoring case.
[[nodiscard]] bool ends_with_insensitive(StringRef Suffix) const;
Expand Down
101 changes: 88 additions & 13 deletions llvm/include/llvm/BinaryFormat/Dwarf.def
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,20 @@
//===----------------------------------------------------------------------===//

// TODO: Add other DW-based macros.
#if !( \
defined HANDLE_DW_TAG || defined HANDLE_DW_AT || defined HANDLE_DW_FORM || \
defined HANDLE_DW_OP || defined HANDLE_DW_OP_LLVM_USEROP || \
defined HANDLE_DW_LANG || defined HANDLE_DW_ATE || \
defined HANDLE_DW_VIRTUALITY || defined HANDLE_DW_DEFAULTED || \
defined HANDLE_DW_CC || defined HANDLE_DW_LNS || defined HANDLE_DW_LNE || \
defined HANDLE_DW_LNCT || defined HANDLE_DW_MACRO || \
defined HANDLE_DW_MACRO_GNU || defined HANDLE_MACRO_FLAG || \
defined HANDLE_DW_RLE || defined HANDLE_DW_LLE || \
(defined HANDLE_DW_CFA && defined HANDLE_DW_CFA_PRED) || \
defined HANDLE_DW_APPLE_PROPERTY || defined HANDLE_DW_UT || \
defined HANDLE_DWARF_SECTION || defined HANDLE_DW_IDX || \
defined HANDLE_DW_END || defined HANDLE_DW_SECT)
#if !(defined HANDLE_DW_TAG || defined HANDLE_DW_AT || \
defined HANDLE_DW_FORM || defined HANDLE_DW_OP || \
defined HANDLE_DW_OP_LLVM_USEROP || defined HANDLE_DW_LANG || \
defined HANDLE_DW_LNAME || defined HANDLE_DW_ATE || \
defined HANDLE_DW_VIRTUALITY || defined HANDLE_DW_DEFAULTED || \
defined HANDLE_DW_CC || defined HANDLE_DW_LNS || \
defined HANDLE_DW_LNE || defined HANDLE_DW_LNCT || \
defined HANDLE_DW_MACRO || defined HANDLE_DW_MACRO_GNU || \
defined HANDLE_MACRO_FLAG || defined HANDLE_DW_RLE || \
defined HANDLE_DW_LLE || \
(defined HANDLE_DW_CFA && defined HANDLE_DW_CFA_PRED) || \
defined HANDLE_DW_APPLE_PROPERTY || defined HANDLE_DW_UT || \
defined HANDLE_DWARF_SECTION || defined HANDLE_DW_IDX || \
defined HANDLE_DW_END || defined HANDLE_DW_SECT)
#error "Missing macro definition of HANDLE_DW*"
#endif

Expand Down Expand Up @@ -61,6 +62,10 @@
#define HANDLE_DW_LANG(ID, NAME, LOWER_BOUND, VERSION, VENDOR)
#endif

#ifndef HANDLE_DW_LNAME
#define HANDLE_DW_LNAME(ID, NAME, DESC, LOWER_BOUND)
#endif

#ifndef HANDLE_DW_ATE
#define HANDLE_DW_ATE(ID, NAME, VERSION, VENDOR)
#endif
Expand Down Expand Up @@ -950,12 +955,81 @@ HANDLE_DW_LANG(0x002c, C17, 0, 0, DWARF)
HANDLE_DW_LANG(0x002d, Fortran18, 0, 0, DWARF)
HANDLE_DW_LANG(0x002e, Ada2005, 0, 0, DWARF)
HANDLE_DW_LANG(0x002f, Ada2012, 0, 0, DWARF)
HANDLE_DW_LANG(0x0030, HIP, 0, 0, DWARF)
HANDLE_DW_LANG(0x0031, Assembly, 0, 0, DWARF)
HANDLE_DW_LANG(0x0032, C_sharp, 0, 0, DWARF)
HANDLE_DW_LANG(0x0033, Mojo, 0, 0, DWARF)
HANDLE_DW_LANG(0x0034, GLSL, 0, 0, DWARF)
HANDLE_DW_LANG(0x0035, GLSL_ES, 0, 0, DWARF)
HANDLE_DW_LANG(0x0036, HLSL, 0, 0, DWARF)
HANDLE_DW_LANG(0x0037, OpenCL_CPP, 0, 0, DWARF)
HANDLE_DW_LANG(0x0038, CPP_for_OpenCL, 0, 0, DWARF)
HANDLE_DW_LANG(0x0039, SYCL, 0, 0, DWARF)
HANDLE_DW_LANG(0x0040, Ruby, 0, 0, DWARF)
HANDLE_DW_LANG(0x0041, Move, 0, 0, DWARF)
HANDLE_DW_LANG(0x0042, Hylo, 0, 0, DWARF)

// Vendor extensions:
HANDLE_DW_LANG(0x8001, Mips_Assembler, std::nullopt, 0, MIPS)
HANDLE_DW_LANG(0x8e57, GOOGLE_RenderScript, 0, 0, GOOGLE)
HANDLE_DW_LANG(0xb000, BORLAND_Delphi, 0, 0, BORLAND)

// Tentative DWARF 6 language codes. This list is subject to change.
HANDLE_DW_LNAME(0x0001, Ada, "ISO Ada", 1) // YYYY
HANDLE_DW_LNAME(0x0002, BLISS, "BLISS", 0)
// YYYYMM
// K&R 000000
// C89 198912
// C99 199901
// C11 201112
// C17 201710
// C23 202311
HANDLE_DW_LNAME(0x0003, C, "C (K&R and ISO)", 0)
// YYYYMM
// C++98 199711
// C++03 200310
// C++11 201103
// C++14 201402
// C++17 201703
// C++20 202002
HANDLE_DW_LNAME(0x0004, C_plus_plus, "ISO C++", 0)
HANDLE_DW_LNAME(0x0005, Cobol, "ISO Cobol", 1) // YYYY
HANDLE_DW_LNAME(0x0006, Crystal, "Crystal", 0)
HANDLE_DW_LNAME(0x0007, D, "D", 0)
HANDLE_DW_LNAME(0x0008, Dylan, "Dylan", 0)
HANDLE_DW_LNAME(0x0009, Fortran, "ISO Fortran", 1) // YYYY
HANDLE_DW_LNAME(0x000a, Go, "Go", 0)
HANDLE_DW_LNAME(0x000b, Haskell, "Haskell", 0)
HANDLE_DW_LNAME(0x000c, Java, "Java", 0)
HANDLE_DW_LNAME(0x000d, Julia, "Julia", 1)
HANDLE_DW_LNAME(0x000e, Kotlin, "Kotlin", 0)
HANDLE_DW_LNAME(0x000f, Modula2, "Modula 2", 1)
HANDLE_DW_LNAME(0x0010, Modula3, "Modula 3", 1)
HANDLE_DW_LNAME(0x0011, ObjC, "Objective C", 0) // YYYYMM
HANDLE_DW_LNAME(0x0012, ObjC_plus_plus, "Objective C++", 0) // YYYYMM
HANDLE_DW_LNAME(0x0013, OCaml, "OCaml", 0)
HANDLE_DW_LNAME(0x0014, OpenCL_C, "OpenCL C", 0)
HANDLE_DW_LNAME(0x0015, Pascal, "ISO Pascal", 1) // YYYY
HANDLE_DW_LNAME(0x0016, PLI, "ANSI PL/I", 1)
HANDLE_DW_LNAME(0x0017, Python, "Python", 0)
HANDLE_DW_LNAME(0x0018, RenderScript, "RenderScript Kernel Language", 0)
HANDLE_DW_LNAME(0x0019, Rust, "Rust", 0)
HANDLE_DW_LNAME(0x001a, Swift, "Swift", 0) // VVMM
HANDLE_DW_LNAME(0x001b, UPC, "Unified Parallel C (UPC)", 0)
HANDLE_DW_LNAME(0x001c, Zig, "Zig", 0)
HANDLE_DW_LNAME(0x001d, Assembly, "Assembly", 0)
// Conflict: HANDLE_DW_LNAME(0x001d, HIP, "HIP", 0)
HANDLE_DW_LNAME(0x001e, C_sharp, "C#", 0)
HANDLE_DW_LNAME(0x001f, Mojo, "Mojo", 0)
HANDLE_DW_LNAME(0x0020, GLSL, "OpenGL Shading Language", 0) // VVMMPP
HANDLE_DW_LNAME(0x0021, GLSL_ES, "OpenGL ES Shading Language", 0) // VVMMPP
HANDLE_DW_LNAME(0x0022, HLSL, "High Level Shading Language", 0) // YYYY
HANDLE_DW_LNAME(0x0023, OpenCL_CPP, "OpenCL C++", 0) // VVMM
HANDLE_DW_LNAME(0x0024, CPP_for_OpenCL, "C++ for OpenCL", 0) // VVMM
HANDLE_DW_LNAME(0x0025, SYCL, "SYCL", 0) // YYYYRR
HANDLE_DW_LNAME(0x0026, Ruby, "Ruby", 0) // VVMMPP
HANDLE_DW_LNAME(0x0027, Move, "Move", 0) // YYYYMM
HANDLE_DW_LNAME(0x0028, Hylo, "Hylo", 0)

// DWARF attribute type encodings.
HANDLE_DW_ATE(0x01, address, 2, DWARF)
Expand Down Expand Up @@ -1267,6 +1341,7 @@ HANDLE_DW_SECT(8, RNGLISTS)
#undef HANDLE_DW_OP
#undef HANDLE_DW_OP_LLVM_USEROP
#undef HANDLE_DW_LANG
#undef HANDLE_DW_LNAME
#undef HANDLE_DW_ATE
#undef HANDLE_DW_VIRTUALITY
#undef HANDLE_DW_DEFAULTED
Expand Down
314 changes: 314 additions & 0 deletions llvm/include/llvm/BinaryFormat/Dwarf.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,284 @@ enum SourceLanguage {
DW_LANG_hi_user = 0xffff
};

enum SourceLanguageName : uint16_t {
#define HANDLE_DW_LNAME(ID, NAME, DESC, LOWER_BOUND) DW_LNAME_##NAME = ID,
#include "llvm/BinaryFormat/Dwarf.def"
};

/// Convert a DWARF 6 pair of language name and version to a DWARF 5 DW_LANG.
/// If the version number doesn't exactly match a known version it is
/// rounded up to the next-highest known version number.
inline std::optional<SourceLanguage> toDW_LANG(SourceLanguageName name,
uint32_t version) {
switch (name) {
case DW_LNAME_Ada: // YYYY
if (version <= 1983)
return DW_LANG_Ada83;
if (version <= 1995)
return DW_LANG_Ada95;
if (version <= 2005)
return DW_LANG_Ada2005;
if (version <= 2012)
return DW_LANG_Ada2012;
return {};
case DW_LNAME_BLISS:
return DW_LANG_BLISS;
case DW_LNAME_C: // YYYYMM, K&R 000000
if (version == 0)
return DW_LANG_C;
if (version <= 198912)
return DW_LANG_C89;
if (version <= 199901)
return DW_LANG_C99;
if (version <= 201112)
return DW_LANG_C11;
if (version <= 201710)
return DW_LANG_C17;
return {};
case DW_LNAME_C_plus_plus: // YYYYMM
if (version == 0)
return DW_LANG_C_plus_plus;
if (version <= 199711)
return DW_LANG_C_plus_plus;
if (version <= 200310)
return DW_LANG_C_plus_plus_03;
if (version <= 201103)
return DW_LANG_C_plus_plus_11;
if (version <= 201402)
return DW_LANG_C_plus_plus_14;
if (version <= 201703)
return DW_LANG_C_plus_plus_17;
if (version <= 202002)
return DW_LANG_C_plus_plus_20;
return {};
case DW_LNAME_Cobol: // YYYY
if (version <= 1974)
return DW_LANG_Cobol74;
if (version <= 1985)
return DW_LANG_Cobol85;
return {};
case DW_LNAME_Crystal:
return DW_LANG_Crystal;
case DW_LNAME_D:
return DW_LANG_D;
case DW_LNAME_Dylan:
return DW_LANG_Dylan;
case DW_LNAME_Fortran: // YYYY
if (version <= 1977)
return DW_LANG_Fortran77;
if (version <= 1990)
return DW_LANG_Fortran90;
if (version <= 1995)
return DW_LANG_Fortran95;
if (version <= 2003)
return DW_LANG_Fortran03;
if (version <= 2008)
return DW_LANG_Fortran08;
if (version <= 2018)
return DW_LANG_Fortran18;
return {};
case DW_LNAME_Go:
return DW_LANG_Go;
case DW_LNAME_Haskell:
return DW_LANG_Haskell;
// case DW_LNAME_HIP:
// return DW_LANG_HIP;
case DW_LNAME_Java:
return DW_LANG_Java;
case DW_LNAME_Julia:
return DW_LANG_Julia;
case DW_LNAME_Kotlin:
return DW_LANG_Kotlin;
case DW_LNAME_Modula2:
return DW_LANG_Modula2;
case DW_LNAME_Modula3:
return DW_LANG_Modula3;
case DW_LNAME_ObjC:
return DW_LANG_ObjC;
case DW_LNAME_ObjC_plus_plus:
return DW_LANG_ObjC_plus_plus;
case DW_LNAME_OCaml:
return DW_LANG_OCaml;
case DW_LNAME_OpenCL_C:
return DW_LANG_OpenCL;
case DW_LNAME_Pascal:
return DW_LANG_Pascal83;
case DW_LNAME_PLI:
return DW_LANG_PLI;
case DW_LNAME_Python:
return DW_LANG_Python;
case DW_LNAME_RenderScript:
return DW_LANG_RenderScript;
case DW_LNAME_Rust:
return DW_LANG_Rust;
case DW_LNAME_Swift:
return DW_LANG_Swift;
case DW_LNAME_UPC:
return DW_LANG_UPC;
case DW_LNAME_Zig:
return DW_LANG_Zig;
case DW_LNAME_Assembly:
return DW_LANG_Assembly;
case DW_LNAME_C_sharp:
return DW_LANG_C_sharp;
case DW_LNAME_Mojo:
return DW_LANG_Mojo;
case DW_LNAME_GLSL:
return DW_LANG_GLSL;
case DW_LNAME_GLSL_ES:
return DW_LANG_GLSL_ES;
case DW_LNAME_HLSL:
return DW_LANG_HLSL;
case DW_LNAME_OpenCL_CPP:
return DW_LANG_OpenCL_CPP;
case DW_LNAME_CPP_for_OpenCL:
return {};
case DW_LNAME_SYCL:
return DW_LANG_SYCL;
case DW_LNAME_Ruby:
return DW_LANG_Ruby;
case DW_LNAME_Move:
return DW_LANG_Move;
case DW_LNAME_Hylo:
return DW_LANG_Hylo;
}
return {};
}

/// Convert a DWARF 5 DW_LANG to a DWARF 6 pair of language name and version.
inline std::optional<std::pair<SourceLanguageName, uint32_t>>
toDW_LNAME(SourceLanguage language) {
switch (language) {
case DW_LANG_Ada83:
return {{DW_LNAME_Ada, 1983}};
case DW_LANG_Ada95:
return {{DW_LNAME_Ada, 1995}};
case DW_LANG_Ada2005:
return {{DW_LNAME_Ada, 2005}};
case DW_LANG_Ada2012:
return {{DW_LNAME_Ada, 2012}};
case DW_LANG_BLISS:
return {{DW_LNAME_BLISS, 0}};
case DW_LANG_C:
return {{DW_LNAME_C, 0}};
case DW_LANG_C89:
return {{DW_LNAME_C, 198912}};
case DW_LANG_C99:
return {{DW_LNAME_C, 199901}};
case DW_LANG_C11:
return {{DW_LNAME_C, 201112}};
case DW_LANG_C17:
return {{DW_LNAME_C, 201712}};
case DW_LANG_C_plus_plus:
return {{DW_LNAME_C_plus_plus, 0}};
case DW_LANG_C_plus_plus_03:
return {{DW_LNAME_C_plus_plus, 200310}};
case DW_LANG_C_plus_plus_11:
return {{DW_LNAME_C_plus_plus, 201103}};
case DW_LANG_C_plus_plus_14:
return {{DW_LNAME_C_plus_plus, 201402}};
case DW_LANG_C_plus_plus_17:
return {{DW_LNAME_C_plus_plus, 201703}};
case DW_LANG_C_plus_plus_20:
return {{DW_LNAME_C_plus_plus, 202002}};
case DW_LANG_Cobol74:
return {{DW_LNAME_Cobol, 1974}};
case DW_LANG_Cobol85:
return {{DW_LNAME_Cobol, 1985}};
case DW_LANG_Crystal:
return {{DW_LNAME_Crystal, 0}};
case DW_LANG_D:
return {{DW_LNAME_D, 0}};
case DW_LANG_Dylan:
return {{DW_LNAME_Dylan, 0}};
case DW_LANG_Fortran77:
return {{DW_LNAME_Fortran, 1977}};
case DW_LANG_Fortran90:
return {{DW_LNAME_Fortran, 1990}};
case DW_LANG_Fortran95:
return {{DW_LNAME_Fortran, 1995}};
case DW_LANG_Fortran03:
return {{DW_LNAME_Fortran, 2003}};
case DW_LANG_Fortran08:
return {{DW_LNAME_Fortran, 2008}};
case DW_LANG_Fortran18:
return {{DW_LNAME_Fortran, 2018}};
case DW_LANG_Go:
return {{DW_LNAME_Go, 0}};
case DW_LANG_Haskell:
return {{DW_LNAME_Haskell, 0}};
case DW_LANG_HIP:
return {}; // return {{DW_LNAME_HIP, 0}};
case DW_LANG_Java:
return {{DW_LNAME_Java, 0}};
case DW_LANG_Julia:
return {{DW_LNAME_Julia, 0}};
case DW_LANG_Kotlin:
return {{DW_LNAME_Kotlin, 0}};
case DW_LANG_Modula2:
return {{DW_LNAME_Modula2, 0}};
case DW_LANG_Modula3:
return {{DW_LNAME_Modula3, 0}};
case DW_LANG_ObjC:
return {{DW_LNAME_ObjC, 0}};
case DW_LANG_ObjC_plus_plus:
return {{DW_LNAME_ObjC_plus_plus, 0}};
case DW_LANG_OCaml:
return {{DW_LNAME_OCaml, 0}};
case DW_LANG_OpenCL:
return {{DW_LNAME_OpenCL_C, 0}};
case DW_LANG_Pascal83:
return {{DW_LNAME_Pascal, 1983}};
case DW_LANG_PLI:
return {{DW_LNAME_PLI, 0}};
case DW_LANG_Python:
return {{DW_LNAME_Python, 0}};
case DW_LANG_RenderScript:
case DW_LANG_GOOGLE_RenderScript:
return {{DW_LNAME_RenderScript, 0}};
case DW_LANG_Rust:
return {{DW_LNAME_Rust, 0}};
case DW_LANG_Swift:
return {{DW_LNAME_Swift, 0}};
case DW_LANG_UPC:
return {{DW_LNAME_UPC, 0}};
case DW_LANG_Zig:
return {{DW_LNAME_Zig, 0}};
case DW_LANG_Assembly:
case DW_LANG_Mips_Assembler:
return {{DW_LNAME_Assembly, 0}};
case DW_LANG_C_sharp:
return {{DW_LNAME_C_sharp, 0}};
case DW_LANG_Mojo:
return {{DW_LNAME_Mojo, 0}};
case DW_LANG_GLSL:
return {{DW_LNAME_GLSL, 0}};
case DW_LANG_GLSL_ES:
return {{DW_LNAME_GLSL_ES, 0}};
case DW_LANG_HLSL:
return {{DW_LNAME_HLSL, 0}};
case DW_LANG_OpenCL_CPP:
return {{DW_LNAME_OpenCL_CPP, 0}};
case DW_LANG_SYCL:
return {{DW_LNAME_SYCL, 0}};
case DW_LANG_Ruby:
return {{DW_LNAME_Ruby, 0}};
case DW_LANG_Move:
return {{DW_LNAME_Move, 0}};
case DW_LANG_Hylo:
return {{DW_LNAME_Hylo, 0}};
case DW_LANG_BORLAND_Delphi:
case DW_LANG_CPP_for_OpenCL:
case DW_LANG_lo_user:
case DW_LANG_hi_user:
return {};
}
return {};
}

llvm::StringRef LanguageDescription(SourceLanguageName name);

inline bool isCPlusPlus(SourceLanguage S) {
bool result = false;
// Deliberately enumerate all the language options so we get a warning when
Expand Down Expand Up @@ -268,7 +546,19 @@ inline bool isCPlusPlus(SourceLanguage S) {
case DW_LANG_Fortran18:
case DW_LANG_Ada2005:
case DW_LANG_Ada2012:
case DW_LANG_HIP:
case DW_LANG_Assembly:
case DW_LANG_C_sharp:
case DW_LANG_Mojo:
case DW_LANG_GLSL:
case DW_LANG_GLSL_ES:
case DW_LANG_HLSL:
case DW_LANG_OpenCL_CPP:
case DW_LANG_CPP_for_OpenCL:
case DW_LANG_SYCL:
case DW_LANG_Ruby:
case DW_LANG_Move:
case DW_LANG_Hylo:
result = false;
break;
}
Expand Down Expand Up @@ -335,7 +625,19 @@ inline bool isFortran(SourceLanguage S) {
case DW_LANG_C17:
case DW_LANG_Ada2005:
case DW_LANG_Ada2012:
case DW_LANG_HIP:
case DW_LANG_Assembly:
case DW_LANG_C_sharp:
case DW_LANG_Mojo:
case DW_LANG_GLSL:
case DW_LANG_GLSL_ES:
case DW_LANG_HLSL:
case DW_LANG_OpenCL_CPP:
case DW_LANG_CPP_for_OpenCL:
case DW_LANG_SYCL:
case DW_LANG_Ruby:
case DW_LANG_Move:
case DW_LANG_Hylo:
result = false;
break;
}
Expand Down Expand Up @@ -400,7 +702,19 @@ inline bool isC(SourceLanguage S) {
case DW_LANG_Fortran18:
case DW_LANG_Ada2005:
case DW_LANG_Ada2012:
case DW_LANG_HIP:
case DW_LANG_Assembly:
case DW_LANG_C_sharp:
case DW_LANG_Mojo:
case DW_LANG_GLSL:
case DW_LANG_GLSL_ES:
case DW_LANG_HLSL:
case DW_LANG_OpenCL_CPP:
case DW_LANG_CPP_for_OpenCL:
case DW_LANG_SYCL:
case DW_LANG_Ruby:
case DW_LANG_Move:
case DW_LANG_Hylo:
return false;
}
llvm_unreachable("Unknown language kind.");
Expand Down
3 changes: 3 additions & 0 deletions llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -853,6 +853,9 @@ class CombinerHelper {
bool matchExtractVectorElementWithDifferentIndices(const MachineOperand &MO,
BuildFnTy &MatchInfo);

/// Combine insert vector element OOB.
bool matchInsertVectorElementOOB(MachineInstr &MI, BuildFnTy &MatchInfo);

private:
/// Checks for legality of an indexed variant of \p LdSt.
bool isIndexedLoadStoreLegal(GLoadStore &LdSt) const;
Expand Down
26 changes: 26 additions & 0 deletions llvm/include/llvm/CodeGen/GlobalISel/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -559,5 +559,31 @@ void salvageDebugInfo(const MachineRegisterInfo &MRI, MachineInstr &MI);
/// having only floating-point operands.
bool isPreISelGenericFloatingPointOpcode(unsigned Opc);

/// Returns true if \p Reg can create undef or poison from non-undef &
/// non-poison operands. \p ConsiderFlagsAndMetadata controls whether poison
/// producing flags and metadata on the instruction are considered. This can be
/// used to see if the instruction could still introduce undef or poison even
/// without poison generating flags and metadata which might be on the
/// instruction.
bool canCreateUndefOrPoison(Register Reg, const MachineRegisterInfo &MRI,
bool ConsiderFlagsAndMetadata = true);

/// Returns true if \p Reg can create poison from non-poison operands.
bool canCreatePoison(Register Reg, const MachineRegisterInfo &MRI,
bool ConsiderFlagsAndMetadata = true);

/// Returns true if \p Reg cannot be poison and undef.
bool isGuaranteedNotToBeUndefOrPoison(Register Reg,
const MachineRegisterInfo &MRI,
unsigned Depth = 0);

/// Returns true if \p Reg cannot be poison, but may be undef.
bool isGuaranteedNotToBePoison(Register Reg, const MachineRegisterInfo &MRI,
unsigned Depth = 0);

/// Returns true if \p Reg cannot be undef, but may be poison.
bool isGuaranteedNotToBeUndef(Register Reg, const MachineRegisterInfo &MRI,
unsigned Depth = 0);

} // End namespace llvm.
#endif
1 change: 1 addition & 0 deletions llvm/include/llvm/CodeGen/ISDOpcodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ enum NodeType {
/// CopyFromReg - This node indicates that the input value is a virtual or
/// physical register that is defined outside of the scope of this
/// SelectionDAG. The register is available from the RegisterSDNode object.
/// Note that CopyFromReg is considered as also freezing the value.
CopyFromReg,

/// UNDEF - An undefined node.
Expand Down
3 changes: 0 additions & 3 deletions llvm/include/llvm/Frontend/OpenMP/OMPKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,6 @@ __OMP_RTL(__tgt_target_kernel, false, Int32, IdentPtr, Int64, Int32, Int32,
VoidPtr, KernelArgsPtr)
__OMP_RTL(__tgt_target_kernel_nowait, false, Int32, IdentPtr, Int64, Int32,
Int32, VoidPtr, KernelArgsPtr, Int32, VoidPtr, Int32, VoidPtr)
__OMP_RTL(__tgt_register_requires, false, Void, Int64)
__OMP_RTL(__tgt_target_data_begin_mapper, false, Void, IdentPtr, Int64, Int32, VoidPtrPtr,
VoidPtrPtr, Int64Ptr, Int64Ptr, VoidPtrPtr, VoidPtrPtr)
__OMP_RTL(__tgt_target_data_begin_nowait_mapper, false, Void, IdentPtr, Int64, Int32,
Expand Down Expand Up @@ -1025,8 +1024,6 @@ __OMP_RTL_ATTRS(__tgt_target_kernel_nowait, ForkAttrs, SExt,
ParamAttrs(AttributeSet(), AttributeSet(), SExt, SExt,
AttributeSet(), AttributeSet(), SExt, AttributeSet(),
SExt))
__OMP_RTL_ATTRS(__tgt_register_requires, ForkAttrs, AttributeSet(),
ParamAttrs())
__OMP_RTL_ATTRS(__tgt_target_data_begin_mapper, ForkAttrs, AttributeSet(),
ParamAttrs(AttributeSet(), AttributeSet(), SExt))
__OMP_RTL_ATTRS(__tgt_target_data_begin_nowait_mapper, ForkAttrs, AttributeSet(),
Expand Down
3 changes: 2 additions & 1 deletion llvm/include/llvm/IR/IntrinsicInst.h
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,8 @@ class DbgVariableIntrinsic : public DbgInfoIntrinsic {

Value *getVariableLocationOp(unsigned OpIdx) const;

void replaceVariableLocationOp(Value *OldValue, Value *NewValue);
void replaceVariableLocationOp(Value *OldValue, Value *NewValue,
bool AllowEmpty = false);
void replaceVariableLocationOp(unsigned OpIdx, Value *NewValue);
/// Adding a new location operand will always result in this intrinsic using
/// an ArgList, and must always be accompanied by a new expression that uses
Expand Down
10 changes: 6 additions & 4 deletions llvm/include/llvm/IR/IntrinsicsAArch64.td
Original file line number Diff line number Diff line change
Expand Up @@ -1762,6 +1762,7 @@ def int_aarch64_sve_uqsub_x : AdvSIMD_2VectorArg_Intrinsic;
def int_aarch64_sve_orqv : AdvSIMD_SVE_V128_Reduce_Intrinsic;
def int_aarch64_sve_eorqv : AdvSIMD_SVE_V128_Reduce_Intrinsic;
def int_aarch64_sve_andqv : AdvSIMD_SVE_V128_Reduce_Intrinsic;
def int_aarch64_sve_addqv : AdvSIMD_SVE_V128_Reduce_Intrinsic;
def int_aarch64_sve_smaxqv : AdvSIMD_SVE_V128_Reduce_Intrinsic;
def int_aarch64_sve_umaxqv : AdvSIMD_SVE_V128_Reduce_Intrinsic;
def int_aarch64_sve_sminqv : AdvSIMD_SVE_V128_Reduce_Intrinsic;
Expand Down Expand Up @@ -2079,11 +2080,12 @@ def int_aarch64_sve_fmaxv : AdvSIMD_SVE_Reduce_Intrinsic;
def int_aarch64_sve_fmaxnmv : AdvSIMD_SVE_Reduce_Intrinsic;
def int_aarch64_sve_fminv : AdvSIMD_SVE_Reduce_Intrinsic;
def int_aarch64_sve_fminnmv : AdvSIMD_SVE_Reduce_Intrinsic;
def int_aarch64_sve_addqv : AdvSIMD_SVE_V128_Reduce_Intrinsic;

def int_aarch64_sve_faddqv : AdvSIMD_SVE_V128_Reduce_Intrinsic;
def int_aarch64_sve_fmaxnmqv : AdvSIMD_SVE_V128_Reduce_Intrinsic;
def int_aarch64_sve_fminnmqv : AdvSIMD_SVE_V128_Reduce_Intrinsic;
def int_aarch64_sve_fmaxqv : AdvSIMD_SVE_V128_Reduce_Intrinsic;
def int_aarch64_sve_fminqv : AdvSIMD_SVE_V128_Reduce_Intrinsic;
def int_aarch64_sve_fmaxqv : AdvSIMD_SVE_V128_Reduce_Intrinsic;
def int_aarch64_sve_fminqv : AdvSIMD_SVE_V128_Reduce_Intrinsic;

//
// Floating-point conversions
Expand Down Expand Up @@ -3646,4 +3648,4 @@ def int_aarch64_sve_pmov_to_pred_lane_zero : SVE2_1VectorArg_Pred_Intrinsic;

def int_aarch64_sve_pmov_to_vector_lane_merging : SVE2_Pred_1VectorArgIndexed_Intrinsic;

def int_aarch64_sve_pmov_to_vector_lane_zeroing : SVE2_Pred_1VectorArg_Intrinsic;
def int_aarch64_sve_pmov_to_vector_lane_zeroing : SVE2_Pred_1VectorArg_Intrinsic;
5 changes: 2 additions & 3 deletions llvm/include/llvm/Object/ELFObjectFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -801,9 +801,8 @@ Expected<uint32_t> ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Sym) const {
} else if (EF.getHeader().e_machine == ELF::EM_RISCV) {
if (Expected<StringRef> NameOrErr = getSymbolName(Sym)) {
StringRef Name = *NameOrErr;
// Mark empty name symbols (used for label differences) and mapping
// symbols.
if (Name.empty() || Name.starts_with("$d") || Name.starts_with("$x"))
// Mark fake labels (used for label differences) and mapping symbols.
if (Name == ".L0 " || Name.starts_with("$d") || Name.starts_with("$x"))
Result |= SymbolRef::SF_FormatSpecific;
} else {
// TODO: Actually report errors helpfully.
Expand Down
1 change: 0 additions & 1 deletion llvm/include/llvm/Support/RISCVAttributeParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ class RISCVAttributeParser : public ELFAttributeParser {

Error unalignedAccess(unsigned tag);
Error stackAlign(unsigned tag);
Error atomicAbi(unsigned tag);

public:
RISCVAttributeParser(ScopedPrinter *sw)
Expand Down
13 changes: 0 additions & 13 deletions llvm/include/llvm/Support/RISCVAttributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,8 @@ enum AttrType : unsigned {
PRIV_SPEC = 8,
PRIV_SPEC_MINOR = 10,
PRIV_SPEC_REVISION = 12,
ATOMIC_ABI = 14,
};

namespace RISCVAtomicAbiTag {
enum AtomicABI : unsigned {
// Values for Tag_RISCV_atomic_abi
// Defined at
// https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#tag_riscv_atomic_abi-14-uleb128version
UNKNOWN = 0,
A6C = 1,
A6S = 2,
A7 = 3,
};
} // namespace RISCVAtomicAbiTag

enum { NOT_ALLOWED = 0, ALLOWED = 1 };

} // namespace RISCVAttrs
Expand Down
7 changes: 7 additions & 0 deletions llvm/include/llvm/Support/RISCVISAUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#define LLVM_SUPPORT_RISCVISAUTILS_H

#include "llvm/ADT/StringRef.h"
#include <map>
#include <string>

namespace llvm {
Expand All @@ -35,6 +36,12 @@ struct ExtensionComparator {
return compareExtension(LHS, RHS);
}
};

/// OrderedExtensionMap is std::map, it's specialized to keep entries
/// in canonical order of extension.
typedef std::map<std::string, ExtensionVersion, ExtensionComparator>
OrderedExtensionMap;

} // namespace RISCVISAUtils

} // namespace llvm
Expand Down
33 changes: 31 additions & 2 deletions llvm/include/llvm/Target/GlobalISel/Combine.td
Original file line number Diff line number Diff line change
Expand Up @@ -1525,11 +1525,39 @@ def combine_shuffle_concat : GICombineRule<
[{ return Helper.matchCombineShuffleConcat(*${root}, ${matchinfo}); }]),
(apply [{ Helper.applyCombineShuffleConcat(*${root}, ${matchinfo}); }])>;

// match_extract_of_element must be the first!
def insert_vector_element_idx_undef : GICombineRule<
(defs root:$root, build_fn_matchinfo:$matchinfo),
(match (G_IMPLICIT_DEF $idx),
(G_INSERT_VECTOR_ELT $root, $src, $elt, $idx)),
(apply (G_IMPLICIT_DEF $root))>;

def insert_vector_element_elt_undef : GICombineRule<
(defs root:$root, build_fn_matchinfo:$matchinfo),
(match (G_IMPLICIT_DEF $elt),
(G_INSERT_VECTOR_ELT $root, $src, $elt, $idx),
[{ return isGuaranteedNotToBePoison(${src}.getReg(), MRI); }]),
(apply (GIReplaceReg $root, $src))>;

def insert_vector_element_extract_vector_element : GICombineRule<
(defs root:$root, build_fn_matchinfo:$matchinfo),
(match (G_EXTRACT_VECTOR_ELT $elt, $src, $idx),
(G_INSERT_VECTOR_ELT $root, $src, $elt, $idx)),
(apply (GIReplaceReg $root, $src))>;

def insert_vector_elt_oob : GICombineRule<
(defs root:$root, build_fn_matchinfo:$matchinfo),
(match (wip_match_opcode G_INSERT_VECTOR_ELT):$root,
[{ return Helper.matchInsertVectorElementOOB(*${root}, ${matchinfo}); }]),
(apply [{ Helper.applyBuildFn(*${root}, ${matchinfo}); }])>;

// match_extract_of_element and insert_vector_elt_oob must be the first!
def vector_ops_combines: GICombineGroup<[
match_extract_of_element_undef_vector,
match_extract_of_element_undef_index,
insert_vector_element_idx_undef,
insert_vector_element_elt_undef,
match_extract_of_element,
insert_vector_elt_oob,
extract_vector_element_not_const,
extract_vector_element_different_indices,
extract_vector_element_build_vector2,
Expand All @@ -1553,7 +1581,8 @@ extract_vector_element_build_vector_trunc5,
extract_vector_element_build_vector_trunc6,
extract_vector_element_build_vector_trunc7,
extract_vector_element_build_vector_trunc8,
extract_vector_element_freeze
extract_vector_element_freeze,
insert_vector_element_extract_vector_element
]>;

// FIXME: These should use the custom predicate feature once it lands.
Expand Down
25 changes: 23 additions & 2 deletions llvm/include/llvm/TargetParser/AArch64TargetParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ inline constexpr ExtensionInfo Extensions[] = {
{"sha3", AArch64::AEK_SHA3, "+sha3", "-sha3", FEAT_SHA3, "+sha3,+sha2,+fp-armv8,+neon", 140},
{"simd", AArch64::AEK_SIMD, "+neon", "-neon", FEAT_SIMD, "+fp-armv8,+neon", 100},
{"sm4", AArch64::AEK_SM4, "+sm4", "-sm4", FEAT_SM4, "+sm4,+fp-armv8,+neon", 106},
{"sme-f16f16", AArch64::AEK_SMEF16F16, "+sme-f16f16", "-sme-f16f16", FEAT_INIT, "", 0},
{"sme-f16f16", AArch64::AEK_SMEF16F16, "+sme-f16f16", "-sme-f16f16", FEAT_INIT, "+sme2,+sme-f16f16", 0},
{"sme-f64f64", AArch64::AEK_SMEF64F64, "+sme-f64f64", "-sme-f64f64", FEAT_SME_F64, "+sme,+sme-f64f64,+bf16", 560},
{"sme-i16i64", AArch64::AEK_SMEI16I64, "+sme-i16i64", "-sme-i16i64", FEAT_SME_I64, "+sme,+sme-i16i64,+bf16", 570},
{"sme", AArch64::AEK_SME, "+sme", "-sme", FEAT_SME, "+sme,+bf16", 430},
Expand Down Expand Up @@ -302,7 +302,7 @@ inline constexpr ExtensionInfo Extensions[] = {
{"ssve-fp8dot4", AArch64::AEK_SSVE_FP8DOT4, "+ssve-fp8dot4", "-ssve-fp8dot4", FEAT_INIT, "+sme2", 0},
{"lut", AArch64::AEK_LUT, "+lut", "-lut", FEAT_INIT, "", 0},
{"sme-lutv2", AArch64::AEK_SME_LUTv2, "+sme-lutv2", "-sme-lutv2", FEAT_INIT, "", 0},
{"sme-f8f16", AArch64::AEK_SMEF8F16, "+sme-f8f16", "-sme-f8f16", FEAT_INIT, "+sme2,+fp8", 0},
{"sme-f8f16", AArch64::AEK_SMEF8F16, "+sme-f8f16", "-sme-f8f16", FEAT_INIT, "+fp8,+sme2", 0},
{"sme-f8f32", AArch64::AEK_SMEF8F32, "+sme-f8f32", "-sme-f8f32", FEAT_INIT, "+sme2,+fp8", 0},
{"sme-fa64", AArch64::AEK_SMEFA64, "+sme-fa64", "-sme-fa64", FEAT_INIT, "", 0},
{"cpa", AArch64::AEK_CPA, "+cpa", "-cpa", FEAT_INIT, "", 0},
Expand Down Expand Up @@ -677,6 +677,13 @@ inline constexpr CpuInfo CpuInfos[] = {
AArch64::AEK_FP16FML, AArch64::AEK_I8MM, AArch64::AEK_MTE,
AArch64::AEK_SB, AArch64::AEK_SSBS, AArch64::AEK_SVE,
AArch64::AEK_SVE2, AArch64::AEK_SVE2BITPERM})},
{"neoverse-n3", ARMV9_2A,
AArch64::ExtensionBitset({AArch64::AEK_MTE, AArch64::AEK_SSBS,
AArch64::AEK_SB, AArch64::AEK_PREDRES,
AArch64::AEK_FP16FML, AArch64::AEK_PAUTH,
AArch64::AEK_FLAGM, AArch64::AEK_PERFMON,
AArch64::AEK_RAND, AArch64::AEK_SVE2BITPERM,
AArch64::AEK_PROFILE, AArch64::AEK_PERFMON})},
{"neoverse-512tvb", ARMV8_4A,
AArch64::ExtensionBitset(
{AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_SHA3,
Expand All @@ -697,6 +704,20 @@ inline constexpr CpuInfo CpuInfos[] = {
AArch64::AEK_FP16, AArch64::AEK_BF16, AArch64::AEK_RAND,
AArch64::AEK_DOTPROD, AArch64::AEK_PROFILE, AArch64::AEK_SVE2BITPERM,
AArch64::AEK_FP16FML, AArch64::AEK_I8MM, AArch64::AEK_MTE})},
{"neoverse-v3", ARMV9_2A,
AArch64::ExtensionBitset(
{AArch64::AEK_PROFILE, AArch64::AEK_MTE, AArch64::AEK_SSBS,
AArch64::AEK_SB, AArch64::AEK_PREDRES, AArch64::AEK_LS64,
AArch64::AEK_BRBE, AArch64::AEK_PAUTH, AArch64::AEK_FLAGM,
AArch64::AEK_PERFMON, AArch64::AEK_RAND, AArch64::AEK_SVE2BITPERM,
AArch64::AEK_FP16FML})},
{"neoverse-v3ae", ARMV9_2A,
(AArch64::ExtensionBitset(
{AArch64::AEK_PROFILE, AArch64::AEK_MTE, AArch64::AEK_SSBS,
AArch64::AEK_SB, AArch64::AEK_PREDRES, AArch64::AEK_LS64,
AArch64::AEK_BRBE, AArch64::AEK_PAUTH, AArch64::AEK_FLAGM,
AArch64::AEK_PERFMON, AArch64::AEK_RAND, AArch64::AEK_SVE2BITPERM,
AArch64::AEK_FP16FML}))},
{"cyclone", ARMV8A,
AArch64::ExtensionBitset(
{AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_NONE})},
Expand Down
14 changes: 5 additions & 9 deletions llvm/include/llvm/TargetParser/RISCVISAInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,7 @@ class RISCVISAInfo {
RISCVISAInfo(const RISCVISAInfo &) = delete;
RISCVISAInfo &operator=(const RISCVISAInfo &) = delete;

/// OrderedExtensionMap is std::map, it's specialized to keep entries
/// in canonical order of extension.
typedef std::map<std::string, RISCVISAUtils::ExtensionVersion,
RISCVISAUtils::ExtensionComparator>
OrderedExtensionMap;

RISCVISAInfo(unsigned XLen, OrderedExtensionMap &Exts)
RISCVISAInfo(unsigned XLen, RISCVISAUtils::OrderedExtensionMap &Exts)
: XLen(XLen), FLen(0), MinVLen(0), MaxELen(0), MaxELenFp(0), Exts(Exts) {}

/// Parse RISC-V ISA info from arch string.
Expand All @@ -59,7 +53,9 @@ class RISCVISAInfo {
std::vector<std::string> toFeatures(bool AddAllExtensions = false,
bool IgnoreUnknown = true) const;

const OrderedExtensionMap &getExtensions() const { return Exts; }
const RISCVISAUtils::OrderedExtensionMap &getExtensions() const {
return Exts;
}

unsigned getXLen() const { return XLen; }
unsigned getFLen() const { return FLen; }
Expand Down Expand Up @@ -90,7 +86,7 @@ class RISCVISAInfo {
unsigned MinVLen;
unsigned MaxELen, MaxELenFp;

OrderedExtensionMap Exts;
RISCVISAUtils::OrderedExtensionMap Exts;

void addExtension(StringRef ExtName, RISCVISAUtils::ExtensionVersion Version);

Expand Down
111 changes: 60 additions & 51 deletions llvm/include/llvm/Transforms/Scalar/GVN.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,13 +232,67 @@ class GVNPass : public PassInfoMixin<GVNPass> {

/// A mapping from value numbers to lists of Value*'s that
/// have that value number. Use findLeader to query it.
struct LeaderTableEntry {
Value *Val;
const BasicBlock *BB;
LeaderTableEntry *Next;
class LeaderMap {
public:
struct LeaderTableEntry {
Value *Val;
const BasicBlock *BB;
};

private:
struct LeaderListNode {
LeaderTableEntry Entry;
LeaderListNode *Next;
};
DenseMap<uint32_t, LeaderListNode> NumToLeaders;
BumpPtrAllocator TableAllocator;

public:
class leader_iterator {
const LeaderListNode *Current;

public:
using iterator_category = std::forward_iterator_tag;
using value_type = const LeaderTableEntry;
using difference_type = std::ptrdiff_t;
using pointer = value_type *;
using reference = value_type &;

leader_iterator(const LeaderListNode *C) : Current(C) {}
leader_iterator &operator++() {
assert(Current && "Dereferenced end of leader list!");
Current = Current->Next;
return *this;
}
bool operator==(const leader_iterator &Other) const {
return Current == Other.Current;
}
bool operator!=(const leader_iterator &Other) const {
return Current != Other.Current;
}
reference operator*() const { return Current->Entry; }
};

iterator_range<leader_iterator> getLeaders(uint32_t N) {
auto I = NumToLeaders.find(N);
if (I == NumToLeaders.end()) {
return iterator_range(leader_iterator(nullptr),
leader_iterator(nullptr));
}

return iterator_range(leader_iterator(&I->second),
leader_iterator(nullptr));
}

void insert(uint32_t N, Value *V, const BasicBlock *BB);
void erase(uint32_t N, Instruction *I, const BasicBlock *BB);
void verifyRemoved(const Value *Inst) const;
void clear() {
NumToLeaders.clear();
TableAllocator.Reset();
}
};
DenseMap<uint32_t, LeaderTableEntry> LeaderTable;
BumpPtrAllocator TableAllocator;
LeaderMap LeaderTable;

// Block-local map of equivalent values to their leader, does not
// propagate to any successors. Entries added mid-block are applied
Expand All @@ -264,51 +318,6 @@ class GVNPass : public PassInfoMixin<GVNPass> {
MemoryDependenceResults *RunMD, LoopInfo &LI,
OptimizationRemarkEmitter *ORE, MemorySSA *MSSA = nullptr);

/// Push a new Value to the LeaderTable onto the list for its value number.
void addToLeaderTable(uint32_t N, Value *V, const BasicBlock *BB) {
LeaderTableEntry &Curr = LeaderTable[N];
if (!Curr.Val) {
Curr.Val = V;
Curr.BB = BB;
return;
}

LeaderTableEntry *Node = TableAllocator.Allocate<LeaderTableEntry>();
Node->Val = V;
Node->BB = BB;
Node->Next = Curr.Next;
Curr.Next = Node;
}

/// Scan the list of values corresponding to a given
/// value number, and remove the given instruction if encountered.
void removeFromLeaderTable(uint32_t N, Instruction *I, BasicBlock *BB) {
LeaderTableEntry *Prev = nullptr;
LeaderTableEntry *Curr = &LeaderTable[N];

while (Curr && (Curr->Val != I || Curr->BB != BB)) {
Prev = Curr;
Curr = Curr->Next;
}

if (!Curr)
return;

if (Prev) {
Prev->Next = Curr->Next;
} else {
if (!Curr->Next) {
Curr->Val = nullptr;
Curr->BB = nullptr;
} else {
LeaderTableEntry *Next = Curr->Next;
Curr->Val = Next->Val;
Curr->BB = Next->BB;
Curr->Next = Next->Next;
}
}
}

// List of critical edges to be split between iterations.
SmallVector<std::pair<Instruction *, unsigned>, 4> toSplit;

Expand Down
10 changes: 5 additions & 5 deletions llvm/include/llvm/Transforms/Scalar/JumpThreading.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "llvm/Analysis/BranchProbabilityInfo.h"
#include "llvm/Analysis/DomTreeUpdater.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
#include <optional>
#include <utility>

Expand Down Expand Up @@ -114,11 +115,10 @@ class JumpThreadingPass : public PassInfoMixin<JumpThreadingPass> {
bool processBlock(BasicBlock *BB);
bool maybeMergeBasicBlockIntoOnlyPred(BasicBlock *BB);
void updateSSA(BasicBlock *BB, BasicBlock *NewBB,
DenseMap<Instruction *, Value *> &ValueMapping);
DenseMap<Instruction *, Value *> cloneInstructions(BasicBlock::iterator BI,
BasicBlock::iterator BE,
BasicBlock *NewBB,
BasicBlock *PredBB);
ValueToValueMapTy &ValueMapping);
void cloneInstructions(ValueToValueMapTy &ValueMapping,
BasicBlock::iterator BI, BasicBlock::iterator BE,
BasicBlock *NewBB, BasicBlock *PredBB);
bool tryThreadEdge(BasicBlock *BB,
const SmallVectorImpl<BasicBlock *> &PredBBs,
BasicBlock *SuccBB);
Expand Down
5 changes: 5 additions & 0 deletions llvm/include/llvm/Transforms/Utils/Local.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "llvm/IR/Dominators.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Transforms/Utils/SimplifyCFGOptions.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
#include <cstdint>

namespace llvm {
Expand Down Expand Up @@ -490,6 +491,10 @@ void hoistAllInstructionsInto(BasicBlock *DomBlock, Instruction *InsertPt,
DIExpression *getExpressionForConstant(DIBuilder &DIB, const Constant &C,
Type &Ty);

/// Remap the operands of the debug records attached to \p Inst, and the
/// operands of \p Inst itself if it's a debug intrinsic.
void remapDebugVariable(ValueToValueMapTy &Mapping, Instruction *Inst);

//===----------------------------------------------------------------------===//
// Intrinsic pattern matching
//
Expand Down
Loading