标签: llvm-c++-api

LLVM.如何根据名称访问struct字段?

我在C++中有一些示例代码:

struct RecordTest
{
    int value1;
    int value2;
};

void test()
{
    RecordTest rt;
    rt.value1 = 15;
    rt.value2 = 75;
}
Run Code Online (Sandbox Code Playgroud)

和LLVM 3.4 IR:

%struct.RecordTest = type { i32, i32 }

; Function Attrs: nounwind
define void @_Z4testv() #0 {
entry:
  %rt = alloca %struct.RecordTest, align 4
  %value1 = getelementptr inbounds %struct.RecordTest* %rt, i32 0, i32 0
  store i32 15, i32* %value1, align 4
  %value2 = getelementptr inbounds %struct.RecordTest* %rt, i32 0, i32 1
  store i32 75, i32* %value2, align …
Run Code Online (Sandbox Code Playgroud)

llvm llvm-c++-api

5
推荐指数
1
解决办法
3799
查看次数

为什么我的特征模板类查找运算符<< for llvm :: StringRef?

下面的问题如何检测类型是否可以流式传输到std :: ostream?我写了一个trait类,说明某些类型是否可以流式传输到IO流.直到现在我发现了一个问题,这个特性似乎运作良好.

我在使用LLVM的项目中使用代码,我正在使用他们的StringRef类(它与提议的std :: string_view类似).是该类的Doxygen doc的链接,如果需要,您可以从中找到它的声明头文件.由于LLVM不提供运算符<<将StringRef对象流式传输到std流(它们使用自定义轻量级流类),因此我写了一个.

但是,当我使用特征时,如果我的自定义运算符<< 在特征之后被声明(这是因为我在一个标题中具有特征而操作符在另一个标题中的函数),则它不起作用.我曾经认为模板实例化中的查找是从实例化点的角度来看的,所以我认为它应该可行.实际上,正如你在下面看到的那样,使用另一个类及其自定义运算符<<,在特征之后声明,一切都按预期工作(这就是为什么我现在才发现这个问题),所以我无法弄清楚StringRef的原因特别.

这是完整的例子:

#include <iostream>

#include "llvm/ADT/StringRef.h"

// Trait class exactly from the cited question's accepted answer
template<typename T>
class is_streamable
{
   template<typename SS, typename TT>
   static auto test(int)
      -> decltype(std::declval<SS&>() << std::declval<TT>(),
                  std::true_type());

   template<typename, typename>
   static auto test(...) -> std::false_type;

public:
   static const bool value = decltype(test<std::ostream,T>(0))::value;
};

// Custom stream operator for StringRef, declared after the trait
inline std::ostream &operator<<(std::ostream &s, llvm::StringRef const&str) {
   return …
Run Code Online (Sandbox Code Playgroud)

c++ llvm type-traits c++11 llvm-c++-api

5
推荐指数
1
解决办法
253
查看次数

LLVM获取指令的操作数和左值名称

对于LLVM IR指令,%cmp7 = icmp eq i32 %6 %7我希望得到所有三个寄存器/符号名称(即%cmp %6 and %7)

现在我可以%cmp通过命令获取字符串,pi->getName()其中pi是指令指针.但是当我尝试获取操作名称时,我通过键入获得了空字符串pi->getOperand(0)->getName().

我试图isa<Instruction>(pi->getOperand(0))检查这是否是一个指令,它返回true但pi->getOperand(0)->hasName()返回false.事情让我感到奇怪的是,为什么这两个pipi->getOperand(0)的指示,但仅pi具有名?

有没有想法我可以使用API 获取操作数名称(字符串%6%7此处)?

我正在使用的LLVM版本是3.4.2

llvm llvm-ir llvm-c++-api

5
推荐指数
1
解决办法
2453
查看次数

链接时LLVM IR类型被错误地折叠(C++ API)

直截了当 - 我正在尝试将两个(或更多)llvm模块链接在一起,而我正面临来自LLVM的某个奇怪错误.

我不想发布太多代码,所以我会在这里使用一堆伪.

我有3个模块,比方说A,B和C. A是主要模块; 我llvm::Linker用它初始化.B和C是辅助模块; 我打电话linker.linkInModule(B and C).

除其他外,所有3个模块都定义了以下两种类型:

%String = type { i8*, i64 }
%Character = type { i8*, i64 }
Run Code Online (Sandbox Code Playgroud)

请注意,它们具有相同的成员类型.此外,函数foo定义为(在模块B中):

define i1 @_ZN9Character7hasDataEv(%Character*) { }
Run Code Online (Sandbox Code Playgroud)

这个函数在模块A和C中声明.现在,一切看起来都很好 - 从模块A和C调用此函数,并且IR看起来很正常,如下所示:

%21 = call i1 @_ZN9Character7hasDataEv(%Character* %4)
Run Code Online (Sandbox Code Playgroud)

问题出在这里:当所有3个模块链接在一起时,这些类型会发生一些事情:

  1. 他们失去了名字,成为%2(%String)和%3(%Character).
  2. 它们似乎合并在一起.

奇怪的是,虽然这种转换发生在模块A和C中,但这种错误只发生在C中 - 注意A是所谓的"主"模块.

现在是链接文件的函数定义

define i1 @_ZN9Character7hasDataEv(%2*)
Run Code Online (Sandbox Code Playgroud)

注意如何%Character,或者%3,变成了%2.此外,在呼叫网站,可能是尝试取消合并类型,我得到了这个:

%10 = call i1 bitcast (i1 (%2*)* @_ZN9Character7hasDataEv to …
Run Code Online (Sandbox Code Playgroud)

c++ llvm llvm-ir llvm-c++-api

5
推荐指数
1
解决办法
163
查看次数

使用LLVM内联特定函数调用

给定一个llvm::CallInst *,如何告诉内联者内联这个特定的调用.我可以将目标函数标记为AlwaysInline,这将内联调用,但它也会内联每个调用.也许有一些方法可以在我发出特定呼叫时调用内联器?内联基本块中的所有调用也会起作用.

c++ llvm llvm-c++-api

5
推荐指数
1
解决办法
264
查看次数

将GetElementPtrInst与包含多个Value的ArrayRef一起使用时的Segfault

我正在尝试用LLVM和C++编写一个玩具编译器.但每当我尝试使用多个索引创建一个GetElementPtrInst时,就会出现一个Segfault.关于这条指令的文档对我没有帮助(API-文档 语言 - 文档)

我的llvm版本是3.1,这是在Arch Linux上.刚刚在另一台Arch机器上测试它并得到了同样的错误.

难道我做错了什么?

这是一个小工作程序来说明我的问题.它可以编译为:

g++ -o segfault_example segfault_example.cpp -Wall -Wextra -pedantic \
    `llvm-config --libs core jit native --cxxflags --ldflags`
Run Code Online (Sandbox Code Playgroud)
#include <llvm/Module.h>
#include <llvm/Constants.h>
#include <llvm/DerivedTypes.h>
#include <llvm/LLVMContext.h>
#include <llvm/Instructions.h>
#include <llvm/Analysis/Verifier.h>
#include <llvm/ADT/ArrayRef.h>
#include <string>
#include <iostream>

static llvm::LLVMContext& global = llvm::getGlobalContext();
static llvm::Type* int32ty = llvm::Type::getInt32Ty(global);

llvm::ConstantInt* getInt32(int n)
{
    return llvm::ConstantInt::get(llvm::Type::getInt32Ty(global), n);
}

int main()
{
    //setup everything for a minimal example
    llvm::Module* mainModule = new llvm::Module("main", global);

    llvm::FunctionType* ftype = llvm::FunctionType::get(int32ty, …
Run Code Online (Sandbox Code Playgroud)

llvm llvm-c++-api

4
推荐指数
1
解决办法
1592
查看次数

通过LLVM API直接生成机器代码

使用以下代码,我可以从模块生成LLVM 位代码文件:

llvm::Module * module;

// fill module with code
module = ...;

std::error_code ec;
llvm::raw_fd_ostream out("anonymous.bc", ec, llvm::sys::fs::F_None);

llvm::WriteBitcodeToFile(module, out);
Run Code Online (Sandbox Code Playgroud)

然后我可以使用该位码文件生成可执行机器代码文件,例如:

clang -o anonymous anonymous.bc
Run Code Online (Sandbox Code Playgroud)

或者:

llc anonymous.bc
gcc -o anonymous anonymous.s
Run Code Online (Sandbox Code Playgroud)

我现在的问题是:我可以使用 LLVM API 直接在 C++ 中生成机器代码,而不需要首先编写位码文件吗?

我正在寻找代码示例或至少 LLVM API 中的一些起点,例如要使用哪些类,将我推向正确的方向可能就足够了。

llvm llvm-c++-api

4
推荐指数
1
解决办法
1347
查看次数

在 FunctionPass llvm 中获取当前模块

我正在 LLVM 中编写一个函数传递,需要调用方法 Module::getOrInsertFunction。我需要访问当前函数的模块。我如何得到它?

llvm llvm-c++-api

4
推荐指数
1
解决办法
2638
查看次数

如何使用整数列表在LLVM中初始化整数数组?

我有以下要生成C ++的IR代码:

@gArray = global [10 x i32] [i32 3, i32 4, i32 5, i32 6, i32 0, i32 0, i32 0, i32 0, i32 12, i32 0], align 16
Run Code Online (Sandbox Code Playgroud)

我知道我可以使用以下代码行将数组初始化为全零:

    ConstantAggregateZero* const_array_2 = ConstantAggregateZero::get(ArrayTy_0);
    GArray->setInitializer(const_array_2);
Run Code Online (Sandbox Code Playgroud)

如何将LLVM中的数组初始化为值列表?

c++ arrays llvm llvm-c++-api

4
推荐指数
1
解决办法
1164
查看次数

llvm 5.0链接错误与llvm :: Module :: dump()

我试图在过去的两天里将LLVM与My C++项目联系起来并且它最终正在工作,但问题是当我使用dump()方法时它会给出链接器错误我认为问题出在我正在链接的库中,所以我'我将可执行文件链接到所有LLVM库(模块)但没有成功.所以这是LLVM5.0代码库中的一个错误,或者我做错了什么以及我专门谈论LLVM5.0的原因,因为我已经在评论部分中读取了其他地方(LLVM-5.0 Makefile未定义引用失败)没有问题使用LLVM4.0编译相同的代码,当然我搜索了其他解决方案,但没有什么

llvm_test.cpp:

#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"

llvm::LLVMContext context;

int main(){
    llvm::Module*module = new llvm::Module("llvm-module",context);
    module->dump();
}
Run Code Online (Sandbox Code Playgroud)

命令:

clang++ -O3  -Wall -std=c++11 `llvm-config --cppflags --ldflags` `llvm-config --libs core --system-libs` toy.cpp 
Run Code Online (Sandbox Code Playgroud)

而且我已经链接了所有模块:

clang++ -O3 -Wall -std=c++11 `llvm-config --cxxflags --ldflags` `llvm-config --libs all --system-libs` toy.cpp 
Run Code Online (Sandbox Code Playgroud)

编译器: Apple Clang 8.0.0 x86_64

操作系统: mac OS 10.12.5

谢谢你提前帮助

c++ llvm llvm-clang llvm-c++-api

4
推荐指数
1
解决办法
2058
查看次数

标签 统计

llvm ×10

llvm-c++-api ×10

c++ ×5

llvm-ir ×2

arrays ×1

c++11 ×1

llvm-clang ×1

type-traits ×1