compiler; add position information to createConstant
Non-functional change. The position information will be used later to emit debug info locations to string constants.
Этот коммит содержится в:
родитель
930255ff46
коммит
0ce539ad42
13 изменённых файлов: 109 добавлений и 108 удалений
|
@ -13,8 +13,8 @@ import (
|
|||
func (b *builder) createAtomicOp(name string) llvm.Value {
|
||||
switch name {
|
||||
case "AddInt32", "AddInt64", "AddUint32", "AddUint64", "AddUintptr":
|
||||
ptr := b.getValue(b.fn.Params[0])
|
||||
val := b.getValue(b.fn.Params[1])
|
||||
ptr := b.getValue(b.fn.Params[0], getPos(b.fn))
|
||||
val := b.getValue(b.fn.Params[1], getPos(b.fn))
|
||||
if strings.HasPrefix(b.Triple, "avr") {
|
||||
// AtomicRMW does not work on AVR as intended:
|
||||
// - There are some register allocation issues (fixed by https://reviews.llvm.org/D97127 which is not yet in a usable LLVM release)
|
||||
|
@ -33,8 +33,8 @@ func (b *builder) createAtomicOp(name string) llvm.Value {
|
|||
// Return the new value, not the original value returned by atomicrmw.
|
||||
return b.CreateAdd(oldVal, val, "")
|
||||
case "SwapInt32", "SwapInt64", "SwapUint32", "SwapUint64", "SwapUintptr", "SwapPointer":
|
||||
ptr := b.getValue(b.fn.Params[0])
|
||||
val := b.getValue(b.fn.Params[1])
|
||||
ptr := b.getValue(b.fn.Params[0], getPos(b.fn))
|
||||
val := b.getValue(b.fn.Params[1], getPos(b.fn))
|
||||
isPointer := val.Type().TypeKind() == llvm.PointerTypeKind
|
||||
if isPointer {
|
||||
// atomicrmw only supports integers, so cast to an integer.
|
||||
|
@ -48,21 +48,21 @@ func (b *builder) createAtomicOp(name string) llvm.Value {
|
|||
}
|
||||
return oldVal
|
||||
case "CompareAndSwapInt32", "CompareAndSwapInt64", "CompareAndSwapUint32", "CompareAndSwapUint64", "CompareAndSwapUintptr", "CompareAndSwapPointer":
|
||||
ptr := b.getValue(b.fn.Params[0])
|
||||
old := b.getValue(b.fn.Params[1])
|
||||
newVal := b.getValue(b.fn.Params[2])
|
||||
ptr := b.getValue(b.fn.Params[0], getPos(b.fn))
|
||||
old := b.getValue(b.fn.Params[1], getPos(b.fn))
|
||||
newVal := b.getValue(b.fn.Params[2], getPos(b.fn))
|
||||
tuple := b.CreateAtomicCmpXchg(ptr, old, newVal, llvm.AtomicOrderingSequentiallyConsistent, llvm.AtomicOrderingSequentiallyConsistent, true)
|
||||
swapped := b.CreateExtractValue(tuple, 1, "")
|
||||
return swapped
|
||||
case "LoadInt32", "LoadInt64", "LoadUint32", "LoadUint64", "LoadUintptr", "LoadPointer":
|
||||
ptr := b.getValue(b.fn.Params[0])
|
||||
ptr := b.getValue(b.fn.Params[0], getPos(b.fn))
|
||||
val := b.CreateLoad(b.getLLVMType(b.fn.Signature.Results().At(0).Type()), ptr, "")
|
||||
val.SetOrdering(llvm.AtomicOrderingSequentiallyConsistent)
|
||||
val.SetAlignment(b.targetData.PrefTypeAlignment(val.Type())) // required
|
||||
return val
|
||||
case "StoreInt32", "StoreInt64", "StoreUint32", "StoreUint64", "StoreUintptr", "StorePointer":
|
||||
ptr := b.getValue(b.fn.Params[0])
|
||||
val := b.getValue(b.fn.Params[1])
|
||||
ptr := b.getValue(b.fn.Params[0], getPos(b.fn))
|
||||
val := b.getValue(b.fn.Params[1], getPos(b.fn))
|
||||
if strings.HasPrefix(b.Triple, "avr") {
|
||||
// SelectionDAGBuilder is currently missing the "are unaligned atomics allowed" check for stores.
|
||||
vType := val.Type()
|
||||
|
|
|
@ -14,7 +14,7 @@ import (
|
|||
func (b *builder) createMakeChan(expr *ssa.MakeChan) llvm.Value {
|
||||
elementSize := b.targetData.TypeAllocSize(b.getLLVMType(expr.Type().Underlying().(*types.Chan).Elem()))
|
||||
elementSizeValue := llvm.ConstInt(b.uintptrType, elementSize, false)
|
||||
bufSize := b.getValue(expr.Size)
|
||||
bufSize := b.getValue(expr.Size, getPos(expr))
|
||||
b.createChanBoundsCheck(elementSize, bufSize, expr.Size.Type().Underlying().(*types.Basic), expr.Pos())
|
||||
if bufSize.Type().IntTypeWidth() < b.uintptrType.IntTypeWidth() {
|
||||
bufSize = b.CreateZExt(bufSize, b.uintptrType, "")
|
||||
|
@ -27,8 +27,8 @@ func (b *builder) createMakeChan(expr *ssa.MakeChan) llvm.Value {
|
|||
// createChanSend emits a pseudo chan send operation. It is lowered to the
|
||||
// actual channel send operation during goroutine lowering.
|
||||
func (b *builder) createChanSend(instr *ssa.Send) {
|
||||
ch := b.getValue(instr.Chan)
|
||||
chanValue := b.getValue(instr.X)
|
||||
ch := b.getValue(instr.Chan, getPos(instr))
|
||||
chanValue := b.getValue(instr.X, getPos(instr))
|
||||
|
||||
// store value-to-send
|
||||
valueType := b.getLLVMType(instr.X.Type())
|
||||
|
@ -62,7 +62,7 @@ func (b *builder) createChanSend(instr *ssa.Send) {
|
|||
// actual channel receive operation during goroutine lowering.
|
||||
func (b *builder) createChanRecv(unop *ssa.UnOp) llvm.Value {
|
||||
valueType := b.getLLVMType(unop.X.Type().Underlying().(*types.Chan).Elem())
|
||||
ch := b.getValue(unop.X)
|
||||
ch := b.getValue(unop.X, getPos(unop))
|
||||
|
||||
// Allocate memory to receive into.
|
||||
isZeroSize := b.targetData.TypeAllocSize(valueType) == 0
|
||||
|
@ -140,7 +140,7 @@ func (b *builder) createSelect(expr *ssa.Select) llvm.Value {
|
|||
var selectStates []llvm.Value
|
||||
chanSelectStateType := b.getLLVMRuntimeType("chanSelectState")
|
||||
for _, state := range expr.States {
|
||||
ch := b.getValue(state.Chan)
|
||||
ch := b.getValue(state.Chan, state.Pos)
|
||||
selectState := llvm.ConstNull(chanSelectStateType)
|
||||
selectState = b.CreateInsertValue(selectState, ch, 0, "")
|
||||
switch state.Dir {
|
||||
|
@ -156,7 +156,7 @@ func (b *builder) createSelect(expr *ssa.Select) llvm.Value {
|
|||
case types.SendOnly:
|
||||
// Store this value in an alloca and put a pointer to this alloca
|
||||
// in the send state.
|
||||
sendValue := b.getValue(state.Send)
|
||||
sendValue := b.getValue(state.Send, state.Pos)
|
||||
alloca := llvmutil.CreateEntryBlockAlloca(b.Builder, sendValue.Type(), "select.send.value")
|
||||
b.CreateStore(sendValue, alloca)
|
||||
ptr := b.CreateBitCast(alloca, b.i8ptrType, "")
|
||||
|
@ -247,7 +247,7 @@ func (b *builder) createSelect(expr *ssa.Select) llvm.Value {
|
|||
func (b *builder) getChanSelectResult(expr *ssa.Extract) llvm.Value {
|
||||
if expr.Index == 0 {
|
||||
// index
|
||||
value := b.getValue(expr.Tuple)
|
||||
value := b.getValue(expr.Tuple, getPos(expr))
|
||||
index := b.CreateExtractValue(value, expr.Index, "")
|
||||
if index.Type().IntTypeWidth() < b.intType.IntTypeWidth() {
|
||||
index = b.CreateSExt(index, b.intType, "")
|
||||
|
@ -255,7 +255,7 @@ func (b *builder) getChanSelectResult(expr *ssa.Extract) llvm.Value {
|
|||
return index
|
||||
} else if expr.Index == 1 {
|
||||
// comma-ok
|
||||
value := b.getValue(expr.Tuple)
|
||||
value := b.getValue(expr.Tuple, getPos(expr))
|
||||
return b.CreateExtractValue(value, expr.Index, "")
|
||||
} else {
|
||||
// Select statements are (index, ok, ...) where ... is a number of
|
||||
|
|
|
@ -1028,7 +1028,7 @@ func (c *compilerContext) createEmbedGlobal(member *ssa.Global, global llvm.Valu
|
|||
var fileStructs []llvm.Value
|
||||
for _, file := range allFiles {
|
||||
fileStruct := llvm.ConstNull(llvmEmbedFileStructType)
|
||||
name := c.createConst(ssa.NewConst(constant.MakeString(file.Name), types.Typ[types.String]))
|
||||
name := c.createConst(ssa.NewConst(constant.MakeString(file.Name), types.Typ[types.String]), getPos(member))
|
||||
fileStruct = c.builder.CreateInsertValue(fileStruct, name, 0, "") // "name" field
|
||||
if file.Hash != "" {
|
||||
data := c.getEmbedFileString(file)
|
||||
|
@ -1321,7 +1321,7 @@ func (b *builder) createFunction() {
|
|||
}
|
||||
dbgVar := b.getLocalVariable(variable)
|
||||
pos := b.program.Fset.Position(instr.Pos())
|
||||
b.dibuilder.InsertValueAtEnd(b.getValue(instr.X), dbgVar, b.dibuilder.CreateExpression(nil), llvm.DebugLoc{
|
||||
b.dibuilder.InsertValueAtEnd(b.getValue(instr.X, getPos(instr)), dbgVar, b.dibuilder.CreateExpression(nil), llvm.DebugLoc{
|
||||
Line: uint(pos.Line),
|
||||
Col: uint(pos.Column),
|
||||
Scope: b.difunc,
|
||||
|
@ -1352,7 +1352,7 @@ func (b *builder) createFunction() {
|
|||
for _, phi := range b.phis {
|
||||
block := phi.ssa.Block()
|
||||
for i, edge := range phi.ssa.Edges {
|
||||
llvmVal := b.getValue(edge)
|
||||
llvmVal := b.getValue(edge, getPos(phi.ssa))
|
||||
llvmBlock := b.blockExits[block.Preds[i]]
|
||||
phi.llvm.AddIncoming([]llvm.Value{llvmVal}, []llvm.BasicBlock{llvmBlock})
|
||||
}
|
||||
|
@ -1460,7 +1460,7 @@ func (b *builder) createInstruction(instr ssa.Instruction) {
|
|||
// Start a new goroutine.
|
||||
b.createGo(instr)
|
||||
case *ssa.If:
|
||||
cond := b.getValue(instr.Cond)
|
||||
cond := b.getValue(instr.Cond, getPos(instr))
|
||||
block := instr.Block()
|
||||
blockThen := b.blockEntries[block.Succs[0]]
|
||||
blockElse := b.blockEntries[block.Succs[1]]
|
||||
|
@ -1469,13 +1469,13 @@ func (b *builder) createInstruction(instr ssa.Instruction) {
|
|||
blockJump := b.blockEntries[instr.Block().Succs[0]]
|
||||
b.CreateBr(blockJump)
|
||||
case *ssa.MapUpdate:
|
||||
m := b.getValue(instr.Map)
|
||||
key := b.getValue(instr.Key)
|
||||
value := b.getValue(instr.Value)
|
||||
m := b.getValue(instr.Map, getPos(instr))
|
||||
key := b.getValue(instr.Key, getPos(instr))
|
||||
value := b.getValue(instr.Value, getPos(instr))
|
||||
mapType := instr.Map.Type().Underlying().(*types.Map)
|
||||
b.createMapUpdate(mapType.Key(), m, key, value, instr.Pos())
|
||||
case *ssa.Panic:
|
||||
value := b.getValue(instr.X)
|
||||
value := b.getValue(instr.X, getPos(instr))
|
||||
b.createRuntimeInvoke("_panic", []llvm.Value{value}, "")
|
||||
b.CreateUnreachable()
|
||||
case *ssa.Return:
|
||||
|
@ -1485,12 +1485,12 @@ func (b *builder) createInstruction(instr ssa.Instruction) {
|
|||
if len(instr.Results) == 0 {
|
||||
b.CreateRetVoid()
|
||||
} else if len(instr.Results) == 1 {
|
||||
b.CreateRet(b.getValue(instr.Results[0]))
|
||||
b.CreateRet(b.getValue(instr.Results[0], getPos(instr)))
|
||||
} else {
|
||||
// Multiple return values. Put them all in a struct.
|
||||
retVal := llvm.ConstNull(b.llvmFn.GlobalValueType().ReturnType())
|
||||
for i, result := range instr.Results {
|
||||
val := b.getValue(result)
|
||||
val := b.getValue(result, getPos(instr))
|
||||
retVal = b.CreateInsertValue(retVal, val, i, "")
|
||||
}
|
||||
b.CreateRet(retVal)
|
||||
|
@ -1500,8 +1500,8 @@ func (b *builder) createInstruction(instr ssa.Instruction) {
|
|||
case *ssa.Send:
|
||||
b.createChanSend(instr)
|
||||
case *ssa.Store:
|
||||
llvmAddr := b.getValue(instr.Addr)
|
||||
llvmVal := b.getValue(instr.Val)
|
||||
llvmAddr := b.getValue(instr.Addr, getPos(instr))
|
||||
llvmVal := b.getValue(instr.Val, getPos(instr))
|
||||
b.createNilCheck(instr.Addr, llvmAddr, "store")
|
||||
if b.targetData.TypeAllocSize(llvmVal.Type()) == 0 {
|
||||
// nothing to store
|
||||
|
@ -1760,7 +1760,7 @@ func (b *builder) createBuiltin(argTypes []types.Type, argValues []llvm.Value, c
|
|||
func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error) {
|
||||
var params []llvm.Value
|
||||
for _, param := range instr.Args {
|
||||
params = append(params, b.getValue(param))
|
||||
params = append(params, b.getValue(param, getPos(instr)))
|
||||
}
|
||||
|
||||
// Try to call the function directly for trivially static calls.
|
||||
|
@ -1777,9 +1777,9 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error)
|
|||
case name == "device.AsmFull" || name == "device/arm.AsmFull" || name == "device/arm64.AsmFull" || name == "device/avr.AsmFull" || name == "device/riscv.AsmFull":
|
||||
return b.createInlineAsmFull(instr)
|
||||
case strings.HasPrefix(name, "device/arm.SVCall"):
|
||||
return b.emitSVCall(instr.Args)
|
||||
return b.emitSVCall(instr.Args, getPos(instr))
|
||||
case strings.HasPrefix(name, "device/arm64.SVCall"):
|
||||
return b.emitSV64Call(instr.Args)
|
||||
return b.emitSV64Call(instr.Args, getPos(instr))
|
||||
case strings.HasPrefix(name, "(device/riscv.CSR)."):
|
||||
return b.emitCSROperation(instr)
|
||||
case strings.HasPrefix(name, "syscall.Syscall") || strings.HasPrefix(name, "syscall.RawSyscall"):
|
||||
|
@ -1816,7 +1816,7 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error)
|
|||
case *ssa.MakeClosure:
|
||||
// A call on a func value, but the callee is trivial to find. For
|
||||
// example: immediately applied functions.
|
||||
funcValue := b.getValue(value)
|
||||
funcValue := b.getValue(value, getPos(value))
|
||||
context = b.extractFuncContext(funcValue)
|
||||
default:
|
||||
panic("StaticCallee returned an unexpected value")
|
||||
|
@ -1831,7 +1831,7 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error)
|
|||
return b.createBuiltin(argTypes, params, call.Name(), instr.Pos())
|
||||
} else if instr.IsInvoke() {
|
||||
// Interface method call (aka invoke call).
|
||||
itf := b.getValue(instr.Value) // interface value (runtime._interface)
|
||||
itf := b.getValue(instr.Value, getPos(instr)) // interface value (runtime._interface)
|
||||
typecode := b.CreateExtractValue(itf, 0, "invoke.func.typecode")
|
||||
value := b.CreateExtractValue(itf, 1, "invoke.func.value") // receiver
|
||||
// Prefix the params with receiver value and suffix with typecode.
|
||||
|
@ -1842,7 +1842,7 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error)
|
|||
context = llvm.Undef(b.i8ptrType)
|
||||
} else {
|
||||
// Function pointer.
|
||||
value := b.getValue(instr.Value)
|
||||
value := b.getValue(instr.Value, getPos(instr))
|
||||
// This is a func value, which cannot be called directly. We have to
|
||||
// extract the function pointer and context first from the func value.
|
||||
calleeType, callee, context = b.decodeFuncValue(value, instr.Value.Type().Underlying().(*types.Signature))
|
||||
|
@ -1860,10 +1860,10 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error)
|
|||
|
||||
// getValue returns the LLVM value of a constant, function value, global, or
|
||||
// already processed SSA expression.
|
||||
func (b *builder) getValue(expr ssa.Value) llvm.Value {
|
||||
func (b *builder) getValue(expr ssa.Value, pos token.Pos) llvm.Value {
|
||||
switch expr := expr.(type) {
|
||||
case *ssa.Const:
|
||||
return b.createConst(expr)
|
||||
return b.createConst(expr, pos)
|
||||
case *ssa.Function:
|
||||
if b.getFunctionInfo(expr).exported {
|
||||
b.addError(expr.Pos(), "cannot use an exported function as value: "+expr.String())
|
||||
|
@ -1948,8 +1948,8 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) {
|
|||
return buf, nil
|
||||
}
|
||||
case *ssa.BinOp:
|
||||
x := b.getValue(expr.X)
|
||||
y := b.getValue(expr.Y)
|
||||
x := b.getValue(expr.X, getPos(expr))
|
||||
y := b.getValue(expr.Y, getPos(expr))
|
||||
return b.createBinOp(expr.Op, expr.X.Type(), expr.Y.Type(), x, y, expr.Pos())
|
||||
case *ssa.Call:
|
||||
return b.createFunctionCall(expr.Common())
|
||||
|
@ -1960,12 +1960,12 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) {
|
|||
// This is different from how the official Go compiler works, because of
|
||||
// heap allocation and because it's easier to implement, see:
|
||||
// https://research.swtch.com/interfaces
|
||||
return b.getValue(expr.X), nil
|
||||
return b.getValue(expr.X, getPos(expr)), nil
|
||||
case *ssa.ChangeType:
|
||||
// This instruction changes the type, but the underlying value remains
|
||||
// the same. This is often a no-op, but sometimes we have to change the
|
||||
// LLVM type as well.
|
||||
x := b.getValue(expr.X)
|
||||
x := b.getValue(expr.X, getPos(expr))
|
||||
llvmType := b.getLLVMType(expr.Type())
|
||||
if x.Type() == llvmType {
|
||||
// Different Go type but same LLVM type (for example, named int).
|
||||
|
@ -1994,20 +1994,20 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) {
|
|||
case *ssa.Const:
|
||||
panic("const is not an expression")
|
||||
case *ssa.Convert:
|
||||
x := b.getValue(expr.X)
|
||||
x := b.getValue(expr.X, getPos(expr))
|
||||
return b.createConvert(expr.X.Type(), expr.Type(), x, expr.Pos())
|
||||
case *ssa.Extract:
|
||||
if _, ok := expr.Tuple.(*ssa.Select); ok {
|
||||
return b.getChanSelectResult(expr), nil
|
||||
}
|
||||
value := b.getValue(expr.Tuple)
|
||||
value := b.getValue(expr.Tuple, getPos(expr))
|
||||
return b.CreateExtractValue(value, expr.Index, ""), nil
|
||||
case *ssa.Field:
|
||||
value := b.getValue(expr.X)
|
||||
value := b.getValue(expr.X, getPos(expr))
|
||||
result := b.CreateExtractValue(value, expr.Field, "")
|
||||
return result, nil
|
||||
case *ssa.FieldAddr:
|
||||
val := b.getValue(expr.X)
|
||||
val := b.getValue(expr.X, getPos(expr))
|
||||
// Check for nil pointer before calculating the address, from the spec:
|
||||
// > For an operand x of type T, the address operation &x generates a
|
||||
// > pointer of type *T to x. [...] If the evaluation of x would cause a
|
||||
|
@ -2025,8 +2025,8 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) {
|
|||
case *ssa.Global:
|
||||
panic("global is not an expression")
|
||||
case *ssa.Index:
|
||||
collection := b.getValue(expr.X)
|
||||
index := b.getValue(expr.Index)
|
||||
collection := b.getValue(expr.X, getPos(expr))
|
||||
index := b.getValue(expr.Index, getPos(expr))
|
||||
|
||||
switch xType := expr.X.Type().Underlying().(type) {
|
||||
case *types.Basic: // extract byte from string
|
||||
|
@ -2075,8 +2075,8 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) {
|
|||
panic("unknown *ssa.Index type")
|
||||
}
|
||||
case *ssa.IndexAddr:
|
||||
val := b.getValue(expr.X)
|
||||
index := b.getValue(expr.Index)
|
||||
val := b.getValue(expr.X, getPos(expr))
|
||||
index := b.getValue(expr.Index, getPos(expr))
|
||||
|
||||
// Get buffer pointer and length
|
||||
var bufptr, buflen llvm.Value
|
||||
|
@ -2127,8 +2127,8 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) {
|
|||
panic("unreachable")
|
||||
}
|
||||
case *ssa.Lookup: // map lookup
|
||||
value := b.getValue(expr.X)
|
||||
index := b.getValue(expr.Index)
|
||||
value := b.getValue(expr.X, getPos(expr))
|
||||
index := b.getValue(expr.Index, getPos(expr))
|
||||
valueType := expr.Type()
|
||||
if expr.CommaOk {
|
||||
valueType = valueType.(*types.Tuple).At(0).Type()
|
||||
|
@ -2139,13 +2139,13 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) {
|
|||
case *ssa.MakeClosure:
|
||||
return b.parseMakeClosure(expr)
|
||||
case *ssa.MakeInterface:
|
||||
val := b.getValue(expr.X)
|
||||
val := b.getValue(expr.X, getPos(expr))
|
||||
return b.createMakeInterface(val, expr.X.Type(), expr.Pos()), nil
|
||||
case *ssa.MakeMap:
|
||||
return b.createMakeMap(expr)
|
||||
case *ssa.MakeSlice:
|
||||
sliceLen := b.getValue(expr.Len)
|
||||
sliceCap := b.getValue(expr.Cap)
|
||||
sliceLen := b.getValue(expr.Len, getPos(expr))
|
||||
sliceCap := b.getValue(expr.Cap, getPos(expr))
|
||||
sliceType := expr.Type().Underlying().(*types.Slice)
|
||||
llvmElemType := b.getLLVMType(sliceType.Elem())
|
||||
elemSize := b.targetData.TypeAllocSize(llvmElemType)
|
||||
|
@ -2197,8 +2197,8 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) {
|
|||
return slice, nil
|
||||
case *ssa.Next:
|
||||
rangeVal := expr.Iter.(*ssa.Range).X
|
||||
llvmRangeVal := b.getValue(rangeVal)
|
||||
it := b.getValue(expr.Iter)
|
||||
llvmRangeVal := b.getValue(rangeVal, getPos(expr))
|
||||
it := b.getValue(expr.Iter, getPos(expr))
|
||||
if expr.IsString {
|
||||
return b.createRuntimeCall("stringNext", []llvm.Value{llvmRangeVal, it}, "range.next"), nil
|
||||
} else { // map
|
||||
|
@ -2224,14 +2224,14 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) {
|
|||
case *ssa.Select:
|
||||
return b.createSelect(expr), nil
|
||||
case *ssa.Slice:
|
||||
value := b.getValue(expr.X)
|
||||
value := b.getValue(expr.X, getPos(expr))
|
||||
|
||||
var lowType, highType, maxType *types.Basic
|
||||
var low, high, max llvm.Value
|
||||
|
||||
if expr.Low != nil {
|
||||
lowType = expr.Low.Type().Underlying().(*types.Basic)
|
||||
low = b.getValue(expr.Low)
|
||||
low = b.getValue(expr.Low, getPos(expr))
|
||||
low = b.extendInteger(low, lowType, b.uintptrType)
|
||||
} else {
|
||||
lowType = types.Typ[types.Uintptr]
|
||||
|
@ -2240,7 +2240,7 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) {
|
|||
|
||||
if expr.High != nil {
|
||||
highType = expr.High.Type().Underlying().(*types.Basic)
|
||||
high = b.getValue(expr.High)
|
||||
high = b.getValue(expr.High, getPos(expr))
|
||||
high = b.extendInteger(high, highType, b.uintptrType)
|
||||
} else {
|
||||
highType = types.Typ[types.Uintptr]
|
||||
|
@ -2248,7 +2248,7 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) {
|
|||
|
||||
if expr.Max != nil {
|
||||
maxType = expr.Max.Type().Underlying().(*types.Basic)
|
||||
max = b.getValue(expr.Max)
|
||||
max = b.getValue(expr.Max, getPos(expr))
|
||||
max = b.extendInteger(max, maxType, b.uintptrType)
|
||||
} else {
|
||||
maxType = types.Typ[types.Uintptr]
|
||||
|
@ -2381,7 +2381,7 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) {
|
|||
// Conversion from a slice to an array pointer, as the name clearly
|
||||
// says. This requires a runtime check to make sure the slice is at
|
||||
// least as big as the array.
|
||||
slice := b.getValue(expr.X)
|
||||
slice := b.getValue(expr.X, getPos(expr))
|
||||
sliceLen := b.CreateExtractValue(slice, 1, "")
|
||||
arrayLen := expr.Type().Underlying().(*types.Pointer).Elem().Underlying().(*types.Array).Len()
|
||||
b.createSliceToArrayPointerCheck(sliceLen, arrayLen)
|
||||
|
@ -2814,7 +2814,7 @@ func (b *builder) createBinOp(op token.Token, typ, ytyp types.Type, x, y llvm.Va
|
|||
}
|
||||
|
||||
// createConst creates a LLVM constant value from a Go constant.
|
||||
func (c *compilerContext) createConst(expr *ssa.Const) llvm.Value {
|
||||
func (c *compilerContext) createConst(expr *ssa.Const, pos token.Pos) llvm.Value {
|
||||
switch typ := expr.Type().Underlying().(type) {
|
||||
case *types.Basic:
|
||||
llvmType := c.getLLVMType(typ)
|
||||
|
@ -2860,15 +2860,15 @@ func (c *compilerContext) createConst(expr *ssa.Const) llvm.Value {
|
|||
n, _ := constant.Float64Val(expr.Value)
|
||||
return llvm.ConstFloat(llvmType, n)
|
||||
} else if typ.Kind() == types.Complex64 {
|
||||
r := c.createConst(ssa.NewConst(constant.Real(expr.Value), types.Typ[types.Float32]))
|
||||
i := c.createConst(ssa.NewConst(constant.Imag(expr.Value), types.Typ[types.Float32]))
|
||||
r := c.createConst(ssa.NewConst(constant.Real(expr.Value), types.Typ[types.Float32]), pos)
|
||||
i := c.createConst(ssa.NewConst(constant.Imag(expr.Value), types.Typ[types.Float32]), pos)
|
||||
cplx := llvm.Undef(c.ctx.StructType([]llvm.Type{c.ctx.FloatType(), c.ctx.FloatType()}, false))
|
||||
cplx = c.builder.CreateInsertValue(cplx, r, 0, "")
|
||||
cplx = c.builder.CreateInsertValue(cplx, i, 1, "")
|
||||
return cplx
|
||||
} else if typ.Kind() == types.Complex128 {
|
||||
r := c.createConst(ssa.NewConst(constant.Real(expr.Value), types.Typ[types.Float64]))
|
||||
i := c.createConst(ssa.NewConst(constant.Imag(expr.Value), types.Typ[types.Float64]))
|
||||
r := c.createConst(ssa.NewConst(constant.Real(expr.Value), types.Typ[types.Float64]), pos)
|
||||
i := c.createConst(ssa.NewConst(constant.Imag(expr.Value), types.Typ[types.Float64]), pos)
|
||||
cplx := llvm.Undef(c.ctx.StructType([]llvm.Type{c.ctx.DoubleType(), c.ctx.DoubleType()}, false))
|
||||
cplx = c.builder.CreateInsertValue(cplx, r, 0, "")
|
||||
cplx = c.builder.CreateInsertValue(cplx, i, 1, "")
|
||||
|
@ -3139,7 +3139,7 @@ func (b *builder) createConvert(typeFrom, typeTo types.Type, value llvm.Value, p
|
|||
// which can all be directly lowered to IR. However, there is also the channel
|
||||
// receive operator which is handled in the runtime directly.
|
||||
func (b *builder) createUnOp(unop *ssa.UnOp) (llvm.Value, error) {
|
||||
x := b.getValue(unop.X)
|
||||
x := b.getValue(unop.X, getPos(unop))
|
||||
switch unop.Op {
|
||||
case token.NOT: // !x
|
||||
return b.CreateNot(x, ""), nil
|
||||
|
|
|
@ -267,13 +267,13 @@ func (b *builder) createDefer(instr *ssa.Defer) {
|
|||
|
||||
// Collect all values to be put in the struct (starting with
|
||||
// runtime._defer fields, followed by the call parameters).
|
||||
itf := b.getValue(instr.Call.Value) // interface
|
||||
itf := b.getValue(instr.Call.Value, getPos(instr)) // interface
|
||||
typecode := b.CreateExtractValue(itf, 0, "invoke.func.typecode")
|
||||
receiverValue := b.CreateExtractValue(itf, 1, "invoke.func.receiver")
|
||||
values = []llvm.Value{callback, next, typecode, receiverValue}
|
||||
valueTypes = append(valueTypes, b.i8ptrType, b.i8ptrType)
|
||||
for _, arg := range instr.Call.Args {
|
||||
val := b.getValue(arg)
|
||||
val := b.getValue(arg, getPos(instr))
|
||||
values = append(values, val)
|
||||
valueTypes = append(valueTypes, val.Type())
|
||||
}
|
||||
|
@ -290,7 +290,7 @@ func (b *builder) createDefer(instr *ssa.Defer) {
|
|||
// runtime._defer fields).
|
||||
values = []llvm.Value{callback, next}
|
||||
for _, param := range instr.Call.Args {
|
||||
llvmParam := b.getValue(param)
|
||||
llvmParam := b.getValue(param, getPos(instr))
|
||||
values = append(values, llvmParam)
|
||||
valueTypes = append(valueTypes, llvmParam.Type())
|
||||
}
|
||||
|
@ -302,7 +302,7 @@ func (b *builder) createDefer(instr *ssa.Defer) {
|
|||
// pointer.
|
||||
// TODO: ignore this closure entirely and put pointers to the free
|
||||
// variables directly in the defer struct, avoiding a memory allocation.
|
||||
closure := b.getValue(instr.Call.Value)
|
||||
closure := b.getValue(instr.Call.Value, getPos(instr))
|
||||
context := b.CreateExtractValue(closure, 0, "")
|
||||
|
||||
// Get the callback number.
|
||||
|
@ -318,7 +318,7 @@ func (b *builder) createDefer(instr *ssa.Defer) {
|
|||
// context pointer).
|
||||
values = []llvm.Value{callback, next}
|
||||
for _, param := range instr.Call.Args {
|
||||
llvmParam := b.getValue(param)
|
||||
llvmParam := b.getValue(param, getPos(instr))
|
||||
values = append(values, llvmParam)
|
||||
valueTypes = append(valueTypes, llvmParam.Type())
|
||||
}
|
||||
|
@ -330,7 +330,7 @@ func (b *builder) createDefer(instr *ssa.Defer) {
|
|||
var argValues []llvm.Value
|
||||
for _, arg := range instr.Call.Args {
|
||||
argTypes = append(argTypes, arg.Type())
|
||||
argValues = append(argValues, b.getValue(arg))
|
||||
argValues = append(argValues, b.getValue(arg, getPos(instr)))
|
||||
}
|
||||
|
||||
if _, ok := b.deferBuiltinFuncs[instr.Call.Value]; !ok {
|
||||
|
@ -353,7 +353,7 @@ func (b *builder) createDefer(instr *ssa.Defer) {
|
|||
}
|
||||
|
||||
} else {
|
||||
funcValue := b.getValue(instr.Call.Value)
|
||||
funcValue := b.getValue(instr.Call.Value, getPos(instr))
|
||||
|
||||
if _, ok := b.deferExprFuncs[instr.Call.Value]; !ok {
|
||||
b.deferExprFuncs[instr.Call.Value] = len(b.allDeferFuncs)
|
||||
|
@ -368,7 +368,7 @@ func (b *builder) createDefer(instr *ssa.Defer) {
|
|||
values = []llvm.Value{callback, next, funcValue}
|
||||
valueTypes = append(valueTypes, funcValue.Type())
|
||||
for _, param := range instr.Call.Args {
|
||||
llvmParam := b.getValue(param)
|
||||
llvmParam := b.getValue(param, getPos(instr))
|
||||
values = append(values, llvmParam)
|
||||
valueTypes = append(valueTypes, llvmParam.Type())
|
||||
}
|
||||
|
|
|
@ -134,7 +134,7 @@ func (b *builder) parseMakeClosure(expr *ssa.MakeClosure) (llvm.Value, error) {
|
|||
boundVars := make([]llvm.Value, len(expr.Bindings))
|
||||
for i, binding := range expr.Bindings {
|
||||
// The context stores the bound variables.
|
||||
llvmBoundVar := b.getValue(binding)
|
||||
llvmBoundVar := b.getValue(binding, getPos(expr))
|
||||
boundVars[i] = llvmBoundVar
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ func (b *builder) createGo(instr *ssa.Go) {
|
|||
// Get all function parameters to pass to the goroutine.
|
||||
var params []llvm.Value
|
||||
for _, param := range instr.Call.Args {
|
||||
params = append(params, b.getValue(param))
|
||||
params = append(params, b.getValue(param, getPos(instr)))
|
||||
}
|
||||
|
||||
var prefix string
|
||||
|
@ -33,7 +33,7 @@ func (b *builder) createGo(instr *ssa.Go) {
|
|||
case *ssa.MakeClosure:
|
||||
// A goroutine call on a func value, but the callee is trivial to find. For
|
||||
// example: immediately applied functions.
|
||||
funcValue := b.getValue(value)
|
||||
funcValue := b.getValue(value, getPos(instr))
|
||||
context = b.extractFuncContext(funcValue)
|
||||
default:
|
||||
panic("StaticCallee returned an unexpected value")
|
||||
|
@ -70,13 +70,13 @@ func (b *builder) createGo(instr *ssa.Go) {
|
|||
var argValues []llvm.Value
|
||||
for _, arg := range instr.Call.Args {
|
||||
argTypes = append(argTypes, arg.Type())
|
||||
argValues = append(argValues, b.getValue(arg))
|
||||
argValues = append(argValues, b.getValue(arg, getPos(instr)))
|
||||
}
|
||||
b.createBuiltin(argTypes, argValues, builtin.Name(), instr.Pos())
|
||||
return
|
||||
} else if instr.Call.IsInvoke() {
|
||||
// This is a method call on an interface value.
|
||||
itf := b.getValue(instr.Call.Value)
|
||||
itf := b.getValue(instr.Call.Value, getPos(instr))
|
||||
itfTypeCode := b.CreateExtractValue(itf, 0, "")
|
||||
itfValue := b.CreateExtractValue(itf, 1, "")
|
||||
funcPtr = b.getInvokeFunction(&instr.Call)
|
||||
|
@ -90,7 +90,7 @@ func (b *builder) createGo(instr *ssa.Go) {
|
|||
// * The function context, for closures.
|
||||
// * The function pointer (for tasks).
|
||||
var context llvm.Value
|
||||
funcPtrType, funcPtr, context = b.decodeFuncValue(b.getValue(instr.Call.Value), instr.Call.Value.Type().Underlying().(*types.Signature))
|
||||
funcPtrType, funcPtr, context = b.decodeFuncValue(b.getValue(instr.Call.Value, getPos(instr)), instr.Call.Value.Type().Underlying().(*types.Signature))
|
||||
params = append(params, context, funcPtr)
|
||||
hasContext = true
|
||||
prefix = b.fn.RelString(nil)
|
||||
|
|
|
@ -5,6 +5,7 @@ package compiler
|
|||
import (
|
||||
"fmt"
|
||||
"go/constant"
|
||||
"go/token"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -55,7 +56,7 @@ func (b *builder) createInlineAsmFull(instr *ssa.CallCommon) (llvm.Value, error)
|
|||
return llvm.Value{}, b.makeError(instr.Pos(), "register value map must be created in the same basic block")
|
||||
}
|
||||
key := constant.StringVal(r.Key.(*ssa.Const).Value)
|
||||
registers[key] = b.getValue(r.Value.(*ssa.MakeInterface).X)
|
||||
registers[key] = b.getValue(r.Value.(*ssa.MakeInterface).X, getPos(instr))
|
||||
case *ssa.Call:
|
||||
if r.Common() == instr {
|
||||
break
|
||||
|
@ -140,7 +141,7 @@ func (b *builder) createInlineAsmFull(instr *ssa.CallCommon) (llvm.Value, error)
|
|||
//
|
||||
// The num parameter must be a constant. All other parameters may be any scalar
|
||||
// value supported by LLVM inline assembly.
|
||||
func (b *builder) emitSVCall(args []ssa.Value) (llvm.Value, error) {
|
||||
func (b *builder) emitSVCall(args []ssa.Value, pos token.Pos) (llvm.Value, error) {
|
||||
num, _ := constant.Uint64Val(args[0].(*ssa.Const).Value)
|
||||
llvmArgs := []llvm.Value{}
|
||||
argTypes := []llvm.Type{}
|
||||
|
@ -153,7 +154,7 @@ func (b *builder) emitSVCall(args []ssa.Value) (llvm.Value, error) {
|
|||
} else {
|
||||
constraints += ",{r" + strconv.Itoa(i) + "}"
|
||||
}
|
||||
llvmValue := b.getValue(arg)
|
||||
llvmValue := b.getValue(arg, pos)
|
||||
llvmArgs = append(llvmArgs, llvmValue)
|
||||
argTypes = append(argTypes, llvmValue.Type())
|
||||
}
|
||||
|
@ -178,7 +179,7 @@ func (b *builder) emitSVCall(args []ssa.Value) (llvm.Value, error) {
|
|||
// The num parameter must be a constant. All other parameters may be any scalar
|
||||
// value supported by LLVM inline assembly.
|
||||
// Same as emitSVCall but for AArch64
|
||||
func (b *builder) emitSV64Call(args []ssa.Value) (llvm.Value, error) {
|
||||
func (b *builder) emitSV64Call(args []ssa.Value, pos token.Pos) (llvm.Value, error) {
|
||||
num, _ := constant.Uint64Val(args[0].(*ssa.Const).Value)
|
||||
llvmArgs := []llvm.Value{}
|
||||
argTypes := []llvm.Type{}
|
||||
|
@ -191,7 +192,7 @@ func (b *builder) emitSV64Call(args []ssa.Value) (llvm.Value, error) {
|
|||
} else {
|
||||
constraints += ",{x" + strconv.Itoa(i) + "}"
|
||||
}
|
||||
llvmValue := b.getValue(arg)
|
||||
llvmValue := b.getValue(arg, pos)
|
||||
llvmArgs = append(llvmArgs, llvmValue)
|
||||
argTypes = append(argTypes, llvmValue.Type())
|
||||
}
|
||||
|
@ -231,19 +232,19 @@ func (b *builder) emitCSROperation(call *ssa.CallCommon) (llvm.Value, error) {
|
|||
fnType := llvm.FunctionType(b.ctx.VoidType(), []llvm.Type{b.uintptrType}, false)
|
||||
asm := fmt.Sprintf("csrw %d, $0", csr)
|
||||
target := llvm.InlineAsm(fnType, asm, "r", true, false, 0, false)
|
||||
return b.CreateCall(fnType, target, []llvm.Value{b.getValue(call.Args[1])}, ""), nil
|
||||
return b.CreateCall(fnType, target, []llvm.Value{b.getValue(call.Args[1], getPos(call))}, ""), nil
|
||||
case "SetBits":
|
||||
// Note: it may be possible to optimize this to csrrsi in many cases.
|
||||
fnType := llvm.FunctionType(b.uintptrType, []llvm.Type{b.uintptrType}, false)
|
||||
asm := fmt.Sprintf("csrrs $0, %d, $1", csr)
|
||||
target := llvm.InlineAsm(fnType, asm, "=r,r", true, false, 0, false)
|
||||
return b.CreateCall(fnType, target, []llvm.Value{b.getValue(call.Args[1])}, ""), nil
|
||||
return b.CreateCall(fnType, target, []llvm.Value{b.getValue(call.Args[1], getPos(call))}, ""), nil
|
||||
case "ClearBits":
|
||||
// Note: it may be possible to optimize this to csrrci in many cases.
|
||||
fnType := llvm.FunctionType(b.uintptrType, []llvm.Type{b.uintptrType}, false)
|
||||
asm := fmt.Sprintf("csrrc $0, %d, $1", csr)
|
||||
target := llvm.InlineAsm(fnType, asm, "=r,r", true, false, 0, false)
|
||||
return b.CreateCall(fnType, target, []llvm.Value{b.getValue(call.Args[1])}, ""), nil
|
||||
return b.CreateCall(fnType, target, []llvm.Value{b.getValue(call.Args[1], getPos(call))}, ""), nil
|
||||
default:
|
||||
return llvm.Value{}, b.makeError(call.Pos(), "unknown CSR operation: "+name)
|
||||
}
|
||||
|
|
|
@ -475,7 +475,7 @@ func (c *compilerContext) getMethodSignature(method *types.Func) llvm.Value {
|
|||
// Type asserts on concrete types are trivial: just compare type numbers. Type
|
||||
// asserts on interfaces are more difficult, see the comments in the function.
|
||||
func (b *builder) createTypeAssert(expr *ssa.TypeAssert) llvm.Value {
|
||||
itf := b.getValue(expr.X)
|
||||
itf := b.getValue(expr.X, getPos(expr))
|
||||
assertedType := b.getLLVMType(expr.AssertedType)
|
||||
|
||||
actualTypeNum := b.CreateExtractValue(itf, 0, "interface.type")
|
||||
|
|
|
@ -24,7 +24,7 @@ func (b *builder) createInterruptGlobal(instr *ssa.CallCommon) (llvm.Value, erro
|
|||
// Note that bound functions are allowed if the function has a pointer
|
||||
// receiver and is a global. This is rather strict but still allows for
|
||||
// idiomatic Go code.
|
||||
funcValue := b.getValue(instr.Args[1])
|
||||
funcValue := b.getValue(instr.Args[1], getPos(instr))
|
||||
if funcValue.IsAConstant().IsNil() {
|
||||
// Try to determine the cause of the non-constantness for a nice error
|
||||
// message.
|
||||
|
|
|
@ -58,7 +58,7 @@ func (b *builder) createMemoryCopyImpl() {
|
|||
}
|
||||
var params []llvm.Value
|
||||
for _, param := range b.fn.Params {
|
||||
params = append(params, b.getValue(param))
|
||||
params = append(params, b.getValue(param, getPos(b.fn)))
|
||||
}
|
||||
params = append(params, llvm.ConstInt(b.ctx.Int1Type(), 0, false))
|
||||
b.CreateCall(llvmFn.GlobalValueType(), llvmFn, params, "")
|
||||
|
@ -80,9 +80,9 @@ func (b *builder) createMemoryZeroImpl() {
|
|||
llvmFn = llvm.AddFunction(b.mod, fnName, fnType)
|
||||
}
|
||||
params := []llvm.Value{
|
||||
b.getValue(b.fn.Params[0]),
|
||||
b.getValue(b.fn.Params[0], getPos(b.fn)),
|
||||
llvm.ConstInt(b.ctx.Int8Type(), 0, false),
|
||||
b.getValue(b.fn.Params[1]),
|
||||
b.getValue(b.fn.Params[1], getPos(b.fn)),
|
||||
llvm.ConstInt(b.ctx.Int1Type(), 0, false),
|
||||
}
|
||||
b.CreateCall(llvmFn.GlobalValueType(), llvmFn, params, "")
|
||||
|
@ -95,7 +95,7 @@ func (b *builder) createKeepAliveImpl() {
|
|||
b.createFunctionStart(true)
|
||||
|
||||
// Get the underlying value of the interface value.
|
||||
interfaceValue := b.getValue(b.fn.Params[0])
|
||||
interfaceValue := b.getValue(b.fn.Params[0], getPos(b.fn))
|
||||
pointerValue := b.CreateExtractValue(interfaceValue, 1, "")
|
||||
|
||||
// Create an equivalent of the following C code, which is basically just a
|
||||
|
@ -149,7 +149,7 @@ func (b *builder) defineMathOp() {
|
|||
// Create a call to the intrinsic.
|
||||
args := make([]llvm.Value, len(b.fn.Params))
|
||||
for i, param := range b.fn.Params {
|
||||
args[i] = b.getValue(param)
|
||||
args[i] = b.getValue(param, getPos(b.fn))
|
||||
}
|
||||
result := b.CreateCall(llvmFn.GlobalValueType(), llvmFn, args, "")
|
||||
b.CreateRet(result)
|
||||
|
|
|
@ -46,7 +46,7 @@ func (b *builder) createMakeMap(expr *ssa.MakeMap) (llvm.Value, error) {
|
|||
sizeHint := llvm.ConstInt(b.uintptrType, 8, false)
|
||||
algEnum := llvm.ConstInt(b.ctx.Int8Type(), alg, false)
|
||||
if expr.Reserve != nil {
|
||||
sizeHint = b.getValue(expr.Reserve)
|
||||
sizeHint = b.getValue(expr.Reserve, getPos(expr))
|
||||
var err error
|
||||
sizeHint, err = b.createConvert(expr.Reserve.Type(), types.Typ[types.Uintptr], sizeHint, expr.Pos())
|
||||
if err != nil {
|
||||
|
|
|
@ -14,7 +14,7 @@ import (
|
|||
// and returns the result as a single integer (the system call result). The
|
||||
// result is not further interpreted.
|
||||
func (b *builder) createRawSyscall(call *ssa.CallCommon) (llvm.Value, error) {
|
||||
num := b.getValue(call.Args[0])
|
||||
num := b.getValue(call.Args[0], getPos(call))
|
||||
switch {
|
||||
case b.GOARCH == "amd64" && b.GOOS == "linux":
|
||||
// Sources:
|
||||
|
@ -37,7 +37,7 @@ func (b *builder) createRawSyscall(call *ssa.CallCommon) (llvm.Value, error) {
|
|||
"{r12}",
|
||||
"{r13}",
|
||||
}[i]
|
||||
llvmValue := b.getValue(arg)
|
||||
llvmValue := b.getValue(arg, getPos(call))
|
||||
args = append(args, llvmValue)
|
||||
argTypes = append(argTypes, llvmValue.Type())
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ func (b *builder) createRawSyscall(call *ssa.CallCommon) (llvm.Value, error) {
|
|||
"{edi}",
|
||||
"{ebp}",
|
||||
}[i]
|
||||
llvmValue := b.getValue(arg)
|
||||
llvmValue := b.getValue(arg, getPos(call))
|
||||
args = append(args, llvmValue)
|
||||
argTypes = append(argTypes, llvmValue.Type())
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ func (b *builder) createRawSyscall(call *ssa.CallCommon) (llvm.Value, error) {
|
|||
"{r5}",
|
||||
"{r6}",
|
||||
}[i]
|
||||
llvmValue := b.getValue(arg)
|
||||
llvmValue := b.getValue(arg, getPos(call))
|
||||
args = append(args, llvmValue)
|
||||
argTypes = append(argTypes, llvmValue.Type())
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ func (b *builder) createRawSyscall(call *ssa.CallCommon) (llvm.Value, error) {
|
|||
"{x4}",
|
||||
"{x5}",
|
||||
}[i]
|
||||
llvmValue := b.getValue(arg)
|
||||
llvmValue := b.getValue(arg, getPos(call))
|
||||
args = append(args, llvmValue)
|
||||
argTypes = append(argTypes, llvmValue.Type())
|
||||
}
|
||||
|
@ -177,12 +177,12 @@ func (b *builder) createSyscall(call *ssa.CallCommon) (llvm.Value, error) {
|
|||
var paramTypes []llvm.Type
|
||||
var params []llvm.Value
|
||||
for _, val := range call.Args[2:] {
|
||||
param := b.getValue(val)
|
||||
param := b.getValue(val, getPos(call))
|
||||
params = append(params, param)
|
||||
paramTypes = append(paramTypes, param.Type())
|
||||
}
|
||||
llvmType := llvm.FunctionType(b.uintptrType, paramTypes, false)
|
||||
fn := b.getValue(call.Args[0])
|
||||
fn := b.getValue(call.Args[0], getPos(call))
|
||||
fnPtr := b.CreateIntToPtr(fn, llvm.PointerType(llvmType, 0), "")
|
||||
|
||||
// Prepare some functions that will be called later.
|
||||
|
|
|
@ -9,7 +9,7 @@ import "go/types"
|
|||
// runtime/volatile.LoadT().
|
||||
func (b *builder) createVolatileLoad() {
|
||||
b.createFunctionStart(true)
|
||||
addr := b.getValue(b.fn.Params[0])
|
||||
addr := b.getValue(b.fn.Params[0], getPos(b.fn))
|
||||
b.createNilCheck(b.fn.Params[0], addr, "deref")
|
||||
valType := b.getLLVMType(b.fn.Params[0].Type().(*types.Pointer).Elem())
|
||||
val := b.CreateLoad(valType, addr, "")
|
||||
|
@ -21,8 +21,8 @@ func (b *builder) createVolatileLoad() {
|
|||
// runtime/volatile.StoreT().
|
||||
func (b *builder) createVolatileStore() {
|
||||
b.createFunctionStart(true)
|
||||
addr := b.getValue(b.fn.Params[0])
|
||||
val := b.getValue(b.fn.Params[1])
|
||||
addr := b.getValue(b.fn.Params[0], getPos(b.fn))
|
||||
val := b.getValue(b.fn.Params[1], getPos(b.fn))
|
||||
b.createNilCheck(b.fn.Params[0], addr, "deref")
|
||||
store := b.CreateStore(val, addr)
|
||||
store.SetVolatile(true)
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче