首页 > 其他分享 >TVM 代码生成—TIR to LLVM IR

TVM 代码生成—TIR to LLVM IR

时间:2023-07-22 13:12:07浏览次数:47  
标签:代码生成 llvm target IR module TVM LLVM build mod

本文地址:https://www.cnblogs.com/wanger-sjtu/p/17573212.html

TVM在编译过程中,经历了

graph LR A[3rd IR] --> B[Relay IR] B --> C[TIR] C --> D[LLVM IR] C -->E[Source]

这一系列的过程。其中在生成cpu、rocm、nvptx、hexagon等平台的相关代码的时候,会先由TVM的TIR转换为LLVM IR,在后续由LLVM生成相关的机器码。

这一步是由tvm::codegen::Build调用转换的。

runtime::Module Build(IRModule mod, Target target) {
if (transform::PassContext::Current()
          ->GetConfig<Bool>("tir.disable_assert", Bool(false))
          .value()) {
    mod = tir::transform::SkipAssert()(mod);
  }
  auto target_attr_map = tvm::TargetKind::GetAttrMap<FTVMTIRToRuntime>("TIRToRuntime");
  if (target_attr_map.count(target->kind)) {
    return target_attr_map[target->kind](mod, target);
  }

  // the build function.
  std::string build_f_name = "target.build." + target->kind->name;
  const PackedFunc* bf = runtime::Registry::Get(build_f_name);
  ICHECK(bf != nullptr) << build_f_name << " is not enabled";
  return (*bf)(mod, target);
}

在LLVM相关的target时候,这里的build_f_name就是target.build.llvm

这时候会走到

TVM_REGISTER_GLOBAL("target.build.llvm")
    .set_body_typed([](IRModule mod, Target target) -> runtime::Module {
      auto n = make_object<LLVMModuleNode>();
      n->Init(mod, target);
      return runtime::Module(n);
    });

Init函数中创建codegen的具体类:


void LLVMModuleNode::Init(const IRModule& mod, const Target& target) {
  llvm_instance_ = std::make_unique<LLVMInstance>();
  With<LLVMTarget> llvm_target(*llvm_instance_, target);
  llvm::TargetMachine* tm = llvm_target->GetOrCreateTargetMachine();
  // 这里会根据target得到不同的codegen的实现类
  std::unique_ptr<CodeGenLLVM> cg = CodeGenLLVM::Create(llvm_target.get());

  std::string entry_func;
  /*
  skip crt/cpp systemlib options
  */
  for (auto kv : mod->functions) {
    if (!kv.second->IsInstance<PrimFuncNode>()) {
      // (@jroesch): we relax constraints here, Relay functions will just be ignored.
      DLOG(INFO) << "Can only lower IR Module with PrimFuncs, but got " << kv.second->GetTypeKey();
      continue;
    }
    auto f = Downcast<PrimFunc>(kv.second);
    auto global_symbol = f->GetAttr<String>(tvm::attr::kGlobalSymbol);
    bool is_entry_func = f->HasNonzeroAttr(tir::attr::kIsEntryFunc);

    if (global_symbol) {
      function_names_.push_back(global_symbol.value());
      if (is_entry_func) {
        entry_func = global_symbol.value();
      }
    }
  }
// 初始化CodeGenLLVM, 会产生builder_, module_等llvm 中codegen需要的基础数据结构
  cg->Init("TVMMod", llvm_target.get(), system_lib_prefix, 
             system_lib_prefix.defined(),
           target_c_runtime);
  cg->SetFastMathFlags(llvm_target->GetFastMathFlags());
    // 核心功能,tir 转化为llvm ir就在此
  cg->AddFunctionsOrdered(mod->functions.begin(), mod->functions.end());
  if (entry_func.length() != 0) {
    cg->AddMainFunction(entry_func);
  }

  module_owning_ptr_ = cg->Finish();
  module_ = module_owning_ptr_.get();
  llvm_target->SetTargetMetadata(module_);
  module_->addModuleFlag(llvm::Module::Override, "Debug Info Version",
                         llvm::DEBUG_METADATA_VERSION);

}

标签:代码生成,llvm,target,IR,module,TVM,LLVM,build,mod
From: https://www.cnblogs.com/wanger-sjtu/p/17573212.html

相关文章

  • Ice and Fire
    IceandFiretimelimitpertest1secondmemorylimitpertest256megabytesinputstandardinputoutputstandardoutputLittle09andhisfriendsareplayingagame.Thereare n players,andthetemperaturevalueoftheplayer i is i.Thetypeso......
  • python的.first()
    Python的.first()方法详解在Python中,列表是一种常用的数据结构,它允许我们存储多个元素,并且可以方便地对其进行操作和访问。Python提供了许多内置方法来操作列表,其中之一就是.first()方法。什么是.first()方法?.first()是一种用于列表的方法,它返回列表中的第一个元素。这个方法可......
  • rmdir
    rmdir用来删除空目录补充说明rmdir命令用来删除空目录。当目录不再被使用时,或者磁盘空间已到达使用限定值,就需要删除失去使用价值的目录。利用rmdir命令可以从一个目录中删除一个或多个空的子目录。该命令从一个目录中删除一个或多个子目录,其中dirname佬表示目录名。如果dirna......
  • 硬件笔记之黑苹果Ventura使用Drop DMR table配合disableIOMapperMapping quirks解决无
    0x00概述关键词:VT-d, appleVTD, 黑苹果,英特尔wifi蓝牙无法打开,AX210,WIFI6E,disableIOMapper,disableIOMapperMapping/*板U配置=>技嘉z590Master+10900kOS=>Ventura13.x引导=>OpenCore0.9.2蓝牙WIFI=>板载Intel®Wi-Fi6EAX210支持wifi6和蓝牙5.......
  • No suitable Java Virtual Machine could be found on your system. The version
    Java虚拟机简介与安装什么是Java虚拟机?Java虚拟机(JavaVirtualMachine,简称JVM)是一种能够运行Java字节码的虚拟机。它是Java语言的核心,提供了跨平台的特性,使得一次编写的Java代码可以在不同的操作系统上运行。JVM有两个主要的任务:将Java源代码编译成字节码。在各个操作系统上......
  • No lockfile in this directory. Run `yarn install` to generate one.
    如何解决"Nolockfileinthisdirectory.Runyarninstalltogenerateone."错误介绍在使用Yarn进行JavaScript项目开发时,有时候会遇到一个错误信息:"Nolockfileinthisdirectory.Runyarninstalltogenerateone."这个错误通常是由于项目缺少yarn.lock文件导致......
  • Wireshark mysql
    实现“WiresharkMySQL”教程1.流程概述在实现“WiresharkMySQL”之前,我们需要了解整个流程。下表展示了实现“WiresharkMySQL”的步骤:步骤描述步骤1安装Wireshark步骤2设置捕获过滤器步骤3捕获MySQL数据包步骤4分析捕获的数据包下面将逐步......
  • AGC032F One Third
    首先先证明几个引理。\(\text{Lemma\#1}\):长度为\(1\)的线段上随机取\(n-1\)个点,将其分成\(n\)段,长度最短段的长度期望为\(\dfrac{1}{n^2}\)。证明:我不知道能不能\(\text{Min-Max}\)容斥,但有更简单的做法。假设最小段长度为\(l_{\min}\),考虑枚举\(x\),计算\(......
  • CF718E Matvey's Birthday
    不难发现答案\(\le15\),极限的情况大概就是\(aabbcc\cdotsgghh\),此时跳一步和走一步等效。这启示我们固定点\(i\),统计\(d(i,j)=D,j<i\)的\(j\)的个数,拆成\(i-j\le15\)的贡献和\(i-j>15\)的贡献。为了方便,以下称从\(i\)到\(i+1\)或\(i-1\)为「走」,在相同颜色......
  • android studio first run
    如何在AndroidStudio中进行首次运行作为一名经验丰富的开发者,我将教你如何在AndroidStudio中进行首次运行。以下是整个流程,包括每个步骤需要做什么,以及所需的代码和代码注释。步骤概述步骤描述1下载并安装AndroidStudio2配置AndroidStudio3创建新项目4......