[llvm-dev] LLVM v6.0 Internalize and GlobalDCE PASS can not work together? (original) (raw)

Hal Finkel via llvm-dev llvm-dev at lists.llvm.org
Wed Oct 25 19:20:15 PDT 2017


On 10/25/2017 09:07 PM, Leslie Zhai wrote:

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:

But "main" is neither necessary nor sufficient depending on the target/configuration. Internalize is really intended to be used by a linker plugin (or in some other context where a callback can be provided that has the right information). Using the pass as you're doing is really a development aid - it's not a user-facing tool by itself.

-Hal

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=somefilename where somefilename 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: x8664-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' > sourcefilename = "hello.c" > target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" > target triple = "x8664-unknown-linux-gnu" >>>> @.str = private unnamedaddr 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, !"wcharsize", 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' > sourcefilename = "hello.c" > target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" > target triple = "x8664-unknown-linux-gnu" >>>> !llvm.module.flags = !{!0} > !llvm.ident = !{!1} >>>> !0 = !{i32 1, !"wcharsize", 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: x8664-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 = "x8664-unknown-linux-gnu" >>>> @.str = private unnamedaddr 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 = "x8664-unknown-linux-gnu" >>>> @.str = private unnamedaddr 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' > sourcefilename = "hello.c" > target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" > target triple = "x8664-unknown-linux-gnu" >>>> @.str = private unnamedaddr 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, !"wcharsize", 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



More information about the llvm-dev mailing list