使用 LLVM API 将全局字符串存储在可变变量中
Store global string in mutable variable using LLVM API
我正在使用 LLVM 和 OCaml 为 PHP 的子集制作编译器。 LLVM 中的字符串处理教程有点缺乏——至少我找不到。
这是我要编译的代码:
<?php
$a = "foo";
这是我为上面的代码输入的 AST:
[(Typedast.Stmt
Typedast.Expr (Typedast.TUnit,
(<opaque>,
Typedast.Binop ((Typedast.Eq None),
(<opaque>, Typedast.Lvar ((<opaque>, "$a"), Typedast.TString)),
(<opaque>, (Typedast.String (<opaque>, "asd"))), Typedast.TUnit))))]
(这里的<opaque>
只是表示没有显示pos
(位置)。)
这是我生成的 LLVM IR:
; ModuleID = 'mymodule'
@foo = private unnamed_addr constant [4 x i8] c"foo[=13=]"
define i32 @main() {
entry:
%"$a" = alloca i8
store i8 0, i8* %"$a"
store i8* getelementptr inbounds ([4 x i8]* @foo, i32 0, i32 0), i8* %"$a"
ret i32 0
}
我的错误信息:
Stored value type does not match pointer operand type!
store i8* getelementptr inbounds ([4 x i8]* @asd, i32 0, i32 0), i8* %"$a"
i8LLVM ERROR: Broken module found, compilation aborted!
问题是 i8* %"$a"
应该是 i8** %"$a"
,如简单 C 程序的 LLVM IR 所示:
int main() {
char* str = "Hello, world!";
puts(str);
return 0;
}
这将生成此 LLVM IR:
@.str = private unnamed_addr constant [14 x i8] c"Hello, world![=16=]", align 1
; Function Attrs: nounwind uwtable
define i32 @main() #0 {
%1 = alloca i32, align 4
%str = alloca i8*, align 8
store i32 0, i32* %1
store i8* getelementptr inbounds ([14 x i8]* @.str, i32 0, i32 0), i8** %str, align 8
%2 = load i8** %str, align 8
%3 = call i32 @puts(i8* %2)
ret i32 0
}
感谢任何帮助。
通过更改分配代码解决了(我真的希望)。而不是
build_alloca i8_t ...
应该是
build_alloca (pointer_type i8_t) ...
我通过直接编辑生成的代码然后用 llc 编译它来调试它,看看需要更改什么。
我正在使用 LLVM 和 OCaml 为 PHP 的子集制作编译器。 LLVM 中的字符串处理教程有点缺乏——至少我找不到。
这是我要编译的代码:
<?php
$a = "foo";
这是我为上面的代码输入的 AST:
[(Typedast.Stmt
Typedast.Expr (Typedast.TUnit,
(<opaque>,
Typedast.Binop ((Typedast.Eq None),
(<opaque>, Typedast.Lvar ((<opaque>, "$a"), Typedast.TString)),
(<opaque>, (Typedast.String (<opaque>, "asd"))), Typedast.TUnit))))]
(这里的<opaque>
只是表示没有显示pos
(位置)。)
这是我生成的 LLVM IR:
; ModuleID = 'mymodule'
@foo = private unnamed_addr constant [4 x i8] c"foo[=13=]"
define i32 @main() {
entry:
%"$a" = alloca i8
store i8 0, i8* %"$a"
store i8* getelementptr inbounds ([4 x i8]* @foo, i32 0, i32 0), i8* %"$a"
ret i32 0
}
我的错误信息:
Stored value type does not match pointer operand type!
store i8* getelementptr inbounds ([4 x i8]* @asd, i32 0, i32 0), i8* %"$a"
i8LLVM ERROR: Broken module found, compilation aborted!
问题是 i8* %"$a"
应该是 i8** %"$a"
,如简单 C 程序的 LLVM IR 所示:
int main() {
char* str = "Hello, world!";
puts(str);
return 0;
}
这将生成此 LLVM IR:
@.str = private unnamed_addr constant [14 x i8] c"Hello, world![=16=]", align 1
; Function Attrs: nounwind uwtable
define i32 @main() #0 {
%1 = alloca i32, align 4
%str = alloca i8*, align 8
store i32 0, i32* %1
store i8* getelementptr inbounds ([14 x i8]* @.str, i32 0, i32 0), i8** %str, align 8
%2 = load i8** %str, align 8
%3 = call i32 @puts(i8* %2)
ret i32 0
}
感谢任何帮助。
通过更改分配代码解决了(我真的希望)。而不是
build_alloca i8_t ...
应该是
build_alloca (pointer_type i8_t) ...
我通过直接编辑生成的代码然后用 llc 编译它来调试它,看看需要更改什么。