您的位置:首页 > 其它

GCC后端及汇编发布(26)

2011-06-11 09:40 363 查看

9.5.8.2.

数据初始化

在构建自动机之前,首先要分配资源。

9416

static
void

9417

generate

(void)
in
genautomata.c

9418

{

9419

automata_num

= split_argument

;

9420

if
(description

->units_num
< automata_num

)

9421

automata_num

= description

->units_num;

9422

initiate_states

();

9423

initiate_arcs

();

9424

initiate_automata_lists

();

9425

initiate_pass_states
();

9426

initiate_excl_sets
();

9427

initiate_presence_absence_pattern_sets
();

9428

automaton_generation_time

= create_ticker ();

9429

create_automata
();

9430

ticker_off (&automaton_generation_time

);

9431

}

split_argument

保存了自动机生成命令中“
split
”选项的值,它显示了所产生的自动机的数量。当然它不可能大于功能单元的数目。

正如我们之前已经看到的,正在构建的自动机的状态描述了指令执行的每个周期中,资源使用的情况。它由指令发布或周期推进所驱动,而周期推进,现在在引入了伪指令
advance_cycle_insn_decl

之后,也可以被视为指令发布。因此在这里,首先,需要把
CPU
功能单元记录入
units_array


它是指令得以完成的资源,然后为状态位图分配资源。

4221

static
void

4222

initiate_states

(void)

in genautomata.c

4223

{

4224

decl_t
decl;

4225

int i;

4226

4227

VLA_PTR_CREATE (units_container

, description

->units_num,
"units_container");

4228

units_array

4229

= (description

->decls_num && description

->units_num

4230

? VLA_PTR_BEGIN (units_container

) : NULL);

4231

for
(i = 0; i < description

->decls_num; i++)

4232

{

4233

decl = description

->decls [i];

4234

if (decl->mode == dm_unit)

4235

units_array

[DECL_UNIT (decl)->unit_num] =
DECL_UNIT (decl);

4236

}

4237

max_cycles_num

= description

->max_insn_reserv_cycles;

4238

els_in_cycle_reserv

4239

= ((description

->units_num + sizeof
(set_el_t) * CHAR_BIT - 1)

4240

/ (sizeof
(set_el_t) * CHAR_BIT));

4241

els_in_reservs

= els_in_cycle_reserv

* max_cycles_num

;

4242

curr_unique_state_num

= 0;

4243

initiate_alt_states
();

4244

VLA_PTR_CREATE (free_states

, 1500, "free states");

4245

state_table

= htab_create (1500, state_hash,
state_eq_p, (htab_del) 0);

4246

temp_reserv

= alloc_empty_reserv_sets
();

4247

}

first_free_alt_state

将指向由空闲
alt_state
组成的链表,对于某个状态,它将把替代链接起来。它首先在
initiate_alt_states

中被初始化为
null


3669

static
void

3670

initiate_alt_states

(void)

in
genautomata.c

3671

{

3672

first_free_alt_state

= NULL;

3673

}

set_el_t

typedef

unsigned HOST_WIDE_INT
,而
reserv_sets_t

typedef
为其指针类型。显然
reserv_sets_t
的值用于代表功能单元的预订。
els_in_reservs


initiate_states


4241
行计算,相关的还有
max_cycles_num


els_in_cycle_reserv



3744

static
reserv_sets_t

3745

alloc_empty_reserv_sets

(void)

in genautomata.c

3746

{

3747

reserv_sets_t result;

3748

3749

obstack_blank (&irp

, els_in_reservs

* sizeof
(set_el_t));

3750

result = (reserv_sets_t) obstack_base (&irp

);

3751

obstack_finish (&irp

);

3752

memset (result, 0, els_in_reservs

* sizeof
(set_el_t));

3753

return
result;

3754

}

first_free_arc

将指向空闲的
arc
链表,它将记录状态的迁移。

4368

static
void

4369

initiate_arcs

(void)

in genautomata.c

4370

{

4371

first_free_arc

= NULL;

4372

}

同样
first_free_automata_list_el

用于指向空闲的
automaton
的链表。所有的自动机对象将被保存在哈希表中,以保证其唯一性。

4474

static
void

4475

initiate_automata_lists

(void)

in
genautomata.c

4476

{

4477

first_free_automata_list_el

= NULL;

4478

automata_list_table

= htab_create (1500,
automata_list_hash,

4479

automata_list_eq_p, (htab_del) 0);

4480

}

静态变量
curr_state_graph_pass_num

将用于记录状态传递图

passing graph of states

的当前数目。

5986

static
void

5987

initiate_pass_states

(void)

in
genautomata.c

5988

{

5989

curr_state_graph_pass_num

= 0;

5990

}

而对于那些被
exclusion_set
所引用的指令,分配用于记录互斥及的位图资源。这里使用到了
obstack
机制的缓存,有关这部分的内容可以参考前端相关章节。总之,
obstack

GCC
自己管理的内存块。

4544

static
void

4545

initiate_excl_sets

(void)

in
genautomata.c

4546

{

4547

decl_t
decl;

4548

reserv_sets_t unit_excl_set;

4549

unit_set_el_t el;

4550

int i;

4551

4552

obstack_blank (&irp

, els_in_cycle_reserv

* sizeof
(set_el_t));

4553

excl_set

= (reserv_sets_t) obstack_base (&irp

);

4554

obstack_finish (&irp

);

4555

obstack_blank (&irp

, description

->units_num * sizeof
(reserv_sets_t));

4556

unit_excl_set_table

= (reserv_sets_t *)
obstack_base (&irp

);

4557

obstack_finish (&irp

);

4558

/* Evaluate unit
exclusion sets.
*/

4559

for
(i = 0; i
< description

->decls_num;
i++)

4560

{

4561

decl = description

->decls [i];

4562

if (decl->mode == dm_unit)

4563

{

4564

obstack_blank (&irp

, els_in_cycle_reserv

* sizeof
(set_el_t));

4565

unit_excl_set = (reserv_sets_t) obstack_base
(&irp

);

4566

obstack_finish (&irp

);

4567

memset (unit_excl_set, 0, els_in_cycle_reserv

* sizeof
(set_el_t));

4568

for
(el =
DECL_UNIT (decl)->excl_list;

4569

el !=
NULL;

4570

el = el->next_unit_set_el)

4571

{

4572

SET_BIT (unit_excl_set,
el->unit_decl->unit_num);

4573

el->unit_decl->in_set_p = TRUE;

4574

}

4575

unit_excl_set_table

[DECL_UNIT
(decl)->unit_num] = unit_excl_set;

4576

}

4577

}

4578

}

4552

4554
行为
excl_set

分配内存,这个对象的内容将由
get_excl_set

来填充。
4555~4557
行则是为
unit_excl_set_table

分配内存,注意
reserv_sets_t

set_el_t
的指针类型。

前面在
处理

decl的第四个循环



DECL_EXCL

一节,整合了功能单元所有的互斥信息,这里就用上了。
4568
行的循环利用这个互斥信息设置
unit_excl_set_table



同样,
unit_presence_set_table


unit_presence_set_table


unit_absence_set_table


unit_final_absence_set_table

也是通过类似的方式设置的。

4653

static
void

4654

initiate_presence_absence_pattern_sets

(void)

in
genautomata.c

4655

{

4656

decl_t
decl;

4657

int i;

4658

4659

obstack_blank (&irp

, description

->units_num * sizeof
(pattern_reserv_t));

4660

unit_presence_set_table

= (pattern_reserv_t *)
obstack_base (&irp

);

4661

obstack_finish (&irp

);

4662

obstack_blank (&irp

, description

->units_num * sizeof
(pattern_reserv_t));

4663

unit_final_presence_set_table

= (pattern_reserv_t
*) obstack_base (&irp

);

4664

obstack_finish (&irp

);

4665

obstack_blank (&irp

, description

->units_num * sizeof
(pattern_reserv_t));

4666

unit_absence_set_table

4667

4668

= (pattern_reserv_t
*) obstack_base (&irp

);

4669

obstack_finish (&irp

);

4670

obstack_blank (&irp

, description

->units_num * sizeof
(pattern_reserv_t));

4671

unit_final_absence_set_table

= (pattern_reserv_t
*) obstack_base (&irp

);

4672

obstack_finish (&irp

);

4673

/* Evaluate unit
presence/absence sets.

*/

4674

for
(i = 0; i < description

->decls_num; i++)

4675

{

4676

decl = description

->decls [i];

4677

if (decl->mode == dm_unit)

4678

{

4679

unit_presence_set_table

[DECL_UNIT
(decl)->unit_num]

4680

= form_reserv_sets_list (DECL_UNIT
(decl)->presence_list);

4681

unit_presence_set_table

[DECL_UNIT
(decl)->unit_num]

4682

= form_reserv_sets_list (DECL_UNIT
(decl)->final_presence_list);

4683

unit_absence_set_table

[DECL_UNIT
(decl)->unit_num]

4684

= form_reserv_sets_list (DECL_UNIT
(decl)->absence_list);

4685

unit_final_absence_set_table

[DECL_UNIT
(decl)->unit_num]

4686

= form_reserv_sets_list (DECL_UNIT
(decl)->final_absence_list);

4687

}

4688

}

4689

}

下面,
automata_num

的值来自自动机生成命令中的选项“
-split
”。不过,在当前版本中它尚不被支持,参见
initiate_automaton_gen


9664
行。

6804

static
void

6805

create_automata

(void)

in genautomata.c

6806

{

6807

automaton_t curr_automaton;

6808

automaton_t prev_automaton;

6809

decl_t
decl;

6810

int curr_automaton_num;

6811

int i;

6812

6813

if (automata_num

!= 0)

6814

{



6830

}

6831

else

6832

{

6833

curr_automaton_num = 0;

6834

prev_automaton = NULL;

6835

for
(i = 0;
i < description

->decls_num;
i++)

6836

{

6837

decl = description

->decls [i];

6838

if (decl->mode == dm_automaton

6839

&& DECL_AUTOMATON
(decl)->automaton_is_used)

6840

{

6841

curr_automaton = create_node (sizeof
(struct
automaton));

6842

curr_automaton->ainsn_list
=
create_ainsns

();

6843

curr_automaton->corresponding_automaton_decl

6844

= DECL_AUTOMATON (decl);

6845

curr_automaton->next_automaton =
NULL;

6846

DECL_AUTOMATON
(decl)->corresponding_automaton = curr_automaton;

6847

curr_automaton->automaton_order_num = curr_automaton_num;

6848

if
(prev_automaton == NULL)

6849

description

->first_automaton = curr_automaton;

6850

else

6851

prev_automaton->next_automaton =
curr_automaton;

6852

curr_automaton_num++;

6853

prev_automaton = curr_automaton;

6854

}

6855

}

6856

if
(curr_automaton_num == 0)

6857

{

6858

curr_automaton = create_node (sizeof
(struct
automaton));

6859

curr_automaton->ainsn_list =
create_ainsns

();

6860

curr_automaton->corresponding_automaton_decl = NULL;

6861

curr_automaton->next_automaton = NULL;

6862

description

->first_automaton = curr_automaton;

6863

}

6864

units_to_automata_distr

();

6865

}

6835
行的循环首先为所有的自动机创建
automaton
对象,这些对象具有如下定义。

1224

struct
automaton

in
genautomata.c

1225

{

1226

/* The following
field value is the list of insn declarations for

1227

given automaton.
*/

1228

ainsn_t ainsn_list;

1229

/* The following
field value is the corresponding automaton

1230

declaration. This field is not NULL only if
the automatic

1231

partition on automata is not used.
*/

1232

struct
automaton_decl
*corresponding_automaton_decl;

1233

/* The following
field value is the next automaton.
*/

1234

automaton_t next_automaton;

1235

/* The following
field is start state of FA. There are not unit

1236

reservations in the state.
*/

1237

state_t
start_state;

1238

/* The following
field value is number of equivalence classes of

1239

insns (see field `insn_equiv_class_num' in

1240

`insn_reserv_decl').
*/

1241

int insn_equiv_classes_num;

1242

/* The following field value is number of states of final
DFA.
*/

1243

int achieved_states_num;

1244

/* The following
field value is the order number (0, 1, ...) of

1245

given automaton.
*/

1246

int automaton_order_num;

1247

/* The following
fields contain statistics information about

1248

building automaton.
*/

1249

int NDFA_states_num, DFA_states_num;

1250

/* The following field value is defined only if
minimization of DFA

1251

is used.

*/

1252

int minimal_DFA_states_num;

1253

int NDFA_arcs_num, DFA_arcs_num;

1254

/* The following field value is defined only if
minimization of DFA

1255

is used.

*/

1256

int minimal_DFA_arcs_num;

1257

/* The following two members refer for two table
state x ainsn ->

1258

int.

*/

1259

state_ainsn_table_t trans_table;

1260

state_ainsn_table_t state_alts_table;

1261

/* The following
member value is maximal value of min issue delay

1262

for insns of the automaton.
*/

1263

int max_min_delay;

1264

/* Usually min
issue delay is small and we can place several (2, 4,

1265

8) elements in one vector element. So the
compression factor can

1266

be 1 (no compression), 2, 4, 8.
*/

1267

int min_issue_delay_table_compression_factor;

1268

};

205

typedef struct
automaton
*automaton_t
;

in
genautomata.c


automaton
定义中,域
ainsn_list

记录了所有会驱动这个自动机从一个状态到另一个状态的指令。而且我们将会看到,在自动机增长时,
ainsn_list

还会记录涉及的状态。它是在
automaton
定义中最重要的域。在
6842
行,
create_ainsns

为每个自动机构建这个链表。

6746

static
ainsn_t

6747

create_ainsns

(void)

in genautomata.c

6748

{

6749

decl_t

decl;

6750

ainsn_t first_ainsn;

6751

ainsn_t curr_ainsn;

6752

ainsn_t prev_ainsn;

6753

int i;

6754

6755

first_ainsn = NULL;

6756

prev_ainsn = NULL;

6757

for
(i = 0; i
< description

->decls_num;
i++)

6758

{

6759

decl = description

->decls [i];

6760

if (decl->mode == dm_insn_reserv)

6761

{

6762

curr_ainsn = create_node (sizeof
(struct
ainsn
));

6763

curr_ainsn->insn_reserv_decl =
DECL_INSN_RESERV (decl);

6764

curr_ainsn->important_p = FALSE;

6765

curr_ainsn->next_ainsn = NULL;

6766

if
(prev_ainsn == NULL)

6767

first_ainsn = curr_ainsn;

6768

else

6769

prev_ainsn->next_ainsn = curr_ainsn;

6770

prev_ainsn = curr_ainsn;

6771

}

6772

}

6773

return
first_ainsn;

6774

}


6762
行的
ainsn
具有如下定义。看到它与
define_insn_reservation
是一一对应的。

1179

struct
ainsn

in
genautomata.c

1180

{

1181

/* The following
field value is the corresponding insn declaration

1182

of description.
*/

1183

struct
insn_reserv_decl
*insn_reserv_decl;

1184

/* The following
field value is the next insn declaration for an

1185

automaton.

*/

1186

ainsn_t next_ainsn;

1187

/* The following
field is states which characterize automaton unit

1188

reservations of the instruction. The value
can be NULL only if it

1189

is special insn `cycle advancing'.

*/

1190

alt_state_t alt_states;

1191

/* The following
field is sorted list of states which characterize

1192

automaton unit reservations of the
instruction. The value can be

1193

NULL only if it is special insn `cycle
advancing'.

*/

1194

alt_state_t sorted_alt_states;

1195

/* The following field refers the next
automaton insn with

1196

the same reservations.
*/

1197

ainsn_t next_same_reservs_insn;

1198

/* The following
field is flag of the first automaton insn with the

1199

same reservations in the declaration list.
Only arcs marked such

1200

insn is present in the automaton. This
significantly decreases

1201

memory requirements especially when several
automata are

1202

formed.

*/

1203

char first_insn_with_same_reservs;

1204

/* The following
member has nonzero value if there is arc from state of

1205

the automaton marked by the ainsn.
*/

1206

char arc_exists_p;

1207

/* Cyclic list of
insns of an equivalence class is formed with the

1208

aid of the following field.
*/

1209

ainsn_t next_equiv_class_insn;

1210

/* The following
field value is nonzero if the insn declaration is

1211

the first insn declaration with given
equivalence number.
*/

1212

char first_ainsn_with_given_equialence_num;

1213

/* The following
field is number of class of equivalence of insns.

1214

It is necessary because many insns may be
equivalent with the

1215

point of view of pipeline hazards.
*/

1216

int insn_equiv_class_num;

1217

/* The following
member value is TRUE if there is an arc in the

1218

automaton marked by the insn into another
state. In other

1219

words, the insn can change the state of the
automaton.
*/

1220

int important_p;

1221

};

某些
define_insn_reservation
模式可能具有多个功能单元预订计划,这意味着,从某个状态出发,通过不同的计划,将导致不同的状态。域
alt_states

将记录这些从同一个状态开始的不同的状态迁移。在当前版本中,如果在机器描述文件中没有定义自动机,所有
CPU
单元将被分配到单个默认自动机,否则分配在机器描述文件中指定。
units_to_automata_distr

执行这个分配。

6778

static
void

6779

units_to_automata_distr

(void)

in
genautomata.c

6780

{

6781

decl_t

decl;

6782

int i;

6783

6784

for
(i = 0; i < description

->decls_num; i++)

6785

{

6786

decl = description

->decls [i];

6787

if (decl->mode == dm_unit)

6788

{

6789

if
(DECL_UNIT (decl)->automaton_decl == NULL

6790

|| (DECL_UNIT
(decl)->automaton_decl->corresponding_automaton

6791

== NULL))

6792

/* Distribute to
the first automaton.
*/

6793

DECL_UNIT
(decl)->corresponding_automaton_num = 0;

6794

else

6795

DECL_UNIT
(decl)->corresponding_automaton_num

6796

= (DECL_UNIT (decl)->automaton_decl

6797

->corresponding_automaton->automaton_order_num);

6798

}

6799

}

6800

}

实际上设置了单元对象的
corresponding_automaton_num

域就完成了分配。

9.5.8.3.

构建位图及准备状态的数据

所有的资源都已经被分配了。是时候填充位图及构建包容替代的数据。注意即便只出现一个候选,出于统一处理的目的,这个数据仍然需要被创建。替代是从某个状态同时触发的分支,本质上它与非替代(
non-alternative
)没有什么不同。

create_automata

(continued)

6866

NDFA_time

= create_ticker ();

6867

ticker_off (&NDFA_time

);

6868

NDFA_to_DFA_time

= create_ticker ();

6869

ticker_off (&NDFA_to_DFA_time

);

6870

minimize_time

= create_ticker ();

6871

ticker_off (&minimize_time

);

6872

equiv_time

= create_ticker ();

6873

ticker_off (&equiv_time

);

6874

for
(curr_automaton = description

->first_automaton;

6875

curr_automaton != NULL;

6876

curr_automaton =
curr_automaton->next_automaton)

6877

{

6878

if (progress_flag

)

6879

{

6880

if
(curr_automaton->corresponding_automaton_decl == NULL)

6881

fprintf (stderr

, "Prepare anonymous
automaton creation ... ");

6882

else

6883

fprintf (stderr

, "Prepare automaton
`%s' creation...",

6884

curr_automaton->corresponding_automaton_decl->name);

6885

}

6886

create_alt_states
(curr_automaton);

6887

form_ainsn_with_same_reservs
(curr_automaton);

6888

if (progress_flag

)

6889

fprintf (stderr

, "done/n");

6890

build_automaton

(curr_automaton);

6891

enumerate_states

(curr_automaton);

6892

ticker_on (&equiv_time

);

6893

set_insn_equiv_classes (curr_automaton);

6894

ticker_off (&equiv_time

);

6895

}

6896

}

我们前面已经看到,
define_insn_reservation
定义了每个周期中资源的使用情况,而且已经分配了位图来记录每条指令每个周期的
CPU
单元的使用情况。当调度指令时,它将显示该指令是否会与其他已经被调度的指令争夺相同的资源,这对于构建聪明、高效的调度器很重要。
create_alt_states

为替代构建数据,并且为每个替代填充位图。

5589

static
void

5590

create_alt_states

(automaton_t
automaton)

in
genautomata.c

5591

{

5592

struct
insn_reserv_decl *reserv_decl;

5593

5594

for
(curr_ainsn

= automaton->ainsn_list;

5595

curr_ainsn

!= NULL;

5596

curr_ainsn

= curr_ainsn

->next_ainsn)

5597

{

5598

reserv_decl = curr_ainsn

->insn_reserv_decl;

5599

if (reserv_decl != DECL_INSN_RESERV (advance_cycle_insn_decl

))

5600

{

5601

curr_ainsn

->alt_states = NULL;

5602

process_alts_for_forming_states
(reserv_decl->transformed_regexp,

5603

automaton, 0);

5604

curr_ainsn

->sorted_alt_states

5605

= uniq_sort_alt_states (curr_ainsn

->alt_states);

5606

}

5607

}

5608

}

define_insn_reservation

regexp

已经被转换,把“
|
”移到最外面,在替代内部不应该看到“
|
”,即替代内部不会包含替代。下面的函数基于这样的假设(参见
5577
行)。

5556

static
void

5557

process_alts_for_forming_states

(regexp_t
regexp,
in genautomata.c

5558

automaton_t

automaton, int inside_oneof_p)

5559

{

5560

int i;

5561

5562

if (regexp->mode != rm_oneof)

5563

{

5564

alt_state_being_formed

= get_free_alt_state ();

5565

state_being_formed

= get_free_state (1,
automaton);

5566

alt_state_being_formed

->state = state_being_formed

;

5567

/* We inserts in
reverse order but we process alternatives also

5568

i
n reverse order. So we have the same order of alternative

5569

as in the description.
*/

5570

alt_state_being_formed

->next_alt_state = curr_ainsn

->alt_states;

5571

curr_ainsn

->alt_states = alt_state_being_formed

;

5572

(void) process_seq_for_forming_states
(regexp, automaton, 0);

5573

finish_forming_alt_state
(alt_state_being_formed

,
automaton);

5574

}

5575

else

5576

{

5577

if (inside_oneof_p)

5578

abort ();

5579

/* We processes
it in reverse order to get list with the same

5580

order as in the description. See also the
previous

5581

commentary.

*/

5582

for
(i = REGEXP_ONEOF (regexp)->regexps_num - 1; i
>= 0; i--)

5583

process_alts_for_forming_states

(REGEXP_ONEOF (regexp)->regexps [i],

5584

automaton, 1);

5585

}

5586

}

上面在
5564


alt_state_being_formed

是一个
alt_state
的对象

它的定义在下面给出。这个数据为每个
define_insn_reservation
构成了一个链表,其
state

域记录了第一个替代的数据,而
next_alt_state

链接其它替代。
next_sorted_alt_state

保存排序了的替代的数据,这个数据用于区分不同的
define_insn_reservation


1165

struct
alt_state

in
genautomata.c

1166

{

1167

/* The following
field is a deterministic state which characterizes

1168

unit reservations of the instruction.
*/

1169

state_t state
;

1170

/* The following
field refers to the next state which characterizes

1171

unit reservations of the instruction.
*/

1172

alt_state_t next_alt_state;

1173

/* The following
field refers to the next state in sorted list.

*/

1174

alt_state_t next_sorted_alt_state;

1175

};

而在
1169
行,
state_t


typedef

state
*
,而
state
的定义如下。一开始,每个
define_insn_reservation
被与替代一一对应的
state

关联起来。在
1085
行,
state

中的
reservs

域记录了每个周期的资源使用情况。

1078

struct
state

in
genautomata.c

1079

{

1080

/* The following
member value is nonzero if there is a transition by

1081

cycle advancing.
*/

1082

int new_cycle_p;

1083

/* The following field is list of processor
unit reservations on

1084

each cycle.

*/

1085

reserv_sets_t reservs;

1086

/* The following field is unique number of
given state between other

1087

states.

*/

1088

int unique_num;

1089

/* The following
field value is automaton to which given state

1090

belongs.

*/

1091

automaton_t automaton;

1092

/* The following field value is the first arc
output from given

1093

state.

*/

1094

arc_t first_out_arc;

1095

/* The following field is used to form
NDFA.
*/

1096

char it_was_placed_in_stack_for_NDFA_forming;

1097

/* The following field is used to form
DFA.
*/

1098

char it_was_placed_in_stack_for_DFA_forming;

1099

/* The following
field is used to transform NDFA to DFA and DFA

1100

minimization. The field value is not NULL
if the state is a

1101

compound state. In this case the value of
field `unit_sets_list'

1102

is NULL. All states in the list are in the
hash table. The list

1103

is formed through field
`next_sorted_alt_state'. We should

1104

support only one level of nesting
state.
*/

1105

alt_state_t component_states;

1106

/* The following
field is used for passing graph of states.

*/

1107

int pass_num;

1108

/* The list of states belonging to one
equivalence class is formed

1109

with the aid of the following field.
*/

1110

state_t next_equiv_class_state;

1111

/* The two following fields are used during
minimization of a finite

1112

state automaton.
*/

1113

int equiv_class_num_1, equiv_class_num_2;

1114

/* The following
field is used during minimization of a finite state

1115

automaton. The field value is state
corresponding to equivalence

1116

class to which given state belongs.
*/

1117

state_t equiv_class_state;

1118

/* The following
field value is the order number of given state.

1119

The states in final DFA is enumerated with
the aid of the

1120

following field.
*/

1121

int order_state_num;

1122

/* This member is used for passing states for
searching minimal

1123

delay time.

*/

1124

int state_pass_num;

1125

/* The following member is used to evaluate min
issue delay of insn

1126

for a state.
*/

1127

int min_insn_issue_delay;

1128

/* The following
member is used to evaluate max issue rate of the

1129

processor. The value of the member is
maximal length of the path

1130

from given state no containing arcs marked
by special insn `cycle

1131

advancing'.

*/

1132

int longest_path_length;

1133

};

process_seq_for_forming_states

则为每个替代构建当前周期的单元预订的位图(这里为周期
0
)。

5484

static
int

5485

process_seq_for_forming_states

(regexp_t
regexp, automaton_t
automaton,
in genautomata.c

5486

int curr_cycle)

5487

{

5488

int i;

5489

5490

if (regexp == NULL)

5491

return
curr_cycle;

5492

else if (regexp->mode == rm_unit)

5493

{

5494

if (REGEXP_UNIT
(regexp)->unit_decl->corresponding_automaton_num

5495

== automaton->automaton_order_num)

5496

set_state_reserv
(state_being_formed

, curr_cycle,

5497

REGEXP_UNIT
(regexp)->unit_decl->unit_num);

5498

return
curr_cycle;

5499

}

5500

else if (regexp->mode == rm_sequence)

5501

{

5502

for
(i = 0; i < REGEXP_SEQUENCE
(regexp)->regexps_num; i++)

5503

curr_cycle

5504

= process_seq_for_forming_states

5505

(REGEXP_SEQUENCE (regexp)->regexps [i],
automaton, curr_cycle) + 1;

5506

return
curr_cycle;

5507

}

5508

else if (regexp->mode == rm_allof)

5509

{

5510

int finish_cycle = 0;

5511

int cycle;

5512

5513

for
(i = 0; i < REGEXP_ALLOF
(regexp)->regexps_num; i++)

5514

{

5515

cycle = process_seq_for_forming_states
(REGEXP_ALLOF (regexp)

5516

->regexps [i],

5517

automaton, curr_cycle);

5518

if
(finish_cycle < cycle)

5519

finish_cycle = cycle;

5520

}

5521

return
finish_cycle;

5522

}

5523

else

5524

{

5525

if (regexp->mode != rm_nothing)

5526

abort ();

5527

return
curr_cycle;

5528

}

5529

}

单元预订位图由
5496
行的
set_state_reserv

填充。这个位图使用
CPU
周期及
unit_num

做索引,这个位图由静态变量
state_being_formed

表示,并且在
5566

state_being_formed

被赋予
alt_state_being_formed

->state


4160

static
void

4161

set_state_reserv

(state_t
state, int cycle_num, int unit_num)

in genautomata.c

4162

{

4163

set_unit_reserv
(state->reservs, cycle_num, unit_num);

4164

}

3826

static
void

3827

set_unit_reserv

(reserv_sets_t reservs,
int cycle_num, int unit_num)

3828

{

3829

if (cycle_num >= max_cycles_num

)

3830

abort ();

3831

SET_BIT (reservs, cycle_num * els_in_cycle_reserv

3832

* sizeof
(set_el_t) * CHAR_BIT + unit_num);

3833

}

上面的
els_in_cycle_reserv


initiate_states


4238
行初始化。它代表
reservs

的大小。
reservs

是记录周期内单元预订的位图。注意到在这里
unit_num

来自
define_cpu_unit

decl

unit_num

域,它是由
gen_unit

赋予的唯一的值。

回到
process_alts_for_forming_states


alt_state_being_formed


finish_forming_alt_state

插入
state_table



5533

static
void

5534

finish_forming_alt_state

(alt_state_t
alt_state,

in
genautomata.c

5535

automaton_t

automaton ATTRIBUTE_UNUSED)

5536

{

5537

state_t
state_in_table;

5538

state_t
corresponding_state;

5539

5540

corresponding_state = alt_state->state;

5541

state_in_table = insert_state (corresponding_state);

5542

if (state_in_table != corresponding_state)

5543

{

5544

free_state (corresponding_state);

5545

alt_state->state = state_in_table;

5546

}

5547

}

在构建了当前周期的位图之后,
form_ainsn_with_same_reservs

遍历同一个自动机中所有代表
define_insn_reservation

ainsn
对象。变长数组
first_insns

记录使用不同单元预订的
ainsn
,在
5654
行看到,
last_insns

则基本与
first_insns

相同,除非找到使用相同单元预订的另一个
ainsn
对象,彼时这些
ainsn
对象将
next_same_reservs_insn

链接起来,形成一个队列(
queue
),
last_insns

指向最后的
ainsn
对象。

注意使用相同单元预订的
ainsn
对象中,第一个被找出的设置了
first_insn_with_same_reservs

。另外,伪指令
advance_cycle_insn_decl

总是构建一个单独的集合,因为这条指令总是推进
CPU
周期。

5617

static
void

5618

form_ainsn_with_same_reservs

(automaton_t
automaton)

in genautomata.c

5619

{

5620

ainsn_t curr_ainsn;

5621

size_t i;

5622

vla_ptr_t first_insns;

5623

vla_ptr_t last_insns;

5624

5625

VLA_PTR_CREATE (first_insns, 150, "first
insns with the same reservs");

5626

VLA_PTR_CREATE (last_insns, 150, "last
insns with the same reservs");

5627

for
(curr_ainsn = automaton->ainsn_list;

5628

curr_ainsn != NULL;

5629

curr_ainsn = curr_ainsn->next_ainsn)

5630

if (curr_ainsn->insn_reserv_decl

5631

== DECL_INSN_RESERV (advance_cycle_insn_decl

))

5632

{

5633

curr_ainsn->next_same_reservs_insn =
NULL;

5634

curr_ainsn->first_insn_with_same_reservs = 1;

5635

}

5636

else

5637

{

5638

for
(i =
0; i < VLA_PTR_LENGTH (first_insns); i++)

5639

if (alt_states_eq

5640

(curr_ainsn->sorted_alt_states,

5641

((ainsn_t) VLA_PTR (first_insns,
i))->sorted_alt_states))

5642

break
;

5643

curr_ainsn->next_same_reservs_insn =
NULL;

5644

if (i < VLA_PTR_LENGTH (first_insns))

5645

{

5646

curr_ainsn->first_insn_with_same_reservs =
0;

5647

((ainsn_t) VLA_PTR (last_insns,
i))->next_same_reservs_insn

5648

= curr_ainsn;

5649

VLA_PTR (last_insns, i) = curr_ainsn;

5650

}

5651

else

5652

{

5653

VLA_PTR_ADD (first_insns, curr_ainsn);

5654

VLA_PTR_ADD (last_insns, curr_ainsn);

5655

curr_ainsn->first_insn_with_same_reservs = 1;

5656

}

5657

}

5658

VLA_PTR_DELETE (first_insns);

5659

VLA_PTR_DELETE (last_insns);

5660

}

因此在这一步我们可以得到如下形式的数据。
First

last
在函数末尾就被删除了,不过链表保留了下来。




72

:等效类别指令的分组,阶段
1
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: