O3都是怪物,这里分析的是CLANG怪物,示例程序遍历数组每个元素然后放大。

  1. void foreach_scale(int arr[],int elem){
  2. for(int i=0;i<elem;i++){
  3. arr[i] += (elem*1024);
  4. }
  5. }

这里删去了用处不大的内容,只保留了关键的LLVM IR。通过分析可以看到,如果循环小于8 LLVM IR会使用vector,vector使用SIMD指令高效进行计算,如果大于8则是普通的for形式。

  1. ; Function Attrs: norecurse nounwind
  2. define void @"\01?foreach_scale@@YAXQAHH@Z"(i32* nocapture %arr, i32 %elem) local_unnamed_addr #0 {
  3. entry:
  4. ;elem>0则进入循环,否则整个函数结束
  5. %cmp5 = icmp sgt i32 %elem, 0
  6. br i1 %cmp5, label %for.body.lr.ph, label %for.cond.cleanup
  7. for.body.lr.ph:
  8. %mul = shl i32 %elem, 10;
  9. ; elem8进行比较(utl表示unsigned less than
  10. ; elem<8则跳到正常循环%for.body.preheader,否则跳到%vector.ph
  11. %min.iters.check = icmp ult i32 %elem, 8
  12. br i1 %min.iters.check, label %for.body.preheader, label %vector.ph
  13. for.body.preheader:
  14. ;phi表示SSA里面的φ函数,详细参见LLVM DOC
  15. %i.06.ph = phi i32 [ 0, %for.body.lr.ph ], [ %n.vec, %middle.block ]
  16. br label %for.body
  17. vector.ph:
  18. %n.vec = and i32 %elem, -8
  19. ;首先构造<%mul val val val>,然后shufflevector构造<%mul %mul %mul %mul>
  20. %broadcast.splatinsert9 = insertelement <4 x i32> undef, i32 %mul, i32 0
  21. %broadcast.splat10 = shufflevector <4 x i32> %broadcast.splatinsert9, <4 x i32> undef, <4 x i32> zeroinitializer
  22. ;ditto %broadcast.splatinsert9 == <%mul %mul %mul %mul>
  23. %broadcast.splatinsert11 = insertelement <4 x i32> undef, i32 %mul, i32 0
  24. %broadcast.splat12 = shufflevector <4 x i32> %broadcast.splatinsert11, <4 x i32> undef, <4 x i32> zeroinitializer
  25. br label %vector.body
  26. vector.body:
  27. %index = phi i32 [ 0, %vector.ph ], [ %index.next, %vector.body ]
  28. ;从arr指向的内存加载数据
  29. ;%0现在表示<arr[0] arr[1] arr[2] arr[3]>
  30. %0 = getelementoptr inbounds i32, i32* %arr, i32 %index
  31. %1 = bitcast i32* %0 to <4 x i32>*
  32. %wide.load = load <4 x i32>, <4 x i32>* %1, align 4, !tbaa !3
  33. ;%2表示<arr[4] arr[5] arr[6] arr[7]>
  34. %2 = getelementptr i32, i32* %0, i32 4
  35. %3 = bitcast i32* %2 to <4 x i32>*
  36. %wide.load8 = load <4 x i32>, <4 x i32>* %3, align 4, !tbaa !3
  37. ;<arr[0] arr[1] arr[2] arr[3]>与<%mul %mul %mul %mul>相加,得到vector:%4
  38. ;<arr[4] arr[5] arr[6] arr[7]>与<%mul %mul %mul %mul>相加,得到vector:%5
  39. %4 = add nsw <4 x i32> %wide.load, %broadcast.splat10
  40. %5 = add nsw <4 x i32> %wide.load8, %broadcast.splat12
  41. ;%4,%5写回内存
  42. %6 = bitcast i32* %0 to <4 x i32>*
  43. store <4 x i32> %4, <4 x i32>* %6, align 4, !tbaa !3
  44. %7 = bitcast i32* %2 to <4 x i32>*
  45. store <4 x i32> %5, <4 x i32>* %7, align 4, !tbaa !3
  46. %index.next = add i32 %index, 8
  47. %8 = icmp eq i32 %index.next, %n.vec
  48. br i1 %8, label %middle.block, label %vector.body, !llvm.loop !7
  49. middle.block:
  50. %cmp.n = icmp eq i32 %n.vec, %elem
  51. br i1 %cmp.n, label %for.cond.cleanup, label %for.body.preheader
  52. ;函数返回
  53. for.cond.cleanup:
  54. ret void
  55. for.body:
  56. %i.06 = phi i32 [ %inc, %for.body ], [ %i.06.ph, %for.body.preheader ]‘
  57. ; arr[i] = arr[i]+ (elem*1024),其中%mul=(elem*1024)
  58. %arrayidx = getelementptr inbounds i32, i32* %arr, i32 %i.06
  59. %9 = load i32, i32* %arrayidx, align 4, !tbaa !3
  60. %add = add nsw i32 %9, %mul
  61. store i32 %add, i32* %arrayidx, align 4, !tbaa !3
  62. ; i++
  63. %inc = add nuw nsw i32 %i.06, 1
  64. ; 循环条件i<elem判断
  65. %exitcond = icmp eq i32 %inc, %elem
  66. br i1 %exitcond, label %for.cond.cleanup, label %for.body, !llvm.loop !10
  67. }

clang -O3 for循环的LLVM IR的更多相关文章

  1. LLVM 笔记(五)—— LLVM IR

    ilocker:关注 Android 安全(新手) QQ: 2597294287 LLVM 的 IR (Intermediate Representation) 是其设计中的最重要的部分.优化器在进行 ...

  2. 手写token解析器、语法解析器、LLVM IR生成器(GO语言)

    最近开始尝试用go写点东西,正好在看LLVM的资料,就写了点相关的内容 - 前端解析器+中间代码生成(本地代码的汇编.执行则靠LLVM工具链完成) https://github.com/daibinh ...

  3. [转帖]什么是 LLVM?Swift, Rust, Clang 等语言背后的支持

    要了解用于以编程方式生成机器原生代码的编译器框架是如何让新语言的推出以及对现有的语言进行增强比以往更加容易了. https://www.oschina.net/translate/what-is-ll ...

  4. LLVM,Clang

    在使用xcode时常常会遇到这2个概念,今天总结一下. wiki中关于llvm的描述: LLVM提供了完整編譯系統的中間層,它會將中間語言(IF, Intermediate form)從編譯器取出與最 ...

  5. ios llvm and clang build tools

    1. 使用 libclan g或 clang 插件 包括( libclang 和  Clangkit) 备注: Clangkit,它是基于 clang 提供的功能,用 Objective-C 进行封装 ...

  6. LLVM每日谈之二十 Everything &amp;&amp; Clang driver

    作者:史宁宁(snsn1984) 近期在读<Getting Started with LLVM Core Libraries>.这是读的第一本LLVM的书.非常多地方尽管讲的是自己知道的东 ...

  7. iOS开发系列-LLVM、Clang

    LLVM LLVM计划启动于2000年,最初由University of Illinois at Urbana-Champaign的Chris Lattner主持开展. 我们可以认为LLVM是一个完整 ...

  8. llvm+clang编译安装

    最近一段时间在llvm+clang上做一些东西,所以顺便将自己如何编译安装llvm+clang写了篇文章发在这里,希望能帮助刚接触llvm+clang的童鞋少走一些弯路(我刚接触的时候为了编译安装这个 ...

  9. 编译器:gcc, clang, llvm

    clang Clang是LLVM的前端,可以用来编译C,C++,ObjectiveC等语言.传统的编译器通常分为三个部分,前端(frontEnd),优化器(Optimizer)和后端(backEnd) ...

随机推荐

  1. [更新中]【South使用总结】django开发中使用South进行数据库迁移

    Django开发中使用South进行数据库迁移的使用总结 South的详细资料可产看官方文档http://south.readthedocs.org/en/latest South安装配置 pip i ...

  2. [Apache]如何查看apache服务器的error log(错误日志)

    在进行网页和服务器的测试时, 有时会提醒 500 Internal Server Error: The server encountered an internal error or misconfi ...

  3. SRW锁的使用

    SRWLock的目的和关键段相同:对一个资源进行保护,不让其它线程访问它.但是,与关键段不同的是,SRWLock允许我们区分哪些想要读取资源的值 的线程(读取者线程)和想要更新资源的值的线程(写入者线 ...

  4. vesamenu.c32:not a COM32R image报错解决方案

    今天用U盘刻录安装Linux Mint 的时候,一直出现 vesamenu.c32:not a COM32R image这个报错,查了很久,原因好像是电脑是老电脑的原因.处理的办法很简单,只需要输入l ...

  5. ajax跨域请求-jsonp

    1. 同源策略 ajax之所以需要“跨域”,罪魁祸首就是浏览器的同源策略.即,一个页面的ajax只能获取这个页面相同源或者相同域的数据. 如何叫“同源”或者“同域”呢?——协议.域名.端口号都必须相同 ...

  6. loader的意义和内部机制浅析

    意义: loader可以异步的加载数据到我们的activity或者fragment上面,让加载数据的时候ui线程不阻塞. 而且当数据发生变化的时候,还可以及时更新 具体用法参考 http://deve ...

  7. secureCrt常用命令

    一.常用命令: 1.ls 只列出文件名 (相当于dir,dir也可以使用) -A:列出所有文件,包含隐藏文件. -l:列表形式,包含文件的绝大部分属性. -R:递归显示. --help:此命令的帮助. ...

  8. 第5章 选举模式和ZooKeeper的集群安装 5-1 集群的一些基本概念

    xx就是我们的master,也就是我们的主节点.心跳机制,当有一个节点挂掉之后,整个集群还是可以工作的.选举模式,我们现在的master是正常运行的,但是在某些情况下它宕机了死机了,那么这个时候它这个 ...

  9. 按钮控件JButton的使用

    ---------------siwuxie095                             工程名:TestUI 包名:com.siwuxie095.ui 类名:TestButton. ...

  10. sequelize 用于PostgreSQL,MySQL,SQLite和MSSQL的Node.js / io.js ORM

    安装 Sequelize可通过NPM获得. $ npm install --save sequelize # And one of the following: $ npm install --sav ...