深入研究Clang(十九) Clang的RISCV支持2

2024-01-16 11:48

本文主要是介绍深入研究Clang(十九) Clang的RISCV支持2,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前文Clang的RISCV支持1介绍了Clang中有关RISCV的代码主要集中在三个地方:Driver部分、Basic部分和CodeGen部分,并且对Basic部分和CodeGen部分的内容和关系进行了介绍,只有Driver部分因为涉及到了ToolChain、Tool和Command(job)等概念体系而未进行深入介绍。

在介绍完ToolChain、Tool和Command(job)等概念和调用关系之后,我们在本文再对Clang的RISCV支持的Driver部分进行深入分析。

一、Driver部分涉及到RISCV是从ToolChain相关操作开始的,这里最早的介入点位于clang/lib/Driver/Driver.cpp中的Compilation *Driver::BuildCompilation(ArrayRef<constchar *> ArgList) 函数,它首先调用了getToolChain函数。位于同个文件下的getToolChain函数之中,逐步拆解了目标的操作系统、环境和目标平台,具体代码如下:

const ToolChain &Driver::getToolChain(const ArgList &Args,const llvm::Triple &Target) const {auto &TC = ToolChains[Target.str()];if (!TC) {switch (Target.getOS()) {case llvm::Triple::AIX:TC = std::make_unique<toolchains::AIX>(*this, Target, Args);break;...case llvm::Triple::Win32:switch (Target.getEnvironment()) {default:if (Target.isOSBinFormatELF())TC = std::make_unique<toolchains::Generic_ELF>(*this, Target, Args);else if (Target.isOSBinFormatMachO())TC = std::make_unique<toolchains::MachO>(*this, Target, Args);elseTC = std::make_unique<toolchains::Generic_GCC>(*this, Target, Args);break;case llvm::Triple::GNU:TC = std::make_unique<toolchains::MinGW>(*this, Target, Args);break;...}break;...default:// Of these targets, Hexagon is the only one that might have// an OS of Linux, in which case it got handled above already.switch (Target.getArch()) {case llvm::Triple::tce:TC = std::make_unique<toolchains::TCEToolChain>(*this, Target, Args);break;...case llvm::Triple::riscv32:case llvm::Triple::riscv64:TC = std::make_unique<toolchains::RISCVToolChain>(*this, Target, Args);break;default:...}}}// Intentionally omitted from the switch above: llvm::Triple::CUDA.  CUDA// compiles always need two toolchains, the CUDA toolchain and the host// toolchain.  So the only valid way to create a CUDA toolchain is via// CreateOffloadingDeviceToolChains.return *TC;
}

这里最早出现了有关RISCV的内容,构建所需要的ToolChain:

      case llvm::Triple::riscv32:case llvm::Triple::riscv64:TC = std::make_unique<toolchains::RISCVToolChain>(*this, Target, Args);break;

二、上文RISCVToolChain的定义和实现,以及为其所用的RISCV相关的Tool,均位于下列两个文件里:

clang/lib/Driver/ToolChains/RISCVToolchain.h

clang/lib/Driver/ToolChains/RISCVToolchain.cpp

下面进行分类讨论:

1、ToolChain方面:定义了RISCVToolChain,它继承于Generic_ELF,Generic_ELF继承于Generic_GCC,Generic_GCC继承于ToolChain。在源码上的体现:

clang/lib/Driver/ToolChains/RISCVToolchain.h

class LLVM_LIBRARY_VISIBILITY RISCVToolChain : public Generic_ELF {

clang/lib/Driver/ToolChains/Gnu.h

namespace toolchains {/// Generic_GCC - A tool chain using the 'gcc' command to perform
/// all subcommands; this relies on gcc translating the majority of
/// command line options.
class LLVM_LIBRARY_VISIBILITY Generic_GCC : public ToolChain {class LLVM_LIBRARY_VISIBILITY Generic_ELF : public Generic_GCC {

2、Tool方面:定义了RISCV::Linker,它继承于GnuTool ,GnuTool 继承于Tool。源码上的体现:

clang/lib/Driver/ToolChains/RISCVToolchain.h

namespace tools {
namespace RISCV {
class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {

clang/lib/Driver/ToolChains/Gnu.h

namespace tools {/// Base class for all GNU tools that provide the same behavior when
/// it comes to response files support
class LLVM_LIBRARY_VISIBILITY GnuTool : public Tool {

三、Driver部分,还有两个相关文件RISCV.h和RISCV.cpp,他们的完整路径为:

clang/lib/Driver/ToolChains/Arch/RISCV.h

clang/lib/Driver/ToolChains/Arch/RISCV.cpp

这两个文件主要提供了获取ABI、Arch和RISCV目标特征的接口,具体代码表示如下:

clang/lib/Driver/ToolChains/Arch/RISCV.h

namespace clang {
namespace driver {
namespace tools {
namespace riscv {
void getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple,const llvm::opt::ArgList &Args,std::vector<llvm::StringRef> &Features);
StringRef getRISCVABI(const llvm::opt::ArgList &Args,const llvm::Triple &Triple);
StringRef getRISCVArch(const llvm::opt::ArgList &Args,const llvm::Triple &Triple);
} // end namespace riscv
} // namespace tools
} // end namespace driver
} // end namespace clang

其中,在实现层面,getRISCVTargetFeatures还会调用getRISCVArch,并且调用getArchFeatures获取Arch特征。getArchFeatures则通过getExtensionVersion获取扩展版本号,然后通过getExtensionFeatures获取扩展特征。所以,具体的扩展版本号、以及扩展特征要进行改动的话,都是在clang/lib/Driver/ToolChains/Arch/RISCV.cpp这个文件里更新。

这里的信息与Basic部分信息不同,Basic部分主要是生成代码所需要的基本信息,而这里则是详细的扩展版本、扩展特征检查和校验。后续会对这里getRISCVABI、getRISCVArch和getRISCVTargetFeatures的被调用关系进行分析。

1、上面所提到的getRISCVABI函数,被调用的地方主要有:

1)Clang、ClangAs这两个Tool子类的AddRISCVTargetArgs函数;(clang/lib/Driver/ToolChains/Clang.h、clang/lib/Driver/ToolChains/Clang.cpp)

2)Assembler这个tool的tools::gnutools::Assembler::ConstructJob函数;

(clang/lib/Driver/ToolChains/Gnu.h、clang/lib/Driver/ToolChains/Gnu.cpp)

3)Generic_GCC::GCCInstallationDetector::ScanGCCForMultilibs函数所调用的findRISCVMultilibs函数之中,以及findRISCVMultilibs函数所调用的findRISCVBareMetalMultilibs函数之中;

(clang/lib/Driver/ToolChains/Gnu.h、clang/lib/Driver/ToolChains/Gnu.cpp)

4)Linux这个toolchain的构造函数,以及它的std::string Linux::getDynamicLinker函数之中。

(clang/lib/Driver/ToolChains/Linux.h、clang/lib/Driver/ToolChains/Linux.cpp)

2、上面所提到的getRISCVArch,被调用的地方在:

1) Assembler这个tool的tools::gnutools::Assembler::ConstructJob函数;

(clang/lib/Driver/ToolChains/Gnu.h、clang/lib/Driver/ToolChains/Gnu.cpp)

2)Generic_GCC::GCCInstallationDetector::ScanGCCForMultilibs函数所调用的findRISCVMultilibs函数所调用的findRISCVBareMetalMultilibs函数之中;

(clang/lib/Driver/ToolChains/Gnu.h、clang/lib/Driver/ToolChains/Gnu.cpp)

3、上面所提到的getRISCVTargetFeatures,被调用的地方在getTargetFeatures函数之中,这个函数主要被Clang这个tool的Clang::RenderTargetOptions函数和Clang::ConstructJob函数、ClangAs这个tool的ClangAs::ConstructJob函数所调用。(clang/lib/Driver/ToolChains/Clang.cpp)

可以看到,这三个函数主要的应用场景还是给Tool的一些子类进行调用。

这篇关于深入研究Clang(十九) Clang的RISCV支持2的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/612491

相关文章

【重学 MySQL】十九、位运算符的使用

【重学 MySQL】十九、位运算符的使用 示例检查权限添加权限移除权限 在 MySQL 中,位运算符允许你直接在整数类型的列或表达式上进行位级操作。这些操作对于处理那些需要在二进制表示上进行直接修改或比较的场景特别有用,比如权限管理、状态标记等。 &(位与) 对两个数的二进制表示进行位与操作。只有两个相应的二进制位都为 1 时,结果的该位才为 1,否则为 0。 |(位

Golang支持平滑升级的HTTP服务

前段时间用Golang在做一个HTTP的接口,因编译型语言的特性,修改了代码需要重新编译可执行文件,关闭正在运行的老程序,并启动新程序。对于访问量较大的面向用户的产品,关闭、重启的过程中势必会出现无法访问的情况,从而影响用户体验。 使用Golang的系统包开发HTTP服务,是无法支持平滑升级(优雅重启)的,本文将探讨如何解决该问题。 一、平滑升级(优雅重启)的一般思路 一般情况下,要实现平滑

sqlite不支持中文排序,采用java排序

方式一 不支持含有重复字段进行排序 /*** sqlite不支持中文排序,改用java排序* 根据指定的对象属性字段,排序对象集合,顺序* @param list* @param field* @return*/public static List sortListByField(List<?> list,String field){List temp = new ArrayList(

一款支持同一个屏幕界面同时播放多个视频的视频播放软件

GridPlayer 是一款基于 VLC 的免费开源跨平台多视频同步播放工具,支持在一块屏幕上同时播放多个视频。其主要功能包括: 多视频播放:用户可以在一个窗口中同时播放任意数量的视频,数量仅受硬件性能限制。支持多种格式和流媒体:GridPlayer 支持所有由 VLC 支持的视频格式以及流媒体 URL(如 m3u8 链接)。自定义网格布局:用户可以配置播放器的网格布局,以适应不同的观看需求。硬

Science Robotics 首尔国立大学研究团队推出BBEX外骨骼,实现多维力量支持!

重复性举起物体可能会对脊柱和背部肌肉造成损伤,由此引发的腰椎损伤是工业环境等工作场所中一个普遍且令人关注的问题。为了减轻这类伤害,有研究人员已经研发出在举起任务中为工人提供辅助的背部支撑装置。然而,现有的这类装置通常无法在非对称性的举重过程中提供多维度的力量支持。此外,针对整个人体脊柱的设备安全性验证也一直是一个缺失的环节。 据探索前沿科技边界,传递前沿科技成果的X-robot投稿,来自首尔国立

超级 密码加密 解密 源码,支持表情,符号,数字,字母,加密

超级 密码加密 解密 源码,支持表情,符号,数字,字母,加密 可以将表情,动物,水果,表情,手势,猫语,兽语,狗语,爱语,符号,数字,字母,加密和解密 可以将文字、字母、数字、代码、标点符号等内容转换成新的文字形式,通过简单的文字以不同的排列顺序来表达不同的内容 源码截图: https://www.httple.net/152649.html

QtC++截图支持窗口获取

介绍 在截图工具中你会发现,接触到窗口后会自动圈出目标窗口,个别强大一点的还能进行元素识别可以自动圈出元素,那么今天简单分析一下QTc++如何获取窗口并圈出当前鼠标下的窗口。 介绍1.如何获取所有窗口2.比较函数3.实现窗口判断 结尾 1.如何获取所有窗口 1.我们需要调用windows接口EnumWindowsProc回调函数来获取所有顶级窗口,需要包含windows.

Nacos Config 配置中心支持配置共享

文章目录 一、什么是配置中心二、Nacos Config2.1 Nacos Config 工作原理 (★)2.2 Nacos Config 的使用2.3 动态刷新2.4 配置共享2.4.1 同一个微服务的不同环境之间共享配置2.4.2 不同微服务中间共享配置 一、什么是配置中心 微服务架构下关于配置文件的存在以下问题: 配置文件相对分散。在一个微服务架构下,配置文件会随

spring笔记 多线程的支持

spring的工作机制 136  属性编辑器 140 spring事件的体系结构 168 Bean间的关系 109 继承 依赖 引用     Bean的继承          1 为了简化初始化的属性注入;          2 子Bean和父Bean相同的属性值,使用子Bean的     Bean的依赖 Srping控制相互依赖的Bean之间,属性注入的顺序,防止出错  depend-on

PageOfficeCtrl支持直接打开服务器磁盘文件

一般来说,PageOfficeCtrl控件的WebOpen方法的第一个参数是待打开文档的URL,此URL可以是相对于当前页面的相对URL,也可以是相对于整个网站根的相对URL,还可以是http开头的完整URL,但是这个URL必须是当前网站的URL,不能跨域。 现在为了更加方便开发者编程,WebOpen支持打开服务器磁盘文件。也就是说,第一个参数可以写成服务器文件的绝对磁盘路径。例如: P