-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;
-}
-