X86: copyConstantToRegister

Hello,
looking at X86 codegen, I see this:

void ISel::copyConstantToRegister(MachineBasicBlock *MBB,
                                  MachineBasicBlock::iterator IP,
                                  Constant *C, unsigned R) {
  if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
  .....
       case Instruction::Add:
          emitSimpleBinaryOperation(MBB, IP, CE->getOperand(0),
                                                  CE->getOperand(1),
                                                  Class, R);

I'm not sure I understand this logic. If we have "1 + 2" as constant
expression, then why emit the code to perform addition? It should be possible
to just fold the expression and copy immediate "3" into a register.

I must be missing something, but what?

Another question is about TargetInstrInfo::CreateCodeToLoadConst. This seems
like a perfect fit for the task, but it's not used in X86 backend at all.
Further, the destination register is represented by Instruction*, and not by
integer number as elsewhere. What does that Instruction* mean?

Thanks,
Volodya

Hello,
looking at X86 codegen, I see this:

void ISel::copyConstantToRegister(MachineBasicBlock *MBB,
                                  MachineBasicBlock::iterator IP,
                                  Constant *C, unsigned R) {
  if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
  .....
       case Instruction::Add:
          emitSimpleBinaryOperation(MBB, IP, CE->getOperand(0),
                                                  CE->getOperand(1),
                                                  Class, R);

I'm not sure I understand this logic. If we have "1 + 2" as constant
expression, then why emit the code to perform addition? It should be possible
to just fold the expression and copy immediate "3" into a register.

I must be missing something, but what?

LLVM constant expressions are used when it is not possible to fold the
constant. In particular expressions like "10/0" are not constant foldable
(so it must be evaluated at runtime), and link-time constants are not
foldable... stuff like:

int X;
int Y;
int Z = (int)&X-(int)&Y;

Yes, this is gross and disturbing, but we do support it. Constant
expressions are the reason why there is a separation in the X86 isel
between the "visit" methods and the "emit" methods.

Another question is about TargetInstrInfo::CreateCodeToLoadConst. This seems
like a perfect fit for the task, but it's not used in X86 backend at all.
Further, the destination register is represented by Instruction*, and not by
integer number as elsewhere. What does that Instruction* mean?

This is a deprecated method that is only used by the SparcV9 backend. It
used an extremely different way of representing virtual registers based on
Value*'s. It turns out that doing this has some serious problems, so we
are slowly migrating away from it.

-Chris

Chris Lattner wrote:

> I'm not sure I understand this logic. If we have "1 + 2" as constant
> expression, then why emit the code to perform addition? It should be
> possible to just fold the expression and copy immediate "3" into a
> register.
>
> I must be missing something, but what?

LLVM constant expressions are used when it is not possible to fold the
constant. In particular expressions like "10/0" are not constant foldable
(so it must be evaluated at runtime), and link-time constants are not
foldable... stuff like:

int X;
int Y;
int Z = (int)&X-(int)&Y;

Yes, this is gross and disturbing, but we do support it. Constant
expressions are the reason why there is a separation in the X86 isel
between the "visit" methods and the "emit" methods.

Thanks for the explanation?

> Another question is about TargetInstrInfo::CreateCodeToLoadConst. This
> seems like a perfect fit for the task, but it's not used in X86 backend
> at all. Further, the destination register is represented by Instruction*,
> and not by integer number as elsewhere. What does that Instruction* mean?

This is a deprecated method that is only used by the SparcV9 backend. It
used an extremely different way of representing virtual registers based on
Value*'s. It turns out that doing this has some serious problems, so we
are slowly migrating away from it.

Understood. It looks like a lot of methods in TargetMachine are for Sparc
backend only, right?

- Volodya

Actually TargetMachine is pretty clean: only the getSchedInfo and
getRegInfo methods are sparc specific, and getSchedInfo is likely to be
refactored at some point to be more target specific (getRegInfo() is
already replaced by getRegisterInfo()). Worse is TargetInstrInfo, which
has a large number of methods that are sparc specific (located under the
"WARNING: these methods are sparc specific" comment).

-Chris