]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/d/d-gimplify.cc
Change references of .c files to .cc files
[thirdparty/gcc.git] / gcc / d / d-gimplify.cc
CommitLineData
e53b6e56 1/* D-specific tree lowering bits; see also gimple.cc.
7adcbafe 2 Copyright (C) 2020-2022 Free Software Foundation, Inc.
e966361c
IB
3
4GCC is free software; you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation; either version 3, or (at your option)
7any later version.
8
9GCC is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with GCC; see the file COPYING3. If not see
16<http://www.gnu.org/licenses/>. */
17
18#include "config.h"
19#include "system.h"
20#include "coretypes.h"
21
22#include "dmd/globals.h"
23
24#include "tree.h"
25#include "gimple-expr.h"
26#include "gimplify.h"
27
28#include "d-tree.h"
29
30
31/* Return TRUE if an operand OP of a given TYPE being copied has no data.
32 The middle-end does a similar check with zero sized types. */
33
34static bool
35empty_modify_p (tree type, tree op)
36{
37 tree_code code = TREE_CODE (op);
38 switch (code)
39 {
40 case COMPOUND_EXPR:
41 return empty_modify_p (type, TREE_OPERAND (op, 1));
42
43 case CONSTRUCTOR:
44 /* Non-empty construcors are valid. */
45 if (CONSTRUCTOR_NELTS (op) != 0 || TREE_CLOBBER_P (op))
46 return false;
47 break;
48
49 case CALL_EXPR:
50 /* Leave nrvo alone because it isn't a copy. */
51 if (CALL_EXPR_RETURN_SLOT_OPT (op))
52 return false;
53 break;
54
55 default:
56 /* If the operand doesn't have a simple form. */
57 if (!is_gimple_lvalue (op) && !INDIRECT_REF_P (op))
58 return false;
59 break;
60 }
61
62 return empty_aggregate_p (type);
63}
64
747f01eb 65/* Gimplify assignment from an INIT_EXPR or MODIFY_EXPR. */
e966361c 66
747f01eb
IB
67static gimplify_status
68d_gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
e966361c 69{
747f01eb
IB
70 tree op0 = TREE_OPERAND (*expr_p, 0);
71 tree op1 = TREE_OPERAND (*expr_p, 1);
e966361c 72
747f01eb
IB
73 if (error_operand_p (op0) || error_operand_p (op1))
74 return GS_UNHANDLED;
75
76 /* Remove any copies of empty aggregates. */
77 if (empty_modify_p (TREE_TYPE (op0), op1))
e966361c 78 {
747f01eb
IB
79 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
80 is_gimple_lvalue, fb_lvalue);
e966361c 81
747f01eb
IB
82 if (TREE_SIDE_EFFECTS (op1))
83 gimplify_and_add (op1, pre_p);
e966361c 84
747f01eb
IB
85 *expr_p = TREE_OPERAND (*expr_p, 0);
86 return GS_OK;
87 }
e966361c 88
747f01eb
IB
89 /* If the back end isn't clever enough to know that the lhs and rhs
90 types are the same, add an explicit conversion. */
91 if ((AGGREGATE_TYPE_P (TREE_TYPE (op0)) || AGGREGATE_TYPE_P (TREE_TYPE (op1)))
92 && !useless_type_conversion_p (TREE_TYPE (op1), TREE_TYPE (op0)))
93 {
94 TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR,
95 TREE_TYPE (op0), op1);
96 return GS_OK;
97 }
e966361c 98
747f01eb
IB
99 return GS_UNHANDLED;
100}
101
102/* Gimplify an ADDR_EXPR node. */
103
104static gimplify_status
105d_gimplify_addr_expr (tree *expr_p)
106{
107 tree op0 = TREE_OPERAND (*expr_p, 0);
108 /* Constructors are not lvalues, so make them one. */
109 if (TREE_CODE (op0) == CONSTRUCTOR)
110 {
111 TREE_OPERAND (*expr_p, 0) = force_target_expr (op0);
112 return GS_OK;
113 }
114
115 return GS_UNHANDLED;
116}
117
118/* Gimplify a CALL_EXPR node. */
119
120static gimplify_status
121d_gimplify_call_expr (tree *expr_p, gimple_seq *pre_p)
122{
0fb57034
IB
123 /* Strictly evaluate all arguments from left to right. */
124 int nargs = call_expr_nargs (*expr_p);
125 location_t loc = EXPR_LOC_OR_LOC (*expr_p, input_location);
747f01eb 126
0fb57034
IB
127 /* No need to enforce evaluation order if only one argument. */
128 if (nargs < 2)
129 return GS_UNHANDLED;
747f01eb 130
0fb57034
IB
131 /* Or if all arguments are already free of side-effects. */
132 bool has_side_effects = false;
133 for (int i = 0; i < nargs; i++)
134 {
135 if (TREE_SIDE_EFFECTS (CALL_EXPR_ARG (*expr_p, i)))
e966361c 136 {
0fb57034
IB
137 has_side_effects = true;
138 break;
e966361c 139 }
0fb57034 140 }
e966361c 141
0fb57034
IB
142 if (!has_side_effects)
143 return GS_UNHANDLED;
e966361c 144
0fb57034
IB
145 /* Leave the last argument for gimplify_call_expr. */
146 for (int i = 0; i < nargs - 1; i++)
147 {
148 tree new_arg = CALL_EXPR_ARG (*expr_p, i);
e966361c 149
0fb57034
IB
150 /* If argument has a side-effect, gimplify_arg will handle it. */
151 if (gimplify_arg (&new_arg, pre_p, loc) == GS_ERROR)
152 return GS_ERROR;
e966361c 153
0fb57034
IB
154 /* Even if an argument itself doesn't have any side-effects, it
155 might be altered by another argument in the list. */
156 if (new_arg == CALL_EXPR_ARG (*expr_p, i)
157 && !really_constant_p (new_arg))
158 new_arg = get_formal_tmp_var (new_arg, pre_p);
e966361c 159
0fb57034 160 CALL_EXPR_ARG (*expr_p, i) = new_arg;
747f01eb 161 }
e966361c 162
0fb57034 163 return GS_OK;
747f01eb 164}
e966361c 165
747f01eb 166/* Gimplify an UNSIGNED_RSHIFT_EXPR node. */
e966361c 167
747f01eb
IB
168static gimplify_status
169d_gimplify_unsigned_rshift_expr (tree *expr_p)
170{
171 /* Convert op0 to an unsigned type. */
172 tree op0 = TREE_OPERAND (*expr_p, 0);
173 tree op1 = TREE_OPERAND (*expr_p, 1);
174 tree type = d_unsigned_type (TREE_TYPE (op0));
175
176 *expr_p = convert (TREE_TYPE (*expr_p),
177 build2 (RSHIFT_EXPR, type, convert (type, op0), op1));
178 return GS_OK;
179}
e966361c 180
747f01eb
IB
181/* Implements the lang_hooks.gimplify_expr routine for language D.
182 Do gimplification of D specific expression trees in EXPR_P. */
e966361c 183
747f01eb
IB
184int
185d_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
186{
187 switch (TREE_CODE (*expr_p))
188 {
189 case INIT_EXPR:
190 case MODIFY_EXPR:
191 return d_gimplify_modify_expr (expr_p, pre_p, post_p);
e966361c 192
747f01eb
IB
193 case ADDR_EXPR:
194 return d_gimplify_addr_expr (expr_p);
e966361c 195
747f01eb
IB
196 case CALL_EXPR:
197 return d_gimplify_call_expr (expr_p, pre_p);
198
199 case UNSIGNED_RSHIFT_EXPR:
200 return d_gimplify_unsigned_rshift_expr (expr_p);
e966361c
IB
201
202 case FLOAT_MOD_EXPR:
203 gcc_unreachable ();
204
205 default:
206 break;
207 }
208
747f01eb 209 return GS_UNHANDLED;
e966361c 210}