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在循环优化略有优势。