 a97ca91c1f
			
		
	
	
		a97ca91c1f
		
			
		
	
	
	
	
		
			
			This is a big combined change. Other changes in this commit:
  * Analyze makeinterface and make sure type switches don't include
    unnecessary cases.
  * Do not include CGo wrapper functions in the analyzer callgraph.
    This also avoids some unnecessary type IDs.
  * Give all Go named structs a name in LLVM.
  * Use such a named struct for compiler-generated task data.
  * Use the type and function names defined by the ssa and types
    package instead of generating our own.
  * Some improvements to function pointers.
  * A few other minor improvements.
The one thing lacking here is interface-to-interface assertions.
		
	
			
		
			
				
	
	
		
			77 строки
		
	
	
	
		
			2,6 КиБ
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			77 строки
		
	
	
	
		
			2,6 КиБ
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # TinyGo - Go compiler for microcontrollers
 | |
| 
 | |
| > We never expected Go to be an embedded language and so it's got serious
 | |
| > problems [...].
 | |
| 
 | |
| -- Rob Pike, [GopherCon 2014 Opening Keynote](https://www.youtube.com/watch?v=VoS7DsT1rdM&feature=youtu.be&t=2799)
 | |
| 
 | |
| TinyGo is a project to bring Go to microcontrollers and small systems with a
 | |
| single processor core. It is similar to [emgo](https://github.com/ziutek/emgo)
 | |
| but a major difference is that I want to keep the Go memory model (which implies
 | |
| garbage collection of some sort). Another difference is that TinyGo uses LLVM
 | |
| internally instead of emitting C, which hopefully leads to smaller and more
 | |
| efficient code and certainly leads to more flexibility.
 | |
| 
 | |
| My original reasoning was: if [Python](https://micropython.org/) can run on
 | |
| microcontrollers, then certainly [Go](https://golang.org/) should be able to and
 | |
| run on even lower level micros.
 | |
| 
 | |
| Example program (blinky):
 | |
| 
 | |
| ```go
 | |
| import "machine"
 | |
| 
 | |
| func main() {
 | |
| 	led := machine.GPIO{machine.LED}
 | |
| 	led.Configure(machine.GPIOConfig{Mode: machine.GPIO_OUTPUT})
 | |
| 	for {
 | |
| 		led.Low()
 | |
| 		runtime.Sleep(runtime.Millisecond * 1000)
 | |
| 
 | |
| 		led.High()
 | |
| 		runtime.Sleep(runtime.Millisecond * 1000)
 | |
| 	}
 | |
| }
 | |
| ```
 | |
| 
 | |
| Currently supported features:
 | |
| 
 | |
|   * control flow
 | |
|   * many (but not all) basic types: most ints, strings, structs
 | |
|   * function calling
 | |
|   * interfaces for basic types (with type switches and asserts)
 | |
|   * goroutines (very initial support)
 | |
|   * function pointers (non-blocking)
 | |
| 
 | |
| Not yet supported:
 | |
| 
 | |
|   * float, complex, etc.
 | |
|   * maps
 | |
|   * slices
 | |
|   * interface methods
 | |
|   * garbage collection
 | |
|   * defer
 | |
|   * closures
 | |
|   * channels
 | |
|   * introspection (if it ever gets implemented)
 | |
|   * standard library (needs more language support)
 | |
|   * ...
 | |
| 
 | |
| ## Analysis
 | |
| 
 | |
| The goal is to reduce code size (and increase performance) by performing all
 | |
| kinds of whole-program analysis passes. The official Go compiler doesn't do a
 | |
| whole lot of analysis (except for escape analysis) becauses it needs to be fast,
 | |
| but embedded programs are necessarily smaller so it becomes practical. And I
 | |
| think especially program size can be reduced by a large margin when actually
 | |
| trying to optimize for it.
 | |
| 
 | |
| Implemented analysis passes:
 | |
| 
 | |
|   * Check which functions are blocking. Blocking functions a functions that call
 | |
|     sleep, chan send, etc. It's parents are also blocking.
 | |
|   * Check whether the scheduler is needed. It is only needed when there are `go`
 | |
|     statements for blocking functions.
 | |
|   * Check whether a given type switch or type assert is possible with
 | |
|     [type-based alias analysis](https://en.wikipedia.org/wiki/Alias_analysis#Type-based_alias_analysis).
 | |
|     I would like to use flow-based alias analysis in the future.
 |