mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 20:23:11 +01:00
[MC] Function stack size section.
Summary: Original RFC: http://lists.llvm.org/pipermail/llvm-dev/2017-August/117028.html I wasn't sure who to put as reviewers, so please add/remove people as appropriate. This change adds a '.stack-size' section containing metadata on function stack sizes to output ELF files behind the new -stack-size-section flag. The section contains pairs of function symbol references (8 byte) and stack sizes (unsigned LEB128). The contents of this section can be used to measure changes to stack sizes between different versions of the compiler or a source base. The advantage of having a section is that we can extract this information when examining binaries that we didn't build, and it allows users and tools easy access to that information just by referencing the binary. There is a follow up change to add an option to clang. Thanks. Reviewers: hfinkel, MatzeB Reviewed By: MatzeB Subscribers: thegameg, asb, llvm-commits Differential Revision: https://reviews.llvm.org/D39788 llvm-svn: 319423
This commit is contained in:
parent
86faf1fe64
commit
4b5d214bc5
File diff suppressed because it is too large
Load Diff
@ -1,196 +1,204 @@
|
||||
llc - LLVM static compiler
|
||||
==========================
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
|
||||
:program:`llc` [*options*] [*filename*]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
||||
The :program:`llc` command compiles LLVM source inputs into assembly language
|
||||
for a specified architecture. The assembly language output can then be passed
|
||||
through a native assembler and linker to generate a native executable.
|
||||
|
||||
The choice of architecture for the output assembly code is automatically
|
||||
determined from the input file, unless the :option:`-march` option is used to
|
||||
override the default.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
|
||||
If ``filename`` is "``-``" or omitted, :program:`llc` reads from standard input.
|
||||
Otherwise, it will from ``filename``. Inputs can be in either the LLVM assembly
|
||||
language format (``.ll``) or the LLVM bitcode format (``.bc``).
|
||||
|
||||
If the :option:`-o` option is omitted, then :program:`llc` will send its output
|
||||
to standard output if the input is from standard input. If the :option:`-o`
|
||||
option specifies "``-``", then the output will also be sent to standard output.
|
||||
|
||||
If no :option:`-o` option is specified and an input file other than "``-``" is
|
||||
specified, then :program:`llc` creates the output filename by taking the input
|
||||
filename, removing any existing ``.bc`` extension, and adding a ``.s`` suffix.
|
||||
|
||||
Other :program:`llc` options are described below.
|
||||
|
||||
End-user Options
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
.. option:: -help
|
||||
|
||||
Print a summary of command line options.
|
||||
|
||||
.. option:: -O=uint
|
||||
|
||||
Generate code at different optimization levels. These correspond to the
|
||||
``-O0``, ``-O1``, ``-O2``, and ``-O3`` optimization levels used by
|
||||
:program:`clang`.
|
||||
|
||||
.. option:: -mtriple=<target triple>
|
||||
|
||||
Override the target triple specified in the input file with the specified
|
||||
string.
|
||||
|
||||
.. option:: -march=<arch>
|
||||
|
||||
Specify the architecture for which to generate assembly, overriding the target
|
||||
encoded in the input file. See the output of ``llc -help`` for a list of
|
||||
valid architectures. By default this is inferred from the target triple or
|
||||
autodetected to the current architecture.
|
||||
|
||||
.. option:: -mcpu=<cpuname>
|
||||
|
||||
Specify a specific chip in the current architecture to generate code for.
|
||||
By default this is inferred from the target triple and autodetected to
|
||||
the current architecture. For a list of available CPUs, use:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
llvm-as < /dev/null | llc -march=xyz -mcpu=help
|
||||
|
||||
.. option:: -filetype=<output file type>
|
||||
|
||||
Specify what kind of output ``llc`` should generated. Options are: ``asm``
|
||||
for textual assembly ( ``'.s'``), ``obj`` for native object files (``'.o'``)
|
||||
and ``null`` for not emitting anything (for performance testing).
|
||||
|
||||
Note that not all targets support all options.
|
||||
|
||||
.. option:: -mattr=a1,+a2,-a3,...
|
||||
|
||||
Override or control specific attributes of the target, such as whether SIMD
|
||||
operations are enabled or not. The default set of attributes is set by the
|
||||
current CPU. For a list of available attributes, use:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
llvm-as < /dev/null | llc -march=xyz -mattr=help
|
||||
|
||||
.. option:: --disable-fp-elim
|
||||
|
||||
Disable frame pointer elimination optimization.
|
||||
|
||||
.. option:: --disable-excess-fp-precision
|
||||
|
||||
Disable optimizations that may produce excess precision for floating point.
|
||||
Note that this option can dramatically slow down code on some systems
|
||||
(e.g. X86).
|
||||
|
||||
.. option:: --enable-no-infs-fp-math
|
||||
|
||||
Enable optimizations that assume no Inf values.
|
||||
|
||||
.. option:: --enable-no-nans-fp-math
|
||||
|
||||
Enable optimizations that assume no NAN values.
|
||||
|
||||
.. option:: --enable-unsafe-fp-math
|
||||
|
||||
Enable optimizations that make unsafe assumptions about IEEE math (e.g. that
|
||||
addition is associative) or may not work for all input ranges. These
|
||||
optimizations allow the code generator to make use of some instructions which
|
||||
would otherwise not be usable (such as ``fsin`` on X86).
|
||||
|
||||
.. option:: --stats
|
||||
|
||||
Print statistics recorded by code-generation passes.
|
||||
|
||||
.. option:: --time-passes
|
||||
|
||||
Record the amount of time needed for each pass and print a report to standard
|
||||
error.
|
||||
|
||||
.. option:: --load=<dso_path>
|
||||
|
||||
Dynamically load ``dso_path`` (a path to a dynamically shared object) that
|
||||
implements an LLVM target. This will permit the target name to be used with
|
||||
the :option:`-march` option so that code can be generated for that target.
|
||||
|
||||
.. option:: -meabi=[default|gnu|4|5]
|
||||
|
||||
Specify which EABI version should conform to. Valid EABI versions are *gnu*,
|
||||
*4* and *5*. Default value (*default*) depends on the triple.
|
||||
|
||||
|
||||
Tuning/Configuration Options
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. option:: --print-machineinstrs
|
||||
|
||||
Print generated machine code between compilation phases (useful for debugging).
|
||||
|
||||
.. option:: --regalloc=<allocator>
|
||||
|
||||
Specify the register allocator to use.
|
||||
Valid register allocators are:
|
||||
|
||||
*basic*
|
||||
|
||||
Basic register allocator.
|
||||
|
||||
*fast*
|
||||
|
||||
Fast register allocator. It is the default for unoptimized code.
|
||||
|
||||
*greedy*
|
||||
|
||||
Greedy register allocator. It is the default for optimized code.
|
||||
|
||||
*pbqp*
|
||||
|
||||
Register allocator based on 'Partitioned Boolean Quadratic Programming'.
|
||||
|
||||
.. option:: --spiller=<spiller>
|
||||
|
||||
Specify the spiller to use for register allocators that support it. Currently
|
||||
this option is used only by the linear scan register allocator. The default
|
||||
``spiller`` is *local*. Valid spillers are:
|
||||
|
||||
*simple*
|
||||
|
||||
Simple spiller
|
||||
|
||||
*local*
|
||||
|
||||
Local spiller
|
||||
|
||||
Intel IA-32-specific Options
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. option:: --x86-asm-syntax=[att|intel]
|
||||
|
||||
Specify whether to emit assembly code in AT&T syntax (the default) or Intel
|
||||
syntax.
|
||||
|
||||
EXIT STATUS
|
||||
-----------
|
||||
|
||||
If :program:`llc` succeeds, it will exit with 0. Otherwise, if an error
|
||||
occurs, it will exit with a non-zero value.
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
|
||||
lli
|
||||
|
||||
llc - LLVM static compiler
|
||||
==========================
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
|
||||
:program:`llc` [*options*] [*filename*]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
||||
The :program:`llc` command compiles LLVM source inputs into assembly language
|
||||
for a specified architecture. The assembly language output can then be passed
|
||||
through a native assembler and linker to generate a native executable.
|
||||
|
||||
The choice of architecture for the output assembly code is automatically
|
||||
determined from the input file, unless the :option:`-march` option is used to
|
||||
override the default.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
|
||||
If ``filename`` is "``-``" or omitted, :program:`llc` reads from standard input.
|
||||
Otherwise, it will from ``filename``. Inputs can be in either the LLVM assembly
|
||||
language format (``.ll``) or the LLVM bitcode format (``.bc``).
|
||||
|
||||
If the :option:`-o` option is omitted, then :program:`llc` will send its output
|
||||
to standard output if the input is from standard input. If the :option:`-o`
|
||||
option specifies "``-``", then the output will also be sent to standard output.
|
||||
|
||||
If no :option:`-o` option is specified and an input file other than "``-``" is
|
||||
specified, then :program:`llc` creates the output filename by taking the input
|
||||
filename, removing any existing ``.bc`` extension, and adding a ``.s`` suffix.
|
||||
|
||||
Other :program:`llc` options are described below.
|
||||
|
||||
End-user Options
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
.. option:: -help
|
||||
|
||||
Print a summary of command line options.
|
||||
|
||||
.. option:: -O=uint
|
||||
|
||||
Generate code at different optimization levels. These correspond to the
|
||||
``-O0``, ``-O1``, ``-O2``, and ``-O3`` optimization levels used by
|
||||
:program:`clang`.
|
||||
|
||||
.. option:: -mtriple=<target triple>
|
||||
|
||||
Override the target triple specified in the input file with the specified
|
||||
string.
|
||||
|
||||
.. option:: -march=<arch>
|
||||
|
||||
Specify the architecture for which to generate assembly, overriding the target
|
||||
encoded in the input file. See the output of ``llc -help`` for a list of
|
||||
valid architectures. By default this is inferred from the target triple or
|
||||
autodetected to the current architecture.
|
||||
|
||||
.. option:: -mcpu=<cpuname>
|
||||
|
||||
Specify a specific chip in the current architecture to generate code for.
|
||||
By default this is inferred from the target triple and autodetected to
|
||||
the current architecture. For a list of available CPUs, use:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
llvm-as < /dev/null | llc -march=xyz -mcpu=help
|
||||
|
||||
.. option:: -filetype=<output file type>
|
||||
|
||||
Specify what kind of output ``llc`` should generated. Options are: ``asm``
|
||||
for textual assembly ( ``'.s'``), ``obj`` for native object files (``'.o'``)
|
||||
and ``null`` for not emitting anything (for performance testing).
|
||||
|
||||
Note that not all targets support all options.
|
||||
|
||||
.. option:: -mattr=a1,+a2,-a3,...
|
||||
|
||||
Override or control specific attributes of the target, such as whether SIMD
|
||||
operations are enabled or not. The default set of attributes is set by the
|
||||
current CPU. For a list of available attributes, use:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
llvm-as < /dev/null | llc -march=xyz -mattr=help
|
||||
|
||||
.. option:: --disable-fp-elim
|
||||
|
||||
Disable frame pointer elimination optimization.
|
||||
|
||||
.. option:: --disable-excess-fp-precision
|
||||
|
||||
Disable optimizations that may produce excess precision for floating point.
|
||||
Note that this option can dramatically slow down code on some systems
|
||||
(e.g. X86).
|
||||
|
||||
.. option:: --enable-no-infs-fp-math
|
||||
|
||||
Enable optimizations that assume no Inf values.
|
||||
|
||||
.. option:: --enable-no-nans-fp-math
|
||||
|
||||
Enable optimizations that assume no NAN values.
|
||||
|
||||
.. option:: --enable-unsafe-fp-math
|
||||
|
||||
Enable optimizations that make unsafe assumptions about IEEE math (e.g. that
|
||||
addition is associative) or may not work for all input ranges. These
|
||||
optimizations allow the code generator to make use of some instructions which
|
||||
would otherwise not be usable (such as ``fsin`` on X86).
|
||||
|
||||
.. option:: --stats
|
||||
|
||||
Print statistics recorded by code-generation passes.
|
||||
|
||||
.. option:: --time-passes
|
||||
|
||||
Record the amount of time needed for each pass and print a report to standard
|
||||
error.
|
||||
|
||||
.. option:: --load=<dso_path>
|
||||
|
||||
Dynamically load ``dso_path`` (a path to a dynamically shared object) that
|
||||
implements an LLVM target. This will permit the target name to be used with
|
||||
the :option:`-march` option so that code can be generated for that target.
|
||||
|
||||
.. option:: -meabi=[default|gnu|4|5]
|
||||
|
||||
Specify which EABI version should conform to. Valid EABI versions are *gnu*,
|
||||
*4* and *5*. Default value (*default*) depends on the triple.
|
||||
|
||||
.. option:: -stack-size-section
|
||||
|
||||
Emit the .stack_sizes section which contains stack size metadata. The section
|
||||
contains an array of pairs of function symbol references (8 byte) and stack
|
||||
sizes (unsigned LEB128). The stack size values only include the space allocated
|
||||
in the function prologue. Functions with dynamic stack allocations are not
|
||||
included.
|
||||
|
||||
|
||||
Tuning/Configuration Options
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. option:: --print-machineinstrs
|
||||
|
||||
Print generated machine code between compilation phases (useful for debugging).
|
||||
|
||||
.. option:: --regalloc=<allocator>
|
||||
|
||||
Specify the register allocator to use.
|
||||
Valid register allocators are:
|
||||
|
||||
*basic*
|
||||
|
||||
Basic register allocator.
|
||||
|
||||
*fast*
|
||||
|
||||
Fast register allocator. It is the default for unoptimized code.
|
||||
|
||||
*greedy*
|
||||
|
||||
Greedy register allocator. It is the default for optimized code.
|
||||
|
||||
*pbqp*
|
||||
|
||||
Register allocator based on 'Partitioned Boolean Quadratic Programming'.
|
||||
|
||||
.. option:: --spiller=<spiller>
|
||||
|
||||
Specify the spiller to use for register allocators that support it. Currently
|
||||
this option is used only by the linear scan register allocator. The default
|
||||
``spiller`` is *local*. Valid spillers are:
|
||||
|
||||
*simple*
|
||||
|
||||
Simple spiller
|
||||
|
||||
*local*
|
||||
|
||||
Local spiller
|
||||
|
||||
Intel IA-32-specific Options
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. option:: --x86-asm-syntax=[att|intel]
|
||||
|
||||
Specify whether to emit assembly code in AT&T syntax (the default) or Intel
|
||||
syntax.
|
||||
|
||||
EXIT STATUS
|
||||
-----------
|
||||
|
||||
If :program:`llc` succeeds, it will exit with 0. Otherwise, if an error
|
||||
occurs, it will exit with a non-zero value.
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
|
||||
lli
|
||||
|
||||
|
@ -295,6 +295,8 @@ public:
|
||||
|
||||
void emitFrameAlloc(const MachineInstr &MI);
|
||||
|
||||
void emitStackSizeSection(const MachineFunction &MF);
|
||||
|
||||
enum CFIMoveType { CFI_M_None, CFI_M_EH, CFI_M_Debug };
|
||||
CFIMoveType needsCFIMoves() const;
|
||||
|
||||
|
@ -1,361 +1,366 @@
|
||||
//===-- CommandFlags.h - Command Line Flags Interface -----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains codegen-specific flags that are shared between different
|
||||
// command line tools. The tools "llc" and "opt" both use this file to prevent
|
||||
// flag duplication.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/Intrinsics.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/MC/MCTargetOptionsCommandFlags.def"
|
||||
#include "llvm/MC/SubtargetFeature.h"
|
||||
#include "llvm/Support/CodeGen.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Host.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
#include <string>
|
||||
using namespace llvm;
|
||||
|
||||
static cl::opt<std::string>
|
||||
MArch("march",
|
||||
cl::desc("Architecture to generate code for (see --version)"));
|
||||
|
||||
static cl::opt<std::string>
|
||||
MCPU("mcpu",
|
||||
cl::desc("Target a specific cpu type (-mcpu=help for details)"),
|
||||
cl::value_desc("cpu-name"), cl::init(""));
|
||||
|
||||
static cl::list<std::string>
|
||||
MAttrs("mattr", cl::CommaSeparated,
|
||||
cl::desc("Target specific attributes (-mattr=help for details)"),
|
||||
cl::value_desc("a1,+a2,-a3,..."));
|
||||
|
||||
static cl::opt<Reloc::Model> RelocModel(
|
||||
"relocation-model", cl::desc("Choose relocation model"),
|
||||
cl::values(
|
||||
clEnumValN(Reloc::Static, "static", "Non-relocatable code"),
|
||||
clEnumValN(Reloc::PIC_, "pic",
|
||||
"Fully relocatable, position independent code"),
|
||||
clEnumValN(Reloc::DynamicNoPIC, "dynamic-no-pic",
|
||||
"Relocatable external references, non-relocatable code"),
|
||||
clEnumValN(Reloc::ROPI, "ropi",
|
||||
"Code and read-only data relocatable, accessed PC-relative"),
|
||||
clEnumValN(
|
||||
Reloc::RWPI, "rwpi",
|
||||
"Read-write data relocatable, accessed relative to static base"),
|
||||
clEnumValN(Reloc::ROPI_RWPI, "ropi-rwpi",
|
||||
"Combination of ropi and rwpi")));
|
||||
|
||||
LLVM_ATTRIBUTE_UNUSED static Optional<Reloc::Model> getRelocModel() {
|
||||
if (RelocModel.getNumOccurrences()) {
|
||||
Reloc::Model R = RelocModel;
|
||||
return R;
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
static cl::opt<ThreadModel::Model> TMModel(
|
||||
"thread-model", cl::desc("Choose threading model"),
|
||||
cl::init(ThreadModel::POSIX),
|
||||
cl::values(clEnumValN(ThreadModel::POSIX, "posix", "POSIX thread model"),
|
||||
clEnumValN(ThreadModel::Single, "single",
|
||||
"Single thread model")));
|
||||
|
||||
static cl::opt<llvm::CodeModel::Model> CMModel(
|
||||
"code-model", cl::desc("Choose code model"),
|
||||
cl::values(clEnumValN(CodeModel::Small, "small", "Small code model"),
|
||||
clEnumValN(CodeModel::Kernel, "kernel", "Kernel code model"),
|
||||
clEnumValN(CodeModel::Medium, "medium", "Medium code model"),
|
||||
clEnumValN(CodeModel::Large, "large", "Large code model")));
|
||||
|
||||
LLVM_ATTRIBUTE_UNUSED static Optional<CodeModel::Model> getCodeModel() {
|
||||
if (CMModel.getNumOccurrences()) {
|
||||
CodeModel::Model M = CMModel;
|
||||
return M;
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
static cl::opt<llvm::ExceptionHandling> ExceptionModel(
|
||||
"exception-model", cl::desc("exception model"),
|
||||
cl::init(ExceptionHandling::None),
|
||||
cl::values(
|
||||
clEnumValN(ExceptionHandling::None, "default",
|
||||
"default exception handling model"),
|
||||
clEnumValN(ExceptionHandling::DwarfCFI, "dwarf",
|
||||
"DWARF-like CFI based exception handling"),
|
||||
clEnumValN(ExceptionHandling::SjLj, "sjlj", "SjLj exception handling"),
|
||||
clEnumValN(ExceptionHandling::ARM, "arm", "ARM EHABI exceptions"),
|
||||
clEnumValN(ExceptionHandling::WinEH, "wineh",
|
||||
"Windows exception model")));
|
||||
|
||||
static cl::opt<TargetMachine::CodeGenFileType> FileType(
|
||||
"filetype", cl::init(TargetMachine::CGFT_AssemblyFile),
|
||||
cl::desc(
|
||||
"Choose a file type (not all types are supported by all targets):"),
|
||||
cl::values(clEnumValN(TargetMachine::CGFT_AssemblyFile, "asm",
|
||||
"Emit an assembly ('.s') file"),
|
||||
clEnumValN(TargetMachine::CGFT_ObjectFile, "obj",
|
||||
"Emit a native object ('.o') file"),
|
||||
clEnumValN(TargetMachine::CGFT_Null, "null",
|
||||
"Emit nothing, for performance testing")));
|
||||
|
||||
static cl::opt<bool>
|
||||
DisableFPElim("disable-fp-elim",
|
||||
cl::desc("Disable frame pointer elimination optimization"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool> EnableUnsafeFPMath(
|
||||
"enable-unsafe-fp-math",
|
||||
cl::desc("Enable optimizations that may decrease FP precision"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool> EnableNoInfsFPMath(
|
||||
"enable-no-infs-fp-math",
|
||||
cl::desc("Enable FP math optimizations that assume no +-Infs"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool> EnableNoNaNsFPMath(
|
||||
"enable-no-nans-fp-math",
|
||||
cl::desc("Enable FP math optimizations that assume no NaNs"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool> EnableNoSignedZerosFPMath(
|
||||
"enable-no-signed-zeros-fp-math",
|
||||
cl::desc("Enable FP math optimizations that assume "
|
||||
"the sign of 0 is insignificant"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool>
|
||||
EnableNoTrappingFPMath("enable-no-trapping-fp-math",
|
||||
cl::desc("Enable setting the FP exceptions build "
|
||||
"attribute not to use exceptions"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<llvm::FPDenormal::DenormalMode> DenormalMode(
|
||||
"denormal-fp-math",
|
||||
cl::desc("Select which denormal numbers the code is permitted to require"),
|
||||
cl::init(FPDenormal::IEEE),
|
||||
cl::values(clEnumValN(FPDenormal::IEEE, "ieee",
|
||||
"IEEE 754 denormal numbers"),
|
||||
clEnumValN(FPDenormal::PreserveSign, "preserve-sign",
|
||||
"the sign of a flushed-to-zero number is preserved "
|
||||
"in the sign of 0"),
|
||||
clEnumValN(FPDenormal::PositiveZero, "positive-zero",
|
||||
"denormals are flushed to positive zero")));
|
||||
|
||||
static cl::opt<bool> EnableHonorSignDependentRoundingFPMath(
|
||||
"enable-sign-dependent-rounding-fp-math", cl::Hidden,
|
||||
cl::desc("Force codegen to assume rounding mode can change dynamically"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<llvm::FloatABI::ABIType> FloatABIForCalls(
|
||||
"float-abi", cl::desc("Choose float ABI type"), cl::init(FloatABI::Default),
|
||||
cl::values(clEnumValN(FloatABI::Default, "default",
|
||||
"Target default float ABI type"),
|
||||
clEnumValN(FloatABI::Soft, "soft",
|
||||
"Soft float ABI (implied by -soft-float)"),
|
||||
clEnumValN(FloatABI::Hard, "hard",
|
||||
"Hard float ABI (uses FP registers)")));
|
||||
|
||||
static cl::opt<llvm::FPOpFusion::FPOpFusionMode> FuseFPOps(
|
||||
"fp-contract", cl::desc("Enable aggressive formation of fused FP ops"),
|
||||
cl::init(FPOpFusion::Standard),
|
||||
cl::values(
|
||||
clEnumValN(FPOpFusion::Fast, "fast", "Fuse FP ops whenever profitable"),
|
||||
clEnumValN(FPOpFusion::Standard, "on", "Only fuse 'blessed' FP ops."),
|
||||
clEnumValN(FPOpFusion::Strict, "off",
|
||||
"Only fuse FP ops when the result won't be affected.")));
|
||||
|
||||
static cl::opt<bool> DontPlaceZerosInBSS(
|
||||
"nozero-initialized-in-bss",
|
||||
cl::desc("Don't place zero-initialized symbols into bss section"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool> EnableGuaranteedTailCallOpt(
|
||||
"tailcallopt",
|
||||
cl::desc(
|
||||
"Turn fastcc calls into tail calls by (potentially) changing ABI."),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool> DisableTailCalls("disable-tail-calls",
|
||||
cl::desc("Never emit tail calls"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool> StackSymbolOrdering("stack-symbol-ordering",
|
||||
cl::desc("Order local stack symbols."),
|
||||
cl::init(true));
|
||||
|
||||
static cl::opt<unsigned>
|
||||
OverrideStackAlignment("stack-alignment",
|
||||
cl::desc("Override default stack alignment"),
|
||||
cl::init(0));
|
||||
|
||||
static cl::opt<bool>
|
||||
StackRealign("stackrealign",
|
||||
cl::desc("Force align the stack to the minimum alignment"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<std::string> TrapFuncName(
|
||||
"trap-func", cl::Hidden,
|
||||
cl::desc("Emit a call to trap function rather than a trap instruction"),
|
||||
cl::init(""));
|
||||
|
||||
static cl::opt<bool> UseCtors("use-ctors",
|
||||
cl::desc("Use .ctors instead of .init_array."),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool> RelaxELFRelocations(
|
||||
"relax-elf-relocations",
|
||||
cl::desc("Emit GOTPCRELX/REX_GOTPCRELX instead of GOTPCREL on x86-64 ELF"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool> DataSections("data-sections",
|
||||
cl::desc("Emit data into separate sections"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool>
|
||||
FunctionSections("function-sections",
|
||||
cl::desc("Emit functions into separate sections"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool> EmulatedTLS("emulated-tls",
|
||||
cl::desc("Use emulated TLS model"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool>
|
||||
UniqueSectionNames("unique-section-names",
|
||||
cl::desc("Give unique names to every section"),
|
||||
cl::init(true));
|
||||
|
||||
static cl::opt<llvm::EABI>
|
||||
EABIVersion("meabi", cl::desc("Set EABI type (default depends on triple):"),
|
||||
cl::init(EABI::Default),
|
||||
cl::values(clEnumValN(EABI::Default, "default",
|
||||
"Triple default EABI version"),
|
||||
clEnumValN(EABI::EABI4, "4", "EABI version 4"),
|
||||
clEnumValN(EABI::EABI5, "5", "EABI version 5"),
|
||||
clEnumValN(EABI::GNU, "gnu", "EABI GNU")));
|
||||
|
||||
static cl::opt<DebuggerKind> DebuggerTuningOpt(
|
||||
"debugger-tune", cl::desc("Tune debug info for a particular debugger"),
|
||||
cl::init(DebuggerKind::Default),
|
||||
cl::values(clEnumValN(DebuggerKind::GDB, "gdb", "gdb"),
|
||||
clEnumValN(DebuggerKind::LLDB, "lldb", "lldb"),
|
||||
clEnumValN(DebuggerKind::SCE, "sce", "SCE targets (e.g. PS4)")));
|
||||
|
||||
// Common utility function tightly tied to the options listed here. Initializes
|
||||
// a TargetOptions object with CodeGen flags and returns it.
|
||||
static TargetOptions InitTargetOptionsFromCodeGenFlags() {
|
||||
TargetOptions Options;
|
||||
Options.AllowFPOpFusion = FuseFPOps;
|
||||
Options.UnsafeFPMath = EnableUnsafeFPMath;
|
||||
Options.NoInfsFPMath = EnableNoInfsFPMath;
|
||||
Options.NoNaNsFPMath = EnableNoNaNsFPMath;
|
||||
Options.NoSignedZerosFPMath = EnableNoSignedZerosFPMath;
|
||||
Options.NoTrappingFPMath = EnableNoTrappingFPMath;
|
||||
Options.FPDenormalMode = DenormalMode;
|
||||
Options.HonorSignDependentRoundingFPMathOption =
|
||||
EnableHonorSignDependentRoundingFPMath;
|
||||
if (FloatABIForCalls != FloatABI::Default)
|
||||
Options.FloatABIType = FloatABIForCalls;
|
||||
Options.NoZerosInBSS = DontPlaceZerosInBSS;
|
||||
Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt;
|
||||
Options.StackAlignmentOverride = OverrideStackAlignment;
|
||||
Options.StackSymbolOrdering = StackSymbolOrdering;
|
||||
Options.UseInitArray = !UseCtors;
|
||||
Options.RelaxELFRelocations = RelaxELFRelocations;
|
||||
Options.DataSections = DataSections;
|
||||
Options.FunctionSections = FunctionSections;
|
||||
Options.UniqueSectionNames = UniqueSectionNames;
|
||||
Options.EmulatedTLS = EmulatedTLS;
|
||||
Options.ExceptionModel = ExceptionModel;
|
||||
|
||||
Options.MCOptions = InitMCTargetOptionsFromFlags();
|
||||
|
||||
Options.ThreadModel = TMModel;
|
||||
Options.EABIVersion = EABIVersion;
|
||||
Options.DebuggerTuning = DebuggerTuningOpt;
|
||||
|
||||
return Options;
|
||||
}
|
||||
|
||||
LLVM_ATTRIBUTE_UNUSED static std::string getCPUStr() {
|
||||
// If user asked for the 'native' CPU, autodetect here. If autodection fails,
|
||||
// this will set the CPU to an empty string which tells the target to
|
||||
// pick a basic default.
|
||||
if (MCPU == "native")
|
||||
return sys::getHostCPUName();
|
||||
|
||||
return MCPU;
|
||||
}
|
||||
|
||||
LLVM_ATTRIBUTE_UNUSED static std::string getFeaturesStr() {
|
||||
SubtargetFeatures Features;
|
||||
|
||||
// If user asked for the 'native' CPU, we need to autodetect features.
|
||||
// This is necessary for x86 where the CPU might not support all the
|
||||
// features the autodetected CPU name lists in the target. For example,
|
||||
// not all Sandybridge processors support AVX.
|
||||
if (MCPU == "native") {
|
||||
StringMap<bool> HostFeatures;
|
||||
if (sys::getHostCPUFeatures(HostFeatures))
|
||||
for (auto &F : HostFeatures)
|
||||
Features.AddFeature(F.first(), F.second);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i != MAttrs.size(); ++i)
|
||||
Features.AddFeature(MAttrs[i]);
|
||||
|
||||
return Features.getString();
|
||||
}
|
||||
|
||||
/// \brief Set function attributes of functions in Module M based on CPU,
|
||||
/// Features, and command line flags.
|
||||
LLVM_ATTRIBUTE_UNUSED static void
|
||||
setFunctionAttributes(StringRef CPU, StringRef Features, Module &M) {
|
||||
for (auto &F : M) {
|
||||
auto &Ctx = F.getContext();
|
||||
AttributeList Attrs = F.getAttributes();
|
||||
AttrBuilder NewAttrs;
|
||||
|
||||
if (!CPU.empty())
|
||||
NewAttrs.addAttribute("target-cpu", CPU);
|
||||
if (!Features.empty())
|
||||
NewAttrs.addAttribute("target-features", Features);
|
||||
if (DisableFPElim.getNumOccurrences() > 0)
|
||||
NewAttrs.addAttribute("no-frame-pointer-elim",
|
||||
DisableFPElim ? "true" : "false");
|
||||
if (DisableTailCalls.getNumOccurrences() > 0)
|
||||
NewAttrs.addAttribute("disable-tail-calls",
|
||||
toStringRef(DisableTailCalls));
|
||||
if (StackRealign)
|
||||
NewAttrs.addAttribute("stackrealign");
|
||||
|
||||
if (TrapFuncName.getNumOccurrences() > 0)
|
||||
for (auto &B : F)
|
||||
for (auto &I : B)
|
||||
if (auto *Call = dyn_cast<CallInst>(&I))
|
||||
if (const auto *F = Call->getCalledFunction())
|
||||
if (F->getIntrinsicID() == Intrinsic::debugtrap ||
|
||||
F->getIntrinsicID() == Intrinsic::trap)
|
||||
Call->addAttribute(
|
||||
llvm::AttributeList::FunctionIndex,
|
||||
Attribute::get(Ctx, "trap-func-name", TrapFuncName));
|
||||
|
||||
// Let NewAttrs override Attrs.
|
||||
F.setAttributes(
|
||||
Attrs.addAttributes(Ctx, AttributeList::FunctionIndex, NewAttrs));
|
||||
}
|
||||
}
|
||||
//===-- CommandFlags.h - Command Line Flags Interface -----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains codegen-specific flags that are shared between different
|
||||
// command line tools. The tools "llc" and "opt" both use this file to prevent
|
||||
// flag duplication.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/Intrinsics.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/MC/MCTargetOptionsCommandFlags.def"
|
||||
#include "llvm/MC/SubtargetFeature.h"
|
||||
#include "llvm/Support/CodeGen.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Host.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
#include <string>
|
||||
using namespace llvm;
|
||||
|
||||
static cl::opt<std::string>
|
||||
MArch("march",
|
||||
cl::desc("Architecture to generate code for (see --version)"));
|
||||
|
||||
static cl::opt<std::string>
|
||||
MCPU("mcpu",
|
||||
cl::desc("Target a specific cpu type (-mcpu=help for details)"),
|
||||
cl::value_desc("cpu-name"), cl::init(""));
|
||||
|
||||
static cl::list<std::string>
|
||||
MAttrs("mattr", cl::CommaSeparated,
|
||||
cl::desc("Target specific attributes (-mattr=help for details)"),
|
||||
cl::value_desc("a1,+a2,-a3,..."));
|
||||
|
||||
static cl::opt<Reloc::Model> RelocModel(
|
||||
"relocation-model", cl::desc("Choose relocation model"),
|
||||
cl::values(
|
||||
clEnumValN(Reloc::Static, "static", "Non-relocatable code"),
|
||||
clEnumValN(Reloc::PIC_, "pic",
|
||||
"Fully relocatable, position independent code"),
|
||||
clEnumValN(Reloc::DynamicNoPIC, "dynamic-no-pic",
|
||||
"Relocatable external references, non-relocatable code"),
|
||||
clEnumValN(Reloc::ROPI, "ropi",
|
||||
"Code and read-only data relocatable, accessed PC-relative"),
|
||||
clEnumValN(
|
||||
Reloc::RWPI, "rwpi",
|
||||
"Read-write data relocatable, accessed relative to static base"),
|
||||
clEnumValN(Reloc::ROPI_RWPI, "ropi-rwpi",
|
||||
"Combination of ropi and rwpi")));
|
||||
|
||||
LLVM_ATTRIBUTE_UNUSED static Optional<Reloc::Model> getRelocModel() {
|
||||
if (RelocModel.getNumOccurrences()) {
|
||||
Reloc::Model R = RelocModel;
|
||||
return R;
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
static cl::opt<ThreadModel::Model> TMModel(
|
||||
"thread-model", cl::desc("Choose threading model"),
|
||||
cl::init(ThreadModel::POSIX),
|
||||
cl::values(clEnumValN(ThreadModel::POSIX, "posix", "POSIX thread model"),
|
||||
clEnumValN(ThreadModel::Single, "single",
|
||||
"Single thread model")));
|
||||
|
||||
static cl::opt<llvm::CodeModel::Model> CMModel(
|
||||
"code-model", cl::desc("Choose code model"),
|
||||
cl::values(clEnumValN(CodeModel::Small, "small", "Small code model"),
|
||||
clEnumValN(CodeModel::Kernel, "kernel", "Kernel code model"),
|
||||
clEnumValN(CodeModel::Medium, "medium", "Medium code model"),
|
||||
clEnumValN(CodeModel::Large, "large", "Large code model")));
|
||||
|
||||
LLVM_ATTRIBUTE_UNUSED static Optional<CodeModel::Model> getCodeModel() {
|
||||
if (CMModel.getNumOccurrences()) {
|
||||
CodeModel::Model M = CMModel;
|
||||
return M;
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
static cl::opt<llvm::ExceptionHandling> ExceptionModel(
|
||||
"exception-model", cl::desc("exception model"),
|
||||
cl::init(ExceptionHandling::None),
|
||||
cl::values(
|
||||
clEnumValN(ExceptionHandling::None, "default",
|
||||
"default exception handling model"),
|
||||
clEnumValN(ExceptionHandling::DwarfCFI, "dwarf",
|
||||
"DWARF-like CFI based exception handling"),
|
||||
clEnumValN(ExceptionHandling::SjLj, "sjlj", "SjLj exception handling"),
|
||||
clEnumValN(ExceptionHandling::ARM, "arm", "ARM EHABI exceptions"),
|
||||
clEnumValN(ExceptionHandling::WinEH, "wineh",
|
||||
"Windows exception model")));
|
||||
|
||||
static cl::opt<TargetMachine::CodeGenFileType> FileType(
|
||||
"filetype", cl::init(TargetMachine::CGFT_AssemblyFile),
|
||||
cl::desc(
|
||||
"Choose a file type (not all types are supported by all targets):"),
|
||||
cl::values(clEnumValN(TargetMachine::CGFT_AssemblyFile, "asm",
|
||||
"Emit an assembly ('.s') file"),
|
||||
clEnumValN(TargetMachine::CGFT_ObjectFile, "obj",
|
||||
"Emit a native object ('.o') file"),
|
||||
clEnumValN(TargetMachine::CGFT_Null, "null",
|
||||
"Emit nothing, for performance testing")));
|
||||
|
||||
static cl::opt<bool>
|
||||
DisableFPElim("disable-fp-elim",
|
||||
cl::desc("Disable frame pointer elimination optimization"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool> EnableUnsafeFPMath(
|
||||
"enable-unsafe-fp-math",
|
||||
cl::desc("Enable optimizations that may decrease FP precision"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool> EnableNoInfsFPMath(
|
||||
"enable-no-infs-fp-math",
|
||||
cl::desc("Enable FP math optimizations that assume no +-Infs"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool> EnableNoNaNsFPMath(
|
||||
"enable-no-nans-fp-math",
|
||||
cl::desc("Enable FP math optimizations that assume no NaNs"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool> EnableNoSignedZerosFPMath(
|
||||
"enable-no-signed-zeros-fp-math",
|
||||
cl::desc("Enable FP math optimizations that assume "
|
||||
"the sign of 0 is insignificant"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool>
|
||||
EnableNoTrappingFPMath("enable-no-trapping-fp-math",
|
||||
cl::desc("Enable setting the FP exceptions build "
|
||||
"attribute not to use exceptions"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<llvm::FPDenormal::DenormalMode> DenormalMode(
|
||||
"denormal-fp-math",
|
||||
cl::desc("Select which denormal numbers the code is permitted to require"),
|
||||
cl::init(FPDenormal::IEEE),
|
||||
cl::values(clEnumValN(FPDenormal::IEEE, "ieee",
|
||||
"IEEE 754 denormal numbers"),
|
||||
clEnumValN(FPDenormal::PreserveSign, "preserve-sign",
|
||||
"the sign of a flushed-to-zero number is preserved "
|
||||
"in the sign of 0"),
|
||||
clEnumValN(FPDenormal::PositiveZero, "positive-zero",
|
||||
"denormals are flushed to positive zero")));
|
||||
|
||||
static cl::opt<bool> EnableHonorSignDependentRoundingFPMath(
|
||||
"enable-sign-dependent-rounding-fp-math", cl::Hidden,
|
||||
cl::desc("Force codegen to assume rounding mode can change dynamically"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<llvm::FloatABI::ABIType> FloatABIForCalls(
|
||||
"float-abi", cl::desc("Choose float ABI type"), cl::init(FloatABI::Default),
|
||||
cl::values(clEnumValN(FloatABI::Default, "default",
|
||||
"Target default float ABI type"),
|
||||
clEnumValN(FloatABI::Soft, "soft",
|
||||
"Soft float ABI (implied by -soft-float)"),
|
||||
clEnumValN(FloatABI::Hard, "hard",
|
||||
"Hard float ABI (uses FP registers)")));
|
||||
|
||||
static cl::opt<llvm::FPOpFusion::FPOpFusionMode> FuseFPOps(
|
||||
"fp-contract", cl::desc("Enable aggressive formation of fused FP ops"),
|
||||
cl::init(FPOpFusion::Standard),
|
||||
cl::values(
|
||||
clEnumValN(FPOpFusion::Fast, "fast", "Fuse FP ops whenever profitable"),
|
||||
clEnumValN(FPOpFusion::Standard, "on", "Only fuse 'blessed' FP ops."),
|
||||
clEnumValN(FPOpFusion::Strict, "off",
|
||||
"Only fuse FP ops when the result won't be affected.")));
|
||||
|
||||
static cl::opt<bool> DontPlaceZerosInBSS(
|
||||
"nozero-initialized-in-bss",
|
||||
cl::desc("Don't place zero-initialized symbols into bss section"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool> EnableGuaranteedTailCallOpt(
|
||||
"tailcallopt",
|
||||
cl::desc(
|
||||
"Turn fastcc calls into tail calls by (potentially) changing ABI."),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool> DisableTailCalls("disable-tail-calls",
|
||||
cl::desc("Never emit tail calls"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool> StackSymbolOrdering("stack-symbol-ordering",
|
||||
cl::desc("Order local stack symbols."),
|
||||
cl::init(true));
|
||||
|
||||
static cl::opt<unsigned>
|
||||
OverrideStackAlignment("stack-alignment",
|
||||
cl::desc("Override default stack alignment"),
|
||||
cl::init(0));
|
||||
|
||||
static cl::opt<bool>
|
||||
StackRealign("stackrealign",
|
||||
cl::desc("Force align the stack to the minimum alignment"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<std::string> TrapFuncName(
|
||||
"trap-func", cl::Hidden,
|
||||
cl::desc("Emit a call to trap function rather than a trap instruction"),
|
||||
cl::init(""));
|
||||
|
||||
static cl::opt<bool> UseCtors("use-ctors",
|
||||
cl::desc("Use .ctors instead of .init_array."),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool> RelaxELFRelocations(
|
||||
"relax-elf-relocations",
|
||||
cl::desc("Emit GOTPCRELX/REX_GOTPCRELX instead of GOTPCREL on x86-64 ELF"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool> DataSections("data-sections",
|
||||
cl::desc("Emit data into separate sections"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool>
|
||||
FunctionSections("function-sections",
|
||||
cl::desc("Emit functions into separate sections"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool> EmulatedTLS("emulated-tls",
|
||||
cl::desc("Use emulated TLS model"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool>
|
||||
UniqueSectionNames("unique-section-names",
|
||||
cl::desc("Give unique names to every section"),
|
||||
cl::init(true));
|
||||
|
||||
static cl::opt<llvm::EABI>
|
||||
EABIVersion("meabi", cl::desc("Set EABI type (default depends on triple):"),
|
||||
cl::init(EABI::Default),
|
||||
cl::values(clEnumValN(EABI::Default, "default",
|
||||
"Triple default EABI version"),
|
||||
clEnumValN(EABI::EABI4, "4", "EABI version 4"),
|
||||
clEnumValN(EABI::EABI5, "5", "EABI version 5"),
|
||||
clEnumValN(EABI::GNU, "gnu", "EABI GNU")));
|
||||
|
||||
static cl::opt<DebuggerKind> DebuggerTuningOpt(
|
||||
"debugger-tune", cl::desc("Tune debug info for a particular debugger"),
|
||||
cl::init(DebuggerKind::Default),
|
||||
cl::values(clEnumValN(DebuggerKind::GDB, "gdb", "gdb"),
|
||||
clEnumValN(DebuggerKind::LLDB, "lldb", "lldb"),
|
||||
clEnumValN(DebuggerKind::SCE, "sce", "SCE targets (e.g. PS4)")));
|
||||
|
||||
static cl::opt<bool> EnableStackSizeSection(
|
||||
"stack-size-section",
|
||||
cl::desc("Emit a section containing stack size metadata"), cl::init(false));
|
||||
|
||||
// Common utility function tightly tied to the options listed here. Initializes
|
||||
// a TargetOptions object with CodeGen flags and returns it.
|
||||
static TargetOptions InitTargetOptionsFromCodeGenFlags() {
|
||||
TargetOptions Options;
|
||||
Options.AllowFPOpFusion = FuseFPOps;
|
||||
Options.UnsafeFPMath = EnableUnsafeFPMath;
|
||||
Options.NoInfsFPMath = EnableNoInfsFPMath;
|
||||
Options.NoNaNsFPMath = EnableNoNaNsFPMath;
|
||||
Options.NoSignedZerosFPMath = EnableNoSignedZerosFPMath;
|
||||
Options.NoTrappingFPMath = EnableNoTrappingFPMath;
|
||||
Options.FPDenormalMode = DenormalMode;
|
||||
Options.HonorSignDependentRoundingFPMathOption =
|
||||
EnableHonorSignDependentRoundingFPMath;
|
||||
if (FloatABIForCalls != FloatABI::Default)
|
||||
Options.FloatABIType = FloatABIForCalls;
|
||||
Options.NoZerosInBSS = DontPlaceZerosInBSS;
|
||||
Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt;
|
||||
Options.StackAlignmentOverride = OverrideStackAlignment;
|
||||
Options.StackSymbolOrdering = StackSymbolOrdering;
|
||||
Options.UseInitArray = !UseCtors;
|
||||
Options.RelaxELFRelocations = RelaxELFRelocations;
|
||||
Options.DataSections = DataSections;
|
||||
Options.FunctionSections = FunctionSections;
|
||||
Options.UniqueSectionNames = UniqueSectionNames;
|
||||
Options.EmulatedTLS = EmulatedTLS;
|
||||
Options.ExceptionModel = ExceptionModel;
|
||||
Options.EmitStackSizeSection = EnableStackSizeSection;
|
||||
|
||||
Options.MCOptions = InitMCTargetOptionsFromFlags();
|
||||
|
||||
Options.ThreadModel = TMModel;
|
||||
Options.EABIVersion = EABIVersion;
|
||||
Options.DebuggerTuning = DebuggerTuningOpt;
|
||||
|
||||
return Options;
|
||||
}
|
||||
|
||||
LLVM_ATTRIBUTE_UNUSED static std::string getCPUStr() {
|
||||
// If user asked for the 'native' CPU, autodetect here. If autodection fails,
|
||||
// this will set the CPU to an empty string which tells the target to
|
||||
// pick a basic default.
|
||||
if (MCPU == "native")
|
||||
return sys::getHostCPUName();
|
||||
|
||||
return MCPU;
|
||||
}
|
||||
|
||||
LLVM_ATTRIBUTE_UNUSED static std::string getFeaturesStr() {
|
||||
SubtargetFeatures Features;
|
||||
|
||||
// If user asked for the 'native' CPU, we need to autodetect features.
|
||||
// This is necessary for x86 where the CPU might not support all the
|
||||
// features the autodetected CPU name lists in the target. For example,
|
||||
// not all Sandybridge processors support AVX.
|
||||
if (MCPU == "native") {
|
||||
StringMap<bool> HostFeatures;
|
||||
if (sys::getHostCPUFeatures(HostFeatures))
|
||||
for (auto &F : HostFeatures)
|
||||
Features.AddFeature(F.first(), F.second);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i != MAttrs.size(); ++i)
|
||||
Features.AddFeature(MAttrs[i]);
|
||||
|
||||
return Features.getString();
|
||||
}
|
||||
|
||||
/// \brief Set function attributes of functions in Module M based on CPU,
|
||||
/// Features, and command line flags.
|
||||
LLVM_ATTRIBUTE_UNUSED static void
|
||||
setFunctionAttributes(StringRef CPU, StringRef Features, Module &M) {
|
||||
for (auto &F : M) {
|
||||
auto &Ctx = F.getContext();
|
||||
AttributeList Attrs = F.getAttributes();
|
||||
AttrBuilder NewAttrs;
|
||||
|
||||
if (!CPU.empty())
|
||||
NewAttrs.addAttribute("target-cpu", CPU);
|
||||
if (!Features.empty())
|
||||
NewAttrs.addAttribute("target-features", Features);
|
||||
if (DisableFPElim.getNumOccurrences() > 0)
|
||||
NewAttrs.addAttribute("no-frame-pointer-elim",
|
||||
DisableFPElim ? "true" : "false");
|
||||
if (DisableTailCalls.getNumOccurrences() > 0)
|
||||
NewAttrs.addAttribute("disable-tail-calls",
|
||||
toStringRef(DisableTailCalls));
|
||||
if (StackRealign)
|
||||
NewAttrs.addAttribute("stackrealign");
|
||||
|
||||
if (TrapFuncName.getNumOccurrences() > 0)
|
||||
for (auto &B : F)
|
||||
for (auto &I : B)
|
||||
if (auto *Call = dyn_cast<CallInst>(&I))
|
||||
if (const auto *F = Call->getCalledFunction())
|
||||
if (F->getIntrinsicID() == Intrinsic::debugtrap ||
|
||||
F->getIntrinsicID() == Intrinsic::trap)
|
||||
Call->addAttribute(
|
||||
llvm::AttributeList::FunctionIndex,
|
||||
Attribute::get(Ctx, "trap-func-name", TrapFuncName));
|
||||
|
||||
// Let NewAttrs override Attrs.
|
||||
F.setAttributes(
|
||||
Attrs.addAttributes(Ctx, AttributeList::FunctionIndex, NewAttrs));
|
||||
}
|
||||
}
|
||||
|
@ -1,371 +1,376 @@
|
||||
//===-- llvm/MC/MCObjectFileInfo.h - Object File Info -----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file describes common object file formats.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_MC_MCOBJECTFILEINFO_H
|
||||
#define LLVM_MC_MCOBJECTFILEINFO_H
|
||||
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/Support/CodeGen.h"
|
||||
|
||||
namespace llvm {
|
||||
class MCContext;
|
||||
class MCSection;
|
||||
|
||||
class MCObjectFileInfo {
|
||||
protected:
|
||||
/// True if .comm supports alignment. This is a hack for as long as we
|
||||
/// support 10.4 Tiger, whose assembler doesn't support alignment on comm.
|
||||
bool CommDirectiveSupportsAlignment;
|
||||
|
||||
/// True if target object file supports a weak_definition of constant 0 for an
|
||||
/// omitted EH frame.
|
||||
bool SupportsWeakOmittedEHFrame;
|
||||
|
||||
/// True if the target object file supports emitting a compact unwind section
|
||||
/// without an associated EH frame section.
|
||||
bool SupportsCompactUnwindWithoutEHFrame;
|
||||
|
||||
/// OmitDwarfIfHaveCompactUnwind - True if the target object file
|
||||
/// supports having some functions with compact unwind and other with
|
||||
/// dwarf unwind.
|
||||
bool OmitDwarfIfHaveCompactUnwind;
|
||||
|
||||
/// PersonalityEncoding, LSDAEncoding, TTypeEncoding - Some encoding values
|
||||
/// for EH.
|
||||
unsigned PersonalityEncoding;
|
||||
unsigned LSDAEncoding;
|
||||
unsigned FDECFIEncoding;
|
||||
unsigned TTypeEncoding;
|
||||
|
||||
/// Compact unwind encoding indicating that we should emit only an EH frame.
|
||||
unsigned CompactUnwindDwarfEHFrameOnly;
|
||||
|
||||
/// Section directive for standard text.
|
||||
MCSection *TextSection;
|
||||
|
||||
/// Section directive for standard data.
|
||||
MCSection *DataSection;
|
||||
|
||||
/// Section that is default initialized to zero.
|
||||
MCSection *BSSSection;
|
||||
|
||||
/// Section that is readonly and can contain arbitrary initialized data.
|
||||
/// Targets are not required to have a readonly section. If they don't,
|
||||
/// various bits of code will fall back to using the data section for
|
||||
/// constants.
|
||||
MCSection *ReadOnlySection;
|
||||
|
||||
/// If exception handling is supported by the target, this is the section the
|
||||
/// Language Specific Data Area information is emitted to.
|
||||
MCSection *LSDASection;
|
||||
|
||||
/// If exception handling is supported by the target and the target can
|
||||
/// support a compact representation of the CIE and FDE, this is the section
|
||||
/// to emit them into.
|
||||
MCSection *CompactUnwindSection;
|
||||
|
||||
// Dwarf sections for debug info. If a target supports debug info, these must
|
||||
// be set.
|
||||
MCSection *DwarfAbbrevSection;
|
||||
MCSection *DwarfInfoSection;
|
||||
MCSection *DwarfLineSection;
|
||||
MCSection *DwarfFrameSection;
|
||||
MCSection *DwarfPubTypesSection;
|
||||
const MCSection *DwarfDebugInlineSection;
|
||||
MCSection *DwarfStrSection;
|
||||
MCSection *DwarfLocSection;
|
||||
MCSection *DwarfARangesSection;
|
||||
MCSection *DwarfRangesSection;
|
||||
MCSection *DwarfMacinfoSection;
|
||||
// The pubnames section is no longer generated by default. The generation
|
||||
// can be enabled by a compiler flag.
|
||||
MCSection *DwarfPubNamesSection;
|
||||
|
||||
/// DWARF5 Experimental Debug Info Sections
|
||||
/// DwarfAccelNamesSection, DwarfAccelObjCSection,
|
||||
/// DwarfAccelNamespaceSection, DwarfAccelTypesSection -
|
||||
/// If we use the DWARF accelerated hash tables then we want to emit these
|
||||
/// sections.
|
||||
MCSection *DwarfAccelNamesSection;
|
||||
MCSection *DwarfAccelObjCSection;
|
||||
MCSection *DwarfAccelNamespaceSection;
|
||||
MCSection *DwarfAccelTypesSection;
|
||||
|
||||
// These are used for the Fission separate debug information files.
|
||||
MCSection *DwarfInfoDWOSection;
|
||||
MCSection *DwarfTypesDWOSection;
|
||||
MCSection *DwarfAbbrevDWOSection;
|
||||
MCSection *DwarfStrDWOSection;
|
||||
MCSection *DwarfLineDWOSection;
|
||||
MCSection *DwarfLocDWOSection;
|
||||
MCSection *DwarfStrOffDWOSection;
|
||||
|
||||
/// The DWARF v5 string offset and address table sections.
|
||||
MCSection *DwarfStrOffSection;
|
||||
MCSection *DwarfAddrSection;
|
||||
|
||||
// These are for Fission DWP files.
|
||||
MCSection *DwarfCUIndexSection;
|
||||
MCSection *DwarfTUIndexSection;
|
||||
|
||||
/// Section for newer gnu pubnames.
|
||||
MCSection *DwarfGnuPubNamesSection;
|
||||
/// Section for newer gnu pubtypes.
|
||||
MCSection *DwarfGnuPubTypesSection;
|
||||
|
||||
// Section for Swift AST
|
||||
MCSection *DwarfSwiftASTSection;
|
||||
|
||||
MCSection *COFFDebugSymbolsSection;
|
||||
MCSection *COFFDebugTypesSection;
|
||||
|
||||
/// Extra TLS Variable Data section.
|
||||
///
|
||||
/// If the target needs to put additional information for a TLS variable,
|
||||
/// it'll go here.
|
||||
MCSection *TLSExtraDataSection;
|
||||
|
||||
/// Section directive for Thread Local data. ELF, MachO, COFF, and Wasm.
|
||||
MCSection *TLSDataSection; // Defaults to ".tdata".
|
||||
|
||||
/// Section directive for Thread Local uninitialized data.
|
||||
///
|
||||
/// Null if this target doesn't support a BSS section. ELF and MachO only.
|
||||
MCSection *TLSBSSSection; // Defaults to ".tbss".
|
||||
|
||||
/// StackMap section.
|
||||
MCSection *StackMapSection;
|
||||
|
||||
/// FaultMap section.
|
||||
MCSection *FaultMapSection;
|
||||
|
||||
/// EH frame section.
|
||||
///
|
||||
/// It is initialized on demand so it can be overwritten (with uniquing).
|
||||
MCSection *EHFrameSection;
|
||||
|
||||
// ELF specific sections.
|
||||
MCSection *DataRelROSection;
|
||||
MCSection *MergeableConst4Section;
|
||||
MCSection *MergeableConst8Section;
|
||||
MCSection *MergeableConst16Section;
|
||||
MCSection *MergeableConst32Section;
|
||||
|
||||
// MachO specific sections.
|
||||
|
||||
/// Section for thread local structure information.
|
||||
///
|
||||
/// Contains the source code name of the variable, visibility and a pointer to
|
||||
/// the initial value (.tdata or .tbss).
|
||||
MCSection *TLSTLVSection; // Defaults to ".tlv".
|
||||
|
||||
/// Section for thread local data initialization functions.
|
||||
const MCSection *TLSThreadInitSection; // Defaults to ".thread_init_func".
|
||||
|
||||
MCSection *CStringSection;
|
||||
MCSection *UStringSection;
|
||||
MCSection *TextCoalSection;
|
||||
MCSection *ConstTextCoalSection;
|
||||
MCSection *ConstDataSection;
|
||||
MCSection *DataCoalSection;
|
||||
MCSection *DataCommonSection;
|
||||
MCSection *DataBSSSection;
|
||||
MCSection *FourByteConstantSection;
|
||||
MCSection *EightByteConstantSection;
|
||||
MCSection *SixteenByteConstantSection;
|
||||
MCSection *LazySymbolPointerSection;
|
||||
MCSection *NonLazySymbolPointerSection;
|
||||
MCSection *ThreadLocalPointerSection;
|
||||
|
||||
/// COFF specific sections.
|
||||
MCSection *DrectveSection;
|
||||
MCSection *PDataSection;
|
||||
MCSection *XDataSection;
|
||||
MCSection *SXDataSection;
|
||||
|
||||
public:
|
||||
void InitMCObjectFileInfo(const Triple &TT, bool PIC, MCContext &ctx,
|
||||
bool LargeCodeModel = false);
|
||||
|
||||
bool getSupportsWeakOmittedEHFrame() const {
|
||||
return SupportsWeakOmittedEHFrame;
|
||||
}
|
||||
bool getSupportsCompactUnwindWithoutEHFrame() const {
|
||||
return SupportsCompactUnwindWithoutEHFrame;
|
||||
}
|
||||
bool getOmitDwarfIfHaveCompactUnwind() const {
|
||||
return OmitDwarfIfHaveCompactUnwind;
|
||||
}
|
||||
|
||||
bool getCommDirectiveSupportsAlignment() const {
|
||||
return CommDirectiveSupportsAlignment;
|
||||
}
|
||||
|
||||
unsigned getPersonalityEncoding() const { return PersonalityEncoding; }
|
||||
unsigned getLSDAEncoding() const { return LSDAEncoding; }
|
||||
unsigned getFDEEncoding() const { return FDECFIEncoding; }
|
||||
unsigned getTTypeEncoding() const { return TTypeEncoding; }
|
||||
|
||||
unsigned getCompactUnwindDwarfEHFrameOnly() const {
|
||||
return CompactUnwindDwarfEHFrameOnly;
|
||||
}
|
||||
|
||||
MCSection *getTextSection() const { return TextSection; }
|
||||
MCSection *getDataSection() const { return DataSection; }
|
||||
MCSection *getBSSSection() const { return BSSSection; }
|
||||
MCSection *getReadOnlySection() const { return ReadOnlySection; }
|
||||
MCSection *getLSDASection() const { return LSDASection; }
|
||||
MCSection *getCompactUnwindSection() const { return CompactUnwindSection; }
|
||||
MCSection *getDwarfAbbrevSection() const { return DwarfAbbrevSection; }
|
||||
MCSection *getDwarfInfoSection() const { return DwarfInfoSection; }
|
||||
MCSection *getDwarfLineSection() const { return DwarfLineSection; }
|
||||
MCSection *getDwarfFrameSection() const { return DwarfFrameSection; }
|
||||
MCSection *getDwarfPubNamesSection() const { return DwarfPubNamesSection; }
|
||||
MCSection *getDwarfPubTypesSection() const { return DwarfPubTypesSection; }
|
||||
MCSection *getDwarfGnuPubNamesSection() const {
|
||||
return DwarfGnuPubNamesSection;
|
||||
}
|
||||
MCSection *getDwarfGnuPubTypesSection() const {
|
||||
return DwarfGnuPubTypesSection;
|
||||
}
|
||||
const MCSection *getDwarfDebugInlineSection() const {
|
||||
return DwarfDebugInlineSection;
|
||||
}
|
||||
MCSection *getDwarfStrSection() const { return DwarfStrSection; }
|
||||
MCSection *getDwarfLocSection() const { return DwarfLocSection; }
|
||||
MCSection *getDwarfARangesSection() const { return DwarfARangesSection; }
|
||||
MCSection *getDwarfRangesSection() const { return DwarfRangesSection; }
|
||||
MCSection *getDwarfMacinfoSection() const { return DwarfMacinfoSection; }
|
||||
|
||||
// DWARF5 Experimental Debug Info Sections
|
||||
MCSection *getDwarfAccelNamesSection() const {
|
||||
return DwarfAccelNamesSection;
|
||||
}
|
||||
MCSection *getDwarfAccelObjCSection() const { return DwarfAccelObjCSection; }
|
||||
MCSection *getDwarfAccelNamespaceSection() const {
|
||||
return DwarfAccelNamespaceSection;
|
||||
}
|
||||
MCSection *getDwarfAccelTypesSection() const {
|
||||
return DwarfAccelTypesSection;
|
||||
}
|
||||
MCSection *getDwarfInfoDWOSection() const { return DwarfInfoDWOSection; }
|
||||
MCSection *getDwarfTypesSection(uint64_t Hash) const;
|
||||
MCSection *getDwarfTypesDWOSection() const { return DwarfTypesDWOSection; }
|
||||
MCSection *getDwarfAbbrevDWOSection() const { return DwarfAbbrevDWOSection; }
|
||||
MCSection *getDwarfStrDWOSection() const { return DwarfStrDWOSection; }
|
||||
MCSection *getDwarfLineDWOSection() const { return DwarfLineDWOSection; }
|
||||
MCSection *getDwarfLocDWOSection() const { return DwarfLocDWOSection; }
|
||||
MCSection *getDwarfStrOffDWOSection() const { return DwarfStrOffDWOSection; }
|
||||
MCSection *getDwarfStrOffSection() const { return DwarfStrOffSection; }
|
||||
MCSection *getDwarfAddrSection() const { return DwarfAddrSection; }
|
||||
MCSection *getDwarfCUIndexSection() const { return DwarfCUIndexSection; }
|
||||
MCSection *getDwarfTUIndexSection() const { return DwarfTUIndexSection; }
|
||||
MCSection *getDwarfSwiftASTSection() const { return DwarfSwiftASTSection; }
|
||||
|
||||
MCSection *getCOFFDebugSymbolsSection() const {
|
||||
return COFFDebugSymbolsSection;
|
||||
}
|
||||
MCSection *getCOFFDebugTypesSection() const {
|
||||
return COFFDebugTypesSection;
|
||||
}
|
||||
|
||||
|
||||
MCSection *getTLSExtraDataSection() const { return TLSExtraDataSection; }
|
||||
const MCSection *getTLSDataSection() const { return TLSDataSection; }
|
||||
MCSection *getTLSBSSSection() const { return TLSBSSSection; }
|
||||
|
||||
MCSection *getStackMapSection() const { return StackMapSection; }
|
||||
MCSection *getFaultMapSection() const { return FaultMapSection; }
|
||||
|
||||
// ELF specific sections.
|
||||
MCSection *getDataRelROSection() const { return DataRelROSection; }
|
||||
const MCSection *getMergeableConst4Section() const {
|
||||
return MergeableConst4Section;
|
||||
}
|
||||
const MCSection *getMergeableConst8Section() const {
|
||||
return MergeableConst8Section;
|
||||
}
|
||||
const MCSection *getMergeableConst16Section() const {
|
||||
return MergeableConst16Section;
|
||||
}
|
||||
const MCSection *getMergeableConst32Section() const {
|
||||
return MergeableConst32Section;
|
||||
}
|
||||
|
||||
// MachO specific sections.
|
||||
const MCSection *getTLSTLVSection() const { return TLSTLVSection; }
|
||||
const MCSection *getTLSThreadInitSection() const {
|
||||
return TLSThreadInitSection;
|
||||
}
|
||||
const MCSection *getCStringSection() const { return CStringSection; }
|
||||
const MCSection *getUStringSection() const { return UStringSection; }
|
||||
MCSection *getTextCoalSection() const { return TextCoalSection; }
|
||||
const MCSection *getConstTextCoalSection() const {
|
||||
return ConstTextCoalSection;
|
||||
}
|
||||
const MCSection *getConstDataSection() const { return ConstDataSection; }
|
||||
const MCSection *getDataCoalSection() const { return DataCoalSection; }
|
||||
const MCSection *getDataCommonSection() const { return DataCommonSection; }
|
||||
MCSection *getDataBSSSection() const { return DataBSSSection; }
|
||||
const MCSection *getFourByteConstantSection() const {
|
||||
return FourByteConstantSection;
|
||||
}
|
||||
const MCSection *getEightByteConstantSection() const {
|
||||
return EightByteConstantSection;
|
||||
}
|
||||
const MCSection *getSixteenByteConstantSection() const {
|
||||
return SixteenByteConstantSection;
|
||||
}
|
||||
MCSection *getLazySymbolPointerSection() const {
|
||||
return LazySymbolPointerSection;
|
||||
}
|
||||
MCSection *getNonLazySymbolPointerSection() const {
|
||||
return NonLazySymbolPointerSection;
|
||||
}
|
||||
MCSection *getThreadLocalPointerSection() const {
|
||||
return ThreadLocalPointerSection;
|
||||
}
|
||||
|
||||
// COFF specific sections.
|
||||
MCSection *getDrectveSection() const { return DrectveSection; }
|
||||
MCSection *getPDataSection() const { return PDataSection; }
|
||||
MCSection *getXDataSection() const { return XDataSection; }
|
||||
MCSection *getSXDataSection() const { return SXDataSection; }
|
||||
|
||||
MCSection *getEHFrameSection() {
|
||||
return EHFrameSection;
|
||||
}
|
||||
|
||||
enum Environment { IsMachO, IsELF, IsCOFF, IsWasm };
|
||||
Environment getObjectFileType() const { return Env; }
|
||||
|
||||
bool isPositionIndependent() const { return PositionIndependent; }
|
||||
|
||||
private:
|
||||
Environment Env;
|
||||
bool PositionIndependent;
|
||||
MCContext *Ctx;
|
||||
Triple TT;
|
||||
|
||||
void initMachOMCObjectFileInfo(const Triple &T);
|
||||
void initELFMCObjectFileInfo(const Triple &T, bool Large);
|
||||
void initCOFFMCObjectFileInfo(const Triple &T);
|
||||
void initWasmMCObjectFileInfo(const Triple &T);
|
||||
|
||||
public:
|
||||
const Triple &getTargetTriple() const { return TT; }
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
//===-- llvm/MC/MCObjectFileInfo.h - Object File Info -----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file describes common object file formats.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_MC_MCOBJECTFILEINFO_H
|
||||
#define LLVM_MC_MCOBJECTFILEINFO_H
|
||||
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/Support/CodeGen.h"
|
||||
|
||||
namespace llvm {
|
||||
class MCContext;
|
||||
class MCSection;
|
||||
|
||||
class MCObjectFileInfo {
|
||||
protected:
|
||||
/// True if .comm supports alignment. This is a hack for as long as we
|
||||
/// support 10.4 Tiger, whose assembler doesn't support alignment on comm.
|
||||
bool CommDirectiveSupportsAlignment;
|
||||
|
||||
/// True if target object file supports a weak_definition of constant 0 for an
|
||||
/// omitted EH frame.
|
||||
bool SupportsWeakOmittedEHFrame;
|
||||
|
||||
/// True if the target object file supports emitting a compact unwind section
|
||||
/// without an associated EH frame section.
|
||||
bool SupportsCompactUnwindWithoutEHFrame;
|
||||
|
||||
/// OmitDwarfIfHaveCompactUnwind - True if the target object file
|
||||
/// supports having some functions with compact unwind and other with
|
||||
/// dwarf unwind.
|
||||
bool OmitDwarfIfHaveCompactUnwind;
|
||||
|
||||
/// PersonalityEncoding, LSDAEncoding, TTypeEncoding - Some encoding values
|
||||
/// for EH.
|
||||
unsigned PersonalityEncoding;
|
||||
unsigned LSDAEncoding;
|
||||
unsigned FDECFIEncoding;
|
||||
unsigned TTypeEncoding;
|
||||
|
||||
/// Compact unwind encoding indicating that we should emit only an EH frame.
|
||||
unsigned CompactUnwindDwarfEHFrameOnly;
|
||||
|
||||
/// Section directive for standard text.
|
||||
MCSection *TextSection;
|
||||
|
||||
/// Section directive for standard data.
|
||||
MCSection *DataSection;
|
||||
|
||||
/// Section that is default initialized to zero.
|
||||
MCSection *BSSSection;
|
||||
|
||||
/// Section that is readonly and can contain arbitrary initialized data.
|
||||
/// Targets are not required to have a readonly section. If they don't,
|
||||
/// various bits of code will fall back to using the data section for
|
||||
/// constants.
|
||||
MCSection *ReadOnlySection;
|
||||
|
||||
/// If exception handling is supported by the target, this is the section the
|
||||
/// Language Specific Data Area information is emitted to.
|
||||
MCSection *LSDASection;
|
||||
|
||||
/// If exception handling is supported by the target and the target can
|
||||
/// support a compact representation of the CIE and FDE, this is the section
|
||||
/// to emit them into.
|
||||
MCSection *CompactUnwindSection;
|
||||
|
||||
// Dwarf sections for debug info. If a target supports debug info, these must
|
||||
// be set.
|
||||
MCSection *DwarfAbbrevSection;
|
||||
MCSection *DwarfInfoSection;
|
||||
MCSection *DwarfLineSection;
|
||||
MCSection *DwarfFrameSection;
|
||||
MCSection *DwarfPubTypesSection;
|
||||
const MCSection *DwarfDebugInlineSection;
|
||||
MCSection *DwarfStrSection;
|
||||
MCSection *DwarfLocSection;
|
||||
MCSection *DwarfARangesSection;
|
||||
MCSection *DwarfRangesSection;
|
||||
MCSection *DwarfMacinfoSection;
|
||||
// The pubnames section is no longer generated by default. The generation
|
||||
// can be enabled by a compiler flag.
|
||||
MCSection *DwarfPubNamesSection;
|
||||
|
||||
/// DWARF5 Experimental Debug Info Sections
|
||||
/// DwarfAccelNamesSection, DwarfAccelObjCSection,
|
||||
/// DwarfAccelNamespaceSection, DwarfAccelTypesSection -
|
||||
/// If we use the DWARF accelerated hash tables then we want to emit these
|
||||
/// sections.
|
||||
MCSection *DwarfAccelNamesSection;
|
||||
MCSection *DwarfAccelObjCSection;
|
||||
MCSection *DwarfAccelNamespaceSection;
|
||||
MCSection *DwarfAccelTypesSection;
|
||||
|
||||
// These are used for the Fission separate debug information files.
|
||||
MCSection *DwarfInfoDWOSection;
|
||||
MCSection *DwarfTypesDWOSection;
|
||||
MCSection *DwarfAbbrevDWOSection;
|
||||
MCSection *DwarfStrDWOSection;
|
||||
MCSection *DwarfLineDWOSection;
|
||||
MCSection *DwarfLocDWOSection;
|
||||
MCSection *DwarfStrOffDWOSection;
|
||||
|
||||
/// The DWARF v5 string offset and address table sections.
|
||||
MCSection *DwarfStrOffSection;
|
||||
MCSection *DwarfAddrSection;
|
||||
|
||||
// These are for Fission DWP files.
|
||||
MCSection *DwarfCUIndexSection;
|
||||
MCSection *DwarfTUIndexSection;
|
||||
|
||||
/// Section for newer gnu pubnames.
|
||||
MCSection *DwarfGnuPubNamesSection;
|
||||
/// Section for newer gnu pubtypes.
|
||||
MCSection *DwarfGnuPubTypesSection;
|
||||
|
||||
// Section for Swift AST
|
||||
MCSection *DwarfSwiftASTSection;
|
||||
|
||||
MCSection *COFFDebugSymbolsSection;
|
||||
MCSection *COFFDebugTypesSection;
|
||||
|
||||
/// Extra TLS Variable Data section.
|
||||
///
|
||||
/// If the target needs to put additional information for a TLS variable,
|
||||
/// it'll go here.
|
||||
MCSection *TLSExtraDataSection;
|
||||
|
||||
/// Section directive for Thread Local data. ELF, MachO, COFF, and Wasm.
|
||||
MCSection *TLSDataSection; // Defaults to ".tdata".
|
||||
|
||||
/// Section directive for Thread Local uninitialized data.
|
||||
///
|
||||
/// Null if this target doesn't support a BSS section. ELF and MachO only.
|
||||
MCSection *TLSBSSSection; // Defaults to ".tbss".
|
||||
|
||||
/// StackMap section.
|
||||
MCSection *StackMapSection;
|
||||
|
||||
/// FaultMap section.
|
||||
MCSection *FaultMapSection;
|
||||
|
||||
/// EH frame section.
|
||||
///
|
||||
/// It is initialized on demand so it can be overwritten (with uniquing).
|
||||
MCSection *EHFrameSection;
|
||||
|
||||
/// Section containing metadata on function stack sizes.
|
||||
MCSection *StackSizesSection;
|
||||
|
||||
// ELF specific sections.
|
||||
MCSection *DataRelROSection;
|
||||
MCSection *MergeableConst4Section;
|
||||
MCSection *MergeableConst8Section;
|
||||
MCSection *MergeableConst16Section;
|
||||
MCSection *MergeableConst32Section;
|
||||
|
||||
// MachO specific sections.
|
||||
|
||||
/// Section for thread local structure information.
|
||||
///
|
||||
/// Contains the source code name of the variable, visibility and a pointer to
|
||||
/// the initial value (.tdata or .tbss).
|
||||
MCSection *TLSTLVSection; // Defaults to ".tlv".
|
||||
|
||||
/// Section for thread local data initialization functions.
|
||||
const MCSection *TLSThreadInitSection; // Defaults to ".thread_init_func".
|
||||
|
||||
MCSection *CStringSection;
|
||||
MCSection *UStringSection;
|
||||
MCSection *TextCoalSection;
|
||||
MCSection *ConstTextCoalSection;
|
||||
MCSection *ConstDataSection;
|
||||
MCSection *DataCoalSection;
|
||||
MCSection *DataCommonSection;
|
||||
MCSection *DataBSSSection;
|
||||
MCSection *FourByteConstantSection;
|
||||
MCSection *EightByteConstantSection;
|
||||
MCSection *SixteenByteConstantSection;
|
||||
MCSection *LazySymbolPointerSection;
|
||||
MCSection *NonLazySymbolPointerSection;
|
||||
MCSection *ThreadLocalPointerSection;
|
||||
|
||||
/// COFF specific sections.
|
||||
MCSection *DrectveSection;
|
||||
MCSection *PDataSection;
|
||||
MCSection *XDataSection;
|
||||
MCSection *SXDataSection;
|
||||
|
||||
public:
|
||||
void InitMCObjectFileInfo(const Triple &TT, bool PIC, MCContext &ctx,
|
||||
bool LargeCodeModel = false);
|
||||
|
||||
bool getSupportsWeakOmittedEHFrame() const {
|
||||
return SupportsWeakOmittedEHFrame;
|
||||
}
|
||||
bool getSupportsCompactUnwindWithoutEHFrame() const {
|
||||
return SupportsCompactUnwindWithoutEHFrame;
|
||||
}
|
||||
bool getOmitDwarfIfHaveCompactUnwind() const {
|
||||
return OmitDwarfIfHaveCompactUnwind;
|
||||
}
|
||||
|
||||
bool getCommDirectiveSupportsAlignment() const {
|
||||
return CommDirectiveSupportsAlignment;
|
||||
}
|
||||
|
||||
unsigned getPersonalityEncoding() const { return PersonalityEncoding; }
|
||||
unsigned getLSDAEncoding() const { return LSDAEncoding; }
|
||||
unsigned getFDEEncoding() const { return FDECFIEncoding; }
|
||||
unsigned getTTypeEncoding() const { return TTypeEncoding; }
|
||||
|
||||
unsigned getCompactUnwindDwarfEHFrameOnly() const {
|
||||
return CompactUnwindDwarfEHFrameOnly;
|
||||
}
|
||||
|
||||
MCSection *getTextSection() const { return TextSection; }
|
||||
MCSection *getDataSection() const { return DataSection; }
|
||||
MCSection *getBSSSection() const { return BSSSection; }
|
||||
MCSection *getReadOnlySection() const { return ReadOnlySection; }
|
||||
MCSection *getLSDASection() const { return LSDASection; }
|
||||
MCSection *getCompactUnwindSection() const { return CompactUnwindSection; }
|
||||
MCSection *getDwarfAbbrevSection() const { return DwarfAbbrevSection; }
|
||||
MCSection *getDwarfInfoSection() const { return DwarfInfoSection; }
|
||||
MCSection *getDwarfLineSection() const { return DwarfLineSection; }
|
||||
MCSection *getDwarfFrameSection() const { return DwarfFrameSection; }
|
||||
MCSection *getDwarfPubNamesSection() const { return DwarfPubNamesSection; }
|
||||
MCSection *getDwarfPubTypesSection() const { return DwarfPubTypesSection; }
|
||||
MCSection *getDwarfGnuPubNamesSection() const {
|
||||
return DwarfGnuPubNamesSection;
|
||||
}
|
||||
MCSection *getDwarfGnuPubTypesSection() const {
|
||||
return DwarfGnuPubTypesSection;
|
||||
}
|
||||
const MCSection *getDwarfDebugInlineSection() const {
|
||||
return DwarfDebugInlineSection;
|
||||
}
|
||||
MCSection *getDwarfStrSection() const { return DwarfStrSection; }
|
||||
MCSection *getDwarfLocSection() const { return DwarfLocSection; }
|
||||
MCSection *getDwarfARangesSection() const { return DwarfARangesSection; }
|
||||
MCSection *getDwarfRangesSection() const { return DwarfRangesSection; }
|
||||
MCSection *getDwarfMacinfoSection() const { return DwarfMacinfoSection; }
|
||||
|
||||
// DWARF5 Experimental Debug Info Sections
|
||||
MCSection *getDwarfAccelNamesSection() const {
|
||||
return DwarfAccelNamesSection;
|
||||
}
|
||||
MCSection *getDwarfAccelObjCSection() const { return DwarfAccelObjCSection; }
|
||||
MCSection *getDwarfAccelNamespaceSection() const {
|
||||
return DwarfAccelNamespaceSection;
|
||||
}
|
||||
MCSection *getDwarfAccelTypesSection() const {
|
||||
return DwarfAccelTypesSection;
|
||||
}
|
||||
MCSection *getDwarfInfoDWOSection() const { return DwarfInfoDWOSection; }
|
||||
MCSection *getDwarfTypesSection(uint64_t Hash) const;
|
||||
MCSection *getDwarfTypesDWOSection() const { return DwarfTypesDWOSection; }
|
||||
MCSection *getDwarfAbbrevDWOSection() const { return DwarfAbbrevDWOSection; }
|
||||
MCSection *getDwarfStrDWOSection() const { return DwarfStrDWOSection; }
|
||||
MCSection *getDwarfLineDWOSection() const { return DwarfLineDWOSection; }
|
||||
MCSection *getDwarfLocDWOSection() const { return DwarfLocDWOSection; }
|
||||
MCSection *getDwarfStrOffDWOSection() const { return DwarfStrOffDWOSection; }
|
||||
MCSection *getDwarfStrOffSection() const { return DwarfStrOffSection; }
|
||||
MCSection *getDwarfAddrSection() const { return DwarfAddrSection; }
|
||||
MCSection *getDwarfCUIndexSection() const { return DwarfCUIndexSection; }
|
||||
MCSection *getDwarfTUIndexSection() const { return DwarfTUIndexSection; }
|
||||
MCSection *getDwarfSwiftASTSection() const { return DwarfSwiftASTSection; }
|
||||
|
||||
MCSection *getCOFFDebugSymbolsSection() const {
|
||||
return COFFDebugSymbolsSection;
|
||||
}
|
||||
MCSection *getCOFFDebugTypesSection() const {
|
||||
return COFFDebugTypesSection;
|
||||
}
|
||||
|
||||
|
||||
MCSection *getTLSExtraDataSection() const { return TLSExtraDataSection; }
|
||||
const MCSection *getTLSDataSection() const { return TLSDataSection; }
|
||||
MCSection *getTLSBSSSection() const { return TLSBSSSection; }
|
||||
|
||||
MCSection *getStackMapSection() const { return StackMapSection; }
|
||||
MCSection *getFaultMapSection() const { return FaultMapSection; }
|
||||
|
||||
MCSection *getStackSizesSection() const { return StackSizesSection; }
|
||||
|
||||
// ELF specific sections.
|
||||
MCSection *getDataRelROSection() const { return DataRelROSection; }
|
||||
const MCSection *getMergeableConst4Section() const {
|
||||
return MergeableConst4Section;
|
||||
}
|
||||
const MCSection *getMergeableConst8Section() const {
|
||||
return MergeableConst8Section;
|
||||
}
|
||||
const MCSection *getMergeableConst16Section() const {
|
||||
return MergeableConst16Section;
|
||||
}
|
||||
const MCSection *getMergeableConst32Section() const {
|
||||
return MergeableConst32Section;
|
||||
}
|
||||
|
||||
// MachO specific sections.
|
||||
const MCSection *getTLSTLVSection() const { return TLSTLVSection; }
|
||||
const MCSection *getTLSThreadInitSection() const {
|
||||
return TLSThreadInitSection;
|
||||
}
|
||||
const MCSection *getCStringSection() const { return CStringSection; }
|
||||
const MCSection *getUStringSection() const { return UStringSection; }
|
||||
MCSection *getTextCoalSection() const { return TextCoalSection; }
|
||||
const MCSection *getConstTextCoalSection() const {
|
||||
return ConstTextCoalSection;
|
||||
}
|
||||
const MCSection *getConstDataSection() const { return ConstDataSection; }
|
||||
const MCSection *getDataCoalSection() const { return DataCoalSection; }
|
||||
const MCSection *getDataCommonSection() const { return DataCommonSection; }
|
||||
MCSection *getDataBSSSection() const { return DataBSSSection; }
|
||||
const MCSection *getFourByteConstantSection() const {
|
||||
return FourByteConstantSection;
|
||||
}
|
||||
const MCSection *getEightByteConstantSection() const {
|
||||
return EightByteConstantSection;
|
||||
}
|
||||
const MCSection *getSixteenByteConstantSection() const {
|
||||
return SixteenByteConstantSection;
|
||||
}
|
||||
MCSection *getLazySymbolPointerSection() const {
|
||||
return LazySymbolPointerSection;
|
||||
}
|
||||
MCSection *getNonLazySymbolPointerSection() const {
|
||||
return NonLazySymbolPointerSection;
|
||||
}
|
||||
MCSection *getThreadLocalPointerSection() const {
|
||||
return ThreadLocalPointerSection;
|
||||
}
|
||||
|
||||
// COFF specific sections.
|
||||
MCSection *getDrectveSection() const { return DrectveSection; }
|
||||
MCSection *getPDataSection() const { return PDataSection; }
|
||||
MCSection *getXDataSection() const { return XDataSection; }
|
||||
MCSection *getSXDataSection() const { return SXDataSection; }
|
||||
|
||||
MCSection *getEHFrameSection() {
|
||||
return EHFrameSection;
|
||||
}
|
||||
|
||||
enum Environment { IsMachO, IsELF, IsCOFF, IsWasm };
|
||||
Environment getObjectFileType() const { return Env; }
|
||||
|
||||
bool isPositionIndependent() const { return PositionIndependent; }
|
||||
|
||||
private:
|
||||
Environment Env;
|
||||
bool PositionIndependent;
|
||||
MCContext *Ctx;
|
||||
Triple TT;
|
||||
|
||||
void initMachOMCObjectFileInfo(const Triple &T);
|
||||
void initELFMCObjectFileInfo(const Triple &T, bool Large);
|
||||
void initCOFFMCObjectFileInfo(const Triple &T);
|
||||
void initWasmMCObjectFileInfo(const Triple &T);
|
||||
|
||||
public:
|
||||
const Triple &getTargetTriple() const { return TT; }
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
|
@ -108,7 +108,7 @@ namespace llvm {
|
||||
DisableIntegratedAS(false), RelaxELFRelocations(false),
|
||||
FunctionSections(false), DataSections(false),
|
||||
UniqueSectionNames(true), TrapUnreachable(false), EmulatedTLS(false),
|
||||
EnableIPRA(false) {}
|
||||
EnableIPRA(false), EmitStackSizeSection(false) {}
|
||||
|
||||
/// PrintMachineCode - This flag is enabled when the -print-machineinstrs
|
||||
/// option is specified on the command line, and should enable debugging
|
||||
@ -216,6 +216,9 @@ namespace llvm {
|
||||
/// This flag enables InterProcedural Register Allocation (IPRA).
|
||||
unsigned EnableIPRA : 1;
|
||||
|
||||
/// Emit section containing metadata on function stack sizes.
|
||||
unsigned EmitStackSizeSection : 1;
|
||||
|
||||
/// FloatABIType - This setting is set by -float-abi=xxx option is specfied
|
||||
/// on the command line. This setting may either be Default, Soft, or Hard.
|
||||
/// Default selects the target's default behavior. Soft selects the ABI for
|
||||
|
@ -964,6 +964,31 @@ void AsmPrinter::emitFrameAlloc(const MachineInstr &MI) {
|
||||
MCConstantExpr::create(FrameOffset, OutContext));
|
||||
}
|
||||
|
||||
void AsmPrinter::emitStackSizeSection(const MachineFunction &MF) {
|
||||
if (!MF.getTarget().Options.EmitStackSizeSection)
|
||||
return;
|
||||
|
||||
MCSection *StackSizeSection = getObjFileLowering().getStackSizesSection();
|
||||
if (!StackSizeSection)
|
||||
return;
|
||||
|
||||
const MachineFrameInfo &FrameInfo = MF.getFrameInfo();
|
||||
// Don't emit functions with dynamic stack allocations.
|
||||
if (FrameInfo.hasVarSizedObjects())
|
||||
return;
|
||||
|
||||
OutStreamer->PushSection();
|
||||
OutStreamer->SwitchSection(StackSizeSection);
|
||||
|
||||
const MCSymbol *FunctionSymbol = getSymbol(MF.getFunction());
|
||||
uint64_t StackSize = FrameInfo.getStackSize();
|
||||
OutStreamer->EmitValue(MCSymbolRefExpr::create(FunctionSymbol, OutContext),
|
||||
/* size = */ 8);
|
||||
OutStreamer->EmitULEB128IntValue(StackSize);
|
||||
|
||||
OutStreamer->PopSection();
|
||||
}
|
||||
|
||||
static bool needFuncLabelsForEHOrDebugInfo(const MachineFunction &MF,
|
||||
MachineModuleInfo *MMI) {
|
||||
if (!MF.getLandingPads().empty() || MF.hasEHFunclets() || MMI->hasDebugInfo())
|
||||
@ -1135,6 +1160,9 @@ void AsmPrinter::EmitFunctionBody() {
|
||||
HI.Handler->endFunction(MF);
|
||||
}
|
||||
|
||||
// Emit section containing stack size metadata.
|
||||
emitStackSizeSection(*MF);
|
||||
|
||||
if (isVerbose())
|
||||
OutStreamer->GetCommentOS() << "-- End function\n";
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
30
test/CodeGen/X86/stack-size-section.ll
Normal file
30
test/CodeGen/X86/stack-size-section.ll
Normal file
@ -0,0 +1,30 @@
|
||||
; RUN: llc < %s -mtriple=x86_64-linux -stack-size-section | FileCheck %s
|
||||
|
||||
; CHECK-LABEL: func1:
|
||||
; CHECK: .section .stack_sizes,"",@progbits
|
||||
; CHECK-NEXT: .quad func1
|
||||
; CHECK-NEXT: .byte 8
|
||||
define void @func1(i32, i32) #0 {
|
||||
alloca i32, align 4
|
||||
alloca i32, align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: func2:
|
||||
; CHECK: .section .stack_sizes,"",@progbits
|
||||
; CHECK-NEXT: .quad func2
|
||||
; CHECK-NEXT: .byte 24
|
||||
define void @func2() #0 {
|
||||
alloca i32, align 4
|
||||
call void @func1(i32 1, i32 2)
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: dynalloc:
|
||||
; CHECK-NOT: .section .stack_sizes
|
||||
define void @dynalloc(i32 %N) #0 {
|
||||
alloca i32, i32 %N
|
||||
ret void
|
||||
}
|
||||
|
||||
attributes #0 = { "no-frame-pointer-elim"="true" }
|
Loading…
Reference in New Issue
Block a user