From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1851) id F3359385781F; Thu, 18 Mar 2021 15:37:18 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org F3359385781F MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="utf-8" From: Martin Liska To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/users/marxin/heads/remove-hsa-completely)] Remove BRIG front-end. X-Act-Checkin: gcc X-Git-Author: Martin Liska X-Git-Refname: refs/users/marxin/heads/remove-hsa-completely X-Git-Oldrev: f52818ac93974ea928b1abcfeaf37e625adc7d37 X-Git-Newrev: dd056b10beb3beb607991901e2e3df25833031e9 Message-Id: <20210318153718.F3359385781F@sourceware.org> Date: Thu, 18 Mar 2021 15:37:18 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 18 Mar 2021 15:37:19 -0000 https://gcc.gnu.org/g:dd056b10beb3beb607991901e2e3df25833031e9 commit dd056b10beb3beb607991901e2e3df25833031e9 Author: Martin Liska Date: Thu Mar 11 16:13:24 2021 +0100 Remove BRIG front-end. gcc/ada/ChangeLog: * gcc-interface/ada-tree.h (BUILT_IN_LIKELY): Use builtins from COROUTINES. (BUILT_IN_UNLIKELY): Likewise. gcc/ChangeLog: * builtins.def (DEF_HSAIL_BUILTIN): Remove. (DEF_HSAIL_ATOMIC_BUILTIN): Likewise. (DEF_HSAIL_SAT_BUILTIN): Likewise. (DEF_HSAIL_INTR_BUILTIN): Likewise. (DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN): Likewise. * doc/frontends.texi: Remove BRIG. * doc/install.texi: Likewise. * doc/invoke.texi: Likewise. * doc/standards.texi: Likewise. * brig-builtins.def: Removed. * brig/ChangeLog: Removed. * brig/Make-lang.in: Removed. * brig/brig-builtins.h: Removed. * brig/brig-c.h: Removed. * brig/brig-lang.c: Removed. * brig/brigfrontend/brig-arg-block-handler.cc: Removed. * brig/brigfrontend/brig-atomic-inst-handler.cc: Removed. * brig/brigfrontend/brig-basic-inst-handler.cc: Removed. * brig/brigfrontend/brig-branch-inst-handler.cc: Removed. * brig/brigfrontend/brig-cmp-inst-handler.cc: Removed. * brig/brigfrontend/brig-code-entry-handler.cc: Removed. * brig/brigfrontend/brig-code-entry-handler.h: Removed. * brig/brigfrontend/brig-comment-handler.cc: Removed. * brig/brigfrontend/brig-control-handler.cc: Removed. * brig/brigfrontend/brig-copy-move-inst-handler.cc: Removed. * brig/brigfrontend/brig-cvt-inst-handler.cc: Removed. * brig/brigfrontend/brig-fbarrier-handler.cc: Removed. * brig/brigfrontend/brig-function-handler.cc: Removed. * brig/brigfrontend/brig-function.cc: Removed. * brig/brigfrontend/brig-function.h: Removed. * brig/brigfrontend/brig-inst-mod-handler.cc: Removed. * brig/brigfrontend/brig-label-handler.cc: Removed. * brig/brigfrontend/brig-lane-inst-handler.cc: Removed. * brig/brigfrontend/brig-machine.c: Removed. * brig/brigfrontend/brig-machine.h: Removed. * brig/brigfrontend/brig-mem-inst-handler.cc: Removed. * brig/brigfrontend/brig-module-handler.cc: Removed. * brig/brigfrontend/brig-queue-inst-handler.cc: Removed. * brig/brigfrontend/brig-seg-inst-handler.cc: Removed. * brig/brigfrontend/brig-signal-inst-handler.cc: Removed. * brig/brigfrontend/brig-to-generic.cc: Removed. * brig/brigfrontend/brig-to-generic.h: Removed. * brig/brigfrontend/brig-util.cc: Removed. * brig/brigfrontend/brig-util.h: Removed. * brig/brigfrontend/brig-variable-handler.cc: Removed. * brig/brigfrontend/hsa-brig-format.h: Removed. * brig/brigfrontend/phsa.h: Removed. * brig/brigspec.c: Removed. * brig/config-lang.in: Removed. * brig/gccbrig.texi: Removed. * brig/lang-specs.h: Removed. * brig/lang.opt: Removed. gcc/testsuite/ChangeLog: * gfortran.dg/goacc/pr78027.f90: Remove -Wno-hsa option. * brig.dg/README: Removed. * brig.dg/dg.exp: Removed. * brig.dg/test/gimple/alloca.hsail: Removed. * brig.dg/test/gimple/atomics.hsail: Removed. * brig.dg/test/gimple/branches.hsail: Removed. * brig.dg/test/gimple/fbarrier.hsail: Removed. * brig.dg/test/gimple/function_calls.hsail: Removed. * brig.dg/test/gimple/internal-casts.hsail: Removed. * brig.dg/test/gimple/kernarg.hsail: Removed. * brig.dg/test/gimple/mem.hsail: Removed. * brig.dg/test/gimple/mulhi.hsail: Removed. * brig.dg/test/gimple/packed.hsail: Removed. * brig.dg/test/gimple/priv-array-offset-access.hsail: Removed. * brig.dg/test/gimple/smoke_test.hsail: Removed. * brig.dg/test/gimple/variables.hsail: Removed. * brig.dg/test/gimple/vector.hsail: Removed. * lib/brig-dg.exp: Removed. * lib/brig.exp: Removed. Diff: --- gcc/ada/gcc-interface/ada-tree.h | 6 +- gcc/brig-builtins.def | 675 --------- gcc/brig/ChangeLog | 433 ------ gcc/brig/Make-lang.in | 251 --- gcc/brig/brig-builtins.h | 99 -- gcc/brig/brig-c.h | 66 - gcc/brig/brig-lang.c | 958 ------------ gcc/brig/brigfrontend/brig-arg-block-handler.cc | 66 - gcc/brig/brigfrontend/brig-atomic-inst-handler.cc | 265 ---- gcc/brig/brigfrontend/brig-basic-inst-handler.cc | 735 --------- gcc/brig/brigfrontend/brig-branch-inst-handler.cc | 238 --- gcc/brig/brigfrontend/brig-cmp-inst-handler.cc | 198 --- gcc/brig/brigfrontend/brig-code-entry-handler.cc | 1305 ---------------- gcc/brig/brigfrontend/brig-code-entry-handler.h | 410 ----- gcc/brig/brigfrontend/brig-comment-handler.cc | 38 - gcc/brig/brigfrontend/brig-control-handler.cc | 108 -- .../brigfrontend/brig-copy-move-inst-handler.cc | 73 - gcc/brig/brigfrontend/brig-cvt-inst-handler.cc | 268 ---- gcc/brig/brigfrontend/brig-fbarrier-handler.cc | 45 - gcc/brig/brigfrontend/brig-function-handler.cc | 431 ------ gcc/brig/brigfrontend/brig-function.cc | 1602 -------------------- gcc/brig/brigfrontend/brig-function.h | 267 ---- gcc/brig/brigfrontend/brig-inst-mod-handler.cc | 58 - gcc/brig/brigfrontend/brig-label-handler.cc | 40 - gcc/brig/brigfrontend/brig-lane-inst-handler.cc | 85 -- gcc/brig/brigfrontend/brig-machine.c | 44 - gcc/brig/brigfrontend/brig-machine.h | 33 - gcc/brig/brigfrontend/brig-mem-inst-handler.cc | 178 --- gcc/brig/brigfrontend/brig-module-handler.cc | 41 - gcc/brig/brigfrontend/brig-queue-inst-handler.cc | 93 -- gcc/brig/brigfrontend/brig-seg-inst-handler.cc | 146 -- gcc/brig/brigfrontend/brig-signal-inst-handler.cc | 42 - gcc/brig/brigfrontend/brig-to-generic.cc | 1045 ------------- gcc/brig/brigfrontend/brig-to-generic.h | 240 --- gcc/brig/brigfrontend/brig-util.cc | 574 ------- gcc/brig/brigfrontend/brig-util.h | 120 -- gcc/brig/brigfrontend/brig-variable-handler.cc | 270 ---- gcc/brig/brigfrontend/hsa-brig-format.h | 1234 --------------- gcc/brig/brigfrontend/phsa.h | 79 - gcc/brig/brigspec.c | 136 -- gcc/brig/config-lang.in | 41 - gcc/brig/gccbrig.texi | 153 -- gcc/brig/lang-specs.h | 28 - gcc/brig/lang.opt | 46 - gcc/builtins.def | 43 - gcc/doc/frontends.texi | 2 +- gcc/doc/install.texi | 6 +- gcc/doc/invoke.texi | 4 - gcc/doc/standards.texi | 8 - gcc/testsuite/brig.dg/README | 12 - gcc/testsuite/brig.dg/dg.exp | 31 - gcc/testsuite/brig.dg/test/gimple/alloca.hsail | 37 - gcc/testsuite/brig.dg/test/gimple/atomics.hsail | 33 - gcc/testsuite/brig.dg/test/gimple/branches.hsail | 58 - gcc/testsuite/brig.dg/test/gimple/fbarrier.hsail | 74 - .../brig.dg/test/gimple/function_calls.hsail | 59 - .../brig.dg/test/gimple/internal-casts.hsail | 146 -- gcc/testsuite/brig.dg/test/gimple/kernarg.hsail | 25 - gcc/testsuite/brig.dg/test/gimple/mem.hsail | 39 - gcc/testsuite/brig.dg/test/gimple/mulhi.hsail | 33 - gcc/testsuite/brig.dg/test/gimple/packed.hsail | 76 - .../test/gimple/priv-array-offset-access.hsail | 87 -- gcc/testsuite/brig.dg/test/gimple/smoke_test.hsail | 91 -- gcc/testsuite/brig.dg/test/gimple/variables.hsail | 125 -- gcc/testsuite/brig.dg/test/gimple/vector.hsail | 57 - gcc/testsuite/gfortran.dg/goacc/pr78027.f90 | 4 - gcc/testsuite/lib/brig-dg.exp | 29 - gcc/testsuite/lib/brig.exp | 40 - 68 files changed, 6 insertions(+), 14376 deletions(-) diff --git a/gcc/ada/gcc-interface/ada-tree.h b/gcc/ada/gcc-interface/ada-tree.h index 461fa2b598c..099bc8ad304 100644 --- a/gcc/ada/gcc-interface/ada-tree.h +++ b/gcc/ada/gcc-interface/ada-tree.h @@ -580,6 +580,6 @@ do { \ #define EXIT_STMT_LABEL(NODE) TREE_OPERAND_CHECK_CODE (NODE, EXIT_STMT, 1) /* Small kludge to be able to define Ada built-in functions locally. - We overload them on top of the HSAIL/BRIG builtin functions. */ -#define BUILT_IN_LIKELY BUILT_IN_HSAIL_WORKITEMABSID -#define BUILT_IN_UNLIKELY BUILT_IN_HSAIL_GRIDSIZE + We overload them on top of the C++ coroutines builtin functions. */ +#define BUILT_IN_LIKELY BUILT_IN_CORO_PROMISE +#define BUILT_IN_UNLIKELY BUILT_IN_CORO_RESUME diff --git a/gcc/brig-builtins.def b/gcc/brig-builtins.def deleted file mode 100644 index a9ae2ffbddc..00000000000 --- a/gcc/brig-builtins.def +++ /dev/null @@ -1,675 +0,0 @@ -/* This file contains the definitions and documentation for the - HSAIL builtins used in the GNU compiler. - Copyright (C) 2016-2021 Free Software Foundation, Inc. - - Contributed by Pekka Jaaskelainen - for General Processor Tech. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ - -/* Following builtins are used by the BRIG (the binary representation of - HSAIL) frontend. Software implementations are available in libhsail-rt. - Use leading double underscore in the name to avoid name space clashes - with kernel program symbols in case the builtin is implemented as - a function call. */ - -/* Work-item ID related builtins are not constant in the work-group function - mode (each WI has a different return value). */ - -#ifndef DEF_HSAIL_BUILTIN -#define DEF_HSAIL_BUILTIN(ENUM, HSAIL_OPCODE, HSAIL_TYPE, \ - NAME, TYPE, ATTRS) -#endif - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_WORKITEMABSID, BRIG_OPCODE_WORKITEMABSID, - BRIG_TYPE_U32, "__hsail_workitemabsid", BT_FN_UINT_UINT_PTR, - ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_GRIDSIZE, BRIG_OPCODE_GRIDSIZE, - BRIG_TYPE_U32, "__hsail_gridsize", BT_FN_UINT_UINT_PTR, - ATTR_PURE_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_WORKITEMFLATABSID_U32, - BRIG_OPCODE_WORKITEMFLATABSID, BRIG_TYPE_U32, - "__hsail_workitemflatabsid_u32", BT_FN_UINT_CONST_PTR, - ATTR_PURE_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_WORKITEMFLATABSID_U64, - BRIG_OPCODE_WORKITEMFLATABSID, BRIG_TYPE_U64, - "__hsail_workitemflatabsid_u64", BT_FN_ULONG_CONST_PTR, - ATTR_PURE_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_WORKITEMFLATID, BRIG_OPCODE_WORKITEMFLATID, - BRIG_TYPE_U32, "__hsail_workitemflatid", BT_FN_UINT_CONST_PTR, - ATTR_PURE_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_WORKITEMID, BRIG_OPCODE_WORKITEMID, - BRIG_TYPE_U32, "__hsail_workitemid", - BT_FN_UINT_UINT_CONST_PTR, ATTR_PURE_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_WORKGROUPID, BRIG_OPCODE_WORKGROUPID, - BRIG_TYPE_U32, "__hsail_workgroupid", - BT_FN_UINT_UINT_CONST_PTR, ATTR_PURE_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_CURRENTWORKITEMFLATID, - BRIG_OPCODE_CURRENTWORKITEMFLATID, - BRIG_TYPE_U32, "__hsail_currentworkitemflatid", - BT_FN_UINT_PTR, ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_WORKITEMABSID_U64, BRIG_OPCODE_WORKITEMABSID, - BRIG_TYPE_U64, "__hsail_workitemabsid_u64", - BT_FN_ULONG_UINT_PTR, ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_PACKETID, BRIG_OPCODE_PACKETID, - BRIG_TYPE_U64, "__hsail_packetid", BT_FN_ULONG_PTR, - ATTR_PURE_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_PACKETCOMPLETIONSIG_SIG64, - BRIG_OPCODE_PACKETCOMPLETIONSIG, BRIG_TYPE_SIG64, - "__hsail_packetcompletionsig_sig64", BT_FN_ULONG_PTR, - ATTR_PURE_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_PACKETCOMPLETIONSIG_SIG32, - BRIG_OPCODE_PACKETCOMPLETIONSIG, BRIG_TYPE_SIG32, - "__hsail_packetcompletionsig_sig32", BT_FN_UINT_PTR, - ATTR_PURE_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_CURRENTWORKGROUPSIZE, - BRIG_OPCODE_CURRENTWORKGROUPSIZE, BRIG_TYPE_U32, - "__hsail_currentworkgroupsize", BT_FN_UINT_UINT_CONST_PTR, - ATTR_PURE_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_WORKGROUPSIZE, BRIG_OPCODE_WORKGROUPSIZE, - BRIG_TYPE_U32, "__hsail_workgroupsize", - BT_FN_UINT_UINT_CONST_PTR, - ATTR_PURE_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_DIM, BRIG_OPCODE_DIM, - BRIG_TYPE_U32, "__hsail_dim", BT_FN_UINT_PTR, - ATTR_PURE_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_GRIDGROUPS, BRIG_OPCODE_GRIDGROUPS, - BRIG_TYPE_U32, "__hsail_gridgroups", BT_FN_UINT_UINT_PTR, - ATTR_PURE_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BITEXTRACT_S32, BRIG_OPCODE_BITEXTRACT, - BRIG_TYPE_S32, "__hsail_bitextract_s32", - BT_FN_INT_INT_UINT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BITEXTRACT_U32, BRIG_OPCODE_BITEXTRACT, - BRIG_TYPE_U32, "__hsail_bitextract_u32", - BT_FN_UINT_UINT_UINT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BITEXTRACT_S64, BRIG_OPCODE_BITEXTRACT, - BRIG_TYPE_S64, "__hsail_bitextract_s64", - BT_FN_LONG_LONG_UINT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BITEXTRACT_U64, BRIG_OPCODE_BITEXTRACT, - BRIG_TYPE_U64, "__hsail_bitextract_u64", - BT_FN_ULONG_ULONG_UINT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BITINSERT_U32, BRIG_OPCODE_BITINSERT, - BRIG_TYPE_U32, "__hsail_bitinsert_u32", - BT_FN_UINT_UINT_UINT_UINT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BITINSERT_U64, BRIG_OPCODE_BITINSERT, - BRIG_TYPE_U64, "__hsail_bitinsert_u64", - BT_FN_ULONG_ULONG_ULONG_UINT_UINT, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BITMASK_B32, BRIG_OPCODE_BITMASK, - BRIG_TYPE_B32, "__hsail_bitmask_u32", BT_FN_UINT_UINT_UINT, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BITMASK_B64, BRIG_OPCODE_BITMASK, - BRIG_TYPE_B64, "__hsail_bitmask_u64", BT_FN_ULONG_UINT_UINT, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BITREV_B32, BRIG_OPCODE_BITREV, - BRIG_TYPE_B32, "__hsail_bitrev_u32", BT_FN_UINT_UINT, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BITREV_B64, BRIG_OPCODE_BITREV, - BRIG_TYPE_B64, "__hsail_bitrev_u64", BT_FN_ULONG_ULONG, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BITSELECT_B32, BRIG_OPCODE_BITSELECT, - BRIG_TYPE_B32, "__hsail_bitselect_u32", - BT_FN_UINT_UINT_UINT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BITSELECT_U64, BRIG_OPCODE_BITSELECT, - BRIG_TYPE_B64, "__hsail_bitselect_u64", - BT_FN_ULONG_ULONG_ULONG_ULONG, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_FIRSTBIT_U32, BRIG_OPCODE_FIRSTBIT, - BRIG_TYPE_U32, "__hsail_firstbit_u32", BT_FN_UINT_UINT, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_FIRSTBIT_S32, BRIG_OPCODE_FIRSTBIT, - BRIG_TYPE_S32, "__hsail_firstbit_s32", BT_FN_UINT_INT, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_FIRSTBIT_U64, BRIG_OPCODE_FIRSTBIT, - BRIG_TYPE_U64, "__hsail_firstbit_u64", BT_FN_UINT_ULONG, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_FIRSTBIT_S64, BRIG_OPCODE_FIRSTBIT, - BRIG_TYPE_S64, "__hsail_firstbit_s64", BT_FN_UINT_LONG, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_LASTBIT_U32, BRIG_OPCODE_LASTBIT, - BRIG_TYPE_U32, "__hsail_lastbit_u32", BT_FN_UINT_UINT, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_LASTBIT_U64, BRIG_OPCODE_LASTBIT, - BRIG_TYPE_U64, "__hsail_lastbit_u64", BT_FN_UINT_ULONG, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BORROW_U32, BRIG_OPCODE_BORROW, - BRIG_TYPE_U32, "__hsail_borrow_u32", BT_FN_UINT_UINT_UINT, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BORROW_U64, BRIG_OPCODE_BORROW, - BRIG_TYPE_U64, "__hsail_borrow_u64", BT_FN_ULONG_ULONG_ULONG, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_CARRY_U32, BRIG_OPCODE_CARRY, - BRIG_TYPE_U32, "__hsail_carry_u32", BT_FN_UINT_UINT_UINT, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_CARRY_U64, BRIG_OPCODE_CARRY, - BRIG_TYPE_U64, "__hsail_carry_u64", BT_FN_ULONG_ULONG_ULONG, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_REM_S32, BRIG_OPCODE_REM, - BRIG_TYPE_S32, "__hsail_rem_s32", BT_FN_INT_INT_INT, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_REM_S64, BRIG_OPCODE_REM, - BRIG_TYPE_S64, "__hsail_rem_s64", BT_FN_LONG_LONG_LONG, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_MIN_F32, BRIG_OPCODE_MIN, - BRIG_TYPE_F32, "__hsail_min_f32", BT_FN_FLOAT_FLOAT_FLOAT, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_MAX_F32, BRIG_OPCODE_MAX, - BRIG_TYPE_F32, "__hsail_max_f32", BT_FN_FLOAT_FLOAT_FLOAT, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_MIN_F64, BRIG_OPCODE_MIN, - BRIG_TYPE_F64, "__hsail_min_f64", BT_FN_DOUBLE_DOUBLE_DOUBLE, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_MAX_F64, BRIG_OPCODE_MAX, - BRIG_TYPE_F64, "__hsail_max_f64", BT_FN_DOUBLE_DOUBLE_DOUBLE, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_CLASS_F32, BRIG_OPCODE_CLASS, - BRIG_TYPE_F32, "__hsail_class_f32", BT_FN_UINT_FLOAT_UINT, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_CLASS_F64, BRIG_OPCODE_CLASS, - BRIG_TYPE_F64, "__hsail_class_f64", BT_FN_UINT_DOUBLE_UINT, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_CLASS_F32_F16, BRIG_OPCODE_CLASS, - BRIG_TYPE_F16, "__hsail_class_f32_f16", - BT_FN_UINT_FLOAT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_FRACT_F32, BRIG_OPCODE_FRACT, - BRIG_TYPE_F32, "__hsail_fract_f32", BT_FN_FLOAT_FLOAT, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_FRACT_F64, BRIG_OPCODE_FRACT, - BRIG_TYPE_F64, "__hsail_fract_f64", BT_FN_DOUBLE_DOUBLE, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BARRIER, BRIG_OPCODE_BARRIER, - BRIG_TYPE_NONE, "__hsail_barrier", BT_FN_VOID_PTR, - ATTR_RT_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_INITFBAR, BRIG_OPCODE_INITFBAR, - BRIG_TYPE_NONE, "__hsail_initfbar", BT_FN_VOID_UINT_PTR, - ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_JOINFBAR, BRIG_OPCODE_JOINFBAR, - BRIG_TYPE_NONE, "__hsail_joinfbar", BT_FN_VOID_UINT_PTR, - ATTR_NOTHROW_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_WAITFBAR, BRIG_OPCODE_WAITFBAR, - BRIG_TYPE_NONE, "__hsail_waitfbar", BT_FN_VOID_UINT_PTR, - ATTR_RT_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_ARRIVEFBAR, BRIG_OPCODE_ARRIVEFBAR, - BRIG_TYPE_NONE, "__hsail_arrivefbar", BT_FN_VOID_UINT_PTR, - ATTR_RT_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_LEAVEFBAR, BRIG_OPCODE_LEAVEFBAR, - BRIG_TYPE_NONE, "__hsail_leavefbar", BT_FN_VOID_UINT_PTR, - ATTR_NOTHROW_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_RELEASEFBAR, BRIG_OPCODE_RELEASEFBAR, - BRIG_TYPE_NONE, "__hsail_releasefbar", BT_FN_VOID_UINT_PTR, - ATTR_NOTHROW_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BITALIGN, BRIG_OPCODE_BITALIGN, - BRIG_TYPE_B32, "__hsail_bitalign", - BT_FN_UINT_ULONG_ULONG_UINT, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BYTEALIGN, BRIG_OPCODE_BYTEALIGN, - BRIG_TYPE_B32, "__hsail_bytealign", - BT_FN_UINT_ULONG_ULONG_UINT, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_LERP, BRIG_OPCODE_LERP, - BRIG_TYPE_U8X4, "__hsail_lerp", BT_FN_UINT_UINT_UINT_UINT, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_PACKCVT, BRIG_OPCODE_PACKCVT, - BRIG_TYPE_U8X4, "__hsail_packcvt", - BT_FN_UINT_FLOAT_FLOAT_FLOAT_FLOAT, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_UNPACKCVT, BRIG_OPCODE_UNPACKCVT, - BRIG_TYPE_F32, "__hsail_unpackcvt", BT_FN_FLOAT_UINT_UINT, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_SAD_U16X2, BRIG_OPCODE_SAD, - BRIG_TYPE_U16X2, "__hsail_sad_u16x2", - BT_FN_UINT_UINT_UINT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_SAD_U32, BRIG_OPCODE_SAD, - BRIG_TYPE_U32, "__hsail_sad_u32", BT_FN_UINT_UINT_UINT_UINT, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_SAD_U8X4, BRIG_OPCODE_SAD, - BRIG_TYPE_U8X4, "__hsail_sad_u8x4", - BT_FN_UINT_UINT_UINT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_SADHI_U8X4, BRIG_OPCODE_SADHI, - BRIG_TYPE_U16X2, "__hsail_sadhi_u16x2_u8x4", - BT_FN_UINT_UINT_UINT_UINT, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_CLOCK, BRIG_OPCODE_CLOCK, - BRIG_TYPE_U64, "__hsail_clock", BT_FN_ULONG, - ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_CUID, BRIG_OPCODE_CUID, - BRIG_TYPE_U32, "__hsail_cuid", BT_FN_UINT_PTR, - ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_MAXCUID, BRIG_OPCODE_MAXCUID, - BRIG_TYPE_U32, "__hsail_maxcuid", BT_FN_UINT_PTR, - ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_DEBUGTRAP, BRIG_OPCODE_DEBUGTRAP, - BRIG_TYPE_U32, "__hsail_debugtrap", BT_FN_VOID_UINT_PTR, - ATTR_NORETURN_NOTHROW_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_GROUPBASEPTR, BRIG_OPCODE_GROUPBASEPTR, - BRIG_TYPE_U32, "__hsail_groupbaseptr", BT_FN_UINT_PTR, - ATTR_PURE_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_KERNARGBASEPTR_U64, - BRIG_OPCODE_KERNARGBASEPTR, BRIG_TYPE_U64, - "__hsail_kernargbaseptr_u64", BT_FN_ULONG_PTR, - ATTR_PURE_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_KERNARGBASEPTR_U32, - BRIG_OPCODE_KERNARGBASEPTR, BRIG_TYPE_U32, - "__hsail_kernargbaseptr_u32", BT_FN_UINT_PTR, - ATTR_PURE_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_ALLOCA, BRIG_OPCODE_ALLOCA, - BRIG_TYPE_U32, "__hsail_alloca", BT_FN_UINT_UINT_UINT_PTR, - ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_LDQUEUEWRITEINDEX, - BRIG_OPCODE_LDQUEUEWRITEINDEX, - BRIG_TYPE_U64, "__hsail_ldqueuewriteindex", - BT_FN_ULONG_ULONG, ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_LDQUEUEREADINDEX, - BRIG_OPCODE_LDQUEUEREADINDEX, - BRIG_TYPE_U64, "__hsail_ldqueuereadindex", - BT_FN_ULONG_ULONG, ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_STQUEUEWRITEINDEX, - BRIG_OPCODE_STQUEUEWRITEINDEX, - BRIG_TYPE_U64, "__hsail_stqueuewriteindex", - BT_FN_VOID_UINT64_UINT64, ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_STQUEUEREADINDEX, - BRIG_OPCODE_STQUEUEREADINDEX, - BRIG_TYPE_U64, "__hsail_stqueuereadindex", - BT_FN_VOID_UINT64_UINT64, ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_ADDQUEUEWRITEINDEX, - BRIG_OPCODE_ADDQUEUEWRITEINDEX, - BRIG_TYPE_U64, "__hsail_addqueuewriteindex", - BT_FN_ULONG_ULONG_ULONG, ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_CASQUEUEWRITEINDEX, - BRIG_OPCODE_CASQUEUEWRITEINDEX, - BRIG_TYPE_U64, "__hsail_casqueuewriteindex", - BT_FN_ULONG_ULONG_ULONG_ULONG, ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_SEGMENTP_GLOBAL, - BRIG_OPCODE_SEGMENTP, - BRIG_TYPE_U32, "__hsail_segmentp_global", - BT_FN_UINT32_UINT64_PTR, ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_SEGMENTP_GROUP, - BRIG_OPCODE_SEGMENTP, - BRIG_TYPE_U32, "__hsail_segmentp_group", - BT_FN_UINT32_UINT64_PTR, ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_SEGMENTP_PRIVATE, - BRIG_OPCODE_SEGMENTP, - BRIG_TYPE_U32, "__hsail_segmentp_private", - BT_FN_UINT32_UINT64_PTR, ATTR_NOTHROW_LEAF_LIST) - -#ifndef DEF_HSAIL_ATOMIC_BUILTIN -#define DEF_HSAIL_ATOMIC_BUILTIN(ENUM, ATOMIC_OPCODE, HSAIL_TYPE, \ - NAME, TYPE, ATTRS) -#endif - -DEF_HSAIL_ATOMIC_BUILTIN (BUILT_IN_HSAIL_ATOMIC_MIN_S32, BRIG_ATOMIC_MIN, - BRIG_TYPE_S32, "__hsail_atomic_min_s32", - BT_FN_INT_PTR_INT, ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_ATOMIC_BUILTIN (BUILT_IN_HSAIL_ATOMIC_MIN_S64, BRIG_ATOMIC_MIN, - BRIG_TYPE_S64, "__hsail_atomic_min_s64", - BT_FN_LONG_PTR_LONG, ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_ATOMIC_BUILTIN (BUILT_IN_HSAIL_ATOMIC_MIN_U32, BRIG_ATOMIC_MIN, - BRIG_TYPE_U32, "__hsail_atomic_min_u32", - BT_FN_UINT_PTR_UINT, ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_ATOMIC_BUILTIN (BUILT_IN_HSAIL_ATOMIC_MIN_U64, BRIG_ATOMIC_MIN, - BRIG_TYPE_U64, "__hsail_atomic_min_u64", - BT_FN_ULONG_PTR_ULONG, ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_ATOMIC_BUILTIN (BUILT_IN_HSAIL_ATOMIC_MAX_S32, BRIG_ATOMIC_MAX, - BRIG_TYPE_S32, "__hsail_atomic_max_s32", - BT_FN_INT_PTR_INT, ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_ATOMIC_BUILTIN (BUILT_IN_HSAIL_ATOMIC_MAX_S64, BRIG_ATOMIC_MAX, - BRIG_TYPE_S64, "__hsail_atomic_max_s64", - BT_FN_LONG_PTR_LONG, ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_ATOMIC_BUILTIN (BUILT_IN_HSAIL_ATOMIC_MAX_U32, BRIG_ATOMIC_MAX, - BRIG_TYPE_U32, "__hsail_atomic_max_u32", - BT_FN_UINT_PTR_UINT, ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_ATOMIC_BUILTIN (BUILT_IN_HSAIL_ATOMIC_MAX_U64, BRIG_ATOMIC_MAX, - BRIG_TYPE_U64, "__hsail_atomic_max_u64", - BT_FN_ULONG_PTR_ULONG, ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_ATOMIC_BUILTIN (BUILT_IN_HSAIL_ATOMIC_WRAPDEC_U32, - BRIG_ATOMIC_WRAPDEC, BRIG_TYPE_U32, - "__hsail_atomic_wrapdec_u32", - BT_FN_UINT_PTR_UINT, ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_ATOMIC_BUILTIN (BUILT_IN_HSAIL_ATOMIC_WRAPDEC_U64, - BRIG_ATOMIC_WRAPDEC, BRIG_TYPE_U64, - "__hsail_atomic_wrapdec_u64", - BT_FN_ULONG_PTR_ULONG, ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_ATOMIC_BUILTIN (BUILT_IN_HSAIL_ATOMIC_WRAPINC_U32, - BRIG_ATOMIC_WRAPINC, BRIG_TYPE_U32, - "__hsail_atomic_wrapinc_u32", - BT_FN_UINT_PTR_UINT, ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_ATOMIC_BUILTIN (BUILT_IN_HSAIL_ATOMIC_WRAPINC_U64, - BRIG_ATOMIC_WRAPINC, BRIG_TYPE_U64, - "__hsail_atomic_wrapinc_u64", - BT_FN_ULONG_PTR_ULONG, ATTR_NOTHROW_LEAF_LIST) - -#ifndef DEF_HSAIL_SAT_BUILTIN -#define DEF_HSAIL_SAT_BUILTIN(ENUM, HSAIL_OPCODE, HSAIL_TYPE, \ - NAME, TYPE, ATTRS) -#endif - -DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_ADD_U64, BRIG_OPCODE_ADD, - BRIG_TYPE_U64, "__hsail_sat_add_u64", - BT_FN_ULONG_ULONG_ULONG, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_ADD_S64, BRIG_OPCODE_ADD, - BRIG_TYPE_S64, "__hsail_sat_add_s64", - BT_FN_LONG_LONG_LONG, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_ADD_U32, BRIG_OPCODE_ADD, - BRIG_TYPE_U32, "__hsail_sat_add_u32", - BT_FN_UINT_UINT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_ADD_S32, BRIG_OPCODE_ADD, - BRIG_TYPE_S32, "__hsail_sat_add_s32", - BT_FN_INT_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_ADD_U16, BRIG_OPCODE_ADD, - BRIG_TYPE_U16, "__hsail_sat_add_u16", - BT_FN_UINT16_UINT16_UINT16, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_ADD_S16, BRIG_OPCODE_ADD, - BRIG_TYPE_S16, "__hsail_sat_add_s16", - BT_FN_INT16_INT16_INT16, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_ADD_U8, BRIG_OPCODE_ADD, - BRIG_TYPE_U8, "__hsail_sat_add_u8", - BT_FN_UINT8_UINT8_UINT8, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_ADD_S8, BRIG_OPCODE_ADD, - BRIG_TYPE_S8, "__hsail_sat_add_s8", - BT_FN_INT8_INT8_INT8, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_SUB_U64, BRIG_OPCODE_SUB, - BRIG_TYPE_U64, "__hsail_sat_sub_u64", - BT_FN_ULONG_ULONG_ULONG, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_SUB_S64, BRIG_OPCODE_SUB, - BRIG_TYPE_S64, "__hsail_sat_sub_s64", - BT_FN_LONG_LONG_LONG, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_SUB_U32, BRIG_OPCODE_SUB, - BRIG_TYPE_U32, "__hsail_sat_sub_u32", - BT_FN_UINT_UINT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_SUB_S32, BRIG_OPCODE_SUB, - BRIG_TYPE_S32, "__hsail_sat_sub_s32", - BT_FN_INT_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_SUB_U16, BRIG_OPCODE_SUB, - BRIG_TYPE_U16, "__hsail_sat_sub_u16", - BT_FN_UINT16_UINT16_UINT16, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_SUB_S16, BRIG_OPCODE_SUB, - BRIG_TYPE_S16, "__hsail_sat_sub_s16", - BT_FN_INT16_INT16_INT16, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_SUB_U8, BRIG_OPCODE_SUB, - BRIG_TYPE_U8, "__hsail_sat_sub_u8", - BT_FN_UINT8_UINT8_UINT8, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_SUB_S8, BRIG_OPCODE_SUB, - BRIG_TYPE_S8, "__hsail_sat_sub_s8", - BT_FN_INT8_INT8_INT8, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_MUL_U64, BRIG_OPCODE_MUL, - BRIG_TYPE_U64, "__hsail_sat_mul_u64", - BT_FN_ULONG_ULONG_ULONG, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_MUL_S64, BRIG_OPCODE_MUL, - BRIG_TYPE_S64, "__hsail_sat_mul_s64", - BT_FN_LONG_LONG_LONG, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_MUL_U32, BRIG_OPCODE_MUL, - BRIG_TYPE_U32, "__hsail_sat_mul_u32", - BT_FN_UINT_UINT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_MUL_S32, BRIG_OPCODE_MUL, - BRIG_TYPE_S32, "__hsail_sat_mul_s32", - BT_FN_INT_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_MUL_U16, BRIG_OPCODE_MUL, - BRIG_TYPE_U16, "__hsail_sat_mul_u16", - BT_FN_UINT16_UINT16_UINT16, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_MUL_S16, BRIG_OPCODE_MUL, - BRIG_TYPE_S16, "__hsail_sat_mul_s16", - BT_FN_INT16_INT16_INT16, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_MUL_U8, BRIG_OPCODE_MUL, - BRIG_TYPE_U8, "__hsail_sat_mul_u8", - BT_FN_UINT8_UINT8_UINT8, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_MUL_S8, BRIG_OPCODE_MUL, - BRIG_TYPE_S8, "__hsail_sat_mul_s8", - BT_FN_INT8_INT8_INT8, ATTR_CONST_NOTHROW_LEAF_LIST) - -#ifndef DEF_HSAIL_INTR_BUILTIN -#define DEF_HSAIL_INTR_BUILTIN(ENUM, NAME, TYPE, ATTRS) -#endif - -DEF_HSAIL_INTR_BUILTIN (BUILT_IN_HSAIL_FTZ_F32_F16, "__hsail_ftz_f32_f16", - BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_INTR_BUILTIN (BUILT_IN_HSAIL_FTZ_F32, "__hsail_ftz_f32", - BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_INTR_BUILTIN (BUILT_IN_HSAIL_FTZ_F64, "__hsail_ftz_f64", - BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_INTR_BUILTIN (BUILT_IN_HSAIL_PUSH_FRAME, "__hsail_alloca_push_frame", - BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_INTR_BUILTIN (BUILT_IN_HSAIL_POP_FRAME, "__hsail_alloca_pop_frame", - BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_INTR_BUILTIN (BUILT_IN_HSAIL_SETWORKITEMID, "__hsail_setworkitemid", - BT_FN_VOID_UINT32_UINT32_PTR, ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_INTR_BUILTIN (BUILT_IN_HSAIL_LAUNCH_WG_FUNC, - "__hsail_launch_wg_function", - BT_FN_VOID_PTR_PTR_UINT32, ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_INTR_BUILTIN (BUILT_IN_HSAIL_LAUNCH_KERNEL, - "__hsail_launch_kernel", - BT_FN_VOID_PTR_PTR_PTR, ATTR_NOTHROW_LEAF_LIST) - -DEF_HSAIL_INTR_BUILTIN (BUILT_IN_HSAIL_F32_TO_F16, "__hsail_f32_to_f16", - BT_FN_UINT16_UINT32, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_INTR_BUILTIN (BUILT_IN_HSAIL_F16_TO_F32, "__hsail_f16_to_f32", - BT_FN_UINT32_UINT16, ATTR_CONST_NOTHROW_LEAF_LIST) - -#ifndef DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN -#define DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN(ENUM, HSAIL_DEST_TYPE, HSAIL_SRC_TYPE, \ - NAME, TYPE, ATTRS) -#endif - -DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_U8_F32, - BRIG_TYPE_U8, BRIG_TYPE_F32, - "__hsail_cvt_zeroi_sat_u8_f32", - BT_FN_UINT8_FLOAT, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_S8_F32, - BRIG_TYPE_S8, BRIG_TYPE_F32, - "__hsail_cvt_zeroi_sat_s8_f32", - BT_FN_INT8_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_U16_F32, - BRIG_TYPE_U16, BRIG_TYPE_F32, - "__hsail_cvt_zeroi_sat_u16_f32", - BT_FN_UINT16_FLOAT, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_S16_F32, - BRIG_TYPE_S16, BRIG_TYPE_F32, - "__hsail_cvt_zeroi_sat_s16_f32", - BT_FN_INT16_FLOAT, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_U32_F32, - BRIG_TYPE_U32, BRIG_TYPE_F32, - "__hsail_cvt_zeroi_sat_u32_f32", - BT_FN_UINT32_FLOAT, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_S32_F32, - BRIG_TYPE_S32, BRIG_TYPE_F32, - "__hsail_cvt_zeroi_sat_s32_f32", - BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_U64_F32, - BRIG_TYPE_U64, BRIG_TYPE_F32, - "__hsail_cvt_zeroi_sat_u64_f32", - BT_FN_UINT64_FLOAT, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_S64_F32, - BRIG_TYPE_S64, BRIG_TYPE_F32, - "__hsail_cvt_zeroi_sat_s64_f32", - BT_FN_LONG_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_U8_F64, - BRIG_TYPE_U8, BRIG_TYPE_F64, - "__hsail_cvt_zeroi_sat_u8_f64", - BT_FN_UINT8_FLOAT, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_S8_F64, - BRIG_TYPE_S8, BRIG_TYPE_F64, - "__hsail_cvt_zeroi_sat_s8_f64", - BT_FN_INT8_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_U16_F64, - BRIG_TYPE_U16, BRIG_TYPE_F64, - "__hsail_cvt_zeroi_sat_u16_f64", - BT_FN_UINT16_FLOAT, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_S16_F64, - BRIG_TYPE_S16, BRIG_TYPE_F64, - "__hsail_cvt_zeroi_sat_s16_f64", - BT_FN_INT16_FLOAT, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_U32_F64, - BRIG_TYPE_U32, BRIG_TYPE_F64, - "__hsail_cvt_zeroi_sat_u32_f64", - BT_FN_UINT32_FLOAT, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_S32_F64, - BRIG_TYPE_S32, BRIG_TYPE_F64, - "__hsail_cvt_zeroi_sat_s32_f64", - BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_U64_F64, - BRIG_TYPE_U64, BRIG_TYPE_F64, - "__hsail_cvt_zeroi_sat_u64_f64", - BT_FN_UINT64_FLOAT, - ATTR_CONST_NOTHROW_LEAF_LIST) - -DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_S64_F64, - BRIG_TYPE_S64, BRIG_TYPE_F64, - "__hsail_cvt_zeroi_sat_s64_f64", - BT_FN_LONG_FLOAT, - ATTR_CONST_NOTHROW_LEAF_LIST) diff --git a/gcc/brig/ChangeLog b/gcc/brig/ChangeLog deleted file mode 100644 index 7d599fab6ac..00000000000 --- a/gcc/brig/ChangeLog +++ /dev/null @@ -1,433 +0,0 @@ -2020-12-16 Martin Liska - - * lang.opt: Remove usage of Report. - -2020-11-20 Jakub Jelinek - - PR other/97911 - * Make-lang.in (brig.serial): Change from goal to a variable. - (.PHONY): Drop brig.serial and brig.prev. - (brig1$(exeext)): Depend on $(brig.serial) rather than brig.serial. - -2020-11-18 Jakub Jelinek - - * Make-lang.in (brig.serial): New goal. - (.PHONY): Add brig.serial brig.prev. - (brig1$(exeext)): Depend on brig.prev. Call LINK_PROGRESS. - -2020-08-03 Martin Jambor - - * brigfrontend/brig-util.h (hsa_type_packed_p): Declared. - * brigfrontend/brig-util.cc (hsa_type_packed_p): Moved here from - removed gcc/hsa-common.c. - * brigfrontend/hsa-brig-format.h: New file. - -2020-01-01 Jakub Jelinek - - Update copyright years. - -2019-10-04 Joseph Myers - - * brig-lang.c (flag_isoc2x): New variable. - -2019-08-23 Jakub Jelinek - - PR middle-end/91283 - * brig-lang.c (brig_langhook_post_options): Set flag_excess_precision - instead of flag_excess_precision_cmdline. - -2019-06-25 Jozef Lawrynowicz - - * brig-lang.c (brig_build_c_type_nodes): Accept "__intN__" - format of "__intN" types for SIZE_TYPE. - -2019-05-16 Martin Sebor - - * brigfrontend/brig-control-handler.cc - (brig_directive_control_handler::operator): Remove trailing newline - from a diagnostic. - * brigfrontend/brig-module-handler.cc - (brig_directive_module_handler::operator): Remove a duplicated space - from a diagnostic. - -2019-01-01 Jakub Jelinek - - Update copyright years. - -2018-10-17 David Malcolm - - * Make-lang.in (selftest-brig): New. - -2018-07-20 Martin Sebor - - PR middle-end/82063 - * brig-lang.c (brig_langhook_handle_option): Change function - argument to HOST_WIDE_INT. - -2018-07-04 Martin Jambor - - PR hsa/86371 - * Make-lang.in (BRIGINCLUDES): Remove erroneous include path in $HOME. - -2018-06-28 Martin Liska - - * brigspec.c: Add missing header file inclusion. - -2018-06-08 David Malcolm - - * brigfrontend/brig-to-generic.cc - (brig_to_generic::write_globals): Use TDF_NONE rather than 0. - (dump_function): Likewise. - -2018-05-18 Richard Sandiford - - * brigfrontend/brig-function.cc - (brig_function::get_builtin_for_hsa_opcode): Use BUILT_IN_FMA - for BRIG_OPCODE_FMA. - (brig_function::get_tree_code_for_hsa_opcode): Treat BUILT_IN_FMA - as a call. - -2018-05-04 Pekka Jääskeläinen - - * brigfrontend/brig-basic-inst-handler.cc: Fix handling of NOPs. - -2018-05-04 Pekka Jääskeläinen - - Add flag -fassume-phsa that is on by default. If -fno-assume-phsa - is given, these optimizations are disabled. With this flag, gccbrig - can generate GENERIC that assumes we are targeting a phsa-runtime - based implementation, which allows us to expose the work-item context - accesses to retrieve WI IDs etc. which helps optimizers. - First optimization that takes advantage of this is to get rid of - the setworkitemid calls whenever we have non-inlined calls that - use IDs internally. Other optimizations added in this commit: - - expand absoluteid to similar level of simplicity as workitemid. - At the moment absoluteid is the best indexing ID to end up with - WG vectorization. - - propagate ID variables closer to their uses. This is mainly - to avoid known useless casts, which confuse at least scalar - evolution analysis. - - use signed long long for storing IDs. Unsigned integers have - defined wraparound semantics, which confuse at least scalar - evolution analysis, leading to unvectorizable WI loops. - - also refactor some BRIG function generation helpers to brig_function. - - no point in having the wi-loop as a for-loop. It's really - a do...while and SCEV can analyze it just fine still. - - add consts to ptrs etc. in BRIG builtin defs. - Improves optimization opportunities. - - add qualifiers to generated function parameters. - Const and restrict on the hidden local/private pointers, - the arg buffer and the context pointer help some optimizations. - * brigfrontend/brig-basic-inst-handler.cc: See above. - * brigfrontend/brig-branch-inst-handler.cc: See above. - * brigfrontend/brig-cmp-inst-handler.cc: See above. - * brigfrontend/brig-code-entry-handler.cc: See above. - * brigfrontend/brig-code-entry-handler.h: See above. - * brigfrontend/brig-control-handler.cc: See above. - * brigfrontend/brig-cvt-inst-handler.cc: See above. - * brigfrontend/brig-function-handler.cc: See above. - * brigfrontend/brig-function.cc: See above. - * brigfrontend/brig-function.h: See above. - * brigfrontend/brig-label-handler.cc: See above. - * brigfrontend/brig-lane-inst-handler.cc: See above. - * brigfrontend/brig-mem-inst-handler.cc: See above. - * brigfrontend/phsa.h: See above. - * lang.opt: See above. - -2018-05-04 Pekka Jääskeläinen - - * brigfrontend/brig-function-handler.cc: Skip multiple forward - declarations of the same function. - -2018-05-04 Pekka Jääskeläinen - - * brig-lang.c: Do not allow optimizations based on known C - builtins. - -2018-05-04 Pekka Jääskeläinen - - * brig-lang.c: Allow controlling strict aliasing from - cmd line. - -2018-05-04 Pekka Jääskeläinen - - * brigfrontend/brig-code-entry-handler.cc: The modulo in - ID computation should not be needed. - -2018-05-04 Pekka Jääskeläinen - - * brig-lang.c: Add support for whole program - optimizations by marking the kernels externally visible. - * brigfrontend/brig-branch-inst-handler.cc: See above. - * brigfrontend/brig-function-handler.cc: See above. - * brigfrontend/brig-function.cc: See above. - * brigfrontend/brig-to-generic.cc: See above. - * brigfrontend/brig-to-generic.h: See above. - * brigfrontend/brig-variable-handler.h: See above. - -2018-01-03 Richard Sandiford - Alan Hayward - David Sherwood - - * brigfrontend/brig-to-generic.cc (get_unsigned_int_type): Handle - polynomial TYPE_VECTOR_SUBPARTS. - * brigfrontend/brig-util.h (gccbrig_type_vector_subparts): Likewise. - -2018-01-03 Jakub Jelinek - - Update copyright years. - -2018-01-03 Richard Sandiford - Alan Hayward - David Sherwood - - * brigfrontend/brig-util.h (gccbrig_type_vector_subparts): New - function. - * brigfrontend/brig-basic-inst-handler.cc - (brig_basic_inst_handler::build_shuffle): Use it instead of - TYPE_VECTOR_SUBPARTS. - (brig_basic_inst_handler::build_unpack): Likewise. - (brig_basic_inst_handler::build_pack): Likewise. - (brig_basic_inst_handler::build_unpack_lo_or_hi): Likewise. - (brig_basic_inst_handler::operator ()): Likewise. - (brig_basic_inst_handler::build_lower_element_broadcast): Likewise. - * brigfrontend/brig-code-entry-handler.cc - (brig_code_entry_handler::get_tree_cst_for_hsa_operand): Likewise. - (brig_code_entry_handler::get_comparison_result_type): Likewise. - (brig_code_entry_handler::expand_or_call_builtin): Likewise. - -2017-12-15 Jakub Jelinek - - * brig-lang.c (brig_attribute_table): Swap affects_type_identity - and handler fields, adjust comments. - -2017-12-08 Jakub Jelinek - - * brig-lang.c (brig_attribute_table): Fix up comment. - -2017-11-28 Jakub Jelinek - - * brigfrontend/brig-branch-inst-handler.cc - (brig_branch_inst_handler::operator): Build SWITCH_EXPR using build2 - instead of build3. - -2017-11-17 Henry Linjamäki - - * brigfrontend/brig-util.cc: Fix sprintf format string type mismatch - on 32b machines. - -2017-11-16 Henry Linjamäki - - Change internal representation of HSA registers. Instead - representing HSA's untyped registers as unsigned int the gccbrig - analyzes brig code and builds the register variables as a type - used in tree expressions at most. This gives better chance to - optimize CONVERT_VIEW_EXPRs away. - * brigfrontend/brig-code-entry-handler.cc: Add analysis method for - register type usage. Handle any-typed register variables. - * brigfrontend/brig-code-entry-handler.h: New declarations for the - above. - * brigfrontend/brig-copy-move-inst-handler.cc: Handle any-typed - register variables. - * brigfrontend/brig-cvt-inst-handler.cc: Likewise. - * brigfrontend/brig-function.cc: Build register variables as a - type based on results of analysis phase. - * brigfrontend/brig-function.h: Move HSA register count defines to - brig-utils.h. - * brigfrontend/brig-to-generic.cc: New analysis handler. Analyze - HSA register usage. - * brigfrontend/brig-to-generic.h: New declarations. - * brigfrontend/brig-util.cc: New utility functions. - * brigfrontend/brig-util.h: New declarations for the above. - -2017-11-16 Pekka Jääskeläinen - - * gccbrig.texi: Added some documentation. - -2017-10-31 Henry Linjamäki - - * brig-lang.c (brig_langhook_type_for_mode): Fix PR 82771. - -2017-10-23 Richard Sandiford - - * brig-lang.c (brig_langhook_type_for_mode): Use scalar_int_mode - and scalar_float_mode. - -2017-10-09 Pekka Jääskeläinen - - * brigfrontend/brig-to-generic.cc: Support BRIG_KIND_NONE - directives. These directives are legal everywhere. They - can be used to patch away BRIG entries at the binary level. - Also add extra error detection for zeroed regions: make sure - the byteCount field is never zero. - * brigfrontend/phsa.h: Added a new error prefix for - errors which are due to corrupted BRIG modules. - -2017-10-09 Henry Linjamäki - - * brigfrontend/brig-branch-inst-handler.cc: The call code - still failed a few test cases. Now all PRM cases pass again. - -2017-10-03 Henry Linjamäki - - * brigfrontend/brig-branch-inst-handler.cc: Fix (more) crash with - calls with more than 4 args. It missed a reference which is required - because vector expansion can move the object to another location. - -2017-09-29 Henry Linjamäki - - * brigfrontend/brig-branch-inst-handler.cc: Fix crash with - calls with more than 4 args. Also fix a misexecution issue - with kernels that have both unexpanded ID functions and - calls to subfunctions. - -2017-09-28 Henry Linjamäki - - * brig-lang.c: Added function attributes and their handlers. - Make BRIGFE 3-level optimize by default. - -2017-09-27 Pekka Jääskeläinen - - * brig-lang.c: Improved support for function and module scope - group segment variables. PRM specs defines function and module - scope group segment variables as an experimental feature. However, - PRM test suite uses and hcc relies on them. In addition, hcc - assumes certain group variable layout in its dynamic group segment - allocation code. We cannot have global group memory offsets if we - want to both have kernel-specific group segment size and multiple - kernels calling the same functions that use function scope group memory - variables. Now group segment is handled by separate book keeping of - module scope and function (kernel) offsets. Each function has a "frame" - in the group segment offset to which is given as an argument. - * brigfrontend/brig-branch-inst-handler.cc: See above. - * brigfrontend/brig-code-entry-handler.cc: See above. - * brigfrontend/brig-fbarrier-handler.cc: See above. - * brigfrontend/brig-function-handler.cc: See above. - * brigfrontend/brig-function.cc: See above. - * brigfrontend/brig-function.h: See above. - * brigfrontend/brig-to-generic.cc: See above. - * brigfrontend/brig-to-generic.h: See above. - * brigfrontend/brig-util.cc: See above. - * brigfrontend/brig-util.h: See above. - * brigfrontend/brig-variable-handler.cc: See above. - -2017-09-25 Pekka Jääskeläinen - - * brigfrontend/brig-to-generic.cc: Ensure per WI copies of - private variables are aligned too. - -2017-09-17 Thomas Schwinge - - * Make-lang.in (GO_TEXI_FILES): Rename to... - (BRIG_TEXI_FILES): ... this. - (doc/gccbrig.info, doc/gccbrig.dvi, doc/gccbrig.pdf, brig.info) - (brig.srcinfo, brig.man, brig.srcman, brig.install-man) - ($(DESTDIR)$(man1dir)/$(GCCBRIG_INSTALL_NAME)$(man1ext)): - Uncomment/enable targets. - (gccbrig.pod): New target. - * gccbrig.texi: New file. - -2017-08-04 Henry Linjamäki - - Fix PR 81713 - * brigfrontend/brig-basic-inst-handler.cc: replace build_int_cst with - bitsize_int in building BIT_FIELD_REF. - * brigfrontend/brig-code-entry-handler.cc: likewise. - -2017-07-05 Richard Sandiford - Alan Hayward - David Sherwood - - * brig-c.h (brig_type_for_mode): Remove "enum" before "machine_mode". - * brig-lang.c (brig_langhook_type_for_mode): Likewise. - -2017-07-04 Jakub Jelinek - - * brigfrontend/brig-function.cc: Include profile-count.h. - * brigfrontend/brig-to-generic.cc: Likewise. - -2017-05-18 Thomas Schwinge - - * brigfrontend/brig-to-generic.h (class brig_to_generic): Use - "dump_flags_t" for "m_dump_flags" member. - -2017-05-13 Pekka Jääskeläinen - - * brigfrontend/brig-code-entry-handler.cc - (brig_code_entry_handler::build_address_operand): Fix - an assertion when doing an 'lda' of a private array - offset. - -2017-05-03 Pekka Jääskeläinen - - * brigfrontend/brig-code-entry-handler.cc - (brig_code_entry_handler::build_address_operand): Fix a bug - with reg+offset addressing on 32b segments. In large mode, - the offset is treated as 32bits unless it's global, readonly or - kernarg address space. - -2016-02-01 Pekka Jääskeläinen - - * brigfrontend/brig-code-entry-handler.cc: fix address - expressions which refer only to offset 0, but nothing else. - * brigfrontend/brig-lane-inst-handler.cc: fix - activelanepermute_b64 HSAIL instruction. - * brigfrontend/brig-to-generic.cc: remove useless c_str() - call. Add missing va_end (). Fix PR79250. - -2017-01-30 Jakub Jelinek - - * brigfrontend/brig-code-entry-handler.cc - (brig_code_entry_handler::get_tree_cst_for_hsa_operand): For %lu - cast size_t arguments to unsigned long. - -2017-01-27 Pekka Jääskeläinen - - * config-lang.in: Removed stale target-libbrig reference. - -2017-01-26 Jakub Jelinek - - Update copyright years. - -2017-01-24 Pekka Jääskeläinen - Martin Jambor - - * Make-lang.in: New file. - * brig-builtins.h: Likewise. - * brig-c.h: Likewise. - * brig-lang.c: Likewise. - * brigspec.c: Likewise. - * config-lang.in: Likewise. - * lang-specs.h: Likewise. - * lang.opt: Likewise. - * brigfrontend/brig-arg-block-handler.cc: Likewise. - * brigfrontend/brig-atomic-inst-handler.cc: Likewise. - * brigfrontend/brig-basic-inst-handler.cc: Likewise. - * brigfrontend/brig-branch-inst-handler.cc: Likewise. - * brigfrontend/brig-cmp-inst-handler.cc: Likewise. - * brigfrontend/brig-code-entry-handler.cc: Likewise. - * brigfrontend/brig-code-entry-handler.h: Likewise. - * brigfrontend/brig-comment-handler.cc: Likewise. - * brigfrontend/brig-control-handler.cc: Likewise. - * brigfrontend/brig-copy-move-inst-handler.cc: Likewise. - * brigfrontend/brig-cvt-inst-handler.cc: Likewise. - * brigfrontend/brig-fbarrier-handler.cc: Likewise. - * brigfrontend/brig-function-handler.cc: Likewise. - * brigfrontend/brig-function.cc: Likewise. - * brigfrontend/brig-function.h: Likewise. - * brigfrontend/brig-inst-mod-handler.cc: Likewise. - * brigfrontend/brig-label-handler.cc: Likewise. - * brigfrontend/brig-lane-inst-handler.cc: Likewise. - * brigfrontend/brig-machine.c: Likewise. - * brigfrontend/brig-machine.h: Likewise. - * brigfrontend/brig-mem-inst-handler.cc: Likewise. - * brigfrontend/brig-module-handler.cc: Likewise. - * brigfrontend/brig-queue-inst-handler.cc: Likewise. - * brigfrontend/brig-seg-inst-handler.cc: Likewise. - * brigfrontend/brig-signal-inst-handler.cc: Likewise. - * brigfrontend/brig-to-generic.cc: Likewise. - * brigfrontend/brig-to-generic.h: Likewise. - * brigfrontend/brig-util.cc: Likewise. - * brigfrontend/brig-util.h: Likewise. - * brigfrontend/brig-variable-handler.cc: Likewise. - * brigfrontend/phsa.h: Likewise. diff --git a/gcc/brig/Make-lang.in b/gcc/brig/Make-lang.in deleted file mode 100644 index 89370f01c64..00000000000 --- a/gcc/brig/Make-lang.in +++ /dev/null @@ -1,251 +0,0 @@ -# Make-lang.in -- Top level -*- makefile -*- fragment for gcc BRIG (HSAIL) -# frontend. - -# Copyright (C) 2015-2021 Free Software Foundation, Inc. - -# This file is part of GCC. - -# GCC is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. - -# GCC is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with GCC; see the file COPYING3. If not see -# . - -# This file provides the language dependent support in the main Makefile. - -# Installation name. - -GCCBRIG_INSTALL_NAME := $(shell echo gccbrig|sed '$(program_transform_name)') -GCCBRIG_TARGET_INSTALL_NAME := $(target_noncanonical)-$(shell echo gccbrig|sed \ - '$(program_transform_name)') - -# The name for selecting brig in LANGUAGES. -brig: brig1$(exeext) -brig.serial = brig1$(exeext) - -.PHONY: brig - -CFLAGS-brig/brigspec.o += $(DRIVER_DEFINES) - -GCCBRIG_OBJS = $(GCC_OBJS) brig/brigspec.o -gccbrig$(exeext): $(GCCBRIG_OBJS) $(EXTRA_GCC_OBJS) libcommon-target.a \ - $(LIBDEPS) - +$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \ - $(GCCBRIG_OBJS) $(EXTRA_GCC_OBJS) libcommon-target.a \ - $(EXTRA_GCC_LIBS) $(LIBS) - -# The cross-compiler version. This is built mainly as a signal to the -# brig.install-common target. If this executable exists, it means that -# brig.all.cross was run. -gccbrig-cross$(exeext): gccbrig$(exeext) - -rm -f gccbrig-cross$(exeext) - cp gccbrig$(exeext) gccbrig-cross$(exeext) - -# Use strict warnings. -brig-warn = $(STRICT_WARN) - -BRIG_OBJS = \ - brig/brig-lang.o \ - brig/brig-code-entry-handler.o \ - brig/brig-function-handler.o \ - brig/brig-variable-handler.o \ - brig/brig-fbarrier-handler.o \ - brig/brig-label-handler.o \ - brig/brig-comment-handler.o \ - brig/brig-basic-inst-handler.o \ - brig/brig-cvt-inst-handler.o \ - brig/brig-seg-inst-handler.o \ - brig/brig-lane-inst-handler.o \ - brig/brig-queue-inst-handler.o \ - brig/brig-copy-move-inst-handler.o \ - brig/brig-signal-inst-handler.o \ - brig/brig-atomic-inst-handler.o \ - brig/brig-arg-block-handler.o \ - brig/brig-control-handler.o \ - brig/brig-cmp-inst-handler.o \ - brig/brig-branch-inst-handler.o \ - brig/brig-mem-inst-handler.o \ - brig/brig-module-handler.o \ - brig/brig-inst-mod-handler.o \ - brig/brig-function.o \ - brig/brig-to-generic.o \ - brig/brig-machine.o \ - brig/brig-util.o - -brig_OBJS = $(BRIG_OBJS) brig/brigspec.o - -brig1$(exeext): $(BRIG_OBJS) attribs.o $(BACKEND) $(LIBDEPS) $(brig.prev) - @$(call LINK_PROGRESS,$(INDEX.brig),start) - +$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \ - $(BRIG_OBJS) attribs.o $(BACKEND) $(LIBS) \ - $(BACKENDLIBS) - @$(call LINK_PROGRESS,$(INDEX.brig),end) - -# Documentation. - -BRIG_TEXI_FILES = \ - brig/gccbrig.texi \ - $(gcc_docdir)/include/fdl.texi \ - $(gcc_docdir)/include/gpl_v3.texi \ - $(gcc_docdir)/include/gcc-common.texi \ - gcc-vers.texi - -doc/gccbrig.info: $(BRIG_TEXI_FILES) - if test "x$(BUILD_INFO)" = xinfo; then \ - rm -f doc/gccbrig.info*; \ - $(MAKEINFO) $(MAKEINFOFLAGS) -I $(gcc_docdir) \ - -I $(gcc_docdir)/include -o $@ $<; \ - else true; fi - -doc/gccbrig.dvi: $(BRIG_TEXI_FILES) - $(TEXI2DVI) -I $(abs_docdir) -I $(abs_docdir)/include -o $@ $< - -doc/gccbrig.pdf: $(BRIG_TEXI_FILES) - $(TEXI2PDF) -I $(abs_docdir) -I $(abs_docdir)/include -o $@ $< - -$(build_htmldir)/brig/index.html: $(BRIG_TEXI_FILES) - $(mkinstalldirs) $(@D) - rm -f $(@D)/* - $(TEXI2HTML) -I $(gcc_docdir) -I $(gcc_docdir)/include \ - -I $(srcdir)/brig -o $(@D) $< - -.INTERMEDIATE: gccbrig.pod - -gccbrig.pod: brig/gccbrig.texi - -$(TEXI2POD) -D gccbrig < $< > $@ - -# Build hooks. - -brig.all.cross: gccbrig-cross$(exeext) -brig.start.encap: gccbrig$(exeext) -brig.rest.encap: -brig.info: doc/gccbrig.info -brig.dvi: doc/gccbrig.dvi -brig.pdf: doc/gccbrig.pdf -brig.html: $(build_htmldir)/brig/index.html -brig.srcinfo: doc/gccbrig.info - -cp -p $^ $(srcdir)/doc - -brig.srcextra: -brig.tags: force - cd $(srcdir)/brig; \ - etags -o TAGS.sub *.c *.h; \ - etags --include TAGS.sub --include ../TAGS.sub - -brig.man: doc/gccbrig.1 -brig.srcman: doc/gccbrig.1 - -cp -p $^ $(srcdir)/doc - -lang_checks += check-brig - -# No brig-specific selftests -selftest-brig: - -# Install hooks. - -brig.install-common: installdirs - -rm -f $(DESTDIR)$(bindir)/$(GCCBRIG_INSTALL_NAME)$(exeext) - $(INSTALL_PROGRAM) gccbrig$(exeext) \ - $(DESTDIR)$(bindir)/$(GCCBRIG_INSTALL_NAME)$(exeext) - -if test -f brig1$(exeext); then \ - if test -f gccbrig-cross$(exeext); then \ - :; \ - else \ - rm -f $(DESTDIR)$(bindir)/$(GCCBRIG_TARGET_INSTALL_NAME)$(exeext); \ - ( cd $(DESTDIR)$(bindir) && \ - $(LN) $(GCCBRIG_INSTALL_NAME)$(exeext) \ - $(GCCBRIG_TARGET_INSTALL_NAME)$(exeext) ); \ - fi; \ - fi - -brig.install-plugin: - -brig.install-info: #$(DESTDIR)$(infodir)/gccbrig.info - -brig.install-pdf: doc/gccbrig.pdf - @$(NORMAL_INSTALL) - test -z "$(pdfdir)" || $(mkinstalldirs) "$(DESTDIR)$(pdfdir)/gcc" - @for p in doc/gccbrig.pdf; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - f=$(pdf__strip_dir) \ - echo " $(INSTALL_DATA) '$$d$$p' '$(DESTDIR)$(pdfdir)/gcc/$$f'"; \ - $(INSTALL_DATA) "$$d$$p" "$(DESTDIR)$(pdfdir)/gcc/$$f"; \ - done - -brig.install-html: $(build_htmldir)/brig - @$(NORMAL_INSTALL) - test -z "$(htmldir)" || $(mkinstalldirs) "$(DESTDIR)$(htmldir)" - @for p in $(build_htmldir)/brig; do \ - if test -f "$$p" || test -d "$$p"; then d=""; else d="$(srcdir)/"; \ - fi; \ - f=$(html__strip_dir) \ - if test -d "$$d$$p"; then \ - echo " $(mkinstalldirs) '$(DESTDIR)$(htmldir)/$$f'"; \ - $(mkinstalldirs) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \ - echo " $(INSTALL_DATA) '$$d$$p'/* '$(DESTDIR)$(htmldir)/$$f'"; \ - $(INSTALL_DATA) "$$d$$p"/* "$(DESTDIR)$(htmldir)/$$f"; \ - else \ - echo " $(INSTALL_DATA) '$$d$$p' '$(DESTDIR)$(htmldir)/$$f'"; \ - $(INSTALL_DATA) "$$d$$p" "$(DESTDIR)$(htmldir)/$$f"; \ - fi; \ - done - -brig.install-man: $(DESTDIR)$(man1dir)/$(GCCBRIG_INSTALL_NAME)$(man1ext) - -$(DESTDIR)$(man1dir)/$(GCCBRIG_INSTALL_NAME)$(man1ext): doc/gccbrig.1 \ - installdirs - -rm -f $@ - -$(INSTALL_DATA) $< $@ - -chmod a-x $@ - -brig.uninstall: - rm -rf $(DESTDIR)$(bindir)/$(GCCBRIG_INSTALL_NAME)$(exeext) - rm -rf $(DESTDIR)$(man1dir)/$(GCCBRIG_INSTALL_NAME)$(man1ext) - rm -rf $(DESTDIR)$(bindir)/$(GCCBRIG_TARGET_INSTALL_NAME)$(exeext) - rm -rf $(DESTDIR)$(infodir)/gccbrig.info* - -# Clean hooks. - -brig.mostlyclean: - -rm -f brig/*$(objext) - -rm -f brig/*$(coverageexts) -brig.clean: -brig.distclean: -brig.maintainer-clean: - -rm -f $(docobjdir)/gccbrig.1 - -# Stage hooks. - -brig.stage1: stage1-start - -mv brig/*$(objext) stage1/brig -brig.stage2: stage2-start - -mv brig/*$(objext) stage2/brig -brig.stage3: stage3-start - -mv brig/*$(objext) stage3/brig -brig.stage4: stage4-start - -mv brig/*$(objext) stage4/brig -brig.stageprofile: stageprofile-start - -mv brig/*$(objext) stageprofile/brig -brig.stagefeedback: stagefeedback-start - -mv brig/*$(objext) stagefeedback/brig - -CFLAGS-brig/brig-lang.o += -DDEFAULT_TARGET_VERSION=\"$(version)\" \ - -DDEFAULT_TARGET_MACHINE=\"$(target_noncanonical)\" - -BRIGINCLUDES = -I $(srcdir)/brig -I $(srcdir)/brig/brigfrontend - -brig/brig-machine.o: brig/brigfrontend/brig-machine.c - $(COMPILE) $(BRIGINCLUDES) $< - $(POSTCOMPILE) - -brig/%.o: brig/brigfrontend/%.cc - $(COMPILE) $(BRIGINCLUDES) $< - $(POSTCOMPILE) diff --git a/gcc/brig/brig-builtins.h b/gcc/brig/brig-builtins.h deleted file mode 100644 index c891cf191fa..00000000000 --- a/gcc/brig/brig-builtins.h +++ /dev/null @@ -1,99 +0,0 @@ -/* brig-builtins.h -- brig builtin definitions - Copyright (C) 2016-2021 Free Software Foundation, Inc. - - Contributed by Pekka Jaaskelainen - for General Processor Tech. - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3, or (at your option) any later - version. - - GCC is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - . */ - -enum built_in_attribute -{ -#define DEF_ATTR_NULL_TREE(ENUM) ENUM, -#define DEF_ATTR_INT(ENUM, VALUE) ENUM, -#define DEF_ATTR_STRING(ENUM, VALUE) ENUM, -#define DEF_ATTR_IDENT(ENUM, STRING) ENUM, -#define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) ENUM, -#include "builtin-attrs.def" -#undef DEF_ATTR_NULL_TREE -#undef DEF_ATTR_INT -#undef DEF_ATTR_STRING -#undef DEF_ATTR_IDENT -#undef DEF_ATTR_TREE_LIST - ATTR_LAST -}; - -/* Builtin types. */ - -enum brig_builtin_type -{ -#define DEF_PRIMITIVE_TYPE(NAME, VALUE) NAME, -#define DEF_FUNCTION_TYPE_0(NAME, RETURN) NAME, -#define DEF_FUNCTION_TYPE_1(NAME, RETURN, ARG1) NAME, -#define DEF_FUNCTION_TYPE_2(NAME, RETURN, ARG1, ARG2) NAME, -#define DEF_FUNCTION_TYPE_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME, -#define DEF_FUNCTION_TYPE_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME, -#define DEF_FUNCTION_TYPE_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) NAME, -#define DEF_FUNCTION_TYPE_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ - ARG6) NAME, -#define DEF_FUNCTION_TYPE_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ - ARG6, ARG7) NAME, -#define DEF_FUNCTION_TYPE_8(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ - ARG6, ARG7, ARG8) NAME, -#define DEF_FUNCTION_TYPE_9(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ - ARG6, ARG7, ARG8, ARG9) NAME, -#define DEF_FUNCTION_TYPE_10(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ - ARG6, ARG7, ARG8, ARG9, ARG10) NAME, -#define DEF_FUNCTION_TYPE_11(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ - ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) NAME, -#define DEF_FUNCTION_TYPE_VAR_0(NAME, RETURN) NAME, -#define DEF_FUNCTION_TYPE_VAR_1(NAME, RETURN, ARG1) NAME, -#define DEF_FUNCTION_TYPE_VAR_2(NAME, RETURN, ARG1, ARG2) NAME, -#define DEF_FUNCTION_TYPE_VAR_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME, -#define DEF_FUNCTION_TYPE_VAR_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME, -#define DEF_FUNCTION_TYPE_VAR_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG6) \ - NAME, -#define DEF_FUNCTION_TYPE_VAR_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ - ARG6) NAME, -#define DEF_FUNCTION_TYPE_VAR_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ - ARG6, ARG7) NAME, -#define DEF_POINTER_TYPE(NAME, TYPE) NAME, -#include "builtin-types.def" -#undef DEF_PRIMITIVE_TYPE -#undef DEF_FUNCTION_TYPE_0 -#undef DEF_FUNCTION_TYPE_1 -#undef DEF_FUNCTION_TYPE_2 -#undef DEF_FUNCTION_TYPE_3 -#undef DEF_FUNCTION_TYPE_4 -#undef DEF_FUNCTION_TYPE_5 -#undef DEF_FUNCTION_TYPE_6 -#undef DEF_FUNCTION_TYPE_7 -#undef DEF_FUNCTION_TYPE_8 -#undef DEF_FUNCTION_TYPE_9 -#undef DEF_FUNCTION_TYPE_10 -#undef DEF_FUNCTION_TYPE_11 -#undef DEF_FUNCTION_TYPE_VAR_0 -#undef DEF_FUNCTION_TYPE_VAR_1 -#undef DEF_FUNCTION_TYPE_VAR_2 -#undef DEF_FUNCTION_TYPE_VAR_3 -#undef DEF_FUNCTION_TYPE_VAR_4 -#undef DEF_FUNCTION_TYPE_VAR_5 -#undef DEF_FUNCTION_TYPE_VAR_6 -#undef DEF_FUNCTION_TYPE_VAR_7 -#undef DEF_POINTER_TYPE - BT_LAST -}; - -typedef enum brig_builtin_type builtin_type; diff --git a/gcc/brig/brig-c.h b/gcc/brig/brig-c.h deleted file mode 100644 index 9defcea0933..00000000000 --- a/gcc/brig/brig-c.h +++ /dev/null @@ -1,66 +0,0 @@ -/* brig-c.h -- Header file for brig input's gcc C interface. - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ - -#ifndef BRIG_BRIG_C_H -#define BRIG_BRIG_C_H - -#define BRIG_EXTERN_C - -#include "machmode.h" - -/* Functions defined in the Brig frontend proper called by the GCC - interface. */ - -extern int brig_enable_dump (const char *); -extern int brig_enable_optimize (const char *); - -extern void brig_add_search_path (const char *); - -extern void brig_create_brigbrig (int int_type_size, int pointer_size, - const char *pkgpath, const char *prefix, - const char *relative_import_path); - -extern void brig_parse_input_files (const char **, unsigned int, - bool only_check_syntax, - bool require_return_statement); -extern void brig_write_globals (void); - -extern tree brig_type_for_size (unsigned int bits, int unsignedp); -extern tree brig_type_for_mode (machine_mode, int unsignedp); - -/* Functions defined in the GCC interface called by the Brig frontend - proper. */ - -extern void brig_preserve_from_gc (tree); - -extern const char *brig_localize_identifier (const char *); - -extern unsigned int brig_field_alignment (tree); - -extern void brig_trampoline_info (unsigned int *size, unsigned int *alignment); - -extern void brig_imported_unsafe (void); - -extern void brig_write_export_data (const char *, unsigned int); - -extern const char *brig_read_export_data (int, off_t, char **, size_t *, int *); - -#endif /* !defined (BRIG_BRIG_C_H) */ diff --git a/gcc/brig/brig-lang.c b/gcc/brig/brig-lang.c deleted file mode 100644 index af903fe3ab7..00000000000 --- a/gcc/brig/brig-lang.c +++ /dev/null @@ -1,958 +0,0 @@ -/* brig-lang.c -- brig (HSAIL) input gcc interface. - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ - -#include "config.h" -#include "system.h" -#include "ansidecl.h" -#include "coretypes.h" -#include "opts.h" -#include "tree.h" -#include "tree-iterator.h" -#include "print-tree.h" -#include "stringpool.h" -#include "basic-block.h" -#include "gimple-expr.h" -#include "gimplify.h" -#include "dumpfile.h" -#include "stor-layout.h" -#include "toplev.h" -#include "debug.h" -#include "options.h" -#include "flags.h" -#include "convert.h" -#include "diagnostic.h" -#include "langhooks.h" -#include "langhooks-def.h" -#include "target.h" -#include "vec.h" -#include "brigfrontend/brig-to-generic.h" -#include "machmode.h" -#include "fold-const.h" -#include "common/common-target.h" -#include -#include "brig-c.h" -#include "brig-builtins.h" - -static tree handle_leaf_attribute (tree *, tree, tree, int, bool *); -static tree handle_const_attribute (tree *, tree, tree, int, bool *); -static tree handle_pure_attribute (tree *, tree, tree, int, bool *); -static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *); -static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *); - -/* This file is based on Go frontend's go-lang.c and gogo-tree.cc. */ - -/* If -v set. */ - -int gccbrig_verbose = 0; - -/* Language-dependent contents of a type. */ - -struct GTY (()) lang_type -{ - char dummy; -}; - -/* Language-dependent contents of a decl. */ - -struct GTY ((variable_size)) lang_decl -{ - char dummy; -}; - -/* Language-dependent contents of an identifier. This must include a - tree_identifier. */ - -struct GTY (()) lang_identifier -{ - struct tree_identifier common; -}; - -/* The resulting tree type. */ - -union GTY ((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"), - chain_next ("CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), " - "TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN " - "(&%h.generic)) : NULL"))) lang_tree_node -{ - union tree_node GTY ((tag ("0"), desc ("tree_node_structure (&%h)"))) generic; - struct lang_identifier GTY ((tag ("1"))) identifier; -}; - -/* We don't use language_function. */ - -struct GTY (()) language_function -{ - int dummy; -}; - - -/* The option mask. */ - -static unsigned int -brig_langhook_option_lang_mask (void) -{ - return CL_BRIG; -} - -/* Initialize the options structure. */ - -static void -brig_langhook_init_options_struct (struct gcc_options *opts) -{ - /* Signed overflow is precisely defined. */ - opts->x_flag_wrapv = 1; - - /* If we set this to one, the whole program optimizations internalize - all global variables, making them invisible to the dyn loader (and - thus the HSA runtime implementation). */ - opts->x_flag_whole_program = 1; - - /* The builtin math functions should not set errno. */ - opts->x_flag_errno_math = 0; - opts->frontend_set_flag_errno_math = false; - - opts->x_flag_exceptions = 0; - opts->x_flag_non_call_exceptions = 0; - - opts->x_flag_finite_math_only = 0; - opts->x_flag_signed_zeros = 1; - - opts->x_optimize = 3; - - flag_no_builtin = 1; -} - -/* Handle Brig specific options. Return 0 if we didn't do anything. */ - -static bool -brig_langhook_handle_option - (size_t scode, const char *arg ATTRIBUTE_UNUSED, - HOST_WIDE_INT value ATTRIBUTE_UNUSED, int kind ATTRIBUTE_UNUSED, - location_t loc ATTRIBUTE_UNUSED, - const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED) -{ - enum opt_code code = (enum opt_code) scode; - switch (code) - { - case OPT_v: - gccbrig_verbose = 1; - break; - default: - break; - } - return 1; -} - -/* Run after parsing options. */ - -static bool -brig_langhook_post_options (const char **pfilename ATTRIBUTE_UNUSED) -{ - if (flag_excess_precision == EXCESS_PRECISION_DEFAULT) - flag_excess_precision = EXCESS_PRECISION_STANDARD; - - /* gccbrig casts pointers around like crazy, TBAA might produce broken - code if not disabling it by default. Some PRM conformance tests such - as prm/core/memory/ordinary/ld/ld_u16 fail currently with strict - aliasing (to fix). It can be enabled from the command line for cases - that are known not to break the C style aliasing requirements. */ - if (!global_options_set.x_flag_strict_aliasing) - flag_strict_aliasing = 0; - else - flag_strict_aliasing = global_options.x_flag_strict_aliasing; - - /* Returning false means that the backend should be used. */ - return false; -} - -static size_t -get_file_size (FILE *file) -{ - size_t size; - fseek (file, 0, SEEK_END); - size = (size_t) ftell (file); - fseek (file, 0, SEEK_SET); - return size; -} - -static void -brig_langhook_parse_file (void) -{ - brig_to_generic brig_to_gen; - - std::vector brig_blobs; - - for (unsigned int i = 0; i < num_in_fnames; ++i) - { - - FILE *f; - f = fopen (in_fnames[i], "r"); - size_t fsize = get_file_size (f); - char *brig_blob = new char[fsize]; - if (fread (brig_blob, 1, fsize, f) != fsize) - { - error ("could not read the BRIG file"); - exit (1); - } - fclose (f); - - brig_to_gen.analyze (brig_blob); - brig_blobs.push_back (brig_blob); - } - - for (size_t i = 0; i < brig_blobs.size(); ++i) - { - char *brig_blob = brig_blobs.at(i); - brig_to_gen.parse (brig_blob); - } - - brig_to_gen.write_globals (); - - for (size_t i = 0; i < brig_blobs.size (); ++i) - delete brig_blobs[i]; -} - -static tree -brig_langhook_type_for_size (unsigned int bits, - int unsignedp) -{ - /* Copied from go-lang.c */ - tree type; - if (unsignedp) - { - if (bits == INT_TYPE_SIZE) - type = unsigned_type_node; - else if (bits == CHAR_TYPE_SIZE) - type = unsigned_char_type_node; - else if (bits == SHORT_TYPE_SIZE) - type = short_unsigned_type_node; - else if (bits == LONG_TYPE_SIZE) - type = long_unsigned_type_node; - else if (bits == LONG_LONG_TYPE_SIZE) - type = long_long_unsigned_type_node; - else - type = make_unsigned_type(bits); - } - else - { - if (bits == INT_TYPE_SIZE) - type = integer_type_node; - else if (bits == CHAR_TYPE_SIZE) - type = signed_char_type_node; - else if (bits == SHORT_TYPE_SIZE) - type = short_integer_type_node; - else if (bits == LONG_TYPE_SIZE) - type = long_integer_type_node; - else if (bits == LONG_LONG_TYPE_SIZE) - type = long_long_integer_type_node; - else - type = make_signed_type(bits); - } - return type; -} - -static tree -brig_langhook_type_for_mode (machine_mode mode, int unsignedp) -{ - if (mode == TYPE_MODE (void_type_node)) - return void_type_node; - - if (VECTOR_MODE_P (mode)) - { - tree inner; - - inner = brig_langhook_type_for_mode (GET_MODE_INNER (mode), unsignedp); - if (inner != NULL_TREE) - return build_vector_type_for_mode (inner, mode); - gcc_unreachable (); - return NULL_TREE; - } - - scalar_int_mode imode; - scalar_float_mode fmode; - if (is_float_mode (mode, &fmode)) - { - switch (GET_MODE_BITSIZE (fmode)) - { - case 32: - return float_type_node; - case 64: - return double_type_node; - default: - /* We have to check for long double in order to support - i386 excess precision. */ - if (fmode == TYPE_MODE (long_double_type_node)) - return long_double_type_node; - - gcc_unreachable (); - return NULL_TREE; - } - } - else if (is_int_mode (mode, &imode)) - return brig_langhook_type_for_size (GET_MODE_BITSIZE (imode), unsignedp); - else - { - /* E.g., build_common_builtin_nodes () asks for modes/builtins - we do not generate or need. Just ignore them silently for now. - */ - return NULL_TREE; - } - return NULL_TREE; -} - -static tree -brig_langhook_builtin_function (tree decl) -{ - return decl; -} - -static GTY(()) tree registered_builtin_types; - -static void -brig_langhook_register_builtin_type (tree type, const char *name) -{ - tree decl; - - if (!TYPE_NAME (type)) - { - decl = build_decl (UNKNOWN_LOCATION, TYPE_DECL, - get_identifier (name), type); - DECL_ARTIFICIAL (decl) = 1; - TYPE_NAME (type) = decl; - } - - registered_builtin_types = tree_cons (0, type, registered_builtin_types); -} - - -/* Return true if we are in the global binding level. */ - -static bool -brig_langhook_global_bindings_p (void) -{ - return current_function_decl == NULL_TREE; -} - -/* Push a declaration into the current binding level. From Go: We can't - usefully implement this since we don't want to convert from tree - back to one of our internal data structures. I think the only way - this is used is to record a decl which is to be returned by - getdecls, and we could implement it for that purpose if - necessary. */ - -static tree -brig_langhook_pushdecl (tree decl ATTRIBUTE_UNUSED) -{ - gcc_unreachable (); -} - -/* This hook is used to get the current list of declarations as trees. - From Go: We don't support that; instead we use the write_globals hook. - This can't simply crash because it is called by -gstabs. */ - -static tree -brig_langhook_getdecls (void) -{ - return NULL; -} - -static int -brig_langhook_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED, - gimple_seq *post_p ATTRIBUTE_UNUSED) -{ - - /* Strip off the static chain info that appears to function - calls for some strange reason even though we don't add - nested functions. Maybe something wrong with the function - declaration contexts? */ - if (TREE_CODE (*expr_p) == CALL_EXPR - && CALL_EXPR_STATIC_CHAIN (*expr_p) != NULL_TREE) - CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL_TREE; - return GS_UNHANDLED; -} - -static tree -brig_langhook_eh_personality (void) -{ - gcc_unreachable (); -} - -/* Functions called directly by the generic backend. - Adapted from go-lang.c. */ - -tree -convert (tree type, tree expr) -{ - if (type == error_mark_node || expr == error_mark_node - || TREE_TYPE (expr) == error_mark_node) - return error_mark_node; - - if (type == TREE_TYPE (expr)) - return expr; - - if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr))) - return fold_convert (type, expr); - - switch (TREE_CODE (type)) - { - case VOID_TYPE: - case BOOLEAN_TYPE: - return fold_convert (type, expr); - case INTEGER_TYPE: - return fold (convert_to_integer (type, expr)); - case REAL_TYPE: - return fold (convert_to_real (type, expr)); - case VECTOR_TYPE: - return fold (convert_to_vector (type, expr)); - case POINTER_TYPE: - return build1 (VIEW_CONVERT_EXPR, type, convert (size_type_node, expr)); - default: - break; - } - - gcc_unreachable (); -} - -static GTY (()) tree brig_gc_root; - -/* Preserve trees that we create from the garbage collector. */ - -void -brig_preserve_from_gc (tree t) -{ - brig_gc_root = tree_cons (NULL_TREE, t, brig_gc_root); -} - -/* Convert an identifier for use in an error message. */ - -const char * -brig_localize_identifier (const char *ident) -{ - return identifier_to_locale (ident); -} - -/* Define supported attributes and their handlers. Code copied from - lto-lang.c */ - -/* Table of machine-independent attributes supported in GIMPLE. */ -const struct attribute_spec brig_attribute_table[] = -{ - /* { name, min_len, max_len, decl_req, type_req, fn_type_req, - affects_type_identity, handler, exclude } */ - { "leaf", 0, 0, true, false, false, false, - handle_leaf_attribute, NULL }, - { "const", 0, 0, true, false, false, false, - handle_const_attribute, NULL }, - { "pure", 0, 0, true, false, false, false, - handle_pure_attribute, NULL }, - { "nothrow", 0, 0, true, false, false, false, - handle_nothrow_attribute, NULL }, - { "returns_twice", 0, 0, true, false, false, false, - handle_returns_twice_attribute, NULL }, - { NULL, 0, 0, false, false, false, false, NULL, NULL } -}; - -/* Attribute handlers. */ -/* Handle a "leaf" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_leaf_attribute (tree *node, tree name, - tree ARG_UNUSED (args), - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - if (TREE_CODE (*node) != FUNCTION_DECL) - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - if (!TREE_PUBLIC (*node)) - { - warning (OPT_Wattributes, - "%qE attribute has no effect on unit local functions", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle a "const" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_const_attribute (tree *node, tree ARG_UNUSED (name), - tree ARG_UNUSED (args), int ARG_UNUSED (flags), - bool * ARG_UNUSED (no_add_attrs)) -{ - tree type = TREE_TYPE (*node); - - /* See FIXME comment on noreturn in c_common_attribute_table. */ - if (TREE_CODE (*node) == FUNCTION_DECL) - TREE_READONLY (*node) = 1; - else if (TREE_CODE (type) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE) - TREE_TYPE (*node) - = build_pointer_type - (build_type_variant (TREE_TYPE (type), 1, - TREE_THIS_VOLATILE (TREE_TYPE (type)))); - else - gcc_unreachable (); - - return NULL_TREE; -} - -/* Handle a "pure" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_pure_attribute (tree *node, tree ARG_UNUSED (name), - tree ARG_UNUSED (args), int ARG_UNUSED (flags), - bool * ARG_UNUSED (no_add_attrs)) -{ - if (TREE_CODE (*node) == FUNCTION_DECL) - DECL_PURE_P (*node) = 1; - else - gcc_unreachable (); - - return NULL_TREE; -} - -/* Handle a "nothrow" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_nothrow_attribute (tree *node, tree ARG_UNUSED (name), - tree ARG_UNUSED (args), int ARG_UNUSED (flags), - bool * ARG_UNUSED (no_add_attrs)) -{ - if (TREE_CODE (*node) == FUNCTION_DECL) - TREE_NOTHROW (*node) = 1; - else - gcc_unreachable (); - - return NULL_TREE; -} - -/* Handle a "returns_twice" attribute. */ - -static tree -handle_returns_twice_attribute (tree *node, tree ARG_UNUSED (name), - tree ARG_UNUSED (args), - int ARG_UNUSED (flags), - bool * ARG_UNUSED (no_add_attrs)) -{ - gcc_assert (TREE_CODE (*node) == FUNCTION_DECL); - - DECL_IS_RETURNS_TWICE (*node) = 1; - - return NULL_TREE; -} - - -/* Built-in initialization code cribbed from lto-lang.c which cribbed it - from c-common.c. */ - - -static GTY(()) tree built_in_attributes[(int) ATTR_LAST]; - - -static GTY(()) tree builtin_types[(int) BT_LAST + 1]; - -static GTY(()) tree string_type_node; -static GTY(()) tree const_string_type_node; -static GTY(()) tree wint_type_node; -static GTY(()) tree intmax_type_node; -static GTY(()) tree uintmax_type_node; -static GTY(()) tree signed_size_type_node; - -/* Flags needed to process builtins.def. */ -int flag_isoc94; -int flag_isoc99; -int flag_isoc11; -int flag_isoc2x; - -static void -def_fn_type (builtin_type def, builtin_type ret, bool var, int n, ...) -{ - tree t; - tree *args = XALLOCAVEC (tree, n); - va_list list; - int i; - bool err = false; - - va_start (list, n); - for (i = 0; i < n; ++i) - { - builtin_type a = (builtin_type) va_arg (list, int); - t = builtin_types[a]; - if (t == error_mark_node) - err = true; - args[i] = t; - } - va_end (list); - - t = builtin_types[ret]; - if (err) - t = error_mark_node; - if (t == error_mark_node) - ; - else if (var) - t = build_varargs_function_type_array (t, n, args); - else - t = build_function_type_array (t, n, args); - - builtin_types[def] = t; -} - -/* Used to help initialize the builtin-types.def table. When a type of - the correct size doesn't exist, use error_mark_node instead of NULL. - The later results in segfaults even when a decl using the type doesn't - get invoked. */ - -static tree -builtin_type_for_size (int size, bool unsignedp) -{ - tree type = brig_langhook_type_for_size (size, unsignedp); - return type ? type : error_mark_node; -} - -/* Support for DEF_BUILTIN. */ - -static void -def_builtin_1 (enum built_in_function fncode, const char *name, - enum built_in_class fnclass ATTRIBUTE_UNUSED, - tree fntype, tree libtype ATTRIBUTE_UNUSED, - bool both_p ATTRIBUTE_UNUSED, bool fallback_p, - bool nonansi_p ATTRIBUTE_UNUSED, tree fnattrs, - bool implicit_p) -{ - tree decl; - const char *libname; - - if (fntype == error_mark_node) - return; - - libname = name + strlen ("__builtin_"); - decl = add_builtin_function (name, fntype, fncode, fnclass, - (fallback_p ? libname : NULL), - fnattrs); - - set_builtin_decl (fncode, decl, implicit_p); -} - - -/* Initialize the attribute table for all the supported builtins. */ - -static void -brig_init_attributes (void) -{ - /* Fill in the built_in_attributes array. */ -#define DEF_ATTR_NULL_TREE(ENUM) \ - built_in_attributes[(int) ENUM] = NULL_TREE; -#define DEF_ATTR_INT(ENUM, VALUE) \ - built_in_attributes[(int) ENUM] = build_int_cst (NULL_TREE, VALUE); -#define DEF_ATTR_STRING(ENUM, VALUE) \ - built_in_attributes[(int) ENUM] = build_string (strlen (VALUE), VALUE); -#define DEF_ATTR_IDENT(ENUM, STRING) \ - built_in_attributes[(int) ENUM] = get_identifier (STRING); -#define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) \ - built_in_attributes[(int) ENUM] \ - = tree_cons (built_in_attributes[(int) PURPOSE], \ - built_in_attributes[(int) VALUE], \ - built_in_attributes[(int) CHAIN]); -#include "builtin-attrs.def" -#undef DEF_ATTR_NULL_TREE -#undef DEF_ATTR_INT -#undef DEF_ATTR_STRING -#undef DEF_ATTR_IDENT -#undef DEF_ATTR_TREE_LIST -} - -/* Create builtin types and functions. VA_LIST_REF_TYPE_NODE and - VA_LIST_ARG_TYPE_NODE are used in builtin-types.def. */ - -static void -brig_define_builtins (tree va_list_ref_type_node ATTRIBUTE_UNUSED, - tree va_list_arg_type_node ATTRIBUTE_UNUSED) -{ -#define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \ - builtin_types[ENUM] = VALUE; -#define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \ - def_fn_type (ENUM, RETURN, 0, 0); -#define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \ - def_fn_type (ENUM, RETURN, 0, 1, ARG1); -#define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \ - def_fn_type (ENUM, RETURN, 0, 2, ARG1, ARG2); -#define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \ - def_fn_type (ENUM, RETURN, 0, 3, ARG1, ARG2, ARG3); -#define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \ - def_fn_type (ENUM, RETURN, 0, 4, ARG1, ARG2, ARG3, ARG4); -#define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \ - def_fn_type (ENUM, RETURN, 0, 5, ARG1, ARG2, ARG3, ARG4, ARG5); -#define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ - ARG6) \ - def_fn_type (ENUM, RETURN, 0, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); -#define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ - ARG6, ARG7) \ - def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); -#define DEF_FUNCTION_TYPE_8(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ - ARG6, ARG7, ARG8) \ - def_fn_type (ENUM, RETURN, 0, 8, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \ - ARG7, ARG8); -#define DEF_FUNCTION_TYPE_9(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ - ARG6, ARG7, ARG8, ARG9) \ - def_fn_type (ENUM, RETURN, 0, 9, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \ - ARG7, ARG8, ARG9); -#define DEF_FUNCTION_TYPE_10(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ - ARG6, ARG7, ARG8, ARG9, ARG10) \ - def_fn_type (ENUM, RETURN, 0, 10, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \ - ARG7, ARG8, ARG9, ARG10); -#define DEF_FUNCTION_TYPE_11(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ - ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) \ - def_fn_type (ENUM, RETURN, 0, 11, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \ - ARG7, ARG8, ARG9, ARG10, ARG11); -#define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \ - def_fn_type (ENUM, RETURN, 1, 0); -#define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \ - def_fn_type (ENUM, RETURN, 1, 1, ARG1); -#define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \ - def_fn_type (ENUM, RETURN, 1, 2, ARG1, ARG2); -#define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \ - def_fn_type (ENUM, RETURN, 1, 3, ARG1, ARG2, ARG3); -#define DEF_FUNCTION_TYPE_VAR_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \ - def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4); -#define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \ - def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5); -#define DEF_FUNCTION_TYPE_VAR_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ - ARG6) \ - def_fn_type (ENUM, RETURN, 1, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); -#define DEF_FUNCTION_TYPE_VAR_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ - ARG6, ARG7) \ - def_fn_type (ENUM, RETURN, 1, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); -#define DEF_POINTER_TYPE(ENUM, TYPE) \ - builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]); - -#include "builtin-types.def" - -#undef DEF_PRIMITIVE_TYPE -#undef DEF_FUNCTION_TYPE_0 -#undef DEF_FUNCTION_TYPE_1 -#undef DEF_FUNCTION_TYPE_2 -#undef DEF_FUNCTION_TYPE_3 -#undef DEF_FUNCTION_TYPE_4 -#undef DEF_FUNCTION_TYPE_5 -#undef DEF_FUNCTION_TYPE_6 -#undef DEF_FUNCTION_TYPE_7 -#undef DEF_FUNCTION_TYPE_8 -#undef DEF_FUNCTION_TYPE_9 -#undef DEF_FUNCTION_TYPE_10 -#undef DEF_FUNCTION_TYPE_11 -#undef DEF_FUNCTION_TYPE_VAR_0 -#undef DEF_FUNCTION_TYPE_VAR_1 -#undef DEF_FUNCTION_TYPE_VAR_2 -#undef DEF_FUNCTION_TYPE_VAR_3 -#undef DEF_FUNCTION_TYPE_VAR_4 -#undef DEF_FUNCTION_TYPE_VAR_5 -#undef DEF_FUNCTION_TYPE_VAR_6 -#undef DEF_FUNCTION_TYPE_VAR_7 -#undef DEF_POINTER_TYPE - builtin_types[(int) BT_LAST] = NULL_TREE; - - brig_init_attributes (); - -#define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, FALLBACK_P,\ - NONANSI_P, ATTRS, IMPLICIT, COND) \ - if (NAME && COND) \ - def_builtin_1 (ENUM, NAME, CLASS, builtin_types[(int) TYPE], \ - builtin_types[(int) LIBTYPE], BOTH_P, FALLBACK_P, \ - NONANSI_P, built_in_attributes[(int) ATTRS], IMPLICIT); - -#undef DEF_HSAIL_BUILTIN -#define DEF_HSAIL_BUILTIN(ENUM, HSAIL_OPCODE, HSAIL_TYPE, NAME, TYPE, ATTRS) \ - DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ - false, true, true, ATTRS, false, true) - -/* HSAIL atomic builtins do not have separate identifying opcodes. */ - -#undef DEF_HSAIL_ATOMIC_BUILTIN -#define DEF_HSAIL_ATOMIC_BUILTIN(ENUM, ATOMIC_OPCODE, HSAIL_TYPE, NAME, \ - TYPE, ATTRS) \ - DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ - false, true, true, ATTRS, false, true) - -/* HSAIL saturating arithmetics builtins. */ - -#undef DEF_HSAIL_SAT_BUILTIN -#define DEF_HSAIL_SAT_BUILTIN(ENUM, BRIG_OPCODE, HSAIL_TYPE, NAME, \ - TYPE, ATTRS) \ - DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ - false, true, true, ATTRS, false, true) - -/* HSAIL builtins used internally by the frontend. */ - -#undef DEF_HSAIL_INTR_BUILTIN -#define DEF_HSAIL_INTR_BUILTIN(ENUM, NAME, TYPE, ATTRS) \ - DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ - false, true, true, ATTRS, false, true) - -/* HSAIL saturated conversions. */ - -#undef DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN -#define DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN(ENUM, HSAIL_DEST_TYPE, HSAIL_SRC_TYPE, \ - NAME, TYPE, ATTRS) \ - DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ - false, true, true, ATTRS, false, true) - -#include "builtins.def" -} - -/* Build nodes that would have be created by the C front-end; necessary - for including builtin-types.def and ultimately builtins.def. Borrowed - from lto-lang.c. */ - -static void -brig_build_c_type_nodes (void) -{ - gcc_assert (void_type_node); - - void_list_node = build_tree_list (NULL_TREE, void_type_node); - string_type_node = build_pointer_type (char_type_node); - const_string_type_node - = build_pointer_type (build_qualified_type (char_type_node, - TYPE_QUAL_CONST)); - - if (strcmp (SIZE_TYPE, "unsigned int") == 0) - { - intmax_type_node = integer_type_node; - uintmax_type_node = unsigned_type_node; - signed_size_type_node = integer_type_node; - } - else if (strcmp (SIZE_TYPE, "long unsigned int") == 0) - { - intmax_type_node = long_integer_type_node; - uintmax_type_node = long_unsigned_type_node; - signed_size_type_node = long_integer_type_node; - } - else if (strcmp (SIZE_TYPE, "long long unsigned int") == 0) - { - intmax_type_node = long_long_integer_type_node; - uintmax_type_node = long_long_unsigned_type_node; - signed_size_type_node = long_long_integer_type_node; - } - else - { - int i; - - signed_size_type_node = NULL_TREE; - for (i = 0; i < NUM_INT_N_ENTS; i++) - if (int_n_enabled_p[i]) - { - char name[50], altname[50]; - sprintf (name, "__int%d unsigned", int_n_data[i].bitsize); - sprintf (altname, "__int%d__ unsigned", int_n_data[i].bitsize); - - if (strcmp (name, SIZE_TYPE) == 0 - || strcmp (altname, SIZE_TYPE) == 0) - { - intmax_type_node = int_n_trees[i].signed_type; - uintmax_type_node = int_n_trees[i].unsigned_type; - signed_size_type_node = int_n_trees[i].signed_type; - } - } - if (signed_size_type_node == NULL_TREE) - gcc_unreachable (); - } - - wint_type_node = unsigned_type_node; - pid_type_node = integer_type_node; -} - - -static bool -brig_langhook_init (void) -{ - build_common_tree_nodes (false); - - /* Builtin initialization related code borrowed from lto-lang.c. */ - void_list_node = build_tree_list (NULL_TREE, void_type_node); - - brig_build_c_type_nodes (); - - if (TREE_CODE (va_list_type_node) == ARRAY_TYPE) - { - tree x = build_pointer_type (TREE_TYPE (va_list_type_node)); - brig_define_builtins (x, x); - } - else - { - brig_define_builtins (build_reference_type (va_list_type_node), - va_list_type_node); - } - - targetm.init_builtins (); - build_common_builtin_nodes (); - - return true; -} - -#undef LANG_HOOKS_NAME -#undef LANG_HOOKS_INIT -#undef LANG_HOOKS_OPTION_LANG_MASK -#undef LANG_HOOKS_INIT_OPTIONS_STRUCT -#undef LANG_HOOKS_HANDLE_OPTION -#undef LANG_HOOKS_POST_OPTIONS -#undef LANG_HOOKS_PARSE_FILE -#undef LANG_HOOKS_TYPE_FOR_MODE -#undef LANG_HOOKS_TYPE_FOR_SIZE -#undef LANG_HOOKS_REGISTER_BUILTIN_TYPE -#undef LANG_HOOKS_BUILTIN_FUNCTION -#undef LANG_HOOKS_GLOBAL_BINDINGS_P -#undef LANG_HOOKS_PUSHDECL -#undef LANG_HOOKS_GETDECLS -#undef LANG_HOOKS_WRITE_GLOBALS -#undef LANG_HOOKS_GIMPLIFY_EXPR -#undef LANG_HOOKS_EH_PERSONALITY - -#define LANG_HOOKS_NAME "GNU Brig" -#define LANG_HOOKS_INIT brig_langhook_init -#define LANG_HOOKS_OPTION_LANG_MASK brig_langhook_option_lang_mask -#define LANG_HOOKS_INIT_OPTIONS_STRUCT brig_langhook_init_options_struct -#define LANG_HOOKS_HANDLE_OPTION brig_langhook_handle_option -#define LANG_HOOKS_POST_OPTIONS brig_langhook_post_options -#define LANG_HOOKS_PARSE_FILE brig_langhook_parse_file -#define LANG_HOOKS_TYPE_FOR_MODE brig_langhook_type_for_mode -#define LANG_HOOKS_TYPE_FOR_SIZE brig_langhook_type_for_size -#define LANG_HOOKS_REGISTER_BUILTIN_TYPE brig_langhook_register_builtin_type -#define LANG_HOOKS_BUILTIN_FUNCTION brig_langhook_builtin_function -#define LANG_HOOKS_GLOBAL_BINDINGS_P brig_langhook_global_bindings_p -#define LANG_HOOKS_PUSHDECL brig_langhook_pushdecl -#define LANG_HOOKS_GETDECLS brig_langhook_getdecls -#define LANG_HOOKS_GIMPLIFY_EXPR brig_langhook_gimplify_expr -#define LANG_HOOKS_EH_PERSONALITY brig_langhook_eh_personality - -/* Attribute hooks. */ -#undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE -#define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE brig_attribute_table - -struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; - -#include "gt-brig-brig-lang.h" -#include "gtype-brig.h" diff --git a/gcc/brig/brigfrontend/brig-arg-block-handler.cc b/gcc/brig/brigfrontend/brig-arg-block-handler.cc deleted file mode 100644 index 9d5a8e99639..00000000000 --- a/gcc/brig/brigfrontend/brig-arg-block-handler.cc +++ /dev/null @@ -1,66 +0,0 @@ -/* brig-arg-block-handler.cc -- brig arg block start/end directive handling - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3, or (at your option) any later - version. - - GCC is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - . */ - -#include "brig-code-entry-handler.h" -#include "tree-iterator.h" -#include "system.h" -#include "errors.h" - -#include "tree-pretty-print.h" -#include "print-tree.h" - -size_t -brig_directive_arg_block_handler::operator () (const BrigBase *base) -{ - if (base->kind == BRIG_KIND_DIRECTIVE_ARG_BLOCK_START) - { - /* Initiate a new code block for the call site. */ - tree stmt_list = alloc_stmt_list (); - tree bind_expr - = build3 (BIND_EXPR, void_type_node, NULL, stmt_list, NULL); - tree block = make_node (BLOCK); - BIND_EXPR_BLOCK (bind_expr) = block; - static int block_id = 0; - BLOCK_NUMBER (block) = block_id++; - TREE_USED (block) = 1; - tree m_parentblock = DECL_INITIAL (m_parent.m_cf->m_func_decl); - BLOCK_SUPERCONTEXT (block) = m_parentblock; - - chainon (BLOCK_SUBBLOCKS (m_parentblock), block); - - m_parent.m_cf->m_current_bind_expr = bind_expr; - m_parent.m_cf->m_generating_arg_block = true; - } - else if (base->kind == BRIG_KIND_DIRECTIVE_ARG_BLOCK_END) - { - /* Restore the used bind expression back to the function - scope. */ - tree new_bind_expr = m_parent.m_cf->m_current_bind_expr; - m_parent.m_cf->m_current_bind_expr - = DECL_SAVED_TREE (m_parent.m_cf->m_func_decl); - m_parent.m_cf->append_statement (new_bind_expr); - m_parent.m_cf->m_generating_arg_block = false; - } - else - gcc_unreachable (); - - return base->byteCount; -} diff --git a/gcc/brig/brigfrontend/brig-atomic-inst-handler.cc b/gcc/brig/brigfrontend/brig-atomic-inst-handler.cc deleted file mode 100644 index eeef2529758..00000000000 --- a/gcc/brig/brigfrontend/brig-atomic-inst-handler.cc +++ /dev/null @@ -1,265 +0,0 @@ -/* brig-atomic-inst-handler.cc -- brig atomic instruction handling - Copyright (C) 2016-2021 Free Software Foundation, Inc. - - Contributed by Pekka Jaaskelainen - for General Processor Tech. - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3, or (at your option) any later - version. - - GCC is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - . */ - -#include - -#include "brig-code-entry-handler.h" -#include "brig-util.h" -#include "fold-const.h" -#include "diagnostic.h" -#include "tree-pretty-print.h" -#include "print-tree.h" -#include "convert.h" -#include "langhooks.h" -#include "gimple-expr.h" -#include "stringpool.h" -#include "brig-builtins.h" - -brig_atomic_inst_handler::brig_atomic_inst_handler (brig_to_generic &parent) - : brig_code_entry_handler (parent) -{ -} - -size_t -brig_atomic_inst_handler::generate_tree (const BrigInstBase &inst, - BrigAtomicOperation8_t atomic_opcode) -{ - tree_stl_vec operands = build_operands (inst); - const int first_input - = gccbrig_hsa_opcode_op_output_p (inst.opcode, 0) ? 1 : 0; - - tree instr_type = gccbrig_tree_type_for_hsa_type (inst.type); - - /* Utilize the atomic data types (from C++11 support) for implementing - atomic operations. */ - - tree atomic_type = build_qualified_type (instr_type, TYPE_QUAL_ATOMIC); - - gcc_assert (atomic_type != NULL_TREE); - - tree signal_handle = operands[first_input]; - tree atomic_ptype = build_pointer_type (atomic_type); - tree casted_to_ptr = convert_to_pointer (atomic_ptype, signal_handle); - - tree src0 = NULL_TREE; - if (atomic_opcode != BRIG_ATOMIC_LD) - src0 = operands[first_input + 1]; - - tree instr_expr = NULL_TREE; - - tree ptype = build_pointer_type (instr_type); - tree ptr = convert_to_pointer (ptype, operands[first_input]); - - if (atomic_opcode == BRIG_ATOMIC_ST) - { - tree mem_ref = build2 (MEM_REF, atomic_type, casted_to_ptr, - build_int_cst (atomic_ptype, 0)); - instr_expr = build2 (MODIFY_EXPR, atomic_type, mem_ref, src0); - } - else if (atomic_opcode == BRIG_ATOMIC_LD - || (atomic_opcode >= BRIG_ATOMIC_WAIT_EQ - && atomic_opcode <= BRIG_ATOMIC_WAITTIMEOUT_GTE)) - { - tree mem_ref = build2 (MEM_REF, atomic_type, casted_to_ptr, - build_int_cst (atomic_ptype, 0)); - /* signal_wait* instructions can return spuriously before the - condition becomes true. Therefore it's legal to return - right away. TODO: builtin calls which can be - implemented with a power efficient sleep-wait. */ - instr_expr = mem_ref; - } - else if (atomic_opcode == BRIG_ATOMIC_CAS) - { - /* Special case for CAS due to the two args. */ - tree built_in = NULL_TREE; - switch (gccbrig_hsa_type_bit_size (inst.type)) - { - case 32: - built_in - = builtin_decl_explicit (BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_4); - break; - case 64: - built_in - = builtin_decl_explicit (BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_8); - break; - default: - gcc_unreachable (); - } - - tree src1 = operands[first_input + 2]; - - tree src0_type - = TREE_VALUE (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (built_in)))); - - tree src1_type = TREE_VALUE - (TREE_CHAIN (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (built_in))))); - - instr_expr = call_builtin (built_in, 3, instr_type, ptype, ptr, - src0_type, src0, src1_type, src1); - } - else - { - tree built_in = NULL_TREE; - /* The rest of the builtins have the same number of parameters. - Generate a big if..else that finds the correct builtin - automagically from the def file. */ -#undef DEF_HSAIL_SAT_BUILTIN -#undef DEF_HSAIL_BUILTIN -#undef DEF_HSAIL_ATOMIC_BUILTIN -#undef DEF_HSAIL_INTR_BUILTIN -#undef DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN - -#define DEF_HSAIL_ATOMIC_BUILTIN(ENUM, ATOMIC_OPCODE, HSAIL_TYPE, \ - NAME, TYPE, ATTRS) \ - if (atomic_opcode == ATOMIC_OPCODE && inst.type == HSAIL_TYPE) \ - built_in = builtin_decl_explicit (ENUM); \ - else -#include "brig-builtins.def" - switch (atomic_opcode) - { - case BRIG_ATOMIC_ADD: - switch (gccbrig_hsa_type_bit_size (inst.type)) - { - case 32: - built_in - = builtin_decl_explicit (BUILT_IN_SYNC_FETCH_AND_ADD_4); - break; - case 64: - built_in - = builtin_decl_explicit (BUILT_IN_SYNC_FETCH_AND_ADD_8); - break; - default: - gcc_unreachable (); - } - break; - case BRIG_ATOMIC_SUB: - switch (gccbrig_hsa_type_bit_size (inst.type)) - { - case 32: - built_in - = builtin_decl_explicit (BUILT_IN_SYNC_FETCH_AND_SUB_4); - break; - case 64: - built_in - = builtin_decl_explicit (BUILT_IN_SYNC_FETCH_AND_SUB_8); - break; - default: - gcc_unreachable (); - } - break; - case BRIG_ATOMIC_AND: - switch (gccbrig_hsa_type_bit_size (inst.type)) - { - case 32: - built_in - = builtin_decl_explicit (BUILT_IN_SYNC_FETCH_AND_AND_4); - break; - case 64: - built_in - = builtin_decl_explicit (BUILT_IN_SYNC_FETCH_AND_AND_8); - break; - default: - gcc_unreachable (); - } - break; - case BRIG_ATOMIC_XOR: - switch (gccbrig_hsa_type_bit_size (inst.type)) - { - case 32: - built_in - = builtin_decl_explicit (BUILT_IN_SYNC_FETCH_AND_XOR_4); - break; - case 64: - built_in - = builtin_decl_explicit (BUILT_IN_SYNC_FETCH_AND_XOR_8); - break; - default: - gcc_unreachable (); - } - break; - case BRIG_ATOMIC_OR: - switch (gccbrig_hsa_type_bit_size (inst.type)) - { - case 32: - built_in - = builtin_decl_explicit (BUILT_IN_SYNC_FETCH_AND_OR_4); - break; - case 64: - built_in - = builtin_decl_explicit (BUILT_IN_SYNC_FETCH_AND_OR_8); - break; - default: - gcc_unreachable (); - } - break; - case BRIG_ATOMIC_EXCH: - switch (gccbrig_hsa_type_bit_size (inst.type)) - { - case 32: - built_in - = builtin_decl_explicit (BUILT_IN_SYNC_LOCK_TEST_AND_SET_4); - break; - case 64: - built_in - = builtin_decl_explicit (BUILT_IN_SYNC_LOCK_TEST_AND_SET_8); - break; - default: - gcc_unreachable (); - } - break; - default: - gcc_unreachable (); - }; - - gcc_assert (built_in != NULL_TREE); - tree arg0_type - = TREE_VALUE (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (built_in)))); - - instr_expr = call_builtin (built_in, 2, instr_type, ptr_type_node, - ptr, arg0_type, src0); - - /* We need a temp variable for the result, because otherwise - the gimplifier drops a necessary (unsigned to signed) cast in - the output assignment and fails a check later. */ - tree tmp_var = create_tmp_var (arg0_type, "builtin_out"); - tree tmp_assign - = build2 (MODIFY_EXPR, TREE_TYPE (tmp_var), tmp_var, instr_expr); - m_parent.m_cf->append_statement (tmp_assign); - instr_expr = tmp_var; - } - - if (first_input > 0) - build_output_assignment (inst, operands[0], instr_expr); - else - m_parent.m_cf->append_statement (instr_expr); - - return inst.base.byteCount; -} - -size_t -brig_atomic_inst_handler::operator () (const BrigBase *base) -{ - const BrigInstAtomic *inst = (const BrigInstAtomic *) base; - BrigAtomicOperation8_t atomic_opcode; - atomic_opcode = inst->atomicOperation; - - return generate_tree (inst->base, atomic_opcode); -} diff --git a/gcc/brig/brigfrontend/brig-basic-inst-handler.cc b/gcc/brig/brigfrontend/brig-basic-inst-handler.cc deleted file mode 100644 index ebce19778de..00000000000 --- a/gcc/brig/brigfrontend/brig-basic-inst-handler.cc +++ /dev/null @@ -1,735 +0,0 @@ -/* brig-basic-inst-handler.cc -- brig basic instruction handling - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3, or (at your option) any later - version. - - GCC is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - . */ - -#include - -#include "brig-code-entry-handler.h" -#include "brig-util.h" - -#include "errors.h" -#include "gimple-expr.h" -#include "convert.h" -#include "print-tree.h" -#include "tree-pretty-print.h" -#include "langhooks.h" -#include "stor-layout.h" -#include "diagnostic-core.h" -#include "brig-builtins.h" -#include "fold-const.h" - -brig_basic_inst_handler::brig_basic_inst_handler (brig_to_generic &parent) - : brig_code_entry_handler (parent) -{ -} - -class scalarized_sat_arithmetics : public tree_element_binary_visitor -{ -public: - scalarized_sat_arithmetics (const BrigInstBase &brig_inst) - : m_brig_inst (brig_inst) - { - BrigType16_t element_type = brig_inst.type & BRIG_TYPE_BASE_MASK; - -#undef DEF_HSAIL_SAT_BUILTIN -#undef DEF_HSAIL_BUILTIN -#undef DEF_HSAIL_ATOMIC_BUILTIN -#undef DEF_HSAIL_INTR_BUILTIN -#undef DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN - -#define DEF_HSAIL_SAT_BUILTIN(ENUM, BRIG_OPCODE, HSAIL_TYPE, \ - NAME, TYPE, ATTRS) \ - if (brig_inst.opcode == BRIG_OPCODE && element_type == HSAIL_TYPE) \ - m_builtin = builtin_decl_explicit (ENUM); \ - else -#include "brig-builtins.def" - gcc_unreachable (); - } - - virtual tree - visit_element (brig_code_entry_handler &, tree operand0, tree operand1) - { - /* Implement saturating arithmetics with scalar built-ins for now. - TODO: emit GENERIC nodes for the simplest cases or at least - emit vector built-ins. */ - return call_builtin (m_builtin, 2, TREE_TYPE (operand0), - TREE_TYPE (operand0), operand0, - TREE_TYPE (operand1), operand1); - } - const BrigInstBase &m_brig_inst; - tree m_builtin; -}; - -/* Implements a vector shuffle. ARITH_TYPE is the type of the vector, - OPERANDS[0] is the first vector, OPERAND[1] the second vector and - OPERANDS[2] the shuffle mask in HSAIL format. The output is a VEC_PERM_EXPR - that implements the shuffle as a GENERIC expression. */ - -tree -brig_basic_inst_handler::build_shuffle (tree arith_type, - tree_stl_vec &operands) -{ - tree element_type - = get_unsigned_int_type (TREE_TYPE (TREE_TYPE (operands[0]))); - - /* Offsets to add to the mask values to convert from the - HSAIL mask to VEC_PERM_EXPR masks. VEC_PERM_EXPR mask - assumes an index spanning from 0 to 2 times the vec - width while HSAIL refers separately to two different - input vectors, thus is not a "full shuffle" where all - output elements can originate from any input element. */ - vec *mask_offset_vals = NULL; - - unsigned int element_count = gccbrig_type_vector_subparts (arith_type); - - vec *input_mask_vals = NULL; - size_t input_mask_element_size = exact_log2 (element_count); - - /* Unpack the tightly packed mask elements to BIT_FIELD_REFs - from which to construct the mask vector as understood by - VEC_PERM_EXPR. */ - tree mask_operand - = m_parent.m_cf->add_temp_var ("shuffle_mask", operands[2]); - - tree mask_element_type - = build_nonstandard_integer_type (input_mask_element_size, true); - - for (size_t i = 0; i < element_count; ++i) - { - tree mask_element - = build3 (BIT_FIELD_REF, mask_element_type, mask_operand, - bitsize_int (input_mask_element_size), - bitsize_int (i * input_mask_element_size)); - - mask_element = convert (element_type, mask_element); - - tree offset; - if (i < element_count / 2) - offset = build_int_cst (element_type, 0); - else - offset = build_int_cst (element_type, element_count); - - CONSTRUCTOR_APPEND_ELT (mask_offset_vals, NULL_TREE, offset); - CONSTRUCTOR_APPEND_ELT (input_mask_vals, NULL_TREE, mask_element); - } - tree mask_vec_type = build_vector_type (element_type, element_count); - - tree mask_vec = build_constructor (mask_vec_type, input_mask_vals); - tree offset_vec = build_constructor (mask_vec_type, mask_offset_vals); - - tree mask = build2 (PLUS_EXPR, mask_vec_type, mask_vec, offset_vec); - - tree perm = build3 (VEC_PERM_EXPR, TREE_TYPE (operands[0]), operands[0], - operands[1], mask); - return perm; -} - -/* Unpacks (extracts) a scalar element with an index in OPERANDS[1] - from the vector expression in OPERANDS[0]. */ - -tree -brig_basic_inst_handler::build_unpack (tree_stl_vec &operands) -{ - /* Implement the unpack with a shuffle that stores the unpacked - element to the lowest bit positions in the dest. After that - a bitwise AND is used to clear the uppermost bits. */ - tree src_element_type = TREE_TYPE (TREE_TYPE (operands[0])); - - /* Perform the operations with a raw (unsigned int type) type. */ - tree element_type = get_unsigned_int_type (src_element_type); - - vec *input_mask_vals = NULL; - vec *and_mask_vals = NULL; - - size_t element_count - = gccbrig_type_vector_subparts (TREE_TYPE (operands[0])); - tree vec_type = build_vector_type (element_type, element_count); - - for (size_t i = 0; i < element_count; ++i) - { - tree mask_element; - if (i == 0) - mask_element = convert (element_type, operands[1]); - else - mask_element = build_int_cst (element_type, 0); - - CONSTRUCTOR_APPEND_ELT (input_mask_vals, NULL_TREE, mask_element); - - tree and_mask_element; - if (i == 0) - and_mask_element = build_int_cst (element_type, -1); - else - and_mask_element = build_int_cst (element_type, 0); - CONSTRUCTOR_APPEND_ELT (and_mask_vals, NULL_TREE, and_mask_element); - } - - tree mask_vec = build_constructor (vec_type, input_mask_vals); - - tree and_mask_vec = build_constructor (vec_type, and_mask_vals); - - tree perm = build3 (VEC_PERM_EXPR, vec_type, - build_resize_convert_view (vec_type, operands[0]), - build_resize_convert_view (vec_type, operands[0]), - mask_vec); - - tree cleared = build2 (BIT_AND_EXPR, vec_type, perm, and_mask_vec); - - size_t s = int_size_in_bytes (TREE_TYPE (cleared)) * BITS_PER_UNIT; - tree raw_type = build_nonstandard_integer_type (s, true); - - tree as_int = build_resize_convert_view (raw_type, cleared); - - if (int_size_in_bytes (src_element_type) < 4) - { - if (INTEGRAL_TYPE_P (src_element_type)) - return extend_int (as_int, uint32_type_node, src_element_type); - } - return as_int; -} - -/* Packs (inserts) a scalar element in OPERANDS[1] - to the vector in OPERANDS[0] at element position defined by - OPERANDS[2]. */ - -tree -brig_basic_inst_handler::build_pack (tree_stl_vec &operands) -{ - /* Implement using a bit level insertion. - TODO: Reuse this for implementing 'bitinsert' - without a builtin call. */ - - size_t ecount = gccbrig_type_vector_subparts (TREE_TYPE (operands[0])); - size_t vecsize = int_size_in_bytes (TREE_TYPE (operands[0])) * BITS_PER_UNIT; - tree wide_type = build_nonstandard_integer_type (vecsize, 1); - - tree src_vect = build_resize_convert_view (wide_type, operands[0]); - src_vect = m_parent.m_cf->add_temp_var ("src_vect", src_vect); - - tree scalar = operands[1]; - scalar = m_parent.m_cf->add_temp_var ("scalar", - convert_to_integer (wide_type, scalar)); - - tree pos = operands[2]; - - /* The upper bits of the position can contain garbage. - Zero them for well-defined semantics. */ - tree t = build2 (BIT_AND_EXPR, TREE_TYPE (pos), operands[2], - build_int_cstu (TREE_TYPE (pos), ecount - 1)); - pos = m_parent.m_cf->add_temp_var ("pos", convert (wide_type, t)); - - tree element_type = TREE_TYPE (TREE_TYPE (operands[0])); - size_t element_width = int_size_in_bytes (element_type) * BITS_PER_UNIT; - tree ewidth = build_int_cstu (wide_type, element_width); - - tree bitoffset = build2 (MULT_EXPR, wide_type, ewidth, pos); - bitoffset = m_parent.m_cf->add_temp_var ("offset", bitoffset); - - uint64_t mask_int - = element_width == 64 ? (uint64_t) -1 : ((uint64_t) 1 << element_width) - 1; - - tree mask = build_int_cstu (wide_type, mask_int); - - mask = m_parent.m_cf->add_temp_var ("mask", - convert_to_integer (wide_type, mask)); - - tree clearing_mask - = build1 (BIT_NOT_EXPR, wide_type, - build2 (LSHIFT_EXPR, wide_type, mask, bitoffset)); - - tree zeroed_element - = build2 (BIT_AND_EXPR, wide_type, src_vect, clearing_mask); - - /* TODO: Is the AND necessary: does HSA define what - happens if the upper bits in the inserted element are not - zero? */ - tree element_in_position - = build2 (LSHIFT_EXPR, wide_type, - build2 (BIT_AND_EXPR, wide_type, scalar, mask), bitoffset); - - tree inserted - = build2 (BIT_IOR_EXPR, wide_type, zeroed_element, element_in_position); - return inserted; -} - -/* Implement the unpack{lo,hi}. BRIG_OPCODE should tell which one and - ARITH_TYPE describe the type of the vector arithmetics. - OPERANDS[0] and OPERANDS[1] are the input vectors. */ - -tree -brig_basic_inst_handler::build_unpack_lo_or_hi (BrigOpcode16_t brig_opcode, - tree arith_type, - tree_stl_vec &operands) -{ - tree element_type = get_unsigned_int_type (TREE_TYPE (arith_type)); - tree mask_vec_type - = build_vector_type (element_type, - gccbrig_type_vector_subparts (arith_type)); - - size_t element_count = gccbrig_type_vector_subparts (arith_type); - vec *input_mask_vals = NULL; - - size_t offset = (brig_opcode == BRIG_OPCODE_UNPACKLO) ? 0 : element_count / 2; - - for (size_t i = 0; i < element_count / 2; ++i) - { - CONSTRUCTOR_APPEND_ELT (input_mask_vals, NULL_TREE, - build_int_cst (element_type, offset + i)); - CONSTRUCTOR_APPEND_ELT (input_mask_vals, NULL_TREE, - build_int_cst (element_type, - offset + i + element_count)); - } - - tree mask_vec = build_constructor (mask_vec_type, input_mask_vals); - - tree perm = build3 (VEC_PERM_EXPR, TREE_TYPE (operands[0]), operands[0], - operands[1], mask_vec); - return perm; -} - -/* Builds a basic instruction expression from a BRIG instruction. BRIG_OPCODE - is the opcode, BRIG_TYPE the brig type of the instruction, ARITH_TYPE the - desired tree type for the instruction, and OPERANDS the instruction's - input operands already converted to tree nodes. */ - -tree -brig_basic_inst_handler::build_inst_expr (BrigOpcode16_t brig_opcode, - BrigType16_t brig_type, - tree arith_type, - tree_stl_vec &operands) -{ - tree_code opcode - = brig_function::get_tree_code_for_hsa_opcode (brig_opcode, brig_type); - - BrigType16_t inner_type = brig_type & BRIG_TYPE_BASE_MASK; - - tree instr_inner_type - = VECTOR_TYPE_P (arith_type) ? TREE_TYPE (arith_type) : arith_type; - - if (opcode == RSHIFT_EXPR || opcode == LSHIFT_EXPR) - { - /* HSA defines modulo/clipping behavior for shift amounts larger - than the bit width, while tree.def leaves it undefined. - We need to mask the upper bits to ensure the defined behavior. */ - tree scalar_mask - = build_int_cst (instr_inner_type, - gccbrig_hsa_type_bit_size (inner_type) - 1); - - tree mask = VECTOR_TYPE_P (arith_type) - ? build_vector_from_val (arith_type, scalar_mask) - : scalar_mask; - - /* The shift amount is a scalar, broadcast it to produce - a vector shift. */ - if (VECTOR_TYPE_P (arith_type)) - operands[1] = build_vector_from_val (arith_type, operands[1]); - operands[1] = build2 (BIT_AND_EXPR, arith_type, operands[1], mask); - } - - size_t input_count = operands.size (); - size_t output_count = gccbrig_hsa_opcode_op_output_p (brig_opcode, 0) ? - 1 : 0; - - if (opcode == TREE_LIST) - { - /* There was no direct GENERIC opcode for the instruction; - try to emulate it with a chain of GENERIC nodes. */ - if (brig_opcode == BRIG_OPCODE_MAD || brig_opcode == BRIG_OPCODE_MAD24) - { - /* There doesn't seem to be a "standard" MAD built-in in gcc so let's - use a chain of multiply + add for now (double rounding method). - It should be easier for optimizers than a custom built-in call - WIDEN_MULT_EXPR is close, but requires a double size result - type. */ - tree mult_res - = build2 (MULT_EXPR, arith_type, operands[0], operands[1]); - return build2 (PLUS_EXPR, arith_type, mult_res, operands[2]); - } - else if (brig_opcode == BRIG_OPCODE_MAD24HI) - { - tree mult_res - = build2 (MULT_HIGHPART_EXPR, arith_type, operands[0], operands[1]); - return build2 (PLUS_EXPR, arith_type, mult_res, operands[2]); - } - else if (brig_opcode == BRIG_OPCODE_SHUFFLE) - { - return build_shuffle (arith_type, operands); - } - else if (brig_opcode == BRIG_OPCODE_UNPACKLO - || brig_opcode == BRIG_OPCODE_UNPACKHI) - { - return build_unpack_lo_or_hi (brig_opcode, arith_type, operands); - } - else if (brig_opcode == BRIG_OPCODE_UNPACK) - { - return build_unpack (operands); - } - else if (brig_opcode == BRIG_OPCODE_PACK) - { - return build_pack (operands); - } - else if (brig_opcode == BRIG_OPCODE_NRSQRT) - { - /* Implement as 1.0/sqrt (x) and assume gcc instruction selects to - native ISA other than a division, if available. - TODO: this will happen only with unsafe math optimizations - on which cannot be used in general to remain HSAIL compliant. - Perhaps a builtin call would be better option here. */ - return build2 (RDIV_EXPR, arith_type, build_one_cst (arith_type), - m_parent.m_cf->expand_or_call_builtin - (BRIG_OPCODE_SQRT, brig_type, arith_type, operands)); - } - else if (brig_opcode == BRIG_OPCODE_NRCP) - { - /* Implement as 1.0/x and assume gcc instruction selects to - native ISA other than a division, if available. */ - return build2 (RDIV_EXPR, arith_type, build_one_cst (arith_type), - operands[0]); - } - else if (brig_opcode == BRIG_OPCODE_LANEID - || brig_opcode == BRIG_OPCODE_MAXWAVEID - || brig_opcode == BRIG_OPCODE_WAVEID) - { - /* Assuming WAVESIZE 1 (for now), therefore LANEID, WAVEID and - MAXWAVEID always return 0. */ - return build_zero_cst (arith_type); - } - else - gcc_unreachable (); - } - else if (opcode == CALL_EXPR) - return m_parent.m_cf->expand_or_call_builtin (brig_opcode, brig_type, - arith_type, operands); - else if (output_count == 1) - { - if (input_count == 1) - { - if (opcode == MODIFY_EXPR) - return operands[0]; - else - return build1 (opcode, arith_type, operands[0]); - } - else if (input_count == 2) - return build2 (opcode, arith_type, operands[0], operands[1]); - else if (input_count == 3) - return build3 (opcode, arith_type, operands[0], operands[1], - operands[2]); - else - gcc_unreachable (); - } - else - gcc_unreachable (); - - return NULL_TREE; -} - -/* Handles the basic instructions, including packed instructions. Deals - with the different packing modes by unpacking/packing the wanted - elements. Delegates most of the instruction cases to build_inst_expr(). */ - -size_t -brig_basic_inst_handler::operator () (const BrigBase *base) -{ - const BrigInstBase *brig_inst = (const BrigInstBase *) base; - if (brig_inst->opcode == BRIG_OPCODE_NOP) - return base->byteCount; - - tree_stl_vec operands = build_operands (*brig_inst); - - size_t output_count - = gccbrig_hsa_opcode_op_output_p (brig_inst->opcode, 0) ? 1 : 0; - size_t input_count - = operands.size () == 0 ? 0 : (operands.size () - output_count); - - gcc_assert (output_count == 0 || output_count == 1); - - tree_stl_vec::iterator first_input_i = operands.begin (); - if (output_count > 0 && operands.size () > 0) - ++first_input_i; - - tree_stl_vec in_operands; - in_operands.assign (first_input_i, operands.end ()); - - BrigType16_t brig_inst_type = brig_inst->type; - - if (brig_inst->opcode == BRIG_OPCODE_FIRSTBIT - || brig_inst->opcode == BRIG_OPCODE_LASTBIT - || brig_inst->opcode == BRIG_OPCODE_SAD) - /* These instructions are reported to be always 32b in HSAIL, but we want - to treat them according to their input argument's type to select the - correct instruction/builtin. */ - brig_inst_type - = gccbrig_tree_type_to_hsa_type (TREE_TYPE (in_operands[0])); - - tree instr_type = gccbrig_tree_type_for_hsa_type (brig_inst_type); - - if (!instr_type) - { - gcc_unreachable (); - return base->byteCount; - } - - bool is_vec_instr = hsa_type_packed_p (brig_inst_type); - - size_t element_size_bits; - size_t element_count; - - if (is_vec_instr) - { - BrigType16_t brig_element_type = brig_inst_type & BRIG_TYPE_BASE_MASK; - element_size_bits = gccbrig_hsa_type_bit_size (brig_element_type); - element_count = gccbrig_hsa_type_bit_size (brig_inst_type) - / gccbrig_hsa_type_bit_size (brig_element_type); - } - else - { - element_size_bits = gccbrig_hsa_type_bit_size (brig_inst_type); - element_count = 1; - } - - /* The actual arithmetics type that should be performed with the - operation. This is not always the same as the original BRIG - opcode's type due to implicit conversions of storage-only f16. */ - tree arith_type = gccbrig_is_bit_operation (brig_inst->opcode) - ? gccbrig_tree_type_for_hsa_type (brig_inst_type) - : get_tree_expr_type_for_hsa_type (brig_inst_type); - - tree instr_expr = NULL_TREE; - - BrigPack8_t p = BRIG_PACK_NONE; - if (brig_inst->base.kind == BRIG_KIND_INST_MOD) - p = ((const BrigInstMod *) brig_inst)->pack; - else if (brig_inst->base.kind == BRIG_KIND_INST_CMP) - p = ((const BrigInstCmp *) brig_inst)->pack; - - if (p == BRIG_PACK_PS || p == BRIG_PACK_PSSAT) - in_operands[1] = build_lower_element_broadcast (in_operands[1]); - else if (p == BRIG_PACK_SP || p == BRIG_PACK_SPSAT) - in_operands[0] = build_lower_element_broadcast (in_operands[0]); - - tree_code opcode - = brig_function::get_tree_code_for_hsa_opcode (brig_inst->opcode, - brig_inst_type); - - if (p >= BRIG_PACK_PPSAT && p <= BRIG_PACK_PSAT) - { - scalarized_sat_arithmetics sat_arith (*brig_inst); - gcc_assert (input_count == 2); - instr_expr = sat_arith (*this, in_operands[0], in_operands[1]); - } - else if (opcode == RETURN_EXPR) - { - if (m_parent.m_cf->m_is_kernel) - { - tree goto_stmt - = build1 (GOTO_EXPR, void_type_node, m_parent.m_cf->m_exit_label); - m_parent.m_cf->append_statement (goto_stmt); - return base->byteCount; - } - else - { - m_parent.m_cf->append_return_stmt (); - return base->byteCount; - } - } - else if (opcode == MULT_HIGHPART_EXPR && - is_vec_instr && element_size_bits < 64) - { - /* MULT_HIGHPART_EXPR works only on target dependent vector sizes and - even the scalars do not seem to work at least for char elements. - - Let's fall back to scalarization and promotion of the vector elements - to larger types with the MULHI computed as a regular MUL. - MULHI for 2x64b seems to work with the Intel CPUs I've tested so - that is passed on for vector processing so there is no need for - 128b scalar arithmetics. - - This is not modular as these type of things do not belong to the - frontend, there should be a legalization phase before the backend - that figures out the best way to compute the MULHI for any - integer vector datatype. - - TODO: promote to larger vector types instead. For example - MULT_HIGHPART_EXPR with s8x8 doesn't work, but s16x8 seems to at least - with my x86-64. - */ - tree_stl_vec operand0_elements; - if (input_count > 0) - m_parent.m_cf->unpack (in_operands[0], operand0_elements); - - tree_stl_vec operand1_elements; - if (input_count > 1) - m_parent.m_cf->unpack (in_operands[1], operand1_elements); - - tree_stl_vec result_elements; - - tree scalar_type = TREE_TYPE (arith_type); - BrigType16_t element_type = brig_inst_type & BRIG_TYPE_BASE_MASK; - tree promoted_type = short_integer_type_node; - switch (element_type) - { - case BRIG_TYPE_S8: - promoted_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_S16); - break; - case BRIG_TYPE_U8: - promoted_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_U16); - break; - case BRIG_TYPE_S16: - promoted_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_S32); - break; - case BRIG_TYPE_U16: - promoted_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_U32); - break; - case BRIG_TYPE_S32: - promoted_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_S64); - break; - case BRIG_TYPE_U32: - promoted_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_U64); - break; - default: - gcc_unreachable (); - } - - size_t promoted_type_size = int_size_in_bytes (promoted_type) * 8; - size_t element_count = gccbrig_type_vector_subparts (arith_type); - for (size_t i = 0; i < element_count; ++i) - { - tree operand0 = convert (promoted_type, operand0_elements.at (i)); - tree operand1 = convert (promoted_type, operand1_elements.at (i)); - - tree scalar_expr - = build2 (MULT_EXPR, promoted_type, operand0, operand1); - - scalar_expr - = build2 (RSHIFT_EXPR, promoted_type, scalar_expr, - build_int_cstu (promoted_type, promoted_type_size / 2)); - - result_elements.push_back (convert (scalar_type, scalar_expr)); - } - instr_expr = m_parent.m_cf->pack (result_elements); - } - else - { - /* 'class' is always of b1 type, let's consider it by its - float type when building the instruction to find the - correct builtin. */ - if (brig_inst->opcode == BRIG_OPCODE_CLASS) - brig_inst_type = ((const BrigInstSourceType *) base)->sourceType; - instr_expr = build_inst_expr (brig_inst->opcode, brig_inst_type, - arith_type, in_operands); - } - - if (instr_expr == NULL_TREE) - { - gcc_unreachable (); - return base->byteCount; - } - - if (p == BRIG_PACK_SS || p == BRIG_PACK_S || p == BRIG_PACK_SSSAT - || p == BRIG_PACK_SSAT) - { - /* In case of _s_ or _ss_, select only the lowest element - from the new input to the output. We could extract - the element and use a scalar operation, but try - to keep data in vector registers as much as possible - to avoid copies between scalar and vector datapaths. */ - tree old_value; - tree half_storage_type = gccbrig_tree_type_for_hsa_type (brig_inst_type); - bool is_fp16_operation - = (brig_inst_type & BRIG_TYPE_BASE_MASK) == BRIG_TYPE_F16 - && !gccbrig_is_bit_operation (brig_inst->opcode); - - if (is_fp16_operation) - old_value = build_h2f_conversion - (build_resize_convert_view (half_storage_type, operands[0])); - else - old_value - = build_resize_convert_view (TREE_TYPE (instr_expr), operands[0]); - - size_t esize = is_fp16_operation ? 32 : element_size_bits; - - /* Construct a permutation mask where other elements than the lowest one - is picked from the old_value. */ - tree mask_inner_type = build_nonstandard_integer_type (esize, 1); - vec *constructor_vals = NULL; - for (size_t i = 0; i < element_count; ++i) - { - tree cst; - - if (i == 0) - cst = build_int_cstu (mask_inner_type, element_count); - else - cst = build_int_cstu (mask_inner_type, i); - CONSTRUCTOR_APPEND_ELT (constructor_vals, NULL_TREE, cst); - } - tree mask_vec_type = build_vector_type (mask_inner_type, element_count); - tree mask = build_vector_from_ctor (mask_vec_type, constructor_vals); - - tree new_value = create_tmp_var (TREE_TYPE (instr_expr), "new_output"); - tree assign - = build2 (MODIFY_EXPR, TREE_TYPE (instr_expr), new_value, instr_expr); - m_parent.m_cf->append_statement (assign); - - instr_expr - = build3 (VEC_PERM_EXPR, arith_type, old_value, new_value, mask); - - tree lower_output = create_tmp_var (TREE_TYPE (instr_expr), "s_output"); - tree assign_lower = build2 (MODIFY_EXPR, TREE_TYPE (instr_expr), - lower_output, instr_expr); - m_parent.m_cf->append_statement (assign_lower); - instr_expr = lower_output; - } - - if (output_count == 1) - build_output_assignment (*brig_inst, operands[0], instr_expr); - else - m_parent.m_cf->append_statement (instr_expr); - return base->byteCount; -} - -/* Create an expression that broadcasts the lowest element of the - vector in VEC_OPERAND to all elements of the returned vector. */ - -tree -brig_basic_inst_handler::build_lower_element_broadcast (tree vec_operand) -{ - /* Build the broadcast using shuffle because there's no - direct broadcast in GENERIC and this way there's no need for - a separate extract of the lowest element. */ - tree element_type = TREE_TYPE (TREE_TYPE (vec_operand)); - size_t esize = 8 * int_size_in_bytes (element_type); - - size_t element_count - = gccbrig_type_vector_subparts (TREE_TYPE (vec_operand)); - tree mask_inner_type = build_nonstandard_integer_type (esize, 1); - vec *constructor_vals = NULL; - - /* Construct the mask. */ - for (size_t i = 0; i < element_count; ++i) - { - tree cst = build_int_cstu (mask_inner_type, element_count); - CONSTRUCTOR_APPEND_ELT (constructor_vals, NULL_TREE, cst); - } - tree mask_vec_type = build_vector_type (mask_inner_type, element_count); - tree mask = build_vector_from_ctor (mask_vec_type, constructor_vals); - - return build3 (VEC_PERM_EXPR, TREE_TYPE (vec_operand), vec_operand, - vec_operand, mask); -} - diff --git a/gcc/brig/brigfrontend/brig-branch-inst-handler.cc b/gcc/brig/brigfrontend/brig-branch-inst-handler.cc deleted file mode 100644 index 39057125373..00000000000 --- a/gcc/brig/brigfrontend/brig-branch-inst-handler.cc +++ /dev/null @@ -1,238 +0,0 @@ -/* brig-branch-inst-handler.cc -- brig branch instruction handling - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3, or (at your option) any later - version. - - GCC is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - . */ - -#include "brig-code-entry-handler.h" - -#include "errors.h" -#include "brig-util.h" -#include "tree-pretty-print.h" -#include "print-tree.h" -#include "vec.h" -#include "fold-const.h" - -size_t -brig_branch_inst_handler::operator () (const BrigBase *base) -{ - const BrigInstBase *brig_inst - = (const BrigInstBase *) &((const BrigInstBasic *) base)->base; - - if (brig_inst->opcode == BRIG_OPCODE_CALL) - { - const BrigData *operand_entries - = m_parent.get_brig_data_entry (brig_inst->operands); - tree func_ref = NULL_TREE; - vec *out_args; - vec_alloc (out_args, 1); - vec *in_args; - /* Ten elem initially, more reserved if needed. */ - vec_alloc (in_args, 10); - - size_t operand_count = operand_entries->byteCount / 4; - gcc_assert (operand_count < 4); - - for (size_t i = 0; i < operand_count; ++i) - { - uint32_t operand_offset - = ((const uint32_t *) &operand_entries->bytes)[i]; - const BrigBase *operand_data - = m_parent.get_brig_operand_entry (operand_offset); - if (i == 1) - { - gcc_assert (operand_data->kind == BRIG_KIND_OPERAND_CODE_REF); - func_ref = build_tree_operand (*brig_inst, *operand_data); - continue; - } - gcc_assert (operand_data->kind == BRIG_KIND_OPERAND_CODE_LIST); - const BrigOperandCodeList *codelist - = (const BrigOperandCodeList *) operand_data; - const BrigData *data - = m_parent.get_brig_data_entry (codelist->elements); - - size_t bytes = data->byteCount; - const BrigOperandOffset32_t *operand_ptr - = (const BrigOperandOffset32_t *) data->bytes; - - bool out_args_p = i == 0; - - while (bytes > 0) - { - BrigOperandOffset32_t offset = *operand_ptr; - const BrigBase *code_element - = m_parent.get_brig_code_entry (offset); - gcc_assert (code_element->kind == BRIG_KIND_DIRECTIVE_VARIABLE); - const BrigDirectiveVariable *brig_var - = (const BrigDirectiveVariable *) code_element; - tree var = m_parent.m_cf->arg_variable (brig_var); - - if (brig_var->type & BRIG_TYPE_ARRAY) - { - /* Array return values are passed as the first argument. */ - out_args_p = false; - /* Pass pointer to the element zero and use its element zero - as the base address. */ - tree etype = TREE_TYPE (TREE_TYPE (var)); - tree ptype = build_pointer_type (etype); - tree element_zero - = build4 (ARRAY_REF, etype, var, integer_zero_node, - NULL_TREE, NULL_TREE); - var = build1 (ADDR_EXPR, ptype, element_zero); - } - - gcc_assert (var != NULL_TREE); - vec_safe_push (out_args_p ? out_args : in_args, var); - ++operand_ptr; - bytes -= 4; - } - } - - gcc_assert (func_ref != NULL_TREE); - gcc_assert (out_args->length () == 0 || out_args->length () == 1); - - tree ret_val_type = void_type_node; - tree ret_val = NULL_TREE; - if (out_args->length () == 1) - { - ret_val = (*out_args)[0]; - ret_val_type = TREE_TYPE (ret_val); - } - - /* Pass the hidden kernel arguments along to the called functions as - they might call builtins that need them or access group/private - memory. */ - - tree group_local_offset - = m_parent.m_cf->add_temp_var ("group_local_offset", - build_int_cst - (uint32_type_node, - m_parent.m_cf-> - m_local_group_variables.size())); - - /* TODO: ensure the callee's frame is aligned! */ - - vec_safe_reserve (in_args, 4); - vec_safe_push (in_args, m_parent.m_cf->m_context_arg); - vec_safe_push (in_args, m_parent.m_cf->m_group_base_arg); - vec_safe_push (in_args, group_local_offset); - vec_safe_push (in_args, m_parent.m_cf->m_private_base_arg); - - tree call = build_call_vec (ret_val_type, build_fold_addr_expr (func_ref), - in_args); - TREE_NOTHROW (func_ref) = 1; - TREE_NOTHROW (call) = 1; - - if (ret_val != NULL_TREE) - { - TREE_ADDRESSABLE (ret_val) = 1; - tree result_assign - = build2 (MODIFY_EXPR, TREE_TYPE (ret_val), ret_val, call); - m_parent.m_cf->append_statement (result_assign); - } - else - { - m_parent.m_cf->append_statement (call); - } - - m_parent.m_cf->m_called_functions.push_back (func_ref); - if (DECL_EXTERNAL (func_ref)) - m_parent.add_decl_call (call); - m_parent.m_cf->start_new_bb (); - - return base->byteCount; - } - - tree instr_type = gccbrig_tree_type_for_hsa_type (brig_inst->type); - tree_stl_vec operands = build_operands (*brig_inst); - - if (brig_inst->opcode == BRIG_OPCODE_BR) - { - tree goto_stmt = build1 (GOTO_EXPR, instr_type, operands[0]); - m_parent.m_cf->append_statement (goto_stmt); - } - else if (brig_inst->opcode == BRIG_OPCODE_SBR) - { - tree select = operands[0]; - tree cases = operands[1]; - - tree switch_expr = build2 (SWITCH_EXPR, TREE_TYPE (select), select, - NULL_TREE); - - tree default_case - = build_case_label (NULL_TREE, NULL_TREE, - create_artificial_label (UNKNOWN_LOCATION)); - append_to_statement_list (default_case, &SWITCH_BODY (switch_expr)); - - tree default_jump - = build1 (GOTO_EXPR, void_type_node, TREE_VEC_ELT (cases, 0)); - append_to_statement_list (default_jump, &SWITCH_BODY (switch_expr)); - - for (int c = 0; c < TREE_VEC_LENGTH (cases); ++c) - { - tree case_label - = build_case_label (build_int_cst (integer_type_node, c), NULL_TREE, - create_artificial_label (UNKNOWN_LOCATION)); - - append_to_statement_list (case_label, &SWITCH_BODY (switch_expr)); - - tree jump - = build1 (GOTO_EXPR, void_type_node, TREE_VEC_ELT (cases, c)); - append_to_statement_list (jump, &SWITCH_BODY (switch_expr)); - } - m_parent.m_cf->append_statement (switch_expr); - } - else if (brig_inst->opcode == BRIG_OPCODE_CBR) - { - tree condition = operands[0]; - tree target_goto = build1 (GOTO_EXPR, void_type_node, operands[1]); - /* Represents the if..else as (condition)?(goto foo):(goto bar). */ - tree if_stmt - = build3 (COND_EXPR, void_type_node, condition, target_goto, NULL_TREE); - m_parent.m_cf->append_statement (if_stmt); - } - else if (brig_inst->opcode == BRIG_OPCODE_WAVEBARRIER) - { - /* WAVEBARRIER is a NOP when WAVESIZE = 1. */ - } - else if (brig_inst->opcode == BRIG_OPCODE_BARRIER) - { - m_parent.m_cf->m_has_barriers = true; - tree_stl_vec call_operands; - /* FIXME. We should add attributes (are there suitable ones in gcc?) that - ensure the barrier won't be duplicated or moved out of loops etc. - Like the 'noduplicate' of LLVM. Same goes for fbarriers. */ - m_parent.m_cf->append_statement - (m_parent.m_cf->expand_or_call_builtin (brig_inst->opcode, - BRIG_TYPE_NONE, NULL_TREE, - call_operands)); - } - else if (brig_inst->opcode >= BRIG_OPCODE_ARRIVEFBAR - && brig_inst->opcode <= BRIG_OPCODE_WAITFBAR) - { - m_parent.m_cf->m_has_barriers = true; - m_parent.m_cf->append_statement - (m_parent.m_cf->expand_or_call_builtin (brig_inst->opcode, - BRIG_TYPE_NONE, - uint32_type_node, operands)); - } - else - gcc_unreachable (); - m_parent.m_cf->start_new_bb (); - return base->byteCount; -} diff --git a/gcc/brig/brigfrontend/brig-cmp-inst-handler.cc b/gcc/brig/brigfrontend/brig-cmp-inst-handler.cc deleted file mode 100644 index 62ebfaca0b3..00000000000 --- a/gcc/brig/brigfrontend/brig-cmp-inst-handler.cc +++ /dev/null @@ -1,198 +0,0 @@ -/* brig-cmp-inst-handler.cc -- brig cmp instruction handling - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ - -#include "brig-code-entry-handler.h" -#include "diagnostic.h" -#include "tree-pretty-print.h" -#include "print-tree.h" -#include "brig-util.h" -#include "convert.h" - -size_t -brig_cmp_inst_handler::operator () (const BrigBase *base) -{ - const BrigInstBase *inst_base = (const BrigInstBase *) base; - const BrigInstCmp *inst = (const BrigInstCmp *) base; - - tree cmp_type = get_tree_expr_type_for_hsa_type (inst->sourceType); - - /* The destination type to convert the comparison result to. */ - tree dest_type = gccbrig_tree_type_for_hsa_type (inst_base->type); - - const bool is_fp16_dest - = (inst_base->type & BRIG_TYPE_BASE_MASK) == BRIG_TYPE_F16; - const bool is_boolean_dest - = (inst_base->type & BRIG_TYPE_BASE_MASK) == BRIG_TYPE_B1; - - bool is_int_cmp = VECTOR_TYPE_P (cmp_type) - ? INTEGRAL_TYPE_P (TREE_TYPE (cmp_type)) - : INTEGRAL_TYPE_P (cmp_type); - - /* The type for the GENERIC comparison. It should match the - input operand width for vector comparisons, a boolean - otherwise. */ - tree result_type = get_comparison_result_type (cmp_type); - - /* Save the result as a boolean and extend/convert it to the - wanted destination type. */ - tree expr = NULL_TREE; - - std::vector operands = build_operands (*inst_base); - - switch (inst->compare) - { - case BRIG_COMPARE_SEQ: - case BRIG_COMPARE_EQ: - expr = build2 (EQ_EXPR, result_type, operands[1], operands[2]); - break; - case BRIG_COMPARE_SNE: - case BRIG_COMPARE_NE: - expr = build2 (NE_EXPR, result_type, operands[1], operands[2]); - - if (!is_int_cmp) - expr = build2 (BIT_AND_EXPR, TREE_TYPE (expr), - expr, - build2 (ORDERED_EXPR, result_type, operands[1], - operands[2])); - break; - case BRIG_COMPARE_SLT: - case BRIG_COMPARE_LT: - expr = build2 (LT_EXPR, result_type, operands[1], operands[2]); - break; - case BRIG_COMPARE_SLE: - case BRIG_COMPARE_LE: - expr = build2 (LE_EXPR, result_type, operands[1], operands[2]); - break; - case BRIG_COMPARE_SGT: - case BRIG_COMPARE_GT: - expr = build2 (GT_EXPR, result_type, operands[1], operands[2]); - break; - case BRIG_COMPARE_SGE: - case BRIG_COMPARE_GE: - expr = build2 (GE_EXPR, result_type, operands[1], operands[2]); - break; - case BRIG_COMPARE_SEQU: - case BRIG_COMPARE_EQU: - expr = build2 (UNEQ_EXPR, result_type, operands[1], operands[2]); - break; - case BRIG_COMPARE_SNEU: - case BRIG_COMPARE_NEU: - expr = build2 (NE_EXPR, result_type, operands[1], operands[2]); - break; - case BRIG_COMPARE_SLTU: - case BRIG_COMPARE_LTU: - expr = build2 (UNLT_EXPR, result_type, operands[1], operands[2]); - break; - case BRIG_COMPARE_SLEU: - case BRIG_COMPARE_LEU: - expr = build2 (UNLE_EXPR, result_type, operands[1], operands[2]); - break; - case BRIG_COMPARE_SGTU: - case BRIG_COMPARE_GTU: - expr = build2 (UNGT_EXPR, result_type, operands[1], operands[2]); - break; - case BRIG_COMPARE_SGEU: - case BRIG_COMPARE_GEU: - expr = build2 (UNGE_EXPR, result_type, operands[1], operands[2]); - break; - case BRIG_COMPARE_SNUM: - case BRIG_COMPARE_NUM: - expr = build2 (ORDERED_EXPR, result_type, operands[1], operands[2]); - break; - case BRIG_COMPARE_SNAN: - case BRIG_COMPARE_NAN: - expr = build2 (UNORDERED_EXPR, result_type, operands[1], operands[2]); - break; - default: - break; - } - - if (expr == NULL_TREE) - gcc_unreachable (); - - if (is_fp16_dest) - { - expr = convert_to_real (brig_to_generic::s_fp32_type, expr); - } - else if (VECTOR_TYPE_P (dest_type) && ANY_INTEGRAL_TYPE_P (dest_type) - && !is_boolean_dest - && (inst->sourceType & BRIG_TYPE_BASE_MASK) != BRIG_TYPE_F16) - { - /* In later gcc versions, the output of comparison is not - all ones for vectors like still in 4.9.1. We need to use - an additional VEC_COND_EXPR to produce the all ones 'true' value - required by HSA. - VEC_COND_EXPR ; */ - - tree all_ones - = build_vector_from_val (dest_type, - build_minus_one_cst (TREE_TYPE (dest_type))); - tree all_zeroes - = build_vector_from_val (dest_type, - build_zero_cst (TREE_TYPE (dest_type))); - expr = build3 (VEC_COND_EXPR, dest_type, expr, all_ones, all_zeroes); - } - else if (INTEGRAL_TYPE_P (dest_type) && !is_boolean_dest) - { - /* We need to produce the all-ones pattern for the width of the whole - resulting integer type. Use back and forth shifts for propagating - the lower 1. */ - tree signed_type = signed_type_for (dest_type); - tree signed_result = convert_to_integer (signed_type, expr); - - size_t result_width = int_size_in_bytes (dest_type) * BITS_PER_UNIT; - - tree shift_amount_cst - = build_int_cstu (signed_type, result_width - 1); - - tree shift_left_result - = build2 (LSHIFT_EXPR, signed_type, signed_result, shift_amount_cst); - - expr = build2 (RSHIFT_EXPR, signed_type, shift_left_result, - shift_amount_cst); - } - else if (SCALAR_FLOAT_TYPE_P (dest_type)) - { - expr = convert_to_real (dest_type, expr); - } - else if (VECTOR_TYPE_P (dest_type) - && (inst->sourceType & BRIG_TYPE_BASE_MASK) == BRIG_TYPE_F16) - { - /* Because F16 comparison is emulated as an F32 comparison with S32 - results, we must now truncate the result vector to S16s so it - fits to the destination register. We can build the target vector - type from the f16 storage type (unsigned ints). */ - expr = m_parent.m_cf->add_temp_var ("wide_cmp_result", expr); - tree_stl_vec wide_elements; - tree_stl_vec shrunk_elements; - m_parent.m_cf->unpack (expr, wide_elements); - for (size_t i = 0; i < wide_elements.size (); ++i) - { - tree wide = wide_elements.at (i); - shrunk_elements.push_back - (convert_to_integer (short_integer_type_node, wide)); - } - expr = m_parent.m_cf->pack (shrunk_elements); - } - build_output_assignment (*inst_base, operands[0], expr); - - return base->byteCount; -} diff --git a/gcc/brig/brigfrontend/brig-code-entry-handler.cc b/gcc/brig/brigfrontend/brig-code-entry-handler.cc deleted file mode 100644 index 7ead226576d..00000000000 --- a/gcc/brig/brigfrontend/brig-code-entry-handler.cc +++ /dev/null @@ -1,1305 +0,0 @@ -/* brig-code-entry-handler.cc -- a gccbrig base class - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3, or (at your option) any later - version. - - GCC is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - . */ - -#include "brig-code-entry-handler.h" - -#include "stringpool.h" -#include "tree-iterator.h" -#include "toplev.h" -#include "diagnostic.h" -#include "brig-machine.h" -#include "brig-util.h" -#include "errors.h" -#include "real.h" -#include "print-tree.h" -#include "tree-pretty-print.h" -#include "target.h" -#include "langhooks.h" -#include "gimple-expr.h" -#include "convert.h" -#include "brig-util.h" -#include "builtins.h" -#include "phsa.h" -#include "brig-builtins.h" -#include "fold-const.h" - -brig_code_entry_handler::brig_code_entry_handler (brig_to_generic &parent) - : brig_entry_handler (parent) -{ -} - -/* Build a tree operand which is a reference to a piece of code. REF is the - original reference as a BRIG object. */ - -tree -brig_code_entry_handler::build_code_ref (const BrigBase &ref) -{ - if (ref.kind == BRIG_KIND_DIRECTIVE_LABEL) - { - const BrigDirectiveLabel *brig_label = (const BrigDirectiveLabel *) &ref; - - const BrigData *label_name - = m_parent.get_brig_data_entry (brig_label->name); - - std::string label_str ((const char *) (label_name->bytes), - label_name->byteCount); - return m_parent.m_cf->label (label_str); - } - else if (ref.kind == BRIG_KIND_DIRECTIVE_FUNCTION) - { - const BrigDirectiveExecutable *func - = (const BrigDirectiveExecutable *) &ref; - return m_parent.function_decl (m_parent.get_mangled_name (func)); - } - else if (ref.kind == BRIG_KIND_DIRECTIVE_FBARRIER) - { - const BrigDirectiveFbarrier* fbar = (const BrigDirectiveFbarrier*)&ref; - - std::string var_name = m_parent.get_mangled_name (fbar); - uint64_t offset - = m_parent.m_cf->group_variable_segment_offset (var_name); - - tree local_offset = build_int_cst (uint32_type_node, offset); - if (m_parent.m_cf->m_local_group_variables.has_variable (var_name)) - local_offset - = build2 (PLUS_EXPR, uint64_type_node, local_offset, - convert (uint64_type_node, - m_parent.m_cf->m_group_local_offset_arg)); - return local_offset; - } - else - gcc_unreachable (); -} - -/* Produce a tree operand for the given BRIG_INST and its OPERAND. - OPERAND_TYPE should be the operand type in case it should not - be dictated by the BrigBase. IS_INPUT indicates if the operand - is an input operand or a result. */ - -tree -brig_code_entry_handler::build_tree_operand (const BrigInstBase &brig_inst, - const BrigBase &operand, - tree operand_type, bool is_input) -{ - switch (operand.kind) - { - case BRIG_KIND_OPERAND_OPERAND_LIST: - { - vec *constructor_vals = NULL; - const BrigOperandOperandList &oplist - = (const BrigOperandOperandList &) operand; - const BrigData *data = m_parent.get_brig_data_entry (oplist.elements); - size_t bytes = data->byteCount; - const BrigOperandOffset32_t *operand_ptr - = (const BrigOperandOffset32_t *) data->bytes; - while (bytes > 0) - { - BrigOperandOffset32_t offset = *operand_ptr; - const BrigBase *operand_element - = m_parent.get_brig_operand_entry (offset); - tree element - = build_tree_operand (brig_inst, *operand_element, operand_type); - - /* In case a vector is used an input, cast the elements to - correct size here so we don't need a separate unpack/pack for it. - fp16-fp32 conversion is done in build_operands (). */ - if (is_input && TREE_TYPE (element) != operand_type) - element = build_resize_convert_view (operand_type, element); - - CONSTRUCTOR_APPEND_ELT (constructor_vals, NULL_TREE, element); - ++operand_ptr; - bytes -= 4; - } - size_t element_count = data->byteCount / 4; - tree vec_type = build_vector_type (operand_type, element_count); - - return build_constructor (vec_type, constructor_vals); - } - case BRIG_KIND_OPERAND_CODE_LIST: - { - /* Build a TREE_VEC of code expressions. */ - - const BrigOperandCodeList &oplist - = (const BrigOperandCodeList &) operand; - const BrigData *data = m_parent.get_brig_data_entry (oplist.elements); - size_t bytes = data->byteCount; - const BrigOperandOffset32_t *operand_ptr - = (const BrigOperandOffset32_t *) data->bytes; - - size_t case_index = 0; - size_t element_count = data->byteCount / 4; - - /* Create a TREE_VEC out of the labels in the list. */ - tree vec = make_tree_vec (element_count); - - while (bytes > 0) - { - BrigOperandOffset32_t offset = *operand_ptr; - const BrigBase *ref = m_parent.get_brig_code_entry (offset); - tree element = build_code_ref (*ref); - - gcc_assert (case_index < element_count); - TREE_VEC_ELT (vec, case_index) = element; - case_index++; - - ++operand_ptr; - bytes -= 4; - } - return vec; - } - case BRIG_KIND_OPERAND_REGISTER: - { - const BrigOperandRegister *brig_reg - = (const BrigOperandRegister *) &operand; - return m_parent.m_cf->get_m_var_declfor_reg (brig_reg); - } - case BRIG_KIND_OPERAND_CONSTANT_BYTES: - { - const BrigOperandConstantBytes *brigConst - = (const BrigOperandConstantBytes *) &operand; - /* The constants can be of different type than the instruction - and are implicitly casted to the input operand. */ - return get_tree_cst_for_hsa_operand (brigConst, NULL_TREE); - } - case BRIG_KIND_OPERAND_WAVESIZE: - { - if (!INTEGRAL_TYPE_P (operand_type)) - { - gcc_unreachable (); - return NULL_TREE; - } - return build_int_cstu (operand_type, gccbrig_get_target_wavesize ()); - } - case BRIG_KIND_OPERAND_CODE_REF: - { - const BrigOperandCodeRef *brig_code_ref - = (const BrigOperandCodeRef *) &operand; - - const BrigBase *ref = m_parent.get_brig_code_entry (brig_code_ref->ref); - - return build_code_ref (*ref); - } - case BRIG_KIND_OPERAND_ADDRESS: - { - return build_address_operand (brig_inst, - (const BrigOperandAddress &) operand); - } - default: - gcc_unreachable (); - } -} - -/* Build a tree node representing an address reference from a BRIG_INST and its - ADDR_OPERAND. */ - -tree -brig_code_entry_handler::build_address_operand - (const BrigInstBase &brig_inst, const BrigOperandAddress &addr_operand) -{ - tree instr_type = gccbrig_tree_type_for_hsa_type (brig_inst.type); - - BrigSegment8_t segment = BRIG_SEGMENT_GLOBAL; - if (brig_inst.opcode == BRIG_OPCODE_LDA) - segment = ((const BrigInstAddr &) brig_inst).segment; - else if (brig_inst.base.kind == BRIG_KIND_INST_MEM) - segment = ((const BrigInstMem &) brig_inst).segment; - else if (brig_inst.base.kind == BRIG_KIND_INST_ATOMIC) - segment = ((const BrigInstAtomic &) brig_inst).segment; - - tree var_offset = NULL_TREE; - tree const_offset = NULL_TREE; - tree symbol_base = NULL_TREE; - - if (addr_operand.symbol != 0) - { - const BrigDirectiveVariable *arg_symbol - = (const BrigDirectiveVariable *) m_parent.get_brig_code_entry - (addr_operand.symbol); - - std::string var_name = m_parent.get_mangled_name (arg_symbol); - - if (segment == BRIG_SEGMENT_KERNARG) - { - /* Find the offset to the kernarg buffer for the given - kernel argument variable. */ - tree func = m_parent.m_cf->m_func_decl; - /* __args is the first parameter in kernel functions. */ - symbol_base = DECL_ARGUMENTS (func); - uint64_t offset = m_parent.m_cf->kernel_arg_offset (arg_symbol); - if (offset > 0) - const_offset = build_int_cst (size_type_node, offset); - } - else if (segment == BRIG_SEGMENT_GROUP) - { - uint64_t offset - = m_parent.m_cf->group_variable_segment_offset (var_name); - const_offset = build_int_cst (size_type_node, offset); - - /* If it's a local group variable reference, substract the local - group segment offset to get the group base ptr offset. */ - if (m_parent.m_cf->m_local_group_variables.has_variable (var_name)) - const_offset - = build2 (PLUS_EXPR, uint64_type_node, const_offset, - convert (uint64_type_node, - m_parent.m_cf->m_group_local_offset_arg)); - - } - else if (segment == BRIG_SEGMENT_PRIVATE || segment == BRIG_SEGMENT_SPILL) - { - uint32_t offset = m_parent.private_variable_segment_offset (var_name); - - /* Compute the offset to the work item's copy: - - single-wi-offset * local_size + wiflatid * varsize - - This way the work items have the same variable in - successive elements to each other in the segment, - helping to achieve autovectorization of loads/stores - with stride 1. */ - - tree_stl_vec uint32_0 - = tree_stl_vec (1, build_int_cst (uint32_type_node, 0)); - - tree_stl_vec uint32_1 - = tree_stl_vec (1, build_int_cst (uint32_type_node, 1)); - - tree_stl_vec uint32_2 - = tree_stl_vec (1, build_int_cst (uint32_type_node, 2)); - - tree local_size - = build2 (MULT_EXPR, uint32_type_node, - m_parent.m_cf->expand_or_call_builtin - (BRIG_OPCODE_WORKGROUPSIZE, BRIG_TYPE_U32, - uint32_type_node, uint32_0), - m_parent.m_cf->expand_or_call_builtin - (BRIG_OPCODE_WORKGROUPSIZE, BRIG_TYPE_U32, - uint32_type_node, uint32_1)); - - local_size - = build2 (MULT_EXPR, uint32_type_node, - m_parent.m_cf->expand_or_call_builtin - (BRIG_OPCODE_WORKGROUPSIZE, BRIG_TYPE_U32, - uint32_type_node, uint32_2), - local_size); - - tree var_region - = build2 (MULT_EXPR, uint32_type_node, - build_int_cst (uint32_type_node, offset), local_size); - - tree_stl_vec operands; - tree pos - = build2 (MULT_EXPR, uint32_type_node, - build_int_cst (uint32_type_node, - m_parent.private_variable_size (var_name)), - m_parent.m_cf->expand_or_call_builtin - (BRIG_OPCODE_WORKITEMFLATID, BRIG_TYPE_U32, - uint32_type_node, operands)); - - tree var_offset - = build2 (PLUS_EXPR, uint32_type_node, var_region, pos); - - /* In case of LDA this is returned directly as an integer value. - For other mem-related instructions, we will convert this segment - offset to a flat address by adding it as an offset to a (private - or group) base pointer later on. Same applies to group_var_offset. */ - symbol_base - = m_parent.m_cf->add_temp_var ("priv_var_offset", - convert (size_type_node, - var_offset)); - } - else if (segment == BRIG_SEGMENT_ARG) - { - tree arg_var_decl; - if (m_parent.m_cf->m_ret_value_brig_var == arg_symbol) - arg_var_decl = m_parent.m_cf->m_ret_temp; - else - arg_var_decl = m_parent.m_cf->arg_variable (arg_symbol); - - gcc_assert (arg_var_decl != NULL_TREE); - - tree ptype = build_pointer_type (instr_type); - - if (arg_symbol->type & BRIG_TYPE_ARRAY) - { - - /* Two different type of array references in case of arguments - depending where they are referred at. In the caller (argument - segment), the reference is to an array object and - in the callee, the array object has been passed as a pointer - to the array object. */ - - if (POINTER_TYPE_P (TREE_TYPE (arg_var_decl))) - symbol_base = build_resize_convert_view (ptype, arg_var_decl); - else - { - /* In case we are referring to an array (the argument in - call site), use its element zero as the base address. */ - tree element_zero - = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (arg_var_decl)), - arg_var_decl, integer_zero_node, NULL_TREE, - NULL_TREE); - symbol_base = build1 (ADDR_EXPR, ptype, element_zero); - } - } - else - symbol_base = build1 (ADDR_EXPR, ptype, arg_var_decl); - } - else - { - tree global_var_decl = m_parent.global_variable (var_name); - - /* In case the global variable hasn't been defined (yet), - use the host def indirection ptr variable. */ - if (global_var_decl == NULL_TREE) - { - std::string host_ptr_name - = std::string (PHSA_HOST_DEF_PTR_PREFIX) + var_name; - tree host_defined_ptr = m_parent.global_variable (host_ptr_name); - gcc_assert (host_defined_ptr != NULL_TREE); - symbol_base = host_defined_ptr; - } - else - { - gcc_assert (global_var_decl != NULL_TREE); - - tree ptype = build_pointer_type (instr_type); - symbol_base = build1 (ADDR_EXPR, ptype, global_var_decl); - } - } - } - - if (brig_inst.opcode != BRIG_OPCODE_LDA) - { - /* In case of lda_* we want to return the segment address because it's - used as a value, perhaps in address computation and later converted - explicitly to a flat address. - - In case of other instructions with memory operands we produce the flat - address directly here (assuming the target does not have a separate - address space for group/private segments for now). */ - if (segment == BRIG_SEGMENT_GROUP) - symbol_base = m_parent.m_cf->m_group_base_arg; - else if (segment == BRIG_SEGMENT_PRIVATE - || segment == BRIG_SEGMENT_SPILL) - { - if (symbol_base != NULL_TREE) - symbol_base = build2 (POINTER_PLUS_EXPR, ptr_type_node, - m_parent.m_cf->m_private_base_arg, - symbol_base); - else - symbol_base = m_parent.m_cf->m_private_base_arg; - } - } - - if (addr_operand.reg != 0) - { - const BrigOperandRegister *mem_base_reg - = (const BrigOperandRegister *) m_parent.get_brig_operand_entry - (addr_operand.reg); - tree base_reg_var = m_parent.m_cf->get_m_var_declfor_reg (mem_base_reg); - tree as_uint = build_reinterpret_to_uint (base_reg_var); - var_offset = convert_to_pointer (ptr_type_node, as_uint); - - gcc_assert (var_offset != NULL_TREE); - } - /* The pointer type we use to access the memory. Should be of the - width of the load/store instruction, not the target/data - register. */ - tree ptype = build_pointer_type (instr_type); - - gcc_assert (ptype != NULL_TREE); - - tree addr = NULL_TREE; - if (symbol_base != NULL_TREE && var_offset != NULL_TREE) - /* The most complex addressing mode: symbol + reg [+ const offset]. */ - addr = build2 (POINTER_PLUS_EXPR, ptr_type_node, - convert (ptr_type_node, symbol_base), - convert (size_type_node, var_offset)); - else if (var_offset != NULL) - addr = var_offset; - else if (symbol_base != NULL) - addr = symbol_base; - - if (const_offset != NULL_TREE) - { - if (addr == NULL_TREE) - /* At least direct module-scope global group symbol access with LDA - has only the const_offset. Group base ptr is not added as LDA should - return the segment address, not the flattened one. */ - addr = const_offset; - else - addr = build2 (POINTER_PLUS_EXPR, ptr_type_node, - addr, convert (size_type_node, const_offset)); - } - - /* We might have two const offsets in case of group or private arrays - which have the first offset to the incoming group/private pointer - arg, and the second one an offset to it. It's also legal to have - a reference with a zero constant offset but no symbol. I've seen - codes that reference kernarg segment like this. Thus, if at this - point there is no address expression at all we assume it's an - access to offset 0. */ - uint64_t offs = gccbrig_to_uint64_t (addr_operand.offset); - if (offs > 0 || addr == NULL_TREE) - { - /* In large mode, the offset is treated as 32bits unless it's - global, readonly or kernarg address space. - See: - http://www.hsafoundation.com/html_spec111/HSA_Library.htm - #PRM/Topics/02_ProgModel/small_and_large_machine_models.htm - #table_machine_model_data_sizes */ - - int is64b_offset = segment == BRIG_SEGMENT_GLOBAL - || segment == BRIG_SEGMENT_READONLY - || segment == BRIG_SEGMENT_KERNARG; - - /* The original offset is signed and should be sign - extended for the pointer arithmetics. */ - tree const_offset_2 = is64b_offset - ? build_int_cst (size_type_node, offs) - : convert (long_integer_type_node, - build_int_cst (integer_type_node, offs)); - - if (addr == NULL_TREE) - addr = const_offset_2; - else - addr = build2 (POINTER_PLUS_EXPR, ptr_type_node, - /* Addr can be a constant offset in case this is - a private array access. */ - convert (ptr_type_node, addr), - convert (size_type_node, const_offset_2)); - } - - gcc_assert (addr != NULL_TREE); - return convert_to_pointer (ptype, addr); -} - -/* Builds a tree operand with the given OPERAND_INDEX for the given - BRIG_INST with the desired tree OPERAND_TYPE. OPERAND_TYPE can - be NULL in case the type is forced by the BRIG_INST type. */ - -tree -brig_code_entry_handler::build_tree_operand_from_brig - (const BrigInstBase *brig_inst, tree operand_type, size_t operand_index) -{ - const BrigData *operand_entries - = m_parent.get_brig_data_entry (brig_inst->operands); - - uint32_t operand_offset - = ((const uint32_t *) &operand_entries->bytes)[operand_index]; - const BrigBase *operand_data - = m_parent.get_brig_operand_entry (operand_offset); - - bool inputp = !gccbrig_hsa_opcode_op_output_p (brig_inst->opcode, - operand_index); - return build_tree_operand (*brig_inst, *operand_data, operand_type, inputp); -} - -/* Builds a single (scalar) constant initialized element of type - ELEMENT_TYPE from the buffer pointed to by NEXT_DATA. */ - -tree -brig_code_entry_handler::build_tree_cst_element - (BrigType16_t element_type, const unsigned char *next_data) const -{ - - tree tree_element_type = gccbrig_tree_type_for_hsa_type (element_type); - - tree cst; - switch (element_type) - { - case BRIG_TYPE_F16: - { - HOST_WIDE_INT low = *(const uint16_t *) next_data; - cst = build_int_cst (uint16_type_node, low); - break; - } - case BRIG_TYPE_F32: - { - REAL_VALUE_TYPE val; - ieee_single_format.decode (&ieee_single_format, &val, - (const long *) next_data); - cst = build_real (tree_element_type, val); - break; - } - case BRIG_TYPE_F64: - { - long data[2]; - data[0] = *(const uint32_t *) next_data; - data[1] = *(const uint32_t *) (next_data + 4); - REAL_VALUE_TYPE val; - ieee_double_format.decode (&ieee_double_format, &val, data); - cst = build_real (tree_element_type, val); - break; - } - case BRIG_TYPE_S8: - case BRIG_TYPE_S16: - case BRIG_TYPE_S32: - case BRIG_TYPE_S64: - { - HOST_WIDE_INT low = *(const int64_t *) next_data; - cst = build_int_cst (tree_element_type, low); - break; - } - case BRIG_TYPE_U8: - case BRIG_TYPE_U16: - case BRIG_TYPE_U32: - case BRIG_TYPE_U64: - { - unsigned HOST_WIDE_INT low = *(const uint64_t *) next_data; - cst = build_int_cstu (tree_element_type, low); - break; - } - case BRIG_TYPE_SIG64: - { - unsigned HOST_WIDE_INT low = *(const uint64_t *) next_data; - cst = build_int_cstu (uint64_type_node, low); - break; - } - case BRIG_TYPE_SIG32: - { - unsigned HOST_WIDE_INT low = *(const uint64_t *) next_data; - cst = build_int_cstu (uint32_type_node, low); - break; - } - default: - gcc_unreachable (); - return NULL_TREE; - } - return cst; -} - -/* Produce a tree constant type for the given BRIG constant (BRIG_CONST). - TYPE should be the forced instruction type, otherwise the type is - dictated by the BRIG_CONST. */ - -tree -brig_code_entry_handler::get_tree_cst_for_hsa_operand - (const BrigOperandConstantBytes *brig_const, tree type) const -{ - const BrigData *data = m_parent.get_brig_data_entry (brig_const->bytes); - - tree cst = NULL_TREE; - - if (type == NULL_TREE) - type = gccbrig_tree_type_for_hsa_type (brig_const->type); - - /* The type of a single (scalar) element inside an array, - vector or an array of vectors. */ - BrigType16_t scalar_element_type - = brig_const->type & BRIG_TYPE_BASE_MASK; - tree tree_element_type = type; - - vec *constructor_vals = NULL; - - if (TREE_CODE (type) == ARRAY_TYPE) - tree_element_type = TREE_TYPE (type); - - size_t bytes_left = data->byteCount; - const unsigned char *next_data = data->bytes; - size_t scalar_element_size - = gccbrig_hsa_type_bit_size (scalar_element_type) / BITS_PER_UNIT; - - while (bytes_left > 0) - { - if (VECTOR_TYPE_P (tree_element_type)) - { - /* In case of vector type elements (or sole vectors), - create a vector ctor. */ - size_t element_count - = gccbrig_type_vector_subparts (tree_element_type); - if (bytes_left < scalar_element_size * element_count) - fatal_error (UNKNOWN_LOCATION, - "Not enough bytes left for the initializer " - "(%lu need %lu).", (unsigned long) bytes_left, - (unsigned long) (scalar_element_size - * element_count)); - - vec *vec_els = NULL; - for (size_t i = 0; i < element_count; ++i) - { - tree element - = build_tree_cst_element (scalar_element_type, next_data); - CONSTRUCTOR_APPEND_ELT (vec_els, NULL_TREE, element); - bytes_left -= scalar_element_size; - next_data += scalar_element_size; - } - cst = build_vector_from_ctor (tree_element_type, vec_els); - } - else - { - if (bytes_left < scalar_element_size) - fatal_error (UNKNOWN_LOCATION, - "Not enough bytes left for the initializer " - "(%lu need %lu).", (unsigned long) bytes_left, - (unsigned long) scalar_element_size); - cst = build_tree_cst_element (scalar_element_type, next_data); - bytes_left -= scalar_element_size; - next_data += scalar_element_size; - } - CONSTRUCTOR_APPEND_ELT (constructor_vals, NULL_TREE, cst); - } - - if (TREE_CODE (type) == ARRAY_TYPE) - return build_constructor (type, constructor_vals); - else - return cst; -} - -/* Return the matching tree instruction arithmetics type for the - given BRIG_TYPE. The aritmethics type is the one with which - computation is done (in contrast to the storage type). F16 - arithmetics type is emulated using F32 for now. */ - -tree -brig_code_entry_handler::get_tree_expr_type_for_hsa_type - (BrigType16_t brig_type) const -{ - BrigType16_t brig_inner_type = brig_type & BRIG_TYPE_BASE_MASK; - if (brig_inner_type == BRIG_TYPE_F16) - { - if (brig_inner_type == brig_type) - return m_parent.s_fp32_type; - size_t element_count = gccbrig_hsa_type_bit_size (brig_type) / 16; - return build_vector_type (m_parent.s_fp32_type, element_count); - } - else - return gccbrig_tree_type_for_hsa_type (brig_type); -} - -/* Return the correct GENERIC type for storing comparison results - of operand with the type given in SOURCE_TYPE. */ - -tree -brig_code_entry_handler::get_comparison_result_type (tree source_type) -{ - if (VECTOR_TYPE_P (source_type)) - { - size_t element_size = int_size_in_bytes (TREE_TYPE (source_type)); - return build_vector_type - (build_nonstandard_boolean_type (element_size * BITS_PER_UNIT), - gccbrig_type_vector_subparts (source_type)); - } - else - return gccbrig_tree_type_for_hsa_type (BRIG_TYPE_B1); -} - -/* Creates a FP32 to FP16 conversion call, assuming the source and destination - are FP32 type variables. */ - -tree -brig_code_entry_handler::build_f2h_conversion (tree source) -{ - return float_to_half () (*this, source); -} - -/* Creates a FP16 to FP32 conversion call, assuming the source and destination - are FP32 type variables. */ - -tree -brig_code_entry_handler::build_h2f_conversion (tree source) -{ - return half_to_float () (*this, source); -} - -/* Builds and "normalizes" the dest and source operands for the instruction - execution; converts the input operands to the expected instruction type, - performs half to float conversions, constant to correct type variable, - and flush to zero (if applicable). */ - -tree_stl_vec -brig_code_entry_handler::build_operands (const BrigInstBase &brig_inst) -{ - return build_or_analyze_operands (brig_inst, false); -} - -void -brig_code_entry_handler::analyze_operands (const BrigInstBase &brig_inst) -{ - build_or_analyze_operands (brig_inst, true); -} - -/* Implements both the build_operands () and analyze_operands () call - so changes go in tandem. Performs build_operands () when ANALYZE - is false. Otherwise, only analyze operands and return empty - list. - - If analyzing record each HSA register operand with the - corresponding resolved operand tree type to - brig_to_generic::m_fn_regs_use_index. */ - -tree_stl_vec -brig_code_entry_handler:: -build_or_analyze_operands (const BrigInstBase &brig_inst, bool analyze) -{ - /* Flush to zero. */ - bool ftz = false; - const BrigBase *base = &brig_inst.base; - - if (base->kind == BRIG_KIND_INST_MOD) - { - const BrigInstMod *mod = (const BrigInstMod *) base; - ftz = mod->modifier & BRIG_ALU_FTZ; - } - else if (base->kind == BRIG_KIND_INST_CMP) - { - const BrigInstCmp *cmp = (const BrigInstCmp *) base; - ftz = cmp->modifier & BRIG_ALU_FTZ; - } - - bool is_vec_instr = hsa_type_packed_p (brig_inst.type); - - size_t element_count; - if (is_vec_instr) - { - BrigType16_t brig_element_type = brig_inst.type & BRIG_TYPE_BASE_MASK; - element_count = gccbrig_hsa_type_bit_size (brig_inst.type) - / gccbrig_hsa_type_bit_size (brig_element_type); - } - else - element_count = 1; - - bool is_fp16_arith = false; - - tree src_type; - tree dest_type; - if (base->kind == BRIG_KIND_INST_CMP) - { - const BrigInstCmp *cmp_inst = (const BrigInstCmp *) base; - src_type = gccbrig_tree_type_for_hsa_type (cmp_inst->sourceType); - dest_type = gccbrig_tree_type_for_hsa_type (brig_inst.type); - is_fp16_arith - = (cmp_inst->sourceType & BRIG_TYPE_BASE_MASK) == BRIG_TYPE_F16; - } - else if (base->kind == BRIG_KIND_INST_SOURCE_TYPE) - { - const BrigInstSourceType *src_type_inst - = (const BrigInstSourceType *) base; - src_type = gccbrig_tree_type_for_hsa_type (src_type_inst->sourceType); - dest_type = gccbrig_tree_type_for_hsa_type (brig_inst.type); - is_fp16_arith - = (src_type_inst->sourceType & BRIG_TYPE_BASE_MASK) == BRIG_TYPE_F16 - && !gccbrig_is_bit_operation (brig_inst.opcode); - } - else if (base->kind == BRIG_KIND_INST_SEG_CVT) - { - const BrigInstSegCvt *seg_cvt_inst = (const BrigInstSegCvt *) base; - src_type = gccbrig_tree_type_for_hsa_type (seg_cvt_inst->sourceType); - dest_type = gccbrig_tree_type_for_hsa_type (brig_inst.type); - } - else if (base->kind == BRIG_KIND_INST_MEM) - { - src_type = gccbrig_tree_type_for_hsa_type (brig_inst.type); - dest_type = src_type; - /* With mem instructions we don't want to cast the fp16 - back and forth between fp32, because the load/stores - are not specific to the data type. */ - is_fp16_arith = false; - } - else if (base->kind == BRIG_KIND_INST_CVT) - { - const BrigInstCvt *cvt_inst = (const BrigInstCvt *) base; - - src_type = gccbrig_tree_type_for_hsa_type (cvt_inst->sourceType); - dest_type = gccbrig_tree_type_for_hsa_type (brig_inst.type); - } - else - { - switch (brig_inst.opcode) - { - case BRIG_OPCODE_INITFBAR: - case BRIG_OPCODE_JOINFBAR: - case BRIG_OPCODE_WAITFBAR: - case BRIG_OPCODE_ARRIVEFBAR: - case BRIG_OPCODE_LEAVEFBAR: - case BRIG_OPCODE_RELEASEFBAR: - src_type = uint32_type_node; - break; - default: - src_type = gccbrig_tree_type_for_hsa_type (brig_inst.type); - break; - } - dest_type = src_type; - is_fp16_arith - = !gccbrig_is_bit_operation (brig_inst.opcode) - && (brig_inst.type & BRIG_TYPE_BASE_MASK) == BRIG_TYPE_F16; - } - - /* Halfs are a tricky special case: their "storage format" is u16, but - scalars are stored in 32b regs while packed f16 are... well packed. */ - tree half_storage_type = element_count > 1 - ? gccbrig_tree_type_for_hsa_type (brig_inst.type) - : uint32_type_node; - - const BrigData *operand_entries - = m_parent.get_brig_data_entry (brig_inst.operands); - std::vector operands; - for (size_t i = 0; i < operand_entries->byteCount / 4; ++i) - { - uint32_t operand_offset = ((const uint32_t *) &operand_entries->bytes)[i]; - const BrigBase *operand_data - = m_parent.get_brig_operand_entry (operand_offset); - - const bool is_output - = gccbrig_hsa_opcode_op_output_p (brig_inst.opcode, i); - - tree operand_type = is_output ? dest_type : src_type; - - bool half_to_float = is_fp16_arith; - - /* Special cases for operand types. */ - if ((brig_inst.opcode == BRIG_OPCODE_SHL - || brig_inst.opcode == BRIG_OPCODE_SHR) - && i == 2) - /* The shift amount is always a scalar. */ - operand_type - = VECTOR_TYPE_P (src_type) ? TREE_TYPE (src_type) : src_type; - else if (brig_inst.opcode == BRIG_OPCODE_SHUFFLE) - { - if (i == 3) - /* HSAIL shuffle inputs the MASK vector as tightly packed bits - while GENERIC VEC_PERM_EXPR expects the mask elements to be - of the same size as the elements in the input vectors. Let's - cast to a scalar type here and convert to the VEC_PERM_EXPR - format in instruction handling. There are no arbitrary bit - width int types in GENERIC so we cannot use the original - vector type. */ - operand_type = uint32_type_node; - else - /* Always treat the element as unsigned ints to avoid - sign extensions/negative offsets with masks, which - are expected to be of the same element type as the - data in VEC_PERM_EXPR. With shuffles the data type - should not matter as it's a "raw operation". */ - operand_type = get_unsigned_int_type (operand_type); - } - else if (brig_inst.opcode == BRIG_OPCODE_PACK) - { - if (i == 1) - operand_type = get_unsigned_int_type (dest_type); - else if (i == 2) - operand_type = get_unsigned_int_type (TREE_TYPE (dest_type)); - else if (i == 3) - operand_type = uint32_type_node; - } - else if (brig_inst.opcode == BRIG_OPCODE_UNPACK && i == 2) - operand_type = uint32_type_node; - else if (brig_inst.opcode == BRIG_OPCODE_SAD && i == 3) - operand_type = uint32_type_node; - else if (brig_inst.opcode == BRIG_OPCODE_CLASS && i == 2) - { - operand_type = uint32_type_node; - half_to_float = false; - } - else if (brig_inst.opcode == BRIG_OPCODE_ACTIVELANEPERMUTE && i == 4) - { - operand_type = uint32_type_node; - } - else if (half_to_float) - /* Treat the operands as the storage type at this point. */ - operand_type = half_storage_type; - - if (analyze) - { - if (operand_data->kind == BRIG_KIND_OPERAND_REGISTER) - { - const BrigOperandRegister &brig_reg - = (const BrigOperandRegister &) *operand_data; - m_parent.add_reg_used_as_type (brig_reg, operand_type); - } - continue; - } - - tree operand = build_tree_operand (brig_inst, *operand_data, operand_type, - !is_output); - gcc_assert (operand); - - /* Cast/convert the inputs to correct types as expected by the GENERIC - opcode instruction. */ - if (!is_output) - { - if (half_to_float) - operand = build_h2f_conversion - (build_resize_convert_view (half_storage_type, operand)); - else if (TREE_CODE (operand) != LABEL_DECL - && TREE_CODE (operand) != TREE_VEC - && operand_data->kind != BRIG_KIND_OPERAND_ADDRESS - && operand_data->kind != BRIG_KIND_OPERAND_OPERAND_LIST) - { - operand = build_resize_convert_view (operand_type, operand); - } - else if (brig_inst.opcode == BRIG_OPCODE_SHUFFLE) - /* Force the operand type to be treated as the raw type. */ - operand = build_resize_convert_view (operand_type, operand); - - if (brig_inst.opcode == BRIG_OPCODE_CMOV && i == 1) - { - /* gcc expects the lower bit to be 1 (or all ones in case of - vectors) while CMOV assumes false iff 0. Convert the input - here to what gcc likes by generating - 'operand = operand != 0'. */ - tree cmp_res_type = get_comparison_result_type (operand_type); - operand = build2 (NE_EXPR, cmp_res_type, operand, - build_zero_cst (TREE_TYPE (operand))); - } - - if (ftz) - operand = flush_to_zero (is_fp16_arith) (*this, operand); - } - operands.push_back (operand); - } - return operands; -} - -/* Build the GENERIC for assigning the result of an instruction to the result - "register" (variable). BRIG_INST is the original brig instruction, - OUTPUT the result variable/register, INST_EXPR the one producing the - result. Required bitcasts and fp32 to fp16 conversions are added as - well. */ - -tree -brig_code_entry_handler::build_output_assignment (const BrigInstBase &brig_inst, - tree output, tree inst_expr) -{ - /* The result/input type might be different from the output register - variable type (can be any type; see get_m_var_declfor_reg @ - brig-function.cc). */ - tree output_type = TREE_TYPE (output); - bool is_fp16 = (brig_inst.type & BRIG_TYPE_BASE_MASK) == BRIG_TYPE_F16 - && brig_inst.base.kind != BRIG_KIND_INST_MEM - && !gccbrig_is_bit_operation (brig_inst.opcode); - - /* Flush to zero. */ - bool ftz = false; - const BrigBase *base = &brig_inst.base; - - if (m_parent.m_cf->is_id_val (inst_expr)) - inst_expr = m_parent.m_cf->id_val (inst_expr); - - tree input_type = TREE_TYPE (inst_expr); - - m_parent.m_cf->add_reg_var_update (output, inst_expr); - - if (base->kind == BRIG_KIND_INST_MOD) - { - const BrigInstMod *mod = (const BrigInstMod *) base; - ftz = mod->modifier & BRIG_ALU_FTZ; - } - else if (base->kind == BRIG_KIND_INST_CMP) - { - const BrigInstCmp *cmp = (const BrigInstCmp *) base; - ftz = cmp->modifier & BRIG_ALU_FTZ; - } - - if (TREE_CODE (inst_expr) == CALL_EXPR) - { - tree func_decl = TREE_OPERAND (TREE_OPERAND (inst_expr, 1), 0); - input_type = TREE_TYPE (TREE_TYPE (func_decl)); - } - - if (ftz && (VECTOR_FLOAT_TYPE_P (TREE_TYPE (inst_expr)) - || SCALAR_FLOAT_TYPE_P (TREE_TYPE (inst_expr)) || is_fp16)) - { - /* Ensure we don't duplicate the arithmetics to the arguments of the bit - field reference operators. */ - inst_expr = m_parent.m_cf->add_temp_var ("before_ftz", inst_expr); - inst_expr = flush_to_zero (is_fp16) (*this, inst_expr); - } - - if (is_fp16) - { - inst_expr = m_parent.m_cf->add_temp_var ("before_f2h", inst_expr); - tree f2h_output = build_f2h_conversion (inst_expr); - tree conv = build_resize_convert_view (output_type, f2h_output); - tree assign = build2 (MODIFY_EXPR, output_type, output, conv); - m_parent.m_cf->append_statement (assign); - return assign; - } - else if (VECTOR_TYPE_P (output_type) && TREE_CODE (output) == CONSTRUCTOR) - { - /* Expand/unpack the input value to the given vector elements. */ - size_t i; - tree input = inst_expr; - tree element_type = gccbrig_tree_type_for_hsa_type (brig_inst.type); - tree element; - tree last_assign = NULL_TREE; - FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (output), i, element) - { - tree element_ref - = build3 (BIT_FIELD_REF, element_type, input, - TYPE_SIZE (element_type), - bitsize_int (i * int_size_in_bytes (element_type) - * BITS_PER_UNIT)); - - last_assign - = build_output_assignment (brig_inst, element, element_ref); - } - return last_assign; - } - else - { - /* All we do here is to bitcast the result and store it to the - 'register' (variable). Mainly need to take care of differing - bitwidths. */ - size_t src_width = int_size_in_bytes (input_type); - size_t dst_width = int_size_in_bytes (output_type); - tree input = inst_expr; - /* Integer results are extended to the target register width, using - the same sign as the inst_expr. */ - if (INTEGRAL_TYPE_P (TREE_TYPE (input)) && src_width != dst_width) - { - bool unsigned_p = TYPE_UNSIGNED (TREE_TYPE (input)); - tree resized_type - = build_nonstandard_integer_type (dst_width * BITS_PER_UNIT, - unsigned_p); - input = convert_to_integer (resized_type, input); - } - input = build_resize_convert_view (output_type, input); - tree assign = build2 (MODIFY_EXPR, output_type, output, input); - m_parent.m_cf->append_statement (assign); - return assign; - } - return NULL_TREE; -} - -/* Appends a GENERIC statement (STMT) to the currently constructed function. */ - -void -brig_code_entry_handler::append_statement (tree stmt) -{ - m_parent.m_cf->append_statement (stmt); -} - -/* Visits the element(s) in the OPERAND, calling HANDLER to each of them. */ - -tree -tree_element_unary_visitor::operator () (brig_code_entry_handler &handler, - tree operand) -{ - if (VECTOR_TYPE_P (TREE_TYPE (operand))) - { - size_t vec_size = int_size_in_bytes (TREE_TYPE (operand)); - size_t element_size = int_size_in_bytes (TREE_TYPE (TREE_TYPE (operand))); - size_t element_count = vec_size / element_size; - - tree input_element_type = TREE_TYPE (TREE_TYPE (operand)); - tree output_element_type = NULL_TREE; - - vec *constructor_vals = NULL; - for (size_t i = 0; i < element_count; ++i) - { - tree element = build3 (BIT_FIELD_REF, input_element_type, operand, - TYPE_SIZE (input_element_type), - bitsize_int (i * element_size - * BITS_PER_UNIT)); - - tree output = visit_element (handler, element); - output_element_type = TREE_TYPE (output); - - CONSTRUCTOR_APPEND_ELT (constructor_vals, NULL_TREE, output); - } - - tree vec_type = build_vector_type (output_element_type, element_count); - - /* build_constructor creates a vector type which is not a vector_cst - that requires compile time constant elements. */ - tree vec = build_constructor (vec_type, constructor_vals); - - /* Add a temp variable for readability. */ - tree tmp_var = create_tmp_var (vec_type, "vec_out"); - tree vec_tmp_assign - = build2 (MODIFY_EXPR, TREE_TYPE (tmp_var), tmp_var, vec); - handler.append_statement (vec_tmp_assign); - return tmp_var; - } - else - return visit_element (handler, operand); -} - -/* Visits the element pair(s) in the OPERAND0 and OPERAND1, calling HANDLER - to each of them. */ - -tree -tree_element_binary_visitor::operator () (brig_code_entry_handler &handler, - tree operand0, tree operand1) -{ - if (VECTOR_TYPE_P (TREE_TYPE (operand0))) - { - gcc_assert (VECTOR_TYPE_P (TREE_TYPE (operand1))); - size_t vec_size = int_size_in_bytes (TREE_TYPE (operand0)); - size_t element_size - = int_size_in_bytes (TREE_TYPE (TREE_TYPE (operand0))); - size_t element_count = vec_size / element_size; - - tree input_element_type = TREE_TYPE (TREE_TYPE (operand0)); - tree output_element_type = NULL_TREE; - - vec *constructor_vals = NULL; - for (size_t i = 0; i < element_count; ++i) - { - - tree element0 = build3 (BIT_FIELD_REF, input_element_type, operand0, - TYPE_SIZE (input_element_type), - bitsize_int (i * element_size - * BITS_PER_UNIT)); - - tree element1 = build3 (BIT_FIELD_REF, input_element_type, operand1, - TYPE_SIZE (input_element_type), - bitsize_int (i * element_size - * BITS_PER_UNIT)); - - tree output = visit_element (handler, element0, element1); - output_element_type = TREE_TYPE (output); - - CONSTRUCTOR_APPEND_ELT (constructor_vals, NULL_TREE, output); - } - - tree vec_type = build_vector_type (output_element_type, element_count); - - /* build_constructor creates a vector type which is not a vector_cst - that requires compile time constant elements. */ - tree vec = build_constructor (vec_type, constructor_vals); - - /* Add a temp variable for readability. */ - tree tmp_var = create_tmp_var (vec_type, "vec_out"); - tree vec_tmp_assign - = build2 (MODIFY_EXPR, TREE_TYPE (tmp_var), tmp_var, vec); - handler.append_statement (vec_tmp_assign); - return tmp_var; - } - else - return visit_element (handler, operand0, operand1); -} - -/* Generates GENERIC code that flushes the visited element to zero. */ - -tree -flush_to_zero::visit_element (brig_code_entry_handler &, tree operand) -{ - size_t size = int_size_in_bytes (TREE_TYPE (operand)); - if (size == 4) - { - tree built_in - = (m_fp16) ? builtin_decl_explicit (BUILT_IN_HSAIL_FTZ_F32_F16) : - builtin_decl_explicit (BUILT_IN_HSAIL_FTZ_F32); - - return call_builtin (built_in, 1, float_type_node, float_type_node, - operand); - } - else if (size == 8) - { - return call_builtin (builtin_decl_explicit (BUILT_IN_HSAIL_FTZ_F64), 1, - double_type_node, double_type_node, operand); - } - else - gcc_unreachable (); - return NULL_TREE; -} - -/* Generates GENERIC code that converts a single precision float to half - precision float. */ - -tree -float_to_half::visit_element (brig_code_entry_handler &caller, tree operand) -{ - tree built_in = builtin_decl_explicit (BUILT_IN_HSAIL_F32_TO_F16); - - tree casted_operand = build_resize_convert_view (uint32_type_node, operand); - - tree call = call_builtin (built_in, 1, uint16_type_node, uint32_type_node, - casted_operand); - tree output - = create_tmp_var (TREE_TYPE (TREE_TYPE (built_in)), "fp16out"); - tree assign = build2 (MODIFY_EXPR, TREE_TYPE (output), output, call); - caller.append_statement (assign); - return output; -} - -/* Generates GENERIC code that converts a half precision float to single - precision float. */ - -tree -half_to_float::visit_element (brig_code_entry_handler &caller, tree operand) -{ - tree built_in = builtin_decl_explicit (BUILT_IN_HSAIL_F16_TO_F32); - tree truncated_source = convert_to_integer (uint16_type_node, operand); - - tree call - = call_builtin (built_in, 1, uint32_type_node, uint16_type_node, - truncated_source); - - tree const_fp32_type - = build_type_variant (brig_to_generic::s_fp32_type, 1, 0); - - tree output = create_tmp_var (const_fp32_type, "fp32out"); - tree casted_result - = build_resize_convert_view (brig_to_generic::s_fp32_type, call); - - tree assign = build2 (MODIFY_EXPR, TREE_TYPE (output), output, casted_result); - - caller.append_statement (assign); - - return output; -} - -/* Treats the INPUT as SRC_TYPE and sign or zero extends it to DEST_TYPE. */ - -tree -brig_code_entry_handler::extend_int (tree input, tree dest_type, tree src_type) -{ - /* Extend integer conversions according to the destination's - ext mode. First we need to clip the input register to - the possible smaller integer size to ensure the correct sign - bit is extended. */ - tree clipped_input = convert_to_integer (src_type, input); - tree conversion_result; - - if (TYPE_UNSIGNED (src_type)) - conversion_result - = convert_to_integer (unsigned_type_for (dest_type), clipped_input); - else - conversion_result - = convert_to_integer (signed_type_for (dest_type), clipped_input); - - /* Treat the result as unsigned so we do not sign extend to the - register width. For some reason this GENERIC sequence sign - extends to the s register: - - D.1541 = (signed char) s1; - D.1542 = (signed short) D.1541; - s0 = (unsigned int) D.1542 - */ - - /* The converted result is then extended to the target register - width, using the same sign as the destination. */ - return convert_to_integer (dest_type, conversion_result); -} - -/* Returns the integer constant value of the given node. - If it's a cast, looks into the source of the cast. */ -HOST_WIDE_INT -brig_code_entry_handler::int_constant_value (tree node) -{ - tree n = node; - if (TREE_CODE (n) == VIEW_CONVERT_EXPR) - n = TREE_OPERAND (n, 0); - return int_cst_value (n); -} diff --git a/gcc/brig/brigfrontend/brig-code-entry-handler.h b/gcc/brig/brigfrontend/brig-code-entry-handler.h deleted file mode 100644 index e8308f77970..00000000000 --- a/gcc/brig/brigfrontend/brig-code-entry-handler.h +++ /dev/null @@ -1,410 +0,0 @@ -/* brig-code-entry-handler.h -- a gccbrig base class - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3, or (at your option) any later - version. - - GCC is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - . */ - -#ifndef GCC_BRIG_CODE_ENTRY_HANDLER_H -#define GCC_BRIG_CODE_ENTRY_HANDLER_H - -#include "brig-to-generic.h" - -#include -#include - -class tree_element_unary_visitor; - -/* An interface to organize the different types of element handlers - for the code section. */ - -class brig_code_entry_handler : public brig_entry_handler -{ -public: - brig_code_entry_handler (brig_to_generic &parent); - - /* Handles the brig_code data at the given pointer and adds it to the - currently built tree. Returns the number of consumed bytes. */ - - virtual size_t operator () (const BrigBase *base) = 0; - - void append_statement (tree stmt); - -protected: - - tree get_tree_expr_type_for_hsa_type (BrigType16_t brig_type) const; - tree get_tree_cst_for_hsa_operand (const BrigOperandConstantBytes *brigConst, - tree type) const; - tree get_comparison_result_type (tree source_type); - - tree build_code_ref (const BrigBase &ref); - - tree build_tree_operand (const BrigInstBase &brig_inst, - const BrigBase &operand, - tree operand_type = NULL_TREE, - bool is_input = false); - - tree build_address_operand (const BrigInstBase &brig_inst, - const BrigOperandAddress &addr_operand); - - tree build_tree_operand_from_brig (const BrigInstBase *brig_inst, - tree operand_type, size_t operand_index); - - tree build_tree_cst_element (BrigType16_t element_type, - const unsigned char *next_data) const; - - bool needs_workitem_context_data (BrigOpcode16_t brig_opcode) const; - - tree add_temp_var (std::string name, tree expr); - - tree build_f2h_conversion (tree source); - tree build_h2f_conversion (tree source); - - tree_stl_vec build_operands (const BrigInstBase &brig_inst); - void analyze_operands (const BrigInstBase &brig_inst); - tree build_output_assignment (const BrigInstBase &brig_inst, tree output, - tree inst_expr); - - tree apply_to_all_elements (tree_element_unary_visitor &visitor, - tree operand); - - HOST_WIDE_INT int_constant_value (tree node); - - tree extend_int (tree input, tree dest_type, tree src_type); - -private: - - tree_stl_vec build_or_analyze_operands (const BrigInstBase &brig_inst, - bool analyze); -}; - -/* Implement the Visitor software pattern for performing various actions on - elements of vector operands. This enables separating the vector element - traversal/extraction/packing code from whatever different actions are - performed to each element. */ - -class tree_element_unary_visitor -{ -public: - tree operator () (brig_code_entry_handler &handler, tree operand); - - /* Performs an action to a single element, which can have originally - been a vector element or a scalar. */ - - virtual tree visit_element (brig_code_entry_handler &handler, tree operand) - = 0; -}; - -class tree_element_binary_visitor -{ -public: - tree operator () (brig_code_entry_handler &handler, tree operand0, - tree operand1); - - /* Performs an action to a pair of elements, which can have originally - been a vector element or a scalar. */ - - virtual tree visit_element (brig_code_entry_handler &handler, tree operand0, - tree operand1) - = 0; -}; - -/* Visitor for flushing float elements to zero. */ - -class flush_to_zero : public tree_element_unary_visitor -{ -public: - flush_to_zero (bool fp16) : m_fp16 (fp16) - { - } - - virtual tree visit_element (brig_code_entry_handler &caller, tree operand); - -private: - - /* True if the value should be flushed according to fp16 limits. */ - - bool m_fp16; -}; - -/* Visitor for converting F16 elements to F32. */ - -class half_to_float : public tree_element_unary_visitor -{ -public: - virtual tree visit_element (brig_code_entry_handler &caller, tree operand); -}; - -/* Visitor for converting F32 elements to F16. */ - -class float_to_half : public tree_element_unary_visitor -{ -public: - virtual tree visit_element (brig_code_entry_handler &caller, tree operand); -}; - -/* A base class for instruction types that support floating point - modifiers. - - operator () delegates to subclasses (template method pattern) in - type specific parts. */ - -class brig_inst_mod_handler : public brig_code_entry_handler -{ -public: - brig_inst_mod_handler (brig_to_generic &parent) - : brig_code_entry_handler (parent) - { - } - - virtual size_t generate (const BrigBase *base); - virtual const BrigAluModifier8_t *modifier (const BrigBase *base) const; - virtual const BrigRound8_t *round (const BrigBase *base) const; - - size_t operator () (const BrigBase *base); -}; - -class brig_directive_function_handler : public brig_code_entry_handler -{ -public: - brig_directive_function_handler (brig_to_generic &parent) - : brig_code_entry_handler (parent) - { - } - size_t operator () (const BrigBase *base); -}; - -class brig_directive_control_handler : public brig_code_entry_handler -{ -public: - brig_directive_control_handler (brig_to_generic &parent) - : brig_code_entry_handler (parent) - { - } - - size_t operator () (const BrigBase *base); -}; - -class brig_directive_variable_handler : public brig_code_entry_handler -{ -public: - brig_directive_variable_handler (brig_to_generic &parent) - : brig_code_entry_handler (parent) - { - } - - size_t operator () (const BrigBase *base); - - tree build_variable (const BrigDirectiveVariable *brigVar, - tree_code var_decltype = VAR_DECL); - - size_t get_brig_var_alignment (const BrigDirectiveVariable *brigVar); -}; - -class brig_directive_fbarrier_handler : public brig_code_entry_handler -{ -public: - brig_directive_fbarrier_handler (brig_to_generic &parent) - : brig_code_entry_handler (parent) - { - } - - size_t operator () (const BrigBase *base); -}; - -class brig_directive_label_handler : public brig_code_entry_handler -{ -public: - brig_directive_label_handler (brig_to_generic &parent) - : brig_code_entry_handler (parent) - { - } - - size_t operator () (const BrigBase *base); -}; - -class brig_directive_comment_handler : public brig_code_entry_handler -{ -public: - brig_directive_comment_handler (brig_to_generic &parent) - : brig_code_entry_handler (parent) - { - } - - size_t operator () (const BrigBase *base); -}; - -class brig_directive_arg_block_handler : public brig_code_entry_handler -{ -public: - brig_directive_arg_block_handler (brig_to_generic &parent) - : brig_code_entry_handler (parent) - { - } - - size_t operator () (const BrigBase *base); -}; - -class brig_basic_inst_handler : public brig_code_entry_handler -{ -public: - brig_basic_inst_handler (brig_to_generic &parent); - - size_t operator () (const BrigBase *base); - -private: - tree build_lower_element_broadcast (tree vec_operand); - - bool must_be_scalarized (const BrigInstBase *brig_inst, - tree instr_type) const; - - tree build_inst_expr (BrigOpcode16_t brig_opcode, BrigType16_t brig_type, - tree arith_type, tree_stl_vec &operands); - - tree build_shuffle (tree arith_type, tree_stl_vec &operands); - tree build_unpack (tree_stl_vec &operands); - tree build_pack (tree_stl_vec &operands); - - tree build_unpack_lo_or_hi (BrigOpcode16_t brig_opcode, tree arith_type, - tree_stl_vec &operands); -}; - -class brig_cvt_inst_handler : public brig_inst_mod_handler -{ -public: - brig_cvt_inst_handler (brig_to_generic &parent) - : brig_inst_mod_handler (parent) - { - } - - virtual size_t generate (const BrigBase *base); - virtual const BrigAluModifier8_t *modifier (const BrigBase *base) const; - virtual const BrigRound8_t *round (const BrigBase *base) const; -}; - -class brig_branch_inst_handler : public brig_code_entry_handler -{ -public: - brig_branch_inst_handler (brig_to_generic &parent) - : brig_code_entry_handler (parent) - { - } - - size_t operator () (const BrigBase *base); -}; - -class brig_mem_inst_handler : public brig_code_entry_handler -{ -public: - brig_mem_inst_handler (brig_to_generic &parent) - : brig_code_entry_handler (parent) - { - } - - size_t operator () (const BrigBase *base); - -private: - tree build_mem_access (const BrigInstBase *brig_inst, tree addr, tree data); -}; - -class brig_copy_move_inst_handler : public brig_code_entry_handler -{ -public: - brig_copy_move_inst_handler (brig_to_generic &parent) - : brig_code_entry_handler (parent) - { - } - - size_t operator () (const BrigBase *base); - -private: - size_t handle_lda (const BrigInstBase *base); -}; - -class brig_atomic_inst_handler : public brig_code_entry_handler -{ -private: - typedef std::map atomic_builtins_map; - -public: - brig_atomic_inst_handler (brig_to_generic &parent); - - size_t operator () (const BrigBase *base); - -protected: - size_t generate_tree (const BrigInstBase &inst, - BrigAtomicOperation8_t atomic_opcode); -}; - -class brig_signal_inst_handler : public brig_atomic_inst_handler -{ -public: - brig_signal_inst_handler (brig_to_generic &parent) - : brig_atomic_inst_handler (parent) - { - } - size_t operator () (const BrigBase *base); -}; - -class brig_cmp_inst_handler : public brig_code_entry_handler -{ -public: - brig_cmp_inst_handler (brig_to_generic &parent) - : brig_code_entry_handler (parent) - { - } - - size_t operator () (const BrigBase *base); -}; - -class brig_seg_inst_handler : public brig_code_entry_handler -{ -public: - brig_seg_inst_handler (brig_to_generic &parent); - - size_t operator () (const BrigBase *base); -}; - -class brig_lane_inst_handler : public brig_code_entry_handler -{ -public: - brig_lane_inst_handler (brig_to_generic &parent); - - size_t operator () (const BrigBase *base); -}; - -class brig_queue_inst_handler : public brig_code_entry_handler -{ -public: - brig_queue_inst_handler (brig_to_generic &parent); - - size_t operator () (const BrigBase *base); -}; - -class brig_directive_module_handler : public brig_code_entry_handler -{ -public: - brig_directive_module_handler (brig_to_generic &parent) - : brig_code_entry_handler (parent) - { - } - - size_t operator () (const BrigBase *base); -}; - - -#endif diff --git a/gcc/brig/brigfrontend/brig-comment-handler.cc b/gcc/brig/brigfrontend/brig-comment-handler.cc deleted file mode 100644 index b20e66f390c..00000000000 --- a/gcc/brig/brigfrontend/brig-comment-handler.cc +++ /dev/null @@ -1,38 +0,0 @@ -/* brig-comment-handler.cc -- brig comment directive handling - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ - -#include "brig-code-entry-handler.h" - -extern int gccbrig_verbose; - -size_t -brig_directive_comment_handler::operator () (const BrigBase *base) -{ - const BrigDirectiveComment *brig_comment - = (const BrigDirectiveComment *) base; - - if (gccbrig_verbose) - { - std::string cmnt = m_parent.get_string (brig_comment->name); - fprintf (stderr, "brig: Comment: '%s'\n", cmnt.c_str()); - } - return base->byteCount; -} diff --git a/gcc/brig/brigfrontend/brig-control-handler.cc b/gcc/brig/brigfrontend/brig-control-handler.cc deleted file mode 100644 index 3fdf3b53470..00000000000 --- a/gcc/brig/brigfrontend/brig-control-handler.cc +++ /dev/null @@ -1,108 +0,0 @@ -/* brig-control-handler.cc -- brig control directive handling - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ - -#include "brig-code-entry-handler.h" -#include "diagnostic.h" -#include "print-tree.h" - -size_t -brig_directive_control_handler::operator () (const BrigBase *base) -{ - const BrigDirectiveControl *inst = (const BrigDirectiveControl *) base; - const BrigData *operand_entries - = m_parent.get_brig_data_entry (inst->operands); - - /* Parse the constant integer operands. */ - std::vector operands; - for (size_t i = 0; i < operand_entries->byteCount / 4; ++i) - { - uint32_t operand_offset - = ((const uint32_t *) &operand_entries->bytes)[i]; - const BrigBase *operand_data - = m_parent.get_brig_operand_entry (operand_offset); - - tree operand_type - = (inst->control == BRIG_CONTROL_REQUIREDGRIDSIZE - || inst->control == BRIG_CONTROL_MAXFLATGRIDSIZE) ? - uint64_type_node : uint32_type_node; - operands.push_back - (build_tree_operand (*(const BrigInstBase*)inst, *operand_data, - operand_type)); - } - - switch (inst->control) - { - case BRIG_CONTROL_MAXDYNAMICGROUPSIZE: - { - m_parent.m_cf->m_descriptor.max_dynamic_group_size - = brig_function::int_constant_value (operands.at (0)); - break; - } - case BRIG_CONTROL_MAXFLATGRIDSIZE: - { - m_parent.m_cf->m_descriptor.max_flat_grid_size - = brig_function::int_constant_value (operands.at (0)); - break; - } - case BRIG_CONTROL_MAXFLATWORKGROUPSIZE: - { - m_parent.m_cf->m_descriptor.max_flat_workgroup_size - = brig_function::int_constant_value (operands.at (0)); - break; - } - case BRIG_CONTROL_REQUIREDDIM: - { - m_parent.m_cf->m_descriptor.required_dim - = brig_function::int_constant_value (operands.at (0)); - break; - } - case BRIG_CONTROL_REQUIREDGRIDSIZE: - { - m_parent.m_cf->m_descriptor.required_grid_size[0] - = brig_function::int_constant_value (operands.at (0)); - m_parent.m_cf->m_descriptor.required_grid_size[1] - = brig_function::int_constant_value (operands.at (1)); - m_parent.m_cf->m_descriptor.required_grid_size[2] - = brig_function::int_constant_value (operands.at (2)); - break; - } - case BRIG_CONTROL_REQUIREDWORKGROUPSIZE: - { - m_parent.m_cf->m_descriptor.required_workgroup_size[0] - = brig_function::int_constant_value (operands.at (0)); - m_parent.m_cf->m_descriptor.required_workgroup_size[1] - = brig_function::int_constant_value (operands.at (1)); - m_parent.m_cf->m_descriptor.required_workgroup_size[2] - = brig_function::int_constant_value (operands.at (2)); - break; - } - case BRIG_CONTROL_REQUIRENOPARTIALWORKGROUPS: - /* Performance hint only, ignored for now. */ - break; - case BRIG_CONTROL_ENABLEBREAKEXCEPTIONS: - case BRIG_CONTROL_ENABLEDETECTEXCEPTIONS: - /* Unimplemented. */ - break; - default: - sorry ("Unsupported control directive %x.", inst->control); - } - return base->byteCount; -} diff --git a/gcc/brig/brigfrontend/brig-copy-move-inst-handler.cc b/gcc/brig/brigfrontend/brig-copy-move-inst-handler.cc deleted file mode 100644 index 121a947b418..00000000000 --- a/gcc/brig/brigfrontend/brig-copy-move-inst-handler.cc +++ /dev/null @@ -1,73 +0,0 @@ -/* brig-copy-move-inst-handler.cc -- brig copy/move instruction handling - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3, or (at your option) any later - version. - - GCC is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - . */ - -#include "brig-code-entry-handler.h" -#include "tree-pretty-print.h" -#include "print-tree.h" -#include "errors.h" -#include "brig-util.h" - -size_t -brig_copy_move_inst_handler::handle_lda (const BrigInstBase *brig_inst) -{ - tree dest_type = gccbrig_tree_type_for_hsa_type (brig_inst->type); - - tree input = build_tree_operand_from_brig (brig_inst, NULL, 1); - tree output = build_tree_operand_from_brig (brig_inst, dest_type, 0); - - build_output_assignment (*brig_inst, output, input); - return brig_inst->base.byteCount; -} - -size_t -brig_copy_move_inst_handler::operator () (const BrigBase *base) -{ - const BrigInstBase *brig_inst - = (const BrigInstBase *) &((const BrigInstBasic *) base)->base; - - if (brig_inst->opcode == BRIG_OPCODE_LDA) - return handle_lda (brig_inst); - - const BrigInstSourceType *inst_src_type = (const BrigInstSourceType *) base; - - tree source_type = gccbrig_tree_type_for_hsa_type (inst_src_type->sourceType); - tree dest_type = gccbrig_tree_type_for_hsa_type (brig_inst->type); - - tree input = build_tree_operand_from_brig (brig_inst, source_type, 1); - tree output = build_tree_operand_from_brig (brig_inst, dest_type, 0); - - if (brig_inst->opcode == BRIG_OPCODE_COMBINE) - { - /* For combine, a simple reinterpret cast from the array constructor - works. */ - tree casted = build_resize_convert_view (TREE_TYPE (output), input); - tree assign = build2 (MODIFY_EXPR, TREE_TYPE (output), output, casted); - m_parent.m_cf->append_statement (assign); - } - else if (brig_inst->opcode == BRIG_OPCODE_EXPAND) - build_output_assignment (*brig_inst, output, input); - else - { - brig_basic_inst_handler basic (m_parent); - return basic (base); - } - return base->byteCount; -} diff --git a/gcc/brig/brigfrontend/brig-cvt-inst-handler.cc b/gcc/brig/brigfrontend/brig-cvt-inst-handler.cc deleted file mode 100644 index 319128dbfd1..00000000000 --- a/gcc/brig/brigfrontend/brig-cvt-inst-handler.cc +++ /dev/null @@ -1,268 +0,0 @@ -/* brig-cvt-inst-handler.cc -- brig cvt (convert) instruction handling - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3, or (at your option) any later - version. - - GCC is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - . */ - -#include - -#include "brig-code-entry-handler.h" - -#include "gimple-expr.h" -#include "errors.h" -#include "convert.h" -#include "tree-pretty-print.h" -#include "print-tree.h" -#include "diagnostic-core.h" -#include "brig-util.h" - -const BrigAluModifier8_t * -brig_cvt_inst_handler::modifier (const BrigBase *base) const -{ - const BrigInstCvt *inst = (const BrigInstCvt *) base; - return &inst->modifier; -} - -const BrigRound8_t * -brig_cvt_inst_handler::round (const BrigBase *base) const -{ - const BrigInstCvt *inst = (const BrigInstCvt *) base; - return &inst->round; -} - -size_t -brig_cvt_inst_handler::generate (const BrigBase *base) -{ - /* In cvt instructions there can be at least four data types involved: - - - the input register type - - the output register type - - the conversion source type - - the conversion destination type - */ - - const BrigInstBase *brig_inst - = (const BrigInstBase *) &((const BrigInstBasic *) base)->base; - const BrigInstCvt *cvt_inst = (const BrigInstCvt *) base; - - const BrigAluModifier8_t *inst_modifier = modifier (base); - const bool FTZ = inst_modifier != NULL && (*inst_modifier) & BRIG_ALU_FTZ; - - /* The conversion source type. */ - tree src_type = get_tree_expr_type_for_hsa_type (cvt_inst->sourceType); - - bool src_is_fp16 = cvt_inst->sourceType == BRIG_TYPE_F16; - - /* The conversion destination type. */ - tree dest_type = gccbrig_tree_type_for_hsa_type (brig_inst->type); - - bool dest_is_fp16 = brig_inst->type == BRIG_TYPE_F16; - - if (!dest_type || !src_type) - { - gcc_unreachable (); - return base->byteCount; - } - - tree_stl_vec operands = build_operands (*brig_inst); - tree &input = operands.at (1); - tree &output = operands.at (0); - - if (m_parent.m_cf->is_id_val (input)) - { - input = m_parent.m_cf->id_val (input); - src_type = TREE_TYPE (input); - } - - size_t conv_src_size = int_size_in_bytes (src_type); - size_t conv_dst_size = int_size_in_bytes (dest_type); - size_t src_reg_size = int_size_in_bytes (TREE_TYPE (input)); - - /* The input register can be of different type&size than the - conversion input size. First cast the input to the conversion - input type. These casts are always bitcasts which can be - expressed as casts between different unsigned integers. */ - if (src_reg_size != conv_src_size) - { - tree unsigned_int_type = NULL_TREE; - if (INTEGRAL_TYPE_P (src_type)) - unsigned_int_type = unsigned_type_for (src_type); - else /* Find a matching size int type for the REAL type. */ - { - if (conv_src_size == 2) - unsigned_int_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_U16); - else if (conv_src_size == 4) - unsigned_int_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_U32); - else if (conv_src_size == 8) - unsigned_int_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_U64); - else - gcc_unreachable (); - } - input = convert_to_integer (unsigned_int_type, input); - } - - if (src_is_fp16) - input = build_h2f_conversion (input); - - /* Flush the float operand to zero if indicated with 'ftz'. */ - if (FTZ && SCALAR_FLOAT_TYPE_P (src_type)) - { - tree casted_input = build_resize_convert_view (src_type, input); - input = flush_to_zero (src_is_fp16) (*this, casted_input); - } - - tree conversion_result = NULL_TREE; - if (brig_inst->type == BRIG_TYPE_B1) - { - /* When the destination is b1, cvt does a 'ztest' operation which is - defined as a != 0 for integers and similarly (!= 0.0f) for floats. */ - if (INTEGRAL_TYPE_P (src_type)) - { - /* Generate an integer not equal operation. */ - conversion_result = build2 (NE_EXPR, TREE_TYPE (input), input, - build_int_cst (TREE_TYPE (input), 0)); - } - else - { - /* For REAL source types, ztest returns 1 if the value is not +- 0.0f. - We can perform this check with an integer comparison after - masking away the sign bit from a correct position. This is safer - than using absf because of exceptions in case of a NaN - input (NaN exceptions are not generated with cvt). */ - tree unsigned_int_type = NULL_TREE; - /* Bit battern with all but the upper bit 1. */ - tree and_mask = NULL_TREE; - if (conv_src_size == 2) - { - unsigned_int_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_U16); - and_mask = build_int_cst (unsigned_int_type, 0x7FFF); - } - else if (conv_src_size == 4) - { - unsigned_int_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_U32); - and_mask = build_int_cst (unsigned_int_type, 0x7FFFFFFF); - } - else if (conv_src_size == 8) - { - unsigned_int_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_U64); - and_mask = build_int_cst (unsigned_int_type, 0x7FFFFFFFFFFFFFFF); - } - else - gcc_unreachable (); - tree casted_input = build_resize_convert_view (unsigned_int_type, - input); - tree masked_input - = build2 (BIT_AND_EXPR, unsigned_int_type, casted_input, and_mask); - conversion_result - = build2 (NE_EXPR, TREE_TYPE (masked_input), masked_input, - build_int_cst (unsigned_int_type, 0)); - } - /* The result from the comparison is a boolean, convert it to such. */ - conversion_result - = convert_to_integer (gccbrig_tree_type_for_hsa_type (BRIG_TYPE_B1), - conversion_result); - } - else if (dest_is_fp16) - { - tree casted_input = build_resize_convert_view (src_type, input); - conversion_result - = convert_to_real (brig_to_generic::s_fp32_type, casted_input); - if (FTZ) - conversion_result = flush_to_zero (true) (*this, conversion_result); - conversion_result = build_f2h_conversion (conversion_result); - } - else if (SCALAR_FLOAT_TYPE_P (dest_type)) - { - tree casted_input = build_resize_convert_view (src_type, input); - conversion_result = convert_to_real (dest_type, casted_input); - } - else if (INTEGRAL_TYPE_P (dest_type) && INTEGRAL_TYPE_P (src_type)) - { - conversion_result = extend_int (input, dest_type, src_type); - } - else if (INTEGRAL_TYPE_P (dest_type) && SCALAR_FLOAT_TYPE_P (src_type)) - { - - if (cvt_inst->round == BRIG_ROUND_INTEGER_ZERO_SAT) - { - - /* Use builtins for the saturating conversions. */ -#undef DEF_HSAIL_SAT_BUILTIN -#undef DEF_HSAIL_BUILTIN -#undef DEF_HSAIL_ATOMIC_BUILTIN -#undef DEF_HSAIL_INTR_BUILTIN -#undef DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN - - tree builtin = NULL_TREE; - BrigType16_t src_arith_type - = src_is_fp16 - ? (BrigType16_t) BRIG_TYPE_F32 : cvt_inst->sourceType; -#define DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN(ENUM, HSAIL_DST_TYPE, HSAIL_SRC_TYPE, \ - NAME, TYPE, ATTRS) \ - if (brig_inst->type == HSAIL_DST_TYPE \ - && src_arith_type == HSAIL_SRC_TYPE) \ - builtin = builtin_decl_explicit (ENUM); \ - else -#include "brig-builtins.def" - gcc_unreachable (); - - tree casted_input = build_resize_convert_view (src_type, input); - conversion_result - = call_builtin (builtin, 1, dest_type, src_type, casted_input); - } - else - { - tree casted_input = build_resize_convert_view (src_type, input); - - /* Perform the float to int conversion. */ - conversion_result = convert_to_integer (dest_type, casted_input); - } - } - else - { - /* Just use CONVERT_EXPR and hope for the best. */ - tree casted_input = build_resize_convert_view (dest_type, input); - conversion_result = build1 (CONVERT_EXPR, dest_type, casted_input); - } - - size_t dst_reg_size = int_size_in_bytes (TREE_TYPE (output)); - - /* The output register can be of different type&size than the - conversion output size. Only need to handle signed integers, rest - is handled by reinterpret_cast. */ - tree casted_output = conversion_result; - if (dst_reg_size > conv_dst_size && - INTEGRAL_TYPE_P (TREE_TYPE (casted_output))) - { - gcc_assert (!VECTOR_TYPE_P (casted_output)); - - bool unsignedp = TYPE_UNSIGNED (TREE_TYPE (casted_output)); - tree resized_int_type - = build_nonstandard_integer_type (dst_reg_size * BITS_PER_UNIT, - unsignedp); - casted_output = build1 (CONVERT_EXPR, resized_int_type, casted_output); - } - - casted_output - = build_resize_convert_view (TREE_TYPE (output), casted_output); - tree assign = build2 (MODIFY_EXPR, TREE_TYPE (output), output, casted_output); - - m_parent.m_cf->append_statement (assign); - - return base->byteCount; -} diff --git a/gcc/brig/brigfrontend/brig-fbarrier-handler.cc b/gcc/brig/brigfrontend/brig-fbarrier-handler.cc deleted file mode 100644 index b29768b8541..00000000000 --- a/gcc/brig/brigfrontend/brig-fbarrier-handler.cc +++ /dev/null @@ -1,45 +0,0 @@ -/* brig-fbarrier-handler.cc -- brig fbarrier directive handling - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ - -#include "brig-code-entry-handler.h" - -#include "stringpool.h" -#include "errors.h" - -/* Allocate this many bytes from the group segment for each fbarrier. */ -#define FBARRIER_STRUCT_SIZE 32 - -size_t -brig_directive_fbarrier_handler::operator () (const BrigBase *base) -{ - /* Model fbarriers as group segment variables with fixed size - large enough to store whatever data the actual target needs - to store to maintain the barrier info. The handle is the - offset to the beginning of the object. */ - - const BrigDirectiveFbarrier* fbar = (const BrigDirectiveFbarrier*)base; - if (m_parent.m_cf != NULL) - m_parent.m_cf->m_function_scope_vars.insert (base); - std::string var_name = m_parent.get_mangled_name (fbar); - m_parent.add_group_variable (var_name, FBARRIER_STRUCT_SIZE, 1, - m_parent.m_cf != NULL); - return base->byteCount; -} diff --git a/gcc/brig/brigfrontend/brig-function-handler.cc b/gcc/brig/brigfrontend/brig-function-handler.cc deleted file mode 100644 index d860bc59cbc..00000000000 --- a/gcc/brig/brigfrontend/brig-function-handler.cc +++ /dev/null @@ -1,431 +0,0 @@ -/* brig-code-entry-handler.cc -- brig function directive handling - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3, or (at your option) any later - version. - - GCC is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - . */ - -#include -#include - -#include "brig-code-entry-handler.h" - -#include "brig-machine.h" -#include "stringpool.h" -#include "tree-iterator.h" -#include "gimple-expr.h" -#include "function.h" -#include "phsa.h" - -#include "tree-pretty-print.h" -#include "print-tree.h" - -extern int gccbrig_verbose; - -size_t -brig_directive_function_handler::operator () (const BrigBase *base) -{ - if (!m_parent.m_analyzing) - m_parent.finish_function (); - - size_t bytes_consumed = base->byteCount; - - const BrigDirectiveExecutable *exec = (const BrigDirectiveExecutable *) base; - - if (gccbrig_verbose) - { - printf ("brig: function name %s\n", - m_parent.get_string (exec->name).c_str()); - printf ("brig: inargs %d outargs %d name offset %d\n", exec->inArgCount, - exec->outArgCount, exec->name); - } - - const bool is_definition - = exec->modifier & BRIG_EXECUTABLE_DEFINITION; - - const bool is_kernel = base->kind == BRIG_KIND_DIRECTIVE_KERNEL; - - /* There doesn't seem to be actual use cases for kernel declarations - as they cannot be called by the program. Ignore them until there's - a reason not to. */ - if (is_kernel && !is_definition) - return bytes_consumed; - - std::string func_name = m_parent.get_mangled_name (exec); - if (is_kernel) - /* The generated kernel function is not the one that should be - called by the host. */ - func_name = std::string ("_") + func_name; - - m_parent.m_cf = new brig_function (exec, &m_parent); - m_parent.m_cf->m_name = func_name; - m_parent.m_cf->m_is_kernel = is_kernel; - - /* During the analyze step, the above information is all we need per - function. */ - if (m_parent.m_analyzing) - return bytes_consumed; - - /* There can be multiple forward declarations of the same function. - Skip all but the first one. */ - if (!is_definition && m_parent.function_decl (func_name) != NULL_TREE) - return bytes_consumed; - tree fndecl; - tree ret_value = NULL_TREE; - - tree stmt_list = alloc_stmt_list (); - - /* Add a function scope BIND_EXPR using which we can push local variables that - represent HSAIL registers. */ - tree bind_expr = build3 (BIND_EXPR, void_type_node, NULL, stmt_list, NULL); - - tree restrict_char_ptr - = build_qualified_type (build_pointer_type (char_type_node), - TYPE_QUAL_RESTRICT); - tree restrict_void_ptr - = build_qualified_type (build_pointer_type (void_type_node), - TYPE_QUAL_RESTRICT); - - tree restrict_const_char_ptr - = build_qualified_type (build_pointer_type - (build_qualified_type (char_type_node, - TYPE_QUAL_CONST)), - TYPE_QUAL_RESTRICT); - - tree restrict_const_void_ptr - = build_qualified_type (build_pointer_type - (build_qualified_type (void_type_node, - TYPE_QUAL_CONST)), - TYPE_QUAL_RESTRICT); - - if (is_kernel) - { - tree name_identifier - = get_identifier_with_length (func_name.c_str (), func_name.size ()); - - /* The generated kernel functions take the following arguments: - - 1) a char* which is a starting address of the argument segment where - the call's arguments are stored by the launcher. - 2) a void* parameter that points to a phsail-finalizer context object - which passes the hsa kernel packet etc. - 3) a void* parameter that contains the first flat address of the group - region allocated to the current work-group. */ - - fndecl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, name_identifier, - build_function_type_list (void_type_node, - restrict_const_char_ptr, - restrict_void_ptr, - restrict_char_ptr, NULL_TREE)); - - SET_DECL_ASSEMBLER_NAME (fndecl, name_identifier); - - tree resdecl - = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, void_type_node); - - tree typelist = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); - tree argtype = TREE_VALUE (typelist); - TYPE_ADDR_SPACE (argtype) - = gccbrig_get_target_addr_space_id (BRIG_SEGMENT_KERNARG); - - tree arg_arg = build_decl (UNKNOWN_LOCATION, PARM_DECL, - get_identifier ("__args"), - restrict_const_char_ptr); - DECL_ARGUMENTS (fndecl) = arg_arg; - DECL_ARG_TYPE (arg_arg) = restrict_const_char_ptr; - DECL_CONTEXT (arg_arg) = fndecl; - DECL_ARTIFICIAL (arg_arg) = 1; - TREE_READONLY (arg_arg) = 1; - TREE_USED (arg_arg) = 1; - - DECL_RESULT (fndecl) = resdecl; - DECL_CONTEXT (resdecl) = fndecl; - DECL_EXTERNAL (fndecl) = 0; - - /* Aggressive inlining to the kernel function is usually a good - idea with offlined functionality to enchance SIMD execution on - GPUs and vector units. */ - - DECL_ATTRIBUTES (fndecl) - = tree_cons (get_identifier ("flatten"), NULL, - DECL_ATTRIBUTES (fndecl)); - } - else - { - /* Build a regular function fingerprint to enable targets to optimize - the calling convention as they see fit. */ - tree name_identifier - = get_identifier_with_length (func_name.c_str (), func_name.size ()); - - m_parent.m_cf->m_arg_variables.clear (); - - brig_directive_variable_handler arg_handler (m_parent); - - vec *args; - vec_alloc (args, 4); - - tree arg_decls = NULL_TREE; - - tree ret_type = void_type_node; - if (exec->outArgCount == 1) - { - /* The return value variable should be the first entry after the - function directive. */ - const BrigBase *retval - = (const BrigBase *) ((const char *) base + base->byteCount); - gcc_assert (retval->kind == BRIG_KIND_DIRECTIVE_VARIABLE); - - const BrigDirectiveVariable *brigVar - = (const BrigDirectiveVariable *) retval; - - brig_directive_variable_handler varhandler (m_parent); - - if (brigVar->type & BRIG_TYPE_ARRAY) - { - /* Push array output arguments to the beginning of the - function argument list instead of regular function - return values. */ - - tree arg_var = varhandler.build_variable (brigVar, PARM_DECL); - vec_safe_push (args, TREE_TYPE (arg_var)); - - m_parent.m_cf->add_arg_variable (brigVar, arg_var); - - if (arg_decls == NULL_TREE) - arg_decls = arg_var; - else - arg_decls = chainon (arg_decls, arg_var); - - m_parent.m_cf->add_arg_variable (brigVar, arg_var); - - ret_value = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, - void_type_node); - } - else - { - ret_value = varhandler.build_variable (brigVar, RESULT_DECL); - m_parent.m_cf->m_ret_value = ret_value; - ret_type = TREE_TYPE (ret_value); - m_parent.m_cf->m_ret_value_brig_var = brigVar; - } - bytes_consumed += retval->byteCount; - } - else - ret_value = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, - void_type_node); - - TREE_ADDRESSABLE (ret_value) = 1; - - if (exec->inArgCount > 0) - { - uint32_t arg_offset = exec->firstInArg; - for (size_t arg = 0; arg < exec->inArgCount; ++arg) - { - - const BrigDirectiveVariable *brigVar - = (const BrigDirectiveVariable *) m_parent.get_brig_code_entry - (arg_offset); - - gcc_assert (brigVar->base.kind == BRIG_KIND_DIRECTIVE_VARIABLE); - - /* Delegate to the brig_directive_variable_handler. */ - brig_directive_variable_handler varhandler (m_parent); - tree arg_var = varhandler.build_variable (brigVar, PARM_DECL); - arg_offset += brigVar->base.byteCount; - vec_safe_push (args, TREE_TYPE (arg_var)); - - m_parent.m_cf->add_arg_variable (brigVar, arg_var); - arg_decls = chainon (arg_decls, arg_var); - } - } - vec_safe_push (args, restrict_void_ptr); - vec_safe_push (args, restrict_char_ptr); - vec_safe_push (args, uint32_type_node); - vec_safe_push (args, restrict_char_ptr); - - fndecl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, name_identifier, - build_function_type_vec (ret_type, args)); - - DECL_RESULT (fndecl) = ret_value; - DECL_CONTEXT (ret_value) = fndecl; - DECL_EXTERNAL (fndecl) = 0; - DECL_ARGUMENTS (fndecl) = arg_decls; - } - - /* All functions need the hidden __context argument passed on - because they might call WI-specific functions which need - the context info. Only kernels can write it, if they need - to update the local ids in the work-item loop. */ - - tree context_arg_type - = true ? restrict_void_ptr : restrict_const_void_ptr; - tree context_arg = build_decl (UNKNOWN_LOCATION, PARM_DECL, - get_identifier ("__context"), - context_arg_type); - DECL_ARGUMENTS (fndecl) = chainon (DECL_ARGUMENTS (fndecl), context_arg); - DECL_CONTEXT (context_arg) = fndecl; - DECL_ARG_TYPE (context_arg) = context_arg_type; - DECL_ARTIFICIAL (context_arg) = 1; - TREE_READONLY (context_arg) = 1; - TREE_USED (context_arg) = 1; - m_parent.m_cf->m_context_arg = context_arg; - - /* They can also access group memory, so we need to pass the - group pointer along too. */ - tree group_base_arg - = build_decl (UNKNOWN_LOCATION, PARM_DECL, - get_identifier ("__group_base_addr"), - restrict_char_ptr); - DECL_ARGUMENTS (fndecl) = chainon (DECL_ARGUMENTS (fndecl), group_base_arg); - DECL_ARG_TYPE (group_base_arg) = restrict_char_ptr; - DECL_CONTEXT (group_base_arg) = fndecl; - DECL_ARTIFICIAL (group_base_arg) = 1; - TREE_READONLY (group_base_arg) = 1; - TREE_USED (group_base_arg) = 1; - m_parent.m_cf->m_group_base_arg = group_base_arg; - - /* To implement call stack and (non-kernel) function scope group variables, - we need to pass an offset which describes how far are we from - group_base_ptr. - That must be substracted from any function local group variable offsets to - get the address related to the bottom of the group memory chunk. */ - tree group_local_offset_arg - = build_decl (UNKNOWN_LOCATION, PARM_DECL, - get_identifier ("__group_local_offset"), uint32_type_node); - DECL_ARGUMENTS (fndecl) = chainon (DECL_ARGUMENTS (fndecl), group_local_offset_arg); - DECL_ARG_TYPE (group_local_offset_arg) = uint32_type_node; - DECL_CONTEXT (group_local_offset_arg) = fndecl; - DECL_ARTIFICIAL (group_local_offset_arg) = 1; - TREE_READONLY (group_local_offset_arg) = 1; - TREE_USED (group_local_offset_arg) = 1; - m_parent.m_cf->m_group_local_offset_arg = group_local_offset_arg; - - /* Same for private. */ - tree private_base_arg - = build_decl (UNKNOWN_LOCATION, PARM_DECL, - get_identifier ("__private_base_addr"), restrict_char_ptr); - DECL_ARGUMENTS (fndecl) = chainon (DECL_ARGUMENTS (fndecl), private_base_arg); - DECL_ARG_TYPE (private_base_arg) = restrict_char_ptr; - DECL_CONTEXT (private_base_arg) = fndecl; - DECL_ARTIFICIAL (private_base_arg) = 1; - TREE_READONLY (private_base_arg) = 1; - TREE_USED (private_base_arg) = 1; - m_parent.m_cf->m_private_base_arg = private_base_arg; - - DECL_SAVED_TREE (fndecl) = bind_expr; - - if (base->kind == BRIG_KIND_DIRECTIVE_FUNCTION) - { - TREE_STATIC (fndecl) = 0; - TREE_PUBLIC (fndecl) = 1; - DECL_EXTERNAL (fndecl) = 0; - DECL_DECLARED_INLINE_P (fndecl) = 1; - set_inline (fndecl); - set_externally_visible (fndecl); - } - else if (base->kind == BRIG_KIND_DIRECTIVE_KERNEL) - { - TREE_STATIC (fndecl) = 0; - TREE_PUBLIC (fndecl) = 1; - DECL_EXTERNAL (fndecl) = 0; - set_externally_visible (fndecl); - } - else if (base->kind == BRIG_KIND_DIRECTIVE_SIGNATURE) - { - TREE_STATIC (fndecl) = 0; - TREE_PUBLIC (fndecl) = 1; - DECL_EXTERNAL (fndecl) = 1; - set_inline (fndecl); - } - else if (base->kind == BRIG_KIND_DIRECTIVE_INDIRECT_FUNCTION) - { - TREE_STATIC (fndecl) = 0; - TREE_PUBLIC (fndecl) = 1; - } - else - gcc_unreachable (); - - TREE_USED (fndecl) = 1; - DECL_ARTIFICIAL (fndecl) = 0; - - tree initial_block = make_node (BLOCK); - DECL_INITIAL (fndecl) = initial_block; - TREE_USED (DECL_INITIAL (fndecl)) = 1; - - if (ret_value != NULL_TREE && TREE_TYPE (ret_value) != void_type_node) - { - DECL_CONTEXT (ret_value) = fndecl; - DECL_CHAIN (ret_value) = BIND_EXPR_VARS (bind_expr); - BIND_EXPR_VARS (bind_expr) = ret_value; - } - - tree arg; - for (arg = DECL_ARGUMENTS (fndecl); arg != NULL_TREE; arg = TREE_CHAIN (arg)) - { - DECL_CONTEXT (arg) = fndecl; - DECL_ARG_TYPE (arg) = TREE_TYPE (arg); - } - - m_parent.add_function_decl (func_name, fndecl); - m_parent.append_global (fndecl); - - - if (!is_definition) - { - DECL_EXTERNAL (fndecl) = 1; - return bytes_consumed; - } - - m_parent.start_function (fndecl); - m_parent.m_cf->m_func_decl = fndecl; - m_parent.m_cf->m_current_bind_expr = bind_expr; - - if (ret_value != NULL_TREE && TREE_TYPE (ret_value) != void_type_node) - { - /* We cannot assign to <> directly in gcc trunk. We need to - create a local temporary variable which can be stored to and when - returning from the function, we'll copy it to the actual <> - in return statement's argument. */ - tree temp_var = m_parent.m_cf->m_ret_temp - = m_parent.m_cf->add_local_variable ("_retvalue_temp", - TREE_TYPE (ret_value)); - TREE_ADDRESSABLE (temp_var) = 1; - } - - if (is_kernel) - { - m_parent.m_cf->add_id_variables (); - - /* Create a single entry point in the function. */ - m_parent.m_cf->m_entry_label_stmt - = build_stmt (LABEL_EXPR, m_parent.m_cf->label ("__kernel_entry")); - m_parent.m_cf->append_statement (m_parent.m_cf->m_entry_label_stmt); - - tree bind_expr = m_parent.m_cf->m_current_bind_expr; - tree stmts = BIND_EXPR_BODY (bind_expr); - - m_parent.m_cf->m_kernel_entry = tsi_last (stmts); - - /* Let's not append the exit label yet, but only after the - function has been built. We need to build it so it can - be referred to because returns are converted to gotos to this - label. */ - m_parent.m_cf->m_exit_label = m_parent.m_cf->label ("__kernel_exit"); - } - - return bytes_consumed; -} diff --git a/gcc/brig/brigfrontend/brig-function.cc b/gcc/brig/brigfrontend/brig-function.cc deleted file mode 100644 index c2bddfb8ca5..00000000000 --- a/gcc/brig/brigfrontend/brig-function.cc +++ /dev/null @@ -1,1602 +0,0 @@ -/* brig-function.cc -- declaration of brig_function class. - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3, or (at your option) any later - version. - - GCC is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - . */ - -#include -#include - -#include "brig-function.h" -#include "stringpool.h" -#include "tree-iterator.h" -#include "toplev.h" -#include "gimplify.h" -#include "gimple-expr.h" -#include "print-tree.h" -#include "hsa-brig-format.h" -#include "stor-layout.h" -#include "diagnostic-core.h" -#include "brig-code-entry-handler.h" -#include "brig-machine.h" -#include "brig-util.h" -#include "phsa.h" -#include "tree-pretty-print.h" -#include "dumpfile.h" -#include "profile-count.h" -#include "tree-cfg.h" -#include "errors.h" -#include "function.h" -#include "brig-to-generic.h" -#include "brig-builtins.h" -#include "options.h" -#include "fold-const.h" -#include "target.h" -#include "builtins.h" - -brig_function::builtin_map brig_function::s_custom_builtins; - -brig_function::brig_function (const BrigDirectiveExecutable *exec, - brig_to_generic *parent) - : m_brig_def (exec), m_is_kernel (false), m_is_finished (false), m_name (""), - m_current_bind_expr (NULL_TREE), m_func_decl (NULL_TREE), - m_context_arg (NULL_TREE), m_group_base_arg (NULL_TREE), - m_private_base_arg (NULL_TREE), m_ret_value (NULL_TREE), - m_next_kernarg_offset (0), m_kernarg_max_align (0), - m_ret_value_brig_var (NULL), m_has_barriers (false), m_has_allocas (false), - m_has_function_calls_with_barriers (false), m_calls_analyzed (false), - m_is_wg_function (false), m_has_unexpanded_dp_builtins (false), - m_generating_arg_block (false), m_parent (parent) -{ - memset (m_regs, 0, - BRIG_2_TREE_HSAIL_TOTAL_REG_COUNT * sizeof (BrigOperandRegister *)); - memset (&m_descriptor, 0, sizeof (phsa_descriptor)); - - if (s_custom_builtins.size () > 0) return; - - /* Populate the builtin index. */ -#undef DEF_HSAIL_ATOMIC_BUILTIN -#undef DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN -#undef DEF_HSAIL_INTR_BUILTIN -#undef DEF_HSAIL_SAT_BUILTIN -#undef DEF_HSAIL_BUILTIN -#define DEF_HSAIL_BUILTIN(ENUM, HSAIL_OPCODE, HSAIL_TYPE, NAME, TYPE, ATTRS) \ - s_custom_builtins[std::make_pair (HSAIL_OPCODE, HSAIL_TYPE)] \ - = builtin_decl_explicit (ENUM); - -#include "brig-builtins.def" -} - -brig_function::~brig_function () -{ - for (size_t i = 0; i < BRIG_2_TREE_HSAIL_TOTAL_REG_COUNT; ++i) - { - if (m_regs[i] != NULL) - { - delete m_regs[i]; - m_regs[i] = NULL; - } - } -} - -/* Returns a GENERIC label with the given name in the given function. - Creates it, if not yet found. */ - -tree -brig_function::label (const std::string &name) -{ - label_index::const_iterator i = m_label_index.find (name); - if (i == m_label_index.end ()) - { - tree name_identifier - = get_identifier_with_length (name.c_str (), name.size ()); - - tree label_decl = build_decl (UNKNOWN_LOCATION, LABEL_DECL, - name_identifier, void_type_node); - - DECL_CONTEXT (label_decl) = m_func_decl; - DECL_ARTIFICIAL (label_decl) = 0; - - m_label_index[name] = label_decl; - return label_decl; - } - else - return (*i).second; -} - -/* Record an argument variable for later use. This includes both local - variables inside arg blocks and incoming function arguments. */ - -void -brig_function::add_arg_variable (const BrigDirectiveVariable *brigVar, - tree treeDecl) -{ - m_arg_variables[brigVar] = treeDecl; -} - -tree -brig_function::arg_variable (const BrigDirectiveVariable *var) const -{ - variable_index::const_iterator i = m_arg_variables.find (var); - if (i == m_arg_variables.end ()) - return NULL_TREE; - else - return (*i).second; -} - -/* Appends a new kernel argument descriptor for the current kernel's - arg space. */ - -void -brig_function::append_kernel_arg (const BrigDirectiveVariable *var, size_t size, - size_t alignment) -{ - gcc_assert (m_func_decl != NULL_TREE); - gcc_assert (m_is_kernel); - - size_t align_padding = m_next_kernarg_offset % alignment == 0 ? - 0 : (alignment - m_next_kernarg_offset % alignment); - m_next_kernarg_offset += align_padding; - m_kernarg_offsets[var] = m_next_kernarg_offset; - m_next_kernarg_offset += size; - - m_kernarg_max_align - = m_kernarg_max_align < alignment ? alignment : m_kernarg_max_align; -} - -size_t -brig_function::kernel_arg_offset (const BrigDirectiveVariable *var) const -{ - var_offset_table::const_iterator i = m_kernarg_offsets.find (var); - gcc_assert (i != m_kernarg_offsets.end ()); - return (*i).second; -} - -/* Add work-item ID variables to the beginning of the kernel function - which can be used for address computation as kernel dispatch packet - instructions can be expanded to GENERIC nodes referring to them. */ - -void -brig_function::add_id_variables () -{ - tree bind_expr = m_current_bind_expr; - tree stmts = BIND_EXPR_BODY (bind_expr); - - /* Initialize the WG limits and local ids. */ - m_kernel_entry = tsi_start (stmts); - - for (int i = 0; i < 3; ++i) - { - char dim_char = (char) ((int) 'x' + i); - - /* The local sizes are limited to 16b values, but let's still use 32b - to avoid unnecessary casts (the ID functions are 32b). */ - m_local_id_vars[i] - = add_local_variable (std::string ("__local_") + dim_char, - long_long_integer_type_node); - - tree workitemid_call - = call_builtin (builtin_decl_explicit (BUILT_IN_HSAIL_WORKITEMID), 2, - uint32_type_node, uint32_type_node, - build_int_cst (uint32_type_node, i), ptr_type_node, - m_context_arg); - - tree id_init = build2 (MODIFY_EXPR, TREE_TYPE (m_local_id_vars[i]), - m_local_id_vars[i], - convert (TREE_TYPE (m_local_id_vars[i]), - workitemid_call)); - - append_statement (id_init); - - m_cur_wg_size_vars[i] - = add_local_variable (std::string ("__cur_wg_size_") + dim_char, - long_long_integer_type_node); - - tree cwgz_call; - if (flag_assume_phsa) - { - tree_stl_vec operands - = tree_stl_vec (1, build_int_cst (uint32_type_node, i)); - cwgz_call - = expand_or_call_builtin (BRIG_OPCODE_CURRENTWORKGROUPSIZE, - BRIG_TYPE_U32, uint32_type_node, - operands); - } - else - cwgz_call = call_builtin - (builtin_decl_explicit (BUILT_IN_HSAIL_CURRENTWORKGROUPSIZE), - 2, uint32_type_node, uint32_type_node, - build_int_cst (uint32_type_node, i), ptr_type_node, m_context_arg); - - tree limit_init = build2 (MODIFY_EXPR, TREE_TYPE (m_cur_wg_size_vars[i]), - m_cur_wg_size_vars[i], - convert (TREE_TYPE (m_cur_wg_size_vars[i]), - cwgz_call)); - - append_statement (limit_init); - - m_wg_id_vars[i] - = add_local_variable (std::string ("__workgroupid_") + dim_char, - uint32_type_node); - - tree wgid_call; - if (flag_assume_phsa) - { - tree_stl_vec operands - = tree_stl_vec (1, build_int_cst (uint32_type_node, i)); - wgid_call - = expand_or_call_builtin (BRIG_OPCODE_WORKGROUPID, BRIG_TYPE_U32, - uint32_type_node, operands); - } - else - wgid_call - = call_builtin (builtin_decl_explicit (BUILT_IN_HSAIL_WORKGROUPID), - 2, uint32_type_node, uint32_type_node, - build_int_cst (uint32_type_node, i), ptr_type_node, - m_context_arg); - - tree wgid_init = build2 (MODIFY_EXPR, TREE_TYPE (m_wg_id_vars[i]), - m_wg_id_vars[i], wgid_call); - - append_statement (wgid_init); - - m_wg_size_vars[i] - = add_local_variable (std::string ("__workgroupsize_") + dim_char, - uint32_type_node); - - tree wgsize_call; - if (flag_assume_phsa) - { - tree_stl_vec operands - = tree_stl_vec (1, build_int_cst (uint32_type_node, i)); - wgsize_call - = expand_or_call_builtin (BRIG_OPCODE_WORKGROUPSIZE, BRIG_TYPE_U32, - uint32_type_node, operands); - } - else - wgsize_call - = call_builtin (builtin_decl_explicit (BUILT_IN_HSAIL_WORKGROUPSIZE), - 2, uint32_type_node, uint32_type_node, - build_int_cst (uint32_type_node, i), ptr_type_node, - m_context_arg); - - tree wgsize_init = build2 (MODIFY_EXPR, TREE_TYPE (m_wg_size_vars[i]), - m_wg_size_vars[i], wgsize_call); - - append_statement (wgsize_init); - - m_grid_size_vars[i] - = add_local_variable (std::string ("__gridsize_") + dim_char, - uint32_type_node); - - tree gridsize_call - = call_builtin (builtin_decl_explicit (BUILT_IN_HSAIL_GRIDSIZE), 2, - uint32_type_node, uint32_type_node, - build_int_cst (uint32_type_node, i), ptr_type_node, - m_context_arg); - - tree gridsize_init = build2 (MODIFY_EXPR, TREE_TYPE (m_grid_size_vars[i]), - m_grid_size_vars[i], gridsize_call); - - append_statement (gridsize_init); - - m_abs_id_base_vars[i] - = add_local_variable (std::string ("__abs_id_base_") + dim_char, - long_long_integer_type_node); - - m_abs_id_vars[i] - = add_local_variable (std::string ("__abs_id_") + dim_char, - long_long_integer_type_node); - - tree abs_id_base - = build2 (MULT_EXPR, long_long_integer_type_node, - convert (long_long_integer_type_node, m_wg_id_vars[i]), - convert (long_long_integer_type_node, m_wg_size_vars[i])); - tree abs_id - = build2 (PLUS_EXPR, long_long_integer_type_node, abs_id_base, - convert (long_long_integer_type_node, m_local_id_vars[i])); - - tree abs_id_base_init - = build2 (MODIFY_EXPR, TREE_TYPE (m_abs_id_base_vars[i]), - m_abs_id_base_vars[i], abs_id_base); - append_statement (abs_id_base_init); - - tree abs_id_init = build2 (MODIFY_EXPR, - TREE_TYPE (m_abs_id_vars[i]), - m_abs_id_vars[i], abs_id); - append_statement (abs_id_init); - } -} - -/* Creates a new local variable with the given NAME and given GENERIC - TYPE. */ - -tree -brig_function::add_local_variable (std::string name, tree type) -{ - tree name_identifier - = get_identifier_with_length (name.c_str (), name.size ()); - tree variable - = build_decl (UNKNOWN_LOCATION, VAR_DECL, name_identifier, type); - - DECL_NONLOCAL (variable) = 0; - TREE_ADDRESSABLE (variable) = 0; - TREE_STATIC (variable) = 0; - TREE_USED (variable) = 1; - DECL_ARTIFICIAL (variable) = 0; - - tree bind_expr = DECL_SAVED_TREE (m_func_decl); - - DECL_CONTEXT (variable) = m_func_decl; - - DECL_CHAIN (variable) = BIND_EXPR_VARS (bind_expr); - BIND_EXPR_VARS (bind_expr) = variable; - return variable; -} - -/* Return tree type for an HSA register. - - The tree type can be anything (scalar, vector, int, float, etc.) - but its size is guaranteed to match the HSA register size. - - HSA registers are untyped but we select a type based on their use - to reduce (sometimes unoptimizable) VIEW_CONVERT_EXPR nodes (seems - to occur when use or def reaches over current BB). */ - -tree -brig_function::get_tree_type_for_hsa_reg (const BrigOperandRegister *reg) const -{ - size_t reg_size = gccbrig_reg_size (reg); - - /* The default type. */ - tree type = build_nonstandard_integer_type (reg_size, true); - - if (m_parent->m_fn_regs_use_index.count (m_name) == 0) - return type; - - const regs_use_index &index = m_parent->m_fn_regs_use_index[m_name]; - size_t reg_id = gccbrig_hsa_reg_id (*reg); - if (index.count (reg_id) == 0) - return type; - - const reg_use_info &info = index.find (reg_id)->second; - std::vector >::const_iterator it - = info.m_type_refs.begin (); - std::vector >::const_iterator it_end - = info.m_type_refs.end (); - size_t max_refs_as_type_count = 0; - for (; it != it_end; it++) - { - size_t type_bit_size = int_size_in_bytes (it->first) * BITS_PER_UNIT; - if (type_bit_size != reg_size) continue; - if (it->second > max_refs_as_type_count) - { - type = it->first; - max_refs_as_type_count = it->second; - } - } - - return type; -} - -/* Returns a DECL_VAR for the given HSAIL operand register. - If it has not been created yet for the function being generated, - creates it as a type determined by analysis phase. */ - -tree -brig_function::get_m_var_declfor_reg (const BrigOperandRegister *reg) -{ - size_t offset = gccbrig_hsa_reg_id (*reg); - - reg_decl_index_entry *regEntry = m_regs[offset]; - if (regEntry == NULL) - { - size_t reg_size = gccbrig_reg_size (reg); - tree type; - if (reg_size > 1) - type = get_tree_type_for_hsa_reg (reg); - else - type = boolean_type_node; - - /* Drop the const qualifier so we do not end up with a read only - register variable which cannot be written to later. */ - tree nonconst_type = build_type_variant (type, false, false); - - regEntry = new reg_decl_index_entry; - - regEntry->m_var_decl - = add_local_variable (gccbrig_reg_name (reg), nonconst_type); - m_regs[offset] = regEntry; - } - return regEntry->m_var_decl; -} - -/* Builds a work-item do..while loop for a single DIM. HEADER_ENTRY is - a statement after which the iteration variables should be initialized and - the loop body starts. BRANCH_AFTER is the statement after which the loop - predicate check and the back edge goto will be appended. */ - -void -brig_function::add_wi_loop (int dim, tree_stmt_iterator *header_entry, - tree_stmt_iterator *branch_after) -{ - tree ivar = m_local_id_vars[dim]; - tree abs_id_base_var = m_abs_id_base_vars[dim]; - tree abs_id_var = m_abs_id_vars[dim]; - tree ivar_max = m_cur_wg_size_vars[dim]; - tree_stmt_iterator entry = *header_entry; - - /* TODO: this is not a parallel loop as we share the "register variables" - across work-items. Should create a copy of them per WI instance. That - is, declare temporaries for new definitions inside the loop body, not at - function scope. */ - - tree ivar_init = build2 (MODIFY_EXPR, TREE_TYPE (ivar), ivar, - build_zero_cst (TREE_TYPE (ivar))); - tsi_link_after (&entry, ivar_init, TSI_NEW_STMT); - - tree abs_id_var_init = build2 (MODIFY_EXPR, TREE_TYPE (abs_id_var), - abs_id_var, - convert (TREE_TYPE (abs_id_var), - abs_id_base_var)); - tsi_link_after (&entry, abs_id_var_init, TSI_NEW_STMT); - - tree loop_body_label - = label (std::string ("__wi_loop_") + (char) ((int) 'x' + dim)); - tree loop_body_label_stmt = build_stmt (LABEL_EXPR, loop_body_label); - - tsi_link_after (&entry, loop_body_label_stmt, TSI_NEW_STMT); - - if (m_has_unexpanded_dp_builtins) - { - if (!flag_assume_phsa) - { - tree id_set_builtin - = builtin_decl_explicit (BUILT_IN_HSAIL_SETWORKITEMID); - /* Set the local ID to the current wi-loop iteration variable value - to ensure the builtins see the correct values. */ - tree id_set_call - = call_builtin (id_set_builtin, 3, - void_type_node, uint32_type_node, - build_int_cst (uint32_type_node, dim), - uint32_type_node, convert (uint32_type_node, ivar), - ptr_type_node, m_context_arg); - tsi_link_after (&entry, id_set_call, TSI_NEW_STMT); - } - else - { - tree ptr_type = build_pointer_type (uint32_type_node); - tree ctx = build2 (MEM_REF, uint32_type_node, m_context_arg, - build_int_cst (ptr_type, dim * 4)); - tree assign = build2 (MODIFY_EXPR, uint32_type_node, ctx, - convert (uint32_type_node, ivar)); - - tsi_link_after (&entry, assign, TSI_NEW_STMT); - } - } - - /* Increment the WI iteration variable. */ - tree incr = build2 (PREINCREMENT_EXPR, TREE_TYPE (ivar), ivar, - build_one_cst (TREE_TYPE (ivar))); - - tsi_link_after (branch_after, incr, TSI_NEW_STMT); - - /* ...and the abs id variable. */ - tree abs_id_incr = build2 (PREINCREMENT_EXPR, TREE_TYPE (abs_id_var), - abs_id_var, - build_one_cst (TREE_TYPE (abs_id_var))); - - tsi_link_after (branch_after, abs_id_incr, TSI_NEW_STMT); - - /* Append the predicate check with the back edge goto. */ - tree condition = build2 (LT_EXPR, TREE_TYPE (ivar), ivar, ivar_max); - tree target_goto = build1 (GOTO_EXPR, void_type_node, loop_body_label); - tree if_stmt - = build3 (COND_EXPR, void_type_node, condition, target_goto, NULL_TREE); - tsi_link_after (branch_after, if_stmt, TSI_NEW_STMT); -} - -/* Recursively analyzes the function and its callees for barrier usage. */ - -void -brig_function::analyze_calls () -{ - if (m_calls_analyzed) - return; - - /* Set this early to not get stuck in case of recursive call graphs. - This is safe because if the function calls itself, either the function - has barrier calls which implies a call to a function with barrier calls, - or it doesn't in which case the result depends on the later called - functions. */ - m_calls_analyzed = true; - - for (size_t i = 0; i < m_called_functions.size (); ++i) - { - tree f = m_called_functions[i]; - brig_function *called_f = m_parent->get_finished_function (f); - if (called_f == NULL) - { - /* Unfinished function (only declaration within the set of BRIGs) - found. Cannot finish the CG analysis. Have to assume it does have - a barrier for safety. */ - m_has_function_calls_with_barriers = true; - m_has_unexpanded_dp_builtins = true; - break; - } - called_f->analyze_calls (); - /* We can assume m_has_barriers has been correctly set during the - construction of the function decl. No need to reanalyze it. */ - m_has_function_calls_with_barriers |= called_f->m_has_barriers; - - /* If the function or any of its called functions has dispatch - packet builtin calls that require the local id, we need to - set the local id to the context in the work item loop before - the functions are called. If we analyze the opposite, these - function calls can be omitted. */ - m_has_unexpanded_dp_builtins |= called_f->m_has_unexpanded_dp_builtins; - } -} - -/* Tries to convert the current kernel to a work-group function that executes - all work-items using loops. Returns true in case the conversion was - successful. */ - -bool -brig_function::convert_to_wg_function () -{ - if (!m_calls_analyzed) - analyze_calls (); - - if (m_has_barriers || m_has_function_calls_with_barriers) - return false; - - /* The most trivial case: No barriers at all in the kernel. - We can create one big work-item loop around the whole kernel. */ - tree bind_expr = m_current_bind_expr; - tree stmts = BIND_EXPR_BODY (bind_expr); - - for (int i = 0; i < 3; ++i) - { - /* The previous loop has added a new label to the end of the function, - the next level loop should wrap around it also. */ - tree_stmt_iterator function_exit = tsi_last (stmts); - add_wi_loop (i, &m_kernel_entry, &function_exit); - } - - m_is_wg_function = true; - return false; -} - -/* Emits a kernel description to a special ELF section so it can be - utilized by an HSA runtime implementation. The assembly block - must be emitted to a statement list of an function, which is given - as an argument. Returns the assembly block used to emit the section. */ - -tree -brig_function::emit_metadata (tree stmt_list) -{ - /* Emit an ELF section via an assembly directive that generates a special - ELF section for each kernel that contains raw bytes of a descriptor - object. This is pretty disgusting, but life is never perfect ;) */ - - /* Use the original kernel name without the '_' prefix in the section name. */ - std::string kern_name = m_is_kernel ? m_name.substr (1) : m_name; - - std::ostringstream strstr; - strstr << std::endl - << ".pushsection " << PHSA_DESC_SECTION_PREFIX << kern_name - << std::endl - << "\t.p2align 1, 1, 1" << std::endl - << "\t.byte "; - - for (size_t i = 0; i < sizeof (phsa_descriptor); ++i) - { - strstr << "0x" << std::setw (2) << std::setfill ('0') << std::hex - << (unsigned) *((unsigned char *) &m_descriptor + i); - if (i + 1 < sizeof (phsa_descriptor)) - strstr << ", "; - } - - strstr << std::endl << ".popsection" << std::endl << std::endl; - - tree metadata_asm - = build_stmt (ASM_EXPR, - build_string (strstr.str ().size (), strstr.str ().c_str ()), - NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE); - - append_to_statement_list_force (metadata_asm, &stmt_list); - return metadata_asm; -} - -/* Emits the kernel launcher function. Also emits the metadata section - creation statements in it. - - The launcher function calls the device-side runtime - that runs the kernel for all work-items. In C: - - void KernelName (void* context, void* group_base_addr) - { - __hsail_launch_kernel (_KernelName, context, group_base_addr); - } - - or, in case of a successful conversion to a work-group function: - - void KernelName (void* context, void* group_base_addr) - { - __hsail_launch_wg_function (_KernelName, context, group_base_addr); - } - - The user/host sees this function as the kernel to call from the - outside. The actual kernel generated from HSAIL was named _KernelName. -*/ - -tree -brig_function::emit_launcher_and_metadata () -{ - /* The original kernel name without the '_' prefix. */ - std::string kern_name = m_name.substr (1); - - tree name_identifier - = get_identifier_with_length (kern_name.c_str (), kern_name.size ()); - - tree restrict_void_ptr - = build_qualified_type (build_pointer_type (void_type_node), - TYPE_QUAL_RESTRICT); - tree restrict_char_ptr - = build_qualified_type (build_pointer_type (char_type_node), - TYPE_QUAL_RESTRICT); - tree launcher - = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, name_identifier, - build_function_type_list (void_type_node, restrict_void_ptr, - restrict_char_ptr, NULL_TREE)); - - TREE_USED (launcher) = 1; - DECL_ARTIFICIAL (launcher) = 1; - - tree context_arg = build_decl (UNKNOWN_LOCATION, PARM_DECL, - get_identifier ("__context"), - restrict_void_ptr); - - DECL_ARGUMENTS (launcher) = context_arg; - DECL_ARG_TYPE (context_arg) = restrict_void_ptr; - DECL_CONTEXT (context_arg) = launcher; - TREE_USED (context_arg) = 1; - DECL_ARTIFICIAL (context_arg) = 1; - - tree group_base_addr_arg - = build_decl (UNKNOWN_LOCATION, PARM_DECL, - get_identifier ("__group_base_addr"), restrict_char_ptr); - - chainon (DECL_ARGUMENTS (launcher), group_base_addr_arg); - DECL_ARG_TYPE (group_base_addr_arg) = restrict_char_ptr; - DECL_CONTEXT (group_base_addr_arg) = launcher; - TREE_USED (group_base_addr_arg) = 1; - DECL_ARTIFICIAL (group_base_addr_arg) = 1; - - tree resdecl - = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, void_type_node); - - DECL_RESULT (launcher) = resdecl; - DECL_CONTEXT (resdecl) = launcher; - - DECL_INITIAL (launcher) = make_node (BLOCK); - TREE_USED (DECL_INITIAL (launcher)) = 1; - - tree stmt_list = alloc_stmt_list (); - - tree bind_expr = build3 (BIND_EXPR, void_type_node, NULL, stmt_list, NULL); - - TREE_STATIC (launcher) = 1; - TREE_PUBLIC (launcher) = 1; - - DECL_SAVED_TREE (launcher) = bind_expr; - - if (DECL_STRUCT_FUNCTION (launcher) == NULL) - push_struct_function (launcher); - else - push_cfun (DECL_STRUCT_FUNCTION (launcher)); - - tree kernel_func_ptr = build1 (ADDR_EXPR, ptr_type_node, m_func_decl); - - tree phsail_launch_kernel_call; - - /* Compute the local group segment frame start pointer. */ - tree group_local_offset_temp - = create_tmp_var (uint32_type_node, "group_local_offset"); - tree group_local_offset_arg - = build2 (MODIFY_EXPR, uint32_type_node, - group_local_offset_temp, - build_int_cst (uint32_type_node, - m_parent->m_module_group_variables.size())); - - /* Emit a launcher depending whether we converted the kernel function to - a work group function or not. */ - if (m_is_wg_function) - phsail_launch_kernel_call - = call_builtin (builtin_decl_explicit (BUILT_IN_HSAIL_LAUNCH_WG_FUNC), - 4, void_type_node, - ptr_type_node, kernel_func_ptr, restrict_void_ptr, - context_arg, restrict_char_ptr, group_base_addr_arg, - uint32_type_node, group_local_offset_arg); - else - phsail_launch_kernel_call - = call_builtin (builtin_decl_explicit (BUILT_IN_HSAIL_LAUNCH_KERNEL), - 4, void_type_node, - ptr_type_node, kernel_func_ptr, restrict_void_ptr, - context_arg, restrict_char_ptr, group_base_addr_arg, - uint32_type_node, group_local_offset_arg); - - append_to_statement_list_force (phsail_launch_kernel_call, &stmt_list); - - emit_metadata (stmt_list); - - set_externally_visible (launcher); - - return launcher; -} - -tree -brig_function::append_statement (tree stmt) -{ - gcc_assert (m_func_decl != NULL); - - tree bind_expr = m_current_bind_expr; - tree stmts = BIND_EXPR_BODY (bind_expr); - - append_to_statement_list_force (stmt, &stmts); - return stmt; -} - -/* Creates a new "alloca frame" for the current function by - injecting an alloca frame push in the beginning of the function - and an alloca frame pop before all function exit points. */ - -void -brig_function::create_alloca_frame () -{ - tree_stmt_iterator entry; - - /* Adds the alloca push only after the ids have been initialized - in case of a kernel function. */ - if (m_is_kernel) - entry = m_kernel_entry; - else - { - tree bind_expr = m_current_bind_expr; - tree stmts = BIND_EXPR_BODY (bind_expr); - entry = tsi_start (stmts); - } - - tree push_frame_builtin = builtin_decl_explicit (BUILT_IN_HSAIL_PUSH_FRAME); - tree push_frame_call - = call_builtin (push_frame_builtin, 1, void_type_node, ptr_type_node, - m_context_arg); - - tsi_link_before (&entry, push_frame_call, TSI_NEW_STMT); - - tree pop_frame_builtin = builtin_decl_explicit (BUILT_IN_HSAIL_POP_FRAME); - - do - { - tree stmt = tsi_stmt (entry); - if (TREE_CODE (stmt) == RETURN_EXPR) - { - tree pop_frame_call - = call_builtin (pop_frame_builtin, 1, void_type_node, - ptr_type_node, m_context_arg); - - tsi_link_before (&entry, pop_frame_call, TSI_SAME_STMT); - } - tsi_next (&entry); - } - while (!tsi_end_p (entry)); -} - -/* Finishes the currently built function. After calling this, no new - statements should be appeneded to the function. */ -void -brig_function::finish () -{ - append_return_stmt (); - - /* Currently assume single alloca frame per WG. */ - if (m_has_allocas) - create_alloca_frame (); -} - -void -brig_function::finish_kernel () -{ - /* Kernel functions should have a single exit point. - Let's create one. The return instructions should have - been converted to branches to this label. */ - append_statement (build_stmt (LABEL_EXPR, m_exit_label)); - /* Attempt to convert the kernel to a work-group function that - executes all work-items of the WG using a loop. */ - convert_to_wg_function (); - - append_return_stmt (); - - /* Currently assume single alloca frame per WG. */ - if (m_has_allocas) - create_alloca_frame (); -} - -void -brig_function::append_return_stmt () -{ - gcc_assert (m_current_bind_expr != NULL_TREE); - tree stmts = BIND_EXPR_BODY (m_current_bind_expr); - - if (STATEMENT_LIST_TAIL (stmts) == NULL) - return; /* Empty function. */ - - tree last_stmt = tsi_stmt (tsi_last (stmts)); - - if (TREE_CODE (last_stmt) == RETURN_EXPR) - return; - - if (m_ret_value != NULL_TREE) - { - tree result_assign - = build2 (MODIFY_EXPR, TREE_TYPE (m_ret_value), m_ret_value, - m_ret_temp); - - tree return_expr - = build1 (RETURN_EXPR, TREE_TYPE (result_assign), result_assign); - append_to_statement_list_force (return_expr, &stmts); - } - else - { - tree return_stmt = build_stmt (RETURN_EXPR, NULL); - append_to_statement_list_force (return_stmt, &stmts); - } -} - -bool -brig_function::has_function_scope_var (const BrigBase* var) const -{ - return m_function_scope_vars.find (var) != m_function_scope_vars.end (); -} - -size_t -brig_function::group_variable_segment_offset (const std::string &name) const -{ - if (m_local_group_variables.has_variable (name)) - return m_local_group_variables.segment_offset (name); - - gcc_assert (m_parent->m_module_group_variables.has_variable (name)); - return m_parent->m_module_group_variables.segment_offset (name); -} - -/* Try to expand the given builtin call to reuse a previously generated - variable, if possible. If not, just call the given builtin. - BRIG_OPCODE and BRIG_TYPE identify the builtin's BRIG opcode/type, - ARITH_TYPE its GENERIC type, and OPERANDS contains the builtin's - input operands. */ - -tree -brig_function::expand_or_call_builtin (BrigOpcode16_t brig_opcode, - BrigType16_t brig_type, - tree arith_type, - tree_stl_vec &operands) -{ - if (needs_workitem_context_data (brig_opcode)) - m_has_unexpanded_dp_builtins = true; - - if (can_expand_builtin (brig_opcode)) - return expand_builtin (brig_opcode, operands); - - tree built_in - = get_builtin_for_hsa_opcode (arith_type, brig_opcode, brig_type); - - if (!VECTOR_TYPE_P (TREE_TYPE (TREE_TYPE (built_in))) - && arith_type != NULL_TREE && VECTOR_TYPE_P (arith_type) - && brig_opcode != BRIG_OPCODE_LERP - && brig_opcode != BRIG_OPCODE_PACKCVT - && brig_opcode != BRIG_OPCODE_SAD - && brig_opcode != BRIG_OPCODE_SADHI) - { - /* Call the scalar built-in for all elements in the vector. */ - tree_stl_vec operand0_elements; - if (operands.size () > 0) - unpack (operands[0], operand0_elements); - - tree_stl_vec operand1_elements; - if (operands.size () > 1) - unpack (operands[1], operand1_elements); - - tree_stl_vec result_elements; - - size_t element_count = gccbrig_type_vector_subparts (arith_type); - for (size_t i = 0; i < element_count; ++i) - { - tree_stl_vec call_operands; - if (operand0_elements.size () > 0) - call_operands.push_back (operand0_elements.at (i)); - - if (operand1_elements.size () > 0) - call_operands.push_back (operand1_elements.at (i)); - - result_elements.push_back - (expand_or_call_builtin (brig_opcode, brig_type, - TREE_TYPE (arith_type), - call_operands)); - } - return pack (result_elements); - } - - tree_stl_vec call_operands; - tree_stl_vec operand_types; - - tree arg_type_chain = TYPE_ARG_TYPES (TREE_TYPE (built_in)); - - for (size_t i = 0; i < operands.size (); ++i) - { - tree operand_type = TREE_VALUE (arg_type_chain); - call_operands.push_back (convert (operand_type, operands[i])); - operand_types.push_back (operand_type); - arg_type_chain = TREE_CHAIN (arg_type_chain); - } - - if (needs_workitem_context_data (brig_opcode)) - { - call_operands.push_back (m_context_arg); - operand_types.push_back (ptr_type_node); - } - - size_t operand_count = call_operands.size (); - - call_operands.resize (4, NULL_TREE); - operand_types.resize (4, NULL_TREE); - for (size_t i = 0; i < operand_count; ++i) - call_operands.at (i) = build_resize_convert_view (operand_types.at (i), - call_operands.at (i)); - - tree fnptr = build_fold_addr_expr (built_in); - return build_call_array (TREE_TYPE (TREE_TYPE (built_in)), fnptr, - operand_count, &call_operands[0]); -} - -/* Instead of calling a built-in function, use a more efficient mechanism - such as reuse a previously returned value known to be still valid, or - access the work-item context struct directly. This is beneficial especially - for the work-item identification related builtins as not having them as - unanalyzable black box calls can lead to more easily vectorizable parallel - loops for multi work-item work-groups. BRIG_OPCODE identifies the builtin - and OPERANDS store the operands. */ - -tree -brig_function::expand_builtin (BrigOpcode16_t brig_opcode, - tree_stl_vec &operands) -{ - tree_stl_vec uint32_0 = tree_stl_vec (1, build_int_cst (uint32_type_node, 0)); - - tree_stl_vec uint32_1 = tree_stl_vec (1, build_int_cst (uint32_type_node, 1)); - - tree_stl_vec uint32_2 = tree_stl_vec (1, build_int_cst (uint32_type_node, 2)); - - if (brig_opcode == BRIG_OPCODE_WORKITEMFLATABSID) - { - tree id0 = expand_builtin (BRIG_OPCODE_WORKITEMABSID, uint32_0); - id0 = convert (uint64_type_node, id0); - - tree id1 = expand_builtin (BRIG_OPCODE_WORKITEMABSID, uint32_1); - id1 = convert (uint64_type_node, id1); - - tree id2 = expand_builtin (BRIG_OPCODE_WORKITEMABSID, uint32_2); - id2 = convert (uint64_type_node, id2); - - tree max0 = convert (uint64_type_node, m_grid_size_vars[0]); - tree max1 = convert (uint64_type_node, m_grid_size_vars[1]); - - tree id2_x_max0_x_max1 = build2 (MULT_EXPR, uint64_type_node, id2, max0); - id2_x_max0_x_max1 - = build2 (MULT_EXPR, uint64_type_node, id2_x_max0_x_max1, max1); - - tree id1_x_max0 = build2 (MULT_EXPR, uint64_type_node, id1, max0); - - tree sum = build2 (PLUS_EXPR, uint64_type_node, id0, id1_x_max0); - sum = build2 (PLUS_EXPR, uint64_type_node, sum, id2_x_max0_x_max1); - - return add_temp_var ("workitemflatabsid", sum); - } - else if (brig_opcode == BRIG_OPCODE_WORKITEMABSID) - { - HOST_WIDE_INT dim = int_constant_value (operands[0]); - return m_abs_id_vars[dim]; - } - else if (brig_opcode == BRIG_OPCODE_WORKITEMFLATID) - { - - tree wg_size_x = expand_builtin (BRIG_OPCODE_WORKGROUPSIZE, uint32_0); - tree wg_size_y = expand_builtin (BRIG_OPCODE_WORKGROUPSIZE, uint32_1); - tree z_x_wgsx_wgsy - = build2 (MULT_EXPR, uint32_type_node, - convert (uint32_type_node, - expand_builtin (BRIG_OPCODE_WORKITEMID, uint32_2)), - wg_size_x); - z_x_wgsx_wgsy = build2 (MULT_EXPR, uint32_type_node, z_x_wgsx_wgsy, - wg_size_y); - - tree y_x_wgsx - = build2 (MULT_EXPR, uint32_type_node, - convert (uint32_type_node, - expand_builtin (BRIG_OPCODE_WORKITEMID, uint32_1)), - wg_size_x); - - tree sum = build2 (PLUS_EXPR, uint32_type_node, y_x_wgsx, z_x_wgsx_wgsy); - sum = build2 (PLUS_EXPR, uint32_type_node, - convert (uint32_type_node, - expand_builtin (BRIG_OPCODE_WORKITEMID, uint32_0)), - sum); - return add_temp_var ("workitemflatid", sum); - } - else if (brig_opcode == BRIG_OPCODE_WORKGROUPSIZE) - { - HOST_WIDE_INT dim = int_constant_value (operands[0]); - if (flag_assume_phsa) - { - tree ptr_type = build_pointer_type (uint32_type_node); - tree ctx = build2 (MEM_REF, uint32_type_node, m_context_arg, - build_int_cst (ptr_type, - PHSA_CONTEXT_WG_SIZES - + dim * 4)); - std::string name ("wgsize_x"); - name [name.length() - 1] += dim; - return add_temp_var (name.c_str(), ctx); - } - else if (m_is_kernel) - { - /* For kernels without phsa we generate certain temps before - the WI loop, which means we don't need to rely on LICM to get - them moved out. */ - return m_wg_size_vars[dim]; - } - else - gcc_unreachable (); - } - else if (brig_opcode == BRIG_OPCODE_WORKITEMID) - { - HOST_WIDE_INT dim = int_constant_value (operands[0]); - if (m_is_kernel) - { - return m_local_id_vars [dim]; - } - else if (flag_assume_phsa) - { - tree ptr_type = build_pointer_type (uint32_type_node); - tree ctx = build2 (MEM_REF, uint32_type_node, m_context_arg, - build_int_cst (ptr_type, - PHSA_CONTEXT_OFFS_WI_IDS - + dim * 4)); - std::string name ("wiid_x"); - name [name.length() - 1] += dim; - return add_temp_var (name.c_str(), ctx); - } - else - gcc_unreachable (); - } - else if (brig_opcode == BRIG_OPCODE_WORKGROUPID) - { - HOST_WIDE_INT dim = int_constant_value (operands[0]); - if (flag_assume_phsa) - { - tree ptr_type = build_pointer_type (uint32_type_node); - tree ctx = build2 (MEM_REF, uint32_type_node, m_context_arg, - build_int_cst (ptr_type, - PHSA_CONTEXT_OFFS_WG_IDS - + dim * 4)); - std::string name ("wgid_x"); - name [name.length() - 1] += dim; - return add_temp_var (name.c_str(), ctx); - } else if (m_is_kernel) - return m_wg_id_vars [dim]; - else - gcc_unreachable (); - } - else if (brig_opcode == BRIG_OPCODE_CURRENTWORKGROUPSIZE) - { - HOST_WIDE_INT dim = int_constant_value (operands[0]); - if (flag_assume_phsa) - { - tree ptr_type = build_pointer_type (uint32_type_node); - tree ctx = build2 (MEM_REF, uint32_type_node, m_context_arg, - build_int_cst (ptr_type, - PHSA_CONTEXT_CURRENT_WG_SIZES - + dim * 4)); - std::string name ("curwgsize_x"); - name [name.length() - 1] += dim; - return add_temp_var (name.c_str(), ctx); - } else if (m_is_kernel) - return m_cur_wg_size_vars[dim]; - else - gcc_unreachable (); - } - else - gcc_unreachable (); - - return NULL_TREE; -} - -/* Returns true in case the given opcode that would normally be generated - as a builtin call can be expanded to tree nodes. */ - -bool -brig_function::can_expand_builtin (BrigOpcode16_t brig_opcode) const -{ - switch (brig_opcode) - { - case BRIG_OPCODE_CURRENTWORKGROUPSIZE: - case BRIG_OPCODE_WORKITEMFLATID: - case BRIG_OPCODE_WORKITEMID: - case BRIG_OPCODE_WORKGROUPID: - case BRIG_OPCODE_WORKGROUPSIZE: - return m_is_kernel || flag_assume_phsa; - case BRIG_OPCODE_WORKITEMFLATABSID: - case BRIG_OPCODE_WORKITEMABSID: - return m_is_kernel; - default: - return false; - }; -} - -/* In case the HSA instruction must be implemented using a builtin, - this function is called to get the correct builtin function. - TYPE is the instruction tree type, BRIG_OPCODE the opcode of the - brig instruction and BRIG_TYPE the brig instruction's type. */ - -tree -brig_function::get_builtin_for_hsa_opcode - (tree type, BrigOpcode16_t brig_opcode, BrigType16_t brig_type) const -{ - tree builtin = NULL_TREE; - tree builtin_type = type; - - /* For vector types, first find the scalar version of the builtin. */ - if (type != NULL_TREE && VECTOR_TYPE_P (type)) - builtin_type = TREE_TYPE (type); - BrigType16_t brig_inner_type = brig_type & BRIG_TYPE_BASE_MASK; - - /* Some BRIG opcodes can use the same builtins for unsigned and - signed types. Force these cases to unsigned types. */ - - if (brig_opcode == BRIG_OPCODE_BORROW - || brig_opcode == BRIG_OPCODE_CARRY - || brig_opcode == BRIG_OPCODE_LASTBIT - || brig_opcode == BRIG_OPCODE_BITINSERT) - { - if (brig_type == BRIG_TYPE_S32) - brig_type = BRIG_TYPE_U32; - else if (brig_type == BRIG_TYPE_S64) - brig_type = BRIG_TYPE_U64; - } - - switch (brig_opcode) - { - case BRIG_OPCODE_FLOOR: - builtin = mathfn_built_in (builtin_type, BUILT_IN_FLOOR); - break; - case BRIG_OPCODE_CEIL: - builtin = mathfn_built_in (builtin_type, BUILT_IN_CEIL); - break; - case BRIG_OPCODE_SQRT: - case BRIG_OPCODE_NSQRT: - builtin = mathfn_built_in (builtin_type, BUILT_IN_SQRT); - break; - case BRIG_OPCODE_RINT: - builtin = mathfn_built_in (builtin_type, BUILT_IN_RINT); - break; - case BRIG_OPCODE_TRUNC: - builtin = mathfn_built_in (builtin_type, BUILT_IN_TRUNC); - break; - case BRIG_OPCODE_COPYSIGN: - builtin = mathfn_built_in (builtin_type, BUILT_IN_COPYSIGN); - break; - case BRIG_OPCODE_NSIN: - builtin = mathfn_built_in (builtin_type, BUILT_IN_SIN); - break; - case BRIG_OPCODE_NLOG2: - builtin = mathfn_built_in (builtin_type, BUILT_IN_LOG2); - break; - case BRIG_OPCODE_NEXP2: - builtin = mathfn_built_in (builtin_type, BUILT_IN_EXP2); - break; - case BRIG_OPCODE_FMA: - case BRIG_OPCODE_NFMA: - builtin = mathfn_built_in (builtin_type, BUILT_IN_FMA); - break; - case BRIG_OPCODE_NCOS: - builtin = mathfn_built_in (builtin_type, BUILT_IN_COS); - break; - case BRIG_OPCODE_POPCOUNT: - /* Popcount should be typed by its argument type (the return value - is always u32). Let's use a b64 version for also for b32 for now. */ - return builtin_decl_explicit (BUILT_IN_POPCOUNTL); - case BRIG_OPCODE_BORROW: - /* Borrow uses the same builtin for unsigned and signed types. */ - if (brig_type == BRIG_TYPE_S32 || brig_type == BRIG_TYPE_U32) - return builtin_decl_explicit (BUILT_IN_HSAIL_BORROW_U32); - else - return builtin_decl_explicit (BUILT_IN_HSAIL_BORROW_U64); - case BRIG_OPCODE_CARRY: - /* Carry also uses the same builtin for unsigned and signed types. */ - if (brig_type == BRIG_TYPE_S32 || brig_type == BRIG_TYPE_U32) - return builtin_decl_explicit (BUILT_IN_HSAIL_CARRY_U32); - else - return builtin_decl_explicit (BUILT_IN_HSAIL_CARRY_U64); - default: - - /* Use our builtin index for finding a proper builtin for the BRIG - opcode and BRIG type. This takes care most of the builtin cases, - the special cases are handled in the separate 'case' statements - above. */ - builtin_map::const_iterator i - = s_custom_builtins.find (std::make_pair (brig_opcode, brig_type)); - if (i != s_custom_builtins.end ()) - return (*i).second; - - if (brig_inner_type != brig_type) - { - /* Try to find a scalar built-in we could use. */ - i = s_custom_builtins.find - (std::make_pair (brig_opcode, brig_inner_type)); - if (i != s_custom_builtins.end ()) - return (*i).second; - } - - /* In case this is an fp16 operation that is promoted to fp32, - try to find a fp32 scalar built-in. */ - if (brig_inner_type == BRIG_TYPE_F16) - { - i = s_custom_builtins.find - (std::make_pair (brig_opcode, BRIG_TYPE_F32)); - if (i != s_custom_builtins.end ()) - return (*i).second; - } - gcc_unreachable (); - } - - if (VECTOR_TYPE_P (type) && builtin != NULL_TREE) - { - /* Try to find a vectorized version of the built-in. - TODO: properly assert that builtin is a mathfn builtin? */ - tree vec_builtin - = targetm.vectorize.builtin_vectorized_function - (builtin_mathfn_code (builtin), type, type); - if (vec_builtin != NULL_TREE) - return vec_builtin; - else - return builtin; - } - if (builtin == NULL_TREE) - gcc_unreachable (); - return builtin; -} - -/* Unpacks the elements of the vector in VALUE to scalars (bit field - references) in ELEMENTS. */ - -void -brig_function::unpack (tree value, tree_stl_vec &elements) -{ - size_t vec_size = int_size_in_bytes (TREE_TYPE (value)); - size_t element_size - = int_size_in_bytes (TREE_TYPE (TREE_TYPE (value))) * BITS_PER_UNIT; - size_t element_count - = vec_size * BITS_PER_UNIT / element_size; - - tree input_element_type = TREE_TYPE (TREE_TYPE (value)); - - value = add_temp_var ("unpack_input", value); - - for (size_t i = 0; i < element_count; ++i) - { - tree element - = build3 (BIT_FIELD_REF, input_element_type, value, - TYPE_SIZE (input_element_type), - bitsize_int(i * element_size)); - - element = add_temp_var ("scalar", element); - elements.push_back (element); - } -} - -/* Pack the elements of the scalars in ELEMENTS to the returned vector. */ - -tree -brig_function::pack (tree_stl_vec &elements) -{ - size_t element_count = elements.size (); - - gcc_assert (element_count > 1); - - tree output_element_type = TREE_TYPE (elements.at (0)); - - vec *constructor_vals = NULL; - for (size_t i = 0; i < element_count; ++i) - CONSTRUCTOR_APPEND_ELT (constructor_vals, NULL_TREE, elements.at (i)); - - tree vec_type = build_vector_type (output_element_type, element_count); - - /* build_constructor creates a vector type which is not a vector_cst - that requires compile time constant elements. */ - tree vec = build_constructor (vec_type, constructor_vals); - - /* Add a temp variable for readability. */ - tree tmp_var = create_tmp_var (vec_type, "vec_out"); - tree vec_tmp_assign = build2 (MODIFY_EXPR, TREE_TYPE (tmp_var), tmp_var, vec); - append_statement (vec_tmp_assign); - return tmp_var; -} - -/* Returns true in case the given opcode needs to know about work-item context - data. In such case the context data is passed as a pointer to a work-item - context object, as the last argument in the builtin call. */ - -bool -brig_function::needs_workitem_context_data -(BrigOpcode16_t brig_opcode) -{ - switch (brig_opcode) - { - case BRIG_OPCODE_WORKITEMABSID: - case BRIG_OPCODE_WORKITEMFLATABSID: - case BRIG_OPCODE_WORKITEMFLATID: - case BRIG_OPCODE_CURRENTWORKITEMFLATID: - case BRIG_OPCODE_WORKITEMID: - case BRIG_OPCODE_WORKGROUPID: - case BRIG_OPCODE_WORKGROUPSIZE: - case BRIG_OPCODE_CURRENTWORKGROUPSIZE: - case BRIG_OPCODE_GRIDGROUPS: - case BRIG_OPCODE_GRIDSIZE: - case BRIG_OPCODE_DIM: - case BRIG_OPCODE_PACKETID: - case BRIG_OPCODE_PACKETCOMPLETIONSIG: - case BRIG_OPCODE_BARRIER: - case BRIG_OPCODE_WAVEBARRIER: - case BRIG_OPCODE_ARRIVEFBAR: - case BRIG_OPCODE_INITFBAR: - case BRIG_OPCODE_JOINFBAR: - case BRIG_OPCODE_LEAVEFBAR: - case BRIG_OPCODE_RELEASEFBAR: - case BRIG_OPCODE_WAITFBAR: - case BRIG_OPCODE_CUID: - case BRIG_OPCODE_MAXCUID: - case BRIG_OPCODE_DEBUGTRAP: - case BRIG_OPCODE_GROUPBASEPTR: - case BRIG_OPCODE_KERNARGBASEPTR: - case BRIG_OPCODE_ALLOCA: - return true; - default: - return false; - }; -} - -/* Appends and returns a new temp variable and an accompanying assignment - statement that stores the value of the given EXPR and has the given NAME. */ - -tree -brig_function::add_temp_var (std::string name, tree expr) -{ - tree temp_var = create_tmp_var (TREE_TYPE (expr), name.c_str ()); - tree assign = build2 (MODIFY_EXPR, TREE_TYPE (temp_var), temp_var, expr); - append_statement (assign); - return temp_var; -} - -/* Returns the integer constant value of the given node. - If it's a cast, looks into the source of the cast. */ - -HOST_WIDE_INT -brig_function::int_constant_value (tree node) -{ - tree n = node; - if (TREE_CODE (n) == VIEW_CONVERT_EXPR) - n = TREE_OPERAND (n, 0); - return int_cst_value (n); -} - -/* Returns the tree code that should be used to implement the given - HSA instruction opcode (BRIG_OPCODE) for the given type of instruction - (BRIG_TYPE). In case the opcode cannot be mapped to a TREE node directly, - returns TREE_LIST (if it can be emulated with a simple chain of tree - nodes) or CALL_EXPR if the opcode should be implemented using a builtin - call. */ - -tree_code -brig_function::get_tree_code_for_hsa_opcode - (BrigOpcode16_t brig_opcode, BrigType16_t brig_type) -{ - BrigType16_t brig_inner_type = brig_type & BRIG_TYPE_BASE_MASK; - switch (brig_opcode) - { - case BRIG_OPCODE_NOP: - return NOP_EXPR; - case BRIG_OPCODE_ADD: - return PLUS_EXPR; - case BRIG_OPCODE_CMOV: - if (brig_inner_type == brig_type) - return COND_EXPR; - else - return VEC_COND_EXPR; - case BRIG_OPCODE_SUB: - return MINUS_EXPR; - case BRIG_OPCODE_MUL: - case BRIG_OPCODE_MUL24: - return MULT_EXPR; - case BRIG_OPCODE_MULHI: - case BRIG_OPCODE_MUL24HI: - return MULT_HIGHPART_EXPR; - case BRIG_OPCODE_DIV: - if (gccbrig_is_float_type (brig_inner_type)) - return RDIV_EXPR; - else - return TRUNC_DIV_EXPR; - case BRIG_OPCODE_NEG: - return NEGATE_EXPR; - case BRIG_OPCODE_MIN: - if (gccbrig_is_float_type (brig_inner_type)) - return CALL_EXPR; - else - return MIN_EXPR; - case BRIG_OPCODE_MAX: - if (gccbrig_is_float_type (brig_inner_type)) - return CALL_EXPR; - else - return MAX_EXPR; - case BRIG_OPCODE_ABS: - return ABS_EXPR; - case BRIG_OPCODE_SHL: - return LSHIFT_EXPR; - case BRIG_OPCODE_SHR: - return RSHIFT_EXPR; - case BRIG_OPCODE_OR: - return BIT_IOR_EXPR; - case BRIG_OPCODE_XOR: - return BIT_XOR_EXPR; - case BRIG_OPCODE_AND: - return BIT_AND_EXPR; - case BRIG_OPCODE_NOT: - return BIT_NOT_EXPR; - case BRIG_OPCODE_RET: - return RETURN_EXPR; - case BRIG_OPCODE_MOV: - case BRIG_OPCODE_LDF: - return MODIFY_EXPR; - case BRIG_OPCODE_LD: - case BRIG_OPCODE_ST: - return MEM_REF; - case BRIG_OPCODE_BR: - return GOTO_EXPR; - case BRIG_OPCODE_REM: - if (brig_type == BRIG_TYPE_U64 || brig_type == BRIG_TYPE_U32) - return TRUNC_MOD_EXPR; - else - return CALL_EXPR; - case BRIG_OPCODE_NRCP: - case BRIG_OPCODE_NRSQRT: - /* Implement as 1/f (x). gcc should pattern detect that and - use a native instruction, if available, for it. */ - return TREE_LIST; - case BRIG_OPCODE_FMA: - case BRIG_OPCODE_FLOOR: - case BRIG_OPCODE_CEIL: - case BRIG_OPCODE_SQRT: - case BRIG_OPCODE_NSQRT: - case BRIG_OPCODE_RINT: - case BRIG_OPCODE_TRUNC: - case BRIG_OPCODE_POPCOUNT: - case BRIG_OPCODE_COPYSIGN: - case BRIG_OPCODE_NCOS: - case BRIG_OPCODE_NSIN: - case BRIG_OPCODE_NLOG2: - case BRIG_OPCODE_NEXP2: - case BRIG_OPCODE_NFMA: - /* Class has type B1 regardless of the float type, thus - the below builtin map search cannot find it. */ - case BRIG_OPCODE_CLASS: - case BRIG_OPCODE_WORKITEMABSID: - return CALL_EXPR; - default: - - /* Some BRIG opcodes can use the same builtins for unsigned and - signed types. Force these cases to unsigned types. - */ - - if (brig_opcode == BRIG_OPCODE_BORROW - || brig_opcode == BRIG_OPCODE_CARRY - || brig_opcode == BRIG_OPCODE_LASTBIT - || brig_opcode == BRIG_OPCODE_BITINSERT) - { - if (brig_type == BRIG_TYPE_S32) - brig_type = BRIG_TYPE_U32; - else if (brig_type == BRIG_TYPE_S64) - brig_type = BRIG_TYPE_U64; - } - - - builtin_map::const_iterator i - = s_custom_builtins.find (std::make_pair (brig_opcode, brig_type)); - if (i != s_custom_builtins.end ()) - return CALL_EXPR; - else if (s_custom_builtins.find - (std::make_pair (brig_opcode, brig_inner_type)) - != s_custom_builtins.end ()) - return CALL_EXPR; - if (brig_inner_type == BRIG_TYPE_F16 - && s_custom_builtins.find - (std::make_pair (brig_opcode, BRIG_TYPE_F32)) - != s_custom_builtins.end ()) - return CALL_EXPR; - break; - } - return TREE_LIST; /* Emulate using a chain of nodes. */ -} - -/* Inform of an update to the REG_VAR. */ - -void -brig_function::add_reg_var_update (tree reg_var, tree var) -{ - if (var == m_abs_id_vars[0] || var == m_abs_id_vars[1] - || var == m_abs_id_vars[2] || var == m_local_id_vars[0] - || var == m_local_id_vars[1] || var == m_local_id_vars[2]) - m_id_val_defs [reg_var] = var; - else - { - /* Possible overwrite of an ID value. */ - - id_val_map::iterator i = m_id_val_defs.find (reg_var); - if (i != m_id_val_defs.end()) - m_id_val_defs.erase (i); - } -} - -/* If the REG_VAR is known to contain an ID value at this point in - the basic block, return true. */ - -bool -brig_function::is_id_val (tree reg_var) -{ - id_val_map::iterator i = m_id_val_defs.find (reg_var); - return i != m_id_val_defs.end(); -} - -/* Return an ID value for the given REG_VAR if its known to contain - one at this point in the BB, NULL_TREE otherwise. */ - -tree -brig_function::id_val (tree reg_var) -{ - id_val_map::iterator i = m_id_val_defs.find (reg_var); - if (i != m_id_val_defs.end()) - return (*i).second; - else - return NULL_TREE; -} - -/* Informs of starting a new basic block. Called when generating - a label, a call, a jump, or a return. */ - -void -brig_function::start_new_bb () -{ - m_id_val_defs.clear (); -} diff --git a/gcc/brig/brigfrontend/brig-function.h b/gcc/brig/brigfrontend/brig-function.h deleted file mode 100644 index 8a9c3ba1808..00000000000 --- a/gcc/brig/brigfrontend/brig-function.h +++ /dev/null @@ -1,267 +0,0 @@ -/* brig-function.h -- declaration of brig_function class. - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3, or (at your option) any later - version. - - GCC is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - . */ - -#ifndef BRIG_FUNCTION_H -#define BRIG_FUNCTION_H - -#include "config.h" -#include "system.h" -#include "ansidecl.h" -#include "coretypes.h" -#include "opts.h" -#include "tree.h" -#include "tree-iterator.h" -#include "hsa-brig-format.h" -#include "brig-util.h" - -#include -#include -#include -#include - -#include "phsa.h" - -class brig_to_generic; - -typedef std::map label_index; -typedef std::map variable_index; -typedef std::vector tree_stl_vec; - -/* Holds data for the currently built GENERIC function. */ - -class brig_function -{ -public: - typedef std::map var_offset_table; - -private: - struct reg_decl_index_entry - { - tree m_var_decl; - }; - -public: - brig_function (const BrigDirectiveExecutable *exec, brig_to_generic *parent); - ~brig_function (); - - tree arg_variable (const BrigDirectiveVariable *var) const; - void add_arg_variable (const BrigDirectiveVariable *brigVar, tree treeDecl); - - void append_kernel_arg (const BrigDirectiveVariable *var, size_t size, - size_t alignment); - - size_t kernel_arg_offset (const BrigDirectiveVariable *var) const; - - void add_id_variables (); - - tree label (const std::string &name); - - tree add_local_variable (std::string name, tree type); - - size_t group_variable_segment_offset (const std::string &name) const; - - bool has_group_variable (const std::string &name) const; - - size_t group_segment_size () const; - - tree get_m_var_declfor_reg (const BrigOperandRegister *reg); - - bool convert_to_wg_function (); - - void add_wi_loop (int dim, tree_stmt_iterator *header_entry, - tree_stmt_iterator *branch_after); - - tree emit_metadata (tree stmt_list); - tree emit_launcher_and_metadata (); - - tree append_statement (tree stmt); - - void create_alloca_frame (); - - void finish (); - void finish_kernel (); - - void append_return_stmt (); - - bool has_function_scope_var (const BrigBase* var) const; - - void analyze_calls (); - - tree expand_builtin (BrigOpcode16_t brig_opcode, tree_stl_vec &operands); - - tree expand_or_call_builtin (BrigOpcode16_t brig_opcode, - BrigType16_t brig_type, tree arith_type, - tree_stl_vec &operands); - bool can_expand_builtin (BrigOpcode16_t brig_opcode) const; - - tree get_builtin_for_hsa_opcode (tree type, BrigOpcode16_t brig_opcode, - BrigType16_t brig_type) const; - - void unpack (tree value, tree_stl_vec &elements); - tree pack (tree_stl_vec &elements); - tree add_temp_var (std::string name, tree expr); - - static bool needs_workitem_context_data (BrigOpcode16_t brig_opcode); - static HOST_WIDE_INT int_constant_value (tree node); - static tree_code get_tree_code_for_hsa_opcode (BrigOpcode16_t brig_opcode, - BrigType16_t brig_type); - - void start_new_bb (); - void add_reg_var_update (tree reg_var, tree val); - bool is_id_val (tree reg_var); - tree id_val (tree reg_var); - - const BrigDirectiveExecutable *m_brig_def; - - bool m_is_kernel; - bool m_is_finished; - std::string m_name; - tree m_current_bind_expr; - tree m_func_decl; - tree m_entry_label_stmt; - tree m_exit_label; - - /* The __context function argument. */ - tree m_context_arg; - - /* The __group_base_ptr argument in the current function. - Points to the start of the group segment for the work-group. */ - tree m_group_base_arg; - - /* The __group_local_offset_ptr argument in the current function. It - contains the offset related to the group_base_ptr where the function's - local area for group variables resides. */ - tree m_group_local_offset_arg; - - /* The __private_base_ptr argument in the current function. - Points to the start of the private segment. */ - tree m_private_base_arg; - - /* The return value variable for the current function. */ - tree m_ret_value; - - /* The offsets of the kernel arguments in the __arg blob - pointing to the kernel argument space. */ - size_t m_next_kernarg_offset; - - /* The largest kernel argument variable alignment. */ - size_t m_kernarg_max_align; - - var_offset_table m_kernarg_offsets; - - /* Argument variables in the currently handled binding expression - (argument segment). */ - variable_index m_arg_variables; - - /* The brig variable for the function return value. */ - const BrigDirectiveVariable *m_ret_value_brig_var; - - /* The function local temporary variable for the return value. */ - tree m_ret_temp; - - /* Labels in the current function are collected here so we can refer - to them from jumps before they have been placed to the function. */ - label_index m_label_index; - - /* If the kernel contains at least one barrier, this is set to true. */ - bool m_has_barriers; - - /* True if the function has at least one alloca instruction. */ - bool m_has_allocas; - - /* If the kernel contains at least one function call that _may_ - contain a barrier call, this is set to true. */ - bool m_has_function_calls_with_barriers; - - /* Set to true after this function has been analyzed for barrier and - dispatch packet instruction usage in the final call graph analysis. */ - bool m_calls_analyzed; - - /* True in case the function was successfully converted to a WG function. */ - bool m_is_wg_function; - - /* Work-item ID related variables are cached in the entry of the kernel - function in order to use them directly in address computations, leading - to more efficient optimizations. The references to the local variables - are stored here. */ - tree m_local_id_vars[3]; - tree m_cur_wg_size_vars[3]; - tree m_wg_id_vars[3]; - tree m_wg_size_vars[3]; - tree m_grid_size_vars[3]; - /* Explicitly computed WG base for the absolute IDs which is used - as the initial value when looping that dimension. We update - the abs id with ++ to make it easy for the vectorizer. */ - tree m_abs_id_base_vars[3]; - tree m_abs_id_vars[3]; - - /* Set to true in case the kernel contains at least one dispatch packet - (work-item ID-related) builtin call that could not be expanded to - tree nodes. */ - bool m_has_unexpanded_dp_builtins; - - /* Points to the instruction after which the real kernel code starts. - Usually points to the last WI ID variable initialization statement. */ - tree_stmt_iterator m_kernel_entry; - - /* True if we are currently generating the contents of an arg block. */ - bool m_generating_arg_block; - - /* A collection of function scope variables seen so far for resolving - variable references vs. module scope declarations. */ - std::set m_function_scope_vars; - - /* The functions called by this function. */ - std::vector m_called_functions; - - /* Stores the kernel scope group variable offsets if the function is - a kernel. */ - group_variable_offset_index m_local_group_variables; - - brig_to_generic *m_parent; - /* The metadata of the function that should be stored with the binary and - passed to the HSA runtime: */ - phsa_descriptor m_descriptor; - -private: - - tree get_tree_type_for_hsa_reg (const BrigOperandRegister *reg) const; - - /* Bookkeeping for the different HSA registers and their tree declarations - for the currently generated function. */ - reg_decl_index_entry *m_regs[BRIG_2_TREE_HSAIL_TOTAL_REG_COUNT]; - - /* Map for keeping book reads of ID variables, which can be propagated - to uses in address expressions to produce cleaner indexing functions - with unnecessary casts stripped off, etc. */ - typedef std::map id_val_map; - - /* Keeps track of ID values alive in registers in the currently - processed BB. */ - id_val_map m_id_val_defs; - - /* HSAIL-specific builtin functions not yet integrated to gcc. */ - typedef std::map, tree> builtin_map; - - static builtin_map s_custom_builtins; -}; - -#endif diff --git a/gcc/brig/brigfrontend/brig-inst-mod-handler.cc b/gcc/brig/brigfrontend/brig-inst-mod-handler.cc deleted file mode 100644 index 3c424686307..00000000000 --- a/gcc/brig/brigfrontend/brig-inst-mod-handler.cc +++ /dev/null @@ -1,58 +0,0 @@ -/* brig-inst-mod-handler.cc -- brig rounding moded instruction handling - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ - -#include "brig-code-entry-handler.h" - -#include "gimple-expr.h" -#include "errors.h" - -size_t -brig_inst_mod_handler::generate (const BrigBase *base) -{ - brig_basic_inst_handler basic_handler (m_parent); - return basic_handler (base); -} - -const BrigAluModifier8_t * -brig_inst_mod_handler::modifier (const BrigBase *base) const -{ - const BrigInstMod *inst = (const BrigInstMod *) base; - return &inst->modifier; -} - -const BrigRound8_t * -brig_inst_mod_handler::round (const BrigBase *base) const -{ - const BrigInstMod *inst = (const BrigInstMod *) base; - return &inst->round; -} - -/* This used to inject fesetround () calls to control the rounding mode of the - actual executed floating point operation. It turned out that supporting - conversions using fesetround calls won't work in gcc due to it not being - able to restrict code motions across calls at the moment. This - functionality is therefore disabled for now until a better solution is - found or if fesetround () is fixed in gcc. */ -size_t -brig_inst_mod_handler::operator () (const BrigBase *base) -{ - return generate (base); -} diff --git a/gcc/brig/brigfrontend/brig-label-handler.cc b/gcc/brig/brigfrontend/brig-label-handler.cc deleted file mode 100644 index 4cf63376893..00000000000 --- a/gcc/brig/brigfrontend/brig-label-handler.cc +++ /dev/null @@ -1,40 +0,0 @@ -/* brig-label-handler.cc -- brig label directive handling - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ - -#include "brig-code-entry-handler.h" - -size_t -brig_directive_label_handler::operator () (const BrigBase *base) -{ - const BrigDirectiveLabel *brig_label = (const BrigDirectiveLabel *) base; - - const BrigData *label_name = m_parent.get_brig_data_entry (brig_label->name); - - std::string label_str ((const char *) (label_name->bytes), - label_name->byteCount); - - m_parent.m_cf->start_new_bb (); - - tree stmt = build_stmt (LABEL_EXPR, m_parent.m_cf->label (label_str)); - m_parent.m_cf->append_statement (stmt); - - return base->byteCount; -} diff --git a/gcc/brig/brigfrontend/brig-lane-inst-handler.cc b/gcc/brig/brigfrontend/brig-lane-inst-handler.cc deleted file mode 100644 index e0a3c05f799..00000000000 --- a/gcc/brig/brigfrontend/brig-lane-inst-handler.cc +++ /dev/null @@ -1,85 +0,0 @@ -/* brig-lane-inst-handler.cc -- brig lane instruction handling - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ - -#include "brig-code-entry-handler.h" -#include "errors.h" -#include "diagnostic-core.h" -#include "brig-util.h" - -brig_lane_inst_handler::brig_lane_inst_handler (brig_to_generic &parent) - : brig_code_entry_handler (parent) -{ -} - -size_t -brig_lane_inst_handler::operator () (const BrigBase *base) -{ - const BrigInstLane &inst = *(const BrigInstLane *) base; - tree_stl_vec operands = build_operands (inst.base); - - tree expr = NULL_TREE; - if (inst.base.opcode == BRIG_OPCODE_ACTIVELANECOUNT) - { - /* Because we are fixed to single WI per wave, it's enough to - just check the src value of the single work item itself. */ - expr = build2 (NE_EXPR, uint32_type_node, - build_zero_cst (uint32_type_node), operands[1]); - } - else if (inst.base.opcode == BRIG_OPCODE_ACTIVELANEID) - { - expr = build_zero_cst (uint32_type_node); - } - else if (inst.base.opcode == BRIG_OPCODE_ACTIVELANEMASK) - { - tree u64_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_U64); - tree zero_cst = build_zero_cst (u64_type); - expr = build2 (NE_EXPR, u64_type, zero_cst, operands[1]); - - tree_stl_vec elements; - elements.push_back (expr); - elements.push_back (zero_cst); - elements.push_back (zero_cst); - elements.push_back (zero_cst); - - expr = m_parent.m_cf->pack (elements); - } - else if (inst.base.opcode == BRIG_OPCODE_ACTIVELANEPERMUTE) - { - tree src = operands[1]; - tree identity = operands[3]; - tree use_identity = operands[4]; - - /* When WAVESIZE is 1, we either select the src of the work-item - itself or 'identity' in case use_identity is 1. */ - - tree cmp = build2 (EQ_EXPR, uint32_type_node, - build_int_cstu (TREE_TYPE (use_identity), 1), - use_identity); - - expr = build3 (COND_EXPR, TREE_TYPE (src), cmp, identity, src); - } - else - gcc_unreachable (); - - build_output_assignment (inst.base, operands[0], expr); - - return base->byteCount; -} diff --git a/gcc/brig/brigfrontend/brig-machine.c b/gcc/brig/brigfrontend/brig-machine.c deleted file mode 100644 index 250c86d4803..00000000000 --- a/gcc/brig/brigfrontend/brig-machine.c +++ /dev/null @@ -1,44 +0,0 @@ -/* brig-machine.c -- gccbrig machine queries - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "brig-machine.h" - -/* Return the numerical address space id for the segment in the current - target. Currently a dummy function that always returns 0, serves as - a placeholder for multi-AS machines. */ - -unsigned -gccbrig_get_target_addr_space_id (BrigSegment8_t) -{ - return 0; -} - -/* Return the WAVESIZE for the current target. For now a dummy placeholder - returning always 1. */ - -unsigned -gccbrig_get_target_wavesize () -{ - return 1; -} diff --git a/gcc/brig/brigfrontend/brig-machine.h b/gcc/brig/brigfrontend/brig-machine.h deleted file mode 100644 index d3fab9953d6..00000000000 --- a/gcc/brig/brigfrontend/brig-machine.h +++ /dev/null @@ -1,33 +0,0 @@ -/* brig-machine.h -- gccbrig machine queries - Copyright (C) 2016-2021 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ - -#ifndef GCC_BRIG_MACHINE_H -#define GCC_BRIG_MACHINE_H - -#include "hsa-brig-format.h" - -/* These functions should be eventually converted to machine info queries and - redefined at backends. At that point make these functions delegate to - those. */ - -unsigned gccbrig_get_target_addr_space_id (BrigSegment8_t segment); - -unsigned gccbrig_get_target_wavesize (); - -#endif diff --git a/gcc/brig/brigfrontend/brig-mem-inst-handler.cc b/gcc/brig/brigfrontend/brig-mem-inst-handler.cc deleted file mode 100644 index 9b09e98afa6..00000000000 --- a/gcc/brig/brigfrontend/brig-mem-inst-handler.cc +++ /dev/null @@ -1,178 +0,0 @@ -/* brig-mem-inst-handler.cc -- brig memory inst handler - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3, or (at your option) any later - version. - - GCC is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - . */ - -#include "brig-code-entry-handler.h" - -#include "errors.h" -#include "brig-util.h" -#include "gimple-expr.h" -#include "print-tree.h" -#include "tree-pretty-print.h" -#include "convert.h" -#include "diagnostic-core.h" - -tree -brig_mem_inst_handler::build_mem_access (const BrigInstBase *brig_inst, - tree addr, tree data) -{ - bool is_load = brig_inst->opcode == BRIG_OPCODE_LD; - bool is_store = brig_inst->opcode == BRIG_OPCODE_ST; - - if (!is_load && !is_store) - gcc_unreachable (); - - tree instr_type = gccbrig_tree_type_for_hsa_type (brig_inst->type); - - /* In case of {ld,st}_v{2,4}. Note: since 'register' variables may - be any type, even a vector type, we distinguish the registers - from operand lists by checking for constructor nodes (which - operand lists are represented as). */ - if (VECTOR_TYPE_P (TREE_TYPE (data)) && TREE_CODE (data) == CONSTRUCTOR) - instr_type = TREE_TYPE (data); - - tree ptype = build_pointer_type (instr_type); - - /* The HSAIL mem instructions are unaligned by default. - TODO: exploit the align modifier, it should lead to faster code. - */ - tree unaligned_type = build_aligned_type (instr_type, 8); - - /* Create a mem ref from the previous result, without offset. */ - tree mem_ref - = build2 (MEM_REF, unaligned_type, addr, build_int_cst (ptype, 0)); - - if (is_load) - { - /* Add a temporary variable so there won't be multiple - reads in case of vector unpack. */ - mem_ref = m_parent.m_cf->add_temp_var ("mem_read", mem_ref); - return build_output_assignment (*brig_inst, data, mem_ref); - } - else - { - tree stmt = build2 (MODIFY_EXPR, TREE_TYPE (mem_ref), mem_ref, data); - return m_parent.m_cf->append_statement (stmt); - } - return mem_ref; -} - -size_t -brig_mem_inst_handler::operator () (const BrigBase *base) -{ - const BrigInstBase *brig_inst - = (const BrigInstBase *) &((const BrigInstBasic *) base)->base; - - if (brig_inst->opcode == BRIG_OPCODE_ALLOCA) - { - tree_stl_vec operands = build_operands (*brig_inst); - size_t alignment = 1; - const BrigInstMem *mem_inst = (const BrigInstMem *) brig_inst; - if (mem_inst->align != BRIG_ALIGNMENT_NONE) - { - alignment = 1 << (mem_inst->align - 1); - } - - tree align_opr = build_int_cstu (size_type_node, alignment); - tree_stl_vec inputs; - inputs.push_back (operands[1]); - inputs.push_back (align_opr); - tree builtin_call - = m_parent.m_cf->expand_or_call_builtin (BRIG_OPCODE_ALLOCA, - BRIG_TYPE_U32, - uint32_type_node, inputs); - build_output_assignment (*brig_inst, operands[0], builtin_call); - m_parent.m_cf->m_has_allocas = true; - return base->byteCount; - } - - tree instr_type = gccbrig_tree_type_for_hsa_type (brig_inst->type); - - const BrigData *operand_entries - = m_parent.get_brig_data_entry (brig_inst->operands); - - uint32_t data_operand_offset; - memcpy (&data_operand_offset, &operand_entries->bytes, 4); - - const BrigBase *operand - = m_parent.get_brig_operand_entry (data_operand_offset); - - const BrigData *operandData = NULL; - - bool is_store = brig_inst->opcode == BRIG_OPCODE_ST; - - bool is_three_element_vector_access - = operand->kind == BRIG_KIND_OPERAND_OPERAND_LIST - && (operandData = m_parent.get_brig_data_entry - (((const BrigOperandOperandList *) operand)->elements)) - && operandData->byteCount / 4 == 3; - - if (is_three_element_vector_access) - { - /* We need to scalarize the 3-element vector accesses here - because gcc assumes the GENERIC vector datatypes are of two exponent - size internally. */ - size_t bytes = operandData->byteCount; - const BrigOperandOffset32_t *operand_ptr - = (const BrigOperandOffset32_t *) operandData->bytes; - - uint32_t addr_operand_offset; - memcpy (&addr_operand_offset, &operand_entries->bytes + 4, 4); - - const BrigOperandAddress *addr_operand - = (const BrigOperandAddress *) m_parent.get_brig_operand_entry - (addr_operand_offset); - - tree address_base = build_address_operand (*brig_inst, *addr_operand); - - uint32_t address_offset = 0; - while (bytes > 0) - { - BrigOperandOffset32_t offset = *operand_ptr; - const BrigBase *operand_element - = m_parent.get_brig_operand_entry (offset); - tree data - = build_tree_operand (*brig_inst, *operand_element, instr_type); - - tree ptr_offset = build_int_cst (size_type_node, address_offset); - tree address = build2 (POINTER_PLUS_EXPR, TREE_TYPE (address_base), - address_base, ptr_offset); - - if (is_store && TREE_TYPE (data) != instr_type) - data = build_resize_convert_view (instr_type, data); - - build_mem_access (brig_inst, address, data); - - address_offset += int_size_in_bytes (instr_type); - ++operand_ptr; - bytes -= 4; - } - } - else - { - tree_stl_vec operands = build_operands (*brig_inst); - - tree &data = operands.at (0); - tree &addr = operands.at (1); - build_mem_access (brig_inst, addr, data); - } - - return base->byteCount; -} diff --git a/gcc/brig/brigfrontend/brig-module-handler.cc b/gcc/brig/brigfrontend/brig-module-handler.cc deleted file mode 100644 index f8eeebfe62e..00000000000 --- a/gcc/brig/brigfrontend/brig-module-handler.cc +++ /dev/null @@ -1,41 +0,0 @@ -/* brig-module-handler.cc -- brig module directive handling - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3, or (at your option) any later - version. - - GCC is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - . */ - -#include "brig-code-entry-handler.h" -#include "diagnostic-core.h" - -size_t -brig_directive_module_handler::operator () (const BrigBase *base) -{ - const BrigDirectiveModule* mod = (const BrigDirectiveModule*)base; - m_parent.m_module_name = m_parent.get_string (mod->name).substr (1); - if (mod->hsailMajor != 1 || mod->hsailMinor != 0) - fatal_error (UNKNOWN_LOCATION, PHSA_ERROR_PREFIX_INCOMPATIBLE_MODULE - "HSAIL version not supported. HSAIL 1.0 required."); - if (mod->machineModel != BRIG_MACHINE_LARGE) - fatal_error (UNKNOWN_LOCATION, PHSA_ERROR_PREFIX_INCOMPATIBLE_MODULE - "Only HSA 'large' machine model supported."); - /* Do not check for the profile as the runtime conformance suite tests - with 'full' profile BRIGs even though they don't use any full profile - features. This allows us to run the conformance suite with the - BRIG FE. */ - return base->byteCount; -} diff --git a/gcc/brig/brigfrontend/brig-queue-inst-handler.cc b/gcc/brig/brigfrontend/brig-queue-inst-handler.cc deleted file mode 100644 index 3c88bc6dda1..00000000000 --- a/gcc/brig/brigfrontend/brig-queue-inst-handler.cc +++ /dev/null @@ -1,93 +0,0 @@ -/* brig-queue-inst-handler.cc -- brig user mode queue related instruction - handling - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ - -#include - -#include "brig-code-entry-handler.h" -#include "brig-util.h" -#include "convert.h" -#include "tree-pretty-print.h" -#include "errors.h" -#include "diagnostic-core.h" -#include "brig-builtins.h" - -brig_queue_inst_handler::brig_queue_inst_handler (brig_to_generic &parent) - : brig_code_entry_handler (parent) -{ -} - -size_t -brig_queue_inst_handler::operator () (const BrigBase *base) -{ - const BrigInstBase &inst_base = *(const BrigInstBase *) base; - - tree_stl_vec operands = build_operands (inst_base); - - if (inst_base.opcode == BRIG_OPCODE_LDQUEUEWRITEINDEX - || inst_base.opcode == BRIG_OPCODE_LDQUEUEREADINDEX) - { - tree builtin - = inst_base.opcode == BRIG_OPCODE_LDQUEUEWRITEINDEX - ? builtin_decl_explicit (BUILT_IN_HSAIL_LDQUEUEWRITEINDEX) - : builtin_decl_explicit (BUILT_IN_HSAIL_LDQUEUEREADINDEX); - - tree expr - = call_builtin (builtin, 1, uint64_type_node, - uint64_type_node, operands[1]); - build_output_assignment (inst_base, operands[0], expr); - } - else if (inst_base.opcode == BRIG_OPCODE_STQUEUEWRITEINDEX - || inst_base.opcode == BRIG_OPCODE_STQUEUEREADINDEX) - { - tree builtin - = inst_base.opcode == BRIG_OPCODE_STQUEUEWRITEINDEX - ? builtin_decl_explicit (BUILT_IN_HSAIL_STQUEUEWRITEINDEX) - : builtin_decl_explicit (BUILT_IN_HSAIL_STQUEUEREADINDEX); - - call_builtin (builtin, 2, void_type_node, - uint64_type_node, operands[0], uint64_type_node, - operands[1]); - } - else if (inst_base.opcode == BRIG_OPCODE_ADDQUEUEWRITEINDEX) - { - tree builtin = builtin_decl_explicit (BUILT_IN_HSAIL_ADDQUEUEWRITEINDEX); - - tree expr = call_builtin (builtin, 2, - uint64_type_node, uint64_type_node, operands[1], - uint64_type_node, operands[2]); - build_output_assignment (inst_base, operands[0], expr); - } - else if (inst_base.opcode == BRIG_OPCODE_CASQUEUEWRITEINDEX) - { - tree builtin = builtin_decl_explicit (BUILT_IN_HSAIL_CASQUEUEWRITEINDEX); - - tree expr - = call_builtin (builtin, 3, uint64_type_node, - uint64_type_node, operands[1], uint64_type_node, - operands[2], uint64_type_node, operands[3]); - build_output_assignment (inst_base, operands[0], expr); - } - else - gcc_unreachable (); - - return base->byteCount; -} diff --git a/gcc/brig/brigfrontend/brig-seg-inst-handler.cc b/gcc/brig/brigfrontend/brig-seg-inst-handler.cc deleted file mode 100644 index 9c22715a909..00000000000 --- a/gcc/brig/brigfrontend/brig-seg-inst-handler.cc +++ /dev/null @@ -1,146 +0,0 @@ -/* brig-seg-inst-handler.cc -- brig segment related instruction handling - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ - -#include - -#include "brig-code-entry-handler.h" -#include "brig-util.h" -#include "convert.h" -#include "tree-pretty-print.h" -#include "errors.h" -#include "diagnostic-core.h" - -brig_seg_inst_handler::brig_seg_inst_handler (brig_to_generic &parent) - : brig_code_entry_handler (parent) -{ -} - -size_t -brig_seg_inst_handler::operator () (const BrigBase *base) -{ - const BrigInstBase &inst_base = *(const BrigInstBase *) base; - - std::vector operands = build_operands (inst_base); - - tree expr = NULL_TREE; - - if (inst_base.opcode == BRIG_OPCODE_STOF) - { - const BrigInstSegCvt &inst = *(const BrigInstSegCvt *) base; - - if (inst.segment == BRIG_SEGMENT_GROUP) - expr = build2 (PLUS_EXPR, size_type_node, - convert_to_integer (size_type_node, - m_parent.m_cf->m_group_base_arg), - convert_to_integer (size_type_node, operands[1])); - else if (inst.segment == BRIG_SEGMENT_PRIVATE - || inst.segment == BRIG_SEGMENT_SPILL) - expr = build2 (PLUS_EXPR, size_type_node, - convert_to_integer (size_type_node, - m_parent.m_cf->m_private_base_arg), - convert_to_integer (size_type_node, operands[1])); - else - gcc_unreachable (); - - if (!(inst.modifier & BRIG_SEG_CVT_NONULL)) - { - /* Need to convert the null value. -1 is used for 32b segments, - and 0 for flat/global. */ - tree cmp - = build2 (EQ_EXPR, uint32_type_node, - build_int_cstu (uint32_type_node, -1), operands[1]); - - tree null_check = build3 (COND_EXPR, size_type_node, cmp, - build_int_cstu (size_type_node, 0), expr); - - expr = null_check; - } - } - else if (inst_base.opcode == BRIG_OPCODE_FTOS) - { - const BrigInstSegCvt &inst = *(const BrigInstSegCvt *) base; - - if (inst.segment == BRIG_SEGMENT_GROUP) - expr = build2 (MINUS_EXPR, size_type_node, - convert_to_integer (size_type_node, - m_parent.m_cf->m_group_base_arg), - convert_to_integer (size_type_node, operands[1])); - else if (inst.segment == BRIG_SEGMENT_PRIVATE) - expr = build2 (MINUS_EXPR, size_type_node, - convert_to_integer (size_type_node, - m_parent.m_cf->m_private_base_arg), - convert_to_integer (size_type_node, operands[1])); - else - gcc_unreachable (); - - if (!(inst.modifier & BRIG_SEG_CVT_NONULL)) - { - /* Need to convert the null value. -1 is used for 32b segments, - and 0 for flat/global. */ - tree cmp = build2 (EQ_EXPR, size_type_node, - build_int_cstu (size_type_node, 0), operands[1]); - - tree null_check - = build3 (COND_EXPR, size_type_node, cmp, - build_int_cstu (uint32_type_node, -1), expr); - expr = null_check; - } - } - else if (inst_base.opcode == BRIG_OPCODE_NULLPTR) - { - const BrigInstSeg &inst = *(const BrigInstSeg *) base; - if (inst.segment == BRIG_SEGMENT_GLOBAL - || inst.segment == BRIG_SEGMENT_FLAT - || inst.segment == BRIG_SEGMENT_READONLY) - expr = build_int_cstu (uint64_type_node, 0); - else - expr = build_int_cstu (uint32_type_node, -1); - } - else if (inst_base.opcode == BRIG_OPCODE_SEGMENTP) - { - const BrigInstSegCvt &inst = *(const BrigInstSegCvt *) base; - - tree builtin = NULL_TREE; - switch (inst.segment) - { - case BRIG_SEGMENT_GLOBAL: - builtin = builtin_decl_explicit (BUILT_IN_HSAIL_SEGMENTP_GLOBAL); - break; - case BRIG_SEGMENT_GROUP: - builtin = builtin_decl_explicit (BUILT_IN_HSAIL_SEGMENTP_GROUP); - break; - case BRIG_SEGMENT_PRIVATE: - builtin = builtin_decl_explicit (BUILT_IN_HSAIL_SEGMENTP_PRIVATE); - break; - default: - gcc_unreachable (); - } - - expr = call_builtin (builtin, 2, - uint32_type_node, uint64_type_node, operands[1], - ptr_type_node, m_parent.m_cf->m_context_arg); - } - else - gcc_unreachable (); - - build_output_assignment (inst_base, operands[0], expr); - return base->byteCount; -} diff --git a/gcc/brig/brigfrontend/brig-signal-inst-handler.cc b/gcc/brig/brigfrontend/brig-signal-inst-handler.cc deleted file mode 100644 index be3f01d1bfa..00000000000 --- a/gcc/brig/brigfrontend/brig-signal-inst-handler.cc +++ /dev/null @@ -1,42 +0,0 @@ -/* brig-signal-inst-handler.cc -- brig signal instruction handling - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ - -#include - -#include "brig-code-entry-handler.h" -#include "brig-util.h" -#include "fold-const.h" -#include "diagnostic.h" -#include "tree-pretty-print.h" -#include "print-tree.h" -#include "convert.h" -#include "langhooks.h" -#include "gimple-expr.h" - -size_t -brig_signal_inst_handler::operator () (const BrigBase *base) -{ - const BrigInstSignal *inst = (const BrigInstSignal *) base; - BrigAtomicOperation8_t atomic_opcode; - atomic_opcode = inst->signalOperation; - - return generate_tree (inst->base, atomic_opcode); -} diff --git a/gcc/brig/brigfrontend/brig-to-generic.cc b/gcc/brig/brigfrontend/brig-to-generic.cc deleted file mode 100644 index 62e8aecd22b..00000000000 --- a/gcc/brig/brigfrontend/brig-to-generic.cc +++ /dev/null @@ -1,1045 +0,0 @@ -/* brig2tree.cc -- brig to gcc generic/gimple tree conversion - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3, or (at your option) any later - version. - - GCC is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - . */ - -#include -#include -#include -#include - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "target.h" -#include "function.h" -#include "brig-to-generic.h" -#include "stringpool.h" -#include "tree-iterator.h" -#include "toplev.h" -#include "gimplify.h" -#include "gimple-expr.h" -#include "print-tree.h" -#include "hsa-brig-format.h" -#include "stor-layout.h" -#include "diagnostic-core.h" -#include "brig-code-entry-handler.h" -#include "brig-machine.h" -#include "brig-util.h" -#include "phsa.h" -#include "tree-pretty-print.h" -#include "dumpfile.h" -#include "profile-count.h" -#include "tree-cfg.h" -#include "errors.h" -#include "fold-const.h" -#include "cgraph.h" -#include "dumpfile.h" -#include "tree-pretty-print.h" -#include "attribs.h" - -extern int gccbrig_verbose; - -tree brig_to_generic::s_fp16_type; -tree brig_to_generic::s_fp32_type; -tree brig_to_generic::s_fp64_type; - -brig_to_generic::brig_to_generic () - : m_cf (NULL), m_analyzing (true), m_total_group_segment_usage (0), - m_brig (NULL), m_next_private_offset (0) -{ - m_globals = NULL_TREE; - - /* Initialize the basic REAL types. - This doesn't work straight away because most of the targets - do not support fp16 natively. Let's by default convert - to fp32 and back before and after each instruction (handle it as - a storage format only), and later add an optimization pass - that removes the extra converts (in case of multiple fp16 ops - in a row). */ - s_fp16_type = make_node (REAL_TYPE); - TYPE_PRECISION (s_fp16_type) = 16; - TYPE_SIZE (s_fp16_type) = bitsize_int (16); - TYPE_SIZE_UNIT (s_fp16_type) = size_int (2); - SET_TYPE_ALIGN (s_fp16_type, 16); - layout_type (s_fp16_type); - - s_fp32_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_F32); - s_fp64_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_F64); - - /* TODO: (machine)query the preferred rounding mode that is set by - the machine by default. This can be redefined by each BRIG module - header. */ - m_default_float_rounding_mode = BRIG_ROUND_FLOAT_ZERO; - - m_dump_file = dump_begin (TDI_original, &m_dump_flags); -} - -class unimplemented_entry_handler : public brig_code_entry_handler -{ -public: - unimplemented_entry_handler (brig_to_generic &parent) - : brig_code_entry_handler (parent) - { - } - - size_t - operator () (const BrigBase *base) - { - gcc_unreachable (); - return base->byteCount; - } -}; - -/* Handler for entries that can be (and are) safely skipped for the purposes - of GENERIC generation. */ - -class skipped_entry_handler : public brig_code_entry_handler -{ -public: - skipped_entry_handler (brig_to_generic &parent) - : brig_code_entry_handler (parent) - { - } - - size_t - operator () (const BrigBase *base) - { - return base->byteCount; - } -}; - -class brig_reg_use_analyzer : public brig_code_entry_handler -{ -public: - brig_reg_use_analyzer (brig_to_generic &parent) - : brig_code_entry_handler (parent) - { - } - - size_t - operator () (const BrigBase *base) - { - const BrigInstBase *brig_inst = (const BrigInstBase *) base; - analyze_operands (*brig_inst); - return base->byteCount; - } - -}; - -/* Helper struct for pairing a BrigKind and a BrigCodeEntryHandler that - should handle its data. */ - -struct code_entry_handler_info -{ - BrigKind kind; - brig_code_entry_handler *handler; -}; - - -/* Finds the BRIG file sections in the currently processed file. */ - -void -brig_to_generic::find_brig_sections () -{ - m_data = m_code = m_operand = NULL; - const BrigModuleHeader *mheader = (const BrigModuleHeader *) m_brig; - - /* Find the positions of the different sections. */ - for (uint32_t sec = 0; sec < mheader->sectionCount; ++sec) - { - uint64_t offset - = ((const uint64_t *) (m_brig + mheader->sectionIndex))[sec]; - - const BrigSectionHeader *section_header - = (const BrigSectionHeader *) (m_brig + offset); - - std::string name ((const char *) (§ion_header->name), - section_header->nameLength); - - if (sec == BRIG_SECTION_INDEX_DATA && name == "hsa_data") - { - m_data = (const char *) section_header; - m_data_size = section_header->byteCount; - } - else if (sec == BRIG_SECTION_INDEX_CODE && name == "hsa_code") - { - m_code = (const char *) section_header; - m_code_size = section_header->byteCount; - } - else if (sec == BRIG_SECTION_INDEX_OPERAND && name == "hsa_operand") - { - m_operand = (const char *) section_header; - m_operand_size = section_header->byteCount; - } - else - { - gcc_unreachable (); - } - } - - if (m_code == NULL) - gcc_unreachable (); - if (m_data == NULL) - gcc_unreachable (); - if (m_operand == NULL) - gcc_unreachable (); - -} - -/* Does a first pass over the given BRIG to collect data needed for the - actual parsing. Currently this includes only collecting the - group segment variable usage to support the experimental HSA PRM feature - where group variables can be declared also in module and function scope - (in addition to kernel scope). -*/ - -void -brig_to_generic::analyze (const char *brig_blob) -{ - const BrigModuleHeader *mheader = (const BrigModuleHeader *) brig_blob; - - if (strncmp (mheader->identification, "HSA BRIG", 8) != 0) - fatal_error (UNKNOWN_LOCATION, PHSA_ERROR_PREFIX_INCOMPATIBLE_MODULE - "Unrecognized file format."); - if (mheader->brigMajor != 1 || mheader->brigMinor != 0) - fatal_error (UNKNOWN_LOCATION, PHSA_ERROR_PREFIX_INCOMPATIBLE_MODULE - "BRIG version not supported. BRIG 1.0 required."); - - m_brig = brig_blob; - - find_brig_sections (); - - brig_directive_variable_handler var_handler (*this); - brig_directive_fbarrier_handler fbar_handler (*this); - brig_directive_function_handler func_handler (*this); - brig_reg_use_analyzer reg_use_analyzer (*this); - - /* Need this for grabbing the module names for mangling the - group variable names. */ - brig_directive_module_handler module_handler (*this); - skipped_entry_handler skipped_handler (*this); - - const BrigSectionHeader *csection_header = (const BrigSectionHeader *) m_code; - - code_entry_handler_info handlers[] - = {{BRIG_KIND_INST_BASIC, ®_use_analyzer}, - {BRIG_KIND_INST_MOD, ®_use_analyzer}, - {BRIG_KIND_INST_CMP, ®_use_analyzer}, - {BRIG_KIND_INST_MEM, ®_use_analyzer}, - {BRIG_KIND_INST_CVT, ®_use_analyzer}, - {BRIG_KIND_INST_SEG_CVT, ®_use_analyzer}, - {BRIG_KIND_INST_SEG, ®_use_analyzer}, - {BRIG_KIND_INST_ADDR, ®_use_analyzer}, - {BRIG_KIND_INST_SOURCE_TYPE, ®_use_analyzer}, - {BRIG_KIND_INST_ATOMIC, ®_use_analyzer}, - {BRIG_KIND_INST_SIGNAL, ®_use_analyzer}, - {BRIG_KIND_INST_BR, ®_use_analyzer}, - {BRIG_KIND_INST_LANE, ®_use_analyzer}, - {BRIG_KIND_INST_QUEUE, ®_use_analyzer}, - {BRIG_KIND_DIRECTIVE_VARIABLE, &var_handler}, - {BRIG_KIND_DIRECTIVE_FBARRIER, &fbar_handler}, - {BRIG_KIND_DIRECTIVE_KERNEL, &func_handler}, - {BRIG_KIND_DIRECTIVE_MODULE, &module_handler}, - {BRIG_KIND_DIRECTIVE_FUNCTION, &func_handler}}; - - m_analyzing = true; - for (size_t b = csection_header->headerByteCount; b < m_code_size;) - { - const BrigBase *entry = (const BrigBase *) (m_code + b); - - brig_code_entry_handler *handler = &skipped_handler; - - if (m_cf != NULL && b >= m_cf->m_brig_def->nextModuleEntry) - { - /* The function definition ended. We can just discard the place - holder function. */ - m_total_group_segment_usage += m_cf->m_local_group_variables.size (); - delete m_cf; - m_cf = NULL; - } - - /* Find a handler. */ - for (size_t i = 0; - i < sizeof (handlers) / sizeof (code_entry_handler_info); ++i) - { - if (handlers[i].kind == entry->kind) - handler = handlers[i].handler; - } - - int bytes_processed = (*handler) (entry); - if (bytes_processed == 0) - fatal_error (UNKNOWN_LOCATION, PHSA_ERROR_PREFIX_CORRUPTED_MODULE - "Element with 0 bytes."); - b += bytes_processed; - } - - if (m_cf != NULL) - { - m_total_group_segment_usage += m_cf->m_local_group_variables.size (); - delete m_cf; - m_cf = NULL; - } - - m_total_group_segment_usage += m_module_group_variables.size (); - m_analyzing = false; -} - -/* Parses the given BRIG blob. */ - -void -brig_to_generic::parse (const char *brig_blob) -{ - m_brig = brig_blob; - find_brig_sections (); - - brig_basic_inst_handler inst_handler (*this); - brig_branch_inst_handler branch_inst_handler (*this); - brig_cvt_inst_handler cvt_inst_handler (*this); - brig_seg_inst_handler seg_inst_handler (*this); - brig_copy_move_inst_handler copy_move_inst_handler (*this); - brig_signal_inst_handler signal_inst_handler (*this); - brig_atomic_inst_handler atomic_inst_handler (*this); - brig_cmp_inst_handler cmp_inst_handler (*this); - brig_mem_inst_handler mem_inst_handler (*this); - brig_inst_mod_handler inst_mod_handler (*this); - brig_directive_label_handler label_handler (*this); - brig_directive_variable_handler var_handler (*this); - brig_directive_fbarrier_handler fbar_handler (*this); - brig_directive_comment_handler comment_handler (*this); - brig_directive_function_handler func_handler (*this); - brig_directive_control_handler control_handler (*this); - brig_directive_arg_block_handler arg_block_handler (*this); - brig_directive_module_handler module_handler (*this); - brig_lane_inst_handler lane_inst_handler (*this); - brig_queue_inst_handler queue_inst_handler (*this); - skipped_entry_handler skipped_handler (*this); - unimplemented_entry_handler unimplemented_handler (*this); - - struct code_entry_handler_info - { - BrigKind kind; - brig_code_entry_handler *handler; - }; - - /* TODO: Convert to a hash table / map. For now, put the more common - entries to the top to keep the scan fast on average. */ - code_entry_handler_info handlers[] - = {{BRIG_KIND_INST_BASIC, &inst_handler}, - {BRIG_KIND_INST_CMP, &cmp_inst_handler}, - {BRIG_KIND_INST_MEM, &mem_inst_handler}, - {BRIG_KIND_INST_MOD, &inst_mod_handler}, - {BRIG_KIND_INST_CVT, &cvt_inst_handler}, - {BRIG_KIND_INST_SEG_CVT, &seg_inst_handler}, - {BRIG_KIND_INST_SEG, &seg_inst_handler}, - {BRIG_KIND_INST_ADDR, ©_move_inst_handler}, - {BRIG_KIND_INST_SOURCE_TYPE, ©_move_inst_handler}, - {BRIG_KIND_INST_ATOMIC, &atomic_inst_handler}, - {BRIG_KIND_INST_SIGNAL, &signal_inst_handler}, - {BRIG_KIND_INST_BR, &branch_inst_handler}, - {BRIG_KIND_INST_LANE, &lane_inst_handler}, - {BRIG_KIND_INST_QUEUE, &queue_inst_handler}, - /* Assuming fences are not needed. FIXME: call builtins - when porting to a platform where they are. */ - {BRIG_KIND_INST_MEM_FENCE, &skipped_handler}, - {BRIG_KIND_DIRECTIVE_LABEL, &label_handler}, - {BRIG_KIND_DIRECTIVE_VARIABLE, &var_handler}, - {BRIG_KIND_DIRECTIVE_ARG_BLOCK_START, &arg_block_handler}, - {BRIG_KIND_DIRECTIVE_ARG_BLOCK_END, &arg_block_handler}, - {BRIG_KIND_DIRECTIVE_FBARRIER, &fbar_handler}, - {BRIG_KIND_DIRECTIVE_COMMENT, &comment_handler}, - {BRIG_KIND_DIRECTIVE_KERNEL, &func_handler}, - {BRIG_KIND_DIRECTIVE_SIGNATURE, &func_handler}, - {BRIG_KIND_DIRECTIVE_FUNCTION, &func_handler}, - {BRIG_KIND_DIRECTIVE_INDIRECT_FUNCTION, &func_handler}, - {BRIG_KIND_DIRECTIVE_MODULE, &module_handler}, - /* Skipping debug locations for now as not needed for conformance. */ - {BRIG_KIND_DIRECTIVE_LOC, &skipped_handler}, - /* There are no supported pragmas at this moment. */ - {BRIG_KIND_DIRECTIVE_PRAGMA, &skipped_handler}, - {BRIG_KIND_DIRECTIVE_CONTROL, &control_handler}, - {BRIG_KIND_DIRECTIVE_EXTENSION, &skipped_handler}, - /* BRIG_KIND_NONE entries are valid anywhere. They can be used - for patching BRIGs before finalization. */ - {BRIG_KIND_NONE, &skipped_handler}}; - - const BrigSectionHeader *csection_header = (const BrigSectionHeader *) m_code; - - for (size_t b = csection_header->headerByteCount; b < m_code_size;) - { - const BrigBase *entry = (const BrigBase *) (m_code + b); - - brig_code_entry_handler *handler = &unimplemented_handler; - - if (m_cf != NULL && b >= m_cf->m_brig_def->nextModuleEntry) - finish_function (); /* The function definition ended. */ - - /* Find a handler. */ - for (size_t i = 0; - i < sizeof (handlers) / sizeof (code_entry_handler_info); ++i) - { - if (handlers[i].kind == entry->kind) - handler = handlers[i].handler; - } - b += (*handler) (entry); - } - - finish_function (); -} - -const BrigData * -brig_to_generic::get_brig_data_entry (size_t entry_offset) const -{ - return (const BrigData *) (m_data + entry_offset); -} - -const BrigBase * -brig_to_generic::get_brig_operand_entry (size_t entry_offset) const -{ - return (const BrigBase *) (m_operand + entry_offset); -} - -const BrigBase * -brig_to_generic::get_brig_code_entry (size_t entry_offset) const -{ - return (const BrigBase *) (m_code + entry_offset); -} - -void -brig_to_generic::append_global (tree g) -{ - if (m_globals == NULL_TREE) - { - m_globals = g; - return; - } - else - { - tree last = tree_last (m_globals); - TREE_CHAIN (last) = g; - } -} - -tree -brig_to_generic::global_variable (const std::string &name) const -{ - label_index::const_iterator i = m_global_variables.find (name); - if (i == m_global_variables.end ()) - return NULL_TREE; - else - return (*i).second; -} - -/* Returns a function declaration with the given name. Assumes it has been - created previously via a DirectiveFunction or similar. */ - -tree -brig_to_generic::function_decl (const std::string &name) -{ - label_index::const_iterator i = m_function_index.find (name); - if (i == m_function_index.end ()) - return NULL_TREE; - return (*i).second; -} - -void -brig_to_generic::add_function_decl (const std::string &name, tree func_decl) -{ - m_function_index[name] = func_decl; -} - -/* Adds a GENERIC global variable VAR_DECL with the given NAME to the - current module. If we have generated a host def var ptr (a place holder - for variables that are defined by the HSA host code) for this global - variable definition (because there was a declaration earlier which looked - like it might have been a host defined variable), we now have - to assign its address and make it private to allow the references to - point to the defined variable instead. */ - -void -brig_to_generic::add_global_variable (const std::string &name, tree var_decl) -{ - append_global (var_decl); - m_global_variables[name] = var_decl; - - std::string host_def_var_name - = std::string (PHSA_HOST_DEF_PTR_PREFIX) + name; - tree host_def_var = global_variable (host_def_var_name); - if (host_def_var == NULL_TREE) - return; - - tree ptype = build_pointer_type (TREE_TYPE (var_decl)); - tree var_addr = build1 (ADDR_EXPR, ptype, var_decl); - - DECL_INITIAL (host_def_var) = var_addr; - TREE_PUBLIC (host_def_var) = 1; - - set_externally_visible (host_def_var); -} - -/* Adds an indirection pointer for a potential host-defined program scope - variable declaration. */ - -void -brig_to_generic::add_host_def_var_ptr (const std::string &name, tree var_decl) -{ - std::string var_name = std::string (PHSA_HOST_DEF_PTR_PREFIX) + name; - - tree name_identifier = get_identifier (var_name.c_str ()); - - tree ptr_var = build_decl (UNKNOWN_LOCATION, VAR_DECL, name_identifier, - build_pointer_type (TREE_TYPE (var_decl))); - DECL_EXTERNAL (ptr_var) = 0; - DECL_ARTIFICIAL (ptr_var) = 0; - - TREE_PUBLIC (ptr_var) = 1; - TREE_USED (ptr_var) = 1; - TREE_ADDRESSABLE (ptr_var) = 1; - TREE_STATIC (ptr_var) = 1; - - set_externally_visible (ptr_var); - - append_global (ptr_var); - m_global_variables[var_name] = ptr_var; -} - -void -brig_to_generic::add_decl_call (tree call) -{ - m_decl_call.push_back (call); -} - -/* Produce a "mangled name" for the given brig function or kernel. - The mangling is used to make unique global symbol name in case of - module scope functions. Program scope functions are not mangled - (except for dropping the leading &), which makes the functions - directly visible for linking using the original function name. */ - -std::string -brig_to_generic::get_mangled_name -(const BrigDirectiveExecutable *func) const -{ - /* Strip the leading &. */ - std::string func_name = get_string (func->name).substr (1); - if (func->linkage == BRIG_LINKAGE_MODULE) - { - /* Mangle the module scope function names with the module name and - make them public so they can be queried by the HSA runtime from - the produced binary. Assume it's the currently processed function - we are always referring to. */ - func_name = "gccbrig." + m_module_name + "." + func_name; - } - return func_name; -} - -std::string -brig_to_generic::get_string (size_t entry_offset) const -{ - const BrigData *data_item = get_brig_data_entry (entry_offset); - return std::string ((const char *) &data_item->bytes, data_item->byteCount); -} - -/* Adapted from c-semantics.c. */ - -tree -build_stmt (enum tree_code code, ...) -{ - tree ret; - int length, i; - va_list p; - bool side_effects; - - /* This function cannot be used to construct variably-sized nodes. */ - gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp); - - va_start (p, code); - - ret = make_node (code); - TREE_TYPE (ret) = void_type_node; - length = TREE_CODE_LENGTH (code); - - /* TREE_SIDE_EFFECTS will already be set for statements with - implicit side effects. Here we make sure it is set for other - expressions by checking whether the parameters have side - effects. */ - - side_effects = false; - for (i = 0; i < length; i++) - { - tree t = va_arg (p, tree); - if (t && !TYPE_P (t)) - side_effects |= TREE_SIDE_EFFECTS (t); - TREE_OPERAND (ret, i) = t; - } - - TREE_SIDE_EFFECTS (ret) |= side_effects; - - va_end (p); - return ret; -} - -/* BRIG regs are untyped, but GENERIC is not. We need to add implicit casts - in case treating the operand with an instruction with a type different - than the created reg var type in order to select correct instruction type - later on. This function creates the necessary reinterpret type cast from - a source variable to the destination type. In case no cast is needed to - the same type, SOURCE is returned directly. - - In case of mismatched type sizes, casting: - - to narrower type the upper bits are clipped and - - to wider type the source value is zero extended. */ - -tree -build_resize_convert_view (tree destination_type, tree source) -{ - - gcc_assert (source && destination_type && TREE_TYPE (source) != NULL_TREE - && destination_type != NULL_TREE); - - tree source_type = TREE_TYPE (source); - if (TREE_CODE (source) == CALL_EXPR) - { - tree func_decl = TREE_OPERAND (TREE_OPERAND (source, 1), 0); - source_type = TREE_TYPE (TREE_TYPE (func_decl)); - } - - if (destination_type == source_type) - return source; - - size_t src_size = int_size_in_bytes (source_type); - size_t dst_size = int_size_in_bytes (destination_type); - if (src_size == dst_size) - return build1 (VIEW_CONVERT_EXPR, destination_type, source); - else /* src_size != dst_size */ - { - /* The src_size can be smaller at least with f16 scalars which are - stored to 32b register variables. First convert to an equivalent - size unsigned type, then extend to an unsigned type of the - target width, after which VIEW_CONVERT_EXPR can be used to - force to the target type. */ - tree resized = convert (get_scalar_unsigned_int_type (destination_type), - build_reinterpret_to_uint (source)); - gcc_assert ((size_t)int_size_in_bytes (TREE_TYPE (resized)) == dst_size); - return build_resize_convert_view (destination_type, resized); - } -} - -/* Reinterprets SOURCE as a scalar unsigned int with the size - corresponding to the orignal. */ - -tree build_reinterpret_to_uint (tree source) -{ - tree src_type = TREE_TYPE (source); - if (INTEGRAL_TYPE_P (src_type) && TYPE_UNSIGNED (src_type)) - return source; - tree dest_type = get_scalar_unsigned_int_type (src_type); - return build1 (VIEW_CONVERT_EXPR, dest_type, source); -} - -/* Returns the finished brig_function for the given generic FUNC_DECL, - or NULL, if not found. */ - -brig_function * -brig_to_generic::get_finished_function (tree func_decl) -{ - std::string func_name - = identifier_to_locale (IDENTIFIER_POINTER (DECL_NAME (func_decl))); - std::map::iterator i - = m_finished_functions.find (func_name); - if (i != m_finished_functions.end ()) - return (*i).second; - else - return NULL; -} - -/* Adds a group variable to a correct book keeping structure depending - on its segment. */ - -void -brig_to_generic::add_group_variable (const std::string &name, size_t size, - size_t alignment, bool function_scope) -{ - /* Module and function scope group region variables are an experimental - feature. We implement module scope group variables with a separate - book keeping inside brig_to_generic which is populated in the 'analyze()' - prepass. This is to ensure we know the group segment offsets when - processing the functions that might refer to them. */ - if (!function_scope) - { - if (!m_module_group_variables.has_variable (name)) - m_module_group_variables.add (name, size, alignment); - return; - } - - if (!m_cf->m_local_group_variables.has_variable (name)) - m_cf->m_local_group_variables.add (name, size, alignment); -} - -/* Finalizes the currently handled function. Should be called before - setting a new function. */ - -void -brig_to_generic::finish_function () -{ - if (m_cf == NULL || m_cf->m_func_decl == NULL_TREE) - { - /* It can be a finished func declaration fingerprint, in that case we - don't have m_func_decl. */ - m_cf = NULL; - return; - } - - if (!m_cf->m_is_kernel) - { - tree bind_expr = m_cf->m_current_bind_expr; - tree stmts = BIND_EXPR_BODY (bind_expr); - m_cf->finish (); - m_cf->emit_metadata (stmts); - dump_function (m_dump_file, m_cf); - } - else - /* Emit the kernel only at the very end so we can analyze the total - group and private memory usage. */ - m_kernels.push_back (m_cf); - - pop_cfun (); - - m_finished_functions[m_cf->m_name] = m_cf; - m_cf = NULL; -} - -/* Initializes a new currently handled function. */ - -void -brig_to_generic::start_function (tree f) -{ - if (DECL_STRUCT_FUNCTION (f) == NULL) - push_struct_function (f); - else - push_cfun (DECL_STRUCT_FUNCTION (f)); - - m_cf->m_func_decl = f; -} - -/* Appends a new variable to the current kernel's private segment. */ - -void -brig_to_generic::append_private_variable (const std::string &name, - size_t size, size_t alignment) -{ - /* We need to take care of two cases of alignment with private - variables because of the layout where the same variable for - each work-item is laid out in successive addresses. - - 1) Ensure the first work-item's variable is in an aligned - offset: */ - size_t align_padding = m_next_private_offset % alignment == 0 ? - 0 : (alignment - m_next_private_offset % alignment); - - /* 2) Each successive per-work-item copy should be aligned. - If the variable has wider alignment than size then we need - to add extra padding to ensure it. The padding must be - included in the size to allow per-work-item offset computation - to find their own aligned copy. */ - - size_t per_var_padding = size % alignment == 0 ? - 0 : (alignment - size % alignment); - m_private_data_sizes[name] = size + per_var_padding; - - m_next_private_offset += align_padding; - m_private_offsets[name] = m_next_private_offset; - m_next_private_offset += size + per_var_padding; -} - -size_t -brig_to_generic::private_variable_segment_offset - (const std::string &name) const -{ - var_offset_table::const_iterator i = m_private_offsets.find (name); - gcc_assert (i != m_private_offsets.end ()); - return (*i).second; -} - -bool -brig_to_generic::has_private_variable (const std::string &name) const -{ - std::map::const_iterator i - = m_private_data_sizes.find (name); - return i != m_private_data_sizes.end (); -} - -size_t -brig_to_generic::private_variable_size (const std::string &name) const -{ - std::map::const_iterator i - = m_private_data_sizes.find (name); - gcc_assert (i != m_private_data_sizes.end ()); - return (*i).second; -} - - -/* The size of private segment required by a single work-item executing - the currently processed kernel. */ - -size_t -brig_to_generic::private_segment_size () const -{ - return m_next_private_offset; -} - -/* Cached builtins indexed by name. */ - -typedef std::map builtin_index; -builtin_index builtin_cache_; - -/* Build a call to a builtin function. PDECL is the builtin function to - call. NARGS is the number of input arguments, RETTYPE the built-in - functions return value type, and ... is the list of arguments passed to - the call with type first, then the value. */ - -tree -call_builtin (tree pdecl, int nargs, tree rettype, ...) -{ - if (rettype == error_mark_node) - return error_mark_node; - - tree *types = new tree[nargs]; - tree *args = new tree[nargs]; - - va_list ap; - va_start (ap, rettype); - for (int i = 0; i < nargs; ++i) - { - types[i] = va_arg (ap, tree); - tree arg = va_arg (ap, tree); - args[i] = build_resize_convert_view (types[i], arg); - if (types[i] == error_mark_node || args[i] == error_mark_node) - { - delete[] types; - delete[] args; - va_end (ap); - return error_mark_node; - } - } - va_end (ap); - - tree fnptr = build_fold_addr_expr (pdecl); - - tree ret = build_call_array (rettype, fnptr, nargs, args); - - delete[] types; - delete[] args; - - return ret; -} - -/* Generate all global declarations. Should be called after the last - BRIG has been fed in. */ - -void -brig_to_generic::write_globals () -{ - - /* Replace calls to declarations with calls to definitions. Otherwise - inlining will fail to find the definition to inline from. */ - - for (size_t i = 0; i < m_decl_call.size(); ++i) - { - tree decl_call = m_decl_call.at(i); - tree func_decl = get_callee_fndecl (decl_call); - brig_function *brig_function = get_finished_function (func_decl); - - if (brig_function && brig_function->m_func_decl - && DECL_EXTERNAL (brig_function->m_func_decl) == 0 - && brig_function->m_func_decl != func_decl) - { - - decl_call = CALL_EXPR_FN (decl_call); - STRIP_NOPS (decl_call); - if (TREE_CODE (decl_call) == ADDR_EXPR - && TREE_CODE (TREE_OPERAND (decl_call, 0)) == FUNCTION_DECL) - TREE_OPERAND (decl_call, 0) = brig_function->m_func_decl; - } - } - - for (std::map::iterator i - = m_finished_functions.begin(), e = m_finished_functions.end(); - i != e; ++i) - { - brig_function *brig_f = (*i).second; - if (brig_f->m_is_kernel) - continue; - - /* Finalize only at this point to allow the cgraph analysis to - see definitions to calls to later functions. */ - gimplify_function_tree (brig_f->m_func_decl); - cgraph_node::finalize_function (brig_f->m_func_decl, true); - } - - /* Now that the whole BRIG module has been processed, build a launcher - and a metadata section for each built kernel. */ - for (size_t i = 0; i < m_kernels.size (); ++i) - { - brig_function *f = m_kernels[i]; - - /* Finish kernels now that we know the call graphs and their barrier - usage. */ - f->finish_kernel (); - - dump_function (m_dump_file, f); - gimplify_function_tree (f->m_func_decl); - cgraph_node::finalize_function (f->m_func_decl, true); - - f->m_descriptor.is_kernel = 1; - /* TODO: analyze the kernel's actual private and group segment usage - using call graph. Now the mem size is overly - pessimistic in case of multiple kernels in the same module. - */ - f->m_descriptor.group_segment_size = m_total_group_segment_usage; - f->m_descriptor.private_segment_size = private_segment_size (); - - /* The kernarg size is rounded up to a multiple of 16 according to - the PRM specs. */ - f->m_descriptor.kernarg_segment_size = f->m_next_kernarg_offset; - if (f->m_descriptor.kernarg_segment_size % 16 > 0) - f->m_descriptor.kernarg_segment_size - += 16 - f->m_next_kernarg_offset % 16; - f->m_descriptor.kernarg_max_align = f->m_kernarg_max_align; - - tree launcher = f->emit_launcher_and_metadata (); - - append_global (launcher); - - if (m_dump_file) - { - std::string kern_name = f->m_name.substr (1); - fprintf (m_dump_file, "\n;; Function %s", kern_name.c_str()); - fprintf (m_dump_file, "\n;; enabled by -%s\n\n", - dump_flag_name (TDI_original)); - print_generic_decl (m_dump_file, launcher, TDF_NONE); - print_generic_expr (m_dump_file, DECL_SAVED_TREE (launcher), - TDF_NONE); - fprintf (m_dump_file, "\n"); - } - - gimplify_function_tree (launcher); - cgraph_node::finalize_function (launcher, true); - pop_cfun (); - } - - int no_globals = list_length (m_globals); - tree *vec = new tree[no_globals]; - - int i = 0; - tree global = m_globals; - while (global) - { - vec[i] = global; - ++i; - global = TREE_CHAIN (global); - } - - wrapup_global_declarations (vec, no_globals); - - delete[] vec; - -} - -/* Returns an type with unsigned int elements corresponding to the - size and element count of ORIGINAL_TYPE. */ - -tree -get_unsigned_int_type (tree original_type) -{ - if (VECTOR_TYPE_P (original_type)) - { - size_t esize - = int_size_in_bytes (TREE_TYPE (original_type)) * BITS_PER_UNIT; - poly_uint64 ecount = TYPE_VECTOR_SUBPARTS (original_type); - return build_vector_type (build_nonstandard_integer_type (esize, true), - ecount); - } - else - return build_nonstandard_integer_type (int_size_in_bytes (original_type) - * BITS_PER_UNIT, - true); -} - -/* Returns a type with unsigned int corresponding to the size - ORIGINAL_TYPE. */ - -tree -get_scalar_unsigned_int_type (tree original_type) -{ - return build_nonstandard_integer_type (int_size_in_bytes (original_type) - * BITS_PER_UNIT, true); -} - -/* Set the declaration externally visible so it won't get removed by - whole program optimizations. */ - -void -set_externally_visible (tree decl) -{ - if (!lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl))) - DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("externally_visible"), - NULL, DECL_ATTRIBUTES (decl)); -} - -void -set_inline (tree decl) -{ - if (!lookup_attribute ("inline", DECL_ATTRIBUTES (decl))) - DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("inline"), - NULL, DECL_ATTRIBUTES (decl)); -} - -void -dump_function (FILE *dump_file, brig_function *f) -{ - /* Dump the BRIG-specific tree IR. */ - if (dump_file) - { - fprintf (dump_file, "\n;; Function %s", f->m_name.c_str ()); - fprintf (dump_file, "\n;; enabled by -%s\n\n", - dump_flag_name (TDI_original)); - print_generic_decl (dump_file, f->m_func_decl, TDF_NONE); - print_generic_expr (dump_file, f->m_current_bind_expr, TDF_NONE); - fprintf (dump_file, "\n"); - } -} - -/* Records use of the BRIG_REG as a TYPE in the current function. */ - -void -brig_to_generic::add_reg_used_as_type (const BrigOperandRegister &brig_reg, - tree type) -{ - gcc_assert (m_cf); - reg_use_info &info - = m_fn_regs_use_index[m_cf->m_name][gccbrig_hsa_reg_id (brig_reg)]; - - if (info.m_type_refs_lookup.count (type)) - info.m_type_refs[info.m_type_refs_lookup[type]].second++; - else - { - info.m_type_refs.push_back (std::make_pair (type, 1)); - info.m_type_refs_lookup[type] = info.m_type_refs.size () - 1; - } -} diff --git a/gcc/brig/brigfrontend/brig-to-generic.h b/gcc/brig/brigfrontend/brig-to-generic.h deleted file mode 100644 index f4a67374e40..00000000000 --- a/gcc/brig/brigfrontend/brig-to-generic.h +++ /dev/null @@ -1,240 +0,0 @@ -/* brig-to-generic.h -- brig to gcc generic conversion - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3, or (at your option) any later - version. - - GCC is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - . */ - -#ifndef BRIG_TO_GENERIC_H -#define BRIG_TO_GENERIC_H - -#include -#include -#include - -#include "config.h" -#include "system.h" -#include "ansidecl.h" -#include "coretypes.h" -#include "opts.h" -#include "tree.h" -#include "tree-iterator.h" -#include "hsa-brig-format.h" -#include "brig-function.h" - -struct reg_decl_index_entry; - -/* Converts an HSAIL BRIG input to GENERIC. This class holds global state - for the translation process. Handling of the smaller pieces of BRIG data - is delegated to various handler classes declared in - brig-code-entry-handlers.h. */ - -class brig_to_generic -{ -public: - typedef std::map variable_index; - -private: - typedef std::map var_offset_table; - typedef std::map name_index; - -public: - brig_to_generic (); - - void analyze (const char *brig_blob); - void parse (const char *brig_blob); - - void write_globals (); - - std::string get_string (size_t entry_offset) const; - - const BrigData *get_brig_data_entry (size_t entry_offset) const; - const BrigBase *get_brig_operand_entry (size_t entry_offset) const; - const BrigBase *get_brig_code_entry (size_t entry_offset) const; - - void append_global (tree g); - - tree function_decl (const std::string &name); - void add_function_decl (const std::string &name, tree func_decl); - - tree global_variable (const std::string &name) const; - void add_global_variable (const std::string &name, tree var_decl); - void add_host_def_var_ptr (const std::string &name, tree var_decl); - void add_decl_call (tree call); - - void start_function (tree f); - void finish_function (); - - void append_private_variable (const std::string &name, size_t size, - size_t alignment); - - size_t - private_variable_segment_offset (const std::string &name) const; - - bool - has_private_variable (const std::string &name) const; - - size_t private_variable_size (const std::string &name) const; - - template - std::string - get_mangled_name_tmpl (const T *brigVar) const; - - std::string get_mangled_name (const BrigDirectiveFbarrier *fbar) const - { return get_mangled_name_tmpl (fbar); } - std::string get_mangled_name (const BrigDirectiveVariable *var) const - { return get_mangled_name_tmpl (var); } - std::string get_mangled_name (const BrigDirectiveExecutable *func) const; - - size_t private_segment_size () const; - - brig_function *get_finished_function (tree func_decl); - - void add_group_variable (const std::string &name, size_t size, - size_t alignment, bool function_scope); - - void add_reg_used_as_type (const BrigOperandRegister &brig_reg, - tree operand_type); - - static tree s_fp16_type; - static tree s_fp32_type; - static tree s_fp64_type; - - /* The default rounding mode that should be used for float instructions. - This can be set in each BRIG module header. */ - BrigRound8_t m_default_float_rounding_mode; - - /* The currently built function. */ - brig_function *m_cf; - - /* Stores the module and function scope group variable offsets. */ - group_variable_offset_index m_module_group_variables; - - /* The name of the currently handled BRIG module. */ - std::string m_module_name; - - /* Set to true if the compilation is in 'analyze' phase. */ - bool m_analyzing; - - /* Accumulates the total group segment usage. */ - size_t m_total_group_segment_usage; - - /* Statistics about register uses per function. */ - std::map m_fn_regs_use_index; - -private: - - void find_brig_sections (); - /* The BRIG blob and its different sections of the file currently being - parsed. */ - const char *m_brig; - const char *m_data; - size_t m_data_size; - const char *m_operand; - size_t m_operand_size; - const char *m_code; - size_t m_code_size; - - tree m_globals; - - label_index m_global_variables; - - /* Calls to declarations to be fixed in the end of processing to call - defs instead. */ - std::vector m_decl_call; - - /* The size of each private variable, including the alignment padding. */ - std::map m_private_data_sizes; - - /* And private. */ - size_t m_next_private_offset; - var_offset_table m_private_offsets; - - /* Name index for declared functions. */ - label_index m_function_index; - - /* Stores all processed kernels in order. */ - std::vector m_kernels; - - /* Stores all already processed functions from the translation unit - for some interprocedural analysis. */ - std::map m_finished_functions; - - /* The original dump file. */ - FILE *m_dump_file; - - /* The original dump file flags. */ - dump_flags_t m_dump_flags; -}; - -/* Produce a "mangled name" for the given brig variable. The mangling is used - to make unique global symbol names for module and function scope variables. - The templated version is suitable for most of the variable types. Functions - and kernels (BrigDirectiveExecutable) are handled with a specialized - get_mangled_name() version. */ - -template -std::string -brig_to_generic::get_mangled_name_tmpl (const T *brigVar) const -{ - std::string var_name = get_string (brigVar->name).substr (1); - - /* Mangle the variable name using the function name and the module name - in case of a function scope variable. */ - if (m_cf != NULL - && m_cf->has_function_scope_var (&brigVar->base)) - var_name = m_cf->m_name + "." + var_name; - - if (brigVar->linkage == BRIG_LINKAGE_MODULE) - var_name = "gccbrig." + m_module_name + "." + var_name; - return var_name; -} - -/* An interface to organize the different types of BRIG element handlers. */ - -class brig_entry_handler -{ -public: - brig_entry_handler (brig_to_generic &parent) : m_parent (parent) - { - } - - /* Handles the brig_code data at the given pointer and adds it to the - currently built tree. Returns the number of consumed bytes; */ - virtual size_t operator () (const BrigBase *base) = 0; - -protected: - brig_to_generic &m_parent; -}; - -tree call_builtin (tree pdecl, int nargs, tree rettype, ...); - -tree build_resize_convert_view (tree destination_type, tree source); -tree build_reinterpret_to_uint (tree source); - -tree build_stmt (enum tree_code code, ...); - -tree get_unsigned_int_type (tree type); - -tree get_scalar_unsigned_int_type (tree type); -void set_externally_visible (tree decl); - -void set_inline (tree decl); - -void dump_function (FILE *dump_file, brig_function *f); - -#endif diff --git a/gcc/brig/brigfrontend/brig-util.cc b/gcc/brig/brigfrontend/brig-util.cc deleted file mode 100644 index 2ee561a65ba..00000000000 --- a/gcc/brig/brigfrontend/brig-util.cc +++ /dev/null @@ -1,574 +0,0 @@ -/* brig-util.cc -- gccbrig utility functions - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ - -#include - -#include "stdint.h" -#include "hsa-brig-format.h" -#include "brig-util.h" -#include "errors.h" -#include "diagnostic-core.h" -#include "print-tree.h" - -bool -group_variable_offset_index::has_variable (const std::string &name) const -{ - varname_offset_table::const_iterator i = m_group_offsets.find (name); - return i != m_group_offsets.end (); -} - -/* Adds a new group segment variable. */ - -void -group_variable_offset_index::add (const std::string &name, size_t size, - size_t alignment) -{ - size_t align_padding = m_next_group_offset % alignment == 0 ? - 0 : (alignment - m_next_group_offset % alignment); - m_next_group_offset += align_padding; - m_group_offsets[name] = m_next_group_offset; - m_next_group_offset += size; -} - -size_t -group_variable_offset_index::segment_offset (const std::string &name) const -{ - varname_offset_table::const_iterator i = m_group_offsets.find (name); - gcc_assert (i != m_group_offsets.end ()); - return (*i).second; -} - -/* Return true if operand number OPNUM of instruction with OPCODE is an output. - False if it is an input. Some code reused from Martin Jambor's gcc-hsa - tree. */ - -bool -gccbrig_hsa_opcode_op_output_p (BrigOpcode16_t opcode, int opnum) -{ - switch (opcode) - { - case BRIG_OPCODE_BR: - case BRIG_OPCODE_SBR: - case BRIG_OPCODE_CBR: - case BRIG_OPCODE_ST: - case BRIG_OPCODE_ATOMICNORET: - case BRIG_OPCODE_SIGNALNORET: - case BRIG_OPCODE_INITFBAR: - case BRIG_OPCODE_JOINFBAR: - case BRIG_OPCODE_WAITFBAR: - case BRIG_OPCODE_ARRIVEFBAR: - case BRIG_OPCODE_LEAVEFBAR: - case BRIG_OPCODE_RELEASEFBAR: - case BRIG_OPCODE_DEBUGTRAP: - return false; - default: - return opnum == 0; - } -} - -unsigned -gccbrig_hsa_type_bit_size (BrigType16_t t) -{ - - unsigned pack_type = t & ~BRIG_TYPE_BASE_MASK; - - if (pack_type == BRIG_TYPE_PACK_32) - return 32; - else if (pack_type == BRIG_TYPE_PACK_64) - return 64; - else if (pack_type == BRIG_TYPE_PACK_128) - return 128; - - switch (t) - { - case BRIG_TYPE_NONE: - return 0; - - case BRIG_TYPE_B1: - return 1; - - case BRIG_TYPE_U8: - case BRIG_TYPE_S8: - case BRIG_TYPE_B8: - return 8; - - case BRIG_TYPE_U16: - case BRIG_TYPE_S16: - case BRIG_TYPE_B16: - case BRIG_TYPE_F16: - return 16; - - case BRIG_TYPE_U32: - case BRIG_TYPE_S32: - case BRIG_TYPE_B32: - case BRIG_TYPE_F32: - case BRIG_TYPE_U8X4: - case BRIG_TYPE_U16X2: - case BRIG_TYPE_S8X4: - case BRIG_TYPE_S16X2: - case BRIG_TYPE_F16X2: - case BRIG_TYPE_SIG32: - return 32; - - case BRIG_TYPE_U64: - case BRIG_TYPE_S64: - case BRIG_TYPE_F64: - case BRIG_TYPE_B64: - case BRIG_TYPE_U8X8: - case BRIG_TYPE_U16X4: - case BRIG_TYPE_U32X2: - case BRIG_TYPE_S8X8: - case BRIG_TYPE_S16X4: - case BRIG_TYPE_S32X2: - case BRIG_TYPE_F16X4: - case BRIG_TYPE_F32X2: - case BRIG_TYPE_SIG64: - return 64; - - case BRIG_TYPE_B128: - case BRIG_TYPE_U8X16: - case BRIG_TYPE_U16X8: - case BRIG_TYPE_U32X4: - case BRIG_TYPE_U64X2: - case BRIG_TYPE_S8X16: - case BRIG_TYPE_S16X8: - case BRIG_TYPE_S32X4: - case BRIG_TYPE_S64X2: - case BRIG_TYPE_F16X8: - case BRIG_TYPE_F32X4: - case BRIG_TYPE_F64X2: - return 128; - - default: - printf ("HMM %d %x\n", t, t); - gcc_unreachable (); - } -} - -/* gcc-hsa borrowed code ENDS. */ - -uint64_t -gccbrig_to_uint64_t (const BrigUInt64 &brig_type) -{ - return (uint64_t (brig_type.hi) << 32) | uint64_t (brig_type.lo); -} - -int -gccbrig_reg_size (const BrigOperandRegister *brig_reg) -{ - switch (brig_reg->regKind) - { - case BRIG_REGISTER_KIND_CONTROL: - return 1; - case BRIG_REGISTER_KIND_SINGLE: - return 32; - case BRIG_REGISTER_KIND_DOUBLE: - return 64; - case BRIG_REGISTER_KIND_QUAD: - return 128; - default: - gcc_unreachable (); - break; - } -} - -std::string -gccbrig_reg_name (const BrigOperandRegister *reg) -{ - std::ostringstream strstr; - switch (reg->regKind) - { - case BRIG_REGISTER_KIND_CONTROL: - strstr << 'c'; - break; - case BRIG_REGISTER_KIND_SINGLE: - strstr << 's'; - break; - case BRIG_REGISTER_KIND_DOUBLE: - strstr << 'd'; - break; - case BRIG_REGISTER_KIND_QUAD: - strstr << 'q'; - break; - default: - gcc_unreachable (); - return ""; - } - strstr << reg->regNum; - return strstr.str (); -} - -std::string -gccbrig_type_name (BrigType16_t type) -{ - switch (type) - { - case BRIG_TYPE_U8: - return "u8"; - case BRIG_TYPE_U16: - return "u16"; - case BRIG_TYPE_U32: - return "u32"; - case BRIG_TYPE_U64: - return "u64"; - case BRIG_TYPE_S8: - return "s8"; - case BRIG_TYPE_S16: - return "s16"; - case BRIG_TYPE_S32: - return "s32"; - case BRIG_TYPE_S64: - return "s64"; - default: - gcc_unreachable (); - break; - } -} - -std::string -gccbrig_segment_name (BrigSegment8_t segment) -{ - if (segment == BRIG_SEGMENT_GLOBAL) - return "global"; - else if (segment == BRIG_SEGMENT_GROUP) - return "group"; - else if (segment == BRIG_SEGMENT_PRIVATE) - return "private"; - else - gcc_unreachable (); -} - -bool -gccbrig_is_float_type (BrigType16_t type) -{ - return (type == BRIG_TYPE_F32 || type == BRIG_TYPE_F64 - || type == BRIG_TYPE_F16); -} - -BrigType16_t -gccbrig_tree_type_to_hsa_type (tree tree_type) -{ - if (INTEGRAL_TYPE_P (tree_type)) - { - if (TYPE_UNSIGNED (tree_type)) - { - switch (int_size_in_bytes (tree_type)) - { - case 1: - return BRIG_TYPE_U8; - case 2: - return BRIG_TYPE_U16; - case 4: - return BRIG_TYPE_U32; - case 8: - return BRIG_TYPE_U64; - default: - break; - } - } - else - { - switch (int_size_in_bytes (tree_type)) - { - case 1: - return BRIG_TYPE_S8; - case 2: - return BRIG_TYPE_S16; - case 4: - return BRIG_TYPE_S32; - case 8: - return BRIG_TYPE_S64; - default: - break; - } - } - } - else if (VECTOR_TYPE_P (tree_type)) - { - tree element_type = TREE_TYPE (tree_type); - size_t element_size = int_size_in_bytes (element_type) * 8; - BrigType16_t brig_element_type; - switch (element_size) - { - case 8: - brig_element_type - = TYPE_UNSIGNED (element_type) ? BRIG_TYPE_U8 : BRIG_TYPE_S8; - break; - case 16: - brig_element_type - = TYPE_UNSIGNED (element_type) ? BRIG_TYPE_U16 : BRIG_TYPE_S16; - break; - case 32: - brig_element_type - = TYPE_UNSIGNED (element_type) ? BRIG_TYPE_U32 : BRIG_TYPE_S32; - break; - case 64: - brig_element_type - = TYPE_UNSIGNED (element_type) ? BRIG_TYPE_U64 : BRIG_TYPE_S64; - break; - default: - gcc_unreachable (); - } - - BrigType16_t pack_type; - switch (int_size_in_bytes (tree_type) * 8) - { - case 32: - pack_type = BRIG_TYPE_PACK_32; - break; - case 64: - pack_type = BRIG_TYPE_PACK_64; - break; - case 128: - pack_type = BRIG_TYPE_PACK_128; - break; - default: - gcc_unreachable (); - } - return brig_element_type | pack_type; - } - gcc_unreachable (); -} - -/* Returns true in case the operation is a "bit level" operation, - that is, not having operand type depending semantical differences. */ - -bool -gccbrig_is_bit_operation (BrigOpcode16_t opcode) -{ - return opcode == BRIG_OPCODE_CMOV || opcode == BRIG_OPCODE_SHUFFLE - || opcode == BRIG_OPCODE_UNPACK || opcode == BRIG_OPCODE_UNPACKLO - || opcode == BRIG_OPCODE_UNPACKHI || opcode == BRIG_OPCODE_ST - || opcode == BRIG_OPCODE_PACK; -} - -/* The program scope definition can be left external within the - kernel binary which means it must be defined by the host via - HSA runtime. For these we have special treatment: - Create additional pointer indirection when accessing the variable - value from kernel code through a generated pointer - __gccbrig_ptr_variable_name. The pointer value then can be set either - within the kernel binary (in case of a later linked in definition) - or from the host. */ - -bool -gccbrig_might_be_host_defined_var_p (const BrigDirectiveVariable *brigVar) -{ - bool is_definition = brigVar->modifier & BRIG_VARIABLE_DEFINITION; - return (brigVar->segment == BRIG_SEGMENT_GLOBAL - || brigVar->segment == BRIG_SEGMENT_READONLY) && !is_definition - && brigVar->linkage == BRIG_LINKAGE_PROGRAM - && (brigVar->allocation == BRIG_ALLOCATION_PROGRAM - || brigVar->allocation == BRIG_ALLOCATION_AGENT); -} - -/* Produce a GENERIC type for the given HSA/BRIG type. Returns the element - type in case of vector instructions. */ - -tree -gccbrig_tree_type_for_hsa_type (BrigType16_t brig_type) -{ - tree tree_type = NULL_TREE; - - if (hsa_type_packed_p (brig_type)) - { - /* The element type is encoded in the bottom 5 bits. */ - BrigType16_t inner_brig_type = brig_type & BRIG_TYPE_BASE_MASK; - - unsigned full_size = gccbrig_hsa_type_bit_size (brig_type); - - if (inner_brig_type == BRIG_TYPE_F16) - return build_vector_type (gccbrig_tree_type_for_hsa_type (BRIG_TYPE_U16), - full_size / 16); - - tree inner_type = gccbrig_tree_type_for_hsa_type (inner_brig_type); - - unsigned inner_size = gccbrig_hsa_type_bit_size (inner_brig_type); - unsigned nunits = full_size / inner_size; - tree_type = build_vector_type (inner_type, nunits); - } - else - { - switch (brig_type) - { - case BRIG_TYPE_NONE: - tree_type = void_type_node; - break; - case BRIG_TYPE_B1: - tree_type = boolean_type_node; - break; - case BRIG_TYPE_S8: - case BRIG_TYPE_S16: - case BRIG_TYPE_S32: - case BRIG_TYPE_S64: - /* Ensure a fixed width integer. */ - tree_type - = build_nonstandard_integer_type - (gccbrig_hsa_type_bit_size (brig_type), false); - break; - case BRIG_TYPE_U8: - return unsigned_char_type_node; - case BRIG_TYPE_U16: - case BRIG_TYPE_U32: - case BRIG_TYPE_U64: - case BRIG_TYPE_B8: /* Handle bit vectors as unsigned ints. */ - case BRIG_TYPE_B16: - case BRIG_TYPE_B32: - case BRIG_TYPE_B64: - case BRIG_TYPE_B128: - case BRIG_TYPE_SIG32: /* Handle signals as integers for now. */ - case BRIG_TYPE_SIG64: - tree_type = build_nonstandard_integer_type - (gccbrig_hsa_type_bit_size (brig_type), true); - break; - case BRIG_TYPE_F16: - tree_type = uint16_type_node; - break; - case BRIG_TYPE_F32: - /* TODO: make sure that the alignment of the float are at least as - strict than mandated by HSA, and conform to IEEE (like mandated - by HSA). */ - tree_type = float_type_node; - break; - case BRIG_TYPE_F64: - tree_type = double_type_node; - break; - case BRIG_TYPE_SAMP: - case BRIG_TYPE_ROIMG: - case BRIG_TYPE_WOIMG: - case BRIG_TYPE_RWIMG: - { - /* Handle images and samplers as target-specific blobs of data - that should be allocated earlier on from the runtime side. - Create a void* that should be initialized to point to the blobs - by the kernel launcher. Images and samplers are accessed - via builtins that take void* as the reference. TODO: who and - how these arrays should be initialized? */ - tree void_ptr = build_pointer_type (void_type_node); - return void_ptr; - } - default: - gcc_unreachable (); - break; - } - } - - /* Drop const qualifiers. */ - return tree_type; -} - -/* Calculates numeric identifier for the HSA register REG. - - Returned value is bound to [0, BRIG_2_TREE_HSAIL_TOTAL_REG_COUNT]. */ - -size_t -gccbrig_hsa_reg_id (const BrigOperandRegister ®) -{ - size_t offset = reg.regNum; - switch (reg.regKind) - { - case BRIG_REGISTER_KIND_QUAD: - offset - += BRIG_2_TREE_HSAIL_D_REG_COUNT + BRIG_2_TREE_HSAIL_S_REG_COUNT - + BRIG_2_TREE_HSAIL_C_REG_COUNT; - break; - case BRIG_REGISTER_KIND_DOUBLE: - offset += BRIG_2_TREE_HSAIL_S_REG_COUNT + BRIG_2_TREE_HSAIL_C_REG_COUNT; - break; - case BRIG_REGISTER_KIND_SINGLE: - offset += BRIG_2_TREE_HSAIL_C_REG_COUNT; - case BRIG_REGISTER_KIND_CONTROL: - break; - default: - gcc_unreachable (); - break; - } - return offset; -} - -std::string -gccbrig_hsa_reg_name_from_id (size_t reg_id) -{ - char reg_name[32]; - long unsigned int reg_hash = (long unsigned int) reg_id; - if (reg_hash < BRIG_2_TREE_HSAIL_C_REG_COUNT) - { - sprintf (reg_name, "$c%lu", reg_hash); - return reg_name; - } - - reg_hash -= BRIG_2_TREE_HSAIL_C_REG_COUNT; - if (reg_hash < BRIG_2_TREE_HSAIL_S_REG_COUNT) - { - sprintf (reg_name, "$s%lu", reg_hash); - return reg_name; - } - - reg_hash -= BRIG_2_TREE_HSAIL_S_REG_COUNT; - if (reg_hash < BRIG_2_TREE_HSAIL_D_REG_COUNT) - { - sprintf (reg_name, "$d%lu", reg_hash); - return reg_name; - } - - reg_hash -= BRIG_2_TREE_HSAIL_D_REG_COUNT; - if (reg_hash < BRIG_2_TREE_HSAIL_Q_REG_COUNT) - { - sprintf (reg_name, "$q%lu", reg_hash); - return reg_name; - } - - gcc_unreachable (); - return "$??"; -} - -/* Prints statistics of register usage to stdout. */ - -void -gccbrig_print_reg_use_info (FILE *dump, const regs_use_index &info) -{ - regs_use_index::const_iterator begin_it = info.begin (); - regs_use_index::const_iterator end_it = info.end (); - for (regs_use_index::const_iterator it = begin_it; it != end_it; it++) - { - std::string hsa_reg = gccbrig_hsa_reg_name_from_id (it->first); - printf ("%s:\n", hsa_reg.c_str ()); - const reg_use_info &info = it->second; - typedef std::vector >::const_iterator reg_use_it; - reg_use_it begin_it2 = info.m_type_refs.begin (); - reg_use_it end_it2 = info.m_type_refs.end (); - for (reg_use_it it2 = begin_it2; it2 != end_it2; it2++) - { - fprintf (dump, "(%lu) ", (long unsigned int) it2->second); - print_node_brief (dump, "", it2->first, 0); - fprintf (dump, "\n"); - } - } -} - -/* Return true if TYPE is a packed HSA type. */ - -bool -hsa_type_packed_p (BrigType16_t type) -{ - return (type & BRIG_TYPE_PACK_MASK) != BRIG_TYPE_PACK_NONE; -} - diff --git a/gcc/brig/brigfrontend/brig-util.h b/gcc/brig/brigfrontend/brig-util.h deleted file mode 100644 index 339db618791..00000000000 --- a/gcc/brig/brigfrontend/brig-util.h +++ /dev/null @@ -1,120 +0,0 @@ -/* brig-util.h -- gccbrig utility functions - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ - -#ifndef GCC_BRIG_UTIL_H -#define GCC_BRIG_UTIL_H - -#include -#include - -#include "config.h" -#include "system.h" -#include "ansidecl.h" -#include "coretypes.h" -#include "opts.h" -#include "tree.h" - -/* There are 128 c regs and 2048 s/d/q regs each in the HSAIL. */ -#define BRIG_2_TREE_HSAIL_C_REG_COUNT (128) -#define BRIG_2_TREE_HSAIL_S_REG_COUNT (2048) -#define BRIG_2_TREE_HSAIL_D_REG_COUNT (2048) -#define BRIG_2_TREE_HSAIL_Q_REG_COUNT (2048) -#define BRIG_2_TREE_HSAIL_TOTAL_REG_COUNT \ - (BRIG_2_TREE_HSAIL_C_REG_COUNT + BRIG_2_TREE_HSAIL_S_REG_COUNT \ - + BRIG_2_TREE_HSAIL_D_REG_COUNT + BRIG_2_TREE_HSAIL_Q_REG_COUNT) - -/* Helper class for keeping book of group variable offsets. */ - -class group_variable_offset_index -{ -public: - group_variable_offset_index () : m_next_group_offset (0) {} - - typedef std::map varname_offset_table; - - bool has_variable (const std::string &name) const; - void add (const std::string &name, size_t size, size_t alignment); - size_t segment_offset (const std::string &name) const; - size_t size () const { return m_next_group_offset; } - -private: - size_t m_next_group_offset; - varname_offset_table m_group_offsets; -}; - -bool gccbrig_hsa_opcode_op_output_p (BrigOpcode16_t opcode, int opnum); - -unsigned gccbrig_hsa_type_bit_size (BrigType16_t t); - -uint64_t gccbrig_to_uint64_t (const BrigUInt64 &brig_type); - -int gccbrig_reg_size (const BrigOperandRegister *brig_reg); - -std::string gccbrig_reg_name (const BrigOperandRegister *reg); - -std::string gccbrig_type_name (BrigType16_t type); - -std::string gccbrig_segment_name (BrigSegment8_t segment); - -bool gccbrig_is_float_type (BrigType16_t type); - -bool gccbrig_is_bit_operation (BrigOpcode16_t opcode); - -BrigType16_t gccbrig_tree_type_to_hsa_type (tree tree_type); -tree gccbrig_tree_type_for_hsa_type (BrigType16_t brig_type); - -bool gccbrig_might_be_host_defined_var_p (const BrigDirectiveVariable *brigVar); - -/* From hsa.h. */ -bool hsa_type_packed_p (BrigType16_t type); - -struct reg_use_info -{ - /* This vector keeps count of the times an HSAIL register is used as - a tree type in generic expressions. The count is used to select - type for 'register' variables to reduce emission of - VIEW_CONVERT_EXPR nodes. The data is kept in vector (insertion - order) for determinism, in a case there is a tie with the - counts. */ - std::vector > m_type_refs; - /* Tree to index. Lookup for the above vector. */ - std::map m_type_refs_lookup; -}; - -/* key = hsa register entry generated by gccbrig_hsa_reg_id (). */ -typedef std::map regs_use_index; - -size_t gccbrig_hsa_reg_id (const BrigOperandRegister ®); -std::string gccbrig_hsa_reg_name_from_id (size_t reg_hash); - -void gccbrig_print_reg_use_info (FILE *dump, const regs_use_index &info); - -/* Return the number of elements in a VECTOR_TYPE. BRIG does not support - variable-length vectors. */ -inline unsigned HOST_WIDE_INT -gccbrig_type_vector_subparts (const_tree type) -{ - return TYPE_VECTOR_SUBPARTS (type).to_constant (); -} - -bool hsa_type_packed_p (BrigType16_t type); - -#endif diff --git a/gcc/brig/brigfrontend/brig-variable-handler.cc b/gcc/brig/brigfrontend/brig-variable-handler.cc deleted file mode 100644 index cd77714ef54..00000000000 --- a/gcc/brig/brigfrontend/brig-variable-handler.cc +++ /dev/null @@ -1,270 +0,0 @@ -/* brig-variable-handler.cc -- brig variable directive handling - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3, or (at your option) any later - version. - - GCC is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - . */ - -#include "brig-code-entry-handler.h" - -#include "stringpool.h" -#include "errors.h" -#include "brig-machine.h" -#include "brig-util.h" -#include "print-tree.h" -#include "diagnostic-core.h" -#include "brig-to-generic.h" - -tree -brig_directive_variable_handler::build_variable - (const BrigDirectiveVariable *brigVar, tree_code var_decltype) -{ - std::string var_name = m_parent.get_mangled_name (brigVar); - - bool is_definition = brigVar->modifier & BRIG_VARIABLE_DEFINITION; - - tree name_identifier = get_identifier (var_name.c_str ()); - - tree var_decl; - tree t; - if (brigVar->type & BRIG_TYPE_ARRAY) - { - tree element_type - = gccbrig_tree_type_for_hsa_type (brigVar->type & ~BRIG_TYPE_ARRAY); - uint64_t element_count = gccbrig_to_uint64_t (brigVar->dim); - if (is_definition && element_count == 0) - fatal_error (UNKNOWN_LOCATION, "Array definition with zero elements."); - if (var_decltype == PARM_DECL) - t = build_pointer_type (element_type); - else - t = build_array_type_nelts (element_type, element_count); - } - else - { - t = gccbrig_tree_type_for_hsa_type (brigVar->type); - } - - size_t alignment = get_brig_var_alignment (brigVar); - - if (brigVar->segment == BRIG_SEGMENT_READONLY - || brigVar->segment == BRIG_SEGMENT_KERNARG - || (brigVar->modifier & BRIG_VARIABLE_CONST)) - TYPE_READONLY (t) = 1; - - TYPE_ADDR_SPACE (t) = gccbrig_get_target_addr_space_id (brigVar->segment); - - var_decl = build_decl (UNKNOWN_LOCATION, var_decltype, name_identifier, t); - - SET_DECL_ALIGN (var_decl, alignment * BITS_PER_UNIT); - - /* Force the HSA alignments. */ - DECL_USER_ALIGN (var_decl) = 1; - - TREE_USED (var_decl) = 1; - - TREE_PUBLIC (var_decl) = 1; - if (is_definition) - DECL_EXTERNAL (var_decl) = 0; - else - DECL_EXTERNAL (var_decl) = 1; /* The definition is elsewhere. */ - - if (brigVar->init != 0) - { - gcc_assert (brigVar->segment == BRIG_SEGMENT_READONLY - || brigVar->segment == BRIG_SEGMENT_GLOBAL); - - const BrigBase *cst_operand_data - = m_parent.get_brig_operand_entry (brigVar->init); - - tree initializer = NULL_TREE; - if (cst_operand_data->kind == BRIG_KIND_OPERAND_CONSTANT_BYTES) - initializer = get_tree_cst_for_hsa_operand - ((const BrigOperandConstantBytes *) cst_operand_data, t); - else - error ("variable initializers of type %x not implemented", - cst_operand_data->kind); - gcc_assert (initializer != NULL_TREE); - DECL_INITIAL (var_decl) = initializer; - } - - if (var_decltype == PARM_DECL) - { - DECL_ARG_TYPE (var_decl) = TREE_TYPE (var_decl); - DECL_EXTERNAL (var_decl) = 0; - TREE_PUBLIC (var_decl) = 0; - } - - TREE_ADDRESSABLE (var_decl) = 1; - - TREE_USED (var_decl) = 1; - DECL_NONLOCAL (var_decl) = 1; - DECL_ARTIFICIAL (var_decl) = 0; - - return var_decl; -} - -size_t -brig_directive_variable_handler::operator () (const BrigBase *base) -{ - const BrigDirectiveVariable *brigVar = (const BrigDirectiveVariable *) base; - - bool is_definition = brigVar->modifier & BRIG_VARIABLE_DEFINITION; - - size_t var_size; - tree var_type; - if (brigVar->type & BRIG_TYPE_ARRAY) - { - tree element_type - = gccbrig_tree_type_for_hsa_type (brigVar->type & ~BRIG_TYPE_ARRAY); - uint64_t element_count = gccbrig_to_uint64_t (brigVar->dim); - if (is_definition && element_count == 0) - fatal_error (UNKNOWN_LOCATION, "Array definition with zero elements."); - var_type = build_array_type_nelts (element_type, element_count); - size_t element_size = tree_to_uhwi (TYPE_SIZE (element_type)); - var_size = element_size * element_count / 8; - } - else - { - var_type = gccbrig_tree_type_for_hsa_type (brigVar->type); - var_size = tree_to_uhwi (TYPE_SIZE (var_type)) / 8; - } - - size_t alignment = get_brig_var_alignment (brigVar); - - bool function_scope = m_parent.m_cf != NULL; - - if (function_scope) - m_parent.m_cf->m_function_scope_vars.insert (base); - - std::string var_name = m_parent.get_mangled_name (brigVar); - if (brigVar->segment == BRIG_SEGMENT_GROUP) - { - /* Non-kernel scope group variables have been added at the - 'analyze' stage. */ - m_parent.add_group_variable (var_name, var_size, alignment, - function_scope); - return base->byteCount; - } - - /* During analyze, handle only (module scope) group variables. */ - if (m_parent.m_analyzing) - return base->byteCount; - - if (brigVar->segment == BRIG_SEGMENT_KERNARG) - { - /* Do not create a real variable, but only a table of - offsets to the kernarg segment buffer passed as the - single argument by the kernel launcher for later - reference. Ignore kernel declarations. */ - if (m_parent.m_cf != NULL && m_parent.m_cf->m_func_decl != NULL_TREE) - m_parent.m_cf->append_kernel_arg (brigVar, var_size, alignment); - return base->byteCount; - } - else if (brigVar->segment == BRIG_SEGMENT_PRIVATE - || brigVar->segment == BRIG_SEGMENT_SPILL) - { - /* Private variables are handled like group variables, - except that their offsets are multiplied by the work-item - flat id, when accessed. */ - if (!m_parent.has_private_variable (var_name)) - m_parent.append_private_variable (var_name, var_size, alignment); - return base->byteCount; - } - else if (brigVar->segment == BRIG_SEGMENT_GLOBAL - || brigVar->segment == BRIG_SEGMENT_READONLY) - { - tree def = is_definition ? NULL_TREE : - m_parent.global_variable (var_name); - - if (!is_definition && def != NULL_TREE) - { - /* We have a definition already for this declaration. - Use the definition instead of the declaration. */ - } - else if (gccbrig_might_be_host_defined_var_p (brigVar)) - { - tree var_decl = build_variable (brigVar); - m_parent.add_host_def_var_ptr (var_name, var_decl); - } - else - { - tree var_decl = build_variable (brigVar); - /* Make all global variables program scope for now - so we can get their address from the Runtime API. */ - DECL_CONTEXT (var_decl) = NULL_TREE; - TREE_STATIC (var_decl) = 1; - TREE_PUBLIC (var_decl) = 1; - set_externally_visible (var_decl); - m_parent.add_global_variable (var_name, var_decl); - } - } - else if (brigVar->segment == BRIG_SEGMENT_ARG) - { - - if (m_parent.m_cf->m_generating_arg_block) - { - tree var_decl = build_variable (brigVar); - tree bind_expr = m_parent.m_cf->m_current_bind_expr; - - DECL_CONTEXT (var_decl) = m_parent.m_cf->m_func_decl; - DECL_CHAIN (var_decl) = BIND_EXPR_VARS (bind_expr); - BIND_EXPR_VARS (bind_expr) = var_decl; - TREE_PUBLIC (var_decl) = 0; - - m_parent.m_cf->add_arg_variable (brigVar, var_decl); - } - else - { - /* Must be an incoming function argument which has - been parsed in brig-function-handler.cc. No - need to generate anything here. */ - } - } - else - gcc_unreachable (); - - return base->byteCount; -} - -/* Returns the alignment for the given BRIG variable. In case the variable - explicitly defines alignment and its larger than the natural alignment, - returns it instead of the natural one. */ - -size_t -brig_directive_variable_handler::get_brig_var_alignment -(const BrigDirectiveVariable *brigVar) -{ - - size_t defined_alignment - = brigVar->align == BRIG_ALIGNMENT_NONE ? 0 : 1 << (brigVar->align - 1); - size_t natural_alignment; - if (brigVar->type & BRIG_TYPE_ARRAY) - { - tree element_type - = gccbrig_tree_type_for_hsa_type (brigVar->type & ~BRIG_TYPE_ARRAY); - size_t element_size = tree_to_uhwi (TYPE_SIZE (element_type)); - natural_alignment = element_size / BITS_PER_UNIT; - } - else - { - tree t = gccbrig_tree_type_for_hsa_type (brigVar->type); - natural_alignment = tree_to_uhwi (TYPE_SIZE (t)) / BITS_PER_UNIT; - } - - return natural_alignment > defined_alignment - ? natural_alignment : defined_alignment; -} diff --git a/gcc/brig/brigfrontend/hsa-brig-format.h b/gcc/brig/brigfrontend/hsa-brig-format.h deleted file mode 100644 index ee72ea83c43..00000000000 --- a/gcc/brig/brigfrontend/hsa-brig-format.h +++ /dev/null @@ -1,1234 +0,0 @@ -/* HSA BRIG (binary representation of HSAIL) 1.0.1 representation description. - Copyright (C) 2016-2021 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. - -GCC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. - -The contents of the file was created by extracting data structures, enum, -typedef and other definitions from HSA Programmer's Reference Manual Version -1.0.1 (http://www.hsafoundation.com/standards/). - -HTML version is provided on the following link: -http://www.hsafoundation.com/html/Content/PRM/Topics/PRM_title_page.htm */ - -#ifndef HSA_BRIG_FORMAT_H -#define HSA_BRIG_FORMAT_H - -struct BrigModuleHeader; -typedef uint16_t BrigKind16_t; -typedef uint32_t BrigVersion32_t; - -typedef BrigModuleHeader *BrigModule_t; -typedef uint32_t BrigDataOffset32_t; -typedef uint32_t BrigCodeOffset32_t; -typedef uint32_t BrigOperandOffset32_t; -typedef BrigDataOffset32_t BrigDataOffsetString32_t; -typedef BrigDataOffset32_t BrigDataOffsetCodeList32_t; -typedef BrigDataOffset32_t BrigDataOffsetOperandList32_t; -typedef uint8_t BrigAlignment8_t; - -enum BrigAlignment -{ - BRIG_ALIGNMENT_NONE = 0, - BRIG_ALIGNMENT_1 = 1, - BRIG_ALIGNMENT_2 = 2, - BRIG_ALIGNMENT_4 = 3, - BRIG_ALIGNMENT_8 = 4, - BRIG_ALIGNMENT_16 = 5, - BRIG_ALIGNMENT_32 = 6, - BRIG_ALIGNMENT_64 = 7, - BRIG_ALIGNMENT_128 = 8, - BRIG_ALIGNMENT_256 = 9 -}; - -typedef uint8_t BrigAllocation8_t; - -enum BrigAllocation -{ - BRIG_ALLOCATION_NONE = 0, - BRIG_ALLOCATION_PROGRAM = 1, - BRIG_ALLOCATION_AGENT = 2, - BRIG_ALLOCATION_AUTOMATIC = 3 -}; - -typedef uint8_t BrigAluModifier8_t; - -enum BrigAluModifierMask -{ - BRIG_ALU_FTZ = 1 -}; - -typedef uint8_t BrigAtomicOperation8_t; - -enum BrigAtomicOperation -{ - BRIG_ATOMIC_ADD = 0, - BRIG_ATOMIC_AND = 1, - BRIG_ATOMIC_CAS = 2, - BRIG_ATOMIC_EXCH = 3, - BRIG_ATOMIC_LD = 4, - BRIG_ATOMIC_MAX = 5, - BRIG_ATOMIC_MIN = 6, - BRIG_ATOMIC_OR = 7, - BRIG_ATOMIC_ST = 8, - BRIG_ATOMIC_SUB = 9, - BRIG_ATOMIC_WRAPDEC = 10, - BRIG_ATOMIC_WRAPINC = 11, - BRIG_ATOMIC_XOR = 12, - BRIG_ATOMIC_WAIT_EQ = 13, - BRIG_ATOMIC_WAIT_NE = 14, - BRIG_ATOMIC_WAIT_LT = 15, - BRIG_ATOMIC_WAIT_GTE = 16, - BRIG_ATOMIC_WAITTIMEOUT_EQ = 17, - BRIG_ATOMIC_WAITTIMEOUT_NE = 18, - BRIG_ATOMIC_WAITTIMEOUT_LT = 19, - BRIG_ATOMIC_WAITTIMEOUT_GTE = 20 -}; - -struct BrigBase -{ - uint16_t byteCount; - BrigKind16_t kind; -}; - -typedef uint8_t BrigCompareOperation8_t; - -enum BrigCompareOperation -{ - BRIG_COMPARE_EQ = 0, - BRIG_COMPARE_NE = 1, - BRIG_COMPARE_LT = 2, - BRIG_COMPARE_LE = 3, - BRIG_COMPARE_GT = 4, - BRIG_COMPARE_GE = 5, - BRIG_COMPARE_EQU = 6, - BRIG_COMPARE_NEU = 7, - BRIG_COMPARE_LTU = 8, - BRIG_COMPARE_LEU = 9, - BRIG_COMPARE_GTU = 10, - BRIG_COMPARE_GEU = 11, - BRIG_COMPARE_NUM = 12, - BRIG_COMPARE_NAN = 13, - BRIG_COMPARE_SEQ = 14, - BRIG_COMPARE_SNE = 15, - BRIG_COMPARE_SLT = 16, - BRIG_COMPARE_SLE = 17, - BRIG_COMPARE_SGT = 18, - BRIG_COMPARE_SGE = 19, - BRIG_COMPARE_SGEU = 20, - BRIG_COMPARE_SEQU = 21, - BRIG_COMPARE_SNEU = 22, - BRIG_COMPARE_SLTU = 23, - BRIG_COMPARE_SLEU = 24, - BRIG_COMPARE_SNUM = 25, - BRIG_COMPARE_SNAN = 26, - BRIG_COMPARE_SGTU = 27 -}; - -typedef uint16_t BrigControlDirective16_t; - -enum BrigControlDirective -{ - BRIG_CONTROL_NONE = 0, - BRIG_CONTROL_ENABLEBREAKEXCEPTIONS = 1, - BRIG_CONTROL_ENABLEDETECTEXCEPTIONS = 2, - BRIG_CONTROL_MAXDYNAMICGROUPSIZE = 3, - BRIG_CONTROL_MAXFLATGRIDSIZE = 4, - BRIG_CONTROL_MAXFLATWORKGROUPSIZE = 5, - BRIG_CONTROL_REQUIREDDIM = 6, - BRIG_CONTROL_REQUIREDGRIDSIZE = 7, - BRIG_CONTROL_REQUIREDWORKGROUPSIZE = 8, - BRIG_CONTROL_REQUIRENOPARTIALWORKGROUPS = 9 -}; - -typedef uint32_t BrigExceptions32_t; - -enum BrigExceptionsMask -{ - BRIG_EXCEPTIONS_INVALID_OPERATION = 1 << 0, - BRIG_EXCEPTIONS_DIVIDE_BY_ZERO = 1 << 1, - BRIG_EXCEPTIONS_OVERFLOW = 1 << 2, - BRIG_EXCEPTIONS_UNDERFLOW = 1 << 3, - BRIG_EXCEPTIONS_INEXACT = 1 << 4, - BRIG_EXCEPTIONS_FIRST_USER_DEFINED = 1 << 16 -}; - -typedef uint8_t BrigExecutableModifier8_t; - -enum BrigExecutableModifierMask -{ - BRIG_EXECUTABLE_DEFINITION = 1 -}; - -typedef uint8_t BrigImageChannelOrder8_t; - -enum BrigImageChannelOrder -{ - BRIG_CHANNEL_ORDER_A = 0, - BRIG_CHANNEL_ORDER_R = 1, - BRIG_CHANNEL_ORDER_RX = 2, - BRIG_CHANNEL_ORDER_RG = 3, - BRIG_CHANNEL_ORDER_RGX = 4, - BRIG_CHANNEL_ORDER_RA = 5, - BRIG_CHANNEL_ORDER_RGB = 6, - BRIG_CHANNEL_ORDER_RGBX = 7, - BRIG_CHANNEL_ORDER_RGBA = 8, - BRIG_CHANNEL_ORDER_BGRA = 9, - BRIG_CHANNEL_ORDER_ARGB = 10, - BRIG_CHANNEL_ORDER_ABGR = 11, - BRIG_CHANNEL_ORDER_SRGB = 12, - BRIG_CHANNEL_ORDER_SRGBX = 13, - BRIG_CHANNEL_ORDER_SRGBA = 14, - BRIG_CHANNEL_ORDER_SBGRA = 15, - BRIG_CHANNEL_ORDER_INTENSITY = 16, - BRIG_CHANNEL_ORDER_LUMINANCE = 17, - BRIG_CHANNEL_ORDER_DEPTH = 18, - BRIG_CHANNEL_ORDER_DEPTH_STENCIL = 19, - BRIG_CHANNEL_ORDER_FIRST_USER_DEFINED = 128 -}; - -typedef uint8_t BrigImageChannelType8_t; - -enum BrigImageChannelType -{ - BRIG_CHANNEL_TYPE_SNORM_INT8 = 0, - BRIG_CHANNEL_TYPE_SNORM_INT16 = 1, - BRIG_CHANNEL_TYPE_UNORM_INT8 = 2, - BRIG_CHANNEL_TYPE_UNORM_INT16 = 3, - BRIG_CHANNEL_TYPE_UNORM_INT24 = 4, - BRIG_CHANNEL_TYPE_UNORM_SHORT_555 = 5, - BRIG_CHANNEL_TYPE_UNORM_SHORT_565 = 6, - BRIG_CHANNEL_TYPE_UNORM_INT_101010 = 7, - BRIG_CHANNEL_TYPE_SIGNED_INT8 = 8, - BRIG_CHANNEL_TYPE_SIGNED_INT16 = 9, - BRIG_CHANNEL_TYPE_SIGNED_INT32 = 10, - BRIG_CHANNEL_TYPE_UNSIGNED_INT8 = 11, - BRIG_CHANNEL_TYPE_UNSIGNED_INT16 = 12, - BRIG_CHANNEL_TYPE_UNSIGNED_INT32 = 13, - BRIG_CHANNEL_TYPE_HALF_FLOAT = 14, - BRIG_CHANNEL_TYPE_FLOAT = 15, - BRIG_CHANNEL_TYPE_FIRST_USER_DEFINED = 128 -}; - -typedef uint8_t BrigImageGeometry8_t; - -enum BrigImageGeometry -{ - BRIG_GEOMETRY_1D = 0, - BRIG_GEOMETRY_2D = 1, - BRIG_GEOMETRY_3D = 2, - BRIG_GEOMETRY_1DA = 3, - BRIG_GEOMETRY_2DA = 4, - BRIG_GEOMETRY_1DB = 5, - BRIG_GEOMETRY_2DDEPTH = 6, - BRIG_GEOMETRY_2DADEPTH = 7, - BRIG_GEOMETRY_FIRST_USER_DEFINED = 128 -}; - -typedef uint8_t BrigImageQuery8_t; - -enum BrigImageQuery -{ - BRIG_IMAGE_QUERY_WIDTH = 0, - BRIG_IMAGE_QUERY_HEIGHT = 1, - BRIG_IMAGE_QUERY_DEPTH = 2, - BRIG_IMAGE_QUERY_ARRAY = 3, - BRIG_IMAGE_QUERY_CHANNELORDER = 4, - BRIG_IMAGE_QUERY_CHANNELTYPE = 5 -}; - -enum BrigKind -{ - BRIG_KIND_NONE = 0x0000, - BRIG_KIND_DIRECTIVE_BEGIN = 0x1000, - BRIG_KIND_DIRECTIVE_ARG_BLOCK_END = 0x1000, - BRIG_KIND_DIRECTIVE_ARG_BLOCK_START = 0x1001, - BRIG_KIND_DIRECTIVE_COMMENT = 0x1002, - BRIG_KIND_DIRECTIVE_CONTROL = 0x1003, - BRIG_KIND_DIRECTIVE_EXTENSION = 0x1004, - BRIG_KIND_DIRECTIVE_FBARRIER = 0x1005, - BRIG_KIND_DIRECTIVE_FUNCTION = 0x1006, - BRIG_KIND_DIRECTIVE_INDIRECT_FUNCTION = 0x1007, - BRIG_KIND_DIRECTIVE_KERNEL = 0x1008, - BRIG_KIND_DIRECTIVE_LABEL = 0x1009, - BRIG_KIND_DIRECTIVE_LOC = 0x100a, - BRIG_KIND_DIRECTIVE_MODULE = 0x100b, - BRIG_KIND_DIRECTIVE_PRAGMA = 0x100c, - BRIG_KIND_DIRECTIVE_SIGNATURE = 0x100d, - BRIG_KIND_DIRECTIVE_VARIABLE = 0x100e, - BRIG_KIND_DIRECTIVE_END = 0x100f, - BRIG_KIND_INST_BEGIN = 0x2000, - BRIG_KIND_INST_ADDR = 0x2000, - BRIG_KIND_INST_ATOMIC = 0x2001, - BRIG_KIND_INST_BASIC = 0x2002, - BRIG_KIND_INST_BR = 0x2003, - BRIG_KIND_INST_CMP = 0x2004, - BRIG_KIND_INST_CVT = 0x2005, - BRIG_KIND_INST_IMAGE = 0x2006, - BRIG_KIND_INST_LANE = 0x2007, - BRIG_KIND_INST_MEM = 0x2008, - BRIG_KIND_INST_MEM_FENCE = 0x2009, - BRIG_KIND_INST_MOD = 0x200a, - BRIG_KIND_INST_QUERY_IMAGE = 0x200b, - BRIG_KIND_INST_QUERY_SAMPLER = 0x200c, - BRIG_KIND_INST_QUEUE = 0x200d, - BRIG_KIND_INST_SEG = 0x200e, - BRIG_KIND_INST_SEG_CVT = 0x200f, - BRIG_KIND_INST_SIGNAL = 0x2010, - BRIG_KIND_INST_SOURCE_TYPE = 0x2011, - BRIG_KIND_INST_END = 0x2012, - BRIG_KIND_OPERAND_BEGIN = 0x3000, - BRIG_KIND_OPERAND_ADDRESS = 0x3000, - BRIG_KIND_OPERAND_ALIGN = 0x3001, - BRIG_KIND_OPERAND_CODE_LIST = 0x3002, - BRIG_KIND_OPERAND_CODE_REF = 0x3003, - BRIG_KIND_OPERAND_CONSTANT_BYTES = 0x3004, - BRIG_KIND_OPERAND_RESERVED = 0x3005, - BRIG_KIND_OPERAND_CONSTANT_IMAGE = 0x3006, - BRIG_KIND_OPERAND_CONSTANT_OPERAND_LIST = 0x3007, - BRIG_KIND_OPERAND_CONSTANT_SAMPLER = 0x3008, - BRIG_KIND_OPERAND_OPERAND_LIST = 0x3009, - BRIG_KIND_OPERAND_REGISTER = 0x300a, - BRIG_KIND_OPERAND_STRING = 0x300b, - BRIG_KIND_OPERAND_WAVESIZE = 0x300c, - BRIG_KIND_OPERAND_END = 0x300d -}; - -typedef uint8_t BrigLinkage8_t; - -enum BrigLinkage -{ - BRIG_LINKAGE_NONE = 0, - BRIG_LINKAGE_PROGRAM = 1, - BRIG_LINKAGE_MODULE = 2, - BRIG_LINKAGE_FUNCTION = 3, - BRIG_LINKAGE_ARG = 4 -}; - -typedef uint8_t BrigMachineModel8_t; - -enum BrigMachineModel -{ - BRIG_MACHINE_SMALL = 0, - BRIG_MACHINE_LARGE = 1 -}; - -typedef uint8_t BrigMemoryModifier8_t; - -enum BrigMemoryModifierMask -{ - BRIG_MEMORY_CONST = 1 -}; - -typedef uint8_t BrigMemoryOrder8_t; - -enum BrigMemoryOrder -{ - BRIG_MEMORY_ORDER_NONE = 0, - BRIG_MEMORY_ORDER_RELAXED = 1, - BRIG_MEMORY_ORDER_SC_ACQUIRE = 2, - BRIG_MEMORY_ORDER_SC_RELEASE = 3, - BRIG_MEMORY_ORDER_SC_ACQUIRE_RELEASE = 4 -}; - -typedef uint8_t BrigMemoryScope8_t; - -enum BrigMemoryScope -{ - BRIG_MEMORY_SCOPE_NONE = 0, - BRIG_MEMORY_SCOPE_WORKITEM = 1, - BRIG_MEMORY_SCOPE_WAVEFRONT = 2, - BRIG_MEMORY_SCOPE_WORKGROUP = 3, - BRIG_MEMORY_SCOPE_AGENT = 4, - BRIG_MEMORY_SCOPE_SYSTEM = 5 -}; - -struct BrigModuleHeader -{ - char identification[8]; - BrigVersion32_t brigMajor; - BrigVersion32_t brigMinor; - uint64_t byteCount; - uint8_t hash[64]; - uint32_t reserved; - uint32_t sectionCount; - uint64_t sectionIndex; -}; - -typedef uint16_t BrigOpcode16_t; - -enum BrigOpcode -{ - BRIG_OPCODE_NOP = 0, - BRIG_OPCODE_ABS = 1, - BRIG_OPCODE_ADD = 2, - BRIG_OPCODE_BORROW = 3, - BRIG_OPCODE_CARRY = 4, - BRIG_OPCODE_CEIL = 5, - BRIG_OPCODE_COPYSIGN = 6, - BRIG_OPCODE_DIV = 7, - BRIG_OPCODE_FLOOR = 8, - BRIG_OPCODE_FMA = 9, - BRIG_OPCODE_FRACT = 10, - BRIG_OPCODE_MAD = 11, - BRIG_OPCODE_MAX = 12, - BRIG_OPCODE_MIN = 13, - BRIG_OPCODE_MUL = 14, - BRIG_OPCODE_MULHI = 15, - BRIG_OPCODE_NEG = 16, - BRIG_OPCODE_REM = 17, - BRIG_OPCODE_RINT = 18, - BRIG_OPCODE_SQRT = 19, - BRIG_OPCODE_SUB = 20, - BRIG_OPCODE_TRUNC = 21, - BRIG_OPCODE_MAD24 = 22, - BRIG_OPCODE_MAD24HI = 23, - BRIG_OPCODE_MUL24 = 24, - BRIG_OPCODE_MUL24HI = 25, - BRIG_OPCODE_SHL = 26, - BRIG_OPCODE_SHR = 27, - BRIG_OPCODE_AND = 28, - BRIG_OPCODE_NOT = 29, - BRIG_OPCODE_OR = 30, - BRIG_OPCODE_POPCOUNT = 31, - BRIG_OPCODE_XOR = 32, - BRIG_OPCODE_BITEXTRACT = 33, - BRIG_OPCODE_BITINSERT = 34, - BRIG_OPCODE_BITMASK = 35, - BRIG_OPCODE_BITREV = 36, - BRIG_OPCODE_BITSELECT = 37, - BRIG_OPCODE_FIRSTBIT = 38, - BRIG_OPCODE_LASTBIT = 39, - BRIG_OPCODE_COMBINE = 40, - BRIG_OPCODE_EXPAND = 41, - BRIG_OPCODE_LDA = 42, - BRIG_OPCODE_MOV = 43, - BRIG_OPCODE_SHUFFLE = 44, - BRIG_OPCODE_UNPACKHI = 45, - BRIG_OPCODE_UNPACKLO = 46, - BRIG_OPCODE_PACK = 47, - BRIG_OPCODE_UNPACK = 48, - BRIG_OPCODE_CMOV = 49, - BRIG_OPCODE_CLASS = 50, - BRIG_OPCODE_NCOS = 51, - BRIG_OPCODE_NEXP2 = 52, - BRIG_OPCODE_NFMA = 53, - BRIG_OPCODE_NLOG2 = 54, - BRIG_OPCODE_NRCP = 55, - BRIG_OPCODE_NRSQRT = 56, - BRIG_OPCODE_NSIN = 57, - BRIG_OPCODE_NSQRT = 58, - BRIG_OPCODE_BITALIGN = 59, - BRIG_OPCODE_BYTEALIGN = 60, - BRIG_OPCODE_PACKCVT = 61, - BRIG_OPCODE_UNPACKCVT = 62, - BRIG_OPCODE_LERP = 63, - BRIG_OPCODE_SAD = 64, - BRIG_OPCODE_SADHI = 65, - BRIG_OPCODE_SEGMENTP = 66, - BRIG_OPCODE_FTOS = 67, - BRIG_OPCODE_STOF = 68, - BRIG_OPCODE_CMP = 69, - BRIG_OPCODE_CVT = 70, - BRIG_OPCODE_LD = 71, - BRIG_OPCODE_ST = 72, - BRIG_OPCODE_ATOMIC = 73, - BRIG_OPCODE_ATOMICNORET = 74, - BRIG_OPCODE_SIGNAL = 75, - BRIG_OPCODE_SIGNALNORET = 76, - BRIG_OPCODE_MEMFENCE = 77, - BRIG_OPCODE_RDIMAGE = 78, - BRIG_OPCODE_LDIMAGE = 79, - BRIG_OPCODE_STIMAGE = 80, - BRIG_OPCODE_IMAGEFENCE = 81, - BRIG_OPCODE_QUERYIMAGE = 82, - BRIG_OPCODE_QUERYSAMPLER = 83, - BRIG_OPCODE_CBR = 84, - BRIG_OPCODE_BR = 85, - BRIG_OPCODE_SBR = 86, - BRIG_OPCODE_BARRIER = 87, - BRIG_OPCODE_WAVEBARRIER = 88, - BRIG_OPCODE_ARRIVEFBAR = 89, - BRIG_OPCODE_INITFBAR = 90, - BRIG_OPCODE_JOINFBAR = 91, - BRIG_OPCODE_LEAVEFBAR = 92, - BRIG_OPCODE_RELEASEFBAR = 93, - BRIG_OPCODE_WAITFBAR = 94, - BRIG_OPCODE_LDF = 95, - BRIG_OPCODE_ACTIVELANECOUNT = 96, - BRIG_OPCODE_ACTIVELANEID = 97, - BRIG_OPCODE_ACTIVELANEMASK = 98, - BRIG_OPCODE_ACTIVELANEPERMUTE = 99, - BRIG_OPCODE_CALL = 100, - BRIG_OPCODE_SCALL = 101, - BRIG_OPCODE_ICALL = 102, - BRIG_OPCODE_RET = 103, - BRIG_OPCODE_ALLOCA = 104, - BRIG_OPCODE_CURRENTWORKGROUPSIZE = 105, - BRIG_OPCODE_CURRENTWORKITEMFLATID = 106, - BRIG_OPCODE_DIM = 107, - BRIG_OPCODE_GRIDGROUPS = 108, - BRIG_OPCODE_GRIDSIZE = 109, - BRIG_OPCODE_PACKETCOMPLETIONSIG = 110, - BRIG_OPCODE_PACKETID = 111, - BRIG_OPCODE_WORKGROUPID = 112, - BRIG_OPCODE_WORKGROUPSIZE = 113, - BRIG_OPCODE_WORKITEMABSID = 114, - BRIG_OPCODE_WORKITEMFLATABSID = 115, - BRIG_OPCODE_WORKITEMFLATID = 116, - BRIG_OPCODE_WORKITEMID = 117, - BRIG_OPCODE_CLEARDETECTEXCEPT = 118, - BRIG_OPCODE_GETDETECTEXCEPT = 119, - BRIG_OPCODE_SETDETECTEXCEPT = 120, - BRIG_OPCODE_ADDQUEUEWRITEINDEX = 121, - BRIG_OPCODE_CASQUEUEWRITEINDEX = 122, - BRIG_OPCODE_LDQUEUEREADINDEX = 123, - BRIG_OPCODE_LDQUEUEWRITEINDEX = 124, - BRIG_OPCODE_STQUEUEREADINDEX = 125, - BRIG_OPCODE_STQUEUEWRITEINDEX = 126, - BRIG_OPCODE_CLOCK = 127, - BRIG_OPCODE_CUID = 128, - BRIG_OPCODE_DEBUGTRAP = 129, - BRIG_OPCODE_GROUPBASEPTR = 130, - BRIG_OPCODE_KERNARGBASEPTR = 131, - BRIG_OPCODE_LANEID = 132, - BRIG_OPCODE_MAXCUID = 133, - BRIG_OPCODE_MAXWAVEID = 134, - BRIG_OPCODE_NULLPTR = 135, - BRIG_OPCODE_WAVEID = 136, - BRIG_OPCODE_FIRST_USER_DEFINED = 32768 -}; - -typedef uint8_t BrigPack8_t; - -enum BrigPack -{ - BRIG_PACK_NONE = 0, - BRIG_PACK_PP = 1, - BRIG_PACK_PS = 2, - BRIG_PACK_SP = 3, - BRIG_PACK_SS = 4, - BRIG_PACK_S = 5, - BRIG_PACK_P = 6, - BRIG_PACK_PPSAT = 7, - BRIG_PACK_PSSAT = 8, - BRIG_PACK_SPSAT = 9, - BRIG_PACK_SSSAT = 10, - BRIG_PACK_SSAT = 11, - BRIG_PACK_PSAT = 12 -}; - -typedef uint8_t BrigProfile8_t; - -enum BrigProfile -{ - BRIG_PROFILE_BASE = 0, - BRIG_PROFILE_FULL = 1 -}; - -typedef uint16_t BrigRegisterKind16_t; - -enum BrigRegisterKind -{ - BRIG_REGISTER_KIND_CONTROL = 0, - BRIG_REGISTER_KIND_SINGLE = 1, - BRIG_REGISTER_KIND_DOUBLE = 2, - BRIG_REGISTER_KIND_QUAD = 3 -}; - -typedef uint8_t BrigRound8_t; - -enum BrigRound -{ - BRIG_ROUND_NONE = 0, - BRIG_ROUND_FLOAT_DEFAULT = 1, - BRIG_ROUND_FLOAT_NEAR_EVEN = 2, - BRIG_ROUND_FLOAT_ZERO = 3, - BRIG_ROUND_FLOAT_PLUS_INFINITY = 4, - BRIG_ROUND_FLOAT_MINUS_INFINITY = 5, - BRIG_ROUND_INTEGER_NEAR_EVEN = 6, - BRIG_ROUND_INTEGER_ZERO = 7, - BRIG_ROUND_INTEGER_PLUS_INFINITY = 8, - BRIG_ROUND_INTEGER_MINUS_INFINITY = 9, - BRIG_ROUND_INTEGER_NEAR_EVEN_SAT = 10, - BRIG_ROUND_INTEGER_ZERO_SAT = 11, - BRIG_ROUND_INTEGER_PLUS_INFINITY_SAT = 12, - BRIG_ROUND_INTEGER_MINUS_INFINITY_SAT = 13, - BRIG_ROUND_INTEGER_SIGNALING_NEAR_EVEN = 14, - BRIG_ROUND_INTEGER_SIGNALING_ZERO = 15, - BRIG_ROUND_INTEGER_SIGNALING_PLUS_INFINITY = 16, - BRIG_ROUND_INTEGER_SIGNALING_MINUS_INFINITY = 17, - BRIG_ROUND_INTEGER_SIGNALING_NEAR_EVEN_SAT = 18, - BRIG_ROUND_INTEGER_SIGNALING_ZERO_SAT = 19, - BRIG_ROUND_INTEGER_SIGNALING_PLUS_INFINITY_SAT = 20, - BRIG_ROUND_INTEGER_SIGNALING_MINUS_INFINITY_SAT = 21 -}; - -typedef uint8_t BrigSamplerAddressing8_t; - -enum BrigSamplerAddressing -{ - BRIG_ADDRESSING_UNDEFINED = 0, - BRIG_ADDRESSING_CLAMP_TO_EDGE = 1, - BRIG_ADDRESSING_CLAMP_TO_BORDER = 2, - BRIG_ADDRESSING_REPEAT = 3, - BRIG_ADDRESSING_MIRRORED_REPEAT = 4, - BRIG_ADDRESSING_FIRST_USER_DEFINED = 128 -}; - -typedef uint8_t BrigSamplerCoordNormalization8_t; - -enum BrigSamplerCoordNormalization -{ - BRIG_COORD_UNNORMALIZED = 0, - BRIG_COORD_NORMALIZED = 1 -}; - -typedef uint8_t BrigSamplerFilter8_t; - -enum BrigSamplerFilter -{ - BRIG_FILTER_NEAREST = 0, - BRIG_FILTER_LINEAR = 1, - BRIG_FILTER_FIRST_USER_DEFINED = 128 -}; - -typedef uint8_t BrigSamplerQuery8_t; - -enum BrigSamplerQuery -{ - BRIG_SAMPLER_QUERY_ADDRESSING = 0, - BRIG_SAMPLER_QUERY_COORD = 1, - BRIG_SAMPLER_QUERY_FILTER = 2 -}; - -typedef uint32_t BrigSectionIndex32_t; - -enum BrigSectionIndex -{ - BRIG_SECTION_INDEX_DATA = 0, - BRIG_SECTION_INDEX_CODE = 1, - BRIG_SECTION_INDEX_OPERAND = 2, - BRIG_SECTION_INDEX_BEGIN_IMPLEMENTATION_DEFINED = 3 -}; - -struct BrigSectionHeader -{ - uint64_t byteCount; - uint32_t headerByteCount; - uint32_t nameLength; - uint8_t name[1]; -}; - -typedef uint8_t BrigSegCvtModifier8_t; - -enum BrigSegCvtModifierMask -{ - BRIG_SEG_CVT_NONULL = 1 -}; - -typedef uint8_t BrigSegment8_t; - -enum BrigSegment -{ - BRIG_SEGMENT_NONE = 0, - BRIG_SEGMENT_FLAT = 1, - BRIG_SEGMENT_GLOBAL = 2, - BRIG_SEGMENT_READONLY = 3, - BRIG_SEGMENT_KERNARG = 4, - BRIG_SEGMENT_GROUP = 5, - BRIG_SEGMENT_PRIVATE = 6, - BRIG_SEGMENT_SPILL = 7, - BRIG_SEGMENT_ARG = 8, - BRIG_SEGMENT_FIRST_USER_DEFINED = 128 -}; - -enum -{ - BRIG_TYPE_BASE_SIZE = 5, - BRIG_TYPE_PACK_SIZE = 2, - BRIG_TYPE_ARRAY_SIZE = 1, - - BRIG_TYPE_BASE_SHIFT = 0, - BRIG_TYPE_PACK_SHIFT = BRIG_TYPE_BASE_SHIFT + BRIG_TYPE_BASE_SIZE, - BRIG_TYPE_ARRAY_SHIFT = BRIG_TYPE_PACK_SHIFT + BRIG_TYPE_PACK_SIZE, - - BRIG_TYPE_BASE_MASK = ((1 << BRIG_TYPE_BASE_SIZE) - 1) - << BRIG_TYPE_BASE_SHIFT, - BRIG_TYPE_PACK_MASK = ((1 << BRIG_TYPE_PACK_SIZE) - 1) - << BRIG_TYPE_PACK_SHIFT, - BRIG_TYPE_ARRAY_MASK = ((1 << BRIG_TYPE_ARRAY_SIZE) - 1) - << BRIG_TYPE_ARRAY_SHIFT, - - BRIG_TYPE_PACK_NONE = 0 << BRIG_TYPE_PACK_SHIFT, - BRIG_TYPE_PACK_32 = 1 << BRIG_TYPE_PACK_SHIFT, - BRIG_TYPE_PACK_64 = 2 << BRIG_TYPE_PACK_SHIFT, - BRIG_TYPE_PACK_128 = 3 << BRIG_TYPE_PACK_SHIFT, - - BRIG_TYPE_ARRAY = 1 << BRIG_TYPE_ARRAY_SHIFT -}; - -typedef uint16_t BrigType16_t; - -enum BrigType -{ - BRIG_TYPE_NONE = 0, - - BRIG_TYPE_U8 = 1, - BRIG_TYPE_U16 = 2, - BRIG_TYPE_U32 = 3, - BRIG_TYPE_U64 = 4, - - BRIG_TYPE_S8 = 5, - BRIG_TYPE_S16 = 6, - BRIG_TYPE_S32 = 7, - BRIG_TYPE_S64 = 8, - - BRIG_TYPE_F16 = 9, - BRIG_TYPE_F32 = 10, - BRIG_TYPE_F64 = 11, - - BRIG_TYPE_B1 = 12, - BRIG_TYPE_B8 = 13, - BRIG_TYPE_B16 = 14, - BRIG_TYPE_B32 = 15, - BRIG_TYPE_B64 = 16, - BRIG_TYPE_B128 = 17, - - BRIG_TYPE_SAMP = 18, - BRIG_TYPE_ROIMG = 19, - BRIG_TYPE_WOIMG = 20, - BRIG_TYPE_RWIMG = 21, - - BRIG_TYPE_SIG32 = 22, - BRIG_TYPE_SIG64 = 23, - - BRIG_TYPE_U8X4 = BRIG_TYPE_U8 | BRIG_TYPE_PACK_32, - BRIG_TYPE_U8X8 = BRIG_TYPE_U8 | BRIG_TYPE_PACK_64, - BRIG_TYPE_U8X16 = BRIG_TYPE_U8 | BRIG_TYPE_PACK_128, - - BRIG_TYPE_U16X2 = BRIG_TYPE_U16 | BRIG_TYPE_PACK_32, - BRIG_TYPE_U16X4 = BRIG_TYPE_U16 | BRIG_TYPE_PACK_64, - BRIG_TYPE_U16X8 = BRIG_TYPE_U16 | BRIG_TYPE_PACK_128, - - BRIG_TYPE_U32X2 = BRIG_TYPE_U32 | BRIG_TYPE_PACK_64, - BRIG_TYPE_U32X4 = BRIG_TYPE_U32 | BRIG_TYPE_PACK_128, - - BRIG_TYPE_U64X2 = BRIG_TYPE_U64 | BRIG_TYPE_PACK_128, - - BRIG_TYPE_S8X4 = BRIG_TYPE_S8 | BRIG_TYPE_PACK_32, - BRIG_TYPE_S8X8 = BRIG_TYPE_S8 | BRIG_TYPE_PACK_64, - BRIG_TYPE_S8X16 = BRIG_TYPE_S8 | BRIG_TYPE_PACK_128, - - BRIG_TYPE_S16X2 = BRIG_TYPE_S16 | BRIG_TYPE_PACK_32, - BRIG_TYPE_S16X4 = BRIG_TYPE_S16 | BRIG_TYPE_PACK_64, - BRIG_TYPE_S16X8 = BRIG_TYPE_S16 | BRIG_TYPE_PACK_128, - - BRIG_TYPE_S32X2 = BRIG_TYPE_S32 | BRIG_TYPE_PACK_64, - BRIG_TYPE_S32X4 = BRIG_TYPE_S32 | BRIG_TYPE_PACK_128, - - BRIG_TYPE_S64X2 = BRIG_TYPE_S64 | BRIG_TYPE_PACK_128, - - BRIG_TYPE_F16X2 = BRIG_TYPE_F16 | BRIG_TYPE_PACK_32, - BRIG_TYPE_F16X4 = BRIG_TYPE_F16 | BRIG_TYPE_PACK_64, - BRIG_TYPE_F16X8 = BRIG_TYPE_F16 | BRIG_TYPE_PACK_128, - - BRIG_TYPE_F32X2 = BRIG_TYPE_F32 | BRIG_TYPE_PACK_64, - BRIG_TYPE_F32X4 = BRIG_TYPE_F32 | BRIG_TYPE_PACK_128, - - BRIG_TYPE_F64X2 = BRIG_TYPE_F64 | BRIG_TYPE_PACK_128, - - BRIG_TYPE_U8_ARRAY = BRIG_TYPE_U8 | BRIG_TYPE_ARRAY, - BRIG_TYPE_U16_ARRAY = BRIG_TYPE_U16 | BRIG_TYPE_ARRAY, - BRIG_TYPE_U32_ARRAY = BRIG_TYPE_U32 | BRIG_TYPE_ARRAY, - BRIG_TYPE_U64_ARRAY = BRIG_TYPE_U64 | BRIG_TYPE_ARRAY, - - BRIG_TYPE_S8_ARRAY = BRIG_TYPE_S8 | BRIG_TYPE_ARRAY, - BRIG_TYPE_S16_ARRAY = BRIG_TYPE_S16 | BRIG_TYPE_ARRAY, - BRIG_TYPE_S32_ARRAY = BRIG_TYPE_S32 | BRIG_TYPE_ARRAY, - BRIG_TYPE_S64_ARRAY = BRIG_TYPE_S64 | BRIG_TYPE_ARRAY, - - BRIG_TYPE_F16_ARRAY = BRIG_TYPE_F16 | BRIG_TYPE_ARRAY, - BRIG_TYPE_F32_ARRAY = BRIG_TYPE_F32 | BRIG_TYPE_ARRAY, - BRIG_TYPE_F64_ARRAY = BRIG_TYPE_F64 | BRIG_TYPE_ARRAY, - - BRIG_TYPE_B8_ARRAY = BRIG_TYPE_B8 | BRIG_TYPE_ARRAY, - BRIG_TYPE_B16_ARRAY = BRIG_TYPE_B16 | BRIG_TYPE_ARRAY, - BRIG_TYPE_B32_ARRAY = BRIG_TYPE_B32 | BRIG_TYPE_ARRAY, - BRIG_TYPE_B64_ARRAY = BRIG_TYPE_B64 | BRIG_TYPE_ARRAY, - BRIG_TYPE_B128_ARRAY = BRIG_TYPE_B128 | BRIG_TYPE_ARRAY, - - BRIG_TYPE_SAMP_ARRAY = BRIG_TYPE_SAMP | BRIG_TYPE_ARRAY, - BRIG_TYPE_ROIMG_ARRAY = BRIG_TYPE_ROIMG | BRIG_TYPE_ARRAY, - BRIG_TYPE_WOIMG_ARRAY = BRIG_TYPE_WOIMG | BRIG_TYPE_ARRAY, - BRIG_TYPE_RWIMG_ARRAY = BRIG_TYPE_RWIMG | BRIG_TYPE_ARRAY, - - BRIG_TYPE_SIG32_ARRAY = BRIG_TYPE_SIG32 | BRIG_TYPE_ARRAY, - BRIG_TYPE_SIG64_ARRAY = BRIG_TYPE_SIG64 | BRIG_TYPE_ARRAY, - - BRIG_TYPE_U8X4_ARRAY = BRIG_TYPE_U8X4 | BRIG_TYPE_ARRAY, - BRIG_TYPE_U8X8_ARRAY = BRIG_TYPE_U8X8 | BRIG_TYPE_ARRAY, - BRIG_TYPE_U8X16_ARRAY = BRIG_TYPE_U8X16 | BRIG_TYPE_ARRAY, - - BRIG_TYPE_U16X2_ARRAY = BRIG_TYPE_U16X2 | BRIG_TYPE_ARRAY, - BRIG_TYPE_U16X4_ARRAY = BRIG_TYPE_U16X4 | BRIG_TYPE_ARRAY, - BRIG_TYPE_U16X8_ARRAY = BRIG_TYPE_U16X8 | BRIG_TYPE_ARRAY, - - BRIG_TYPE_U32X2_ARRAY = BRIG_TYPE_U32X2 | BRIG_TYPE_ARRAY, - BRIG_TYPE_U32X4_ARRAY = BRIG_TYPE_U32X4 | BRIG_TYPE_ARRAY, - - BRIG_TYPE_U64X2_ARRAY = BRIG_TYPE_U64X2 | BRIG_TYPE_ARRAY, - - BRIG_TYPE_S8X4_ARRAY = BRIG_TYPE_S8X4 | BRIG_TYPE_ARRAY, - BRIG_TYPE_S8X8_ARRAY = BRIG_TYPE_S8X8 | BRIG_TYPE_ARRAY, - BRIG_TYPE_S8X16_ARRAY = BRIG_TYPE_S8X16 | BRIG_TYPE_ARRAY, - - BRIG_TYPE_S16X2_ARRAY = BRIG_TYPE_S16X2 | BRIG_TYPE_ARRAY, - BRIG_TYPE_S16X4_ARRAY = BRIG_TYPE_S16X4 | BRIG_TYPE_ARRAY, - BRIG_TYPE_S16X8_ARRAY = BRIG_TYPE_S16X8 | BRIG_TYPE_ARRAY, - - BRIG_TYPE_S32X2_ARRAY = BRIG_TYPE_S32X2 | BRIG_TYPE_ARRAY, - BRIG_TYPE_S32X4_ARRAY = BRIG_TYPE_S32X4 | BRIG_TYPE_ARRAY, - - BRIG_TYPE_S64X2_ARRAY = BRIG_TYPE_S64X2 | BRIG_TYPE_ARRAY, - - BRIG_TYPE_F16X2_ARRAY = BRIG_TYPE_F16X2 | BRIG_TYPE_ARRAY, - BRIG_TYPE_F16X4_ARRAY = BRIG_TYPE_F16X4 | BRIG_TYPE_ARRAY, - BRIG_TYPE_F16X8_ARRAY = BRIG_TYPE_F16X8 | BRIG_TYPE_ARRAY, - - BRIG_TYPE_F32X2_ARRAY = BRIG_TYPE_F32X2 | BRIG_TYPE_ARRAY, - BRIG_TYPE_F32X4_ARRAY = BRIG_TYPE_F32X4 | BRIG_TYPE_ARRAY, - - BRIG_TYPE_F64X2_ARRAY = BRIG_TYPE_F64X2 | BRIG_TYPE_ARRAY -}; - -struct BrigUInt64 -{ - uint32_t lo; - uint32_t hi; -}; - -typedef uint8_t BrigVariableModifier8_t; - -enum BrigVariableModifierMask -{ - BRIG_VARIABLE_DEFINITION = 1, - BRIG_VARIABLE_CONST = 2 -}; - -enum BrigVersion -{ - BRIG_VERSION_HSAIL_MAJOR = 1, - BRIG_VERSION_HSAIL_MINOR = 0, - BRIG_VERSION_BRIG_MAJOR = 1, - BRIG_VERSION_BRIG_MINOR = 0 -}; - -typedef uint8_t BrigWidth8_t; - -enum BrigWidth -{ - BRIG_WIDTH_NONE = 0, - BRIG_WIDTH_1 = 1, - BRIG_WIDTH_2 = 2, - BRIG_WIDTH_4 = 3, - BRIG_WIDTH_8 = 4, - BRIG_WIDTH_16 = 5, - BRIG_WIDTH_32 = 6, - BRIG_WIDTH_64 = 7, - BRIG_WIDTH_128 = 8, - BRIG_WIDTH_256 = 9, - BRIG_WIDTH_512 = 10, - BRIG_WIDTH_1024 = 11, - BRIG_WIDTH_2048 = 12, - BRIG_WIDTH_4096 = 13, - BRIG_WIDTH_8192 = 14, - BRIG_WIDTH_16384 = 15, - BRIG_WIDTH_32768 = 16, - BRIG_WIDTH_65536 = 17, - BRIG_WIDTH_131072 = 18, - BRIG_WIDTH_262144 = 19, - BRIG_WIDTH_524288 = 20, - BRIG_WIDTH_1048576 = 21, - BRIG_WIDTH_2097152 = 22, - BRIG_WIDTH_4194304 = 23, - BRIG_WIDTH_8388608 = 24, - BRIG_WIDTH_16777216 = 25, - BRIG_WIDTH_33554432 = 26, - BRIG_WIDTH_67108864 = 27, - BRIG_WIDTH_134217728 = 28, - BRIG_WIDTH_268435456 = 29, - BRIG_WIDTH_536870912 = 30, - BRIG_WIDTH_1073741824 = 31, - BRIG_WIDTH_2147483648 = 32, - BRIG_WIDTH_WAVESIZE = 33, - BRIG_WIDTH_ALL = 34 -}; - -struct BrigData -{ - uint32_t byteCount; - uint8_t bytes[1]; -}; - -struct BrigDirectiveArgBlock -{ - BrigBase base; -}; - -struct BrigDirectiveComment -{ - BrigBase base; - BrigDataOffsetString32_t name; -}; - -struct BrigDirectiveControl -{ - BrigBase base; - BrigControlDirective16_t control; - uint16_t reserved; - BrigDataOffsetOperandList32_t operands; -}; - -struct BrigDirectiveExecutable -{ - BrigBase base; - BrigDataOffsetString32_t name; - uint16_t outArgCount; - uint16_t inArgCount; - BrigCodeOffset32_t firstInArg; - BrigCodeOffset32_t firstCodeBlockEntry; - BrigCodeOffset32_t nextModuleEntry; - BrigExecutableModifier8_t modifier; - BrigLinkage8_t linkage; - uint16_t reserved; -}; - -struct BrigDirectiveExtension -{ - BrigBase base; - BrigDataOffsetString32_t name; -}; - -struct BrigDirectiveFbarrier -{ - BrigBase base; - BrigDataOffsetString32_t name; - BrigVariableModifier8_t modifier; - BrigLinkage8_t linkage; - uint16_t reserved; -}; - -struct BrigDirectiveLabel -{ - BrigBase base; - BrigDataOffsetString32_t name; -}; - -struct BrigDirectiveLoc -{ - BrigBase base; - BrigDataOffsetString32_t filename; - uint32_t line; - uint32_t column; -}; - -struct BrigDirectiveModule -{ - BrigBase base; - BrigDataOffsetString32_t name; - BrigVersion32_t hsailMajor; - BrigVersion32_t hsailMinor; - BrigProfile8_t profile; - BrigMachineModel8_t machineModel; - BrigRound8_t defaultFloatRound; - uint8_t reserved; -}; - -struct BrigDirectiveNone -{ - BrigBase base; -}; - -struct BrigDirectivePragma -{ - BrigBase base; - BrigDataOffsetOperandList32_t operands; -}; - -struct BrigDirectiveVariable -{ - BrigBase base; - BrigDataOffsetString32_t name; - BrigOperandOffset32_t init; - BrigType16_t type; - BrigSegment8_t segment; - BrigAlignment8_t align; - BrigUInt64 dim; - BrigVariableModifier8_t modifier; - BrigLinkage8_t linkage; - BrigAllocation8_t allocation; - uint8_t reserved; -}; - -struct BrigInstBase -{ - BrigBase base; - BrigOpcode16_t opcode; - BrigType16_t type; - BrigDataOffsetOperandList32_t operands; -}; - -struct BrigInstAddr -{ - BrigInstBase base; - BrigSegment8_t segment; - uint8_t reserved[3]; -}; - -struct BrigInstAtomic -{ - BrigInstBase base; - BrigSegment8_t segment; - BrigMemoryOrder8_t memoryOrder; - BrigMemoryScope8_t memoryScope; - BrigAtomicOperation8_t atomicOperation; - uint8_t equivClass; - uint8_t reserved[3]; -}; - -struct BrigInstBasic -{ - BrigInstBase base; -}; - -struct BrigInstBr -{ - BrigInstBase base; - BrigWidth8_t width; - uint8_t reserved[3]; -}; - -struct BrigInstCmp -{ - BrigInstBase base; - BrigType16_t sourceType; - BrigAluModifier8_t modifier; - BrigCompareOperation8_t compare; - BrigPack8_t pack; - uint8_t reserved[3]; -}; - -struct BrigInstCvt -{ - BrigInstBase base; - BrigType16_t sourceType; - BrigAluModifier8_t modifier; - BrigRound8_t round; -}; - -struct BrigInstImage -{ - BrigInstBase base; - BrigType16_t imageType; - BrigType16_t coordType; - BrigImageGeometry8_t geometry; - uint8_t equivClass; - uint16_t reserved; -}; - -struct BrigInstLane -{ - BrigInstBase base; - BrigType16_t sourceType; - BrigWidth8_t width; - uint8_t reserved; -}; - -struct BrigInstMem -{ - BrigInstBase base; - BrigSegment8_t segment; - BrigAlignment8_t align; - uint8_t equivClass; - BrigWidth8_t width; - BrigMemoryModifier8_t modifier; - uint8_t reserved[3]; -}; - -struct BrigInstMemFence -{ - BrigInstBase base; - BrigMemoryOrder8_t memoryOrder; - BrigMemoryScope8_t globalSegmentMemoryScope; - BrigMemoryScope8_t groupSegmentMemoryScope; - BrigMemoryScope8_t imageSegmentMemoryScope; -}; - -struct BrigInstMod -{ - BrigInstBase base; - BrigAluModifier8_t modifier; - BrigRound8_t round; - BrigPack8_t pack; - uint8_t reserved; -}; - -struct BrigInstQueryImage -{ - BrigInstBase base; - BrigType16_t imageType; - BrigImageGeometry8_t geometry; - BrigImageQuery8_t query; -}; - -struct BrigInstQuerySampler -{ - BrigInstBase base; - BrigSamplerQuery8_t query; - uint8_t reserved[3]; -}; - -struct BrigInstQueue -{ - BrigInstBase base; - BrigSegment8_t segment; - BrigMemoryOrder8_t memoryOrder; - uint16_t reserved; -}; - -struct BrigInstSeg -{ - BrigInstBase base; - BrigSegment8_t segment; - uint8_t reserved[3]; -}; - -struct BrigInstSegCvt -{ - BrigInstBase base; - BrigType16_t sourceType; - BrigSegment8_t segment; - BrigSegCvtModifier8_t modifier; -}; - -struct BrigInstSignal -{ - BrigInstBase base; - BrigType16_t signalType; - BrigMemoryOrder8_t memoryOrder; - BrigAtomicOperation8_t signalOperation; -}; - -struct BrigInstSourceType -{ - BrigInstBase base; - BrigType16_t sourceType; - uint16_t reserved; -}; - -struct BrigOperandAddress -{ - BrigBase base; - BrigCodeOffset32_t symbol; - BrigOperandOffset32_t reg; - BrigUInt64 offset; -}; - -struct BrigOperandAlign -{ - BrigBase base; - BrigAlignment8_t align; - uint8_t reserved[3]; -}; - -struct BrigOperandCodeList -{ - BrigBase base; - BrigDataOffsetCodeList32_t elements; -}; - -struct BrigOperandCodeRef -{ - BrigBase base; - BrigCodeOffset32_t ref; -}; - -struct BrigOperandConstantBytes -{ - BrigBase base; - BrigType16_t type; - uint16_t reserved; - BrigDataOffsetString32_t bytes; -}; - -struct BrigOperandConstantImage -{ - BrigBase base; - BrigType16_t type; - BrigImageGeometry8_t geometry; - BrigImageChannelOrder8_t channelOrder; - BrigImageChannelType8_t channelType; - uint8_t reserved[3]; - BrigUInt64 width; - BrigUInt64 height; - BrigUInt64 depth; - BrigUInt64 array; -}; - -struct BrigOperandConstantOperandList -{ - BrigBase base; - BrigType16_t type; - uint16_t reserved; - BrigDataOffsetOperandList32_t elements; -}; - -struct BrigOperandConstantSampler -{ - BrigBase base; - BrigType16_t type; - BrigSamplerCoordNormalization8_t coord; - BrigSamplerFilter8_t filter; - BrigSamplerAddressing8_t addressing; - uint8_t reserved[3]; -}; - -struct BrigOperandOperandList -{ - BrigBase base; - BrigDataOffsetOperandList32_t elements; -}; - -struct BrigOperandRegister -{ - BrigBase base; - BrigRegisterKind16_t regKind; - uint16_t regNum; -}; - -struct BrigOperandString -{ - BrigBase base; - BrigDataOffsetString32_t string; -}; - -struct BrigOperandWavesize -{ - BrigBase base; -}; - -#endif /* HSA_BRIG_FORMAT_H */ diff --git a/gcc/brig/brigfrontend/phsa.h b/gcc/brig/brigfrontend/phsa.h deleted file mode 100644 index 2103a31774a..00000000000 --- a/gcc/brig/brigfrontend/phsa.h +++ /dev/null @@ -1,79 +0,0 @@ -/* phsa.h -- interfacing between the gcc BRIG FE and the phsa runtime - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ - -#ifndef PHSA_H -#define PHSA_H - -#include - -/* This struct is used to pass information from the BRIG FE to the - runtime of the finalizer kernel, its control directives etc. - The data is passed raw in a special ELF section named - phsa.kerneldesc.kernel_function_name. */ - -typedef struct __attribute__((__packed__)) -{ - /* Set to 1 in case the function is a kernel. */ - uint8_t is_kernel; - /* The size of the group segment used by the kernel. */ - uint32_t group_segment_size; - /* Size of the private segment used by a single work-item. */ - uint32_t private_segment_size; - /* Total size of the kernel arguments. */ - uint32_t kernarg_segment_size; - /* Maximum alignment of a kernel argument variable. */ - uint16_t kernarg_max_align; - /* Maximum size (in bytes) of dynamic group memory. */ - uint32_t max_dynamic_group_size; - /* Max number of work-items used to launch the kernel. */ - uint64_t max_flat_grid_size; - /* Max number of work-items in a work-group used to launch the kernel. */ - uint32_t max_flat_workgroup_size; - /* The grid size required by the kernel. */ - uint64_t required_grid_size[3]; - /* The work group size required by the kernel. */ - uint32_t required_workgroup_size[3]; - /* The number of dimensions required by the kernel. */ - uint8_t required_dim; - -} phsa_descriptor; - -/* The prefix to use in the ELF section containing descriptor for - a function. */ - -#define PHSA_DESC_SECTION_PREFIX "phsa.desc." -#define PHSA_HOST_DEF_PTR_PREFIX "__phsa.host_def." - -/* The frontend error messages are parsed by the host runtime. Known - prefix strings are used to separate the different runtime error - codes. */ - -#define PHSA_ERROR_PREFIX_INCOMPATIBLE_MODULE "Incompatible module: " -#define PHSA_ERROR_PREFIX_CORRUPTED_MODULE "Corrupted module: " - -/* Offsets of attributes in the PHSA context structs. - Used by -fphsa-wi-context-opt. */ -#define PHSA_CONTEXT_OFFS_WI_IDS 0 -#define PHSA_CONTEXT_OFFS_WG_IDS (PHSA_CONTEXT_OFFS_WI_IDS + 3 * 4) -#define PHSA_CONTEXT_WG_SIZES (PHSA_CONTEXT_OFFS_WG_IDS + 3 * 4) -#define PHSA_CONTEXT_CURRENT_WG_SIZES (PHSA_CONTEXT_WG_SIZES + 3 * 4) - -#endif diff --git a/gcc/brig/brigspec.c b/gcc/brig/brigspec.c deleted file mode 100644 index cbbc8ea076d..00000000000 --- a/gcc/brig/brigspec.c +++ /dev/null @@ -1,136 +0,0 @@ -/* brigspec.c -- Specific flags and argument handling of the gcc BRIG front end. - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tm.h" -#include "opt-suggestions.h" -#include "gcc.h" -#include "opts.h" - -/* This bit is set if we saw a `-xfoo' language specification. */ -#define LANGSPEC (1 << 1) -/* This bit is set if they did `-lm' or `-lmath'. */ -#define MATHLIB (1 << 2) -/* This bit is set if they did `-lpthread'. */ -#define THREADLIB (1 << 3) -/* This bit is set if they did `-lc'. */ -#define WITHLIBC (1 << 4) -/* Skip this option. */ -#define SKIPOPT (1 << 5) - -#ifndef MATH_LIBRARY -#define MATH_LIBRARY "m" -#endif -#ifndef MATH_LIBRARY_PROFILE -#define MATH_LIBRARY_PROFILE MATH_LIBRARY -#endif - -#define LIBHSAIL "hsail-rt" - -void -lang_specific_driver (struct cl_decoded_option **in_decoded_options, - unsigned int *in_decoded_options_count, - int *in_added_libraries) -{ - unsigned int i, j; - - /* The new argument list will be contained in this. */ - struct cl_decoded_option *new_decoded_options; - - /* An array used to flag each argument that needs a bit set for - LANGSPEC, MATHLIB, or WITHLIBC. */ - int *args; - - /* By default, we throw on the math library if we have one. */ - int need_math = (MATH_LIBRARY[0] != '\0'); - - /* True if we should add -shared-libgcc to the command-line. */ - int shared_libgcc = 1; - - /* The total number of arguments with the new stuff. */ - unsigned int argc; - - /* The argument list. */ - struct cl_decoded_option *decoded_options; - - /* The number of libraries added in. */ - int added_libraries; - - /* The total number of arguments with the new stuff. */ - int num_args = 1; - - argc = *in_decoded_options_count; - decoded_options = *in_decoded_options; - added_libraries = *in_added_libraries; - - args = XCNEWVEC (int, argc); - - for (i = 1; i < argc; i++) - { - switch (decoded_options[i].opt_index) - { - case OPT_o: - break; - - case OPT_SPECIAL_input_file: - break; - } - } - - /* Make sure to have room for the trailing NULL argument. */ - num_args = argc + need_math + shared_libgcc + 10; - new_decoded_options = XNEWVEC (struct cl_decoded_option, num_args); - - i = 0; - j = 0; - - /* Copy the 0th argument, i.e., the name of the program itself. */ - new_decoded_options[j++] = decoded_options[i++]; - - /* NOTE: We start at 1 now, not 0. */ - while (i < argc) - { - new_decoded_options[j] = decoded_options[i]; - - if ((args[i] & SKIPOPT) != 0) - --j; - - i++; - j++; - } - - generate_option (OPT_l, LIBHSAIL, 1, CL_DRIVER, &new_decoded_options[j]); - j++; - - *in_decoded_options_count = j; - *in_decoded_options = new_decoded_options; - *in_added_libraries = added_libraries; -} - -/* Called before linking. Returns 0 on success and -1 on failure. */ - -int lang_specific_pre_link (void) /* Not used for Brig. */ { return 0; } - -/* Number of extra output files that lang_specific_pre_link may generate. */ - -int lang_specific_extra_outfiles = 0; /* Not used for Brig. */ diff --git a/gcc/brig/config-lang.in b/gcc/brig/config-lang.in deleted file mode 100644 index cf04aac93ca..00000000000 --- a/gcc/brig/config-lang.in +++ /dev/null @@ -1,41 +0,0 @@ -# config-lang.in -- Top level configure fragment for gcc BRIG (HSAIL) frontend. - -# Copyright (C) 2015-2021 Free Software Foundation, Inc. - -# This file is part of GCC. - -# GCC is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. - -# GCC is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with GCC; see the file COPYING3. If not see -# . - -# Configure looks for the existence of this file to auto-config each language. -# We define several parameters used by configure: -# -# language - name of language as it would appear in $(LANGUAGES) -# compilers - value to add to $(COMPILERS) - -language="brig" - -compilers="brig1\$(exeext)" - -target_libs="target-libhsail-rt" - -# The BRIG frontend is written in C++, so we need to build the C++ -# compiler during stage 1. Note: when cross-compiling / not bootstrapping, -# this can be safely removed. gcc 4.9.1 force enables c++/libstdc++ to the -# target compiler due to this. -lang_requires_boot_languages=c++ - -gtfiles="\$(srcdir)/brig/brig-lang.c \$(srcdir)/brig/brig-c.h" - -build_by_default="no" diff --git a/gcc/brig/gccbrig.texi b/gcc/brig/gccbrig.texi deleted file mode 100644 index 87b36014098..00000000000 --- a/gcc/brig/gccbrig.texi +++ /dev/null @@ -1,153 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@setfilename gccbrig.info -@settitle The GNU BRIG (HSAIL) Compiler -@set copyrights-brig 2017-2021 - -@c Merge the standard indexes into a single one. -@syncodeindex fn cp -@syncodeindex vr cp -@syncodeindex ky cp -@syncodeindex pg cp -@syncodeindex tp cp - -@include gcc-common.texi - -@copying -@c man begin COPYRIGHT -Copyright @copyright{} @value{copyrights-brig} Free Software Foundation, Inc. - -Permission is granted to copy, distribute and/or modify this document -under the terms of the GNU Free Documentation License, Version 1.3 or -any later version published by the Free Software Foundation; with no -Invariant Sections, the Front-Cover Texts being (a) (see below), and -with the Back-Cover Texts being (b) (see below). -A copy of the license is included in the -@c man end -section entitled ``GNU Free Documentation License''. -@ignore -@c man begin COPYRIGHT -man page gfdl(7). -@c man end -@end ignore - -@c man begin COPYRIGHT - -(a) The FSF's Front-Cover Text is: - - A GNU Manual - -(b) The FSF's Back-Cover Text is: - - You have freedom to copy and modify this GNU Manual, like GNU - software. Copies published by the Free Software Foundation raise - funds for GNU development. -@c man end -@end copying - -@ifinfo -@format -@dircategory Software development -@direntry -* Gccbrig: (gccbrig). A GCC-based compiler for BRIG/HSAIL finalization -@end direntry -@end format - -@insertcopying -@end ifinfo - -@titlepage -@title The GNU BRIG (HSAIL) Compiler -@versionsubtitle -@author Pekka Jääskeläinen - -@page -@vskip 0pt plus 1filll -Published by the Free Software Foundation @* -51 Franklin Street, Fifth Floor@* -Boston, MA 02110-1301, USA@* -@sp 1 -@insertcopying -@end titlepage -@contents -@page - -@node Top -@top Introduction - -This manual describes how to use @command{gccbrig}, the GNU compiler for -the binary representation (BRIG) of the HSA Intermediate Language (HSAIL). -For more information about the Heterogeneous System Architecture (HSA) -Foundation's standards in general, see @uref{http://www.hsafoundation.com/}. - -@menu -* Copying:: The GNU General Public License. -* GNU Free Documentation License:: - How you can share and copy this manual. -* Using Gccbrig:: How to use Gccbrig. -* Index:: Index. -@end menu - -@include gpl_v3.texi - -@include fdl.texi - - -@node Using Gccbrig -@chapter Using Gccbrig - -@c man title gccbrig A GCC-based compiler for HSAIL - -@ignore -@c man begin SYNOPSIS gccbrig -gccbrig [@option{-c}|@option{-S}] - [@option{-O}@var{level}] [@option{-L}@var{dir}@dots{}] - [@option{-o} @var{outfile}] @var{infile}@dots{} - -Gccbrig is typically not invoked from the command line, but -through an HSA finalizer implementation. -@c man end -@c man begin SEEALSO -The Info entry for @file{gccbrig} and -@uref{https://github.com/HSAFoundation/phsa} -@c man end -@end ignore - -@c man begin DESCRIPTION gccbrig - -The BRIG frontend (@command{gccbrig}) differs from the -other frontends in GCC on how it's typically used. It's a translator -for an intermediate language that is not meant to be written directly -by programmers. Its input format BRIG is a binary representation of -HSAIL, which is a textual assembly format for an imaginary machine -of which instruction set is defined in HSA Programmer Reference Manual -(PRM) Specification. Gccbrig currently implements the Base profile -of the PRM version 1.0. - -HSA Runtime Specification defines an API which includes means -to build and launch ``kernels'' from a host program running on a CPU -to one or more heterogeneous ``kernel agents''. A kernel Agent -is typically a GPU or a DSP device controlled by the CPU. -The build phase is called ``finalization'', which means translation of -one or more target-independent BRIG files describing the program that -one wants to run in the Agent to the Agent's instruction set. Gccbrig -implements the translation process by generating GENERIC, which is -translated to the ISA of any supported GCC target by the GCC's backend -framework, thus enabling potentially any GCC target to act as an HSA agent. - -As the kernel finalization process can be only launched from the host API, -@command{gccbrig} is not typically used directly from the command line by -the end user, but through an HSA runtime implementation that implements -the finalizer API running on the host CPU. Gccbrig is -designed to work with an open source HSA runtime implementation -called ``phsa-runtime'', which can be installed from -@uref{https://github.com/HSAFoundation/phsa-runtime}. Phsa-runtime -has an example Agent driver that allows any GCC-supported CPU to act as -a kernel Agent. The web page has further installation instructions for -setting up it to work with a gccbrig binary installed with the GCC. - -@node Index -@unnumbered Index - -@printindex cp - -@bye diff --git a/gcc/brig/lang-specs.h b/gcc/brig/lang-specs.h deleted file mode 100644 index 1075801c678..00000000000 --- a/gcc/brig/lang-specs.h +++ /dev/null @@ -1,28 +0,0 @@ -/* lang-specs.h -- gcc driver specs for BRIG (HSAIL) frontend. - Copyright (C) 2016-2021 Free Software Foundation, Inc. - Contributed by Pekka Jaaskelainen - for General Processor Tech. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ - -/* This is the contribution to the `default_compilers' array in gcc.c - for the BRIG (HSAIL) input. */ - -{".brig", "@brig", 0, 1, 0}, - {"@brig", - "brig1 %i %(cc1_options) %{I*} %{L*} %D %{!fsyntax-only:%(invoke_as)}", 0, 1, - 0}, diff --git a/gcc/brig/lang.opt b/gcc/brig/lang.opt deleted file mode 100644 index 6fcceceb57c..00000000000 --- a/gcc/brig/lang.opt +++ /dev/null @@ -1,46 +0,0 @@ -; lang.opt -- Options for the gcc BRIG (HSAIL) front end. - -; Copyright (C) 2015-2021 Free Software Foundation, Inc. -; -; This file is part of GCC. -; -; GCC is free software; you can redistribute it and/or modify it under -; the terms of the GNU General Public License as published by the Free -; Software Foundation; either version 3, or (at your option) any later -; version. -; -; GCC is distributed in the hope that it will be useful, but WITHOUT ANY -; WARRANTY; without even the implied warranty of MERCHANTABILITY or -; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -; for more details. -; -; You should have received a copy of the GNU General Public License -; along with GCC; see the file COPYING3. If not see -; . - -; See the GCC internals manual for a description of this file's format. - -; Please try to keep this file in ASCII collating order. - -Language -BRIG - --dump -BRIG Separate Alias(d) - --dump= -BRIG Joined Alias(d) - -fassume-phsa -BRIG Var(flag_assume_phsa) Init(1) Optimization -Assume we are finalizing for phsa and its libhsail-rt. Enables additional -phsa-specific optimizations (default). - -L -BRIG Joined Separate -; Not documented - --output= -BRIG Driver Joined Alias(o) MissingArgError(missing filename after %qs) - -; This comment is to ensure we retain the blank line above. diff --git a/gcc/builtins.def b/gcc/builtins.def index b67649a13a9..ec556df4f66 100644 --- a/gcc/builtins.def +++ b/gcc/builtins.def @@ -1073,47 +1073,4 @@ DEF_GCC_BUILTIN (BUILT_IN_LINE, "LINE", BT_FN_INT, ATTR_NOTHROW_LEAF_LIST) /* Coroutine builtins. */ #include "coroutine-builtins.def" -/* Do not expose the BRIG builtins by default gcc-wide, but only privately in - the BRIG FE as long as there are no references for them in the middle end - or any of the upstream backends. */ - -#ifndef DEF_HSAIL_BUILTIN -#define DEF_HSAIL_BUILTIN(ENUM, HSAIL_OPCODE, HSAIL_TYPE, NAME, TYPE, ATTRS) \ - DEF_BUILTIN_STUB (ENUM, "__builtin_" NAME) -#endif - -/* HSAIL atomic builtins do not have separate identifying opcodes. */ - -#ifndef DEF_HSAIL_ATOMIC_BUILTIN -#define DEF_HSAIL_ATOMIC_BUILTIN(ENUM, ATOMIC_OPCODE, HSAIL_TYPE, NAME, \ - TYPE, ATTRS) \ - DEF_BUILTIN_STUB (ENUM, "__builtin_" NAME) -#endif - -/* HSAIL saturating arithmetics builtins. */ - -#ifndef DEF_HSAIL_SAT_BUILTIN -#define DEF_HSAIL_SAT_BUILTIN(ENUM, BRIG_OPCODE, HSAIL_TYPE, NAME, \ - TYPE, ATTRS) \ - DEF_BUILTIN_STUB (ENUM, "__builtin_" NAME) -#endif - -/* HSAIL builtins used internally by the frontend. */ - -#ifndef DEF_HSAIL_INTR_BUILTIN -#define DEF_HSAIL_INTR_BUILTIN(ENUM, NAME, TYPE, ATTRS) \ - DEF_BUILTIN_STUB (ENUM, "__builtin_" NAME) -#endif - -/* HSAIL saturated conversions. */ - -#ifndef DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN -#define DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN(ENUM, HSAIL_DEST_TYPE, HSAIL_SRC_TYPE, \ - NAME, TYPE, ATTRS) \ - DEF_BUILTIN_STUB (ENUM, "__builtin_" NAME) -#endif - -/* HSAIL/BRIG frontend builtins. */ -#include "brig-builtins.def" - #undef DEF_BUILTIN diff --git a/gcc/doc/frontends.texi b/gcc/doc/frontends.texi index 78f579f2152..7ff691bbaa5 100644 --- a/gcc/doc/frontends.texi +++ b/gcc/doc/frontends.texi @@ -17,7 +17,7 @@ GCC stands for ``GNU Compiler Collection''. GCC is an integrated distribution of compilers for several major programming languages. These languages currently include C, C++, Objective-C, Objective-C++, -Fortran, Ada, D, Go, and BRIG (HSAIL). +Fortran, Ada, D, and Go. The abbreviation @dfn{GCC} has multiple meanings in common use. The current official meaning is ``GNU Compiler Collection'', which refers diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi index 4c38244ae58..5308ebdcb03 100644 --- a/gcc/doc/install.texi +++ b/gcc/doc/install.texi @@ -2987,10 +2987,8 @@ separately. Second, you must have the testing tools installed. This includes @uref{http://www.gnu.org/software/dejagnu/,,DejaGnu}, Tcl, and Expect; -the DejaGnu site has links to these. For running the BRIG frontend -tests, a tool to assemble the binary BRIGs from HSAIL text, -@uref{https://github.com/HSAFoundation/HSAIL-Tools/,,HSAILasm} must -be installed. Some optional tests also require Python3 and pytest module. +the DejaGnu site has links to these. +Some optional tests also require Python3 and pytest module. If the directories where @command{runtest} and @command{expect} were installed are not in the @env{PATH}, you may need to set the following diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 7a368959e5e..9488ec72a8c 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -1535,9 +1535,6 @@ traditional preprocessor). @item @var{file}.go Go source code. -@item @var{file}.brig -BRIG files (binary representation of HSAIL). - @item @var{file}.d D source code. @@ -1593,7 +1590,6 @@ ada d f77 f77-cpp-input f95 f95-cpp-input go -brig @end smallexample @item -x none diff --git a/gcc/doc/standards.texi b/gcc/doc/standards.texi index 0f88333eec6..128b1c67bbc 100644 --- a/gcc/doc/standards.texi +++ b/gcc/doc/standards.texi @@ -320,14 +320,6 @@ available online, see @uref{http://gcc.gnu.org/readings.html} As of the GCC 4.7.1 release, GCC supports the Go 1 language standard, described at @uref{https://golang.org/doc/go1}. -@section HSA Intermediate Language (HSAIL) - -GCC can compile the binary representation (BRIG) of the HSAIL text format as -described in HSA Programmer's Reference Manual version 1.0.1. This -capability is typically utilized to implement the HSA runtime API's HSAIL -finalization extension for a gcc supported processor. HSA standards are -freely available at @uref{http://www.hsafoundation.com/standards/}. - @section D language GCC supports the D 2.0 programming language. The D language itself is diff --git a/gcc/testsuite/brig.dg/README b/gcc/testsuite/brig.dg/README deleted file mode 100644 index 2ad5b24e75e..00000000000 --- a/gcc/testsuite/brig.dg/README +++ /dev/null @@ -1,12 +0,0 @@ -BRIG (HSAIL) frontend test cases --------------------------------- - -The suite consists of "smoke tests" that test several features of -the compilation and regression tests, but is not an exhaustive test -suite for all HSAIL instructions. The HSA PRM conformance suite -is supposed to be used for that. - -HSAILasm is required for converting the text HSAIL files to BRIGs -which the compiler consumes. It can be built from -https://github.com/HSAFoundation/HSAIL-Tools - diff --git a/gcc/testsuite/brig.dg/dg.exp b/gcc/testsuite/brig.dg/dg.exp deleted file mode 100644 index 6441092895a..00000000000 --- a/gcc/testsuite/brig.dg/dg.exp +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (C) 2009-2021 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GCC; see the file COPYING3. If not see -# . - -# GCC testsuite that uses the `dg.exp' driver. - -load_lib brig-dg.exp - -# Initialize `dg'. -dg-init - -if [expr [llength [auto_execok HSAILasm]] > 0] { - dg-runtest [find $srcdir/$subdir *.hsail] "" "" -} else { - unsupported "All BRIG FE tests require HSAILasm in PATH." -} - -# All done. -dg-finish diff --git a/gcc/testsuite/brig.dg/test/gimple/alloca.hsail b/gcc/testsuite/brig.dg/test/gimple/alloca.hsail deleted file mode 100644 index 479ab7237b8..00000000000 --- a/gcc/testsuite/brig.dg/test/gimple/alloca.hsail +++ /dev/null @@ -1,37 +0,0 @@ -module &module:1:0:$full:$large:$default; - -/* Tests for alloca. */ - -/* { dg-do compile } */ -/* { dg-options "-fdump-tree-gimple" } */ - -prog function &subfunction(arg_u32 %return_value)() { - alloca_align(1)_u32 $s2, 256; - st_arg_u32 $s2, [%return_value]; - ret; -}; - -prog kernel &kernel(kernarg_u64 %input_ptr, kernarg_u64 %output_ptr) -{ - ld_kernarg_u64 $d0, [%input_ptr]; - ld_global_u32 $s0, [$d0]; - - alloca_align(256)_u32 $s1, 16; - { - arg_u32 %return_value; - call &subfunction(%return_value)(); - ld_arg_u32 $s1, [%return_value]; - } - ld_kernarg_u64 $d1, [%output_ptr]; - st_global_u32 $s1, [$d0]; -}; - -/* { dg-final { scan-tree-dump "s2 = __builtin___hsail_alloca \\\(256, 1, __context\\\);" "gimple" } } */ - -/* { dg-final { scan-tree-dump "s1 = __builtin___hsail_alloca \\\(16, 256, __context\\\);" "gimple" } } */ - - -/* Both functions should have an alloca frame push and pop. */ -/* { dg-final { scan-tree-dump-times "__builtin___hsail_alloca_push_frame \\\(__context\\\);" 2 "gimple" } } */ - -/* { dg-final { scan-tree-dump-times "__builtin___hsail_alloca_pop_frame \\\(__context\\\);" 2 "gimple" } } */ diff --git a/gcc/testsuite/brig.dg/test/gimple/atomics.hsail b/gcc/testsuite/brig.dg/test/gimple/atomics.hsail deleted file mode 100644 index b877a668ec9..00000000000 --- a/gcc/testsuite/brig.dg/test/gimple/atomics.hsail +++ /dev/null @@ -1,33 +0,0 @@ -module &module:1:0:$full:$large:$default; - -/* Test for atomic instructions. */ - -/* { dg-do compile } */ -/* { dg-options "-fdump-tree-original" } */ - -prog kernel &Kernel(kernarg_u64 %input_ptr, kernarg_u64 %output_ptr) -{ - ld_kernarg_u64 $d0, [%input_ptr]; - - atomic_ld_global_rlx_system_b32 $s0, [$d0]; - atomic_add_global_rlx_system_u32 $s1, [$d0 + 4], $s0; - - ld_kernarg_u64 $d0, [%output_ptr]; - atomicnoret_st_global_rlx_system_b32 [$d0], $s2; - - atomicnoret_min_global_rlx_system_u32 [$d0 + 4], $s1; - - ret; -}; - -/* The atomic loads are implemented by casting to an atomic pointer. */ -/* { dg-final { scan-tree-dump "s0 = VIEW_CONVERT_EXPR\\\(\\\*\\\(atomic unsigned int \\\*\\\)" "original"} } */ - -/* The atomic add should call a gcc builtin. */ -/* { dg-final { scan-tree-dump "= __sync_fetch_and_add_4 \\\(" "original"} } */ - -/* The atomic stores are implemented by casting to an atomic pointer. */ -/* { dg-final { scan-tree-dump "\\\*\\\(atomic unsigned int \\\*\\\) d0 = s2;" "original"} } */ - -/* The atomic min is implemented by a custom builtin. */ -/* { dg-final { scan-tree-dump "builtin_out.\[0-9\]+ = __builtin___hsail_atomic_min_u32 \\\(" "original"} } */ diff --git a/gcc/testsuite/brig.dg/test/gimple/branches.hsail b/gcc/testsuite/brig.dg/test/gimple/branches.hsail deleted file mode 100644 index 081fde3f1c2..00000000000 --- a/gcc/testsuite/brig.dg/test/gimple/branches.hsail +++ /dev/null @@ -1,58 +0,0 @@ -module &module:1:0:$full:$large:$default; - -/* Test different style of branches. */ - -/* { dg-do compile } */ -/* { dg-options "-fdump-tree-gimple" } */ - -prog kernel &Kernel(kernarg_u64 %input_ptr, kernarg_u64 %output_ptr) -{ - ld_kernarg_u64 $d0, [%input_ptr]; - ld_global_u64 $d1, [$d0]; - ld_global_u64 $d2, [$d0 + 8]; - - ld_global_u32 $s0, [$d0 + 16]; - ld_global_u32 $s1, [$d0 + 20]; - - sbr_width(all)_u32 $s1 [@case0, @case1, @case2]; -@case0: - st_global_u64 0, [$d0]; - br @out; -@case1: - st_global_u64 1, [$d0]; - br @out; -@case2: - st_global_u64 2, [$d0]; -@out: - cmp_eq_u32_u32 $s2, $s1, $s0; - cvt_b1_u32 $c0, $s2; - - cbr_width(all)_b1 $c0, @true_branch; -@false_branch: - st_global_u64 $d1, [$d0]; - -@true_branch: - ld_kernarg_u64 $d0, [%output_ptr]; - - st_global_u32 $s2, [$d0 + 8]; - br @skip; - st_global_u32 $s3, [$d0 + 12]; - -@skip: - ret; -}; - -/* sbr is converted to a switch */ -/* { dg-final { scan-tree-dump "switch \\\(s1\\\) , case 0: , case 1: , case 2: >" "gimple"} } */ - -/* br @out converted to gotos */ -/* { dg-final { scan-tree-dump-times "goto @out" 2 "gimple"} } */ - -/* the comparison instruction */ -/* { dg-final { scan-tree-dump "c0 = s2 != 0;" "gimple" } } */ - -/* cbr to an if clause */ -/* { dg-final { scan-tree-dump "if \\\(c0 != 0\\\) goto @true_branch; else goto ;" "gimple" } } */ - -/* br @skip converted to a goto */ -/* { dg-final { scan-tree-dump "goto @skip" "gimple"} } */ diff --git a/gcc/testsuite/brig.dg/test/gimple/fbarrier.hsail b/gcc/testsuite/brig.dg/test/gimple/fbarrier.hsail deleted file mode 100644 index 9efe0271571..00000000000 --- a/gcc/testsuite/brig.dg/test/gimple/fbarrier.hsail +++ /dev/null @@ -1,74 +0,0 @@ -module &module:1:0:$full:$large:$default; - -/* Tests for fbarrier. */ - -/* { dg-do compile } */ -/* { dg-options "-fdump-tree-gimple" } */ - -fbarrier &fb_module_scope; - -prog function &subfunction(arg_u32 %return_value)() { - - workitemflatabsid_u32 $s3; - cvt_b1_u32 $c1, $s3; - cbr_width(all)_b1 $c1, @skip_fbar; - waitfbar &fb_module_scope; -@skip_fbar: - - st_arg_u32 $s3, [%return_value]; - ret; -}; - -prog kernel &kernel(kernarg_u64 %input_ptr, kernarg_u64 %output_ptr) -{ - fbarrier %fb_func_scope; - - ld_kernarg_u64 $d0, [%input_ptr]; - ld_global_u32 $s0, [$d0]; - - workitemflatabsid_u32 $s1; - cvt_b1_u32 $c1, $s1; - cbr_width(all)_b1 $c1, @skip_init; - - initfbar &fb_module_scope; - initfbar %fb_func_scope; - - joinfbar &fb_module_scope; - -@skip_init: - barrier_width(all); - - joinfbar %fb_func_scope; - - { - arg_u32 %return_value; - call &subfunction(%return_value)(); - ld_arg_u32 $s1, [%return_value]; - } - arrivefbar %fb_func_scope; - - ld_kernarg_u64 $d1, [%output_ptr]; - st_global_u32 $s1, [$d0]; - - workitemflatabsid_u32 $s1; - cvt_b1_u32 $c0, $s1; - cbr_width(all)_b1 $c0, @skip_fini; - - releasefbar &fb_module_scope; - releasefbar %fb_func_scope; - -@skip_fini: - -}; -/* fbarriers are allocated from the group memory in the order of - appearance. The current implementation allocates 32B per fbarrier. */ - -/* { dg-final { scan-tree-dump "__hsail_waitfbar \\\(0, __context\\\);" "gimple"} } */ -/* { dg-final { scan-tree-dump "__hsail_initfbar \\\(0, __context\\\);" "gimple"} } */ -/* { dg-final { scan-tree-dump "__hsail_initfbar \\\(__group_local_offset, __context\\\);" "gimple"} } */ -/* { dg-final { scan-tree-dump "__hsail_joinfbar \\\(0, __context\\\);" "gimple"} } */ -/* { dg-final { scan-tree-dump "@skip_init:\[\n ]+__builtin___hsail_barrier \\\(__context\\\);\[\n ]+__builtin___hsail_joinfbar \\\(__group_local_offset, __context\\\);" "gimple"} } */ - -/* { dg-final { scan-tree-dump "__hsail_arrivefbar \\\(__group_local_offset, __context\\\);" "gimple"} } */ - -/* { dg-final { scan-tree-dump "__hsail_releasefbar \\\(0, __context\\\);\[\n ]+__builtin___hsail_releasefbar \\\(__group_local_offset, __context\\\);" "gimple"} } */ diff --git a/gcc/testsuite/brig.dg/test/gimple/function_calls.hsail b/gcc/testsuite/brig.dg/test/gimple/function_calls.hsail deleted file mode 100644 index 50f79060b59..00000000000 --- a/gcc/testsuite/brig.dg/test/gimple/function_calls.hsail +++ /dev/null @@ -1,59 +0,0 @@ -module &module:1:0:$full:$large:$default; - -/* Function calls and argument passing. */ - -/* { dg-do compile } */ -/* { dg-options "-fdump-tree-gimple" } */ - -prog function &subfunction(arg_u32 %return_value)(arg_f32 %float_arg, arg_f64 %double_arg, arg_f16 %half_arg) { - ld_arg_f32 $s0, [%float_arg]; - cvt_u32_f32 $s0, $s0; - - ld_arg_f64 $d0, [%double_arg]; - cvt_u32_f64 $s1, $d0; - - ld_arg_f16 $s2, [%half_arg]; - cvt_u32_f16 $s2, $s2; - - add_u32 $s3, $s0, $s1; - add_u32 $s3, $s3, $s2; - - st_arg_u32 $s3, [%return_value]; - ret; -}; - -prog kernel &kernel(kernarg_u64 %input_ptr, kernarg_u64 %output_ptr) -{ - ld_kernarg_u64 $d0, [%input_ptr]; - ld_global_u32 $s0, [$d0]; - { - arg_f32 %float_arg; - arg_f64 %double_arg; - arg_f16 %half_arg; - arg_u32 %return_value; - - st_arg_f32 12.0f, [%float_arg]; - st_arg_f64 640.0d, [%double_arg]; - st_arg_f16 12.0h, [%half_arg]; - - call &subfunction(%return_value)(%float_arg, %double_arg, %half_arg); - - ld_arg_u32 $s1, [%return_value]; - } - ld_kernarg_u64 $d1, [%output_ptr]; - st_global_u32 $s1, [$d0]; -}; - -/* The generated function call should have the incoming arguments and three hidden arguments. */ - -/* { dg-final { scan-tree-dump "_\[0-9\]+ = subfunction \\\(_kernel.float_arg.\[_0-9\]+, _kernel.double_arg.\[_0-9\]+, _kernel.half_arg.\[_0-9\]+, __context, __group_base_addr, group_local_offset.*, __private_base_addr\\\);" "gimple"} } */ - -/* The callee should refer directly to the scalar arguments when it reads them. */ -/* { dg-final { scan-tree-dump "= float_arg;" "gimple"} } */ -/* { dg-final { scan-tree-dump "= double_arg;" "gimple"} } */ -/* { dg-final { scan-tree-dump "= half_arg;" "gimple"} } */ - -/* The return value is stored to a temporary before returned. */ -/* { dg-final { scan-tree-dump "_retvalue_temp = s3;" "gimple"} } */ -/* { dg-final { scan-tree-dump "D.\[0-9\]+ = _retvalue_temp;" "gimple"} } */ -/* { dg-final { scan-tree-dump "return D.\[0-9\]+;" "gimple"} } */ diff --git a/gcc/testsuite/brig.dg/test/gimple/internal-casts.hsail b/gcc/testsuite/brig.dg/test/gimple/internal-casts.hsail deleted file mode 100644 index 52673c9e65a..00000000000 --- a/gcc/testsuite/brig.dg/test/gimple/internal-casts.hsail +++ /dev/null @@ -1,146 +0,0 @@ -module &module:1:0:$full:$large:$default; - -/* Test for casting from/to representation of HSA registers. */ - -/* HSA registers are untyped but in gccbrig they are presented as */ -/* variables with a type selected by analysis. Currently, each */ -/* register variable, per function, has a type as it is used at */ -/* most. Therefore, register variable can be nearly any type. The */ -/* tests makes sure the generic/tree expressions have the right casts */ -/* from/to the register variables. */ - - -/* { dg-do compile } */ -/* { dg-options "-fdump-tree-original" } */ - -prog kernel &Kernel(kernarg_u64 %input_ptr, kernarg_u64 %output_ptr) -{ - private_u64 %foo; - private_u64 %bar; - private_b128 %baz; - - ld_kernarg_u64 $d0, [%input_ptr]; - ld_global_u32 $s0, [$d0]; - - /* Trick gccbrig to set wanted type for the registers. */ - -/* $s0 is selected as float... */ -/* { dg-final { scan-tree-dump " s0;" "original"} } */ -/* ..., therefore, there should not be any casts. */ -/* { dg-final { scan-tree-dump "s10 = s0 \\\+ s0;" "original"} } */ - - add_f32 $s10, $s0, $s0; - add_f32 $s10, $s0, $s0; - add_f32 $s10, $s0, $s0; - add_f32 $s10, $s0, $s0; - add_f32 $s10, $s0, $s0; - -/* Expression with other type, a cast is needed. */ -/* { dg-final { scan-tree-dump "s1 = VIEW_CONVERT_EXPR.s0. \\\+ 123;" "original"} } */ - - add_u32 $s1, $s0, 123; - -/* { dg-final { scan-tree-dump "unsigned int s1;" "original"} } */ - - add_u32 $s10, $s1, 0; - add_u32 $s10, $s1, 0; - add_u32 $s10, $s1, 0; - add_u32 $s10, $s1, 0; - add_u32 $s10, $s1, 0; - -/* { dg-final { scan-tree-dump "s0 = VIEW_CONVERT_EXPR<>.s1.;" "original"} } */ - - mov_b32 $s0, $s1; - -/* Rig the election for $d0 to be double. */ -/* { dg-final { scan-tree-dump " d0;" "original"} } */ -/* { dg-final { scan-tree-dump "d10 = d0 \\\+ d0;" "original"} } */ - - add_f64 $d10, $d0, $d0; - add_f64 $d10, $d0, $d0; - add_f64 $d10, $d0, $d0; - add_f64 $d10, $d0, $d0; - add_f64 $d10, $d0, $d0; - -/* Make $s2 to be vector type. */ -/* { dg-final { scan-tree-dump "vector.4. unsigned char s2;" "original"} } */ -/* { dg-final { scan-tree-dump "s2 = VIEW_CONVERT_EXPR\\\(s1\\\) \\\+ VIEW_CONVERT_EXPR\\\(s1\\\);" "original"} } */ - - add_pp_u8x4 $s2, $s1, $s1; - -/* { dg-final { scan-tree-dump "s20 = s2 \\\+ s2;" "original"} } */ - - add_pp_u8x4 $s20, $s2, $s2; - add_pp_u8x4 $s20, $s2, $s2; - add_pp_u8x4 $s20, $s2, $s2; - add_pp_u8x4 $s20, $s2, $s2; - -/* { dg-final { scan-tree-dump "d0 = VIEW_CONVERT_EXPR<>.{VIEW_CONVERT_EXPR.s0., VIEW_CONVERT_EXPR.s2.}.;" "original"} } */ - - combine_v2_b64_b32 $d0, ($s0, $s2); - -/* { dg-final { scan-tree-dump "s2 = VIEW_CONVERT_EXPR.BIT_FIELD_REF .;" "original"} } */ -/* { dg-final { scan-tree-dump "s1 = BIT_FIELD_REF ;" "original"} } */ - - expand_v2_b32_b64 ($s2, $s1), $d0; - -/* { dg-final { scan-tree-dump "s0 = VIEW_CONVERT_EXPR<>\\\(.*VIEW_CONVERT_EXPR.s0\[\)\]*;" "original"} } */ - - cvt_s16_s8 $s0, $s0; - -/* { dg-final { scan-tree-dump "c0 = .*VIEW_CONVERT_EXPR<>.s2..* != 0;" "original"} } */ - - cvt_b1_f32 $c0, $s2; - -/* { dg-final { scan-tree-dump ".*__private_base_addr.* = .*\\\(unsigned char\\\) VIEW_CONVERT_EXPR\\\(s0\\\)\[\)\]*;" "original"} } */ - - st_private_u8 $s0, [%foo]; - -/* { dg-final { scan-tree-dump ".*__private_base_addr.* = .*\\\(unsigned short\\\) VIEW_CONVERT_EXPR\\\(s2\\\)\[\)\]*;" "original"} } */ - - st_private_u16 $s2, [%bar]; - -/* { dg-final { scan-tree-dump "mem_read.\[0-9\]* = \\\*\\\(signed char \\\*\\\) \\\(__private_base_addr .*\\\);\[ \n\]*s2 = VIEW_CONVERT_EXPR\\\(\\\(signed int\\\) mem_read.\[0-9\]*\\\);" "original"} } */ - - ld_private_s8 $s2, [%foo]; - -/* { dg-final { scan-tree-dump "mem_read.\[0-9\]* = \\\*\\\(signed short \\\*\\\) \\\(__private_base_addr .*\\\);\[ \n\]*s0 = VIEW_CONVERT_EXPR<>\\\(\\\(signed int\\\) mem_read.\[0-9\]*\\\);" "original"} } */ - - ld_private_s16 $s0, [%bar]; - -/* { dg-final { scan-tree-dump "\\\*\\\( \\\*\\\) \\\(__private_base_addr.*\\\) \\\+ 0 = s0;" "original"} } */ -/* { dg-final { scan-tree-dump "\\\*\\\( \\\*\\\) \\\(__private_base_addr.*\\\) \\\+ 4 = VIEW_CONVERT_EXPR<>\\\(s1\\\);" "original"} } */ -/* { dg-final { scan-tree-dump "\\\*\\\( \\\*\\\) \\\(__private_base_addr.*\\\) \\\+ 8 = VIEW_CONVERT_EXPR<>\\\(s2\\\);" "original"} } */ - - st_v3_private_f32 ($s0, $s1, $s2), [%baz]; - -/* { dg-final { scan-tree-dump "mem_read.\[0-9\]* = \\\*\\\(signed short \\\*\\\) \\\(__private_base_addr.*\\\) \\\+ 0;\[ \n\]*s0 = VIEW_CONVERT_EXPR<>\\\(\\\(signed int\\\) mem_read.\[0-9\]*\\\);" "original"} } */ -/* { dg-final { scan-tree-dump "mem_read.\[0-9\]* = \\\*\\\(signed short \\\*\\\) \\\(__private_base_addr.*\\\) \\\+ 2;\[ \n\]*s1 = VIEW_CONVERT_EXPR\\\(\\\(signed int\\\) mem_read.\[0-9\]*\\\);" "original"} } */ -/* { dg-final { scan-tree-dump "mem_read.\[0-9\]* = \\\*\\\(signed short \\\*\\\) \\\(__private_base_addr.*\\\) \\\+ 4;\[ \n\]*s2 = VIEW_CONVERT_EXPR\\\(\\\(signed int\\\) mem_read.\[0-9\]*\\\);" "original"} } */ - - ld_v3_private_s16 ($s0, $s1, $s2), [%baz]; - -/* { dg-final { scan-tree-dump "s5 = .*VIEW_CONVERT_EXPR\\\(s0\\\) == VIEW_CONVERT_EXPR\\\(s2\\\)\\\) .*;" "original"} } */ - - cmp_eq_s32_u32 $s5, $s0, $s2; - -/* { dg-final { scan-tree-dump "s6 = VIEW_CONVERT_EXPR<>\\\(.*VIEW_CONVERT_EXPR\\\(s0\\\).*VIEW_CONVERT_EXPR\\\(s2\\\).*;" "original"} } */ - - cmp_eq_pp_u16x2_u16x2 $s6, $s0, $s2; - -/* { dg-final { scan-tree-dump " s60;" "original"} } */ - - add_f32 $s60, $s6, $s6; - add_f32 $s60, $s6, $s6; - add_f32 $s60, $s6, $s6; - add_f32 $s60, $s6, $s6; - - ld_kernarg_u64 $d0, [%output_ptr]; - st_global_u32 $s0, [$d0]; - - ret; -}; - - - - diff --git a/gcc/testsuite/brig.dg/test/gimple/kernarg.hsail b/gcc/testsuite/brig.dg/test/gimple/kernarg.hsail deleted file mode 100644 index 7f30919e308..00000000000 --- a/gcc/testsuite/brig.dg/test/gimple/kernarg.hsail +++ /dev/null @@ -1,25 +0,0 @@ -module &module:1:0:$full:$large:$default; - -/* Tests for kernarg addressing modes. */ - -/* { dg-do compile } */ -/* { dg-options "-fdump-tree-original" } */ - -prog kernel &Kernel(kernarg_u64 %input[4], kernarg_u64 %output_ptr, kernarg_u64 %i) -{ - ld_kernarg_u64 $d0, [%i]; - ld_kernarg_u64 $d0, [%input][$d0 + 1]; - - ld_kernarg_u64 $d1, [%output_ptr]; - st_global_u64 $d0, [$d1]; - - ret; -}; - -/* [%i] */ -/* { dg-final { scan-tree-dump " = \\\*\\\(unsigned long \\\*\\\) \\\(__args \\\+ 40\\\);" "original"} } */ - -/* [%input][$d0 + 1] */ -/* { dg-final { scan-tree-dump "\\\*\\\(unsigned long \\\*\\\) \\\(\\\(VIEW_CONVERT_EXPR\\\(\\\(unsigned long\\\) __args\\\) \\\+ \\\(unsigned long\\\) d0\\\) \\\+ 1\\\);" "original"} } */ - - diff --git a/gcc/testsuite/brig.dg/test/gimple/mem.hsail b/gcc/testsuite/brig.dg/test/gimple/mem.hsail deleted file mode 100644 index 75835a10259..00000000000 --- a/gcc/testsuite/brig.dg/test/gimple/mem.hsail +++ /dev/null @@ -1,39 +0,0 @@ -module &module:1:0:$full:$large:$default; - -/* Tests for load/store addressing modes. */ - -/* { dg-do compile } */ -/* { dg-options "-fdump-tree-original" } */ - -prog kernel &Kernel(kernarg_u64 %input_ptr, kernarg_u64 %input_ptr2, kernarg_u64 %output_ptr) -{ - global_u32 %global_array[4]; - - ld_kernarg_u64 $d0, [%input_ptr]; - ld_kernarg_u64 $d2, [%input_ptr2]; - ld_global_u32 $s0, [$d0]; - ld_global_u64 $d1, [$d2 + 4]; - - ld_global_u32 $s2, [%global_array][$d1 + 4]; - - ld_kernarg_u64 $d0, [%output_ptr]; - st_global_u32 $s0, [$d0]; - st_global_u32 $s1, [$d0 + 4]; - st_global_u32 $s2, [$d0 + 8]; - - ret; -}; - -/* %input_ptr, %input_ptr2 and %output_ptr accesses should generate offsets to the __args array */ -/* { dg-final { scan-tree-dump "__args;\[\n \]+d0 =" "original"} } */ -/* { dg-final { scan-tree-dump "\\\(__args \\\+ 8\\\);\[\n \]+d2 =" "original"} } */ -/* { dg-final { scan-tree-dump "\\\(__args \\\+ 16\\\);\[\n \]+d0 =" "original"} } */ - -/* ld_global_u32 $s0, [$d0] */ -/* { dg-final { scan-tree-dump "\\\*\\\(unsigned int \\\*\\\) d0;\[\n \]+s0 =" "original"} } */ - -/* ld_global_u64 $d1, [$d2 + 4] pointer arithmetics*/ -/* { dg-final { scan-tree-dump "d2 \\\+ 4\\\);\[\n \]+d1 = " "original"} } */ - -/* ld_global_u32 $s2, [%global_array][$d1 + 4]; is the most complex form */ -/* { dg-final { scan-tree-dump "\\\(unsigned long\\\) &_Kernel.global_array\\\) \\\+ \\\(unsigned long\\\) d1\\\) \\\+ 4" "original" } } */ diff --git a/gcc/testsuite/brig.dg/test/gimple/mulhi.hsail b/gcc/testsuite/brig.dg/test/gimple/mulhi.hsail deleted file mode 100644 index acdced9ad1c..00000000000 --- a/gcc/testsuite/brig.dg/test/gimple/mulhi.hsail +++ /dev/null @@ -1,33 +0,0 @@ -module &module:1:0:$full:$large:$default; - -/* Test high part multiplies. */ - -/* { dg-do compile } */ -/* { dg-options "-fdump-tree-gimple" } */ - -prog kernel &Kernel(kernarg_u64 %input_ptr, kernarg_u64 %output_ptr) -{ - ld_kernarg_u64 $d0, [%input_ptr]; - ld_global_u64 $d1, [$d0]; - ld_global_u64 $d2, [$d0 + 8]; - - ld_global_u32 $s0, [$d0 + 16]; - ld_global_u32 $s1, [$d0 + 20]; - - mulhi_s32 $s2, $s0, $s1; - mulhi_s64 $d2, $d1, $d2; - - mad24hi_s32 $s3, $s0, $s1, $s2; - mul24hi_s32 $s3, $s3, $s1; - - ld_kernarg_u64 $d0, [%output_ptr]; - st_global_u64 $d1, [$d0]; - st_global_u32 $s2, [$d0 + 8]; - st_global_u32 $s3, [$d0 + 12]; - - ret; -}; - -/* All of the hipart mults areImplemented using MULT_HIGHPART_EXPR (h*). */ -/* { dg-final { scan-tree-dump-times " h\\\* " 4 "gimple"} } */ - diff --git a/gcc/testsuite/brig.dg/test/gimple/packed.hsail b/gcc/testsuite/brig.dg/test/gimple/packed.hsail deleted file mode 100644 index 1e2bb53de0d..00000000000 --- a/gcc/testsuite/brig.dg/test/gimple/packed.hsail +++ /dev/null @@ -1,76 +0,0 @@ -module &module:1:0:$full:$large:$default; - -/* Test for different cases of packed instruction controls. */ - -/* { dg-do compile } */ -/* { dg-options "-fdump-tree-gimple -fdump-tree-original" } */ - -prog kernel &Kernel(kernarg_u64 %input_ptr, kernarg_u64 %output_ptr) -{ - ld_kernarg_u64 $d0, [%input_ptr]; - ld_global_b128 $q0, [$d0]; - - add_pp_u8x16 $q1, $q0, u8x16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); - - /* Broadcast the 15 as it's the lowest element (pos 0) in the resulting vector. */ - add_ps_u8x16 $q2, $q1, u8x16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); - - /* Broadcast the lowest element of q1. */ - add_sp_u8x16 $q3, $q1, $q2; - - /* Perform a scalar computation with the lowest element of both inputs and store it to the lowest element of dest. */ - add_ss_u8x16 $q4, $q2, $q3; - - /* Saturating arithmetics variations. */ - add_pp_sat_u8x16 $q5, $q4, u8x16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); - - /* Broadcast the 15 as it's the lowest element (pos 0) in the resulting vector. */ - add_ps_sat_u8x16 $q6, $q5, u8x16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); - - /* Broadcast the lowest element of q1. */ - add_sp_sat_u8x16 $q7, $q6, $q5; - - /* Perform a scalar computation with the lowest element of both inputs and store it to the lowest element of dest. */ - add_ss_sat_u8x16 $q8, $q7, $q6; - - /* Single operand vector computation. */ - neg_p_s16x8 $q9, $q8; - - ld_kernarg_u64 $d0, [%output_ptr]; - st_global_b128 $q8, [$d0]; - - ret; -}; - -/* The b128 load is done using uint128_t*. */ -/* { dg-final { scan-tree-dump "q0 = VIEW_CONVERT_EXPR\\\(mem_read.\[0-9\]+\\\);" "original"} } */ - -/* Before arithmetics, the uint128_t is casted to a vector datatype. */ -/* { dg-final { scan-tree-dump "\\\(q0\\\) \\\+ \\\{" "original"} } */ - -/* The u8x16 constant is generated to an array with elements in reverse order */ -/* in comparison to the HSAIL syntax. */ -/* { dg-final { scan-tree-dump "\\\+ { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }" "original"} } */ - -/* Broadcasted the constant vector's lowest element and summed it up in the next line. */ -/* { dg-final { scan-tree-dump "= { 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 };\[\n \]+\[a-z0-9_\]+ = \[a-z0-9_\]+ \\\+ \[a-z0-9_\]+;" "gimple"} } */ - -/* Broadcasted the registers lowest element via a VEC_PERM_EXPR that has an all-zeros mask. */ -/* { dg-final { scan-tree-dump "VEC_PERM_EXPR <\[a-z0-9_\]+, \[a-z0-9_\]+, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }>;" "gimple" } } */ - -/* For the add_ss we assume performing the computation over the whole vector is cheaper than */ -/* extracting the scalar and performing a scalar operation. This aims to stay in the vector -/* datapath as long as possible. */ -/* { dg-final { scan-tree-dump "new_output.\[0-9\]+ = q2 \\\+ q3;" "gimple" } } */ - -/* Insert the lowest element of the result to the lowest element of the result register. */ -/* { dg-final { scan-tree-dump "= VEC_PERM_EXPR ;" "gimple" } } */ - -/* FIXME */ -/* { dg-final { scan-tree-dump "q4 = \(VIEW_CONVERT_EXPR\\\()?s_output.\[0-9\]+\(_\[0-9\]+\)*\\\)?;" "gimple" } } */ - -/* The saturating arithmetics are (curently) implemented using scalar builtin calls. */ -/* { dg-final { scan-tree-dump-times "= __builtin___hsail_sat_add_u8" 64 "gimple" } } */ - -/* A single operand vector instr (neg.) */ -/* { dg-final { scan-tree-dump "= VIEW_CONVERT_EXPR\\\(\(s_output.\[0-9\]+_\[0-9\]+|q8\)\\\);\[\n \]+q9 = -_\[0-9\]+;\[\n \]+" "gimple" } } */ diff --git a/gcc/testsuite/brig.dg/test/gimple/priv-array-offset-access.hsail b/gcc/testsuite/brig.dg/test/gimple/priv-array-offset-access.hsail deleted file mode 100644 index b20704b2caa..00000000000 --- a/gcc/testsuite/brig.dg/test/gimple/priv-array-offset-access.hsail +++ /dev/null @@ -1,87 +0,0 @@ -module &__llvm_hsail_module:1:0:$full:$large:$near; - -/* Regression test for a private array access case which used to assert. */ - -/* { dg-do compile } */ -/* { dg-options "-fdump-tree-gimple" } */ - -decl prog function &vec_sum()( - arg_u32 %a, - arg_u32 %b, - arg_u32 %res, - arg_u32 %N); - -prog function &vec_sum()( - arg_u32 %a, - arg_u32 %b, - arg_u32 %res, - arg_u32 %N) -{ - - ld_arg_align(4)_u32 $s0, [%N]; - ld_arg_align(4)_u32 $s1, [%res]; - ld_arg_align(4)_u32 $s2, [%b]; - ld_arg_align(4)_u32 $s3, [%a]; - cmp_le_b1_s32 $c0, $s0, 0; - cbr_b1 $c0, @BB0_2; -@BB0_1: - ld_private_align(4)_u32 $s4, [$s3]; - ld_private_align(4)_u32 $s5, [$s2]; - add_u32 $s4, $s5, $s4; - st_private_align(4)_u32 $s4, [$s1]; - add_u32 $s1, $s1, 4; - add_u32 $s2, $s2, 4; - add_u32 $s3, $s3, 4; - add_u32 $s0, $s0, 4294967295; - cmp_ne_b1_s32 $c0, $s0, 0; - cbr_b1 $c0, @BB0_1; -@BB0_2: - ret; -}; - -prog kernel &test( - kernarg_u64 %in, - kernarg_u64 %out) -{ - - align(4) private_u8 %__privateStack[1200]; - mov_b64 $d1, 0; -/* This used to crash when gcc asserts enabled: */ - lda_private_u32 $s0, [%__privateStack][400]; - lda_private_u32 $s1, [%__privateStack]; - ld_kernarg_align(8)_width(all)_u64 $d0, [%out]; - ld_kernarg_align(8)_width(all)_u64 $d2, [%in]; -@BB1_1: - add_u64 $d3, $d2, $d1; - ld_global_align(4)_u32 $s2, [$d3]; - st_private_align(4)_u32 $s2, [$s0]; - st_private_align(4)_u32 $s2, [$s1]; - add_u32 $s1, $s1, 4; - add_u32 $s0, $s0, 4; - add_u64 $d1, $d1, 4; - cmp_ne_b1_s64 $c0, $d1, 400; - cbr_b1 $c0, @BB1_1; - mov_b32 $s1, 0; - lda_private_u32 $s0, [%__privateStack][800]; -@BB1_3: - ld_private_align(4)_u32 $s2, [%__privateStack][$s1]; - ld_private_align(4)_u32 $s3, [%__privateStack][$s1+400]; - add_u32 $s2, $s3, $s2; - st_private_align(4)_u32 $s2, [%__privateStack][$s1+800]; - add_u32 $s1, $s1, 4; - cmp_ne_b1_s32 $c0, $s1, 400; - cbr_b1 $c0, @BB1_3; - mov_b64 $d1, 0; -@BB1_5: - add_u64 $d2, $d0, $d1; - ld_private_align(4)_u32 $s1, [$s0]; - st_global_align(4)_u32 $s1, [$d2]; - add_u32 $s0, $s0, 4; - add_u64 $d1, $d1, 4; - cmp_ne_b1_s64 $c0, $d1, 400; - cbr_b1 $c0, @BB1_5; - ret; -}; - -/* br @skip converted to a goto */ -/* { dg-final { scan-tree-dump "= \\\(void \\\*\\\) priv_var_offset" "gimple"} } */ diff --git a/gcc/testsuite/brig.dg/test/gimple/smoke_test.hsail b/gcc/testsuite/brig.dg/test/gimple/smoke_test.hsail deleted file mode 100644 index 6e2326391da..00000000000 --- a/gcc/testsuite/brig.dg/test/gimple/smoke_test.hsail +++ /dev/null @@ -1,91 +0,0 @@ -module &module:1:0:$full:$large:$default; - -/* A basic smoke test. */ - -/* { dg-do compile } */ -/* { dg-options "-fdump-tree-gimple" } */ - -prog kernel &Kernel(kernarg_u64 %input_ptr, kernarg_u64 %output_ptr) -{ - ld_kernarg_u64 $d0, [%input_ptr]; - ld_global_u32 $s0, [$d0]; - ld_global_u32 $s1, [$d0 + 4]; - - add_u32 $s2, $s0, $s1; - add_u32 $s3, $s0, 4294967295; - - ld_kernarg_u64 $d0, [%output_ptr]; - st_global_u32 $s2, [$d0]; - st_global_u32 $s3, [$d0 + 4]; - - ret; -}; - -prog kernel &KernelWithBarrier(kernarg_u64 %input_ptr, kernarg_u64 %output_ptr) -{ - ld_kernarg_u64 $d0, [%input_ptr]; - ld_global_u32 $s0, [$d0]; - ld_global_u32 $s1, [$d0 + 4]; - - add_u32 $s2, $s0, $s1; - - barrier_width(all); - - add_u32 $s3, $s0, 4294967295; - - ld_kernarg_u64 $d0, [%output_ptr]; - st_global_u32 $s2, [$d0]; - st_global_u32 $s3, [$d0 + 4]; - - ret; -}; - -/* The kernel function itself should have a fingerprint as follows */ -/* _Kernel (const unsigned char * restrict __args, void * restrict __context, unsigned char * restrict __group_base_addr, unsigned int __group_local_offset, unsigned char * restrict __private_base_addr) */ -/* { dg-final { scan-tree-dump "_Kernel \\\(const unsigned char \\\* restrict __args, void \\\* restrict __context, unsigned char \\\* restrict __group_base_addr, unsigned int __group_local_offset, unsigned char \\\* restrict __private_base_addr\\\)" "gimple"} } */ - -/* ld_kernarg: mem_read.0 = MEM[(unsigned long *)__args]; */ -/* { dg-final { scan-tree-dump "mem_read.\[0-9\] = MEM\\\[\\\(unsigned long \\\*\\\)__args\\\];" "gimple"} } */ - -/* The latter ld_global_u32 should be visible as a pointer dereference (after pointer arithmetics on a temporary var): */ -/* mem_read.2 = *D.1691; */ -/* { dg-final { scan-tree-dump "mem_read.\[0-9\]+ = \\\*\[_0-9\]+;" "gimple"} } */ - -/* add_u32s should generate +operators */ -/* { dg-final { scan-tree-dump "s2 = s0 \\\+ s1;" "gimple"} } */ -/* { dg-final { scan-tree-dump "s3 = s0 \\\+ 4294967295;" "gimple"} } */ - -/* The latter st_global_u32 should be visible as a pointer dereference (after pointer arithmetics on a temporary var): */ -/* *D.1694 = s3; */ -/* { dg-final { scan-tree-dump "\\\*\[_0-9\]+ = s3;" "gimple"} } */ - -/* The return inside the kernel should be generated to a goto to the end of the kernel. */ -/* goto __kernel_exit; */ -/* __kernel_exit: */ -/* { dg-final { scan-tree-dump "goto __kernel_exit;" "gimple"} } */ -/* { dg-final { scan-tree-dump "__kernel_exit:" "gimple"} } */ - -/* Expecting a work item loop because there are no barrier calls. */ -/* { dg-final { scan-tree-dump "if \\\(__local_x < __cur_wg_size_x\\\) goto __wi_loop_x; else goto" "gimple"} } */ -/* { dg-final { scan-tree-dump "if \\\(__local_y < __cur_wg_size_y\\\) goto __wi_loop_y; else goto" "gimple"} } */ -/* { dg-final { scan-tree-dump "if \\\(__local_z < __cur_wg_size_z\\\) goto __wi_loop_z; else goto" "gimple"} } */ - -/* The launcher should call __hsail_launch_wg_function in this case: */ -/* Kernel (void * restrict __context, unsigned char * restrict __group_base_addr) */ -/* { dg-final { scan-tree-dump "Kernel \\\(void \\\* restrict __context, unsigned char \\\* restrict __group_base_addr\\\)" "gimple"} } */ -/* { dg-final { scan-tree-dump "__hsail_launch_wg_function \\\(_Kernel, __context, __group_base_addr, group_local_offset.*\\\);" "gimple"} }*/ - -/* The kernel should have the magic metadata section injected to the ELF. */ -/* TODO: this should be disabled in case not outputting to an ELF. */ -/* Currently ELF is assumed by the brig frontend. Do not check for the context */ -/* as it is likely to change. */ -/* { dg-final { scan-tree-dump "\\\.pushsection phsa\\\.desc\\\.Kernel" "gimple"} }*/ - -/* The kernel with the barrier call should have the barrier builtin call in between the two summations. */ -/* { dg-final { scan-tree-dump "s2 = s0 \\\+ s1;\[\n \]+__builtin___hsail_barrier \\\(__context\\\);\[\n \]+s3 = s0 \\\+ 4294967295;" "gimple"} } */ - -/* The kernel with the barrier call's launcher function should call the thread-spawning function. */ -/* { dg-final { scan-tree-dump "__hsail_launch_kernel \\\(_KernelWithBarrier, __context, __group_base_addr, group_local_offset.*\\\);" "gimple" } } */ - - - diff --git a/gcc/testsuite/brig.dg/test/gimple/variables.hsail b/gcc/testsuite/brig.dg/test/gimple/variables.hsail deleted file mode 100644 index 5fd96c1c7bd..00000000000 --- a/gcc/testsuite/brig.dg/test/gimple/variables.hsail +++ /dev/null @@ -1,125 +0,0 @@ -module &module:1:0:$full:$large:$default; - -/* Tests for different variable scopes and address spaces. */ - -/* { dg-do compile } */ -/* { dg-options "-fdump-tree-gimple -fdump-tree-original" } */ - -prog align(256) private_u32 &prog_private; -private_u32 &mod_private; - -prog group_u32 &prog_group; -group_u32 &mod_group; - -prog global_u32 &prog_global; -global_u32 &mod_global; - -decl prog global_u32 &prog_global_host_def; - -prog readonly_u32 &prog_readonly; -readonly_u32 &mod_readonly; - -prog function &subfunction(arg_u32 %return_value)(arg_u32 %arg) { - - private_u32 %func_private; - group_u32 %func_group; - align(256) global_u32 %func_global; - readonly_u32 %func_readonly; - - ld_private_u32 $s200, [%func_private]; - st_private_u32 $s200, [&prog_private]; - -/* { dg-final { scan-tree-dump "__group_base_addr \\\+ \\\(0 \\\+" "original" } } */ - ld_group_u32 $s203, [%func_group]; - -/* { dg-final { scan-tree-dump "__group_base_addr \\\+ 0" "original" } } */ - st_group_u32 $s203, [&prog_group]; - - ld_global_u32 $s204, [%func_global]; - st_global_u32 $s204, [&prog_global]; - - ld_readonly_u32 $s205, [%func_readonly]; - st_global_u32 $s205, [%func_global]; - - st_arg_u32 $s2, [%return_value]; - ret; -}; - -prog kernel &kernel(kernarg_u64 %input_ptr, kernarg_u64 %output_ptr) -{ - private_u32 %kern_private; - group_u32 %kern_group; - global_u32 %kern_global; - readonly_u32 %kern_readonly; - - ld_kernarg_u64 $d0, [%input_ptr]; - ld_global_u32 $s0, [$d0]; - - ld_private_u32 $s2, [&prog_private]; - st_private_u32 $s2, [%kern_private]; - ld_private_u32 $s3, [&mod_private]; - st_private_u32 $s3, [&prog_private]; - - ld_group_u32 $s4, [&prog_group]; - st_group_u32 $s4, [%kern_group]; - ld_group_u32 $s5, [&mod_group]; - st_group_u32 $s5, [&prog_group]; - - ld_global_u32 $s6, [&prog_global]; - st_global_u32 $s6, [%kern_global]; - ld_global_u32 $s7, [&mod_global]; - st_global_u32 $s7, [&prog_global]; - - ld_readonly_u32 $s8, [&prog_readonly]; - st_global_u32 $s8, [%kern_global]; - ld_readonly_u32 $s9, [&mod_readonly]; - st_global_u32 $s9, [&prog_global]; - - ld_readonly_u32 $s10, [%kern_readonly]; - st_global_u32 $s10, [%kern_global]; - ld_readonly_u32 $s11, [%kern_readonly]; - st_global_u32 $s11, [&prog_global_host_def]; - - { - arg_u32 %arg; - arg_u32 %return_value; - st_arg_u32 $s1, [%arg]; - call &subfunction(%return_value)(%arg); - ld_arg_u32 $s1, [%return_value]; - } - ld_kernarg_u64 $d1, [%output_ptr]; - st_global_u32 $s1, [$d0]; -}; - -/* Private variable offsets assigned in the order of their appearance */ -/* - prog_private @0 (align 256) -> until 254 to ensure all WIs - mod_private @256 have their chunks aligned - func_private @260 - kern_private @264 -*/ - -/* Group variable offsets assigned in the order of their appearance */ -/* - prog_group @0 (2) - mod_group @4 (4) - func_group @8 (1) - kern_group @12 (3) -*/ - -/* The "mangling" of the global and readonly vars. */ -/* { dg-final { scan-tree-dump "\[ \]*prog_global = s204;" "gimple" } } */ - -/* { dg-final { scan-tree-dump "\.module.mod_global;" "gimple" } } */ - -/* Host defined variables need indirect access as the address is - known only at run time. */ -/* { dg-final { scan-tree-dump "\\\*\\\__phsa.host_def.prog_global_host_def.\[0-9\]+_\[0-9\]+ = s11;" "gimple" } } */ - -/* { dg-final { scan-tree-dump "\.subfunction.func_global;" "gimple" } } */ -/* { dg-final { scan-tree-dump "\.subfunction.func_readonly;" "gimple" } } */ - -/* { dg-final { scan-tree-dump "kernel.kern_global" "gimple" } } */ -/* { dg-final { scan-tree-dump "kernel.kern_readonly" "gimple" } } */ - - diff --git a/gcc/testsuite/brig.dg/test/gimple/vector.hsail b/gcc/testsuite/brig.dg/test/gimple/vector.hsail deleted file mode 100644 index 75293339542..00000000000 --- a/gcc/testsuite/brig.dg/test/gimple/vector.hsail +++ /dev/null @@ -1,57 +0,0 @@ -module &module:1:0:$full:$large:$default; - -/* A test for vector operands. */ - -/* { dg-do compile } */ -/* { dg-options "-fdump-tree-original" } */ - -prog kernel &Kernel(kernarg_u64 %input_ptr, kernarg_u64 %output_ptr) -{ - ld_kernarg_u64 $d0, [%input_ptr]; - ld_v2_global_f32 ($s0, $s1), [$d0]; - ld_v3_global_f32 ($s2, $s3, $s4), [$d0 + 8]; - ld_v4_global_f32 ($s5, $s6, $s7, $s8), [$d0 + 20]; - - add_f32 $s9, $s0, $s1; - combine_v2_b64_b32 $d2, ($s1, $s0); - combine_v2_b64_b32 $d3, ($s2, $s3); - - add_pp_f32x2 $d4, $d2, $d3; - - expand_v2_b32_b64 ($s0, $s3), $d4; - - ld_kernarg_u64 $d1, [%output_ptr]; - st_v2_global_f32 ($s0, $s1), [$d1]; - st_v3_global_f32 ($s2, $s3, $s4), [$d1 + 8]; - st_v4_global_f32 ($s5, $s6, $s7, $s8), [$d1 + 20]; - - ret; -}; - -/* The v2 load is done via casting to a vector datatype ptr. */ -/* { dg-final { scan-tree-dump " = MEM\\\[\\\(vector\\\(2\\\) \\\*\\\)" "original"} } */ - -/* The v3 load is scalarized (at the moment) due to gcc requiring 2's exponent wide vectors. */ -/* { dg-final { scan-tree-dump "s0 = .*BIT_FIELD_REF \\\)?;\[\n ]+s1 = .*BIT_FIELD_REF \\\)?;" "original"} } */ - -/* The v4 load is done via casting to a vector datatype ptr. */ -/* { dg-final { scan-tree-dump " = MEM\\\[\\\(vector\\\(4\\\) \\\*\\\)" "original"} } */ - -/* The combines are generated to vector constructors. */ -/* { dg-final { scan-tree-dump "{.*s1\\\)?, .*s0\\\)?}" "original"} } */ -/* { dg-final { scan-tree-dump "{.*s2\\\)?, .*s3\\\)?}" "original"} } */ - -/* Expands to BIT_FIELD_REFs. */ -/* { dg-final { scan-tree-dump "s0 = \(VIEW_CONVERT_EXPR.*\\\(\)?BIT_FIELD_REF \\\)?;" "original"} } */ -/* { dg-final { scan-tree-dump "s3 = \(VIEW_CONVERT_EXPR.*\\\(\)?BIT_FIELD_REF \\\)?;" "original"} } */ - -/* The v1 store is done via casting to a vector datatype ptr and constructing a vector from the inputs. */ -/* { dg-final { scan-tree-dump "MEM\\\[\\\(vector\\\(2\\\) \\\*\\\)\\\( \\\*\\\) d1\\\] = " "original"} } */ - -/* The v3 store is scalarized (at the moment) due to gcc requiring 2's exponent wide vectors. */ -/* { dg-final { scan-tree-dump "\\\*\\\( \\\*\\\) \\\(\\\(sizetype\\\) d1 \\\+ 8\\\) \\\+ 0 = VIEW_CONVERT_EXPR<>\\\(s2\\\);" "original"} } */ -/* { dg-final { scan-tree-dump "\\\*\\\( \\\*\\\) \\\(\\\(sizetype\\\) d1 \\\+ 8\\\) \\\+ 4 = VIEW_CONVERT_EXPR<>\\\(s3\\\);" "original"} } */ -/* { dg-final { scan-tree-dump "\\\*\\\( \\\*\\\) \\\(\\\(sizetype\\\) d1 \\\+ 8\\\) \\\+ 8 = VIEW_CONVERT_EXPR<>\\\(s4\\\);" "original"} } */ - -/* The v4 store is done via casting to a vector datatype and constructing a vector from the inputs. */ -/* { dg-final { scan-tree-dump "MEM\\\[\\\(vector\\\(4\\\) \\\*\\\)\\\( \\\*\\\) \\\(\\\(sizetype\\\) d1 \\\+ 20\\\)\\\] = {VIEW_CONVERT_EXPR<>\\\(s5\\\), VIEW_CONVERT_EXPR<>\\\(s6\\\), VIEW_CONVERT_EXPR<>\\\(s7\\\), VIEW_CONVERT_EXPR<>\\\(s8\\\)};" "original"} } */ diff --git a/gcc/testsuite/gfortran.dg/goacc/pr78027.f90 b/gcc/testsuite/gfortran.dg/goacc/pr78027.f90 index cf13ff7e6a9..415e3a17ecd 100644 --- a/gcc/testsuite/gfortran.dg/goacc/pr78027.f90 +++ b/gcc/testsuite/gfortran.dg/goacc/pr78027.f90 @@ -1,9 +1,5 @@ ! { dg-additional-options "-fopenmp -O2 -fdump-ipa-icf" } -! f951: warning: could not emit HSAIL for the function [-Whsa] -! f951: note: HSA does not support functions with variadic arguments (or unknown return type): 'GOACC_parallel_keyed' -! { dg-additional-options "-Wno-hsa" } - real function f() !$omp declare target(f) f = 1. diff --git a/gcc/testsuite/lib/brig-dg.exp b/gcc/testsuite/lib/brig-dg.exp deleted file mode 100644 index 41c55f91301..00000000000 --- a/gcc/testsuite/lib/brig-dg.exp +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (C) 2009-2021 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GCC; see the file COPYING3. If not see -# . - -load_lib gcc-dg.exp - -# Define brig callbacks for dg.exp. - -proc brig-dg-test { prog do_what extra_tool_flags } { - set result \ - [gcc-dg-test-1 brig_target_compile $prog $do_what $extra_tool_flags] - - set comp_output [lindex $result 0] - set output_file [lindex $result 1] - - return [list $comp_output $output_file] -} diff --git a/gcc/testsuite/lib/brig.exp b/gcc/testsuite/lib/brig.exp deleted file mode 100644 index d82cd884ad4..00000000000 --- a/gcc/testsuite/lib/brig.exp +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright (C) 2009-2021 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GCC; see the file COPYING3. If not see -# . - -load_lib prune.exp -load_lib gcc-defs.exp -load_lib timeout.exp -load_lib target-libpath.exp -# -# brig_target_compile -- compile a HSAIL input to BRIG using HSAILasm and then -# compile the BRIG to target ISA using gcc - -proc brig_target_compile { source dest type options } { - global tmpdir - global testname_with_flags - if { [file extension $source] == ".hsail" } { - # We cannot assume all inputs are .hsail as the dg machinery - # calls this for a some c files to check linker plugin support or - # similar. - set brig_source ${tmpdir}/[file rootname [file tail ${source}]].brig - exec HSAILasm $source -o ${brig_source} - set source ${brig_source} - # Change the testname the .brig. - set testname_with_flags [file tail $source] - } - return [target_compile $source $dest $type $options] -} -