我在函数上写了一个包装器,我想内联它(这个包装器只是以另一种方式映射原始函数的参数).我试图在我的模块之后通过我的模块调用llvm中的内联器并且它没有完成工作,虽然我尝试从opt工具调用传递并且它工作,任何想法什么可能是错的?
以下是我如何调用内联传递:
llvm::PassManager my_passes;
my_passes.add(llvm::createFunctionInliningPass(4096));
my_passes.run(module);
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传递,即i32类型的两个参数来选择函数.我的第一次尝试(在下面描绘)失败了:
bool MyFunctionPass::runOnFunction(Function &f)
{
Type *int32 = Type::getInt32Ty(f.getParent()->getContext());
Argument *xC = new Argument(int32, "__xC", &f);
...
Run Code Online (Sandbox Code Playgroud)
如果我尝试上述操作,模块验证程序会崩溃.新添加的参数类型是垃圾0xCDCDCDCD(未初始化的堆内存).功能类型仍然是:
void (i32 addrspace(1)*, i32 addrspace(1)*, i32)
Run Code Online (Sandbox Code Playgroud)
而不是被新的扩展i32.
此外,将参数直接添加到参数列表Function::getArgumentList()失败,因为Argument构造函数将自身链接到函数,并将其检测为双链接.
谢谢!
我是 LLVM 的初学者,我有一个简单的问题,但我在文档中找不到解决方案。
我正在做一个计算指令的函数传递,为此我需要指令中的所有“数据”,我的意思是运算符、所有操作数和结果。
我的问题是,我无法获得结果变量。例如,对于指令:
%add1 = add nsw i32 %x, %y
Run Code Online (Sandbox Code Playgroud)
我可以有x和y名称和变量,我可以有 opCode,我可以有add1名称,但是,我不能有add1变量。
我从文档的说明页面阅读了所有功能,但找不到任何看起来像我正在寻找的东西。
那么什么是可以解决我的问题的正确 API?
我正在尝试将 LLVM 添加到 cmake 项目中,使用 cygwin 作为编译器。我从 cygwin 的安装程序下载了 LLVM(刚刚安装了所有与 llvm 相关的包)。文件在那里,但是我不能在我的项目中包含 LLVM。我尝试使用 3.5.2 的官方指南(它安装的版本),我的 CMakeLists.txt 看起来像
cmake_minimum_required(VERSION 3.2)
project(Lang)
find_package(LLVM REQUIRED CONFIG)
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
include_directories(${LLVM_INCLUDE_DIRS})
add_definitions(${LLVM_DEFINITIONS})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES main.cpp)
add_executable(Lang ${SOURCE_FILES})
llvm_map_components_to_libnames(llvm_libs support core irreader)
# Link against LLVM libraries
target_link_libraries(Lang ${llvm_libs})
Run Code Online (Sandbox Code Playgroud)
但是,我收到了一堆这样的错误

难道我做错了什么?我想要做的就是在我的项目中使用 LLVM。
我希望我的大部分程序都是一个通常编译的C++程序.所述程序使用一块连续的内存用于堆栈.堆栈的顶部由普通指针维护.
我想与通过LLVM JIT生成的代码共享该指针.例如,给定:
llvm::InitializeNativeTarget();
llvm::LLVMContext ctx;
std::unique_ptr<llvm::Module> uptr_module = llvm::make_unique<llvm::Module>( "lt", ctx );
llvm::Module *const module = uptr_module.get();
int *const stack = new int[100];
int *top = stack; // I want this pointer to be shared with JIT'd code
llvm::Function *const func = llvm::cast<llvm::Function>(
module->getOrInsertFunction( "func", llvm::Type::getVoidTy( ctx ), (llvm::Type*)0 )
);
llvm::BasicBlock *const block = llvm::BasicBlock::Create( ctx, "entry", func );
pointerInc( &top, block ); // Increment the pointer in JIT'd code
llvm::ReturnInst::Create( ctx, block );
llvm::verifyFunction( *func, &llvm::outs() ); …Run Code Online (Sandbox Code Playgroud) 我有一个能够生成C语言代码的软件,希望在即时编译环境中使用。据我了解,LLVM / Clang是可行的方法,为了项目的可维护性,我想使用llvm和Clang的C API(libclang)。
我开始使用创建一个libclang上下文,clang_createIndex并使用一个翻译单元创建一个createTranslationUnitFromSourceFile(很高兴能够避免通过文件系统,而是将源代码作为字符串传递)。但是我几乎被困在那里。如何从libclang转换单元转到LLVM“执行引擎”,这似乎是JIT所需要的?还是使用C API甚至无法做到这一点?
我想在堆栈上创建 LLVM ArrayType 所以我想使用AllocaInst (Type *Ty, Value *ArraySize=nullptr, const Twine &Name="", Instruction *InsertBefore=nullptr). 问题是我不明白这个界面。我猜那Ty会是类似的东西ArrayType::get(I.getType(), 4),但我应该付出什么ArraySize。此外,它需要Value*,所以它让我很困惑。
要么我误解了 llvm alloc,要么我需要提供一个 llvm 常量作为数组大小的值。如果我必须给出常量,是不是有点多余,因为ArrayType包含 numElement 作为信息。
作为示例代码行,我尝试的方式是:
AllocaInst* arr_alloc = new AllocaInst(ArrayType::get(I.getType(), num)
/*, What is this parameter for?*/,
"",
funcEntry.getFirstInsertionPt());
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 …
我正在努力弄清楚如何使用 LLVM c++ API 分配数组元素。考虑这个 C 代码:
int main()
{
int aa[68];
aa[56] = 7;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用
clang -S -emit-llvm main.c
Run Code Online (Sandbox Code Playgroud)
我得到以下 IR(为了简单起见,跳过了属性和其他内容):
define dso_local i32 @main() #0 {
%1 = alloca i32, align 4
%2 = alloca [68 x i32], align 16
store i32 0, i32* %1, align 4
%3 = getelementptr inbounds [68 x i32], [68 x i32]* %2, i64 0, i64 56
store i32 7, i32* %3, align 16
ret i32 0
}
Run Code Online (Sandbox Code Playgroud)
我已经知道如何创建入站 GEP,但是当将值 …
llvm ×10
llvm-c++-api ×10
c++ ×4
llvm-ir ×3
cmake ×1
inline ×1
jit ×1
libclang ×1
llvm-3.0 ×1
llvm-clang ×1