FrozenGene commented on a change in pull request #6261: URL: https://github.com/apache/incubator-tvm/pull/6261#discussion_r470527554
########## File path: src/target/llvm/codegen_hexagon.cc ########## @@ -0,0 +1,798 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#if defined(TVM_LLVM_VERSION) && TVM_LLVM_VERSION >= 70 + +#include <llvm/Bitcode/BitcodeWriter.h> +#if TVM_LLVM_VERSION <= 90 +#include <llvm/IR/Intrinsics.h> +#else +#include <llvm/IR/IntrinsicsHexagon.h> +#endif +#include <llvm/Support/CommandLine.h> +#include <tvm/runtime/module.h> +#include <tvm/target/codegen.h> +#include <tvm/tir/analysis.h> + +#include <cstdio> +#include <cstdlib> +#include <map> +#include <sstream> +#include <string> +#include <unordered_map> +#include <utility> +#include <vector> + +#include "../../runtime/hexagon/hexagon_module.h" +#include "../build_common.h" +#include "codegen_llvm.h" + +namespace tvm { +namespace codegen { + +static std::string get_name(const PrimFunc& f) { + auto global_symbol = f->GetAttr<runtime::String>(tvm::attr::kGlobalSymbol); + CHECK(global_symbol.defined()) + << "CodeGenLLVM: Expect PrimFunc to have the global_symbol attribute"; + return std::string(global_symbol.value()); +} + +// Hexagon code generation +class CodeGenHexagon final : public CodeGenLLVM { + public: + void InitTarget(llvm::TargetMachine* tm) final; + void Init(const std::string& module_name, llvm::TargetMachine* tm, llvm::LLVMContext* ctx, + bool system_lib, bool dynamic_lookup, bool target_c_runtime) final; + + void VisitStmt_(const AssertStmtNode* op) override; + + llvm::Value* CreateIntrinsic(const CallNode* op) override; + llvm::Value* CreateCallExtern(Type ret_type, String global_symbol, const Array<PrimExpr>& args, + bool skip_first_arg) override; + llvm::Module* GetModulePtr() const { return module_.get(); } + + protected: + // meta data + llvm::MDNode* md_tbaa_ctx_ptr_{nullptr}; + llvm::FunctionType* ftype_tvm_func_call_{nullptr}; + llvm::FunctionType* ftype_tvm_get_func_from_env_{nullptr}; + llvm::FunctionType* ftype_tvm_api_set_last_error_{nullptr}; + + private: + llvm::Value* CreateStructRefPtr(DataType t, llvm::Value* buf, llvm::Value* index, int kind); + + // Check if the call to packed function is successful + // if not directly finalize function and pass on return code. + // return the end block after the check + llvm::BasicBlock* CheckCallSuccess(llvm::Value* retcode); + + // Get runtime functions + llvm::Value* RuntimeTVMFuncCall(); + llvm::Value* RuntimeTVMGetFuncFromEnv(); + llvm::Value* RuntimeTVMAPISetLastError(); + + void InitGlobalContext(bool dynamic_lookup); + llvm::GlobalVariable* InitContextPtr(llvm::Type* type, std::string name); + llvm::Value* GetContextPtr(llvm::GlobalVariable* gv); + std::vector<std::pair<std::string, llvm::Value*>> export_system_symbols_; + llvm::Value* GetPackedFuncHandle(const std::string& str); + + // global to packed function handle + std::unordered_map<std::string, llvm::GlobalVariable*> func_handle_map_; + + // Make packed call. + llvm::BasicBlock* MakeCallPacked(const Array<PrimExpr>& args, llvm::Value** rvalue, + llvm::Value** ret_tcode, const DataType& r_type, + const int64_t begin, const int64_t end); + // create call into tvm packed function. + llvm::Value* CreateCallPacked(const CallNode* op); + // Create trace call into tvm packed function. + llvm::Value* CreateCallTracePacked(const CallNode* op); + + std::map<std::string, llvm::Type*> types_for_alloca_; + + // Type definitions. + llvm::Type* t_tvm_func_handle_{nullptr}; + llvm::Type* t_tvm_value_{nullptr}; + llvm::Type* t_tvm_shape_index_{nullptr}; + llvm::Type* t_tvm_context_{nullptr}; + llvm::Type* t_tvm_type_{nullptr}; + llvm::Type* t_tvm_array_{nullptr}; + + // Context for injection lookup + llvm::GlobalVariable* gv_mod_ctx_{nullptr}; + llvm::GlobalVariable* gv_tvm_func_call_{nullptr}; + llvm::GlobalVariable* gv_tvm_get_func_from_env_{nullptr}; + llvm::GlobalVariable* gv_tvm_api_set_last_error_{nullptr}; + std::unordered_map<std::string, llvm::GlobalVariable*> gv_func_map_; + + // context for direct dynamic lookup + llvm::Function* f_tvm_func_call_{nullptr}; + llvm::Function* f_tvm_get_func_from_env_{nullptr}; + llvm::Function* f_tvm_api_set_last_error_{nullptr}; + llvm::Function* f_tvm_register_system_symbol_{nullptr}; +}; + +void CodeGenHexagon::InitTarget(llvm::TargetMachine* tm) { + native_vector_bits_ = 128 * 8; Review comment: Should get the hvx vector size from target, because we could support 64 / 128. Like this: ```cpp auto features = tm->getTargetFeatureString(); auto hvx_bytes_mode = features.substr(features.find("+hvx-length") + std::strlen("+hvx-length")).drop_back(); int hvx_vector_bytes = 0; CHECK(hvx_bytes_mode.getAsInteger(10, hvx_vector_bytes) == 0) << "Can not get the right hvx bytes mode"; CHECK(hvx_vector_bytes == 128 || hvx_vector_bytes == 64); native_vector_bits_ = hvx_vector_bytes * 8; ``` ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: [email protected]
