mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
[SelectionDAGBuilder] Refactor GetRegistersForValue. NFCI.
llvm-svn: 350841
This commit is contained in:
parent
263ffa3eae
commit
8782dad3bd
@ -7343,10 +7343,11 @@ static SDValue getAddressForMemoryInput(SDValue Chain, const SDLoc &Location,
|
||||
///
|
||||
/// OpInfo describes the operand
|
||||
/// RefOpInfo describes the matching operand if any, the operand otherwise
|
||||
static void GetRegistersForValue(SelectionDAG &DAG, const TargetLowering &TLI,
|
||||
const SDLoc &DL, SDISelAsmOperandInfo &OpInfo,
|
||||
static void GetRegistersForValue(SelectionDAG &DAG, const SDLoc &DL,
|
||||
SDISelAsmOperandInfo &OpInfo,
|
||||
SDISelAsmOperandInfo &RefOpInfo) {
|
||||
LLVMContext &Context = *DAG.getContext();
|
||||
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
|
||||
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
SmallVector<unsigned, 4> Regs;
|
||||
@ -7354,11 +7355,19 @@ static void GetRegistersForValue(SelectionDAG &DAG, const TargetLowering &TLI,
|
||||
|
||||
// If this is a constraint for a single physreg, or a constraint for a
|
||||
// register class, find it.
|
||||
std::pair<unsigned, const TargetRegisterClass *> PhysReg =
|
||||
TLI.getRegForInlineAsmConstraint(&TRI, RefOpInfo.ConstraintCode,
|
||||
RefOpInfo.ConstraintVT);
|
||||
unsigned AssignedReg;
|
||||
const TargetRegisterClass *RC;
|
||||
std::tie(AssignedReg, RC) = TLI.getRegForInlineAsmConstraint(
|
||||
&TRI, RefOpInfo.ConstraintCode, RefOpInfo.ConstraintVT);
|
||||
// RC is unset only on failure. Return immediately.
|
||||
if (!RC)
|
||||
return;
|
||||
|
||||
// Get the actual register value type. This is important, because the user
|
||||
// may have asked for (e.g.) the AX register in i32 type. We need to
|
||||
// remember that AX is actually i16 to get the right extension.
|
||||
const MVT RegVT = *TRI.legalclasstypes_begin(*RC);
|
||||
|
||||
unsigned NumRegs = 1;
|
||||
if (OpInfo.ConstraintVT != MVT::Other) {
|
||||
// If this is an FP operand in an integer register (or visa versa), or more
|
||||
// generally if the operand value disagrees with the register class we plan
|
||||
@ -7368,13 +7377,11 @@ static void GetRegistersForValue(SelectionDAG &DAG, const TargetLowering &TLI,
|
||||
// Bitcast for output value is done at the end of visitInlineAsm().
|
||||
if ((OpInfo.Type == InlineAsm::isOutput ||
|
||||
OpInfo.Type == InlineAsm::isInput) &&
|
||||
PhysReg.second &&
|
||||
!TRI.isTypeLegalForClass(*PhysReg.second, OpInfo.ConstraintVT)) {
|
||||
!TRI.isTypeLegalForClass(*RC, OpInfo.ConstraintVT)) {
|
||||
// Try to convert to the first EVT that the reg class contains. If the
|
||||
// types are identical size, use a bitcast to convert (e.g. two differing
|
||||
// vector types). Note: output bitcast is done at the end of
|
||||
// visitInlineAsm().
|
||||
MVT RegVT = *TRI.legalclasstypes_begin(*PhysReg.second);
|
||||
if (RegVT.getSizeInBits() == OpInfo.ConstraintVT.getSizeInBits()) {
|
||||
// Exclude indirect inputs while they are unsupported because the code
|
||||
// to perform the load is missing and thus OpInfo.CallOperand still
|
||||
@ -7387,15 +7394,13 @@ static void GetRegistersForValue(SelectionDAG &DAG, const TargetLowering &TLI,
|
||||
// use the corresponding integer type. This turns an f64 value into
|
||||
// i64, which can be passed with two i32 values on a 32-bit machine.
|
||||
} else if (RegVT.isInteger() && OpInfo.ConstraintVT.isFloatingPoint()) {
|
||||
RegVT = MVT::getIntegerVT(OpInfo.ConstraintVT.getSizeInBits());
|
||||
MVT VT = MVT::getIntegerVT(OpInfo.ConstraintVT.getSizeInBits());
|
||||
if (OpInfo.Type == InlineAsm::isInput)
|
||||
OpInfo.CallOperand =
|
||||
DAG.getNode(ISD::BITCAST, DL, RegVT, OpInfo.CallOperand);
|
||||
OpInfo.ConstraintVT = RegVT;
|
||||
DAG.getNode(ISD::BITCAST, DL, VT, OpInfo.CallOperand);
|
||||
OpInfo.ConstraintVT = VT;
|
||||
}
|
||||
}
|
||||
|
||||
NumRegs = TLI.getNumRegisters(Context, OpInfo.ConstraintVT);
|
||||
}
|
||||
|
||||
// No need to allocate a matching input constraint since the constraint it's
|
||||
@ -7403,59 +7408,36 @@ static void GetRegistersForValue(SelectionDAG &DAG, const TargetLowering &TLI,
|
||||
if (OpInfo.isMatchingInputConstraint())
|
||||
return;
|
||||
|
||||
MVT RegVT;
|
||||
EVT ValueVT = OpInfo.ConstraintVT;
|
||||
if (OpInfo.ConstraintVT == MVT::Other)
|
||||
ValueVT = RegVT;
|
||||
|
||||
// Initialize NumRegs.
|
||||
unsigned NumRegs = 1;
|
||||
if (OpInfo.ConstraintVT != MVT::Other)
|
||||
NumRegs = TLI.getNumRegisters(Context, OpInfo.ConstraintVT);
|
||||
|
||||
// If this is a constraint for a specific physical register, like {r17},
|
||||
// assign it now.
|
||||
if (unsigned AssignedReg = PhysReg.first) {
|
||||
const TargetRegisterClass *RC = PhysReg.second;
|
||||
if (OpInfo.ConstraintVT == MVT::Other)
|
||||
ValueVT = *TRI.legalclasstypes_begin(*RC);
|
||||
|
||||
// Get the actual register value type. This is important, because the user
|
||||
// may have asked for (e.g.) the AX register in i32 type. We need to
|
||||
// remember that AX is actually i16 to get the right extension.
|
||||
RegVT = *TRI.legalclasstypes_begin(*RC);
|
||||
// If this associated to a specific register, initialize iterator to correct
|
||||
// place. If virtual, make sure we have enough registers
|
||||
|
||||
// This is an explicit reference to a physical register.
|
||||
Regs.push_back(AssignedReg);
|
||||
|
||||
// If this is an expanded reference, add the rest of the regs to Regs.
|
||||
if (NumRegs != 1) {
|
||||
TargetRegisterClass::iterator I = RC->begin();
|
||||
for (; *I != AssignedReg; ++I)
|
||||
assert(I != RC->end() && "Didn't find reg!");
|
||||
|
||||
// Already added the first reg.
|
||||
--NumRegs; ++I;
|
||||
for (; NumRegs; --NumRegs, ++I) {
|
||||
assert(I != RC->end() && "Ran out of registers to allocate!");
|
||||
Regs.push_back(*I);
|
||||
}
|
||||
}
|
||||
|
||||
OpInfo.AssignedRegs = RegsForValue(Regs, RegVT, ValueVT);
|
||||
return;
|
||||
// Initialize iterator if necessary
|
||||
TargetRegisterClass::iterator I = RC->begin();
|
||||
MachineRegisterInfo &RegInfo = MF.getRegInfo();
|
||||
if (AssignedReg) {
|
||||
for (; *I != AssignedReg; ++I)
|
||||
assert(I != RC->end() && "Didn't find reg!");
|
||||
}
|
||||
|
||||
// Otherwise, if this was a reference to an LLVM register class, create vregs
|
||||
// for this reference.
|
||||
if (const TargetRegisterClass *RC = PhysReg.second) {
|
||||
RegVT = *TRI.legalclasstypes_begin(*RC);
|
||||
if (OpInfo.ConstraintVT == MVT::Other)
|
||||
ValueVT = RegVT;
|
||||
|
||||
// Create the appropriate number of virtual registers.
|
||||
MachineRegisterInfo &RegInfo = MF.getRegInfo();
|
||||
for (; NumRegs; --NumRegs)
|
||||
Regs.push_back(RegInfo.createVirtualRegister(RC));
|
||||
|
||||
OpInfo.AssignedRegs = RegsForValue(Regs, RegVT, ValueVT);
|
||||
return;
|
||||
for (; NumRegs; --NumRegs, ++I) {
|
||||
assert(I != RC->end() && "Ran out of registers to allocate!");
|
||||
auto R = (AssignedReg) ? *I : RegInfo.createVirtualRegister(RC);
|
||||
Regs.push_back(R);
|
||||
}
|
||||
|
||||
// Otherwise, we couldn't allocate enough registers for this.
|
||||
OpInfo.AssignedRegs = RegsForValue(Regs, RegVT, ValueVT);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
@ -7635,7 +7617,7 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) {
|
||||
? ConstraintOperands[OpInfo.getMatchedOperand()]
|
||||
: OpInfo;
|
||||
if (RefOpInfo.ConstraintType == TargetLowering::C_Register)
|
||||
GetRegistersForValue(DAG, TLI, getCurSDLoc(), OpInfo, RefOpInfo);
|
||||
GetRegistersForValue(DAG, getCurSDLoc(), OpInfo, RefOpInfo);
|
||||
}
|
||||
|
||||
// Third pass - Loop over all of the operands, assigning virtual or physregs
|
||||
@ -7649,7 +7631,7 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) {
|
||||
// C_Register operands have already been allocated, Other/Memory don't need
|
||||
// to be.
|
||||
if (RefOpInfo.ConstraintType == TargetLowering::C_RegisterClass)
|
||||
GetRegistersForValue(DAG, TLI, getCurSDLoc(), OpInfo, RefOpInfo);
|
||||
GetRegistersForValue(DAG, getCurSDLoc(), OpInfo, RefOpInfo);
|
||||
}
|
||||
|
||||
// AsmNodeOperands - The operands for the ISD::INLINEASM node.
|
||||
|
Loading…
Reference in New Issue
Block a user