diff options
Diffstat (limited to 'gcc/gimple-caster.c')
-rw-r--r-- | gcc/gimple-caster.c | 41 |
1 files changed, 34 insertions, 7 deletions
diff --git a/gcc/gimple-caster.c b/gcc/gimple-caster.c index 299bbf6abfb..3452c552baa 100644 --- a/gcc/gimple-caster.c +++ b/gcc/gimple-caster.c @@ -22,11 +22,31 @@ GimpleCaster::_walk_pre(gassign *s) const_tree t_lhs = TREE_TYPE(lhs); const_tree t_rhs = TREE_TYPE(rhs); gcc_assert(t_lhs && t_rhs); - const bool is_cast = !equality.equal(t_lhs, t_rhs); + bool is_cast = !equality.equal(t_lhs, t_rhs); + TypeStringifier stringifier; + const std::string name_l = stringifier.stringify(t_lhs); + const std::string name_r = stringifier.stringify(t_rhs); + // If it is cast, we might need to look at the definition of rhs + // If the definition comes from a known function... then we are good... + bool is_ssa = TREE_CODE(rhs) == SSA_NAME; + while (is_ssa) { + gimple *def_for_rhs = SSA_NAME_DEF_STMT(rhs); + gcall *is_call = dyn_cast<gcall*>(def_for_rhs); + if (!is_call) break; + + const_tree fn = gimple_call_fndecl(is_call); + if (!fn) break; + + cgraph_node *node = cgraph_node::get(fn); + bool known_function = GimpleEscaper::filter_known_function(node); + is_cast = !known_function; + + is_ssa = false; + } reason.is_escaping = is_cast; reason.type_is_casted = is_cast; - exprEscaper.update(lhs, reason); - exprEscaper.update(rhs, reason); + exprEscaper.update_single_level(lhs, reason); + exprEscaper.update_single_level(rhs, reason); // TODO: // I think this will re-do the work... But it might be necessary? GimpleEscaper::_walk_pre(s); @@ -38,7 +58,15 @@ GimpleCaster::_walk_pre(gcall *s) GimpleEscaper::_walk_pre(s); const_tree fn = gimple_call_fndecl(s); - cgraph_node *node = cgraph_node::get(fn); + // gcc_assert(fn) + // The above will not always be true + if (!fn) + { + //TODO: We should at least assert that the types are already + //marked as escaping? + return; + } + cgraph_node *node = fn ? cgraph_node::get(fn) : NULL; const bool known_function = GimpleEscaper::filter_known_function(node); if (known_function) return; @@ -58,11 +86,10 @@ GimpleCaster::_walk_pre(gcall *s) const bool is_casted = !equality.equal(formal_t, real_t); const std::string name_r = stringifier.stringify(real_t); const std::string name_f = stringifier.stringify(formal_t); - log("looking at casted argument %s == %s ? %s\n", name_r.c_str(), name_f.c_str(), is_casted ? "t" : "f"); Reason arg_reason; arg_reason.is_escaping = is_casted; arg_reason.type_is_casted = is_casted; - exprEscaper.update(real, arg_reason); + exprEscaper.update_single_level(real, arg_reason); i++; } @@ -85,5 +112,5 @@ GimpleCaster::_walk_pre(gcall *s) Reason ret_reason; ret_reason.is_escaping = is_casted; ret_reason.type_is_casted = is_casted; - exprEscaper.update(lhs, ret_reason); + exprEscaper.update_single_level(lhs, ret_reason); } |