llvm-6 代码生成实例

1 篇文章 0 订阅
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/IR/TypeBuilder.h"
#include <iostream>

using namespace llvm;


int foo(int x)
{
    return 2 * x;
}

int value = 10;

int main()
{
    static LLVMContext MyGlobalContext;
    LLVMContext &context = MyGlobalContext;
    Module *module = new Module("test", context);

    // 在IR代码中声明一个全局变量`
    GlobalVariable *v = cast<GlobalVariable>(
        module->getOrInsertGlobal("value", Type::getInt32Ty(context)));
    // 在IR中声明一个函数,注意我们并不会在IR中定义foo,我们会将这个IR中声明的函数映射到C++代码中的函数
    FunctionType *foo_type =
      TypeBuilder<int(int), false>::get(context);

    Function *f = cast<Function>(
        module->getOrInsertFunction("foo", foo_type));

    // 在IR中声明一个函数bar,我们会用IR定义这个函数
    FunctionType *bar_type =
      TypeBuilder<int(), false>::get(context);
    Function *bar = cast<Function>(
        module->getOrInsertFunction("bar", bar_type));

    // 创建函数bar的代码块
    BasicBlock *entry = BasicBlock::Create(context, "entry", bar);
    IRBuilder<> builder(entry);

    // 用一个局部变量获取全局变量v的值
    Value *v_IR = builder.CreateLoad(v);
    // 调用函数foo
    Value *ret = builder.CreateCall(f, v_IR);
    // 返回值
    builder.CreateRet(ret);

    InitializeNativeTarget();
    InitializeNativeTargetAsmPrinter();
    InitializeNativeTargetAsmParser();
    ExecutionEngine *ee =
        EngineBuilder(std::unique_ptr<Module>(module)).setEngineKind(EngineKind::JIT).create();

    // 将外部的C++代码中的全局变量映射到IR代码中,IR代码中只有声明
    ee->addGlobalMapping(v, &value);

    // 将外部的C++代码中的全局函数映射到IR代码中,IR代码中只有声明
    ee->addGlobalMapping(f, (void *)foo);

    void *barAddr = ee->getPointerToFunction(bar);
    typedef int (*FuncType)();
    FuncType barFunc = (FuncType)barAddr;
    ee->finalizeObject();
    std::cout << barFunc() << std::endl;
    
    return 0;
}

 

 

编译:

clang++ -O3 ./main.cpp -o test -I/usr/include/llvm-6.0 -I/usr/include/llvm-c-6.0 `llvm-config-6.0 --cxxflags --ldflags --libs --libfiles --system-libs`

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
llvm-mc是一款基于LLVM框架的模拟器,用于将汇编代码翻译成机器码并进行相关操作。其工作流程可以简单概括为以下几步。 首先,llvm-mc会通过命令行参数或者脚本来指定输入的汇编代码文件。然后,它会将这些代码解析为一系列的指令对象。每个指令对象都包含了指令的类型、操作数以及其他属性。 接下来,llvm-mc会对指令对象进行表达式求解和一些优化操作。这些优化包括常量折叠、常量传播和复用等。这些优化可以提高代码的执行效率并减少生成的机器码的大小。 然后,llvm-mc会将优化后的指令对象转化为机器指令。这个过程涉及到指令选择、指令调度和机器寄存器分配等操作。在指令选择阶段,llvm-mc会根据目标架构的特性和约束选择最适合的指令形式。指令调度则是为了优化指令的执行顺序,提高并行度和数据访问效率。机器寄存器分配阶段是为了将虚拟寄存器映射到实际的物理寄存器。 最后,llvm-mc会生成目标机器码。生成的目标机器码可以保存到二进制文件中,也可以直接输出到标准输出。生成的机器码可以在目标架构上直接执行,实现对汇编代码的模拟执行。 综上所述,llvm-mc的工作流程包括汇编代码解析、表达式求解与优化、指令选择与调度以及机器码生成等步骤。通过这些步骤,llvm-mc可以将汇编代码转化为目标机器码并进行相关操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值