我正在尝试编写一个简单的解释器。
我正在尝试生成 LLVM IR 进行赋值操作。生成部分的代码如下所示
llvm::Value* codeGenSymTab(llvm::LLVMContext& context) {
printf("\n CodeGen SymTab \n");
Value *num = ConstantInt::get(Type::getInt64Ty(context), aTable.value, true);
Value *alloc = new AllocaInst(IntegerType::get(context, 32), aTable.variableName,entry);
StoreInst *ptr = new StoreInst(num,alloc,false,entry);
}
Run Code Online (Sandbox Code Playgroud)
SymTab 定义如下:
struct SymTab {
char* variableName;
int value;
llvm::Value* (*codeGen)(llvm::LLVMContext& context);
};
Run Code Online (Sandbox Code Playgroud)
当我尝试执行输出文件时,出现以下错误:
Assertion failed: (getOperand(0)->getType() == cast<PointerType>(getOperand(1)->getType())->getElementType() && "Ptr must be a pointer to Val type!"), function AssertOK, file Instructions.cpp, line 1084.
Abort trap: 6
Run Code Online (Sandbox Code Playgroud)
你能帮我解决吗?
谢谢
我希望从现有的 LLVM IR 代码创建一个 LLVM 模块。
我发现的两种方法如下:
ParseIRFile
- 这接受文件名并生成模块ParseIR
- 这接受 MemoryBuffer 并生成一个模块当 LLVM IR 已作为std::string
or读取到字符串时,我想创建一个模块const char *
。
有没有办法将 IR 字符串转换为llvm::MemoryBuffer
?
我正在学习 LLVM 基础知识。我正在尝试进入构建器框架并设置模块、函数头等,但我还无法找到在构建器中创建这样的简单序列的方法:
%0 = 41
%1 = add i32 42, %0
Run Code Online (Sandbox Code Playgroud)
这意味着我如何通过构建器框架使用伪寄存器表示法?
我尝试根据两个常量创建一条加指令。我用来生成(整数)加法的核心行是:
Value *L = (Value *)m_left->Create_LLVM( );
Value *R = (Value *)m_right->Create_LLVM();
if ( L == 0 || R == 0 ) return 0;
llvm::Value *p_instruction = Get_Builder().CreateAdd( L, R, "addtmp" );
Run Code Online (Sandbox Code Playgroud)
这包含很多我自己的功能,但我想基础知识很清楚。我获得左操作数和右操作数的值指针,它们都是常量,然后使用构建器框架创建添加操作。模块和构建器再次正确设置,当我调用 dump() 时,我看到我所做的所有其他内容,但上面的这一行不会创建任何 IR 代码。
我希望它能共同创造类似的东西
%4 = add i32 %3, %2
Run Code Online (Sandbox Code Playgroud)
或类似的东西。我是否误解了与构建器一起构建操作的基本方式,或者只是对某些细节的一些小疏忽?
谢谢
我有以下指示:
\n\n%ptrA = getelementptr float, float addrspace(1)* %A, i32 %id\n
Run Code Online (Sandbox Code Playgroud)\n\n我可以获取操作数%A
并%id
使用getOperand(0)
and getOperand(1)
。我想知道是否getOperand
会继续工作%ptrA
?如果是的话,会是吗getOperand(3)
?
- - - - - - - - - - - - - - - - - - 编辑 - - - - - - - ----------------
\n\n所以我改变了我的代码如下:
\n\nfor (Instruction &I : instructions(F)){\n if (cast<Operator>(I).getOpcode() == Instruction::GetElementPtr){\n Value* AddrPointer = cast<Value>(I);\n
Run Code Online (Sandbox Code Playgroud)\n\n我不断收到错误:
\n\n%ptrA = getelementptr float, float addrspace(1)* …
Run Code Online (Sandbox Code Playgroud) 我目前正处于学习如何使用 LLVM 的阶段。我正在尝试通过 编译以下文件llc struct-method.ll -o struct-method
。
结构体方法.ll
; ModuleID = 'struct-method.ll'
@.formatstring = private unnamed_addr constant [13 x i8] c"%c\0A%ld\0A%lld\0A\00"
%box = type { i8, i32, i64 }
declare i32 @printf(i8* noalias nocapture, ...)
define i32 @set_prop_32(%box* %object, i32 %value) {
entry:
%0 = getelementptr inbounds %box, %box* %object, i64 0, i64 1
%1 = load i32, i32* %0
ret i32 %1
}
define i32 @main() {
alloca:
%mybox = alloca %box
br label %entry
entry:
%format …
Run Code Online (Sandbox Code Playgroud) 在克隆函数的上下文中,使用的对象之一是ValueToValueMapTy &VMap
a typedef
of ValueMap<const Value *, WeakVH>
。
例如,它在cloneFunctionInto(...)
in期间使用llvm/lib/Transforms/Utils/CloneFunction.cpp
因此,我有一些问题可以帮助我阐明其目的:
llvm::Value
每个都在 VMap 上吗?或者这仅属于功能或模块或什么?llvm::Values
函数的信息,这是否正确?附:
我已经检查过那些可能对其他人在 Vmap 上提问有帮助的链接,但没有一个能完全回答我的问题。
对于带有嵌入位码的二进制文件(即使用 编译-fembed-bitcode
)。我怎样才能提取该部分,以便我可以像任何其他位码文件一样使用该位码文件,例如运行opt
或llvm-dis
作为测试用例,我有这个 hello-world 程序:
// hello.cpp
#include<iostream>
int main() {
std::cout << "hello world";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译为:clang++ -O2 test.cpp -o test.o -fembed-bitcode -c
显示其中objdump
有一个__bitcode部分:
objdump -h test.o
test.o: file format Mach-O 64-bit x86-64
Sections:
Idx Name Size Address Type
0 __text 000002eb 0000000000000000 TEXT
1 __gcc_except_tab 00000068 00000000000002ec DATA
2 __cstring 0000000c 0000000000000354 DATA
3 __bitcode 00002bc0 0000000000000360 DATA
4 __cmdline 00000046 0000000000002f20 DATA
5 __compact_unwind 00000060 0000000000002f68 …
Run Code Online (Sandbox Code Playgroud) 创建 raw_ostream 对象并将其用于打印的正确方法是什么?我阅读了各种文章,我能找到的唯一示例是(如何将 llvm::outs() 重定向到文件?)
raw_ostream *output = &outs();
Run Code Online (Sandbox Code Playgroud)
它利用了 llvm::outs。
抱歉问这个,因为我不太熟悉 C++,但必须了解 LLVM 的工作原理。
我正在尝试运行此代码,但收到:错误:预期指令操作码 label_3:
这是代码的相关部分:
define void @main(){
%r1 = alloca [50 x i32]
%r7 = alloca i32
store i32 0 , i32* %r7
label_3:
%r9 = load i32 , i32* %r7
%r8 = getelementptr [258 x i32], [258 x i32]* %r6 , i32 0 , i32 %r9
store i32 0 , i32* %r8
%r10 = add i32 1 , %r9
store i32 %r10 , i32* %r7
%r11 = icmp eq i32 256 , i32 %r10
br i1 %r11 , label %label_4 …
Run Code Online (Sandbox Code Playgroud) 我正在开始编译器优化领域的新研究。首先,我正在研究几篇相关的不同论文,并遇到了一些不同的优化技术。
我目前正在研究的一件主要事情是编译器的技术,它将输入源代码转换为图形(例如控制流、数据流、链表等),然后对图形执行优化并生成机器代码。代码到图形到代码。例如,JavaScript引擎中的JIT编译器,即V8、ChakraCore等。
然后,我遇到了 LLVM IR。由于之前的搜索,我对代码优化的印象是在上面解释的图表上进行的。然而,我不认为 LLVM 是这种情况,但我也不确定。我发现有一些工具可以从 LLVM IR 生成控制流图,但这并不意味着它正在优化该图。
所以,我的问题是“LLVM IR 是图表吗?” 如果不是,它如何优化代码?直接代码到代码?