GCC后端及汇编发布(29)
2011-06-18 08:30
477 查看
9.5.9.
其它
从create_automata
返回,然后是
generate
,接着看
expand_automata
。
expand_automata (continued)
9847
if (!have_error
)
9848
{
9849
generate
();
9850
check_automata_insn_issues
();
9851
}
9852
if (!have_error
)
9853
{
9854
form_important_insn_automata_lists
();
9855
if (progress_flag
)
9856
fprintf (stderr
, "Generation of
attributes...");
9857
make_internal_dfa_insn_code_attr
();
9858
make_insn_alts_attr
();
9859
make_default_insn_latency_attr
();
9860
make_bypass_attr
();
9861
if (progress_flag
)
9862
fprintf (stderr, "done/n");
9863
}
9864
ticker_off (&generation_time
);
9865
ticker_off (&all_time
);
9866
if (progress_flag
)
9867
fprintf (stderr
, "All other genattrtab
stuff...");
9868
}
在
expand_automata
的
9850
行,
check_automata_insn_issues
检查是否存在不会被发布的指令类别,这意味着这个
define_insn_reservation
是错误的。
9687
static
void
9688
check_automata_insn_issues
(void)
in genautomata.c
9689
{
9690
automaton_t
automaton;
9691
ainsn_t ainsn, reserv_ainsn;
9692
9693
for
(automaton = description
->first_automaton;
9694
automaton != NULL;
9695
automaton = automaton->next_automaton)
9696
{
9697
for
(ainsn = automaton->ainsn_list;
9698
ainsn != NULL;
9699
ainsn = ainsn->next_ainsn)
9700
if
(ainsn->first_insn_with_same_reservs && !ainsn->arc_exists_p)
9701
{
9702
for
(reserv_ainsn = ainsn;
9703
reserv_ainsn != NULL;
9704
reserv_ainsn = reserv_ainsn->next_same_reservs_insn)
9705
if
(automaton->corresponding_automaton_decl != NULL)
9706
{
9707
if (!w_flag
)
9708
error ("Automaton `%s': Insn
`%s' will never be issued",
9709
automaton->corresponding_automaton_decl->name,
9710
reserv_ainsn->insn_reserv_decl->name);
9711
else
9712
warning
9713
("Automaton `%s': Insn
`%s' will never be issued",
9714
automaton->corresponding_automaton_decl->name,
9715
reserv_ainsn->insn_reserv_decl->name);
9716
}
9717
else
9718
{
9719
if (!w_flag
)
9720
error ("Insn `%s' will never
be issued",
9721
reserv_ainsn->insn_reserv_decl->name);
9722
else
9723
warning ("Insn `%s' will
never be issued",
9724
reserv_ainsn->insn_reserv_decl->name);
9725
}
9726
}
9727
}
9728
}
接着在
expand_automata
的
9854
行,
form_important_insn_automata_lists
过滤掉不包含有效状态迁移的自动机。
9744
static
void
9745
form_important_insn_automata_lists
(void)
in genautomata.c
9746
{
9747
automaton_t
automaton;
9748
state_t
*state_ptr;
9749
decl_t decl;
9750
ainsn_t ainsn;
9751
arc_t arc;
9752
int i;
9753
9754
VLA_PTR_CREATE (automaton_states
, 1500,
9755
"automaton states for
forming important insn automata sets");
9756
/* Mark important
ainsns.
*/
9757
for
(automaton = description
->first_automaton;
9758
automaton != NULL;
9759
automaton = automaton->next_automaton)
9760
{
9761
VLA_PTR_NULLIFY (automaton_states
);
9762
pass_states
(automaton,
add_automaton_state
);
9763
for
(state_ptr = VLA_PTR_BEGIN (automaton_states
);
9764
state_ptr <= (
state_t
*)
VLA_PTR_LAST (automaton_states
);
9765
state_ptr++)
9766
{
9767
for
(arc
= first_out_arc (*state_ptr);
9768
arc != NULL;
9769
arc = next_out_arc (arc))
9770
if (arc->to_state != *state_ptr)
9771
{
9772
if
(!arc->insn->first_insn_with_same_reservs)
9773
abort ();
9774
for
(ainsn = arc->insn;
9775
ainsn != NULL;
9776
ainsn =
ainsn->next_same_reservs_insn)
9777
ainsn->important_p = TRUE;
9778
}
9779
}
9780
}
9781
VLA_PTR_DELETE (automaton_states
);
9782
/* Create automata
sets for the insns.
*/
9783
for
(i = 0; i < description
->decls_num; i++)
9784
{
9785
decl = description
->decls [i];
9786
if (decl->mode == dm_insn_reserv)
9787
{
9788
automata_list_start ();
9789
for
(automaton = description->first_automaton;
9790
automaton != NULL;
9791
automaton =
automaton->next_automaton)
9792
for
(ainsn
= automaton->ainsn_list;
9793
ainsn != NULL;
9794
ainsn = ainsn->next_ainsn)
9795
if (ainsn->important_p
9796
&& ainsn->insn_reserv_decl ==
DECL_INSN_RESERV (decl))
9797
{
9798
automata_list_add (automaton);
9799
break
;
9800
}
9801
DECL_INSN_RESERV (decl)->important_automata_list
9802
= automata_list_finish ();
9803
}
9804
}
9805
}
上面在
9762
行
,
pass_states
从自动机的
start_state
开始通过状态迁移遍历所有的状态
,
并把所遇到的状态放入新创建的缓存
automaton_states
中。
9736
static
void
9737
add_automaton_state
(
state_t
state)
in
genautomata.c
9738
{
9739
VLA_PTR_ADD (automaton_states, state);
9740
}
在这之后,在
9763
行的
FOR
循环接着访问在
automaton_states
中的状态,如果从这个状态我们可以到达其它状态,我们就认为关联的指令是重要的。通过这个方式,我们过滤出单个迁移构成的封闭的环。
接着在
9783
行的
FOR
循环找出上面找到的包含重要
ainsn
的自动机。最后,这个自动机列表将被保存在
automata_list_table
中,这个表构建在
initiate_automata_lists
中。
然后在
expand_automata
的
9857
行,
make_internal_dfa_insn_code_attr
构建一个深度嵌套的条件表达式,它为所有的
define_insn_reservation
返回
insn_num
(模式的序列号,在
gen_insn_reserv
中产生),然后通过名字为“
*internal_dfa_insn_code
”的属性保存之。
9474
static
void
9475
make_internal_dfa_insn_code_attr
(void)
in
genautomata.c
9476
{
9477
int i, insn_num;
9478
decl_t
decl;
9479
rtx condexp;
9480
9481
condexp = rtx_alloc (COND);
9482
XVEC (condexp, 0) = rtvec_alloc ((description
->insns_num - 1) * 2);
9483
XEXP (condexp, 1)
9484
=
make_numeric_value
(DECL_INSN_RESERV
(advance_cycle_insn_decl
)
9485
->insn_num + 1);
9486
for
(i = insn_num = 0; i < description
->decls_num; i++)
9487
{
9488
decl = description
->decls [i];
9489
if (decl->mode == dm_insn_reserv
&& decl != advance_cycle_insn_decl
)
9490
{
9491
XVECEXP (condexp, 0, 2 * insn_num)
9492
= DECL_INSN_RESERV
(decl)->condexp;
9493
XVECEXP (condexp, 0, 2 * insn_num + 1)
9494
=
make_numeric_value
(DECL_INSN_RESERV (decl)->insn_num);
9495
insn_num++;
9496
}
9497
}
9498
if (description
->insns_num != insn_num + 1)
9499
abort ();
9500
make_internal_attr
9501
(attr_printf (sizeof ("*")
9502
+ strlen
(INTERNAL_DFA_INSN_CODE_FUNC_NAME) + 1,
9503
"*%s",
INTERNAL_DFA_INSN_CODE_FUNC_NAME),
9504
condexp, ATTR_STATIC);
9505
}
在上面的
9482
行,
description
的
insns_num
记录了
define_insn_reservation
,包括
advance_cycle_insn_decl
的数目(参考
process_decls
及
add_advance_cycle_insn_decl
)。而在
9486
行,
decls_num
记录了所有为自动机生成所构建的
decl
(参见
expand_automata
的
9818
行,及
add_advance_cycle_insn_decl
)。
接着在
expand_automata
的
9853
行,
make_insn_alts_attr
构建另一个深度嵌套的条件表达式,它返回特定指令的替代的数目,并通过名为“
*insn_alts
”的属性保存之。
9437
static
void
9438
make_insn_alts_attr
(void)
in
genautomata.c
9439
{
9440
int i, insn_num;
9441
decl_t decl;
9442
rtx condexp;
9443
9444
condexp = rtx_alloc (COND);
9445
XVEC (condexp, 0) = rtvec_alloc ((description
->insns_num - 1) * 2);
9446
XEXP (condexp, 1) = make_numeric_value (0);
9447
for
(i = insn_num = 0; i < description
->decls_num; i++)
9448
{
9449
decl = description
->decls [i];
9450
if (decl->mode == dm_insn_reserv
&& decl != advance_cycle_insn_decl
)
9451
{
9452
XVECEXP (condexp, 0, 2 * insn_num)
9453
= DECL_INSN_RESERV
(decl)->condexp;
9454
XVECEXP (condexp, 0, 2 * insn_num + 1)
9455
= make_numeric_value
9456
(DECL_INSN_RESERV
(decl)->transformed_regexp->mode != rm_oneof
9457
? 1 : REGEXP_ONEOF
(DECL_INSN_RESERV (decl)
9458
->transformed_regexp)->regexps_num);
9459
insn_num++;
9460
}
9461
}
9462
if (description
->insns_num != insn_num + 1)
9463
abort ();
9464
make_internal_attr
(attr_printf
(sizeof ("*")
9465
+ strlen (INSN_ALTS_FUNC_NAME) + 1,
9466
"*%s",
INSN_ALTS_FUNC_NAME),
9467
condexp, ATTR_NONE);
9468
}
接着在
expand_automata
的
9854
行,
make_default_insn_latency_attr
构建了另一个条件表达式,它返回指定指令的
default_latency
,并通过名为“
*insn_default_latency
”的属性保存之。
9511
static
void
9512
make_default_insn_latency_attr
(void)
in
genautomata.c
9513
{
9514
int i, insn_num;
9515
decl_t decl;
9516
rtx condexp;
9517
9518
condexp = rtx_alloc (COND);
9519
XVEC (condexp, 0) = rtvec_alloc ((description
->insns_num - 1) * 2);
9520
XEXP (condexp, 1) = make_numeric_value (0);
9521
for
(i = insn_num = 0; i < description
->decls_num; i++)
9522
{
9523
decl = description
->decls [i];
9524
if (decl->mode == dm_insn_reserv
&& decl != advance_cycle_insn_decl
)
9525
{
9526
XVECEXP (condexp, 0, 2 * insn_num)
9527
= DECL_INSN_RESERV
(decl)->condexp;
9528
XVECEXP (condexp, 0, 2 * insn_num + 1)
9529
= make_numeric_value
(DECL_INSN_RESERV (decl)->default_latency);
9530
insn_num++;
9531
}
9532
}
9533
if (description
->insns_num != insn_num + 1)
9534
abort ();
9535
make_internal_attr
(attr_printf
(sizeof ("*")
9536
+ strlen (INSN_DEFAULT_LATENCY_FUNC_NAME)
9537
+ 1, "*%s",
INSN_DEFAULT_LATENCY_FUNC_NAME),
9538
condexp, ATTR_NONE);
9539
}
而在
expand_automata
的
9855
行,
make_bypass_attr
计算指令列表的数目(参考
process_decls
的
2962
行),如果存在指令类别,构建一个向量,它保存具有
bypass_list
的指令类别中的条件部分,并通过名为“
*bypass_p
”的属性保存之。
9545
static
void
9546
make_bypass_attr
(void)
in
genautomata.c
9547
{
9548
int i, bypass_insn;
9549
int bypass_insns_num = 0;
9550
decl_t decl;
9551
rtx result_rtx;
9552
9553
for
(i = 0; i
< description
->decls_num;
i++)
9554
{
9555
decl = description
->decls [i];
9556
if (decl->mode == dm_insn_reserv
9557
&& DECL_INSN_RESERV
(decl)->condexp != NULL
9558
&& DECL_INSN_RESERV
(decl)->bypass_list != NULL)
9559
bypass_insns_num++;
9560
}
9561
if (bypass_insns_num == 0)
9562
result_rtx =
make_numeric_value
(0);
9563
else
9564
{
9565
result_rtx = rtx_alloc (COND);
9566
XVEC (result_rtx, 0) = rtvec_alloc
(bypass_insns_num * 2);
9567
XEXP
(result_rtx, 1) =
make_numeric_value
(0);
9568
9569
for
(i =
bypass_insn = 0; i < description
->decls_num; i++)
9570
{
9571
decl = description
->decls [i];
9572
if (decl->mode == dm_insn_reserv
9573
&& DECL_INSN_RESERV
(decl)->condexp != NULL
9574
&& DECL_INSN_RESERV
(decl)->bypass_list != NULL)
9575
{
9576
XVECEXP (result_rtx, 0, 2 *
bypass_insn)
9577
= DECL_INSN_RESERV
(decl)->condexp;
9578
XVECEXP (result_rtx, 0, 2 * bypass_insn
+ 1)
9579
=
make_numeric_value
(1);
9580
bypass_insn++;
9581
}
9582
}
9583
}
9584
make_internal_attr
(attr_printf
(sizeof ("*")
9585
+ strlen (BYPASS_P_FUNC_NAME)
+ 1,
9586
"*%s",
BYPASS_P_FUNC_NAME),
9587
result_rtx, ATTR_NONE);
9588
}
相关文章推荐