本文整理汇总了Golang中github.com/axw/gollvm/llvm.InsertBasicBlock函数的典型用法代码示例。如果您正苦于以下问题:Golang InsertBasicBlock函数的具体用法?Golang InsertBasicBlock怎么用?Golang InsertBasicBlock使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了InsertBasicBlock函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的Golang代码示例。
示例1: VisitIfStmt
func (c *compiler) VisitIfStmt(stmt *ast.IfStmt) {
currBlock := c.builder.GetInsertBlock()
resumeBlock := llvm.AddBasicBlock(currBlock.Parent(), "endif")
resumeBlock.MoveAfter(currBlock)
defer c.builder.SetInsertPointAtEnd(resumeBlock)
var ifBlock, elseBlock llvm.BasicBlock
if stmt.Else != nil {
elseBlock = llvm.InsertBasicBlock(resumeBlock, "else")
ifBlock = llvm.InsertBasicBlock(elseBlock, "if")
} else {
ifBlock = llvm.InsertBasicBlock(resumeBlock, "if")
}
if stmt.Else == nil {
elseBlock = resumeBlock
}
if stmt.Init != nil {
c.VisitStmt(stmt.Init)
}
cond_val := c.VisitExpr(stmt.Cond)
c.builder.CreateCondBr(cond_val.LLVMValue(), ifBlock, elseBlock)
c.builder.SetInsertPointAtEnd(ifBlock)
c.VisitBlockStmt(stmt.Body, false)
c.maybeImplicitBranch(resumeBlock)
if stmt.Else != nil {
c.builder.SetInsertPointAtEnd(elseBlock)
c.VisitStmt(stmt.Else)
c.maybeImplicitBranch(resumeBlock)
}
}
开发者ID:qioixiy,项目名称:llgo,代码行数:33,代码来源:stmt.go
示例2: convertI2V
// convertI2V converts an interface to a value.
func (v *LLVMValue) convertI2V(typ types.Type) (result, success Value) {
builder := v.compiler.builder
predicate := v.interfaceTypeEquals(typ).LLVMValue()
// If result is zero, then we've got a match.
end := llvm.InsertBasicBlock(builder.GetInsertBlock(), "end")
end.MoveAfter(builder.GetInsertBlock())
nonmatch := llvm.InsertBasicBlock(end, "nonmatch")
match := llvm.InsertBasicBlock(nonmatch, "match")
builder.CreateCondBr(predicate, match, nonmatch)
builder.SetInsertPointAtEnd(match)
matchResultValue := v.loadI2V(typ).LLVMValue()
builder.CreateBr(end)
builder.SetInsertPointAtEnd(nonmatch)
nonmatchResultValue := llvm.ConstNull(matchResultValue.Type())
builder.CreateBr(end)
builder.SetInsertPointAtEnd(end)
successValue := builder.CreatePHI(llvm.Int1Type(), "")
resultValue := builder.CreatePHI(matchResultValue.Type(), "")
successValues := []llvm.Value{llvm.ConstAllOnes(llvm.Int1Type()), llvm.ConstNull(llvm.Int1Type())}
successBlocks := []llvm.BasicBlock{match, nonmatch}
successValue.AddIncoming(successValues, successBlocks)
success = v.compiler.NewValue(successValue, types.Typ[types.Bool])
resultValues := []llvm.Value{matchResultValue, nonmatchResultValue}
resultBlocks := []llvm.BasicBlock{match, nonmatch}
resultValue.AddIncoming(resultValues, resultBlocks)
result = v.compiler.NewValue(resultValue, typ)
return result, success
}
开发者ID:hzmangel,项目名称:llgo,代码行数:35,代码来源:interfaces.go
示例3: compareI2V
func (lhs *LLVMValue) compareI2V(rhs *LLVMValue) Value {
c := lhs.compiler
predicate := lhs.interfaceTypeEquals(rhs.typ).LLVMValue()
end := llvm.InsertBasicBlock(c.builder.GetInsertBlock(), "end")
end.MoveAfter(c.builder.GetInsertBlock())
nonmatch := llvm.InsertBasicBlock(end, "nonmatch")
match := llvm.InsertBasicBlock(nonmatch, "match")
c.builder.CreateCondBr(predicate, match, nonmatch)
c.builder.SetInsertPointAtEnd(match)
lhsValue := lhs.loadI2V(rhs.typ)
matchResultValue := lhsValue.BinaryOp(token.EQL, rhs).LLVMValue()
c.builder.CreateBr(end)
c.builder.SetInsertPointAtEnd(nonmatch)
nonmatchResultValue := llvm.ConstNull(llvm.Int1Type())
c.builder.CreateBr(end)
c.builder.SetInsertPointAtEnd(end)
resultValue := c.builder.CreatePHI(matchResultValue.Type(), "")
resultValues := []llvm.Value{matchResultValue, nonmatchResultValue}
resultBlocks := []llvm.BasicBlock{match, nonmatch}
resultValue.AddIncoming(resultValues, resultBlocks)
return c.NewValue(resultValue, types.Typ[types.Bool])
}
开发者ID:hzmangel,项目名称:llgo,代码行数:26,代码来源:interfaces.go
示例4: VisitBlockStmt
func (c *compiler) VisitBlockStmt(stmt *ast.BlockStmt, createNewBlock bool) {
// This is a little awkward, but it makes dealing with branching easier.
// A free-standing block statement (i.e. one not attached to a control
// statement) will splice in a new block.
var doneBlock llvm.BasicBlock
if createNewBlock {
currBlock := c.builder.GetInsertBlock()
doneBlock = llvm.InsertBasicBlock(currBlock, "")
doneBlock.MoveAfter(currBlock)
newBlock := llvm.InsertBasicBlock(doneBlock, "")
c.builder.CreateBr(newBlock)
c.builder.SetInsertPointAtEnd(newBlock)
}
for _, stmt := range stmt.List {
c.VisitStmt(stmt)
if _, ok := stmt.(*ast.BranchStmt); ok {
// Ignore anything after a branch statement.
break
}
}
if createNewBlock {
c.maybeImplicitBranch(doneBlock)
c.builder.SetInsertPointAtEnd(doneBlock)
}
}
开发者ID:spate,项目名称:llgo,代码行数:27,代码来源:stmt.go
示例5: VisitBlockStmt
func (c *compiler) VisitBlockStmt(stmt *ast.BlockStmt, createNewBlock bool) {
// This is a little awkward, but it makes dealing with branching easier.
// A free-standing block statement (i.e. one not attached to a control
// statement) will splice in a new block.
var doneBlock llvm.BasicBlock
if createNewBlock {
currBlock := c.builder.GetInsertBlock()
doneBlock = llvm.InsertBasicBlock(currBlock, "")
doneBlock.MoveAfter(currBlock)
newBlock := llvm.InsertBasicBlock(doneBlock, "")
c.builder.CreateBr(newBlock)
c.builder.SetInsertPointAtEnd(newBlock)
}
// Visit each statement in the block. When we have a terminator,
// ignore everything until we get to a labeled statement.
for _, stmt := range stmt.List {
currBlock := c.builder.GetInsertBlock()
in := currBlock.LastInstruction()
if in.IsNil() || in.IsATerminatorInst().IsNil() {
c.VisitStmt(stmt)
} else if _, ok := stmt.(*ast.LabeledStmt); ok {
// FIXME we might end up with a labeled statement
// with no predecessors, due to dead code elimination.
c.VisitStmt(stmt)
}
}
if createNewBlock {
c.maybeImplicitBranch(doneBlock)
c.builder.SetInsertPointAtEnd(doneBlock)
}
}
开发者ID:hzmangel,项目名称:llgo,代码行数:33,代码来源:stmt.go
示例6: compileLogicalOp
// Binary logical operators are handled specially, outside of the Value
// type, because of the need to perform lazy evaluation.
//
// Binary logical operators are implemented using a Phi node, which takes
// on the appropriate value depending on which basic blocks branch to it.
func (c *compiler) compileLogicalOp(op token.Token, lhs Value, rhsFunc func() Value) Value {
lhsBlock := c.builder.GetInsertBlock()
resultBlock := llvm.AddBasicBlock(lhsBlock.Parent(), "")
resultBlock.MoveAfter(lhsBlock)
rhsBlock := llvm.InsertBasicBlock(resultBlock, "")
falseBlock := llvm.InsertBasicBlock(resultBlock, "")
if op == token.LOR {
c.builder.CreateCondBr(lhs.LLVMValue(), resultBlock, rhsBlock)
} else {
c.builder.CreateCondBr(lhs.LLVMValue(), rhsBlock, falseBlock)
}
c.builder.SetInsertPointAtEnd(rhsBlock)
rhs := rhsFunc()
rhsBlock = c.builder.GetInsertBlock() // rhsFunc may create blocks
c.builder.CreateCondBr(rhs.LLVMValue(), resultBlock, falseBlock)
c.builder.SetInsertPointAtEnd(falseBlock)
c.builder.CreateBr(resultBlock)
c.builder.SetInsertPointAtEnd(resultBlock)
result := c.builder.CreatePHI(llvm.Int1Type(), "")
trueValue := llvm.ConstAllOnes(llvm.Int1Type())
falseValue := llvm.ConstNull(llvm.Int1Type())
var values []llvm.Value
var blocks []llvm.BasicBlock
if op == token.LOR {
values = []llvm.Value{trueValue, trueValue, falseValue}
blocks = []llvm.BasicBlock{lhsBlock, rhsBlock, falseBlock}
} else {
values = []llvm.Value{trueValue, falseValue}
blocks = []llvm.BasicBlock{rhsBlock, falseBlock}
}
result.AddIncoming(values, blocks)
return c.NewLLVMValue(result, types.Bool)
}
开发者ID:kisielk,项目名称:llgo,代码行数:40,代码来源:expr.go
示例7: VisitForStmt
func (c *compiler) VisitForStmt(stmt *ast.ForStmt) {
currBlock := c.builder.GetInsertBlock()
doneBlock := llvm.AddBasicBlock(currBlock.Parent(), "done")
doneBlock.MoveAfter(currBlock)
loopBlock := llvm.InsertBasicBlock(doneBlock, "loop")
defer c.builder.SetInsertPointAtEnd(doneBlock)
condBlock := loopBlock
if stmt.Cond != nil {
condBlock = llvm.InsertBasicBlock(loopBlock, "cond")
}
postBlock := condBlock
if stmt.Post != nil {
postBlock = llvm.InsertBasicBlock(doneBlock, "post")
}
if c.lastlabel != nil {
labelData := c.labelData(c.lastlabel)
labelData.Break = doneBlock
labelData.Continue = postBlock
c.lastlabel = nil
}
c.breakblocks = append(c.breakblocks, doneBlock)
c.continueblocks = append(c.continueblocks, postBlock)
defer func() {
c.breakblocks = c.breakblocks[:len(c.breakblocks)-1]
c.continueblocks = c.continueblocks[:len(c.continueblocks)-1]
}()
// Is there an initializer? Create a new scope and visit the statement.
if stmt.Init != nil {
c.VisitStmt(stmt.Init)
}
// Start the loop.
if stmt.Cond != nil {
c.builder.CreateBr(condBlock)
c.builder.SetInsertPointAtEnd(condBlock)
condVal := c.VisitExpr(stmt.Cond)
c.builder.CreateCondBr(condVal.LLVMValue(), loopBlock, doneBlock)
} else {
c.builder.CreateBr(loopBlock)
}
// Post.
if stmt.Post != nil {
c.builder.SetInsertPointAtEnd(postBlock)
c.VisitStmt(stmt.Post)
c.builder.CreateBr(condBlock)
}
// Loop body.
c.builder.SetInsertPointAtEnd(loopBlock)
c.VisitBlockStmt(stmt.Body, false)
c.maybeImplicitBranch(postBlock)
}
开发者ID:dtcaciuc,项目名称:llgo,代码行数:58,代码来源:stmt.go
示例8: mustConvertI2V
func (v *LLVMValue) mustConvertI2V(typ types.Type) Value {
result, ok := v.convertI2V(typ)
c, builder := v.compiler, v.compiler.builder
end := llvm.InsertBasicBlock(builder.GetInsertBlock(), "end")
end.MoveAfter(builder.GetInsertBlock())
failed := llvm.InsertBasicBlock(end, "failed")
builder.CreateCondBr(ok.LLVMValue(), end, failed)
builder.SetInsertPointAtEnd(failed)
s := fmt.Sprintf("convertI2V(%s, %s) failed", v.typ, typ)
c.visitPanic(c.NewConstValue(exact.MakeString(s), types.Typ[types.String]))
builder.SetInsertPointAtEnd(end)
return result
}
开发者ID:hzmangel,项目名称:llgo,代码行数:15,代码来源:interfaces.go
示例9: mustConvertI2I
func (v *LLVMValue) mustConvertI2I(iface *types.Interface) Value {
result, ok := v.convertI2I(iface)
c, builder := v.compiler, v.compiler.builder
end := llvm.InsertBasicBlock(builder.GetInsertBlock(), "end")
end.MoveAfter(builder.GetInsertBlock())
failed := llvm.InsertBasicBlock(end, "failed")
builder.CreateCondBr(ok.LLVMValue(), end, failed)
builder.SetInsertPointAtEnd(failed)
s := fmt.Sprintf("convertI2I(%s, %s) failed", v.typ, iface)
c.visitPanic(c.NewConstValue(token.STRING, strconv.Quote(s)))
builder.SetInsertPointAtEnd(end)
return result
}
开发者ID:kelsieflynn,项目名称:llgo,代码行数:15,代码来源:interfaces.go
示例10: VisitIfStmt
func (c *compiler) VisitIfStmt(stmt *ast.IfStmt) {
curr_block := c.builder.GetInsertBlock()
resume_block := llvm.AddBasicBlock(curr_block.Parent(), "endif")
resume_block.MoveAfter(curr_block)
var if_block, else_block llvm.BasicBlock
if stmt.Else != nil {
else_block = llvm.InsertBasicBlock(resume_block, "else")
if_block = llvm.InsertBasicBlock(else_block, "if")
} else {
if_block = llvm.InsertBasicBlock(resume_block, "if")
}
if stmt.Else == nil {
else_block = resume_block
}
if stmt.Init != nil {
c.PushScope()
c.VisitStmt(stmt.Init)
defer c.PopScope()
}
cond_val := c.VisitExpr(stmt.Cond)
c.builder.CreateCondBr(cond_val.LLVMValue(), if_block, else_block)
c.builder.SetInsertPointAtEnd(if_block)
c.VisitBlockStmt(stmt.Body)
if in := if_block.LastInstruction(); in.IsNil() || in.IsATerminatorInst().IsNil() {
c.builder.CreateBr(resume_block)
}
if stmt.Else != nil {
c.builder.SetInsertPointAtEnd(else_block)
c.VisitStmt(stmt.Else)
if in := else_block.LastInstruction(); in.IsNil() || in.IsATerminatorInst().IsNil() {
c.builder.CreateBr(resume_block)
}
}
// If there's a block after the "resume" block (i.e. a nested control
// statement), then create a branch to it as the last instruction.
c.builder.SetInsertPointAtEnd(resume_block)
if last := resume_block.Parent().LastBasicBlock(); last != resume_block {
c.builder.CreateBr(last)
c.builder.SetInsertPointBefore(resume_block.FirstInstruction())
}
}
开发者ID:prattmic,项目名称:llgo,代码行数:46,代码来源:stmt.go
示例11: VisitForStmt
func (c *compiler) VisitForStmt(stmt *ast.ForStmt) {
currBlock := c.builder.GetInsertBlock()
doneBlock := llvm.AddBasicBlock(currBlock.Parent(), "done")
doneBlock.MoveAfter(currBlock)
loopBlock := llvm.InsertBasicBlock(doneBlock, "loop")
defer c.builder.SetInsertPointAtEnd(doneBlock)
condBlock := loopBlock
if stmt.Cond != nil {
condBlock = llvm.InsertBasicBlock(loopBlock, "cond")
}
postBlock := condBlock
if stmt.Post != nil {
postBlock = llvm.InsertBasicBlock(doneBlock, "post")
}
// Is there an initializer? Create a new scope and visit the statement.
if stmt.Init != nil {
c.PushScope()
c.VisitStmt(stmt.Init)
defer c.PopScope()
}
// Start the loop.
if stmt.Cond != nil {
c.builder.CreateBr(condBlock)
c.builder.SetInsertPointAtEnd(condBlock)
condVal := c.VisitExpr(stmt.Cond)
c.builder.CreateCondBr(condVal.LLVMValue(), loopBlock, doneBlock)
} else {
c.builder.CreateBr(loopBlock)
}
// Post.
if stmt.Post != nil {
c.builder.SetInsertPointAtEnd(postBlock)
c.VisitStmt(stmt.Post)
c.builder.CreateBr(condBlock)
}
// Loop body.
c.builder.SetInsertPointAtEnd(loopBlock)
c.VisitBlockStmt(stmt.Body)
c.maybeImplicitBranch(postBlock)
}
开发者ID:c0der007,项目名称:llgo,代码行数:46,代码来源:stmt.go
示例12: convertI2V
// convertI2V converts an interface to a value.
func (v *LLVMValue) convertI2V(typ types.Type) (result, success Value) {
typptrType := llvm.PointerType(llvm.Int8Type(), 0)
runtimeType := v.compiler.types.ToRuntime(typ)
runtimeType = llvm.ConstBitCast(runtimeType, typptrType)
vval := v.LLVMValue()
builder := v.compiler.builder
ifaceType := builder.CreateExtractValue(vval, 0, "")
diff := builder.CreatePtrDiff(runtimeType, ifaceType, "")
zero := llvm.ConstNull(diff.Type())
predicate := builder.CreateICmp(llvm.IntEQ, diff, zero, "")
// If result is zero, then we've got a match.
end := llvm.InsertBasicBlock(builder.GetInsertBlock(), "end")
end.MoveAfter(builder.GetInsertBlock())
nonmatch := llvm.InsertBasicBlock(end, "nonmatch")
match := llvm.InsertBasicBlock(nonmatch, "match")
builder.CreateCondBr(predicate, match, nonmatch)
builder.SetInsertPointAtEnd(match)
matchResultValue := v.loadI2V(typ).LLVMValue()
builder.CreateBr(end)
builder.SetInsertPointAtEnd(nonmatch)
nonmatchResultValue := llvm.ConstNull(matchResultValue.Type())
builder.CreateBr(end)
builder.SetInsertPointAtEnd(end)
successValue := builder.CreatePHI(llvm.Int1Type(), "")
resultValue := builder.CreatePHI(matchResultValue.Type(), "")
successValues := []llvm.Value{llvm.ConstAllOnes(llvm.Int1Type()), llvm.ConstNull(llvm.Int1Type())}
successBlocks := []llvm.BasicBlock{match, nonmatch}
successValue.AddIncoming(successValues, successBlocks)
success = v.compiler.NewLLVMValue(successValue, types.Bool)
resultValues := []llvm.Value{matchResultValue, nonmatchResultValue}
resultBlocks := []llvm.BasicBlock{match, nonmatch}
resultValue.AddIncoming(resultValues, resultBlocks)
result = v.compiler.NewLLVMValue(resultValue, typ)
return result, success
}
开发者ID:kisielk,项目名称:llgo,代码行数:43,代码来源:interfaces.go
示例13: getBoolString
func (c *compiler) getBoolString(v llvm.Value) llvm.Value {
startBlock := c.builder.GetInsertBlock()
resultBlock := llvm.InsertBasicBlock(startBlock, "")
resultBlock.MoveAfter(startBlock)
falseBlock := llvm.InsertBasicBlock(resultBlock, "")
CharPtr := llvm.PointerType(llvm.Int8Type(), 0)
falseString := c.builder.CreateGlobalStringPtr("false", "")
falseString = c.builder.CreateBitCast(falseString, CharPtr, "")
trueString := c.builder.CreateGlobalStringPtr("true", "")
trueString = c.builder.CreateBitCast(trueString, CharPtr, "")
c.builder.CreateCondBr(v, resultBlock, falseBlock)
c.builder.SetInsertPointAtEnd(falseBlock)
c.builder.CreateBr(resultBlock)
c.builder.SetInsertPointAtEnd(resultBlock)
result := c.builder.CreatePHI(CharPtr, "")
result.AddIncoming([]llvm.Value{trueString, falseString},
[]llvm.BasicBlock{startBlock, falseBlock})
return result
}
开发者ID:hzmangel,项目名称:llgo,代码行数:21,代码来源:println.go
示例14: convertI2V
// convertI2V converts an interface to a value.
func (v *LLVMValue) convertI2V(typ types.Type) Value {
typptrType := llvm.PointerType(llvm.Int8Type(), 0)
runtimeType := v.compiler.types.ToRuntime(typ)
runtimeType = llvm.ConstBitCast(runtimeType, typptrType)
vptr := v.pointer.LLVMValue()
builder := v.compiler.builder
ifaceType := builder.CreateLoad(builder.CreateStructGEP(vptr, 1, ""), "")
diff := builder.CreatePtrDiff(runtimeType, ifaceType, "")
zero := llvm.ConstNull(diff.Type())
predicate := builder.CreateICmp(llvm.IntEQ, diff, zero, "")
llvmtype := v.compiler.types.ToLLVM(typ)
result := builder.CreateAlloca(llvmtype, "")
// If result is zero, then we've got a match.
end := llvm.InsertBasicBlock(builder.GetInsertBlock(), "end")
end.MoveAfter(builder.GetInsertBlock())
nonmatch := llvm.InsertBasicBlock(end, "nonmatch")
match := llvm.InsertBasicBlock(nonmatch, "match")
builder.CreateCondBr(predicate, match, nonmatch)
builder.SetInsertPointAtEnd(match)
value := builder.CreateLoad(builder.CreateStructGEP(vptr, 0, ""), "")
value = builder.CreateBitCast(value, result.Type(), "")
value = builder.CreateLoad(value, "")
builder.CreateStore(value, result)
builder.CreateBr(end)
// TODO should return {value, ok}
builder.SetInsertPointAtEnd(nonmatch)
builder.CreateStore(llvm.ConstNull(llvmtype), result)
builder.CreateBr(end)
//builder.SetInsertPointAtEnd(end)
result = builder.CreateLoad(result, "")
return v.compiler.NewLLVMValue(result, typ)
}
开发者ID:prattmic,项目名称:llgo,代码行数:38,代码来源:interfaces.go
示例15: VisitRangeStmt
func (c *compiler) VisitRangeStmt(stmt *ast.RangeStmt) {
currBlock := c.builder.GetInsertBlock()
doneBlock := llvm.AddBasicBlock(currBlock.Parent(), "done")
doneBlock.MoveAfter(currBlock)
postBlock := llvm.InsertBasicBlock(doneBlock, "post")
loopBlock := llvm.InsertBasicBlock(postBlock, "loop")
condBlock := llvm.InsertBasicBlock(loopBlock, "cond")
defer c.builder.SetInsertPointAtEnd(doneBlock)
// Evaluate range expression first.
x := c.VisitExpr(stmt.X)
// If it's a pointer type, we'll first check that it's non-nil.
typ := types.Underlying(x.Type())
if _, ok := typ.(*types.Pointer); ok {
ifBlock := llvm.InsertBasicBlock(doneBlock, "if")
isnotnull := c.builder.CreateIsNotNull(x.LLVMValue(), "")
c.builder.CreateCondBr(isnotnull, ifBlock, doneBlock)
c.builder.SetInsertPointAtEnd(ifBlock)
}
// Is it a new var definition? Then allocate some memory on the stack.
var keyType, valueType types.Type
var keyPtr, valuePtr llvm.Value
if stmt.Tok == token.DEFINE {
if key := stmt.Key.(*ast.Ident); key.Name != "_" {
keyType = key.Obj.Type.(types.Type)
keyPtr = c.builder.CreateAlloca(c.types.ToLLVM(keyType), "")
key.Obj.Data = c.NewLLVMValue(keyPtr, &types.Pointer{Base: keyType}).makePointee()
}
if stmt.Value != nil {
if value := stmt.Value.(*ast.Ident); value.Name != "_" {
valueType = value.Obj.Type.(types.Type)
valuePtr = c.builder.CreateAlloca(c.types.ToLLVM(valueType), "")
value.Obj.Data = c.NewLLVMValue(valuePtr, &types.Pointer{Base: valueType}).makePointee()
}
}
}
c.breakblocks = append(c.breakblocks, doneBlock)
c.continueblocks = append(c.continueblocks, postBlock)
defer func() {
c.breakblocks = c.breakblocks[:len(c.breakblocks)-1]
c.continueblocks = c.continueblocks[:len(c.continueblocks)-1]
}()
isarray := false
var base, length llvm.Value
_, isptr := typ.(*types.Pointer)
if isptr {
typ = typ.(*types.Pointer).Base
}
switch typ := types.Underlying(typ).(type) {
case *types.Map:
goto maprange
case *types.Name:
stringvalue := x.LLVMValue()
length = c.builder.CreateExtractValue(stringvalue, 1, "")
goto stringrange
case *types.Array:
isarray = true
x := x
if !isptr {
if x_, ok := x.(*LLVMValue); ok && x_.pointer != nil {
x = x_.pointer
} else {
// TODO load value onto stack for indexing?
}
}
base = x.LLVMValue()
length = llvm.ConstInt(llvm.Int32Type(), typ.Len, false)
goto arrayrange
case *types.Slice:
slicevalue := x.LLVMValue()
base = c.builder.CreateExtractValue(slicevalue, 0, "")
length = c.builder.CreateExtractValue(slicevalue, 1, "")
goto arrayrange
}
maprange:
{
currBlock = c.builder.GetInsertBlock()
c.builder.CreateBr(condBlock)
c.builder.SetInsertPointAtEnd(condBlock)
nextptrphi := c.builder.CreatePHI(c.target.IntPtrType(), "next")
nextptr, pk, pv := c.mapNext(x.(*LLVMValue), nextptrphi)
notnull := c.builder.CreateIsNotNull(nextptr, "")
c.builder.CreateCondBr(notnull, loopBlock, doneBlock)
c.builder.SetInsertPointAtEnd(loopBlock)
if !keyPtr.IsNil() {
keyval := c.builder.CreateLoad(pk, "")
c.builder.CreateStore(keyval, keyPtr)
}
if !valuePtr.IsNil() {
valval := c.builder.CreateLoad(pv, "")
c.builder.CreateStore(valval, valuePtr)
}
c.VisitBlockStmt(stmt.Body, false)
c.maybeImplicitBranch(postBlock)
c.builder.SetInsertPointAtEnd(postBlock)
//.........这里部分代码省略.........
开发者ID:kisielk,项目名称:llgo,代码行数:101,代码来源:stmt.go
示例16: createCall
// createCall emits the code for a function call, taking into account
// variadic functions, receivers, and panic/defer.
//
// dotdotdot is true if the last argument is followed with "...".
func (c *compiler) createCall(fn *LLVMValue, argValues []Value, dotdotdot, invoke bool) *LLVMValue {
fn_type := fn.Type().Underlying().(*types.Signature)
var args []llvm.Value
// TODO Move all of this to evalCallArgs?
params := fn_type.Params()
if nparams := int(params.Len()); nparams > 0 {
if fn_type.IsVariadic() {
nparams--
}
for i := 0; i < nparams; i++ {
value := argValues[i]
args = append(args, value.LLVMValue())
}
if fn_type.IsVariadic() {
if dotdotdot {
// Calling f(x...). Just pass the slice directly.
slice_value := argValues[nparams].LLVMValue()
args = append(args, slice_value)
} else {
varargs := make([]llvm.Value, len(argValues)-nparams)
for i, value := range argValues[nparams:] {
varargs[i] = value.LLVMValue()
}
param_type := params.At(nparams).Type().(*types.Slice).Elem()
slice_value := c.makeLiteralSlice(varargs, param_type)
args = append(args, slice_value)
}
}
}
var result_type types.Type
switch results := fn_type.Results(); results.Len() {
case 0: // no-op
case 1:
result_type = results.At(0).Type()
default:
result_type = results
}
// Depending on whether the function contains defer statements or not,
// we'll generate either a "call" or an "invoke" instruction.
var createCall = c.builder.CreateCall
if invoke {
f := c.functions.top()
// TODO Create a method on compiler (avoid creating closures).
createCall = func(fn llvm.Value, args []llvm.Value, name string) llvm.Value {
currblock := c.builder.GetInsertBlock()
returnblock := llvm.AddBasicBlock(currblock.Parent(), "")
returnblock.MoveAfter(currblock)
value := c.builder.CreateInvoke(fn, args, returnblock, f.unwindblock, "")
c.builder.SetInsertPointAtEnd(returnblock)
return value
}
}
var fnptr llvm.Value
fnval := fn.LLVMValue()
if fnval.Type().TypeKind() == llvm.PointerTypeKind {
fnptr = fnval
} else {
fnptr = c.builder.CreateExtractValue(fnval, 0, "")
context := c.builder.CreateExtractValue(fnval, 1, "")
fntyp := fnptr.Type().ElementType()
paramTypes := fntyp.ParamTypes()
// If the context is not a constant null, and we're not
// dealing with a method (where we don't care about the value
// of the receiver), then we must conditionally call the
// function with the additional receiver/closure.
if !context.IsNull() || fn_type.Recv() != nil {
// Store the blocks for referencing in the Phi below;
// note that we update the block after each createCall,
// since createCall may create new blocks and we want
// the predecessors to the Phi.
var nullctxblock llvm.BasicBlock
var nonnullctxblock llvm.BasicBlock
var endblock llvm.BasicBlock
var nullctxresult llvm.Value
// len(paramTypes) == len(args) iff function is not a method.
if !context.IsConstant() && len(paramTypes) == len(args) {
currblock := c.builder.GetInsertBlock()
endblock = llvm.AddBasicBlock(currblock.Parent(), "")
endblock.MoveAfter(currblock)
nonnullctxblock = llvm.InsertBasicBlock(endblock, "")
nullctxblock = llvm.InsertBasicBlock(nonnullctxblock, "")
nullctx := c.builder.CreateIsNull(context, "")
c.builder.CreateCondBr(nullctx, nullctxblock, nonnullctxblock)
// null context case.
c.builder.SetInsertPointAtEnd(nullctxblock)
nullctxresult = createCall(fnptr, args, "")
nullctxblock = c.builder.GetInsertBlock()
c.builder.CreateBr(endblock)
c.builder.SetInsertPointAtEnd(nonnullctxblock)
//.........这里部分代码省略.........
开发者ID:quarnster,项目名称:llgo,代码行数:101,代码来源:expr.go
示例17: VisitTypeSwitchStmt
func (c *compiler) VisitTypeSwitchStmt(stmt *ast.TypeSwitchStmt) {
if stmt.Init != nil {
c.VisitStmt(stmt.Init)
}
var assignIdent *ast.Ident
var typeAssertExpr *ast.TypeAssertExpr
switch stmt := stmt.Assign.(type) {
case *ast.AssignStmt:
assignIdent = stmt.Lhs[0].(*ast.Ident)
typeAssertExpr = stmt.Rhs[0].(*ast.TypeAssertExpr)
case *ast.ExprStmt:
typeAssertExpr = stmt.X.(*ast.TypeAssertExpr)
}
if len(stmt.Body.List) == 0 {
// No case clauses, so just evaluate the expression.
c.VisitExpr(typeAssertExpr.X)
return
}
currBlock := c.builder.GetInsertBlock()
endBlock := llvm.AddBasicBlock(currBlock.Parent(), "")
endBlock.MoveAfter(currBlock)
defer c.builder.SetInsertPointAtEnd(endBlock)
// Add a "break" block to the stack.
c.breakblocks = append(c.breakblocks, endBlock)
defer func() { c.breakblocks = c.breakblocks[:len(c.breakblocks)-1] }()
// TODO: investigate the use of a switch instruction
// on the type's hash (when we compute type hashes).
// Create blocks for each statement.
defaultBlock := endBlock
var condBlocks []llvm.BasicBlock
var stmtBlocks []llvm.BasicBlock
for _, stmt := range stmt.Body.List {
caseClause := stmt.(*ast.CaseClause)
if caseClause.List == nil {
defaultBlock = llvm.InsertBasicBlock(endBlock, "")
} else {
condBlock := llvm.InsertBasicBlock(endBlock, "")
stmtBlock := llvm.InsertBasicBlock(endBlock, "")
condBlocks = append(condBlocks, condBlock)
stmtBlocks = append(stmtBlocks, stmtBlock)
}
}
stmtBlocks = append(stmtBlocks, defaultBlock)
// Evaluate the expression, then jump to the first condition block.
iface := c.VisitExpr(typeAssertExpr.X).(*LLVMValue)
typptr := c.builder.CreateExtractValue(iface.LLVMValue(), 0, "")
typptr = c.builder.CreatePtrToInt(typptr, c.target.IntPtrType(), "")
if len(stmt.Body.List) == 1 && defaultBlock != endBlock {
c.builder.CreateBr(defaultBlock)
} else {
c.builder.CreateBr(condBlocks[0])
}
i := 0
for _, stmt := range stmt.Body.List {
caseClause := stmt.(*ast.CaseClause)
if caseClause.List != nil {
c.builder.SetInsertPointAtEnd(condBlocks[i])
stmtBlock := stmtBlocks[i]
nextCondBlock := defaultBlock
if i+1 < len(condBlocks) {
nextCondBlock = condBlocks[i+1]
}
// TODO handle multiple types
// TODO use runtime type equality function
if len(caseClause.List) > 1 {
panic("unimplemented")
}
var cond llvm.Value
if isNilIdent(caseClause.List[0]) {
cond = c.builder.CreateIsNull(typptr, "")
} else {
typ := c.types.expr[caseClause.List[0]]
check := c.types.ToRuntime(typ)
check = c.builder.CreatePtrToInt(check, c.target.IntPtrType(), "")
cond = c.builder.CreateICmp(llvm.IntEQ, typptr, check, "")
}
c.builder.CreateCondBr(cond, stmtBlock, nextCondBlock)
i++
}
}
i = 0
for _, stmt := range stmt.Body.List {
caseClause := stmt.(*ast.CaseClause)
var block llvm.BasicBlock
var typ types.Type
if caseClause.List != nil {
block = stmtBlocks[i]
if len(caseClause.List) == 1 {
typ = c.types.expr[caseClause.List[0]]
}
i++
} else {
//.........这里部分代码省略.........
开发者ID:kisielk,项目名称:llgo,代码行数:101,代码来源:stmt.go
示例18: VisitSelectStmt
func (c *compiler) VisitSelectStmt(stmt *ast.SelectStmt) {
// TODO optimisations:
// 1. No clauses: runtime.block.
// 2. Single recv, and default clause: runtime.selectnbrecv
// 2. Single send, and default clause: runtime.selectnbsend
startBlock := c.builder.GetInsertBlock()
function := startBlock.Parent()
endBlock := llvm.AddBasicBlock(function, "end")
endBlock.MoveAfter(startBlock)
defer c.builder.SetInsertPointAtEnd(endBlock)
// Cache runtime functions
var selectrecv, selectsend llvm.Value
getselectsend := func() llvm.Value {
if selectsend.IsNil() {
selectsend = c.NamedFunction("runtime.selectsend", "func(selectp, blockaddr, ch, elem unsafe.Pointer)")
}
return selectsend
}
getselectrecv := func() llvm.Value {
if selectrecv.IsNil() {
selectrecv = c.NamedFunction("runtime.selectrecv", "func(selectp, blockaddr, ch, elem unsafe.Pointer, received *bool)")
}
return selectrecv
}
// We create a pointer-pointer for each newly defined var on the
// lhs of receive expressions, which will be assigned to when the
// expressions are (conditionally) evaluated.
lhsptrs := make([][]llvm.Value, len(stmt.Body.List))
for i, stmt := range stmt.Body.List {
clause := stmt.(*ast.CommClause)
if stmt, ok := clause.Comm.(*ast.AssignStmt); ok && stmt.Tok == token.DEFINE {
lhs := make([]llvm.Value, len(stmt.Lhs))
for i, expr := range stmt.Lhs {
ident := expr.(*ast.Ident)
if !isBlank(ident.Name) {
typ := c.target.IntPtrType()
lhs[i] = c.builder.CreateAlloca(typ, "")
c.builder.CreateStore(llvm.ConstNull(typ), lhs[i])
}
}
lhsptrs[i] = lhs
}
}
// Create clause basic blocks.
blocks := make([]llvm.BasicBlock, len(stmt.Body.List))
var basesize uint64
for i, stmt := range stmt.Body.List {
clause := stmt.(*ast.CommClause)
if clause.Comm == nil {
basesize++
}
currBlock := c.builder.GetInsertBlock()
block := llvm.InsertBasicBlock(endBlock, "")
c.builder.SetInsertPointAtEnd(block)
blocks[i] = block
lhs := lhsptrs[i]
if stmt, ok := clause.Comm.(*ast.AssignStmt); ok {
for i, expr := range stmt.Lhs {
ident := expr.(*ast.Ident)
if !isBlank(ident.Name) {
ptr := c.builder.CreateLoad(lhs[i], "")
obj := c.typeinfo.Objects[ident]
ptrtyp := types.NewPointer(obj.Type())
ptr = c.builder.CreateIntToPtr(ptr, c.types.ToLLVM(ptrtyp), "")
value := c.NewValue(ptr, ptrtyp).makePointee()
c.objectdata[obj].Value = value
}
}
}
for _, stmt := range clause.Body {
c.VisitStmt(stmt)
}
c.maybeImplicitBranch(endBlock)
c.builder.SetInsertPointAtEnd(currBlock)
}
// We need to make an initial pass through the cases,
// discarding those where the channel is nil.
size := llvm.ConstInt(llvm.Int32Type(), basesize, false)
channels := make([]Value, len(stmt.Body.List))
rhs := make([]*LLVMValue, len(stmt.Body.List))
for i, stmt := range stmt.Body.List {
clause := stmt.(*ast.CommClause)
switch comm := clause.Comm.(type) {
case nil:
case *ast.SendStmt:
channels[i] = c.VisitExpr(comm.Chan)
rhs[i] = c.VisitExpr(comm.Value).(*LLVMValue)
case *ast.ExprStmt:
channels[i] = c.VisitExpr(comm.X.(*ast.UnaryExpr).X)
case *ast.AssignStmt:
channels[i] = c.VisitExpr(comm.Rhs[0].(*ast.UnaryExpr).X)
default:
panic(fmt.Errorf("unhandled: %T", comm))
}
if channels[i] != nil {
//.........这里部分代码省略.........
开发者ID:quarnster,项目名称:llgo,代码行数:101,代码来源:channels.go
示例19: VisitSwitchStmt
func (c *compiler) VisitSwitchStmt(stmt *ast.SwitchStmt) {
if stmt.Init != nil {
c.VisitStmt(stmt.Init)
}
var tag Value
if stmt.Tag != nil {
tag = c.VisitExpr(stmt.Tag)
} else {
True := types.Universe.Lookup("true")
tag = c.Resolve(True)
}
if len(stmt.Body.List) == 0 {
return
}
// makeValueFunc takes an expression, evaluates it, and returns
// a Value representing its equality comparison with the tag.
makeValueFunc := func(expr ast.Expr) func() Value {
return func() Value {
return c.VisitExpr(expr).BinaryOp(token.EQL, tag)
}
}
// Create a BasicBlock for each case clause and each associated
// statement body. Each case clause will branch to either its
// statement body (success) or to the next case (failure), or the
// end block if there are no remaining cases.
startBlock := c.builder.GetInsertBlock()
endBlock := llvm.AddBasicBlock(startBlock.Parent(), "end")
endBlock.MoveAfter(startBlock)
defer c.builder.SetInsertPointAtEnd(endBlock)
// Add a "break" block to the stack.
c.breakblocks = append(c.breakblocks, endBlock)
defer func() { c.breakblocks = c.breakblocks[:len(c.breakblocks)-1] }()
caseBlocks := make([]llvm.BasicBlock, 0, len(stmt.Body.List))
stmtBlocks := make([]llvm.BasicBlock, 0, len(stmt.Body.List))
for _ = range stmt.Body.List {
caseBlocks = append(caseBlocks, llvm.InsertBasicBlock(endBlock, ""))
}
for _ = range stmt.Body.List {
stmtBlocks = append(stmtBlocks, llvm.InsertBasicBlock(endBlock, ""))
}
c.builder.CreateBr(caseBlocks[0])
for i, stmt := range stmt.Body.List {
c.builder.SetInsertPointAtEnd(caseBlocks[i])
stmtBlock := stmtBlocks[i]
nextBlock := endBlock
if i+1 < len(caseBlocks) {
nextBlock = caseBlocks[i+1]
}
clause := stmt.(*ast.CaseClause)
if clause.List != nil {
value := c.VisitExpr(clause.List[0])
result := value.BinaryOp(token.EQL, tag)
for _, expr := range clause.List[1:] {
rhsResultFunc := makeValueFunc(expr)
result = c.compileLogicalOp(token.LOR, result, rhsResultFunc)
}
c.builder.CreateCondBr(result.LLVMValue(), stmtBlock, nextBlock)
} else {
// default case
c.builder.CreateBr(stmtBlock)
}
c.builder.SetInsertPointAtEnd(stmtBlock)
branchBlock := endBlock
for _, stmt := range clause.Body {
if br, isbr := stmt.(*ast.BranchStmt); isbr {
if br.Tok == token.FALLTHROUGH {
if i+1 < len(stmtBlocks) {
branchBlock = stmtBlocks[i+1]
}
} else {
c.VisitStmt(stmt)
}
// Ignore anything after a branch statement.
break
} else {
c.VisitStmt(stmt)
}
}
c.maybeImplicitBranch(branchBlock)
}
}
开发者ID:kisielk,项目名称:llgo,代码行数:89,代码来源:stmt.go
示例20: VisitTypeSwitchStmt
func (c *compiler) VisitTypeSwitchStmt(stmt *ast.TypeSwitchStmt) {
if stmt.Init != nil {
c.VisitStmt(stmt.Init)
}
var assignIdent *ast.Ident
var typeAssertExpr *ast.TypeAssertExpr
switch stmt := stmt.Assign.(type) {
case *ast.AssignStmt:
assignIdent = stmt.Lhs[0].(*ast.Ident)
typeAssertExpr = stmt.Rhs[0].(*ast.TypeAssertExpr)
case *ast.ExprStmt:
typeAssertExpr = stmt.X.(*ast.TypeAssertExpr)
}
if len(stmt.Body.List) == 0 {
// No case clauses, so just evaluate the expression.
c.VisitExpr(typeAssertExpr.X)
return
}
currBlock := c.builder.GetInsertBlock()
endBlock := llvm.AddBasicBlock(currBlock.Parent(), "")
endBlock.MoveAfter(currBlock)
defer c.builder.SetInsertPointAtEnd(endBlock)
// Add a "break" block to the stack.
c.breakblocks = append(c.breakblocks, endBlock)
defer func() { c.breakblocks = c.breakblocks[:len(c.breakblocks)-1] }()
// TODO: investigate the use of a switch instruction
// on the type's hash (when we compute type hashes).
// Create blocks for each statement.
defaultBlock := endBlock
var condBlocks []llvm.BasicBlock
var stmtBlocks []llvm.BasicBlock
for _, stmt := range stmt.Body.List {
caseClause := stmt.(*ast.CaseClause)
if caseClause.List == nil {
defaultBlock = llvm.InsertBasicBlock(endBlock, "")
} else {
condBlock := llvm.InsertBasicBlock(endBlock, "")
stmtBlock := llvm.InsertBasicBlock(endBlock, "")
condBlocks = append(condBlocks, condBlock)
stmtBlocks = append(stmtBlocks, stmtBlock)
}
}
stmtBlocks = append(stmtBlocks, defaultBlock)
// Evaluate the expression, then jump to the first condition block.
iface := c.VisitExpr(typeAssertExpr.X).(*LLVMValue)
if len(stmt.Body.List) == 1 && defaultBlock != endBlock {
c.builder.CreateBr(defaultBlock)
} else {
c.builder.CreateBr(condBlocks[0])
}
i := 0
for _, stmt := range stmt.Body.List {
caseClause := stmt.(*ast.CaseClause)
if caseClause.List != nil {
c.builder.SetInsertPointAtEnd(condBlocks[i])
stmtBlock := stmtBlocks[i]
nextCondBlock := defaultBlock
if i+1 < len(condBlocks) {
nextCondBlock = condBlocks[i+1]
}
caseCond := func(j int) Value {
if c.isNilIdent(caseClause.List[j]) {
iface := iface.LLVMValue()
ifacetyp := c.builder.CreateExtractValue(iface, 0, "")
isnil := c.builder.CreateIsNull(ifacetyp, "")
return c.NewValue(isnil, types.Typ[types.Bool])
}
typ := c.typeinfo.Types[caseClause.List[j]]
switch typ := typ.Underlying().(type) {
case *types.Interface:
_, ok := iface.convertI2I(typ)
return ok
}
return iface.interfaceTypeEquals(typ)
}
cond := caseCond(0)
for j := 1; j < len(caseClause.List); j++ {
f := func() Value {
return caseCond(j)
}
cond = c.compileLogicalOp(token.LOR
|
请发表评论