Skip to content

unable to generate LLVM: structure, external , noundef and ptr #236

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ghost opened this issue Mar 15, 2024 · 1 comment
Closed

unable to generate LLVM: structure, external , noundef and ptr #236

ghost opened this issue Mar 15, 2024 · 1 comment

Comments

@ghost
Copy link

ghost commented Mar 15, 2024

Based on my test with clang I need to generate the following code :

%struct.GarbageCollector = type { ptr, i8, ptr, i64 }
@gc = external global %struct.GarbageCollector, align 8

declare void @gc_start(ptr noundef, ptr noundef) #1
declare i64 @gc_stop(ptr noundef) #1
declare ptr @gc_malloc(ptr noundef, i64 noundef) #1

define i32 @main(i32 %argc, i8** %argv) {
0:
	%1 = alloca i32
	store i32 %argc, i32* %1
  	call void @gc_start(ptr noundef @gc, ptr noundef %1)
   	%2 = call i64 @gc_stop(ptr noundef @gc)
	ret i32 0
}

I don't see how to generate structure, external, noundef and ptr. Do we have alternative to these in the current library or are they missing features? I so, could they be added? How could I help?

@ghost ghost changed the title unable to generate LLVM: structure, external and ptr unable to generate LLVM: structure, external , noundef and ptr Mar 15, 2024
@mewmew
Copy link
Member

mewmew commented Mar 16, 2024

Hi @dequeb,

Here's an example to get you started. It's not identical, but showcases how to get external global variables and add parameter attributes to the LLVM IR.

In general, remember to take a look at the ir/types and ir/enum packages, in addition to ir.

Note, however that llir/llvm does not yet support opaque pointers (see #222 (comment)).

package main

import (
	"fmt"

	"github.com/llir/llvm/ir"
	"github.com/llir/llvm/ir/constant"
	"github.com/llir/llvm/ir/enum"
	"github.com/llir/llvm/ir/types"
)

func main() {
	i8 := types.I8
	i32 := types.I32
	i64 := types.I64
	ptrType := types.NewPointer(i8)
	m := ir.NewModule()

	// %struct.GarbageCollector type definition
	garbageCollectorType := types.NewStruct(ptrType, i8, ptrType, i64)
	m.NewTypeDef("struct.GarbageCollector", garbageCollectorType)

	// gc global
	gcGlobal := ir.NewGlobal("gc", garbageCollectorType)
	gcGlobal.Linkage = enum.LinkageExternal
	gcGlobal.Align = 8

	garbageCollectorPtrType := types.NewPointer(garbageCollectorType)

	// gc_start
	gcStartParam1 := ir.NewParam("param1", garbageCollectorPtrType)
	gcStartParam1.Attrs = append(gcStartParam1.Attrs, enum.ParamAttrNoUndef)
	gcStartParam2 := ir.NewParam("param2", ptrType)
	gcStartParam2.Attrs = append(gcStartParam2.Attrs, enum.ParamAttrNoUndef)
	gcStart := m.NewFunc("gc_start", types.Void, gcStartParam1, gcStartParam2)
	// gc_stop
	gcStopParam1 := ir.NewParam("param1", ptrType)
	gcStopParam1.Attrs = append(gcStopParam1.Attrs, enum.ParamAttrNoUndef)
	gcStop := m.NewFunc("gc_stop", i64, gcStopParam1)
	// gc_malloc
	gcMallocParam1 := ir.NewParam("param1", ptrType)
	gcMallocParam1.Attrs = append(gcMallocParam1.Attrs, enum.ParamAttrNoUndef)
	gcMallocParam2 := ir.NewParam("param2", ptrType)
	gcMallocParam2.Attrs = append(gcMallocParam2.Attrs, enum.ParamAttrNoUndef)
	gcMalloc := m.NewFunc("gc_malloc", ptrType, gcMallocParam1, gcMallocParam2)
	_ = gcStart
	_ = gcStop
	_ = gcMalloc

	// main function
	argcParam := ir.NewParam("argc", i32)
	argvType := types.NewPointer(types.NewPointer(i8))
	argvParam := ir.NewParam("argv", argvType)
	main := m.NewFunc("main", i32, argcParam, argvParam)
	entry := main.NewBlock("")
	localVar := entry.NewAlloca(i32)
	entry.NewStore(argcParam, localVar)
	entry.NewCall(gcStart, gcGlobal, localVar)
	entry.NewCall(gcStop, gcGlobal)
	zero := constant.NewInt(i32, 0)
	entry.NewRet(zero)
	// print LLVM IR module
	fmt.Println(m)
}

Output LLVM IR:

%struct.GarbageCollector = type { i8*, i8, i8*, i64 }

declare void @gc_start(%struct.GarbageCollector* noundef %param1, i8* noundef %param2)

declare i64 @gc_stop(i8* noundef %param1)

declare i8* @gc_malloc(i8* noundef %param1, i8* noundef %param2)

define i32 @main(i32 %argc, i8** %argv) {
0:
	%1 = alloca i32
	store i32 %argc, i32* %1
	call void @gc_start(%struct.GarbageCollector* @gc, i32* %1)
	%2 = call i64 @gc_stop(%struct.GarbageCollector* @gc)
	ret i32 0
}

Cheers,
Robin

@ghost ghost closed this as completed Mar 23, 2024
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant