2011-01-14 Richard Guenther <rguenther@suse.de>
+ PR tree-optimization/47179
+ * target.def (ref_may_alias_errno): New target hook.
+ * targhooks.h (default_ref_may_alias_errno): Declare.
+ * targhooks.c: Include tree-ssa-alias.h and tree-flow.h.
+ (default_ref_may_alias_errno): New function.
+ * target.h (struct ao_ref_s): Declare.
+ * tree-ssa-alias.c: Include target.h.
+ (call_may_clobber_ref_p_1): Use the ref_may_alias_errno target hook.
+ * Makefile.in (tree-ssa-alias.o): Adjust dependencies.
+ (targhooks.o): Likewise.
+ * doc/tm.texi.in (TARGET_REF_MAY_ALIAS_ERRNO): Document.
+ * doc/tm.texi (TARGET_REF_MAY_ALIAS_ERRNO): Copy documentation.
+
+2011-01-14 Richard Guenther <rguenther@suse.de>
+
* tree-ssa-structalias.c (new_var_info): Use DECL_HARD_REGISTER.
2011-01-14 Richard Guenther <rguenther@suse.de>
$(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) $(TREE_INLINE_H) $(FLAGS_H) \
$(FUNCTION_H) $(TIMEVAR_H) convert.h $(TM_H) coretypes.h langhooks.h \
$(TREE_DUMP_H) $(TREE_PASS_H) $(PARAMS_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) \
- $(GIMPLE_H) $(VEC_H) \
+ $(GIMPLE_H) $(VEC_H) $(TARGET_H) \
$(IPA_TYPE_ESCAPE_H) vecprim.h pointer-set.h alloc-pool.h \
tree-pretty-print.h
tree-ssa-reassoc.o : tree-ssa-reassoc.c $(TREE_FLOW_H) $(CONFIG_H) \
targhooks.o : targhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \
$(EXPR_H) $(TM_H) $(RTL_H) $(TM_P_H) $(FUNCTION_H) output.h $(DIAGNOSTIC_CORE_H) \
$(MACHMODE_H) $(TARGET_DEF_H) $(TARGET_H) $(GGC_H) gt-targhooks.h \
- $(OPTABS_H) $(RECOG_H) reload.h hard-reg-set.h intl.h $(OPTS_H)
+ $(OPTABS_H) $(RECOG_H) reload.h hard-reg-set.h intl.h $(OPTS_H) \
+ tree-ssa-alias.h $(TREE_FLOW_H)
bversion.h: s-bversion; @true
s-bversion: BASE-VER
hook returns true for both @code{ptr_mode} and @code{Pmode}.
@end deftypefn
+@deftypefn {Target Hook} bool TARGET_REF_MAY_ALIAS_ERRNO (struct ao_ref_s *@var{ref})
+Define this to return nonzero if the memory reference @var{ref} may alias with the system C library errno location. The default version of this hook assumes the system C library errno location is either a declaration of type int or accessed by dereferencing a pointer to int.
+@end deftypefn
+
@deftypefn {Target Hook} bool TARGET_SCALAR_MODE_SUPPORTED_P (enum machine_mode @var{mode})
Define this to return nonzero if the port is prepared to handle
insns involving scalar mode @var{mode}. For a scalar mode to be
hook returns true for both @code{ptr_mode} and @code{Pmode}.
@end deftypefn
+@hook TARGET_REF_MAY_ALIAS_ERRNO
+
@hook TARGET_SCALAR_MODE_SUPPORTED_P
Define this to return nonzero if the port is prepared to handle
insns involving scalar mode @var{mode}. For a scalar mode to be
bool, (enum machine_mode mode),
default_valid_pointer_mode)
+/* Disambiguate with errno. */
+DEFHOOK
+(ref_may_alias_errno,
+ "Define this to return nonzero if the memory reference @var{ref}\
+ may alias with the system C library errno location. The default\
+ version of this hook assumes the system C library errno location\
+ is either a declaration of type int or accessed by dereferencing\
+ a pointer to int.",
+ bool, (struct ao_ref_s *ref),
+ default_ref_may_alias_errno)
+
/* Support for named address spaces. */
#undef HOOK_PREFIX
#define HOOK_PREFIX "TARGET_ADDR_SPACE_"
/* This is defined in cfgloop.h . */
struct loop;
+/* This is defined in tree-ssa-alias.h. */
+struct ao_ref_s;
+
/* Assembler instructions for creating various kinds of integer object. */
struct asm_int_op
#include "recog.h"
#include "intl.h"
#include "opts.h"
+#include "tree-flow.h"
+#include "tree-ssa-alias.h"
bool
return (mode == ptr_mode || mode == Pmode);
}
+/* Determine whether the memory reference specified by REF may alias
+ the C libraries errno location. */
+bool
+default_ref_may_alias_errno (ao_ref *ref)
+{
+ tree base = ao_ref_base (ref);
+ /* The default implementation assumes the errno location is
+ a declaration of type int or is always accessed via a
+ pointer to int. We assume that accesses to errno are
+ not deliberately obfuscated (even in conforming ways). */
+ if (TYPE_UNSIGNED (TREE_TYPE (base))
+ || TYPE_MODE (TREE_TYPE (base)) != TYPE_MODE (integer_type_node))
+ return false;
+ /* The default implementation assumes an errno location
+ declaration is never defined in the current compilation unit. */
+ if (DECL_P (base)
+ && !TREE_STATIC (base))
+ return true;
+ else if (TREE_CODE (base) == MEM_REF
+ && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
+ {
+ struct ptr_info_def *pi = SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0));
+ return !pi || pi->pt.anything || pi->pt.nonlocal;
+ }
+ return false;
+}
+
/* Return the mode for a pointer to a given ADDRSPACE, defaulting to ptr_mode
for the generic address space only. */
extern bool default_target_option_pragma_parse (tree, tree);
extern bool default_target_can_inline_p (tree, tree);
extern bool default_valid_pointer_mode (enum machine_mode);
+extern bool default_ref_may_alias_errno (struct ao_ref_s *);
extern enum machine_mode default_addr_space_pointer_mode (addr_space_t);
extern enum machine_mode default_addr_space_address_mode (addr_space_t);
extern bool default_addr_space_valid_pointer_mode (enum machine_mode,
#include "tm.h"
#include "tree.h"
#include "tm_p.h"
+#include "target.h"
#include "basic-block.h"
#include "timevar.h"
#include "ggc.h"
being the definition point for the pointer. */
case BUILT_IN_MALLOC:
case BUILT_IN_CALLOC:
- /* Unix98 specifies that errno is set on allocation failure.
- Until we properly can track the errno location assume it
- is not a local decl but external or anonymous storage in
- a different translation unit. Also assume it is of
- type int as required by the standard. */
+ /* Unix98 specifies that errno is set on allocation failure. */
if (flag_errno_math
- && TREE_TYPE (base) == integer_type_node)
- {
- struct ptr_info_def *pi;
- if (DECL_P (base)
- && !TREE_STATIC (base))
- return true;
- else if ((INDIRECT_REF_P (base)
- || TREE_CODE (base) == MEM_REF)
- && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME
- && (pi = SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0))))
- return pi->pt.anything || pi->pt.nonlocal;
- }
+ && targetm.ref_may_alias_errno (ref))
+ return true;
return false;
/* Freeing memory kills the pointed-to memory. More importantly
the call has to serve as a barrier for moving loads and stores