[llvm-dev] need help for customized backend LowerFormalArguments

Xiangyang Guo via llvm-dev llvm-dev at lists.llvm.org
Wed Nov 25 14:06:38 PST 2015


Hi, All,

I'm trying to build a customized backend and I need to lower the formal
arguments like this:

There are several specific registers just for storing formal arguments. And
also there are several general purpose registers for computation. If there
is an instruction which uses parameters, I should first use a move
instruction, which moves the value to general purpose register. For
example, in RegisterInfo.td , I have following register classes:

// this is for storing parameters only
def PRegs : RegisterClass<"FOO", [i32], 32,
  (add P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14,
P15)>;

// this is general purpose register class
def GRRegs : RegisterClass<"FOO", [i32], 32,
  (add R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10)>;

// this is also general purpose register class
def GRRegsAdditional : RegisterClass<"FOO", [i32], 32,
  (add R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14,
R15, SP)>;

If I have a piece of bitcode looks like this:

define i32 @_Z3fooii(i32 %a, i32 %b) #0 {
  %1 = add nsw i32 %a, %b
  ret i32 %1
}

I want the assembly looks like this:
        move v0, p0
        move v1, p1
        add-int v10, v0, v1
        return v10

So far, I have tried is to implement the LowerFormalArguments() like this:

SDValue FOOTargetLowering::LowerFormalArguments(
    SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
    const SmallVectorImpl<ISD::InputArg> &Ins, SDLoc dl, SelectionDAG &DAG,
    SmallVectorImpl<SDValue> &InVals) const {
  MachineFunction &MF = DAG.getMachineFunction();
  MachineRegisterInfo &RegInfo = MF.getRegInfo();

  assert(!isVarArg && "VarArg not supported");

  // Assign locations to all of the incoming arguments.
  SmallVector<CCValAssign, 16> ArgLocs;
  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
                 *DAG.getContext());

  CCInfo.AnalyzeFormalArguments(Ins, CC_FOO);

  for (auto &VA : ArgLocs) {
    if (VA.isRegLoc()) {
      // Arguments passed in registers
      EVT RegVT = VA.getLocVT();
      const unsigned VReg =
RegInfo.createVirtualRegister(&FOO::PRegsRegClass);
      RegInfo.addLiveIn(VA.getLocReg(), VReg);
      SDValue ArgIn = DAG.getCopyFromReg(Chain, dl, VReg, RegVT);

      InVals.push_back(ArgIn);
      continue;
    }
    // assume the parameter registers are enough, no need to store in frame
right now
  }
  return Chain;
}

In the above function, CC_FOO is defined in CallingConv.td and
"CCIfType<[i32],
CCAssignToReg<[P0,P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15]>>" is
used.
Also I define a move instruction which move the value from PRegs to GRRegs
because my add instruction's source registers should belong to GRRegs or
GRRegsAdditional.
I define 'move' and 'add' instructions like this:

def MoveRRTy : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisInt<0>]>;

def moverr : SDNode<"FOOISD::MOVERR", MoveRRTy>;

def MOVE : InstFOO<(outs GRRegsAdditional:$dst),
                   (ins PRegs:$src),
                   "move $dst, $src",[(set i32:$dst, (moverr i32:$src))]>;

def ADDINT: InstFOO<(outs GRRegsAdditional:$dst),
                   (ins GRRegsAdditional:$src1, GRRegsAdditional:$src2),
                   "add-int $dst, $src1, $src2",
                   [(set i32:$dst, (add i32:$src1, i32:$src2))]>;

I assume this could work.

However, when I use llc and print-after-all to check the machine
instructions. At very beginning, the machine instructions look like this:

 %vreg1<def> = COPY %P1; PRegs:%vreg1 %vreg0<def> = COPY %P0; PRegs:%vreg0
%vreg3<def> = COPY %vreg0; GRRegsAdditional:%vreg3 PRegs:%vreg0 %vreg4<def>
= COPY %vreg1; GRRegsAdditional:%vreg4 PRegs:%vreg1 %vreg2<def> = ADDINT
%vreg3, %vreg4; GRRegsAdditional:%vreg2,%vreg3,%vreg4 %R10<def> = COPY
%vreg2; GRRegsAdditional:%vreg2 RET %R10
And after "Post-RA pseudo instruction expansion pass", it looks like this

Function Live Ins: %P0 in %vreg0, %P1 in %vreg1
BB#0: derived from LLVM BB %0
    Live Ins: %P0 %P1
%R10<def> = ADDINT %R0<kill>, %R1<kill>
RET %R10

And eventually, the assembly file .s looks like this

# BB#0:
        add-int v10, v0, v1
        return v10

It seems that there is no "move v0, p0" and "move v1, p1" at all. But I'm
not sure why is this. I appreciate any suggestions and points.

Regards,

Xiangyang
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20151125/c14231a7/attachment.html>


More information about the llvm-dev mailing list