首页 > 其他分享 >03_llvm_IR测试创建变量

03_llvm_IR测试创建变量

时间:2023-08-02 20:13:32浏览次数:71  
标签:03 llvm FunctionType IR test include Type

主要分全局变量、函数参数、局部变量(常量)与返回值

测试全局变量

介绍说明、代码、编译与结果如下:

#include "llvm/IR/Module.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/Support/Alignment.h"

using namespace llvm;
/*
全局变量(Global Variable)在一个module内全局可见,以@符号开头,
llvm通过Module::getNamedGlobal()创建,还可配置链接类型、内存对齐等属性,
其中,链接类型是指全局变量在链接时指向同一个全局变量还是不同的全局变量,
不同的全局变量是指名称一样,但内存实例不同,互不影响。
| 链接类型                    | 用途                                        |
| -------------------------- | ------------------------------------------- |
| ExternalLinkage            | 模块外部可见                                 |
| AvailableExternallyLinkage | 只在查询而非代码生成的时候外部可见             |
| LinkOnceAnyLinkage         | 函数在链接(或内连inline)的时候仅保存一份实现 |
| LinkOnceODRLinkage         | 同上,但有些链接属性可以用类似的属性替换       |
| WeakAnyLinkage             | 函数在链接的时候仅保存一份实现(弱链接)       |
| WeakODRLinkage             | 同上,但有些链接属性可以用类似的属性替换       |
| AppendingLinkage           | 这是特殊的链接类型,只适用于全局数组           |
| InternalLinkage            | 链接时若发现有重命名的静态函数,则进行重命名   |
| PrivateLinkage             | 只做内部链接,但不会添加到符号表中            |
| ExternalWeakLinkage        | 外部弱链接                                  |
| CommonLinkage              | 由编译器(链接器)自动选择链接类型            |

llvm官方linkage types:https://llvm.org/docs/LangRef.html#linkage

*/
int main() {
  LLVMContext c;
  Module *m = new Module("test module", c);

  // 创建一个全局变量
  m->getOrInsertGlobal("test_global_var", Type::getInt32Ty(c));
  GlobalVariable *gv = m->getNamedGlobal("test_global_var");
  gv->setLinkage(GlobalValue::CommonLinkage); // 链接类型
  /*llvm 13写法
  函数定义变了 ../output/include/llvm/IR/GlobalObject.h函数 void setAlignment(MaybeAlign Align);
  其中 include/llvm/Support/Alignment.h:109:struct MaybeAlign : public llvm::Optional<Align> {
  */
  // gv->setAlignment(MaybeAlign(4));/*llvm 13写法*/

  /*以下是基于低版本llvm 6.0的写法*/
  // llvm-6.0/include/llvm/IR/GlobalObject.h:64函数 void setAlignment(unsigned Align),参数是unsigned int即可
  gv->setAlignment(4);


  Type *voidTy = Type::getVoidTy(c);
  /*函数在 include/llvm/IR/DerivedTypes.h:102:class FunctionType : public Type {
  /// Create a FunctionType taking no parameters.
  static FunctionType *get(Type *Result, bool isVarArg);
  */
  FunctionType *funcTy = FunctionType::get(voidTy, false);
  Function *func = Function::Create(funcTy, GlobalValue::ExternalLinkage, "test_function IR", m);

  // 创建一个block
  IRBuilder<> builder(c);
  BasicBlock *b = BasicBlock::Create(c, "entry_block", func);
  builder.SetInsertPoint(b);

  verifyFunction(*func);
  m->print(outs(), nullptr);
  return 0;
}
// 编译命令:./output/bin/clang++ -w -o test_gvaria_bin `llvm-config --cxxflags --ldflags --system-libs --libs core` ./04_test_gvaria.cpp

// 运行结果
/*
; ModuleID = 'test module'
source_filename = "test module"

@test_global_var = common global i32, align 4

define void @"test_function IR"() {
entry_block:
}
*/

测试返回值

说明、代码、编译与运行见如下代码注释:

#include "llvm/IR/Module.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/GlobalVariable.h"
// #include "llvm/Support/Alignment.h"
#include "llvm/IR/Constants.h"

using namespace llvm;
/*
若函数无返回值可如之前样式直接结束,这里测试通过Constant类返回常量
*/
int main() {
  LLVMContext c;
  Module *m = new Module("test module", c);

  // 创建一个全局变量
  m->getOrInsertGlobal("test_global_var", Type::getInt32Ty(c));
  GlobalVariable *gv = m->getNamedGlobal("test_global_var");
  gv->setLinkage(GlobalValue::CommonLinkage); // 链接类型
  /*llvm 13写法
  函数定义变了 ../output/include/llvm/IR/GlobalObject.h函数 void setAlignment(MaybeAlign Align);
  其中 include/llvm/Support/Alignment.h:109:struct MaybeAlign : public llvm::Optional<Align> {
  */
  // gv->setAlignment(MaybeAlign(4));/*llvm 13写法*/

  /*以下是基于低版本llvm 6.0的写法*/
  // llvm-6.0/include/llvm/IR/GlobalObject.h:64函数 void setAlignment(unsigned Align),参数是unsigned int即可
  gv->setAlignment(4);


  Type *voidTy = Type::getVoidTy(c);
  /*函数在 include/llvm/IR/DerivedTypes.h:102:class FunctionType : public Type {
  /// Create a FunctionType taking no parameters.
  static FunctionType *get(Type *Result, bool isVarArg);
  */
  FunctionType *funcTy = FunctionType::get(voidTy, false);
  Function *func = Function::Create(funcTy, GlobalValue::ExternalLinkage, "test_function IR", m);

  // 创建一个block
  IRBuilder<> builder(c);
  BasicBlock *b = BasicBlock::Create(c, "entry_block", func);
  builder.SetInsertPoint(b);

  // 创建返回值
  ConstantInt *one = builder.getInt32(1);
  builder.CreateRet(one);

  verifyFunction(*func);
  m->print(outs(), nullptr);
  return 0;
}
// 编译命令:./output/bin/clang++ -w -o test_return_bin `llvm-config --cxxflags --ldflags --system-libs --libs core` ./05_test_return.cpp
// 运行结果
/*
; ModuleID = 'test module'
source_filename = "test module"

@test_global_var = common global i32, align 4

define void @"test_function IR"() {
entry_block:
  ret i32 1
}
*/

测试函数参数

说明、代码、编译与运行见如下代码注释:

#include <vector>
#include "llvm/IR/Module.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/GlobalVariable.h"
// #include "llvm/Support/Alignment.h"
#include "llvm/IR/Constants.h"

using namespace llvm;
using namespace std;
/*
若函数无返回值可如之前样式直接结束,这里测试通过Constant类返回常量
*/
int main() {
  LLVMContext c;
  Module *m = new Module("test module", c);
  IRBuilder<> builder(c);

  // 创建一个全局变量
  m->getOrInsertGlobal("test_global_var", Type::getInt32Ty(c));
  GlobalVariable *gv = m->getNamedGlobal("test_global_var");
  gv->setLinkage(GlobalValue::CommonLinkage); // 链接类型
  /*llvm 13写法
  函数定义变了 ../output/include/llvm/IR/GlobalObject.h函数 void setAlignment(MaybeAlign Align);
  其中 include/llvm/Support/Alignment.h:109:struct MaybeAlign : public llvm::Optional<Align> {
  */
  // gv->setAlignment(MaybeAlign(4));/*llvm 13写法*/

  /*以下是基于低版本llvm 6.0的写法*/
  // llvm-6.0/include/llvm/IR/GlobalObject.h:64函数 void setAlignment(unsigned Align),参数是unsigned int即可
  gv->setAlignment(4);

  // Type *voidTy = Type::getVoidTy(c);// 原来创建void 参数类型
  vector<Type *> paramTys(2, builder.getInt32Ty());
  /*get函数在 include/llvm/IR/DerivedTypes.h:102:class FunctionType : public Type {
  /// This static method is the primary way of constructing a FunctionType.
  static FunctionType *get(Type *Result, ArrayRef<Type*> Params, bool isVarArg);
  */
  FunctionType *funcTy = FunctionType::get(builder.getInt32Ty(), paramTys, false);
  Function *func = Function::Create(funcTy, GlobalValue::ExternalLinkage, "test_function IR", m);
  // 低版本无getArg()函数
  func->getArg(0)->setName("a");
  func->getArg(1)->setName("b");

  // 创建一个block
  BasicBlock *b = BasicBlock::Create(c, "entry_block", func);
  builder.SetInsertPoint(b);

  // 创建返回值
  ConstantInt *one = builder.getInt32(1);
  builder.CreateRet(one);

  verifyFunction(*func);
  m->print(outs(), nullptr);
  return 0;
}
// 编译命令:../output/bin/clang++ -w -o test_func_args_bin `llvm-config --cxxflags --ldflags --system-libs --libs core` ./06_test_func_args.cpp

// 运行结果
/*
; ModuleID = 'test module'
source_filename = "test module"

@test_global_var = common global i32, align 4

define i32 @"test_function IR"(i32 %a, i32 %b) {
entry_block:
  ret i32 1
}

低版本运行结果
; ModuleID = 'test module'
source_filename = "test module"

@test_global_var = common global i32, align 4

define i32 @"test_function IR"(i32, i32) {
entry_block:
  ret i32 1
}
*/

标签:03,llvm,FunctionType,IR,test,include,Type
From: https://www.cnblogs.com/UFO-blogs/p/17601634.html

相关文章

  • 剑指 Offer 03. 数组中重复的数字(简单)
    题目;classSolution{public:intfindRepeatNumber(vector<int>&nums){intresult;unordered_set<int>set;//利用集合寻找重复的数字for(auton:nums){if(set.find(n)==set.end()){//如果set里没找到就加入set......
  • JavaScript基础03
    流程控制语句----循环语句循环条件---可以是次数可以状态whilewhile(循环条件){循环体代码}do-whiledo{循环体代码}while(循环条件)do-while和while的区别do-while至少会执行一次循环体代码因为do-while执行过程是先执行一次循环体代码再判断循环条件执......
  • @RequiredArgsConstructor 用法
    在我们写controller或者Service层的时候,需要注入很多的mapper接口或者另外的service接口,这时候就会写很多的@Autowired注解,代码看起来很乱lombok提供了一个注解:@RequiredArgsConstructor(onConstructor=@_(@Autowired))写在类上可以代替@Autowired注解,需要注意的是在注入时需要......
  • The Report Viewer Web Control HTTP Handler has not been registered in the applic
     system.webServer内加<handlers><addname="ReportViewerWebControlHandler"preCondition="integratedMode"verb="*"path="Reserved.ReportViewerWebControl.axd"type="Microsoft.Reporting.WebForms.Htt......
  • Virtualbox for Apple M1
    等了2年,Virtualbox终于支持AppleM1了,目前还是开发版,下载的话不在首页得找找,在这里:https://www.virtualbox.org/wiki/Testbuilds下载后立即安装,终于可以跑虚机啦!......
  • [刷题笔记] Luogu P2340 [USACO03FALL] Cow Exhibition G
    ProblemSolution乍看可能没有思路。我们注意到本题是牵扯到一头奶牛选or不选的问题,非常自然地想到01背包。接下来我们就尝试将本题背景转换成01背包问题。我们可以将智商转换成容量,情商转换成价值。(当然反过来也可)然后就可以套用01背包板子了:\[f_{i,j}=min(f_{i-1,j},f_{i-1......
  • "account_id like '%':account_id||'%'", hasKey(p, "account_id&quot
    该SQL语句用于进行模糊查询,目标是根据传入的参数p中的account_id来查询sys_account表中的数据。解释如下:"account_idlike'%':account_id||'%'":这是SQL的查询条件部分,其中account_id是表sys_account的一个字段名。like是SQL中的模糊查询操作符,用于进行字符......
  • virtualbox升级
    目的vbox6.x升级到vbox7.x,当前的配置、实例能在新的版本可以正常打开步骤x01、下载vboxhttps://www.virtualbox.org/wiki/Downloadsx02、安装......
  • python3 install 其他包 报:ModuleNotFoundError: No module named '_ctypes' 的问题
    python3install其他包报:ModuleNotFoundError:Nomodulenamed'_ctypes'的问题python2import_ctypes没有问题python3import_ctypes报上述错误,说明_ctypes确实无法导入。据网上资料显示时没有安装libdiff库,但使用yum安装后,还需要重新编译python3。但python3好......
  • Nginx报错Can't open PID file /var/run/nginx.pid (yet?) after start: No such file
    1.关于报错启动nginx服务发现Systemd中存在报错:Can'topenPIDfile/var/run/nginx.pid(yet?)afterstart:Nosuchfileordirectory2.解决办法2.1查看版本和配置选项信息nginx-V参数看到报错中提到的信息2.2定位问题文件增加启动参数配置发现该文件存......