【问题标题】:LLVM IR - Can someone explain this behavior?LLVM IR - 有人可以解释这种行为吗?
【发布时间】:2016-09-18 09:21:28
【问题描述】:

目前我正在尝试为我的语言构建一个编译器。在我的语言中,我希望像在 Java 中一样对对象/结构使用隐式指针。在下面的程序中,我正在测试这个功能。但是,程序并没有像我预期的那样运行。我不希望你们通读我的整个编译器代码,因为那会浪费时间。相反,我希望我能解释我打算让程序做什么,并且你们可以在 llvm ir 中发现哪里出了问题。这样,我可以调整编译器以生成正确的 llvm ir。


流量:
[函数] Main - [返回:Int] {
-> 为一个 i32 的结构分配空间
-> 调用 createObj 函数并将返回值存储在先前分配的空间中
-> 返回结构的 i32
}

[函数] createObj - [返回:struct { i32 }] {
-> 为一个 i32 的结构分配空间
-> 在这个空间上调用 Object 函数(确实是指针)
-> 返回这个空间(确实是指针)
}

[函数] 对象 - [返回:void] {
-> 将 i32 值 5 存储在结构指针参数中
}


该程序是 main 不断返回一些随机数而不是 5。其中一个数字是 159383856。我猜这是指针地址的十进制表示,但我不确定它为什么打印出指针地址。
; ModuleID = 'main'

%Object = type { i32 }

define i32 @main() {
entry:
  %0 = call %Object* @createObj()
  %o = alloca %Object*
  store %Object* %0, %Object** %o
  %1 = load %Object** %o
  %2 = getelementptr inbounds %Object* %1, i32 0, i32 0
  %3 = load i32* %2
  ret i32 %3
}

define %Object* @createObj() {
entry:
  %0 = alloca %Object
  call void @-Object(%Object* %0)
  %o = alloca %Object*
  store %Object* %0, %Object** %o
  %1 = load %Object** %o
  ret %Object* %1
}

define void @-Object(%Object* %this) {
entry:
  %0 = getelementptr inbounds %Object* %this, i32 0, i32 0
  store i32 5, i32* %0
  ret void
}

这个 llvm ir 就是根据这个语法生成的。

func () > main > (int) {
    Object o = createObj();

    return o.id;
}

// Create an object and returns it
func () > createObj > (Object) { 
    Object o = make Object < ();

    return o;
}

// Object decl
tmpl Object {
    int id; // Property

    // This is run every time an object is created.
    constructor < () {
        this.id = 5;
    }
}

【问题讨论】:

    标签: llvm llvm-ir


    【解决方案1】:

    似乎在 createObj 中,您正在返回一个指向堆栈变量的指针,该指针在函数返回后将不再有效。

    如果您至少要使用 Java 之类的隐式对象指针,您将需要调用诸如 malloc 之类的堆分配,我认为您没有。

    【讨论】:

    • 啊,这很有道理!谢谢你。我会尝试并报告。
    猜你喜欢
    • 2013-11-30
    • 1970-01-01
    • 1970-01-01
    • 2021-12-11
    • 2020-02-23
    • 2019-12-06
    • 1970-01-01
    • 1970-01-01
    • 2020-12-18
    相关资源
    最近更新 更多