diff --git a/Makefile b/Makefile index 8c3f6d77bde3..29b826691931 100644 --- a/Makefile +++ b/Makefile @@ -591,23 +591,18 @@ HEADER_FILES = \ Buffer.h \ CanonicalizeGPUVars.h \ Closure.h \ - CodeGen_ARM.h \ CodeGen_C.h \ CodeGen_D3D12Compute_Dev.h \ CodeGen_GPU_Dev.h \ CodeGen_Internal.h \ CodeGen_LLVM.h \ CodeGen_Metal_Dev.h \ - CodeGen_MIPS.h \ CodeGen_OpenCL_Dev.h \ CodeGen_OpenGLCompute_Dev.h \ CodeGen_Posix.h \ - CodeGen_PowerPC.h \ CodeGen_PTX_Dev.h \ CodeGen_PyTorch.h \ - CodeGen_RISCV.h \ - CodeGen_WebAssembly.h \ - CodeGen_X86.h \ + CodeGen_Targets.h \ CompilerLogger.h \ ConciseCasts.h \ CPlusPlusMangle.h \ @@ -1091,7 +1086,7 @@ $(BUILD_DIR)/initmod_ptx.%_ll.o: $(BUILD_DIR)/initmod_ptx.%_ll.cpp $(BUILD_DIR)/initmod.%.o: $(BUILD_DIR)/initmod.%.cpp $(CXX) -c $< -o $@ -MMD -MP -MF $(BUILD_DIR)/$*.d -MT $(BUILD_DIR)/$*.o -$(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp $(SRC_DIR)/%.h $(BUILD_DIR)/llvm_ok +$(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp $(BUILD_DIR)/llvm_ok @mkdir -p $(@D) $(CXX) $(CXX_FLAGS) -c $< -o $@ -MMD -MP -MF $(BUILD_DIR)/$*.d -MT $(BUILD_DIR)/$*.o diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b74006aa3528..8bc68eeeb26c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -23,23 +23,18 @@ set(HEADER_FILES Buffer.h CanonicalizeGPUVars.h Closure.h - CodeGen_ARM.h CodeGen_C.h CodeGen_D3D12Compute_Dev.h CodeGen_GPU_Dev.h CodeGen_Internal.h CodeGen_LLVM.h CodeGen_Metal_Dev.h - CodeGen_MIPS.h CodeGen_OpenCL_Dev.h CodeGen_OpenGLCompute_Dev.h CodeGen_Posix.h - CodeGen_PowerPC.h CodeGen_PTX_Dev.h CodeGen_PyTorch.h - CodeGen_RISCV.h - CodeGen_WebAssembly.h - CodeGen_X86.h + CodeGen_Targets.h CompilerLogger.h ConciseCasts.h CPlusPlusMangle.h diff --git a/src/CodeGen_ARM.cpp b/src/CodeGen_ARM.cpp index 89260d758cc7..e43097b95180 100644 --- a/src/CodeGen_ARM.cpp +++ b/src/CodeGen_ARM.cpp @@ -1,9 +1,8 @@ -#include #include #include "CSE.h" -#include "CodeGen_ARM.h" #include "CodeGen_Internal.h" +#include "CodeGen_Posix.h" #include "ConciseCasts.h" #include "Debug.h" #include "IREquality.h" @@ -25,6 +24,8 @@ using std::vector; using namespace Halide::ConciseCasts; using namespace llvm; +#if defined(WITH_ARM) || defined(WITH_AARCH64) + namespace { // Broadcast to an unknown number of lanes, for making patterns. @@ -32,21 +33,59 @@ Expr bc(Expr x) { return Broadcast::make(std::move(x), 0); } -} // namespace +/** A code generator that emits ARM code from a given Halide stmt. */ +class CodeGen_ARM : public CodeGen_Posix { +public: + /** Create an ARM code generator for the given arm target. */ + CodeGen_ARM(const Target &); + +protected: + using CodeGen_Posix::visit; + + /** Assuming 'inner' is a function that takes two vector arguments, define a wrapper that + * takes one vector argument and splits it into two to call inner. */ + llvm::Function *define_concat_args_wrapper(llvm::Function *inner, const string &name); + void init_module() override; + + /** Nodes for which we want to emit specific neon intrinsics */ + // @{ + void visit(const Cast *) override; + void visit(const Sub *) override; + void visit(const Mul *) override; + void visit(const Min *) override; + void visit(const Max *) override; + void visit(const Store *) override; + void visit(const Load *) override; + void visit(const Call *) override; + void visit(const LT *) override; + void visit(const LE *) override; + void codegen_vector_reduce(const VectorReduce *, const Expr &) override; + // @} + + /** Various patterns to peephole match against */ + struct Pattern { + string intrin; ///< Name of the intrinsic + Expr pattern; ///< The pattern to match against + Pattern() = default; + Pattern(const string &intrin, Expr p) + : intrin(intrin), pattern(std::move(p)) { + } + }; + vector casts, averagings, negations; + + string mcpu() const override; + string mattrs() const override; + bool use_soft_float_abi() const override; + int native_vector_bits() const override; + + // NEON can be disabled for older processors. + bool neon_intrinsics_disabled() { + return target.has_feature(Target::NoNEON); + } +}; CodeGen_ARM::CodeGen_ARM(const Target &target) : CodeGen_Posix(target) { - if (target.bits == 32) { -#if !defined(WITH_ARM) - user_error << "arm not enabled for this build of Halide."; -#endif - user_assert(llvm_ARM_enabled) << "llvm build not configured with ARM target enabled\n."; - } else { -#if !defined(WITH_AARCH64) - user_error << "aarch64 not enabled for this build of Halide."; -#endif - user_assert(llvm_AArch64_enabled) << "llvm build not configured with AArch64 target enabled.\n"; - } // RADDHN - Add and narrow with rounding // These must come before other narrowing rounding shift patterns @@ -162,8 +201,6 @@ CodeGen_ARM::CodeGen_ARM(const Target &target) // clang-format on } -namespace { - constexpr int max_intrinsic_args = 4; struct ArmIntrinsic { @@ -512,9 +549,7 @@ const ArmIntrinsic intrinsic_defs[] = { }; // clang-format on -} // namespace - -llvm::Function *CodeGen_ARM::define_concat_args_wrapper(llvm::Function *inner, const std::string &name) { +llvm::Function *CodeGen_ARM::define_concat_args_wrapper(llvm::Function *inner, const string &name) { llvm::FunctionType *inner_ty = inner->getFunctionType(); internal_assert(inner_ty->getNumParams() == 2); @@ -558,7 +593,7 @@ void CodeGen_ARM::init_module() { return; } - std::string prefix = target.bits == 32 ? "llvm.arm.neon." : "llvm.aarch64.neon."; + string prefix = target.bits == 32 ? "llvm.arm.neon." : "llvm.aarch64.neon."; for (const ArmIntrinsic &intrin : intrinsic_defs) { // Get the name of the intrinsic with the appropriate prefix. const char *intrin_name = nullptr; @@ -570,13 +605,13 @@ void CodeGen_ARM::init_module() { if (!intrin_name) { continue; } - std::string full_name = intrin_name; + string full_name = intrin_name; if (!starts_with(full_name, "llvm.")) { full_name = prefix + full_name; } // We might have to generate versions of this intrinsic with multiple widths. - std::vector width_factors = {1}; + vector width_factors = {1}; if (intrin.flags & ArmIntrinsic::HalfWidth) { width_factors.push_back(2); } @@ -585,7 +620,7 @@ void CodeGen_ARM::init_module() { Type ret_type = intrin.ret_type; ret_type = ret_type.with_lanes(ret_type.lanes() * width_factor); internal_assert(ret_type.bits() * ret_type.lanes() <= 128) << full_name << "\n"; - std::vector arg_types; + vector arg_types; arg_types.reserve(4); for (halide_type_t i : intrin.arg_types) { if (i.bits == 0) { @@ -603,7 +638,7 @@ void CodeGen_ARM::init_module() { mangled_name_builder << full_name; if (starts_with(full_name, "llvm.") && (intrin.flags & ArmIntrinsic::NoMangle) == 0) { // Append LLVM name mangling for either the return type or the arguments, or both. - std::vector types; + vector types; if (intrin.flags & ArmIntrinsic::MangleArgs) { types = arg_types; } else if (intrin.flags & ArmIntrinsic::MangleRetArgs) { @@ -622,12 +657,12 @@ void CodeGen_ARM::init_module() { mangled_name_builder << t.bits(); } } - std::string mangled_name = mangled_name_builder.str(); + string mangled_name = mangled_name_builder.str(); llvm::Function *intrin_impl = nullptr; if (intrin.flags & ArmIntrinsic::SplitArg0) { // This intrinsic needs a wrapper to split the argument. - std::string wrapper_name = intrin.name + unique_name("_wrapper"); + string wrapper_name = intrin.name + unique_name("_wrapper"); Type split_arg_type = arg_types[0].with_lanes(arg_types[0].lanes() / 2); llvm::Function *to_wrap = get_llvm_intrin(ret_type, mangled_name, {split_arg_type, split_arg_type}); intrin_impl = define_concat_args_wrapper(to_wrap, wrapper_name); @@ -1178,7 +1213,7 @@ void CodeGen_ARM::codegen_vector_reduce(const VectorReduce *op, const Expr &init // clang-format on int factor = op->value.type().lanes() / op->type.lanes(); - std::vector matches; + vector matches; for (const Pattern &p : patterns) { if (op->op != p.reduce_op || factor % p.factor != 0) { continue; @@ -1208,7 +1243,7 @@ void CodeGen_ARM::codegen_vector_reduce(const VectorReduce *op, const Expr &init // TODO: Move this to be patterns? The patterns are pretty trivial, but some // of the other logic is tricky. const char *intrin = nullptr; - std::vector intrin_args; + vector intrin_args; Expr accumulator = init; if (op->op == VectorReduce::Add && factor == 2) { Type narrow_type = op->type.narrow().with_lanes(op->value.type().lanes()); @@ -1340,5 +1375,20 @@ int CodeGen_ARM::native_vector_bits() const { return 128; } +} // namespace + +std::unique_ptr new_CodeGen_ARM(const Target &target) { + return std::make_unique(target); +} + +#else // WITH_ARM || WITH_AARCH64 + +std::unique_ptr new_CodeGen_ARM(const Target &target) { + user_error << "ARM not enabled for this build of Halide.\n"; + return nullptr; +} + +#endif // WITH_ARM || WITH_AARCH64 + } // namespace Internal } // namespace Halide diff --git a/src/CodeGen_ARM.h b/src/CodeGen_ARM.h deleted file mode 100644 index 39d1a39d7a0f..000000000000 --- a/src/CodeGen_ARM.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef HALIDE_CODEGEN_ARM_H -#define HALIDE_CODEGEN_ARM_H - -/** \file - * Defines the code-generator for producing ARM machine code - */ - -#include - -#include "CodeGen_Posix.h" - -namespace Halide { - -struct Target; - -namespace Internal { - -/** A code generator that emits ARM code from a given Halide stmt. */ -class CodeGen_ARM : public CodeGen_Posix { -public: - /** Create an ARM code generator for the given arm target. */ - CodeGen_ARM(const Target &); - -protected: - using CodeGen_Posix::visit; - - /** Assuming 'inner' is a function that takes two vector arguments, define a wrapper that - * takes one vector argument and splits it into two to call inner. */ - llvm::Function *define_concat_args_wrapper(llvm::Function *inner, const std::string &name); - void init_module() override; - - /** Nodes for which we want to emit specific neon intrinsics */ - // @{ - void visit(const Cast *) override; - void visit(const Sub *) override; - void visit(const Mul *) override; - void visit(const Min *) override; - void visit(const Max *) override; - void visit(const Store *) override; - void visit(const Load *) override; - void visit(const Call *) override; - void visit(const LT *) override; - void visit(const LE *) override; - void codegen_vector_reduce(const VectorReduce *, const Expr &) override; - // @} - - /** Various patterns to peephole match against */ - struct Pattern { - std::string intrin; ///< Name of the intrinsic - Expr pattern; ///< The pattern to match against - Pattern() = default; - Pattern(const std::string &intrin, Expr p) - : intrin(intrin), pattern(std::move(p)) { - } - }; - std::vector casts, averagings, negations; - - std::string mcpu() const override; - std::string mattrs() const override; - bool use_soft_float_abi() const override; - int native_vector_bits() const override; - - // NEON can be disabled for older processors. - bool neon_intrinsics_disabled() { - return target.has_feature(Target::NoNEON); - } -}; - -} // namespace Internal -} // namespace Halide - -#endif diff --git a/src/CodeGen_Hexagon.cpp b/src/CodeGen_Hexagon.cpp index 223a5231da66..1f033fdcc33c 100644 --- a/src/CodeGen_Hexagon.cpp +++ b/src/CodeGen_Hexagon.cpp @@ -1,7 +1,3 @@ -#include "CodeGen_Hexagon.h" - -#include -#include #include #include @@ -12,14 +8,11 @@ #include "Debug.h" #include "HexagonOptimize.h" #include "IREquality.h" -#include "IRMatch.h" #include "IRMutator.h" #include "IROperator.h" #include "IRPrinter.h" -#include "LICM.h" #include "LLVM_Headers.h" #include "LoopCarry.h" -#include "Monotonic.h" #include "Simplify.h" #include "Substitute.h" #include "Target.h" @@ -138,8 +131,6 @@ class CodeGen_Hexagon : public CodeGen_Posix { CodeGen_Hexagon::CodeGen_Hexagon(const Target &t) : CodeGen_Posix(t) { - user_assert(llvm_Hexagon_enabled) - << "llvm build not configured with Hexagon target enabled.\n"; if (target.has_feature(Halide::Target::HVX_v66)) { isa_version = 66; } else if (target.has_feature(Halide::Target::HVX_v65)) { @@ -2326,15 +2317,13 @@ void CodeGen_Hexagon::visit(const Allocate *alloc) { } // namespace -std::unique_ptr new_CodeGen_Hexagon(const Target &target, llvm::LLVMContext &context) { - std::unique_ptr ret(std::make_unique(target)); - ret->set_context(context); - return ret; +std::unique_ptr new_CodeGen_Hexagon(const Target &target) { + return std::make_unique(target); } #else // WITH_HEXAGON -std::unique_ptr new_CodeGen_Hexagon(const Target &target, llvm::LLVMContext &context) { +std::unique_ptr new_CodeGen_Hexagon(const Target &target) { user_error << "hexagon not enabled for this build of Halide.\n"; return nullptr; } diff --git a/src/CodeGen_Hexagon.h b/src/CodeGen_Hexagon.h deleted file mode 100644 index a844c594e6c7..000000000000 --- a/src/CodeGen_Hexagon.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef HALIDE_CODEGEN_HEXAGON_H -#define HALIDE_CODEGEN_HEXAGON_H - -/** \file - * Defines the code-generator for producing Hexagon machine code - */ - -#include - -namespace llvm { - -class LLVMContext; - -} - -namespace Halide { - -struct Target; - -namespace Internal { - -class CodeGen_Posix; - -std::unique_ptr new_CodeGen_Hexagon(const Target &target, llvm::LLVMContext &context); - -} // namespace Internal -} // namespace Halide - -#endif diff --git a/src/CodeGen_LLVM.cpp b/src/CodeGen_LLVM.cpp index 9f61485d27ab..eda89aca82da 100644 --- a/src/CodeGen_LLVM.cpp +++ b/src/CodeGen_LLVM.cpp @@ -1,20 +1,13 @@ -#include #include #include -#include #include #include "CPlusPlusMangle.h" #include "CSE.h" -#include "CodeGen_ARM.h" -#include "CodeGen_Hexagon.h" #include "CodeGen_Internal.h" #include "CodeGen_LLVM.h" -#include "CodeGen_MIPS.h" -#include "CodeGen_PowerPC.h" -#include "CodeGen_RISCV.h" -#include "CodeGen_WebAssembly.h" -#include "CodeGen_X86.h" +#include "CodeGen_Posix.h" +#include "CodeGen_Targets.h" #include "CompilerLogger.h" #include "Debug.h" #include "Deinterleave.h" @@ -81,8 +74,7 @@ using std::vector; #define InitializeTarget(target) \ LLVMInitialize##target##Target(); \ LLVMInitialize##target##TargetInfo(); \ - LLVMInitialize##target##TargetMC(); \ - llvm_##target##_enabled = true; + LLVMInitialize##target##TargetMC(); #define InitializeAsmParser(target) \ LLVMInitialize##target##AsmParser(); @@ -222,41 +214,30 @@ CodeGen_LLVM::CodeGen_LLVM(const Target &t) initialize_llvm(); } -namespace { - -template -std::unique_ptr make_codegen(const Target &target, llvm::LLVMContext &context) { - std::unique_ptr ret = std::make_unique(target); - ret->set_context(context); - return ret; -} - -} // namespace - void CodeGen_LLVM::set_context(llvm::LLVMContext &context) { this->context = &context; } std::unique_ptr CodeGen_LLVM::new_for_target(const Target &target, llvm::LLVMContext &context) { + std::unique_ptr result; if (target.arch == Target::X86) { - return make_codegen(target, context); + result = new_CodeGen_X86(target); } else if (target.arch == Target::ARM) { - return make_codegen(target, context); + result = new_CodeGen_ARM(target); } else if (target.arch == Target::MIPS) { - return make_codegen(target, context); + result = new_CodeGen_MIPS(target); } else if (target.arch == Target::POWERPC) { - return make_codegen(target, context); + result = new_CodeGen_PowerPC(target); } else if (target.arch == Target::Hexagon) { - return new_CodeGen_Hexagon(target, context); + result = new_CodeGen_Hexagon(target); } else if (target.arch == Target::WebAssembly) { - return make_codegen(target, context); + result = new_CodeGen_WebAssembly(target); } else if (target.arch == Target::RISCV) { - return make_codegen(target, context); + result = new_CodeGen_RISCV(target); } - - user_error << "Unknown target architecture: " - << target.to_string() << "\n"; - return nullptr; + user_assert(result) << "Unknown target architecture: " << target.to_string() << "\n"; + result->set_context(context); + return result; } void CodeGen_LLVM::initialize_llvm() { @@ -352,17 +333,6 @@ CodeGen_LLVM::~CodeGen_LLVM() { delete builder; } -bool CodeGen_LLVM::llvm_X86_enabled = false; -bool CodeGen_LLVM::llvm_ARM_enabled = false; -bool CodeGen_LLVM::llvm_Hexagon_enabled = false; -bool CodeGen_LLVM::llvm_AArch64_enabled = false; -bool CodeGen_LLVM::llvm_NVPTX_enabled = false; -bool CodeGen_LLVM::llvm_Mips_enabled = false; -bool CodeGen_LLVM::llvm_PowerPC_enabled = false; -bool CodeGen_LLVM::llvm_AMDGPU_enabled = false; -bool CodeGen_LLVM::llvm_WebAssembly_enabled = false; -bool CodeGen_LLVM::llvm_RISCV_enabled = false; - namespace { struct MangledNames { diff --git a/src/CodeGen_LLVM.h b/src/CodeGen_LLVM.h index 060fe9ee10ce..092bc7713b5b 100644 --- a/src/CodeGen_LLVM.h +++ b/src/CodeGen_LLVM.h @@ -138,21 +138,6 @@ class CodeGen_LLVM : public IRVisitor { * of functions as. */ virtual Type upgrade_type_for_argument_passing(const Type &) const; - /** State needed by llvm for code generation, including the - * current module, function, context, builder, and most recently - * generated llvm value. */ - //@{ - static bool llvm_X86_enabled; - static bool llvm_ARM_enabled; - static bool llvm_Hexagon_enabled; - static bool llvm_AArch64_enabled; - static bool llvm_NVPTX_enabled; - static bool llvm_Mips_enabled; - static bool llvm_PowerPC_enabled; - static bool llvm_AMDGPU_enabled; - static bool llvm_WebAssembly_enabled; - static bool llvm_RISCV_enabled; - std::unique_ptr module; llvm::Function *function; llvm::LLVMContext *context; diff --git a/src/CodeGen_MIPS.cpp b/src/CodeGen_MIPS.cpp index ddc0b9d9c9ea..4118a12b684f 100644 --- a/src/CodeGen_MIPS.cpp +++ b/src/CodeGen_MIPS.cpp @@ -1,20 +1,32 @@ -#include "CodeGen_MIPS.h" -#include "LLVM_Headers.h" -#include "Util.h" +#include "CodeGen_Posix.h" namespace Halide { namespace Internal { using std::string; -using namespace llvm; +#if defined(WITH_MIPS) + +namespace { + +/** A code generator that emits mips code from a given Halide stmt. */ +class CodeGen_MIPS : public CodeGen_Posix { +public: + /** Create a mips code generator. Processor features can be + * enabled using the appropriate flags in the target struct. */ + CodeGen_MIPS(const Target &); + +protected: + using CodeGen_Posix::visit; + + string mcpu() const override; + string mattrs() const override; + bool use_soft_float_abi() const override; + int native_vector_bits() const override; +}; CodeGen_MIPS::CodeGen_MIPS(const Target &t) : CodeGen_Posix(t) { -#if !defined(WITH_MIPS) - user_error << "llvm build not configured with MIPS target enabled.\n"; -#endif - user_assert(llvm_Mips_enabled) << "llvm build not configured with MIPS target enabled.\n"; } string CodeGen_MIPS::mcpu() const { @@ -41,5 +53,20 @@ int CodeGen_MIPS::native_vector_bits() const { return 128; } +} // namespace + +std::unique_ptr new_CodeGen_MIPS(const Target &target) { + return std::make_unique(target); +} + +#else // WITH_MIPS + +std::unique_ptr new_CodeGen_MIPS(const Target &target) { + user_error << "MIPS not enabled for this build of Halide.\n"; + return nullptr; +} + +#endif // WITH_MIPS + } // namespace Internal } // namespace Halide diff --git a/src/CodeGen_MIPS.h b/src/CodeGen_MIPS.h deleted file mode 100644 index fe5e2d2cb12e..000000000000 --- a/src/CodeGen_MIPS.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef HALIDE_CODEGEN_MIPS_H -#define HALIDE_CODEGEN_MIPS_H - -/** \file - * Defines the code-generator for producing MIPS machine code. - */ - -#include "CodeGen_Posix.h" - -namespace Halide { -namespace Internal { - -/** A code generator that emits mips code from a given Halide stmt. */ -class CodeGen_MIPS : public CodeGen_Posix { -public: - /** Create a mips code generator. Processor features can be - * enabled using the appropriate flags in the target struct. */ - CodeGen_MIPS(const Target &); - - static void test(); - -protected: - using CodeGen_Posix::visit; - - std::string mcpu() const override; - std::string mattrs() const override; - bool use_soft_float_abi() const override; - int native_vector_bits() const override; -}; - -} // namespace Internal -} // namespace Halide - -#endif diff --git a/src/CodeGen_PTX_Dev.cpp b/src/CodeGen_PTX_Dev.cpp index efe0b25bd2c0..26822cda2296 100644 --- a/src/CodeGen_PTX_Dev.cpp +++ b/src/CodeGen_PTX_Dev.cpp @@ -37,6 +37,8 @@ using namespace Halide::ConciseCasts; using namespace llvm; +#ifdef WITH_NVPTX + namespace { /** A code generator that emits GPU code from a given Halide stmt. */ @@ -111,11 +113,6 @@ class CodeGen_PTX_Dev : public CodeGen_LLVM, public CodeGen_GPU_Dev { CodeGen_PTX_Dev::CodeGen_PTX_Dev(const Target &host) : CodeGen_LLVM(host) { -#if !defined(WITH_NVPTX) - user_error << "ptx not enabled for this build of Halide.\n"; -#endif - user_assert(llvm_NVPTX_enabled) << "llvm build not configured with nvptx target enabled\n."; - context = new llvm::LLVMContext(); } @@ -229,9 +226,7 @@ void CodeGen_PTX_Dev::add_kernel(Stmt stmt, void CodeGen_PTX_Dev::init_module() { init_context(); -#ifdef WITH_NVPTX module = get_initial_module_for_ptx_device(target, context); -#endif declare_intrin_overload("dp4a", Int(32), "dp4a_s32_s32", {Int(8, 4), Int(8, 4), Int(32)}); declare_intrin_overload("dp4a", Int(32), "dp4a_s32_u32", {Int(8, 4), UInt(8, 4), Int(32)}); @@ -587,9 +582,6 @@ bool CodeGen_PTX_Dev::use_soft_float_abi() const { } vector CodeGen_PTX_Dev::compile_to_src() { - -#ifdef WITH_NVPTX - debug(2) << "In CodeGen_PTX_Dev::compile_to_src"; // DISABLED - hooked in here to force PrintBeforeAll option - seems to be the only way? @@ -755,9 +747,6 @@ vector CodeGen_PTX_Dev::compile_to_src() { // Null-terminate the ptx source buffer.push_back(0); return buffer; -#else // WITH_NVPTX - return vector(); -#endif } int CodeGen_PTX_Dev::native_vector_bits() const { @@ -801,5 +790,14 @@ std::unique_ptr new_CodeGen_PTX_Dev(const Target &target) { return std::make_unique(target); } +#else // WITH_PTX + +std::unique_ptr new_CodeGen_PTX_Dev(const Target &target) { + user_error << "PTX not enabled for this build of Halide.\n"; + return nullptr; +} + +#endif // WITH_PTX + } // namespace Internal } // namespace Halide diff --git a/src/CodeGen_PowerPC.cpp b/src/CodeGen_PowerPC.cpp index e81d6f281b93..312649280f62 100644 --- a/src/CodeGen_PowerPC.cpp +++ b/src/CodeGen_PowerPC.cpp @@ -1,9 +1,4 @@ -#include "CodeGen_PowerPC.h" -#include "ConciseCasts.h" -#include "IRMatch.h" -#include "IROperator.h" -#include "LLVM_Headers.h" -#include "Util.h" +#include "CodeGen_Posix.h" namespace Halide { namespace Internal { @@ -11,19 +6,38 @@ namespace Internal { using std::string; using std::vector; -using namespace Halide::ConciseCasts; -using namespace llvm; +#if defined(WITH_POWERPC) + +namespace { + +/** A code generator that emits mips code from a given Halide stmt. */ +class CodeGen_PowerPC : public CodeGen_Posix { +public: + /** Create a powerpc code generator. Processor features can be + * enabled using the appropriate flags in the target struct. */ + CodeGen_PowerPC(const Target &); + +protected: + void init_module() override; + + string mcpu() const override; + string mattrs() const override; + bool use_soft_float_abi() const override; + int native_vector_bits() const override; + + using CodeGen_Posix::visit; + + /** Nodes for which we want to emit specific PowerPC intrinsics */ + // @{ + void visit(const Min *) override; + void visit(const Max *) override; + // @} +}; CodeGen_PowerPC::CodeGen_PowerPC(const Target &t) : CodeGen_Posix(t) { -#if !defined(WITH_POWERPC) - user_error << "llvm build not configured with PowerPC target enabled.\n"; -#endif - user_assert(llvm_PowerPC_enabled) << "llvm build not configured with PowerPC target enabled.\n"; } -namespace { - const int max_intrinsic_args = 4; struct PowerPCIntrinsic { @@ -81,8 +95,6 @@ const PowerPCIntrinsic intrinsic_defs[] = { }; // clang-format on -} // namespace - void CodeGen_PowerPC::init_module() { CodeGen_Posix::init_module(); @@ -92,7 +104,7 @@ void CodeGen_PowerPC::init_module() { } Type ret_type = i.ret_type; - std::vector arg_types; + vector arg_types; arg_types.reserve(max_intrinsic_args); for (halide_type_t j : i.arg_types) { if (j.bits == 0) { @@ -140,9 +152,9 @@ string CodeGen_PowerPC::mcpu() const { } string CodeGen_PowerPC::mattrs() const { - std::string features; - std::string separator; - std::string enable; + string features; + string separator; + string enable; features += "+altivec"; separator = ","; @@ -172,5 +184,20 @@ int CodeGen_PowerPC::native_vector_bits() const { return 128; } +} // namespace + +std::unique_ptr new_CodeGen_PowerPC(const Target &target) { + return std::make_unique(target); +} + +#else // WITH_POWERPC + +std::unique_ptr new_CodeGen_PowerPC(const Target &target) { + user_error << "PowerPC not enabled for this build of Halide.\n"; + return nullptr; +} + +#endif // WITH_POWERPC + } // namespace Internal } // namespace Halide diff --git a/src/CodeGen_PowerPC.h b/src/CodeGen_PowerPC.h deleted file mode 100644 index c23cc5011e68..000000000000 --- a/src/CodeGen_PowerPC.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef HALIDE_CODEGEN_POWERPC_H -#define HALIDE_CODEGEN_POWERPC_H - -/** \file - * Defines the code-generator for producing POWERPC machine code. - */ - -#include "CodeGen_Posix.h" - -namespace Halide { -namespace Internal { - -/** A code generator that emits mips code from a given Halide stmt. */ -class CodeGen_PowerPC : public CodeGen_Posix { -public: - /** Create a powerpc code generator. Processor features can be - * enabled using the appropriate flags in the target struct. */ - CodeGen_PowerPC(const Target &); - - static void test(); - -protected: - void init_module() override; - - std::string mcpu() const override; - std::string mattrs() const override; - bool use_soft_float_abi() const override; - int native_vector_bits() const override; - - using CodeGen_Posix::visit; - - /** Nodes for which we want to emit specific PowerPC intrinsics */ - // @{ - void visit(const Min *) override; - void visit(const Max *) override; - // @} -}; - -} // namespace Internal -} // namespace Halide - -#endif diff --git a/src/CodeGen_RISCV.cpp b/src/CodeGen_RISCV.cpp index 3fa9e3a529c3..01395f596b91 100644 --- a/src/CodeGen_RISCV.cpp +++ b/src/CodeGen_RISCV.cpp @@ -1,19 +1,33 @@ -#include "CodeGen_RISCV.h" -#include "LLVM_Headers.h" -#include "Util.h" +#include "CodeGen_Posix.h" namespace Halide { namespace Internal { using std::string; -using namespace llvm; +#if defined(WITH_RISCV) + +namespace { + +/** A code generator that emits mips code from a given Halide stmt. */ +class CodeGen_RISCV : public CodeGen_Posix { +public: + /** Create a mips code generator. Processor features can be + * enabled using the appropriate flags in the target struct. */ + CodeGen_RISCV(const Target &); + +protected: + using CodeGen_Posix::visit; + + string mcpu() const override; + string mattrs() const override; + string mabi() const override; + bool use_soft_float_abi() const override; + int native_vector_bits() const override; +}; CodeGen_RISCV::CodeGen_RISCV(const Target &t) : CodeGen_Posix(t) { -#if !defined(WITH_RISCV) - user_error << "llvm build not configured with RISCV target enabled.\n"; -#endif } string CodeGen_RISCV::mcpu() const { @@ -57,5 +71,20 @@ int CodeGen_RISCV::native_vector_bits() const { return 128; } +} // namespace + +std::unique_ptr new_CodeGen_RISCV(const Target &target) { + return std::make_unique(target); +} + +#else // WITH_RISCV + +std::unique_ptr new_CodeGen_RISCV(const Target &target) { + user_error << "RISCV not enabled for this build of Halide.\n"; + return nullptr; +} + +#endif // WITH_RISCV + } // namespace Internal } // namespace Halide diff --git a/src/CodeGen_RISCV.h b/src/CodeGen_RISCV.h deleted file mode 100644 index d6cb8328dec5..000000000000 --- a/src/CodeGen_RISCV.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef HALIDE_CODEGEN_RISCV_H -#define HALIDE_CODEGEN_RISCV_H - -/** \file - * Defines the code-generator for producing RISCV machine code. - */ - -#include "CodeGen_Posix.h" - -namespace Halide { -namespace Internal { - -/** A code generator that emits mips code from a given Halide stmt. */ -class CodeGen_RISCV : public CodeGen_Posix { -public: - /** Create a mips code generator. Processor features can be - * enabled using the appropriate flags in the target struct. */ - CodeGen_RISCV(const Target &); - -protected: - using CodeGen_Posix::visit; - - std::string mcpu() const override; - std::string mattrs() const override; - std::string mabi() const override; - bool use_soft_float_abi() const override; - int native_vector_bits() const override; -}; - -} // namespace Internal -} // namespace Halide - -#endif diff --git a/src/CodeGen_Targets.h b/src/CodeGen_Targets.h new file mode 100644 index 000000000000..1667703fe5e3 --- /dev/null +++ b/src/CodeGen_Targets.h @@ -0,0 +1,30 @@ +#ifndef HALIDE_CODEGEN_TARGETS_H +#define HALIDE_CODEGEN_TARGETS_H + +/** \file + * Provides constructors for code generators for various targets. + */ + +#include + +namespace Halide { + +struct Target; + +namespace Internal { + +class CodeGen_Posix; + +/** Construct CodeGen object for a variety of targets. */ +std::unique_ptr new_CodeGen_ARM(const Target &target); +std::unique_ptr new_CodeGen_Hexagon(const Target &target); +std::unique_ptr new_CodeGen_MIPS(const Target &target); +std::unique_ptr new_CodeGen_PowerPC(const Target &target); +std::unique_ptr new_CodeGen_RISCV(const Target &target); +std::unique_ptr new_CodeGen_X86(const Target &target); +std::unique_ptr new_CodeGen_WebAssembly(const Target &target); + +} // namespace Internal +} // namespace Halide + +#endif diff --git a/src/CodeGen_WebAssembly.cpp b/src/CodeGen_WebAssembly.cpp index 6d5292195abe..fe7ee2fe6db0 100644 --- a/src/CodeGen_WebAssembly.cpp +++ b/src/CodeGen_WebAssembly.cpp @@ -1,33 +1,37 @@ -#include "CodeGen_WebAssembly.h" - -#include "ConciseCasts.h" -#include "IRMatch.h" -#include "IROperator.h" -#include "LLVM_Headers.h" -#include "Util.h" +#include "CodeGen_Posix.h" #include namespace Halide { namespace Internal { -using namespace Halide::ConciseCasts; -using namespace llvm; using std::string; -using std::vector; + +#if defined(WITH_WEBASSEMBLY) + +namespace { + +/** A code generator that emits WebAssembly code from a given Halide stmt. */ +class CodeGen_WebAssembly : public CodeGen_Posix { +public: + CodeGen_WebAssembly(const Target &); + +protected: + using CodeGen_Posix::visit; + + void init_module() override; + + string mcpu() const override; + string mattrs() const override; + bool use_soft_float_abi() const override; + int native_vector_bits() const override; + bool use_pic() const override; +}; CodeGen_WebAssembly::CodeGen_WebAssembly(const Target &t) : CodeGen_Posix(t) { -#if !defined(WITH_WEBASSEMBLY) - user_error << "llvm build not configured with WebAssembly target enabled.\n"; -#endif - user_assert(LLVM_VERSION >= 110) << "Generating WebAssembly is only supported under LLVM 11+."; - user_assert(llvm_WebAssembly_enabled) << "llvm build not configured with WebAssembly target enabled.\n"; - user_assert(target.bits == 32) << "Only wasm32 is supported."; } -namespace { - constexpr int max_intrinsic_args = 4; struct WasmIntrinsic { @@ -65,8 +69,6 @@ const WasmIntrinsic intrinsic_defs[] = { }; // clang-format on -} // namespace - void CodeGen_WebAssembly::init_module() { CodeGen_Posix::init_module(); @@ -140,5 +142,22 @@ int CodeGen_WebAssembly::native_vector_bits() const { return 128; } +} // namespace + +std::unique_ptr new_CodeGen_WebAssembly(const Target &target) { + user_assert(LLVM_VERSION >= 110) << "Generating WebAssembly is only supported under LLVM 11+."; + user_assert(target.bits == 32) << "Only wasm32 is supported."; + return std::make_unique(target); +} + +#else // WITH_WEBASSEMBLY + +std::unique_ptr new_CodeGen_WebAssembly(const Target &target) { + user_error << "WebAssembly not enabled for this build of Halide.\n"; + return nullptr; +} + +#endif // WITH_WEBASSEMBLY + } // namespace Internal } // namespace Halide diff --git a/src/CodeGen_WebAssembly.h b/src/CodeGen_WebAssembly.h deleted file mode 100644 index ffbedae8d907..000000000000 --- a/src/CodeGen_WebAssembly.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef HALIDE_CODEGEN_WEBASSEMBLY_H -#define HALIDE_CODEGEN_WEBASSEMBLY_H - -/** \file - * Defines the code-generator for producing WebAssembly machine code. - */ - -#include "CodeGen_Posix.h" - -namespace Halide { -namespace Internal { - -/** A code generator that emits WebAssembly code from a given Halide stmt. */ -class CodeGen_WebAssembly : public CodeGen_Posix { -public: - CodeGen_WebAssembly(const Target &); - - static void test(); - -protected: - using CodeGen_Posix::visit; - - void init_module() override; - - std::string mcpu() const override; - std::string mattrs() const override; - bool use_soft_float_abi() const override; - int native_vector_bits() const override; - bool use_pic() const override; -}; - -} // namespace Internal -} // namespace Halide - -#endif diff --git a/src/CodeGen_X86.cpp b/src/CodeGen_X86.cpp index 83cdae86dbdd..fbfc4881e70d 100644 --- a/src/CodeGen_X86.cpp +++ b/src/CodeGen_X86.cpp @@ -1,17 +1,12 @@ -#include - -#include "CodeGen_X86.h" +#include "CodeGen_Posix.h" #include "ConciseCasts.h" #include "Debug.h" #include "IRMatch.h" #include "IRMutator.h" #include "IROperator.h" -#include "JITModule.h" #include "LLVM_Headers.h" -#include "Param.h" #include "Simplify.h" #include "Util.h" -#include "Var.h" namespace Halide { namespace Internal { @@ -22,7 +17,10 @@ using std::vector; using namespace Halide::ConciseCasts; using namespace llvm; +#if defined(WITH_X86) + namespace { + // Populate feature flags in a target according to those implied by // existing flags, so that instruction patterns can just check for the // oldest feature flag that supports an instruction. @@ -46,20 +44,49 @@ Target complete_x86_target(Target t) { } return t; } -} // namespace + +/** A code generator that emits x86 code from a given Halide stmt. */ +class CodeGen_X86 : public CodeGen_Posix { +public: + /** Create an x86 code generator. Processor features can be + * enabled using the appropriate flags in the target struct. */ + CodeGen_X86(Target); + +protected: + string mcpu() const override; + string mattrs() const override; + bool use_soft_float_abi() const override; + int native_vector_bits() const override; + + int vector_lanes_for_slice(const Type &t) const; + + llvm::Type *llvm_type_of(const Type &t) const override; + + using CodeGen_Posix::visit; + + void init_module() override; + + /** Nodes for which we want to emit specific sse/avx intrinsics */ + // @{ + void visit(const Add *) override; + void visit(const Sub *) override; + void visit(const Cast *) override; + void visit(const Call *) override; + void visit(const GT *) override; + void visit(const LT *) override; + void visit(const LE *) override; + void visit(const GE *) override; + void visit(const EQ *) override; + void visit(const NE *) override; + void visit(const Select *) override; + void codegen_vector_reduce(const VectorReduce *, const Expr &init) override; + // @} +}; CodeGen_X86::CodeGen_X86(Target t) : CodeGen_Posix(complete_x86_target(t)) { - -#if !defined(WITH_X86) - user_error << "x86 not enabled for this build of Halide.\n"; -#endif - - user_assert(llvm_X86_enabled) << "llvm build not configured with X86 target enabled.\n"; } -namespace { - const int max_intrinsic_args = 4; struct x86Intrinsic { @@ -160,8 +187,6 @@ const x86Intrinsic intrinsic_defs[] = { }; // clang-format on -} // namespace - void CodeGen_X86::init_module() { CodeGen_Posix::init_module(); @@ -171,7 +196,7 @@ void CodeGen_X86::init_module() { } Type ret_type = i.ret_type; - std::vector arg_types; + vector arg_types; arg_types.reserve(max_intrinsic_args); for (halide_type_t j : i.arg_types) { if (j.bits == 0) { @@ -184,8 +209,6 @@ void CodeGen_X86::init_module() { } } -namespace { - // i32(i16_a)*i32(i16_b) +/- i32(i16_c)*i32(i16_d) can be done by // interleaving a, c, and b, d, and then using pmaddwd. We // recognize it here, and implement it in the initial module. @@ -230,8 +253,6 @@ bool should_use_pmaddwd(const Expr &a, const Expr &b, vector &result) { return false; } -} // namespace - void CodeGen_X86::visit(const Add *op) { vector matches; if (should_use_pmaddwd(op->a, op->b, matches)) { @@ -581,8 +602,8 @@ string CodeGen_X86::mcpu() const { } string CodeGen_X86::mattrs() const { - std::string features; - std::string separator; + string features; + string separator; if (target.has_feature(Target::FMA)) { features += "+fma"; separator = ","; @@ -669,5 +690,20 @@ llvm::Type *CodeGen_X86::llvm_type_of(const Type &t) const { } } +} // namespace + +std::unique_ptr new_CodeGen_X86(const Target &target) { + return std::make_unique(target); +} + +#else // WITH_X86 + +std::unique_ptr new_CodeGen_X86(const Target &target) { + user_error << "x86 not enabled for this build of Halide.\n"; + return nullptr; +} + +#endif // WITH_X86 + } // namespace Internal } // namespace Halide diff --git a/src/CodeGen_X86.h b/src/CodeGen_X86.h deleted file mode 100644 index 5d1d503df6a0..000000000000 --- a/src/CodeGen_X86.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef HALIDE_CODEGEN_X86_H -#define HALIDE_CODEGEN_X86_H - -/** \file - * Defines the code-generator for producing x86 machine code - */ - -#include "CodeGen_Posix.h" - -namespace llvm { -class JITEventListener; -} - -namespace Halide { -namespace Internal { - -/** A code generator that emits x86 code from a given Halide stmt. */ -class CodeGen_X86 : public CodeGen_Posix { -public: - /** Create an x86 code generator. Processor features can be - * enabled using the appropriate flags in the target struct. */ - CodeGen_X86(Target); - -protected: - std::string mcpu() const override; - std::string mattrs() const override; - bool use_soft_float_abi() const override; - int native_vector_bits() const override; - - int vector_lanes_for_slice(const Type &t) const; - - llvm::Type *llvm_type_of(const Type &t) const override; - - using CodeGen_Posix::visit; - - void init_module() override; - - /** Nodes for which we want to emit specific sse/avx intrinsics */ - // @{ - void visit(const Add *) override; - void visit(const Sub *) override; - void visit(const Cast *) override; - void visit(const Call *) override; - void visit(const GT *) override; - void visit(const LT *) override; - void visit(const LE *) override; - void visit(const GE *) override; - void visit(const EQ *) override; - void visit(const NE *) override; - void visit(const Select *) override; - void codegen_vector_reduce(const VectorReduce *, const Expr &init) override; - // @} -}; - -} // namespace Internal -} // namespace Halide - -#endif diff --git a/src/WasmExecutor.cpp b/src/WasmExecutor.cpp index 8415e0eca39d..6a6208d47ba7 100644 --- a/src/WasmExecutor.cpp +++ b/src/WasmExecutor.cpp @@ -1,6 +1,7 @@ #include "WasmExecutor.h" -#include "CodeGen_WebAssembly.h" +#include "CodeGen_Posix.h" +#include "CodeGen_Targets.h" #include "Error.h" #include "Float16.h" #include "Func.h" @@ -285,7 +286,7 @@ std::vector compile_to_wasm(const Module &module, const std::string &fn_na // for the alloca usage. size_t stack_size = 65536; { - std::unique_ptr cg(new CodeGen_WebAssembly(module.target())); + std::unique_ptr cg(new_CodeGen_WebAssembly(module.target())); cg->set_context(context); fn_module = cg->compile(module); stack_size += cg->get_requested_alloca_total(); diff --git a/test/internal.cpp b/test/internal.cpp index bb50f45390d8..35e9fa4efcbc 100644 --- a/test/internal.cpp +++ b/test/internal.cpp @@ -5,7 +5,6 @@ #include "CSE.h" #include "CodeGen_C.h" #include "CodeGen_PyTorch.h" -#include "CodeGen_X86.h" #include "Deinterleave.h" #include "Func.h" #include "Generator.h"