I think I got it. The LLVM host module compilation generates it.
src/target/llvm/llvm_module.cc: ``` TVM_REGISTER_GLOBAL("target.build.llvm").set_body_typed([](IRModule mod, std::string target) { auto n = make_object<LLVMModuleNode>(); n->Init(mod, target); return runtime::Module(n); }); ... void Init(const IRModule& mod, std::string target) { InitializeLLVM(); tm_ = GetLLVMTargetMachine(target); ... module_ = cg->Finish(); ... } ``` The cg->Finish() calls src/target/llvm/codegen_llvm.cc: ``` std::unique_ptr<llvm::Module> CodeGenLLVM::Finish() { this->AddStartupFunction(); for (size_t i = 0; i < link_modules_.size(); ++i) { CHECK(!llvm::Linker::linkModules(*module_, std::move(link_modules_[i]))) << "Failed to link modules"; } link_modules_.clear(); // optimize this->Optimize(); return std::move(module_); } ``` The AddStartupFunction() is overridden in src/target/llvm/codegen_cpu.cc. Here you see the __tvm_module_startup. ``` void CodeGenCPU::AddStartupFunction() { if (export_system_symbols_.size() != 0) { llvm::FunctionType* ftype = llvm::FunctionType::get(t_void_, {}, false); function_ = llvm::Function::Create(ftype, llvm::Function::InternalLinkage, "__tvm_module_startup", module_.get()); llvm::BasicBlock* startup_entry = llvm::BasicBlock::Create(*ctx_, "entry", function_); builder_->SetInsertPoint(startup_entry); for (const auto& kv : export_system_symbols_) { llvm::Value* name = GetConstString(kv.first); builder_->CreateCall(f_tvm_register_system_symbol_, {name, builder_->CreateBitCast(kv.second, t_void_p_)}); } llvm::appendToGlobalCtors(*module_, function_, 65535); builder_->CreateRet(nullptr); } } ``` --- [Visit Topic](https://discuss.tvm.ai/t/how-is-tvm-module-startup-invoked/6891/3) to respond. You are receiving this because you enabled mailing list mode. To unsubscribe from these emails, [click here](https://discuss.tvm.ai/email/unsubscribe/47257f16ad867e45237a039e72bd8113eaecd32711c2624474d66c5a461ccecf).