This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFA PATCH, i386] Implement automatic x87/MMX mode switching, take 3


Hello!

  This patch implements third version of FPU mode switching between
x87 and MMX mode. The changes from previous version include:

  - Mode switching is now enabled only if TARGET_MMX _and_
TARGET_80387 are both enabled. This simplifies code a bit and we can
always default to FPU_MODE_X87 (as was suggested by rth some time ago)
if no MMX registers are used to pass parameters to function or no MMX
registers are used as a return register from function.

- EPILOGUE_USES, CALL_INSN_USES and CALL_INSN_SETS are now enabled
only when mode changing instruction is emitted (emitted efpu, emms or
call insn that changes mode set ix86_fpu_mode_changed flag). Those
macros change global register life information, so life analysis is
needed after mode_switching pass. However, life analysis is performed
only when ix86_fpu_mode_changed flag is set. This substantially lowers
compilation time for functions that don't switch modes. Additional
feature of this change is, that by clearing optimize_mode_switching
flag for I387_FPU_MODE entity in ix86_init_machine_status () disables
mode switching entirely.

Patch was bootstrapped on i686-pc-linux-gnu, regtested for c and c++.
Two additional regressions are introduced, gcc.dg/i386-3dnow-2.c and
gcc.dg/i386-3dnowA-2.c in addition to gcc.dg/20020218-1.c.

The problem uncovered by this patch can be shown by compiling
following testcase:

--cut here--
typedef int __m64 __attribute__ ((__vector_size__ (8)));
typedef float __v2sf __attribute__ ((__vector_size__ (8)));

__m64
_m_from_float (float __A)
{
  return (__m64)(__v2sf){ __A, 0 };
}
--cut here--

gcc -O0 -m3dnow 3dnow.c
3dnow.c: In function â_m_from_floatâ:
3dnow.c:8: internal compiler error: in ix86_secondary_memory_needed,
at config/i386/i386.c:15720

This looks like a generic problem to me, as the compilation fails only
for -O0 (and the asm code is rather suspicious even for -mno-80387).
It looks like mm3dnow.h has bitrotten, because a m_from_int ()
function from mmintrin.h is implemented differently, by using
__builtin_ia32_vec_init_v2si builtin. I'll look into this problem and
eventually implement __builtin_ia32_vec_init_v2sf builtin.

(A midlevel support patch at
http://gcc.gnu.org/ml/gcc-patches/2005-07/msg00894.html must be
applied for this patch to work properly).

OK for mainline?

2005-07-13  Uros Bizjak  <uros@kss-loka.si>

	* reg-stack.c (subst_stack_regs_pat): Handle MMX/x87 FPU mode
	UNSPEC_EFPU and UNSPEC_EMMS switching instructions.
	(subst_stack_regs): Handle CALL_INSN_SETS for stack registers.
	(convert_regs_entry): Do not emit stack compensation code if
	all stack regs are live at function entry.
	(convert_regs_exit): Handle EPILOGUE_USES mentioned stack
	registers at function exit.

	* config/i386/i386-modes.def (ALLREGS): New RANDOM_MODE.

	* config/i386/i386-protos.h (emit_i387_cw_initialization):
	Remove prototype.
	(ix86_epilogue_uses): New prototype.
	(ix86_call_insn_sets): New prototype.
	(ix86_call_insn_uses): New prototype.
	(ix86_mode_after): New prototype.
	(ix86_mode_entry): New prototype.
	(ix86_mode_exit): New prototype.
	(ix86_emit_mode_set): New prototype.

	* config/i386/i386.h (HARD_REGNO_NREGS):Return 8 for
	ALLREGS mode.
	(EPILOGUE_USES): New define.
	(CALL_INSN_SETS): New define.
	(CALL_INSN_USES): New define.
	(enum ix86_fpu_mode): New enum.
	(enum ix86_entity): Add new I387_FPU_MODE entity.
	(NUM_MODES_FOR_MODE_SWITCHING): Add FPU_MODE_ANY to
	enable switching for I387_FPU_MODE entity.
	(LIFE_ANALYSIS_AFTER_MODE_SWITCHING): New define.
	(MODE_AFTER): New define.
	(MODE_ENTRY): New define.
	(MODE_EXIT): New define.
	(EMIT_MODE_SET): Change definition to use ix86_emit_mode_set.
	(struct machine_function): Add fpu_mode_changed variable.
	(ix86_fpu_mode_changed): New define.

	* config/i386/i386.c (ix86_mode_needed): Handle I387_FPU_MODE
	entity.
	(ix86_mode_after): New function.
	(ix86_mode_entry): New function.
	(ix86_mode_exit): New function.
	(ix86_emit_mode_set): Renamed from emit_i387_cw_initialization.
	Handle I387_FPU_MODE entity.
	(ix86_init_machine_status): Set optimize_mode_switching flag
	for I387_FPU_MODE entity if (TARGET_80387 && TARGET_MMX).
	(ix86_epilogue_uses): New function.
	(ix86_call_insn_uses): New function.
	(ix86_call_insn_sets): New function.
	(ix86_expand_builtin) [IX86_BUILTIN_EMMS, IX86_BUILTIN_FEMMS]:
	Do not emit instruction patterns anymore.

	* config/i386/i386.md (UNSPECV_FEMMS): Remove UNSPECV constant.
	(UNSPECV_EFPU): New UNSPECV constant.
	(FIRSTFP_REG, FIRSTMMX_REG): New constants.

	* config/i386/mmx.md ("efpu", "emms"): New instruction definitions.
	("mmx_emms", "mmx_femms"): Remove instruction definition.

Uros.

Attachment: emms_3.diff
Description: Binary data


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]