BasicBlock: 保存了一组语句, BasicBlock内原则上跳转指令只会出现在最后一个语句
Statement: 一个语句就是一棵树, 在内部Statement也是一个GenTree的子类(GenTreeStmt)
GenTree: 组成树的节点, 有很多不同的类型例如GenTreeUnOp(unary op), GenTreeIntCon(int constant)
有人可能会好奇为什么上面的BasicBlock从02开始, 这是因为01是内部用的block, 里面会保存函数开始时运行的内部处理.
接下来RyuJIT的前端会不断的修改HIR结构, 做出各种变形和优化:
Trees before IR Rationalize ------------------------------------------------------------------------------------------------------------------------------------- BBnum descAddr ref try hnd preds weight [IL range] [jump] [EH region] [flags] ------------------------------------------------------------------------------------------------------------------------------------- BB01 [00000000024701F8] 1 1 [???..???) i internal label target BB02 [0000000002473350] 1 BB01 1 [???..???)-> BB04 ( cond ) internal BB03 [0000000002473460] 1 BB02 0.5 [???..???) internal BB04 [0000000002473240] 2 BB02,BB03 1 [???..???) i internal label target BB05 [0000000002470470] 1 BB04 1 [000..005)-> BB07 (always) i BB06 [0000000002470580] 1 BB07 1 [005..012) i label target gcsafe bwd BB07 [0000000002470690] 2 BB05,BB06 1 [012..01A)-> BB06 ( cond ) i label target bwd BB08 [00000000024707A0] 1 BB07 1 [01A..01B) (return) i ------------------------------------------------------------------------------------------------------------------------------------- ------------ BB01 [???..???), preds={} succs={BB02} ***** BB01, stmt 1 ( 0, 0) [000001] ------------ * stmtExpr void (IL ???... ???) N001 ( 0, 0) [000000] ------------ \--* nop void ------------ BB02 [???..???) -> BB04 (cond), preds={BB01} succs={BB03,BB04} ***** BB02, stmt 2 ( 9, 16) [000055] ------------ * stmtExpr void (IL ???... ???) N005 ( 9, 16) [000054] ------------ \--* jmpTrue void N003 ( 1, 1) [000045] ------------ | /--* const int 0 N004 ( 7, 14) [000046] J------N---- \--* == int N002 ( 5, 12) [000044] ------------ \--* indir int N001 ( 3, 10) [000043] ------------ \--* const(h) long 0x7f95ea870610 token ------------ BB03 [???..???), preds={BB02} succs={BB04} ***** BB03, stmt 3 ( 14, 5) [000056] ------------ * stmtExpr void (IL ???... ???) 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} ***** BB05, stmt 4 ( 1, 1) [000004] ------------ * stmtExpr void (IL 0x000...0x000) N001 ( 1, 1) [000003] ------------ \--* no_op void ***** BB05, stmt 5 ( 1, 3) [000008] ------------ * stmtExpr void (IL 0x001...0x002) N001 ( 1, 1) [000005] ------------ | /--* const int 0 N003 ( 1, 3) [000007] -A------R--- \--* = int N002 ( 1, 1) [000006] D------N---- \--* lclVar int V01 loc0 ***** BB05, stmt 6 ( 0, 0) [000010] ------------ * stmtExpr void (IL 0x003...0x003) N001 ( 0, 0) [000009] ------------ \--* nop void ------------ BB06 [005..012), preds={BB07} succs={BB07} ***** BB06, stmt 7 ( 1, 1) [000025] ------------ * stmtExpr void (IL 0x005...0x005) N001 ( 1, 1) [000024] ------------ \--* no_op void ***** BB06, stmt 8 ( 15, 7) [000029] ------------ * stmtExpr void (IL 0x006...0x00C) N005 ( 15, 7) [000027] --C-G------- \--* call void System.Console.WriteLine N003 ( 1, 1) [000026] ------------ arg0 in rdi \--* lclVar int V01 loc0 ***** BB06, stmt 9 ( 1, 1) [000031] ------------ * stmtExpr void (IL 0x00C... ???) N001 ( 1, 1) [000030] ------------ \--* no_op void ***** BB06, stmt 10 ( 1, 1) [000033] ------------ * stmtExpr void (IL 0x00D...0x00D) N001 ( 1, 1) [000032] ------------ \--* no_op void ***** BB06, stmt 11 ( 3, 3) [000039] ------------ * stmtExpr void (IL 0x00E...0x011) N002 ( 1, 1) [000035] ------------ | /--* const int 1 N003 ( 3, 3) [000036] ------------ | /--* + int N001 ( 1, 1) [000034] ------------ | | \--* lclVar int V01 loc0 N005 ( 3, 3) [000038] -A------R--- \--* = int N004 ( 1, 1) [000037] D------N---- \--* lclVar int V01 loc0 ------------ BB07 [012..01A) -> BB06 (cond), preds={BB05,BB06} succs={BB08,BB06} ***** BB07, stmt 12 ( 10, 6) [000017] ------------ * stmtExpr void (IL 0x012...0x016) N002 ( 1, 1) [000013] ------------ | /--* const int 3 N003 ( 6, 3) [000014] ------------ | /--* < int N001 ( 1, 1) [000012] ------------ | | \--* lclVar int V01 loc0 N005 ( 10, 6) [000016] -A------R--- \--* = int N004 ( 3, 2) [000015] D------N---- \--* lclVar int V02 loc1 ***** BB07, stmt 13 ( 7, 6) [000022] ------------ * stmtExpr void (IL 0x017...0x018) N004 ( 7, 6) [000021] ------------ \--* jmpTrue void N002 ( 1, 1) [000019] ------------ | /--* const int 0 N003 ( 5, 4) [000020] J------N---- \--* != int N001 ( 3, 2) [000018] ------------ \--* lclVar int V02 loc1 ------------ BB08 [01A..01B) (return), preds={BB07} succs={} ***** BB08, stmt 14 ( 0, 0) [000042] ------------ * stmtExpr void (IL 0x01A...0x01A) N001 ( 0, 0) [000041] ------------ \--* return void上面的内容目前可以不用理解, 我贴出来只是为了说明HIR结构经过了转换和变形.