Studying note of GCC-3.4.6 source (70)

4.3.4. Finish compiler’s initialization

Back lang_dependent_init, it is happy to see the end of the function. The initialization of the compiler will be finished soon.

 

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 }

 

Here creating the dummy function context is not necessary, as we don’t indeed emit rtl instrucitons (call emit_insn). The purpose of init_expr_once is to set up which modes can be used directly in memory and to initialize the block move optab. To collect data, SET instruction is created for test. Notice that mem and mem1 should be carefully selected, either of one should be valid on any machine, otherwise incorrect result may gotten. Here men and mem1 are stack pointer and frame poiner respectively, then test storing and loading between memory they refer and register.

 

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  }

 

At line 273, HARD_REGNO_MODE_OK selects the real hard register. And routine recog is generated by back-end from target machine description file, which returns nonzero, if the RTL instruction is matched by patterns in the description file. At line 317, insn_data is also filled out by back-end, the predicate slot will select out valid operands for the RTL instruction. It is also settled by back-end. float_extend_from_mem records modes whether we can float-extend from memory.

 

你可能感兴趣的:(function,null,Class,float,compiler,initialization)