Qs about TwoOperandAliasConstraint and TIED_TO

in llvm-3.6.2.src

  1. when I put this around one of my instruction definitions in my target “InstrInfo.td” file,

let TwoOperandAliasConstraint = “$dst = $rs1” in {

}

I do not see any TIED_TO in the generated GenInstrInfo.inc file for the OperandInfo used by the instruction,

the question is what am I doing wrong ?

  1. I’ve noticed that TwoOperandAliasConstraint does not appear anywhere in source/lib/Target/X86/*

yet TIED_TO occurs in 162 of the OperandInfo’s in build/lib/Target/X86/X86GenInstrInfo.inc

the question is how does TIED_TO happen if not by TwoOperandAliasConstraint ?

thanks, Peter Lawrence.

I think I have answered my own questions below, but now have additional questions,

I am now using : let Constraints = “$src = $dst”; following examples from X86,

rather than TwoOperandAliasConstraint that I had been following from Mips,

and I am now seeing TIED_TO in my GenInstrInfo.inc for the appropriate OperandInfo’s,

but I am still seeing assembly code emitted that violates this constraint,

what else am I missing ?

thanks, Peter Lawrence.

the only thing I see that is out-of-the-ordinary in my GenInstrInfo.inc is

the OPERAND_MEMORY rather than OPERAND_REGISTER for my base-register operand

and OPERAND_MEMORY rather than OPERAND_IMMEDIATE for my offset operand,

but am still not sure how that happens or what to do to fix it ?

static const MCOperandInfo OperandInfo25[] = {

{ Xmc::AddrRegsRegClassID, 0, MCOI::OPERAND_REGISTER, 0 },

{ Xmc::AddrRegsRegClassID, 0, MCOI::OPERAND_MEMORY, ((0 << 16) | (1 << MCOI::TIED_TO)) },

{ -1, 0, MCOI::OPERAND_MEMORY, 0 }, };

I seem to be between a rock and a hard place:

let OperandType = “OPERAND_MEMORY” in { <----- I suspect my MEMORY_OPERAND comes from this

def memri : Operand {

let MIOperandInfo = (ops addrreg:$base, i16imm:$offset); }

}

def LEA : FMT_I6 <0x4c00, (outs addrreg:$dst), (ins memri:$addr), <----- I suspect the fix would be to split the memri

----- into separate reg and imm “ins” operands,

“lea $dst, ${addr:arith}”,

[(set iPTR:$dst, addrri:$addr)]> { <----- but then I would not be able to write this pattern

----- and ISel would fail ???

let Constraints = “$addr.base = $dst”;

let isCodeGenOnly = 1;

}

– Sleepless in Silicon Valley…

I think I have answered my own question again,

I will use a CustomInserter to create my own MachineInstruction for my LEA instruction,

that way I can call BuildMI myself, and add whatever operands are needed,

with whatever TiedTo information is needed.

I have looked into the register allocator’s “TwoOperandInstructionPass.cpp”,

and it does not look up any information in the “XyzGenInstrInfo.inc” OperandInfo tables,

rather CodeGen (or in my case my CustomInserter) puts the necessary info into the

MachineOperand, and RA gets it from there.

so the fact that the generated OperandInfo table has the wrong operand type

(Memory, when Register is needed) won’t matter.

-Peter Lawrence.

I think I have answered my own question again,

I will use a CustomInserter to create my own MachineInstruction for my LEA instruction,

that way I can call BuildMI myself, and add whatever operands are needed,

with whatever TiedTo information is needed.

let TwoOperandAliasConstraint = “$dst = $rs1” in {

}

I do not see any TIED_TO in the generated GenInstrInfo.inc file for the OperandInfo used by the instruction,

the question is what am I doing wrong ?

TwoOperandAliasConstraint is about assembly matching rather than instruction selection. If you have an instruction of the form:

addu $dst, $rs1, $rs2

and set TwoOperandAliasConstraint to “$dst = $rs1”, then the assembly matcher will accept both of these:

addu $dst, $rs1, $rs2

addu $dst, $rs2

with the latter being expanded to:

addu $dst, $dst, $rs2.

As you’ve found, ‘Constraints’ is the right place to say that $rs1 and $dst must always be the same register.