blob: 0459b2f8b4b7610f661935224f14766990b03c97 [file] [log] [blame]
// Copyright 2020 The IREE Authors
//
// Licensed 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
#ifndef IREE_COMPILER_PLUGINS_TARGET_LLVMCPU_LLVMTARGETOPTIONS_H_
#define IREE_COMPILER_PLUGINS_TARGET_LLVMCPU_LLVMTARGETOPTIONS_H_
#include <string_view>
#include "compiler/plugins/target/LLVMCPU/ResolveCPUAndCPUFeatures.h"
#include "iree/compiler/Utils/OptionUtils.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetOptions.h"
#include "mlir/IR/BuiltinAttributes.h"
#include "mlir/IR/Location.h"
namespace mlir::iree_compiler::IREE::HAL {
// Defines kinds of Sanitizer
// The order in enum class should be same as one in flat buffer schema
enum class SanitizerKind {
kNone = 0,
kAddress,
kThread,
};
// The LLVMTarget contains all of the information to perform code generation
// and linking for an ExecutableVariant. It should not contain any
// environmental configuration like linker paths, diagnostic aids, etc.
struct LLVMTarget {
static constexpr const char *DEFAULT_DATA_LAYOUT = "";
static constexpr int64_t DEFAULT_VECTOR_WIDTH_IN_BYTES = 0;
static constexpr bool DEFAULT_LINK_EMBEDDED = true;
static constexpr bool DEFAULT_DEBUG_SYMBOLS = true;
static constexpr SanitizerKind DEFAULT_SANITIZER_KIND = SanitizerKind::kNone;
static constexpr bool DEFAULT_LINK_STATIC = false;
static constexpr bool DEFAULT_LOOP_INTERLEAVING = false;
static constexpr bool DEFAULT_LOOP_VECTORIZATION = false;
static constexpr bool DEFAULT_LOOP_UNROLLING = false;
static constexpr bool DEFAULT_SLP_VECTORIZATION = false;
static constexpr llvm::FloatABI::ABIType DEFAULT_FLOAT_ABI =
llvm::FloatABI::ABIType::Hard;
static constexpr const char *DEFAULT_ENABLE_UKERNELS = "default";
static constexpr bool DEFAULT_LINK_UKERNEL_BITCODE = true;
// Default initialize all fields.
LLVMTarget();
void copy(const LLVMTarget &other) {
triple = other.triple;
cpu = other.cpu;
cpuFeatures = other.cpuFeatures;
dataLayout = other.dataLayout;
vectorWidthInBytes = other.vectorWidthInBytes;
linkEmbedded = other.linkEmbedded;
ukernels = other.ukernels;
linkUkernelBitcode = other.linkUkernelBitcode;
}
void print(llvm::raw_ostream &os) const;
// Stores the target to the given DictionaryAttr in a way that can be
// later loaded from loadFromConfigAttr().
void storeToConfigAttrs(MLIRContext *context,
SmallVector<NamedAttribute> &config) const;
static std::optional<LLVMTarget>
create(std::string_view triple, std::string_view cpu,
std::string_view cpuFeatures, bool requestLinkEmbedded,
ResolveCPUAndCPUFeaturesStatus &status);
static std::optional<LLVMTarget> createForHost();
// Loads from a DictionaryAttr. On failure returns none and emits.
static std::optional<LLVMTarget>
loadFromConfigAttr(Location loc, DictionaryAttr config,
const LLVMTarget &defaultTarget);
// Key fields about the machine can only be set via constructor.
const std::string &getTriple() const { return triple; }
const std::string &getCpu() const { return cpu; }
const std::string &getCpuFeatures() const { return cpuFeatures; }
// Overrides the data layout of the target.
std::string dataLayout = DEFAULT_DATA_LAYOUT;
// Overrides the vector width (in bytes) of the target.
int64_t vectorWidthInBytes = DEFAULT_VECTOR_WIDTH_IN_BYTES;
llvm::PipelineTuningOptions pipelineTuningOptions;
// Optimization level to be used by the LLVM optimizer (middle-end).
llvm::OptimizationLevel optimizerOptLevel;
// Optimization level to be used by the LLVM code generator (back-end).
llvm::CodeGenOptLevel codeGenOptLevel;
llvm::TargetOptions llvmTargetOptions;
bool getLinkEmbedded() const { return linkEmbedded; }
// Include debug information in output files (PDB, DWARF, etc).
// Though this can be set independently from the optLevel (so -O3 with debug
// information is valid) it may significantly change the output program
// contents and benchmarking of binary sizes and to some extent execution
// time should be avoided with symbols present.
bool debugSymbols = DEFAULT_DEBUG_SYMBOLS;
// Sanitizer Kind for CPU Kernels
SanitizerKind sanitizerKind = DEFAULT_SANITIZER_KIND;
// Build for IREE static library loading using this output path for
// a "{staticLibraryOutput}.o" object file and "{staticLibraryOutput}.h"
// header file.
//
// This option is incompatible with the linkEmbedded option.
std::string staticLibraryOutput;
// Link any required runtime libraries into the produced binaries statically.
// This increases resulting binary size but enables the binaries to be used on
// any machine without requiring matching system libraries to be installed.
bool linkStatic = DEFAULT_LINK_STATIC;
// Enables ukernels in the generated executables. May be `default`, `none`,
// `all`, or a comma-separated list of specific unprefixed ukernels to
// enable, e.g. `mmt4d`.
std::string ukernels = DEFAULT_ENABLE_UKERNELS;
// Link built-in ukernel bitcode libraries into generated executables.
bool linkUkernelBitcode = DEFAULT_LINK_UKERNEL_BITCODE;
private:
void populateDefaultsFromTargetMachine();
std::string triple;
std::string cpu;
std::string cpuFeatures;
// Build for the IREE embedded platform-agnostic ELF loader.
// Note: this is ignored for target machines that do not support the ELF
// loader, such as WebAssembly.
bool linkEmbedded = DEFAULT_LINK_EMBEDDED;
friend struct LLVMTargetOptions;
friend struct LLVMCPUTargetCLOptions;
};
struct LLVMTargetOptions {
// Default target machine configuration.
LLVMTarget target;
// Tool to use for native platform linking (like ld on Unix or link.exe on
// Windows). Acts as a prefix to the command line and can contain additional
// arguments.
std::string systemLinkerPath;
// Tool to use for linking embedded ELFs. Must be lld.
std::string embeddedLinkerPath;
// Tool to use for linking WebAssembly modules. Must be wasm-ld or lld.
std::string wasmLinkerPath;
// True to keep linker artifacts for debugging.
bool keepLinkerArtifacts = false;
};
// Creates target machine form target options.
std::unique_ptr<llvm::TargetMachine>
createTargetMachine(const LLVMTarget &target);
// Raw commandline options for LLVMCPUTarget.
// Parse into LLVMTargetOptions using getTargetOptions().
struct LLVMCPUTargetCLOptions {
// Target invariant flags.
std::string systemLinkerPath;
std::string embeddedLinkerPath;
std::string wasmLinkerPath;
bool keepLinkerArtifacts = false;
// Default device options.
std::string targetTriple;
std::string targetCPU;
std::string loggingUnspecifiedTargetCPU;
std::string targetCPUFeatures;
bool linkEmbedded = LLVMTarget::DEFAULT_LINK_EMBEDDED;
bool linkStatic = LLVMTarget::DEFAULT_LINK_STATIC;
std::string staticLibraryOutputPath;
bool debugSymbols = LLVMTarget::DEFAULT_DEBUG_SYMBOLS;
bool llvmLoopInterleaving = LLVMTarget::DEFAULT_LOOP_INTERLEAVING;
bool llvmLoopVectorization = LLVMTarget::DEFAULT_LOOP_VECTORIZATION;
bool llvmLoopUnrolling = LLVMTarget::DEFAULT_LOOP_UNROLLING;
bool llvmSLPVectorization = LLVMTarget::DEFAULT_SLP_VECTORIZATION;
SanitizerKind sanitizerKind = LLVMTarget::DEFAULT_SANITIZER_KIND;
std::string targetABI;
llvm::FloatABI::ABIType targetFloatABI = LLVMTarget::DEFAULT_FLOAT_ABI;
std::string targetDataLayout = LLVMTarget::DEFAULT_DATA_LAYOUT;
unsigned targetVectorWidthInBytes = LLVMTarget::DEFAULT_VECTOR_WIDTH_IN_BYTES;
std::string enableUkernels = LLVMTarget::DEFAULT_ENABLE_UKERNELS;
bool linkUKernelBitcode = LLVMTarget::DEFAULT_LINK_UKERNEL_BITCODE;
bool listTargets; // Ignored - used with llvm::cl::ValueDisallowed.
void bindOptions(OptionsBinder &binder);
LLVMTargetOptions getTargetOptions();
};
} // namespace mlir::iree_compiler::IREE::HAL
#endif // IREE_COMPILER_PLUGINS_TARGET_LLVMCPU_LLVMTARGETOPTIONS_H_