LLVM项目不区分此处描述的有符号和无符号整数.在某些情况下,您需要知道特定变量是应该被解释为有符号还是无符号变量,例如,当它是大小扩展时或在分区中使用时.我的解决方案是为每个变量保留一个单独的类型信息,描述它是整数还是基数类型.
但是,我想知道,是不是有办法在LLVM中"归属"这种类型?我正在寻找可以添加到某种类型的某种"用户数据",但似乎什么都没有.在创建类型时必须以某种方式发生这种情况,因为在LLVM中只生成一次相同的类型.
因此,我的问题是:
有没有办法跟踪整数变量是否应该在LLVM基础结构中被解释为有符号或无符号,或者确实是像我一样保留单独信息的唯一方法?
谢谢
无论如何,我可以确定被调用函数是否是用户定义?例如:
void foo()
{
printf("hello world again");
}
int main()
{
printf("hello world\n");
foo();
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,foo()是用户定义,而printf()是库函数.
我目前使用的方法是迭代所有模块并检查其大小是否大于0.即:
for(Module::iterator F = M.begin(); F != M.end(); ++F)
{
Function &Func = *F;
if(F->size()>0)
errs() << "User Define";
}
Run Code Online (Sandbox Code Playgroud)
但我不确定它的准确性?
使用ModulePass,我的目标是向上遍历一个SSA图:从一个带有0..2个操作数的语句(大多数操作码都属于那个),我想找出两件事:
例如,假设遵循LLVM IR:
define i32 @mul_add(i32 %x, i32 %y, i32 %z) {
entry:
%tmp = mul i32 %x, %y
%tmp2 = add i32 %tmp, %z
ret i32 %tmp2
}
Run Code Online (Sandbox Code Playgroud)
我将从return语句开始.现在我想知道我要回来的东西:
我如何使用C++ API来实现这些步骤?
如何运行非传统PassManager?我尝试过以下操作,但在尝试使run函数中的分析管理器失效时会抛出一些异常.我还应该为初始化做些什么吗?
llvm::AnalysisManager<Module> mm;
PassBuilder builder;
auto pm = builder.buildModuleOptimizationPipeline(PassBuilder::OptimizationLevel::O3);
pm.run(module, mm );
Run Code Online (Sandbox Code Playgroud) clang 3.0在线演示页面http://llvm.org/demo/index.cgi提供了输出LLVM C++ API代码的选项,"代表输入程序的LLVM-IR.
"生成LLVM C++ API代码"输出一个clang选项(如果是,它是什么)?
或者它是一个llvm工具选项(哪一个)?
是否可以通过LLVM-IR输入执行相同的操作?基本上我希望看到生成特定llvm-ir序列所需的正确llvm c ++ api调用.我想通过示例向后学习,而不是从文档中向前学习.
clang,llvm-as和llvm-dis的手册页和--help和--help-hidden没有显示任何明显的内容.
编辑:好的,现在我在该网页的输出中看到"由llvm2cpp生成".但我在最近的llvm版本中找不到该工具,只有旧版本,在llvm2cpp中有一个2.9和3.0接管的新工具?
通过llvm教程我已经实现了JIT并发现我的REPL意外地因segfault而失败.调试器显示运算符throw导致此段错误.但是只有在抛出异常之前使用JIT编译某些代码时才会发生崩溃.可以使用此答案的代码进行一些修改来重现问题:
#include <string>
#include <vector>
#include <iostream>
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Verifier.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Mangler.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/TargetSelect.h"
using namespace llvm;
typedef orc::ObjectLinkingLayer<> ObjLayerT;
typedef orc::IRCompileLayer<ObjLayerT> CompileLayerT;
static LLVMContext Context;
static auto MyModule = make_unique<Module>("my compiler", Context);
Function *createFunc(IRBuilder<> &Builder, std::string …Run Code Online (Sandbox Code Playgroud) 我正在编写一个自制语言的编译器,它只能处理int值,即i32.条件和表达式与C语言类似.因此,我正在考虑条件语句作为表达式,即它们返回一个int值.它们也可以用在表达式中,例如(2 > 1) + (3 > 2)将返回2.但LLVM条件输出i1值.
i1应该转换成i32,以便我可以执行二进制操作if(variable)或if(a + b).为此,我需要转换i32为i1最后,我想办法从类型转换i1到i32和i32到i1.我的代码现在提供这些错误:
对于如下声明if(variable):
error: branch condition must have 'i1' type
br i32 %0, label %ifb, label %else
^
Run Code Online (Sandbox Code Playgroud)
对于声明 a = b > 3
error: stored value and pointer type do not match
store i1 %gttmp, i32* @a
^
Run Code Online (Sandbox Code Playgroud)
有关如何做到这一点的任何建议?
我最近安装了 LLVM v8.0.0(在 RHEL 7.4 上)。我正在阅读LLVM Kaleidoscope 教程以了解如何使用该系统,但遇到了链接问题。
根据教程(第 2 章结尾),我运行:
clang++ -g -O3 kld.cpp `llvm-config --cxxflags` -o kld
Run Code Online (Sandbox Code Playgroud)
它编译,但链接器失败:
/tmp/kld-f7264f.o:(.data+0x0): undefined reference to `llvm::EnableABIBreakingChecks'
clang-8: error: linker command failed with exit code 1 (use -v to see invocation)
Run Code Online (Sandbox Code Playgroud)
我怀疑这可能是 的问题llvm-config,所以我也尝试使用--ldflags和--system-libs标志,但没有运气。
llvm-config --cxxflags 给出(重新格式化以提高可读性)
-I~/project/llvm-src/include -I~/project/llvm-build/include
-fPIC -fvisibility-inlines-hidden
-std=c++11
-Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual
-Wno-missing-field-initializers -pedantic -Wno-long-long
-Wno-maybe-uninitialized -Wdelete-non-virtual-dtor -Wno-comment
-g
-fno-exceptions -fno-rtti
-D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS
-D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
Run Code Online (Sandbox Code Playgroud)
哪里~/... …
我想从两个基本的 C++ 函数生成 LLVM IR 代码,如下所示。
int newFun2(int x){
int z = x + x;
return z;
}
int newFun(int *y){
int first = y[3]; //How to define it using the LLVM API?
int num = newFun2(first);
return num;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是使用 LLVM API 获取数组参数的索引。有任何想法吗 ?非常感谢
已编辑
这是我使用 API 的代码:
llvm::LLVMContext &context = llvm::getGlobalContext();
llvm::Module *module = new llvm::Module("AST", context);
llvm::IRBuilder<> builder(context);
//newFun2
llvm::FunctionType *newFunc2Type = llvm::FunctionType::get(builder.getInt32Ty(), builder.getInt32Ty(), false);
llvm::Function *newFunc2 = llvm::Function::Create(newFunc2Type, llvm::Function::ExternalLinkage, "newFun2", module);
llvm::Function::arg_iterator argsFun2 = newFunc2->arg_begin();
llvm::Value* …Run Code Online (Sandbox Code Playgroud) 加载一组预先生成的 LLVM IR 并使其可用于运行时 JIT 模块以便相同类型不会被赋予新名称并且内联和常量传播仍然可以发生的正确方法是什么?
到目前为止我的尝试:
我通过以下方式将这些 C 函数离线编译为 LLVM IR clang -c -emit-llvm -S -ffast-math -msse2 -O3 -o MyLib.ll MyLib.c
对于每个运行时 JIT 模块,我通过加载生成的 LLVM IRllvm::parseIRFile()并将其“粘贴”到运行时 JIT 模块中llvm::Linker::linkModules()。
这适用于第一个 JIT 模块,但不适用于创建的后续 JIT 模块。每次llvm::parseIRFile()调用时,IR 中生成的模块的类型定义都会被赋予新的名称。
例如,离线 MyLib.ll 如下所示:
%struct.A = type { <4 x float> }
define <4 x float> @Foo(A*)(%struct.A* nocapture readonly)
{
...
}
第一次调用的结果模块llvm::parseIRFile()看起来与离线版本完全一样。第二次调用的结果模块llvm:parseIRFile()看起来像:
%struct.A.1 = type { <4 x float> }
define <4 x …