diff --git a/python/tvm/target/__init__.py b/python/tvm/target/__init__.py index 92d72b25b44d3..1e906cb381d8c 100644 --- a/python/tvm/target/__init__.py +++ b/python/tvm/target/__init__.py @@ -43,6 +43,10 @@ such as whether SIMD operations are enabled or not. The default set of attributes is set by the current CPU. +- **-mabi=** + + Generate code for the specified ABI, for example "lp64d". + - **-system-lib** Build TVM system library module. System lib is a global module that contains @@ -55,7 +59,18 @@ We can also use other specific function in this module to create specific targets. """ from .target import Target, create -from .target import cuda, rocm, mali, intel_graphics, arm_cpu, rasp, vta, bifrost, hexagon +from .target import ( + cuda, + rocm, + mali, + intel_graphics, + arm_cpu, + rasp, + vta, + bifrost, + riscv_cpu, + hexagon, +) from .tag import list_tags from .generic_func import GenericFunc from .generic_func import generic_func, get_native_generic_func, override_native_generic_func diff --git a/python/tvm/target/target.py b/python/tvm/target/target.py index aa9226101b521..d4b538a4bef0c 100644 --- a/python/tvm/target/target.py +++ b/python/tvm/target/target.py @@ -87,6 +87,8 @@ def __init__(self, target, host=None): mfloat-abi : str (optional) An llvm setting that is one of 'hard' or 'soft' indicating whether to use hardware or software floating-point operations. + mabi : str (optional) + An llvm setting. Generate code for the specified ABI, for example "lp64d". host : Union[str, Dict[str, Any]] (optional) Description for target host. Can be recursive. Similar to target. host : Optional[Union[str, Dict[str, Any]]] @@ -413,6 +415,54 @@ def bifrost(model="unknown", options=None): return Target(" ".join(["opencl"] + opts)) +def riscv_cpu(model="sifive-u54", options=None): + """Returns a RISC-V CPU target. + Default: sifive-u54 rv64gc + + Parameters + ---------- + model: str + CPU name. + options : str or list of str + Additional options + """ + trans_table = { + "sifive-e31": [ + "-model=sifive-e31", + "-mtriple=riscv32-unknown-linux-gnu", + "-mcpu=sifive-e31", + "-mabi=ilp32", + # cc: riscv64-unknown-linux-gnu-g++ -march=rv32imac -mabi=ilp32 -mcpu=sifive-e31 + ], + "sifive-e76": [ + "-model=sifive-e76", + "-mtriple=riscv32-unknown-linux-gnu", + "-mcpu=sifive-e76", + "-mabi=ilp32", + # cc: riscv64-unknown-linux-gnu-g++ -march=rv32imafc -mabi=ilp32 -mcpu=sifive-e76 + ], + "sifive-u54": [ + "-model=sifive-u54", + "-mtriple=riscv64-unknown-linux-gnu", + "-mcpu=sifive-u54", + "-mabi=lp64d", + # cc: riscv64-unknown-linux-gnu-g++ -march=rv64gc -mabi=lp64d -mcpu=sifive-u54 + ], + "sifive-u74": [ + "-model=sifive-u74", + "-mtriple=riscv64-unknown-linux-gnu", + "-mcpu=sifive-u74", + "-mabi=lp64d", + # cc: riscv64-unknown-linux-gnu-g++ -march=rv64gc -mabi=lp64d -mcpu=sifive-u74 + ], + } + pre_defined_opt = trans_table.get(model, ["-model=%s" % model]) + + opts = ["-device=arm_cpu"] + pre_defined_opt + opts = _merge_opts(opts, options) + return Target(" ".join(["llvm"] + opts)) + + def hexagon(cpu_ver="v66", **kwargs): """Returns a Hexagon target. diff --git a/src/target/llvm/llvm_common.cc b/src/target/llvm/llvm_common.cc index 61dd7024ff055..be80a8bc767e0 100644 --- a/src/target/llvm/llvm_common.cc +++ b/src/target/llvm/llvm_common.cc @@ -115,6 +115,9 @@ void ParseLLVMTargetOptions(const Target& target, std::string* triple, std::stri } else { opt.FloatABIType = llvm::FloatABI::Hard; } + if (const Optional& v = target->GetAttr("mabi")) { + opt.MCOptions.ABIName = v.value(); + } } std::unique_ptr GetLLVMTargetMachine(const Target& target, bool allow_null) { @@ -164,6 +167,9 @@ std::string LLVMTargetToString(const Target& target) { if (Optional mfloat_abo = target->GetAttr("mfloat-abi")) { os << " -mfloat-abi=" << mfloat_abo.value(); } + if (Optional mabi = target->GetAttr("mabi")) { + os << " -mabi=" << mabi.value(); + } return os.str(); } diff --git a/src/target/llvm/llvm_module.cc b/src/target/llvm/llvm_module.cc index 12c7a31329476..8bdf6d1b0422a 100644 --- a/src/target/llvm/llvm_module.cc +++ b/src/target/llvm/llvm_module.cc @@ -69,12 +69,22 @@ class LLVMModuleNode final : public runtime::ModuleNode { } else if (name == "get_const_vars") { return PackedFunc(nullptr); } else if (name == "_get_target_triple") { - std::string target_triple = tm_->getTargetTriple().str(); + std::ostringstream target_triple_ss; + target_triple_ss << tm_->getTargetTriple().str(); // getTargetTriple() doesn't include other flags besides the triple. Add back flags which are // important for ModulePackImportsToLLVM. if (tm_->Options.FloatABIType == llvm::FloatABI::ABIType::Soft) { - target_triple += " -mfloat-abi=soft"; + target_triple_ss << " -mfloat-abi=soft"; } + std::string mabi = tm_->Options.MCOptions.ABIName; + if (!mabi.empty()) { + target_triple_ss << " -mabi=" << mabi; + } + llvm::StringRef mcpu = tm_->getTargetCPU(); + if (!mcpu.empty() && mcpu != "generic") { + target_triple_ss << " -mcpu=" << mcpu.str(); + } + std::string target_triple = target_triple_ss.str(); return PackedFunc([target_triple](TVMArgs args, TVMRetValue* rv) { *rv = target_triple; }); } if (ee_ == nullptr) LazyInitJIT(); diff --git a/src/target/target_kind.cc b/src/target/target_kind.cc index 97317b5c48003..d536b2e7b4b4c 100644 --- a/src/target/target_kind.cc +++ b/src/target/target_kind.cc @@ -216,6 +216,7 @@ TVM_REGISTER_TARGET_KIND("llvm", kDLCPU) .add_attr_option("mcpu") .add_attr_option("mtriple") .add_attr_option("mfloat-abi") + .add_attr_option("mabi") .add_attr_option("system-lib") .add_attr_option("runtime") .add_attr_option("link-params", Bool(false))