1 //===----- X86CallFrameOptimization.cpp - Optimize x86 call sequences -----===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines a pass that optimizes call sequences on x86. 11 // Currently, it converts movs of function parameters onto the stack into 12 // pushes. This is beneficial for two main reasons: 13 // 1) The push instruction encoding is much smaller than a stack-ptr-based mov. 14 // 2) It is possible to push memory arguments directly. So, if the 15 // the transformation is performed pre-reg-alloc, it can help relieve 16 // register pressure. 17 // 18 //===----------------------------------------------------------------------===// 19 20 #include "MCTargetDesc/X86BaseInfo.h" 21 #include "X86FrameLowering.h" 22 #include "X86InstrInfo.h" 23 #include "X86MachineFunctionInfo.h" 24 #include "X86RegisterInfo.h" 25 #include "X86Subtarget.h" 26 #include "llvm/ADT/DenseSet.h" 27 #include "llvm/ADT/SmallVector.h" 28 #include "llvm/ADT/StringRef.h" 29 #include "llvm/CodeGen/MachineBasicBlock.h" 30 #include "llvm/CodeGen/MachineFrameInfo.h" 31 #include "llvm/CodeGen/MachineFunction.h" 32 #include "llvm/CodeGen/MachineFunctionPass.h" 33 #include "llvm/CodeGen/MachineInstr.h" 34 #include "llvm/CodeGen/MachineInstrBuilder.h" 35 #include "llvm/CodeGen/MachineOperand.h" 36 #include "llvm/CodeGen/MachineRegisterInfo.h" 37 #include "llvm/IR/DebugLoc.h" 38 #include "llvm/IR/Function.h" 39 #include "llvm/MC/MCDwarf.h" 40 #include "llvm/Support/CommandLine.h" 41 #include "llvm/Support/ErrorHandling.h" 42 #include "llvm/Support/MathExtras.h" 43 #include "llvm/Target/TargetInstrInfo.h" 44 #include "llvm/Target/TargetRegisterInfo.h" 45 #include <cassert> 46 #include <cstddef> 47 #include <cstdint> 48 #include <iterator> 49 50 using namespace llvm; 51 52 #define DEBUG_TYPE "x86-cf-opt" 53 54 static cl::opt<bool> 55 NoX86CFOpt("no-x86-call-frame-opt", 56 cl::desc("Avoid optimizing x86 call frames for size"), 57 cl::init(false), cl::Hidden); 58 59 namespace { 60 61 class X86CallFrameOptimization : public MachineFunctionPass { 62 public: 63 X86CallFrameOptimization() : MachineFunctionPass(ID) {} 64 65 bool runOnMachineFunction(MachineFunction &MF) override; 66 67 private: 68 // Information we know about a particular call site 69 struct CallContext { 70 CallContext() : FrameSetup(nullptr), MovVector(4, nullptr) {} 71 72 // Iterator referring to the frame setup instruction 73 MachineBasicBlock::iterator FrameSetup; 74 75 // Actual call instruction 76 MachineInstr *Call = nullptr; 77 78 // A copy of the stack pointer 79 MachineInstr *SPCopy = nullptr; 80 81 // The total displacement of all passed parameters 82 int64_t ExpectedDist = 0; 83 84 // The sequence of movs used to pass the parameters 85 SmallVector<MachineInstr *, 4> MovVector; 86 87 // True if this call site has no stack parameters 88 bool NoStackParams = false; 89 90 // True if this call site can use push instructions 91 bool UsePush = false; 92 }; 93 94 typedef SmallVector<CallContext, 8> ContextVector; 95 96 bool isLegal(MachineFunction &MF); 97 98 bool isProfitable(MachineFunction &MF, ContextVector &CallSeqMap); 99 100 void collectCallInfo(MachineFunction &MF, MachineBasicBlock &MBB, 101 MachineBasicBlock::iterator I, CallContext &Context); 102 103 void adjustCallSequence(MachineFunction &MF, const CallContext &Context); 104 105 MachineInstr *canFoldIntoRegPush(MachineBasicBlock::iterator FrameSetup, 106 unsigned Reg); 107 108 enum InstClassification { Convert, Skip, Exit }; 109 110 InstClassification classifyInstruction(MachineBasicBlock &MBB, 111 MachineBasicBlock::iterator MI, 112 const X86RegisterInfo &RegInfo, 113 DenseSet<unsigned int> &UsedRegs); 114 115 StringRef getPassName() const override { return "X86 Optimize Call Frame"; } 116 117 const X86InstrInfo *TII; 118 const X86FrameLowering *TFL; 119 const X86Subtarget *STI; 120 MachineRegisterInfo *MRI; 121 unsigned SlotSize; 122 unsigned Log2SlotSize; 123 static char ID; 124 }; 125 126 char X86CallFrameOptimization::ID = 0; 127 128 } // end anonymous namespace 129 130 // This checks whether the transformation is legal. 131 // Also returns false in cases where it's potentially legal, but 132 // we don't even want to try. 133 bool X86CallFrameOptimization::isLegal(MachineFunction &MF) { 134 if (NoX86CFOpt.getValue()) 135 return false; 136 137 // Work around LLVM PR30879 (bad interaction between CFO and libunwind) 138 if (STI->isTargetFreeBSD() && STI->is32Bit() && 139 STI->getTargetTriple().getOSMajorVersion() >= 12) 140 return false; 141 142 // We can't encode multiple DW_CFA_GNU_args_size or DW_CFA_def_cfa_offset 143 // in the compact unwind encoding that Darwin uses. So, bail if there 144 // is a danger of that being generated. 145 if (STI->isTargetDarwin() && 146 (!MF.getLandingPads().empty() || 147 (MF.getFunction()->needsUnwindTableEntry() && !TFL->hasFP(MF)))) 148 return false; 149 150 // It is not valid to change the stack pointer outside the prolog/epilog 151 // on 64-bit Windows. 152 if (STI->isTargetWin64()) 153 return false; 154 155 // You would expect straight-line code between call-frame setup and 156 // call-frame destroy. You would be wrong. There are circumstances (e.g. 157 // CMOV_GR8 expansion of a select that feeds a function call!) where we can 158 // end up with the setup and the destroy in different basic blocks. 159 // This is bad, and breaks SP adjustment. 160 // So, check that all of the frames in the function are closed inside 161 // the same block, and, for good measure, that there are no nested frames. 162 unsigned FrameSetupOpcode = TII->getCallFrameSetupOpcode(); 163 unsigned FrameDestroyOpcode = TII->getCallFrameDestroyOpcode(); 164 for (MachineBasicBlock &BB : MF) { 165 bool InsideFrameSequence = false; 166 for (MachineInstr &MI : BB) { 167 if (MI.getOpcode() == FrameSetupOpcode) { 168 if (InsideFrameSequence) 169 return false; 170 InsideFrameSequence = true; 171 } else if (MI.getOpcode() == FrameDestroyOpcode) { 172 if (!InsideFrameSequence) 173 return false; 174 InsideFrameSequence = false; 175 } 176 } 177 178 if (InsideFrameSequence) 179 return false; 180 } 181 182 return true; 183 } 184 185 // Check whether this transformation is profitable for a particular 186 // function - in terms of code size. 187 bool X86CallFrameOptimization::isProfitable(MachineFunction &MF, 188 ContextVector &CallSeqVector) { 189 // This transformation is always a win when we do not expect to have 190 // a reserved call frame. Under other circumstances, it may be either 191 // a win or a loss, and requires a heuristic. 192 bool CannotReserveFrame = MF.getFrameInfo().hasVarSizedObjects(); 193 if (CannotReserveFrame) 194 return true; 195 196 unsigned StackAlign = TFL->getStackAlignment(); 197 198 int64_t Advantage = 0; 199 for (auto CC : CallSeqVector) { 200 // Call sites where no parameters are passed on the stack 201 // do not affect the cost, since there needs to be no 202 // stack adjustment. 203 if (CC.NoStackParams) 204 continue; 205 206 if (!CC.UsePush) { 207 // If we don't use pushes for a particular call site, 208 // we pay for not having a reserved call frame with an 209 // additional sub/add esp pair. The cost is ~3 bytes per instruction, 210 // depending on the size of the constant. 211 // TODO: Callee-pop functions should have a smaller penalty, because 212 // an add is needed even with a reserved call frame. 213 Advantage -= 6; 214 } else { 215 // We can use pushes. First, account for the fixed costs. 216 // We'll need a add after the call. 217 Advantage -= 3; 218 // If we have to realign the stack, we'll also need a sub before 219 if (CC.ExpectedDist % StackAlign) 220 Advantage -= 3; 221 // Now, for each push, we save ~3 bytes. For small constants, we actually, 222 // save more (up to 5 bytes), but 3 should be a good approximation. 223 Advantage += (CC.ExpectedDist >> Log2SlotSize) * 3; 224 } 225 } 226 227 return Advantage >= 0; 228 } 229 230 bool X86CallFrameOptimization::runOnMachineFunction(MachineFunction &MF) { 231 STI = &MF.getSubtarget<X86Subtarget>(); 232 TII = STI->getInstrInfo(); 233 TFL = STI->getFrameLowering(); 234 MRI = &MF.getRegInfo(); 235 236 const X86RegisterInfo &RegInfo = 237 *static_cast<const X86RegisterInfo *>(STI->getRegisterInfo()); 238 SlotSize = RegInfo.getSlotSize(); 239 assert(isPowerOf2_32(SlotSize) && "Expect power of 2 stack slot size"); 240 Log2SlotSize = Log2_32(SlotSize); 241 242 if (skipFunction(*MF.getFunction()) || !isLegal(MF)) 243 return false; 244 245 unsigned FrameSetupOpcode = TII->getCallFrameSetupOpcode(); 246 247 bool Changed = false; 248 249 ContextVector CallSeqVector; 250 251 for (auto &MBB : MF) 252 for (auto &MI : MBB) 253 if (MI.getOpcode() == FrameSetupOpcode) { 254 CallContext Context; 255 collectCallInfo(MF, MBB, MI, Context); 256 CallSeqVector.push_back(Context); 257 } 258 259 if (!isProfitable(MF, CallSeqVector)) 260 return false; 261 262 for (auto CC : CallSeqVector) { 263 if (CC.UsePush) { 264 adjustCallSequence(MF, CC); 265 Changed = true; 266 } 267 } 268 269 return Changed; 270 } 271 272 X86CallFrameOptimization::InstClassification 273 X86CallFrameOptimization::classifyInstruction( 274 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, 275 const X86RegisterInfo &RegInfo, DenseSet<unsigned int> &UsedRegs) { 276 if (MI == MBB.end()) 277 return Exit; 278 279 // The instructions we actually care about are movs onto the stack 280 int Opcode = MI->getOpcode(); 281 if (Opcode == X86::MOV32mi || Opcode == X86::MOV32mr || 282 Opcode == X86::MOV64mi32 || Opcode == X86::MOV64mr) 283 return Convert; 284 285 // Not all calling conventions have only stack MOVs between the stack 286 // adjust and the call. 287 288 // We want to tolerate other instructions, to cover more cases. 289 // In particular: 290 // a) PCrel calls, where we expect an additional COPY of the basereg. 291 // b) Passing frame-index addresses. 292 // c) Calling conventions that have inreg parameters. These generate 293 // both copies and movs into registers. 294 // To avoid creating lots of special cases, allow any instruction 295 // that does not write into memory, does not def or use the stack 296 // pointer, and does not def any register that was used by a preceding 297 // push. 298 // (Reading from memory is allowed, even if referenced through a 299 // frame index, since these will get adjusted properly in PEI) 300 301 // The reason for the last condition is that the pushes can't replace 302 // the movs in place, because the order must be reversed. 303 // So if we have a MOV32mr that uses EDX, then an instruction that defs 304 // EDX, and then the call, after the transformation the push will use 305 // the modified version of EDX, and not the original one. 306 // Since we are still in SSA form at this point, we only need to 307 // make sure we don't clobber any *physical* registers that were 308 // used by an earlier mov that will become a push. 309 310 if (MI->isCall() || MI->mayStore()) 311 return Exit; 312 313 for (const MachineOperand &MO : MI->operands()) { 314 if (!MO.isReg()) 315 continue; 316 unsigned int Reg = MO.getReg(); 317 if (!RegInfo.isPhysicalRegister(Reg)) 318 continue; 319 if (RegInfo.regsOverlap(Reg, RegInfo.getStackRegister())) 320 return Exit; 321 if (MO.isDef()) { 322 for (unsigned int U : UsedRegs) 323 if (RegInfo.regsOverlap(Reg, U)) 324 return Exit; 325 } 326 } 327 328 return Skip; 329 } 330 331 void X86CallFrameOptimization::collectCallInfo(MachineFunction &MF, 332 MachineBasicBlock &MBB, 333 MachineBasicBlock::iterator I, 334 CallContext &Context) { 335 // Check that this particular call sequence is amenable to the 336 // transformation. 337 const X86RegisterInfo &RegInfo = 338 *static_cast<const X86RegisterInfo *>(STI->getRegisterInfo()); 339 340 // We expect to enter this at the beginning of a call sequence 341 assert(I->getOpcode() == TII->getCallFrameSetupOpcode()); 342 MachineBasicBlock::iterator FrameSetup = I++; 343 Context.FrameSetup = FrameSetup; 344 345 // How much do we adjust the stack? This puts an upper bound on 346 // the number of parameters actually passed on it. 347 unsigned int MaxAdjust = TII->getFrameSize(*FrameSetup) >> Log2SlotSize; 348 349 // A zero adjustment means no stack parameters 350 if (!MaxAdjust) { 351 Context.NoStackParams = true; 352 return; 353 } 354 355 // Skip over DEBUG_VALUE. 356 // For globals in PIC mode, we can have some LEAs here. Skip them as well. 357 // TODO: Extend this to something that covers more cases. 358 while (I->getOpcode() == X86::LEA32r || I->isDebugValue()) 359 ++I; 360 361 unsigned StackPtr = RegInfo.getStackRegister(); 362 // SelectionDAG (but not FastISel) inserts a copy of ESP into a virtual 363 // register here. If it's there, use that virtual register as stack pointer 364 // instead. 365 if (I->isCopy() && I->getOperand(0).isReg() && I->getOperand(1).isReg() && 366 I->getOperand(1).getReg() == StackPtr) { 367 Context.SPCopy = &*I++; 368 StackPtr = Context.SPCopy->getOperand(0).getReg(); 369 } 370 371 // Scan the call setup sequence for the pattern we're looking for. 372 // We only handle a simple case - a sequence of store instructions that 373 // push a sequence of stack-slot-aligned values onto the stack, with 374 // no gaps between them. 375 if (MaxAdjust > 4) 376 Context.MovVector.resize(MaxAdjust, nullptr); 377 378 InstClassification Classification; 379 DenseSet<unsigned int> UsedRegs; 380 381 while ((Classification = classifyInstruction(MBB, I, RegInfo, UsedRegs)) != 382 Exit) { 383 if (Classification == Skip) { 384 ++I; 385 continue; 386 } 387 388 // We know the instruction has a supported store opcode. 389 // We only want movs of the form: 390 // mov imm/reg, k(%StackPtr) 391 // If we run into something else, bail. 392 // Note that AddrBaseReg may, counter to its name, not be a register, 393 // but rather a frame index. 394 // TODO: Support the fi case. This should probably work now that we 395 // have the infrastructure to track the stack pointer within a call 396 // sequence. 397 if (!I->getOperand(X86::AddrBaseReg).isReg() || 398 (I->getOperand(X86::AddrBaseReg).getReg() != StackPtr) || 399 !I->getOperand(X86::AddrScaleAmt).isImm() || 400 (I->getOperand(X86::AddrScaleAmt).getImm() != 1) || 401 (I->getOperand(X86::AddrIndexReg).getReg() != X86::NoRegister) || 402 (I->getOperand(X86::AddrSegmentReg).getReg() != X86::NoRegister) || 403 !I->getOperand(X86::AddrDisp).isImm()) 404 return; 405 406 int64_t StackDisp = I->getOperand(X86::AddrDisp).getImm(); 407 assert(StackDisp >= 0 && 408 "Negative stack displacement when passing parameters"); 409 410 // We really don't want to consider the unaligned case. 411 if (StackDisp & (SlotSize - 1)) 412 return; 413 StackDisp >>= Log2SlotSize; 414 415 assert((size_t)StackDisp < Context.MovVector.size() && 416 "Function call has more parameters than the stack is adjusted for."); 417 418 // If the same stack slot is being filled twice, something's fishy. 419 if (Context.MovVector[StackDisp] != nullptr) 420 return; 421 Context.MovVector[StackDisp] = &*I; 422 423 for (const MachineOperand &MO : I->uses()) { 424 if (!MO.isReg()) 425 continue; 426 unsigned int Reg = MO.getReg(); 427 if (RegInfo.isPhysicalRegister(Reg)) 428 UsedRegs.insert(Reg); 429 } 430 431 ++I; 432 } 433 434 // We now expect the end of the sequence. If we stopped early, 435 // or reached the end of the block without finding a call, bail. 436 if (I == MBB.end() || !I->isCall()) 437 return; 438 439 Context.Call = &*I; 440 if ((++I)->getOpcode() != TII->getCallFrameDestroyOpcode()) 441 return; 442 443 // Now, go through the vector, and see that we don't have any gaps, 444 // but only a series of MOVs. 445 auto MMI = Context.MovVector.begin(), MME = Context.MovVector.end(); 446 for (; MMI != MME; ++MMI, Context.ExpectedDist += SlotSize) 447 if (*MMI == nullptr) 448 break; 449 450 // If the call had no parameters, do nothing 451 if (MMI == Context.MovVector.begin()) 452 return; 453 454 // We are either at the last parameter, or a gap. 455 // Make sure it's not a gap 456 for (; MMI != MME; ++MMI) 457 if (*MMI != nullptr) 458 return; 459 460 Context.UsePush = true; 461 } 462 463 void X86CallFrameOptimization::adjustCallSequence(MachineFunction &MF, 464 const CallContext &Context) { 465 // Ok, we can in fact do the transformation for this call. 466 // Do not remove the FrameSetup instruction, but adjust the parameters. 467 // PEI will end up finalizing the handling of this. 468 MachineBasicBlock::iterator FrameSetup = Context.FrameSetup; 469 MachineBasicBlock &MBB = *(FrameSetup->getParent()); 470 TII->setFrameAdjustment(*FrameSetup, Context.ExpectedDist); 471 472 DebugLoc DL = FrameSetup->getDebugLoc(); 473 bool Is64Bit = STI->is64Bit(); 474 // Now, iterate through the vector in reverse order, and replace the movs 475 // with pushes. MOVmi/MOVmr doesn't have any defs, so no need to 476 // replace uses. 477 for (int Idx = (Context.ExpectedDist >> Log2SlotSize) - 1; Idx >= 0; --Idx) { 478 MachineBasicBlock::iterator MOV = *Context.MovVector[Idx]; 479 MachineOperand PushOp = MOV->getOperand(X86::AddrNumOperands); 480 MachineBasicBlock::iterator Push = nullptr; 481 unsigned PushOpcode; 482 switch (MOV->getOpcode()) { 483 default: 484 llvm_unreachable("Unexpected Opcode!"); 485 case X86::MOV32mi: 486 case X86::MOV64mi32: 487 PushOpcode = Is64Bit ? X86::PUSH64i32 : X86::PUSHi32; 488 // If the operand is a small (8-bit) immediate, we can use a 489 // PUSH instruction with a shorter encoding. 490 // Note that isImm() may fail even though this is a MOVmi, because 491 // the operand can also be a symbol. 492 if (PushOp.isImm()) { 493 int64_t Val = PushOp.getImm(); 494 if (isInt<8>(Val)) 495 PushOpcode = Is64Bit ? X86::PUSH64i8 : X86::PUSH32i8; 496 } 497 Push = BuildMI(MBB, Context.Call, DL, TII->get(PushOpcode)).add(PushOp); 498 break; 499 case X86::MOV32mr: 500 case X86::MOV64mr: { 501 unsigned int Reg = PushOp.getReg(); 502 503 // If storing a 32-bit vreg on 64-bit targets, extend to a 64-bit vreg 504 // in preparation for the PUSH64. The upper 32 bits can be undef. 505 if (Is64Bit && MOV->getOpcode() == X86::MOV32mr) { 506 unsigned UndefReg = MRI->createVirtualRegister(&X86::GR64RegClass); 507 Reg = MRI->createVirtualRegister(&X86::GR64RegClass); 508 BuildMI(MBB, Context.Call, DL, TII->get(X86::IMPLICIT_DEF), UndefReg); 509 BuildMI(MBB, Context.Call, DL, TII->get(X86::INSERT_SUBREG), Reg) 510 .addReg(UndefReg) 511 .add(PushOp) 512 .addImm(X86::sub_32bit); 513 } 514 515 // If PUSHrmm is not slow on this target, try to fold the source of the 516 // push into the instruction. 517 bool SlowPUSHrmm = STI->isAtom() || STI->isSLM(); 518 519 // Check that this is legal to fold. Right now, we're extremely 520 // conservative about that. 521 MachineInstr *DefMov = nullptr; 522 if (!SlowPUSHrmm && (DefMov = canFoldIntoRegPush(FrameSetup, Reg))) { 523 PushOpcode = Is64Bit ? X86::PUSH64rmm : X86::PUSH32rmm; 524 Push = BuildMI(MBB, Context.Call, DL, TII->get(PushOpcode)); 525 526 unsigned NumOps = DefMov->getDesc().getNumOperands(); 527 for (unsigned i = NumOps - X86::AddrNumOperands; i != NumOps; ++i) 528 Push->addOperand(DefMov->getOperand(i)); 529 530 DefMov->eraseFromParent(); 531 } else { 532 PushOpcode = Is64Bit ? X86::PUSH64r : X86::PUSH32r; 533 Push = BuildMI(MBB, Context.Call, DL, TII->get(PushOpcode)) 534 .addReg(Reg) 535 .getInstr(); 536 } 537 break; 538 } 539 } 540 541 // For debugging, when using SP-based CFA, we need to adjust the CFA 542 // offset after each push. 543 // TODO: This is needed only if we require precise CFA. 544 if (!TFL->hasFP(MF)) 545 TFL->BuildCFI( 546 MBB, std::next(Push), DL, 547 MCCFIInstruction::createAdjustCfaOffset(nullptr, SlotSize)); 548 549 MBB.erase(MOV); 550 } 551 552 // The stack-pointer copy is no longer used in the call sequences. 553 // There should not be any other users, but we can't commit to that, so: 554 if (Context.SPCopy && MRI->use_empty(Context.SPCopy->getOperand(0).getReg())) 555 Context.SPCopy->eraseFromParent(); 556 557 // Once we've done this, we need to make sure PEI doesn't assume a reserved 558 // frame. 559 X86MachineFunctionInfo *FuncInfo = MF.getInfo<X86MachineFunctionInfo>(); 560 FuncInfo->setHasPushSequences(true); 561 } 562 563 MachineInstr *X86CallFrameOptimization::canFoldIntoRegPush( 564 MachineBasicBlock::iterator FrameSetup, unsigned Reg) { 565 // Do an extremely restricted form of load folding. 566 // ISel will often create patterns like: 567 // movl 4(%edi), %eax 568 // movl 8(%edi), %ecx 569 // movl 12(%edi), %edx 570 // movl %edx, 8(%esp) 571 // movl %ecx, 4(%esp) 572 // movl %eax, (%esp) 573 // call 574 // Get rid of those with prejudice. 575 if (!TargetRegisterInfo::isVirtualRegister(Reg)) 576 return nullptr; 577 578 // Make sure this is the only use of Reg. 579 if (!MRI->hasOneNonDBGUse(Reg)) 580 return nullptr; 581 582 MachineInstr &DefMI = *MRI->getVRegDef(Reg); 583 584 // Make sure the def is a MOV from memory. 585 // If the def is in another block, give up. 586 if ((DefMI.getOpcode() != X86::MOV32rm && 587 DefMI.getOpcode() != X86::MOV64rm) || 588 DefMI.getParent() != FrameSetup->getParent()) 589 return nullptr; 590 591 // Make sure we don't have any instructions between DefMI and the 592 // push that make folding the load illegal. 593 for (MachineBasicBlock::iterator I = DefMI; I != FrameSetup; ++I) 594 if (I->isLoadFoldBarrier()) 595 return nullptr; 596 597 return &DefMI; 598 } 599 600 FunctionPass *llvm::createX86CallFrameOptimization() { 601 return new X86CallFrameOptimization(); 602 } 603