在llvm的clang中添加新的后端和Intrinsic function

博客已迁移到http://www.zhaochaoxing.cn/blog/?p=51
本文记录一下如何在llvm的clang源码中添加一种新的后端(暂时命名为cpu0),并在其中添加Intrinsic function。

一、 涉及到的文件列表:

./src/include/llvm/IR/IntrinsicsCpu0.td
./src/include/llvm/IR/Intrinsics.td
./src/include/llvm/ADT/Triple.h
./src/lib/Support/Triple.cpp
./src/tools/clang/include/clang/Basic/TargetBuiltins.h
./src/tools/clang/include/clang/Basic/BuiltinsCpu0.def
./src/tools/clang/lib/CodeGen/CGBuiltin.cpp
./src/tools/clang/lib/Basic/Targets.cpp

1、./src/include/llvm/IR/IntrinsicsCpu0.td

添加这个文件,命名规则就和其他的后端保持一致好了。
这个文件建议参照着其他后端的写就行了。我添加了两条Intrinsic Function。

def cpu0_32_ty : LLVMType<i32>;

let TargetPrefix = "cpu0" in {

def int_cpu0_max_qb: GCCBuiltin<"__builtin_cpu0_max_qb">,
  Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [Commutative]>;

def int_cpu0_min_qb: GCCBuiltin<"__builtin_cpu0_min_qb">,
  Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [Commutative]>;
}

2、 ./src/include/llvm/IR/Intrinsics.td

需要在这个文件的末尾添加上:

include "llvm/IR/IntrinsicsCpu0.td"

这个文件里面包含了所有后端的关于intrinsic function的文件。

3、 ./src/include/llvm/ADT/Triple.h

在class Triple里面你会发现注册了好多后端,仿照着添加上我们的cpu0。

4、 ./src/lib/Support/Triple.cpp

需要在这个文件里的多个函数中注册后端,把你的后端添加在合适的位置。我们的cpu0是32位的dsp,添加在了54行、106行、217行、292行、840行、895行、926行。

5、 ./src/tools/clang/include/clang/Basic/TargetBuiltins.h

在这个文件的85行添加了如下代码:

  /// \brief cpu0 builtins
  namespace Cpu0 {
    enum {
        LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
#include "clang/Basic/BuiltinsCpu0.def"
        LastTSBuiltin
    };  
  }

其实也是仿照着其他后端写的。

6、 ./src/tools/clang/include/clang/Basic/BuiltinsCpu0.def

这个文件也是跟Intrinsic Function相关的,我添加了如下两行代码:

BUILTIN(__builtin_cpu0_max_qb, "iii", "") 
BUILTIN(__builtin_cpu0_min_qb, "iii", "")

7、 ./src/tools/clang/lib/CodeGen/CGBuiltin.cpp

在1705行添加了两行代码如下:

case llvm::Triple::cpu0:
     return EmitCpu0BuiltinExpr(BuiltinID,E);

在5666行左右找个合适的地方添加了如下代码:

Value *CodeGenFunction::EmitCpu0BuiltinExpr(unsigned BuiltinID,
                                           const CallExpr *E) {

    switch (BuiltinID)
    {    
    case Cpu0::BI__builtin_cpu0_max_qb:{
                            Value *F =CGM.getIntrinsic(Intrinsic::cpu0_max_qb);
                            return Builder.CreateCall(F);
    }    

    case Cpu0::BI__builtin_cpu0_min_qb:{
                            Value *F =CGM.getIntrinsic(Intrinsic::cpu0_min_qb);
                            return Builder.CreateCall(F);
    }    
    default: return nullptr;
    }    
}

8、 ./src/tools/clang/lib/Basic/Targets.cpp

在6337行添加了两行代码:

case llvm::Triple::cpu0:
           return new Cpu0TargetInfo(Triple);

二、 测试

关于intrinsic function的测试代码:

//test.c
void test_main()
{
    int a = 5;
    int b = 10; 
    int c,d;
    c = __builtin_cpu0_max_qb(a, b); 
    c = __builtin_cpu0_min_qb(a, b); 

}

make clang之前先clean一下,然后编译出clang之后,用clang来编译测试文件test.c。会在.bc文件中产生中间代码。

%3 = call i32 @llvm.cpu0.max.qb(i32 %1, i32 %2)
%6 = call i32 @llvm.cpu0.min.qb(i32 %4, i32 %5)

三、 总结

至此,完成了在llvm的clang中添加一个新的后端,并在后端中添加了两条intrinsic function。

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值