Ping [ARM back-end and middle-end patch] stack check for threads

2012-01-09 Thread Thomas Klein

Hello

Even if I'm going to bore everyone.
Is it possible to get an answer from the ARM maintainers?
This is a serious question, and I hope there will be a serious answer.

Regards
 Thomas Klein

reference:
http://gcc.gnu.org/ml/gcc-patches/2011-12/msg01774.html



Ping [ARM back-end and middle-end patch] stack check for threads

2011-12-28 Thread Thomas Klein

ping

I would like to introduce two new -fstack-check options named direct and 
indirect.
Targets that did not supporting the new stack checking options will work 
as before.

At the ARM platform the old generic options is working as before.
(Including that is now possible to have a checking code sequence even if 
optimization

is switched on.)
The check against a given limit value while doing dynamic stack 
allocation is now

also working, too.
This was not the case due to missing trap function.
For this case I've added a code sequence to let "generic" act like the 
dynamic part

doing a compare against a given limit value.
I'm treating this as keeping old stuff alive.

Back to my new options I like to have here.
Maybe you are happy with the above, but I'm not.
Sometimes you do not have a one single limit value that is valid for all.
For example if you are having an environment with threads and each 
threads is using

its own stack at an different location.
In case all functions should have a common knowledge about a global 
limit variable

which is holding the limit value.
This limit value can be used to check if a stack overflow has occurred 
or not.


There are two ways to inform the compiler about this limit variable.
 If it is an ordinary variable (located somewhere in data space) you 
should

 use the option combination
 -fstack-check=indirect and -fstack-limit-symbol=global_stack_limit

 If it is a register global variable you should use the option combination
 -fstack-check=direct} and -fstack-limit-register=r6
 In this case you have to make sure that this register isn't be used by 
others.

 For example you can add the option -ffixed-r6 to all files that are
 not going to do stack checking.
The OS is responsible to insert the correct limit value.
For example at the end of a context switch.

I've added a little bit of documentation, too.
This may not be as god as you expect, but it the best I can do.
Sorry for that.

I have added some tests running on arm simulator and linux arm target 
machine.
I'm using ../src/configure --target=arm-elf and --target=arm-elf-eabi 
cross compilers

and running tests with:
gmake check-gcc RUNTESTFLAGS="--target_board=arm-sim arm_stack_check.exp"
Also using a native linux compiler (on armv7-a machine) and running 
tests with:

gmake check-gcc RUNTESTFLAGS="arm_stack_check.exp"

Each test case is done with:
- stack checking variants
  generic using a limit-symbol, generic using a limit register,
  direct using a limit-symbol, direct using a limit register and
  indirect using a limit-symbol
- various modes ARM, Thumb, (and if possible with Thumb-2)
- With and without optimization.
- Without -fpic, with -fpic and with -fpic -msingle-pic-base

I have also detected a minor bug if using combination:
-fpic -mpic-register=r9 -march=armv4t -mthumb.
(A move of the hi register to a lo register is missing here.)
So I've added the few lines of code in here, too.
Maybe you think that this is a nasty hack, so insert a better one instead.

All tests succeeds.

I'm still thinking that my idea isn't that bad.
How ever any feedback from the ARM maintainers would be god.
Even if is something like: "We hate this bull shit at all."
Any feedback is better than no feedback.

Regards
  Thomas Klein

references
http://gcc.gnu.org/ml/gcc-patches/2011-09/msg01261.html
http://gcc.gnu.org/ml/gcc-patches/2011-09/msg00310.html
http://gcc.gnu.org/ml/gcc-patches/2011-08/msg00216.html
http://gcc.gnu.org/ml/gcc-patches/2011-07/msg00281.html
http://gcc.gnu.org/ml/gcc-patches/2011-07/msg00149.html
http://gcc.gnu.org/ml/gcc-patches/2011-06/msg01872.html
http://gcc.gnu.org/ml/gcc-patches/2011-03/msg01226.html


ChangeLog.check.bz2
Description: Binary data


gcc.diff_chk.bz2
Description: Binary data


gcc.diff_dep.bz2
Description: Binary data


ChangeLog.test.bz2
Description: Binary data


gcc.diff_test.bz2
Description: Binary data


Ping [ARM back-end and middle-end patch] stack check for threads

2011-09-21 Thread Thomas Klein

ping

rename subject line due to
http://gcc.gnu.org/ml/gcc-patches/2011-09/msg01189.html

references
http://gcc.gnu.org/ml/gcc-patches/2011-09/msg00310.html
http://gcc.gnu.org/ml/gcc-patches/2011-08/msg00216.html
http://gcc.gnu.org/ml/gcc-patches/2011-07/msg00281.html
http://gcc.gnu.org/ml/gcc-patches/2011-07/msg00149.html
http://gcc.gnu.org/ml/gcc-patches/2011-06/msg01872.html
http://gcc.gnu.org/ml/gcc-patches/2011-03/msg01226.html

gcc/ChangeLog

2011-09-21  Thomas Klein 
* opts.c (common_handle_option): introduce new parameters "direct" and
"indirect"
* flag-types.h (enum stack_check_type): Likewise

* explow.c (allocate_dynamic_stack_space):
- suppress stack probing if parameter "direct", "indirect" or if a
stack-limit is given
- do additional read of limit value if parameter "indirect" and a
stack-limit symbol is given
- emit a call to a stack_failure function [as an alternative to a trap
call]
(function probe_stack_range): if allowed to override the range porbe
emit generic_limit_check_stack

* config/arm/arm.c
(stack_check_work_registers): new function to find possible working
registers [only used by "stack check"]
(emit_push_regs): add push RTL instruction without keeping regnumber
and frame memory in mind.
(emit_pop_regs): add pop RTL instruction to revert the above push
(emit_stack_check_insns): new function to write RTL instructions for
stack check at prologue stage.
(arm_expand_prologue): stack check integration for ARM and Thumb-2
(thumb1_output_function_prologue): stack check integration for Thumb-1

* config/arm/arm.md
(cbranchsi4_insn): allow compare and branch using stack pointer
register [at thumb mode]
(arm_cmpsi_insn): allow comparing using stack pointer register [at arm]
(probe_stack): do not emit code when parameters "direct" or "indirect"
is given, emit move code way same as in gcc/explow.c [function
emit_stack_probe]
(probe_stack_done): dummy to make sure probe_stack insns are not
optimized away
(generic_limit_check_stack): if stack-limit and parameter "generic" is
given use the limit the same way as in function
allocate_dynamic_stack_space
(stack_failure): failure call used in stack check functions
emit_stack_check_insns, generic_limit_check_stack or
allocate_dynamic_stack_space [similar to a trap but avoid conflict with
builtin_trap]

Index: gcc/opts.c
===
--- gcc/opts.c  (revision 179052)
+++ gcc/opts.c  (working copy)
@@ -1644,6 +1644,12 @@ common_handle_option (struct gcc_options *opts,
   : STACK_CHECK_STATIC_BUILTIN
 ? STATIC_BUILTIN_STACK_CHECK
 : GENERIC_STACK_CHECK;
+  else if (!strcmp (arg, "indirect"))
+   /* This is an other stack checking method.  */
+   opts->x_flag_stack_check = INDIRECT_STACK_CHECK;
+  else if (!strcmp (arg, "direct"))
+   /* This is an other stack checking method.  */
+   opts->x_flag_stack_check = DIRECT_STACK_CHECK;
   else
warning_at (loc, 0, "unknown stack check parameter \"%s\"", arg);
   break;
Index: gcc/flag-types.h
===
--- gcc/flag-types.h(revision 179052)
+++ gcc/flag-types.h(working copy)
@@ -153,7 +153,15 @@ enum stack_check_type
 
   /* Check the stack and entirely rely on the target configuration
  files, i.e. do not use the generic mechanism at all.  */
-  FULL_BUILTIN_STACK_CHECK
+  FULL_BUILTIN_STACK_CHECK,
+
+  /* Check the stack (if possible) before allocation of local variables at
+ each function entry. The stack limit is directly given e.g. by address
+ of a symbol */
+  DIRECT_STACK_CHECK,
+  /* Check the stack (if possible) before allocation of local variables at
+ each function entry. The stack limit is given by global variable. */
+  INDIRECT_STACK_CHECK
 };
 
 /* Names for the different levels of -Wstrict-overflow=N.  The numeric
Index: gcc/explow.c
===
--- gcc/explow.c(revision 179052)
+++ gcc/explow.c(working copy)
@@ -1386,7 +1386,12 @@ allocate_dynamic_stack_space (rtx size, unsigned s
 
   /* If needed, check that we have the required amount of stack.  Take into
  account what has already been checked.  */
-  if (STACK_CHECK_MOVING_SP)
+  if (  STACK_CHECK_MOVING_SP 
+#ifdef HAVE_generic_limit_check_stack
+ || crtl->limit_stack
+#endif
+ || flag_stack_check == DIRECT_STACK_CHECK
+ || flag_stack_check == INDIRECT_STACK_CHECK)
 ;
   else if (flag_stack_check == GENERIC_STACK_CHECK)
 probe_stack_range (STACK_OLD_CHECK_PROTECT + STACK_CHECK_MAX_FRAME_SIZE,
@@ -1423,19 +1428,32 @@ allocate_dynamic_stack_space (rtx size, unsigned s
   /* Check stack bounds if necessary.  */
   if (crtl->limit_