| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | // Copyright 2009 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. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package gc | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //	case OADD: | 
					
						
							|  |  |  | //		if(n->right->op == OLITERAL) { | 
					
						
							|  |  |  | //			v = n->right->vconst; | 
					
						
							|  |  |  | //			naddr(n->left, a, canemitcode); | 
					
						
							|  |  |  | //		} else | 
					
						
							|  |  |  | //		if(n->left->op == OLITERAL) { | 
					
						
							|  |  |  | //			v = n->left->vconst; | 
					
						
							|  |  |  | //			naddr(n->right, a, canemitcode); | 
					
						
							|  |  |  | //		} else | 
					
						
							|  |  |  | //			goto bad; | 
					
						
							|  |  |  | //		a->offset += v; | 
					
						
							|  |  |  | //		break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* | 
					
						
							|  |  |  |  * a function named init is a special case. | 
					
						
							|  |  |  |  * it is called by the initialization before | 
					
						
							|  |  |  |  * main is run. to make it unique within a | 
					
						
							|  |  |  |  * package and also uncallable, the name, | 
					
						
							| 
									
										
										
										
											2015-02-20 13:54:45 -05:00
										 |  |  |  * normally "pkg.init", is altered to "pkg.init.1". | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var renameinit_initgen int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func renameinit() *Sym { | 
					
						
							|  |  |  | 	renameinit_initgen++ | 
					
						
							| 
									
										
										
										
											2015-03-06 12:02:24 -08:00
										 |  |  | 	return Lookupf("init.%d", renameinit_initgen) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* | 
					
						
							|  |  |  |  * hand-craft the following initialization code | 
					
						
							|  |  |  |  *	var initdone· uint8 				(1) | 
					
						
							|  |  |  |  *	func init()					(2) | 
					
						
							|  |  |  |  *		if initdone· != 0 {			(3) | 
					
						
							|  |  |  |  *			if initdone· == 2		(4) | 
					
						
							|  |  |  |  *				return | 
					
						
							|  |  |  |  *			throw();			(5) | 
					
						
							|  |  |  |  *		} | 
					
						
							|  |  |  |  *		initdone· = 1;				(6) | 
					
						
							|  |  |  |  *		// over all matching imported symbols | 
					
						
							|  |  |  |  *			<pkg>.init()			(7) | 
					
						
							|  |  |  |  *		{ <init stmts> }			(8) | 
					
						
							| 
									
										
										
										
											2015-02-20 13:54:45 -05:00
										 |  |  |  *		init.<n>() // if any			(9) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  |  *		initdone· = 2;				(10) | 
					
						
							|  |  |  |  *		return					(11) | 
					
						
							|  |  |  |  *	} | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | func anyinit(n *NodeList) bool { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	// are there any interesting init statements | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 	for l := n; l != nil; l = l.Next { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		switch l.N.Op { | 
					
						
							| 
									
										
										
										
											2015-04-01 09:38:44 -07:00
										 |  |  | 		case ODCLFUNC, ODCLCONST, ODCLTYPE, OEMPTY: | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			break | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												cmd/internal/gc: emit write barriers at lower level
This is primarily preparation for inlining, not an optimization by itself,
but it still helps some.
name                                       old                     new          delta
BenchmarkBinaryTree17              18.2s × (0.99,1.01)     17.9s × (0.99,1.01)  -1.57%
BenchmarkFannkuch11                4.44s × (1.00,1.00)     4.42s × (1.00,1.00)  -0.40%
BenchmarkFmtFprintfEmpty           119ns × (0.95,1.02)     118ns × (0.96,1.02)  ~
BenchmarkFmtFprintfString          501ns × (0.99,1.02)     486ns × (0.99,1.01)  -2.89%
BenchmarkFmtFprintfInt             474ns × (0.99,1.00)     457ns × (0.99,1.01)  -3.59%
BenchmarkFmtFprintfIntInt          792ns × (1.00,1.00)     768ns × (1.00,1.01)  -3.03%
BenchmarkFmtFprintfPrefixedInt     574ns × (1.00,1.01)     584ns × (0.99,1.03)  +1.83%
BenchmarkFmtFprintfFloat           749ns × (1.00,1.00)     739ns × (0.99,1.00)  -1.34%
BenchmarkFmtManyArgs              2.94µs × (1.00,1.01)    2.77µs × (1.00,1.00)  -5.76%
BenchmarkGobDecode                39.5ms × (0.99,1.01)    39.3ms × (0.99,1.01)  ~
BenchmarkGobEncode                39.4ms × (1.00,1.01)    39.4ms × (0.99,1.00)  ~
BenchmarkGzip                      658ms × (1.00,1.01)     661ms × (0.99,1.01)  ~
BenchmarkGunzip                    142ms × (1.00,1.00)     142ms × (1.00,1.00)  +0.22%
BenchmarkHTTPClientServer          134µs × (0.99,1.01)     133µs × (0.98,1.01)  ~
BenchmarkJSONEncode               57.1ms × (0.99,1.01)    56.5ms × (0.99,1.01)  ~
BenchmarkJSONDecode                141ms × (1.00,1.00)     143ms × (1.00,1.00)  +1.09%
BenchmarkMandelbrot200            6.01ms × (1.00,1.00)    6.01ms × (1.00,1.00)  ~
BenchmarkGoParse                  10.1ms × (0.91,1.09)     9.6ms × (0.94,1.07)  ~
BenchmarkRegexpMatchEasy0_32       207ns × (1.00,1.01)     210ns × (1.00,1.00)  +1.45%
BenchmarkRegexpMatchEasy0_1K       592ns × (0.99,1.00)     596ns × (0.99,1.01)  +0.68%
BenchmarkRegexpMatchEasy1_32       184ns × (0.99,1.01)     184ns × (0.99,1.01)  ~
BenchmarkRegexpMatchEasy1_1K      1.01µs × (1.00,1.00)    1.01µs × (0.99,1.01)  ~
BenchmarkRegexpMatchMedium_32      327ns × (0.99,1.00)     327ns × (1.00,1.01)  ~
BenchmarkRegexpMatchMedium_1K     92.5µs × (1.00,1.00)    93.0µs × (1.00,1.02)  +0.48%
BenchmarkRegexpMatchHard_32       4.79µs × (0.95,1.00)    4.76µs × (0.95,1.01)  ~
BenchmarkRegexpMatchHard_1K        136µs × (1.00,1.00)     136µs × (1.00,1.01)  ~
BenchmarkRevcomp                   900ms × (0.99,1.01)     892ms × (1.00,1.01)  ~
BenchmarkTemplate                  170ms × (0.99,1.01)     175ms × (0.99,1.00)  +2.95%
BenchmarkTimeParse                 645ns × (1.00,1.00)     638ns × (1.00,1.00)  -1.16%
BenchmarkTimeFormat                740ns × (1.00,1.00)     772ns × (1.00,1.00)  +4.39%
Change-Id: I0be905e32791e0cb70ff01f169c4b309a971d981
Reviewed-on: https://go-review.googlesource.com/9159
Reviewed-by: Rick Hudson <rlh@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
											
										 
											2015-04-17 00:25:10 -04:00
										 |  |  | 		case OAS, OASWB: | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 			if isblank(l.N.Left) && candiscard(l.N.Right) { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 				break | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			fallthrough | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// fall through | 
					
						
							|  |  |  | 		default: | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 			return true | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// is this main | 
					
						
							|  |  |  | 	if localpkg.Name == "main" { | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 		return true | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// is there an explicit init function | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 	s := Lookup("init.1") | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if s.Def != nil { | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 		return true | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// are there any imported init functions | 
					
						
							| 
									
										
										
										
											2015-03-02 16:21:15 -05:00
										 |  |  | 	for _, s := range initSyms { | 
					
						
							|  |  |  | 		if s.Def != nil { | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 			return true | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// then none | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 	return false | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func fninit(n *NodeList) { | 
					
						
							|  |  |  | 	if Debug['A'] != 0 { | 
					
						
							|  |  |  | 		// sys.go or unsafe.go during compiler build | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	n = initfix(n) | 
					
						
							| 
									
										
										
										
											2015-02-17 22:13:49 -05:00
										 |  |  | 	if !anyinit(n) { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-02 14:22:05 -05:00
										 |  |  | 	var r *NodeList | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// (1) | 
					
						
							| 
									
										
										
										
											2015-03-06 12:02:24 -08:00
										 |  |  | 	gatevar := newname(Lookup("initdone·")) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	addvar(gatevar, Types[TUINT8], PEXTERN) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// (2) | 
					
						
							|  |  |  | 	Maxarg = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 	fn := Nod(ODCLFUNC, nil, nil) | 
					
						
							| 
									
										
										
										
											2015-03-06 12:02:24 -08:00
										 |  |  | 	initsym := Lookup("init") | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	fn.Nname = newname(initsym) | 
					
						
							|  |  |  | 	fn.Nname.Defn = fn | 
					
						
							| 
									
										
										
										
											2015-05-19 15:25:35 -07:00
										 |  |  | 	fn.Nname.Param.Ntype = Nod(OTFUNC, nil, nil) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	declare(fn.Nname, PFUNC) | 
					
						
							|  |  |  | 	funchdr(fn) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// (3) | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 	a := Nod(OIF, nil, nil) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-26 21:30:20 -04:00
										 |  |  | 	a.Left = Nod(ONE, gatevar, Nodintconst(0)) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	r = list(r, a) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// (4) | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 	b := Nod(OIF, nil, nil) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-26 21:30:20 -04:00
										 |  |  | 	b.Left = Nod(OEQ, gatevar, Nodintconst(2)) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 	b.Nbody = list1(Nod(ORETURN, nil, nil)) | 
					
						
							|  |  |  | 	a.Nbody = list1(b) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// (5) | 
					
						
							|  |  |  | 	b = syslook("throwinit", 0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	b = Nod(OCALL, b, nil) | 
					
						
							|  |  |  | 	a.Nbody = list(a.Nbody, b) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// (6) | 
					
						
							|  |  |  | 	a = Nod(OAS, gatevar, Nodintconst(1)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	r = list(r, a) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// (7) | 
					
						
							| 
									
										
										
										
											2015-03-02 16:21:15 -05:00
										 |  |  | 	for _, s := range initSyms { | 
					
						
							|  |  |  | 		if s.Def != nil && s != initsym { | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 			// could check that it is fn of no args/returns | 
					
						
							|  |  |  | 			a = Nod(OCALL, s.Def, nil) | 
					
						
							|  |  |  | 			r = list(r, a) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// (8) | 
					
						
							|  |  |  | 	r = concat(r, n) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// (9) | 
					
						
							|  |  |  | 	// could check that it is fn of no args/returns | 
					
						
							| 
									
										
										
										
											2015-02-23 16:07:24 -05:00
										 |  |  | 	for i := 1; ; i++ { | 
					
						
							| 
									
										
										
										
											2015-03-06 12:02:24 -08:00
										 |  |  | 		s := Lookupf("init.%d", i) | 
					
						
							| 
									
										
										
										
											2015-02-13 14:40:36 -05:00
										 |  |  | 		if s.Def == nil { | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		a = Nod(OCALL, s.Def, nil) | 
					
						
							|  |  |  | 		r = list(r, a) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// (10) | 
					
						
							|  |  |  | 	a = Nod(OAS, gatevar, Nodintconst(2)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	r = list(r, a) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// (11) | 
					
						
							|  |  |  | 	a = Nod(ORETURN, nil, nil) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	r = list(r, a) | 
					
						
							|  |  |  | 	exportsym(fn.Nname) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fn.Nbody = r | 
					
						
							|  |  |  | 	funcbody(fn) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Curfn = fn | 
					
						
							|  |  |  | 	typecheck(&fn, Etop) | 
					
						
							|  |  |  | 	typechecklist(r, Etop) | 
					
						
							|  |  |  | 	Curfn = nil | 
					
						
							|  |  |  | 	funccompile(fn) | 
					
						
							|  |  |  | } |