本文整理汇总了Golang中github.com/axw/gollvm/llvm.BasicBlock.MoveAfter方法的典型用法代码示例。如果您正苦于以下问题:Golang BasicBlock.MoveAfter方法的具体用法?Golang BasicBlock.MoveAfter怎么用?Golang BasicBlock.MoveAfter使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类github.com/axw/gollvm/llvm.BasicBlock
的用法示例。
在下文中一共展示了BasicBlock.MoveAfter方法的3个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: 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)
}
}
示例2: 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)
}
}
示例3: 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)
//.........这里部分代码省略.........