Skip to content

Commit

Permalink
[MIPS GlobalISel] Select add i32, i32
Browse files Browse the repository at this point in the history
Add the minimal support necessary to lower a function that returns the
sum of two i32 values.
Support argument/return lowering of i32 values through registers only.
Add tablegen for regbankselect and instructionselect.

Patch by Petar Avramovic.

Differential Revision: https://reviews.llvm.org/D44304

llvm-svn: 329819
  • Loading branch information
petar-jovanovic committed Apr 11, 2018
1 parent 5ba3795 commit 366857a
Show file tree
Hide file tree
Showing 16 changed files with 537 additions and 13 deletions.
2 changes: 2 additions & 0 deletions llvm/lib/Target/Mips/CMakeLists.txt
Expand Up @@ -6,9 +6,11 @@ tablegen(LLVM MipsGenCallingConv.inc -gen-callingconv)
tablegen(LLVM MipsGenDAGISel.inc -gen-dag-isel)
tablegen(LLVM MipsGenDisassemblerTables.inc -gen-disassembler)
tablegen(LLVM MipsGenFastISel.inc -gen-fast-isel)
tablegen(LLVM MipsGenGlobalISel.inc -gen-global-isel)
tablegen(LLVM MipsGenInstrInfo.inc -gen-instr-info)
tablegen(LLVM MipsGenMCCodeEmitter.inc -gen-emitter)
tablegen(LLVM MipsGenMCPseudoLowering.inc -gen-pseudo-lowering)
tablegen(LLVM MipsGenRegisterBank.inc -gen-register-bank)
tablegen(LLVM MipsGenRegisterInfo.inc -gen-register-info)
tablegen(LLVM MipsGenSubtargetInfo.inc -gen-subtarget)

Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/Mips/Mips.td
Expand Up @@ -59,6 +59,7 @@ include "MipsRegisterInfo.td"
include "MipsSchedule.td"
include "MipsInstrInfo.td"
include "MipsCallingConv.td"
include "MipsRegisterBanks.td"

// Avoid forward declaration issues.
include "MipsScheduleP5600.td"
Expand Down
193 changes: 190 additions & 3 deletions llvm/lib/Target/Mips/MipsCallLowering.cpp
Expand Up @@ -14,6 +14,7 @@
//===----------------------------------------------------------------------===//

#include "MipsCallLowering.h"
#include "MipsCCState.h"
#include "MipsISelLowering.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"

Expand All @@ -22,13 +23,125 @@ using namespace llvm;
MipsCallLowering::MipsCallLowering(const MipsTargetLowering &TLI)
: CallLowering(&TLI) {}

bool MipsCallLowering::MipsHandler::assign(const CCValAssign &VA,
unsigned vreg) {
if (VA.isRegLoc()) {
assignValueToReg(vreg, VA.getLocReg());
} else {
return false;
}
return true;
}

namespace {
class IncomingValueHandler : public MipsCallLowering::MipsHandler {
public:
IncomingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
: MipsHandler(MIRBuilder, MRI) {}

bool handle(ArrayRef<CCValAssign> ArgLocs,
ArrayRef<CallLowering::ArgInfo> Args);

private:
virtual void assignValueToReg(unsigned ValVReg, unsigned PhysReg) override;

void markPhysRegUsed(unsigned PhysReg) {
MIRBuilder.getMBB().addLiveIn(PhysReg);
}
};
} // end anonymous namespace

void IncomingValueHandler::assignValueToReg(unsigned ValVReg,
unsigned PhysReg) {
MIRBuilder.buildCopy(ValVReg, PhysReg);
markPhysRegUsed(PhysReg);
}

bool IncomingValueHandler::handle(ArrayRef<CCValAssign> ArgLocs,
ArrayRef<CallLowering::ArgInfo> Args) {
for (unsigned i = 0, ArgsSize = Args.size(); i < ArgsSize; ++i) {
if (!assign(ArgLocs[i], Args[i].Reg))
return false;
}
return true;
}

namespace {
class OutgoingValueHandler : public MipsCallLowering::MipsHandler {
public:
OutgoingValueHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
MachineInstrBuilder &MIB)
: MipsHandler(MIRBuilder, MRI), MIB(MIB) {}

bool handle(ArrayRef<CCValAssign> ArgLocs,
ArrayRef<CallLowering::ArgInfo> Args);

private:
virtual void assignValueToReg(unsigned ValVReg, unsigned PhysReg) override;

MachineInstrBuilder &MIB;
};
} // end anonymous namespace

void OutgoingValueHandler::assignValueToReg(unsigned ValVReg,
unsigned PhysReg) {
MIRBuilder.buildCopy(PhysReg, ValVReg);
MIB.addUse(PhysReg, RegState::Implicit);
}

bool OutgoingValueHandler::handle(ArrayRef<CCValAssign> ArgLocs,
ArrayRef<CallLowering::ArgInfo> Args) {
for (unsigned i = 0; i < Args.size(); ++i) {
if (!assign(ArgLocs[i], Args[i].Reg))
return false;
}
return true;
}

static bool isSupportedType(Type *T) {
if (T->isIntegerTy() && T->getScalarSizeInBits() == 32)
return true;
return false;
}

bool MipsCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
const Value *Val, unsigned VReg) const {

MachineInstrBuilder Ret = MIRBuilder.buildInstrNoInsert(Mips::RetRA);

if (Val != nullptr) {
return false;
if (!isSupportedType(Val->getType()))
return false;

MachineFunction &MF = MIRBuilder.getMF();
const Function &F = MF.getFunction();
const DataLayout &DL = MF.getDataLayout();
const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();

SmallVector<ArgInfo, 8> RetInfos;
SmallVector<unsigned, 8> OrigArgIndices;

ArgInfo ArgRetInfo(VReg, Val->getType());
setArgFlags(ArgRetInfo, AttributeList::ReturnIndex, DL, F);
splitToValueTypes(ArgRetInfo, 0, RetInfos, OrigArgIndices);

SmallVector<ISD::OutputArg, 8> Outs;
subTargetRegTypeForCallingConv(
MIRBuilder, RetInfos, OrigArgIndices,
[&](ISD::ArgFlagsTy flags, EVT vt, EVT argvt, bool used,
unsigned origIdx, unsigned partOffs) {
Outs.emplace_back(flags, vt, argvt, used, origIdx, partOffs);
});

SmallVector<CCValAssign, 16> ArgLocs;
MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
F.getContext());
CCInfo.AnalyzeReturn(Outs, TLI.CCAssignFnForReturn());

OutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret);
if (!RetHandler.handle(ArgLocs, RetInfos)) {
return false;
}
}
MIRBuilder.insertInstr(Ret);
return true;
Expand All @@ -42,6 +155,80 @@ bool MipsCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
if (F.arg_empty())
return true;

// Function had args, but we didn't lower them.
return false;
if (F.isVarArg()) {
return false;
}

for (auto &Arg : F.args()) {
if (!isSupportedType(Arg.getType()))
return false;
}

MachineFunction &MF = MIRBuilder.getMF();
const DataLayout &DL = MF.getDataLayout();
const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();

SmallVector<ArgInfo, 8> ArgInfos;
SmallVector<unsigned, 8> OrigArgIndices;
unsigned i = 0;
for (auto &Arg : F.args()) {
ArgInfo AInfo(VRegs[i], Arg.getType());
setArgFlags(AInfo, i + AttributeList::FirstArgIndex, DL, F);
splitToValueTypes(AInfo, i, ArgInfos, OrigArgIndices);
++i;
}

SmallVector<ISD::InputArg, 8> Ins;
subTargetRegTypeForCallingConv(
MIRBuilder, ArgInfos, OrigArgIndices,
[&](ISD::ArgFlagsTy flags, EVT vt, EVT argvt, bool used, unsigned origIdx,
unsigned partOffs) {
Ins.emplace_back(flags, vt, argvt, used, origIdx, partOffs);
});

SmallVector<CCValAssign, 16> ArgLocs;
MipsCCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs,
F.getContext());

CCInfo.AnalyzeFormalArguments(Ins, TLI.CCAssignFnForCall());

IncomingValueHandler Handler(MIRBuilder, MIRBuilder.getMF().getRegInfo());
if (!Handler.handle(ArgLocs, ArgInfos))
return false;

return true;
}

void MipsCallLowering::subTargetRegTypeForCallingConv(
MachineIRBuilder &MIRBuilder, ArrayRef<ArgInfo> Args,
ArrayRef<unsigned> OrigArgIndices, const FunTy &PushBack) const {
MachineFunction &MF = MIRBuilder.getMF();
const Function &F = MF.getFunction();
const DataLayout &DL = F.getParent()->getDataLayout();
const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>();

unsigned ArgNo = 0;
for (auto &Arg : Args) {

EVT VT = TLI.getValueType(DL, Arg.Ty);
MVT RegisterVT = TLI.getRegisterTypeForCallingConv(F.getContext(), VT);

ISD::ArgFlagsTy Flags = Arg.Flags;
Flags.setOrigAlign(TLI.getABIAlignmentForCallingConv(Arg.Ty, DL));

PushBack(Flags, RegisterVT, VT, true, OrigArgIndices[ArgNo], 0);

++ArgNo;
}
}

void MipsCallLowering::splitToValueTypes(
const ArgInfo &OrigArg, unsigned OriginalIndex,
SmallVectorImpl<ArgInfo> &SplitArgs,
SmallVectorImpl<unsigned> &SplitArgsOrigIndices) const {

// TODO : perform structure and array split. For now we only deal with
// types that pass isSupportedType check.
SplitArgs.push_back(OrigArg);
SplitArgsOrigIndices.push_back(OriginalIndex);
}
36 changes: 36 additions & 0 deletions llvm/lib/Target/Mips/MipsCallLowering.h
Expand Up @@ -26,13 +26,49 @@ class MipsTargetLowering;
class MipsCallLowering : public CallLowering {

public:
class MipsHandler {
public:
MipsHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
: MIRBuilder(MIRBuilder), MRI(MRI) {}

virtual ~MipsHandler() = default;

protected:
virtual void assignValueToReg(unsigned ValVReg, unsigned PhysReg) = 0;

bool assign(const CCValAssign &VA, unsigned vreg);

MachineIRBuilder &MIRBuilder;
MachineRegisterInfo &MRI;
};

MipsCallLowering(const MipsTargetLowering &TLI);

bool lowerReturn(MachineIRBuilder &MIRBuiler, const Value *Val,
unsigned VReg) const override;

bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F,
ArrayRef<unsigned> VRegs) const override;

private:
using FunTy =
std::function<void(ISD::ArgFlagsTy flags, EVT vt, EVT argvt, bool used,
unsigned origIdx, unsigned partOffs)>;

/// Based on registers available on target machine split or extend
/// type if needed, also change pointer type to appropriate integer
/// type. Lambda will fill some info so we can tell MipsCCState to
/// assign physical registers.
void subTargetRegTypeForCallingConv(MachineIRBuilder &MIRBuilder,
ArrayRef<ArgInfo> Args,
ArrayRef<unsigned> OrigArgIndices,
const FunTy &PushBack) const;

/// Split structures and arrays, save original argument indices since
/// Mips calling conv needs info about original argument type.
void splitToValueTypes(const ArgInfo &OrigArg, unsigned OriginalIndex,
SmallVectorImpl<ArgInfo> &SplitArgs,
SmallVectorImpl<unsigned> &SplitArgsOrigIndices) const;
};

} // end namespace llvm
Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/Target/Mips/MipsISelLowering.cpp
Expand Up @@ -2833,6 +2833,13 @@ static bool CC_MipsO32(unsigned ValNo, MVT ValVT, MVT LocVT,

#include "MipsGenCallingConv.inc"

CCAssignFn *MipsTargetLowering::CCAssignFnForCall() const{
return CC_Mips;
}

CCAssignFn *MipsTargetLowering::CCAssignFnForReturn() const{
return RetCC_Mips;
}
//===----------------------------------------------------------------------===//
// Call Calling Convention Implementation
//===----------------------------------------------------------------------===//
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/Target/Mips/MipsISelLowering.h
Expand Up @@ -19,6 +19,7 @@
#include "MCTargetDesc/MipsBaseInfo.h"
#include "MCTargetDesc/MipsMCTargetDesc.h"
#include "Mips.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/ISDOpcodes.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/SelectionDAG.h"
Expand Down Expand Up @@ -365,6 +366,10 @@ class TargetRegisterClass;
return getTargetMachine().isPositionIndependent();
}

CCAssignFn *CCAssignFnForCall() const;

CCAssignFn *CCAssignFnForReturn() const;

protected:
SDValue getGlobalReg(SelectionDAG &DAG, EVT Ty) const;

Expand Down

0 comments on commit 366857a

Please sign in to comment.