diff options
author | doko <doko@6ca36cf4-e1d1-0310-8c6f-e303bb2178ca> | 2014-08-01 15:22:15 +0000 |
---|---|---|
committer | doko <doko@6ca36cf4-e1d1-0310-8c6f-e303bb2178ca> | 2014-08-01 15:22:15 +0000 |
commit | 58c6d0e2da5be692c258997797c212f0d82cde62 (patch) | |
tree | 8ee80e05048bbfb94795e845ad04c869fb832c71 | |
parent | 525a0893a750b6a99050c77e26612cd6ebd014b5 (diff) | |
download | gcc-49-58c6d0e2da5be692c258997797c212f0d82cde62.tar.gz |
* Update to SVN 20140731 (r213317) from the gcc-4_9-branch.
- Fix PR tree-optimization/61964. LP: #1347147.
git-svn-id: svn://svn.debian.org/svn/gcccvs/branches/sid/gcc-4.9@7550 6ca36cf4-e1d1-0310-8c6f-e303bb2178ca
-rw-r--r-- | debian/changelog | 7 | ||||
-rw-r--r-- | debian/patches/svn-updates.diff | 970 |
2 files changed, 962 insertions, 15 deletions
diff --git a/debian/changelog b/debian/changelog index d8b8241..87686eb 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +gcc-4.9 (4.9.1-5) UNRELEASED; urgency=medium + + * Update to SVN 20140731 (r213317) from the gcc-4_9-branch. + - Fix PR tree-optimization/61964. LP: #1347147. + + -- Matthias Klose <doko@debian.org> Fri, 01 Aug 2014 17:20:58 +0200 + gcc-4.9 (4.9.1-4) unstable; urgency=high * Update to SVN 20140731 (r213317) from the gcc-4_9-branch. diff --git a/debian/patches/svn-updates.diff b/debian/patches/svn-updates.diff index f096fdf..dd917a4 100644 --- a/debian/patches/svn-updates.diff +++ b/debian/patches/svn-updates.diff @@ -1,10 +1,10 @@ -# DP: updates from the 4.9 branch upto 20140731 (r213317). +# DP: updates from the 4.9 branch upto 20140801 (r213487). last_update() { cat > ${dir}LAST_UPDATED <EOF -Thu Jul 31 09:55:11 CEST 2014 -Thu Jul 31 07:55:11 UTC 2014 (revision 213317) +Fri Aug 1 17:14:05 CEST 2014 +Fri Aug 1 15:14:05 UTC 2014 (revision 213487) EOF } @@ -185,6 +185,689 @@ Index: libitm/config/aarch64/target.h +} + +} // namespace GTM +Index: libgomp/libgomp.h +=================================================================== +--- a/src/libgomp/libgomp.h (.../tags/gcc_4_9_1_release) ++++ b/src/libgomp/libgomp.h (.../branches/gcc-4_9-branch) +@@ -274,6 +274,7 @@ + struct gomp_task *task; + bool is_in; + bool redundant; ++ bool redundant_out; + }; + + struct gomp_dependers_vec +@@ -283,6 +284,17 @@ + struct gomp_task *elem[]; + }; + ++/* Used when in GOMP_taskwait or in gomp_task_maybe_wait_for_dependencies. */ ++ ++struct gomp_taskwait ++{ ++ bool in_taskwait; ++ bool in_depend_wait; ++ size_t n_depend; ++ struct gomp_task *last_parent_depends_on; ++ gomp_sem_t taskwait_sem; ++}; ++ + /* This structure describes a "task" to be run by a thread. */ + + struct gomp_task +@@ -298,6 +310,7 @@ + struct gomp_taskgroup *taskgroup; + struct gomp_dependers_vec *dependers; + struct htab *depend_hash; ++ struct gomp_taskwait *taskwait; + size_t depend_count; + size_t num_dependees; + struct gomp_task_icv icv; +@@ -304,11 +317,10 @@ + void (*fn) (void *); + void *fn_data; + enum gomp_task_kind kind; +- bool in_taskwait; + bool in_tied_task; + bool final_task; + bool copy_ctors_done; +- gomp_sem_t taskwait_sem; ++ bool parent_depends_on; + struct gomp_task_depend_entry depend[]; + }; + +@@ -582,7 +594,6 @@ + { + if (__builtin_expect (task->depend_hash != NULL, 0)) + free (task->depend_hash); +- gomp_sem_destroy (&task->taskwait_sem); + } + + /* team.c */ +Index: libgomp/task.c +=================================================================== +--- a/src/libgomp/task.c (.../tags/gcc_4_9_1_release) ++++ b/src/libgomp/task.c (.../branches/gcc-4_9-branch) +@@ -66,16 +66,16 @@ + task->parent = parent_task; + task->icv = *prev_icv; + task->kind = GOMP_TASK_IMPLICIT; +- task->in_taskwait = false; ++ task->taskwait = NULL; + task->in_tied_task = false; + task->final_task = false; + task->copy_ctors_done = false; ++ task->parent_depends_on = false; + task->children = NULL; + task->taskgroup = NULL; + task->dependers = NULL; + task->depend_hash = NULL; + task->depend_count = 0; +- gomp_sem_init (&task->taskwait_sem, 0); + } + + /* Clean up a task, after completing it. */ +@@ -104,6 +104,8 @@ + while (task != children); + } + ++static void gomp_task_maybe_wait_for_dependencies (void **depend); ++ + /* Called when encountering an explicit task directive. If IF_CLAUSE is + false, then we must not delay in executing the task. If UNTIED is true, + then the task may be executed by any member of the team. */ +@@ -141,35 +143,12 @@ + + /* If there are depend clauses and earlier deferred sibling tasks + with depend clauses, check if there isn't a dependency. If there +- is, fall through to the deferred task handling, as we can't +- schedule such tasks right away. There is no need to handle ++ is, we need to wait for them. There is no need to handle + depend clauses for non-deferred tasks other than this, because + the parent task is suspended until the child task finishes and thus + it can't start further child tasks. */ + if ((flags & 8) && thr->task && thr->task->depend_hash) +- { +- struct gomp_task *parent = thr->task; +- struct gomp_task_depend_entry elem, *ent = NULL; +- size_t ndepend = (uintptr_t) depend[0]; +- size_t nout = (uintptr_t) depend[1]; +- size_t i; +- gomp_mutex_lock (&team->task_lock); +- for (i = 0; i < ndepend; i++) +- { +- elem.addr = depend[i + 2]; +- ent = htab_find (parent->depend_hash, &elem); +- for (; ent; ent = ent->next) +- if (i >= nout && ent->is_in) +- continue; +- else +- break; +- if (ent) +- break; +- } +- gomp_mutex_unlock (&team->task_lock); +- if (ent) +- goto defer; +- } ++ gomp_task_maybe_wait_for_dependencies (depend); + + gomp_init_task (&task, thr->task, gomp_icv (false)); + task.kind = GOMP_TASK_IFFALSE; +@@ -209,7 +188,6 @@ + } + else + { +- defer:; + struct gomp_task *task; + struct gomp_task *parent = thr->task; + struct gomp_taskgroup *taskgroup = parent->taskgroup; +@@ -275,11 +253,12 @@ + task->depend[i].task = task; + task->depend[i].is_in = i >= nout; + task->depend[i].redundant = false; ++ task->depend[i].redundant_out = false; + + hash_entry_type *slot + = htab_find_slot (&parent->depend_hash, &task->depend[i], + INSERT); +- hash_entry_type out = NULL; ++ hash_entry_type out = NULL, last = NULL; + if (*slot) + { + /* If multiple depends on the same task are the +@@ -294,6 +273,11 @@ + } + for (ent = *slot; ent; ent = ent->next) + { ++ if (ent->redundant_out) ++ break; ++ ++ last = ent; ++ + /* depend(in:...) doesn't depend on earlier + depend(in:...). */ + if (i >= nout && ent->is_in) +@@ -341,7 +325,8 @@ + *slot = &task->depend[i]; + + /* There is no need to store more than one depend({,in}out:) +- task per address in the hash table chain, because each out ++ task per address in the hash table chain for the purpose ++ of creation of deferred tasks, because each out + depends on all earlier outs, thus it is enough to record + just the last depend({,in}out:). For depend(in:), we need + to keep all of the previous ones not terminated yet, because +@@ -348,14 +333,23 @@ + a later depend({,in}out:) might need to depend on all of + them. So, if the new task's clause is depend({,in}out:), + we know there is at most one other depend({,in}out:) clause +- in the list (out) and to maintain the invariant we now +- need to remove it from the list. */ ++ in the list (out). For non-deferred tasks we want to see ++ all outs, so they are moved to the end of the chain, ++ after first redundant_out entry all following entries ++ should be redundant_out. */ + if (!task->depend[i].is_in && out) + { +- if (out->next) +- out->next->prev = out->prev; +- out->prev->next = out->next; +- out->redundant = true; ++ if (out != last) ++ { ++ out->next->prev = out->prev; ++ out->prev->next = out->next; ++ out->next = last->next; ++ out->prev = last; ++ last->next = out; ++ if (out->next) ++ out->next->prev = out; ++ } ++ out->redundant_out = true; + } + } + if (task->num_dependees) +@@ -421,8 +415,20 @@ + gomp_task_run_pre (struct gomp_task *child_task, struct gomp_task *parent, + struct gomp_taskgroup *taskgroup, struct gomp_team *team) + { +- if (parent && parent->children == child_task) +- parent->children = child_task->next_child; ++ if (parent) ++ { ++ if (parent->children == child_task) ++ parent->children = child_task->next_child; ++ if (__builtin_expect (child_task->parent_depends_on, 0) ++ && parent->taskwait->last_parent_depends_on == child_task) ++ { ++ if (child_task->prev_child->kind == GOMP_TASK_WAITING ++ && child_task->prev_child->parent_depends_on) ++ parent->taskwait->last_parent_depends_on = child_task->prev_child; ++ else ++ parent->taskwait->last_parent_depends_on = NULL; ++ } ++ } + if (taskgroup && taskgroup->children == child_task) + taskgroup->children = child_task->next_taskgroup; + child_task->prev_queue->next_queue = child_task->next_queue; +@@ -489,8 +495,23 @@ + { + if (parent->children) + { +- task->next_child = parent->children; +- task->prev_child = parent->children->prev_child; ++ /* If parent is in gomp_task_maybe_wait_for_dependencies ++ and it doesn't need to wait for this task, put it after ++ all ready to run tasks it needs to wait for. */ ++ if (parent->taskwait && parent->taskwait->last_parent_depends_on ++ && !task->parent_depends_on) ++ { ++ struct gomp_task *last_parent_depends_on ++ = parent->taskwait->last_parent_depends_on; ++ task->next_child = last_parent_depends_on->next_child; ++ task->prev_child = last_parent_depends_on; ++ } ++ else ++ { ++ task->next_child = parent->children; ++ task->prev_child = parent->children->prev_child; ++ parent->children = task; ++ } + task->next_child->prev_child = task; + task->prev_child->next_child = task; + } +@@ -498,12 +519,23 @@ + { + task->next_child = task; + task->prev_child = task; ++ parent->children = task; + } +- parent->children = task; +- if (parent->in_taskwait) ++ if (parent->taskwait) + { +- parent->in_taskwait = false; +- gomp_sem_post (&parent->taskwait_sem); ++ if (parent->taskwait->in_taskwait) ++ { ++ parent->taskwait->in_taskwait = false; ++ gomp_sem_post (&parent->taskwait->taskwait_sem); ++ } ++ else if (parent->taskwait->in_depend_wait) ++ { ++ parent->taskwait->in_depend_wait = false; ++ gomp_sem_post (&parent->taskwait->taskwait_sem); ++ } ++ if (parent->taskwait->last_parent_depends_on == NULL ++ && task->parent_depends_on) ++ parent->taskwait->last_parent_depends_on = task; + } + } + if (taskgroup) +@@ -575,6 +607,13 @@ + struct gomp_task *parent = child_task->parent; + if (parent == NULL) + return; ++ if (__builtin_expect (child_task->parent_depends_on, 0) ++ && --parent->taskwait->n_depend == 0 ++ && parent->taskwait->in_depend_wait) ++ { ++ parent->taskwait->in_depend_wait = false; ++ gomp_sem_post (&parent->taskwait->taskwait_sem); ++ } + child_task->prev_child->next_child = child_task->next_child; + child_task->next_child->prev_child = child_task->prev_child; + if (parent->children != child_task) +@@ -589,10 +628,10 @@ + written by child_task->fn above is flushed + before the NULL is written. */ + __atomic_store_n (&parent->children, NULL, MEMMODEL_RELEASE); +- if (parent->in_taskwait) ++ if (parent->taskwait && parent->taskwait->in_taskwait) + { +- parent->in_taskwait = false; +- gomp_sem_post (&parent->taskwait_sem); ++ parent->taskwait->in_taskwait = false; ++ gomp_sem_post (&parent->taskwait->taskwait_sem); + } + } + } +@@ -736,6 +775,7 @@ + struct gomp_task *task = thr->task; + struct gomp_task *child_task = NULL; + struct gomp_task *to_free = NULL; ++ struct gomp_taskwait taskwait; + int do_wake = 0; + + /* The acquire barrier on load of task->children here synchronizes +@@ -748,6 +788,7 @@ + || __atomic_load_n (&task->children, MEMMODEL_ACQUIRE) == NULL) + return; + ++ memset (&taskwait, 0, sizeof (taskwait)); + gomp_mutex_lock (&team->task_lock); + while (1) + { +@@ -754,6 +795,8 @@ + bool cancelled = false; + if (task->children == NULL) + { ++ bool destroy_taskwait = task->taskwait != NULL; ++ task->taskwait = NULL; + gomp_mutex_unlock (&team->task_lock); + if (to_free) + { +@@ -760,6 +803,8 @@ + gomp_finish_task (to_free); + free (to_free); + } ++ if (destroy_taskwait) ++ gomp_sem_destroy (&taskwait.taskwait_sem); + return; + } + if (task->children->kind == GOMP_TASK_WAITING) +@@ -780,9 +825,180 @@ + } + } + else ++ { ++ /* All tasks we are waiting for are already running ++ in other threads. Wait for them. */ ++ if (task->taskwait == NULL) ++ { ++ taskwait.in_depend_wait = false; ++ gomp_sem_init (&taskwait.taskwait_sem, 0); ++ task->taskwait = &taskwait; ++ } ++ taskwait.in_taskwait = true; ++ } ++ gomp_mutex_unlock (&team->task_lock); ++ if (do_wake) ++ { ++ gomp_team_barrier_wake (&team->barrier, do_wake); ++ do_wake = 0; ++ } ++ if (to_free) ++ { ++ gomp_finish_task (to_free); ++ free (to_free); ++ to_free = NULL; ++ } ++ if (child_task) ++ { ++ thr->task = child_task; ++ child_task->fn (child_task->fn_data); ++ thr->task = task; ++ } ++ else ++ gomp_sem_wait (&taskwait.taskwait_sem); ++ gomp_mutex_lock (&team->task_lock); ++ if (child_task) ++ { ++ finish_cancelled:; ++ size_t new_tasks ++ = gomp_task_run_post_handle_depend (child_task, team); ++ child_task->prev_child->next_child = child_task->next_child; ++ child_task->next_child->prev_child = child_task->prev_child; ++ if (task->children == child_task) ++ { ++ if (child_task->next_child != child_task) ++ task->children = child_task->next_child; ++ else ++ task->children = NULL; ++ } ++ gomp_clear_parent (child_task->children); ++ gomp_task_run_post_remove_taskgroup (child_task); ++ to_free = child_task; ++ child_task = NULL; ++ team->task_count--; ++ if (new_tasks > 1) ++ { ++ do_wake = team->nthreads - team->task_running_count ++ - !task->in_tied_task; ++ if (do_wake > new_tasks) ++ do_wake = new_tasks; ++ } ++ } ++ } ++} ++ ++/* This is like GOMP_taskwait, but we only wait for tasks that the ++ upcoming task depends on. */ ++ ++static void ++gomp_task_maybe_wait_for_dependencies (void **depend) ++{ ++ struct gomp_thread *thr = gomp_thread (); ++ struct gomp_task *task = thr->task; ++ struct gomp_team *team = thr->ts.team; ++ struct gomp_task_depend_entry elem, *ent = NULL; ++ struct gomp_taskwait taskwait; ++ struct gomp_task *last_parent_depends_on = NULL; ++ size_t ndepend = (uintptr_t) depend[0]; ++ size_t nout = (uintptr_t) depend[1]; ++ size_t i; ++ size_t num_awaited = 0; ++ struct gomp_task *child_task = NULL; ++ struct gomp_task *to_free = NULL; ++ int do_wake = 0; ++ ++ gomp_mutex_lock (&team->task_lock); ++ for (i = 0; i < ndepend; i++) ++ { ++ elem.addr = depend[i + 2]; ++ ent = htab_find (task->depend_hash, &elem); ++ for (; ent; ent = ent->next) ++ if (i >= nout && ent->is_in) ++ continue; ++ else ++ { ++ struct gomp_task *tsk = ent->task; ++ if (!tsk->parent_depends_on) ++ { ++ tsk->parent_depends_on = true; ++ ++num_awaited; ++ if (tsk->num_dependees == 0 && tsk->kind == GOMP_TASK_WAITING) ++ { ++ /* If a task we need to wait for is not already ++ running and is ready to be scheduled, move it ++ to front, so that we run it as soon as possible. */ ++ if (last_parent_depends_on) ++ { ++ tsk->prev_child->next_child = tsk->next_child; ++ tsk->next_child->prev_child = tsk->prev_child; ++ tsk->prev_child = last_parent_depends_on; ++ tsk->next_child = last_parent_depends_on->next_child; ++ tsk->prev_child->next_child = tsk; ++ tsk->next_child->prev_child = tsk; ++ } ++ else if (tsk != task->children) ++ { ++ tsk->prev_child->next_child = tsk->next_child; ++ tsk->next_child->prev_child = tsk->prev_child; ++ tsk->prev_child = task->children; ++ tsk->next_child = task->children->next_child; ++ task->children = tsk; ++ tsk->prev_child->next_child = tsk; ++ tsk->next_child->prev_child = tsk; ++ } ++ last_parent_depends_on = tsk; ++ } ++ } ++ } ++ } ++ if (num_awaited == 0) ++ { ++ gomp_mutex_unlock (&team->task_lock); ++ return; ++ } ++ ++ memset (&taskwait, 0, sizeof (taskwait)); ++ taskwait.n_depend = num_awaited; ++ taskwait.last_parent_depends_on = last_parent_depends_on; ++ gomp_sem_init (&taskwait.taskwait_sem, 0); ++ task->taskwait = &taskwait; ++ ++ while (1) ++ { ++ bool cancelled = false; ++ if (taskwait.n_depend == 0) ++ { ++ task->taskwait = NULL; ++ gomp_mutex_unlock (&team->task_lock); ++ if (to_free) ++ { ++ gomp_finish_task (to_free); ++ free (to_free); ++ } ++ gomp_sem_destroy (&taskwait.taskwait_sem); ++ return; ++ } ++ if (task->children->kind == GOMP_TASK_WAITING) ++ { ++ child_task = task->children; ++ cancelled ++ = gomp_task_run_pre (child_task, task, child_task->taskgroup, ++ team); ++ if (__builtin_expect (cancelled, 0)) ++ { ++ if (to_free) ++ { ++ gomp_finish_task (to_free); ++ free (to_free); ++ to_free = NULL; ++ } ++ goto finish_cancelled; ++ } ++ } ++ else + /* All tasks we are waiting for are already running + in other threads. Wait for them. */ +- task->in_taskwait = true; ++ taskwait.in_depend_wait = true; + gomp_mutex_unlock (&team->task_lock); + if (do_wake) + { +@@ -802,7 +1018,7 @@ + thr->task = task; + } + else +- gomp_sem_wait (&task->taskwait_sem); ++ gomp_sem_wait (&taskwait.taskwait_sem); + gomp_mutex_lock (&team->task_lock); + if (child_task) + { +@@ -809,6 +1025,8 @@ + finish_cancelled:; + size_t new_tasks + = gomp_task_run_post_handle_depend (child_task, team); ++ if (child_task->parent_depends_on) ++ --taskwait.n_depend; + child_task->prev_child->next_child = child_task->next_child; + child_task->next_child->prev_child = child_task->prev_child; + if (task->children == child_task) +Index: libgomp/ChangeLog +=================================================================== +--- a/src/libgomp/ChangeLog (.../tags/gcc_4_9_1_release) ++++ b/src/libgomp/ChangeLog (.../branches/gcc-4_9-branch) +@@ -1,3 +1,33 @@ ++2014-08-01 Jakub Jelinek <jakub@redhat.com> ++ ++ * libgomp.h (struct gomp_task_depend_entry): Add redundant_out field. ++ (struct gomp_taskwait): New type. ++ (struct gomp_task): Add taskwait and parent_depends_on, remove ++ in_taskwait and taskwait_sem fields. ++ (gomp_finish_task): Don't destroy taskwait_sem. ++ * task.c (gomp_init_task): Don't init in_taskwait, instead init ++ taskwait and parent_depends_on. ++ (GOMP_task): For if (0) tasks with depend clause that depend on ++ earlier tasks don't defer them, instead call ++ gomp_task_maybe_wait_for_dependencies to wait for the dependencies. ++ Initialize redundant_out field, for redundant out entries just ++ move them at the end of linked list instead of removing them ++ completely, and set redundant_out flag instead of redundant. ++ (gomp_task_run_pre): Update last_parent_depends_on if scheduling ++ that task. ++ (gomp_task_run_post_handle_dependers): If parent is in ++ gomp_task_maybe_wait_for_dependencies and newly runnable task ++ is not parent_depends_on, queue it in parent->children linked ++ list after all runnable tasks with parent_depends_on set. ++ Adjust for addition of taskwait indirection. ++ (gomp_task_run_post_remove_parent): If parent is in ++ gomp_task_maybe_wait_for_dependencies and task to be removed ++ is parent_depends_on, decrement n_depend and if needed awake ++ parent. Adjust for addition of taskwait indirection. ++ (GOMP_taskwait): Adjust for addition of taskwait indirection. ++ (gomp_task_maybe_wait_for_dependencies): New function. ++ * testsuite/libgomp.c/depend-5.c: New test. ++ + 2014-07-16 Release Manager + + * GCC 4.9.1 released. +Index: libgomp/testsuite/libgomp.c/depend-5.c +=================================================================== +--- a/src/libgomp/testsuite/libgomp.c/depend-5.c (.../tags/gcc_4_9_1_release) ++++ b/src/libgomp/testsuite/libgomp.c/depend-5.c (.../branches/gcc-4_9-branch) +@@ -0,0 +1,98 @@ ++#include <stdlib.h> ++ ++__attribute__((noinline, noclone)) void ++f1 (int ifval) ++{ ++ int x = 1, y = 2, z = 3; ++ #pragma omp parallel ++ #pragma omp single ++ { ++ #pragma omp task shared (x) depend(out: x) ++ x = 2; ++ #pragma omp task shared (x) depend(inout: x) ++ { ++ if (x != 2) ++ abort (); ++ x = 3; ++ } ++ #pragma omp task shared (x) depend(inout: x) ++ { ++ if (x != 3) ++ abort (); ++ x = 4; ++ } ++ #pragma omp task shared (z) depend(in: z) ++ if (z != 3) ++ abort (); ++ #pragma omp task shared (z) depend(in: z) ++ if (z != 3) ++ abort (); ++ #pragma omp task shared (z) depend(in: z) ++ if (z != 3) ++ abort (); ++ #pragma omp task shared (z) depend(in: z) ++ if (z != 3) ++ abort (); ++ #pragma omp task shared (z) depend(in: z) ++ if (z != 3) ++ abort (); ++ #pragma omp task shared (z) depend(in: z) ++ if (z != 3) ++ abort (); ++ #pragma omp task shared (y) depend(in: y) ++ if (y != 2) ++ abort (); ++ #pragma omp task shared (y) depend(in: y) ++ if (y != 2) ++ abort (); ++ #pragma omp task shared (y) depend(in: y) ++ if (y != 2) ++ abort (); ++ #pragma omp task shared (y) depend(in: y) ++ if (y != 2) ++ abort (); ++ #pragma omp task if (ifval) shared (x, y) depend(in: x) depend(inout: y) ++ { ++ if (x != 4 || y != 2) ++ abort (); ++ y = 3; ++ } ++ if (ifval == 0) ++ { ++ /* The above if (0) task should have waited till all ++ the tasks with x and y dependencies finish. */ ++ if (x != 4 || y != 3) ++ abort (); ++ x = 5; ++ y = 4; ++ } ++ #pragma omp task shared (z) depend(inout: z) ++ { ++ if (z != 3) ++ abort (); ++ z = 4; ++ } ++ #pragma omp task shared (z) depend(inout: z) ++ { ++ if (z != 4) ++ abort (); ++ z = 5; ++ } ++ #pragma omp taskwait ++ if (x != (ifval ? 4 : 5) || y != (ifval ? 3 : 4) || z != 5) ++ abort (); ++ #pragma omp task if (ifval) shared (x, y) depend(in: x) depend(inout: y) ++ { ++ if (x != (ifval ? 4 : 5) || y != (ifval ? 3 : 4)) ++ abort (); ++ } ++ } ++} ++ ++int ++main () ++{ ++ f1 (0); ++ f1 (1); ++ return 0; ++} Index: libstdc++-v3/include/ext/random.tcc =================================================================== --- a/src/libstdc++-v3/include/ext/random.tcc (.../tags/gcc_4_9_1_release) @@ -374,6 +1057,31 @@ Index: configure hppa*-hp-hpux10*) host_makefile_frag="config/mh-pa-hpux10" ;; +Index: gcc/tree-ssa-tail-merge.c +=================================================================== +--- a/src/gcc/tree-ssa-tail-merge.c (.../tags/gcc_4_9_1_release) ++++ b/src/gcc/tree-ssa-tail-merge.c (.../branches/gcc-4_9-branch) +@@ -1159,17 +1159,9 @@ + lhs2 = gimple_get_lhs (s2); + if (TREE_CODE (lhs1) != SSA_NAME + && TREE_CODE (lhs2) != SSA_NAME) +- { +- /* If the vdef is the same, it's the same statement. */ +- if (vn_valueize (gimple_vdef (s1)) +- == vn_valueize (gimple_vdef (s2))) +- return true; +- +- /* Test for structural equality. */ +- return (operand_equal_p (lhs1, lhs2, 0) +- && gimple_operand_equal_value_p (gimple_assign_rhs1 (s1), +- gimple_assign_rhs1 (s2))); +- } ++ return (operand_equal_p (lhs1, lhs2, 0) ++ && gimple_operand_equal_value_p (gimple_assign_rhs1 (s1), ++ gimple_assign_rhs1 (s2))); + else if (TREE_CODE (lhs1) == SSA_NAME + && TREE_CODE (lhs2) == SSA_NAME) + return vn_valueize (lhs1) == vn_valueize (lhs2); Index: gcc/c-family/c-gimplify.c =================================================================== --- a/src/gcc/c-family/c-gimplify.c (.../tags/gcc_4_9_1_release) @@ -413,7 +1121,7 @@ Index: gcc/DATESTAMP +++ b/src/gcc/DATESTAMP (.../branches/gcc-4_9-branch) @@ -1 +1 @@ -20140716 -+20140731 ++20140801 Index: gcc/omp-low.c =================================================================== --- a/src/gcc/omp-low.c (.../tags/gcc_4_9_1_release) @@ -459,7 +1167,35 @@ Index: gcc/ChangeLog =================================================================== --- a/src/gcc/ChangeLog (.../tags/gcc_4_9_1_release) +++ b/src/gcc/ChangeLog (.../branches/gcc-4_9-branch) -@@ -1,3 +1,179 @@ +@@ -1,3 +1,207 @@ ++2014-08-01 Thomas Preud'homme <thomas.preudhomme@arm.com> ++ ++ Backport from mainline ++ 2014-06-13 Thomas Preud'homme <thomas.preudhomme@arm.com> ++ ++ PR tree-optimization/61375 ++ * tree-ssa-math-opts.c (find_bswap_or_nop_1): Cancel optimization if ++ symbolic number cannot be represented in an unsigned HOST_WIDE_INT. ++ (execute_optimize_bswap): Cancel optimization if CHAR_BIT != 8. ++ ++2014-08-01 Richard Biener <rguenther@suse.de> ++ ++ PR tree-optimization/61964 ++ * tree-ssa-tail-merge.c (gimple_equal_p): Handle non-SSA LHS solely ++ by structural equality. ++ ++2014-07-31 Oleg Endo <olegendo@gcc.gnu.org> ++ ++ Backport from mainline ++ 2014-07-31 Oleg Endo <olegendo@gcc.gnu.org> ++ ++ PR target/61844 ++ * config/sh/sh.c (sh_legitimate_address_p, ++ sh_legitimize_reload_address): Handle reg+reg address modes when ++ ALLOW_INDEXED_ADDRESS is false. ++ * config/sh/predicates.md (general_movsrc_operand, ++ general_movdst_operand): Likewise. ++ +2014-07-25 Uros Bizjak <ubizjak@gmail.com> + + Backport from mainline @@ -639,7 +1375,7 @@ Index: gcc/ChangeLog 2014-07-16 Release Manager * GCC 4.9.1 released. -@@ -4,14 +183,14 @@ +@@ -4,14 +211,14 @@ 2014-07-10 Cary Coutant <ccoutant@google.com> @@ -658,7 +1394,7 @@ Index: gcc/ChangeLog 2014-07-10 Tom G. Christensen <tgc@jupiterrise.com> -@@ -33,13 +212,13 @@ +@@ -33,13 +240,13 @@ PR target/61062 * config/arm/arm_neon.h (vtrn_s8, vtrn_s16, vtrn_u8, vtrn_u16, vtrn_p8, vtrn_p16, vtrn_s32, vtrn_f32, vtrn_u32, vtrnq_s8, vtrnq_s16, vtrnq_s32, @@ -679,7 +1415,7 @@ Index: gcc/ChangeLog 2014-07-09 Alan Lawrence <alan.lawrence@arm.com> -@@ -157,11 +336,9 @@ +@@ -157,11 +364,9 @@ 2014-06-24 Jakub Jelinek <jakub@redhat.com> * gimplify.c (gimplify_scan_omp_clauses) <case OMP_CLAUSE_MAP, @@ -693,7 +1429,7 @@ Index: gcc/ChangeLog (gimplify_adjust_omp_clauses): Likewise. * omp-low.c (lower_rec_simd_input_clauses, lower_rec_input_clauses, expand_omp_simd): Handle non-constant -@@ -176,9 +353,8 @@ +@@ -176,9 +381,8 @@ 2014-06-18 Jakub Jelinek <jakub@redhat.com> @@ -705,7 +1441,7 @@ Index: gcc/ChangeLog (struct gimplify_adjust_omp_clauses_data): New type. (gimplify_adjust_omp_clauses_1): Adjust for data being a struct gimplify_adjust_omp_clauses_data pointer instead -@@ -196,14 +372,12 @@ +@@ -196,14 +400,12 @@ gimple_seq * argument to omp_finish_clause hook. * omp-low.c (scan_sharing_clauses): Call scan_omp_op on non-DECL_P OMP_CLAUSE_DECL if ctx->outer. @@ -723,7 +1459,7 @@ Index: gcc/ChangeLog 2014-06-10 Jakub Jelinek <jakub@redhat.com> -@@ -227,8 +401,7 @@ +@@ -227,8 +429,7 @@ OMP_CLAUSE_LINEAR_STMT. * omp-low.c (lower_rec_input_clauses): Fix typo. (maybe_add_implicit_barrier_cancel, lower_omp_1): Add @@ -733,7 +1469,7 @@ Index: gcc/ChangeLog 2014-06-30 Jason Merrill <jason@redhat.com> -@@ -279,8 +452,7 @@ +@@ -279,8 +480,7 @@ (aarch64_sqdmlsl_lane<mode>): Likewise. (aarch64_sqdmull_lane<mode>): Likewise. (aarch64_sqdmull2_lane<mode>): Likewise. @@ -907,6 +1643,46 @@ Index: gcc/testsuite/gcc.c-torture/execute/20050604-1.x +set additional_flags "-Wno-psabi" return 0 +Index: gcc/testsuite/gcc.c-torture/execute/pr61375.c +=================================================================== +--- a/src/gcc/testsuite/gcc.c-torture/execute/pr61375.c (.../tags/gcc_4_9_1_release) ++++ b/src/gcc/testsuite/gcc.c-torture/execute/pr61375.c (.../branches/gcc-4_9-branch) +@@ -0,0 +1,35 @@ ++#ifdef __UINT64_TYPE__ ++typedef __UINT64_TYPE__ uint64_t; ++#else ++typedef unsigned long long uint64_t; ++#endif ++ ++#ifndef __SIZEOF_INT128__ ++#define __int128 long long ++#endif ++ ++/* Some version of bswap optimization would ICE when analyzing a mask constant ++ too big for an HOST_WIDE_INT (PR61375). */ ++ ++__attribute__ ((noinline, noclone)) uint64_t ++uint128_central_bitsi_ior (unsigned __int128 in1, uint64_t in2) ++{ ++ __int128 mask = (__int128)0xffff << 56; ++ return ((in1 & mask) >> 56) | in2; ++} ++ ++int ++main (int argc) ++{ ++ __int128 in = 1; ++#ifdef __SIZEOF_INT128__ ++ in <<= 64; ++#endif ++ if (sizeof (uint64_t) * __CHAR_BIT__ != 64) ++ return 0; ++ if (sizeof (unsigned __int128) * __CHAR_BIT__ != 128) ++ return 0; ++ if (uint128_central_bitsi_ior (in, 2) != 0x102) ++ __builtin_abort (); ++ return 0; ++} Index: gcc/testsuite/gcc.c-torture/execute/20050316-1.x =================================================================== --- a/src/gcc/testsuite/gcc.c-torture/execute/20050316-1.x (.../tags/gcc_4_9_1_release) @@ -970,6 +1746,55 @@ Index: gcc/testsuite/gnat.dg/pack20_pkg.ads + procedure Modify (Fixed : in out String_Ptr); + +end Pack20_Pkg; +Index: gcc/testsuite/gcc.dg/pr51879-18.c +=================================================================== +--- a/src/gcc/testsuite/gcc.dg/pr51879-18.c (.../tags/gcc_4_9_1_release) ++++ b/src/gcc/testsuite/gcc.dg/pr51879-18.c (.../branches/gcc-4_9-branch) +@@ -13,5 +13,5 @@ + *q = foo (); + } + +-/* { dg-final { scan-tree-dump-times "foo \\(" 1 "pre"} } */ ++/* { dg-final { scan-tree-dump-times "foo \\(" 1 "pre" { xfail *-*-* } } } */ + /* { dg-final { cleanup-tree-dump "pre" } } */ +Index: gcc/testsuite/gcc.dg/torture/pr61964.c +=================================================================== +--- a/src/gcc/testsuite/gcc.dg/torture/pr61964.c (.../tags/gcc_4_9_1_release) ++++ b/src/gcc/testsuite/gcc.dg/torture/pr61964.c (.../branches/gcc-4_9-branch) +@@ -0,0 +1,33 @@ ++/* { dg-do run } */ ++ ++extern void abort (void); ++ ++struct node { struct node *next, *prev; } node; ++struct head { struct node *first; } heads[5]; ++int k = 2; ++struct head *head = &heads[2]; ++ ++static int __attribute__((noinline)) ++foo() ++{ ++ node.prev = (void *)head; ++ head->first = &node; ++ ++ struct node *n = head->first; ++ struct head *h = &heads[k]; ++ ++ if (n->prev == (void *)h) ++ h->first = n->next; ++ else ++ n->prev->next = n->next; ++ ++ n->next = h->first; ++ return n->next == &node; ++} ++ ++int main() ++{ ++ if (foo ()) ++ abort (); ++ return 0; ++} Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-copyprop-2.c =================================================================== --- a/src/gcc/testsuite/gcc.dg/tree-ssa/ssa-copyprop-2.c (.../tags/gcc_4_9_1_release) @@ -1039,7 +1864,21 @@ Index: gcc/testsuite/ChangeLog =================================================================== --- a/src/gcc/testsuite/ChangeLog (.../tags/gcc_4_9_1_release) +++ b/src/gcc/testsuite/ChangeLog (.../branches/gcc-4_9-branch) -@@ -1,3 +1,104 @@ +@@ -1,3 +1,118 @@ ++2014-08-01 Thomas Preud'homme <thomas.preudhomme@arm.com> ++ ++ Backport from mainline ++ 2014-06-13 Thomas Preud'homme <thomas.preudhomme@arm.com> ++ ++ PR tree-optimization/61375 ++ * gcc.c-torture/execute/pr61375-1.c: New test. ++ ++2014-08-01 Richard Biener <rguenther@suse.de> ++ ++ PR tree-optimization/61964 ++ * gcc.dg/torture/pr61964.c: New testcase. ++ * gcc.dg/pr51879-18.c: XFAIL. ++ +2014-07-28 Richard Biener <rguenther@suse.de> + + PR rtl-optimization/61801 @@ -1144,7 +1983,7 @@ Index: gcc/testsuite/ChangeLog 2014-07-16 Release Manager * GCC 4.9.1 released. -@@ -17,7 +118,8 @@ +@@ -17,7 +132,8 @@ 2014-06-09 Alan Lawrence <alan.lawrence@arm.com> PR target/61062 @@ -1154,7 +1993,7 @@ Index: gcc/testsuite/ChangeLog 2014-07-08 Jakub Jelinek <jakub@redhat.com> -@@ -34,8 +136,8 @@ +@@ -34,8 +150,8 @@ 2014-07-08 Alan Lawrence <alan.lawrence@arm.com> @@ -1230,6 +2069,37 @@ Index: gcc/testsuite/c-c++-common/pr61741.c + __builtin_abort (); + return 0; +} +Index: gcc/tree-ssa-math-opts.c +=================================================================== +--- a/src/gcc/tree-ssa-math-opts.c (.../tags/gcc_4_9_1_release) ++++ b/src/gcc/tree-ssa-math-opts.c (.../branches/gcc-4_9-branch) +@@ -1749,6 +1749,8 @@ + size = TYPE_PRECISION (n->type); + if (size % BITS_PER_UNIT != 0) + return NULL_TREE; ++ if (size > HOST_BITS_PER_WIDEST_INT) ++ return NULL_TREE; + size /= BITS_PER_UNIT; + n->n = (sizeof (HOST_WIDEST_INT) < 8 ? 0 : + (unsigned HOST_WIDEST_INT)0x08070605 << 32 | 0x04030201); +@@ -1792,6 +1794,8 @@ + type_size = TYPE_PRECISION (type); + if (type_size % BITS_PER_UNIT != 0) + return NULL_TREE; ++ if (type_size > (int) HOST_BITS_PER_WIDEST_INT) ++ return NULL_TREE; + + /* Sign extension: result is dependent on the value. */ + old_type_size = TYPE_PRECISION (n->type); +@@ -1932,7 +1936,7 @@ + bool changed = false; + tree bswap16_type = NULL_TREE, bswap32_type = NULL_TREE, bswap64_type = NULL_TREE; + +- if (BITS_PER_UNIT != 8) ++ if (BITS_PER_UNIT != 8 || CHAR_BIT != 8) + return 0; + + if (sizeof (HOST_WIDEST_INT) < 8) Index: gcc/expr.c =================================================================== --- a/src/gcc/expr.c (.../tags/gcc_4_9_1_release) @@ -1613,6 +2483,76 @@ Index: gcc/config/i386/i386.c classes[i] = merge_classes (subclasses[i], classes[i]); } } +Index: gcc/config/sh/predicates.md +=================================================================== +--- a/src/gcc/config/sh/predicates.md (.../tags/gcc_4_9_1_release) ++++ b/src/gcc/config/sh/predicates.md (.../branches/gcc-4_9-branch) +@@ -489,6 +489,10 @@ + rtx mem_rtx = MEM_P (op) ? op : SUBREG_REG (op); + rtx x = XEXP (mem_rtx, 0); + ++ if (! ALLOW_INDEXED_ADDRESS ++ && GET_CODE (x) == PLUS && REG_P (XEXP (x, 0)) && REG_P (XEXP (x, 1))) ++ return false; ++ + if ((mode == QImode || mode == HImode) + && GET_CODE (x) == PLUS + && REG_P (XEXP (x, 0)) +@@ -567,6 +571,10 @@ + rtx mem_rtx = MEM_P (op) ? op : SUBREG_REG (op); + rtx x = XEXP (mem_rtx, 0); + ++ if (! ALLOW_INDEXED_ADDRESS ++ && GET_CODE (x) == PLUS && REG_P (XEXP (x, 0)) && REG_P (XEXP (x, 1))) ++ return false; ++ + if ((mode == QImode || mode == HImode) + && GET_CODE (x) == PLUS + && REG_P (XEXP (x, 0)) +Index: gcc/config/sh/sh.c +=================================================================== +--- a/src/gcc/config/sh/sh.c (.../tags/gcc_4_9_1_release) ++++ b/src/gcc/config/sh/sh.c (.../branches/gcc-4_9-branch) +@@ -10207,6 +10207,10 @@ + static bool + sh_legitimate_address_p (enum machine_mode mode, rtx x, bool strict) + { ++ if (! ALLOW_INDEXED_ADDRESS ++ && GET_CODE (x) == PLUS && REG_P (XEXP (x, 0)) && REG_P (XEXP (x, 1))) ++ return false; ++ + if (REG_P (x) && REGNO (x) == GBR_REG) + return true; + +@@ -10436,6 +10440,28 @@ + enum reload_type type = (enum reload_type) itype; + const int mode_sz = GET_MODE_SIZE (mode); + ++ if (! ALLOW_INDEXED_ADDRESS ++ && GET_CODE (*p) == PLUS ++ && REG_P (XEXP (*p, 0)) && REG_P (XEXP (*p, 1))) ++ { ++ *p = copy_rtx (*p); ++ push_reload (*p, NULL_RTX, p, NULL, ++ BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum, type); ++ return true; ++ } ++ ++ if (! ALLOW_INDEXED_ADDRESS ++ && GET_CODE (*p) == PLUS ++ && GET_CODE (XEXP (*p, 0)) == PLUS) ++ { ++ rtx sum = gen_rtx_PLUS (Pmode, XEXP (XEXP (*p, 0), 0), ++ XEXP (XEXP (*p, 0), 1)); ++ *p = gen_rtx_PLUS (Pmode, sum, XEXP (*p, 1)); ++ push_reload (sum, NULL_RTX, &XEXP (*p, 0), NULL, ++ BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum, type); ++ return true; ++ } ++ + if (TARGET_SHMEDIA) + return false; + Index: gcc/config/nios2/rtems.h =================================================================== --- a/src/gcc/config/nios2/rtems.h (.../tags/gcc_4_9_1_release) |