Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Print all paths if no argument is given to twiggy paths #63

Merged
merged 1 commit into from
May 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 47 additions & 15 deletions analyze/analyze.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,11 @@ impl traits::Emit for Paths {
label.push_str(" ");
}
if depth > 0 {
label.push_str(" ⬑ ");
if opts.descending() {
label.push_str(" ↳ ");
} else {
label.push_str(" ⬑ ");
}
}
label.push_str(item.name());

Expand All @@ -432,12 +436,21 @@ impl traits::Emit for Paths {
]);

seen.insert(id);
for (i, caller) in items.predecessors(id).enumerate() {
if i > 0 {

if opts.descending() {
for callee in items.neighbors(id) {
*paths += 1;
recursive_callers(items, seen, table, depth + 1, &mut paths, &opts, callee);
}
} else {
for (i, caller) in items.predecessors(id).enumerate() {
if i > 0 {
*paths += 1;
}
recursive_callers(items, seen, table, depth + 1, &mut paths, &opts, caller);
}
recursive_callers(items, seen, table, depth + 1, &mut paths, &opts, caller);
}

seen.remove(&id);
}

Expand Down Expand Up @@ -518,20 +531,39 @@ impl traits::Emit for Paths {

/// Find all retaining paths for the given items.
pub fn paths(items: &mut ir::Items, opts: &opt::Paths) -> Result<Box<traits::Emit>, traits::Error> {
items.compute_predecessors();
if !opts.descending() {
items.compute_predecessors();
}

let mut paths = Paths {
items: Vec::with_capacity(opts.functions().len()),
opts: opts.clone(),
let functions: Vec<ir::Id> = match opts.functions().is_empty() {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed this to a Vecir::Id rather than a BTreeSet so that the items could be sorted by size :)

true => {
if opts.descending() {
let mut roots: Vec<_> = items
.neighbors(items.meta_root())
.map(|id| &items[id])
.collect();
roots.sort_by(|a, b| b.size().cmp(&a.size()));
roots.into_iter().map(|item| item.id()).collect()
} else {
let mut sorted_items: Vec<_> = items
.iter()
.filter(|item| item.id() != items.meta_root())
.collect();
sorted_items.sort_by(|a, b| b.size().cmp(&a.size()));
sorted_items.iter().map(|item| item.id()).collect()
}
}
false => opts.functions()
.iter()
.filter_map(|s| items.get_item_by_name(s))
.map(|item| item.id())
.collect(),
};

let functions: BTreeSet<_> = opts.functions().iter().map(|s| s.as_str()).collect();

for item in items.iter() {
if functions.contains(item.name()) {
paths.items.push(item.id());
}
}
let paths = Paths {
items: functions,
opts: opts.clone(),
};

Ok(Box::new(paths) as Box<traits::Emit>)
}
Expand Down
16 changes: 16 additions & 0 deletions opt/definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,10 @@ pub struct Paths {
/// The maximum number of paths, regardless of depth in the tree, to display.
#[structopt(short = "r", default_value = "10")]
max_paths: u32,

/// This direction of the path traversal.
#[structopt(long = "descending")]
descending: bool,
}

impl Default for Paths {
Expand All @@ -235,6 +239,7 @@ impl Default for Paths {
functions: Default::default(),
max_depth: 10,
max_paths: 10,
descending: false,
}
}
}
Expand Down Expand Up @@ -271,6 +276,11 @@ impl Paths {
self.max_paths
}

/// The direction in which the call paths are traversed.
pub fn descending(&self) -> bool {
self.descending
}

/// Set the maximum depth to print the paths.
pub fn set_max_depth(&mut self, max_depth: u32) {
self.max_depth = max_depth;
Expand All @@ -280,6 +290,12 @@ impl Paths {
pub fn set_max_paths(&mut self, max_paths: u32) {
self.max_paths = max_paths;
}

/// Set the call path traversal direction.
pub fn set_descending(&mut self, descending: bool) {
self.descending = descending;
}

}

/// List the generic function monomorphizations that are contributing to
Expand Down
7 changes: 7 additions & 0 deletions twiggy/tests/expectations/paths_test_called_once
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Shallow Bytes │ Shallow % │ Retaining Paths
───────────────┼───────────┼────────────────────────────────
5 ┊ 3.47% ┊ calledOnce
┊ ┊ ⬑ func[0]
┊ ┊ ⬑ woof
┊ ┊ ⬑ func[3]
┊ ┊ ⬑ export "woof"
13 changes: 13 additions & 0 deletions twiggy/tests/expectations/paths_test_called_twice
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Shallow Bytes │ Shallow % │ Retaining Paths
───────────────┼───────────┼────────────────────────────────────────
5 ┊ 3.47% ┊ calledTwice
┊ ┊ ⬑ func[1]
┊ ┊ ⬑ bark
┊ ┊ ⬑ func[2]
┊ ┊ ⬑ export "bark"
┊ ┊ ⬑ awoo
┊ ┊ ⬑ func[4]
┊ ┊ ⬑ export "awoo"
┊ ┊ ⬑ woof
┊ ┊ ⬑ func[3]
┊ ┊ ⬑ export "woof"
81 changes: 81 additions & 0 deletions twiggy/tests/expectations/paths_test_default_output
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
Shallow Bytes │ Shallow % │ Retaining Paths
───────────────┼───────────┼────────────────────────────────────────
44 ┊ 30.56% ┊ "function names" subsection
8 ┊ 5.56% ┊ woof
┊ ┊ ⬑ func[3]
┊ ┊ ⬑ export "woof"
7 ┊ 4.86% ┊ export "awoo"
7 ┊ 4.86% ┊ export "bark"
7 ┊ 4.86% ┊ export "woof"
5 ┊ 3.47% ┊ calledOnce
┊ ┊ ⬑ func[0]
┊ ┊ ⬑ woof
┊ ┊ ⬑ func[3]
┊ ┊ ⬑ export "woof"
5 ┊ 3.47% ┊ calledTwice
┊ ┊ ⬑ func[1]
┊ ┊ ⬑ bark
┊ ┊ ⬑ func[2]
┊ ┊ ⬑ export "bark"
┊ ┊ ⬑ awoo
┊ ┊ ⬑ func[4]
┊ ┊ ⬑ export "awoo"
┊ ┊ ⬑ woof
┊ ┊ ⬑ func[3]
┊ ┊ ⬑ export "woof"
5 ┊ 3.47% ┊ bark
┊ ┊ ⬑ func[2]
┊ ┊ ⬑ export "bark"
┊ ┊ ⬑ awoo
┊ ┊ ⬑ func[4]
┊ ┊ ⬑ export "awoo"
5 ┊ 3.47% ┊ awoo
┊ ┊ ⬑ func[4]
┊ ┊ ⬑ export "awoo"
4 ┊ 2.78% ┊ type[0]
┊ ┊ ⬑ func[0]
┊ ┊ ⬑ woof
┊ ┊ ⬑ func[3]
┊ ┊ ⬑ export "woof"
┊ ┊ ⬑ func[1]
┊ ┊ ⬑ bark
┊ ┊ ⬑ func[2]
┊ ┊ ⬑ export "bark"
┊ ┊ ⬑ awoo
┊ ┊ ⬑ func[4]
┊ ┊ ⬑ export "awoo"
┊ ┊ ⬑ woof
┊ ┊ ⬑ func[3]
┊ ┊ ⬑ export "woof"
┊ ┊ ⬑ func[2]
┊ ┊ ⬑ export "bark"
┊ ┊ ⬑ awoo
┊ ┊ ⬑ func[4]
┊ ┊ ⬑ export "awoo"
┊ ┊ ⬑ func[3]
┊ ┊ ⬑ export "woof"
┊ ┊ ⬑ func[4]
┊ ┊ ⬑ export "awoo"
1 ┊ 0.69% ┊ func[0]
┊ ┊ ⬑ woof
┊ ┊ ⬑ func[3]
┊ ┊ ⬑ export "woof"
1 ┊ 0.69% ┊ func[1]
┊ ┊ ⬑ bark
┊ ┊ ⬑ func[2]
┊ ┊ ⬑ export "bark"
┊ ┊ ⬑ awoo
┊ ┊ ⬑ func[4]
┊ ┊ ⬑ export "awoo"
┊ ┊ ⬑ woof
┊ ┊ ⬑ func[3]
┊ ┊ ⬑ export "woof"
1 ┊ 0.69% ┊ func[2]
┊ ┊ ⬑ export "bark"
┊ ┊ ⬑ awoo
┊ ┊ ⬑ func[4]
┊ ┊ ⬑ export "awoo"
1 ┊ 0.69% ┊ func[3]
┊ ┊ ⬑ export "woof"
1 ┊ 0.69% ┊ func[4]
┊ ┊ ⬑ export "awoo"
30 changes: 30 additions & 0 deletions twiggy/tests/expectations/paths_test_default_output_desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
Shallow Bytes │ Shallow % │ Retaining Paths
───────────────┼───────────┼──────────────────────────────────────
44 ┊ 30.56% ┊ "function names" subsection
7 ┊ 4.86% ┊ export "awoo"
┊ ┊ ↳ func[4]
┊ ┊ ↳ type[0]
┊ ┊ ↳ awoo
┊ ┊ ↳ func[2]
┊ ┊ ↳ type[0]
┊ ┊ ↳ bark
┊ ┊ ↳ func[1]
┊ ┊ ↳ type[0]
┊ ┊ ↳ calledTwice
7 ┊ 4.86% ┊ export "bark"
┊ ┊ ↳ func[2]
┊ ┊ ↳ type[0]
┊ ┊ ↳ bark
┊ ┊ ↳ func[1]
┊ ┊ ↳ type[0]
┊ ┊ ↳ calledTwice
7 ┊ 4.86% ┊ export "woof"
┊ ┊ ↳ func[3]
┊ ┊ ↳ type[0]
┊ ┊ ↳ woof
┊ ┊ ↳ func[0]
┊ ┊ ↳ type[0]
┊ ┊ ↳ calledOnce
┊ ┊ ↳ func[1]
┊ ┊ ↳ type[0]
┊ ┊ ↳ calledTwice
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Shallow Bytes │ Shallow % │ Retaining Paths
───────────────┼───────────┼────────────────────────────
44 ┊ 30.56% ┊ "function names" subsection
7 ┊ 4.86% ┊ export "awoo"
┊ ┊ ↳ func[4]
┊ ┊ ↳ type[0]
┊ ┊ ↳ awoo
7 ┊ 4.86% ┊ export "bark"
┊ ┊ ↳ func[2]
┊ ┊ ↳ type[0]
┊ ┊ ↳ bark
7 ┊ 4.86% ┊ export "woof"
┊ ┊ ↳ func[3]
┊ ┊ ↳ type[0]
┊ ┊ ↳ woof
Binary file added twiggy/tests/fixtures/paths_test.wasm
Binary file not shown.
50 changes: 50 additions & 0 deletions twiggy/tests/fixtures/paths_test.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
(module
;; ------------------------------------------------------------------------
;; This is a WebAssembly text file that can be compiled in a wasm module to
;; test the `twiggy paths` command. This intends to provide a non-trivial
;; structure of call paths for testing purposes.
;;
;; The call path is shown in the ascii diagram below with exported
;; functions enclosed in braces, and unexported functions in quotes.
;;
;; [awoo]
;; |
;; v
;; [woof] [bark]
;; | | |
;; | -------- |
;; | | |
;; v v v
;; 'calledOnce' 'calledTwice'
;; ------------------------------------------------------------------------
;; NOTE: The test cases expect that this module is compiled with debug
;; names written to the binary file, which affects the size percentages.
;; Compile this file using the following command:
;;
;; wat2wasm --debug-names paths_test.wat -o paths_test.wasm
;; -------------------------------------------------------------------------


;; This function is called once, by 'woof'.
(func $calledOnce (result i32)
i32.const 1)

;; This function is called twice, by 'bark' and 'woof'.
(func $calledTwice (result i32)
i32.const 2)

(func $bark (result i32)
call $calledTwice)

(func $woof (result i32)
call $calledOnce
call $calledTwice
i32.add)

(func $awoo (result i32)
call $bark)

(export "awoo" (func $awoo))
(export "bark" (func $bark))
(export "woof" (func $woof))
)
Loading