Handle local variables correctly
They were computed again and again each time they were used.
Этот коммит содержится в:
родитель
e0e04b88cb
коммит
01ee0c456c
1 изменённых файлов: 12 добавлений и 7 удалений
19
tgo.go
19
tgo.go
|
@ -45,7 +45,7 @@ type Frame struct {
|
||||||
pkgName string
|
pkgName string
|
||||||
name string // full name, including package
|
name string // full name, including package
|
||||||
params map[*ssa.Parameter]int // arguments to the function
|
params map[*ssa.Parameter]int // arguments to the function
|
||||||
values map[ssa.Value]llvm.Value // local variables
|
locals map[ssa.Value]llvm.Value // local variables
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCompiler(path, triple string) (*Compiler, error) {
|
func NewCompiler(path, triple string) (*Compiler, error) {
|
||||||
|
@ -148,7 +148,7 @@ func (c *Compiler) parseFuncDecl(pkgName string, f *ssa.Function) (*Frame, error
|
||||||
pkgName: pkgName,
|
pkgName: pkgName,
|
||||||
name: name,
|
name: name,
|
||||||
params: make(map[*ssa.Parameter]int),
|
params: make(map[*ssa.Parameter]int),
|
||||||
values: make(map[ssa.Value]llvm.Value),
|
locals: make(map[ssa.Value]llvm.Value),
|
||||||
}
|
}
|
||||||
|
|
||||||
var retType llvm.Type
|
var retType llvm.Type
|
||||||
|
@ -220,8 +220,9 @@ func (c *Compiler) parseFunc(frame *Frame, f *ssa.Function) error {
|
||||||
|
|
||||||
func (c *Compiler) parseInstr(frame *Frame, instr ssa.Instruction) error {
|
func (c *Compiler) parseInstr(frame *Frame, instr ssa.Instruction) error {
|
||||||
switch instr := instr.(type) {
|
switch instr := instr.(type) {
|
||||||
case *ssa.Call:
|
case ssa.Value:
|
||||||
_, err := c.parseCall(frame, instr)
|
value, err := c.parseExpr(frame, instr)
|
||||||
|
frame.locals[instr] = value
|
||||||
return err
|
return err
|
||||||
case *ssa.Return:
|
case *ssa.Return:
|
||||||
if len(instr.Results) == 0 {
|
if len(instr.Results) == 0 {
|
||||||
|
@ -237,9 +238,6 @@ func (c *Compiler) parseInstr(frame *Frame, instr ssa.Instruction) error {
|
||||||
} else {
|
} else {
|
||||||
return errors.New("todo: return value")
|
return errors.New("todo: return value")
|
||||||
}
|
}
|
||||||
case ssa.Value:
|
|
||||||
_, err := c.parseExpr(frame, instr)
|
|
||||||
return err
|
|
||||||
default:
|
default:
|
||||||
return errors.New("unknown instruction: " + fmt.Sprintf("%#v", instr))
|
return errors.New("unknown instruction: " + fmt.Sprintf("%#v", instr))
|
||||||
}
|
}
|
||||||
|
@ -337,6 +335,13 @@ func (c *Compiler) parseBinOp(frame *Frame, binop *ssa.BinOp) (llvm.Value, error
|
||||||
|
|
||||||
func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) {
|
func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) {
|
||||||
fmt.Printf(" expr: %v\n", expr)
|
fmt.Printf(" expr: %v\n", expr)
|
||||||
|
|
||||||
|
if value, ok := frame.locals[expr]; ok {
|
||||||
|
// Value is a local variable that has already been computed.
|
||||||
|
fmt.Println(" from local var")
|
||||||
|
return value, nil
|
||||||
|
}
|
||||||
|
|
||||||
switch expr := expr.(type) {
|
switch expr := expr.(type) {
|
||||||
case *ssa.Const:
|
case *ssa.Const:
|
||||||
switch expr.Value.Kind() {
|
switch expr.Value.Kind() {
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче