LLVM improvements
This commit is contained in:
parent
dc16a17271
commit
38a4cd7aaa
|
@ -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 ++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
Loading…
Reference in New Issue