diff -cr gcc.orig/cgraph.c gcc/cgraph.c
*** gcc.orig/cgraph.c	2008-08-13 22:38:39.000000000 +0100
--- gcc/cgraph.c	2010-10-27 18:25:21.540795001 +0100
***************
*** 201,206 ****
--- 201,207 ----
  cgraph_node (tree decl)
  {
    struct cgraph_node key, *node, **slot;
+   tree context;
  
    gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
  
***************
*** 222,233 ****
    node = cgraph_create_node ();
    node->decl = decl;
    *slot = node;
!   if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL)
      {
!       node->origin = cgraph_node (DECL_CONTEXT (decl));
!       node->next_nested = node->origin->nested;
!       node->origin->nested = node;
!       node->master_clone = node;
      }
    return node;
  }
--- 223,238 ----
    node = cgraph_create_node ();
    node->decl = decl;
    *slot = node;
!   if (!DECL_NO_STATIC_CHAIN (decl))
      {
!       context = decl_function_context (decl);
!       if (context)
! 	{
! 	  node->origin = cgraph_node (context);
! 	  node->next_nested = node->origin->nested;
! 	  node->origin->nested = node;
! 	  node->master_clone = node;
! 	}
      }
    return node;
  }
diff -cr gcc.orig/config/i386/i386.c gcc/config/i386/i386.c
*** gcc.orig/config/i386/i386.c	2010-03-18 20:58:49.000000000 +0000
--- gcc/config/i386/i386.c	2010-10-27 18:29:33.728795000 +0100
***************
*** 5707,5712 ****
--- 5707,5715 ----
      frame->red_zone_size = 0;
    frame->to_allocate -= frame->red_zone_size;
    frame->stack_pointer_offset -= frame->red_zone_size;
+   if (cfun->naked)
+     /* As above, skip return address */
+     frame->stack_pointer_offset = UNITS_PER_WORD;
  #if 0
    fprintf (stderr, "nregs: %i\n", frame->nregs);
    fprintf (stderr, "size: %i\n", size);
***************
*** 20551,20557 ****
  	  output_set_got (tmp, NULL_RTX);
  
  	  xops[1] = tmp;
! 	  output_asm_insn ("mov{l}\t{%0@GOT(%1), %1|%1, %0@GOT[%1]}", xops);
  	  output_asm_insn ("jmp\t{*}%1", xops);
  	}
      }
--- 20554,20560 ----
  	  output_set_got (tmp, NULL_RTX);
  
  	  xops[1] = tmp;
! 	  output_asm_insn ("mov{l}\t{%a0@GOT(%1), %1|%1, %0@GOT[%1]}", xops);
  	  output_asm_insn ("jmp\t{*}%1", xops);
  	}
      }
diff -cr gcc.orig/config/rs6000/rs6000.c gcc/config/rs6000/rs6000.c
*** gcc.orig/config/rs6000/rs6000.c	2009-07-31 19:05:38.000000000 +0100
--- gcc/config/rs6000/rs6000.c	2010-10-27 18:30:14.400795000 +0100
***************
*** 17932,17937 ****
--- 17932,17938 ----
  	 Java is 13.  Objective-C is 14.  Objective-C++ isn't assigned
  	 a number, so for now use 9.  */
        if (! strcmp (language_string, "GNU C"))
+ 	  || ! strcmp (language_string, "GNU D"))
  	i = 0;
        else if (! strcmp (language_string, "GNU F77")
  	       || ! strcmp (language_string, "GNU F95"))
diff -cr gcc.orig/convert.c gcc/convert.c
*** gcc.orig/convert.c	2008-07-15 23:56:59.000000000 +0100
--- gcc/convert.c	2010-10-27 18:31:59.272795002 +0100
***************
*** 30,39 ****
--- 30,43 ----
  #include "tree.h"
  #include "flags.h"
  #include "convert.h"
+ #if 0
  /* APPLE LOCAL begin AltiVec */
  #include "c-tree.h"
  #include "c-common.h"
  /* APPLE LOCAL end AltiVec */
+ #else
+ #include "c-common.h"
+ #endif
  #include "toplev.h"
  #include "langhooks.h"
  #include "real.h"
***************
*** 854,859 ****
--- 856,862 ----
      }
  }
  
+ #if 0
  /* APPLE LOCAL begin AltiVec */
  /* Build a COMPOUND_LITERAL_EXPR.  TYPE is the type given in the compound
     literal.  INIT is a CONSTRUCTOR that initializes the compound literal.  */
***************
*** 878,883 ****
--- 881,887 ----
    return complit;
  }
  /* APPLE LOCAL end AltiVec */
+ #endif
  
  /* Convert EXPR to the vector type TYPE in the usual ways.  */
  
***************
*** 893,898 ****
--- 897,903 ----
  	  error ("can't convert between vector values of different size");
  	  return error_mark_node;
  	}
+ #if 0
        /* APPLE LOCAL begin AltiVec */
        if (TREE_CODE (type) == VECTOR_TYPE  
  	  && TREE_CODE (TREE_TYPE (expr)) == VECTOR_TYPE
***************
*** 900,905 ****
--- 905,911 ----
  	  /* converting a constant vector to new vector type with Motorola Syntax. */
  	  return convert (type, build_compound_literal_vector (TREE_TYPE (expr), expr));
        /* APPLE LOCAL end AltiVec */
+ #endif
  
        return build1 (VIEW_CONVERT_EXPR, type, expr);
  
diff -cr gcc.orig/dwarf2out.c gcc/dwarf2out.c
*** gcc.orig/dwarf2out.c	2010-01-27 16:18:52.000000000 +0000
--- gcc/dwarf2out.c	2010-10-27 18:52:37.048795002 +0100
***************
*** 5582,5588 ****
  
    return (lang == DW_LANG_C || lang == DW_LANG_C89 || lang == DW_LANG_ObjC
  	  || lang == DW_LANG_C99
! 	  || lang == DW_LANG_C_plus_plus || lang == DW_LANG_ObjC_plus_plus);
  }
  
  /* Return TRUE if the language is C++.  */
--- 5582,5589 ----
  
    return (lang == DW_LANG_C || lang == DW_LANG_C89 || lang == DW_LANG_ObjC
  	  || lang == DW_LANG_C99
! 	  || lang == DW_LANG_C_plus_plus || lang == DW_LANG_ObjC_plus_plus
! 	  || lang == DW_LANG_D);
  }
  
  /* Return TRUE if the language is C++.  */
***************
*** 13584,13589 ****
--- 13585,13592 ----
      language = DW_LANG_ObjC;
    else if (strcmp (language_string, "GNU Objective-C++") == 0)
      language = DW_LANG_ObjC_plus_plus;
+   else if (strcmp (language_string, "GNU D") == 0)
+     language = DW_LANG_D;
    else
      language = DW_LANG_C89;
  
***************
*** 14726,14732 ****
  
        /* For local statics lookup proper context die.  */
        if (TREE_STATIC (decl) && decl_function_context (decl))
! 	context_die = lookup_decl_die (DECL_CONTEXT (decl));
  
        /* If we are in terse mode, don't generate any DIEs to represent any
  	 variable declarations or definitions.  */
--- 14729,14735 ----
  
        /* For local statics lookup proper context die.  */
        if (TREE_STATIC (decl) && decl_function_context (decl))
! 	context_die = lookup_decl_die (decl_function_context (decl));
  
        /* If we are in terse mode, don't generate any DIEs to represent any
  	 variable declarations or definitions.  */
diff -cr gcc.orig/expr.c gcc/expr.c
*** gcc.orig/expr.c	2008-08-06 01:07:14.000000000 +0100
--- gcc/expr.c	2010-10-27 18:35:09.872795000 +0100
***************
*** 8806,8811 ****
--- 8806,8816 ----
        /* Lowered by gimplify.c.  */
        gcc_unreachable ();
  
+     case STATIC_CHAIN_EXPR:
+     case STATIC_CHAIN_DECL:
+       /* Lowered by tree-nested.c */
+       gcc_unreachable ();
+ 
      case EXC_PTR_EXPR:
        return get_exception_pointer (cfun);
  
diff -cr gcc.orig/function.c gcc/function.c
*** gcc.orig/function.c	2008-10-09 18:08:15.000000000 +0100
--- gcc/function.c	2010-10-27 18:40:05.092795002 +0100
***************
*** 3081,3087 ****
            FUNCTION_ARG_ADVANCE (all.args_so_far, data.promoted_mode,
  			        data.passed_type, data.named_arg);
  
!           assign_parm_adjust_stack_rtl (&data);
  
            if (assign_parm_setup_block_p (&data))
  	    assign_parm_setup_block (&all, parm, &data);
--- 3081,3088 ----
            FUNCTION_ARG_ADVANCE (all.args_so_far, data.promoted_mode,
  			        data.passed_type, data.named_arg);
  
! 	  if (!cfun->naked)
! 	    assign_parm_adjust_stack_rtl (&data);
  
            if (assign_parm_setup_block_p (&data))
  	    assign_parm_setup_block (&all, parm, &data);
***************
*** 3098,3104 ****
  
    /* Output all parameter conversion instructions (possibly including calls)
       now that all parameters have been copied out of hard registers.  */
!   emit_insn (all.conversion_insns);
  
    /* If we are receiving a struct value address as the first argument, set up
       the RTL for the function result. As this might require code to convert
--- 3099,3106 ----
  
    /* Output all parameter conversion instructions (possibly including calls)
       now that all parameters have been copied out of hard registers.  */
!   if (!cfun->naked)
!     emit_insn (all.conversion_insns);
  
    /* If we are receiving a struct value address as the first argument, set up
       the RTL for the function result. As this might require code to convert
***************
*** 3232,3237 ****
--- 3234,3242 ----
    struct assign_parm_data_all all;
    tree fnargs, parm, stmts = NULL;
  
+   if (cfun->naked)
+     return NULL;
+ 
    assign_parms_initialize_all (&all);
    fnargs = assign_parms_augmented_arg_list (&all);
  
***************
*** 4230,4240 ****
        tree parm = cfun->static_chain_decl;
        rtx local = gen_reg_rtx (Pmode);
  
-       set_decl_incoming_rtl (parm, static_chain_incoming_rtx);
        SET_DECL_RTL (parm, local);
        mark_reg_pointer (local, TYPE_ALIGN (TREE_TYPE (TREE_TYPE (parm))));
! 
!       emit_move_insn (local, static_chain_incoming_rtx);
      }
  
    /* If the function receives a non-local goto, then store the
--- 4235,4248 ----
        tree parm = cfun->static_chain_decl;
        rtx local = gen_reg_rtx (Pmode);
  
        SET_DECL_RTL (parm, local);
        mark_reg_pointer (local, TYPE_ALIGN (TREE_TYPE (TREE_TYPE (parm))));
!       if (!cfun->custom_static_chain)
! 	{
! 	  set_decl_incoming_rtl (parm, static_chain_incoming_rtx);
! 	  emit_move_insn (local, static_chain_incoming_rtx);
! 	}
!       /* else, the static chain will be set in the main body */
      }
  
    /* If the function receives a non-local goto, then store the
***************
*** 5286,5291 ****
--- 5294,5302 ----
  #endif
    edge_iterator ei;
  
+   if (cfun->naked)
+     return;
+ 
  #ifdef HAVE_prologue
    if (HAVE_prologue)
      {
diff -cr gcc.orig/function.h gcc/function.h
*** gcc.orig/function.h	2008-12-03 17:43:56.000000000 +0000
--- gcc/function.h	2010-10-27 18:41:14.556795002 +0100
***************
*** 495,500 ****
--- 495,508 ----
    /* Number of units of floating point registers that need saving in stdarg
       function.  */
    unsigned int va_list_fpr_size : 8;
+ 
+   /* Nonzero if static chain is initialized by something other than
+      static_chain_incoming_rtx. */
+   unsigned int custom_static_chain : 1;
+ 
+   /* Nonzero if no code should be generated for prologues, copying
+      parameters, etc. */
+   unsigned int naked : 1;
  };
  
  /* If va_list_[gf]pr_size is set to this, it means we don't know how
diff -cr gcc.orig/gcc.c gcc/gcc.c
*** gcc.orig/gcc.c	2008-11-12 19:57:33.000000000 +0000
--- gcc/gcc.c	2010-10-27 18:45:59.332795000 +0100
***************
*** 127,132 ****
--- 127,135 ----
  /* Flag set by cppspec.c to 1.  */
  int is_cpp_driver;
  
+ /* Flag set by drivers needing Pthreads. */
+ int need_pthreads;
+ 
  /* Flag saying to pass the greatest exit code returned by a sub-process
     to the calling program.  */
  static int pass_exit_codes;
***************
*** 473,478 ****
--- 476,482 ----
  	assembler has done its job.
   %D	Dump out a -L option for each directory in startfile_prefixes.
  	If multilib_dir is set, extra entries are generated with it affixed.
+  %N     Output the currently selected multilib directory name.
   %l     process LINK_SPEC as a spec.
   %L     process LIB_SPEC as a spec.
   %G     process LIBGCC_SPEC as a spec.
***************
*** 4095,4100 ****
--- 4101,4109 ----
  	}
      }
  
+   if (need_pthreads)
+     n_switches++;
+ 
    if (save_temps_flag && use_pipes)
      {
        /* -save-temps overrides -pipe, so that temp files are produced */
***************
*** 4475,4480 ****
--- 4484,4501 ----
  	}
      }
  
+   if (need_pthreads)
+     {
+       switches[n_switches].part1 = "pthread";
+       switches[n_switches].args = 0;
+       switches[n_switches].live_cond = SWITCH_OK;
+       /* Do not print an error if there is not expansion for -pthread. */
+       switches[n_switches].validated = 1;
+       switches[n_switches].ordering = 0;
+ 
+       n_switches++;
+     }
+ 
    switches[n_switches].part1 = 0;
    infiles[n_infiles].name = 0;
  }
***************
*** 5528,5533 ****
--- 5549,5565 ----
  	      return value;
  	    break;
  
+ 	  case 'N':
+ 	    if (multilib_dir)
+ 	      {
+ 		arg_going = 1;
+ 		obstack_grow (&obstack, "-fmultilib-dir=",
+ 			      strlen ("-fmultilib-dir="));
+ 		obstack_grow (&obstack, multilib_dir,
+ 			      strlen (multilib_dir));
+ 	      }
+ 	    break;
+ 
  	    /* Here we define characters other than letters and digits.  */
  
  	  case '{':
diff -cr gcc.orig/gcc.h gcc/gcc.h
*** gcc.orig/gcc.h	2008-05-27 23:39:57.000000000 +0100
--- gcc/gcc.h	2010-10-27 18:46:24.452795001 +0100
***************
*** 40,46 ****
     || (CHAR) == 'L' || (CHAR) == 'A' || (CHAR) == 'V' \
     /* APPLE LOCAL frameworks */ \
     || (CHAR) == 'F' \
!    || (CHAR) == 'B' || (CHAR) == 'b')
  
  /* This defines which multi-letter switches take arguments.  */
  
--- 40,46 ----
     || (CHAR) == 'L' || (CHAR) == 'A' || (CHAR) == 'V' \
     /* APPLE LOCAL frameworks */ \
     || (CHAR) == 'F' \
!    || (CHAR) == 'B' || (CHAR) == 'b' || (CHAR) == 'J')
  
  /* This defines which multi-letter switches take arguments.  */
  
diff -cr gcc.orig/predict.c gcc/predict.c
*** gcc.orig/predict.c	2007-07-06 14:59:24.000000000 +0100
--- gcc/predict.c	2010-10-27 18:56:10.580795000 +0100
***************
*** 1317,1322 ****
--- 1317,1323 ----
  	     care for error returns and other cases are often used for
  	     fast paths through function.  */
  	  if (e->dest == EXIT_BLOCK_PTR
+ 	      && last_stmt (bb) == NULL_TREE
  	      && TREE_CODE (last_stmt (bb)) == RETURN_EXPR
  	      && !single_pred_p (bb))
  	    {
diff -cr gcc.orig/tree.def gcc/tree.def
*** gcc.orig/tree.def	2008-07-09 01:37:53.000000000 +0100
--- gcc/tree.def	2010-10-27 18:48:30.944795000 +0100
***************
*** 533,538 ****
--- 533,545 ----
     Operand 2 is the static chain argument, or NULL.  */
  DEFTREECODE (CALL_EXPR, "call_expr", tcc_expression, 3)
  
+ /* Operand 0 is the FUNC_DECL of the outer function for
+    which the static chain is to be computed. */
+ DEFTREECODE (STATIC_CHAIN_EXPR, "static_chain_expr", tcc_expression, 1)
+     
+ /* Represents a function's static chain.  It can be used as an lvalue. */
+ DEFTREECODE (STATIC_CHAIN_DECL, "static_chain_decl", tcc_expression, 0)
+ 
  /* Specify a value to compute along with its corresponding cleanup.
     Operand 0 is the cleanup expression.
     The cleanup is executed by the first enclosing CLEANUP_POINT_EXPR,
***************
*** 906,912 ****
  
  /* APPLE LOCAL begin AV vmul_uch --haifa  */
  /* Used during vectorization to represent computation idioms.  */
! DEFTREECODE (MULT_UCH_EXPR, "mult_uch", '2', 2)
  /* APPLE LOCAL end AV vmul_uch --haifa  */
  
  /* Value handles.  Artificial nodes to represent expressions in
--- 913,919 ----
  
  /* APPLE LOCAL begin AV vmul_uch --haifa  */
  /* Used during vectorization to represent computation idioms.  */
! DEFTREECODE (MULT_UCH_EXPR, "mult_uch", tcc_binary, 2)
  /* APPLE LOCAL end AV vmul_uch --haifa  */
  
  /* Value handles.  Artificial nodes to represent expressions in
diff -cr gcc.orig/tree-gimple.c gcc/tree-gimple.c
*** gcc.orig/tree-gimple.c	2006-10-31 03:22:44.000000000 +0000
--- gcc/tree-gimple.c	2010-10-27 18:50:13.892795002 +0100
***************
*** 72,77 ****
--- 72,79 ----
      case VECTOR_CST:
      case OBJ_TYPE_REF:
      case ASSERT_EXPR:
+     case STATIC_CHAIN_EXPR: /* not sure if this is right...*/
+     case STATIC_CHAIN_DECL:
        return true;
  
      default:
***************
*** 145,151 ****
  	  || TREE_CODE (t) == WITH_SIZE_EXPR
  	  /* These are complex lvalues, but don't have addresses, so they
  	     go here.  */
! 	  || TREE_CODE (t) == BIT_FIELD_REF);
  }
  
  /*  Return true if T is a GIMPLE condition.  */
--- 147,156 ----
  	  || TREE_CODE (t) == WITH_SIZE_EXPR
  	  /* These are complex lvalues, but don't have addresses, so they
  	     go here.  */
! 	  || TREE_CODE (t) == BIT_FIELD_REF
! 	  /* This is an lvalue because it will be replaced with the real
! 	     static chain decl. */
! 	  || TREE_CODE (t) == STATIC_CHAIN_DECL);
  }
  
  /*  Return true if T is a GIMPLE condition.  */
diff -cr gcc.orig/tree-inline.c gcc/tree-inline.c
*** gcc.orig/tree-inline.c	2008-08-18 19:53:16.000000000 +0100
--- gcc/tree-inline.c	2010-10-27 19:00:07.800795002 +0100
***************
*** 554,563 ****
       knows not to copy VAR_DECLs, etc., so this is safe.  */
    else
      {
        /* Here we handle trees that are not completely rewritten.
  	 First we detect some inlining-induced bogosities for
  	 discarding.  */
!       if (TREE_CODE (*tp) == MODIFY_EXPR
  	  && TREE_OPERAND (*tp, 0) == TREE_OPERAND (*tp, 1)
  	  && (lang_hooks.tree_inlining.auto_var_in_fn_p
  	      (TREE_OPERAND (*tp, 0), fn)))
--- 554,574 ----
       knows not to copy VAR_DECLs, etc., so this is safe.  */
    else
      {
+       if (id->transform_call_graph_edges == CB_CGE_MOVE
+ 	  && TREE_CODE (*tp) == MODIFY_EXPR
+ 	  && TREE_OPERAND (*tp, 0) ==
+ 		DECL_STRUCT_FUNCTION (fn)->static_chain_decl)
+ 	{
+ 	  /* Don't use special methods to initialize the static chain
+ 	     if expanding inline.  If this code could somehow be
+ 	     expanded in expand_start_function, it would not be
+ 	     necessary to deal with it here. */
+ 	  *tp = build_empty_stmt ();
+ 	}
        /* Here we handle trees that are not completely rewritten.
  	 First we detect some inlining-induced bogosities for
  	 discarding.  */
!       else if (TREE_CODE (*tp) == MODIFY_EXPR
  	  && TREE_OPERAND (*tp, 0) == TREE_OPERAND (*tp, 1)
  	  && (lang_hooks.tree_inlining.auto_var_in_fn_p
  	      (TREE_OPERAND (*tp, 0), fn)))
diff -cr gcc.orig/tree-nested.c gcc/tree-nested.c
*** gcc.orig/tree-nested.c	2008-10-27 17:10:05.000000000 +0000
--- gcc/tree-nested.c	2010-10-27 19:04:20.940795001 +0100
***************
*** 801,806 ****
--- 801,808 ----
  
    if (info->context == target_context)
      {
+       /* might be doing something wrong to need the following line.. */
+       get_frame_type (info);
        x = build_addr (info->frame_decl, target_context);
      }
    else
***************
*** 1623,1628 ****
--- 1625,1634 ----
        if (DECL_NO_STATIC_CHAIN (decl))
  	break;
  
+       /* Don't use a trampoline for a static reference. */
+       if (TREE_STATIC (t))
+ 	break;
+ 
        /* Lookup the immediate parent of the callee, as that's where
  	 we need to insert the trampoline.  */
        for (i = info; i->context != target_context; i = i->outer)
***************
*** 1693,1698 ****
--- 1699,1712 ----
  	}
        break;
  
+     case STATIC_CHAIN_EXPR:
+       *tp = get_static_chain (info, TREE_OPERAND (t, 0), &wi->tsi);
+       break;
+ 
+     case STATIC_CHAIN_DECL:
+       *tp = get_chain_decl (info);
+       break;
+ 
      case RETURN_EXPR:
      case MODIFY_EXPR:
      case WITH_SIZE_EXPR:
***************
*** 1828,1834 ****
        tree x = build3 (COMPONENT_REF, TREE_TYPE (root->chain_field),
  		       root->frame_decl, root->chain_field, NULL_TREE);
        x = build2 (MODIFY_EXPR, TREE_TYPE (x), x, get_chain_decl (root));
!       append_to_statement_list (x, &stmt_list);
      }
  
    /* If trampolines were created, then we need to initialize them.  */
--- 1842,1866 ----
        tree x = build3 (COMPONENT_REF, TREE_TYPE (root->chain_field),
  		       root->frame_decl, root->chain_field, NULL_TREE);
        x = build2 (MODIFY_EXPR, TREE_TYPE (x), x, get_chain_decl (root));
!       if (DECL_STRUCT_FUNCTION (root->context)->custom_static_chain)
! 	{
! 	  tree_stmt_iterator i =
! 	      tsi_start ( BIND_EXPR_BODY (DECL_SAVED_TREE (context)));
! 	  while (!tsi_end_p (i))
! 	    {
! 	      tree t = tsi_stmt (i);
! 	      if (TREE_CODE (t) == MODIFY_EXPR &&
! 		  TREE_OPERAND (t, 0) == root->chain_decl)
! 		{
! 		  tsi_link_after (& i, x, TSI_SAME_STMT);
! 		  x = NULL_TREE;
! 		  break;
! 		}
! 	    }
! 	  gcc_assert (x == NULL_TREE);
! 	}
!       else
! 	append_to_statement_list (x, &stmt_list);
      }
  
    /* If trampolines were created, then we need to initialize them.  */
diff -cr gcc.orig/tree-pretty-print.c gcc/tree-pretty-print.c
*** gcc.orig/tree-pretty-print.c	2006-06-04 20:13:47.000000000 +0100
--- gcc/tree-pretty-print.c	2010-10-27 19:05:17.384795001 +0100
***************
*** 1156,1161 ****
--- 1156,1171 ----
  	pp_string (buffer, " [tail call]");
        break;
  
+     case STATIC_CHAIN_EXPR:
+       pp_string (buffer, "<<static chain of ");
+       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+       pp_string (buffer, ">>");
+       break;
+ 
+     case STATIC_CHAIN_DECL:
+       pp_string (buffer, "<<static chain decl>>");
+       break;
+ 
      case WITH_CLEANUP_EXPR:
        NIY;
        break;
diff -cr gcc.orig/tree-sra.c gcc/tree-sra.c
*** gcc.orig/tree-sra.c	2007-11-28 18:58:25.000000000 +0000
--- gcc/tree-sra.c	2010-10-27 19:06:59.540795002 +0100
***************
*** 259,264 ****
--- 259,266 ----
      case RECORD_TYPE:
        {
  	bool saw_one_field = false;
+ 	tree last_offset = size_zero_node;
+ 	tree cmp;
  
  	for (t = TYPE_FIELDS (type); t ; t = TREE_CHAIN (t))
  	  if (TREE_CODE (t) == FIELD_DECL)
***************
*** 268,273 ****
--- 270,280 ----
  		  && (tree_low_cst (DECL_SIZE (t), 1)
  		      != TYPE_PRECISION (TREE_TYPE (t))))
  		goto fail;
+ 	      /* Reject aliased fields created by GDC for anonymous unions. */
+ 	      cmp = fold_binary_to_constant (LE_EXPR, boolean_type_node,
+ 					     DECL_FIELD_OFFSET (t), last_offset);
+ 	      if (cmp == NULL_TREE || tree_expr_nonzero_p (cmp))
+ 		goto fail;
  
  	      saw_one_field = true;
  	    }
diff -cr gcc.orig/tree-vect-analyze.c gcc/tree-vect-analyze.c
*** gcc.orig/tree-vect-analyze.c	2007-12-11 19:58:17.000000000 +0000
--- gcc/tree-vect-analyze.c	2010-10-27 19:09:40.268795001 +0100
***************
*** 595,600 ****
--- 595,603 ----
           
    if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
      return false;
+ 
+   if ((DR_IS_READ (dra) && DR_IS_READ (drb)) || (dra == drb))
+     return false;
    
    if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
      {
***************
*** 605,610 ****
--- 608,619 ----
            print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
            fprintf (vect_dump, " and ");
            print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
+ 	  fprintf (vect_dump, "\n");
+ 	  dump_data_reference (vect_dump, dra);
+ 	  fprintf (vect_dump, " ---- ");
+ 	  dump_data_reference (vect_dump, drb);
+ 	  fprintf (vect_dump, "\n");
+ 	  fprintf (vect_dump, "Eq test %i\n", DR_REF (dra) == DR_REF (drb));
          }
        return true;
      }
