Clean up HiPE prologue emission a bit and avoid signed arithmetic tricks.

No intended functionality change.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175536 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Benjamin Kramer
2013-02-19 17:32:57 +00:00
parent e5a83d15b2
commit b1e1d5d4a5

View File

@@ -1433,7 +1433,6 @@ X86FrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
bool Is64Bit = STI.is64Bit(); bool Is64Bit = STI.is64Bit();
unsigned TlsReg, TlsOffset; unsigned TlsReg, TlsOffset;
DebugLoc DL; DebugLoc DL;
const X86Subtarget *ST = &MF.getTarget().getSubtarget<X86Subtarget>();
unsigned ScratchReg = GetScratchRegister(Is64Bit, MF, true); unsigned ScratchReg = GetScratchRegister(Is64Bit, MF, true);
assert(!MF.getRegInfo().isLiveIn(ScratchReg) && assert(!MF.getRegInfo().isLiveIn(ScratchReg) &&
@@ -1441,8 +1440,8 @@ X86FrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
if (MF.getFunction()->isVarArg()) if (MF.getFunction()->isVarArg())
report_fatal_error("Segmented stacks do not support vararg functions."); report_fatal_error("Segmented stacks do not support vararg functions.");
if (!ST->isTargetLinux() && !ST->isTargetDarwin() && if (!STI.isTargetLinux() && !STI.isTargetDarwin() &&
!ST->isTargetWin32() && !ST->isTargetFreeBSD()) !STI.isTargetWin32() && !STI.isTargetFreeBSD())
report_fatal_error("Segmented stacks not supported on this platform."); report_fatal_error("Segmented stacks not supported on this platform.");
MachineBasicBlock *allocMBB = MF.CreateMachineBasicBlock(); MachineBasicBlock *allocMBB = MF.CreateMachineBasicBlock();
@@ -1480,13 +1479,13 @@ X86FrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
// Read the limit off the current stacklet off the stack_guard location. // Read the limit off the current stacklet off the stack_guard location.
if (Is64Bit) { if (Is64Bit) {
if (ST->isTargetLinux()) { if (STI.isTargetLinux()) {
TlsReg = X86::FS; TlsReg = X86::FS;
TlsOffset = 0x70; TlsOffset = 0x70;
} else if (ST->isTargetDarwin()) { } else if (STI.isTargetDarwin()) {
TlsReg = X86::GS; TlsReg = X86::GS;
TlsOffset = 0x60 + 90*8; // See pthread_machdep.h. Steal TLS slot 90. TlsOffset = 0x60 + 90*8; // See pthread_machdep.h. Steal TLS slot 90.
} else if (ST->isTargetFreeBSD()) { } else if (STI.isTargetFreeBSD()) {
TlsReg = X86::FS; TlsReg = X86::FS;
TlsOffset = 0x18; TlsOffset = 0x18;
} else { } else {
@@ -1502,16 +1501,16 @@ X86FrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
BuildMI(checkMBB, DL, TII.get(X86::CMP64rm)).addReg(ScratchReg) BuildMI(checkMBB, DL, TII.get(X86::CMP64rm)).addReg(ScratchReg)
.addReg(0).addImm(1).addReg(0).addImm(TlsOffset).addReg(TlsReg); .addReg(0).addImm(1).addReg(0).addImm(TlsOffset).addReg(TlsReg);
} else { } else {
if (ST->isTargetLinux()) { if (STI.isTargetLinux()) {
TlsReg = X86::GS; TlsReg = X86::GS;
TlsOffset = 0x30; TlsOffset = 0x30;
} else if (ST->isTargetDarwin()) { } else if (STI.isTargetDarwin()) {
TlsReg = X86::GS; TlsReg = X86::GS;
TlsOffset = 0x48 + 90*4; TlsOffset = 0x48 + 90*4;
} else if (ST->isTargetWin32()) { } else if (STI.isTargetWin32()) {
TlsReg = X86::FS; TlsReg = X86::FS;
TlsOffset = 0x14; // pvArbitrary, reserved for application use TlsOffset = 0x14; // pvArbitrary, reserved for application use
} else if (ST->isTargetFreeBSD()) { } else if (STI.isTargetFreeBSD()) {
report_fatal_error("Segmented stacks not supported on FreeBSD i386."); report_fatal_error("Segmented stacks not supported on FreeBSD i386.");
} else { } else {
report_fatal_error("Segmented stacks not supported on this platform."); report_fatal_error("Segmented stacks not supported on this platform.");
@@ -1523,10 +1522,10 @@ X86FrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
BuildMI(checkMBB, DL, TII.get(X86::LEA32r), ScratchReg).addReg(X86::ESP) BuildMI(checkMBB, DL, TII.get(X86::LEA32r), ScratchReg).addReg(X86::ESP)
.addImm(1).addReg(0).addImm(-StackSize).addReg(0); .addImm(1).addReg(0).addImm(-StackSize).addReg(0);
if (ST->isTargetLinux() || ST->isTargetWin32()) { if (STI.isTargetLinux() || STI.isTargetWin32()) {
BuildMI(checkMBB, DL, TII.get(X86::CMP32rm)).addReg(ScratchReg) BuildMI(checkMBB, DL, TII.get(X86::CMP32rm)).addReg(ScratchReg)
.addReg(0).addImm(0).addReg(0).addImm(TlsOffset).addReg(TlsReg); .addReg(0).addImm(0).addReg(0).addImm(TlsOffset).addReg(TlsReg);
} else if (ST->isTargetDarwin()) { } else if (STI.isTargetDarwin()) {
// TlsOffset doesn't fit into a mod r/m byte so we need an extra register // TlsOffset doesn't fit into a mod r/m byte so we need an extra register
unsigned ScratchReg2; unsigned ScratchReg2;
@@ -1632,19 +1631,18 @@ X86FrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
void X86FrameLowering::adjustForHiPEPrologue(MachineFunction &MF) const { void X86FrameLowering::adjustForHiPEPrologue(MachineFunction &MF) const {
const X86InstrInfo &TII = *TM.getInstrInfo(); const X86InstrInfo &TII = *TM.getInstrInfo();
MachineFrameInfo *MFI = MF.getFrameInfo(); MachineFrameInfo *MFI = MF.getFrameInfo();
const uint64_t SlotSize = TM.getRegisterInfo()->getSlotSize(); const unsigned SlotSize = TM.getRegisterInfo()->getSlotSize();
const bool Is64Bit = STI.is64Bit(); const bool Is64Bit = STI.is64Bit();
DebugLoc DL; DebugLoc DL;
// HiPE-specific values // HiPE-specific values
const unsigned HipeLeafWords = 24; const unsigned HipeLeafWords = 24;
const unsigned CCRegisteredArgs = Is64Bit ? 6 : 5; const unsigned CCRegisteredArgs = Is64Bit ? 6 : 5;
const unsigned Guaranteed = HipeLeafWords * SlotSize; const unsigned Guaranteed = HipeLeafWords * SlotSize;
const unsigned CallerStkArity = unsigned CallerStkArity = MF.getFunction()->arg_size() > CCRegisteredArgs ?
std::max<int>(0, MF.getFunction()->arg_size() - CCRegisteredArgs); MF.getFunction()->arg_size() - CCRegisteredArgs : 0;
unsigned MaxStack = unsigned MaxStack = MFI->getStackSize() + CallerStkArity*SlotSize + SlotSize;
MFI->getStackSize() + CallerStkArity * SlotSize + SlotSize;
assert(MF.getTarget().getSubtarget<X86Subtarget>().isTargetLinux() && assert(STI.isTargetLinux() &&
"HiPE prologue is only supported on Linux operating systems."); "HiPE prologue is only supported on Linux operating systems.");
// Compute the largest caller's frame that is needed to fit the callees' // Compute the largest caller's frame that is needed to fit the callees'
@@ -1660,31 +1658,37 @@ void X86FrameLowering::adjustForHiPEPrologue(MachineFunction &MF) const {
for (MachineFunction::iterator MBBI = MF.begin(), MBBE = MF.end(); for (MachineFunction::iterator MBBI = MF.begin(), MBBE = MF.end();
MBBI != MBBE; ++MBBI) MBBI != MBBE; ++MBBI)
for (MachineBasicBlock::iterator MI = MBBI->begin(), ME = MBBI->end(); for (MachineBasicBlock::iterator MI = MBBI->begin(), ME = MBBI->end();
MI != ME; ++MI) MI != ME; ++MI) {
if (MI->isCall()) { if (!MI->isCall())
// Get callee operand. continue;
const MachineOperand &MO = MI->getOperand(0);
const Function *F;
// Only take account of global function calls (no closures etc.). // Get callee operand.
if (!MO.isGlobal()) continue; const MachineOperand &MO = MI->getOperand(0);
if (!(F = dyn_cast<Function>(MO.getGlobal()))) continue;
// Do not update 'MaxStack' for primitive and built-in functions // Only take account of global function calls (no closures etc.).
// (encoded with names either starting with "erlang."/"bif_" or not if (!MO.isGlobal())
// having a ".", such as a simple <Module>.<Function>.<Arity>, or an continue;
// "_", such as the BIF "suspend_0") as they are executed on another
// stack.
if ((F->getName().find("erlang.") != std::string::npos) ||
(F->getName().find("bif_") != std::string::npos)) continue;
if (F->getName().find_first_of("._") == std::string::npos)
continue;
const uint64_t CalleeStkArity = const Function *F = dyn_cast<Function>(MO.getGlobal());
std::max<ssize_t>(0, F->arg_size() - CCRegisteredArgs); if (!F)
MoreStackForCalls = std::max<int64_t>( continue;
MoreStackForCalls, (HipeLeafWords - 1 - CalleeStkArity) * SlotSize);
} // Do not update 'MaxStack' for primitive and built-in functions
// (encoded with names either starting with "erlang."/"bif_" or not
// having a ".", such as a simple <Module>.<Function>.<Arity>, or an
// "_", such as the BIF "suspend_0") as they are executed on another
// stack.
if (F->getName().find("erlang.") != StringRef::npos ||
F->getName().find("bif_") != StringRef::npos ||
F->getName().find_first_of("._") == StringRef::npos)
continue;
unsigned CalleeStkArity =
F->arg_size() > CCRegisteredArgs ? F->arg_size()-CCRegisteredArgs : 0;
if (HipeLeafWords - 1 > CalleeStkArity)
MoreStackForCalls = std::max(MoreStackForCalls,
(HipeLeafWords - 1 - CalleeStkArity) * SlotSize);
}
MaxStack += MoreStackForCalls; MaxStack += MoreStackForCalls;
} }