Graal vs C2 compiler optimization


太经典的优化,比如DCE,GVN,常量折叠这些可能没有提及,这些都有的。

Graal

入口点在GraalCompiler.compile里面,分为前端和后端两个部分。前端又可以分成1.构造IR,2.HIR Phase,2. MIR Phasae,4. LIR Phase这四步。后端主要是LIR生成和寄存器分配。

前端

1. 构造HIR

解析字节码,生成HIR。

2. HIR

  • NodeCounterPhase: 算每种类型的节点的数量
  • CanonicalizerPhase/IncrementalCanonicalizerPhase: 类似C2的IGVN
  • InliningPhase:贪婪策略的内联
  • DeadCodeEliminationPhase:死代码消除
  • ConditionalEliminationPhase/IterativeConditionalEliminationPhase:条件常量传播
  • ConvertDeoptimizeToGuardPhase:将推优化转换为GuardNode(后面会转回来)
  • LoopPeelingPhase:loop peeling。类似C2
  • LoopUnswitchingPhase:loop unswitching。类似C2
  • LoopFullUnrollPhase:循环完全展开
  • PartialEscapePhase:流敏感逃逸分析
  • ReadEliminationPhase:读(以及简单的写)消除
  • LoweringPhase:lowering到midtier

3. MIR

  • LockEliminationPhase:锁消除
  • FloatingReadPhase
  • LoopPredication:类似C2,比C2弱一些
  • LoopSafepointEliminationPhase:循环中尽可能减少安全点
  • GuardLoweringPhase:将GuardNode转换为对应控制流结构的DeoptimizeNode
  • InsertGuardFencesPhase
  • VerifyHeapAtReturnPhase:verify一下heap
  • OptimizeDivPhase:类似C2的DivNode/ModNode里面的transform_int_divide
  • RemoveValueProxyPhase
  • LoopSafepointInsertionPhase:给循环插必要的安全点
  • FrameStateAssignmentPhase
  • LoopPartialUnrollPhase:循环部分展开
  • ReassociationPhase:循环不变量重组。类似C2的ReassociateInvariants
  • DeoptimizationGroupingPhase
  • WriteBarrierAdditionPhase:为读写操作插入必要的barrier

4. LIR

  • ProfileCompiledMethodsPhase:为节点加上counter和动态执行次数信息,用于profling
  • LoweringPhase
  • ExpandLogicPhase:逻辑展开,比如把短路运算展开
  • FixReadsPhase:将浮动的读固定下来。
  • UseTrappingNullChecksPhase
  • DeadCodeEliminationPhase:死代码消除
  • PropagateDeoptimizeProbabilityPhase:
  • SchedulePhase:指令调度,将GraalIR下沉到线性代码,类似C2的GCM

后端

  • block ordering
  • LSRA:寄存器分配

后端又可以继续细分:先生成LIR,然后发射最终的二进制代码。其中生成LIR步骤如下
?

C2

入口在Compile::Compile,C2是一个IR基本到最后。C2有些优化藏在很深的地方,或者非常杂的地方,如果漏掉了可以指出。

1. Optimize

  • IGVN:迭代式局部优化,包罗万象。这个轻量级优化再很多优化后面都会跟一个。
    • DIV/MOD优化:参考Division by Invariant Integers using Multiplication by Granlund and Montgomery
    • ...
  • Incrementally inline:增量内联,也是很多优化后面会跟一个
    • PhaseStringOpts:stringbuilder优化相关优化
  • Boxing elimination:内联valueOf调用
  • PhaseVector: 优化Vector_box/unbox
  • PhaseRenumberLive:死代码消除+
  • EA:逃逸分析
    • Lock elimination: 锁消除优化
    • Ptr Compare Opt:指针比较优化
    • alias type lifting: memory alias type提升
  • Macro Elimination:宏节点消除
    • allocation elimination:与EA配合,标量替换
    • boxing elimination:boxing消除
    • lock coarsen:锁合并优化
  • LoopOpts:循环优化合集
    • 死代码消除
    • 最大限度循环展开
    • 特殊的GC barrier针对循环的优化
    • 重组循环不变量
    • Split if(PhaseIdealLoop::split_if_with_blocks)
    • Loop predication(IdealLoopTree::loop_predication)
      • RCE
      • 循环不变量外提
    • Array filling (do_intrinsify_fill)
    • Iteration Splitting
      • 移除循环body里面的死代码
      • 算trip count
      • 将一次循环转换为正常代码
      • 移除空循环
      • partial loop peeling
      • loop peeling
      • loop unswitching
      • 最大限度循环展开
      • 创建pre-main-post三个循环
      • 让pre-post做充分检查,main不做检查
      • main loop multiversioning
      • main loop unrolling
    • 向量化
  • CCP:条件常量传播
  • Macro Expand:宏节点展开
  • Barrier Expand:GC barrier展开
  • Graph Reshaping:最终图变形

2. CodeGen

  • Matcher:指令选择
  • GCM:全局指令调度
    • LCM:局部指令调度
  • RegisterAllocation:寄存器分配
  • Block ordering:基本块重排序
  • Peephole:窥孔优化
  • PostAllocExpand:寄存器分配之后的节点展开
  • PhaseOutput:二进制代码生成

总结:旗鼓相当的对手,可能Graal在逃逸分析/Partial Inline略有优势,C2在循环优化略有优势。