10b57cec5SDimitry Andric //===--- Stack.h - Utilities for dealing with stack space -------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric /// 90b57cec5SDimitry Andric /// \file 100b57cec5SDimitry Andric /// Defines utilities for dealing with stack allocation and stack space. 110b57cec5SDimitry Andric /// 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #ifndef LLVM_CLANG_BASIC_STACK_H 150b57cec5SDimitry Andric #define LLVM_CLANG_BASIC_STACK_H 160b57cec5SDimitry Andric 170b57cec5SDimitry Andric #include <cstddef> 180b57cec5SDimitry Andric 19a7dea167SDimitry Andric #include "llvm/ADT/STLExtras.h" 20a7dea167SDimitry Andric #include "llvm/Support/Compiler.h" 21a7dea167SDimitry Andric 220b57cec5SDimitry Andric namespace clang { 230b57cec5SDimitry Andric /// The amount of stack space that Clang would like to be provided with. 240b57cec5SDimitry Andric /// If less than this much is available, we may be unable to reach our 250b57cec5SDimitry Andric /// template instantiation depth limit and other similar limits. 260b57cec5SDimitry Andric constexpr size_t DesiredStackSize = 8 << 20; 27a7dea167SDimitry Andric 28a7dea167SDimitry Andric /// Call this once on each thread, as soon after starting the thread as 29a7dea167SDimitry Andric /// feasible, to note the approximate address of the bottom of the stack. 30a7dea167SDimitry Andric void noteBottomOfStack(); 31a7dea167SDimitry Andric 32a7dea167SDimitry Andric /// Determine whether the stack is nearly exhausted. 33a7dea167SDimitry Andric bool isStackNearlyExhausted(); 34a7dea167SDimitry Andric 35a7dea167SDimitry Andric void runWithSufficientStackSpaceSlow(llvm::function_ref<void()> Diag, 36a7dea167SDimitry Andric llvm::function_ref<void()> Fn); 37a7dea167SDimitry Andric 38a7dea167SDimitry Andric /// Run a given function on a stack with "sufficient" space. If stack space 39a7dea167SDimitry Andric /// is insufficient, calls Diag to emit a diagnostic before calling Fn. runWithSufficientStackSpace(llvm::function_ref<void ()> Diag,llvm::function_ref<void ()> Fn)40a7dea167SDimitry Andric inline void runWithSufficientStackSpace(llvm::function_ref<void()> Diag, 41a7dea167SDimitry Andric llvm::function_ref<void()> Fn) { 42*349cc55cSDimitry Andric #if LLVM_ENABLE_THREADS 43a7dea167SDimitry Andric if (LLVM_UNLIKELY(isStackNearlyExhausted())) 44a7dea167SDimitry Andric runWithSufficientStackSpaceSlow(Diag, Fn); 45a7dea167SDimitry Andric else 46a7dea167SDimitry Andric Fn(); 47a7dea167SDimitry Andric #else 48a7dea167SDimitry Andric if (LLVM_UNLIKELY(isStackNearlyExhausted())) 49a7dea167SDimitry Andric Diag(); 50a7dea167SDimitry Andric Fn(); 51a7dea167SDimitry Andric #endif 52a7dea167SDimitry Andric } 530b57cec5SDimitry Andric } // end namespace clang 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric #endif // LLVM_CLANG_BASIC_STACK_H 56