annotate gcc/brig/brigfrontend/brig-mem-inst-handler.cc @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* brig-mem-inst-handler.cc -- brig memory inst handler
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2 Copyright (C) 2016-2018 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
3 Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
kono
parents:
diff changeset
4 for General Processor Tech.
kono
parents:
diff changeset
5
kono
parents:
diff changeset
6 This file is part of GCC.
kono
parents:
diff changeset
7
kono
parents:
diff changeset
8 GCC is free software; you can redistribute it and/or modify it under
kono
parents:
diff changeset
9 the terms of the GNU General Public License as published by the Free
kono
parents:
diff changeset
10 Software Foundation; either version 3, or (at your option) any later
kono
parents:
diff changeset
11 version.
kono
parents:
diff changeset
12
kono
parents:
diff changeset
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
kono
parents:
diff changeset
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
kono
parents:
diff changeset
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
kono
parents:
diff changeset
16 for more details.
kono
parents:
diff changeset
17
kono
parents:
diff changeset
18 You should have received a copy of the GNU General Public License
kono
parents:
diff changeset
19 along with GCC; see the file COPYING3. If not see
kono
parents:
diff changeset
20 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
21
kono
parents:
diff changeset
22 #include "brig-code-entry-handler.h"
kono
parents:
diff changeset
23
kono
parents:
diff changeset
24 #include "errors.h"
kono
parents:
diff changeset
25 #include "brig-util.h"
kono
parents:
diff changeset
26 #include "gimple-expr.h"
kono
parents:
diff changeset
27 #include "print-tree.h"
kono
parents:
diff changeset
28 #include "tree-pretty-print.h"
kono
parents:
diff changeset
29 #include "convert.h"
kono
parents:
diff changeset
30 #include "diagnostic-core.h"
kono
parents:
diff changeset
31
kono
parents:
diff changeset
32 tree
kono
parents:
diff changeset
33 brig_mem_inst_handler::build_mem_access (const BrigInstBase *brig_inst,
kono
parents:
diff changeset
34 tree addr, tree data)
kono
parents:
diff changeset
35 {
kono
parents:
diff changeset
36 bool is_load = brig_inst->opcode == BRIG_OPCODE_LD;
kono
parents:
diff changeset
37 bool is_store = brig_inst->opcode == BRIG_OPCODE_ST;
kono
parents:
diff changeset
38
kono
parents:
diff changeset
39 if (!is_load && !is_store)
kono
parents:
diff changeset
40 gcc_unreachable ();
kono
parents:
diff changeset
41
kono
parents:
diff changeset
42 tree instr_type = gccbrig_tree_type_for_hsa_type (brig_inst->type);
kono
parents:
diff changeset
43
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
44 /* In case of {ld,st}_v{2,4}. Note: since 'register' variables may
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
45 be any type, even a vector type, we distinguish the registers
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
46 from operand lists by checking for constructor nodes (which
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
47 operand lists are represented as). */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
48 if (VECTOR_TYPE_P (TREE_TYPE (data)) && TREE_CODE (data) == CONSTRUCTOR)
111
kono
parents:
diff changeset
49 instr_type = TREE_TYPE (data);
kono
parents:
diff changeset
50
kono
parents:
diff changeset
51 tree ptype = build_pointer_type (instr_type);
kono
parents:
diff changeset
52
kono
parents:
diff changeset
53 /* The HSAIL mem instructions are unaligned by default.
kono
parents:
diff changeset
54 TODO: exploit the align modifier, it should lead to faster code.
kono
parents:
diff changeset
55 */
kono
parents:
diff changeset
56 tree unaligned_type = build_aligned_type (instr_type, 8);
kono
parents:
diff changeset
57
kono
parents:
diff changeset
58 /* Create a mem ref from the previous result, without offset. */
kono
parents:
diff changeset
59 tree mem_ref
kono
parents:
diff changeset
60 = build2 (MEM_REF, unaligned_type, addr, build_int_cst (ptype, 0));
kono
parents:
diff changeset
61
kono
parents:
diff changeset
62 if (is_load)
kono
parents:
diff changeset
63 {
kono
parents:
diff changeset
64 /* Add a temporary variable so there won't be multiple
kono
parents:
diff changeset
65 reads in case of vector unpack. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
66 mem_ref = m_parent.m_cf->add_temp_var ("mem_read", mem_ref);
111
kono
parents:
diff changeset
67 return build_output_assignment (*brig_inst, data, mem_ref);
kono
parents:
diff changeset
68 }
kono
parents:
diff changeset
69 else
kono
parents:
diff changeset
70 {
kono
parents:
diff changeset
71 tree stmt = build2 (MODIFY_EXPR, TREE_TYPE (mem_ref), mem_ref, data);
kono
parents:
diff changeset
72 return m_parent.m_cf->append_statement (stmt);
kono
parents:
diff changeset
73 }
kono
parents:
diff changeset
74 return mem_ref;
kono
parents:
diff changeset
75 }
kono
parents:
diff changeset
76
kono
parents:
diff changeset
77 size_t
kono
parents:
diff changeset
78 brig_mem_inst_handler::operator () (const BrigBase *base)
kono
parents:
diff changeset
79 {
kono
parents:
diff changeset
80 const BrigInstBase *brig_inst
kono
parents:
diff changeset
81 = (const BrigInstBase *) &((const BrigInstBasic *) base)->base;
kono
parents:
diff changeset
82
kono
parents:
diff changeset
83 if (brig_inst->opcode == BRIG_OPCODE_ALLOCA)
kono
parents:
diff changeset
84 {
kono
parents:
diff changeset
85 tree_stl_vec operands = build_operands (*brig_inst);
kono
parents:
diff changeset
86 size_t alignment = 1;
kono
parents:
diff changeset
87 const BrigInstMem *mem_inst = (const BrigInstMem *) brig_inst;
kono
parents:
diff changeset
88 if (mem_inst->align != BRIG_ALIGNMENT_NONE)
kono
parents:
diff changeset
89 {
kono
parents:
diff changeset
90 alignment = 1 << (mem_inst->align - 1);
kono
parents:
diff changeset
91 }
kono
parents:
diff changeset
92
kono
parents:
diff changeset
93 tree align_opr = build_int_cstu (size_type_node, alignment);
kono
parents:
diff changeset
94 tree_stl_vec inputs;
kono
parents:
diff changeset
95 inputs.push_back (operands[1]);
kono
parents:
diff changeset
96 inputs.push_back (align_opr);
kono
parents:
diff changeset
97 tree builtin_call
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
98 = m_parent.m_cf->expand_or_call_builtin (BRIG_OPCODE_ALLOCA,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
99 BRIG_TYPE_U32,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
100 uint32_type_node, inputs);
111
kono
parents:
diff changeset
101 build_output_assignment (*brig_inst, operands[0], builtin_call);
kono
parents:
diff changeset
102 m_parent.m_cf->m_has_allocas = true;
kono
parents:
diff changeset
103 return base->byteCount;
kono
parents:
diff changeset
104 }
kono
parents:
diff changeset
105
kono
parents:
diff changeset
106 tree instr_type = gccbrig_tree_type_for_hsa_type (brig_inst->type);
kono
parents:
diff changeset
107
kono
parents:
diff changeset
108 const BrigData *operand_entries
kono
parents:
diff changeset
109 = m_parent.get_brig_data_entry (brig_inst->operands);
kono
parents:
diff changeset
110
kono
parents:
diff changeset
111 uint32_t data_operand_offset;
kono
parents:
diff changeset
112 memcpy (&data_operand_offset, &operand_entries->bytes, 4);
kono
parents:
diff changeset
113
kono
parents:
diff changeset
114 const BrigBase *operand
kono
parents:
diff changeset
115 = m_parent.get_brig_operand_entry (data_operand_offset);
kono
parents:
diff changeset
116
kono
parents:
diff changeset
117 const BrigData *operandData = NULL;
kono
parents:
diff changeset
118
kono
parents:
diff changeset
119 bool is_store = brig_inst->opcode == BRIG_OPCODE_ST;
kono
parents:
diff changeset
120
kono
parents:
diff changeset
121 bool is_three_element_vector_access
kono
parents:
diff changeset
122 = operand->kind == BRIG_KIND_OPERAND_OPERAND_LIST
kono
parents:
diff changeset
123 && (operandData = m_parent.get_brig_data_entry
kono
parents:
diff changeset
124 (((const BrigOperandOperandList *) operand)->elements))
kono
parents:
diff changeset
125 && operandData->byteCount / 4 == 3;
kono
parents:
diff changeset
126
kono
parents:
diff changeset
127 if (is_three_element_vector_access)
kono
parents:
diff changeset
128 {
kono
parents:
diff changeset
129 /* We need to scalarize the 3-element vector accesses here
kono
parents:
diff changeset
130 because gcc assumes the GENERIC vector datatypes are of two exponent
kono
parents:
diff changeset
131 size internally. */
kono
parents:
diff changeset
132 size_t bytes = operandData->byteCount;
kono
parents:
diff changeset
133 const BrigOperandOffset32_t *operand_ptr
kono
parents:
diff changeset
134 = (const BrigOperandOffset32_t *) operandData->bytes;
kono
parents:
diff changeset
135
kono
parents:
diff changeset
136 uint32_t addr_operand_offset;
kono
parents:
diff changeset
137 memcpy (&addr_operand_offset, &operand_entries->bytes + 4, 4);
kono
parents:
diff changeset
138
kono
parents:
diff changeset
139 const BrigOperandAddress *addr_operand
kono
parents:
diff changeset
140 = (const BrigOperandAddress *) m_parent.get_brig_operand_entry
kono
parents:
diff changeset
141 (addr_operand_offset);
kono
parents:
diff changeset
142
kono
parents:
diff changeset
143 tree address_base = build_address_operand (*brig_inst, *addr_operand);
kono
parents:
diff changeset
144
kono
parents:
diff changeset
145 uint32_t address_offset = 0;
kono
parents:
diff changeset
146 while (bytes > 0)
kono
parents:
diff changeset
147 {
kono
parents:
diff changeset
148 BrigOperandOffset32_t offset = *operand_ptr;
kono
parents:
diff changeset
149 const BrigBase *operand_element
kono
parents:
diff changeset
150 = m_parent.get_brig_operand_entry (offset);
kono
parents:
diff changeset
151 tree data
kono
parents:
diff changeset
152 = build_tree_operand (*brig_inst, *operand_element, instr_type);
kono
parents:
diff changeset
153
kono
parents:
diff changeset
154 tree ptr_offset = build_int_cst (size_type_node, address_offset);
kono
parents:
diff changeset
155 tree address = build2 (POINTER_PLUS_EXPR, TREE_TYPE (address_base),
kono
parents:
diff changeset
156 address_base, ptr_offset);
kono
parents:
diff changeset
157
kono
parents:
diff changeset
158 if (is_store && TREE_TYPE (data) != instr_type)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
159 data = build_resize_convert_view (instr_type, data);
111
kono
parents:
diff changeset
160
kono
parents:
diff changeset
161 build_mem_access (brig_inst, address, data);
kono
parents:
diff changeset
162
kono
parents:
diff changeset
163 address_offset += int_size_in_bytes (instr_type);
kono
parents:
diff changeset
164 ++operand_ptr;
kono
parents:
diff changeset
165 bytes -= 4;
kono
parents:
diff changeset
166 }
kono
parents:
diff changeset
167 }
kono
parents:
diff changeset
168 else
kono
parents:
diff changeset
169 {
kono
parents:
diff changeset
170 tree_stl_vec operands = build_operands (*brig_inst);
kono
parents:
diff changeset
171
kono
parents:
diff changeset
172 tree &data = operands.at (0);
kono
parents:
diff changeset
173 tree &addr = operands.at (1);
kono
parents:
diff changeset
174 build_mem_access (brig_inst, addr, data);
kono
parents:
diff changeset
175 }
kono
parents:
diff changeset
176
kono
parents:
diff changeset
177 return base->byteCount;
kono
parents:
diff changeset
178 }