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.