LLVM improvements

This commit is contained in:
Sasha Koshka 2023-11-26 04:00:20 -05:00
parent dc16a17271
commit 38a4cd7aaa
3 changed files with 83 additions and 20 deletions

View File

@ -13,8 +13,6 @@ type Function struct {
AddressSpace AddressSpace
// TODO complete this
nextIdent int
}
type Parameter struct {
@ -32,16 +30,8 @@ func NewParameter (name string, ty Type) *Parameter {
return parameter
}
func (this *Function) newIdent () string {
name := fmt.Sprint(this.nextIdent)
this.nextIdent ++
return name
}
func (this *Function) NewBlock (name string) *Block {
if name == "" { name = this.newIdent() }
func (this *Function) NewBlock () *Block {
block := &Block {
Name: name,
Parent: this,
}
this.Blocks = append(this.Blocks, block)
@ -49,6 +39,7 @@ func (this *Function) NewBlock (name string) *Block {
}
func (this *Function) LLString () string {
this.assignIDs()
buffer := &strings.Builder { }
if len(this.Blocks) == 0 {
// Function declaration.
@ -85,6 +76,15 @@ func (this *Function) String () string {
return fmt.Sprintf("ptr %v", this.Identifier())
}
func (this *Function) assignIDs () {
counter := 0
for _, block := range this.Blocks {
block.SetName(fmt.Sprint(counter))
counter ++
block.assignIDs(&counter)
}
}
func (this *Function) headerString () string {
buffer := &strings.Builder { }
fmt.Fprintf(buffer, " %v", this.Signature.Return)
@ -120,27 +120,58 @@ func (this *Function) bodyString () string {
}
type Block struct {
Name string
BlockName string
Parent *Function
Instructions []Instruction
}
func (this *Block) LLString () string {
buffer := &strings.Builder { }
fmt.Fprintf(buffer, "%s:\n", this.Name)
fmt.Fprintf(buffer, "%s:\n", this.Name())
for _, instruction := range this.Instructions {
fmt.Fprintf(buffer, "\t%s\n", instruction.LLString())
}
return buffer.String()
}
func (this *Block) Name () string {
return this.BlockName
}
func (this *Block) SetName (name string) {
this.BlockName = name
}
func (this *Block) Identifier () string {
return EncodeRegisterName(this.Name)
return EncodeRegisterName(this.Name())
}
func (this *Block) String () string {
return fmt.Sprintf("%v %v", this.Type(), this.Identifier())
}
func (this *Block) Type () Type {
return Label
}
func (this *Block) AddInstruction (instruction Instruction) {
if instruction, ok := instruction.(ValueInstruction); ok {
instruction.SetName(this.Parent.newIdent())
if this.Terminated() {
panic("block is already terminated")
}
this.Instructions = append(this.Instructions, instruction)
}
}
func (this *Block) Terminated () bool {
if len(this.Instructions) == 0 { return false }
_, ok := this.Instructions[len(this.Instructions) - 1].(Terminator)
return ok
}
func (this *Block) assignIDs (counter *int) {
for _, instruction := range this.Instructions {
if instruction, ok := instruction.(ValueInstruction); ok {
instruction.SetName(fmt.Sprint(*counter))
*counter ++
}
}
}

View File

@ -133,13 +133,18 @@ type InstructionAlloca struct {
}
func (this *Block) NewAlloca (element Type) *InstructionAlloca {
instruction := NewAlloca(element)
this.AddInstruction(instruction)
return instruction
}
func NewAlloca (element Type) *InstructionAlloca {
instruction := &InstructionAlloca {
Element: element,
}
ty := &TypePointer { }
ty.AddressSpace = instruction.AddressSpace
instruction.Ty = ty
this.AddInstruction(instruction)
return instruction
}

View File

@ -4,6 +4,7 @@ import "fmt"
import "strings"
type Terminator interface {
IsTerminator ()
Instruction
}
@ -11,6 +12,8 @@ type TerminatorBr struct {
Target Value
}
func (*TerminatorBr) IsTerminator () { }
func (this *TerminatorBr) LLString () string {
buf := &strings.Builder{}
fmt.Fprintf(buf, "br %s", this.Target)
@ -29,6 +32,8 @@ type TerminatorCallBr struct {
OtherTargets []Value
}
func (*TerminatorCallBr) IsTerminator () { }
func (this *TerminatorCallBr) LLString () string {
buf := &strings.Builder{}
if _, ok := this.Type().(*TypeVoid); !ok {
@ -86,6 +91,8 @@ type TerminatorCatchRet struct {
Target Value
}
func (*TerminatorCatchRet) IsTerminator () { }
func (this *TerminatorCatchRet) LLString () string {
buf := &strings.Builder{}
fmt.Fprintf(buf, "catchret from %s to %s", this.CatchPad.Name(), this.Target)
@ -108,6 +115,8 @@ type TerminatorCatchSwitch struct {
DefaultUnwindTarget Value
}
func (*TerminatorCatchSwitch) IsTerminator () { }
func (this *TerminatorCatchSwitch) LLString () string {
buf := &strings.Builder{}
fmt.Fprintf(buf, "%s = ", this.Name())
@ -143,6 +152,8 @@ type TerminatorCleanupRet struct {
UnwindTarget Value
}
func (*TerminatorCleanupRet) IsTerminator () { }
func (this *TerminatorCleanupRet) LLString () string {
buf := &strings.Builder{}
fmt.Fprintf(buf, "cleanupret from %s unwind ", this.CleanupPad.Name())
@ -154,7 +165,7 @@ func (this *TerminatorCleanupRet) LLString () string {
return buf.String()
}
func (this *Block) NewTerminatorCleanupRet (cleanupPad, unwindTarget Value) *TerminatorCleanupRet {
func (this *Block) NewCleanupRet (cleanupPad, unwindTarget Value) *TerminatorCleanupRet {
terminator := &TerminatorCleanupRet {
CleanupPad: cleanupPad,
UnwindTarget: unwindTarget,
@ -169,13 +180,15 @@ type TerminatorCondBr struct {
False Value
}
func (*TerminatorCondBr) IsTerminator () { }
func (this *TerminatorCondBr) LLString () string {
buf := &strings.Builder{}
fmt.Fprintf(buf, "br %s, %s, %s", this.Condition, this.True, this.False)
return buf.String()
}
func (this *Block) NewTerminatorCondBr (condition Value, tru, fals Value) *TerminatorCondBr {
func (this *Block) NewCondBr (condition Value, tru, fals Value) *TerminatorCondBr {
terminator := &TerminatorCondBr {
Condition: condition,
True: tru,
@ -190,6 +203,8 @@ type TerminatorIndirectBr struct {
ValidTargets []Value
}
func (*TerminatorIndirectBr) IsTerminator () { }
func (this *TerminatorIndirectBr) LLString () string {
buf := &strings.Builder{}
fmt.Fprintf(buf, "indirectbr %s, [", this.Address)
@ -224,6 +239,8 @@ type TerminatorInvoke struct {
// TODO complete this
}
func (*TerminatorInvoke) IsTerminator () { }
func (this *TerminatorInvoke) LLString () string {
buf := &strings.Builder{}
if _, ok := this.Type().(*TypeVoid); !ok {
@ -273,6 +290,8 @@ type TerminatorResume struct {
X Value
}
func (*TerminatorResume) IsTerminator () { }
func (this *TerminatorResume) LLString () string {
buf := &strings.Builder{}
fmt.Fprintf(buf, "resume %s", this.X)
@ -289,6 +308,8 @@ type TerminatorRet struct {
X Value
}
func (*TerminatorRet) IsTerminator () { }
func (this *TerminatorRet) LLString () string {
buf := &strings.Builder { }
if this.X == nil {
@ -310,6 +331,8 @@ type Case struct {
Target Value
}
func (*Case) IsTerminator () { }
func (this *Case) String () string {
return fmt.Sprintf("%s, %s", this.X, this.Target)
}
@ -320,6 +343,8 @@ type TerminatorSwitch struct {
Cases []*Case
}
func (*TerminatorSwitch) IsTerminator () { }
func (this *TerminatorSwitch) LLString () string {
buf := &strings.Builder{}
fmt.Fprintf(buf, "switch %s, %s [\n", this.X, this.Default)
@ -344,6 +369,8 @@ type TerminatorUnreachable struct {
}
func (*TerminatorUnreachable) IsTerminator () { }
func (this *TerminatorUnreachable) LLString () string {
buf := &strings.Builder{}
buf.WriteString("unreachable")