接下来就会进入RyuJIT的后端, RyuJIT的后端会根据HIR结构生成LIR结构:
Trees after IR Rationalize ------------------------------------------------------------------------------------------------------------------------------------- BBnum descAddr ref try hnd preds weight [IL range] [jump] [EH region] [flags] ------------------------------------------------------------------------------------------------------------------------------------- BB01 [00000000024701F8] 1 1 [???..???) i internal label target LIR BB02 [0000000002473350] 1 BB01 1 [???..???)-> BB04 ( cond ) internal LIR BB03 [0000000002473460] 1 BB02 0.5 [???..???) internal LIR BB04 [0000000002473240] 2 BB02,BB03 1 [???..???) i internal label target LIR BB05 [0000000002470470] 1 BB04 1 [000..005)-> BB07 (always) i LIR BB06 [0000000002470580] 1 BB07 1 [005..012) i label target gcsafe bwd LIR BB07 [0000000002470690] 2 BB05,BB06 1 [012..01A)-> BB06 ( cond ) i label target bwd LIR BB08 [00000000024707A0] 1 BB07 1 [01A..01B) (return) i LIR ------------------------------------------------------------------------------------------------------------------------------------- ------------ BB01 [???..???), preds={} succs={BB02} N001 ( 0, 0) [000000] ------------ nop void ------------ BB02 [???..???) -> BB04 (cond), preds={BB01} succs={BB03,BB04} N001 ( 3, 10) [000043] ------------ t43 = const(h) long 0x7f95ea870610 token /--* t43 long N002 ( 5, 12) [000044] ------------ t44 = * indir int N003 ( 1, 1) [000045] ------------ t45 = const int 0 /--* t44 int +--* t45 int N004 ( 7, 14) [000046] J------N---- t46 = * == int /--* t46 int N005 ( 9, 16) [000054] ------------ * jmpTrue void ------------ BB03 [???..???), preds={BB02} succs={BB04} N001 ( 14, 5) [000047] --C-G-?----- call help void HELPER.CORINFO_HELP_DBG_IS_JUST_MY_CODE ------------ BB04 [???..???), preds={BB02,BB03} succs={BB05} ------------ BB05 [000..005) -> BB07 (always), preds={BB04} succs={BB07} ( 1, 1) [000004] ------------ il_offset void IL offset: 0 N001 ( 1, 1) [000003] ------------ no_op void ( 1, 3) [000008] ------------ il_offset void IL offset: 1 N001 ( 1, 1) [000005] ------------ t5 = const int 0 /--* t5 int N003 ( 1, 3) [000007] DA---------- * st.lclVar int V01 loc0 ( 0, 0) [000010] ------------ il_offset void IL offset: 3 N001 ( 0, 0) [000009] ------------ nop void ------------ BB06 [005..012), preds={BB07} succs={BB07} ( 1, 1) [000025] ------------ il_offset void IL offset: 5 N001 ( 1, 1) [000024] ------------ no_op void ( 15, 7) [000029] ------------ il_offset void IL offset: 6 N003 ( 1, 1) [000026] ------------ t26 = lclVar int V01 loc0 /--* t26 int arg0 in rdi N005 ( 15, 7) [000027] --C-G------- * call void System.Console.WriteLine ( 1, 1) [000031] ------------ il_offset void IL offset: 12 N001 ( 1, 1) [000030] ------------ no_op void ( 1, 1) [000033] ------------ il_offset void IL offset: 13 N001 ( 1, 1) [000032] ------------ no_op void ( 3, 3) [000039] ------------ il_offset void IL offset: 14 N001 ( 1, 1) [000034] ------------ t34 = lclVar int V01 loc0 N002 ( 1, 1) [000035] ------------ t35 = const int 1 /--* t34 int +--* t35 int N003 ( 3, 3) [000036] ------------ t36 = * + int /--* t36 int N005 ( 3, 3) [000038] DA---------- * st.lclVar int V01 loc0 ------------ BB07 [012..01A) -> BB06 (cond), preds={BB05,BB06} succs={BB08,BB06} ( 10, 6) [000017] ------------ il_offset void IL offset: 18 N001 ( 1, 1) [000012] ------------ t12 = lclVar int V01 loc0 N002 ( 1, 1) [000013] ------------ t13 = const int 3 /--* t12 int +--* t13 int N003 ( 6, 3) [000014] ------------ t14 = * < int /--* t14 int N005 ( 10, 6) [000016] DA---------- * st.lclVar int V02 loc1 ( 7, 6) [000022] ------------ il_offset void IL offset: 23 N001 ( 3, 2) [000018] ------------ t18 = lclVar int V02 loc1 N002 ( 1, 1) [000019] ------------ t19 = const int 0 /--* t18 int +--* t19 int N003 ( 5, 4) [000020] J------N---- t20 = * != int /--* t20 int N004 ( 7, 6) [000021] ------------ * jmpTrue void ------------ BB08 [01A..01B) (return), preds={BB07} succs={} ( 0, 0) [000042] ------------ il_offset void IL offset: 26 N001 ( 0, 0) [000041] ------------ return void我们可以看到在LIR结构里, BasicBlock包含的是GenTree节点的有序列表, 原来是树结构的节点现在都连成了一串.
LIR结构跟最终生成的机器代码结构非常的相似.