Merge trunk version 203886 into gupc branch.
[official-gcc.git] / gcc / upc / upc-gasp.c
bloba275b89e942ca0f958d1ac8c9e1a1d238c7ca792
1 /* upc-gasp.c: UPC GASP (GAS Performance) instrumentation support
2 Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011
3 Free Software Foundation, Inc.
4 Contributed by Gary Funck <gary@intrepid.com>
5 and Nenad Vukicevic <nenad@intrepid.com>.
6 Based on original Implementation by Adam Leko <leko@hcs.ufl.edu>.
8 This file is part of GCC.
10 GCC is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3, or (at your option)
13 any later version.
15 GCC is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3. If not see
22 <http://www.gnu.org/licenses/>. */
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tree.h"
28 #include "ggc.h"
29 #include "hashtab.h"
30 #include "input.h"
31 #include "c/c-tree.h"
32 #include "tree-iterator.h"
33 #include "langhooks.h"
34 #include "flags.h"
35 #include "opts.h"
36 #include "options.h"
37 #include "output.h"
38 #include "toplev.h"
39 #include "tm.h"
40 #include "function.h"
41 #include "target.h"
42 #include "c-family/c-common.h"
43 #include "c-family/c-pragma.h"
44 #include "c-family/c-upc.h"
45 #include "upc-gasp.h"
46 #include "upc-rts-names.h"
48 static tree build_string_ref (const char *string);
50 /* Build a reference to a literal string.
51 (cribbed from mf_build_string in tree-mudflap.c) */
53 static tree
54 build_string_ref (const char *string)
56 size_t len = strlen (string);
57 tree result = build_string (len + 1, string);
58 TREE_TYPE (result) = build_array_type
59 (char_type_node, build_index_type (build_int_cst (NULL_TREE, len)));
60 TREE_CONSTANT (result) = 1;
61 TREE_READONLY (result) = 1;
62 TREE_STATIC (result) = 1;
63 result = build1 (ADDR_EXPR, build_pointer_type (char_type_node), result);
64 return result;
67 /* Add source args to the argument list. */
69 tree
70 upc_gasp_add_src_args (tree args, const char *filename, int lineno)
72 return chainon (args,
73 tree_cons (NULL_TREE, build_string_ref (filename),
74 tree_cons (NULL_TREE,
75 build_int_cst (NULL_TREE, lineno),
76 NULL_TREE)));
79 /* Instrument `upc_forall' statement begin/end.
80 Return a call to the profiling function. */
82 tree
83 upc_instrument_forall (location_t loc, int start)
85 const char *filename = LOCATION_FILE (loc);
86 const int lineno = LOCATION_LINE (loc);
87 tree pfunc;
89 pfunc = lookup_name (get_identifier (UPC_INSTRUMENT_FORALL));
90 if (!pfunc)
91 internal_error ("UPC profiling function `%s' not found",
92 UPC_INSTRUMENT_FORALL);
94 return build_call_expr (pfunc, 3,
95 build_int_cst (NULL_TREE, start),
96 build_string_ref (filename),
97 build_int_cst (NULL_TREE, lineno));
100 /* If UPC function profiling has been enabled, rewrite the
101 body of FNDECL so that the GASP intrumentation function
102 is called before the body of the function is executed,
103 and then after it is executed (as a TRY_FINALLY_EXPR). */
105 void
106 upc_instrument_func (tree fndecl)
108 tree tf, x, pfunc, bind;
109 const char *filename, *funcname;
110 int lineno;
112 /* Skip, if profiling disabled via #pragma pupc. */
113 if (!get_upc_pupc_mode ())
114 return;
116 pfunc = lookup_name (get_identifier (UPC_INSTRUMENT_FUNC));
117 if (!pfunc)
118 internal_error ("UPC profiling function `%s' not found",
119 UPC_INSTRUMENT_FUNC);
120 funcname = "<unknown>";
121 if (DECL_NAME (fndecl))
122 funcname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
123 lineno = DECL_SOURCE_LINE (fndecl);
124 filename = DECL_SOURCE_FILE (fndecl);
125 tf = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
126 TREE_SIDE_EFFECTS (tf) = 1;
127 x = DECL_SAVED_TREE (fndecl);
128 append_to_statement_list (x, &TREE_OPERAND (tf, 0));
129 x = build_call_expr (pfunc, 4, integer_zero_node, /* start == 0 */
130 build_string_ref (funcname),
131 build_string_ref (filename),
132 build_int_cst (NULL_TREE, lineno));
133 append_to_statement_list (x, &TREE_OPERAND (tf, 1));
135 bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
136 TREE_SIDE_EFFECTS (bind) = 1;
137 x = build_call_expr (pfunc, 4, integer_one_node, /* start == 1 */
138 build_string_ref (funcname),
139 build_string_ref (filename),
140 build_int_cst (NULL_TREE, lineno));
141 append_to_statement_list (x, &BIND_EXPR_BODY (bind));
142 append_to_statement_list (tf, &BIND_EXPR_BODY (bind));
144 DECL_SAVED_TREE (fndecl) = bind;