diff mbox

Go patch committed: Clean up AST dumping code

Message ID mcraaay8vi0.fsf@coign.corp.google.com
State New
Headers show

Commit Message

Ian Lance Taylor Aug. 24, 2011, 7:22 p.m. UTC
This patch from Roberto Lublinerman cleans up the AST dumping code he
added, and removes some trailing whitespace.  It also adds support for
frontend specific optimization options.  Bootstrapped and ran Go
testsuite on x86_64-unknown-linux-gnu.  Committed to mainline.

Ian


2011-08-24  Roberto Lublinerman  <rluble@gmail.com>

	* lang.opt: Add fgo-optimize-.
	* go-lang.c (go_langhook_handle_option): Handle OPT_fgo_optimize.
	* go-c.h (go_enable_optimize): Declare.
	* Make-lang.in (GO_OBJS): Add go/go-optimize.o.
	(GO_EXPORT_H): Define.
	(GO_IMPORT_H): Add $(GO_EXPORT_H).
	(GO_AST_DUMP_H): Define.
	(go/ast-dump.o, go/statements.o): Use GO_AST_DUMP_H.
	(go/export.o, go/gogo.o, go/import.o): Use GO_EXPORT_H.
	(go/types.o): Likewise.
	(go/expressions.o): Use GO_AST_DUMP_H and GO_EXPORT_H.
	(go/go-optimize.o): New target.
diff mbox

Patch

Index: gcc/go/Make-lang.in
===================================================================
--- gcc/go/Make-lang.in	(revision 178040)
+++ gcc/go/Make-lang.in	(working copy)
@@ -54,6 +54,7 @@  GO_OBJS = \
 	go/go-dump.o \
 	go/go-gcc.o \
 	go/go-lang.o \
+	go/go-optimize.o \
 	go/go.o \
 	go/gogo-tree.o \
 	go/gogo.o \
@@ -222,8 +223,10 @@  GO_GOGO_H = go/gofrontend/gogo.h
 GO_TYPES_H = go/gofrontend/types.h
 GO_STATEMENTS_H = go/gofrontend/statements.h go/gofrontend/operator.h
 GO_EXPRESSIONS_H = go/gofrontend/expressions.h go/gofrontend/operator.h
-GO_IMPORT_H = go/gofrontend/import.h go/gofrontend/export.h
+GO_EXPORT_H = go/gofrontend/export.h go/gofrontend/string-dump.h
+GO_IMPORT_H = go/gofrontend/import.h $(GO_EXPORT_H)
 GO_RUNTIME_H = go/gofrontend/runtime.h go/gofrontend/runtime.def
+GO_AST_DUMP_H = go/gofrontend/ast-dump.h go/gofrontend/string-dump.h
 
 go/go-backend.o: go/go-backend.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
 	$(TM_H) $(RTL_H) $(TREE_H) $(TM_P_H) output.h $(TARGET_H) \
@@ -249,22 +252,24 @@  go/%.o: go/gofrontend/%.cc
 
 go/ast-dump.o: go/gofrontend/ast-dump.cc $(GO_SYSTME_H) $(GO_GOGO_H) \
 	$(GO_EXPRESSIONS_H) $(GO_STATEMENTS_H) $(GO_TYPES_H) \
-	go/gofrontend/ast-dump.h $(GO_C_H) go/gofrontend/go-dump.h
+	$(GO_AST_DUMP_H) $(GO_C_H) go/gofrontend/go-dump.h
 go/dataflow.o: go/gofrontend/dataflow.cc $(GO_SYSTEM_H) $(GO_GOGO_H) \
 	$(GO_EXPRESSIONS_H) $(GO_STATEMENTS_H) go/gofrontend/dataflow.h
 go/export.o: go/gofrontend/export.cc $(GO_SYSTEM_H) \
 	$(srcdir)/../include/sha1.h $(GO_C_H) $(GO_GOGO_H) $(GO_TYPES_H) \
-	$(GO_STATEMENTS_H) go/gofrontend/export.h
+	$(GO_STATEMENTS_H) $(GO_EXPORT_H)
 go/expressions.o: go/gofrontend/expressions.cc $(GO_SYSTEM_H) $(TOPLEV_H) \
 	intl.h $(TREE_H) $(GIMPLE_H) tree-iterator.h convert.h $(REAL_H) \
 	realmpfr.h $(GO_C_H) $(GO_GOGO_H) $(GO_TYPES_H) \
-	go/gofrontend/export.h $(GO_IMPORT_H) $(GO_STATEMENTS_H) $(GO_LEX_H) \
+	$(GO_EXPORT_H) $(GO_IMPORT_H) $(GO_STATEMENTS_H) $(GO_LEX_H) \
 	$(GO_RUNTIME_H) go/gofrontend/backend.h $(GO_EXPRESSIONS_H) \
-	go/gofrontend/ast-dump.h
+	$(GO_AST_DUMP_H)
 go/go.o: go/gofrontend/go.cc $(GO_SYSTEM_H) $(GO_C_H) $(GO_LEX_H) \
 	$(GO_PARSE_H) go/gofrontend/backend.h $(GO_GOGO_H)
 go/go-dump.o: go/gofrontend/go-dump.cc $(GO_SYSTEM_H) $(GO_C_H) \
 	go/gofrontend/go-dump.h
+go/go-optimize.o: go/gofrontend/go-optimize.cc $(GO_SYSTEM_H) $(GO_C_H) \
+	go/gofrontend/go-optimize.h
 go/gogo-tree.o: go/gofrontend/gogo-tree.cc $(GO_SYSTEM_H) $(TOPLEV_H) \
 	$(TREE_H) $(GIMPLE_H) tree-iterator.h $(CGRAPH_H) langhooks.h \
 	convert.h output.h $(DIAGNOSTIC_H) $(GO_TYPES_H) \
@@ -273,12 +278,10 @@  go/gogo-tree.o: go/gofrontend/gogo-tree.
 go/gogo.o: go/gofrontend/gogo.cc $(GO_SYSTEM_H) $(GO_C_H) \
 	go/gofrontend/go-dump.h $(GO_LEX_H) $(GO_TYPES_H) $(GO_STATEMENTS_H) \
 	$(GO_EXPRESSIONS_H) go/gofrontend/dataflow.h $(GO_RUNTIME_H) \
-	$(GO_IMPORT_H) go/gofrontend/export.h go/gofrontend/backend.h \
-	$(GO_GOGO_H)
+	$(GO_IMPORT_H) $(GO_EXPORT_H) go/gofrontend/backend.h $(GO_GOGO_H)
 go/import.o: go/gofrontend/import.cc $(GO_SYSTEM_H) \
 	$(srcdir)/../include/filenames.h $(srcdir)/../include/simple-object.h \
-	$(GO_C_H) $(GO_GOGO_H) $(GO_TYPES_H) go/gofrontend/export.h \
-	$(GO_IMPORT_H)
+	$(GO_C_H) $(GO_GOGO_H) $(GO_TYPES_H) $(GO_EXPORT_H) $(GO_IMPORT_H)
 go/import-archive.o: go/gofrontend/import-archive.cc $(GO_SYSTEM_H) \
 	$(GO_IMPORT_H)
 go/lex.o: go/gofrontend/lex.cc $(GO_LEX_H) $(GO_SYSTEM_H)
@@ -290,11 +293,10 @@  go/runtime.o: go/gofrontend/runtime.cc $
 go/statements.o: go/gofrontend/statements.cc $(GO_SYSTEM_H) \
 	$(GO_C_H) $(GO_TYPES_H) $(GO_EXPRESSIONS_H) $(GO_GOGO_H) \
 	$(GO_RUNTIME_H) go/gofrontend/backend.h $(GO_STATEMENTS_H) \
-	go/gofrontend/ast-dump.h
+	$(GO_AST_DUMP_H)
 go/types.o: go/gofrontend/types.cc $(GO_SYSTEM_H) $(TOPLEV_H) intl.h $(TREE_H) \
 	$(GIMPLE_H) $(REAL_H) convert.h $(GO_C_H) $(GO_GOGO_H) \
 	go/gofrontend/operator.h $(GO_EXPRESSIONS_H) $(GO_STATEMENTS_H) \
-	go/gofrontend/export.h $(GO_IMPORT_H) go/gofrontend/backend.h \
-	$(GO_TYPES_H)
+	$(GO_EXPORT_H) $(GO_IMPORT_H) go/gofrontend/backend.h $(GO_TYPES_H)
 go/unsafe.o: go/gofrontend/unsafe.cc $(GO_SYSTEM_H) $(GO_C_H) $(GO_TYPES_H) \
 	$(GO_GOGO_H)
Index: gcc/go/lang.opt
===================================================================
--- gcc/go/lang.opt	(revision 178040)
+++ gcc/go/lang.opt	(working copy)
@@ -1,6 +1,6 @@ 
 ; lang.opt -- Options for the gcc Go front end.
 
-; Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+; Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
 ;
 ; This file is part of GCC.
 ;
@@ -41,6 +41,10 @@  fgo-dump-
 Go Joined RejectNegative
 -fgo-dump-<type>	Dump Go frontend internal information
 
+fgo-optimize-
+Go Joined RejectNegative
+-fgo-optimize-<type>	Turn on optimization passes in the frontend
+
 fgo-prefix=
 Go Joined RejectNegative
 -fgo-prefix=<string>	Set package-specific prefix for exported Go names
Index: gcc/go/gofrontend/ast-dump.h
===================================================================
--- gcc/go/gofrontend/ast-dump.h	(revision 178040)
+++ gcc/go/gofrontend/ast-dump.h	(working copy)
@@ -7,6 +7,8 @@ 
 #ifndef GO_AST_DUMP_H
 #define GO_AST_DUMP_H
 
+#include "string-dump.h"
+
 class Expression;
 class Expression_list;
 class Named_object;
@@ -16,10 +18,10 @@  class Gogo;
 // This class implements fgo-dump-ast. the
 // Abstract syntax tree dump of the Go program.
 
-class Ast_dump_context 
+class Ast_dump_context : public String_dump
 {
  public:
-  Ast_dump_context();
+  Ast_dump_context(std::ostream* out = NULL, bool dump_subblocks = true);
 
   // Initialize the dump context.
   void
@@ -28,38 +30,43 @@  class Ast_dump_context 
   // Dump spaces to dumpfile as indentation.
   void
   print_indent();
-  
+
   // Increase current indentation for print_indent().
   void
-  indent() 
+  indent()
   { ++this->indent_;}
 
   // Decrease current indentation for print_indent().
   void
-  unindent() 
+  unindent()
   { --this->indent_;}
 
+  // Whether subblocks should be dumped or not.
+  bool
+  dump_subblocks()
+  { return this->dump_subblocks_; }
+
   // Get dump output stream.
-  std::ostream& 
-  ostream() 
+  std::ostream&
+  ostream()
   { return *this->ostream_;}
 
   // Dump a Block to dump file.
-  void 
+  void
   dump_block(Block*);
-  
+
   // Dump a type to dump file.
-  void 
+  void
   dump_type(const Type*);
-  
+
   // Dump an expression to dump file.
-  void 
+  void
   dump_expression(const Expression*);
 
   // Dump an expression list to dump file.
-  void 
-  dump_expression_list(const Expression_list*);
-  
+  void
+  dump_expression_list(const Expression_list*, bool as_pairs = false);
+
   // Dump a typed identifier to dump file.
   void
   dump_typed_identifier(const  Typed_identifier*);
@@ -67,7 +74,7 @@  class Ast_dump_context 
   // Dump a typed identifier list to dump file.
   void
   dump_typed_identifier_list(const Typed_identifier_list*);
-  
+
   // Dump temporary variable name to dump file.
   void
   dump_temp_variable_name(const Statement*);
@@ -79,17 +86,36 @@  class Ast_dump_context 
   // Dump operator symbol to dump file.
   void
   dump_operator(Operator);
-    
+
+  // Implementation of String_dump interface.
+  void
+  write_c_string(const char*);
+
+  // Implements the String_dump interface.
+  void
+  write_string(const std::string& s);
+
+  // Dump statement to stream.
+  static void
+  dump_to_stream(const Statement*, std::ostream*);
+
+  // Dump expression to stream.
+  static void
+  dump_to_stream(const Expression* expr, std::ostream* out);
+
  private:
    // Current indent level.
   int indent_;
-  
+
   // Indentation offset.
   static const int offset_;
-  
+
+  // Whether subblocks of composite statements should be dumped or not.
+  bool dump_subblocks_;
+
   // Stream on output dump file.
   std::ostream* ostream_;
-    
+
   Gogo* gogo_;
 };
 
Index: gcc/go/gofrontend/export.h
===================================================================
--- gcc/go/gofrontend/export.h	(revision 178040)
+++ gcc/go/gofrontend/export.h	(working copy)
@@ -7,6 +7,8 @@ 
 #ifndef GO_EXPORT_H
 #define GO_EXPORT_H
 
+#include "string-dump.h"
+
 struct sha1_ctx;
 class Gogo;
 class Import_init;
@@ -45,7 +47,7 @@  enum Builtin_code
 // loop of exporting.  A pointer to this class is also passed to the
 // various specific export implementations.
 
-class Export
+class Export : public String_dump
 {
  public:
   // The Stream class is an interface used to output the exported
@@ -57,12 +59,12 @@  class Export
     Stream();
     virtual ~Stream();
 
-    // Write a string.
+    // Write a string. Implements the String_dump interface.
     void
     write_string(const std::string& s)
     { this->write_and_sum_bytes(s.data(), s.length()); }
 
-    // Write a nul terminated string.
+    // Write a nul terminated string. Implements the String_dump interface.
     void
     write_c_string(const char* s)
     { this->write_and_sum_bytes(s, strlen(s)); }
Index: gcc/go/gofrontend/expressions.h
===================================================================
--- gcc/go/gofrontend/expressions.h	(revision 178040)
+++ gcc/go/gofrontend/expressions.h	(working copy)
@@ -43,6 +43,7 @@  class Import;
 class Temporary_statement;
 class Label;
 class Ast_dump_context;
+class String_dump;
 
 // The base class for all expressions.
 
@@ -1043,6 +1044,10 @@  class String_expression : public Express
   tree
   do_get_tree(Translate_context*);
 
+  // Write string literal to a string dump.
+  static void
+  export_string(String_dump* exp, const String_expression* str);
+
   void
   do_export(Export*) const;
 
Index: gcc/go/gofrontend/statements.cc
===================================================================
--- gcc/go/gofrontend/statements.cc	(revision 178040)
+++ gcc/go/gofrontend/statements.cc	(working copy)
@@ -308,11 +308,11 @@  Variable_declaration_statement::do_dump_
     Ast_dump_context* ast_dump_context) const
 {
   ast_dump_context->print_indent();
-  
+
   go_assert(var_->is_variable());
   ast_dump_context->ostream() << "var " << this->var_->name() <<  " ";
   Variable* var = this->var_->var_value();
-  if (var->has_type()) 
+  if (var->has_type())
     {
       ast_dump_context->dump_type(var->type());
       ast_dump_context->ostream() << " ";
@@ -478,7 +478,6 @@  Temporary_statement::do_dump_statement(A
     {
       ast_dump_context->ostream() << " ";
       ast_dump_context->dump_type(this->type_);
-      
     }
   if (this->init_ != NULL)
     {
@@ -797,7 +796,7 @@  Assignment_operation_statement::do_dump_
 {
   ast_dump_context->print_indent();
   ast_dump_context->dump_expression(this->lhs_);
-  ast_dump_context->dump_operator(this->op_); 
+  ast_dump_context->dump_operator(this->op_);
   ast_dump_context->dump_expression(this->rhs_);
   ast_dump_context->ostream() << std::endl;
 }
@@ -1548,7 +1547,7 @@  Tuple_type_guard_assignment_statement::l
 
 // Dump the AST representation for a tuple type guard statement.
 
-void 
+void
 Tuple_type_guard_assignment_statement::do_dump_statement(
     Ast_dump_context* ast_dump_context) const
 {
@@ -1652,7 +1651,7 @@  Expression_statement::do_get_backend(Tra
 
 // Dump the AST representation for an expression statement
 
-void 
+void
 Expression_statement::do_dump_statement(Ast_dump_context* ast_dump_context)
     const
 {
@@ -2269,7 +2268,7 @@  Thunk_statement::build_thunk(Gogo* gogo,
 
   // For a defer statement, start with a call to
   // __go_set_defer_retaddr.  */
-  Label* retaddr_label = NULL; 
+  Label* retaddr_label = NULL;
   if (may_call_recover)
     {
       retaddr_label = gogo->add_label_reference("retaddr");
@@ -2757,12 +2756,12 @@  Bc_statement::do_dump_statement(Ast_dump
 {
   ast_dump_context->print_indent();
   ast_dump_context->ostream() << (this->is_break_ ? "break" : "continue");
-  if (this->label_ != NULL) 
+  if (this->label_ != NULL)
     {
-      ast_dump_context->ostream() << " "; 
+      ast_dump_context->ostream() << " ";
       ast_dump_context->dump_label_name(this->label_);
     }
-  ast_dump_context->ostream() << std::endl; 
+  ast_dump_context->ostream() << std::endl;
 }
 
 // Make a break statement.
@@ -3098,12 +3097,15 @@  If_statement::do_dump_statement(Ast_dump
   ast_dump_context->ostream() << "if ";
   ast_dump_context->dump_expression(this->cond_);
   ast_dump_context->ostream() << std::endl;
-  ast_dump_context->dump_block(this->then_block_);
-  if (this->else_block_ != NULL) 
+  if (ast_dump_context->dump_subblocks())
     {
-      ast_dump_context->print_indent();
-      ast_dump_context->ostream() << "else" << std::endl;
-      ast_dump_context->dump_block(this->else_block_);
+      ast_dump_context->dump_block(this->then_block_);
+      if (this->else_block_ != NULL)
+	{
+	  ast_dump_context->print_indent();
+	  ast_dump_context->ostream() << "else" << std::endl;
+	  ast_dump_context->dump_block(this->else_block_);
+	}
     }
 }
 
@@ -3401,7 +3403,7 @@  Case_clauses::Case_clause::get_backend(T
 // Dump the AST representation for a case clause
 
 void
-Case_clauses::Case_clause::dump_clause(Ast_dump_context* ast_dump_context) 
+Case_clauses::Case_clause::dump_clause(Ast_dump_context* ast_dump_context)
     const
 {
   ast_dump_context->print_indent();
@@ -3508,7 +3510,6 @@  Case_clauses::lower(Block* b, Temporary_
   if (default_case != NULL)
     default_case->lower(b, val_temp, default_start_label,
 			default_finish_label);
-      
 }
 
 // Determine types.
@@ -3592,7 +3593,7 @@  Case_clauses::dump_clauses(Ast_dump_cont
 {
   for (Clauses::const_iterator p = this->clauses_.begin();
        p != this->clauses_.end();
-       ++p)    
+       ++p)
     p->dump_clause(ast_dump_context);
 }
 
@@ -3716,9 +3717,15 @@  Constant_switch_statement::do_dump_state
   ast_dump_context->print_indent();
   ast_dump_context->ostream() << "switch ";
   ast_dump_context->dump_expression(this->val_);
-  ast_dump_context->ostream() << " {" << std::endl;
-  this->clauses_->dump_clauses(ast_dump_context);
-  ast_dump_context->ostream() << "}" << std::endl;
+
+  if (ast_dump_context->dump_subblocks())
+    {
+      ast_dump_context->ostream() << " {" << std::endl;
+      this->clauses_->dump_clauses(ast_dump_context);
+      ast_dump_context->ostream() << "}";
+    }
+
+   ast_dump_context->ostream() << std::endl;
 }
 
 // Class Switch_statement.
@@ -3806,12 +3813,15 @@  Switch_statement::do_dump_statement(Ast_
   if (this->val_ != NULL)
     {
       ast_dump_context->dump_expression(this->val_);
-      ast_dump_context->ostream() << " ";
     }
-  ast_dump_context->ostream() << "{" << std::endl;
-  this->clauses_->dump_clauses(ast_dump_context);
-  ast_dump_context->print_indent();
-  ast_dump_context->ostream() << "}" << std::endl;
+  if (ast_dump_context->dump_subblocks())
+    {
+      ast_dump_context->ostream() << " {" << std::endl;
+      this->clauses_->dump_clauses(ast_dump_context);
+      ast_dump_context->print_indent();
+      ast_dump_context->ostream() << "}";
+    }
+  ast_dump_context->ostream() << std::endl;
 }
 
 // Make a switch statement.
@@ -3951,7 +3961,7 @@  Type_case_clauses::Type_case_clause::dum
     }
   else
     {
-      ast_dump_context->ostream() << "case "; 
+      ast_dump_context->ostream() << "case ";
       ast_dump_context->dump_type(this->type_);
       ast_dump_context->ostream() << ":" ;
     }
@@ -4040,7 +4050,7 @@  Type_case_clauses::dump_clauses(Ast_dump
 {
   for (Type_clauses::const_iterator p = this->clauses_.begin();
        p != this->clauses_.end();
-       ++p)    
+       ++p)
     p->dump_clause(ast_dump_context);
 }
 
@@ -4150,15 +4160,20 @@  Type_switch_statement::break_label()
 // Dump the AST representation for a type switch statement
 
 void
-Type_switch_statement::do_dump_statement(Ast_dump_context* ast_dump_context) 
+Type_switch_statement::do_dump_statement(Ast_dump_context* ast_dump_context)
     const
 {
   ast_dump_context->print_indent();
   ast_dump_context->ostream() << "switch " << this->var_->name() << " = ";
   ast_dump_context->dump_expression(this->expr_);
-  ast_dump_context->ostream() << " .(type) {" << std::endl;
-  this->clauses_->dump_clauses(ast_dump_context);
-  ast_dump_context->ostream() << "}" << std::endl;
+  ast_dump_context->ostream() << " .(type)";
+  if (ast_dump_context->dump_subblocks())
+    {
+      ast_dump_context->ostream() << " {" << std::endl;
+      this->clauses_->dump_clauses(ast_dump_context);
+      ast_dump_context->ostream() << "}";
+    }
+  ast_dump_context->ostream() << std::endl;
 }
 
 // Make a type switch statement.
@@ -4554,7 +4569,7 @@  Select_clauses::Select_clause::dump_clau
           ast_dump_context->ostream() << " <- " ;
           ast_dump_context->dump_expression(this->val_);
         }
-      else 
+      else
         {
 	  if (this->val_ != NULL)
 	    ast_dump_context->dump_expression(this->val_);
@@ -4567,7 +4582,7 @@  Select_clauses::Select_clause::dump_clau
           if (this->closedvar_ != NULL ||
               this->var_ != NULL)
             ast_dump_context->ostream() << " := " ;
-            
+
           ast_dump_context->ostream() << " <- " ;
           ast_dump_context->dump_expression(this->channel_);
         }
@@ -4842,7 +4857,7 @@  Select_clauses::add_clause_backend(
 			  ? clause->location()
 			  : clause->statements()->end_location());
   Bstatement* g = bottom_label->get_goto(context, gloc);
-				
+
   if (s == NULL)
     (*clauses)[index] = g;
   else
@@ -4856,7 +4871,7 @@  Select_clauses::dump_clauses(Ast_dump_co
 {
   for (Clauses::const_iterator p = this->clauses_.begin();
        p != this->clauses_.end();
-       ++p)    
+       ++p)
     p->dump_clause(ast_dump_context);
 }
 
@@ -4902,13 +4917,18 @@  Select_statement::do_get_backend(Transla
 
 // Dump the AST representation for a select statement.
 
-void 
+void
 Select_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
 {
   ast_dump_context->print_indent();
-  ast_dump_context->ostream() << "select {" << std::endl;
-  this->clauses_->dump_clauses(ast_dump_context);
-  ast_dump_context->ostream() << "}" << std::endl;
+  ast_dump_context->ostream() << "select";
+  if (ast_dump_context->dump_subblocks())
+    {
+      ast_dump_context->ostream() << " {" << std::endl;
+      this->clauses_->dump_clauses(ast_dump_context);
+      ast_dump_context->ostream() << "}";
+    }
+  ast_dump_context->ostream() << std::endl;
 }
 
 // Make a select statement.
@@ -5051,7 +5071,7 @@  For_statement::set_break_continue_labels
 void
 For_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
 {
-  if (this->init_ != NULL)
+  if (this->init_ != NULL && ast_dump_context->dump_subblocks())
     {
       ast_dump_context->print_indent();
       ast_dump_context->indent();
@@ -5063,19 +5083,24 @@  For_statement::do_dump_statement(Ast_dum
   ast_dump_context->ostream() << "for ";
   if (this->cond_ != NULL)
     ast_dump_context->dump_expression(this->cond_);
-  ast_dump_context->ostream() << " {" << std::endl;
-  ast_dump_context->indent();
 
-  ast_dump_context->dump_block(this->statements_);
-  if (this->init_ != NULL)
+  if (ast_dump_context->dump_subblocks())
     {
+      ast_dump_context->ostream() << " {" << std::endl;
+      ast_dump_context->dump_block(this->statements_);
+      if (this->init_ != NULL)
+	{
+	  ast_dump_context->print_indent();
+	  ast_dump_context->ostream() << "// POST " << std::endl;
+	  ast_dump_context->dump_block(this->post_);
+	}
+      ast_dump_context->unindent();
+
       ast_dump_context->print_indent();
-      ast_dump_context->ostream() << "// POST " << std::endl;
-      ast_dump_context->dump_block(this->post_);
+      ast_dump_context->ostream() << "}";
     }
-  ast_dump_context->unindent();
-  ast_dump_context->print_indent();
-  ast_dump_context->ostream() << "}" << std::endl;
+
+  ast_dump_context->ostream() << std::endl;
 }
 
 // Make a for statement.
@@ -5701,7 +5726,7 @@  For_range_statement::continue_label()
 void
 For_range_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
 {
-  
+
   ast_dump_context->print_indent();
   ast_dump_context->ostream() << "for ";
   ast_dump_context->dump_expression(this->index_var_);
@@ -5710,17 +5735,22 @@  For_range_statement::do_dump_statement(A
       ast_dump_context->ostream() << ", ";
       ast_dump_context->dump_expression(this->value_var_);
     }
-    
-  ast_dump_context->ostream() << " = range ";      
+
+  ast_dump_context->ostream() << " = range ";
   ast_dump_context->dump_expression(this->range_);
-  ast_dump_context->ostream() << " {" << std::endl;
-  ast_dump_context->indent();
+  if (ast_dump_context->dump_subblocks())
+    {
+      ast_dump_context->ostream() << " {" << std::endl;
 
-  ast_dump_context->dump_block(this->statements_);
+      ast_dump_context->indent();
 
-  ast_dump_context->unindent();
-  ast_dump_context->print_indent();
-  ast_dump_context->ostream() << "}" << std::endl;
+      ast_dump_context->dump_block(this->statements_);
+
+      ast_dump_context->unindent();
+      ast_dump_context->print_indent();
+      ast_dump_context->ostream() << "}";
+    }
+  ast_dump_context->ostream() << std::endl;
 }
 
 // Make a for statement with a range clause.
Index: gcc/go/gofrontend/ast-dump.cc
===================================================================
--- gcc/go/gofrontend/ast-dump.cc	(revision 178040)
+++ gcc/go/gofrontend/ast-dump.cc	(working copy)
@@ -19,9 +19,9 @@ 
 
 // The -fgo-dump-ast flag to activate AST dumps.
 
-Go_dump ast_dump_context_flag("ast");
+Go_dump ast_dump_flag("ast");
 
-// This class is used to traverse the tree to look for blocks and 
+// This class is used to traverse the tree to look for blocks and
 // function headers.
 
 class Ast_dump_traverse_blocks_and_functions : public Traverse
@@ -33,9 +33,9 @@  class Ast_dump_traverse_blocks_and_funct
   { }
 
  protected:
-  int 
+  int
   block(Block*);
- 
+
   int
   function(Named_object*);
 
@@ -79,7 +79,7 @@  int Ast_dump_traverse_blocks_and_functio
 
   return TRAVERSE_SKIP_COMPONENTS;
 }
- 
+
 // Dump each traversed statement.
 
 int
@@ -87,7 +87,7 @@  Ast_dump_traverse_statements::statement(
                                         Statement* statement)
 {
   statement->dump_statement(this->ast_dump_context_);
- 
+
   if (statement->is_block_statement())
     {
       Ast_dump_traverse_blocks_and_functions adtbf(this->ast_dump_context_);
@@ -103,49 +103,51 @@  int
 Ast_dump_traverse_blocks_and_functions::function(Named_object* no)
 {
   this->ast_dump_context_->ostream() << no->name();
- 
+
   go_assert(no->is_function());
   Function* func = no->func_value();
-  
-  this->ast_dump_context_->ostream() << "("; 
+
+  this->ast_dump_context_->ostream() << "(";
   this->ast_dump_context_->dump_typed_identifier_list(
                               func->type()->parameters());
-  
-  this->ast_dump_context_->ostream() << ")"; 
-  
+
+  this->ast_dump_context_->ostream() << ")";
+
   Function::Results* res = func->result_variables();
   if (res != NULL && !res->empty())
-    {  
-      this->ast_dump_context_->ostream() << " ("; 
-      
-      for (Function::Results::const_iterator it = res->begin(); 
-          it != res->end(); 
+    {
+      this->ast_dump_context_->ostream() << " (";
+
+      for (Function::Results::const_iterator it = res->begin();
+          it != res->end();
           it++)
         {
           if (it != res->begin())
             this->ast_dump_context_->ostream() << ",";
           Named_object* no = (*it);
-          
+
           this->ast_dump_context_->ostream() << no->name() << " ";
           go_assert(no->is_result_variable());
           Result_variable* resvar = no->result_var_value();
-          
+
           this->ast_dump_context_->dump_type(resvar->type());
-        
+
         }
       this->ast_dump_context_->ostream() << ")";
     }
-    
+
   this->ast_dump_context_->ostream() << " : ";
   this->ast_dump_context_->dump_type(func->type());
   this->ast_dump_context_->ostream() << std::endl;
-  
+
   return TRAVERSE_CONTINUE;
 }
 
 // Class Ast_dump_context.
 
-Ast_dump_context::Ast_dump_context() : ostream_(NULL)
+Ast_dump_context::Ast_dump_context(std::ostream* out /* = NULL */,
+				   bool dump_subblocks /* = true */)
+  :  indent_(0), dump_subblocks_(dump_subblocks), ostream_(out), gogo_(NULL)
 {
 }
 
@@ -168,8 +170,7 @@  Ast_dump_context::dump(Gogo* gogo, const
       error("cannot open %s:%m, -fgo-dump-ast ignored", dumpname.c_str());
       return;
     }
-  
-  this->indent_ = 0;
+
   this->gogo_ = gogo;
   this->ostream_ = out;
 
@@ -188,9 +189,10 @@  Ast_dump_context::dump_type(const Type* 
   if (t == NULL)
     this->ostream() << "(nil type)";
   else
-    // FIXME: write a type pretty printer instead of 
+    // FIXME: write a type pretty printer instead of
     // using mangled names.
-    this->ostream() << "(" << t->mangled_name(this->gogo_) <<  ")"; 
+    if (this->gogo_ != NULL)
+      this->ostream() << "(" << t->mangled_name(this->gogo_) <<  ")";
 }
 
 // Dump a textual representation of a block to the
@@ -216,18 +218,28 @@  Ast_dump_context::dump_expression(const 
 // the dump file.
 
 void
-Ast_dump_context::dump_expression_list(const Expression_list* el)
+Ast_dump_context::dump_expression_list(const Expression_list* el,
+				       bool as_pairs /* = false */)
 {
   if (el == NULL)
     return;
-  
-  for (std::vector<Expression*>::const_iterator it = el->begin(); 
+
+  for (std::vector<Expression*>::const_iterator it = el->begin();
        it != el->end();
        it++)
     {
       if ( it != el->begin())
         this->ostream() << ",";
-      (*it)->dump_expression(this);
+      if (*it != NULL)
+	(*it)->dump_expression(this);
+      else
+        this->ostream() << "NULL";
+      if (as_pairs)
+        {
+	  this->ostream() << ":";
+	  ++it;
+	  (*it)->dump_expression(this);
+        }
     }
 }
 
@@ -246,13 +258,13 @@  Ast_dump_context::dump_typed_identifier(
 
 void
 Ast_dump_context::dump_typed_identifier_list(
-    const Typed_identifier_list* ti_list)         
+    const Typed_identifier_list* ti_list)
 {
   if (ti_list == NULL)
     return;
-  
-  for (Typed_identifier_list::const_iterator it = ti_list->begin(); 
-       it != ti_list->end(); 
+
+  for (Typed_identifier_list::const_iterator it = ti_list->begin();
+       it != ti_list->end();
        it++)
     {
       if (it != ti_list->begin())
@@ -300,6 +312,8 @@  op_string(Operator op)
       return "!";
     case OPERATOR_XOR:
       return "^";
+    case OPERATOR_OR:
+      return "|";
     case OPERATOR_AND:
       return "&";
     case OPERATOR_MULT:
@@ -415,9 +429,41 @@  Ast_dump_context::print_indent()
 
 void Gogo::dump_ast(const char* basename)
 {
-  if (ast_dump_context_flag.is_enabled())
+  if (::ast_dump_flag.is_enabled())
     {
       Ast_dump_context adc;
       adc.dump(this, basename);
     }
 }
+
+// Implementation of String_dump interface.
+
+void
+Ast_dump_context::write_c_string(const char* s)
+{
+  this->ostream() << s;
+}
+
+void
+Ast_dump_context::write_string(const std::string& s)
+{
+  this->ostream() << s;
+}
+
+// Dump statment to stream.
+
+void
+Ast_dump_context::dump_to_stream(const Statement* stm, std::ostream* out)
+{
+  Ast_dump_context adc(out, false);
+  stm->dump_statement(&adc);
+}
+
+// Dump expression to stream.
+
+void
+Ast_dump_context::dump_to_stream(const Expression* expr, std::ostream* out)
+{
+  Ast_dump_context adc(out, false);
+  expr->dump_expression(&adc);
+}
\ No newline at end of file
Index: gcc/go/gofrontend/go-optimize.cc
===================================================================
--- gcc/go/gofrontend/go-optimize.cc	(revision 0)
+++ gcc/go/gofrontend/go-optimize.cc	(revision 0)
@@ -0,0 +1,53 @@ 
+// go-optimize.cc -- Go frontend optimizer flags.
+
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "go-system.h"
+
+#include "go-c.h"
+#include "go-optimize.h"
+
+namespace {
+
+// The list of optimizations.
+
+Go_optimize* optimizations;
+
+} // End empty namespace.
+
+// Create a new optimization.
+
+Go_optimize::Go_optimize(const char* name)
+  : next_(optimizations), name_(name), is_enabled_(false)
+{
+  optimizations = this;
+}
+
+// Enable an optimization by name.
+
+bool
+Go_optimize::enable_by_name(const char* name)
+{
+  bool is_all = strcmp(name, "all") == 0;
+  bool found = false;
+  for (Go_optimize* p = optimizations; p != NULL; p = p->next_)
+    {
+      if (is_all || strcmp(name, p->name_) == 0)
+	{
+	  p->is_enabled_ = true;
+	  found = true;
+	}
+    }
+  return found;
+}
+
+// Enable an optimization.  Return 1 if this is a real name, 0 if not.
+
+GO_EXTERN_C
+int
+go_enable_optimize(const char* name)
+{
+  return Go_optimize::enable_by_name(name) ? 1 : 0;
+}
Index: gcc/go/gofrontend/go-optimize.h
===================================================================
--- gcc/go/gofrontend/go-optimize.h	(revision 0)
+++ gcc/go/gofrontend/go-optimize.h	(revision 0)
@@ -0,0 +1,38 @@ 
+// go-optimize.h -- Go frontend optimizer flags.    -*- C++ -*-
+
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#ifndef GO_OPTIMIZE_H
+#define GO_OPTIMIZE_H
+
+// This class manages different arguments to -fgo-optimize-XXX.  If you
+// want to create a new optimization, create a variable of this type with the
+// name to use for XXX.  You can then use is_enabled to see whether
+// the -fgo-optimize-XXX option was used on the command line.
+
+class Go_optimize
+{
+ public:
+  Go_optimize(const char* name);
+
+  // Whether this optimizaiton was enabled.
+  bool
+  is_enabled() const
+  { return this->is_enabled_; }
+
+  // Enable an optimization by name.  Return true if found.
+  static bool
+  enable_by_name(const char*);
+
+ private:
+  // The next optimize flag.  These are not in any order.
+  Go_optimize* next_;
+  // The name of this optimization pass.
+  const char* name_;
+  // Whether this dump was enabled.
+  bool is_enabled_;
+};
+
+#endif // !defined(GO_OPTIMIZE_H)
Index: gcc/go/gofrontend/string-dump.h
===================================================================
--- gcc/go/gofrontend/string-dump.h	(revision 0)
+++ gcc/go/gofrontend/string-dump.h	(revision 0)
@@ -0,0 +1,25 @@ 
+// string-dump.h -- Abstract base class for dumping strings.    -*- C++ -*-
+
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#ifndef GO_STRING_DUMP_H
+#define GO_STRING_DUMP_H
+
+// This abstract class provides an interface strings for whatever purpose.
+// Used for example for exporting and dumping objects.
+
+class String_dump 
+{
+ public:
+  // Write a string. Implements the String_dump interface.
+  virtual void
+  write_string(const std::string& s) = 0;
+
+  // Implementors should override this member, to dump a formatted c string.
+  virtual void
+  write_c_string(const char*) = 0;
+};
+
+#endif  // GO_STRING_DUMP_H
Index: gcc/go/gofrontend/expressions.cc
===================================================================
--- gcc/go/gofrontend/expressions.cc	(revision 178040)
+++ gcc/go/gofrontend/expressions.cc	(working copy)
@@ -1345,7 +1345,13 @@  Func_expression::do_get_tree(Translate_c
 void
 Func_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
 {
-  ast_dump_context->ostream() << this->function_->name() ;
+  ast_dump_context->ostream() << this->function_->name();
+  if (this->closure_ != NULL)
+    {
+      ast_dump_context->ostream() << " {closure =  ";
+      this->closure_->dump_expression(ast_dump_context);
+      ast_dump_context->ostream() << "}";
+    }
 }
 
 // Make a reference to a function in an expression.
@@ -1423,7 +1429,6 @@  Unknown_expression::do_dump_expression(A
 {
   ast_dump_context->ostream() << "_Unknown_(" << this->named_object_->name()
 			      << ")";
-   
 }
 
 // Make a reference to an unknown name.
@@ -1563,16 +1568,17 @@  String_expression::do_get_tree(Translate
   return context->gogo()->go_string_constant_tree(this->val_);
 }
 
-// Export a string expression.
+ // Write string literal to string dump.
 
 void
-String_expression::do_export(Export* exp) const
+String_expression::export_string(String_dump* exp,
+				 const String_expression* str)
 {
   std::string s;
-  s.reserve(this->val_.length() * 4 + 2);
+  s.reserve(str->val_.length() * 4 + 2);
   s += '"';
-  for (std::string::const_iterator p = this->val_.begin();
-       p != this->val_.end();
+  for (std::string::const_iterator p = str->val_.begin();
+       p != str->val_.end();
        ++p)
     {
       if (*p == '\\' || *p == '"')
@@ -1600,6 +1606,14 @@  String_expression::do_export(Export* exp
   exp->write_string(s);
 }
 
+// Export a string expression.
+
+void
+String_expression::do_export(Export* exp) const
+{
+  String_expression::export_string(exp, this);
+}
+
 // Import a string expression.
 
 Expression*
@@ -1647,8 +1661,7 @@  String_expression::do_import(Import* imp
 void
 String_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
 {
-  // FIXME: Do proper backshlash quoting for this->val_
-  ast_dump_context->ostream() << "\"" << this->val_ << "\"";
+  String_expression::export_string(ast_dump_context, this);
 }
 
 // Make a string expression.
@@ -1676,9 +1689,9 @@  class Integer_expression : public Expres
   static bool
   check_constant(mpz_t val, Type*, source_location);
 
-  // Write VAL to export data.
+  // Write VAL to string dump.
   static void
-  export_integer(Export* exp, const mpz_t val);
+  export_integer(String_dump* exp, const mpz_t val);
 
   // Write VAL to dump context.
   static void
@@ -1861,7 +1874,7 @@  Integer_expression::do_get_tree(Translat
 // Write VAL to export data.
 
 void
-Integer_expression::export_integer(Export* exp, const mpz_t val)
+Integer_expression::export_integer(String_dump* exp, const mpz_t val)
 {
   char* s = mpz_get_str(NULL, 10, val);
   exp->write_c_string(s);
@@ -1962,27 +1975,12 @@  Integer_expression::do_import(Import* im
       return ret;
     }
 }
-
-// Write integer to dump context.
-
-void
-Integer_expression::dump_integer(Ast_dump_context* ast_dump_context, 
-                                 const mpz_t val)
-{
-  // FIXME: refactor this code so that is used both by dump and export. Extract
-  // a common interface for Ast_dump_context and Export.
-  char* s = mpz_get_str(NULL, 10, val);
-  ast_dump_context->ostream() << s ;
-  free(s);
-}
-
-
 // Ast dump for integer expression.
 
 void
 Integer_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
 {
-  Integer_expression::dump_integer(ast_dump_context, this->val_);
+  Integer_expression::export_integer(ast_dump_context, this->val_);
 }
 
 // Build a new integer value.
@@ -2016,8 +2014,8 @@  class Float_expression : public Expressi
 
   // Write VAL to export data.
   static void
-  export_float(Export* exp, const mpfr_t val);
-  
+  export_float(String_dump* exp, const mpfr_t val);
+
   // Write VAL to dump file.
   static void
   dump_float(Ast_dump_context* ast_dump_context, const mpfr_t val);
@@ -2203,10 +2201,10 @@  Float_expression::do_get_tree(Translate_
   return Expression::float_constant_tree(this->val_, type);
 }
 
-// Write a floating point number to export data.
+// Write a floating point number to a string dump.
 
 void
-Float_expression::export_float(Export *exp, const mpfr_t val)
+Float_expression::export_float(String_dump *exp, const mpfr_t val)
 {
   mp_exp_t exponent;
   char* s = mpfr_get_str(NULL, &exponent, 10, 0, val, GMP_RNDN);
@@ -2230,33 +2228,12 @@  Float_expression::do_export(Export* exp)
   exp->write_c_string(" ");
 }
 
-// Write  a floating point number to a dump context.
-
-void
-Float_expression::dump_float(Ast_dump_context* ast_dump_context, 
-                                  const mpfr_t val)
-{
-  // FIXME: this code should be refactored so that the same code is used here
-  // and in export_float.
-
-  mp_exp_t exponent;
-  char* s = mpfr_get_str(NULL, &exponent, 10, 0, val, GMP_RNDN);
-  if (*s == '-')
-    ast_dump_context->ostream() << "-";
-  ast_dump_context->ostream() << "0.";
-  ast_dump_context->ostream() << (*s == '-' ? s + 1 : s);
-  mpfr_free_str(s);
-  char buf[30];
-  snprintf(buf, sizeof buf, "E%ld", exponent);
-  ast_dump_context->ostream()  << buf;
-}
-
 // Dump a floating point number to the dump file.
 
 void
 Float_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
 {
-  Float_expression::dump_float(ast_dump_context, this->val_);
+  Float_expression::export_float(ast_dump_context, this->val_);
 }
 
 // Make a float expression.
@@ -2289,9 +2266,9 @@  class Complex_expression : public Expres
   static bool
   check_constant(mpfr_t real, mpfr_t imag, Type*, source_location);
 
-  // Write REAL/IMAG to export data.
+  // Write REAL/IMAG to string dump.
   static void
-  export_complex(Export* exp, const mpfr_t real, const mpfr_t val);
+  export_complex(String_dump* exp, const mpfr_t real, const mpfr_t val);
 
   // Write REAL/IMAG to dump context.
   static void
@@ -2477,7 +2454,7 @@  Complex_expression::do_get_tree(Translat
 // Write REAL/IMAG to export data.
 
 void
-Complex_expression::export_complex(Export* exp, const mpfr_t real,
+Complex_expression::export_complex(String_dump* exp, const mpfr_t real,
 				   const mpfr_t imag)
 {
   if (!mpfr_zero_p(real))
@@ -2500,30 +2477,12 @@  Complex_expression::do_export(Export* ex
   exp->write_c_string(" ");
 }
 
-// Write a complex number to a dump context.
-
-void
-Complex_expression::dump_complex(Ast_dump_context* ast_dump_context,
-                                    const mpfr_t real, const mpfr_t imag) 
-{
-  // FIXME: this code should be refactored so that it is used both here
-  // and by export _complex
-  if (!mpfr_zero_p(real))
-    {
-      Float_expression::dump_float(ast_dump_context, real);
-      if (mpfr_sgn(imag) > 0)
-        ast_dump_context->ostream() << "+";
-    }
-  Float_expression::dump_float(ast_dump_context, imag);
-  ast_dump_context->ostream() << "i";
-}
-
 // Dump a complex expression to the dump file.
 
 void
 Complex_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
 {
-  Complex_expression::dump_complex(ast_dump_context, 
+  Complex_expression::export_complex(ast_dump_context,
                                       this->real_,
                                       this->imag_);
 }
@@ -11622,7 +11581,6 @@  void
 Struct_construction_expression::do_dump_expression(
     Ast_dump_context* ast_dump_context) const
 {
-
   ast_dump_context->dump_type(this->type_);
   ast_dump_context->ostream() << "{";
   ast_dump_context->dump_expression_list(this->vals_);
@@ -11875,6 +11833,15 @@  void
 Array_construction_expression::do_dump_expression(
     Ast_dump_context* ast_dump_context) const
 {
+  Expression* length = this->type_->array_type() != NULL ?
+			 this->type_->array_type()->length() : NULL;
+
+  ast_dump_context->ostream() << "[" ;
+  if (length != NULL)
+    {
+      ast_dump_context->dump_expression(length);
+    }
+  ast_dump_context->ostream() << "]" ;
   ast_dump_context->dump_type(this->type_);
   ast_dump_context->ostream() << "{" ;
   ast_dump_context->dump_expression_list(this->vals_);
@@ -11910,6 +11877,9 @@  class Fixed_array_construction_expressio
 
   tree
   do_get_tree(Translate_context*);
+
+  void
+  do_dump_expression(Ast_dump_context*);
 };
 
 // Return a tree for constructing a fixed array.
@@ -11922,6 +11892,22 @@  Fixed_array_construction_expression::do_
   return this->get_constructor_tree(context, type_to_tree(btype));
 }
 
+// Dump ast representation of an array construction expressin.
+
+void
+Fixed_array_construction_expression::do_dump_expression(
+    Ast_dump_context* ast_dump_context)
+{
+
+  ast_dump_context->ostream() << "[";
+  ast_dump_context->dump_expression (this->type()->array_type()->length());
+  ast_dump_context->ostream() << "]";
+  ast_dump_context->dump_type(this->type());
+  ast_dump_context->ostream() << "{";
+  ast_dump_context->dump_expression_list(this->vals());
+  ast_dump_context->ostream() << "}";
+
+}
 // Construct an open array.
 
 class Open_array_construction_expression : public Array_construction_expression
@@ -12410,9 +12396,8 @@  void
 Map_construction_expression::do_dump_expression(
     Ast_dump_context* ast_dump_context) const
 {
-  // FIXME: We should print key:value pairs here.
   ast_dump_context->ostream() << "{" ;
-  ast_dump_context->dump_expression_list(this->vals_);
+  ast_dump_context->dump_expression_list(this->vals_, true);
   ast_dump_context->ostream() << "}";
 }
 
@@ -12866,11 +12851,10 @@  void
 Composite_literal_expression::do_dump_expression(
                                Ast_dump_context* ast_dump_context) const
 {
-  // FIXME: We should print colons if this->has_keys_ is true
-  ast_dump_context->ostream() << "composite_literal(" ;
+  ast_dump_context->ostream() << "composite(";
   ast_dump_context->dump_type(this->type_);
   ast_dump_context->ostream() << ", {";
-  ast_dump_context->dump_expression_list(this->vals_);
+  ast_dump_context->dump_expression_list(this->vals_, this->has_keys_);
   ast_dump_context->ostream() << "})";
 }
 
Index: gcc/go/go-lang.c
===================================================================
--- gcc/go/go-lang.c	(revision 178040)
+++ gcc/go/go-lang.c	(working copy)
@@ -223,6 +223,10 @@  go_langhook_handle_option (
       ret = go_enable_dump (arg) ? true : false;
       break;
 
+    case OPT_fgo_optimize_:
+      ret = go_enable_optimize (arg) ? true : false;
+      break;
+
     case OPT_fgo_prefix_:
       go_set_prefix (arg);
       break;
Index: gcc/go/ChangeLog
===================================================================
--- gcc/go/ChangeLog	(revision 178040)
+++ gcc/go/ChangeLog	(working copy)
@@ -1,3 +1,18 @@ 
+2011-08-24  Roberto Lublinerman  <rluble@gmail.com>
+
+	* lang.opt: Add fgo-optimize-.
+	* go-lang.c (go_langhook_handle_option): Handle OPT_fgo_optimize.
+	* go-c.h (go_enable_optimize): Declare.
+	* Make-lang.in (GO_OBJS): Add go/go-optimize.o.
+	(GO_EXPORT_H): Define.
+	(GO_IMPORT_H): Add $(GO_EXPORT_H).
+	(GO_AST_DUMP_H): Define.
+	(go/ast-dump.o, go/statements.o): Use GO_AST_DUMP_H.
+	(go/export.o, go/gogo.o, go/import.o): Use GO_EXPORT_H.
+	(go/types.o): Likewise.
+	(go/expressions.o): Use GO_AST_DUMP_H and GO_EXPORT_H.
+	(go/go-optimize.o): New target.
+
 2011-08-24  Joseph Myers  <joseph@codesourcery.com>
 
 	* Make-lang.in (CFLAGS-go/go-lang.o): New.
Index: gcc/go/go-c.h
===================================================================
--- gcc/go/go-c.h	(revision 178040)
+++ gcc/go/go-c.h	(working copy)
@@ -37,6 +37,7 @@  extern "C"
    interface.  */
 
 extern int go_enable_dump (const char*);
+extern int go_enable_optimize (const char*);
 extern void go_set_prefix (const char*);
 
 extern void go_add_search_path (const char*);