Comments (3)
One of the issues with stoat (documented at LAC) is that it does not use any data dependent information to determine if a function will be called.
For example if you have the function:
void a(void) {
if(0)
b();
}
Then stoat will (to the best of my knowledge) report that a can possibly call b as clang is called with -O0.
The above case is fairly easy to handle with a few of LLVM's optimization passes, though optimization operations make it a fair bit harder to reason about the original code. The case that you're interested in is a harder one however as you want to be able to propagate a constant through a function call. As to why this is difficult let's look at the minimum test example:
void a(void) { }
void b(int c)
{
if(c)
a();
}
void d(void) { b(1); }
void e(void) { b(0); }
Translated to LLVM IR this looks like:
; ModuleID = '<stdin>'
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"
; Function Attrs: nounwind uwtable
define void @a() #0 {
ret void
}
; Function Attrs: nounwind uwtable
define void @b(i32 %c) #0 {
%1 = alloca i32, align 4
store i32 %c, i32* %1, align 4
%2 = load i32, i32* %1, align 4
%3 = icmp ne i32 %2, 0
br i1 %3, label %4, label %5
; <label>:4 ; preds = %0
call void @a()
br label %5
; <label>:5 ; preds = %4, %0
ret void
}
; Function Attrs: nounwind uwtable
define void @d() #0 {
call void @b(i32 1)
ret void
}
; Function Attrs: nounwind uwtable
define void @e() #0 {
call void @b(i32 0)
ret void
}
attributes #0 = { nounwind uwtable "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" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
!llvm.ident = !{!0}
!0 = !{!"clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)"}
To use the data dependency within function b(), we must look at the branch above <label>:4 . From there we need to establish if %3 is true/false. Next we need to invert the logic about %2 to say that 0== no branch, then a few more steps have to trace the value back to being an argument.
Expanding this to across functions, then there needs to be a new node in the stoat graph which is a specialization of b() whenever there's a 0 argument. With that established then there likely needs to be another pass over all calls of b() to determine if they're b(special-case) or b(unknown-case). Then it's possible to say that e calls b_specialization0 rather than just b().
So the feature request is certainly doable, but a non-trivial bit of work. My current suggestion is to have separate functions for realtime and non-realtime operations, though I realize that this may not always be a possibility. In those cases a suppression would be useful.
from stoat.
hmm I see.
would it be possible to add a decorator/attribute for functions that can be called like this?
that would mean only selected functions will need to go through the special argument verification
from stoat.
An attribute doesn't save that much time/effort IMO. Most of the work is in the complexity of implementing the feature, not the time spent executing the feature after it's implemented.
from stoat.
Related Issues (20)
- Stoat fails to track virtual methods in multiple interitance cases involving templates HOT 2
- Graphviz generation error with 2.38.0 HOT 2
- More vtable Chasing HOT 1
- Demangled names can exceed YAML's 1024 character key limit HOT 6
- quick README glitch HOT 1
- Ingen Build Results In Unparsed Vtable Entries
- Add Line Numbers HOT 1
- Produce Errors in GCC Style To Make It More Parseable
- Add define when using stoat-compile
- Crash on Clang 4.0.0 (arch) HOT 2
- Error in suppressions mechanism HOT 2
- Functions with same name in multiple compilation targets do not increase counters HOT 3
- Error when trying to install on gentoo because of ldconfig invocation HOT 3
- build fails on macOS Sierra and homebrew LLVM HOT 6
- find_program needs to handle newer llvm versions
- RT-Safe classes based on non-rt safe ones ignore higher-level implementation HOT 2
- Ruby error in create_alias_map HOT 2
- Add type checks when loading the YAML from the LLVM pass
- LLVM Pass may be broken under LLVM 5.0.1 HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from stoat.