Skip to content

Commit 3f58af5

Browse files
committed
ir: use value.Value for basic block targets and operands of terminators
Note: this commit is targetted for the v0.4 release. Updates llir#50.
1 parent b6ec77e commit 3f58af5

File tree

5 files changed

+98
-37
lines changed

5 files changed

+98
-37
lines changed

asm/term.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ func (fgen *funcGen) irIndirectBrTerm(new ir.Terminator, old *ast.IndirectBrTerm
305305
term.Addr = addr
306306
// Valid targets.
307307
if oldValidTargets := old.ValidTargets(); len(oldValidTargets) > 0 {
308-
term.ValidTargets = make([]*ir.Block, len(oldValidTargets))
308+
term.ValidTargets = make([]value.Value, len(oldValidTargets))
309309
for i, oldValidTarget := range oldValidTargets {
310310
validTarget, err := fgen.irBlock(oldValidTarget)
311311
if err != nil {
@@ -568,7 +568,7 @@ func (fgen *funcGen) irCatchSwitchTerm(new ir.Terminator, old *ast.CatchSwitchTe
568568
term.Scope = scope
569569
// Exception handlers.
570570
if oldHandlers := old.Handlers().Labels(); len(oldHandlers) > 0 {
571-
term.Handlers = make([]*ir.Block, len(oldHandlers))
571+
term.Handlers = make([]value.Value, len(oldHandlers))
572572
for i, oldHandler := range oldHandlers {
573573
handler, err := fgen.irBlock(oldHandler)
574574
if err != nil {

ir/helper.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -335,16 +335,19 @@ type ReturnAttribute interface {
335335
IsReturnAttribute()
336336
}
337337

338+
// TODO: figure out definition of UnwindTarget.
339+
338340
// UnwindTarget is an unwind target.
339341
//
340342
// An UnwindTarget has one of the following underlying types.
341343
//
342344
// *ir.Block
343345
// ir.UnwindToCaller
344346
type UnwindTarget interface {
347+
value.Value
345348
// isUnwindTarget ensures that only unwind targets can be assigned to the
346349
// ir.UnwindTarget interface.
347-
isUnwindTarget()
350+
//isUnwindTarget()
348351
}
349352

350353
// UnwindToCaller specifies the caller as an unwind target.

ir/inst_other.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,7 @@ type InstCleanupPad struct {
618618
LocalIdent
619619
// Exception scope.
620620
// TODO: rename to Parent? rename to From?
621-
Scope value.Value // ExceptionScope
621+
Scope value.Value // ir.ExceptionScope
622622
// Exception arguments.
623623
//
624624
// Arg has one of the following underlying types:

ir/sumtype.go

+27
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
package ir
22

3+
import (
4+
"github.com/llir/llvm/ir/types"
5+
)
6+
37
// === [ constant.Constant ] ===================================================
48

59
// IsConstant ensures that only constants can be assigned to the
@@ -164,3 +168,26 @@ func (*Block) isUnwindTarget() {}
164168
// isUnwindTarget ensures that only unwind targets can be assigned to the
165169
// ir.UnwindTarget interface.
166170
func (UnwindToCaller) isUnwindTarget() {}
171+
172+
// === [ ir.UnwindTarget ] =====================================================
173+
174+
// isUnwindTarget ensures that only unwind targets can be assigned to the
175+
// ir.UnwindTarget interface.
176+
//func (*Block) isUnwindTarget() {}
177+
178+
// isUnwindTarget ensures that only unwind targets can be assigned to the
179+
// ir.UnwindTarget interface.
180+
//func (UnwindToCaller) isUnwindTarget() {}
181+
182+
// TODO: figure out how to handle UnwindToCaller.Type.
183+
184+
// Type returns the type of the value.
185+
func (UnwindToCaller) Type() types.Type {
186+
// Type is a dummy method for UnwindToCaller to implement value.Value.
187+
panic("UnwindToCaller does not have a type")
188+
}
189+
190+
// Ident returns the identifier associated with the value.
191+
func (u UnwindToCaller) Ident() string {
192+
return u.String()
193+
}

ir/terminator.go

+64-33
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ func (term *TermRet) LLString() string {
8989
// TermBr is an unconditional LLVM IR br terminator.
9090
type TermBr struct {
9191
// Target branch.
92-
Target *Block
92+
Target value.Value // *ir.Block
9393

9494
// extra.
9595

@@ -109,7 +109,7 @@ func NewBr(target *Block) *TermBr {
109109
func (term *TermBr) Succs() []*Block {
110110
// Cache successors if not present.
111111
if term.Successors == nil {
112-
term.Successors = []*Block{term.Target}
112+
term.Successors = []*Block{term.Target.(*Block)}
113113
}
114114
return term.Successors
115115
}
@@ -132,9 +132,9 @@ type TermCondBr struct {
132132
// Branching condition.
133133
Cond value.Value
134134
// True condition target branch.
135-
TargetTrue *Block
135+
TargetTrue value.Value // *ir.Block
136136
// False condition target branch.
137-
TargetFalse *Block
137+
TargetFalse value.Value // *ir.Block
138138

139139
// extra.
140140

@@ -154,7 +154,7 @@ func NewCondBr(cond value.Value, targetTrue, targetFalse *Block) *TermCondBr {
154154
func (term *TermCondBr) Succs() []*Block {
155155
// Cache successors if not present.
156156
if term.Successors == nil {
157-
term.Successors = []*Block{term.TargetTrue, term.TargetFalse}
157+
term.Successors = []*Block{term.TargetTrue.(*Block), term.TargetFalse.(*Block)}
158158
}
159159
return term.Successors
160160
}
@@ -178,7 +178,7 @@ type TermSwitch struct {
178178
// Control variable.
179179
X value.Value
180180
// Default target branch.
181-
TargetDefault *Block
181+
TargetDefault value.Value // *ir.Block
182182
// Switch cases.
183183
Cases []*Case
184184

@@ -201,9 +201,9 @@ func (term *TermSwitch) Succs() []*Block {
201201
// Cache successors if not present.
202202
if term.Successors == nil {
203203
succs := make([]*Block, 0, 1+len(term.Cases))
204-
succs = append(succs, term.TargetDefault)
204+
succs = append(succs, term.TargetDefault.(*Block))
205205
for _, c := range term.Cases {
206-
succs = append(succs, c.Target)
206+
succs = append(succs, c.Target.(*Block))
207207
}
208208
term.Successors = succs
209209
}
@@ -231,9 +231,9 @@ func (term *TermSwitch) LLString() string {
231231
// Case is a switch case.
232232
type Case struct {
233233
// Case comparand.
234-
X constant.Constant // integer constant or integer constant expression
234+
X value.Value // constant.Constant (integer constant or integer constant expression)
235235
// Case target branch.
236-
Target *Block
236+
Target value.Value // *ir.Block
237237
}
238238

239239
// NewCase returns a new switch case based on the given case comparand and
@@ -255,10 +255,12 @@ type TermIndirectBr struct {
255255
// Target address.
256256
Addr value.Value // blockaddress
257257
// Set of valid target basic blocks.
258-
ValidTargets []*Block
258+
ValidTargets []value.Value // slice of *ir.Block
259259

260260
// extra.
261261

262+
// Successor basic blocks of the terminator.
263+
Successors []*Block
262264
// (optional) Metadata.
263265
Metadata
264266
}
@@ -267,12 +269,24 @@ type TermIndirectBr struct {
267269
// address (derived from a blockaddress constant) and set of valid target basic
268270
// blocks.
269271
func NewIndirectBr(addr constant.Constant, validTargets ...*Block) *TermIndirectBr {
270-
return &TermIndirectBr{Addr: addr, ValidTargets: validTargets}
272+
// convert validTargets slice to []value.Value.
273+
var targets []value.Value
274+
for _, target := range validTargets {
275+
targets = append(targets, target)
276+
}
277+
return &TermIndirectBr{Addr: addr, ValidTargets: targets}
271278
}
272279

273280
// Succs returns the successor basic blocks of the terminator.
274281
func (term *TermIndirectBr) Succs() []*Block {
275-
return term.ValidTargets
282+
// Cache successors if not present.
283+
if term.Successors == nil {
284+
// convert ValidTargets slice to []*ir.Block.
285+
for _, target := range term.ValidTargets {
286+
term.Successors = append(term.Successors, target.(*Block))
287+
}
288+
}
289+
return term.Successors
276290
}
277291

278292
// LLString returns the LLVM syntax representation of the terminator.
@@ -310,9 +324,9 @@ type TermInvoke struct {
310324
// TODO: add metadata value?
311325
Args []value.Value
312326
// Normal control flow return point.
313-
Normal *Block
327+
Normal value.Value // *ir.Block
314328
// Exception control flow return point.
315-
Exception *Block
329+
Exception value.Value // *ir.Block
316330

317331
// extra.
318332

@@ -366,7 +380,7 @@ func (term *TermInvoke) Type() types.Type {
366380
func (term *TermInvoke) Succs() []*Block {
367381
// Cache successors if not present.
368382
if term.Successors == nil {
369-
term.Successors = []*Block{term.Normal, term.Exception}
383+
term.Successors = []*Block{term.Normal.(*Block), term.Exception.(*Block)}
370384
}
371385
return term.Successors
372386
}
@@ -454,9 +468,9 @@ type TermCallBr struct {
454468
// TODO: add metadata value?
455469
Args []value.Value
456470
// Normal control flow return point.
457-
Normal *Block
471+
Normal value.Value // *ir.Block
458472
// Other control flow return points.
459-
Others []*Block
473+
Others []value.Value // slice of *ir.Block
460474

461475
// extra.
462476

@@ -484,7 +498,12 @@ type TermCallBr struct {
484498
//
485499
// TODO: specify the set of underlying types of callee.
486500
func NewCallBr(callee value.Value, args []value.Value, normal *Block, others ...*Block) *TermCallBr {
487-
term := &TermCallBr{Callee: callee, Args: args, Normal: normal, Others: others}
501+
// convert others slice to []value.Value.
502+
var os []value.Value
503+
for _, other := range others {
504+
os = append(os, other)
505+
}
506+
term := &TermCallBr{Callee: callee, Args: args, Normal: normal, Others: os}
488507
// Compute type.
489508
term.Type()
490509
return term
@@ -510,8 +529,11 @@ func (term *TermCallBr) Type() types.Type {
510529
func (term *TermCallBr) Succs() []*Block {
511530
// Cache successors if not present.
512531
if term.Successors == nil {
513-
term.Successors = []*Block{term.Normal}
514-
term.Successors = append(term.Successors, term.Others...)
532+
term.Successors = []*Block{term.Normal.(*Block)}
533+
// convert others slice to []*ir.Block.
534+
for _, other := range term.Others {
535+
term.Successors = append(term.Successors, other.(*Block))
536+
}
515537
}
516538
return term.Successors
517539
}
@@ -633,11 +655,13 @@ type TermCatchSwitch struct {
633655
// Name of local variable associated with the result.
634656
LocalIdent
635657
// Exception scope.
636-
Scope ExceptionScope // TODO: rename to Parent? rename to From?
658+
// TODO: rename to Parent? rename to From?
659+
Scope value.Value // ir.ExceptionScope
637660
// Exception handlers.
638-
Handlers []*Block
661+
Handlers []value.Value // []*ir.Block
639662
// Unwind target; basic block or caller function.
640-
UnwindTarget UnwindTarget // TODO: rename to To? rename to DefaultTarget?
663+
// TODO: rename to To? rename to DefaultTarget?
664+
UnwindTarget value.Value // ir.UnwindTarget
641665

642666
// extra.
643667

@@ -650,7 +674,12 @@ type TermCatchSwitch struct {
650674
// NewCatchSwitch returns a new catchswitch terminator based on the given
651675
// exception scope, exception handlers and unwind target.
652676
func NewCatchSwitch(scope ExceptionScope, handlers []*Block, unwindTarget UnwindTarget) *TermCatchSwitch {
653-
return &TermCatchSwitch{Scope: scope, Handlers: handlers, UnwindTarget: unwindTarget}
677+
// convert handlers slice to []value.Value.
678+
var hs []value.Value
679+
for _, handler := range handlers {
680+
hs = append(hs, handler)
681+
}
682+
return &TermCatchSwitch{Scope: scope, Handlers: hs, UnwindTarget: unwindTarget}
654683
}
655684

656685
// String returns the LLVM syntax representation of the terminator as a type-
@@ -668,10 +697,12 @@ func (term *TermCatchSwitch) Type() types.Type {
668697
func (term *TermCatchSwitch) Succs() []*Block {
669698
// Cache successors if not present.
670699
if term.Successors == nil {
700+
// convert Handlers slice to []*ir.Block.
701+
for _, handler := range term.Handlers {
702+
term.Successors = append(term.Successors, handler.(*Block))
703+
}
671704
if unwindTarget, ok := term.UnwindTarget.(*Block); ok {
672-
term.Successors = append(term.Handlers, unwindTarget)
673-
} else {
674-
term.Successors = term.Handlers
705+
term.Successors = append(term.Successors, unwindTarget)
675706
}
676707
}
677708
return term.Successors
@@ -703,9 +734,9 @@ func (term *TermCatchSwitch) LLString() string {
703734
// TermCatchRet is an LLVM IR catchret terminator.
704735
type TermCatchRet struct {
705736
// Exit catchpad.
706-
From *InstCatchPad
737+
From value.Value // *ir.InstCatchPad
707738
// Target basic block to transfer control flow to.
708-
To *Block
739+
To value.Value // *ir.Block
709740

710741
// extra.
711742

@@ -725,7 +756,7 @@ func NewCatchRet(from *InstCatchPad, to *Block) *TermCatchRet {
725756
func (term *TermCatchRet) Succs() []*Block {
726757
// Cache successors if not present.
727758
if term.Successors == nil {
728-
term.Successors = []*Block{term.To}
759+
term.Successors = []*Block{term.To.(*Block)}
729760
}
730761
return term.Successors
731762
}
@@ -747,9 +778,9 @@ func (term *TermCatchRet) LLString() string {
747778
// TermCleanupRet is an LLVM IR cleanupret terminator.
748779
type TermCleanupRet struct {
749780
// Exit cleanuppad.
750-
From *InstCleanupPad
781+
From value.Value // *ir.InstCleanupPad
751782
// Unwind target; basic block or caller function.
752-
UnwindTarget UnwindTarget
783+
UnwindTarget value.Value // ir.UnwindTarget
753784

754785
// extra.
755786

0 commit comments

Comments
 (0)