aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/auto-profile.cc228
-rw-r--r--gcc/config/i386/mmx.md11
-rw-r--r--gcc/lra-constraints.cc19
3 files changed, 144 insertions, 114 deletions
diff --git a/gcc/auto-profile.cc b/gcc/auto-profile.cc
index 5226e455..d1954b4 100644
--- a/gcc/auto-profile.cc
+++ b/gcc/auto-profile.cc
@@ -240,6 +240,8 @@ public:
/* Add new name and return its index. */
int add_name (char *);
+ /* Return cgraph node corresponding to given name index. */
+ cgraph_node *get_cgraph_node (int);
private:
typedef std::map<const char *, unsigned, string_compare> string_index_map;
string_vector vector_;
@@ -445,7 +447,6 @@ public:
/* Lookup count and warn about duplicates. */
count_info *lookup_count (location_t loc, inline_stack &stack,
cgraph_node *node);
-
private:
/* Callsite, represented as (decl_lineno, callee_function_name_index). */
typedef std::pair<unsigned, unsigned> callsite;
@@ -888,21 +889,13 @@ string_table::read ()
return true;
}
-/* Member functions for function_instance. */
-
-function_instance::~function_instance ()
-{
- gcc_assert (!in_worklist_p ());
- for (callsite_map::iterator iter = callsites.begin ();
- iter != callsites.end (); ++iter)
- delete iter->second;
-}
-
-/* Return corresponding cgraph node, NULL if unavailable. */
+/* Return cgraph node corresponding to given NAME_INDEX,
+ NULL if unavailable. */
cgraph_node *
-function_instance::get_cgraph_node ()
+string_table::get_cgraph_node (int name_index)
{
- const char *sname = afdo_string_table->get_name (name ());
+ const char *sname = get_name (name_index);
+
symtab_node *n = cgraph_node::get_for_asmname (get_identifier (sname));
for (;n; n = n->next_sharing_asm_name)
if (cgraph_node *cn = dyn_cast <cgraph_node *> (n))
@@ -911,6 +904,24 @@ function_instance::get_cgraph_node ()
return NULL;
}
+/* Return corresponding cgraph node. */
+
+cgraph_node *
+function_instance::get_cgraph_node ()
+{
+ return afdo_string_table->get_cgraph_node (name ());
+}
+
+/* Member functions for function_instance. */
+
+function_instance::~function_instance ()
+{
+ gcc_assert (!in_worklist_p ());
+ for (callsite_map::iterator iter = callsites.begin ();
+ iter != callsites.end (); ++iter)
+ delete iter->second;
+}
+
/* Traverse callsites of the current function_instance to find one at the
location of LINENO and callee name represented in DECL. */
@@ -1169,7 +1180,7 @@ match_with_target (cgraph_node *n,
}
/* Accept dwarf names and stripped suffixes. */
if (!strcmp (lang_hooks.dwarf_name (callee->decl, 0),
- afdo_string_table->get_name (inlined_fn->name ()))
+ afdo_string_table->get_name (inlined_fn->name ()))
|| (!name[i] && symbol_name[i] == '.')
|| in_suffix)
{
@@ -1183,8 +1194,8 @@ match_with_target (cgraph_node *n,
inlined_fn->set_name (index);
return 2;
}
- /* Only warn about declarations. It is possible that the function is
- declared as alias in other module and we inlined cross-module. */
+ /* Only warn about declarations. It is possible that the function
+ is declared as alias in other module and we inlined cross-module. */
if (callee->definition
&& warning (OPT_Wauto_profile,
"auto-profile of %q+F contains inlined "
@@ -1491,8 +1502,8 @@ function_instance::match (cgraph_node *node,
== inlined_fn);
callsite key2 = {stack[0].afdo_loc,
inlined_fn->name ()};
- callsites[key2] = inlined_fn;
callsites.erase (iter);
+ callsites[key2] = inlined_fn;
}
if (r)
functions.add (inlined_fn);
@@ -1554,10 +1565,10 @@ function_instance::match (cgraph_node *node,
callsite key2 = {stack[0].afdo_loc,
newn ? *newn
: inlined_fn->name ()};
+ callsites.erase (iter);
callsites[key2] = inlined_fn;
inlined_fn->set_name (newn ? *newn
: inlined_fn->name ());
- callsites.erase (iter);
}
functions.add (inlined_fn);
}
@@ -1690,7 +1701,6 @@ function_instance::match (cgraph_node *node,
f->dump_inline_stack (dump_file);
fprintf (dump_file, "\n");
}
- warned = true;
callsites.erase (iter);
offline (f, new_functions);
iter = callsites.begin ();
@@ -1752,9 +1762,9 @@ function_instance::remove_external_functions
auto iter = callsites.find (key);
callsite key2 = key;
key2.second = *to_symbol_name.get (key.second);
- callsites[key2] = iter->second;
iter->second->set_name (key2.second);
callsites.erase (iter);
+ callsites[key2] = iter->second;
}
auto_vec <int, 20> target_to_rename;
for (auto &iter : pos_counts)
@@ -1951,6 +1961,7 @@ autofdo_source_profile::offline_external_functions ()
cgraph_node *node;
name_index_set seen;
name_index_map to_symbol_name;
+ size_t last_name;
/* Add renames erasing suffixes produced by late clones, such as
.isra, .ipcp. */
@@ -1986,10 +1997,10 @@ autofdo_source_profile::offline_external_functions ()
index = afdo_string_table->add_name (n2);
to_symbol_name.put (i, index);
}
+ last_name = afdo_string_table->num_entries ();
FOR_EACH_DEFINED_FUNCTION (node)
{
- const char *name
- = raw_symbol_name (node->decl);
+ const char *name = raw_symbol_name (node->decl);
const char *dwarf_name = lang_hooks.dwarf_name (node->decl, 0);
int index = afdo_string_table->get_index (name);
@@ -2026,11 +2037,17 @@ autofdo_source_profile::offline_external_functions ()
{
if (dump_file)
{
- fprintf (dump_file,
- "Node %s not in auto profile (%s neither %s)\n",
- node->dump_name (),
- name,
- dwarf_name);
+ if (dwarf_name && strcmp (dwarf_name, name))
+ fprintf (dump_file,
+ "Node %s not in auto profile (%s neither %s)\n",
+ node->dump_name (),
+ name,
+ dwarf_name);
+ else
+ fprintf (dump_file,
+ "Node %s (symbol %s) not in auto profile\n",
+ node->dump_name (),
+ name);
}
}
}
@@ -2074,72 +2091,87 @@ autofdo_source_profile::offline_external_functions ()
should be done on unmodified profile and merging works better if
mismatches are already resolved both in source and destination. */
while (fns.length () || fns2.length ())
- if (fns.length ())
- {
- function_instance *f = fns.pop ();
- if (f->get_location () == UNKNOWN_LOCATION)
- {
- int index = f->name ();
- int *newn = to_symbol_name.get (index);
- if (newn)
- {
- f->set_name (*newn);
- if (map_.count (index)
- && map_[index] == f)
- map_.erase (index);
- if (!map_.count (*newn))
- map_[*newn] = f;
- }
- if (cgraph_node *n = f->get_cgraph_node ())
- {
- gcc_checking_assert (seen.contains (f->name ()));
- f->match (n, fns, to_symbol_name);
- }
- }
- fns2.safe_push (f);
- }
- else
- {
- function_instance *f = fns2.pop ();
- int index = f->name ();
- gcc_checking_assert (f->in_worklist_p ());
+ {
+ /* In case renaming introduced new name, keep seen up to date. */
+ for (; last_name < afdo_string_table->num_entries (); last_name++)
+ {
+ const char *name = afdo_string_table->get_name (last_name);
+ symtab_node *n
+ = afdo_string_table->get_cgraph_node (last_name);
+ if (dump_file)
+ fprintf (dump_file, "New name %s %s\n", name,
+ n ? "wth corresponding definition"
+ : "with no corresponding definition");
+ if (n)
+ seen.add (last_name);
+ }
+ if (fns.length ())
+ {
+ function_instance *f = fns.pop ();
+ if (f->get_location () == UNKNOWN_LOCATION)
+ {
+ int index = f->name ();
+ int *newn = to_symbol_name.get (index);
+ if (newn)
+ {
+ f->set_name (*newn);
+ if (map_.count (index)
+ && map_[index] == f)
+ map_.erase (index);
+ if (!map_.count (*newn))
+ map_[*newn] = f;
+ }
+ if (cgraph_node *n = f->get_cgraph_node ())
+ {
+ gcc_checking_assert (seen.contains (f->name ()));
+ f->match (n, fns, to_symbol_name);
+ }
+ }
+ fns2.safe_push (f);
+ }
+ else
+ {
+ function_instance *f = fns2.pop ();
+ int index = f->name ();
+ gcc_checking_assert (f->in_worklist_p ());
- /* If map has different function_instance of same name, then
- this is a duplicated entry which needs to be merged. */
- if (map_.count (index) && map_[index] != f)
- {
- if (dump_file)
- {
- fprintf (dump_file, "Merging duplicate instance: ");
- f->dump_inline_stack (dump_file);
- fprintf (dump_file, "\n");
- }
- map_[index]->merge (f, fns);
- gcc_checking_assert (!f->inlined_to ());
- f->clear_in_worklist ();
- delete f;
- }
- /* If name was not seen in the symbol table, remove it. */
- else if (!seen.contains (index))
- {
- f->offline_if_in_set (seen, fns);
- f->clear_in_worklist ();
- if (dump_file)
- fprintf (dump_file, "Removing external %s\n",
- afdo_string_table->get_name (f->name ()));
- if (map_.count (index) && map_[index] == f)
- map_.erase (f->name ());
- delete f;
- }
- /* If this is offline function instance seen in this
- translation unit offline external inlines and possibly
- rename from dwarf name. */
- else
- {
- f->remove_external_functions (seen, to_symbol_name, fns);
- f->clear_in_worklist ();
- }
- }
+ /* If map has different function_instance of same name, then
+ this is a duplicated entry which needs to be merged. */
+ if (map_.count (index) && map_[index] != f)
+ {
+ if (dump_file)
+ {
+ fprintf (dump_file, "Merging duplicate instance: ");
+ f->dump_inline_stack (dump_file);
+ fprintf (dump_file, "\n");
+ }
+ map_[index]->merge (f, fns);
+ gcc_checking_assert (!f->inlined_to ());
+ f->clear_in_worklist ();
+ delete f;
+ }
+ /* If name was not seen in the symbol table, remove it. */
+ else if (!seen.contains (index))
+ {
+ f->offline_if_in_set (seen, fns);
+ f->clear_in_worklist ();
+ if (dump_file)
+ fprintf (dump_file, "Removing external %s\n",
+ afdo_string_table->get_name (f->name ()));
+ if (map_.count (index) && map_[index] == f)
+ map_.erase (f->name ());
+ delete f;
+ }
+ /* If this is offline function instance seen in this
+ translation unit offline external inlines and possibly
+ rename from dwarf name. */
+ else
+ {
+ f->remove_external_functions (seen, to_symbol_name, fns);
+ f->clear_in_worklist ();
+ }
+ }
+ }
if (dump_file)
for (auto const &iter : map_)
{
@@ -2288,7 +2320,7 @@ autofdo_source_profile::offline_unrealized_inlines ()
function_instance *
function_instance::read_function_instance (function_instance_stack *stack,
- gcov_type head_count)
+ gcov_type head_count)
{
unsigned name = gcov_read_unsigned ();
unsigned num_pos_counts = gcov_read_unsigned ();
@@ -2311,10 +2343,10 @@ function_instance::read_function_instance (function_instance_stack *stack,
(*stack)[j]->total_count_ += count;
for (unsigned j = 0; j < num_targets; j++)
{
- /* Only indirect call target histogram is supported now. */
- gcov_read_unsigned ();
- gcov_type target_idx = gcov_read_counter ();
- s->pos_counts[offset].targets[target_idx] = gcov_read_counter ();
+ /* Only indirect call target histogram is supported now. */
+ gcov_read_unsigned ();
+ gcov_type target_idx = gcov_read_counter ();
+ s->pos_counts[offset].targets[target_idx] = gcov_read_counter ();
}
}
for (unsigned i = 0; i < num_callsites; i++)
diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md
index 7920232..29a8cb5 100644
--- a/gcc/config/i386/mmx.md
+++ b/gcc/config/i386/mmx.md
@@ -329,7 +329,7 @@
(define_expand "mov<mode>"
[(set (match_operand:V_32 0 "nonimmediate_operand")
- (match_operand:V_32 1 "nonimmediate_operand"))]
+ (match_operand:V_32 1 "nonimm_or_0_operand"))]
""
{
ix86_expand_vector_move (<MODE>mode, operands);
@@ -339,7 +339,7 @@
(define_insn "*mov<mode>_internal"
[(set (match_operand:V_32 0 "nonimmediate_operand"
"=r ,m ,v,v,v,m,r,v")
- (match_operand:V_32 1 "general_operand"
+ (match_operand:V_32 1 "nonimm_or_0_operand"
"rmC,rC,C,v,m,v,v,r"))]
"!(MEM_P (operands[0]) && MEM_P (operands[1]))
&& ix86_hardreg_mov_ok (operands[0], operands[1])"
@@ -457,7 +457,7 @@
(define_expand "movv2qi"
[(set (match_operand:V2QI 0 "nonimmediate_operand")
- (match_operand:V2QI 1 "nonimmediate_operand"))]
+ (match_operand:V2QI 1 "nonimm_or_0_operand"))]
""
{
ix86_expand_vector_move (V2QImode, operands);
@@ -467,9 +467,10 @@
(define_insn "*movv2qi_internal"
[(set (match_operand:V2QI 0 "nonimmediate_operand"
"=r,r,r,m ,v,v,v,jm,m,r,v")
- (match_operand:V2QI 1 "general_operand"
+ (match_operand:V2QI 1 "nonimm_or_0_operand"
"r ,C,m,rC,C,v,m,x,v,v,r"))]
- "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
+ "!(MEM_P (operands[0]) && MEM_P (operands[1]))
+ && ix86_hardreg_mov_ok (operands[0], operands[1])"
{
switch (get_attr_type (insn))
{
diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc
index 274b52cd..c941d2f 100644
--- a/gcc/lra-constraints.cc
+++ b/gcc/lra-constraints.cc
@@ -2416,14 +2416,15 @@ process_alt_operands (int only_alternative)
if (curr_static_id->operand[nop].type == OP_INOUT
|| curr_static_id->operand[m].type == OP_INOUT)
break;
- /* Operands don't match. If the operands are
- different user defined explicit hard
+ /* Operands don't match. For asm if the operands
+ are different user defined explicit hard
registers, then we cannot make them match
when one is early clobber operand. */
if ((REG_P (*curr_id->operand_loc[nop])
|| SUBREG_P (*curr_id->operand_loc[nop]))
&& (REG_P (*curr_id->operand_loc[m])
- || SUBREG_P (*curr_id->operand_loc[m])))
+ || SUBREG_P (*curr_id->operand_loc[m]))
+ && INSN_CODE (curr_insn) < 0)
{
rtx nop_reg = *curr_id->operand_loc[nop];
if (SUBREG_P (nop_reg))
@@ -3328,19 +3329,15 @@ process_alt_operands (int only_alternative)
first_conflict_j = j;
last_conflict_j = j;
/* Both the earlyclobber operand and conflicting operand
- cannot both be user defined hard registers. */
+ cannot both be user defined hard registers for asm.
+ Let curr_insn_transform diagnose it. */
if (HARD_REGISTER_P (operand_reg[i])
&& REG_USERVAR_P (operand_reg[i])
&& operand_reg[j] != NULL_RTX
&& HARD_REGISTER_P (operand_reg[j])
- && REG_USERVAR_P (operand_reg[j]))
- {
- /* For asm, let curr_insn_transform diagnose it. */
- if (INSN_CODE (curr_insn) < 0)
+ && REG_USERVAR_P (operand_reg[j])
+ && INSN_CODE (curr_insn) < 0)
return false;
- fatal_insn ("unable to generate reloads for "
- "impossible constraints:", curr_insn);
- }
}
if (last_conflict_j < 0)
continue;