+ FILE *f;
+ char buf[8];
+ size_t ret;
+
+ f = fopen(filename, "r");
+ if(f == NULL) {
+ return;
+ }
+ printf("found profile data '%s'.\n", filename);
+
+ /* check magic */
+ ret = fread(buf, 8, 1, f);
+ if(ret == 0 || strncmp(buf, "firmprof", 8) != 0) {
+ return;
+ }
+
+ if(profile) be_profile_free();
+ profile = new_set(cmp_execcount, 16);
+
+ do {
+ execcount_t query;
+ ret = fread(&query, sizeof(unsigned int), 2, f);
+
+ if(ret != 2) break;
+
+ set_insert(profile, &query, sizeof(query), query.block);
+ } while(1);
+
+ fclose(f);
+ register_vcg_hook();
+}
+
+/**
+ * Frees the profile info
+ */
+void
+be_profile_free(void)
+{
+ if(profile) {
+ unregister_vcg_hook();
+ del_set(profile);
+ }
+}
+
+/**
+ * Tells whether profile module has acquired data
+ */
+int
+be_profile_has_data(void)
+{
+ return (profile != NULL);
+}
+
+/**
+ * Get block execution count as determined be profiling
+ */
+unsigned int
+be_profile_get_block_execcount(const ir_node *block)
+{
+ execcount_t *ec, query;
+
+ if(!profile)
+ return 1;
+
+ query.block = get_irn_node_nr(block);
+ ec = set_find(profile, &query, sizeof(query), get_irn_node_nr(block));
+
+ if(ec != NULL) {
+ return ec->count;
+ } else {
+ ir_fprintf(stderr, "Warning: Profile contains no data for %+F\n",
+ block);
+ return 1;
+ }
+}
+
+typedef struct _intialize_execfreq_env_t {
+ ir_graph *irg;
+ ir_exec_freq *execfreqs;
+ double freq_factor;
+} initialize_execfreq_env_t;
+
+// minimal execution frequency (an execfreq of 0 confuses algos)
+static const double MIN_EXECFREQ = 0.00001;
+
+static void initialize_execfreq(ir_node *block, void *data) {
+ initialize_execfreq_env_t *env = data;
+ double freq;
+
+ if(block == get_irg_start_block(env->irg)
+ || block == get_irg_end_block(env->irg)) {
+ freq = 1.0;
+ } else {
+ freq = be_profile_get_block_execcount(block);
+ freq *= env->freq_factor;
+ if(freq < MIN_EXECFREQ)
+ freq = MIN_EXECFREQ;
+ }
+
+ set_execfreq(env->execfreqs, block, freq);
+}
+
+ir_exec_freq *be_create_execfreqs_from_profile(ir_graph *irg)
+{
+ ir_node *block2 = NULL;
+ ir_node *start_block;
+ const ir_edge_t *edge;
+ initialize_execfreq_env_t env;
+ unsigned count;
+
+ env.irg = irg;
+ env.execfreqs = create_execfreq(irg);
+
+ // find the successor to the start block
+ start_block = get_irg_start_block(irg);
+ foreach_block_succ(start_block, edge) {
+ ir_node *succ = get_edge_src_irn(edge);
+ if(succ != start_block) {
+ block2 = succ;
+ break;
+ }
+ }
+ assert(block2 != NULL);
+
+ count = be_profile_get_block_execcount(block2);
+ if(count == 0) {
+ // the function was never executed, so fallback to estimated freqs
+ free_execfreq(env.execfreqs);
+
+ return compute_execfreq(irg, 10);
+ }
+
+ env.freq_factor = 1.0 / count;
+ irg_block_walk_graph(irg, initialize_execfreq, NULL, &env);