A few suggestions regarding CallLowering

Hi,

This information is mostly for GlobalISel developers. I’d like to make a couple of suggestions about the process of lowering of function arguments / return values. I’ve heard that GlobalISel is developing rapidly, maybe it is not too late to make little changes to the API.

Although GlobalISel has different interface compared to SelectionDAGISel, the approach to lowering function arguments / return values is essentially the same. Below I describe SelectionDAGISel, which I’m more familiar with.

Targets implement function argument / return value lowering by implementing LowerFormalArguments and LowerReturn, each of which does two things:

  • associates a function argument (or return value) with some location, which may be a register or a position in the stack;

  • emits some SDNodes to load arguments from (store return values to) the associated locations.

LowerFormalArguments is called before processing the function body, and LowerReturn is called during lowering the function body. I.e. high level process of lowering arguments / return value looks like this:

  • figure out locations for function arguments;

  • emit some code to load the arguments out of their locations;

  • lower some basic blocks;

  • figure out locations for the return value;

  • emit some code to store the return value to its location.

The last two steps are repeated for every ret instruction encountered.

While this works in most cases, this approach has notable flaws:

  1. While lowering the function body in general (and lowering ret instruction in particular), information about function argument locations is already lost. Some targets wish to have this information. In order to overcome this, they add variables to MachineFunctionInfo, set them in LowerFunctionArguments and query while lowering the body. It seems to me that MachineFunctionInfo is not the best place for such things, as this kind of information is only needed for the instruction selection process. It should not survive to later passes.
  2. Similarly, LowerFunctionArguments does not have information about return value location, and there is no straightforward way to overcome this. A target may want to know how the return value is returned in order to properly generate function entry code.
  3. LowerReturn is called for each ret instruction, repeating the job of analyzing the return value every time.
    A few examples:
  • most targets save information about vararg starting location to MachineFrameInfo and use it in lowering VASTART and similar;
  • many targets save SRet virtual register as well;
  • XCore backend stores ReturnStackOffset to use in LowerReturn;
  • X86 and M68k targets save BytesToPopOnReturn to use in LowerReturn.
    These are just a few random picks, there are more.

I would suggest two changes to the current approach:

  • Extract the analysis part of LowerFormalArguments and LowerReturn to a common function (say, AnalyzeFunctionPrototype). It will be responsible for choosing locations for the arguments and the return value only (no code generated). Typically, this new function will only contain calls to CCState::AnalyzeFormalArguments and CCState::AnalyzeReturn, saving CCValAssign instances and target-dependent information (see examples above) for later use.
  • This new function will need to save the result of analysis somewhere to be available in LowerOperation, LowerReturn, and others. So, let the targets maintain a state of the currently lowered function. One possible (and most obvious) way to do this is to allow targets to inherit from existing FunctionLoweringInfo.

With the suggested changes, the high level process will change to:

  • figure out locations for function arguments and return values, save this information for later use;
  • lower some basic blocks (analysis results should also be available for use);
  • emit some code to load the arguments out of their locations using the results of the earlier analysis;
  • emit some code to store the return value to its location using the results of the earlier analysis.

//
Sorry for my English