From ae3048300979b15448eb3c52c7b5271c8203e4d3 Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Sun, 14 Oct 2012 22:06:03 +0200 Subject: [PATCH] rework timer API --- include/libfirm/irgopt.h | 5 ++ include/libfirm/timing.h | 14 ++++- ir/ana/irlivechk.c | 3 + ir/be/be_t.h | 16 ++--- ir/be/bemain.c | 4 +- ir/common/timing.c | 133 ++++++++++++++++++++++++++++----------- ir/lpp/lpp_net.c | 6 +- 7 files changed, 127 insertions(+), 54 deletions(-) diff --git a/include/libfirm/irgopt.h b/include/libfirm/irgopt.h index 169931d4f..a3891093a 100644 --- a/include/libfirm/irgopt.h +++ b/include/libfirm/irgopt.h @@ -63,6 +63,11 @@ FIRM_API void local_optimize_graph(ir_graph *irg); */ FIRM_API void local_opts(ir_graph *irg); +/** + * Perform local optimizations on nodes on const code irg + */ +FIRM_API void local_opts_const_code(void); + /** Same functionality as local_opts above, but without framework wrapper * @deprecated */ diff --git a/include/libfirm/timing.h b/include/libfirm/timing.h index 282e4ece1..14f70b372 100644 --- a/include/libfirm/timing.h +++ b/include/libfirm/timing.h @@ -96,6 +96,11 @@ FIRM_API void ir_timer_reset(ir_timer_t *timer); */ FIRM_API void ir_timer_stop(ir_timer_t *timer); +/** + * Set currently running timer as parent to @p timer + */ +FIRM_API void ir_timer_init_parent(ir_timer_t *timer); + /** * Push a timer of the timer stack. This automatically * stop the previous timer on tos and start the new one. @@ -103,14 +108,14 @@ FIRM_API void ir_timer_stop(ir_timer_t *timer); * @param timer The timer to push on stack. * @return non-zero on succes, zero if the timer is already on the stack. */ -FIRM_API int ir_timer_push(ir_timer_t *timer); +FIRM_API void ir_timer_push(ir_timer_t *timer); /** * Pop the current timer. This automatically stops it and * start the timer that is now on the stack. * @return the popped timer */ -FIRM_API ir_timer_t *ir_timer_pop(void); +FIRM_API void ir_timer_pop(ir_timer_t *timer); /** * Returns the number of milliseconds, the timer has elapsed. @@ -126,6 +131,11 @@ FIRM_API unsigned long ir_timer_elapsed_msec(const ir_timer_t *timer); */ FIRM_API unsigned long ir_timer_elapsed_usec(const ir_timer_t *timer); +/** + * Returns the number of seconds, the timer has elapsed. + */ +FIRM_API double ir_timer_elapsed_sec(const ir_timer_t *timer); + #include "end.h" #endif diff --git a/ir/ana/irlivechk.c b/ir/ana/irlivechk.c index a5aeba1a4..8da414d7b 100644 --- a/ir/ana/irlivechk.c +++ b/ir/ana/irlivechk.c @@ -40,6 +40,9 @@ #include +/* statev is expensive here, only enable when needed */ +#define DISABLE_STATEV + #include "irgraph_t.h" #include "irnode_t.h" #include "irnodemap.h" diff --git a/ir/be/be_t.h b/ir/be/be_t.h index d2ce75362..67fa9be05 100644 --- a/ir/be/be_t.h +++ b/ir/be/be_t.h @@ -139,26 +139,18 @@ extern ir_timer_t *be_timers[T_LAST+1]; static inline void be_timer_push(be_timer_id_t id) { - int res; + assert(id <= T_LAST); if (!be_timing) return; - - assert(id <= T_LAST); - res = ir_timer_push(be_timers[id]); - (void) res; - assert(res && "Timer already on stack, cannot be pushed twice."); + ir_timer_push(be_timers[id]); } static inline void be_timer_pop(be_timer_id_t id) { - ir_timer_t *tmp; + assert(id <= T_LAST); if (!be_timing) return; - - tmp = ir_timer_pop(); - (void) tmp; - (void) id; - assert(tmp == be_timers[id] && "Attempt to pop wrong timer."); + ir_timer_pop(be_timers[id]); } #endif diff --git a/ir/be/bemain.c b/ir/be/bemain.c index d5977ad2b..529b3373c 100644 --- a/ir/be/bemain.c +++ b/ir/be/bemain.c @@ -621,6 +621,9 @@ static void be_main_loop(FILE *file_handle, const char *cup_name) assert(num_irgs == get_irp_n_irgs()); } + for (be_timer_id_t t = T_FIRST; t < T_LAST+1; ++t) { + ir_timer_init_parent(be_timers[t]); + } if (!have_profile) { be_timer_push(T_EXECFREQ); for (i = 0; i < num_irgs; ++i) { @@ -833,7 +836,6 @@ static void be_main_loop(FILE *file_handle, const char *cup_name) } } for (t = T_FIRST; t < T_LAST+1; ++t) { - ir_timer_stop(be_timers[t]); ir_timer_reset(be_timers[t]); } } diff --git a/ir/common/timing.c b/ir/common/timing.c index 59c9409f2..61dd04130 100644 --- a/ir/common/timing.c +++ b/ir/common/timing.c @@ -28,6 +28,7 @@ #include "timing.h" #include "xmalloc.h" +#include "error.h" #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN @@ -69,7 +70,8 @@ static inline void _time_reset(ir_timer_val_t *val); struct ir_timer_t { ir_timer_val_t elapsed; /**< the elapsed time so far */ ir_timer_val_t start; /**< the start value of the timer */ - ir_timer_t *link; /**< link to the next entry in the timer stack */ + ir_timer_t *parent; /**< parent of a timer */ + ir_timer_t *displaced; /**< former timer in case of timer_push */ unsigned running : 1; /**< set if this timer is running */ }; @@ -79,12 +81,8 @@ static ir_timer_t *timer_stack; ir_timer_t *ir_timer_new(void) { ir_timer_t *timer = XMALLOCZ(ir_timer_t); - _time_reset(&timer->elapsed); _time_reset(&timer->start); - timer->link = NULL; - timer->running = 0; - return timer; } @@ -117,6 +115,11 @@ static inline unsigned long _time_to_usec(const ir_timer_val_t *elapsed) + (unsigned long) elapsed->tv_usec; } +static inline double _time_to_sec(const ir_timer_val_t *elapsed) +{ + return (double)elapsed->tv_sec + (double)elapsed->tv_usec / 1000000.0; +} + static inline ir_timer_val_t *_time_add(ir_timer_val_t *res, const ir_timer_val_t *lhs, const ir_timer_val_t *rhs) { @@ -159,11 +162,21 @@ static inline unsigned long _time_to_usec(const ir_timer_val_t *elapsed) LARGE_INTEGER freq; if (!QueryPerformanceFrequency(&freq)) - return (unsigned long) elapsed->lo_prec; + return (unsigned long) elapsed->lo_prec * 1000; return (unsigned long) ((elapsed->hi_prec.QuadPart * 1000000) / freq.QuadPart); } +static inline double _time_to_sec(const ir_timer_val_t *elapsed) +{ + LARGE_INTEGER freq; + + if (!QueryPerformanceFrequency(&freq)) + return (double) elapsed->lo_prec / 1000.; + + return (double)elapsed->hi_prec.QuadPart / (double)freq.QuadPart; +} + static inline ir_timer_val_t *_time_add(ir_timer_val_t *res, const ir_timer_val_t *lhs, const ir_timer_val_t *rhs) { LARGE_INTEGER dummy; @@ -320,9 +333,19 @@ void ir_timer_reset(ir_timer_t *timer) /* start a timer */ void ir_timer_start(ir_timer_t *timer) { + if (timer->running) + panic("timer started twice"); + _time_reset(&timer->start); _time_get(&timer->start); timer->running = 1; + + if (timer->parent == NULL) { + timer->parent = timer_stack; + } else if (timer->parent != timer_stack) { + panic("timer used at different stack positions"); + } + timer_stack = timer; } void ir_timer_reset_and_start(ir_timer_t *timer) @@ -331,47 +354,72 @@ void ir_timer_reset_and_start(ir_timer_t *timer) ir_timer_start(timer); } -/* stop a running timer */ void ir_timer_stop(ir_timer_t *timer) { - /* If the timer is running stop, measure the time and add it to the - * elapsed time. */ - if (timer->running) { - ir_timer_val_t val; - ir_timer_val_t tgt; + if (!timer->running) + panic("attempting to stop stopped timer"); + if (timer != timer_stack) + panic("timer stack error"); + timer_stack = timer->parent; + + ir_timer_val_t val; + ir_timer_val_t tgt; + + _time_get(&val); + timer->running = 0; + _time_add(&timer->elapsed, &timer->elapsed, _time_sub(&tgt, &val, &timer->start)); +} - _time_get(&val); - timer->running = 0; - _time_add(&timer->elapsed, &timer->elapsed, _time_sub(&tgt, &val, &timer->start)); - _time_reset(&timer->start); +void ir_timer_init_parent(ir_timer_t *timer) +{ + if (timer == NULL) + return; + if (timer->parent != NULL && timer->parent != timer_stack) + panic("timer parent mismatch"); + timer->parent = timer_stack; +} + +void ir_timer_push(ir_timer_t *timer) +{ + if (timer->running) + panic("timer started twice"); + + ir_timer_t *parent = timer->parent; + if (timer->parent == NULL) + panic("pushing timer with unknown parent"); + + timer->displaced = timer_stack; + for (ir_timer_t *t = timer_stack; t != parent; t = t->parent) { + if (t == NULL) + panic("parent timer not on stack"); + ir_timer_stop(t); } + timer_stack = parent; + + ir_timer_start(timer); } -/* push a timer on the stack */ -int ir_timer_push(ir_timer_t *timer) +static void start_stack(ir_timer_t *timer, ir_timer_t *stop) { - if (timer->link) - return 0; - timer->link = timer_stack; - if (timer_stack) - ir_timer_stop(timer_stack); + if (timer == stop) + return; + start_stack(timer->parent, stop); ir_timer_start(timer); - timer_stack = timer; - return 1; } -/* pop a timer from the stack */ -ir_timer_t *ir_timer_pop(void) +void ir_timer_pop(ir_timer_t *timer) { - ir_timer_t *timer = timer_stack; - if (timer) { - ir_timer_stop(timer); - timer_stack = timer->link; - timer->link = NULL; - if (timer_stack) - ir_timer_start(timer_stack); - } - return timer; + if (!timer->running) + panic("attempting to stop stopped timer"); + ir_timer_t *displaced = timer->displaced; + if (displaced == NULL) + panic("timer start/stop/push/pop mismatch"); + + ir_timer_t *parent = timer->parent; + timer->displaced = NULL; + + ir_timer_stop(timer); + start_stack(displaced, parent); } unsigned long ir_timer_elapsed_msec(const ir_timer_t *timer) @@ -399,3 +447,16 @@ unsigned long ir_timer_elapsed_usec(const ir_timer_t *timer) } return _time_to_usec(elapsed); } + +double ir_timer_elapsed_sec(const ir_timer_t *timer) +{ + ir_timer_val_t v; + const ir_timer_val_t *elapsed = &timer->elapsed; + + if (timer->running) { + elapsed = &v; + _time_get(&v); + _time_add(&v, &timer->elapsed, _time_sub(&v, &v, &timer->start)); + } + return _time_to_sec(elapsed); +} diff --git a/ir/lpp/lpp_net.c b/ir/lpp/lpp_net.c index 7ef72858f..6af263659 100644 --- a/ir/lpp/lpp_net.c +++ b/ir/lpp/lpp_net.c @@ -196,12 +196,12 @@ void lpp_solve_net(lpp_t *lpp, const char *host, const char *solver) t_send = ir_timer_new(); t_recv = ir_timer_new(); - ir_timer_push(t_send); + ir_timer_start(t_send); lpp_writel(comm, LPP_CMD_PROBLEM); lpp_serialize(comm, lpp, 1); lpp_serialize_values(comm, lpp, lpp_value_start); lpp_flush(comm); - ir_timer_pop(); + ir_timer_stop(t_send); lpp->send_time = ir_timer_elapsed_usec(t_send); ready = 0; @@ -212,7 +212,7 @@ void lpp_solve_net(lpp_t *lpp, const char *host, const char *solver) ir_timer_push(t_recv); lpp_deserialize_stats(comm, lpp); lpp_deserialize_values(comm, lpp, lpp_value_solution); - ir_timer_pop(); + ir_timer_stop(t_recv); lpp->recv_time = ir_timer_elapsed_usec(t_recv); ready = 1; break; -- 2.20.1