aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/X86/X86CallFrameOptimization.cpp
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2015-07-16 01:30:00 +0000
committerReid Kleckner <reid@kleckner.net>2015-07-16 01:30:00 +0000
commit938bd6fc963af5028a31b315b982ac390786af1b (patch)
treee76eb92b5fd43c06c5492358827de1e9c0cf7d33 /llvm/lib/Target/X86/X86CallFrameOptimization.cpp
parentef9828fb473164c881fb88f1669a2a4055e218f9 (diff)
downloadllvm-938bd6fc963af5028a31b315b982ac390786af1b.zip
llvm-938bd6fc963af5028a31b315b982ac390786af1b.tar.gz
llvm-938bd6fc963af5028a31b315b982ac390786af1b.tar.bz2
Revert "[X86] Allow more call sequences to use push instructions for argument passing"
It miscompiles some code and a reduced test case has been sent to the author. This reverts commit r240257. llvm-svn: 242373
Diffstat (limited to 'llvm/lib/Target/X86/X86CallFrameOptimization.cpp')
-rw-r--r--llvm/lib/Target/X86/X86CallFrameOptimization.cpp117
1 files changed, 26 insertions, 91 deletions
diff --git a/llvm/lib/Target/X86/X86CallFrameOptimization.cpp b/llvm/lib/Target/X86/X86CallFrameOptimization.cpp
index 031ba4b..4412125 100644
--- a/llvm/lib/Target/X86/X86CallFrameOptimization.cpp
+++ b/llvm/lib/Target/X86/X86CallFrameOptimization.cpp
@@ -78,7 +78,7 @@ private:
typedef DenseMap<MachineInstr *, CallContext> ContextMap;
bool isLegal(MachineFunction &MF);
-
+
bool isProfitable(MachineFunction &MF, ContextMap &CallSeqMap);
void collectCallInfo(MachineFunction &MF, MachineBasicBlock &MBB,
@@ -90,13 +90,6 @@ private:
MachineInstr *canFoldIntoRegPush(MachineBasicBlock::iterator FrameSetup,
unsigned Reg);
- enum InstClassification { Convert, Skip, Exit };
-
- InstClassification classifyInstruction(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator MI,
- const X86RegisterInfo &RegInfo,
- DenseSet<unsigned int> &UsedRegs);
-
const char *getPassName() const override { return "X86 Optimize Call Frame"; }
const TargetInstrInfo *TII;
@@ -112,7 +105,7 @@ FunctionPass *llvm::createX86CallFrameOptimization() {
return new X86CallFrameOptimization();
}
-// This checks whether the transformation is legal.
+// This checks whether the transformation is legal.
// Also returns false in cases where it's potentially legal, but
// we don't even want to try.
bool X86CallFrameOptimization::isLegal(MachineFunction &MF) {
@@ -177,8 +170,9 @@ bool X86CallFrameOptimization::isProfitable(MachineFunction &MF,
if (!OptForSize)
return false;
- unsigned StackAlign = TFL->getStackAlignment();
+ unsigned StackAlign = TFL->getStackAlignment();
+
int64_t Advantage = 0;
for (auto CC : CallSeqMap) {
// Call sites where no parameters are passed on the stack
@@ -211,6 +205,7 @@ bool X86CallFrameOptimization::isProfitable(MachineFunction &MF,
return (Advantage >= 0);
}
+
bool X86CallFrameOptimization::runOnMachineFunction(MachineFunction &MF) {
TII = MF.getSubtarget().getInstrInfo();
TFL = MF.getSubtarget().getFrameLowering();
@@ -242,64 +237,6 @@ bool X86CallFrameOptimization::runOnMachineFunction(MachineFunction &MF) {
return Changed;
}
-X86CallFrameOptimization::InstClassification
-X86CallFrameOptimization::classifyInstruction(
- MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
- const X86RegisterInfo &RegInfo, DenseSet<unsigned int> &UsedRegs) {
- if (MI == MBB.end())
- return Exit;
-
- // The instructions we actually care about are movs onto the stack
- int Opcode = MI->getOpcode();
- if (Opcode == X86::MOV32mi || Opcode == X86::MOV32mr)
- return Convert;
-
- // Not all calling conventions have only stack MOVs between the stack
- // adjust and the call.
-
- // We want to tolerate other instructions, to cover more cases.
- // In particular:
- // a) PCrel calls, where we expect an additional COPY of the basereg.
- // b) Passing frame-index addresses.
- // c) Calling conventions that have inreg parameters. These generate
- // both copies and movs into registers.
- // To avoid creating lots of special cases, allow any instruction
- // that does not write into memory, does not def or use the stack
- // pointer, and does not def any register that was used by a preceding
- // push.
- // (Reading from memory is allowed, even if referenced through a
- // frame index, since these will get adjusted properly in PEI)
-
- // The reason for the last condition is that the pushes can't replace
- // the movs in place, because the order must be reversed.
- // So if we have a MOV32mr that uses EDX, then an instruction that defs
- // EDX, and then the call, after the transformation the push will use
- // the modified version of EDX, and not the original one.
- // Since we are still in SSA form at this point, we only need to
- // make sure we don't clobber any *physical* registers that were
- // used by an earlier mov that will become a push.
-
- if (MI->isCall() || MI->mayStore())
- return Exit;
-
- for (const MachineOperand &MO : MI->operands()) {
- if (!MO.isReg())
- continue;
- unsigned int Reg = MO.getReg();
- if (!RegInfo.isPhysicalRegister(Reg))
- continue;
- if (RegInfo.regsOverlap(Reg, RegInfo.getStackRegister()))
- return Exit;
- if (MO.isDef()) {
- for (unsigned int U : UsedRegs)
- if (RegInfo.regsOverlap(Reg, U))
- return Exit;
- }
- }
-
- return Skip;
-}
-
void X86CallFrameOptimization::collectCallInfo(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
@@ -317,8 +254,8 @@ void X86CallFrameOptimization::collectCallInfo(MachineFunction &MF,
// How much do we adjust the stack? This puts an upper bound on
// the number of parameters actually passed on it.
- unsigned int MaxAdjust = FrameSetup->getOperand(0).getImm() / 4;
-
+ unsigned int MaxAdjust = FrameSetup->getOperand(0).getImm() / 4;
+
// A zero adjustment means no stack parameters
if (!MaxAdjust) {
Context.NoStackParams = true;
@@ -347,17 +284,11 @@ void X86CallFrameOptimization::collectCallInfo(MachineFunction &MF,
if (MaxAdjust > 4)
Context.MovVector.resize(MaxAdjust, nullptr);
- InstClassification Classification;
- DenseSet<unsigned int> UsedRegs;
-
- while ((Classification = classifyInstruction(MBB, I, RegInfo, UsedRegs)) !=
- Exit) {
- if (Classification == Skip) {
- ++I;
- continue;
- }
+ do {
+ int Opcode = I->getOpcode();
+ if (Opcode != X86::MOV32mi && Opcode != X86::MOV32mr)
+ break;
- // We know the instruction is a MOV32mi/MOV32mr.
// We only want movs of the form:
// movl imm/r32, k(%esp)
// If we run into something else, bail.
@@ -392,20 +323,24 @@ void X86CallFrameOptimization::collectCallInfo(MachineFunction &MF,
return;
Context.MovVector[StackDisp] = I;
- for (const MachineOperand &MO : I->uses()) {
- if (!MO.isReg())
- continue;
- unsigned int Reg = MO.getReg();
- if (RegInfo.isPhysicalRegister(Reg))
- UsedRegs.insert(Reg);
- }
-
++I;
+ } while (I != MBB.end());
+
+ // We now expect the end of the sequence - a call and a stack adjust.
+ if (I == MBB.end())
+ return;
+
+ // For PCrel calls, we expect an additional COPY of the basereg.
+ // If we find one, skip it.
+ if (I->isCopy()) {
+ if (I->getOperand(1).getReg() ==
+ MF.getInfo<X86MachineFunctionInfo>()->getGlobalBaseReg())
+ ++I;
+ else
+ return;
}
- // We now expect the end of the sequence. If we stopped early,
- // or reached the end of the block without finding a call, bail.
- if (I == MBB.end() || !I->isCall())
+ if (!I->isCall())
return;
Context.Call = I;