Leslie Zhai via llvm-dev
2017-Oct-25 04:22 UTC
[llvm-dev] LLVM v6.0 Internalize and GlobalDCE PASS can not work together?
Hi LLVM developers,
$ cat hello.c
#include <stdio.h>
void foo() {
}
int main(int argc, char *argv[]) {
for (int i = 0; i < 10; i++) {
printf("%d\n", i);
}
return 0;
}
$ /opt/llvm-svn/bin/clang --version
Fedora clang version 6.0.0 (trunk 316308) (based on LLVM 6.0.0svn)
Target: x86_64-redhat-linux
Thread model: posix
InstalledDir: /opt/llvm-svn/bin
$ /opt/llvm-svn/bin/clang -Xclang -disable-O0-optnone -S -emit-llvm
hello.c -o hello2.ll
$ cat hello2.ll
; ModuleID = 'hello.c'
source_filename = "hello.c"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
@.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
; Function Attrs: noinline nounwind uwtable
define void @foo() #0 {
entry:
ret void
}
; Function Attrs: noinline nounwind uwtable
define i32 @main(i32 %argc, i8** %argv) #0 {
entry:
%retval = alloca i32, align 4
%argc.addr = alloca i32, align 4
%argv.addr = alloca i8**, align 8
%i = alloca i32, align 4
store i32 0, i32* %retval, align 4
store i32 %argc, i32* %argc.addr, align 4
store i8** %argv, i8*** %argv.addr, align 8
store i32 0, i32* %i, align 4
br label %for.cond
for.cond: ; preds = %for.inc, %entry
%0 = load i32, i32* %i, align 4
%cmp = icmp slt i32 %0, 10
br i1 %cmp, label %for.body, label %for.end
for.body: ; preds = %for.cond
%1 = load i32, i32* %i, align 4
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x
i8], [4 x i8]* @.str, i32 0, i32 0), i32 %1)
br label %for.inc
for.inc: ; preds = %for.body
%2 = load i32, i32* %i, align 4
%inc = add nsw i32 %2, 1
store i32 %inc, i32* %i, align 4
br label %for.cond
for.end: ; preds = %for.cond
ret i32 0
}
declare i32 @printf(i8*, ...) #1
attributes #0 = { noinline nounwind 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" }
attributes #1 = {
"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-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 6.0.0 (git at github.com:llvm-mirror/clang.git
0aed123216ad4a38a9c2b16f1783895fd5cb1a04)
(git at github.com:llvm-mirror/llvm.git
d209b37aec1e392dabbf9b5324ea4a60c36fbc55)"}
$ /opt/llvm-svn/bin/opt -S -internalize -globaldce hello2.ll -o
hello2.dce.ll
$ cat hello2.dce.ll
; ModuleID = 'hello2.ll'
source_filename = "hello.c"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
!llvm.module.flags = !{!0}
!llvm.ident = !{!1}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{!"clang version 6.0.0 (git at github.com:llvm-mirror/clang.git
0aed123216ad4a38a9c2b16f1783895fd5cb1a04)
(git at github.com:llvm-mirror/llvm.git
d209b37aec1e392dabbf9b5324ea4a60c36fbc55)"}
$ /opt/llvm-svn/bin/lli hello2.dce.ll
'main' function not found in module.
*No* more Alive Functions, so LLVM v6.0 Internalize and GlobalDCE PASS
failed to MarkLive Function together?
But LLVM 3.1 is able to work together:
$ ./build/Release+Asserts/bin/opt --version
LLVM (http://llvm.org/):
LLVM version 3.1
Optimized build with assertions.
Built Oct 23 2017 (16:22:51).
Default target: x86_64-unknown-linux-gnu
Host CPU: corei7-avx
$ ./build/Release+Asserts/bin/clang -S -emit-llvm hello.c -o hello0.ll
$ cat hello0.ll
; ModuleID = 'hello.c'
target datalayout =
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
@.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
define void @foo() nounwind uwtable {
entry:
ret void
}
define i32 @main(i32 %argc, i8** %argv) nounwind uwtable {
entry:
%retval = alloca i32, align 4
%argc.addr = alloca i32, align 4
%argv.addr = alloca i8**, align 8
%i = alloca i32, align 4
store i32 0, i32* %retval
store i32 %argc, i32* %argc.addr, align 4
store i8** %argv, i8*** %argv.addr, align 8
store i32 0, i32* %i, align 4
br label %for.cond
for.cond: ; preds = %for.inc, %entry
%0 = load i32* %i, align 4
%cmp = icmp slt i32 %0, 10
br i1 %cmp, label %for.body, label %for.end
for.body: ; preds = %for.cond
%1 = load i32* %i, align 4
%call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x
i8]* @.str, i32 0, i32 0), i32 %1)
br label %for.inc
for.inc: ; preds = %for.body
%2 = load i32* %i, align 4
%inc = add nsw i32 %2, 1
store i32 %inc, i32* %i, align 4
br label %for.cond
for.end: ; preds = %for.cond
ret i32 0
}
declare i32 @printf(i8*, ...)
$ ./build/Release+Asserts/bin/opt -S -internalize -globaldce hello0.ll
-o hello0.dce.ll
$ cat hello0.dce.ll
; ModuleID = 'hello0.ll'
target datalayout =
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
@.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
define i32 @main(i32 %argc, i8** %argv) nounwind uwtable {
entry:
%retval = alloca i32, align 4
%argc.addr = alloca i32, align 4
%argv.addr = alloca i8**, align 8
%i = alloca i32, align 4
store i32 0, i32* %retval
store i32 %argc, i32* %argc.addr, align 4
store i8** %argv, i8*** %argv.addr, align 8
store i32 0, i32* %i, align 4
br label %for.cond
for.cond: ; preds = %for.inc, %entry
%0 = load i32* %i, align 4
%cmp = icmp slt i32 %0, 10
br i1 %cmp, label %for.body, label %for.end
for.body: ; preds = %for.cond
%1 = load i32* %i, align 4
%call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x
i8]* @.str, i32 0, i32 0), i32 %1)
br label %for.inc
for.inc: ; preds = %for.body
%2 = load i32* %i, align 4
%inc = add nsw i32 %2, 1
store i32 %inc, i32* %i, align 4
br label %for.cond
for.end: ; preds = %for.cond
ret i32 0
}
declare i32 @printf(i8*, ...)
Succeeded drop DeadFunction foo.
Maybe I wrongly use the Internalize and GlobalDCE PASS together? please
give me some hints, thanks a lot!
PS: LLVM 6.0 Internalize PASS is able to work, internal foo:
$ /opt/llvm-svn/bin/opt -S -internalize hello2.ll -o hello2.internal.ll
$ cat hello2.internal.ll
; ModuleID = 'hello2.ll'
source_filename = "hello.c"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
@.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
; Function Attrs: noinline nounwind uwtable
define internal void @foo() #0 {
entry:
ret void
}
; Function Attrs: noinline nounwind uwtable
define internal i32 @main(i32 %argc, i8** %argv) #0 {
entry:
%retval = alloca i32, align 4
%argc.addr = alloca i32, align 4
%argv.addr = alloca i8**, align 8
%i = alloca i32, align 4
store i32 0, i32* %retval, align 4
store i32 %argc, i32* %argc.addr, align 4
store i8** %argv, i8*** %argv.addr, align 8
store i32 0, i32* %i, align 4
br label %for.cond
for.cond: ; preds = %for.inc, %entry
%0 = load i32, i32* %i, align 4
%cmp = icmp slt i32 %0, 10
br i1 %cmp, label %for.body, label %for.end
for.body: ; preds = %for.cond
%1 = load i32, i32* %i, align 4
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x
i8], [4 x i8]* @.str, i32 0, i32 0), i32 %1)
br label %for.inc
for.inc: ; preds = %for.body
%2 = load i32, i32* %i, align 4
%inc = add nsw i32 %2, 1
store i32 %inc, i32* %i, align 4
br label %for.cond
for.end: ; preds = %for.cond
ret i32 0
}
declare i32 @printf(i8*, ...) #1
attributes #0 = { noinline nounwind 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" }
attributes #1 = {
"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-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 6.0.0 (git at github.com:llvm-mirror/clang.git
0aed123216ad4a38a9c2b16f1783895fd5cb1a04)
(git at github.com:llvm-mirror/llvm.git
d209b37aec1e392dabbf9b5324ea4a60c36fbc55)"}
--
Regards,
Leslie Zhai - https://reviews.llvm.org/p/xiangzhai/
Leslie Zhai via llvm-dev
2017-Oct-25 07:42 UTC
[llvm-dev] LLVM v6.0 Internalize and GlobalDCE PASS can not work together?
Workaround patch not the root cause:
diff --git a/lib/Transforms/IPO/Internalize.cpp
b/lib/Transforms/IPO/Internalize.cpp
index 26db146..a12a8d5 100644
--- a/lib/Transforms/IPO/Internalize.cpp
+++ b/lib/Transforms/IPO/Internalize.cpp
@@ -115,6 +115,9 @@ bool InternalizePass::shouldPreserveGV(const
GlobalValue &GV) {
bool InternalizePass::maybeInternalize(
GlobalValue &GV, const std::set<const Comdat *>
&ExternalComdats) {
+ if (GV.getName() == "main")
+ return false;
+
if (Comdat *C = GV.getComdat()) {
if (ExternalComdats.count(C))
return false;
在 2017年10月25日 12:22, Leslie Zhai 写道:> Hi LLVM developers,
>
> $ cat hello.c
> #include <stdio.h>
>
> void foo() {
> }
>
> int main(int argc, char *argv[]) {
> for (int i = 0; i < 10; i++) {
> printf("%d\n", i);
> }
> return 0;
> }
>
> $ /opt/llvm-svn/bin/clang --version
> Fedora clang version 6.0.0 (trunk 316308) (based on LLVM 6.0.0svn)
> Target: x86_64-redhat-linux
> Thread model: posix
> InstalledDir: /opt/llvm-svn/bin
>
> $ /opt/llvm-svn/bin/clang -Xclang -disable-O0-optnone -S -emit-llvm
> hello.c -o hello2.ll
>
> $ cat hello2.ll
> ; ModuleID = 'hello.c'
> source_filename = "hello.c"
> target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
> target triple = "x86_64-unknown-linux-gnu"
>
> @.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align
1
>
> ; Function Attrs: noinline nounwind uwtable
> define void @foo() #0 {
> entry:
> ret void
> }
>
> ; Function Attrs: noinline nounwind uwtable
> define i32 @main(i32 %argc, i8** %argv) #0 {
> entry:
> %retval = alloca i32, align 4
> %argc.addr = alloca i32, align 4
> %argv.addr = alloca i8**, align 8
> %i = alloca i32, align 4
> store i32 0, i32* %retval, align 4
> store i32 %argc, i32* %argc.addr, align 4
> store i8** %argv, i8*** %argv.addr, align 8
> store i32 0, i32* %i, align 4
> br label %for.cond
>
> for.cond: ; preds = %for.inc,
> %entry
> %0 = load i32, i32* %i, align 4
> %cmp = icmp slt i32 %0, 10
> br i1 %cmp, label %for.body, label %for.end
>
> for.body: ; preds = %for.cond
> %1 = load i32, i32* %i, align 4
> %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x
> i8], [4 x i8]* @.str, i32 0, i32 0), i32 %1)
> br label %for.inc
>
> for.inc: ; preds = %for.body
> %2 = load i32, i32* %i, align 4
> %inc = add nsw i32 %2, 1
> store i32 %inc, i32* %i, align 4
> br label %for.cond
>
> for.end: ; preds = %for.cond
> ret i32 0
> }
>
> declare i32 @printf(i8*, ...) #1
>
> attributes #0 = { noinline nounwind 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" }
> attributes #1 = {
"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-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 6.0.0 (git at github.com:llvm-mirror/clang.git
> 0aed123216ad4a38a9c2b16f1783895fd5cb1a04)
> (git at github.com:llvm-mirror/llvm.git
> d209b37aec1e392dabbf9b5324ea4a60c36fbc55)"}
>
> $ /opt/llvm-svn/bin/opt -S -internalize -globaldce hello2.ll -o
> hello2.dce.ll
>
> $ cat hello2.dce.ll
> ; ModuleID = 'hello2.ll'
> source_filename = "hello.c"
> target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
> target triple = "x86_64-unknown-linux-gnu"
>
> !llvm.module.flags = !{!0}
> !llvm.ident = !{!1}
>
> !0 = !{i32 1, !"wchar_size", i32 4}
> !1 = !{!"clang version 6.0.0 (git at github.com:llvm-mirror/clang.git
> 0aed123216ad4a38a9c2b16f1783895fd5cb1a04)
> (git at github.com:llvm-mirror/llvm.git
> d209b37aec1e392dabbf9b5324ea4a60c36fbc55)"}
>
> $ /opt/llvm-svn/bin/lli hello2.dce.ll
> 'main' function not found in module.
>
>
> *No* more Alive Functions, so LLVM v6.0 Internalize and GlobalDCE PASS
> failed to MarkLive Function together?
>
>
> But LLVM 3.1 is able to work together:
>
> $ ./build/Release+Asserts/bin/opt --version
> LLVM (http://llvm.org/):
> LLVM version 3.1
> Optimized build with assertions.
> Built Oct 23 2017 (16:22:51).
> Default target: x86_64-unknown-linux-gnu
> Host CPU: corei7-avx
>
> $ ./build/Release+Asserts/bin/clang -S -emit-llvm hello.c -o hello0.ll
>
> $ cat hello0.ll
> ; ModuleID = 'hello.c'
> target datalayout =
>
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
> target triple = "x86_64-unknown-linux-gnu"
>
> @.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align
1
>
> define void @foo() nounwind uwtable {
> entry:
> ret void
> }
>
> define i32 @main(i32 %argc, i8** %argv) nounwind uwtable {
> entry:
> %retval = alloca i32, align 4
> %argc.addr = alloca i32, align 4
> %argv.addr = alloca i8**, align 8
> %i = alloca i32, align 4
> store i32 0, i32* %retval
> store i32 %argc, i32* %argc.addr, align 4
> store i8** %argv, i8*** %argv.addr, align 8
> store i32 0, i32* %i, align 4
> br label %for.cond
>
> for.cond: ; preds = %for.inc,
> %entry
> %0 = load i32* %i, align 4
> %cmp = icmp slt i32 %0, 10
> br i1 %cmp, label %for.body, label %for.end
>
> for.body: ; preds = %for.cond
> %1 = load i32* %i, align 4
> %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4
> x i8]* @.str, i32 0, i32 0), i32 %1)
> br label %for.inc
>
> for.inc: ; preds = %for.body
> %2 = load i32* %i, align 4
> %inc = add nsw i32 %2, 1
> store i32 %inc, i32* %i, align 4
> br label %for.cond
>
> for.end: ; preds = %for.cond
> ret i32 0
> }
>
> declare i32 @printf(i8*, ...)
>
> $ ./build/Release+Asserts/bin/opt -S -internalize -globaldce hello0.ll
> -o hello0.dce.ll
>
> $ cat hello0.dce.ll
> ; ModuleID = 'hello0.ll'
> target datalayout =
>
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
> target triple = "x86_64-unknown-linux-gnu"
>
> @.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align
1
>
> define i32 @main(i32 %argc, i8** %argv) nounwind uwtable {
> entry:
> %retval = alloca i32, align 4
> %argc.addr = alloca i32, align 4
> %argv.addr = alloca i8**, align 8
> %i = alloca i32, align 4
> store i32 0, i32* %retval
> store i32 %argc, i32* %argc.addr, align 4
> store i8** %argv, i8*** %argv.addr, align 8
> store i32 0, i32* %i, align 4
> br label %for.cond
>
> for.cond: ; preds = %for.inc,
> %entry
> %0 = load i32* %i, align 4
> %cmp = icmp slt i32 %0, 10
> br i1 %cmp, label %for.body, label %for.end
>
> for.body: ; preds = %for.cond
> %1 = load i32* %i, align 4
> %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4
> x i8]* @.str, i32 0, i32 0), i32 %1)
> br label %for.inc
>
> for.inc: ; preds = %for.body
> %2 = load i32* %i, align 4
> %inc = add nsw i32 %2, 1
> store i32 %inc, i32* %i, align 4
> br label %for.cond
>
> for.end: ; preds = %for.cond
> ret i32 0
> }
>
> declare i32 @printf(i8*, ...)
>
>
> Succeeded drop DeadFunction foo.
>
> Maybe I wrongly use the Internalize and GlobalDCE PASS together?
> please give me some hints, thanks a lot!
>
>
> PS: LLVM 6.0 Internalize PASS is able to work, internal foo:
>
> $ /opt/llvm-svn/bin/opt -S -internalize hello2.ll -o hello2.internal.ll
>
> $ cat hello2.internal.ll
> ; ModuleID = 'hello2.ll'
> source_filename = "hello.c"
> target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
> target triple = "x86_64-unknown-linux-gnu"
>
> @.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align
1
>
> ; Function Attrs: noinline nounwind uwtable
> define internal void @foo() #0 {
> entry:
> ret void
> }
>
> ; Function Attrs: noinline nounwind uwtable
> define internal i32 @main(i32 %argc, i8** %argv) #0 {
Let `main` Function *NOT* maybeInternalize, then
$ ./build/bin/opt -S -globaldce hello2.internal.ll -o hello2.dce.ll
$ cat hello2.dce.ll
; ModuleID = 'hello2.ll'
source_filename = "hello.c"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
@.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
; Function Attrs: noinline nounwind uwtable
define i32 @main(i32 %argc, i8** %argv) #0 {
entry:
%retval = alloca i32, align 4
%argc.addr = alloca i32, align 4
%argv.addr = alloca i8**, align 8
%i = alloca i32, align 4
store i32 0, i32* %retval, align 4
store i32 %argc, i32* %argc.addr, align 4
store i8** %argv, i8*** %argv.addr, align 8
store i32 0, i32* %i, align 4
br label %for.cond
for.cond: ; preds = %for.inc, %entry
%0 = load i32, i32* %i, align 4
%cmp = icmp slt i32 %0, 10
br i1 %cmp, label %for.body, label %for.end
for.body: ; preds = %for.cond
%1 = load i32, i32* %i, align 4
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x
i8], [4 x i8]* @.str, i32 0, i32 0), i32 %1)
br label %for.inc
for.inc: ; preds = %for.body
%2 = load i32, i32* %i, align 4
%inc = add nsw i32 %2, 1
store i32 %inc, i32* %i, align 4
br label %for.cond
for.end: ; preds = %for.cond
ret i32 0
}
declare i32 @printf(i8*, ...) #1
attributes #0 = { noinline nounwind 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" }
attributes #1 = {
"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-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 6.0.0 (git at github.com:llvm-mirror/clang.git
0aed123216ad4a38a9c2b16f1783895fd5cb1a04)
(git at github.com:llvm-mirror/llvm.git
d209b37aec1e392dabbf9b5324ea4a60c36fbc55)"}
$ ./build/bin/lli hello2.dce.ll
0
1
2
3
4
5
6
7
8
9
> entry:
> %retval = alloca i32, align 4
> %argc.addr = alloca i32, align 4
> %argv.addr = alloca i8**, align 8
> %i = alloca i32, align 4
> store i32 0, i32* %retval, align 4
> store i32 %argc, i32* %argc.addr, align 4
> store i8** %argv, i8*** %argv.addr, align 8
> store i32 0, i32* %i, align 4
> br label %for.cond
>
> for.cond: ; preds = %for.inc,
> %entry
> %0 = load i32, i32* %i, align 4
> %cmp = icmp slt i32 %0, 10
> br i1 %cmp, label %for.body, label %for.end
>
> for.body: ; preds = %for.cond
> %1 = load i32, i32* %i, align 4
> %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x
> i8], [4 x i8]* @.str, i32 0, i32 0), i32 %1)
> br label %for.inc
>
> for.inc: ; preds = %for.body
> %2 = load i32, i32* %i, align 4
> %inc = add nsw i32 %2, 1
> store i32 %inc, i32* %i, align 4
> br label %for.cond
>
> for.end: ; preds = %for.cond
> ret i32 0
> }
>
> declare i32 @printf(i8*, ...) #1
>
> attributes #0 = { noinline nounwind 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" }
> attributes #1 = {
"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-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 6.0.0 (git at github.com:llvm-mirror/clang.git
> 0aed123216ad4a38a9c2b16f1783895fd5cb1a04)
> (git at github.com:llvm-mirror/llvm.git
> d209b37aec1e392dabbf9b5324ea4a60c36fbc55)"}
>
--
Regards,
Leslie Zhai - https://reviews.llvm.org/p/xiangzhai/
Hal Finkel via llvm-dev
2017-Oct-25 13:20 UTC
[llvm-dev] LLVM v6.0 Internalize and GlobalDCE PASS can not work together?
Hi, Leslie, When you use internalize, you need to provide it with a list of symbols to preserve as external (otherwise everything will be internalized, including main, and then DCE will remove everything). You can use -internalize-public-api-list=main (a comma-separated list) or -internalize-public-api-file=some_file_name where some_file_name has the list of symbols. See the comments in lib/Transforms/IPO/Internalize.cpp. -Hal On 10/24/2017 11:22 PM, Leslie Zhai via llvm-dev wrote:> Hi LLVM developers, > > $ cat hello.c > #include <stdio.h> > > void foo() { > } > > int main(int argc, char *argv[]) { > for (int i = 0; i < 10; i++) { > printf("%d\n", i); > } > return 0; > } > > $ /opt/llvm-svn/bin/clang --version > Fedora clang version 6.0.0 (trunk 316308) (based on LLVM 6.0.0svn) > Target: x86_64-redhat-linux > Thread model: posix > InstalledDir: /opt/llvm-svn/bin > > $ /opt/llvm-svn/bin/clang -Xclang -disable-O0-optnone -S -emit-llvm > hello.c -o hello2.ll > > $ cat hello2.ll > ; ModuleID = 'hello.c' > source_filename = "hello.c" > target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" > target triple = "x86_64-unknown-linux-gnu" > > @.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 > > ; Function Attrs: noinline nounwind uwtable > define void @foo() #0 { > entry: > ret void > } > > ; Function Attrs: noinline nounwind uwtable > define i32 @main(i32 %argc, i8** %argv) #0 { > entry: > %retval = alloca i32, align 4 > %argc.addr = alloca i32, align 4 > %argv.addr = alloca i8**, align 8 > %i = alloca i32, align 4 > store i32 0, i32* %retval, align 4 > store i32 %argc, i32* %argc.addr, align 4 > store i8** %argv, i8*** %argv.addr, align 8 > store i32 0, i32* %i, align 4 > br label %for.cond > > for.cond: ; preds = %for.inc, > %entry > %0 = load i32, i32* %i, align 4 > %cmp = icmp slt i32 %0, 10 > br i1 %cmp, label %for.body, label %for.end > > for.body: ; preds = %for.cond > %1 = load i32, i32* %i, align 4 > %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x > i8], [4 x i8]* @.str, i32 0, i32 0), i32 %1) > br label %for.inc > > for.inc: ; preds = %for.body > %2 = load i32, i32* %i, align 4 > %inc = add nsw i32 %2, 1 > store i32 %inc, i32* %i, align 4 > br label %for.cond > > for.end: ; preds = %for.cond > ret i32 0 > } > > declare i32 @printf(i8*, ...) #1 > > attributes #0 = { noinline nounwind 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" } > attributes #1 = { "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-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 6.0.0 (git at github.com:llvm-mirror/clang.git > 0aed123216ad4a38a9c2b16f1783895fd5cb1a04) > (git at github.com:llvm-mirror/llvm.git > d209b37aec1e392dabbf9b5324ea4a60c36fbc55)"} > > $ /opt/llvm-svn/bin/opt -S -internalize -globaldce hello2.ll -o > hello2.dce.ll > > $ cat hello2.dce.ll > ; ModuleID = 'hello2.ll' > source_filename = "hello.c" > target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" > target triple = "x86_64-unknown-linux-gnu" > > !llvm.module.flags = !{!0} > !llvm.ident = !{!1} > > !0 = !{i32 1, !"wchar_size", i32 4} > !1 = !{!"clang version 6.0.0 (git at github.com:llvm-mirror/clang.git > 0aed123216ad4a38a9c2b16f1783895fd5cb1a04) > (git at github.com:llvm-mirror/llvm.git > d209b37aec1e392dabbf9b5324ea4a60c36fbc55)"} > > $ /opt/llvm-svn/bin/lli hello2.dce.ll > 'main' function not found in module. > > > *No* more Alive Functions, so LLVM v6.0 Internalize and GlobalDCE PASS > failed to MarkLive Function together? > > > But LLVM 3.1 is able to work together: > > $ ./build/Release+Asserts/bin/opt --version > LLVM (http://llvm.org/): > LLVM version 3.1 > Optimized build with assertions. > Built Oct 23 2017 (16:22:51). > Default target: x86_64-unknown-linux-gnu > Host CPU: corei7-avx > > $ ./build/Release+Asserts/bin/clang -S -emit-llvm hello.c -o hello0.ll > > $ cat hello0.ll > ; ModuleID = 'hello.c' > target datalayout = > "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" > target triple = "x86_64-unknown-linux-gnu" > > @.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 > > define void @foo() nounwind uwtable { > entry: > ret void > } > > define i32 @main(i32 %argc, i8** %argv) nounwind uwtable { > entry: > %retval = alloca i32, align 4 > %argc.addr = alloca i32, align 4 > %argv.addr = alloca i8**, align 8 > %i = alloca i32, align 4 > store i32 0, i32* %retval > store i32 %argc, i32* %argc.addr, align 4 > store i8** %argv, i8*** %argv.addr, align 8 > store i32 0, i32* %i, align 4 > br label %for.cond > > for.cond: ; preds = %for.inc, > %entry > %0 = load i32* %i, align 4 > %cmp = icmp slt i32 %0, 10 > br i1 %cmp, label %for.body, label %for.end > > for.body: ; preds = %for.cond > %1 = load i32* %i, align 4 > %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 > x i8]* @.str, i32 0, i32 0), i32 %1) > br label %for.inc > > for.inc: ; preds = %for.body > %2 = load i32* %i, align 4 > %inc = add nsw i32 %2, 1 > store i32 %inc, i32* %i, align 4 > br label %for.cond > > for.end: ; preds = %for.cond > ret i32 0 > } > > declare i32 @printf(i8*, ...) > > $ ./build/Release+Asserts/bin/opt -S -internalize -globaldce hello0.ll > -o hello0.dce.ll > > $ cat hello0.dce.ll > ; ModuleID = 'hello0.ll' > target datalayout = > "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" > target triple = "x86_64-unknown-linux-gnu" > > @.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 > > define i32 @main(i32 %argc, i8** %argv) nounwind uwtable { > entry: > %retval = alloca i32, align 4 > %argc.addr = alloca i32, align 4 > %argv.addr = alloca i8**, align 8 > %i = alloca i32, align 4 > store i32 0, i32* %retval > store i32 %argc, i32* %argc.addr, align 4 > store i8** %argv, i8*** %argv.addr, align 8 > store i32 0, i32* %i, align 4 > br label %for.cond > > for.cond: ; preds = %for.inc, > %entry > %0 = load i32* %i, align 4 > %cmp = icmp slt i32 %0, 10 > br i1 %cmp, label %for.body, label %for.end > > for.body: ; preds = %for.cond > %1 = load i32* %i, align 4 > %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 > x i8]* @.str, i32 0, i32 0), i32 %1) > br label %for.inc > > for.inc: ; preds = %for.body > %2 = load i32* %i, align 4 > %inc = add nsw i32 %2, 1 > store i32 %inc, i32* %i, align 4 > br label %for.cond > > for.end: ; preds = %for.cond > ret i32 0 > } > > declare i32 @printf(i8*, ...) > > > Succeeded drop DeadFunction foo. > > Maybe I wrongly use the Internalize and GlobalDCE PASS together? > please give me some hints, thanks a lot! > > > PS: LLVM 6.0 Internalize PASS is able to work, internal foo: > > $ /opt/llvm-svn/bin/opt -S -internalize hello2.ll -o hello2.internal.ll > > $ cat hello2.internal.ll > ; ModuleID = 'hello2.ll' > source_filename = "hello.c" > target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" > target triple = "x86_64-unknown-linux-gnu" > > @.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 > > ; Function Attrs: noinline nounwind uwtable > define internal void @foo() #0 { > entry: > ret void > } > > ; Function Attrs: noinline nounwind uwtable > define internal i32 @main(i32 %argc, i8** %argv) #0 { > entry: > %retval = alloca i32, align 4 > %argc.addr = alloca i32, align 4 > %argv.addr = alloca i8**, align 8 > %i = alloca i32, align 4 > store i32 0, i32* %retval, align 4 > store i32 %argc, i32* %argc.addr, align 4 > store i8** %argv, i8*** %argv.addr, align 8 > store i32 0, i32* %i, align 4 > br label %for.cond > > for.cond: ; preds = %for.inc, > %entry > %0 = load i32, i32* %i, align 4 > %cmp = icmp slt i32 %0, 10 > br i1 %cmp, label %for.body, label %for.end > > for.body: ; preds = %for.cond > %1 = load i32, i32* %i, align 4 > %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x > i8], [4 x i8]* @.str, i32 0, i32 0), i32 %1) > br label %for.inc > > for.inc: ; preds = %for.body > %2 = load i32, i32* %i, align 4 > %inc = add nsw i32 %2, 1 > store i32 %inc, i32* %i, align 4 > br label %for.cond > > for.end: ; preds = %for.cond > ret i32 0 > } > > declare i32 @printf(i8*, ...) #1 > > attributes #0 = { noinline nounwind 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" } > attributes #1 = { "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-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 6.0.0 (git at github.com:llvm-mirror/clang.git > 0aed123216ad4a38a9c2b16f1783895fd5cb1a04) > (git at github.com:llvm-mirror/llvm.git > d209b37aec1e392dabbf9b5324ea4a60c36fbc55)"} >-- Hal Finkel Lead, Compiler Technology and Programming Languages Leadership Computing Facility Argonne National Laboratory
Leslie Zhai via llvm-dev
2017-Oct-26 02:07 UTC
[llvm-dev] LLVM v6.0 Internalize and GlobalDCE PASS can not work together?
Hi Hal,
Thanks for your hint!
$ /opt/llvm-svn/bin/opt -S -internalize
-internalize-public-api-list=main -globaldce hello3.ll -o
hello3.dce.ll it works :)
But I argue that `main` Function should be inserted into ExternalNames
by default:
Index: lib/Transforms/IPO/Internalize.cpp
==================================================================---
lib/Transforms/IPO/Internalize.cpp (revision 316540)
+++ lib/Transforms/IPO/Internalize.cpp (working copy)
@@ -61,6 +61,7 @@
if (!APIFile.empty())
LoadFile(APIFile);
ExternalNames.insert(APIList.begin(), APIList.end());
+ ExternalNames.insert("main");
}
bool operator()(const GlobalValue &GV) {
在 2017年10月25日 21:20, Hal Finkel 写道:> Hi, Leslie,
>
> When you use internalize, you need to provide it with a list of
> symbols to preserve as external (otherwise everything will be
> internalized, including main, and then DCE will remove everything).
> You can use -internalize-public-api-list=main (a comma-separated list)
> or -internalize-public-api-file=some_file_name where some_file_name
> has the list of symbols. See the comments in
> lib/Transforms/IPO/Internalize.cpp.
>
> -Hal
>
> On 10/24/2017 11:22 PM, Leslie Zhai via llvm-dev wrote:
>> Hi LLVM developers,
>>
>> $ cat hello.c
>> #include <stdio.h>
>>
>> void foo() {
>> }
>>
>> int main(int argc, char *argv[]) {
>> for (int i = 0; i < 10; i++) {
>> printf("%d\n", i);
>> }
>> return 0;
>> }
>>
>> $ /opt/llvm-svn/bin/clang --version
>> Fedora clang version 6.0.0 (trunk 316308) (based on LLVM 6.0.0svn)
>> Target: x86_64-redhat-linux
>> Thread model: posix
>> InstalledDir: /opt/llvm-svn/bin
>>
>> $ /opt/llvm-svn/bin/clang -Xclang -disable-O0-optnone -S -emit-llvm
>> hello.c -o hello2.ll
>>
>> $ cat hello2.ll
>> ; ModuleID = 'hello.c'
>> source_filename = "hello.c"
>> target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
>> target triple = "x86_64-unknown-linux-gnu"
>>
>> @.str = private unnamed_addr constant [4 x i8] c"%d\0A\00",
align 1
>>
>> ; Function Attrs: noinline nounwind uwtable
>> define void @foo() #0 {
>> entry:
>> ret void
>> }
>>
>> ; Function Attrs: noinline nounwind uwtable
>> define i32 @main(i32 %argc, i8** %argv) #0 {
>> entry:
>> %retval = alloca i32, align 4
>> %argc.addr = alloca i32, align 4
>> %argv.addr = alloca i8**, align 8
>> %i = alloca i32, align 4
>> store i32 0, i32* %retval, align 4
>> store i32 %argc, i32* %argc.addr, align 4
>> store i8** %argv, i8*** %argv.addr, align 8
>> store i32 0, i32* %i, align 4
>> br label %for.cond
>>
>> for.cond: ; preds = %for.inc,
>> %entry
>> %0 = load i32, i32* %i, align 4
>> %cmp = icmp slt i32 %0, 10
>> br i1 %cmp, label %for.body, label %for.end
>>
>> for.body: ; preds = %for.cond
>> %1 = load i32, i32* %i, align 4
>> %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4
>> x i8], [4 x i8]* @.str, i32 0, i32 0), i32 %1)
>> br label %for.inc
>>
>> for.inc: ; preds = %for.body
>> %2 = load i32, i32* %i, align 4
>> %inc = add nsw i32 %2, 1
>> store i32 %inc, i32* %i, align 4
>> br label %for.cond
>>
>> for.end: ; preds = %for.cond
>> ret i32 0
>> }
>>
>> declare i32 @printf(i8*, ...) #1
>>
>> attributes #0 = { noinline nounwind 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" }
>> attributes #1 = {
"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-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 6.0.0 (git at
github.com:llvm-mirror/clang.git
>> 0aed123216ad4a38a9c2b16f1783895fd5cb1a04)
>> (git at github.com:llvm-mirror/llvm.git
>> d209b37aec1e392dabbf9b5324ea4a60c36fbc55)"}
>>
>> $ /opt/llvm-svn/bin/opt -S -internalize -globaldce hello2.ll -o
>> hello2.dce.ll
>>
>> $ cat hello2.dce.ll
>> ; ModuleID = 'hello2.ll'
>> source_filename = "hello.c"
>> target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
>> target triple = "x86_64-unknown-linux-gnu"
>>
>> !llvm.module.flags = !{!0}
>> !llvm.ident = !{!1}
>>
>> !0 = !{i32 1, !"wchar_size", i32 4}
>> !1 = !{!"clang version 6.0.0 (git at
github.com:llvm-mirror/clang.git
>> 0aed123216ad4a38a9c2b16f1783895fd5cb1a04)
>> (git at github.com:llvm-mirror/llvm.git
>> d209b37aec1e392dabbf9b5324ea4a60c36fbc55)"}
>>
>> $ /opt/llvm-svn/bin/lli hello2.dce.ll
>> 'main' function not found in module.
>>
>>
>> *No* more Alive Functions, so LLVM v6.0 Internalize and GlobalDCE
>> PASS failed to MarkLive Function together?
>>
>>
>> But LLVM 3.1 is able to work together:
>>
>> $ ./build/Release+Asserts/bin/opt --version
>> LLVM (http://llvm.org/):
>> LLVM version 3.1
>> Optimized build with assertions.
>> Built Oct 23 2017 (16:22:51).
>> Default target: x86_64-unknown-linux-gnu
>> Host CPU: corei7-avx
>>
>> $ ./build/Release+Asserts/bin/clang -S -emit-llvm hello.c -o hello0.ll
>>
>> $ cat hello0.ll
>> ; ModuleID = 'hello.c'
>> target datalayout =
>>
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
>> target triple = "x86_64-unknown-linux-gnu"
>>
>> @.str = private unnamed_addr constant [4 x i8] c"%d\0A\00",
align 1
>>
>> define void @foo() nounwind uwtable {
>> entry:
>> ret void
>> }
>>
>> define i32 @main(i32 %argc, i8** %argv) nounwind uwtable {
>> entry:
>> %retval = alloca i32, align 4
>> %argc.addr = alloca i32, align 4
>> %argv.addr = alloca i8**, align 8
>> %i = alloca i32, align 4
>> store i32 0, i32* %retval
>> store i32 %argc, i32* %argc.addr, align 4
>> store i8** %argv, i8*** %argv.addr, align 8
>> store i32 0, i32* %i, align 4
>> br label %for.cond
>>
>> for.cond: ; preds = %for.inc,
>> %entry
>> %0 = load i32* %i, align 4
>> %cmp = icmp slt i32 %0, 10
>> br i1 %cmp, label %for.body, label %for.end
>>
>> for.body: ; preds = %for.cond
>> %1 = load i32* %i, align 4
>> %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4
>> x i8]* @.str, i32 0, i32 0), i32 %1)
>> br label %for.inc
>>
>> for.inc: ; preds = %for.body
>> %2 = load i32* %i, align 4
>> %inc = add nsw i32 %2, 1
>> store i32 %inc, i32* %i, align 4
>> br label %for.cond
>>
>> for.end: ; preds = %for.cond
>> ret i32 0
>> }
>>
>> declare i32 @printf(i8*, ...)
>>
>> $ ./build/Release+Asserts/bin/opt -S -internalize -globaldce
>> hello0.ll -o hello0.dce.ll
>>
>> $ cat hello0.dce.ll
>> ; ModuleID = 'hello0.ll'
>> target datalayout =
>>
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
>> target triple = "x86_64-unknown-linux-gnu"
>>
>> @.str = private unnamed_addr constant [4 x i8] c"%d\0A\00",
align 1
>>
>> define i32 @main(i32 %argc, i8** %argv) nounwind uwtable {
>> entry:
>> %retval = alloca i32, align 4
>> %argc.addr = alloca i32, align 4
>> %argv.addr = alloca i8**, align 8
>> %i = alloca i32, align 4
>> store i32 0, i32* %retval
>> store i32 %argc, i32* %argc.addr, align 4
>> store i8** %argv, i8*** %argv.addr, align 8
>> store i32 0, i32* %i, align 4
>> br label %for.cond
>>
>> for.cond: ; preds = %for.inc,
>> %entry
>> %0 = load i32* %i, align 4
>> %cmp = icmp slt i32 %0, 10
>> br i1 %cmp, label %for.body, label %for.end
>>
>> for.body: ; preds = %for.cond
>> %1 = load i32* %i, align 4
>> %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4
>> x i8]* @.str, i32 0, i32 0), i32 %1)
>> br label %for.inc
>>
>> for.inc: ; preds = %for.body
>> %2 = load i32* %i, align 4
>> %inc = add nsw i32 %2, 1
>> store i32 %inc, i32* %i, align 4
>> br label %for.cond
>>
>> for.end: ; preds = %for.cond
>> ret i32 0
>> }
>>
>> declare i32 @printf(i8*, ...)
>>
>>
>> Succeeded drop DeadFunction foo.
>>
>> Maybe I wrongly use the Internalize and GlobalDCE PASS together?
>> please give me some hints, thanks a lot!
>>
>>
>> PS: LLVM 6.0 Internalize PASS is able to work, internal foo:
>>
>> $ /opt/llvm-svn/bin/opt -S -internalize hello2.ll -o hello2.internal.ll
>>
>> $ cat hello2.internal.ll
>> ; ModuleID = 'hello2.ll'
>> source_filename = "hello.c"
>> target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
>> target triple = "x86_64-unknown-linux-gnu"
>>
>> @.str = private unnamed_addr constant [4 x i8] c"%d\0A\00",
align 1
>>
>> ; Function Attrs: noinline nounwind uwtable
>> define internal void @foo() #0 {
>> entry:
>> ret void
>> }
>>
>> ; Function Attrs: noinline nounwind uwtable
>> define internal i32 @main(i32 %argc, i8** %argv) #0 {
>> entry:
>> %retval = alloca i32, align 4
>> %argc.addr = alloca i32, align 4
>> %argv.addr = alloca i8**, align 8
>> %i = alloca i32, align 4
>> store i32 0, i32* %retval, align 4
>> store i32 %argc, i32* %argc.addr, align 4
>> store i8** %argv, i8*** %argv.addr, align 8
>> store i32 0, i32* %i, align 4
>> br label %for.cond
>>
>> for.cond: ; preds = %for.inc,
>> %entry
>> %0 = load i32, i32* %i, align 4
>> %cmp = icmp slt i32 %0, 10
>> br i1 %cmp, label %for.body, label %for.end
>>
>> for.body: ; preds = %for.cond
>> %1 = load i32, i32* %i, align 4
>> %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4
>> x i8], [4 x i8]* @.str, i32 0, i32 0), i32 %1)
>> br label %for.inc
>>
>> for.inc: ; preds = %for.body
>> %2 = load i32, i32* %i, align 4
>> %inc = add nsw i32 %2, 1
>> store i32 %inc, i32* %i, align 4
>> br label %for.cond
>>
>> for.end: ; preds = %for.cond
>> ret i32 0
>> }
>>
>> declare i32 @printf(i8*, ...) #1
>>
>> attributes #0 = { noinline nounwind 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" }
>> attributes #1 = {
"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-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 6.0.0 (git at
github.com:llvm-mirror/clang.git
>> 0aed123216ad4a38a9c2b16f1783895fd5cb1a04)
>> (git at github.com:llvm-mirror/llvm.git
>> d209b37aec1e392dabbf9b5324ea4a60c36fbc55)"}
>>
>
--
Regards,
Leslie Zhai - https://reviews.llvm.org/p/xiangzhai/
Possibly Parallel Threads
- LLVM v6.0 Internalize and GlobalDCE PASS can not work together?
- Is the instruction %4 = select i1 %tobool.i, metadata !12, metadata !10 legal?
- loop unrolling introduces conditional branch
- loop unrolling introduces conditional branch
- Expected constant simplification not happening