GCC-3.4.6源代码学习笔记(70)

4.3.4. 完成编译器初始化

回到lang_dependent_init,终于看到函数的结尾了,编译器的初始化马上就要完成了。

 

lang_dependent_init (continue)

 

4542   /* The following initialization functions need to generate rtl, so

4543     provide a dummy function context for them.  */

4544   init_dummy_function_start ();

4545   init_expr_once ();

4546   expand_dummy_function_end ();

4547

4548   /* If dbx symbol table desired, initialize writing it and output the

4549     predefined types.  */

4550   timevar_push (TV_SYMOUT);

4551

4552 #ifdef DWARF2_UNWIND_INFO

4553   if (dwarf2out_do_frame ())

4554     dwarf2out_frame_init ();

4555 #endif

4556

4557   /* Now we have the correct original filename, we can initialize

4558     debug output.  */

4559   (*debug_hooks->init) (name);

4560

4561   timevar_pop (TV_SYMOUT);

4562

4563   return 1;

4564 }

 

这里创建伪函数上下文是不必要的,因为我们不需要产生rtl指令(调用emit_insn)。init_expr_once的目的是,找出可以直接在内存中使用的模式,并初始化块移动的optab。为了收集数据,构建了用于测试的SET指令。注意memmem1应该被小心选择,在任何机器上,它们都应该至少有一个是有效的,否则可能会得到错误的结果。这里选择的memmem1分别是栈指针及栈框指针,分别测试,由它们所引用的内存与相同模式寄存器之间的,存取操作。

 

232  void

233  init_expr_once (void)                                                                                       in expr.c

234  {

235    rtx insn, pat;

236    enum machine_mode mode;

237    int num_clobbers;

238    rtx mem, mem1;

239    rtx reg;

240 

241    /* Try indexing by frame ptr and try by stack ptr.

242      It is known that on the Convex the stack ptr isn't a valid index.

243      With luck, one or the other is valid on any machine.  */

244    mem = gen_rtx_MEM (VOIDmode, stack_pointer_rtx);

245    mem1 = gen_rtx_MEM (VOIDmode, frame_pointer_rtx);

246 

247   /* A scratch register we can modify in-place below to avoid

248      useless RTL allocations.  */

249    reg = gen_rtx_REG (VOIDmode, -1);

250 

251    insn = rtx_alloc (INSN);

252    pat = gen_rtx_SET (0, NULL_RTX, NULL_RTX);

253    PATTERN (insn) = pat;

254 

255    for (mode = VOIDmode; (int) mode < NUM_MACHINE_MODES;

256         mode = (enum machine_mode) ((int) mode + 1))

257    {

258      int regno;

259 

260      direct_load[(int) mode] = direct_store[(int) mode] = 0;

261      PUT_MODE (mem, mode);

262      PUT_MODE (mem1, mode);

263      PUT_MODE (reg, mode);

264 

265      /* See if there is some register that can be used in this mode and

266        directly loaded or stored from memory.  */

267 

268      if (mode != VOIDmode && mode != BLKmode)

269        for (regno = 0; regno < FIRST_PSEUDO_REGISTER

270            && (direct_load[(int) mode] == 0 || direct_store[(int) mode] == 0);

271            regno++)

272        {

273          if (!HARD_REGNO_MODE_OK (regno, mode))

274            continue;

275 

276          REGNO (reg) = regno;

277 

278           SET_SRC (pat) = mem;

279           SET_DEST (pat) = reg;

280           if (recog (pat, insn, &num_clobbers) >= 0)

281             direct_load[(int) mode] = 1;

282 

283           SET_SRC (pat) = mem1;

284           SET_DEST (pat) = reg;

285           if (recog (pat, insn, &num_clobbers) >= 0)

286             direct_load[(int) mode] = 1;

287 

288           SET_SRC (pat) = reg;

289           SET_DEST (pat) = mem;

290           if (recog (pat, insn, &num_clobbers) >= 0)

291             direct_store[(int) mode] = 1;

292 

293           SET_SRC (pat) = reg;

294           SET_DEST (pat) = mem1;

295           if (recog (pat, insn, &num_clobbers) >= 0)

296             direct_store[(int) mode] = 1;

297        }

298    }

299 

300    mem = gen_rtx_MEM (VOIDmode, gen_rtx_raw_REG (Pmode, 10000));

301 

302    for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode;

303         mode = GET_MODE_WIDER_MODE (mode))

304    {

305      enum machine_mode srcmode;

306      for (srcmode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); srcmode != mode;

307          srcmode = GET_MODE_WIDER_MODE (srcmode))

308      {

309        enum insn_code ic;

310 

311         ic = can_extend_p (mode, srcmode, 0);

312        if (ic == CODE_FOR_nothing)

313          continue;

314 

315        PUT_MODE (mem, srcmode);

316 

317        if ((*insn_data[ic].operand[1].predicate) (mem, srcmode))

318          float_extend_from_mem[mode][srcmode] = true;

319      }

320    }

321  }

 

273行,HARD_REGNO_MODE_OK选择真实的物理寄存器。而例程recog也是由后端根据机器描述文件产生,如果考查的RTL指令可以被机器描述文件中的模式所匹配,该函数返回非0值。在317行,insn_data亦是由后端填充,函数指针predicate将选出对于该RTL指令有效的操作数(返回非0值)。这也是由后端设定的。float_extend_from_mem记录的是可以从内存进行浮点扩展的模式。

 

你可能感兴趣的:(GCC-3.4.6源代码学习笔记(70))