您的位置:首页 > 其它

GCC后端及汇编发布(27-续)

2011-06-11 17:14 323 查看
build_automaton (continued)

6418

if (progress_flag

)

6419

fprintf (stderr

, " done/n");

6420

ticker_off (&NDFA_time

);

6421

count_states_and_arcs
(automaton, &states_num, &arcs_num);

6422

automaton->NDFA_states_num = states_num;

6423

automaton->NDFA_arcs_num = arcs_num;

6424

ticker_on (&NDFA_to_DFA_time

);

6425

if (progress_flag

)

6426

{

6427

if (automaton->corresponding_automaton_decl
== NULL)

6428

fprintf (stderr

, "Make anonymous
DFA");

6429

else

6430

fprintf (stderr

, "Make DFA `%s'",

6431

automaton->corresponding_automaton_decl->name);

6432

fprintf (stderr

, " (1 dot is 100 new
states):");

6433

}

count_states_and_arcs

计算指定自动机的状态及迁移的数目。

6387

static
void

6388

count_states_and_arcs

(automaton_t
automaton, int *states_num,
in genautomata.c

6389

int *arcs_num)

6390

{

6391

curr_counted_states_num

= 0;

6392

curr_counted_arcs_num

= 0;

6393

pass_states
(automaton, incr_states_and_arcs_nums
);

6394

*states_num = curr_counted_states_num

;

6395

*arcs_num = curr_counted_arcs_num

;

6396

}

5978

static
void

5979

pass_states

(automaton_t
automaton, void (*applied_func) (state_t
state)) in genautomata.c

5980

{

5981

curr_state_graph_pass_num

++;

5982

pass_state_graph
(automaton->start_state, applied_func
);

5983

}

上面在
6394
行,
curr_state_graph_pass_num

确保每个状态将仅会被计算一次。在下面的
5966
行我们可以看到这一点。

5961

static
void

5962

pass_state_graph

(state_t
start_state, void (*applied_func) (state_t
state))
in genautomata.c

5963

{

5964

arc_t arc;

5965

5966

if (start_state->pass_num == curr_state_graph_pass_num

)

5967

return
;

5968

start_state->pass_num = curr_state_graph_pass_num

;

5969

(*applied_func
)
(start_state);

5970

for
(arc = first_out_arc
(start_state);

5971

arc != NULL;

5972

arc = next_out_arc (arc))

5973

pass_state_graph
(arc->to_state, applied_func);

5974

}

对于每个状态,调用
incr_states_and_arcs_nums



6376

static
void

6377

incr_states_and_arcs_nums

(state_t
state)
in
genautomata.c

6378

{

6379

arc_t arc;

6380

6381

curr_counted_states_num

++;

6382

for
(arc = first_out_arc
(state); arc != NULL; arc = next_out_arc (arc))

6383

curr_counted_arcs_num

++;

6384

}

现在是时候把
NDFA
转换为
DFA
了。继续看
build_automaton



build_automaton (continued)

6434

NDFA_to_DFA
(automaton);

6435

if (progress_flag

)

6436

fprintf (stderr

, " done/n");

6437

ticker_off (&NDFA_to_DFA_time

);

6438

count_states_and_arcs
(automaton, &states_num, &arcs_num);

6439

automaton->DFA_states_num = states_num;

6440

automaton->DFA_arcs_num = arcs_num;

6441

if (!no_minimization_flag

)

6442

{

6443

ticker_on (&minimize_time

);

6444

if (progress_flag

)

6445

{

6446

if
(automaton->corresponding_automaton_decl == NULL)

6447

fprintf (stderr, "Minimize
anonymous DFA...");

6448

else

6449

fprintf (stderr

,
"Minimize DFA `%s'...",

6450

automaton->corresponding_automaton_decl->name);

6451

}

6452

minimize_DFA
(automaton);

6453

if (progress_flag

)

6454

fprintf (stderr

, "done/n");

6455

ticker_off (&minimize_time

);

6456

count_states_and_arcs
(automaton, &states_num, &arcs_num);

6457

automaton->minimal_DFA_states_num =
states_num;

6458

automaton->minimal_DFA_arcs_num =
arcs_num;

6459

}

6460

}

在这里转换
NDFA

DFA
的算法很简单。对于我们的例子,从
start_state

状态出发,可以迁移到
SA

SB

SC
状态。为了解决这个非确定性,我们构建了一个新状态
A’

A’ = {SA

SB

SC} –
这意味着它是一个在状态
S
下由类别为
(A|B|C)
的指令所触发的组合状态,它具有所有从状态
SA

SB

SC
出发的迁移。看到这个从状态
S

A’
的迁移,现在是确定性的。对所有具有非确定性迁移的状态重复上述步骤,直到不存在这样的状态。

为了更好地清楚这个算法,考虑以下自动机。




74


NDFA
转换到
DFA
的例子,步骤
1

除了状态
S
以外,从每个状态出发,可以找到至少一个闭环

对于可行的芯片这是个必须条件,因为任意开放的节点意味着芯片将死在那一点上。并且注意到初始状态(
S
)不能有进入的迁移。这个自动机例子是一个
NDFA
,看到从状态
S
到状态
A1
的迁移是非确定性的。




75


NDFA
转换到
DFA
的例子,步骤
2

在状态
A1

A2
上应用这个算法,我们可以得到上图。状态
A12
仍然是非确定性的,因为指令类别
ib
可以触发两个迁移。看到状态
A12
是从状态
A1

A2
构建的复合状态,现在我们不能确定其单元预订了。不过,我们不再需要单元预订,我们所需要的仅是状态及其之间的迁移。




76


NDFA
转换到
DFA
的例子,步骤
3

又,合并状态
B1

B2
,我们得到上图,不过这个状态仍然是非确定性的,因为
advance_cycle_insn_decl

将触发两个状态迁移。看到这个状态
B12
甚至不能在前面自动机生成过程中存在。




77


NDFA
转换到
DFA
的例子,步骤
4

最后修改出的确定性自动机显示于上图。注意到这个确定性版本及非确定性版本,仅从指令发布机会的意义上而言,是相等的。

5917

static
void

5918

NDFA_to_DFA

(automaton_t
automaton)

5919

{

5920

state_t
start_state;

5921

state_t
state;

5922

decl_t
decl;

5923

vla_ptr_t state_stack;

5924

int i;

5925

int states_n;

5926

5927

VLA_PTR_CREATE (state_stack, 150, "state
stack");

5928

/* Create the start
state (empty state).
*/

5929

start_state = automaton->start_state;

5930

start_state->it_was_placed_in_stack_for_DFA_forming
= 1;

5931

VLA_PTR_ADD (state_stack, start_state);

5932

states_n = 1;

5933

while
(VLA_PTR_LENGTH (state_stack) != 0)

5934

{

5935

state = VLA_PTR (state_stack,
VLA_PTR_LENGTH (state_stack) - 1);

5936

VLA_PTR_SHORTEN (state_stack, 1);

5937

form_arcs_marked_by_insn
(state);

5938

for
(i = 0; i < description

->decls_num;
i++)

5939

{

5940

decl = description

->decls [i];

5941

if (decl->mode == dm_insn_reserv

5942

&& create_composed_state

5943

(state, DECL_INSN_RESERV
(decl)->arcs_marked_by_insn,

5944

&state_stack))

5945

{

5946

states_n++;

5947

if (progress_flag

&& states_n % 100 == 0)

5948

fprintf (stderr

, ".");

5949

}

5950

}

5951

}

5952

VLA_PTR_DELETE (state_stack);

5953

}

记住对于非确定性自动机,在我们上面的例子中,将评估
define_insn_reservation
中的每个替代;而对于确定性自动机,将仅评估第一个合格的替代。从这之后,这将形成很大的区别。事实上,当替代以确定性方式来处理时,构建出的自动机已经就是确定性的。

5787

static
void

5788

form_arcs_marked_by_insn

(state_t
state)

in
genautomata.c

5789

{

5790

decl_t

decl;

5791

arc_t arc;

5792

int i;

5793

5794

for
(i = 0; i < description

->decls_num; i++)

5795

{

5796

decl = description

->decls [i];

5797

if (decl->mode == dm_insn_reserv)

5798

DECL_INSN_RESERV (decl)->arcs_marked_by_insn
= NULL;

5799

}

5800

for
(arc =
first_out_arc (state); arc != NULL; arc = next_out_arc (arc))

5801

{

5802

if (arc->insn == NULL)

5803

abort ();

5804

arc->next_arc_marked_by_insn

5805

= arc->insn->insn_reserv_decl->arcs_marked_by_insn;

5806

arc->insn->insn_reserv_decl->arcs_marked_by_insn = arc;

5807

}

5808

}

在跨越发布包含替代的指令类别的状态中,为了把这些特殊的迁移与其它确定性迁移区分开来,
form_arcs_marked_by_insn

将通过
next_arc_marked_by_insn

域链接这些迁移(以
arc
的形式)。

在非确定性的例子中,对于
start_state

将得到如下。

对于指令类别(
E|F


arcSF->next_arc_marked_by_insn = NULL (arcSF->to_state =
stateSF)

arcSF->insn->insn_reserv_decl->arcs_marked_by_insn = arcSF

arcSE->next_arc_marked_by_insn = arcSF (arcSE->to_state =
stateSE)

arcSE->insn->insn_reserv_decl->arcs_marked_by_insn = arcSE
最后的值)

对于指令类别(
A|B|C


arcSC->next_arc_marked_by_insn = NULL (arcSC->to_state =
stateSC)

arcSC->insn->insn_reserv_decl->arcs_marked_by_insn = arcSC

arcSB->next_arc_marked_by_insn = arcSC (arcSB->to_state = stateSB)

arcSB->insn->insn_reserv_decl->arcs_marked_by_insn = arcSB

arcSA->next_arc_marked_by_insn = arcSB (arcSA->to_state =
stateSA)

arcSA->insn->insn_reserv_decl->arcs_marked_by_insn = arcSA
最后的值)

(注意到上面的两部分被
state


arc


next_out_arc

域链接起来)

在确定性的例子中,对于
start_state

将得到如下。

对于指令类别
A

arcSA->next_arc_marked_by_insn = NULL (arcSA->to_state =
stateSA)

arcSA->insn->insn_reserv_decl->arcs_marked_by_insn = arcSA

对于指令类别
E

arcSE->next_arc_marked_by_insn = NULL (arcSE->to_state =
stateSE)

arcSE->insn->insn_reserv_decl->arcs_marked_by_insn = arcSE

(注意到上面的两部分被
state


arc


next_out_arc

域链接起来)

显示在下图,
insn (x1|x2|x3)
代表在
define_insn_reservation
中具有三个替代:
x1

x2

x3
的指令类别。在图中两个
arcs_marked_by_insn

是对应不同
insn_reserv_decl
的域

对应
define_insn_reservations
模式的
decl





78


构建
DFA
,阶段
2

现在在
state_stack

里仅是
state_start

。对于确定性自动机,
create_composed_state

是简单的,因为
next_arc_marked_by_insn

总是
NULL
(参见
5853
行的检查)。它将把在
5382
行获取的
to_state

压入
state_stack

并返回。现在在
state_stack

里,是
SA

SE


在非确定性自动机的例子中,域
component_states

用于所谓的复合状态(例如,上图中的状态
A12

B12

xy
)。对于具有替代
A

B

C
的指令类别来说,第一个参数
original_state


start_state

,而第二个参数
arcs_marked_by_insn

指向上图中的
arcs_marked_by_insn

,它是
insn_reserv_decl – define_insn_reservation
模式的
decl
,中的域。

5814

static
int

5815

create_composed_state

(state_t
original_state, arc_t arcs_marked_by_insn,
in
genautomata.c

5816

vla_ptr_t *state_stack)

5817

{

5818

state_t
state;

5819

alt_state_t alt_state, curr_alt_state;

5820

alt_state_t new_alt_state;

5821

arc_t curr_arc;

5822

arc_t next_arc;

5823

state_t
state_in_table;

5824

state_t
temp_state;

5825

alt_state_t canonical_alt_states_list;

5826

int alts_number;

5827

int new_state_p = 0;

5828

5829

if (arcs_marked_by_insn == NULL)

5830

return
new_state_p;

5831

if
(arcs_marked_by_insn->next_arc_marked_by_insn == NULL)

5832

state = arcs_marked_by_insn->to_state;

5833

else

5834

{

5835

if (!ndfa_flag

)

5836

abort ();

5837

/* Create
composed state.
*/

5838

state = get_free_state (0,
arcs_marked_by_insn->to_state->automaton);

5839

curr_alt_state = NULL;

5840

for
(curr_arc = arcs_marked_by_insn;

5841

curr_arc != NULL;

5842

curr_arc =
curr_arc->next_arc_marked_by_insn)

5843

if
(curr_arc->to_state->component_states == NULL)

5844

{

5845

new_alt_state = get_free_alt_state ();

5846

new_alt_state->next_alt_state =
curr_alt_state;

5847

new_alt_state->state =
curr_arc->to_state;

5848

curr_alt_state = new_alt_state;

5849

}

5850

else

5851

for
(alt_state = curr_arc->to_state->component_states;

5852

alt_state != NULL;

5853

alt_state =
alt_state->next_sorted_alt_state)

5854

{

5855

new_alt_state = get_free_alt_state
();

5856

new_alt_state->next_alt_state =
curr_alt_state;

5857

new_alt_state->state =
alt_state->state;

5858

if
(alt_state->state->component_states != NULL)

5859

abort ();

5860

curr_alt_state = new_alt_state;

5861

}

5862

/* There are
not identical sets in the alt state list.

*/

5863

canonical_alt_states_list = uniq_sort_alt_states
(curr_alt_state);

5864

if
(canonical_alt_states_list->next_sorted_alt_state == NULL)

5865

{

5866

temp_state = state;

5867

state =
canonical_alt_states_list->state;

5868

free_state (temp_state);

5869

}

5870

else

5871

{

5872

state->component_states =
canonical_alt_states_list;

5873

state_in_table = insert_state (state);

5874

if (state_in_table != state)

5875

{

5876

if
(!state_in_table->it_was_placed_in_stack_for_DFA_forming)

5877

abort ();

5878

free_state (state);

5879

state = state_in_table;

5880

}

5881

else

5882

{

5883

if
(state->it_was_placed_in_stack_for_DFA_forming)

5884

abort ();

5885

new_state_p = 1;

5886

for
(curr_alt_state = state->component_states;

5887

curr_alt_state != NULL;

5888

curr_alt_state =
curr_alt_state->next_sorted_alt_state)

5889

for
(curr_arc = first_out_arc (curr_alt_state->state);

5890

curr_arc != NULL;

5891

curr_arc = next_out_arc (curr_arc))

5892

add_arc
(state, curr_arc->to_state, curr_arc->insn, 1);

5893

}

5894

arcs_marked_by_insn->to_state =
state;

5895

for
(alts_number = 0,

5896

curr_arc =
arcs_marked_by_insn->next_arc_marked_by_insn;

5897

curr_arc != NULL;

5898

curr_arc = next_arc)

5899

{

5900

next_arc =
curr_arc->next_arc_marked_by_insn;

5901

remove_arc (original_state,
curr_arc);

5902

alts_number++;

5903

}

5904

arcs_marked_by_insn->state_alts =
alts_number;

5905

}

5906

}

5907

if
(!state->it_was_placed_in_stack_for_DFA_forming)

5908

{

5909

state->it_was_placed_in_stack_for_DFA_forming
= 1;

5910

VLA_PTR_ADD (*state_stack, state);

5911

}

5912

return
new_state_p;

5913

}

在我们例子中,
curr_alt_state

是一个链表,形如:
curr_alt_state(SA)->next_alt_state(SB)->
next_alt_state(SC)
。然后这个链表被传递给
uniq_sort_alt_states

,这个函数排序
alt_states_list

,并从这个链表中移去重复的
alt_state
。在这里,对于我们的非确定性例子,这个链表没有改变。


5864
行,如果
next_sorted_alt_state

不是
NULL
,那么在
5872
行的
state

是新构建的,它必然不出现在
state_table

里,因此我们进入
5882
行。在
create_composed_state

中构建的数据显示如下图。




79


构建
DFA
,阶段
3

正如我们之前提及的,一旦构建了新状态,当前状态的所有替代的迁移目标,就被设置为这个新状态的迁移目标。然后当前状态,在理论上,可以确定性地迁移到这个新状态,注意到在图中
arcSA
被留下了,蓝色的域被修改了;而其它用于当前状态替代的
arc
都被移除了。接着,这个新状态将被压入
state_stack

。然后在这个状态上重复上面的步骤。直到
state_stack

中没有状态(即,没有状态具有非确定性迁移),
NDFA_to_DFA

才退出。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: