00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 #if defined(BUILD_OS_DARWIN)
00058 #include <darwin_elf.h>
00059 #else
00060 #include <elf.h>
00061 #endif
00062 #include <sys/types.h>
00063 #include <unistd.h>
00064 #include <signal.h>
00065 #include <wait.h>
00066
00067 #define USE_STANDARD_TYPES
00068 #include "defs.h"
00069 #include "errors.h"
00070 #include "ip_graph.h"
00071 #include "ip_binding.h"
00072 #include "strtab.h"
00073 #include "stab.h"
00074 #include "const.h"
00075 #include "irbdata.h"
00076 #define USE_DST_INTERNALS
00077 #include "dwarf_DST_mem.h"
00078 #include "ipc_file.h"
00079 #include "pu_info.h"
00080 #include "ipa_cg.h"
00081 #include "ipa_inline.h"
00082 #include "ipa_option.h"
00083 #include "ipc_daVinci.h"
00084
00085 daVinci *cg_display = 0;
00086
00087 daVinci::daVinci (GRAPH *_g, MEM_POOL *_m)
00088 {
00089 g = _g;
00090 m = _m;
00091 IPA_Enable_daVinci = display_ok = FALSE;
00092 to_display = from_display = NULL;
00093
00094 if (isatty (1) == 0 && isatty (2) == 0)
00095 return;
00096
00097
00098 int read_pipe[2], write_pipe[2];
00099
00100 if (pipe (read_pipe) == -1 || pipe (write_pipe) == -1)
00101 return;
00102
00103 from_display = fdopen (read_pipe[0], "r");
00104 setbuf (from_display, NULL);
00105 to_display = fdopen (write_pipe[1], "w");
00106 setbuf (to_display, NULL);
00107
00108 switch (pid = fork ()) {
00109 case -1:
00110 close (read_pipe[0]);
00111 close (read_pipe[1]);
00112 close (write_pipe[0]);
00113 close (write_pipe[1]);
00114 return;
00115
00116 case 0:
00117 dup2 (write_pipe[0], 0);
00118 dup2 (read_pipe[1], 1);
00119 dup2 (read_pipe[1], 2);
00120
00121 close (write_pipe[0]);
00122 close (read_pipe[1]);
00123
00124
00125
00126 execlp ("daVinci", "daVinci", "-pipe", 0);
00127 exit (1);
00128
00129 default:
00130 close (read_pipe[1]);
00131 close (write_pipe[0]);
00132 wait_for ();
00133 }
00134
00135 IPA_Enable_daVinci = TRUE;
00136
00137 }
00138
00139
00140
00141 void
00142 daVinci::wait_for (const char *str)
00143 {
00144 char buf[512];
00145
00146 while (fgets (buf, 512, from_display) != NULL) {
00147 if (strcmp (buf, "ok\n") == 0) {
00148 display_ok = TRUE;
00149 return;
00150 } else {
00151 switch (buf[0]) {
00152 case 'n':
00153 case 'e':
00154 case 'm':
00155 case 'a':
00156 if (strncmp (buf, str, strlen(str)) == 0) {
00157 display_ok = TRUE;
00158 return;
00159 }
00160 break;
00161 default:
00162 fputs (buf, stderr);
00163 cleanup ();
00164 return;
00165 }
00166 }
00167 }
00168
00169 cleanup ();
00170 return;
00171 }
00172
00173
00174 void
00175 daVinci::cleanup (void)
00176 {
00177 int stat;
00178
00179 display_ok = FALSE;
00180 kill (pid, SIGINT);
00181 waitpid (pid, &stat, WNOHANG);
00182
00183 fclose (to_display);
00184 fclose (from_display);
00185 }
00186
00187
00188
00189 void
00190 daVinci::Graph_To_Term (NODE_INDEX v, mUINT8 *visit)
00191 {
00192 IPA_NODE *node = (IPA_NODE *) g->Node_User(v);
00193 static const char attr[] = "a(\"COLOR\",\"lightblue\")";
00194
00195 visit[v] = 1;
00196 fprintf (to_display, "l(\"%d\",n(\"\",[a(\"OBJECT\",\"%s\"),%s],[",
00197 v, node->Name(), attr);
00198
00199 NODE_ITER vitr(g, v);
00200
00201 for (NODE_INDEX vi = vitr.First_Succ(); vi != -1; vi = vitr.Next_Succ()) {
00202
00203 fprintf(to_display, "l(\"%d\",e(\"\",[],", vitr.Current_Edge_Index());
00204 if (visit[vi] == 0)
00205 Graph_To_Term (vi, visit);
00206 else
00207 fprintf (to_display, "r(\"%d\")", vi);
00208 fprintf (to_display, ")),");
00209 }
00210
00211 fprintf (to_display, "]))");
00212 }
00213
00214
00215 void
00216 daVinci::Translate_Call_Graph (void)
00217 {
00218 if (!display_ok)
00219 return;
00220
00221 mUINT8 *visit = CXX_NEW_ARRAY (mUINT8, GRAPH_vmax (g), m);
00222 BZERO (visit, sizeof(mUINT8)*GRAPH_vmax(g));
00223
00224 fprintf (to_display, "new_term([");
00225 NODE_ITER vitr(g, GRAPH_root(g));
00226 for (NODE_INDEX vi = vitr.First_Succ(); vi != -1; vi = vitr.Next_Succ()) {
00227 if (visit[vi] == 0) {
00228 Graph_To_Term (vi, visit);
00229 fprintf (to_display, ",");
00230 }
00231 }
00232 fprintf (to_display, "])\n");
00233
00234 CXX_DELETE (visit, m);
00235
00236 wait_for ();
00237 }
00238
00239
00240 void
00241 daVinci::Mark_Used (NODE_INDEX v)
00242 {
00243
00244 if (!display_ok)
00245 return;
00246
00247 fprintf (to_display, "change_node_color(\"%d\",\"red\")\n", v);
00248 wait_for ();
00249 }
00250
00251
00252 void
00253 daVinci::Mark_Deleted (NODE_INDEX v)
00254 {
00255
00256 if (!display_ok)
00257 return;
00258
00259 fprintf (to_display, "change_node_color(\"%d\",\"lightgray\")\n", v);
00260 wait_for ();
00261 }
00262
00263
00264 void
00265 daVinci::Mark_Inlined_Caller (NODE_INDEX v)
00266 {
00267 if (!display_ok)
00268 return;
00269
00270 fprintf (to_display, "change_node_color(\"%d\",\"violet\")\n", v);
00271 wait_for ();
00272 }
00273
00274
00275 void
00276 daVinci::Mark_Inlined_Callee (NODE_INDEX v)
00277 {
00278 if (!display_ok)
00279 return;
00280
00281 fprintf (to_display, "change_node_color(\"%d\",\"lightred\")\n", v);
00282 wait_for ();
00283 }
00284
00285
00286 void
00287 daVinci::Mark_Inlined_Deleted (NODE_INDEX v)
00288 {
00289 if (!display_ok)
00290 return;
00291 fprintf (to_display, "select_nodes_labels([\"%d\"])\n", v);
00292 wait_for ("node_selections_labels");
00293 fprintf (to_display, "hide_or_show_edges\n");
00294 wait_for ();
00295 }