From patchwork Thu Sep 19 19:58:37 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 276051 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 359FD2C0109 for ; Fri, 20 Sep 2013 05:59:42 +1000 (EST) Received: from localhost ([::1]:52851 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VMkO3-0007NH-1F for incoming@patchwork.ozlabs.org; Thu, 19 Sep 2013 15:59:39 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53041) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VMkNi-0007M5-0I for qemu-devel@nongnu.org; Thu, 19 Sep 2013 15:59:23 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VMkNc-0005bD-4i for qemu-devel@nongnu.org; Thu, 19 Sep 2013 15:59:17 -0400 Received: from mail-vc0-x231.google.com ([2607:f8b0:400c:c03::231]:44624) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VMkNb-0005b7-VQ for qemu-devel@nongnu.org; Thu, 19 Sep 2013 15:59:12 -0400 Received: by mail-vc0-f177.google.com with SMTP id hv10so4532559vcb.8 for ; Thu, 19 Sep 2013 12:59:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id; bh=3xMqnUA31NIIQ0XYbidb9eG+NdQHOZxfGxhVnB9Lz8E=; b=iKzjrfMBXtiV4aQvnc1RBR+wzE1cND1q2qxLB6dEJCtWJm8L41pvMoe6MXwayaDgLk igjseQzI0d/QibAVN4dGW6hCYxWYSEZLQnxWbF231WIl2NQMdTmsTrmnoH/NEU5Kfg4s JjeTAZl9y7SH0DliwkkEDn2czZC4wHDhMsmoxU5W9KVoypV2n1ke68dhmQ5kxpJpn/TY rU/6Dne1QpBWStjgvXX/rjuZedZ06anRrLzFbZDMxcwj0ijpv1RBK7sZXLlNHacSixPe /PjKpvMaScfOy70fnIgeLs0bL6VR4JMCPKkHqu3C9qdIbHn3Se0a/sd+54IkEa+vJnb6 Ykxg== X-Received: by 10.58.208.130 with SMTP id me2mr2537018vec.13.1379620751374; Thu, 19 Sep 2013 12:59:11 -0700 (PDT) Received: from anchor.com (50-194-63-110-static.hfc.comcastbusiness.net. [50.194.63.110]) by mx.google.com with ESMTPSA id fh2sm8677666vdb.13.1969.12.31.16.00.00 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Thu, 19 Sep 2013 12:59:10 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Thu, 19 Sep 2013 12:58:37 -0700 Message-Id: <1379620717-20358-1-git-send-email-rth@twiddle.net> X-Mailer: git-send-email 1.8.1.4 X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:400c:c03::231 Cc: aurelien@aurel32.net Subject: [Qemu-devel] [PATCH] tcg: Use bitmaps for free temporaries X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org We previously allocated 32-bits per temp for the next_free_temp entry. We now allocate 4 bits per temp across the 4 bitmaps. Using a linked list meant that if a translator is tweeked, resulting in temps being freed in a different order, that would have follow-on effects throughout the TB. Always allocating the lowest free temp means that follow-on effects are minimized, which can make it easier to diff output when debugging the translators. Signed-off-by: Richard Henderson Reviewed-by: Peter Maydell Reviewed-by: Aurelien Jarno --- tcg/tcg.c | 32 +++++++++++++++----------------- tcg/tcg.h | 11 ++++++----- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/tcg/tcg.c b/tcg/tcg.c index fd7fb6b..41ed8b0 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -316,11 +316,12 @@ void tcg_set_frame(TCGContext *s, int reg, intptr_t start, intptr_t size) void tcg_func_start(TCGContext *s) { - int i; tcg_pool_reset(s); s->nb_temps = s->nb_globals; - for(i = 0; i < (TCG_TYPE_COUNT * 2); i++) - s->first_free_temp[i] = -1; + + /* No temps have been previously allocated for size or locality. */ + memset(s->free_temps, 0, sizeof(s->free_temps)); + s->labels = tcg_malloc(sizeof(TCGLabel) * TCG_MAX_LABELS); s->nb_labels = 0; s->current_frame_offset = s->frame_start; @@ -468,16 +469,15 @@ static inline int tcg_temp_new_internal(TCGType type, int temp_local) TCGTemp *ts; int idx, k; - k = type; - if (temp_local) - k += TCG_TYPE_COUNT; - idx = s->first_free_temp[k]; - if (idx != -1) { - /* There is already an available temp with the - right type */ + k = type + (temp_local ? TCG_TYPE_COUNT : 0); + idx = find_first_bit(s->free_temps[k].l, TCG_MAX_TEMPS); + if (idx < TCG_MAX_TEMPS) { + /* There is already an available temp with the right type. */ + clear_bit(idx, s->free_temps[k].l); + ts = &s->temps[idx]; - s->first_free_temp[k] = ts->next_free_temp; ts->temp_allocated = 1; + assert(ts->base_type == type); assert(ts->temp_local == temp_local); } else { idx = s->nb_temps; @@ -533,7 +533,7 @@ TCGv_i64 tcg_temp_new_internal_i64(int temp_local) return MAKE_TCGV_I64(idx); } -static inline void tcg_temp_free_internal(int idx) +static void tcg_temp_free_internal(int idx) { TCGContext *s = &tcg_ctx; TCGTemp *ts; @@ -550,11 +550,9 @@ static inline void tcg_temp_free_internal(int idx) ts = &s->temps[idx]; assert(ts->temp_allocated != 0); ts->temp_allocated = 0; - k = ts->base_type; - if (ts->temp_local) - k += TCG_TYPE_COUNT; - ts->next_free_temp = s->first_free_temp[k]; - s->first_free_temp[k] = idx; + + k = ts->type + (ts->temp_local ? TCG_TYPE_COUNT : 0); + set_bit(idx, s->free_temps[k].l); } void tcg_temp_free_i32(TCGv_i32 arg) diff --git a/tcg/tcg.h b/tcg/tcg.h index 902c751..c45e41b 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -26,7 +26,7 @@ #define TCG_H #include "qemu-common.h" - +#include "qemu/bitops.h" #include "tcg-target.h" /* Default target word size to pointer size. */ @@ -400,8 +400,6 @@ typedef struct TCGTemp { basic blocks. Otherwise, it is not preserved across basic blocks. */ unsigned int temp_allocated:1; /* never used for code gen */ - /* index of next free temp of same base type, -1 if end */ - int next_free_temp; const char *name; } TCGTemp; @@ -412,6 +410,10 @@ typedef struct TCGHelperInfo { typedef struct TCGContext TCGContext; +typedef struct TCGTempSet { + unsigned long l[BITS_TO_LONGS(TCG_MAX_TEMPS)]; +} TCGTempSet; + struct TCGContext { uint8_t *pool_cur, *pool_end; TCGPool *pool_first, *pool_current, *pool_first_large; @@ -419,8 +421,6 @@ struct TCGContext { int nb_labels; int nb_globals; int nb_temps; - /* index of free temps, -1 if none */ - int first_free_temp[TCG_TYPE_COUNT * 2]; /* goto_tb support */ uint8_t *code_buf; @@ -446,6 +446,7 @@ struct TCGContext { uint8_t *code_ptr; TCGTemp temps[TCG_MAX_TEMPS]; /* globals first, temps after */ + TCGTempSet free_temps[TCG_TYPE_COUNT * 2]; TCGHelperInfo *helpers; int nb_helpers;