为什么Clang自动向我的函数添加属性? [英] Why is Clang automatically adding attributes to my functions?
问题描述
我有一段代码正试图转换为LLVM位代码:
I have a piece of code that I'm trying to turn into LLVM bitcode:
int main() {
volatile double n = 0.45;
for (int j = 0; j < 32; j++) {
n *= j;
}
return 0;
}
我在其上运行以下命令:
I run the following command on it:
clang -O0 -S -emit-llvm TrainingCode/trainingCode.cpp -o TrainingCode/trainingCode.ll
生成以下LLVM位代码(请注意第6行,即"Function Attrs"):
to generate the following LLVM bitcode (take note of the 6th line, the one with "Function Attrs"):
; ModuleID = 'TrainingCode/trainingCode.cpp'
source_filename = "TrainingCode/trainingCode.cpp"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
; Function Attrs: noinline norecurse nounwind optnone uwtable
define i32 @main() #0 {
entry:
%retval = alloca i32, align 4
%n = alloca double, align 8
%j = alloca i32, align 4
store i32 0, i32* %retval, align 4
store double 4.500000e-01, double* %n, align 8
store i32 0, i32* %j, align 4
br label %for.cond
for.cond: ; preds = %for.inc, %entry
%0 = load i32, i32* %j, align 4
%cmp = icmp slt i32 %0, 32
br i1 %cmp, label %for.body, label %for.end
for.body: ; preds = %for.cond
%1 = load i32, i32* %j, align 4
%conv = sitofp i32 %1 to double
%2 = load double, double* %n, align 8
%mul = fmul double %2, %conv
store double %mul, double* %n, align 8
br label %for.inc
for.inc: ; preds = %for.body
%3 = load i32, i32* %j, align 4
%inc = add nsw i32 %3, 1
store i32 %inc, i32* %j, align 4
br label %for.cond
for.end: ; preds = %for.cond
ret i32 0
}
attributes #0 = { noinline norecurse nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
!llvm.module.flags = !{!0}
!llvm.ident = !{!1}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{!"clang version 5.0.0 (tags/RELEASE_500/final)"}
为什么clang将optnone
属性添加到main
?我需要LLVM在位码上运行各种转换,并且optnone
属性导致LLVM跳过main ...我需要不添加此属性.
Why is clang adding the optnone
attribute to main
? I need LLVM to run various transformation passes on the bitcode and the optnone
attribute is causing LLVM to skip over main... I need this attribute to not be added.
使用-O1
进行编译似乎可以解决此问题,但是这是不可接受的,因为我需要使用Clang来提供未优化的代码.我希望LLVM优化Clang给我的未优化代码,但是optnone
属性的存在导致LLVM不执行任何优化.
Compiling with -O1
seems to fix this, however this is unacceptable because I need Clang to give me unoptimized code. I want LLVM to optimize the unoptimized code given to me by Clang, but the presence of the optnone
attribute is causing LLVM to not perform any optimizations.
推荐答案
有一些clang选项可以禁用其对LLVM-IR的优化.请参阅 https://reviews.llvm.org/D28047 ,以了解可以更改它们的补丁的讨论,和 @ Anton的答案有关使用它的更多问题.这些选项中的一些或全部可能是正确的:
There are clang options to disable its optimization of the LLVM-IR. See https://reviews.llvm.org/D28047 for discussion of a patch that would change them, and @Anton's answer to this question for more about using it. Some or all of these options might be the right thing:
clang -O1 -mllvm -disable-llvm-optzns -disable-llvm-passes
(该讨论的解决方案是提交rL290392:Make '-disable-llvm-optzns' an alias for '-disable-llvm-passes'
,所以当前的clang只需要一个.)
(The resolution of that discussion was commit rL290392: Make '-disable-llvm-optzns' an alias for '-disable-llvm-passes'
, so current clang only needs one.)
或者有一种愚蠢的方法:使用sed
(或您最喜欢的文本处理工具)可以实现简单的解决方法.
Or there's the dumb way: A simple workaround is possible with sed
(or your favourite text-processing tool).
您仅在编译器生成的代码上使用此代码,因此您不必担心使用正则表达式来解析自由格式的手写代码.因此,您可以匹配编译器始终使用的固定格式,以确保仅在正确的行上进行操作.
You're only using this on compiler-generated code, so you don't have to worry about using regexes to parse free-form hand-written code. Thus you can match fixed formatting that the compiler always uses to make sure you operate only on the correct lines.
# tested and works on the .ll in your question
sed -i '/^; Function Attrs:\|^attributes #/ s/optnone //' *.ll
在以attributes #
(重要的)或以; Function Attrs:
(注释)开头的行上,用空字符串替换optnone
的第一个匹配项(带有尾随空格).
Replaces the first occurence of optnone
(with a trailing space) with the empty string, on lines that start with attributes #
(the one that matters) or with ; Function Attrs:
(the comment).
这是由/foo\|bar/
地址正则表达式控制的s///
命令,用于选择要在其上操作的行.
It's an s///
command controlled by a /foo\|bar/
address regex to select which lines it operates on.
sed -i
就地重写输入文件.
这篇关于为什么Clang自动向我的函数添加属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!