1 Star 1 Fork 1

U语言组织 / U语言

forked from 秋来冬风 / U语言 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
vreg.go 11.50 KB
一键复制 编辑 原始数据 按行查看 历史
package amd64
import (
"fmt"
"sync"
"sync/atomic"
"gitee.com/u-language/u-language/ucom/internal/utils"
)
const (
allocX86Reg = 12
allocSSEReg = 8
)
type virtualRegMem struct {
_zero int16
Type vrmTypeEnum
Size VrmSizeEnum
Num int32
}
// newvrm创建虚拟寄存器
func newvrm(Type vrmTypeEnum, Size VrmSizeEnum, Num int32) RegEnum {
return vrmToRegEnum(vrm{Type: Type, Size: Size, Num: Num})
}
func (v vrm) String() string {
return fmt.Sprintf("Type:=%s Size:=%s _zero:=%d Num:=%d", v.Type.String(), v.Size.String(), v._zero, v.Num)
}
// vrm是虚拟寄存器内存布局
type vrm = virtualRegMem
type virtualReg struct {
x86num int32
ssenum int32
}
// VReg是虚拟寄存器分配器
type VReg = virtualReg
// NewVReg创建虚拟寄存器分配器
func NewVReg() *VReg {
return &VReg{x86num: 0, ssenum: 0}
}
// GetX86Reg获取一个X86的虚拟寄存器
// - bit是寄存器大小
func (v *VReg) GetX86Reg(bit VrmSizeEnum) RegEnum {
n := atomic.AddInt32(&v.x86num, 1)
return newvrm(vrmx86, bit, n)
}
// GetSSEReg获取一个SSE的虚拟寄存器
func (v *VReg) GetSSEReg() RegEnum {
n := atomic.AddInt32(&v.ssenum, 1)
return newvrm(vrmsse, 0, n)
}
// AllocReg为虚拟寄存器分配实际寄存器
func AllocReg(nodes [][]TextNode, regrun *RegRun, sserun *SseRegRun, vtr *vRegToReg, vt vregToRegTable, Thread bool) {
nl := len(nodes)
if nl == 0 {
return
}
var (
wg = utils.NewWaitGroup(Thread)
_regrun = regrun
_sserun = sserun
vreg_to_reg *vRegToReg = vtr
vreg_To_Reg_Table = vt
)
for i := 0; i < nl; i++ {
for j := 0; j < len(nodes[i]); j++ {
n := &(nodes[i][j])
wg.Add()
bol := isManyKind(*n)
if bol {
var info VRegUseInfo = (*n).GetVRegUseInfo()
x86ret, sseret := vreg_to_reg.Add(info)
vreg_To_Reg_Table, _regrun, _sserun = vreg_To_Reg_Table.AllOrStore(x86ret, sseret, _regrun, _sserun, Thread)
}
go func(n *TextNode, vt vregToRegTable, vtr *vRegToReg, gregrun *RegRun, gsserun *SseRegRun) {
defer wg.Done()
switch (*n).Type() {
case ASSIGN:
an := (*n).(AssignKind)
AllocReg([][]TextNode{an.nodes}, gregrun, gsserun, vtr, vt, Thread)
case StackVarMov:
sn := (*n).(StackVarMovKind)
AllocReg([][]TextNode{sn.nodes}, gregrun, gsserun, vtr, vt, Thread)
case Func:
fn := (*n).(FuncKind)
AllocReg(fn.nodes, gregrun, gsserun, vtr, vt, Thread)
case AmExpr:
an := (*n).(AmExprKind)
AllocReg([][]TextNode{an.nodes}, gregrun, gsserun, vtr, vt, Thread)
case VarMov:
sn := (*n).(VarMovKind)
AllocReg([][]TextNode{sn.nodes}, gregrun, gsserun, vtr, vt, Thread)
case TypeSrcMemDestReg:
sn := (*n).(*SrcMemDestReg)
sn.Reg = _RegRePlace(sn.Reg, gregrun, gsserun, vt)
case TypeSrcRegDestMem:
sn := (*n).(*SrcRegDestMem)
sn.Reg = _RegRePlace(sn.Reg, gregrun, gsserun, vt)
case TypeSrcNumDestReg:
sn := (*n).(*SrcNumDestReg)
sn.Reg = _RegRePlace(sn.Reg, gregrun, gsserun, vt)
case TypeSrcRegDestReg:
sn := (*n).(*SrcRegDestReg)
sn.Src = _RegRePlace(sn.Src, gregrun, gsserun, vt)
sn.Dest = _RegRePlace(sn.Dest, gregrun, gsserun, vt)
case TypeSrcRegOffsetDestReg:
sn := (*n).(*SrcRegOffsetDestReg)
sn.Src = _RegRePlace(sn.Src, gregrun, gsserun, vt)
sn.Dest = _RegRePlace(sn.Dest, gregrun, gsserun, vt)
case TypeSrcRegDestRegOffset:
sn := (*n).(*SrcRegDestRegOffset)
sn.Src = _RegRePlace(sn.Src, gregrun, gsserun, vt)
sn.Dest = _RegRePlace(sn.Dest, gregrun, gsserun, vt)
case TypeSrcNumDestRegOffset:
sn := (*n).(*SrcNumDestRegOffset)
sn.Dest = _RegRePlace(sn.Dest, gregrun, gsserun, vt)
case TypeSrcRegMemDestReg:
sn := (*n).(*SrcRegMemDestReg)
sn.Src = _RegRePlace(sn.Src, gregrun, gsserun, vt)
sn.Dest = _RegRePlace(sn.Dest, gregrun, gsserun, vt)
case TypeSrcNumDestMem, Labels, StackAlloc, StackFree:
default:
panic(fmt.Errorf("未知的类型:%+v", *n))
}
}(n, vreg_To_Reg_Table, vtr.Copy(), _regrun, _sserun)
}
}
wg.Wait()
wg.Close()
}
// _RegRePlace为虚拟寄存器分配实际寄存器
// 同一个虚拟寄存器(x)在vt相同时返回同一个实际寄存器(y)
// 可以认为 vt相同 x ->(推导出) y
func _RegRePlace(reg RegEnum, regrun *RegRun, sserun *SseRegRun, vt vregToRegTable) RegEnum {
v := _RegEnumTovrm(reg)
switch v.Type {
case vrmx86:
switch v.Size {
case vrm64bit:
return vt.GetX86Reg(v, 64, regrun)
case vrm32bit:
return vt.GetX86Reg(v, 32, regrun)
case vrm16bit:
return vt.GetX86Reg(v, 16, regrun)
case vrm8bit:
return vt.GetX86Reg(v, 8, regrun)
default:
panic(fmt.Errorf("未知的x86寄存器大小 %+v", v))
}
case vrmsse:
return vt.GetSSEReg(v, sserun)
default:
return reg
}
}
// retVRegUseInfo返回 虚拟寄存器使用信息
// 用于只有一条汇编指令的指令节点
func retVRegUseInfo(reg ...RegEnum) VRegUseInfo {
regl := len(reg)
if regl == 0 {
return VRegUseInfo{}
}
var ret VRegUseInfo
var ret_table = newvregUseTable()
for i := 0; i < regl; i++ {
v := _RegEnumTovrm(reg[i])
if v._zero != 0 { //不是虚拟寄存器
continue
}
if ok := ret_table.VrmOk(v); ok { //同一个虚拟寄存器不重复计算
continue
}
ret_table.Vrm(v)
switch v.Type {
case vrmx86:
ret.X86++
case vrmsse:
ret.SSE++
default: //不是虚拟寄存器
continue
}
}
return ret
}
// retTextNodeVRegUseInfo返回 虚拟寄存器使用信息
// 用于有多条汇编指令的(组合指令节点)
// 同一个虚拟寄存器 只记录 一次
func retTextNodeVRegUseInfo(nodes []TextNode, ret_table vregUseTable) VRegUseInfo {
regl := len(nodes)
if regl == 0 { //没有节点
return VRegUseInfo{}
}
var ret VRegUseInfo
for i := 0; i < regl; i++ {
switch n := nodes[i]; n.Type() {
case ASSIGN:
an := n.(AssignKind)
ret = ret.Add(an.GetVRegUseInfo())
case StackVarMov:
sn := n.(StackVarMovKind)
ret = ret.Add(sn.GetVRegUseInfo())
case AmExpr:
an := n.(AmExprKind)
ret = ret.Add(retTextNodeVRegUseInfo(an.nodes, ret_table))
case VarMov:
sn := n.(VarMovKind)
ret = ret.Add(sn.GetVRegUseInfo())
case TypeSrcMemDestReg:
sn := n.(*SrcMemDestReg)
if ok := ret_table.RegEnumOk(sn.Reg); ok { //同一个虚拟寄存器不重复计算
continue
}
ret_table.RegEnum(sn.Reg)
ret = ret.add(sn.Reg)
case TypeSrcRegDestMem:
sn := n.(*SrcRegDestMem)
if ok := ret_table.RegEnumOk(sn.Reg); ok { //同一个虚拟寄存器不重复计算
continue
}
ret_table.RegEnum(sn.Reg)
ret = ret.add(sn.Reg)
case TypeSrcNumDestReg:
sn := n.(*SrcNumDestReg)
if ok := ret_table.RegEnumOk(sn.Reg); ok { //同一个虚拟寄存器不重复计算
continue
}
ret_table.RegEnum(sn.Reg)
ret = ret.add(sn.Reg)
case TypeSrcRegDestReg:
sn := n.(*SrcRegDestReg)
if ok := ret_table.RegEnumOk(sn.Src); ok { //同一个虚拟寄存器不重复计算
continue
}
ret_table.RegEnum(sn.Src)
ret = ret.add(sn.Src)
if ok := ret_table.RegEnumOk(sn.Dest); ok { //同一个虚拟寄存器不重复计算
continue
}
ret_table.RegEnum(sn.Dest)
ret = ret.add(sn.Dest)
case TypeSrcRegOffsetDestReg:
sn := n.(*SrcRegOffsetDestReg)
if ok := ret_table.RegEnumOk(sn.Src); ok { //同一个虚拟寄存器不重复计算
continue
}
ret_table.RegEnum(sn.Src)
ret = ret.add(sn.Src)
if ok := ret_table.RegEnumOk(sn.Dest); ok { //同一个虚拟寄存器不重复计算
continue
}
ret_table.RegEnum(sn.Dest)
ret = ret.add(sn.Dest)
case TypeSrcRegDestRegOffset:
sn := n.(*SrcRegDestRegOffset)
if ok := ret_table.RegEnumOk(sn.Src); ok { //同一个虚拟寄存器不重复计算
continue
}
ret_table.RegEnum(sn.Src)
ret = ret.add(sn.Src)
if ok := ret_table.RegEnumOk(sn.Dest); ok { //同一个虚拟寄存器不重复计算
continue
}
ret_table.RegEnum(sn.Dest)
ret = ret.add(sn.Dest)
case TypeSrcNumDestRegOffset:
sn := n.(*SrcNumDestRegOffset)
if ok := ret_table.RegEnumOk(sn.Dest); ok { //同一个虚拟寄存器不重复计算
continue
}
ret_table.RegEnum(sn.Dest)
ret = ret.add(sn.Dest)
case TypeSrcRegMemDestReg:
sn := n.(*SrcRegMemDestReg)
if ok := ret_table.RegEnumOk(sn.Src); ok { //同一个虚拟寄存器不重复计算
continue
}
ret_table.RegEnum(sn.Src)
ret = ret.add(sn.Src)
if ok := ret_table.RegEnumOk(sn.Dest); ok { //同一个虚拟寄存器不重复计算
continue
}
ret_table.RegEnum(sn.Dest)
ret = ret.add(sn.Dest)
case TypeSrcNumDestMem:
default:
panic(fmt.Errorf("未知的类型 %+v", n))
}
}
return ret
}
// vRegToReg是 记录 虚拟寄存器分配到实际寄存器 分配数量
type vRegToReg struct {
x86 int16
sse int16
}
func _NewvRegToReg() *vRegToReg {
return &vRegToReg{}
}
// Add记录新增分配数量
func (v *vRegToReg) Add(info VRegUseInfo) (x86ret bool, sseret bool) {
v.x86 += info.X86
v.sse += info.SSE
if v.x86 >= allocX86Reg {
x86ret = true
v.x86 = 0
}
if v.sse >= allocSSEReg {
sseret = true
v.sse = 0
}
return
}
// 复制一个副本
func (v *vRegToReg) Copy() *vRegToReg {
return &vRegToReg{x86: v.x86, sse: v.sse}
}
// vregToRegTable 是虚拟寄存器分配表
type vregToRegTable struct {
x86map map[vrm]RegEnum
x86lock *sync.Mutex
ssemap map[vrm]RegEnum
sselock *sync.Mutex
}
func _NewvregToRegTable() vregToRegTable {
var ret vregToRegTable
ret.x86map = make(map[vrm]RegEnum, 3)
ret.ssemap = make(map[vrm]RegEnum, 3)
ret.x86lock = new(sync.Mutex)
ret.sselock = new(sync.Mutex)
return ret
}
// 获取一个X86虚拟寄存器
// 同一个虚拟寄存器(vrm) 返回同一个实际寄存器(y)
//
// vrm ->(推导出) y
func (v vregToRegTable) GetX86Reg(vreg vrm, size int8, regrun *RegRun) RegEnum {
v.x86lock.Lock()
defer v.x86lock.Unlock()
if ret, ok := v.x86map[vreg]; ok {
return ret
}
ret := regrun.RetReg(size)
v.x86map[vreg] = ret
return ret
}
// 获取一个SSE虚拟寄存器
// 同一个虚拟寄存器(vrm) 返回同一个实际寄存器(y)
//
// vrm ->(推导出) y
func (v vregToRegTable) GetSSEReg(vreg vrm, sserun *SseRegRun) RegEnum {
v.sselock.Lock()
defer v.sselock.Unlock()
if ret, ok := v.ssemap[vreg]; ok {
return ret
}
ret := sserun.RetReg()
v.ssemap[vreg] = ret
return ret
}
// AllOrStore判断 所有可分配寄存器 是否,全部被分配且全部可重新分配
// 所有可分配寄存器(ax bx cx dx r8-r15)
// 全部被分配 == 全部被分配给虚拟寄存器过
// 全部可重新分配 == 全部被分配给虚拟寄存器,且这些虚拟寄存器都不再使用
func (v vregToRegTable) AllOrStore(x86, sse bool, regrun *RegRun, sserun *SseRegRun, Thread bool) (vregToRegTable, *RegRun, *SseRegRun) {
ret := v
retreg := regrun
retsse := sserun
if x86 {
ret.x86map = make(map[vrm]RegEnum, 3)
ret.x86lock = new(sync.Mutex)
retreg = NewRegRun(Thread)
}
if sse {
ret.ssemap = make(map[vrm]RegEnum, 3)
ret.sselock = new(sync.Mutex)
retsse = NewSseRegRun(Thread)
}
return ret, retreg, retsse
}
// vregUseTable 是虚拟寄存器使用记录表
type vregUseTable struct {
ret_table map[vrm]struct{}
}
func newvregUseTable() vregUseTable {
return vregUseTable{ret_table: make(map[vrm]struct{})}
}
// Vrm记录v
func (table vregUseTable) Vrm(v vrm) {
table.ret_table[v] = struct{}{}
}
// Vrm返回v是否被记录过
func (table vregUseTable) VrmOk(v vrm) bool {
_, ok := table.ret_table[v]
return ok
}
func (table vregUseTable) RegEnumOk(reg RegEnum) bool {
return table.VrmOk(_RegEnumTovrm(reg))
}
func (table vregUseTable) RegEnum(reg RegEnum) {
table.Vrm(_RegEnumTovrm(reg))
}
Go
1
https://gitee.com/u-language/u-language.git
git@gitee.com:u-language/u-language.git
u-language
u-language
U语言
a214d6007862

搜索帮助