天天看點

GCC-3.4.6源代碼學習筆記(48續)

4.2.10. 評估算術操作的代價

4.2.10.1. 建立僞函數上下文

回到backend_init,下來是init_dummy_function_start。它初始化了rtl的展開機制,因而我們可以進行一些簡單序列的生成。

6518 void

6519 init_dummy_function_start (void)                                                                      in function.c

6520 {

6521   prepare_function_start (NULL);

6522 }

在這裡調用了prepare_function_start來建立僞函數上下文cfun,因為下面的初始化函數需要産生rtl(在正式的代碼編譯中,隻有完成代碼解析及前端的優化後,才會生成rtl的表示形式,并交予後端)。

6482 static void

6483 prepare_function_start (tree fndecl)                                                            in function.c

6484 {

6485   if (fndecl && DECL_SAVED_INSNS (fndecl))

6486     cfun = DECL_SAVED_INSNS (fndecl);

6487   else

6488     allocate_struct_function (fndecl);

6489   init_emit ();

6490   init_varasm_status (cfun);

6491   init_expr ();

6492

6493   cse_not_expected = ! optimize;

6494

6495   

6496   caller_save_needed = 0;

6497

6498   

6499   reg_renumber = 0;

6500

6501   

6503   rtx_equal_function_value_matters = 1;

6504

6505   

6506   virtuals_instantiated = 0;

6507

6508   

6509   generating_concat_p = 1;

6510

6511   

6512   frame_pointer_needed = 0;

6513 }

結構體function儲存了,描述目前被編譯函數狀态的所有重要的,全局及靜态變量。

176    struct function GTY(())                                                                            in function.h

177    {

178      struct eh_status *eh;

179      struct stmt_status *stmt;

180      struct expr_status *expr;

181      struct emit_status *emit;

182      struct varasm_status *varasm;

183   

184     

185   

186     

187      tree decl;

188   

189     

190      struct function *outer;

191   

192     

195      int pops_args;

196   

197     

200      int args_size;

201   

202     

205      int pretend_args_size;

206   

207     

209      int outgoing_args_size;

210   

211      

213      rtx arg_offset_rtx;

214   

215     

217      CUMULATIVE_ARGS args_info;

218   

219     

223      rtx return_rtx;

224   

225     

226      rtx internal_arg_pointer;

227   

228     

230      const char *cannot_inline;

231   

232     

234      struct initial_value_struct *hard_reg_initial_vals;

235   

236     

237      int x_function_call_count;

238   

239     

242      tree x_nonlocal_labels;

243   

244     

248      rtx x_nonlocal_goto_handler_slots;

249   

250     

252      rtx x_nonlocal_goto_handler_labels;

253   

254     

257      rtx x_nonlocal_goto_stack_level;

258   

259     

263      rtx x_cleanup_label;

264   

265     

268      rtx x_return_label;

269   

270     

273      rtx x_naked_return_label;

274   

275     

276      rtx computed_goto_common_label;

277      rtx computed_goto_common_reg;

278   

279     

281      rtx x_save_expr_regs;

282   

283     

285      rtx x_stack_slot_list;

286   

287     

288      tree x_rtl_expr_chain;

289   

290     

292      rtx x_tail_recursion_label;

293   

294     

295      rtx x_tail_recursion_reentry;

296   

297     

301      rtx x_arg_pointer_save_area;

302   

303     

306      rtx x_clobber_return_insn;

307   

308     

311       HOST_WIDE_INT x_frame_offset;

312   

313     

316      tree x_context_display;

317   

318     

325      tree x_trampoline_list;

326   

327     

328      rtx x_parm_birth_insn;

329   

330     

332      rtx x_last_parm_insn;

333   

334     

336      unsigned int x_max_parm_reg;

337   

338     

342      rtx * GTY ((length ("%h.x_max_parm_reg"))) x_parm_reg_stack_loc;

343   

344     

345      struct temp_slot *x_temp_slots;

346   

347     

348      int x_temp_slot_level;

349   

350     

351      int x_var_temp_slot_level;

352   

353     

357      int x_target_temp_slot_level;

358   

359     

361      struct var_refs_queue *fixup_var_refs_queue;

362   

363     

364      int inlinable;

365      int no_debugging_symbols;

366      rtvec original_arg_vector;

367      tree original_decl_initial;

368     

370      rtx inl_last_parm_insn;

371     

372      int inl_max_label_num;

373   

374     

375      int funcdef_no;

376   

377     

378   

379     

380      struct machine_function * GTY ((maybe_undef (""))) machine;

381     

382      int stack_alignment_needed;

383     

384      int preferred_stack_boundary;

385     

386      bool recursive_call_emit;

387   

388     

389      struct language_function * language;

390   

391     

392   

393     

395      rtx epilogue_delay_list;

396   

397     

399      enum function_frequency {

400       

402        FUNCTION_FREQUENCY_UNLIKELY_EXECUTED,

403       

404        FUNCTION_FREQUENCY_NORMAL,

405       

407        FUNCTION_FREQUENCY_HOT

408      } function_frequency;

409   

410     

412      int max_jumptable_ents;

413   

414     

415   

416     

418      unsigned int returns_struct : 1;

419   

420     

422      unsigned int returns_pcc_struct : 1;

423   

424     

425      unsigned int returns_pointer : 1;

426   

427     

428      unsigned int needs_context : 1;

429   

430     

431      unsigned int calls_setjmp : 1;

432   

433     

434      unsigned int calls_longjmp : 1;

435   

436     

438      unsigned int calls_alloca : 1;

439   

440     

441      unsigned int calls_eh_return : 1;

442   

443     

444      unsigned int calls_constant_p : 1;

445   

446     

448      unsigned int has_nonlocal_label : 1;

449   

450     

452      unsigned int has_nonlocal_goto : 1;

453   

454     

455      unsigned int contains_functions : 1;

456   

457     

458      unsigned int has_computed_jump : 1;

459   

460     

464      unsigned int is_thunk : 1;

465   

466     

471      unsigned int all_throwers_are_sibcalls : 1;

472   

473     

475      unsigned int instrument_entry_exit : 1;

476   

477     

478      unsigned int profile : 1;

479   

480     

482      unsigned int limit_stack : 1;

483   

484     

485      unsigned int stdarg : 1;

486   

487     

491      unsigned int x_whole_function_mode_p : 1;

492   

493     

500      unsigned int x_dont_save_pending_sizes_p : 1;

501   

502     

503      unsigned int uses_const_pool : 1;

504   

505     

506      unsigned int uses_pic_offset_table : 1;

507   

508     

509      unsigned int uses_eh_lsda : 1;

510   

511      

512      unsigned int arg_pointer_save_area_init : 1;

513   

514     

516      unsigned int rtl_inline_init : 1;

517   

518     

519      unsigned int saved_for_inline : 1;

520    };

其結構中前6個成員是非常重要的部分。其中,eh_status控制了函數的異常處理;stmt_status記錄了語句對棧,資料流的累積效應,這些效應将影響目前語句的翻譯;expr_status則記錄了函數被調用及退出的行為;emit_status控制相應的rtx形式指令的生成;varasm_status提供了記錄函數中常量的方法。

6434 void

6435 allocate_struct_function (tree fndecl)                                                          in function.c

6436 {

6437   tree result;

6438

6439   cfun = ggc_alloc_cleared (sizeof (struct function));

6440

6441   max_parm_reg = LAST_VIRTUAL_REGISTER + 1;

6442

6443   cfun->stack_alignment_needed = STACK_BOUNDARY;

6444   cfun->preferred_stack_boundary = STACK_BOUNDARY;

6445

6446   current_function_funcdef_no = funcdef_no++;

6447

6448   cfun->function_frequency = FUNCTION_FREQUENCY_NORMAL;

6449

6450   init_stmt_for_function ();

6451   init_eh_for_function ();

6452

6453   (*lang_hooks.function.init) (cfun);

6454   if (init_machine_status)

6455     cfun->machine = (*init_machine_status) ();

6456

6457   if (fndecl == NULL)

6458     return;

  …

6477 }

在上面,current_function_funcdef_no,current_function_returns_pcc_struct,current_function_returns_struct,current_function_returns_pointer,max_parm_reg,current_function_needs_context都是用于從function結構體中選擇特定成員的宏。例如。

558    #define current_function_funcdef_no (cfun->funcdef_no)                                   in function.h

567    #define max_parm_reg (cfun->x_max_parm_reg)

在6441行,對于x86機器,LAST_VIRTUAL_REGISTER被定義成FIRST_PSEUDO_REGISTER +4。其值是57,它定義了可被用于rtx形式代碼的最大寄存器數目。

在6443及6444行,STACK_BOUNDARY定義了對棧的對齊邊界要求。對于x86,這是32(4位元組)。

在6446行,funcdef_no為用于概要分析(profiling)及調試等目的的标簽賦予唯一的号碼。在function 結構體相應的域則記錄這個值。

接下來,在6450及6451行,函數init_stmt_for_function,init_eh_for_function僅是配置設定了結構體中的eh及stmt域,它們分别用于異常處理及語句。

在6453行,鈎子lang_hooks.function.init對于C++語言是cxx_push_function_context。在目前上下文環境中,它僅為function對象配置設定language_function執行個體。結構體language_function将儲存及恢複那些記錄目前函數編譯進度的變量。它被用于嵌套函數。

在6454行,對于x86機器,init_machine_status指向ix86_init_machine_status。它為function 對象建立了machine_function的執行個體,這個結構儲存了與函數處理相關的機器資訊。

在6457行,在這次的調用中,fndecl為null,函數在此傳回。

繼續閱讀