diff options
author | Roberto Lublinerman <rluble@gmail.com> | 2011-08-24 19:22:44 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-08-24 19:22:44 +0000 |
commit | 706cd57f714fcb3572f97ded0bfbfcfe090181bc (patch) | |
tree | b321299877c5f4c075b0bf489c636f9c0c8dc1f3 | |
parent | 8020d73e39fbeef5c52455b8d935569b004fb031 (diff) | |
download | gcc-706cd57f714fcb3572f97ded0bfbfcfe090181bc.zip gcc-706cd57f714fcb3572f97ded0bfbfcfe090181bc.tar.gz gcc-706cd57f714fcb3572f97ded0bfbfcfe090181bc.tar.bz2 |
gccgo...
gccgo: fixes to ast-dump, refactoring of export and ast-dump
to implement a common interface for writing basic
type literals and added flags for optimization.
* 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.
From-SVN: r178046
-rw-r--r-- | gcc/go/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/go/Make-lang.in | 26 | ||||
-rw-r--r-- | gcc/go/go-c.h | 1 | ||||
-rw-r--r-- | gcc/go/go-lang.c | 4 | ||||
-rw-r--r-- | gcc/go/gofrontend/ast-dump.cc | 118 | ||||
-rw-r--r-- | gcc/go/gofrontend/ast-dump.h | 66 | ||||
-rw-r--r-- | gcc/go/gofrontend/export.h | 8 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 148 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.h | 5 | ||||
-rw-r--r-- | gcc/go/gofrontend/go-optimize.cc | 53 | ||||
-rw-r--r-- | gcc/go/gofrontend/go-optimize.h | 38 | ||||
-rw-r--r-- | gcc/go/gofrontend/statements.cc | 148 | ||||
-rw-r--r-- | gcc/go/gofrontend/string-dump.h | 25 | ||||
-rw-r--r-- | gcc/go/lang.opt | 6 |
14 files changed, 448 insertions, 213 deletions
diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index 16b24ac..3802fa8 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -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. diff --git a/gcc/go/Make-lang.in b/gcc/go/Make-lang.in index fc43612..d7ae7ae 100644 --- a/gcc/go/Make-lang.in +++ b/gcc/go/Make-lang.in @@ -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.cc $(GO_SYSTEM_H) $(TOPLEV_H) \ 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_SYSTEM_H) $(GO_GOGO_H) \ 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) diff --git a/gcc/go/go-c.h b/gcc/go/go-c.h index f70f1ad..f5ecbeb 100644 --- a/gcc/go/go-c.h +++ b/gcc/go/go-c.h @@ -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*); diff --git a/gcc/go/go-lang.c b/gcc/go/go-lang.c index 6abe3b8..7d2de44 100644 --- a/gcc/go/go-lang.c +++ b/gcc/go/go-lang.c @@ -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; diff --git a/gcc/go/gofrontend/ast-dump.cc b/gcc/go/gofrontend/ast-dump.cc index d52d367..850e31a 100644 --- a/gcc/go/gofrontend/ast-dump.cc +++ b/gcc/go/gofrontend/ast-dump.cc @@ -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_functions : public Traverse { } protected: - int + int block(Block*); - + int function(Named_object*); @@ -79,7 +79,7 @@ int Ast_dump_traverse_blocks_and_functions::block(Block * block) return TRAVERSE_SKIP_COMPONENTS; } - + // Dump each traversed statement. int @@ -87,7 +87,7 @@ Ast_dump_traverse_statements::statement(Block* block, size_t* pindex, 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 char* basename) 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* t) 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 Expression* e) // 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(const Typed_identifier* ti) 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 diff --git a/gcc/go/gofrontend/ast-dump.h b/gcc/go/gofrontend/ast-dump.h index 92a4915..55c9369 100644 --- a/gcc/go/gofrontend/ast-dump.h +++ b/gcc/go/gofrontend/ast-dump.h @@ -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_; }; diff --git a/gcc/go/gofrontend/export.h b/gcc/go/gofrontend/export.h index ef24977..1f8278f 100644 --- a/gcc/go/gofrontend/export.h +++ b/gcc/go/gofrontend/export.h @@ -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)); } diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 8053456..a082012 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -1345,7 +1345,13 @@ Func_expression::do_get_tree(Translate_context* context) 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(Ast_dump_context* ast_dump_context) const { 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_context* context) 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) const 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 Expression 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(Translate_context* context) // 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* imp) 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 Expression // 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_context* context) 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) const 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 Expression 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(Translate_context* context) // 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* exp) const 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_expression : 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_get_tree(Translate_context* context) 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() << "})"; } diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h index 6f74f73..ec59846 100644 --- a/gcc/go/gofrontend/expressions.h +++ b/gcc/go/gofrontend/expressions.h @@ -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 Expression 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; diff --git a/gcc/go/gofrontend/go-optimize.cc b/gcc/go/gofrontend/go-optimize.cc new file mode 100644 index 0000000..6da934f --- /dev/null +++ b/gcc/go/gofrontend/go-optimize.cc @@ -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; +} diff --git a/gcc/go/gofrontend/go-optimize.h b/gcc/go/gofrontend/go-optimize.h new file mode 100644 index 0000000..8638498 --- /dev/null +++ b/gcc/go/gofrontend/go-optimize.h @@ -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) diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc index c6d2ace..f653ef6 100644 --- a/gcc/go/gofrontend/statements.cc +++ b/gcc/go/gofrontend/statements.cc @@ -308,11 +308,11 @@ Variable_declaration_statement::do_dump_statement( 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(Ast_dump_context* ast_dump_context) const { ast_dump_context->ostream() << " "; ast_dump_context->dump_type(this->type_); - } if (this->init_ != NULL) { @@ -797,7 +796,7 @@ Assignment_operation_statement::do_dump_statement( { 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::lower_to_object_type( // 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(Translate_context* context) // 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, const std::string& thunk_name, // 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_context* ast_dump_context) const { 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_context* ast_dump_context) const 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(Translate_context* context, // 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_statement* val_temp, 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_context* ast_dump_context) const { 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_statement(Ast_dump_context* ast_dump_context) 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_dump_context* ast_dump_context) const 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::dump_clause( } 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_context* ast_dump_context) const { 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_clause( 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_clause( 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_context* ast_dump_context) const { 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(Translate_context* context) // 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(Unnamed_label* break_label, 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_dump_context* ast_dump_context) const 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(Ast_dump_context* ast_dump_context) const 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. diff --git a/gcc/go/gofrontend/string-dump.h b/gcc/go/gofrontend/string-dump.h new file mode 100644 index 0000000..fe4807d --- /dev/null +++ b/gcc/go/gofrontend/string-dump.h @@ -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 diff --git a/gcc/go/lang.opt b/gcc/go/lang.opt index 9d9b1ff..96c8d73 100644 --- a/gcc/go/lang.opt +++ b/gcc/go/lang.opt @@ -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 |