Tree-Traversal Orientation Analysis Stephen Curial, Kevin Andrusky and José Nelson Amaral University of Alberta Stephen Curial, Kevin Andrusky and José.

Slides:



Advertisements
Similar presentations
1 Lecture 10 Intermediate Representations. 2 front end »produces an intermediate representation (IR) for the program. optimizer »transforms the code in.
Advertisements

ECE 454 Computer Systems Programming Compiler and Optimization (I) Ding Yuan ECE Dept., University of Toronto
Comp 122, Spring 2004 Binary Search Trees. btrees - 2 Comp 122, Spring 2004 Binary Trees  Recursive definition 1.An empty tree is a binary tree 2.A node.
S. Sudarshan Based partly on material from Fawzi Emad & Chau-Wen Tseng
Tree Searching. Tree searches A tree search starts at the root and explores nodes from there, looking for a goal node (a node that satisfies certain conditions,
Computer Science C++ High School Level By Guillermo Moreno.
1 A Two-Level Binary Expression ‘-’ ‘8’ ‘5’ treePtr INORDER TRAVERSAL : has value 3 PREORDER TRAVERSAL: POSTORDER TRAVERSAL: 8 5 -
Lecture 8 CS203. Implementation of Data Structures 2 In the last couple of weeks, we have covered various data structures that are implemented in the.
1 Trees Tree nomenclature Implementation strategies Traversals –Depth-first –Breadth-first Implementing binary trees Reading: L&C 9.1 – 9.7.
Determining Tree-Traversals Orientation using Feedback-Directed Analysis Stephen Curial, Kevin Andrusky and José Nelson Amaral University of Alberta Stephen.
Run-Time Storage Organization
A Context-Sensitive Pointer Analysis Phase in Open64 Compiler Tianwei Sheng, Wenguang Chen, Weimin Zheng Tsinghua University.
Cache Conscious Allocation of Pointer Based Data Structures, Revisited with HW/SW Prefetching by: Josefin Hallberg, Tuva Palm and Mats Brorsson Presented.
Chapter 12 C Data Structures Acknowledgment The notes are adapted from those provided by Deitel & Associates, Inc. and Pearson Education Inc.
Transforming Infix to Postfix
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved. Chapter 12 – Data Structures Outline 12.1Introduction.
Loop Induction Variable Canonicalization. Motivation Background: Open64 Compilation Scheme Loop Induction Variable Canonicalization Project Tracing and.
Using Generational Garbage Collection To Implement Cache- conscious Data Placement Trishul M. Chilimbi & James R. Larus מציג : ראובן ביק.
1 Foundations of Software Design Fall 2002 Marti Hearst Lecture 17: Binary Search Trees; Heaps.
More Trees COL 106 Amit Kumar and Shweta Agrawal Most slides courtesy : Douglas Wilhelm Harder, MMath, UWaterloo
Nirmalya Roy School of Electrical Engineering and Computer Science Washington State University Cpt S 122 – Data Structures Data Structures Trees.
1 HEAPS & PRIORITY QUEUES Array and Tree implementations.
1 Chapter 18 Trees Objective To learn general trees and recursion binary trees and recursion tree traversal.
Chapter 12 Data Structure Associate Prof. Yuh-Shyan Chen Dept. of Computer Science and Information Engineering National Chung-Cheng University.
Recursion Bryce Boe 2013/11/18 CS24, Fall Outline Wednesday Recap Lab 7 Iterative Solution Recursion Binary Tree Traversals Lab 7 Recursive Solution.
1 Data Structures Lists and Trees. 2 Real-Life Computational Problems All about organizing data! –What shape the data should have to solve your problem.
Nirmalya Roy School of Electrical Engineering and Computer Science Washington State University Cpt S 122 – Data Structures Custom Templatized Data Structures.
Chapter 8 Data Abstractions Introduction to CS 1 st Semester, 2015 Sanghyun Park.
1 Trees Tree nomenclature Implementation strategies Traversals –Depth-first –Breadth-first Implementing binary search trees.
 2007 Pearson Education, Inc. All rights reserved C Data Structures.
Cache Locality for Non-numerical Codes María Jesús Garzarán University of Illinois at Urbana-Champaign.
Information and Computer Sciences University of Hawaii, Manoa
Binary Trees Chapter Definition And Application Of Binary Trees Binary tree: a nonlinear linked list in which each node may point to 0, 1, or two.
1 Trees A tree is a data structure used to represent different kinds of data and help solve a number of algorithmic problems Game trees (i.e., chess ),
Computer Science Department Data Structure & Algorithms Lecture 8 Recursion.
Starting at Binary Trees
Binary Search Tree Traversal Methods. How are they different from Binary Trees?  In computer science, a binary tree is a tree data structure in which.
1 Recursive Data Structure Profiling Easwaran Raman David I. August Princeton University.
Programming Practice 3 - Dynamic Data Structure
Data Structures Systems Programming. Systems Programming: Data Structures 2 2 Systems Programming: 2 Data Structures  Queues –Queuing System Models –Queue.
CMPUT Compiler Design and Optimization1 CMPUT680 - Fall 2006 Topic 3: Intermediate Representation in the ORC José Nelson Amaral
Data Flow Analysis for Software Prefetching Linked Data Structures in Java Brendon Cahoon Dept. of Computer Science University of Massachusetts Amherst,
Copyright © 2012 Pearson Education, Inc. Chapter 20: Binary Trees.
1 Trees General Trees  Nonrecursive definition: a tree consists of a set of nodes and a set of directed edges that connect pairs of nodes.
Copyright © 2015, 2012, 2009 Pearson Education, Inc., Publishing as Addison-Wesley All rights reserved. Chapter 20: Binary Trees.
Cache-Conscious Data Placement Adapted from CS 612 talk by Amy M. Henning.
Data Structure and Algorithms
Graph Traversal Text Weiss, § 9.6 Depth-First Search Think Stack Breadth-First Search Think Queue.
1 Trees General Trees  Nonrecursive definition: a tree consists of a set of nodes and a set of directed edges that connect pairs of nodes.
Copyright © 2009 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Chapter 20: Binary Trees.
RealTimeSystems Lab Jong-Koo, Lim
Recursion ITFN The Stack. A data structure maintained by each program at runtime. Push Pop.
Graphs. What is a graph? In simple words, A graph is a set of vertices and edges which connect them. A node (or vertex) is a discrete position in the.
Trees Binary Trees Extended Binary Trees. Tree A Tree consist of Nodes connected by Edges. Node is represented by Circle Edges as Lines or Arrows A Tree.
Chapter 12 – Data Structures
12 C Data Structures.
Data Structure and Algorithms
Trees.
i206: Lecture 13: Recursion, continued Trees
Binary Tree and General Tree
Chapter 20: Binary Trees.
For Example: User level quicksort program Three address code.
Chapter 21: Binary Trees.
Review & Lab assignments
A Robust Data Structure
Data Structures – Week #5
CSC 143 Java Applications of Trees.
Chapter 20: Binary Trees.
Trees.
Topic 2b ISA Support for High-Level Languages
Presentation transcript:

Tree-Traversal Orientation Analysis Stephen Curial, Kevin Andrusky and José Nelson Amaral University of Alberta Stephen Curial, Kevin Andrusky and José Nelson Amaral University of Alberta

Overview A compiler-based analysis to determine the predominant orientation of traversal of trees. The compiler automatically inserts instrumentation into the the program to create an instrumented executable that computes an orientation score for each tree in the program.

Overview A compiler-based analysis to determine the predominant orientation of traversal of trees. The compiler automatically inserts instrumentation into the the program to create an instrumented executable that computes an orientation score for each tree in the program.

dfs(tree *t){ if(t = NULL) return; dfs(t->left); dfs(t->right); } Overview Program Source Instrumented Executable ? Compiler Tree Analysis Library Orientation Score “Typical” Input

Tree-Traversal Orientation Analysis Returns an orientation score  [-1,1] 1 is depth-first traversal -1 is breadth first traversal 0 is an unknown traversal Returns an orientation score  [-1,1] 1 is depth-first traversal -1 is breadth first traversal 0 is an unknown traversal DFS BFS 0 1

Overview struct tree *t1, *t2; init(t1,t2); dfs(t1); bfs(t2); … …… t1t2 orientation score = 1.0 orientation score = -1.0

Calculating the Orientation Score Every memory access to a tree is classified as: Depth-First Breadth-First Both Neither The orientation score of each tree is calculated as: Every memory access to a tree is classified as: Depth-First Breadth-First Both Neither The orientation score of each tree is calculated as:

Calculating the Orientation Score A linked-list access could be classified as both Breadth- and Depth-First. In this analysis a memory access to a 1-arity tree is classified as Depth-First. An alternative is to provide a three-dimensional score that also classifies linked-list traversal. A linked-list access could be classified as both Breadth- and Depth-First. In this analysis a memory access to a 1-arity tree is classified as Depth-First. An alternative is to provide a three-dimensional score that also classifies linked-list traversal.

Determining if an Access is Depth-First The TAL maintains a stack of choice- points for each tree. Each choice-point consists of: 1. the address of a node, t, in the tree, 2. all n children of t, c 1 … c n, with a boolean representing if they have been visited, and 3. a boolean value representing if the node has been visited The TAL maintains a stack of choice- points for each tree. Each choice-point consists of: 1. the address of a node, t, in the tree, 2. all n children of t, c 1 … c n, with a boolean representing if they have been visited, and 3. a boolean value representing if the node has been visited

Determining if a Access is Depth-First cp top : the address of the choice point on top of the stack; t: the address of the tree node been referenced now; cp low : the address of a choice point below cp top in the stack; cp top : the address of the choice point on top of the stack; t: the address of the tree node been referenced now; cp low : the address of a choice point below cp top in the stack; cp top cp low

Determining if a Access is Depth-First An access to tree node t is classified as depth-first if and only if: 1. cp top is equal to t; OR 2. A child c i of cp top is equal to t; OR 3. There exists a lower choice point in the stack cp low such that cp low or a child of cp low is equal t AND all of the choice-points on the stack above cp low have been visited. An access to tree node t is classified as depth-first if and only if: 1. cp top is equal to t; OR 2. A child c i of cp top is equal to t; OR 3. There exists a lower choice point in the stack cp low such that cp low or a child of cp low is equal t AND all of the choice-points on the stack above cp low have been visited. cp top cp low

Determining if a Access is Depth-First Every time a node is visited, a choice-point for that node is pushed onto the stack abcdef 7654 …

Determining if a Access is Depth-First Every time a node is visited, a choice-point for that node is pushed onto the stack abcdef 7654 … 1 (2,3) t = 1 c top node (c1,c2)

Determining if a Access is Depth-First abcdef 7654 … 1(2,3) 2 (4,5) Dark color means visited t = 2 c top Condition 2: t = c 1  2 is DFS

Determining if a Access is Depth-First abcdef 7654 … t = 4 4 (8,9) 1(2,3) 2 (4,5) c top Condition 2: t = c 1  4 is DFS

Determining if a Access is Depth-First abcdef 7654 … t = 8 4 (8,9) 1(2,3) 2 (4,5) c top Condition 2: t = c 1  8 is DFS Note: Children of 8 are null thus 8 is not a choice point.

Determining if a Access is Depth-First abcdef 7654 … t = 9 4 (8,9) 1(2,3) 2 (4,5) c top Condition 2: t = c 2  9 is DFS Note: Children of 9 are null thus 9 is not a choice point.

Determining if a Access is Depth-First abcdef 7654 … t = 5 4 (8,9) 1(2,3) 2 (4,5) c top c low Condition 3: t = c low.c 2  5 is DFS Pop everything above c low

Determining if a Access is Depth-First abcdef 7654 … t = 5 1(2,3) 2 (4,5) c top Condition 3: t = c low.c 2  5 is DFS Pop everything above c low

Determining if a Access is Depth-First abcdef 7654 … t = 5 1(2,3) 2 (4,5) c top 5 (a,b)

Determining if a Access is Depth-First abcdef 7654 … t = a 1(2,3) 2 (4,5) c top Condition 2: t = c 1  a is DFS 5 (a,b)

Determining if a Access is Depth-First abcdef 7654 … t = b 1(2,3) 2 (4,5) c top Condition 2: t = c 2  b is DFS 5 (a,b)

Determining if a Access is Depth-First abcdef 7654 … t = 3 1(2,3) 2 (4,5) c top Condition 3: t = c low.c 2  b is DFS Pop everything above c low 5 (a,b) c low

Determining if a Access is Depth-First abcdef 7654 … t = 3 1(2,3) 3 (6,7) c top

Determining if a Access is Breadth-First The TAL maintains an open and next list for each tree. They are stored as double-ended bit-vectors. If an access is found in the open list it is classified as Breadth-First. The TAL maintains an open and next list for each tree. They are stored as double-ended bit-vectors. If an access is found in the open list it is classified as Breadth-First abcdef abcdef Open Next

Determining if a Access is Breadth-First When tree node t is accessed: The children of t are added to the next list. If t is in the open list it is removed from the open list and the access is classified as breadth first. When the open list is empty it is swapped with the next list. When tree node t is accessed: The children of t are added to the next list. If t is in the open list it is removed from the open list and the access is classified as breadth first. When the open list is empty it is swapped with the next list abcdef 7654 … Open Next

Determining if a Access is Breadth-First When tree node t is accessed: The children of t are added to the next list. If t is in the open list it is removed from the open list and the access is classified as breadth first. When the open list is empty it is swapped with the next list. When tree node t is accessed: The children of t are added to the next list. If t is in the open list it is removed from the open list and the access is classified as breadth first. When the open list is empty it is swapped with the next list abcdef 7654 … 23 Open Next

Determining if a Access is Breadth-First When tree node t is accessed: The children of t are added to the next list. If t is in the open list it is removed from the open list and the access is classified as breadth first. When the open list is empty it is swapped with the next list. When tree node t is accessed: The children of t are added to the next list. If t is in the open list it is removed from the open list and the access is classified as breadth first. When the open list is empty it is swapped with the next list abcdef 7654 … 23 Open Next

Determining if a Access is Breadth-First When tree node t is accessed: The children of t are added to the next list. If t is in the open list it is removed from the open list and the access is classified as breadth first. When the open list is empty it is swapped with the next list. When tree node t is accessed: The children of t are added to the next list. If t is in the open list it is removed from the open list and the access is classified as breadth first. When the open list is empty it is swapped with the next list abcdef 7654 … 23 Open Next Access is classified as Breadth-First

Determining if a Access is Breadth-First When tree node t is accessed: The children of t are added to the next list. If t is in the open list it is removed from the open list and the access is classified as breadth first. When the open list is empty it is swapped with the next list. When tree node t is accessed: The children of t are added to the next list. If t is in the open list it is removed from the open list and the access is classified as breadth first. When the open list is empty it is swapped with the next list abcdef 7654 … 3 Open Next

Determining if a Access is Breadth-First When tree node t is accessed: The children of t are added to the next list. If t is in the open list it is removed from the open list and the access is classified as breadth first. When the open list is empty it is swapped with the next list. When tree node t is accessed: The children of t are added to the next list. If t is in the open list it is removed from the open list and the access is classified as breadth first. When the open list is empty it is swapped with the next list abcdef 7654 … 3 45 Open Next

Determining if a Access is Breadth-First When tree node t is accessed: The children of t are added to the next list. If t is in the open list it is removed from the open list and the access is classified as breadth first. When the open list is empty it is swapped with the next list. When tree node t is accessed: The children of t are added to the next list. If t is in the open list it is removed from the open list and the access is classified as breadth first. When the open list is empty it is swapped with the next list abcdef 7654 … Open Next Access is classified as Breadth-First

Determining if a Access is Breadth-First When tree node t is accessed: The children of t are added to the next list. If t is in the open list it is removed from the open list and the access is classified as breadth first. When the open list is empty it is swapped with the next list. When tree node t is accessed: The children of t are added to the next list. If t is in the open list it is removed from the open list and the access is classified as breadth first. When the open list is empty it is swapped with the next list abcdef 7654 … 4567 Open Next

Determining if a Access is Breadth-First When tree node t is accessed: The children of t are added to the next list. If t is in the open list it is removed from the open list and the access is classified as breadth first. When the open list is empty it is swapped with the next list. When tree node t is accessed: The children of t are added to the next list. If t is in the open list it is removed from the open list and the access is classified as breadth first. When the open list is empty it is swapped with the next list abcdef 7654 … 4567 Open Next

Determining if a Access is Breadth-First When tree node t is accessed: The children of t are added to the next list. If t is in the open list it is removed from the open list and the access is classified as breadth first. When the open list is empty it is swapped with the next list. When tree node t is accessed: The children of t are added to the next list. If t is in the open list it is removed from the open list and the access is classified as breadth first. When the open list is empty it is swapped with the next list abcdef 7654 … Open Next Access is classified as Breadth-First

Determining if a Access is Breadth-First When tree node t is accessed: The children of t are added to the next list. If t is in the open list it is removed from the open list and the access is classified as breadth first. When the open list is empty it is swapped with the next list. When tree node t is accessed: The children of t are added to the next list. If t is in the open list it is removed from the open list and the access is classified as breadth first. When the open list is empty it is swapped with the next list abcdef 7654 … Open Next

Implementation Built in the Open Research Compiler (ORC) Operates on the WHIRL (Winning Hierarchical Intermediate Representation Language) IR. Analysis requires Interprocedural Analysis (IPA). Automatically identifies link-based tree data structures using Ghiya and Hendren’s analysis [2] or programmer annotations. Instrumentation can be inserted into each procedure without IPA. Built in the Open Research Compiler (ORC) Operates on the WHIRL (Winning Hierarchical Intermediate Representation Language) IR. Analysis requires Interprocedural Analysis (IPA). Automatically identifies link-based tree data structures using Ghiya and Hendren’s analysis [2] or programmer annotations. Instrumentation can be inserted into each procedure without IPA.

Implementation Calls our Tree Analysis Library (TAL) register_tree_access_with_children() Takes Parameters: void *addr_deref int tree_id int num_children void *child_addr, … Calls our Tree Analysis Library (TAL) register_tree_access_with_children() Takes Parameters: void *addr_deref int tree_id int num_children void *child_addr, …

Implementation Analysis is safe and will not cause a correct program to fail. Replace calls to malloc/calloc/realloc with TALs wrapper functions. If memory allocation fails, the analysis is abandoned and the memory used by the analysis is freed. Memory address are calculated and accessed for the instrumentation in locations that are safe. i.e. Will not dereference null pointers if( tree != NULL && tree->data == 1) Analysis is safe and will not cause a correct program to fail. Replace calls to malloc/calloc/realloc with TALs wrapper functions. If memory allocation fails, the analysis is abandoned and the memory used by the analysis is freed. Memory address are calculated and accessed for the instrumentation in locations that are safe. i.e. Will not dereference null pointers if( tree != NULL && tree->data == 1)

How do we identify tree references? Example Code: /* inorder tree traversal */ void inorder_traverse_tree(struct tn *tree_ptr) { if(tree_ptr == NULL) return; inorder_traverse_tree(tree_ptr->left); tree_ptr->data++; inorder_traverse_tree(tree_ptr->right); } Example Code: /* inorder tree traversal */ void inorder_traverse_tree(struct tn *tree_ptr) { if(tree_ptr == NULL) return; inorder_traverse_tree(tree_ptr->left); tree_ptr->data++; inorder_traverse_tree(tree_ptr->right); }

How do we identify tree references? LOC 1 94 void inorder_traverse_tree(struct tn *tree_ptr) LOC 1 95 { FUNC_ENTRY IDNAME 0 BODY LOC 1 96 if(tree_ptr == NULL) IF U8U8LDID 0 T U8INTCONST 0 (0x0) I4U8EQ THEN BLOCK LOC 1 97 return; RETURN END_BLOCK ELSE LOC 1 96 BLOCK END_BLOCK END_IF LOC LOC inorder_traverse_tree(tree_ptr->left); U8U8LDID 0 T U8U8ILOAD 8 T T U8PARM 2 T # by_value VCALL 126 # flags 0x7e LOC 1 94 void inorder_traverse_tree(struct tn *tree_ptr) LOC 1 95 { FUNC_ENTRY IDNAME 0 BODY LOC 1 96 if(tree_ptr == NULL) IF U8U8LDID 0 T U8INTCONST 0 (0x0) I4U8EQ THEN BLOCK LOC 1 97 return; RETURN END_BLOCK ELSE LOC 1 96 BLOCK END_BLOCK END_IF LOC LOC inorder_traverse_tree(tree_ptr->left); U8U8LDID 0 T U8U8ILOAD 8 T T U8PARM 2 T # by_value VCALL 126 # flags 0x7e LOC tree_ptr->data++; U8U8LDID 0 T I4I4ILOAD 0 T T I4INTCONST 1 (0x1) I4ADD U8U8LDID 0 T I4ISTORE 0 T LOC inorder_traverse_tree(tree_ptr->right); U8U8LDID 0 T U8U8ILOAD 16 T T U8PARM 2 T # by_value VCALL 126 # flags 0x7e RETURN END_BLOCK void inorder_traverse_tree(struct tn *tree_ptr) { if(tree_ptr == NULL) return; inorder_traverse_tree(tree_ptr->left); tree_ptr->data++; inorder_traverse_tree(tree_ptr->right); } void inorder_traverse_tree(struct tn *tree_ptr) { if(tree_ptr == NULL) return; inorder_traverse_tree(tree_ptr->left); tree_ptr->data++; inorder_traverse_tree(tree_ptr->right); }

How do we identify tree references? LOC 1 94 void inorder_traverse_tree(struct tn *tree_ptr) LOC 1 95 { FUNC_ENTRY IDNAME 0 BODY BLOCK END_BLOCK BLOCK END_BLOCK BLOCK PRAGMA (0x0) # PREAMBLE_END LOC 1 96 if(tree_ptr == NULL) IF U8U8LDID 0 T U8INTCONST 0 (0x0) I4U8EQ THEN BLOCK LOC 1 97 return; RETURN END_BLOCK ELSE LOC 1 96 BLOCK END_BLOCK END_IF LOC 1 94 void inorder_traverse_tree(struct tn *tree_ptr) LOC 1 95 { FUNC_ENTRY IDNAME 0 BODY BLOCK END_BLOCK BLOCK END_BLOCK BLOCK PRAGMA (0x0) # PREAMBLE_END LOC 1 96 if(tree_ptr == NULL) IF U8U8LDID 0 T U8INTCONST 0 (0x0) I4U8EQ THEN BLOCK LOC 1 97 return; RETURN END_BLOCK ELSE LOC 1 96 BLOCK END_BLOCK END_IF LOC LOC inorder_traverse_tree(tree_ptr->left); U8U8LDID 0 T U8U8ILOAD 8 T T U8PARM 2 T # by_value VCALL 126 # flags 0x7e LOC tree_ptr->data++; U8U8LDID 0 T I4I4ILOAD 0 T T I4INTCONST 1 (0x1) I4ADD U8U8LDID 0 T I4ISTORE 0 T LOC inorder_traverse_tree(tree_ptr->right); U8U8LDID 0 T U8U8ILOAD 16 T T U8PARM 2 T # by_value VCALL 126 # flags 0x7e RETURN END_BLOCK FUNC_ENTRY (inorder_traverse_tree) IDNAME (tree_ptr) BLOCK LOC 1 94 void inorder_traverse_tree(struct tn *tree_ptr) LOC 1 95 { FUNC_ENTRY IDNAME 0 BODY BLOCK END_BLOCK BLOCK END_BLOCK BLOCK void inorder_traverse_tree(struct tn *tree_ptr)

How do we identify tree references? LOC 1 94 void inorder_traverse_tree(struct tn *tree_ptr) LOC 1 95 { FUNC_ENTRY IDNAME 0 BODY BLOCK END_BLOCK BLOCK END_BLOCK BLOCK PRAGMA (0x0) # PREAMBLE_END LOC 1 96 if(tree_ptr == NULL) IF U8U8LDID 0 T U8INTCONST 0 (0x0) I4U8EQ THEN BLOCK LOC 1 97 return; RETURN END_BLOCK ELSE LOC 1 96 BLOCK END_BLOCK END_IF LOC 1 94 void inorder_traverse_tree(struct tn *tree_ptr) LOC 1 95 { FUNC_ENTRY IDNAME 0 BODY BLOCK END_BLOCK BLOCK END_BLOCK BLOCK PRAGMA (0x0) # PREAMBLE_END LOC 1 96 if(tree_ptr == NULL) IF U8U8LDID 0 T U8INTCONST 0 (0x0) I4U8EQ THEN BLOCK LOC 1 97 return; RETURN END_BLOCK ELSE LOC 1 96 BLOCK END_BLOCK END_IF LOC LOC inorder_traverse_tree(tree_ptr->left); U8U8LDID 0 T U8U8ILOAD 8 T T U8PARM 2 T # by_value VCALL 126 # flags 0x7e LOC tree_ptr->data++; U8U8LDID 0 T I4I4ILOAD 0 T T I4INTCONST 1 (0x1) I4ADD U8U8LDID 0 T I4ISTORE 0 T LOC inorder_traverse_tree(tree_ptr->right); U8U8LDID 0 T U8U8ILOAD 16 T T U8PARM 2 T # by_value VCALL 126 # flags 0x7e RETURN END_BLOCK FUNC_ENTRY (inorder_traverse_tree) IDNAME (tree_ptr) BLOCK IF EQ LDID (tree_ptr) INTCONST 0x0 RETURN BLOCK (then) LOC 1 96 if(tree_ptr == NULL) IF U8U8LDID 0 T U8INTCONST 0 (0x0) I4U8EQ THEN BLOCK LOC 1 97 return; RETURN END_BLOCK if(tree_ptr == NULL)

How do we identify tree references? LOC 1 94 void inorder_traverse_tree(struct tn *tree_ptr) LOC 1 95 { FUNC_ENTRY IDNAME 0 BODY BLOCK END_BLOCK BLOCK END_BLOCK BLOCK PRAGMA (0x0) # PREAMBLE_END LOC 1 96 if(tree_ptr == NULL) IF U8U8LDID 0 T U8INTCONST 0 (0x0) I4U8EQ THEN BLOCK LOC 1 97 return; RETURN END_BLOCK ELSE LOC 1 96 BLOCK END_BLOCK END_IF LOC 1 94 void inorder_traverse_tree(struct tn *tree_ptr) LOC 1 95 { FUNC_ENTRY IDNAME 0 BODY BLOCK END_BLOCK BLOCK END_BLOCK BLOCK PRAGMA (0x0) # PREAMBLE_END LOC 1 96 if(tree_ptr == NULL) IF U8U8LDID 0 T U8INTCONST 0 (0x0) I4U8EQ THEN BLOCK LOC 1 97 return; RETURN END_BLOCK ELSE LOC 1 96 BLOCK END_BLOCK END_IF LOC LOC inorder_traverse_tree(tree_ptr->left); U8U8LDID 0 T U8U8ILOAD 8 T T U8PARM 2 T # by_value VCALL 126 # flags 0x7e LOC tree_ptr->data++; U8U8LDID 0 T I4I4ILOAD 0 T T I4INTCONST 1 (0x1) I4ADD U8U8LDID 0 T I4ISTORE 0 T LOC inorder_traverse_tree(tree_ptr->right); U8U8LDID 0 T U8U8ILOAD 16 T T U8PARM 2 T # by_value VCALL 126 # flags 0x7e RETURN END_BLOCK BLOCK VCALL PARAM ILOAD (offset 8) LDID (tree_ptr) LOC inorder_traverse_tree(tree_ptr->left); U8U8LDID 0 T U8U8ILOAD 8 T T U8PARM 2 T # by_value VCALL 126 # flags 0x7e inorder_traverse_tree(tree_ptr->left);

How do we identify tree references? LOC 1 94 void inorder_traverse_tree(struct tn *tree_ptr) LOC 1 95 { FUNC_ENTRY IDNAME 0 BODY BLOCK END_BLOCK BLOCK END_BLOCK BLOCK PRAGMA (0x0) # PREAMBLE_END LOC 1 96 if(tree_ptr == NULL) IF U8U8LDID 0 T U8INTCONST 0 (0x0) I4U8EQ THEN BLOCK LOC 1 97 return; RETURN END_BLOCK ELSE LOC 1 96 BLOCK END_BLOCK END_IF LOC 1 94 void inorder_traverse_tree(struct tn *tree_ptr) LOC 1 95 { FUNC_ENTRY IDNAME 0 BODY BLOCK END_BLOCK BLOCK END_BLOCK BLOCK PRAGMA (0x0) # PREAMBLE_END LOC 1 96 if(tree_ptr == NULL) IF U8U8LDID 0 T U8INTCONST 0 (0x0) I4U8EQ THEN BLOCK LOC 1 97 return; RETURN END_BLOCK ELSE LOC 1 96 BLOCK END_BLOCK END_IF LOC LOC inorder_traverse_tree(tree_ptr->left); U8U8LDID 0 T U8U8ILOAD 8 T T U8PARM 2 T # by_value VCALL 126 # flags 0x7e LOC tree_ptr->data++; U8U8LDID 0 T I4I4ILOAD 0 T T I4INTCONST 1 (0x1) I4ADD U8U8LDID 0 T I4ISTORE 0 T LOC inorder_traverse_tree(tree_ptr->right); U8U8LDID 0 T U8U8ILOAD 16 T T U8PARM 2 T # by_value VCALL 126 # flags 0x7e RETURN END_BLOCK BLOCK VCALL PARAM ILOAD (offset 8) LDID (tree_ptr) ISTORE (offset 8) LDID (tree_ptr) ADD INTCONST 0x1 ILOAD (offset 0) LDID (tree_ptr) LOC tree_ptr->data++; U8U8LDID 0 T I4I4ILOAD 0 T T I4INTCONST 1 (0x1) I4ADD U8U8LDID 0 T I4ISTORE 0 T tree_ptr->data++;

How do we identify tree references? BLOCK VCALL PARAM ILOAD (offset 8) LDID (tree_ptr) VCALL PARAM ILOAD (offset 16) LDID (tree_ptr) ISTORE (offset 8) LDID (tree_ptr) ADD INTCONST 0x1 ILOAD (offset 0) LDID (tree_ptr) FUNC_ENTRY (inorder_traverse_tree) BLOCK IF EQ LDIDINTCONST 0x0 RETURN BLOCK (then) void inorder_traverse_tree(struct tn *tree_ptr) { if(tree_ptr == NULL) return; inorder_traverse_tree(tree_ptr->left); tree_ptr->data++; inorder_traverse_tree(tree_ptr->right); } void inorder_traverse_tree(struct tn *tree_ptr) { if(tree_ptr == NULL) return; inorder_traverse_tree(tree_ptr->left); tree_ptr->data++; inorder_traverse_tree(tree_ptr->right); }

How do we identify tree references? BLOCK VCALL PARAM VCALL PARAM ISTORE (offset 8) LDID (tree_ptr) ADD INTCONST 0x1 FUNC_ENTRY (inorder_traverse_tree) BLOCK IF EQ LDIDINTCONST 0x0 RETURN BLOCK (then) ILOAD (offset 8) LDID (tree_ptr) ILOAD (offset 0) LDID (tree_ptr) ILOAD (offset 16) LDID (tree_ptr) Where are the tree accesses?

How do we identify tree references? BLOCK VCALL PARAM VCALL PARAM ISTORE (offset 8) LDID (tree_ptr) ADD INTCONST 0x1 FUNC_ENTRY (inorder_traverse_tree) BLOCK IF EQ LDIDINTCONST 0x0 RETURN BLOCK (then) ILOAD (offset 8) LDID (tree_ptr) ILOAD (offset 0) LDID (tree_ptr) ILOAD (offset 16) LDID (tree_ptr) This is where our extension to the ORC inserts code into the WHIRL Tree.

The Nodes we Insert Into WHIRL U8U8LDID 0 T U8PARM 2 T # by_value U4INTCONST 1 (0x1) U4PARM 2 T # by_value U4INTCONST 2 (0x2) U4PARM 2 T # by_value U8U8LDID 0 T U8U8ILOAD 8 T T U8PARM 2 T # by_value U8U8LDID 0 T U8U8ILOAD 16 T T U8PARM 2 T # by_value VCALL 126 # flags 0x7e U8U8LDID 0 T U8PARM 2 T # by_value U4INTCONST 1 (0x1) U4PARM 2 T # by_value U4INTCONST 2 (0x2) U4PARM 2 T # by_value U8U8LDID 0 T U8U8ILOAD 8 T T U8PARM 2 T # by_value U8U8LDID 0 T U8U8ILOAD 16 T T U8PARM 2 T # by_value VCALL 126 # flags 0x7e

The Nodes we Insert Into WHIRL VCALL (register_tree_access_with_children) ILOAD (offset 16) ILOAD (offset 8) PARM INTCONST 0x1 INTCONST 0x2 LDID (tree_ptr) LDID (tree_ptr) PARM LDID (tree_ptr)

Experimental Setup Open Research Compiler v2.1 Optimization level -O3 1.3 GHz Itanium2 1 GB of RAM Open Research Compiler v2.1 Optimization level -O3 1.3 GHz Itanium2 1 GB of RAM

Synthetic Benchmarks RandomDepth: DFS traversal of binary tree, children visited in random order ; BreadthFirst: BFS on binary tree; DepthBreadth: DFS followed by BFS on binary tree; NonStandard: A traversal that is neither BFS nor DFS; MultiDepth: Several DFSs: in-order, pre-order, and post- order; BreadthSearch: Several BFS searchers on a tree with random branching factor (2 to 6); BinarySearch: Several searches in a binary tree. RandomDepth: DFS traversal of binary tree, children visited in random order ; BreadthFirst: BFS on binary tree; DepthBreadth: DFS followed by BFS on binary tree; NonStandard: A traversal that is neither BFS nor DFS; MultiDepth: Several DFSs: in-order, pre-order, and post- order; BreadthSearch: Several BFS searchers on a tree with random branching factor (2 to 6); BinarySearch: Several searches in a binary tree.

Analysis Results (Synthetic Benchmark) Benchmark Orientation Score ExpectedExperimental Random Depth Breadth-First Depth-Breadth Non-Standard Multi Depth Breadth Search Binary Search

Analysis Results (Olden Benchmark) Benchmark Orientation Score ExpectedExperimental BH Bisort Health MSTLow positive PerimeterLow positive Power Treeadd TSPLow positive

Runtime Overhead (Synthetic Benchmark) Benchmark Runtime (s) OriginalInstrumented Random Depth Breadth-First Depth-Breadth Non-Standard Multi Depth Breadth Search Binary Search

Runtime Overhead (Olden Benchmark) Benchmark Runtime (s) OriginalInstrumented BH Bisort Health MST Perimeter Power Treeadd TSP

Memory Overhead (Synthetic Benchmark) Benchmark Memory Usage (kbytes) OriginalInstrumented Random Depth Breadth-First Depth-Breadth Non-Standard Multi Depth Breadth Search Binary Search

Memory Overhead (Olden Benchmark) Benchmark Memory Usage (kbytes) OriginalInstrumented BH3 520 Bisort Health MST Perimeter Power Treeadd3 008 TSP

Possible Clients of the Analysis Prefetching Luk and Mowry - History-Pointer Prefetching [7] Cahoon and McKinley - Jump-Pointer Prefetching [3] Prefetching Luk and Mowry - History-Pointer Prefetching [7] Cahoon and McKinley - Jump-Pointer Prefetching [3] struct myStruct{ int data; struct myStruct *next; }; struct myStruct{ int data; struct myStruct *next; struct myStruct *prefetch; };

Possible Clients of the Analysis Prefetching In the first iteration through the pointer chasing loop there is no prefetching (initializing prefetch pointers). If the traversal is known, the history pointers can be initialized as the data structure is allocated. Eliminate compulsory cache misses Prefetching In the first iteration through the pointer chasing loop there is no prefetching (initializing prefetch pointers). If the traversal is known, the history pointers can be initialized as the data structure is allocated. Eliminate compulsory cache misses

Possible Clients of the Analysis Modify Data Layout Memory Allocation Calder et al. [4] and Chilimbi, Hill and Larus [6] Create a custom allocator or a reallocation method that (re)organizes the data structure. Manual & semi-automatic techniques. Automatically insert the allocation calls with a hint from our analysis. Modify Data Layout Memory Allocation Calder et al. [4] and Chilimbi, Hill and Larus [6] Create a custom allocator or a reallocation method that (re)organizes the data structure. Manual & semi-automatic techniques. Automatically insert the allocation calls with a hint from our analysis.

Possible Clients of the Analysis Modify Data Layout Structure Reorganization Truong, Bodin and Seznec [8] Chilimbi, Davidson and Larus [5] Use analysis information with Chilimbi’s data outlining or Truong’s ialloc memory allocator to improve spatial locality. Modify Data Layout Structure Reorganization Truong, Bodin and Seznec [8] Chilimbi, Davidson and Larus [5] Use analysis information with Chilimbi’s data outlining or Truong’s ialloc memory allocator to improve spatial locality.

Conclusion Developed an efficient analysis to automatically determine the orientation of tree traversals. Instrumented applications only require 7% more memory. There are many clients for this analysis that can potentially improve program performance. Developed an efficient analysis to automatically determine the orientation of tree traversals. Instrumented applications only require 7% more memory. There are many clients for this analysis that can potentially improve program performance.

Questions?

References [1] J. Patterson. Modern Microprocessors A 90 Minute Guide! [2] R. Ghiya and L. J. Hendren. Is it a tree, a dag, or a cyclic graph? A shape analysis for heap directed pointers in C. POPL 1996 [3] B.Cahoon and K.S. McKinley. Data flow analysis for software prefetching linked data structures in Java. PACT ‘01 [4] B.Calder, C. Krintz, S. John, T. Austin. Cache-conscious data placement. ASPLOS-VIII, 1998 [5] T.M. Chilimbi, B. Davidson and J.R. Larus. Cache-conscious structure definition. PLDI ‘99 [6] T.M. Chilimbi, M.D. Hill and J.R. Larus. Cache-conscious structure layout. PLDI ‘99 [7] C.K. Luk and T.C. Mowry. Compiler-based prefetching for recursive data structures. ACM SIGOPS Operating Systems Review, [8] D.N. Truong, F. Bodin and A. Seznec. Improving cache behavior of dynamically allocated data structures. PACT ‘98 [1] J. Patterson. Modern Microprocessors A 90 Minute Guide! [2] R. Ghiya and L. J. Hendren. Is it a tree, a dag, or a cyclic graph? A shape analysis for heap directed pointers in C. POPL 1996 [3] B.Cahoon and K.S. McKinley. Data flow analysis for software prefetching linked data structures in Java. PACT ‘01 [4] B.Calder, C. Krintz, S. John, T. Austin. Cache-conscious data placement. ASPLOS-VIII, 1998 [5] T.M. Chilimbi, B. Davidson and J.R. Larus. Cache-conscious structure definition. PLDI ‘99 [6] T.M. Chilimbi, M.D. Hill and J.R. Larus. Cache-conscious structure layout. PLDI ‘99 [7] C.K. Luk and T.C. Mowry. Compiler-based prefetching for recursive data structures. ACM SIGOPS Operating Systems Review, [8] D.N. Truong, F. Bodin and A. Seznec. Improving cache behavior of dynamically allocated data structures. PACT ‘98