target-supports.exp (check_effective_target_mips_soft_float): Return true for MIPS16...
[official-gcc.git] / gcc / matrix-reorg.c
blob38b0d5e146b8d03472bab1b1a699a5eb81b17664
1 /* Matrix layout transformations.
2 Copyright (C) 2006, 2007 Free Software Foundation, Inc.
3 Contributed by Razya Ladelsky <razya@il.ibm.com>
4 Originally written by Revital Eres and Mustafa Hagog.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
23 Matrix flattening optimization tries to replace a N-dimensional
24 matrix with its equivalent M-dimensional matrix, where M < N.
25 This first implementation focuses on global matrices defined dynamically.
27 When N==1, we actually flatten the whole matrix.
28 For instance consider a two-dimensional array a [dim1] [dim2].
29 The code for allocating space for it usually looks like:
31 a = (int **) malloc(dim1 * sizeof(int *));
32 for (i=0; i<dim1; i++)
33 a[i] = (int *) malloc (dim2 * sizeof(int));
35 If the array "a" is found suitable for this optimization,
36 its allocation is replaced by:
38 a = (int *) malloc (dim1 * dim2 *sizeof(int));
40 and all the references to a[i][j] are replaced by a[i * dim2 + j].
42 The two main phases of the optimization are the analysis
43 and transformation.
44 The driver of the optimization is matrix_reorg ().
48 Analysis phase:
49 ===============
51 We'll number the dimensions outside-in, meaning the most external
52 is 0, then 1, and so on.
53 The analysis part of the optimization determines K, the escape
54 level of a N-dimensional matrix (K <= N), that allows flattening of
55 the external dimensions 0,1,..., K-1. Escape level 0 means that the
56 whole matrix escapes and no flattening is possible.
58 The analysis part is implemented in analyze_matrix_allocation_site()
59 and analyze_matrix_accesses().
61 Transformation phase:
62 =====================
63 In this phase we define the new flattened matrices that replace the
64 original matrices in the code.
65 Implemented in transform_allocation_sites(),
66 transform_access_sites().
68 Matrix Transposing
69 ==================
70 The idea of Matrix Transposing is organizing the matrix in a different
71 layout such that the dimensions are reordered.
72 This could produce better cache behavior in some cases.
74 For example, lets look at the matrix accesses in the following loop:
76 for (i=0; i<N; i++)
77 for (j=0; j<M; j++)
78 access to a[i][j]
80 This loop can produce good cache behavior because the elements of
81 the inner dimension are accessed sequentially.
83 However, if the accesses of the matrix were of the following form:
85 for (i=0; i<N; i++)
86 for (j=0; j<M; j++)
87 access to a[j][i]
89 In this loop we iterate the columns and not the rows.
90 Therefore, replacing the rows and columns
91 would have had an organization with better (cache) locality.
92 Replacing the dimensions of the matrix is called matrix transposing.
94 This example, of course, could be enhanced to multiple dimensions matrices
95 as well.
97 Since a program could include all kind of accesses, there is a decision
98 mechanism, implemented in analyze_transpose(), which implements a
99 heuristic that tries to determine whether to transpose the matrix or not,
100 according to the form of the more dominant accesses.
101 This decision is transferred to the flattening mechanism, and whether
102 the matrix was transposed or not, the matrix is flattened (if possible).
104 This decision making is based on profiling information and loop information.
105 If profiling information is available, decision making mechanism will be
106 operated, otherwise the matrix will only be flattened (if possible).
108 Both optimizations are described in the paper "Matrix flattening and
109 transposing in GCC" which was presented in GCC summit 2006.
110 http://www.gccsummit.org/2006/2006-GCC-Summit-Proceedings.pdf
114 #include "config.h"
115 #include "system.h"
116 #include "coretypes.h"
117 #include "tm.h"
118 #include "tree.h"
119 #include "rtl.h"
120 #include "c-tree.h"
121 #include "tree-inline.h"
122 #include "tree-flow.h"
123 #include "tree-flow-inline.h"
124 #include "langhooks.h"
125 #include "hashtab.h"
126 #include "toplev.h"
127 #include "flags.h"
128 #include "ggc.h"
129 #include "debug.h"
130 #include "target.h"
131 #include "cgraph.h"
132 #include "diagnostic.h"
133 #include "timevar.h"
134 #include "params.h"
135 #include "fibheap.h"
136 #include "c-common.h"
137 #include "intl.h"
138 #include "function.h"
139 #include "basic-block.h"
140 #include "cfgloop.h"
141 #include "tree-iterator.h"
142 #include "tree-pass.h"
143 #include "opts.h"
144 #include "tree-data-ref.h"
145 #include "tree-chrec.h"
146 #include "tree-scalar-evolution.h"
149 We need to collect a lot of data from the original malloc,
150 particularly as the gimplifier has converted:
152 orig_var = (struct_type *) malloc (x * sizeof (struct_type *));
154 into
156 T3 = <constant> ; ** <constant> is amount to malloc; precomputed **
157 T4 = malloc (T3);
158 T5 = (struct_type *) T4;
159 orig_var = T5;
161 The following struct fields allow us to collect all the necessary data from
162 the gimplified program. The comments in the struct below are all based
163 on the gimple example above. */
165 struct malloc_call_data
167 tree call_stmt; /* Tree for "T4 = malloc (T3);" */
168 tree size_var; /* Var decl for T3. */
169 tree malloc_size; /* Tree for "<constant>", the rhs assigned to T3. */
172 /* The front end of the compiler, when parsing statements of the form:
174 var = (type_cast) malloc (sizeof (type));
176 always converts this single statement into the following statements
177 (GIMPLE form):
179 T.1 = sizeof (type);
180 T.2 = malloc (T.1);
181 T.3 = (type_cast) T.2;
182 var = T.3;
184 Since we need to create new malloc statements and modify the original
185 statements somewhat, we need to find all four of the above statements.
186 Currently record_call_1 (called for building cgraph edges) finds and
187 records the statements containing the actual call to malloc, but we
188 need to find the rest of the variables/statements on our own. That
189 is what the following function does. */
190 static void
191 collect_data_for_malloc_call (tree stmt, struct malloc_call_data *m_data)
193 tree size_var = NULL;
194 tree malloc_fn_decl;
195 tree tmp;
196 tree arg1;
198 gcc_assert (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT);
200 tmp = get_call_expr_in (stmt);
201 malloc_fn_decl = CALL_EXPR_FN (tmp);
202 if (TREE_CODE (malloc_fn_decl) != ADDR_EXPR
203 || TREE_CODE (TREE_OPERAND (malloc_fn_decl, 0)) != FUNCTION_DECL
204 || DECL_FUNCTION_CODE (TREE_OPERAND (malloc_fn_decl, 0)) !=
205 BUILT_IN_MALLOC)
206 return;
208 arg1 = CALL_EXPR_ARG (tmp, 0);
209 size_var = arg1;
211 m_data->call_stmt = stmt;
212 m_data->size_var = size_var;
213 if (TREE_CODE (size_var) != VAR_DECL)
214 m_data->malloc_size = size_var;
215 else
216 m_data->malloc_size = NULL_TREE;
219 /* Information about matrix access site.
220 For example: if an access site of matrix arr is arr[i][j]
221 the ACCESS_SITE_INFO structure will have the address
222 of arr as its stmt. The INDEX_INFO will hold information about the
223 initial address and index of each dimension. */
224 struct access_site_info
226 /* The statement (INDIRECT_REF or POINTER_PLUS_EXPR). */
227 tree stmt;
229 /* In case of POINTER_PLUS_EXPR, what is the offset. */
230 tree offset;
232 /* The index which created the offset. */
233 tree index;
235 /* The indirection level of this statement. */
236 int level;
238 /* TRUE for allocation site FALSE for access site. */
239 bool is_alloc;
241 /* The function containing the access site. */
242 tree function_decl;
244 /* This access is iterated in the inner most loop */
245 bool iterated_by_inner_most_loop_p;
248 typedef struct access_site_info *access_site_info_p;
249 DEF_VEC_P (access_site_info_p);
250 DEF_VEC_ALLOC_P (access_site_info_p, heap);
252 /* Information about matrix to flatten. */
253 struct matrix_info
255 /* Decl tree of this matrix. */
256 tree decl;
257 /* Number of dimensions; number
258 of "*" in the type declaration. */
259 int num_dims;
261 /* Minimum indirection level that escapes, 0 means that
262 the whole matrix escapes, k means that dimensions
263 0 to ACTUAL_DIM - k escapes. */
264 int min_indirect_level_escape;
266 tree min_indirect_level_escape_stmt;
268 /* Is the matrix transposed. */
269 bool is_transposed_p;
271 /* Hold the allocation site for each level (dimension).
272 We can use NUM_DIMS as the upper bound and allocate the array
273 once with this number of elements and no need to use realloc and
274 MAX_MALLOCED_LEVEL. */
275 tree *malloc_for_level;
277 int max_malloced_level;
279 /* The location of the allocation sites (they must be in one
280 function). */
281 tree allocation_function_decl;
283 /* The calls to free for each level of indirection. */
284 struct free_info
286 tree stmt;
287 tree func;
288 } *free_stmts;
290 /* An array which holds for each dimension its size. where
291 dimension 0 is the outer most (one that contains all the others).
293 tree *dimension_size;
295 /* An array which holds for each dimension it's original size
296 (before transposing and flattening take place). */
297 tree *dimension_size_orig;
299 /* An array which holds for each dimension the size of the type of
300 of elements accessed in that level (in bytes). */
301 HOST_WIDE_INT *dimension_type_size;
303 int dimension_type_size_len;
305 /* An array collecting the count of accesses for each dimension. */
306 gcov_type *dim_hot_level;
308 /* An array of the accesses to be flattened.
309 elements are of type "struct access_site_info *". */
310 VEC (access_site_info_p, heap) * access_l;
312 /* A map of how the dimensions will be organized at the end of
313 the analyses. */
314 int *dim_map;
317 /* In each phi node we want to record the indirection level we have when we
318 get to the phi node. Usually we will have phi nodes with more than two
319 arguments, then we must assure that all of them get to the phi node with
320 the same indirection level, otherwise it's not safe to do the flattening.
321 So we record the information regarding the indirection level each time we
322 get to the phi node in this hash table. */
324 struct matrix_access_phi_node
326 tree phi;
327 int indirection_level;
330 /* We use this structure to find if the SSA variable is accessed inside the
331 tree and record the tree containing it. */
333 struct ssa_acc_in_tree
335 /* The variable whose accesses in the tree we are looking for. */
336 tree ssa_var;
337 /* The tree and code inside it the ssa_var is accessed, currently
338 it could be an INDIRECT_REF or CALL_EXPR. */
339 enum tree_code t_code;
340 tree t_tree;
341 /* The place in the containing tree. */
342 tree *tp;
343 tree second_op;
344 bool var_found;
347 static void analyze_matrix_accesses (struct matrix_info *, tree, int, bool,
348 sbitmap, bool);
349 static int transform_allocation_sites (void **, void *);
350 static int transform_access_sites (void **, void *);
351 static int analyze_transpose (void **, void *);
352 static int dump_matrix_reorg_analysis (void **, void *);
354 static bool check_transpose_p;
356 /* Hash function used for the phi nodes. */
358 static hashval_t
359 mat_acc_phi_hash (const void *p)
361 const struct matrix_access_phi_node *ma_phi = p;
363 return htab_hash_pointer (ma_phi->phi);
366 /* Equality means phi node pointers are the same. */
368 static int
369 mat_acc_phi_eq (const void *p1, const void *p2)
371 const struct matrix_access_phi_node *phi1 = p1;
372 const struct matrix_access_phi_node *phi2 = p2;
374 if (phi1->phi == phi2->phi)
375 return 1;
377 return 0;
380 /* Hold the PHI nodes we visit during the traversal for escaping
381 analysis. */
382 static htab_t htab_mat_acc_phi_nodes = NULL;
384 /* This hash-table holds the information about the matrices we are
385 going to handle. */
386 static htab_t matrices_to_reorg = NULL;
388 /* Return a hash for MTT, which is really a "matrix_info *". */
389 static hashval_t
390 mtt_info_hash (const void *mtt)
392 return htab_hash_pointer (((const struct matrix_info *) mtt)->decl);
395 /* Return true if MTT1 and MTT2 (which are really both of type
396 "matrix_info *") refer to the same decl. */
397 static int
398 mtt_info_eq (const void *mtt1, const void *mtt2)
400 const struct matrix_info *i1 = mtt1;
401 const struct matrix_info *i2 = mtt2;
403 if (i1->decl == i2->decl)
404 return true;
406 return false;
409 /* Return the inner most tree that is not a cast. */
410 static tree
411 get_inner_of_cast_expr (tree t)
413 while (TREE_CODE (t) == CONVERT_EXPR || TREE_CODE (t) == NOP_EXPR
414 || TREE_CODE (t) == VIEW_CONVERT_EXPR)
415 t = TREE_OPERAND (t, 0);
417 return t;
420 /* Return false if STMT may contain a vector expression.
421 In this situation, all matrices should not be flattened. */
422 static bool
423 may_flatten_matrices_1 (tree stmt)
425 tree t;
427 switch (TREE_CODE (stmt))
429 case GIMPLE_MODIFY_STMT:
430 t = GIMPLE_STMT_OPERAND (stmt, 1);
431 while (TREE_CODE (t) == CONVERT_EXPR || TREE_CODE (t) == NOP_EXPR)
433 if (TREE_TYPE (t) && POINTER_TYPE_P (TREE_TYPE (t)))
435 tree pointee;
437 pointee = TREE_TYPE (t);
438 while (POINTER_TYPE_P (pointee))
439 pointee = TREE_TYPE (pointee);
440 if (TREE_CODE (pointee) == VECTOR_TYPE)
442 if (dump_file)
443 fprintf (dump_file,
444 "Found vector type, don't flatten matrix\n");
445 return false;
448 t = TREE_OPERAND (t, 0);
450 break;
451 case ASM_EXPR:
452 /* Asm code could contain vector operations. */
453 return false;
454 break;
455 default:
456 break;
458 return true;
461 /* Return false if there are hand-written vectors in the program.
462 We disable the flattening in such a case. */
463 static bool
464 may_flatten_matrices (struct cgraph_node *node)
466 tree decl;
467 struct function *func;
468 basic_block bb;
469 block_stmt_iterator bsi;
471 decl = node->decl;
472 if (node->analyzed)
474 func = DECL_STRUCT_FUNCTION (decl);
475 FOR_EACH_BB_FN (bb, func)
476 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
477 if (!may_flatten_matrices_1 (bsi_stmt (bsi)))
478 return false;
480 return true;
483 /* Given a VAR_DECL, check its type to determine whether it is
484 a definition of a dynamic allocated matrix and therefore is
485 a suitable candidate for the matrix flattening optimization.
486 Return NULL if VAR_DECL is not such decl. Otherwise, allocate
487 a MATRIX_INFO structure, fill it with the relevant information
488 and return a pointer to it.
489 TODO: handle also statically defined arrays. */
490 static struct matrix_info *
491 analyze_matrix_decl (tree var_decl)
493 struct matrix_info *m_node, tmpmi, *mi;
494 tree var_type;
495 int dim_num = 0;
497 gcc_assert (matrices_to_reorg);
499 if (TREE_CODE (var_decl) == PARM_DECL)
500 var_type = DECL_ARG_TYPE (var_decl);
501 else if (TREE_CODE (var_decl) == VAR_DECL)
502 var_type = TREE_TYPE (var_decl);
503 else
504 return NULL;
506 if (!POINTER_TYPE_P (var_type))
507 return NULL;
509 while (POINTER_TYPE_P (var_type))
511 var_type = TREE_TYPE (var_type);
512 dim_num++;
515 if (dim_num <= 1)
516 return NULL;
518 if (!COMPLETE_TYPE_P (var_type)
519 || TREE_CODE (TYPE_SIZE_UNIT (var_type)) != INTEGER_CST)
520 return NULL;
522 /* Check to see if this pointer is already in there. */
523 tmpmi.decl = var_decl;
524 mi = htab_find (matrices_to_reorg, &tmpmi);
526 if (mi)
527 return NULL;
529 /* Record the matrix. */
531 m_node = (struct matrix_info *) xcalloc (1, sizeof (struct matrix_info));
532 m_node->decl = var_decl;
533 m_node->num_dims = dim_num;
534 m_node->free_stmts
535 = (struct free_info *) xcalloc (dim_num, sizeof (struct free_info));
537 /* Init min_indirect_level_escape to -1 to indicate that no escape
538 analysis has been done yet. */
539 m_node->min_indirect_level_escape = -1;
540 m_node->is_transposed_p = false;
542 return m_node;
545 /* Free matrix E. */
546 static void
547 mat_free (void *e)
549 struct matrix_info *mat = (struct matrix_info *) e;
551 if (!mat)
552 return;
554 if (mat->free_stmts)
555 free (mat->free_stmts);
556 if (mat->dim_hot_level)
557 free (mat->dim_hot_level);
558 if (mat->malloc_for_level)
559 free (mat->malloc_for_level);
562 /* Find all potential matrices.
563 TODO: currently we handle only multidimensional
564 dynamically allocated arrays. */
565 static void
566 find_matrices_decl (void)
568 struct matrix_info *tmp;
569 PTR *slot;
570 struct varpool_node *vnode;
572 gcc_assert (matrices_to_reorg);
574 /* For every global variable in the program:
575 Check to see if it's of a candidate type and record it. */
576 for (vnode = varpool_nodes_queue; vnode; vnode = vnode->next_needed)
578 tree var_decl = vnode->decl;
580 if (!var_decl || TREE_CODE (var_decl) != VAR_DECL)
581 continue;
583 if (matrices_to_reorg)
584 if ((tmp = analyze_matrix_decl (var_decl)))
586 if (!TREE_ADDRESSABLE (var_decl))
588 slot = htab_find_slot (matrices_to_reorg, tmp, INSERT);
589 *slot = tmp;
593 return;
596 /* Mark that the matrix MI escapes at level L. */
597 static void
598 mark_min_matrix_escape_level (struct matrix_info *mi, int l, tree s)
600 if (mi->min_indirect_level_escape == -1
601 || (mi->min_indirect_level_escape > l))
603 mi->min_indirect_level_escape = l;
604 mi->min_indirect_level_escape_stmt = s;
608 /* Find if the SSA variable is accessed inside the
609 tree and record the tree containing it.
610 The only relevant uses are the case of SSA_NAME, or SSA inside
611 INDIRECT_REF, CALL_EXPR, PLUS_EXPR, POINTER_PLUS_EXPR, MULT_EXPR. */
612 static void
613 ssa_accessed_in_tree (tree t, struct ssa_acc_in_tree *a)
615 tree call, decl;
616 tree arg;
617 call_expr_arg_iterator iter;
619 a->t_code = TREE_CODE (t);
620 switch (a->t_code)
622 tree op1, op2;
624 case SSA_NAME:
625 if (t == a->ssa_var)
626 a->var_found = true;
627 break;
628 case INDIRECT_REF:
629 if (SSA_VAR_P (TREE_OPERAND (t, 0))
630 && TREE_OPERAND (t, 0) == a->ssa_var)
631 a->var_found = true;
632 break;
633 case CALL_EXPR:
634 FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
636 if (arg == a->ssa_var)
638 a->var_found = true;
639 call = get_call_expr_in (t);
640 if (call && (decl = get_callee_fndecl (call)))
641 a->t_tree = decl;
642 break;
645 break;
646 case POINTER_PLUS_EXPR:
647 case PLUS_EXPR:
648 case MULT_EXPR:
649 op1 = TREE_OPERAND (t, 0);
650 op2 = TREE_OPERAND (t, 1);
652 if (op1 == a->ssa_var)
654 a->var_found = true;
655 a->second_op = op2;
657 else if (op2 == a->ssa_var)
659 a->var_found = true;
660 a->second_op = op1;
662 break;
663 default:
664 break;
668 /* Record the access/allocation site information for matrix MI so we can
669 handle it later in transformation. */
670 static void
671 record_access_alloc_site_info (struct matrix_info *mi, tree stmt, tree offset,
672 tree index, int level, bool is_alloc)
674 struct access_site_info *acc_info;
676 if (!mi->access_l)
677 mi->access_l = VEC_alloc (access_site_info_p, heap, 100);
679 acc_info
680 = (struct access_site_info *)
681 xcalloc (1, sizeof (struct access_site_info));
682 acc_info->stmt = stmt;
683 acc_info->offset = offset;
684 acc_info->index = index;
685 acc_info->function_decl = current_function_decl;
686 acc_info->level = level;
687 acc_info->is_alloc = is_alloc;
689 VEC_safe_push (access_site_info_p, heap, mi->access_l, acc_info);
693 /* Record the malloc as the allocation site of the given LEVEL. But
694 first we Make sure that all the size parameters passed to malloc in
695 all the allocation sites could be pre-calculated before the call to
696 the malloc of level 0 (the main malloc call). */
697 static void
698 add_allocation_site (struct matrix_info *mi, tree stmt, int level)
700 struct malloc_call_data mcd;
702 /* Make sure that the allocation sites are in the same function. */
703 if (!mi->allocation_function_decl)
704 mi->allocation_function_decl = current_function_decl;
705 else if (mi->allocation_function_decl != current_function_decl)
707 int min_malloc_level;
709 gcc_assert (mi->malloc_for_level);
711 /* Find the minimum malloc level that already has been seen;
712 we known its allocation function must be
713 MI->allocation_function_decl since it's different than
714 CURRENT_FUNCTION_DECL then the escaping level should be
715 MIN (LEVEL, MIN_MALLOC_LEVEL) - 1 , and the allocation function
716 must be set accordingly. */
717 for (min_malloc_level = 0;
718 min_malloc_level < mi->max_malloced_level
719 && mi->malloc_for_level[min_malloc_level]; min_malloc_level++);
720 if (level < min_malloc_level)
722 mi->allocation_function_decl = current_function_decl;
723 mark_min_matrix_escape_level (mi, min_malloc_level, stmt);
725 else
727 mark_min_matrix_escape_level (mi, level, stmt);
728 /* cannot be that (level == min_malloc_level)
729 we would have returned earlier. */
730 return;
734 /* Find the correct malloc information. */
735 collect_data_for_malloc_call (stmt, &mcd);
737 /* We accept only calls to malloc function; we do not accept
738 calls like calloc and realloc. */
739 if (!mi->malloc_for_level)
741 mi->malloc_for_level = xcalloc (level + 1, sizeof (tree));
742 mi->max_malloced_level = level + 1;
744 else if (mi->max_malloced_level <= level)
746 mi->malloc_for_level
747 = xrealloc (mi->malloc_for_level, (level + 1) * sizeof (tree));
749 /* Zero the newly allocated items. */
750 memset (&(mi->malloc_for_level[mi->max_malloced_level + 1]),
751 0, (level - mi->max_malloced_level) * sizeof (tree));
753 mi->max_malloced_level = level + 1;
755 mi->malloc_for_level[level] = stmt;
758 /* Given an assignment statement STMT that we know that its
759 left-hand-side is the matrix MI variable, we traverse the immediate
760 uses backwards until we get to a malloc site. We make sure that
761 there is one and only one malloc site that sets this variable. When
762 we are performing the flattening we generate a new variable that
763 will hold the size for each dimension; each malloc that allocates a
764 dimension has the size parameter; we use that parameter to
765 initialize the dimension size variable so we can use it later in
766 the address calculations. LEVEL is the dimension we're inspecting.
767 Return if STMT is related to an allocation site. */
769 static void
770 analyze_matrix_allocation_site (struct matrix_info *mi, tree stmt,
771 int level, sbitmap visited)
773 if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
775 tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
777 rhs = get_inner_of_cast_expr (rhs);
778 if (TREE_CODE (rhs) == SSA_NAME)
780 tree def = SSA_NAME_DEF_STMT (rhs);
782 analyze_matrix_allocation_site (mi, def, level, visited);
783 return;
786 /* A result of call to malloc. */
787 else if (TREE_CODE (rhs) == CALL_EXPR)
789 int call_flags = call_expr_flags (rhs);
791 if (!(call_flags & ECF_MALLOC))
793 mark_min_matrix_escape_level (mi, level, stmt);
794 return;
796 else
798 tree malloc_fn_decl;
799 const char *malloc_fname;
801 malloc_fn_decl = CALL_EXPR_FN (rhs);
802 if (TREE_CODE (malloc_fn_decl) != ADDR_EXPR
803 || TREE_CODE (TREE_OPERAND (malloc_fn_decl, 0)) !=
804 FUNCTION_DECL)
806 mark_min_matrix_escape_level (mi, level, stmt);
807 return;
809 malloc_fn_decl = TREE_OPERAND (malloc_fn_decl, 0);
810 malloc_fname = IDENTIFIER_POINTER (DECL_NAME (malloc_fn_decl));
811 if (DECL_FUNCTION_CODE (malloc_fn_decl) != BUILT_IN_MALLOC)
813 if (dump_file)
814 fprintf (dump_file,
815 "Matrix %s is an argument to function %s\n",
816 get_name (mi->decl), get_name (malloc_fn_decl));
817 mark_min_matrix_escape_level (mi, level, stmt);
818 return;
821 /* This is a call to malloc of level 'level'.
822 mi->max_malloced_level-1 == level means that we've
823 seen a malloc statement of level 'level' before.
824 If the statement is not the same one that we've
825 seen before, then there's another malloc statement
826 for the same level, which means that we need to mark
827 it escaping. */
828 if (mi->malloc_for_level
829 && mi->max_malloced_level-1 == level
830 && mi->malloc_for_level[level] != stmt)
832 mark_min_matrix_escape_level (mi, level, stmt);
833 return;
835 else
836 add_allocation_site (mi, stmt, level);
837 return;
839 /* If we are back to the original matrix variable then we
840 are sure that this is analyzed as an access site. */
841 else if (rhs == mi->decl)
842 return;
844 /* Looks like we don't know what is happening in this
845 statement so be in the safe side and mark it as escaping. */
846 mark_min_matrix_escape_level (mi, level, stmt);
849 /* The transposing decision making.
850 In order to to calculate the profitability of transposing, we collect two
851 types of information regarding the accesses:
852 1. profiling information used to express the hotness of an access, that
853 is how often the matrix is accessed by this access site (count of the
854 access site).
855 2. which dimension in the access site is iterated by the inner
856 most loop containing this access.
858 The matrix will have a calculated value of weighted hotness for each
859 dimension.
860 Intuitively the hotness level of a dimension is a function of how
861 many times it was the most frequently accessed dimension in the
862 highly executed access sites of this matrix.
864 As computed by following equation:
865 m n
866 __ __
867 \ \ dim_hot_level[i] +=
868 /_ /_
869 j i
870 acc[j]->dim[i]->iter_by_inner_loop * count(j)
872 Where n is the number of dims and m is the number of the matrix
873 access sites. acc[j]->dim[i]->iter_by_inner_loop is 1 if acc[j]
874 iterates over dim[i] in innermost loop, and is 0 otherwise.
876 The organization of the new matrix should be according to the
877 hotness of each dimension. The hotness of the dimension implies
878 the locality of the elements.*/
879 static int
880 analyze_transpose (void **slot, void *data ATTRIBUTE_UNUSED)
882 struct matrix_info *mi = *slot;
883 int min_escape_l = mi->min_indirect_level_escape;
884 struct loop *loop;
885 affine_iv iv;
886 struct access_site_info *acc_info;
887 int i;
889 if (min_escape_l < 2 || !mi->access_l)
891 if (mi->access_l)
893 for (i = 0;
894 VEC_iterate (access_site_info_p, mi->access_l, i, acc_info);
895 i++)
896 free (acc_info);
897 VEC_free (access_site_info_p, heap, mi->access_l);
900 return 1;
902 if (!mi->dim_hot_level)
903 mi->dim_hot_level =
904 (gcov_type *) xcalloc (min_escape_l, sizeof (gcov_type));
907 for (i = 0; VEC_iterate (access_site_info_p, mi->access_l, i, acc_info);
908 i++)
910 if (TREE_CODE (GIMPLE_STMT_OPERAND (acc_info->stmt, 1)) == POINTER_PLUS_EXPR
911 && acc_info->level < min_escape_l)
913 loop = loop_containing_stmt (acc_info->stmt);
914 if (!loop || loop->inner)
916 free (acc_info);
917 continue;
919 if (simple_iv (loop, acc_info->stmt, acc_info->offset, &iv, true))
921 if (iv.step != NULL)
923 HOST_WIDE_INT istep;
925 istep = int_cst_value (iv.step);
926 if (istep != 0)
928 acc_info->iterated_by_inner_most_loop_p = 1;
929 mi->dim_hot_level[acc_info->level] +=
930 bb_for_stmt (acc_info->stmt)->count;
936 free (acc_info);
938 VEC_free (access_site_info_p, heap, mi->access_l);
940 return 1;
943 /* Find the index which defines the OFFSET from base.
944 We walk from use to def until we find how the offset was defined. */
945 static tree
946 get_index_from_offset (tree offset, tree def_stmt)
948 tree op1, op2, expr, index;
950 if (TREE_CODE (def_stmt) == PHI_NODE)
951 return NULL;
952 expr = get_inner_of_cast_expr (GIMPLE_STMT_OPERAND (def_stmt, 1));
953 if (TREE_CODE (expr) == SSA_NAME)
954 return get_index_from_offset (offset, SSA_NAME_DEF_STMT (expr));
955 else if (TREE_CODE (expr) == MULT_EXPR)
957 op1 = TREE_OPERAND (expr, 0);
958 op2 = TREE_OPERAND (expr, 1);
959 if (TREE_CODE (op1) != INTEGER_CST && TREE_CODE (op2) != INTEGER_CST)
960 return NULL;
961 index = (TREE_CODE (op1) == INTEGER_CST) ? op2 : op1;
962 return index;
964 else
965 return NULL_TREE;
968 /* update MI->dimension_type_size[CURRENT_INDIRECT_LEVEL] with the size
969 of the type related to the SSA_VAR, or the type related to the
970 lhs of STMT, in the case that it is an INDIRECT_REF. */
971 static void
972 update_type_size (struct matrix_info *mi, tree stmt, tree ssa_var,
973 int current_indirect_level)
975 tree lhs;
976 HOST_WIDE_INT type_size;
978 /* Update type according to the type of the INDIRECT_REF expr. */
979 if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
980 && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == INDIRECT_REF)
982 lhs = GIMPLE_STMT_OPERAND (stmt, 0);
983 gcc_assert (POINTER_TYPE_P
984 (TREE_TYPE (SSA_NAME_VAR (TREE_OPERAND (lhs, 0)))));
985 type_size =
986 int_size_in_bytes (TREE_TYPE
987 (TREE_TYPE
988 (SSA_NAME_VAR (TREE_OPERAND (lhs, 0)))));
990 else
991 type_size = int_size_in_bytes (TREE_TYPE (ssa_var));
993 /* Record the size of elements accessed (as a whole)
994 in the current indirection level (dimension). If the size of
995 elements is not known at compile time, mark it as escaping. */
996 if (type_size <= 0)
997 mark_min_matrix_escape_level (mi, current_indirect_level, stmt);
998 else
1000 int l = current_indirect_level;
1002 if (!mi->dimension_type_size)
1004 mi->dimension_type_size
1005 = (HOST_WIDE_INT *) xcalloc (l + 1, sizeof (HOST_WIDE_INT));
1006 mi->dimension_type_size_len = l + 1;
1008 else if (mi->dimension_type_size_len < l + 1)
1010 mi->dimension_type_size
1011 = (HOST_WIDE_INT *) xrealloc (mi->dimension_type_size,
1012 (l + 1) * sizeof (HOST_WIDE_INT));
1013 memset (&mi->dimension_type_size[mi->dimension_type_size_len],
1014 0, (l + 1 - mi->dimension_type_size_len)
1015 * sizeof (HOST_WIDE_INT));
1016 mi->dimension_type_size_len = l + 1;
1018 /* Make sure all the accesses in the same level have the same size
1019 of the type. */
1020 if (!mi->dimension_type_size[l])
1021 mi->dimension_type_size[l] = type_size;
1022 else if (mi->dimension_type_size[l] != type_size)
1023 mark_min_matrix_escape_level (mi, l, stmt);
1027 /* USE_STMT represents a call_expr ,where one of the arguments is the
1028 ssa var that we want to check because it came from some use of matrix
1029 MI. CURRENT_INDIRECT_LEVEL is the indirection level we reached so
1030 far. */
1032 static void
1033 analyze_accesses_for_call_expr (struct matrix_info *mi, tree use_stmt,
1034 int current_indirect_level)
1036 tree call = get_call_expr_in (use_stmt);
1037 if (call && get_callee_fndecl (call))
1039 if (DECL_FUNCTION_CODE (get_callee_fndecl (call)) != BUILT_IN_FREE)
1041 if (dump_file)
1042 fprintf (dump_file,
1043 "Matrix %s: Function call %s, level %d escapes.\n",
1044 get_name (mi->decl), get_name (get_callee_fndecl (call)),
1045 current_indirect_level);
1046 mark_min_matrix_escape_level (mi, current_indirect_level, use_stmt);
1048 else if (mi->free_stmts[current_indirect_level].stmt != NULL
1049 && mi->free_stmts[current_indirect_level].stmt != use_stmt)
1050 mark_min_matrix_escape_level (mi, current_indirect_level, use_stmt);
1051 else
1053 /*Record the free statements so we can delete them
1054 later. */
1055 int l = current_indirect_level;
1057 mi->free_stmts[l].stmt = use_stmt;
1058 mi->free_stmts[l].func = current_function_decl;
1063 /* USE_STMT represents a phi node of the ssa var that we want to
1064 check because it came from some use of matrix
1066 We check all the escaping levels that get to the PHI node
1067 and make sure they are all the same escaping;
1068 if not (which is rare) we let the escaping level be the
1069 minimum level that gets into that PHI because starting from
1070 that level we cannot expect the behavior of the indirections.
1071 CURRENT_INDIRECT_LEVEL is the indirection level we reached so far. */
1073 static void
1074 analyze_accesses_for_phi_node (struct matrix_info *mi, tree use_stmt,
1075 int current_indirect_level, sbitmap visited,
1076 bool record_accesses)
1079 struct matrix_access_phi_node tmp_maphi, *maphi, **pmaphi;
1081 tmp_maphi.phi = use_stmt;
1082 if ((maphi = htab_find (htab_mat_acc_phi_nodes, &tmp_maphi)))
1084 if (maphi->indirection_level == current_indirect_level)
1085 return;
1086 else
1088 int level = MIN (maphi->indirection_level,
1089 current_indirect_level);
1090 int j;
1091 tree t = NULL_TREE;
1093 maphi->indirection_level = level;
1094 for (j = 0; j < PHI_NUM_ARGS (use_stmt); j++)
1096 tree def = PHI_ARG_DEF (use_stmt, j);
1098 if (TREE_CODE (SSA_NAME_DEF_STMT (def)) != PHI_NODE)
1099 t = SSA_NAME_DEF_STMT (def);
1101 mark_min_matrix_escape_level (mi, level, t);
1103 return;
1105 maphi = (struct matrix_access_phi_node *)
1106 xcalloc (1, sizeof (struct matrix_access_phi_node));
1107 maphi->phi = use_stmt;
1108 maphi->indirection_level = current_indirect_level;
1110 /* Insert to hash table. */
1111 pmaphi = (struct matrix_access_phi_node **)
1112 htab_find_slot (htab_mat_acc_phi_nodes, maphi, INSERT);
1113 gcc_assert (pmaphi);
1114 *pmaphi = maphi;
1116 if (!TEST_BIT (visited, SSA_NAME_VERSION (PHI_RESULT (use_stmt))))
1118 SET_BIT (visited, SSA_NAME_VERSION (PHI_RESULT (use_stmt)));
1119 analyze_matrix_accesses (mi, PHI_RESULT (use_stmt),
1120 current_indirect_level, false, visited,
1121 record_accesses);
1122 RESET_BIT (visited, SSA_NAME_VERSION (PHI_RESULT (use_stmt)));
1126 /* USE_STMT represents a modify statement (the rhs or lhs include
1127 the ssa var that we want to check because it came from some use of matrix
1129 CURRENT_INDIRECT_LEVEL is the indirection level we reached so far. */
1131 static int
1132 analyze_accesses_for_modify_stmt (struct matrix_info *mi, tree ssa_var,
1133 tree use_stmt, int current_indirect_level,
1134 bool last_op, sbitmap visited,
1135 bool record_accesses)
1138 tree lhs = GIMPLE_STMT_OPERAND (use_stmt, 0);
1139 tree rhs = GIMPLE_STMT_OPERAND (use_stmt, 1);
1140 struct ssa_acc_in_tree lhs_acc, rhs_acc;
1142 memset (&lhs_acc, 0, sizeof (lhs_acc));
1143 memset (&rhs_acc, 0, sizeof (rhs_acc));
1145 lhs_acc.ssa_var = ssa_var;
1146 lhs_acc.t_code = ERROR_MARK;
1147 ssa_accessed_in_tree (lhs, &lhs_acc);
1148 rhs_acc.ssa_var = ssa_var;
1149 rhs_acc.t_code = ERROR_MARK;
1150 ssa_accessed_in_tree (get_inner_of_cast_expr (rhs), &rhs_acc);
1152 /* The SSA must be either in the left side or in the right side,
1153 to understand what is happening.
1154 In case the SSA_NAME is found in both sides we should be escaping
1155 at this level because in this case we cannot calculate the
1156 address correctly. */
1157 if ((lhs_acc.var_found && rhs_acc.var_found
1158 && lhs_acc.t_code == INDIRECT_REF)
1159 || (!rhs_acc.var_found && !lhs_acc.var_found))
1161 mark_min_matrix_escape_level (mi, current_indirect_level, use_stmt);
1162 return current_indirect_level;
1164 gcc_assert (!rhs_acc.var_found || !lhs_acc.var_found);
1166 /* If we are storing to the matrix at some level, then mark it as
1167 escaping at that level. */
1168 if (lhs_acc.var_found)
1170 tree def;
1171 int l = current_indirect_level + 1;
1173 gcc_assert (lhs_acc.t_code == INDIRECT_REF);
1174 def = get_inner_of_cast_expr (rhs);
1175 if (TREE_CODE (def) != SSA_NAME)
1176 mark_min_matrix_escape_level (mi, l, use_stmt);
1177 else
1179 def = SSA_NAME_DEF_STMT (def);
1180 analyze_matrix_allocation_site (mi, def, l, visited);
1181 if (record_accesses)
1182 record_access_alloc_site_info (mi, use_stmt, NULL_TREE,
1183 NULL_TREE, l, true);
1184 update_type_size (mi, use_stmt, NULL, l);
1186 return current_indirect_level;
1188 /* Now, check the right-hand-side, to see how the SSA variable
1189 is used. */
1190 if (rhs_acc.var_found)
1192 /* If we are passing the ssa name to a function call and
1193 the pointer escapes when passed to the function
1194 (not the case of free), then we mark the matrix as
1195 escaping at this level. */
1196 if (rhs_acc.t_code == CALL_EXPR)
1198 analyze_accesses_for_call_expr (mi, use_stmt,
1199 current_indirect_level);
1201 return current_indirect_level;
1203 if (rhs_acc.t_code != INDIRECT_REF
1204 && rhs_acc.t_code != POINTER_PLUS_EXPR && rhs_acc.t_code != SSA_NAME)
1206 mark_min_matrix_escape_level (mi, current_indirect_level, use_stmt);
1207 return current_indirect_level;
1209 /* If the access in the RHS has an indirection increase the
1210 indirection level. */
1211 if (rhs_acc.t_code == INDIRECT_REF)
1213 if (record_accesses)
1214 record_access_alloc_site_info (mi, use_stmt, NULL_TREE,
1215 NULL_TREE,
1216 current_indirect_level, true);
1217 current_indirect_level += 1;
1219 else if (rhs_acc.t_code == POINTER_PLUS_EXPR)
1221 gcc_assert (rhs_acc.second_op);
1222 if (last_op)
1223 /* Currently we support only one PLUS expression on the
1224 SSA_NAME that holds the base address of the current
1225 indirection level; to support more general case there
1226 is a need to hold a stack of expressions and regenerate
1227 the calculation later. */
1228 mark_min_matrix_escape_level (mi, current_indirect_level,
1229 use_stmt);
1230 else
1232 tree index;
1233 tree op1, op2;
1235 op1 = TREE_OPERAND (rhs, 0);
1236 op2 = TREE_OPERAND (rhs, 1);
1238 op2 = (op1 == ssa_var) ? op2 : op1;
1239 if (TREE_CODE (op2) == INTEGER_CST)
1240 index =
1241 build_int_cst (TREE_TYPE (op1),
1242 TREE_INT_CST_LOW (op2) /
1243 int_size_in_bytes (TREE_TYPE (op1)));
1244 else
1246 index =
1247 get_index_from_offset (op2, SSA_NAME_DEF_STMT (op2));
1248 if (index == NULL_TREE)
1250 mark_min_matrix_escape_level (mi,
1251 current_indirect_level,
1252 use_stmt);
1253 return current_indirect_level;
1256 if (record_accesses)
1257 record_access_alloc_site_info (mi, use_stmt, op2,
1258 index,
1259 current_indirect_level, false);
1262 /* If we are storing this level of indirection mark it as
1263 escaping. */
1264 if (lhs_acc.t_code == INDIRECT_REF || TREE_CODE (lhs) != SSA_NAME)
1266 int l = current_indirect_level;
1268 /* One exception is when we are storing to the matrix
1269 variable itself; this is the case of malloc, we must make
1270 sure that it's the one and only one call to malloc so
1271 we call analyze_matrix_allocation_site to check
1272 this out. */
1273 if (TREE_CODE (lhs) != VAR_DECL || lhs != mi->decl)
1274 mark_min_matrix_escape_level (mi, current_indirect_level,
1275 use_stmt);
1276 else
1278 /* Also update the escaping level. */
1279 analyze_matrix_allocation_site (mi, use_stmt, l, visited);
1280 if (record_accesses)
1281 record_access_alloc_site_info (mi, use_stmt, NULL_TREE,
1282 NULL_TREE, l, true);
1285 else
1287 /* We are placing it in an SSA, follow that SSA. */
1288 analyze_matrix_accesses (mi, lhs,
1289 current_indirect_level,
1290 rhs_acc.t_code == POINTER_PLUS_EXPR,
1291 visited, record_accesses);
1294 return current_indirect_level;
1297 /* Given a SSA_VAR (coming from a use statement of the matrix MI),
1298 follow its uses and level of indirection and find out the minimum
1299 indirection level it escapes in (the highest dimension) and the maximum
1300 level it is accessed in (this will be the actual dimension of the
1301 matrix). The information is accumulated in MI.
1302 We look at the immediate uses, if one escapes we finish; if not,
1303 we make a recursive call for each one of the immediate uses of the
1304 resulting SSA name. */
1305 static void
1306 analyze_matrix_accesses (struct matrix_info *mi, tree ssa_var,
1307 int current_indirect_level, bool last_op,
1308 sbitmap visited, bool record_accesses)
1310 imm_use_iterator imm_iter;
1311 use_operand_p use_p;
1313 update_type_size (mi, SSA_NAME_DEF_STMT (ssa_var), ssa_var,
1314 current_indirect_level);
1316 /* We don't go beyond the escaping level when we are performing the
1317 flattening. NOTE: we keep the last indirection level that doesn't
1318 escape. */
1319 if (mi->min_indirect_level_escape > -1
1320 && mi->min_indirect_level_escape <= current_indirect_level)
1321 return;
1323 /* Now go over the uses of the SSA_NAME and check how it is used in
1324 each one of them. We are mainly looking for the pattern INDIRECT_REF,
1325 then a POINTER_PLUS_EXPR, then INDIRECT_REF etc. while in between there could
1326 be any number of copies and casts. */
1327 gcc_assert (TREE_CODE (ssa_var) == SSA_NAME);
1329 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, ssa_var)
1331 tree use_stmt = USE_STMT (use_p);
1332 if (TREE_CODE (use_stmt) == PHI_NODE)
1333 /* We check all the escaping levels that get to the PHI node
1334 and make sure they are all the same escaping;
1335 if not (which is rare) we let the escaping level be the
1336 minimum level that gets into that PHI because starting from
1337 that level we cannot expect the behavior of the indirections. */
1339 analyze_accesses_for_phi_node (mi, use_stmt, current_indirect_level,
1340 visited, record_accesses);
1342 else if (TREE_CODE (use_stmt) == CALL_EXPR)
1343 analyze_accesses_for_call_expr (mi, use_stmt, current_indirect_level);
1344 else if (TREE_CODE (use_stmt) == GIMPLE_MODIFY_STMT)
1345 current_indirect_level =
1346 analyze_accesses_for_modify_stmt (mi, ssa_var, use_stmt,
1347 current_indirect_level, last_op,
1348 visited, record_accesses);
1353 /* A walk_tree function to go over the VAR_DECL, PARM_DECL nodes of
1354 the malloc size expression and check that those aren't changed
1355 over the function. */
1356 static tree
1357 check_var_notmodified_p (tree * tp, int *walk_subtrees, void *data)
1359 basic_block bb;
1360 tree t = *tp;
1361 tree fn = data;
1362 block_stmt_iterator bsi;
1363 tree stmt;
1365 if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL)
1366 return NULL_TREE;
1368 FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (fn))
1370 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
1372 stmt = bsi_stmt (bsi);
1373 if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
1374 continue;
1375 if (GIMPLE_STMT_OPERAND (stmt, 0) == t)
1376 return stmt;
1379 *walk_subtrees = 1;
1380 return NULL_TREE;
1383 /* Go backwards in the use-def chains and find out the expression
1384 represented by the possible SSA name in EXPR, until it is composed
1385 of only VAR_DECL, PARM_DECL and INT_CST. In case of phi nodes
1386 we make sure that all the arguments represent the same subexpression,
1387 otherwise we fail. */
1388 static tree
1389 can_calculate_expr_before_stmt (tree expr, sbitmap visited)
1391 tree def_stmt, op1, op2, res;
1393 switch (TREE_CODE (expr))
1395 case SSA_NAME:
1396 /* Case of loop, we don't know to represent this expression. */
1397 if (TEST_BIT (visited, SSA_NAME_VERSION (expr)))
1398 return NULL_TREE;
1400 SET_BIT (visited, SSA_NAME_VERSION (expr));
1401 def_stmt = SSA_NAME_DEF_STMT (expr);
1402 res = can_calculate_expr_before_stmt (def_stmt, visited);
1403 RESET_BIT (visited, SSA_NAME_VERSION (expr));
1404 return res;
1405 case VAR_DECL:
1406 case PARM_DECL:
1407 case INTEGER_CST:
1408 return expr;
1409 case POINTER_PLUS_EXPR:
1410 case PLUS_EXPR:
1411 case MINUS_EXPR:
1412 case MULT_EXPR:
1413 op1 = TREE_OPERAND (expr, 0);
1414 op2 = TREE_OPERAND (expr, 1);
1416 op1 = can_calculate_expr_before_stmt (op1, visited);
1417 if (!op1)
1418 return NULL_TREE;
1419 op2 = can_calculate_expr_before_stmt (op2, visited);
1420 if (op2)
1421 return fold_build2 (TREE_CODE (expr), TREE_TYPE (expr), op1, op2);
1422 return NULL_TREE;
1423 case GIMPLE_MODIFY_STMT:
1424 return can_calculate_expr_before_stmt (GIMPLE_STMT_OPERAND (expr, 1),
1425 visited);
1426 case PHI_NODE:
1428 int j;
1430 res = NULL_TREE;
1431 /* Make sure all the arguments represent the same value. */
1432 for (j = 0; j < PHI_NUM_ARGS (expr); j++)
1434 tree new_res;
1435 tree def = PHI_ARG_DEF (expr, j);
1437 new_res = can_calculate_expr_before_stmt (def, visited);
1438 if (res == NULL_TREE)
1439 res = new_res;
1440 else if (!new_res || !expressions_equal_p (res, new_res))
1441 return NULL_TREE;
1443 return res;
1445 case NOP_EXPR:
1446 case CONVERT_EXPR:
1447 res = can_calculate_expr_before_stmt (TREE_OPERAND (expr, 0), visited);
1448 if (res != NULL_TREE)
1449 return build1 (TREE_CODE (expr), TREE_TYPE (expr), res);
1450 else
1451 return NULL_TREE;
1453 default:
1454 return NULL_TREE;
1458 /* There should be only one allocation function for the dimensions
1459 that don't escape. Here we check the allocation sites in this
1460 function. We must make sure that all the dimensions are allocated
1461 using malloc and that the malloc size parameter expression could be
1462 pre-calculated before the call to the malloc of dimension 0.
1464 Given a candidate matrix for flattening -- MI -- check if it's
1465 appropriate for flattening -- we analyze the allocation
1466 sites that we recorded in the previous analysis. The result of the
1467 analysis is a level of indirection (matrix dimension) in which the
1468 flattening is safe. We check the following conditions:
1469 1. There is only one allocation site for each dimension.
1470 2. The allocation sites of all the dimensions are in the same
1471 function.
1472 (The above two are being taken care of during the analysis when
1473 we check the allocation site).
1474 3. All the dimensions that we flatten are allocated at once; thus
1475 the total size must be known before the allocation of the
1476 dimension 0 (top level) -- we must make sure we represent the
1477 size of the allocation as an expression of global parameters or
1478 constants and that those doesn't change over the function. */
1480 static int
1481 check_allocation_function (void **slot, void *data ATTRIBUTE_UNUSED)
1483 int level;
1484 block_stmt_iterator bsi;
1485 basic_block bb_level_0;
1486 struct matrix_info *mi = *slot;
1487 sbitmap visited;
1489 if (!mi->malloc_for_level)
1490 return 1;
1492 visited = sbitmap_alloc (num_ssa_names);
1494 /* Do nothing if the current function is not the allocation
1495 function of MI. */
1496 if (mi->allocation_function_decl != current_function_decl
1497 /* We aren't in the main allocation function yet. */
1498 || !mi->malloc_for_level[0])
1499 return 1;
1501 for (level = 1; level < mi->max_malloced_level; level++)
1502 if (!mi->malloc_for_level[level])
1503 break;
1505 mark_min_matrix_escape_level (mi, level, NULL_TREE);
1507 bsi = bsi_for_stmt (mi->malloc_for_level[0]);
1508 bb_level_0 = bsi.bb;
1510 /* Check if the expression of the size passed to malloc could be
1511 pre-calculated before the malloc of level 0. */
1512 for (level = 1; level < mi->min_indirect_level_escape; level++)
1514 tree call_stmt, size;
1515 struct malloc_call_data mcd;
1517 call_stmt = mi->malloc_for_level[level];
1519 /* Find the correct malloc information. */
1520 collect_data_for_malloc_call (call_stmt, &mcd);
1522 /* No need to check anticipation for constants. */
1523 if (TREE_CODE (mcd.size_var) == INTEGER_CST)
1525 if (!mi->dimension_size)
1527 mi->dimension_size =
1528 (tree *) xcalloc (mi->min_indirect_level_escape,
1529 sizeof (tree));
1530 mi->dimension_size_orig =
1531 (tree *) xcalloc (mi->min_indirect_level_escape,
1532 sizeof (tree));
1534 mi->dimension_size[level] = mcd.size_var;
1535 mi->dimension_size_orig[level] = mcd.size_var;
1536 continue;
1538 /* ??? Here we should also add the way to calculate the size
1539 expression not only know that it is anticipated. */
1540 sbitmap_zero (visited);
1541 size = can_calculate_expr_before_stmt (mcd.size_var, visited);
1542 if (size == NULL_TREE)
1544 mark_min_matrix_escape_level (mi, level, call_stmt);
1545 if (dump_file)
1546 fprintf (dump_file,
1547 "Matrix %s: Cannot calculate the size of allocation. escaping at level %d\n",
1548 get_name (mi->decl), level);
1549 break;
1551 if (!mi->dimension_size)
1553 mi->dimension_size =
1554 (tree *) xcalloc (mi->min_indirect_level_escape, sizeof (tree));
1555 mi->dimension_size_orig =
1556 (tree *) xcalloc (mi->min_indirect_level_escape, sizeof (tree));
1558 mi->dimension_size[level] = size;
1559 mi->dimension_size_orig[level] = size;
1562 /* We don't need those anymore. */
1563 for (level = mi->min_indirect_level_escape;
1564 level < mi->max_malloced_level; level++)
1565 mi->malloc_for_level[level] = NULL;
1566 return 1;
1569 /* Track all access and allocation sites. */
1570 static void
1571 find_sites_in_func (bool record)
1573 sbitmap visited_stmts_1;
1575 block_stmt_iterator bsi;
1576 tree stmt;
1577 basic_block bb;
1578 struct matrix_info tmpmi, *mi;
1580 visited_stmts_1 = sbitmap_alloc (num_ssa_names);
1582 FOR_EACH_BB (bb)
1584 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
1586 stmt = bsi_stmt (bsi);
1587 if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
1588 && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == VAR_DECL)
1590 tmpmi.decl = GIMPLE_STMT_OPERAND (stmt, 0);
1591 if ((mi = htab_find (matrices_to_reorg, &tmpmi)))
1593 sbitmap_zero (visited_stmts_1);
1594 analyze_matrix_allocation_site (mi, stmt, 0, visited_stmts_1);
1597 if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
1598 && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == SSA_NAME
1599 && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == VAR_DECL)
1601 tmpmi.decl = GIMPLE_STMT_OPERAND (stmt, 1);
1602 if ((mi = htab_find (matrices_to_reorg, &tmpmi)))
1604 sbitmap_zero (visited_stmts_1);
1605 analyze_matrix_accesses (mi,
1606 GIMPLE_STMT_OPERAND (stmt, 0), 0,
1607 false, visited_stmts_1, record);
1612 sbitmap_free (visited_stmts_1);
1615 /* Traverse the use-def chains to see if there are matrices that
1616 are passed through pointers and we cannot know how they are accessed.
1617 For each SSA-name defined by a global variable of our interest,
1618 we traverse the use-def chains of the SSA and follow the indirections,
1619 and record in what level of indirection the use of the variable
1620 escapes. A use of a pointer escapes when it is passed to a function,
1621 stored into memory or assigned (except in malloc and free calls). */
1623 static void
1624 record_all_accesses_in_func (void)
1626 unsigned i;
1627 sbitmap visited_stmts_1;
1629 visited_stmts_1 = sbitmap_alloc (num_ssa_names);
1631 for (i = 0; i < num_ssa_names; i++)
1633 struct matrix_info tmpmi, *mi;
1634 tree ssa_var = ssa_name (i);
1635 tree rhs, lhs;
1637 if (!ssa_var
1638 || TREE_CODE (SSA_NAME_DEF_STMT (ssa_var)) != GIMPLE_MODIFY_STMT)
1639 continue;
1640 rhs = GIMPLE_STMT_OPERAND (SSA_NAME_DEF_STMT (ssa_var), 1);
1641 lhs = GIMPLE_STMT_OPERAND (SSA_NAME_DEF_STMT (ssa_var), 0);
1642 if (TREE_CODE (rhs) != VAR_DECL && TREE_CODE (lhs) != VAR_DECL)
1643 continue;
1645 /* If the RHS is a matrix that we want to analyze, follow the def-use
1646 chain for this SSA_VAR and check for escapes or apply the
1647 flattening. */
1648 tmpmi.decl = rhs;
1649 if ((mi = htab_find (matrices_to_reorg, &tmpmi)))
1651 /* This variable will track the visited PHI nodes, so we can limit
1652 its size to the maximum number of SSA names. */
1653 sbitmap_zero (visited_stmts_1);
1654 analyze_matrix_accesses (mi, ssa_var,
1655 0, false, visited_stmts_1, true);
1659 sbitmap_free (visited_stmts_1);
1662 /* Used when we want to convert the expression: RESULT = something * ORIG to RESULT = something * NEW. If ORIG and NEW are power of 2, shift operations can be done, else division and multiplication. */
1663 static tree
1664 compute_offset (HOST_WIDE_INT orig, HOST_WIDE_INT new, tree result)
1667 int x, y;
1668 tree result1, ratio, log, orig_tree, new_tree;
1670 x = exact_log2 (orig);
1671 y = exact_log2 (new);
1673 if (x != -1 && y != -1)
1675 if (x == y)
1676 return result;
1677 else if (x > y)
1679 log = build_int_cst (TREE_TYPE (result), x - y);
1680 result1 =
1681 fold_build2 (LSHIFT_EXPR, TREE_TYPE (result), result, log);
1682 return result1;
1684 log = build_int_cst (TREE_TYPE (result), y - x);
1685 result1 = fold_build2 (RSHIFT_EXPR, TREE_TYPE (result), result, log);
1687 return result1;
1689 orig_tree = build_int_cst (TREE_TYPE (result), orig);
1690 new_tree = build_int_cst (TREE_TYPE (result), new);
1691 ratio = fold_build2 (TRUNC_DIV_EXPR, TREE_TYPE (result), result, orig_tree);
1692 result1 = fold_build2 (MULT_EXPR, TREE_TYPE (result), ratio, new_tree);
1694 return result1;
1698 /* We know that we are allowed to perform matrix flattening (according to the
1699 escape analysis), so we traverse the use-def chains of the SSA vars
1700 defined by the global variables pointing to the matrices of our interest.
1701 in each use of the SSA we calculate the offset from the base address
1702 according to the following equation:
1704 a[I1][I2]...[Ik] , where D1..Dk is the length of each dimension and the
1705 escaping level is m <= k, and a' is the new allocated matrix,
1706 will be translated to :
1708 b[I(m+1)]...[Ik]
1710 where
1711 b = a' + I1*D2...*Dm + I2*D3...Dm + ... + Im
1714 static int
1715 transform_access_sites (void **slot, void *data ATTRIBUTE_UNUSED)
1717 block_stmt_iterator bsi;
1718 struct matrix_info *mi = *slot;
1719 int min_escape_l = mi->min_indirect_level_escape;
1720 struct access_site_info *acc_info;
1721 int i;
1723 if (min_escape_l < 2 || !mi->access_l)
1724 return 1;
1725 for (i = 0; VEC_iterate (access_site_info_p, mi->access_l, i, acc_info);
1726 i++)
1728 tree orig, type;
1730 /* This is possible because we collect the access sites before
1731 we determine the final minimum indirection level. */
1732 if (acc_info->level >= min_escape_l)
1734 free (acc_info);
1735 continue;
1737 if (acc_info->is_alloc)
1739 if (acc_info->level >= 0 && bb_for_stmt (acc_info->stmt))
1741 ssa_op_iter iter;
1742 tree def;
1743 tree stmt = acc_info->stmt;
1745 FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)
1746 mark_sym_for_renaming (SSA_NAME_VAR (def));
1747 bsi = bsi_for_stmt (stmt);
1748 gcc_assert (TREE_CODE (acc_info->stmt) == GIMPLE_MODIFY_STMT);
1749 if (TREE_CODE (GIMPLE_STMT_OPERAND (acc_info->stmt, 0)) ==
1750 SSA_NAME && acc_info->level < min_escape_l - 1)
1752 imm_use_iterator imm_iter;
1753 use_operand_p use_p;
1754 tree use_stmt;
1756 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter,
1757 GIMPLE_STMT_OPERAND (acc_info->stmt,
1759 FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
1761 tree conv, tmp, stmts;
1763 /* Emit convert statement to convert to type of use. */
1764 conv =
1765 fold_build1 (CONVERT_EXPR,
1766 TREE_TYPE (GIMPLE_STMT_OPERAND
1767 (acc_info->stmt, 0)),
1768 TREE_OPERAND (GIMPLE_STMT_OPERAND
1769 (acc_info->stmt, 1), 0));
1770 tmp =
1771 create_tmp_var (TREE_TYPE
1772 (GIMPLE_STMT_OPERAND
1773 (acc_info->stmt, 0)), "new");
1774 add_referenced_var (tmp);
1775 stmts =
1776 fold_build2 (GIMPLE_MODIFY_STMT,
1777 TREE_TYPE (GIMPLE_STMT_OPERAND
1778 (acc_info->stmt, 0)), tmp,
1779 conv);
1780 tmp = make_ssa_name (tmp, stmts);
1781 GIMPLE_STMT_OPERAND (stmts, 0) = tmp;
1782 bsi = bsi_for_stmt (acc_info->stmt);
1783 bsi_insert_after (&bsi, stmts, BSI_SAME_STMT);
1784 SET_USE (use_p, tmp);
1787 if (acc_info->level < min_escape_l - 1)
1788 bsi_remove (&bsi, true);
1790 free (acc_info);
1791 continue;
1793 orig = GIMPLE_STMT_OPERAND (acc_info->stmt, 1);
1794 type = TREE_TYPE (orig);
1795 if (TREE_CODE (orig) == INDIRECT_REF
1796 && acc_info->level < min_escape_l - 1)
1798 /* Replace the INDIRECT_REF with NOP (cast) usually we are casting
1799 from "pointer to type" to "type". */
1800 orig =
1801 build1 (NOP_EXPR, TREE_TYPE (orig),
1802 GIMPLE_STMT_OPERAND (orig, 0));
1803 GIMPLE_STMT_OPERAND (acc_info->stmt, 1) = orig;
1805 else if (TREE_CODE (orig) == POINTER_PLUS_EXPR
1806 && acc_info->level < (min_escape_l))
1808 imm_use_iterator imm_iter;
1809 use_operand_p use_p;
1811 tree offset;
1812 int k = acc_info->level;
1813 tree num_elements, total_elements;
1814 tree tmp1;
1815 tree d_size = mi->dimension_size[k];
1817 /* We already make sure in the analysis that the first operand
1818 is the base and the second is the offset. */
1819 offset = acc_info->offset;
1820 if (mi->dim_map[k] == min_escape_l - 1)
1822 if (!check_transpose_p || mi->is_transposed_p == false)
1823 tmp1 = offset;
1824 else
1826 tree new_offset;
1827 tree d_type_size, d_type_size_k;
1829 d_type_size = size_int (mi->dimension_type_size[min_escape_l]);
1830 d_type_size_k = size_int (mi->dimension_type_size[k + 1]);
1832 new_offset =
1833 compute_offset (mi->dimension_type_size[min_escape_l],
1834 mi->dimension_type_size[k + 1], offset);
1836 total_elements = new_offset;
1837 if (new_offset != offset)
1839 bsi = bsi_for_stmt (acc_info->stmt);
1840 tmp1 = force_gimple_operand_bsi (&bsi, total_elements,
1841 true, NULL,
1842 true, BSI_SAME_STMT);
1844 else
1845 tmp1 = offset;
1848 else
1850 d_size = mi->dimension_size[mi->dim_map[k] + 1];
1851 num_elements =
1852 fold_build2 (MULT_EXPR, sizetype, fold_convert (sizetype, acc_info->index),
1853 fold_convert (sizetype, d_size));
1854 add_referenced_var (d_size);
1855 bsi = bsi_for_stmt (acc_info->stmt);
1856 tmp1 = force_gimple_operand_bsi (&bsi, num_elements, true,
1857 NULL, true, BSI_SAME_STMT);
1859 /* Replace the offset if needed. */
1860 if (tmp1 != offset)
1862 if (TREE_CODE (offset) == SSA_NAME)
1864 tree use_stmt;
1866 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, offset)
1867 FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
1868 if (use_stmt == acc_info->stmt)
1869 SET_USE (use_p, tmp1);
1871 else
1873 gcc_assert (TREE_CODE (offset) == INTEGER_CST);
1874 TREE_OPERAND (orig, 1) = tmp1;
1878 /* ??? meanwhile this happens because we record the same access
1879 site more than once; we should be using a hash table to
1880 avoid this and insert the STMT of the access site only
1881 once.
1882 else
1883 gcc_unreachable (); */
1884 free (acc_info);
1886 VEC_free (access_site_info_p, heap, mi->access_l);
1888 update_ssa (TODO_update_ssa);
1889 #ifdef ENABLE_CHECKING
1890 verify_ssa (true);
1891 #endif
1892 return 1;
1895 /* Sort A array of counts. Arrange DIM_MAP to reflect the new order. */
1897 static void
1898 sort_dim_hot_level (gcov_type * a, int *dim_map, int n)
1900 int i, j, tmp1;
1901 gcov_type tmp;
1903 for (i = 0; i < n - 1; i++)
1905 for (j = 0; j < n - 1 - i; j++)
1907 if (a[j + 1] < a[j])
1909 tmp = a[j]; /* swap a[j] and a[j+1] */
1910 a[j] = a[j + 1];
1911 a[j + 1] = tmp;
1912 tmp1 = dim_map[j];
1913 dim_map[j] = dim_map[j + 1];
1914 dim_map[j + 1] = tmp1;
1920 /* Replace multiple mallocs (one for each dimension) to one malloc
1921 with the size of DIM1*DIM2*...*DIMN*size_of_element
1922 Make sure that we hold the size in the malloc site inside a
1923 new global variable; this way we ensure that the size doesn't
1924 change and it is accessible from all the other functions that
1925 uses the matrix. Also, the original calls to free are deleted,
1926 and replaced by a new call to free the flattened matrix. */
1928 static int
1929 transform_allocation_sites (void **slot, void *data ATTRIBUTE_UNUSED)
1931 int i;
1932 struct matrix_info *mi;
1933 tree type, call_stmt_0, malloc_stmt, oldfn, prev_dim_size, use_stmt;
1934 struct cgraph_node *c_node;
1935 struct cgraph_edge *e;
1936 block_stmt_iterator bsi;
1937 struct malloc_call_data mcd;
1938 HOST_WIDE_INT element_size;
1940 imm_use_iterator imm_iter;
1941 use_operand_p use_p;
1942 tree old_size_0, tmp;
1943 int min_escape_l;
1944 int id;
1946 mi = *slot;
1948 min_escape_l = mi->min_indirect_level_escape;
1950 if (!mi->malloc_for_level)
1951 mi->min_indirect_level_escape = 0;
1953 if (mi->min_indirect_level_escape < 2)
1954 return 1;
1956 mi->dim_map = (int *) xcalloc (mi->min_indirect_level_escape, sizeof (int));
1957 for (i = 0; i < mi->min_indirect_level_escape; i++)
1958 mi->dim_map[i] = i;
1959 if (check_transpose_p)
1961 int i;
1963 if (dump_file)
1965 fprintf (dump_file, "Matrix %s:\n", get_name (mi->decl));
1966 for (i = 0; i < min_escape_l; i++)
1968 fprintf (dump_file, "dim %d before sort ", i);
1969 if (mi->dim_hot_level)
1970 fprintf (dump_file,
1971 "count is " HOST_WIDEST_INT_PRINT_DEC " \n",
1972 mi->dim_hot_level[i]);
1975 sort_dim_hot_level (mi->dim_hot_level, mi->dim_map,
1976 mi->min_indirect_level_escape);
1977 if (dump_file)
1978 for (i = 0; i < min_escape_l; i++)
1980 fprintf (dump_file, "dim %d after sort\n", i);
1981 if (mi->dim_hot_level)
1982 fprintf (dump_file, "count is " HOST_WIDE_INT_PRINT_DEC
1983 " \n", (HOST_WIDE_INT) mi->dim_hot_level[i]);
1985 for (i = 0; i < mi->min_indirect_level_escape; i++)
1987 if (dump_file)
1988 fprintf (dump_file, "dim_map[%d] after sort %d\n", i,
1989 mi->dim_map[i]);
1990 if (mi->dim_map[i] != i)
1992 if (dump_file)
1993 fprintf (dump_file,
1994 "Transposed dimensions: dim %d is now dim %d\n",
1995 mi->dim_map[i], i);
1996 mi->is_transposed_p = true;
2000 else
2002 for (i = 0; i < mi->min_indirect_level_escape; i++)
2003 mi->dim_map[i] = i;
2005 /* Call statement of allocation site of level 0. */
2006 call_stmt_0 = mi->malloc_for_level[0];
2008 /* Finds the correct malloc information. */
2009 collect_data_for_malloc_call (call_stmt_0, &mcd);
2011 mi->dimension_size[0] = mcd.size_var;
2012 mi->dimension_size_orig[0] = mcd.size_var;
2013 /* Make sure that the variables in the size expression for
2014 all the dimensions (above level 0) aren't modified in
2015 the allocation function. */
2016 for (i = 1; i < mi->min_indirect_level_escape; i++)
2018 tree t;
2020 /* mi->dimension_size must contain the expression of the size calculated
2021 in check_allocation_function. */
2022 gcc_assert (mi->dimension_size[i]);
2024 t = walk_tree_without_duplicates (&(mi->dimension_size[i]),
2025 check_var_notmodified_p,
2026 mi->allocation_function_decl);
2027 if (t != NULL_TREE)
2029 mark_min_matrix_escape_level (mi, i, t);
2030 break;
2034 if (mi->min_indirect_level_escape < 2)
2035 return 1;
2037 /* Since we should make sure that the size expression is available
2038 before the call to malloc of level 0. */
2039 bsi = bsi_for_stmt (call_stmt_0);
2041 /* Find out the size of each dimension by looking at the malloc
2042 sites and create a global variable to hold it.
2043 We add the assignment to the global before the malloc of level 0. */
2045 /* To be able to produce gimple temporaries. */
2046 oldfn = current_function_decl;
2047 current_function_decl = mi->allocation_function_decl;
2048 push_cfun (DECL_STRUCT_FUNCTION (mi->allocation_function_decl));
2050 /* Set the dimension sizes as follows:
2051 DIM_SIZE[i] = DIM_SIZE[n] * ... * DIM_SIZE[i]
2052 where n is the maximum non escaping level. */
2053 element_size = mi->dimension_type_size[mi->min_indirect_level_escape];
2054 prev_dim_size = NULL_TREE;
2056 for (i = mi->min_indirect_level_escape - 1; i >= 0; i--)
2058 tree dim_size, dim_var, tmp;
2059 tree d_type_size;
2061 /* Now put the size expression in a global variable and initialize it to
2062 the size expression before the malloc of level 0. */
2063 dim_var =
2064 add_new_static_var (TREE_TYPE
2065 (mi->dimension_size_orig[mi->dim_map[i]]));
2066 type = TREE_TYPE (mi->dimension_size_orig[mi->dim_map[i]]);
2068 /* DIM_SIZE = MALLOC_SIZE_PARAM / TYPE_SIZE. */
2069 /* Find which dim ID becomes dim I. */
2070 for (id = 0; id < mi->min_indirect_level_escape; id++)
2071 if (mi->dim_map[id] == i)
2072 break;
2073 d_type_size =
2074 build_int_cst (type, mi->dimension_type_size[id + 1]);
2075 if (!prev_dim_size)
2076 prev_dim_size = build_int_cst (type, element_size);
2077 if (!check_transpose_p && i == mi->min_indirect_level_escape - 1)
2079 dim_size = mi->dimension_size_orig[id];
2081 else
2083 dim_size =
2084 fold_build2 (TRUNC_DIV_EXPR, type, mi->dimension_size_orig[id],
2085 d_type_size);
2087 dim_size = fold_build2 (MULT_EXPR, type, dim_size, prev_dim_size);
2089 dim_size = force_gimple_operand_bsi (&bsi, dim_size, true, NULL,
2090 true, BSI_SAME_STMT);
2091 /* GLOBAL_HOLDING_THE_SIZE = DIM_SIZE. */
2092 tmp = fold_build2 (GIMPLE_MODIFY_STMT, type, dim_var, dim_size);
2093 GIMPLE_STMT_OPERAND (tmp, 0) = dim_var;
2094 mark_symbols_for_renaming (tmp);
2095 bsi_insert_before (&bsi, tmp, BSI_SAME_STMT);
2097 prev_dim_size = mi->dimension_size[i] = dim_var;
2099 update_ssa (TODO_update_ssa);
2100 /* Replace the malloc size argument in the malloc of level 0 to be
2101 the size of all the dimensions. */
2102 malloc_stmt = GIMPLE_STMT_OPERAND (call_stmt_0, 1);
2103 c_node = cgraph_node (mi->allocation_function_decl);
2104 old_size_0 = CALL_EXPR_ARG (malloc_stmt, 0);
2105 tmp = force_gimple_operand_bsi (&bsi, mi->dimension_size[0], true,
2106 NULL, true, BSI_SAME_STMT);
2107 if (TREE_CODE (old_size_0) == SSA_NAME)
2109 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, old_size_0)
2110 FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
2111 if (use_stmt == call_stmt_0)
2112 SET_USE (use_p, tmp);
2114 /* When deleting the calls to malloc we need also to remove the edge from
2115 the call graph to keep it consistent. Notice that cgraph_edge may
2116 create a new node in the call graph if there is no node for the given
2117 declaration; this shouldn't be the case but currently there is no way to
2118 check this outside of "cgraph.c". */
2119 for (i = 1; i < mi->min_indirect_level_escape; i++)
2121 block_stmt_iterator bsi;
2122 tree use_stmt1 = NULL;
2123 tree call;
2125 tree call_stmt = mi->malloc_for_level[i];
2126 call = GIMPLE_STMT_OPERAND (call_stmt, 1);
2127 gcc_assert (TREE_CODE (call) == CALL_EXPR);
2128 e = cgraph_edge (c_node, call_stmt);
2129 gcc_assert (e);
2130 cgraph_remove_edge (e);
2131 bsi = bsi_for_stmt (call_stmt);
2132 /* Remove the call stmt. */
2133 bsi_remove (&bsi, true);
2134 /* remove the type cast stmt. */
2135 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter,
2136 GIMPLE_STMT_OPERAND (call_stmt, 0))
2138 use_stmt1 = use_stmt;
2139 bsi = bsi_for_stmt (use_stmt);
2140 bsi_remove (&bsi, true);
2142 /* Remove the assignment of the allocated area. */
2143 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter,
2144 GIMPLE_STMT_OPERAND (use_stmt1, 0))
2146 bsi = bsi_for_stmt (use_stmt);
2147 bsi_remove (&bsi, true);
2150 update_ssa (TODO_update_ssa);
2151 #ifdef ENABLE_CHECKING
2152 verify_ssa (true);
2153 #endif
2154 /* Delete the calls to free. */
2155 for (i = 1; i < mi->min_indirect_level_escape; i++)
2157 block_stmt_iterator bsi;
2158 tree call;
2160 /* ??? wonder why this case is possible but we failed on it once. */
2161 if (!mi->free_stmts[i].stmt)
2162 continue;
2164 call = TREE_OPERAND (mi->free_stmts[i].stmt, 1);
2165 c_node = cgraph_node (mi->free_stmts[i].func);
2167 gcc_assert (TREE_CODE (mi->free_stmts[i].stmt) == CALL_EXPR);
2168 e = cgraph_edge (c_node, mi->free_stmts[i].stmt);
2169 gcc_assert (e);
2170 cgraph_remove_edge (e);
2171 current_function_decl = mi->free_stmts[i].func;
2172 set_cfun (DECL_STRUCT_FUNCTION (mi->free_stmts[i].func));
2173 bsi = bsi_for_stmt (mi->free_stmts[i].stmt);
2174 bsi_remove (&bsi, true);
2176 /* Return to the previous situation. */
2177 current_function_decl = oldfn;
2178 pop_cfun ();
2179 return 1;
2184 /* Print out the results of the escape analysis. */
2185 static int
2186 dump_matrix_reorg_analysis (void **slot, void *data ATTRIBUTE_UNUSED)
2188 struct matrix_info *mi = *slot;
2190 if (!dump_file)
2191 return 1;
2192 fprintf (dump_file, "Matrix \"%s\"; Escaping Level: %d, Num Dims: %d,",
2193 get_name (mi->decl), mi->min_indirect_level_escape, mi->num_dims);
2194 fprintf (dump_file, " Malloc Dims: %d, ", mi->max_malloced_level);
2195 fprintf (dump_file, "\n");
2196 if (mi->min_indirect_level_escape >= 2)
2197 fprintf (dump_file, "Flattened %d dimensions \n",
2198 mi->min_indirect_level_escape);
2199 return 1;
2203 /* Perform matrix flattening. */
2205 static unsigned int
2206 matrix_reorg (void)
2208 struct cgraph_node *node;
2210 if (profile_info)
2211 check_transpose_p = true;
2212 else
2213 check_transpose_p = false;
2214 /* If there are hand written vectors, we skip this optimization. */
2215 for (node = cgraph_nodes; node; node = node->next)
2216 if (!may_flatten_matrices (node))
2217 return 0;
2218 matrices_to_reorg = htab_create (37, mtt_info_hash, mtt_info_eq, mat_free);
2219 /* Find and record all potential matrices in the program. */
2220 find_matrices_decl ();
2221 /* Analyze the accesses of the matrices (escaping analysis). */
2222 for (node = cgraph_nodes; node; node = node->next)
2223 if (node->analyzed)
2225 tree temp_fn;
2227 temp_fn = current_function_decl;
2228 current_function_decl = node->decl;
2229 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
2230 bitmap_obstack_initialize (NULL);
2231 tree_register_cfg_hooks ();
2233 if (!gimple_in_ssa_p (cfun))
2235 free_dominance_info (CDI_DOMINATORS);
2236 free_dominance_info (CDI_POST_DOMINATORS);
2237 pop_cfun ();
2238 current_function_decl = temp_fn;
2240 return 0;
2243 #ifdef ENABLE_CHECKING
2244 verify_flow_info ();
2245 #endif
2247 if (!matrices_to_reorg)
2249 free_dominance_info (CDI_DOMINATORS);
2250 free_dominance_info (CDI_POST_DOMINATORS);
2251 pop_cfun ();
2252 current_function_decl = temp_fn;
2254 return 0;
2257 /* Create htap for phi nodes. */
2258 htab_mat_acc_phi_nodes = htab_create (37, mat_acc_phi_hash,
2259 mat_acc_phi_eq, free);
2260 if (!check_transpose_p)
2261 find_sites_in_func (false);
2262 else
2264 find_sites_in_func (true);
2265 loop_optimizer_init (LOOPS_NORMAL);
2266 if (current_loops)
2267 scev_initialize ();
2268 htab_traverse (matrices_to_reorg, analyze_transpose, NULL);
2269 if (current_loops)
2271 scev_finalize ();
2272 loop_optimizer_finalize ();
2273 current_loops = NULL;
2276 /* If the current function is the allocation function for any of
2277 the matrices we check its allocation and the escaping level. */
2278 htab_traverse (matrices_to_reorg, check_allocation_function, NULL);
2279 free_dominance_info (CDI_DOMINATORS);
2280 free_dominance_info (CDI_POST_DOMINATORS);
2281 pop_cfun ();
2282 current_function_decl = temp_fn;
2284 htab_traverse (matrices_to_reorg, transform_allocation_sites, NULL);
2285 /* Now transform the accesses. */
2286 for (node = cgraph_nodes; node; node = node->next)
2287 if (node->analyzed)
2289 /* Remember that allocation sites have been handled. */
2290 tree temp_fn;
2292 temp_fn = current_function_decl;
2293 current_function_decl = node->decl;
2294 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
2295 bitmap_obstack_initialize (NULL);
2296 tree_register_cfg_hooks ();
2297 record_all_accesses_in_func ();
2298 htab_traverse (matrices_to_reorg, transform_access_sites, NULL);
2299 free_dominance_info (CDI_DOMINATORS);
2300 free_dominance_info (CDI_POST_DOMINATORS);
2301 pop_cfun ();
2302 current_function_decl = temp_fn;
2304 htab_traverse (matrices_to_reorg, dump_matrix_reorg_analysis, NULL);
2306 current_function_decl = NULL;
2307 set_cfun (NULL);
2308 matrices_to_reorg = NULL;
2309 return 0;
2313 /* The condition for matrix flattening to be performed. */
2314 static bool
2315 gate_matrix_reorg (void)
2317 return flag_ipa_matrix_reorg && flag_whole_program;
2320 struct tree_opt_pass pass_ipa_matrix_reorg = {
2321 "matrix-reorg", /* name */
2322 gate_matrix_reorg, /* gate */
2323 matrix_reorg, /* execute */
2324 NULL, /* sub */
2325 NULL, /* next */
2326 0, /* static_pass_number */
2327 0, /* tv_id */
2328 0, /* properties_required */
2329 PROP_trees, /* properties_provided */
2330 0, /* properties_destroyed */
2331 0, /* todo_flags_start */
2332 TODO_dump_cgraph | TODO_dump_func, /* todo_flags_finish */
2333 0 /* letter */