Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions IRBindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"

Expand Down Expand Up @@ -50,6 +51,11 @@ void LLVMSetMetadata2(LLVMValueRef Inst, unsigned KindID, LLVMMetadataRef MD) {
unwrap<Instruction>(Inst)->setMetadata(KindID, N);
}

void LLVMGoReplaceIncomingBlock(LLVMValueRef Phi, LLVMBasicBlockRef Old,
LLVMBasicBlockRef New) {
unwrap<PHINode>(Phi)->replaceIncomingBlockWith(unwrap(Old), unwrap(New));
}

void LLVMGoSetCurrentDebugLocation(LLVMBuilderRef Bref, unsigned Line,
unsigned Col, LLVMMetadataRef Scope,
LLVMMetadataRef InlinedAt) {
Expand Down
3 changes: 3 additions & 0 deletions IRBindings.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ void LLVMAddNamedMetadataOperand2(LLVMModuleRef M, const char *name,
LLVMMetadataRef Val);
void LLVMSetMetadata2(LLVMValueRef Inst, unsigned KindID, LLVMMetadataRef MD);

void LLVMGoReplaceIncomingBlock(LLVMValueRef Phi, LLVMBasicBlockRef Old,
LLVMBasicBlockRef New);

void LLVMGoSetCurrentDebugLocation(LLVMBuilderRef Bref, unsigned Line,
unsigned Col, LLVMMetadataRef Scope,
LLVMMetadataRef InlinedAt);
Expand Down
3 changes: 3 additions & 0 deletions ir.go
Original file line number Diff line number Diff line change
Expand Up @@ -1260,6 +1260,9 @@ func (v Value) IncomingBlock(i int) (bb BasicBlock) {
bb.C = C.LLVMGetIncomingBlock(v.C, C.unsigned(i))
return
}
func (v Value) ReplaceIncomingBlock(old, new BasicBlock) {
C.LLVMGoReplaceIncomingBlock(v.C, old.C, new.C)
}

// Operations on inline assembly
func InlineAsm(t Type, asmString, constraints string, hasSideEffects, isAlignStack bool, dialect InlineAsmDialect, canThrow bool) (rv Value) {
Expand Down
34 changes: 34 additions & 0 deletions ir_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,40 @@ import (
"testing"
)

func TestReplaceIncomingBlock(t *testing.T) {
ctx := NewContext()
defer ctx.Dispose()
mod := ctx.NewModule("phi-incoming-block")
defer mod.Dispose()
b := ctx.NewBuilder()
defer b.Dispose()

fn := AddFunction(mod, "f", FunctionType(ctx.Int32Type(), nil, false))
entry := ctx.AddBasicBlock(fn, "entry")
old := ctx.AddBasicBlock(fn, "old")
replacement := ctx.AddBasicBlock(fn, "replacement")
merge := ctx.AddBasicBlock(fn, "merge")

b.SetInsertPointAtEnd(entry)
b.CreateBr(replacement)
b.SetInsertPointAtEnd(old)
b.CreateRet(ConstInt(ctx.Int32Type(), 0, false))
b.SetInsertPointAtEnd(replacement)
b.CreateBr(merge)
b.SetInsertPointAtEnd(merge)
phi := b.CreatePHI(ctx.Int32Type(), "value")
phi.AddIncoming([]Value{ConstInt(ctx.Int32Type(), 7, false)}, []BasicBlock{old})
b.CreateRet(phi)

phi.ReplaceIncomingBlock(old, replacement)
if got := phi.IncomingBlock(0); got != replacement {
t.Fatalf("incoming block = %v, want replacement", got)
}
if err := VerifyModule(mod, ReturnStatusAction); err != nil {
t.Fatalf("module verification failed: %v\n%s", err, mod.String())
}
}

func testAttribute(t *testing.T, name string) {
ctx := NewContext()
mod := ctx.NewModule("")
Expand Down
Loading