LLVM 尾调用优化

2024-04-28

以下是我对事情的理解:

当函数“f”调用自身是其最后一个动作时,它是尾递归的。 通过形成循环而不是再次调用函数,可以显着优化尾递归;函数的参数已就地更新,并且函数体再次运行。这称为递归尾调用优化。

LLVM 在使用 fastcc、GHC 或 HiPE 调用约定时实现递归尾部调用优化。http://llvm.org/docs/CodeGenerator.html#tail-call-optimization http://llvm.org/docs/CodeGenerator.html#tail-call-optimization

我有一些疑问: 让我们考虑一个愚蠢的例子:

int h(int x){
  if (x <= 0)
    return x;
  else
    h(x-1);
}

1)在他们的示例中,关键字“tail”位于调用之前。我在其他地方读到这个关键字是可选的。假设上面的函数被适当地翻译为 LLVM,最后几行是否需要

%x' = load *i32 %x
%m = tail call fastcc i32 @h(i32 %x')
ret %m

2)示例中 inreg 选项的含义是什么?

3)我不想到处执行尾调用优化,只针对递归函数。有没有办法让 LLVM 只对递归函数执行优化(如果可用)?


显然答案是肯定的。你必须改变 h 的定义才能看到这一点(因为优化器太好了!它会计算出 h 要么是恒等式,要么返回 0)。

Consider

int factorial (int x, int y){
  if (x==0)
    return y;
  else
    return factorial(x-1,y*x);
}

使用 clang -S -emit-llvm 编译,因此不执行任何优化。人们看到没有直接指定调用约定,这意味着默认的调用约定足以支持尾递归优化(通常是否支持尾调用是另一回事——知道这一点会很有趣,但我想这确实是一个不同的问题)。

clang -S -emit-llvm 发出的文件是 main.s (假设阶乘定义在 main.c 中)。如果你跑

opt -O3 main.s -S -o mainOpt.s

然后你可以看到尾递归被消除了。有一个称为 tailcallelim 的优化,可以作为 -O3 打开。这很难说,因为帮助文件 opt --help 只说 -O3 与 gcc -O3 类似。

关键是我们可以看到不需要为此指定调用约定。也许不需要 fastcc,或者它是默认的?所以(1)得到了部分回答;但是,我仍然不知道(2)或(3)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

LLVM 尾调用优化 的相关文章

随机推荐

  • 无需重新计算即可获取字典键哈希

    有没有办法从字典中提取现有的密钥哈希 而无需再次重新计算它们 暴露它们并因此通过哈希而不是密钥访问字典会有什么风险 我认为 Python 的字典对象没有任何公共 API 可以让您查看存储其对象的哈希值 您无法在 Python 代码中直接通过
  • Scala 恢复或recoverWith

    我们公司正在用Scala开发一些系统 我们有一些疑问 我们正在讨论如何映射未来的异常 但我们不知道何时应该使用选项 1 或选项 2 val created Future 选项1 val a created recover case e da
  • 具有运行空间池的 SessionStateProxy 变量

    我想在 PowerShell 中使用运行空间池来执行后台操作 但我需要从主线程访问 WPF 窗口变量 普通运行空间有以下选项 runspace SessionStateProxy SetVariable xamGUI xamGUI 但是我如
  • 内容更改时 DataGridView 样式不更新

    好的 这是我的情况 我有一个DataGridView含有Messages 应用以下样式
  • 计算具有不均匀间隔点的 3D 梯度

    我目前有一个由几百万个不均匀间隔的粒子组成的体积 每个粒子都有一个属性 对于那些好奇的人来说是潜力 我想计算其局部力 加速度 np gradient 仅适用于均匀分布的数据 我在这里查看 numpy 中的二阶梯度 https stackov
  • Python 和 Scipy:如何拟合冯·米塞斯分布?

    我正在尝试拟合来自 scipy 的冯 米塞斯分布 http docs scipy org doc scipy reference generated scipy stats vonmises html http docs scipy org
  • ValueError:无法解释优化器标识符:

    我尝试运行此代码 但出现此错误 请任何人过去也遇到过相同的错误 sgd optimizers SGD lr 0 01 decay 1e 6 momentum 0 9 nesterov True 编译模型 model compile opti
  • IE 中“对象不支持属性或方法‘查找’”

  • 如何在java中将ojalgo稀疏数组存储到文件中?

    我目前有一个 SparseStore 矩阵 我在其中执行大量计数和计算 我想将其存储到文件中 以便以后可以重复使用它 而无需重新执行之前的所有计算 我尝试了 Java 中的基本序列化 ObjectOutputStream outputStr
  • 滚动文件实现

    我一直很好奇滚动文件是如何在日志中实现的 如何开始用任何语言创建一个文件写入类 以确保不超过文件大小 我能想到的唯一可能的解决方案是 write method size file size size of string to write i
  • python 正则表达式 - 列表中的 re.findall()

    这是我的清单 lista u REG S 3 UMTS 0 0 RNC u REG S 3 UMTS 0 1 RNC u REG S 3 UMTS 0 2 RNC u REG S 2 GSM NORT CBSP bsc 0 0 BSC u
  • 无法从 JAR 文件加载主类

    我有一个 Spark scala 应用程序 我尝试显示一条简单的消息 Hello my App 当我编译它时sbt compile并运行它sbt run没关系 我成功显示了我的消息 但他显示了错误 像这样 Hello my applicat
  • 在 ant 脚本中包含外部 JAR 时出错

    这是我第一次尝试编写 ANT 脚本 这是我使用 Spring 构建的简单 Hello World 应用程序的 build xml
  • 如何找到具有特定字符串但不在注释中的代码

    我试图在 1 000 个存储过程和函数中搜索特定字符串 在本例中为电子邮件地址 但当它位于注释块中时我想忽略它 这是查找对象的 SQL 语法 但有数百个结果 我不想遍历每个结果来确定电子邮件地址是在代码中使用还是仅在注释块中使用 SELEC
  • MySQL ORDER BY rand(),名称 ASC

    我想获取一个包含 1000 个用户的数据库并随机选择 20 个用户 ORDER BY rand LIMIT 20 然后按名称对结果集进行排序 我想出了以下查询not像我希望的那样工作 SELECT FROM users WHERE 1 OR
  • 使用 Excel 从 Lotus Notes 发送电子邮件并具有附件和 HTML 正文

    是的 我正在尝试通过 Lotus Notes 发送 Excel 电子表格的电子邮件 它有一个附件 并且正文需要采用 HTML 格式 从我读过的所有代码来看 我有一些代码应该允许我这样做 但事实并非如此 如果没有 HTML 正文 附件将发送
  • 如何从电子表格加载特定工作表

    我有一个包含很多工作表的电子表格 我需要加载其中一张工作表 我该怎么做 Here is a photo of the sheets in my Spreadsheet 这是我的想法如何做到这一点 var sheet SpreadsheetA
  • 如何分配二维数组? [复制]

    这个问题在这里已经有答案了 我需要创建一个二维数组 目前我将其创建为int a 100 100 但我需要使用动态分配内存malloc在C语言中 我用了代码 include
  • AWS SAM CLI 在构建、打包和部署期间忽略我的 Python 依赖项

    我正在尝试使用 MacOS 中的 SAM CLI 工具部署 AWS Lambda 函数 而不是使用 Docker 容器 SAM CLI 版本 0 4 0 Lambda 函数的 Python 3 8 运行时 MacOS 上本地安装的 Pyth
  • LLVM 尾调用优化

    以下是我对事情的理解 当函数 f 调用自身是其最后一个动作时 它是尾递归的 通过形成循环而不是再次调用函数 可以显着优化尾递归 函数的参数已就地更新 并且函数体再次运行 这称为递归尾调用优化 LLVM 在使用 fastcc GHC 或 Hi