1 /* Copyright (C) 2021 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
23 #include "DerivedMetrics.h"
46 definition::definition ()
52 definition::~definition ()
58 DerivedMetrics::DerivedMetrics ()
60 items = new Vector<definition*>;
63 DerivedMetrics::~DerivedMetrics ()
69 DerivedMetrics::add_definition (char *_name, char *_username, char *_def)
73 // if the name doesn't matter, maybe there is a duplicate we can use
77 Vec_loop (definition*, items, i, p)
79 if (strcmp (p->def, _def) == 0)
85 p->name = dbe_strdup (_name);
86 p->def = dbe_strdup (_def);
88 // parse the definition
89 if (strchr (_def, '/') == NULL)
91 // it's a primitive metric
93 p->arg1 = p->arg2 = NULL;
98 // it's some operation on arguments
100 char *op_ptr = strchr (p->def, '/');
102 p->arg1 = add_definition (NULL, NULL, p->def);
104 p->arg2 = add_definition (NULL, NULL, op_ptr + 1);
106 p->index = items->size ();
112 DerivedMetrics::construct_map (Vector<Metric*> *mitems, BaseMetric::SubType st, char *expr_spec)
116 int ndm = items->size ();
119 int nmetrics = mitems->size ();
121 // allocate arrays for the mapping between derived metrics and requested values
122 int *map = (int *) malloc (ndm * sizeof (int));
124 // map derived metrics to requested metrics // EUGENE explain this more clearly
125 // 0 means not mapped
126 // >0 means primitive metric maps to map-1
127 // <0 means derived metric maps to 1-map
128 int ndm_requested = 0;
129 for (int idm = 0; idm < ndm; idm++)
131 definition *defdm = items->fetch (idm);
134 // figure out what name to use for this derived metric
136 if (defdm->op == opPrimitive)
141 if (dname == NULL) break;
144 // look for this name among metrics
146 for (im = 0; im < nmetrics; im++)
148 Metric *m = mitems->fetch (im);
149 if (strcmp (dname, m->get_cmd ()) == 0 && m->get_subtype () == st)
150 // apparent match, but let's check comparison mode
151 if (dbe_strcmp (expr_spec, m->get_expr_spec ()) == 0)
155 // encode the mapping
157 map[idm] = 0; // does not map to requested metrics
158 else if (defdm->op == opPrimitive)
159 map[idm] = +1 + im; // encode as a positive index
162 map[idm] = -1 - im; // encode as a negative index
166 if (ndm_requested == 0)
175 DerivedMetrics::fill_dependencies (definition *def, int *vec)
183 fill_dependencies (def->arg1, vec);
184 fill_dependencies (def->arg2, vec);
191 Vector<definition*> *
192 DerivedMetrics::get_dependencies (definition *def)
194 int n = items->size ();
196 // zero out a vector representing definitions
197 int *vec = (int *) malloc (n * sizeof (int));
198 for (int i = 0; i < n; i++)
200 fill_dependencies (def, vec);
202 // construct the dependency vector
203 Vector<definition*> *dependencies = new Vector<definition*>;
204 for (int i = 0; i < n; i++)
206 dependencies->append (items->fetch (i));
212 DerivedMetrics::dump (FILE *dis_file, int verbosity)
217 // deal with the possibility that names might be NULL
218 const char *UNNAMED = "(unnamed)";
219 #define NAME(x) ( (x) ? (x) : UNNAMED)
221 Vec_loop (definition*, items, i, item)
223 // at low verbosity, skip over some items
226 if (item->name == NULL)
228 if (strcmp (item->name, item->def) && item->op == opPrimitive)
232 // dump the definition
236 fprintf (dis_file, "%s [%s] is a primitive metric\n", NAME (item->name),
240 fprintf (dis_file, "%s [%s] = %s [%s] / %s [%s]\n", NAME (item->name),
241 item->def, NAME (item->arg1->name), item->arg1->def,
242 NAME (item->arg2->name), item->arg2->def);
245 fprintf (dis_file, "%s [%s] has an unrecognized op %d\n",
246 NAME (item->name), item->def, item->op);
253 DerivedMetrics::eval_one_item (definition *def, int *map, double *values)
258 fprintf (stderr, GTXT ("cannot eval NULL expression\n"));
262 int ival = map[def->index];
263 if (ival <= 0) return 0.;
269 double x1 = eval_one_item (def->arg1, map, values);
270 double x2 = eval_one_item (def->arg2, map, values);
271 if (x2 == 0) return 0.;
275 fprintf (stderr, GTXT ("unknown expression\n"));
281 DerivedMetrics::eval (int *map, double *values)
283 for (int i = 0, n = items->size (); i < n; i++)
287 int ival = -1 - map[i];
288 values[ival] = eval_one_item (items->fetch (i), map, values);