return "";
}
-/* Update the maximum stack slot alignment from memory alignment in
- PAT. */
-
-static void
-ix86_update_stack_alignment (rtx, const_rtx pat, void *data)
-{
- /* This insn may reference stack slot. Update the maximum stack slot
- alignment. */
- subrtx_iterator::array_type array;
- FOR_EACH_SUBRTX (iter, array, pat, ALL)
- if (MEM_P (*iter))
- {
- unsigned int alignment = MEM_ALIGN (*iter);
- unsigned int *stack_alignment
- = (unsigned int *) data;
- if (alignment > *stack_alignment)
- *stack_alignment = alignment;
- break;
- }
-}
-
-/* Helper function for ix86_find_all_reg_use. */
-
-static void
-ix86_find_all_reg_use_1 (rtx set, HARD_REG_SET &stack_slot_access,
- auto_bitmap &worklist)
-{
- rtx dest = SET_DEST (set);
- if (!REG_P (dest))
- return;
-
- rtx src = SET_SRC (set);
- if (MEM_P (src) || CONST_SCALAR_INT_P (src))
- return;
-
- if (TEST_HARD_REG_BIT (stack_slot_access, REGNO (dest)))
- return;
-
- /* Add this register to stack_slot_access. */
- add_to_hard_reg_set (&stack_slot_access, Pmode, REGNO (dest));
- bitmap_set_bit (worklist, REGNO (dest));
-}
-
-/* Find all registers defined with REG. */
-
-static void
-ix86_find_all_reg_use (HARD_REG_SET &stack_slot_access,
- unsigned int reg, auto_bitmap &worklist)
-{
- for (df_ref ref = DF_REG_USE_CHAIN (reg);
- ref != NULL;
- ref = DF_REF_NEXT_REG (ref))
- {
- if (DF_REF_IS_ARTIFICIAL (ref))
- continue;
-
- rtx_insn *insn = DF_REF_INSN (ref);
-
- if (!NONJUMP_INSN_P (insn))
- continue;
-
- rtx set = single_set (insn);
- if (set)
- ix86_find_all_reg_use_1 (set, stack_slot_access, worklist);
-
- rtx pat = PATTERN (insn);
- if (GET_CODE (pat) != PARALLEL)
- continue;
-
- for (int i = 0; i < XVECLEN (pat, 0); i++)
- {
- rtx exp = XVECEXP (pat, 0, i);
- switch (GET_CODE (exp))
- {
- case ASM_OPERANDS:
- case CLOBBER:
- case PREFETCH:
- case USE:
- break;
- case UNSPEC:
- case UNSPEC_VOLATILE:
- for (int j = XVECLEN (exp, 0) - 1; j >= 0; j--)
- {
- rtx x = XVECEXP (exp, 0, j);
- if (GET_CODE (x) == SET)
- ix86_find_all_reg_use_1 (x, stack_slot_access,
- worklist);
- }
- break;
- case SET:
- ix86_find_all_reg_use_1 (exp, stack_slot_access,
- worklist);
- break;
- default:
- gcc_unreachable ();
- break;
- }
- }
- }
-}
-
/* Set stack_frame_required to false if stack frame isn't required.
Update STACK_ALIGNMENT to the largest alignment, in bits, of stack
slot used if stack frame is required and CHECK_STACK_SLOT is true. */
add_to_hard_reg_set (&set_up_by_prologue, Pmode,
HARD_FRAME_POINTER_REGNUM);
+ /* The preferred stack alignment is the minimum stack alignment. */
+ if (stack_alignment > crtl->preferred_stack_boundary)
+ stack_alignment = crtl->preferred_stack_boundary;
+
bool require_stack_frame = false;
FOR_EACH_BB_FN (bb, cfun)
set_up_by_prologue))
{
require_stack_frame = true;
- break;
+
+ if (check_stack_slot)
+ {
+ /* Find the maximum stack alignment. */
+ subrtx_iterator::array_type array;
+ FOR_EACH_SUBRTX (iter, array, PATTERN (insn), ALL)
+ if (MEM_P (*iter)
+ && (reg_mentioned_p (stack_pointer_rtx,
+ *iter)
+ || reg_mentioned_p (frame_pointer_rtx,
+ *iter)))
+ {
+ unsigned int alignment = MEM_ALIGN (*iter);
+ if (alignment > stack_alignment)
+ stack_alignment = alignment;
+ }
+ }
}
}
cfun->machine->stack_frame_required = require_stack_frame;
-
- /* Stop if we don't need to check stack slot. */
- if (!check_stack_slot)
- return;
-
- /* The preferred stack alignment is the minimum stack alignment. */
- if (stack_alignment > crtl->preferred_stack_boundary)
- stack_alignment = crtl->preferred_stack_boundary;
-
- HARD_REG_SET stack_slot_access;
- CLEAR_HARD_REG_SET (stack_slot_access);
-
- /* Stack slot can be accessed by stack pointer, frame pointer or
- registers defined by stack pointer or frame pointer. */
- auto_bitmap worklist;
-
- add_to_hard_reg_set (&stack_slot_access, Pmode,
- STACK_POINTER_REGNUM);
- bitmap_set_bit (worklist, STACK_POINTER_REGNUM);
-
- if (frame_pointer_needed)
- {
- add_to_hard_reg_set (&stack_slot_access, Pmode,
- HARD_FRAME_POINTER_REGNUM);
- bitmap_set_bit (worklist, HARD_FRAME_POINTER_REGNUM);
- }
-
- unsigned int reg;
-
- do
- {
- reg = bitmap_clear_first_set_bit (worklist);
- ix86_find_all_reg_use (stack_slot_access, reg, worklist);
- }
- while (!bitmap_empty_p (worklist));
-
- hard_reg_set_iterator hrsi;
-
- EXECUTE_IF_SET_IN_HARD_REG_SET (stack_slot_access, 0, reg, hrsi)
- for (df_ref ref = DF_REG_USE_CHAIN (reg);
- ref != NULL;
- ref = DF_REF_NEXT_REG (ref))
- {
- if (DF_REF_IS_ARTIFICIAL (ref))
- continue;
-
- rtx_insn *insn = DF_REF_INSN (ref);
-
- if (!NONJUMP_INSN_P (insn))
- continue;
-
- note_stores (insn, ix86_update_stack_alignment,
- &stack_alignment);
- }
}
/* Finalize stack_realign_needed and frame_pointer_needed flags, which
+++ /dev/null
-/* { dg-do compile } */
-/* { dg-require-effective-target c++17 } */
-/* { dg-options "-O2 -mavx2 -mtune=haswell" } */
-
-template <typename _Tp> struct remove_reference {
- using type = __remove_reference(_Tp);
-};
-template <typename T> struct MaybeStorageBase {
- T val;
- struct Union {
- ~Union();
- } mStorage;
-};
-template <typename T> struct MaybeStorage : MaybeStorageBase<T> {
- char mIsSome;
-};
-template <typename T, typename U = typename remove_reference<T>::type>
-constexpr MaybeStorage<U> Some(T &&);
-template <typename T, typename U> constexpr MaybeStorage<U> Some(T &&aValue) {
- return {aValue};
-}
-template <class> struct Span {
- int operator[](long idx) {
- int *__trans_tmp_4;
- if (__builtin_expect(idx, 0))
- *(int *)__null = false;
- __trans_tmp_4 = storage_.data();
- return __trans_tmp_4[idx];
- }
- struct {
- int *data() { return data_; }
- int *data_;
- } storage_;
-};
-struct Variant {
- template <typename RefT> Variant(RefT) {}
-};
-long from_i, from___trans_tmp_9;
-namespace js::intl {
-struct DecimalNumber {
- Variant string_;
- unsigned long significandStart_;
- unsigned long significandEnd_;
- bool zero_ = false;
- bool negative_;
- template <typename CharT> DecimalNumber(CharT string) : string_(string) {}
- template <typename CharT>
- static MaybeStorage<DecimalNumber> from(Span<const CharT>);
- void from();
-};
-} // namespace js::intl
-void js::intl::DecimalNumber::from() {
- Span<const char16_t> __trans_tmp_3;
- from(__trans_tmp_3);
-}
-template <typename CharT>
-MaybeStorage<js::intl::DecimalNumber>
-js::intl::DecimalNumber::from(Span<const CharT> chars) {
- DecimalNumber number(chars);
- if (auto ch = chars[from_i]) {
- from_i++;
- number.negative_ = ch == '-';
- }
- while (from___trans_tmp_9 && chars[from_i])
- ;
- if (chars[from_i])
- while (chars[from_i - 1])
- number.zero_ = true;
- return Some(number);
-}
-
-/* { dg-final { scan-assembler-not "and\[lq\]?\[^\\n\]*-32,\[^\\n\]*sp" } } */