2020-03-04 00:47:43 +01:00
|
|
|
//===-- CommandFlags.cpp - Command Line Flags Interface ---------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// 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
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// 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/CodeGen/CommandFlags.h"
|
2022-03-15 10:54:19 +01:00
|
|
|
#include "llvm/ADT/StringExtras.h"
|
|
|
|
#include "llvm/IR/Instructions.h"
|
|
|
|
#include "llvm/IR/Intrinsics.h"
|
2020-05-19 17:12:32 +01:00
|
|
|
#include "llvm/IR/Module.h"
|
2022-03-15 10:54:19 +01:00
|
|
|
#include "llvm/MC/MCTargetOptionsCommandFlags.h"
|
2022-11-24 11:23:38 +00:00
|
|
|
#include "llvm/MC/TargetRegistry.h"
|
2020-05-19 17:12:32 +01:00
|
|
|
#include "llvm/Support/CommandLine.h"
|
2021-04-21 10:00:30 -04:00
|
|
|
#include "llvm/Support/MemoryBuffer.h"
|
2022-11-24 11:23:38 +00:00
|
|
|
#include "llvm/Target/TargetMachine.h"
|
2023-02-10 09:59:46 +00:00
|
|
|
#include "llvm/TargetParser/Host.h"
|
2023-06-26 10:26:56 +02:00
|
|
|
#include "llvm/TargetParser/SubtargetFeature.h"
|
2023-02-07 12:21:51 +00:00
|
|
|
#include "llvm/TargetParser/Triple.h"
|
2022-12-03 11:06:12 -06:00
|
|
|
#include <optional>
|
2020-03-04 00:47:43 +01:00
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
|
|
|
|
#define CGOPT(TY, NAME) \
|
|
|
|
static cl::opt<TY> *NAME##View; \
|
|
|
|
TY codegen::get##NAME() { \
|
|
|
|
assert(NAME##View && "RegisterCodeGenFlags not created."); \
|
|
|
|
return *NAME##View; \
|
|
|
|
}
|
|
|
|
|
|
|
|
#define CGLIST(TY, NAME) \
|
|
|
|
static cl::list<TY> *NAME##View; \
|
|
|
|
std::vector<TY> codegen::get##NAME() { \
|
|
|
|
assert(NAME##View && "RegisterCodeGenFlags not created."); \
|
|
|
|
return *NAME##View; \
|
|
|
|
}
|
|
|
|
|
2022-12-03 11:06:12 -06:00
|
|
|
// Temporary macro for incremental transition to std::optional.
|
2022-12-03 18:38:12 +00:00
|
|
|
#define CGOPT_EXP(TY, NAME) \
|
2022-12-03 11:06:12 -06:00
|
|
|
CGOPT(TY, NAME) \
|
|
|
|
std::optional<TY> codegen::getExplicit##NAME() { \
|
|
|
|
if (NAME##View->getNumOccurrences()) { \
|
|
|
|
TY res = *NAME##View; \
|
|
|
|
return res; \
|
|
|
|
} \
|
|
|
|
return std::nullopt; \
|
|
|
|
}
|
|
|
|
|
2020-03-04 00:47:43 +01:00
|
|
|
CGOPT(std::string, MArch)
|
|
|
|
CGOPT(std::string, MCPU)
|
|
|
|
CGLIST(std::string, MAttrs)
|
|
|
|
CGOPT_EXP(Reloc::Model, RelocModel)
|
|
|
|
CGOPT(ThreadModel::Model, ThreadModel)
|
2022-12-03 18:38:12 +00:00
|
|
|
CGOPT_EXP(CodeModel::Model, CodeModel)
|
2023-05-10 13:13:58 -07:00
|
|
|
CGOPT_EXP(uint64_t, LargeDataThreshold)
|
2020-03-04 00:47:43 +01:00
|
|
|
CGOPT(ExceptionHandling, ExceptionModel)
|
|
|
|
CGOPT_EXP(CodeGenFileType, FileType)
|
2021-04-22 18:07:29 -07:00
|
|
|
CGOPT(FramePointerKind, FramePointerUsage)
|
2020-03-04 00:47:43 +01:00
|
|
|
CGOPT(bool, EnableUnsafeFPMath)
|
|
|
|
CGOPT(bool, EnableNoInfsFPMath)
|
|
|
|
CGOPT(bool, EnableNoNaNsFPMath)
|
|
|
|
CGOPT(bool, EnableNoSignedZerosFPMath)
|
2022-02-02 07:54:19 -08:00
|
|
|
CGOPT(bool, EnableApproxFuncFPMath)
|
2020-03-04 00:47:43 +01:00
|
|
|
CGOPT(bool, EnableNoTrappingFPMath)
|
2020-11-24 18:11:46 -05:00
|
|
|
CGOPT(bool, EnableAIXExtendedAltivecABI)
|
2020-03-11 17:12:20 -04:00
|
|
|
CGOPT(DenormalMode::DenormalModeKind, DenormalFPMath)
|
2019-12-04 14:34:14 +05:30
|
|
|
CGOPT(DenormalMode::DenormalModeKind, DenormalFP32Math)
|
2020-03-04 00:47:43 +01:00
|
|
|
CGOPT(bool, EnableHonorSignDependentRoundingFPMath)
|
|
|
|
CGOPT(FloatABI::ABIType, FloatABIForCalls)
|
|
|
|
CGOPT(FPOpFusion::FPOpFusionMode, FuseFPOps)
|
2021-09-15 13:35:08 -07:00
|
|
|
CGOPT(SwiftAsyncFramePointerMode, SwiftAsyncFramePointer)
|
2020-03-04 00:47:43 +01:00
|
|
|
CGOPT(bool, DontPlaceZerosInBSS)
|
|
|
|
CGOPT(bool, EnableGuaranteedTailCallOpt)
|
|
|
|
CGOPT(bool, DisableTailCalls)
|
|
|
|
CGOPT(bool, StackSymbolOrdering)
|
|
|
|
CGOPT(bool, StackRealign)
|
|
|
|
CGOPT(std::string, TrapFuncName)
|
|
|
|
CGOPT(bool, UseCtors)
|
2023-07-12 12:45:50 -04:00
|
|
|
CGOPT(bool, DisableIntegratedAS)
|
2020-03-04 00:47:43 +01:00
|
|
|
CGOPT_EXP(bool, DataSections)
|
|
|
|
CGOPT_EXP(bool, FunctionSections)
|
2020-10-08 09:34:58 -04:00
|
|
|
CGOPT(bool, IgnoreXCOFFVisibility)
|
2020-12-11 17:50:25 -05:00
|
|
|
CGOPT(bool, XCOFFTracebackTable)
|
[SHT_LLVM_BB_ADDR_MAP] Allow basic-block-sections and labels be used together by decoupling the handling of the two features. (#74128)
Today `-split-machine-functions` and `-fbasic-block-sections={all,list}`
cannot be combined with `-basic-block-sections=labels` (the labels
option will be ignored).
The inconsistency comes from the way basic block address map -- the
underlying mechanism for basic block labels -- encodes basic block
addresses
(https://lists.llvm.org/pipermail/llvm-dev/2020-July/143512.html).
Specifically, basic block offsets are computed relative to the function
begin symbol. This relies on functions being contiguous which is not the
case for MFS and basic block section binaries. This means Propeller
cannot use binary profiles collected from these binaries, which limits
the applicability of Propeller for iterative optimization.
To make the `SHT_LLVM_BB_ADDR_MAP` feature work with basic block section
binaries, we propose modifying the encoding of this section as follows.
First let us review the current encoding which emits the address of each
function and its number of basic blocks, followed by basic block entries
for each basic block.
| | |
|--|--|
| Address of the function | Function Address |
| Number of basic blocks in this function | NumBlocks |
| BB entry 1
| BB entry 2
| ...
| BB entry #NumBlocks
To make this work for basic block sections, we treat each basic block
section similar to a function, except that basic block sections of the
same function must be encapsulated in the same structure so we can map
all of them to their single function.
We modify the encoding to first emit the number of basic block sections
(BB ranges) in the function. Then we emit the address map of each basic
block section section as before: the base address of the section, its
number of blocks, and BB entries for its basic block. The first section
in the BB address map is always the function entry section.
| | |
|--|--|
| Number of sections for this function | NumBBRanges |
| Section 1 begin address | BaseAddress[1] |
| Number of basic blocks in section 1 | NumBlocks[1] |
| BB entries for Section 1
|..................|
| Section #NumBBRanges begin address | BaseAddress[NumBBRanges] |
| Number of basic blocks in section #NumBBRanges |
NumBlocks[NumBBRanges] |
| BB entries for Section #NumBBRanges
The encoding of basic block entries remains as before with the minor
change that each basic block offset is now computed relative to the
begin symbol of its containing BB section.
This patch adds a new boolean codegen option `-basic-block-address-map`.
Correspondingly, the front-end flag `-fbasic-block-address-map` and LLD
flag `--lto-basic-block-address-map` are introduced.
Analogously, we add a new TargetOption field `BBAddrMap`. This means BB
address maps are either generated for all functions in the compiling
unit, or for none (depending on `TargetOptions::BBAddrMap`).
This patch keeps the functionality of the old
`-fbasic-block-sections=labels` option but does not remove it. A
subsequent patch will remove the obsolete option.
We refactor the `BasicBlockSections` pass by separating the BB address
map and BB sections handing to their own functions (named
`handleBBAddrMap` and `handleBBSections`). `handleBBSections` renumbers
basic blocks and places them in their assigned sections.
`handleBBAddrMap` is invoked after `handleBBSections` (if requested) and
only renumbers the blocks.
- New tests added:
- Two tests basic-block-address-map-with-basic-block-sections.ll and
basic-block-address-map-with-mfs.ll to exercise the combination of
`-basic-block-address-map` with `-basic-block-sections=list` and
'-split-machine-functions`.
- A driver sanity test for the `-fbasic-block-address-map` option
(basic-block-address-map.c).
- An LLD test for testing the `--lto-basic-block-address-map` option.
This reuses the LLVM IR from `lld/test/ELF/lto/basic-block-sections.ll`.
- Renamed and modified the two existing codegen tests for basic block
address map (`basic-block-sections-labels-functions-sections.ll` and
`basic-block-sections-labels.ll`)
- Removed `SHT_LLVM_BB_ADDR_MAP_V0` tests. Full deprecation of
`SHT_LLVM_BB_ADDR_MAP_V0` and `SHT_LLVM_BB_ADDR_MAP` version less than 2
will happen in a separate PR in a few months.
2024-02-01 17:50:46 -08:00
|
|
|
CGOPT(bool, EnableBBAddrMap)
|
2020-03-04 00:47:43 +01:00
|
|
|
CGOPT(std::string, BBSections)
|
|
|
|
CGOPT(unsigned, TLSSize)
|
2023-04-23 11:55:12 -07:00
|
|
|
CGOPT_EXP(bool, EmulatedTLS)
|
2024-01-23 16:16:07 -08:00
|
|
|
CGOPT_EXP(bool, EnableTLSDESC)
|
2020-03-04 00:47:43 +01:00
|
|
|
CGOPT(bool, UniqueSectionNames)
|
2020-06-01 23:17:29 -07:00
|
|
|
CGOPT(bool, UniqueBasicBlockSectionNames)
|
2024-05-07 09:18:55 -07:00
|
|
|
CGOPT(bool, SeparateNamedSections)
|
2020-03-04 00:47:43 +01:00
|
|
|
CGOPT(EABI, EABIVersion)
|
|
|
|
CGOPT(DebuggerKind, DebuggerTuningOpt)
|
|
|
|
CGOPT(bool, EnableStackSizeSection)
|
|
|
|
CGOPT(bool, EnableAddrsig)
|
|
|
|
CGOPT(bool, EmitCallSiteInfo)
|
2020-08-05 15:34:31 -07:00
|
|
|
CGOPT(bool, EnableMachineFunctionSplitter)
|
2020-03-04 00:47:43 +01:00
|
|
|
CGOPT(bool, EnableDebugEntryValues)
|
|
|
|
CGOPT(bool, ForceDwarfFrameSection)
|
2023-06-11 15:27:22 -07:00
|
|
|
CGOPT(bool, XRayFunctionIndex)
|
2021-05-09 22:04:02 -04:00
|
|
|
CGOPT(bool, DebugStrictDwarf)
|
2021-08-04 12:45:17 -07:00
|
|
|
CGOPT(unsigned, AlignLoops)
|
2022-02-10 15:10:48 -08:00
|
|
|
CGOPT(bool, JMCInstrument)
|
[AIX][CodeGen] Storage Locations for Constant Pointers
This patch adds an `llc` option `-mroptr` to specify storage locations for constant pointers on AIX.
When the `-mroptr` option is specified, constant pointers, virtual function tables, and virtual type tables are placed in read-only storage. Otherwise, by default, pointers, virtual function tables, and virtual type tables are placed are placed in read/write storage.
https://reviews.llvm.org/D144190 enables the `-mroptr` option for `clang`.
Reviewed By: hubert.reinterpretcast, stephenpeckham, myhsu, MaskRay, serge-sans-paille
Differential Revision: https://reviews.llvm.org/D144189
2023-03-23 09:16:18 -04:00
|
|
|
CGOPT(bool, XCOFFReadOnlyPointers)
|
2020-03-04 00:47:43 +01:00
|
|
|
|
|
|
|
codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
|
|
|
|
#define CGBINDOPT(NAME) \
|
|
|
|
do { \
|
|
|
|
NAME##View = std::addressof(NAME); \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
static cl::opt<std::string> MArch(
|
|
|
|
"march", cl::desc("Architecture to generate code for (see --version)"));
|
|
|
|
CGBINDOPT(MArch);
|
|
|
|
|
|
|
|
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(""));
|
|
|
|
CGBINDOPT(MCPU);
|
|
|
|
|
|
|
|
static cl::list<std::string> MAttrs(
|
|
|
|
"mattr", cl::CommaSeparated,
|
|
|
|
cl::desc("Target specific attributes (-mattr=help for details)"),
|
|
|
|
cl::value_desc("a1,+a2,-a3,..."));
|
|
|
|
CGBINDOPT(MAttrs);
|
|
|
|
|
|
|
|
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")));
|
|
|
|
CGBINDOPT(RelocModel);
|
|
|
|
|
|
|
|
static cl::opt<ThreadModel::Model> ThreadModel(
|
|
|
|
"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")));
|
|
|
|
CGBINDOPT(ThreadModel);
|
|
|
|
|
|
|
|
static cl::opt<CodeModel::Model> CodeModel(
|
|
|
|
"code-model", cl::desc("Choose code model"),
|
|
|
|
cl::values(clEnumValN(CodeModel::Tiny, "tiny", "Tiny code model"),
|
|
|
|
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")));
|
|
|
|
CGBINDOPT(CodeModel);
|
|
|
|
|
2023-05-10 13:13:58 -07:00
|
|
|
static cl::opt<uint64_t> LargeDataThreshold(
|
|
|
|
"large-data-threshold",
|
|
|
|
cl::desc("Choose large data threshold for x86_64 medium code model"),
|
|
|
|
cl::init(0));
|
|
|
|
CGBINDOPT(LargeDataThreshold);
|
|
|
|
|
2020-03-04 00:47:43 +01:00
|
|
|
static cl::opt<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"),
|
|
|
|
clEnumValN(ExceptionHandling::Wasm, "wasm",
|
|
|
|
"WebAssembly exception handling")));
|
|
|
|
CGBINDOPT(ExceptionModel);
|
|
|
|
|
|
|
|
static cl::opt<CodeGenFileType> FileType(
|
2023-09-14 14:10:14 -07:00
|
|
|
"filetype", cl::init(CodeGenFileType::AssemblyFile),
|
2020-03-04 00:47:43 +01:00
|
|
|
cl::desc(
|
|
|
|
"Choose a file type (not all types are supported by all targets):"),
|
2023-09-14 14:10:14 -07:00
|
|
|
cl::values(clEnumValN(CodeGenFileType::AssemblyFile, "asm",
|
|
|
|
"Emit an assembly ('.s') file"),
|
|
|
|
clEnumValN(CodeGenFileType::ObjectFile, "obj",
|
|
|
|
"Emit a native object ('.o') file"),
|
|
|
|
clEnumValN(CodeGenFileType::Null, "null",
|
|
|
|
"Emit nothing, for performance testing")));
|
2020-03-04 00:47:43 +01:00
|
|
|
CGBINDOPT(FileType);
|
|
|
|
|
2021-04-22 18:07:29 -07:00
|
|
|
static cl::opt<FramePointerKind> FramePointerUsage(
|
2020-03-04 00:47:43 +01:00
|
|
|
"frame-pointer",
|
|
|
|
cl::desc("Specify frame pointer elimination optimization"),
|
2021-04-22 18:07:29 -07:00
|
|
|
cl::init(FramePointerKind::None),
|
2020-03-04 00:47:43 +01:00
|
|
|
cl::values(
|
2021-04-22 18:07:29 -07:00
|
|
|
clEnumValN(FramePointerKind::All, "all",
|
2020-03-04 00:47:43 +01:00
|
|
|
"Disable frame pointer elimination"),
|
2021-04-22 18:07:29 -07:00
|
|
|
clEnumValN(FramePointerKind::NonLeaf, "non-leaf",
|
2020-03-04 00:47:43 +01:00
|
|
|
"Disable frame pointer elimination for non-leaf frame"),
|
2024-06-07 10:58:10 +01:00
|
|
|
clEnumValN(FramePointerKind::Reserved, "reserved",
|
|
|
|
"Enable frame pointer elimination, but reserve the frame "
|
|
|
|
"pointer register"),
|
2021-04-22 18:07:29 -07:00
|
|
|
clEnumValN(FramePointerKind::None, "none",
|
2020-03-04 00:47:43 +01:00
|
|
|
"Enable frame pointer elimination")));
|
|
|
|
CGBINDOPT(FramePointerUsage);
|
|
|
|
|
|
|
|
static cl::opt<bool> EnableUnsafeFPMath(
|
|
|
|
"enable-unsafe-fp-math",
|
|
|
|
cl::desc("Enable optimizations that may decrease FP precision"),
|
|
|
|
cl::init(false));
|
|
|
|
CGBINDOPT(EnableUnsafeFPMath);
|
|
|
|
|
|
|
|
static cl::opt<bool> EnableNoInfsFPMath(
|
|
|
|
"enable-no-infs-fp-math",
|
|
|
|
cl::desc("Enable FP math optimizations that assume no +-Infs"),
|
|
|
|
cl::init(false));
|
|
|
|
CGBINDOPT(EnableNoInfsFPMath);
|
|
|
|
|
|
|
|
static cl::opt<bool> EnableNoNaNsFPMath(
|
|
|
|
"enable-no-nans-fp-math",
|
|
|
|
cl::desc("Enable FP math optimizations that assume no NaNs"),
|
|
|
|
cl::init(false));
|
|
|
|
CGBINDOPT(EnableNoNaNsFPMath);
|
|
|
|
|
|
|
|
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));
|
|
|
|
CGBINDOPT(EnableNoSignedZerosFPMath);
|
|
|
|
|
2022-02-02 07:54:19 -08:00
|
|
|
static cl::opt<bool> EnableApproxFuncFPMath(
|
|
|
|
"enable-approx-func-fp-math",
|
|
|
|
cl::desc("Enable FP math optimizations that assume approx func"),
|
|
|
|
cl::init(false));
|
|
|
|
CGBINDOPT(EnableApproxFuncFPMath);
|
|
|
|
|
2020-03-04 00:47:43 +01:00
|
|
|
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));
|
|
|
|
CGBINDOPT(EnableNoTrappingFPMath);
|
|
|
|
|
LangRef: Add "dynamic" option to "denormal-fp-math"
This is stricter than the default "ieee", and should probably be the
default. This patch leaves the default alone. I can change this in a
future patch.
There are non-reversible transforms I would like to perform which are
legal under IEEE denormal handling, but illegal with flushing zero
behavior. Namely, conversions between llvm.is.fpclass and fcmp with
zeroes.
Under "ieee" handling, it is legal to translate between
llvm.is.fpclass(x, fcZero) and fcmp x, 0.
Under "preserve-sign" handling, it is legal to translate between
llvm.is.fpclass(x, fcSubnormal|fcZero) and fcmp x, 0.
I would like to compile and distribute some math library functions in
a mode where it's callable from code with and without denormals
enabled, which requires not changing the compares with denormals or
zeroes.
If an IEEE function transforms an llvm.is.fpclass call into an fcmp 0,
it is no longer possible to call the function from code with denormals
enabled, or write an optimization to move the function into a denormal
flushing mode. For the original function, if x was a denormal, the
class would evaluate to false. If the function compiled with denormal
handling was converted to or called from a preserve-sign function, the
fcmp now evaluates to true.
This could also be of use for strictfp handling, where code may be
changing the denormal mode.
Alternative name could be "unknown".
Replaces the old AMDGPU custom inlining logic with more conservative
logic which tries to permit inlining for callees with dynamic handling
and avoids inlining other mismatched modes.
2022-12-06 09:25:33 -05:00
|
|
|
static const auto DenormFlagEnumOptions = cl::values(
|
|
|
|
clEnumValN(DenormalMode::IEEE, "ieee", "IEEE 754 denormal numbers"),
|
|
|
|
clEnumValN(DenormalMode::PreserveSign, "preserve-sign",
|
|
|
|
"the sign of a flushed-to-zero number is preserved "
|
|
|
|
"in the sign of 0"),
|
|
|
|
clEnumValN(DenormalMode::PositiveZero, "positive-zero",
|
|
|
|
"denormals are flushed to positive zero"),
|
|
|
|
clEnumValN(DenormalMode::Dynamic, "dynamic",
|
|
|
|
"denormals have unknown treatment"));
|
2019-12-04 14:34:14 +05:30
|
|
|
|
|
|
|
// FIXME: Doesn't have way to specify separate input and output modes.
|
2020-03-11 17:12:20 -04:00
|
|
|
static cl::opt<DenormalMode::DenormalModeKind> DenormalFPMath(
|
2019-12-04 14:34:14 +05:30
|
|
|
"denormal-fp-math",
|
|
|
|
cl::desc("Select which denormal numbers the code is permitted to require"),
|
|
|
|
cl::init(DenormalMode::IEEE),
|
|
|
|
DenormFlagEnumOptions);
|
2020-03-04 00:47:43 +01:00
|
|
|
CGBINDOPT(DenormalFPMath);
|
|
|
|
|
2019-12-04 14:34:14 +05:30
|
|
|
static cl::opt<DenormalMode::DenormalModeKind> DenormalFP32Math(
|
|
|
|
"denormal-fp-math-f32",
|
|
|
|
cl::desc("Select which denormal numbers the code is permitted to require for float"),
|
|
|
|
cl::init(DenormalMode::Invalid),
|
|
|
|
DenormFlagEnumOptions);
|
|
|
|
CGBINDOPT(DenormalFP32Math);
|
|
|
|
|
2020-03-04 00:47:43 +01:00
|
|
|
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));
|
|
|
|
CGBINDOPT(EnableHonorSignDependentRoundingFPMath);
|
|
|
|
|
|
|
|
static cl::opt<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)")));
|
|
|
|
CGBINDOPT(FloatABIForCalls);
|
|
|
|
|
|
|
|
static cl::opt<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.")));
|
|
|
|
CGBINDOPT(FuseFPOps);
|
|
|
|
|
2021-09-15 13:35:08 -07:00
|
|
|
static cl::opt<SwiftAsyncFramePointerMode> SwiftAsyncFramePointer(
|
|
|
|
"swift-async-fp",
|
|
|
|
cl::desc("Determine when the Swift async frame pointer should be set"),
|
|
|
|
cl::init(SwiftAsyncFramePointerMode::Always),
|
|
|
|
cl::values(clEnumValN(SwiftAsyncFramePointerMode::DeploymentBased, "auto",
|
|
|
|
"Determine based on deployment target"),
|
|
|
|
clEnumValN(SwiftAsyncFramePointerMode::Always, "always",
|
|
|
|
"Always set the bit"),
|
|
|
|
clEnumValN(SwiftAsyncFramePointerMode::Never, "never",
|
|
|
|
"Never set the bit")));
|
|
|
|
CGBINDOPT(SwiftAsyncFramePointer);
|
|
|
|
|
2020-03-04 00:47:43 +01:00
|
|
|
static cl::opt<bool> DontPlaceZerosInBSS(
|
|
|
|
"nozero-initialized-in-bss",
|
|
|
|
cl::desc("Don't place zero-initialized symbols into bss section"),
|
|
|
|
cl::init(false));
|
|
|
|
CGBINDOPT(DontPlaceZerosInBSS);
|
|
|
|
|
2020-11-24 18:11:46 -05:00
|
|
|
static cl::opt<bool> EnableAIXExtendedAltivecABI(
|
|
|
|
"vec-extabi", cl::desc("Enable the AIX Extended Altivec ABI."),
|
|
|
|
cl::init(false));
|
|
|
|
CGBINDOPT(EnableAIXExtendedAltivecABI);
|
|
|
|
|
2020-03-04 00:47:43 +01:00
|
|
|
static cl::opt<bool> EnableGuaranteedTailCallOpt(
|
|
|
|
"tailcallopt",
|
|
|
|
cl::desc(
|
|
|
|
"Turn fastcc calls into tail calls by (potentially) changing ABI."),
|
|
|
|
cl::init(false));
|
|
|
|
CGBINDOPT(EnableGuaranteedTailCallOpt);
|
|
|
|
|
|
|
|
static cl::opt<bool> DisableTailCalls(
|
|
|
|
"disable-tail-calls", cl::desc("Never emit tail calls"), cl::init(false));
|
|
|
|
CGBINDOPT(DisableTailCalls);
|
|
|
|
|
|
|
|
static cl::opt<bool> StackSymbolOrdering(
|
|
|
|
"stack-symbol-ordering", cl::desc("Order local stack symbols."),
|
|
|
|
cl::init(true));
|
|
|
|
CGBINDOPT(StackSymbolOrdering);
|
|
|
|
|
|
|
|
static cl::opt<bool> StackRealign(
|
|
|
|
"stackrealign",
|
|
|
|
cl::desc("Force align the stack to the minimum alignment"),
|
|
|
|
cl::init(false));
|
|
|
|
CGBINDOPT(StackRealign);
|
|
|
|
|
|
|
|
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(""));
|
|
|
|
CGBINDOPT(TrapFuncName);
|
|
|
|
|
|
|
|
static cl::opt<bool> UseCtors("use-ctors",
|
|
|
|
cl::desc("Use .ctors instead of .init_array."),
|
|
|
|
cl::init(false));
|
|
|
|
CGBINDOPT(UseCtors);
|
|
|
|
|
|
|
|
static cl::opt<bool> DataSections(
|
|
|
|
"data-sections", cl::desc("Emit data into separate sections"),
|
|
|
|
cl::init(false));
|
|
|
|
CGBINDOPT(DataSections);
|
|
|
|
|
|
|
|
static cl::opt<bool> FunctionSections(
|
|
|
|
"function-sections", cl::desc("Emit functions into separate sections"),
|
|
|
|
cl::init(false));
|
|
|
|
CGBINDOPT(FunctionSections);
|
|
|
|
|
2020-10-08 09:34:58 -04:00
|
|
|
static cl::opt<bool> IgnoreXCOFFVisibility(
|
|
|
|
"ignore-xcoff-visibility",
|
|
|
|
cl::desc("Not emit the visibility attribute for asm in AIX OS or give "
|
|
|
|
"all symbols 'unspecified' visibility in XCOFF object file"),
|
|
|
|
cl::init(false));
|
|
|
|
CGBINDOPT(IgnoreXCOFFVisibility);
|
|
|
|
|
2020-12-11 17:50:25 -05:00
|
|
|
static cl::opt<bool> XCOFFTracebackTable(
|
|
|
|
"xcoff-traceback-table", cl::desc("Emit the XCOFF traceback table"),
|
|
|
|
cl::init(true));
|
|
|
|
CGBINDOPT(XCOFFTracebackTable);
|
|
|
|
|
[SHT_LLVM_BB_ADDR_MAP] Allow basic-block-sections and labels be used together by decoupling the handling of the two features. (#74128)
Today `-split-machine-functions` and `-fbasic-block-sections={all,list}`
cannot be combined with `-basic-block-sections=labels` (the labels
option will be ignored).
The inconsistency comes from the way basic block address map -- the
underlying mechanism for basic block labels -- encodes basic block
addresses
(https://lists.llvm.org/pipermail/llvm-dev/2020-July/143512.html).
Specifically, basic block offsets are computed relative to the function
begin symbol. This relies on functions being contiguous which is not the
case for MFS and basic block section binaries. This means Propeller
cannot use binary profiles collected from these binaries, which limits
the applicability of Propeller for iterative optimization.
To make the `SHT_LLVM_BB_ADDR_MAP` feature work with basic block section
binaries, we propose modifying the encoding of this section as follows.
First let us review the current encoding which emits the address of each
function and its number of basic blocks, followed by basic block entries
for each basic block.
| | |
|--|--|
| Address of the function | Function Address |
| Number of basic blocks in this function | NumBlocks |
| BB entry 1
| BB entry 2
| ...
| BB entry #NumBlocks
To make this work for basic block sections, we treat each basic block
section similar to a function, except that basic block sections of the
same function must be encapsulated in the same structure so we can map
all of them to their single function.
We modify the encoding to first emit the number of basic block sections
(BB ranges) in the function. Then we emit the address map of each basic
block section section as before: the base address of the section, its
number of blocks, and BB entries for its basic block. The first section
in the BB address map is always the function entry section.
| | |
|--|--|
| Number of sections for this function | NumBBRanges |
| Section 1 begin address | BaseAddress[1] |
| Number of basic blocks in section 1 | NumBlocks[1] |
| BB entries for Section 1
|..................|
| Section #NumBBRanges begin address | BaseAddress[NumBBRanges] |
| Number of basic blocks in section #NumBBRanges |
NumBlocks[NumBBRanges] |
| BB entries for Section #NumBBRanges
The encoding of basic block entries remains as before with the minor
change that each basic block offset is now computed relative to the
begin symbol of its containing BB section.
This patch adds a new boolean codegen option `-basic-block-address-map`.
Correspondingly, the front-end flag `-fbasic-block-address-map` and LLD
flag `--lto-basic-block-address-map` are introduced.
Analogously, we add a new TargetOption field `BBAddrMap`. This means BB
address maps are either generated for all functions in the compiling
unit, or for none (depending on `TargetOptions::BBAddrMap`).
This patch keeps the functionality of the old
`-fbasic-block-sections=labels` option but does not remove it. A
subsequent patch will remove the obsolete option.
We refactor the `BasicBlockSections` pass by separating the BB address
map and BB sections handing to their own functions (named
`handleBBAddrMap` and `handleBBSections`). `handleBBSections` renumbers
basic blocks and places them in their assigned sections.
`handleBBAddrMap` is invoked after `handleBBSections` (if requested) and
only renumbers the blocks.
- New tests added:
- Two tests basic-block-address-map-with-basic-block-sections.ll and
basic-block-address-map-with-mfs.ll to exercise the combination of
`-basic-block-address-map` with `-basic-block-sections=list` and
'-split-machine-functions`.
- A driver sanity test for the `-fbasic-block-address-map` option
(basic-block-address-map.c).
- An LLD test for testing the `--lto-basic-block-address-map` option.
This reuses the LLVM IR from `lld/test/ELF/lto/basic-block-sections.ll`.
- Renamed and modified the two existing codegen tests for basic block
address map (`basic-block-sections-labels-functions-sections.ll` and
`basic-block-sections-labels.ll`)
- Removed `SHT_LLVM_BB_ADDR_MAP_V0` tests. Full deprecation of
`SHT_LLVM_BB_ADDR_MAP_V0` and `SHT_LLVM_BB_ADDR_MAP` version less than 2
will happen in a separate PR in a few months.
2024-02-01 17:50:46 -08:00
|
|
|
static cl::opt<bool> EnableBBAddrMap(
|
|
|
|
"basic-block-address-map",
|
|
|
|
cl::desc("Emit the basic block address map section"), cl::init(false));
|
|
|
|
CGBINDOPT(EnableBBAddrMap);
|
|
|
|
|
2020-03-04 00:47:43 +01:00
|
|
|
static cl::opt<std::string> BBSections(
|
2020-07-31 11:14:49 -07:00
|
|
|
"basic-block-sections",
|
2020-03-04 00:47:43 +01:00
|
|
|
cl::desc("Emit basic blocks into separate sections"),
|
|
|
|
cl::value_desc("all | <function list (file)> | labels | none"),
|
|
|
|
cl::init("none"));
|
|
|
|
CGBINDOPT(BBSections);
|
|
|
|
|
|
|
|
static cl::opt<unsigned> TLSSize(
|
|
|
|
"tls-size", cl::desc("Bit size of immediate TLS offsets"), cl::init(0));
|
|
|
|
CGBINDOPT(TLSSize);
|
|
|
|
|
|
|
|
static cl::opt<bool> EmulatedTLS(
|
|
|
|
"emulated-tls", cl::desc("Use emulated TLS model"), cl::init(false));
|
|
|
|
CGBINDOPT(EmulatedTLS);
|
|
|
|
|
2024-01-23 16:16:07 -08:00
|
|
|
static cl::opt<bool> EnableTLSDESC(
|
|
|
|
"enable-tlsdesc", cl::desc("Enable the use of TLS Descriptors"),
|
|
|
|
cl::init(false));
|
|
|
|
CGBINDOPT(EnableTLSDESC);
|
|
|
|
|
2020-03-04 00:47:43 +01:00
|
|
|
static cl::opt<bool> UniqueSectionNames(
|
|
|
|
"unique-section-names", cl::desc("Give unique names to every section"),
|
|
|
|
cl::init(true));
|
|
|
|
CGBINDOPT(UniqueSectionNames);
|
|
|
|
|
2020-06-01 23:17:29 -07:00
|
|
|
static cl::opt<bool> UniqueBasicBlockSectionNames(
|
2020-07-31 11:14:49 -07:00
|
|
|
"unique-basic-block-section-names",
|
2020-03-04 00:47:43 +01:00
|
|
|
cl::desc("Give unique names to every basic block section"),
|
|
|
|
cl::init(false));
|
2020-06-01 23:17:29 -07:00
|
|
|
CGBINDOPT(UniqueBasicBlockSectionNames);
|
2020-03-04 00:47:43 +01:00
|
|
|
|
2024-05-07 09:18:55 -07:00
|
|
|
static cl::opt<bool> SeparateNamedSections(
|
|
|
|
"separate-named-sections",
|
|
|
|
cl::desc("Use separate unique sections for named sections"),
|
|
|
|
cl::init(false));
|
|
|
|
CGBINDOPT(SeparateNamedSections);
|
|
|
|
|
2020-03-04 00:47:43 +01:00
|
|
|
static cl::opt<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")));
|
|
|
|
CGBINDOPT(EABIVersion);
|
|
|
|
|
|
|
|
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"),
|
2021-04-08 07:20:22 +00:00
|
|
|
clEnumValN(DebuggerKind::DBX, "dbx", "dbx"),
|
2020-03-04 00:47:43 +01:00
|
|
|
clEnumValN(DebuggerKind::SCE, "sce", "SCE targets (e.g. PS4)")));
|
|
|
|
CGBINDOPT(DebuggerTuningOpt);
|
|
|
|
|
|
|
|
static cl::opt<bool> EnableStackSizeSection(
|
|
|
|
"stack-size-section",
|
|
|
|
cl::desc("Emit a section containing stack size metadata"),
|
|
|
|
cl::init(false));
|
|
|
|
CGBINDOPT(EnableStackSizeSection);
|
|
|
|
|
|
|
|
static cl::opt<bool> EnableAddrsig(
|
|
|
|
"addrsig", cl::desc("Emit an address-significance table"),
|
|
|
|
cl::init(false));
|
|
|
|
CGBINDOPT(EnableAddrsig);
|
|
|
|
|
|
|
|
static cl::opt<bool> EmitCallSiteInfo(
|
|
|
|
"emit-call-site-info",
|
|
|
|
cl::desc(
|
|
|
|
"Emit call site debug information, if debug information is enabled."),
|
|
|
|
cl::init(false));
|
|
|
|
CGBINDOPT(EmitCallSiteInfo);
|
|
|
|
|
|
|
|
static cl::opt<bool> EnableDebugEntryValues(
|
|
|
|
"debug-entry-values",
|
2020-03-19 12:13:18 +01:00
|
|
|
cl::desc("Enable debug info for the debug entry values."),
|
2020-03-04 00:47:43 +01:00
|
|
|
cl::init(false));
|
|
|
|
CGBINDOPT(EnableDebugEntryValues);
|
|
|
|
|
2020-08-05 15:34:31 -07:00
|
|
|
static cl::opt<bool> EnableMachineFunctionSplitter(
|
|
|
|
"split-machine-functions",
|
|
|
|
cl::desc("Split out cold basic blocks from machine functions based on "
|
|
|
|
"profile information"),
|
|
|
|
cl::init(false));
|
|
|
|
CGBINDOPT(EnableMachineFunctionSplitter);
|
|
|
|
|
2020-03-04 00:47:43 +01:00
|
|
|
static cl::opt<bool> ForceDwarfFrameSection(
|
|
|
|
"force-dwarf-frame-section",
|
|
|
|
cl::desc("Always emit a debug frame section."), cl::init(false));
|
|
|
|
CGBINDOPT(ForceDwarfFrameSection);
|
|
|
|
|
2023-06-11 15:27:22 -07:00
|
|
|
static cl::opt<bool> XRayFunctionIndex("xray-function-index",
|
|
|
|
cl::desc("Emit xray_fn_idx section"),
|
|
|
|
cl::init(true));
|
|
|
|
CGBINDOPT(XRayFunctionIndex);
|
2020-06-16 20:36:11 -04:00
|
|
|
|
2021-05-09 22:04:02 -04:00
|
|
|
static cl::opt<bool> DebugStrictDwarf(
|
|
|
|
"strict-dwarf", cl::desc("use strict dwarf"), cl::init(false));
|
|
|
|
CGBINDOPT(DebugStrictDwarf);
|
|
|
|
|
2021-08-04 12:45:17 -07:00
|
|
|
static cl::opt<unsigned> AlignLoops("align-loops",
|
|
|
|
cl::desc("Default alignment for loops"));
|
|
|
|
CGBINDOPT(AlignLoops);
|
|
|
|
|
2022-02-10 15:10:48 -08:00
|
|
|
static cl::opt<bool> JMCInstrument(
|
|
|
|
"enable-jmc-instrument",
|
|
|
|
cl::desc("Instrument functions with a call to __CheckForDebuggerJustMyCode"),
|
|
|
|
cl::init(false));
|
|
|
|
CGBINDOPT(JMCInstrument);
|
|
|
|
|
[AIX][CodeGen] Storage Locations for Constant Pointers
This patch adds an `llc` option `-mroptr` to specify storage locations for constant pointers on AIX.
When the `-mroptr` option is specified, constant pointers, virtual function tables, and virtual type tables are placed in read-only storage. Otherwise, by default, pointers, virtual function tables, and virtual type tables are placed are placed in read/write storage.
https://reviews.llvm.org/D144190 enables the `-mroptr` option for `clang`.
Reviewed By: hubert.reinterpretcast, stephenpeckham, myhsu, MaskRay, serge-sans-paille
Differential Revision: https://reviews.llvm.org/D144189
2023-03-23 09:16:18 -04:00
|
|
|
static cl::opt<bool> XCOFFReadOnlyPointers(
|
2023-03-31 09:47:07 -04:00
|
|
|
"mxcoff-roptr",
|
[AIX][CodeGen] Storage Locations for Constant Pointers
This patch adds an `llc` option `-mroptr` to specify storage locations for constant pointers on AIX.
When the `-mroptr` option is specified, constant pointers, virtual function tables, and virtual type tables are placed in read-only storage. Otherwise, by default, pointers, virtual function tables, and virtual type tables are placed are placed in read/write storage.
https://reviews.llvm.org/D144190 enables the `-mroptr` option for `clang`.
Reviewed By: hubert.reinterpretcast, stephenpeckham, myhsu, MaskRay, serge-sans-paille
Differential Revision: https://reviews.llvm.org/D144189
2023-03-23 09:16:18 -04:00
|
|
|
cl::desc("When set to true, const objects with relocatable address "
|
|
|
|
"values are put into the RO data section."),
|
|
|
|
cl::init(false));
|
|
|
|
CGBINDOPT(XCOFFReadOnlyPointers);
|
|
|
|
|
2023-07-12 12:45:50 -04:00
|
|
|
static cl::opt<bool> DisableIntegratedAS(
|
|
|
|
"no-integrated-as", cl::desc("Disable integrated assembler"),
|
|
|
|
cl::init(false));
|
|
|
|
CGBINDOPT(DisableIntegratedAS);
|
|
|
|
|
2020-03-04 00:47:43 +01:00
|
|
|
#undef CGBINDOPT
|
|
|
|
|
|
|
|
mc::RegisterMCTargetOptionsFlags();
|
|
|
|
}
|
|
|
|
|
|
|
|
llvm::BasicBlockSection
|
|
|
|
codegen::getBBSectionsMode(llvm::TargetOptions &Options) {
|
|
|
|
if (getBBSections() == "all")
|
|
|
|
return BasicBlockSection::All;
|
|
|
|
else if (getBBSections() == "labels")
|
|
|
|
return BasicBlockSection::Labels;
|
|
|
|
else if (getBBSections() == "none")
|
|
|
|
return BasicBlockSection::None;
|
|
|
|
else {
|
|
|
|
ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
|
|
|
|
MemoryBuffer::getFile(getBBSections());
|
|
|
|
if (!MBOrErr) {
|
|
|
|
errs() << "Error loading basic block sections function list file: "
|
|
|
|
<< MBOrErr.getError().message() << "\n";
|
|
|
|
} else {
|
|
|
|
Options.BBSectionsFuncListBuf = std::move(*MBOrErr);
|
|
|
|
}
|
|
|
|
return BasicBlockSection::List;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Common utility function tightly tied to the options listed here. Initializes
|
|
|
|
// a TargetOptions object with CodeGen flags and returns it.
|
2020-10-14 15:55:55 +00:00
|
|
|
TargetOptions
|
|
|
|
codegen::InitTargetOptionsFromCodeGenFlags(const Triple &TheTriple) {
|
2020-03-04 00:47:43 +01:00
|
|
|
TargetOptions Options;
|
|
|
|
Options.AllowFPOpFusion = getFuseFPOps();
|
|
|
|
Options.UnsafeFPMath = getEnableUnsafeFPMath();
|
|
|
|
Options.NoInfsFPMath = getEnableNoInfsFPMath();
|
|
|
|
Options.NoNaNsFPMath = getEnableNoNaNsFPMath();
|
|
|
|
Options.NoSignedZerosFPMath = getEnableNoSignedZerosFPMath();
|
2022-02-02 07:54:19 -08:00
|
|
|
Options.ApproxFuncFPMath = getEnableApproxFuncFPMath();
|
2020-03-04 00:47:43 +01:00
|
|
|
Options.NoTrappingFPMath = getEnableNoTrappingFPMath();
|
2020-03-11 17:12:20 -04:00
|
|
|
|
|
|
|
DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath();
|
|
|
|
|
|
|
|
// FIXME: Should have separate input and output flags
|
|
|
|
Options.setFPDenormalMode(DenormalMode(DenormKind, DenormKind));
|
|
|
|
|
2020-03-04 00:47:43 +01:00
|
|
|
Options.HonorSignDependentRoundingFPMathOption =
|
|
|
|
getEnableHonorSignDependentRoundingFPMath();
|
|
|
|
if (getFloatABIForCalls() != FloatABI::Default)
|
|
|
|
Options.FloatABIType = getFloatABIForCalls();
|
2020-11-24 18:11:46 -05:00
|
|
|
Options.EnableAIXExtendedAltivecABI = getEnableAIXExtendedAltivecABI();
|
2020-03-04 00:47:43 +01:00
|
|
|
Options.NoZerosInBSS = getDontPlaceZerosInBSS();
|
|
|
|
Options.GuaranteedTailCallOpt = getEnableGuaranteedTailCallOpt();
|
|
|
|
Options.StackSymbolOrdering = getStackSymbolOrdering();
|
|
|
|
Options.UseInitArray = !getUseCtors();
|
2023-07-12 12:45:50 -04:00
|
|
|
Options.DisableIntegratedAS = getDisableIntegratedAS();
|
2020-10-14 15:55:55 +00:00
|
|
|
Options.DataSections =
|
2022-06-18 23:07:11 -07:00
|
|
|
getExplicitDataSections().value_or(TheTriple.hasDefaultDataSections());
|
2020-03-04 00:47:43 +01:00
|
|
|
Options.FunctionSections = getFunctionSections();
|
2020-10-08 09:34:58 -04:00
|
|
|
Options.IgnoreXCOFFVisibility = getIgnoreXCOFFVisibility();
|
2020-12-11 17:50:25 -05:00
|
|
|
Options.XCOFFTracebackTable = getXCOFFTracebackTable();
|
[SHT_LLVM_BB_ADDR_MAP] Allow basic-block-sections and labels be used together by decoupling the handling of the two features. (#74128)
Today `-split-machine-functions` and `-fbasic-block-sections={all,list}`
cannot be combined with `-basic-block-sections=labels` (the labels
option will be ignored).
The inconsistency comes from the way basic block address map -- the
underlying mechanism for basic block labels -- encodes basic block
addresses
(https://lists.llvm.org/pipermail/llvm-dev/2020-July/143512.html).
Specifically, basic block offsets are computed relative to the function
begin symbol. This relies on functions being contiguous which is not the
case for MFS and basic block section binaries. This means Propeller
cannot use binary profiles collected from these binaries, which limits
the applicability of Propeller for iterative optimization.
To make the `SHT_LLVM_BB_ADDR_MAP` feature work with basic block section
binaries, we propose modifying the encoding of this section as follows.
First let us review the current encoding which emits the address of each
function and its number of basic blocks, followed by basic block entries
for each basic block.
| | |
|--|--|
| Address of the function | Function Address |
| Number of basic blocks in this function | NumBlocks |
| BB entry 1
| BB entry 2
| ...
| BB entry #NumBlocks
To make this work for basic block sections, we treat each basic block
section similar to a function, except that basic block sections of the
same function must be encapsulated in the same structure so we can map
all of them to their single function.
We modify the encoding to first emit the number of basic block sections
(BB ranges) in the function. Then we emit the address map of each basic
block section section as before: the base address of the section, its
number of blocks, and BB entries for its basic block. The first section
in the BB address map is always the function entry section.
| | |
|--|--|
| Number of sections for this function | NumBBRanges |
| Section 1 begin address | BaseAddress[1] |
| Number of basic blocks in section 1 | NumBlocks[1] |
| BB entries for Section 1
|..................|
| Section #NumBBRanges begin address | BaseAddress[NumBBRanges] |
| Number of basic blocks in section #NumBBRanges |
NumBlocks[NumBBRanges] |
| BB entries for Section #NumBBRanges
The encoding of basic block entries remains as before with the minor
change that each basic block offset is now computed relative to the
begin symbol of its containing BB section.
This patch adds a new boolean codegen option `-basic-block-address-map`.
Correspondingly, the front-end flag `-fbasic-block-address-map` and LLD
flag `--lto-basic-block-address-map` are introduced.
Analogously, we add a new TargetOption field `BBAddrMap`. This means BB
address maps are either generated for all functions in the compiling
unit, or for none (depending on `TargetOptions::BBAddrMap`).
This patch keeps the functionality of the old
`-fbasic-block-sections=labels` option but does not remove it. A
subsequent patch will remove the obsolete option.
We refactor the `BasicBlockSections` pass by separating the BB address
map and BB sections handing to their own functions (named
`handleBBAddrMap` and `handleBBSections`). `handleBBSections` renumbers
basic blocks and places them in their assigned sections.
`handleBBAddrMap` is invoked after `handleBBSections` (if requested) and
only renumbers the blocks.
- New tests added:
- Two tests basic-block-address-map-with-basic-block-sections.ll and
basic-block-address-map-with-mfs.ll to exercise the combination of
`-basic-block-address-map` with `-basic-block-sections=list` and
'-split-machine-functions`.
- A driver sanity test for the `-fbasic-block-address-map` option
(basic-block-address-map.c).
- An LLD test for testing the `--lto-basic-block-address-map` option.
This reuses the LLVM IR from `lld/test/ELF/lto/basic-block-sections.ll`.
- Renamed and modified the two existing codegen tests for basic block
address map (`basic-block-sections-labels-functions-sections.ll` and
`basic-block-sections-labels.ll`)
- Removed `SHT_LLVM_BB_ADDR_MAP_V0` tests. Full deprecation of
`SHT_LLVM_BB_ADDR_MAP_V0` and `SHT_LLVM_BB_ADDR_MAP` version less than 2
will happen in a separate PR in a few months.
2024-02-01 17:50:46 -08:00
|
|
|
Options.BBAddrMap = getEnableBBAddrMap();
|
2020-03-04 00:47:43 +01:00
|
|
|
Options.BBSections = getBBSectionsMode(Options);
|
|
|
|
Options.UniqueSectionNames = getUniqueSectionNames();
|
2020-06-01 23:17:29 -07:00
|
|
|
Options.UniqueBasicBlockSectionNames = getUniqueBasicBlockSectionNames();
|
2024-05-07 09:18:55 -07:00
|
|
|
Options.SeparateNamedSections = getSeparateNamedSections();
|
2020-03-04 00:47:43 +01:00
|
|
|
Options.TLSSize = getTLSSize();
|
2023-04-23 11:55:12 -07:00
|
|
|
Options.EmulatedTLS =
|
|
|
|
getExplicitEmulatedTLS().value_or(TheTriple.hasDefaultEmulatedTLS());
|
2024-01-23 16:16:07 -08:00
|
|
|
Options.EnableTLSDESC =
|
|
|
|
getExplicitEnableTLSDESC().value_or(TheTriple.hasDefaultTLSDESC());
|
2020-03-04 00:47:43 +01:00
|
|
|
Options.ExceptionModel = getExceptionModel();
|
|
|
|
Options.EmitStackSizeSection = getEnableStackSizeSection();
|
2020-08-05 15:34:31 -07:00
|
|
|
Options.EnableMachineFunctionSplitter = getEnableMachineFunctionSplitter();
|
2020-03-04 00:47:43 +01:00
|
|
|
Options.EmitAddrsig = getEnableAddrsig();
|
|
|
|
Options.EmitCallSiteInfo = getEmitCallSiteInfo();
|
|
|
|
Options.EnableDebugEntryValues = getEnableDebugEntryValues();
|
|
|
|
Options.ForceDwarfFrameSection = getForceDwarfFrameSection();
|
2023-06-11 15:27:22 -07:00
|
|
|
Options.XRayFunctionIndex = getXRayFunctionIndex();
|
2021-05-09 22:04:02 -04:00
|
|
|
Options.DebugStrictDwarf = getDebugStrictDwarf();
|
2021-08-04 12:45:17 -07:00
|
|
|
Options.LoopAlignment = getAlignLoops();
|
2022-02-10 15:10:48 -08:00
|
|
|
Options.JMCInstrument = getJMCInstrument();
|
[AIX][CodeGen] Storage Locations for Constant Pointers
This patch adds an `llc` option `-mroptr` to specify storage locations for constant pointers on AIX.
When the `-mroptr` option is specified, constant pointers, virtual function tables, and virtual type tables are placed in read-only storage. Otherwise, by default, pointers, virtual function tables, and virtual type tables are placed are placed in read/write storage.
https://reviews.llvm.org/D144190 enables the `-mroptr` option for `clang`.
Reviewed By: hubert.reinterpretcast, stephenpeckham, myhsu, MaskRay, serge-sans-paille
Differential Revision: https://reviews.llvm.org/D144189
2023-03-23 09:16:18 -04:00
|
|
|
Options.XCOFFReadOnlyPointers = getXCOFFReadOnlyPointers();
|
2020-03-04 00:47:43 +01:00
|
|
|
|
|
|
|
Options.MCOptions = mc::InitMCTargetOptionsFromFlags();
|
|
|
|
|
|
|
|
Options.ThreadModel = getThreadModel();
|
|
|
|
Options.EABIVersion = getEABIVersion();
|
|
|
|
Options.DebuggerTuning = getDebuggerTuningOpt();
|
2021-09-15 13:35:08 -07:00
|
|
|
Options.SwiftAsyncFramePointer = getSwiftAsyncFramePointer();
|
2020-03-04 00:47:43 +01:00
|
|
|
return Options;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string codegen::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 (getMCPU() == "native")
|
|
|
|
return std::string(sys::getHostCPUName());
|
|
|
|
|
|
|
|
return getMCPU();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string codegen::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 (getMCPU() == "native") {
|
|
|
|
StringMap<bool> HostFeatures;
|
|
|
|
if (sys::getHostCPUFeatures(HostFeatures))
|
2022-12-04 18:36:41 +01:00
|
|
|
for (const auto &[Feature, IsEnabled] : HostFeatures)
|
|
|
|
Features.AddFeature(Feature, IsEnabled);
|
2020-03-04 00:47:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
for (auto const &MAttr : getMAttrs())
|
|
|
|
Features.AddFeature(MAttr);
|
|
|
|
|
|
|
|
return Features.getString();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<std::string> codegen::getFeatureList() {
|
|
|
|
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 (getMCPU() == "native") {
|
|
|
|
StringMap<bool> HostFeatures;
|
|
|
|
if (sys::getHostCPUFeatures(HostFeatures))
|
2022-12-04 18:36:41 +01:00
|
|
|
for (const auto &[Feature, IsEnabled] : HostFeatures)
|
|
|
|
Features.AddFeature(Feature, IsEnabled);
|
2020-03-04 00:47:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
for (auto const &MAttr : getMAttrs())
|
|
|
|
Features.AddFeature(MAttr);
|
|
|
|
|
|
|
|
return Features.getFeatures();
|
|
|
|
}
|
|
|
|
|
|
|
|
void codegen::renderBoolStringAttr(AttrBuilder &B, StringRef Name, bool Val) {
|
|
|
|
B.addAttribute(Name, Val ? "true" : "false");
|
|
|
|
}
|
|
|
|
|
|
|
|
#define HANDLE_BOOL_ATTR(CL, AttrName) \
|
|
|
|
do { \
|
|
|
|
if (CL->getNumOccurrences() > 0 && !F.hasFnAttribute(AttrName)) \
|
|
|
|
renderBoolStringAttr(NewAttrs, AttrName, *CL); \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
/// Set function attributes of function \p F based on CPU, Features, and command
|
|
|
|
/// line flags.
|
|
|
|
void codegen::setFunctionAttributes(StringRef CPU, StringRef Features,
|
|
|
|
Function &F) {
|
|
|
|
auto &Ctx = F.getContext();
|
|
|
|
AttributeList Attrs = F.getAttributes();
|
2022-01-03 13:32:19 -05:00
|
|
|
AttrBuilder NewAttrs(Ctx);
|
2020-03-04 00:47:43 +01:00
|
|
|
|
|
|
|
if (!CPU.empty() && !F.hasFnAttribute("target-cpu"))
|
|
|
|
NewAttrs.addAttribute("target-cpu", CPU);
|
|
|
|
if (!Features.empty()) {
|
|
|
|
// Append the command line features to any that are already on the function.
|
|
|
|
StringRef OldFeatures =
|
|
|
|
F.getFnAttribute("target-features").getValueAsString();
|
|
|
|
if (OldFeatures.empty())
|
|
|
|
NewAttrs.addAttribute("target-features", Features);
|
|
|
|
else {
|
|
|
|
SmallString<256> Appended(OldFeatures);
|
|
|
|
Appended.push_back(',');
|
|
|
|
Appended.append(Features);
|
|
|
|
NewAttrs.addAttribute("target-features", Appended);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (FramePointerUsageView->getNumOccurrences() > 0 &&
|
|
|
|
!F.hasFnAttribute("frame-pointer")) {
|
2021-04-22 18:07:29 -07:00
|
|
|
if (getFramePointerUsage() == FramePointerKind::All)
|
2020-03-04 00:47:43 +01:00
|
|
|
NewAttrs.addAttribute("frame-pointer", "all");
|
2021-04-22 18:07:29 -07:00
|
|
|
else if (getFramePointerUsage() == FramePointerKind::NonLeaf)
|
2020-03-04 00:47:43 +01:00
|
|
|
NewAttrs.addAttribute("frame-pointer", "non-leaf");
|
2024-06-07 10:58:10 +01:00
|
|
|
else if (getFramePointerUsage() == FramePointerKind::Reserved)
|
|
|
|
NewAttrs.addAttribute("frame-pointer", "reserved");
|
2021-04-22 18:07:29 -07:00
|
|
|
else if (getFramePointerUsage() == FramePointerKind::None)
|
2020-03-04 00:47:43 +01:00
|
|
|
NewAttrs.addAttribute("frame-pointer", "none");
|
|
|
|
}
|
|
|
|
if (DisableTailCallsView->getNumOccurrences() > 0)
|
|
|
|
NewAttrs.addAttribute("disable-tail-calls",
|
|
|
|
toStringRef(getDisableTailCalls()));
|
|
|
|
if (getStackRealign())
|
|
|
|
NewAttrs.addAttribute("stackrealign");
|
|
|
|
|
|
|
|
HANDLE_BOOL_ATTR(EnableUnsafeFPMathView, "unsafe-fp-math");
|
|
|
|
HANDLE_BOOL_ATTR(EnableNoInfsFPMathView, "no-infs-fp-math");
|
|
|
|
HANDLE_BOOL_ATTR(EnableNoNaNsFPMathView, "no-nans-fp-math");
|
|
|
|
HANDLE_BOOL_ATTR(EnableNoSignedZerosFPMathView, "no-signed-zeros-fp-math");
|
2022-02-02 07:54:19 -08:00
|
|
|
HANDLE_BOOL_ATTR(EnableApproxFuncFPMathView, "approx-func-fp-math");
|
2020-03-04 00:47:43 +01:00
|
|
|
|
2020-03-11 17:12:20 -04:00
|
|
|
if (DenormalFPMathView->getNumOccurrences() > 0 &&
|
|
|
|
!F.hasFnAttribute("denormal-fp-math")) {
|
|
|
|
DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath();
|
|
|
|
|
|
|
|
// FIXME: Command line flag should expose separate input/output modes.
|
|
|
|
NewAttrs.addAttribute("denormal-fp-math",
|
|
|
|
DenormalMode(DenormKind, DenormKind).str());
|
|
|
|
}
|
|
|
|
|
2019-12-04 14:34:14 +05:30
|
|
|
if (DenormalFP32MathView->getNumOccurrences() > 0 &&
|
|
|
|
!F.hasFnAttribute("denormal-fp-math-f32")) {
|
|
|
|
// FIXME: Command line flag should expose separate input/output modes.
|
|
|
|
DenormalMode::DenormalModeKind DenormKind = getDenormalFP32Math();
|
|
|
|
|
|
|
|
NewAttrs.addAttribute(
|
|
|
|
"denormal-fp-math-f32",
|
|
|
|
DenormalMode(DenormKind, DenormKind).str());
|
|
|
|
}
|
|
|
|
|
2020-03-04 00:47:43 +01:00
|
|
|
if (TrapFuncNameView->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)
|
2021-08-17 20:25:16 -07:00
|
|
|
Call->addFnAttr(
|
2020-03-04 00:47:43 +01:00
|
|
|
Attribute::get(Ctx, "trap-func-name", getTrapFuncName()));
|
|
|
|
|
|
|
|
// Let NewAttrs override Attrs.
|
2021-08-16 18:24:22 -07:00
|
|
|
F.setAttributes(Attrs.addFnAttributes(Ctx, NewAttrs));
|
2020-03-04 00:47:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Set function attributes of functions in Module M based on CPU,
|
|
|
|
/// Features, and command line flags.
|
|
|
|
void codegen::setFunctionAttributes(StringRef CPU, StringRef Features,
|
|
|
|
Module &M) {
|
|
|
|
for (Function &F : M)
|
|
|
|
setFunctionAttributes(CPU, Features, F);
|
|
|
|
}
|
2022-11-24 11:23:38 +00:00
|
|
|
|
|
|
|
Expected<std::unique_ptr<TargetMachine>>
|
|
|
|
codegen::createTargetMachineForTriple(StringRef TargetTriple,
|
|
|
|
CodeGenOptLevel OptLevel) {
|
|
|
|
Triple TheTriple(TargetTriple);
|
|
|
|
std::string Error;
|
|
|
|
const auto *TheTarget =
|
|
|
|
TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error);
|
|
|
|
if (!TheTarget)
|
|
|
|
return createStringError(inconvertibleErrorCode(), Error);
|
|
|
|
auto *Target = TheTarget->createTargetMachine(
|
|
|
|
TheTriple.getTriple(), codegen::getCPUStr(), codegen::getFeaturesStr(),
|
|
|
|
codegen::InitTargetOptionsFromCodeGenFlags(TheTriple),
|
|
|
|
codegen::getExplicitRelocModel(), codegen::getExplicitCodeModel(),
|
|
|
|
OptLevel);
|
|
|
|
if (!Target)
|
|
|
|
return createStringError(inconvertibleErrorCode(),
|
|
|
|
Twine("could not allocate target machine for ") +
|
|
|
|
TargetTriple);
|
|
|
|
return std::unique_ptr<TargetMachine>(Target);
|
|
|
|
}
|