2015-07-09 11:01:51 +02:00
|
|
|
/* Lower and optimize address expressions.
|
2017-01-01 13:07:43 +01:00
|
|
|
Copyright (C) 2015-2017 Free Software Foundation, Inc.
|
2015-07-09 11:01:51 +02:00
|
|
|
Contributed by Marek Polacek <polacek@redhat.com>
|
|
|
|
|
|
|
|
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
|
|
|
|
<http://www.gnu.org/licenses/>. */
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
#include "system.h"
|
|
|
|
#include "coretypes.h"
|
|
|
|
#include "alias.h"
|
|
|
|
#include "predict.h"
|
|
|
|
#include "tm.h"
|
|
|
|
#include "function.h"
|
|
|
|
#include "dominance.h"
|
|
|
|
#include "cfg.h"
|
|
|
|
#include "basic-block.h"
|
|
|
|
#include "tree-ssa-alias.h"
|
|
|
|
#include "symtab.h"
|
|
|
|
#include "tree.h"
|
|
|
|
#include "stringpool.h"
|
2016-08-20 07:43:01 +02:00
|
|
|
#include "tree-vrp.h"
|
2015-07-09 11:01:51 +02:00
|
|
|
#include "tree-ssanames.h"
|
|
|
|
#include "fold-const.h"
|
|
|
|
#include "gimple-expr.h"
|
|
|
|
#include "gimple.h"
|
|
|
|
#include "gimplify.h"
|
|
|
|
#include "gimple-iterator.h"
|
|
|
|
#include "gimplify-me.h"
|
|
|
|
#include "tree-pass.h"
|
|
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
const pass_data pass_data_laddress =
|
|
|
|
{
|
|
|
|
GIMPLE_PASS, /* type */
|
|
|
|
"laddress", /* name */
|
|
|
|
OPTGROUP_NONE, /* optinfo_flags */
|
|
|
|
TV_GIMPLE_LADDRESS, /* tv_id */
|
|
|
|
( PROP_cfg | PROP_ssa ), /* properties_required */
|
|
|
|
0, /* properties_provided */
|
|
|
|
0, /* properties_destroyed */
|
|
|
|
0, /* todo_flags_start */
|
|
|
|
0, /* todo_flags_finish */
|
|
|
|
};
|
|
|
|
|
|
|
|
class pass_laddress : public gimple_opt_pass
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
pass_laddress (gcc::context *ctxt)
|
|
|
|
: gimple_opt_pass (pass_data_laddress, ctxt)
|
|
|
|
{}
|
|
|
|
|
|
|
|
/* opt_pass methods: */
|
|
|
|
opt_pass * clone () { return new pass_laddress (m_ctxt); }
|
|
|
|
virtual bool gate (function *) { return optimize != 0; }
|
|
|
|
virtual unsigned int execute (function *);
|
|
|
|
|
|
|
|
}; // class pass_laddress
|
|
|
|
|
|
|
|
unsigned int
|
|
|
|
pass_laddress::execute (function *fun)
|
|
|
|
{
|
|
|
|
basic_block bb;
|
|
|
|
|
|
|
|
FOR_EACH_BB_FN (bb, fun)
|
|
|
|
{
|
|
|
|
for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
|
|
|
|
{
|
2015-09-20 02:52:59 +02:00
|
|
|
gimple *stmt = gsi_stmt (gsi);
|
2015-07-09 11:01:51 +02:00
|
|
|
if (!is_gimple_assign (stmt)
|
|
|
|
|| gimple_assign_rhs_code (stmt) != ADDR_EXPR
|
|
|
|
|| is_gimple_invariant_address (gimple_assign_rhs1 (stmt)))
|
|
|
|
{
|
|
|
|
gsi_next (&gsi);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Lower ADDR_EXPR assignments:
|
|
|
|
_4 = &b[i_9];
|
|
|
|
into
|
|
|
|
_1 = (sizetype) i_9;
|
|
|
|
_7 = _1 * 4;
|
|
|
|
_4 = &b + _7;
|
|
|
|
This ought to aid the vectorizer and expose CSE opportunities.
|
|
|
|
*/
|
|
|
|
|
|
|
|
tree expr = gimple_assign_rhs1 (stmt);
|
|
|
|
HOST_WIDE_INT bitsize, bitpos;
|
|
|
|
tree base, offset;
|
|
|
|
machine_mode mode;
|
2015-11-08 19:33:42 +01:00
|
|
|
int volatilep = 0, reversep, unsignedp = 0;
|
2015-07-09 11:01:51 +02:00
|
|
|
base = get_inner_reference (TREE_OPERAND (expr, 0), &bitsize,
|
|
|
|
&bitpos, &offset, &mode, &unsignedp,
|
Convert TYPE_ALIGN_OK to a TYPE_LANG_FLAG.
2016-07-11 Bernd Edlinger <bernd.edlinger@hotmail.de>
Convert TYPE_ALIGN_OK to a TYPE_LANG_FLAG.
* tree-core.h (tree_base::nothrow_flag): Adjust comment.
(tree_type_common::lang_flag_7): New.
(tree_type_common::spare): Reduce size.
* tree.h (TYPE_ALIGN_OK): Remove.
(TYPE_LANG_FLAG_7): New.
(get_inner_reference): Adjust header.
* print-tree.c (print_node): Adjust.
* expr.c (get_inner_reference): Remove parameter keep_aligning.
(get_bit_range, expand_assignment, expand_expr_addr_expr_1): Adjust
calls to get_inner_reference.
(expand_expr_real_1): Adjust call to get_inner_reference. Remove
handling of TYPE_ALIGN_OK.
* builtins.c (get_object_alignment_2): Adjust call to
get_inner_reference. Remove handling of VIEW_CONVERT_EXPR.
* emit-rtl.c (set_mem_attributes_minus_bitpos): Remove handling of
TYPE_ALIGN_OK.
* asan.c (instrument_derefs): Adjust calls to get_inner_reference.
* cfgexpand.c (expand_debug_expr): Likewise.
* dbxout.c (dbxout_expand_expr): Likewise.
* dwarf2out.c (loc_list_for_address_of_addr_expr_of_indirect_ref,
loc_list_from_tree, fortran_common): Likewise.
* fold-const.c (optimize_bit_field_compare,
decode_field_reference, fold_unary_loc, fold_comparison,
split_address_to_core_and_offset): Likewise.
* gimple-laddress.c (execute): Likewise.
* gimple-ssa-strength-reduction.c (slsr_process_ref): Likewise.
* gimplify.c (gimplify_scan_omp_clauses): Likewise.
* hsa-gen.c (gen_hsa_addr): Likewise.
* simplifx-rtx.c (delegitimize_mem_from_attrs): Likewise.
* tsan.c (instrument_expr): Likewise.
* ubsan.c (instrument_bool_enum_load, instrument_object_size): Likewise.
* tree.c (verify_type_variant): Remove handling of TYPE_ALIGN_OK.
* tree-affine.c (tree_to_aff_combination,
get_inner_reference_aff): Adjust calls to get_inner_reference.
* tree-data-ref.c (split_constant_offset_1,
dr_analyze_innermost): Likewise.
* tree-scalar-evolution.c (interpret_rhs_expr): Likewise.
* tree-sra.c (ipa_sra_check_caller): Likewise.
* tree-ssa-loop-ivopts.c (split_address_cost): Likewise.
* tree-ssa-math-opts.c (find_bswap_or_nop_load,
bswap_replace): Likewise.
* tree-vect-data-refs.c (vect_check_gather,
vect_analyze_data_refs): Likewise.
* config/mips/mips.c (r10k_safe_mem_expr_p): Likewise.
* config/pa/pa.c (pa_emit_move_sequence): Remove handling of
TYPE_ALIGN_OK.
ada:
2016-07-11 Bernd Edlinger <bernd.edlinger@hotmail.de>
Convert TYPE_ALIGN_OK to a TYPE_LANG_FLAG.
* gcc-interface/ada-tree.h (TYPE_ALIGN_OK): Define.
* gcc-interface/trans.c (Attribute_to_gnu): Adjust call to
get_inner_reference.
* gcc-interface/utils2.c (build_unary_op): Likewise.
From-SVN: r238210
2016-07-11 17:02:12 +02:00
|
|
|
&reversep, &volatilep);
|
2015-07-09 11:01:51 +02:00
|
|
|
gcc_assert (base != NULL_TREE && (bitpos % BITS_PER_UNIT) == 0);
|
|
|
|
if (offset != NULL_TREE)
|
|
|
|
{
|
|
|
|
if (bitpos != 0)
|
|
|
|
offset = size_binop (PLUS_EXPR, offset,
|
|
|
|
size_int (bitpos / BITS_PER_UNIT));
|
|
|
|
offset = force_gimple_operand_gsi (&gsi, offset, true, NULL,
|
|
|
|
true, GSI_SAME_STMT);
|
|
|
|
base = build_fold_addr_expr (base);
|
|
|
|
base = force_gimple_operand_gsi (&gsi, base, true, NULL,
|
|
|
|
true, GSI_SAME_STMT);
|
2015-09-20 02:52:59 +02:00
|
|
|
gimple *g = gimple_build_assign (gimple_assign_lhs (stmt),
|
2015-07-09 11:01:51 +02:00
|
|
|
POINTER_PLUS_EXPR, base, offset);
|
|
|
|
gsi_replace (&gsi, g, false);
|
|
|
|
}
|
|
|
|
gsi_next (&gsi);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // anon namespace
|
|
|
|
|
|
|
|
gimple_opt_pass *
|
|
|
|
make_pass_laddress (gcc::context *ctxt)
|
|
|
|
{
|
|
|
|
return new pass_laddress (ctxt);
|
|
|
|
}
|