blob: 1b49c3b08c7814fd057a7b20a73fda2fb6be9156 [file]
// 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
#include "iree/compiler/Dialect/HAL/Target/LLVM/LLVMTargetOptions.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Host.h"
#include "llvm/Target/TargetOptions.h"
namespace mlir {
namespace iree_compiler {
namespace IREE {
namespace HAL {
LLVMTargetOptions getDefaultLLVMTargetOptions() {
LLVMTargetOptions targetOptions;
// Host target triple.
targetOptions.targetTriple = llvm::sys::getDefaultTargetTriple();
targetOptions.targetCPU = llvm::sys::getHostCPUName().str();
{
llvm::SubtargetFeatures features;
llvm::StringMap<bool> hostFeatures;
if (llvm::sys::getHostCPUFeatures(hostFeatures)) {
for (auto &feature : hostFeatures) {
features.AddFeature(feature.first(), feature.second);
}
}
targetOptions.targetCPUFeatures = features.getString();
}
// LLVM loop optimization options.
targetOptions.pipelineTuningOptions.LoopInterleaving = true;
targetOptions.pipelineTuningOptions.LoopVectorization = true;
targetOptions.pipelineTuningOptions.LoopUnrolling = true;
// LLVM SLP Auto vectorizer.
targetOptions.pipelineTuningOptions.SLPVectorization = true;
// LLVM -O3.
// TODO(benvanik): add an option for this.
targetOptions.optLevel = llvm::PassBuilder::OptimizationLevel::O3;
targetOptions.options.FloatABIType = llvm::FloatABI::Hard;
return targetOptions;
}
LLVMTargetOptions getLLVMTargetOptionsFromFlags() {
auto llvmTargetOptions = getDefaultLLVMTargetOptions();
static llvm::cl::opt<std::string> clTargetTriple(
"iree-llvm-target-triple", llvm::cl::desc("LLVM target machine triple"),
llvm::cl::init(llvmTargetOptions.targetTriple));
static llvm::cl::opt<std::string> clTargetCPU(
"iree-llvm-target-cpu",
llvm::cl::desc(
"LLVM target machine CPU; use 'host' for your host native CPU"),
llvm::cl::init("generic"));
static llvm::cl::opt<std::string> clTargetCPUFeatures(
"iree-llvm-target-cpu-features",
llvm::cl::desc("LLVM target machine CPU features; use 'host' for your "
"host native CPU"),
llvm::cl::init(""));
static llvm::cl::opt<bool> llvmLoopInterleaving(
"iree-llvm-loop-interleaving", llvm::cl::init(false),
llvm::cl::desc("Enable LLVM loop interleaving opt"));
static llvm::cl::opt<bool> llvmLoopVectorization(
"iree-llvm-loop-vectorization", llvm::cl::init(true),
llvm::cl::desc("Enable LLVM loop vectorization opt"));
static llvm::cl::opt<bool> llvmLoopUnrolling(
"iree-llvm-loop-unrolling", llvm::cl::init(false),
llvm::cl::desc("Enable LLVM loop unrolling opt"));
static llvm::cl::opt<bool> llvmSLPVectorization(
"iree-llvm-slp-vectorization", llvm::cl::init(false),
llvm::cl::desc("Enable LLVM SLP Vectorization opt"));
llvmTargetOptions.targetTriple = clTargetTriple;
if (clTargetCPU != "host") {
llvmTargetOptions.targetCPU = clTargetCPU;
}
if (clTargetCPUFeatures != "host") {
llvmTargetOptions.targetCPUFeatures = clTargetCPUFeatures;
}
// LLVM opt options.
llvmTargetOptions.pipelineTuningOptions.LoopInterleaving =
llvmLoopInterleaving;
llvmTargetOptions.pipelineTuningOptions.LoopVectorization =
llvmLoopVectorization;
llvmTargetOptions.pipelineTuningOptions.LoopUnrolling = llvmLoopUnrolling;
llvmTargetOptions.pipelineTuningOptions.SLPVectorization =
llvmSLPVectorization;
static llvm::cl::opt<SanitizerKind> clSanitizerKind(
"iree-llvm-sanitize", llvm::cl::desc("Apply LLVM sanitize feature"),
llvm::cl::init(SanitizerKind::kNone),
llvm::cl::values(clEnumValN(SanitizerKind::kAddress, "address",
"Address sanitizer support")));
llvmTargetOptions.sanitizerKind = clSanitizerKind;
static llvm::cl::opt<std::string> clTargetABI(
"iree-llvm-target-abi",
llvm::cl::desc("LLVM target machine ABI; specify for -mabi"),
llvm::cl::init(""));
llvmTargetOptions.options.MCOptions.ABIName = clTargetABI;
static llvm::cl::opt<llvm::FloatABI::ABIType> clTargetFloatABI(
"iree-llvm-target-float-abi",
llvm::cl::desc("LLVM target codegen enables soft float abi e.g "
"-mfloat-abi=softfp"),
llvm::cl::init(llvmTargetOptions.options.FloatABIType),
llvm::cl::values(
clEnumValN(llvm::FloatABI::Default, "default", "Default (softfp)"),
clEnumValN(llvm::FloatABI::Soft, "soft",
"Software floating-point emulation"),
clEnumValN(llvm::FloatABI::Hard, "hard",
"Hardware floating-point instructions")));
llvmTargetOptions.options.FloatABIType = clTargetFloatABI;
static llvm::cl::opt<bool> clDebugSymbols(
"iree-llvm-debug-symbols",
llvm::cl::desc("Generate and embed debug information (DWARF, PDB, etc)"),
llvm::cl::init(llvmTargetOptions.debugSymbols));
llvmTargetOptions.debugSymbols = clDebugSymbols;
static llvm::cl::opt<bool> clLinkEmbedded(
"iree-llvm-link-embedded",
llvm::cl::desc("Links binaries into a platform-agnostic ELF to be loaded "
"by the embedded IREE ELF loader"),
llvm::cl::init(llvmTargetOptions.linkEmbedded));
llvmTargetOptions.linkEmbedded = clLinkEmbedded;
static llvm::cl::opt<bool> clLinkStatic(
"iree-llvm-link-static",
llvm::cl::desc(
"Links system libraries into binaries statically to isolate them "
"from platform dependencies needed at runtime"),
llvm::cl::init(llvmTargetOptions.linkStatic));
llvmTargetOptions.linkStatic = clLinkStatic;
static llvm::cl::opt<bool> clKeepLinkerArtifacts(
"iree-llvm-keep-linker-artifacts",
llvm::cl::desc("Keep LLVM linker target artifacts (.so/.dll/etc)"),
llvm::cl::init(llvmTargetOptions.keepLinkerArtifacts));
llvmTargetOptions.keepLinkerArtifacts = clKeepLinkerArtifacts;
static llvm::cl::opt<std::string> clStaticLibraryOutputPath(
"iree-llvm-static-library-output-path",
llvm::cl::desc(
"Path to output static object (EX: '/path/to/static-library.o'). "
"This will produce the static library at the specified path along "
"with a similarly named '.h' file for static linking."),
llvm::cl::init(llvmTargetOptions.staticLibraryOutput));
llvmTargetOptions.staticLibraryOutput = clStaticLibraryOutputPath;
return llvmTargetOptions;
}
} // namespace HAL
} // namespace IREE
} // namespace iree_compiler
} // namespace mlir