mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-28 06:32:09 +00:00
refactor GetRegistersForValue to take OpInfo as an argument instead of various
pieces of it. No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36592 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
3ff90dc1c8
commit
bf996f1d5e
@ -82,6 +82,8 @@ namespace {
|
||||
createDefaultScheduler);
|
||||
} // namespace
|
||||
|
||||
namespace { struct AsmOperandInfo; }
|
||||
|
||||
namespace {
|
||||
/// RegsForValue - This struct represents the physical registers that a
|
||||
/// particular value is assigned and the type information about the value.
|
||||
@ -516,8 +518,7 @@ public:
|
||||
N = NewN;
|
||||
}
|
||||
|
||||
RegsForValue GetRegistersForValue(const std::string &ConstrCode,
|
||||
MVT::ValueType VT,
|
||||
RegsForValue GetRegistersForValue(AsmOperandInfo &OpInfo,
|
||||
bool OutReg, bool InReg,
|
||||
std::set<unsigned> &OutputRegs,
|
||||
std::set<unsigned> &InputRegs);
|
||||
@ -3013,126 +3014,6 @@ isAllocatableRegister(unsigned Reg, MachineFunction &MF,
|
||||
return FoundRC;
|
||||
}
|
||||
|
||||
RegsForValue SelectionDAGLowering::
|
||||
GetRegistersForValue(const std::string &ConstrCode,
|
||||
MVT::ValueType VT, bool isOutReg, bool isInReg,
|
||||
std::set<unsigned> &OutputRegs,
|
||||
std::set<unsigned> &InputRegs) {
|
||||
std::pair<unsigned, const TargetRegisterClass*> PhysReg =
|
||||
TLI.getRegForInlineAsmConstraint(ConstrCode, VT);
|
||||
std::vector<unsigned> Regs;
|
||||
|
||||
unsigned NumRegs = VT != MVT::Other ? TLI.getNumElements(VT) : 1;
|
||||
MVT::ValueType RegVT;
|
||||
MVT::ValueType ValueVT = VT;
|
||||
|
||||
// If this is a constraint for a specific physical register, like {r17},
|
||||
// assign it now.
|
||||
if (PhysReg.first) {
|
||||
if (VT == MVT::Other)
|
||||
ValueVT = *PhysReg.second->vt_begin();
|
||||
|
||||
// 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 = *PhysReg.second->vt_begin();
|
||||
|
||||
// This is a explicit reference to a physical register.
|
||||
Regs.push_back(PhysReg.first);
|
||||
|
||||
// If this is an expanded reference, add the rest of the regs to Regs.
|
||||
if (NumRegs != 1) {
|
||||
TargetRegisterClass::iterator I = PhysReg.second->begin();
|
||||
TargetRegisterClass::iterator E = PhysReg.second->end();
|
||||
for (; *I != PhysReg.first; ++I)
|
||||
assert(I != E && "Didn't find reg!");
|
||||
|
||||
// Already added the first reg.
|
||||
--NumRegs; ++I;
|
||||
for (; NumRegs; --NumRegs, ++I) {
|
||||
assert(I != E && "Ran out of registers to allocate!");
|
||||
Regs.push_back(*I);
|
||||
}
|
||||
}
|
||||
return RegsForValue(Regs, RegVT, ValueVT);
|
||||
}
|
||||
|
||||
// Otherwise, if this was a reference to an LLVM register class, create vregs
|
||||
// for this reference.
|
||||
std::vector<unsigned> RegClassRegs;
|
||||
if (PhysReg.second) {
|
||||
// If this is an early clobber or tied register, our regalloc doesn't know
|
||||
// how to maintain the constraint. If it isn't, go ahead and create vreg
|
||||
// and let the regalloc do the right thing.
|
||||
if (!isOutReg || !isInReg) {
|
||||
RegVT = *PhysReg.second->vt_begin();
|
||||
|
||||
if (VT == MVT::Other)
|
||||
ValueVT = RegVT;
|
||||
|
||||
// Create the appropriate number of virtual registers.
|
||||
SSARegMap *RegMap = DAG.getMachineFunction().getSSARegMap();
|
||||
for (; NumRegs; --NumRegs)
|
||||
Regs.push_back(RegMap->createVirtualRegister(PhysReg.second));
|
||||
|
||||
return RegsForValue(Regs, RegVT, ValueVT);
|
||||
}
|
||||
|
||||
// Otherwise, we can't allocate it. Let the code below figure out how to
|
||||
// maintain these constraints.
|
||||
RegClassRegs.assign(PhysReg.second->begin(), PhysReg.second->end());
|
||||
|
||||
} else {
|
||||
// This is a reference to a register class that doesn't directly correspond
|
||||
// to an LLVM register class. Allocate NumRegs consecutive, available,
|
||||
// registers from the class.
|
||||
RegClassRegs = TLI.getRegClassForInlineAsmConstraint(ConstrCode, VT);
|
||||
}
|
||||
|
||||
const MRegisterInfo *MRI = DAG.getTarget().getRegisterInfo();
|
||||
MachineFunction &MF = *CurMBB->getParent();
|
||||
unsigned NumAllocated = 0;
|
||||
for (unsigned i = 0, e = RegClassRegs.size(); i != e; ++i) {
|
||||
unsigned Reg = RegClassRegs[i];
|
||||
// See if this register is available.
|
||||
if ((isOutReg && OutputRegs.count(Reg)) || // Already used.
|
||||
(isInReg && InputRegs.count(Reg))) { // Already used.
|
||||
// Make sure we find consecutive registers.
|
||||
NumAllocated = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check to see if this register is allocatable (i.e. don't give out the
|
||||
// stack pointer).
|
||||
const TargetRegisterClass *RC = isAllocatableRegister(Reg, MF, TLI, MRI);
|
||||
if (!RC) {
|
||||
// Make sure we find consecutive registers.
|
||||
NumAllocated = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Okay, this register is good, we can use it.
|
||||
++NumAllocated;
|
||||
|
||||
// If we allocated enough consecutive registers, succeed.
|
||||
if (NumAllocated == NumRegs) {
|
||||
unsigned RegStart = (i-NumAllocated)+1;
|
||||
unsigned RegEnd = i+1;
|
||||
// Mark all of the allocated registers used.
|
||||
for (unsigned i = RegStart; i != RegEnd; ++i) {
|
||||
unsigned Reg = RegClassRegs[i];
|
||||
Regs.push_back(Reg);
|
||||
if (isOutReg) OutputRegs.insert(Reg); // Mark reg used.
|
||||
if (isInReg) InputRegs.insert(Reg); // Mark reg used.
|
||||
}
|
||||
|
||||
return RegsForValue(Regs, *RC->vt_begin(), VT);
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, we couldn't allocate enough registers for this.
|
||||
return RegsForValue();
|
||||
}
|
||||
|
||||
namespace {
|
||||
/// AsmOperandInfo - This contains information for each constraint that we are
|
||||
@ -3212,6 +3093,131 @@ void AsmOperandInfo::ComputeConstraintToUse(const TargetLowering &TLI) {
|
||||
}
|
||||
|
||||
|
||||
RegsForValue SelectionDAGLowering::
|
||||
GetRegistersForValue(AsmOperandInfo &OpInfo, bool isOutReg, bool isInReg,
|
||||
std::set<unsigned> &OutputRegs,
|
||||
std::set<unsigned> &InputRegs) {
|
||||
std::pair<unsigned, const TargetRegisterClass*> PhysReg =
|
||||
TLI.getRegForInlineAsmConstraint(OpInfo.ConstraintCode,OpInfo.ConstraintVT);
|
||||
std::vector<unsigned> Regs;
|
||||
|
||||
unsigned NumRegs = 1;
|
||||
if (OpInfo.ConstraintVT != MVT::Other)
|
||||
NumRegs = TLI.getNumElements(OpInfo.ConstraintVT);
|
||||
MVT::ValueType RegVT;
|
||||
MVT::ValueType ValueVT = OpInfo.ConstraintVT;
|
||||
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
|
||||
// If this is a constraint for a specific physical register, like {r17},
|
||||
// assign it now.
|
||||
if (PhysReg.first) {
|
||||
if (OpInfo.ConstraintVT == MVT::Other)
|
||||
ValueVT = *PhysReg.second->vt_begin();
|
||||
|
||||
// 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 = *PhysReg.second->vt_begin();
|
||||
|
||||
// This is a explicit reference to a physical register.
|
||||
Regs.push_back(PhysReg.first);
|
||||
|
||||
// If this is an expanded reference, add the rest of the regs to Regs.
|
||||
if (NumRegs != 1) {
|
||||
TargetRegisterClass::iterator I = PhysReg.second->begin();
|
||||
TargetRegisterClass::iterator E = PhysReg.second->end();
|
||||
for (; *I != PhysReg.first; ++I)
|
||||
assert(I != E && "Didn't find reg!");
|
||||
|
||||
// Already added the first reg.
|
||||
--NumRegs; ++I;
|
||||
for (; NumRegs; --NumRegs, ++I) {
|
||||
assert(I != E && "Ran out of registers to allocate!");
|
||||
Regs.push_back(*I);
|
||||
}
|
||||
}
|
||||
return RegsForValue(Regs, RegVT, ValueVT);
|
||||
}
|
||||
|
||||
// Otherwise, if this was a reference to an LLVM register class, create vregs
|
||||
// for this reference.
|
||||
std::vector<unsigned> RegClassRegs;
|
||||
if (PhysReg.second) {
|
||||
// If this is an early clobber or tied register, our regalloc doesn't know
|
||||
// how to maintain the constraint. If it isn't, go ahead and create vreg
|
||||
// and let the regalloc do the right thing.
|
||||
if (!isOutReg || !isInReg) {
|
||||
RegVT = *PhysReg.second->vt_begin();
|
||||
|
||||
if (OpInfo.ConstraintVT == MVT::Other)
|
||||
ValueVT = RegVT;
|
||||
|
||||
// Create the appropriate number of virtual registers.
|
||||
SSARegMap *RegMap = MF.getSSARegMap();
|
||||
for (; NumRegs; --NumRegs)
|
||||
Regs.push_back(RegMap->createVirtualRegister(PhysReg.second));
|
||||
|
||||
return RegsForValue(Regs, RegVT, ValueVT);
|
||||
}
|
||||
|
||||
// Otherwise, we can't allocate it. Let the code below figure out how to
|
||||
// maintain these constraints.
|
||||
RegClassRegs.assign(PhysReg.second->begin(), PhysReg.second->end());
|
||||
|
||||
} else {
|
||||
// This is a reference to a register class that doesn't directly correspond
|
||||
// to an LLVM register class. Allocate NumRegs consecutive, available,
|
||||
// registers from the class.
|
||||
RegClassRegs = TLI.getRegClassForInlineAsmConstraint(OpInfo.ConstraintCode,
|
||||
OpInfo.ConstraintVT);
|
||||
}
|
||||
|
||||
const MRegisterInfo *MRI = DAG.getTarget().getRegisterInfo();
|
||||
unsigned NumAllocated = 0;
|
||||
for (unsigned i = 0, e = RegClassRegs.size(); i != e; ++i) {
|
||||
unsigned Reg = RegClassRegs[i];
|
||||
// See if this register is available.
|
||||
if ((isOutReg && OutputRegs.count(Reg)) || // Already used.
|
||||
(isInReg && InputRegs.count(Reg))) { // Already used.
|
||||
// Make sure we find consecutive registers.
|
||||
NumAllocated = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check to see if this register is allocatable (i.e. don't give out the
|
||||
// stack pointer).
|
||||
const TargetRegisterClass *RC = isAllocatableRegister(Reg, MF, TLI, MRI);
|
||||
if (!RC) {
|
||||
// Make sure we find consecutive registers.
|
||||
NumAllocated = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Okay, this register is good, we can use it.
|
||||
++NumAllocated;
|
||||
|
||||
// If we allocated enough consecutive registers, succeed.
|
||||
if (NumAllocated == NumRegs) {
|
||||
unsigned RegStart = (i-NumAllocated)+1;
|
||||
unsigned RegEnd = i+1;
|
||||
// Mark all of the allocated registers used.
|
||||
for (unsigned i = RegStart; i != RegEnd; ++i) {
|
||||
unsigned Reg = RegClassRegs[i];
|
||||
Regs.push_back(Reg);
|
||||
if (isOutReg) OutputRegs.insert(Reg); // Mark reg used.
|
||||
if (isInReg) InputRegs.insert(Reg); // Mark reg used.
|
||||
}
|
||||
|
||||
return RegsForValue(Regs, *RC->vt_begin(), OpInfo.ConstraintVT);
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, we couldn't allocate enough registers for this.
|
||||
return RegsForValue();
|
||||
}
|
||||
|
||||
|
||||
/// visitInlineAsm - Handle a call to an InlineAsm object.
|
||||
///
|
||||
void SelectionDAGLowering::visitInlineAsm(CallInst &I) {
|
||||
@ -3336,8 +3342,7 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) {
|
||||
|
||||
// Build a list of regs that this operand uses. This always has a single
|
||||
// element for promoted/expanded operands.
|
||||
RegsForValue Regs = GetRegistersForValue(OpInfo.ConstraintCode, OpVT,
|
||||
false, false,
|
||||
RegsForValue Regs = GetRegistersForValue(OpInfo, false, false,
|
||||
OutputRegs, InputRegs);
|
||||
|
||||
switch (OpInfo.Type) {
|
||||
@ -3407,8 +3412,7 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) {
|
||||
// Copy the output from the appropriate register. Find a register that
|
||||
// we can use.
|
||||
RegsForValue Regs =
|
||||
GetRegistersForValue(OpInfo.ConstraintCode, OpInfo.ConstraintVT,
|
||||
true, UsesInputRegister,
|
||||
GetRegistersForValue(OpInfo, true, UsesInputRegister,
|
||||
OutputRegs, InputRegs);
|
||||
if (Regs.Regs.empty()) {
|
||||
cerr << "Couldn't allocate output reg for contraint '"
|
||||
@ -3515,8 +3519,7 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) {
|
||||
|
||||
// Copy the input into the appropriate registers.
|
||||
RegsForValue InRegs =
|
||||
GetRegistersForValue(OpInfo.ConstraintCode, OpInfo.ConstraintVT,
|
||||
false, true, OutputRegs, InputRegs);
|
||||
GetRegistersForValue(OpInfo, false, true, OutputRegs, InputRegs);
|
||||
// FIXME: should be match fail.
|
||||
assert(!InRegs.Regs.empty() && "Couldn't allocate input reg!");
|
||||
|
||||
@ -3527,8 +3530,8 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) {
|
||||
}
|
||||
case InlineAsm::isClobber: {
|
||||
RegsForValue ClobberedRegs =
|
||||
GetRegistersForValue(OpInfo.ConstraintCode, MVT::Other, false, false,
|
||||
OutputRegs, InputRegs);
|
||||
GetRegistersForValue(OpInfo, false,
|
||||
false, OutputRegs, InputRegs);
|
||||
// Add the clobbered value to the operand list, so that the register
|
||||
// allocator is aware that the physreg got clobbered.
|
||||
if (!ClobberedRegs.Regs.empty())
|
||||
|
Loading…
x
Reference in New Issue
Block a user