From patchwork Sun Oct 11 19:47:19 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aldy Hernandez X-Patchwork-Id: 528794 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id C75811402B0 for ; Mon, 12 Oct 2015 06:47:34 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=ZsAx53/K; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=WJVuJzCrP5GWZAzHoH0DfufYZiZWJJKWnvhpZXfRpINUw0zhtA 4p7Gsj+a8FxZyXys9kCpNE/M7DYTuqPrASyUMz8X0iYm2s5efKWuXZzWiO0/fsz4 05gQXYqjU/crLm/51KgMdHc/id6MYaCJjEHnDfWGeoZNjdtad1sv0nAek= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to :from:subject:message-id:date:mime-version:content-type; s= default; bh=lBa3jR7eFzB8aUxtOdrhSYq8Ffw=; b=ZsAx53/KUIB/22L/zmAC a1SbJ5b1WlEMr21h13jiTxFdV00VwN6GB7DcK15IHrEPmBe1I+3mQZ297QrOQUNo 0lRbpYtG8oq69OfB3Ph/0CpgBtDVcpMWXCpfaZS0iX+pD6AX3VhJpVI5nRw3cVsl /XPI4GmQlRo0RXR2GK7d+Dw= Received: (qmail 18625 invoked by alias); 11 Oct 2015 19:47:27 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 18615 invoked by uid 89); 11 Oct 2015 19:47:25 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-4.6 required=5.0 tests=AWL, BAYES_50, SPF_HELO_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Sun, 11 Oct 2015 19:47:22 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id 89D59A144D for ; Sun, 11 Oct 2015 19:47:21 +0000 (UTC) Received: from reynosa.quesejoda.com (vpn-49-80.rdu2.redhat.com [10.10.49.80]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BJlJTm008279; Sun, 11 Oct 2015 15:47:20 -0400 To: gcc-patches , Jakub Jelinek From: Aldy Hernandez Subject: [gomp4.1] make libgomp's splay tree implementation key agnostic Message-ID: <561ABCC7.9090605@redhat.com> Date: Sun, 11 Oct 2015 12:47:19 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.1.0 MIME-Version: 1.0 Hi. I'm investigating balanced binary tree options for the multiple priorities variant of the task scheduler. In looking at the splay tree adaption in libgomp, I noticed that it requires preexisting typedefs and other definitions before including splay-tree.h. This makes it impossible to reuse for another key within the library because splay-tree.c must know about the node contents, and other files throughout libgomp all share the aforementioned typedefs (because they all include libgomp.h). I also can't use libiberty's version because there are name conflicts with libgomp's adaptation. I see no reason why the splay tree implementation itself (splay-tree.c) needs to know about the content of the nodes. With a little rearranging of the data structures and some casts, we can reuse the splay trees at will. With the following patch we achieve the above, with the only penalty of an indirection for a compare callback. Tested with make check-target-libgomp on x86-64 Linux. OK for branch? Aldy commit 870adcc7fc9b0beb72a4cd78a5cda710c6bff661 Author: Aldy Hernandez Date: Sat Oct 10 16:28:06 2015 -0700 * libgomp.h: Include splay-tree.h earlier. Use a splay_tree_key_s pointer, instead of splay_tree_key throughout. * oacc-mem.c (KEY): New macro. Rename all uses of splay_tree_key to a splay_tree_key_s pointer. Cast things appropriately. * oacc-parallel.c: Same as oacc-mem.c. * splay-tree.h: Adjust comment to reflect that we no longer need preexisting typedefs before including file. Rename splay_tree_node_s to __internal_splay_tree_node_s. Move left and right pointers before any other field, and make "key" a generic array. * target.c (KEY): New macro. (splay_compare): Make function static. Rename all uses of splay_tree_key to a splay_tree_key_s pointer. Cast things appropriately. (gomp_map_vars): Adjust gomp_malloc() call to take into account size of key. (gomp_load_image_to_device): Same. (omp_target_associate_ptr): Same. (gomp_target_init): Set mem_map.compare to its comparison function. diff --git a/libgomp/libgomp.h b/libgomp/libgomp.h index 19b3dab..48c5442 100644 --- a/libgomp/libgomp.h +++ b/libgomp/libgomp.h @@ -44,6 +44,7 @@ #include "config.h" #include "gstdint.h" #include "libgomp-plugin.h" +#include "splay-tree.h" #include #include @@ -741,13 +742,27 @@ extern void gomp_init_targets_once (void); extern int gomp_get_num_devices (void); extern void gomp_target_task_fn (void *); -typedef struct splay_tree_node_s *splay_tree_node; -typedef struct splay_tree_s *splay_tree; -typedef struct splay_tree_key_s *splay_tree_key; +/* Special value for refcount - infinity. */ +#define REFCOUNT_INFINITY (~(uintptr_t) 0) + +struct splay_tree_key_s { + /* Address of the host object. */ + uintptr_t host_start; + /* Address immediately after the host object. */ + uintptr_t host_end; + /* Descriptor of the target memory. */ + struct target_mem_desc *tgt; + /* Offset from tgt->tgt_start to the start of the target object. */ + uintptr_t tgt_offset; + /* Reference count. */ + uintptr_t refcount; + /* Asynchronous reference count. */ + uintptr_t async_refcount; +}; struct target_var_desc { /* Splay key. */ - splay_tree_key key; + struct splay_tree_key_s *key; /* True if data should be copied from device to host at the end. */ bool copy_from; /* True if data always should be copied from device to host at the end. */ @@ -782,26 +797,6 @@ struct target_mem_desc { struct target_var_desc list[]; }; -/* Special value for refcount - infinity. */ -#define REFCOUNT_INFINITY (~(uintptr_t) 0) - -struct splay_tree_key_s { - /* Address of the host object. */ - uintptr_t host_start; - /* Address immediately after the host object. */ - uintptr_t host_end; - /* Descriptor of the target memory. */ - struct target_mem_desc *tgt; - /* Offset from tgt->tgt_start to the start of the target object. */ - uintptr_t tgt_offset; - /* Reference count. */ - uintptr_t refcount; - /* Asynchronous reference count. */ - uintptr_t async_refcount; -}; - -#include "splay-tree.h" - typedef struct acc_dispatch_t { /* This is a linked list of data mapped using the diff --git a/libgomp/oacc-mem.c b/libgomp/oacc-mem.c index af067d6..873f3a5 100644 --- a/libgomp/oacc-mem.c +++ b/libgomp/oacc-mem.c @@ -35,21 +35,20 @@ #include #include +#define KEY(K) ((struct splay_tree_key_s *) (K)) + /* Return block containing [H->S), or NULL if not contained. The device lock for DEV must be locked on entry, and remains locked on exit. */ -static splay_tree_key +static struct splay_tree_key_s * lookup_host (struct gomp_device_descr *dev, void *h, size_t s) { struct splay_tree_key_s node; - splay_tree_key key; node.host_start = (uintptr_t) h; node.host_end = (uintptr_t) h + s; - key = splay_tree_lookup (&dev->mem_map, &node); - - return key; + return KEY (splay_tree_lookup (&dev->mem_map, &node)); } /* Return block containing [D->S), or NULL if not contained. @@ -58,7 +57,7 @@ lookup_host (struct gomp_device_descr *dev, void *h, size_t s) operation. The device lock associated with TGT must be locked on entry, and remains locked on exit. */ -static splay_tree_key +static struct splay_tree_key_s * lookup_dev (struct target_mem_desc *tgt, void *d, size_t s) { int i; @@ -80,7 +79,7 @@ lookup_dev (struct target_mem_desc *tgt, void *d, size_t s) { void * offset; - splay_tree_key k = &t->array[i].key; + struct splay_tree_key_s *k = KEY (&t->array[i].key); offset = d - t->tgt_start + k->tgt_offset; if (k->host_start + offset <= (void *) k->host_end) @@ -114,7 +113,7 @@ acc_malloc (size_t s) void acc_free (void *d) { - splay_tree_key k; + struct splay_tree_key_s *k; if (!d) return; @@ -176,7 +175,6 @@ acc_memcpy_from_device (void *h, void *d, size_t s) void * acc_deviceptr (void *h) { - splay_tree_key n; void *d; void *offset; @@ -187,7 +185,7 @@ acc_deviceptr (void *h) gomp_mutex_lock (&dev->lock); - n = lookup_host (dev, h, 1); + struct splay_tree_key_s *n = lookup_host (dev, h, 1); if (!n) { @@ -210,7 +208,7 @@ acc_deviceptr (void *h) void * acc_hostptr (void *d) { - splay_tree_key n; + struct splay_tree_key_s *n; void *h; void *offset; @@ -243,8 +241,6 @@ acc_hostptr (void *d) int acc_is_present (void *h, size_t s) { - splay_tree_key n; - if (!s || !h) return 0; @@ -255,7 +251,7 @@ acc_is_present (void *h, size_t s) gomp_mutex_lock (&acc_dev->lock); - n = lookup_host (acc_dev, h, s); + struct splay_tree_key_s *n = lookup_host (acc_dev, h, s); if (n && ((uintptr_t)h < n->host_start || (uintptr_t)h + s > n->host_end @@ -340,7 +336,7 @@ acc_unmap_data (void *h) gomp_mutex_lock (&acc_dev->lock); - splay_tree_key n = lookup_host (acc_dev, h, 1); + struct splay_tree_key_s *n = lookup_host (acc_dev, h, 1); struct target_mem_desc *t; if (!n) @@ -396,7 +392,6 @@ static void * present_create_copy (unsigned f, void *h, size_t s) { void *d; - splay_tree_key n; if (!h || !s) gomp_fatal ("[%p,+%d] is a bad range", (void *)h, (int)s); @@ -408,7 +403,7 @@ present_create_copy (unsigned f, void *h, size_t s) gomp_mutex_lock (&acc_dev->lock); - n = lookup_host (acc_dev, h, s); + struct splay_tree_key_s *n = lookup_host (acc_dev, h, s); if (n) { /* Present. */ @@ -492,14 +487,13 @@ static void delete_copyout (unsigned f, void *h, size_t s) { size_t host_size; - splay_tree_key n; void *d; struct goacc_thread *thr = goacc_thread (); struct gomp_device_descr *acc_dev = thr->dev; gomp_mutex_lock (&acc_dev->lock); - n = lookup_host (acc_dev, h, s); + struct splay_tree_key_s *n = lookup_host (acc_dev, h, s); /* No need to call lazy open, as the data must already have been mapped. */ @@ -545,14 +539,13 @@ void acc_copyout (void *h, size_t s) static void update_dev_host (int is_dev, void *h, size_t s) { - splay_tree_key n; void *d; struct goacc_thread *thr = goacc_thread (); struct gomp_device_descr *acc_dev = thr->dev; gomp_mutex_lock (&acc_dev->lock); - n = lookup_host (acc_dev, h, s); + struct splay_tree_key_s *n = lookup_host (acc_dev, h, s); /* No need to call lazy open, as the data must already have been mapped. */ @@ -609,13 +602,12 @@ gomp_acc_remove_pointer (void *h, bool force_copyfrom, int async, int mapnum) { struct goacc_thread *thr = goacc_thread (); struct gomp_device_descr *acc_dev = thr->dev; - splay_tree_key n; struct target_mem_desc *t; int minrefs = (mapnum == 1) ? 2 : 3; gomp_mutex_lock (&acc_dev->lock); - n = lookup_host (acc_dev, h, 1); + struct splay_tree_key_s *n = lookup_host (acc_dev, h, 1); if (!n) { diff --git a/libgomp/oacc-parallel.c b/libgomp/oacc-parallel.c index 8f8ad77..9a452ca 100644 --- a/libgomp/oacc-parallel.c +++ b/libgomp/oacc-parallel.c @@ -38,6 +38,8 @@ #include #include +#define KEY(K) ((struct splay_tree_key_s *) (K)) + static int find_pset (int pos, size_t mapnum, unsigned short *kinds) { @@ -66,7 +68,7 @@ GOACC_parallel (int device, void (*fn) (void *), void **devaddrs; unsigned int i; struct splay_tree_key_s k; - splay_tree_key tgt_fn_key; + struct splay_tree_key_s *tgt_fn_key; void (*tgt_fn); if (num_gangs != 1) @@ -119,7 +121,7 @@ GOACC_parallel (int device, void (*fn) (void *), k.host_start = (uintptr_t) fn; k.host_end = k.host_start + 1; gomp_mutex_lock (&acc_dev->lock); - tgt_fn_key = splay_tree_lookup (&acc_dev->mem_map, &k); + tgt_fn_key = KEY (splay_tree_lookup (&acc_dev->mem_map, &k)); gomp_mutex_unlock (&acc_dev->lock); if (tgt_fn_key == NULL) diff --git a/libgomp/splay-tree.c b/libgomp/splay-tree.c index 030ca8f..0d00faa 100644 --- a/libgomp/splay-tree.c +++ b/libgomp/splay-tree.c @@ -25,8 +25,8 @@ . */ /* The splay tree code copied from include/splay-tree.h and adjusted, - so that all the data lives directly in splay_tree_node_s structure - and no extra allocations are needed. */ + so that all the data lives directly in the node structure and no + extra allocations are needed. */ /* For an easily readable description of splay-trees, see: @@ -37,9 +37,6 @@ are amortized O(log n) time for a tree with n nodes. */ #include "libgomp.h" -#include "splay-tree.h" - -extern int splay_compare (splay_tree_key, splay_tree_key); /* Rotate the edge joining the left child N with its parent P. PP is the grandparents' pointer to P. */ @@ -80,7 +77,7 @@ splay_tree_splay (splay_tree sp, splay_tree_key key) splay_tree_node n, c; n = sp->root; - cmp1 = splay_compare (key, &n->key); + cmp1 = sp->compare (key, &n->key); /* Found. */ if (cmp1 == 0) @@ -96,7 +93,7 @@ splay_tree_splay (splay_tree sp, splay_tree_key key) /* Next one left or right? If found or no child, we're done after one rotation. */ - cmp2 = splay_compare (key, &c->key); + cmp2 = sp->compare (key, &c->key); if (cmp2 == 0 || (cmp2 < 0 && !c->left) || (cmp2 > 0 && !c->right)) @@ -142,7 +139,7 @@ splay_tree_insert (splay_tree sp, splay_tree_node node) splay_tree_splay (sp, &node->key); if (sp->root) - comparison = splay_compare (&sp->root->key, &node->key); + comparison = sp->compare (&sp->root->key, &node->key); if (sp->root && comparison == 0) gomp_fatal ("Duplicate node"); @@ -175,7 +172,7 @@ splay_tree_remove (splay_tree sp, splay_tree_key key) { splay_tree_splay (sp, key); - if (sp->root && splay_compare (&sp->root->key, key) == 0) + if (sp->root && sp->compare (&sp->root->key, key) == 0) { splay_tree_node left, right; @@ -210,7 +207,7 @@ splay_tree_lookup (splay_tree sp, splay_tree_key key) { splay_tree_splay (sp, key); - if (sp->root && splay_compare (&sp->root->key, key) == 0) + if (sp->root && sp->compare (&sp->root->key, key) == 0) return &sp->root->key; else return NULL; diff --git a/libgomp/splay-tree.h b/libgomp/splay-tree.h index 085021c..aed07c3 100644 --- a/libgomp/splay-tree.h +++ b/libgomp/splay-tree.h @@ -25,15 +25,8 @@ . */ /* The splay tree code copied from include/splay-tree.h and adjusted, - so that all the data lives directly in splay_tree_node_s structure - and no extra allocations are needed. - - Files including this header should before including it add: -typedef struct splay_tree_node_s *splay_tree_node; -typedef struct splay_tree_s *splay_tree; -typedef struct splay_tree_key_s *splay_tree_key; - define splay_tree_key_s structure, and define - splay_compare inline function. */ + so that all the data lives directly in the node structure and no + extra allocations are needed. */ /* For an easily readable description of splay-trees, see: @@ -46,18 +39,29 @@ typedef struct splay_tree_key_s *splay_tree_key; #ifndef _SPLAY_TREE_H #define _SPLAY_TREE_H 1 -/* The nodes in the splay tree. */ -struct splay_tree_node_s { - struct splay_tree_key_s key; +/* The nodes in the splay tree. The sizeof this structure would be + sizeof(__internal_splay_tree_node_s) plus the size of the actual + key. */ +typedef struct __internal_splay_tree_node_s { /* The left and right children, respectively. */ - splay_tree_node left; - splay_tree_node right; -}; + struct __internal_splay_tree_node_s *left; + struct __internal_splay_tree_node_s *right; + /* This is actually a place holder. The actual key is embedded in + this node, and can be accessed by the bits starting at &key + here. */ + char key[1]; +} *splay_tree_node; + +/* Pointer to the KEY. We declare it void, to make sure we don't + dereference it, since the splay-tree.c implementation should make + no assumptions as to its contents. */ +typedef void *splay_tree_key; /* The splay tree. */ -struct splay_tree_s { +typedef struct splay_tree_s { + int (*compare)(splay_tree_key, splay_tree_key); splay_tree_node root; -}; +} *splay_tree; extern splay_tree_key splay_tree_lookup (splay_tree, splay_tree_key); extern void splay_tree_insert (splay_tree, splay_tree_node); diff --git a/libgomp/target.c b/libgomp/target.c index de6a2c9..bb2ac03 100644 --- a/libgomp/target.c +++ b/libgomp/target.c @@ -45,6 +45,8 @@ #include "plugin-suffix.h" #endif +#define KEY(K) ((struct splay_tree_key_s *) (K)) + static void gomp_target_init (void); /* The whole initialization code for offloading plugins is only run one. */ @@ -94,9 +96,11 @@ gomp_realloc_unlock (void *old, size_t size) /* The comparison function. */ -attribute_hidden int -splay_compare (splay_tree_key x, splay_tree_key y) +static int +splay_compare (splay_tree_key xp, splay_tree_key yp) { + struct splay_tree_key_s *x = KEY (xp); + struct splay_tree_key_s *y = KEY (yp); if (x->host_start == x->host_end && y->host_start == y->host_end) return 0; @@ -143,8 +147,8 @@ resolve_device (int device_id) } -static inline splay_tree_key -gomp_map_lookup (splay_tree mem_map, splay_tree_key key) +static inline struct splay_tree_key_s * +gomp_map_lookup (splay_tree mem_map, struct splay_tree_key_s *key) { if (key->host_start != key->host_end) return splay_tree_lookup (mem_map, key); @@ -158,16 +162,18 @@ gomp_map_lookup (splay_tree mem_map, splay_tree_key key) n = splay_tree_lookup (mem_map, key); key->host_start++; if (n) - return n; - return splay_tree_lookup (mem_map, key); + return KEY (n); + return KEY (splay_tree_lookup (mem_map, key)); } /* Handle the case where gomp_map_lookup found oldn for newn. Helper function of gomp_map_vars. */ static inline void -gomp_map_vars_existing (struct gomp_device_descr *devicep, splay_tree_key oldn, - splay_tree_key newn, struct target_var_desc *tgt_var, +gomp_map_vars_existing (struct gomp_device_descr *devicep, + struct splay_tree_key_s *oldn, + struct splay_tree_key_s *newn, + struct target_var_desc *tgt_var, unsigned char kind) { tgt_var->key = oldn; @@ -226,7 +232,7 @@ gomp_map_pointer (struct target_mem_desc *tgt, uintptr_t host_ptr, /* Add bias to the pointer value. */ cur_node.host_start += bias; cur_node.host_end = cur_node.host_start; - splay_tree_key n = gomp_map_lookup (mem_map, &cur_node); + struct splay_tree_key_s *n = gomp_map_lookup (mem_map, &cur_node); if (n == NULL) { gomp_mutex_unlock (&devicep->lock); @@ -247,7 +253,8 @@ gomp_map_pointer (struct target_mem_desc *tgt, uintptr_t host_ptr, } static void -gomp_map_fields_existing (struct target_mem_desc *tgt, splay_tree_key n, +gomp_map_fields_existing (struct target_mem_desc *tgt, + struct splay_tree_key_s *n, size_t first, size_t i, void **hostaddrs, size_t *sizes, void *kinds) { @@ -260,7 +267,7 @@ gomp_map_fields_existing (struct target_mem_desc *tgt, splay_tree_key n, cur_node.host_start = (uintptr_t) hostaddrs[i]; cur_node.host_end = cur_node.host_start + sizes[i]; - splay_tree_key n2 = splay_tree_lookup (mem_map, &cur_node); + struct splay_tree_key_s *n2 = KEY (splay_tree_lookup (mem_map, &cur_node)); kind = get_kind (short_mapkind, kinds, i); if (n2 && n2->tgt == n->tgt @@ -351,7 +358,7 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum, { cur_node.host_start = (uintptr_t) hostaddrs[i]; cur_node.host_end = cur_node.host_start; - splay_tree_key n = gomp_map_lookup (mem_map, &cur_node); + struct splay_tree_key_s *n = gomp_map_lookup (mem_map, &cur_node); if (n == NULL) { gomp_mutex_unlock (&devicep->lock); @@ -495,8 +502,9 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum, tgt->array = NULL; if (not_found_cnt || has_firstprivate) { + size_t asize = sizeof (*tgt->array) + sizeof (struct splay_tree_key_s); if (not_found_cnt) - tgt->array = gomp_malloc (not_found_cnt * sizeof (*tgt->array)); + tgt->array = gomp_malloc (not_found_cnt * asize); splay_tree_node array = tgt->array; size_t j, field_tgt_offset = 0, field_tgt_clear = ~(size_t) 0; uintptr_t field_tgt_base = 0; @@ -557,7 +565,7 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum, default: break; } - splay_tree_key k = &array->key; + struct splay_tree_key_s *k = KEY (&array->key); k->host_start = (uintptr_t) hostaddrs[i]; if (!GOMP_MAP_POINTER_P (kind & typemask)) k->host_end = k->host_start + sizes[i]; @@ -774,7 +782,7 @@ gomp_copy_from_async (struct target_mem_desc *tgt) } else { - splay_tree_key k = tgt->list[i].key; + struct splay_tree_key_s *k = KEY (tgt->list[i].key); if (tgt->list[i].copy_from) devicep->dev2host_func (devicep->target_id, (void *) k->host_start, (void *) (k->tgt->tgt_start + k->tgt_offset), @@ -804,7 +812,7 @@ gomp_unmap_vars (struct target_mem_desc *tgt, bool do_copyfrom) size_t i; for (i = 0; i < tgt->list_count; i++) { - splay_tree_key k = tgt->list[i].key; + struct splay_tree_key_s *k = KEY (tgt->list[i].key); if (k == NULL) continue; @@ -867,7 +875,8 @@ gomp_update (struct gomp_device_descr *devicep, size_t mapnum, void **hostaddrs, { cur_node.host_start = (uintptr_t) hostaddrs[i]; cur_node.host_end = cur_node.host_start + sizes[i]; - splay_tree_key n = splay_tree_lookup (&devicep->mem_map, &cur_node); + struct splay_tree_key_s *n = KEY (splay_tree_lookup (&devicep->mem_map, + &cur_node)); if (n) { int kind = get_kind (short_mapkind, kinds, i); @@ -943,7 +952,8 @@ gomp_load_image_to_device (struct gomp_device_descr *devicep, unsigned version, /* Insert host-target address mapping into splay tree. */ struct target_mem_desc *tgt = gomp_malloc (sizeof (*tgt)); - tgt->array = gomp_malloc ((num_funcs + num_vars) * sizeof (*tgt->array)); + size_t asize = sizeof (*tgt->array) + sizeof (struct splay_tree_key_s); + tgt->array = gomp_malloc ((num_funcs + num_vars) * asize); tgt->refcount = REFCOUNT_INFINITY; tgt->tgt_start = 0; tgt->tgt_end = 0; @@ -955,7 +965,7 @@ gomp_load_image_to_device (struct gomp_device_descr *devicep, unsigned version, for (i = 0; i < num_funcs; i++) { - splay_tree_key k = &array->key; + struct splay_tree_key_s *k = KEY (&array->key); k->host_start = (uintptr_t) host_func_table[i]; k->host_end = k->host_start + 1; k->tgt = tgt; @@ -980,7 +990,7 @@ gomp_load_image_to_device (struct gomp_device_descr *devicep, unsigned version, gomp_fatal ("Can't map target variables (size mismatch)"); } - splay_tree_key k = &array->key; + struct splay_tree_key_s *k = KEY (&array->key); k->host_start = (uintptr_t) host_var_table[i * 2]; k->host_end = k->host_start + (uintptr_t) host_var_table[i * 2 + 1]; k->tgt = tgt; @@ -1016,7 +1026,7 @@ gomp_unload_image_from_device (struct gomp_device_descr *devicep, unsigned j; struct splay_tree_key_s k; - splay_tree_key node = NULL; + struct splay_tree_key_s *node = NULL; /* Find mapping at start of node array */ if (num_funcs || num_vars) @@ -1189,7 +1199,8 @@ gomp_free_memmap (struct splay_tree_s *mem_map) { while (mem_map->root) { - struct target_mem_desc *tgt = mem_map->root->key.tgt; + struct splay_tree_key_s *key = KEY (&mem_map->root->key); + struct target_mem_desc *tgt = key->tgt; splay_tree_remove (mem_map, &mem_map->root->key); free (tgt->array); @@ -1241,7 +1252,8 @@ gomp_get_target_fn_addr (struct gomp_device_descr *devicep, struct splay_tree_key_s k; k.host_start = (uintptr_t) host_fn; k.host_end = k.host_start + 1; - splay_tree_key tgt_fn = splay_tree_lookup (&devicep->mem_map, &k); + struct splay_tree_key_s *tgt_fn + = KEY (splay_tree_lookup (&devicep->mem_map, &k)); gomp_mutex_unlock (&devicep->lock); if (tgt_fn == NULL) gomp_fatal ("Target function wasn't mapped"); @@ -1521,10 +1533,11 @@ gomp_exit_data (struct gomp_device_descr *devicep, size_t mapnum, case GOMP_MAP_DELETE_ZERO_LEN_ARRAY_SECTION: cur_node.host_start = (uintptr_t) hostaddrs[i]; cur_node.host_end = cur_node.host_start + sizes[i]; - splay_tree_key k = (kind == GOMP_MAP_DELETE_ZERO_LEN_ARRAY_SECTION + struct splay_tree_key_s *k + = (kind == GOMP_MAP_DELETE_ZERO_LEN_ARRAY_SECTION || kind == GOMP_MAP_ZERO_LEN_ARRAY_SECTION) ? gomp_map_lookup (&devicep->mem_map, &cur_node) - : splay_tree_lookup (&devicep->mem_map, &cur_node); + : KEY (splay_tree_lookup (&devicep->mem_map, &cur_node)); if (!k) continue; @@ -1977,7 +1990,7 @@ omp_target_associate_ptr (void *host_ptr, void *device_ptr, size_t size, cur_node.host_start = (uintptr_t) host_ptr; cur_node.host_end = cur_node.host_start + size; - splay_tree_key n = gomp_map_lookup (mem_map, &cur_node); + struct splay_tree_key_s *n = gomp_map_lookup (mem_map, &cur_node); if (n) { if (n->tgt->tgt_start + n->tgt_offset @@ -1989,7 +2002,8 @@ omp_target_associate_ptr (void *host_ptr, void *device_ptr, size_t size, else { struct target_mem_desc *tgt = gomp_malloc (sizeof (*tgt)); - tgt->array = gomp_malloc (sizeof (*tgt->array)); + tgt->array = gomp_malloc (sizeof (*tgt->array) + + sizeof (struct splay_tree_key_s)); tgt->refcount = 1; tgt->tgt_start = 0; tgt->tgt_end = 0; @@ -1998,7 +2012,7 @@ omp_target_associate_ptr (void *host_ptr, void *device_ptr, size_t size, tgt->list_count = 0; tgt->device_descr = devicep; splay_tree_node array = tgt->array; - splay_tree_key k = &array->key; + struct splay_tree_key_s *k = KEY (&array->key); k->host_start = cur_node.host_start; k->host_end = cur_node.host_end; k->tgt = tgt; @@ -2038,7 +2052,7 @@ omp_target_disassociate_ptr (void *ptr, int device_num) cur_node.host_start = (uintptr_t) ptr; cur_node.host_end = cur_node.host_start; - splay_tree_key n = gomp_map_lookup (mem_map, &cur_node); + struct splay_tree_key_s *n = gomp_map_lookup (mem_map, &cur_node); if (n && n->host_start == cur_node.host_start && n->refcount == REFCOUNT_INFINITY @@ -2224,6 +2238,7 @@ gomp_target_init (void) /* current_device.capabilities has already been set. */ current_device.type = current_device.get_type_func (); current_device.mem_map.root = NULL; + current_device.mem_map.compare = splay_compare; current_device.is_initialized = false; current_device.openacc.data_environ = NULL; for (i = 0; i < new_num_devices; i++)