gcc/gcc/gimple-laddress.c

139 lines
3.6 KiB
C
Raw Permalink Normal View History

/* Lower and optimize address expressions.
Copyright (C) 2015-2017 Free Software Foundation, Inc.
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"
#include "tree-vrp.h"
#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);)
{
gimple *stmt = gsi_stmt (gsi);
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;
int volatilep = 0, reversep, unsignedp = 0;
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);
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);
gimple *g = gimple_build_assign (gimple_assign_lhs (stmt),
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);
}