Skip to content

Commit 73a1250

Browse files
committed
builder/createInlineAsm:with independant logic to avoid goto operate
1 parent 633688c commit 73a1250

File tree

1 file changed

+34
-20
lines changed

1 file changed

+34
-20
lines changed

compiler/inlineasm.go

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,35 @@ func (b *builder) createInlineAsm(args []ssa.Value) (llvm.Value, error) {
2929
return b.CreateCall(fnType, target, nil, ""), nil
3030
}
3131

32+
// collectInlineAsmRegisters extracts register values from the map referrers,
33+
// stopping when it encounters the AsmFull call itself to avoid processing
34+
// MapUpdate operations that happen after the call.
35+
func (b *builder) collectInlineAsmRegisters(instr *ssa.CallCommon, registerMap *ssa.MakeMap) (map[string]llvm.Value, error) {
36+
registers := map[string]llvm.Value{}
37+
for _, r := range *registerMap.Referrers() {
38+
switch r := r.(type) {
39+
case *ssa.DebugRef:
40+
// ignore
41+
case *ssa.MapUpdate:
42+
if r.Block() != registerMap.Block() {
43+
return nil, b.makeError(instr.Pos(), "register value map must be created in the same basic block")
44+
}
45+
key := constant.StringVal(r.Key.(*ssa.Const).Value)
46+
registers[key] = b.getValue(r.Value.(*ssa.MakeInterface).X, getPos(instr))
47+
case *ssa.Call:
48+
if r.Common() == instr {
49+
// Stop processing when we encounter the AsmFull call itself
50+
// to avoid including MapUpdate operations that happen after the call
51+
return registers, nil
52+
}
53+
default:
54+
return nil, b.makeError(instr.Pos(), "don't know how to handle argument to inline assembly: "+r.String())
55+
}
56+
}
57+
58+
return registers, nil
59+
}
60+
3261
// This is a compiler builtin, which allows assembly to be called in a flexible
3362
// way.
3463
//
@@ -46,28 +75,13 @@ func (b *builder) createInlineAsm(args []ssa.Value) (llvm.Value, error) {
4675
func (b *builder) createInlineAsmFull(instr *ssa.CallCommon) (llvm.Value, error) {
4776
asmString := constant.StringVal(instr.Args[0].(*ssa.Const).Value)
4877
registers := map[string]llvm.Value{}
78+
4979
if registerMap, ok := instr.Args[1].(*ssa.MakeMap); ok {
50-
for _, r := range *registerMap.Referrers() {
51-
switch r := r.(type) {
52-
case *ssa.DebugRef:
53-
// ignore
54-
case *ssa.MapUpdate:
55-
if r.Block() != registerMap.Block() {
56-
return llvm.Value{}, b.makeError(instr.Pos(), "register value map must be created in the same basic block")
57-
}
58-
key := constant.StringVal(r.Key.(*ssa.Const).Value)
59-
registers[key] = b.getValue(r.Value.(*ssa.MakeInterface).X, getPos(instr))
60-
case *ssa.Call:
61-
if r.Common() == instr {
62-
// Stop processing when we encounter the AsmFull call itself
63-
// to avoid including MapUpdate operations that happen after the call
64-
goto done
65-
}
66-
default:
67-
return llvm.Value{}, b.makeError(instr.Pos(), "don't know how to handle argument to inline assembly: "+r.String())
68-
}
80+
var err error
81+
registers, err = b.collectInlineAsmRegisters(instr, registerMap)
82+
if err != nil {
83+
return llvm.Value{}, err
6984
}
70-
done:
7185
}
7286
// TODO: handle dollar signs in asm string
7387
registerNumbers := map[string]int{}

0 commit comments

Comments
 (0)