1 Star 1 Fork 1

U语言组织 / U语言

forked from 秋来冬风 / U语言 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
optimize.go 4.63 KB
一键复制 编辑 原始数据 按行查看 历史
package ir
import (
"strconv"
"gitee.com/u-language/u-language/ucom/enum"
"gitee.com/u-language/u-language/ucom/internal/utils"
)
// AmexprOptimize 算术表达式优化
//
// 实现下列优化
// - 如果结果为立即数临时变量(也就是编译期可求值),直接使用该立即数,不等到运行时计算
func (t *ToState) AmexprOptimize(ret *[]IrNode) (ArgObj string, ArgTyp ArgEnum) {
switch resultret := (*ret)[len(*ret)-1]; resultret.ResultTyp {
case TmpIntVar:
ArgTyp = ImmInt
ArgObj = t.HavaTmpVar(resultret.ResultObj)
(*ret) = (*ret)[:len(*ret)-1]
case TmpFloatVar:
ArgTyp = ImmFloat
ArgObj = t.HavaTmpVar(resultret.ResultObj)
(*ret) = (*ret)[:len(*ret)-1]
}
if len(*ret) == 0 {
return
}
return (*ret)[len(*ret)-1].ResultObj, (*ret)[len(*ret)-1].ResultTyp
}
// AmexprOptimizeOrImm 算术表达式可能立即数优化
//
// 如果算术表达式的操作数都是立即数(也就是编译期可求值),直接计算该立即数,不等到运行时计算
func (t *ToState) AmexprOptimizeOrImm(ptrir *IrNode, typ int8, op enum.OPSymbol) bool {
switch typ {
case intTyp:
if ptrir.Arg1Typ.IsImm() && ptrir.Arg2Typ.IsImm() { //都是int型立即数,语义检查会保证类型一致
src1, err := strconv.Atoi(ptrir.Arg1Obj)
utils.MustErr(err)
src2, err := strconv.Atoi(ptrir.Arg2Obj)
utils.MustErr(err)
result := intop(op, src1, src2)
tmp := t.auto.Get()
t.table[tmp] = strconv.Itoa(result)
ptrir.ResultObj = tmp
ptrir.ResultTyp = TmpIntVar
return true
}
case floatTyp:
if ptrir.Arg1Typ.IsImm() && ptrir.Arg2Typ.IsImm() { //都是float型立即数,语义检查会保证类型一致
src1, err := strconv.ParseFloat(ptrir.Arg1Obj, 64)
utils.MustErr(err)
src2, err := strconv.ParseFloat(ptrir.Arg2Obj, 64)
utils.MustErr(err)
result := floatop(op, src1, src2)
tmp := t.auto.Get()
t.table[tmp] = strconv.FormatFloat(result, 'f', -1, 64)
ptrir.ResultObj = tmp
ptrir.ResultTyp = TmpFloatVar
return true
}
}
return false
}
func intop(op enum.OPSymbol, src1, src2 int) int {
switch op {
case enum.ADDOP:
return src1 + src2
case enum.SUBOP:
return src1 - src2
}
return 0
}
func floatop(op enum.OPSymbol, src1, src2 float64) float64 {
switch op {
case enum.ADDOP:
return src1 + src2
case enum.SUBOP:
return src1 - src2
}
return 0
}
// ASSIGNOptimize 赋值转换的中间代码优化
//
// 实现下列优化
// - 如果赋值源操作数类型为临时变量,且这个临时变量为上一个的结果,将上一个的结果改写为赋值目的操作数
// - 如果其中任意两条中间代码形如(a op1 b) op2 c,且b和c为立即数,同时op1和op2优先级相同,改写为a op1 (b op2 c),并编译期求值
func (t *ToState) ASSIGNOptimize(ptrir *IrNode, ret *[]IrNode) {
if ptrir.Arg1Typ == Tmp {
if resultret := &((*ret)[len(*ret)-2]); resultret.ResultObj == ptrir.Arg1Obj {
resultret.ResultObj = ptrir.ResultObj
resultret.ResultTyp = ptrir.ResultTyp
(*ret) = (*ret)[:len(*ret)-1]
}
}
if len(*ret) < 2 {
return
}
for i := len(*ret); i >= 2; i-- {
if src1node, src2node := &((*ret)[i-2]), &((*ret)[i-1]); immTypeEqual(src1node.Arg2Typ, src2node.Arg2Typ) {
switch src1node.Arg2Typ {
case ImmInt:
src1, err := strconv.Atoi(src1node.Arg2Obj)
utils.MustErr(err)
src2, err := strconv.Atoi(src2node.Arg2Obj)
utils.MustErr(err)
switch src2node.Op {
case ADDOP:
src1node.Arg2Obj = strconv.Itoa(intop(enum.ADDOP, src1, src2))
src1node.ResultObj, src1node.ResultTyp = src2node.ResultObj, src2node.ResultTyp
(*ret) = append((*ret)[:i-1], (*ret)[i:]...)
case SUBOP:
src1node.Arg2Obj = strconv.Itoa(intop(enum.SUBOP, src1, src2))
src1node.ResultObj, src1node.ResultTyp = src2node.ResultObj, src2node.ResultTyp
(*ret) = append((*ret)[:i-1], (*ret)[i:]...)
}
case ImmFloat:
src1, err := strconv.ParseFloat(src1node.Arg2Obj, 64)
utils.MustErr(err)
src2, err := strconv.ParseFloat(src2node.Arg2Obj, 64)
utils.MustErr(err)
switch src2node.Op {
case ADDOP:
src1node.Arg2Obj = strconv.FormatFloat(floatop(enum.ADDOP, src1, src2), 'f', -1, 64)
src1node.ResultObj, src1node.ResultTyp = src2node.ResultObj, src2node.ResultTyp
(*ret) = append((*ret)[:i-1], (*ret)[i:]...)
case SUBOP:
src1node.Arg2Obj = strconv.FormatFloat(floatop(enum.SUBOP, src1, src2), 'f', -1, 64)
src1node.ResultObj, src1node.ResultTyp = src2node.ResultObj, src2node.ResultTyp
(*ret) = append((*ret)[:i-1], (*ret)[i:]...)
}
}
}
}
}
func immTypeEqual(src1, src2 ArgEnum) bool {
if src1.IsImm() && src2.IsImm() && src1 == src2 {
return true
}
return false
}
Go
1
https://gitee.com/u-language/u-language.git
git@gitee.com:u-language/u-language.git
u-language
u-language
U语言
a214d6007862

搜索帮助