首页 > 编程语言 >gcc源码分析 GIMPLIFY相关

gcc源码分析 GIMPLIFY相关

时间:2024-06-01 23:59:07浏览次数:34  
标签:node decl gcc GIMPLIFY cgraph 源码 gimple 节点 函数

gcc源码分析 GIMPLIFY相关

四、GIMPLIFY相关

GCC通过前端的词法/语法分析后,将高级编程语言转换成抽象的AST中间表示。为了对AST中间表示进行语言无关的处理和优化,GCC引入了GIMPLE。GENERIC就是规范的AST。一般来说,如果一种前端语言的AST树均可以使用树节点表示,那么该AST就是GENERIC/AST,GIMPLE为是了处理不同的前端语言及其相应的AST/GENERIC, GCC引入的一种与前端语言无关的中间表示。GIMPLE是一种三地址码的中间表示形式。在从AST向GIMPLE转换的过程中,GIMPLE的生成先后经历了两个阶段,分别称为高级GIMPLE(High-Level GIMPLE)和低级GIMPLE(Low-Level GIMPLE)

4.1 gcc全局符号表与符号分析

4.1.1 全局符号表

全局符号表中的主要符号都是伴随源码解析过程中AST树的生成而生成的,在整个编译单元中所有外部声明都被解析为AST树节点后,所有的外部声明都总能对应到全局符号表中的一个函数节点或一个变量节点,在gcc中有一个全局变量symbol_table *symtab,这个变量用于记录编译过程中产生的函数和符号,symbol_table类大体结构表如下所示:

## gcc/cgraph.h

class symbol_table
{
   
public:
  friend class symtab_node;
  friend class cgraph_node;
  friend class cgraph_edge;
 ........
  int cgraph_count;    /* 记录当前全局符号表中的函数节点个数*/
  int cgraph_max_uid;    
  int cgraph_max_summary_id;
  int edges_count;       
  int edges_max_uid;    
  int edges_max_summary_id;

  /* 
     这里是一个链表,其中链接当前编译单元的所有符号节点,函数节点实际上是一个 cgraph_node结构体
  */
  symtab_node* GTY(()) nodes;
  asm_node* GTY(()) asmnodes;
  asm_node* GTY(()) asm_last_node;
  cgraph_node* GTY(()) free_nodes;
  cgraph_edge * GTY(()) free_edges;
  int order;

  /* Set when whole unit has been analyzed so we can access global info.  */
  bool global_info_ready;
  /* What state callgraph is in right now.  */
  enum symtab_state state;
  
};

这个symtab->nodes成员,记录了当前编译单元所有的函数和变量节点信息:对于函数而言,其节点信息通过一个cgraph_node结构体去表示;对于变量来说,其节点信息是通过一个varpoool_node结构体来表示,都是可以链接到nodes上。
在分析语法解析时,解析一个函数时(c_parser_declaration_or_fndef)会调用cgraph_node::get_create为当前函数创建一个函数节点(cgraph_node);解析到一个变量时(同样c_parser_declaration_or_fndef)会调用varpool_node::get_create为变量创建一个变量节点(varpool_node),这两种情况创建的节点都会链接到全局符号表中。
函数节点的分析,主要是对其进行gimplify(包括gimple高端化和gimple低端化),变量节点的分析,主要是对其做对齐操作

4.1.2 函数节点的gimplify

函数节点的分析,主要是对其进行gimplify,当分析完毕后,会设置symtab_node.analzed = true,代表此节点已经分析完毕,cgraph_node::analyze函数大体如下:

void
cgraph_node::analyze (void)
{
   
  tree decl = this->decl; /*从函数节点中找到此函数的声明树节点*/
  location_t saved_loc = input_location;
  input_location = DECL_SOURCE_LOCATION (decl);

  if (thunk.thunk_p)
    {
   
      cgraph_node *t = cgraph_node::get (thunk.alias);

      create_edge (t, NULL, 0, CGRAPH_FREQ_BASE);
      callees->can_throw_external = !TREE_NOTHROW (t->decl);
      /* Target code in expand_thunk may need the thunk's target
	 to be analyzed, so recurse here.  */
      if (!t->analyzed)
	t->analyze ();
      if (t->alias)
	{
   
	  t = t->get_alias_target ();
	  if (!t->analyzed)
	    t->analyze ();
	}
      if (!expand_thunk (false, false))
	{
   
	  thunk.alias = NULL;
	  return;
	}
      thunk.alias = NULL;
    }
  if (alias)
    resolve_alias (cgraph_node::get (alias_target), transparent_alias);
  else if (dispatcher_function)
    {
   
      cgraph_function_version_info *dispatcher_version_info
	= function_version ();
      if (dispatcher_version_info != NULL
          && (dispatcher_version_info->dispatcher_resolver
	      == NULL_TREE))
	{
   
	  tree resolver = NULL_TREE;
	  gcc_assert (targetm.generate_version_dispatcher_body);
	  resolver = targetm.generate_version_dispatcher_body (this);
	  gcc_assert (resolver != NULL_TREE);
	}
    }
  else
    {
   
      push_cfun (DECL_STRUCT_FUNCTION (decl));  /* 重置全局的current_function_decl到当前待分析函数 */
      assign_assembler_name_if_neeeded (decl);  /* 为此函数设置汇编名 */

      if (!gimple_has_body_p (decl)) /* 若当前函数节点尚未做过gimple 高端化,则对其进行gimple 高端化 */
	gimplify_function_tree (decl);
      /* Lower the function.  */
      if (!lowered)     /* 若当前函数节点尚未做过giomple低端化,则对其进行gimple 低端化 */
	{
   
	  if (nested)
	    lower_nested_functions (decl);
	  gcc_assert (!nested);

	  gimple_register_cfg_hooks ();
	  bitmap_obstack_initialize (NULL);
	  execute_pass_list (cfun, g->get_passes ()->all_lowering_passes);/* gimple低端化并不是执行某个具体的函数,而是执行 all_lowering_passes链表中的所有pass,这些pass执行完毕则代表gimple低端化完成 */
	  free_dominance_info (CDI_POST_DOMINATORS);
	  free_dominance_info (CDI_DOMINATORS);
	  compact_blocks ();
	  bitmap_obstack_release (NULL);
	  lowered = true;    /* 整个all_lowering_passes中所有pass都执行完毕,则在函数节点中标记gimple低端化结束 */
	}
      pop_cfun ();       /* 恢复之前的cfunc / current_function_decl */
    }
  analyzed = true;       /*标记分析完毕*/

  input_location = saved_loc;
}

由上面的函数节点分析基本上就是gimple高端化+gimple低端化,其中:gimple高端化通过函数gimplify_function_tree完成,gimple低端化通过all_lowering_passes中的一系列pass完成,这些pass如下:

## gcc/passes.def
## 这里展示的所有all_lowering_passes可能被执行的pass,是否被执行,取决于gcc的编译选项和被编译代码的编译选项。
  INSERT_PASSES_AFTER (all_lowering_passes)
  NEXT_PASS 

标签:node,decl,gcc,GIMPLIFY,cgraph,源码,gimple,节点,函数
From: https://blog.csdn.net/swh547/article/details/139194889

相关文章

  • GPT-4o大模型分析文档和识图理解能力(6月最新ChatGPT商业运营网站程序源码)
    6月最新ChatGPT商业运营网站程序源码、支持Midjourney绘画,GPT语音对话+DALL-E3文生图+文档分析+suno-ai音乐生成+支持GPTs文章目录一、如何评价GPT-4o?1、GPT-4o大模型(文档分析)2、GPT-4o大模型(识图理解能力)3、SparkAi系统核心能力二、系统功能模块演示1、AI全模型支持/......
  • spdlog日志库源码:日志记录器logger类
    特性一个logger类对象代表一个日志记录器,为用户提供日志记录接口。每个logger对象都有一个唯一的名称,用于标识该logger。logger对象维护一个日志等级(如DEBUG、INFO、WARN、ERROR等)。只有当日志消息的等级高于或等于logger的当前等级时,消息才会被记录下来。logger......
  • spdlog日志库源码:输出通道sink
    概述在spdlog日志库中,sinks并不是一个单独的类,而是一系列类的集合,这些类以基类-派生类的形式组织,每一个sink派生类代表了一种输出日志消息的方式。输出目标可以是普通文件、标准输出(stdout)、标准错误输出(stderr)、系统日志(syslog)等等。其文件位于include/spd......
  • 【技术突破】优秘数字人独立部署源码功能进化
    随着数字人直播系统的兴起,越来越多的人对数字人直播系统源码(源码:ai6ai69)搭建感兴趣。数字人直播系统源码在一些市场上是可以找到的,但是鱼目混杂、五花八门想要找一个合适自己的就需要一定技巧,要选择一个技术专业的AI数字人直播系统源码服务商是很关键的,关系到成败。优秘数字......
  • 轻松学AI:数字人系统源码部署简易教程“
    随着短视频领域的迅猛发展,数字化概念已经成为我们生活中不可或缺的一部分。在数字化的大潮中,数字人源码部署(源码部署:ai6ai69)成为了一个热门的商业风口项目。很多企业和个人创业者开始关注并探索如何选择适合自己的数字人源码部署方案。在选择数字人系统源码厂家时,我们需要明......
  • 解决源码部署难题:如何定位数字人系统的源头厂商“
    解决源码部署难题:如何定位数字人系统的源头厂商随着短视频领域的爆发,AI人工智能也开始慢慢向这个行业渗透,在这个大背景下,数字人源码部署成为了创业者中热门的话题。面对市场上众多的数字人源码厂家,如何选择一个值得信赖、技术实力过硬的企业成为了很多人的难题。今天,小编就咨......
  • html中轮播图的做法及源码
    <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>Document</title>......
  • 全开源源码---小红书卡片-跳转微信-自动回复跳转卡片-商品卡片-发私信-发群聊-安全导
    做小红书的人都知道小红书的用户商业价值非常高,消费能力很强,很多做高客单产品的都想从小红书平台上引流到私域成交,但是都会遇到账号违规、被封的问题,因为小红书的平台是所有平台里对引流导流最严的。不允许留公众号、手机号、微信号等联系方式,一旦被发现就会面临封禁等处罚。......
  • 开源源码---小红书卡片-跳转微信-自动回复跳转卡片-商品卡片-发私信-发群聊-安全导流
     做小红书的人都知道小红书的用户商业价值非常高,消费能力很强,很多做高客单产品的都想从小红书平台上引流到私域成交,但是都会遇到账号违规、被封的问题,因为小红书的平台是所有平台里对引流导流最严的。不允许留公众号、手机号、微信号等联系方式,一旦被发现就会面临封禁等处罚。......
  • 基于SpringBoot+Vue的在线答疑管理系统设计与实现毕设(文档+源码)
            目录一、项目介绍二、开发环境三、功能介绍四、核心代码五、效果图六、源码获取:        大家好呀,我是一个混迹在java圈的码农。今天要和大家分享的是一款基于SpringBoot+Vue的在线答疑管理系统,项目源码请点击文章末尾联系我哦~目前有各类成......