1 //===- ARCFrameLowering.cpp - ARC Frame Information -------------*- C++ -*-===// 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 contains the ARC implementation of the TargetFrameLowering class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "ARCFrameLowering.h" 15 #include "ARCMachineFunctionInfo.h" 16 #include "ARCSubtarget.h" 17 #include "llvm/CodeGen/MachineInstrBuilder.h" 18 #include "llvm/CodeGen/MachineModuleInfo.h" 19 #include "llvm/CodeGen/RegisterScavenging.h" 20 #include "llvm/CodeGen/TargetRegisterInfo.h" 21 #include "llvm/IR/Function.h" 22 #include "llvm/Support/Debug.h" 23 24 #define DEBUG_TYPE "arc-frame-lowering" 25 26 using namespace llvm; 27 28 static cl::opt<bool> 29 UseSaveRestoreFunclet("arc-save-restore-funclet", cl::Hidden, 30 cl::desc("Use arc callee save/restore functions"), 31 cl::init(true)); 32 33 static const char *store_funclet_name[] = { 34 "__st_r13_to_r15", "__st_r13_to_r16", "__st_r13_to_r17", "__st_r13_to_r18", 35 "__st_r13_to_r19", "__st_r13_to_r20", "__st_r13_to_r21", "__st_r13_to_r22", 36 "__st_r13_to_r23", "__st_r13_to_r24", "__st_r13_to_r25", 37 }; 38 39 static const char *load_funclet_name[] = { 40 "__ld_r13_to_r15", "__ld_r13_to_r16", "__ld_r13_to_r17", "__ld_r13_to_r18", 41 "__ld_r13_to_r19", "__ld_r13_to_r20", "__ld_r13_to_r21", "__ld_r13_to_r22", 42 "__ld_r13_to_r23", "__ld_r13_to_r24", "__ld_r13_to_r25", 43 }; 44 45 static void generateStackAdjustment(MachineBasicBlock &MBB, 46 MachineBasicBlock::iterator MBBI, 47 const ARCInstrInfo &TII, DebugLoc dl, 48 int Amount, int StackPtr) { 49 unsigned AdjOp; 50 if (!Amount) 51 return; 52 bool Positive; 53 unsigned AbsAmount; 54 if (Amount < 0) { 55 AbsAmount = -Amount; 56 Positive = false; 57 } else { 58 AbsAmount = Amount; 59 Positive = true; 60 } 61 62 LLVM_DEBUG(dbgs() << "Internal: adjust stack by: " << Amount << "," 63 << AbsAmount << "\n"); 64 65 assert((AbsAmount % 4 == 0) && "Stack adjustments must be 4-byte aligned."); 66 if (isUInt<6>(AbsAmount)) 67 AdjOp = Positive ? ARC::ADD_rru6 : ARC::SUB_rru6; 68 else 69 AdjOp = Positive ? ARC::ADD_rrlimm : ARC::SUB_rrlimm; 70 71 BuildMI(MBB, MBBI, dl, TII.get(AdjOp), StackPtr) 72 .addReg(StackPtr) 73 .addImm(AbsAmount); 74 } 75 76 static unsigned 77 determineLastCalleeSave(const std::vector<CalleeSavedInfo> &CSI) { 78 unsigned Last = 0; 79 for (auto Reg : CSI) { 80 assert(Reg.getReg() >= ARC::R13 && Reg.getReg() <= ARC::R25 && 81 "Unexpected callee saved reg."); 82 if (Reg.getReg() > Last) 83 Last = Reg.getReg(); 84 } 85 return Last; 86 } 87 88 void ARCFrameLowering::determineCalleeSaves(MachineFunction &MF, 89 BitVector &SavedRegs, 90 RegScavenger *RS) const { 91 LLVM_DEBUG(dbgs() << "Determine Callee Saves: " << MF.getName() << "\n"); 92 TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); 93 SavedRegs.set(ARC::BLINK); 94 } 95 96 void ARCFrameLowering::adjustStackToMatchRecords( 97 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 98 bool Allocate) const { 99 MachineFunction &MF = *MBB.getParent(); 100 int ScalarAlloc = MF.getFrameInfo().getStackSize(); 101 102 if (Allocate) { 103 // Allocate by adjusting by the negative of what the record holder tracked 104 // it tracked a positive offset in a downward growing stack. 105 ScalarAlloc = -ScalarAlloc; 106 } 107 108 generateStackAdjustment(MBB, MBBI, *ST.getInstrInfo(), DebugLoc(), 109 ScalarAlloc, ARC::SP); 110 } 111 112 /// Insert prolog code into the function. 113 /// For ARC, this inserts a call to a function that puts required callee saved 114 /// registers onto the stack, when enough callee saved registers are required. 115 void ARCFrameLowering::emitPrologue(MachineFunction &MF, 116 MachineBasicBlock &MBB) const { 117 LLVM_DEBUG(dbgs() << "Emit Prologue: " << MF.getName() << "\n"); 118 auto *AFI = MF.getInfo<ARCFunctionInfo>(); 119 MachineModuleInfo &MMI = MF.getMMI(); 120 MCContext &Context = MMI.getContext(); 121 const MCRegisterInfo *MRI = Context.getRegisterInfo(); 122 const ARCInstrInfo *TII = MF.getSubtarget<ARCSubtarget>().getInstrInfo(); 123 MachineBasicBlock::iterator MBBI = MBB.begin(); 124 // Debug location must be unknown since the first debug location is used 125 // to determine the end of the prologue. 126 DebugLoc dl; 127 MachineFrameInfo &MFI = MF.getFrameInfo(); 128 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); 129 unsigned Last = determineLastCalleeSave(CSI); 130 unsigned StackSlotsUsedByFunclet = 0; 131 bool SavedBlink = false; 132 unsigned AlreadyAdjusted = 0; 133 if (MF.getFunction().isVarArg()) { 134 // Add in the varargs area here first. 135 LLVM_DEBUG(dbgs() << "Varargs\n"); 136 unsigned VarArgsBytes = MFI.getObjectSize(AFI->getVarArgsFrameIndex()); 137 BuildMI(MBB, MBBI, dl, TII->get(ARC::SUB_rru6)) 138 .addReg(ARC::SP) 139 .addReg(ARC::SP) 140 .addImm(VarArgsBytes); 141 } 142 if (hasFP(MF)) { 143 LLVM_DEBUG(dbgs() << "Saving FP\n"); 144 BuildMI(MBB, MBBI, dl, TII->get(ARC::ST_AW_rs9)) 145 .addReg(ARC::SP, RegState::Define) 146 .addReg(ARC::FP) 147 .addReg(ARC::SP) 148 .addImm(-4); 149 AlreadyAdjusted += 4; 150 } 151 if (UseSaveRestoreFunclet && Last > ARC::R14) { 152 LLVM_DEBUG(dbgs() << "Creating store funclet.\n"); 153 // BL to __save_r13_to_<TRI->getRegAsmName()> 154 StackSlotsUsedByFunclet = Last - ARC::R12; 155 BuildMI(MBB, MBBI, dl, TII->get(ARC::PUSH_S_BLINK)); 156 BuildMI(MBB, MBBI, dl, TII->get(ARC::SUB_rru6)) 157 .addReg(ARC::SP) 158 .addReg(ARC::SP) 159 .addImm(4 * StackSlotsUsedByFunclet); 160 BuildMI(MBB, MBBI, dl, TII->get(ARC::BL)) 161 .addExternalSymbol(store_funclet_name[Last - ARC::R15]) 162 .addReg(ARC::BLINK, RegState::Implicit | RegState::Kill); 163 AlreadyAdjusted += 4 * (StackSlotsUsedByFunclet + 1); 164 SavedBlink = true; 165 } 166 // If we haven't saved BLINK, but we need to...do that now. 167 if (MFI.hasCalls() && !SavedBlink) { 168 LLVM_DEBUG(dbgs() << "Creating save blink.\n"); 169 BuildMI(MBB, MBBI, dl, TII->get(ARC::PUSH_S_BLINK)); 170 AlreadyAdjusted += 4; 171 } 172 if (AFI->MaxCallStackReq > 0) 173 MFI.setStackSize(MFI.getStackSize() + AFI->MaxCallStackReq); 174 // We have already saved some of the stack... 175 LLVM_DEBUG(dbgs() << "Adjusting stack by: " 176 << (MFI.getStackSize() - AlreadyAdjusted) << "\n"); 177 generateStackAdjustment(MBB, MBBI, *ST.getInstrInfo(), dl, 178 -(MFI.getStackSize() - AlreadyAdjusted), ARC::SP); 179 180 if (hasFP(MF)) { 181 LLVM_DEBUG(dbgs() << "Setting FP from SP.\n"); 182 BuildMI(MBB, MBBI, dl, 183 TII->get(isUInt<6>(MFI.getStackSize()) ? ARC::ADD_rru6 184 : ARC::ADD_rrlimm), 185 ARC::FP) 186 .addReg(ARC::SP) 187 .addImm(MFI.getStackSize()); 188 } 189 190 // Emit CFI records: 191 // .cfi_def_cfa_offset StackSize 192 // .cfi_offset fp, -StackSize 193 // .cfi_offset blink, -StackSize+4 194 unsigned CFIIndex = MF.addFrameInst( 195 MCCFIInstruction::createDefCfaOffset(nullptr, -MFI.getStackSize())); 196 BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION)) 197 .addCFIIndex(CFIIndex) 198 .setMIFlags(MachineInstr::FrameSetup); 199 200 int CurOffset = -4; 201 if (hasFP(MF)) { 202 CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( 203 nullptr, MRI->getDwarfRegNum(ARC::FP, true), CurOffset)); 204 BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION)) 205 .addCFIIndex(CFIIndex) 206 .setMIFlags(MachineInstr::FrameSetup); 207 CurOffset -= 4; 208 } 209 210 if (MFI.hasCalls()) { 211 CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( 212 nullptr, MRI->getDwarfRegNum(ARC::BLINK, true), CurOffset)); 213 BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION)) 214 .addCFIIndex(CFIIndex) 215 .setMIFlags(MachineInstr::FrameSetup); 216 } 217 // CFI for the rest of the registers. 218 for (const auto &Entry : CSI) { 219 unsigned Reg = Entry.getReg(); 220 int FI = Entry.getFrameIdx(); 221 // Skip BLINK and FP. 222 if ((hasFP(MF) && Reg == ARC::FP) || (MFI.hasCalls() && Reg == ARC::BLINK)) 223 continue; 224 CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( 225 nullptr, MRI->getDwarfRegNum(Reg, true), MFI.getObjectOffset(FI))); 226 BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION)) 227 .addCFIIndex(CFIIndex) 228 .setMIFlags(MachineInstr::FrameSetup); 229 } 230 } 231 232 /// Insert epilog code into the function. 233 /// For ARC, this inserts a call to a function that restores callee saved 234 /// registers onto the stack, when enough callee saved registers are required. 235 void ARCFrameLowering::emitEpilogue(MachineFunction &MF, 236 MachineBasicBlock &MBB) const { 237 LLVM_DEBUG(dbgs() << "Emit Epilogue: " << MF.getName() << "\n"); 238 auto *AFI = MF.getInfo<ARCFunctionInfo>(); 239 const ARCInstrInfo *TII = MF.getSubtarget<ARCSubtarget>().getInstrInfo(); 240 MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator(); 241 MachineFrameInfo &MFI = MF.getFrameInfo(); 242 uint64_t StackSize = MF.getFrameInfo().getStackSize(); 243 bool SavedBlink = false; 244 unsigned AmountAboveFunclet = 0; 245 // If we have variable sized frame objects, then we have to move 246 // the stack pointer to a known spot (fp - StackSize). 247 // Then, replace the frame pointer by (new) [sp,StackSize-4]. 248 // Then, move the stack pointer the rest of the way (sp = sp + StackSize). 249 if (hasFP(MF)) { 250 BuildMI(MBB, MBBI, DebugLoc(), TII->get(ARC::SUB_rru6), ARC::SP) 251 .addReg(ARC::FP) 252 .addImm(StackSize); 253 AmountAboveFunclet += 4; 254 } 255 256 // Now, move the stack pointer to the bottom of the save area for the funclet. 257 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); 258 unsigned Last = determineLastCalleeSave(CSI); 259 unsigned StackSlotsUsedByFunclet = 0; 260 // Now, restore the callee save registers. 261 if (UseSaveRestoreFunclet && Last > ARC::R14) { 262 // BL to __ld_r13_to_<TRI->getRegAsmName()> 263 StackSlotsUsedByFunclet = Last - ARC::R12; 264 AmountAboveFunclet += 4 * (StackSlotsUsedByFunclet + 1); 265 SavedBlink = true; 266 } 267 268 if (MFI.hasCalls() && !SavedBlink) { 269 AmountAboveFunclet += 4; 270 SavedBlink = true; 271 } 272 273 // Move the stack pointer up to the point of the funclet. 274 if (StackSize - AmountAboveFunclet) { 275 BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::ADD_rru6)) 276 .addReg(ARC::SP) 277 .addReg(ARC::SP) 278 .addImm(StackSize - AmountAboveFunclet); 279 } 280 281 if (StackSlotsUsedByFunclet) { 282 BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::BL)) 283 .addExternalSymbol(load_funclet_name[Last - ARC::R15]) 284 .addReg(ARC::BLINK, RegState::Implicit | RegState::Kill); 285 BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::ADD_rru6)) 286 .addReg(ARC::SP) 287 .addReg(ARC::SP) 288 .addImm(4 * (StackSlotsUsedByFunclet)); 289 } 290 // Now, pop blink if necessary. 291 if (SavedBlink) { 292 BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::POP_S_BLINK)); 293 } 294 // Now, pop fp if necessary. 295 if (hasFP(MF)) { 296 BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::LD_AB_rs9)) 297 .addReg(ARC::SP, RegState::Define) 298 .addReg(ARC::FP, RegState::Define) 299 .addReg(ARC::SP) 300 .addImm(4); 301 } 302 303 // Relieve the varargs area if necessary. 304 if (MF.getFunction().isVarArg()) { 305 // Add in the varargs area here first. 306 LLVM_DEBUG(dbgs() << "Varargs\n"); 307 unsigned VarArgsBytes = MFI.getObjectSize(AFI->getVarArgsFrameIndex()); 308 BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::ADD_rru6)) 309 .addReg(ARC::SP) 310 .addReg(ARC::SP) 311 .addImm(VarArgsBytes); 312 } 313 } 314 315 static std::vector<CalleeSavedInfo>::iterator 316 getSavedReg(std::vector<CalleeSavedInfo> &V, unsigned reg) { 317 for (auto I = V.begin(), E = V.end(); I != E; ++I) { 318 if (reg == I->getReg()) 319 return I; 320 } 321 return V.end(); 322 } 323 324 bool ARCFrameLowering::assignCalleeSavedSpillSlots( 325 MachineFunction &MF, const TargetRegisterInfo *TRI, 326 std::vector<CalleeSavedInfo> &CSI) const { 327 // Use this opportunity to assign the spill slots for all of the potential 328 // callee save registers (blink, fp, r13->r25) that we care about the 329 // placement for. We can calculate all of that data here. 330 int CurOffset = -4; 331 unsigned Last = determineLastCalleeSave(CSI); 332 MachineFrameInfo &MFI = MF.getFrameInfo(); 333 if (hasFP(MF)) { 334 // Create a fixed slot at for FP 335 int StackObj = MFI.CreateFixedSpillStackObject(4, CurOffset, true); 336 LLVM_DEBUG(dbgs() << "Creating fixed object (" << StackObj << ") for FP at " 337 << CurOffset << "\n"); 338 (void)StackObj; 339 CurOffset -= 4; 340 } 341 if (MFI.hasCalls() || (UseSaveRestoreFunclet && Last > ARC::R14)) { 342 // Create a fixed slot for BLINK. 343 int StackObj = MFI.CreateFixedSpillStackObject(4, CurOffset, true); 344 LLVM_DEBUG(dbgs() << "Creating fixed object (" << StackObj 345 << ") for BLINK at " << CurOffset << "\n"); 346 (void)StackObj; 347 CurOffset -= 4; 348 } 349 350 // Create slots for last down to r13. 351 for (unsigned Which = Last; Which > ARC::R12; Which--) { 352 auto RegI = getSavedReg(CSI, Which); 353 if (RegI == CSI.end() || RegI->getFrameIdx() == 0) { 354 // Always create the stack slot. If for some reason the register isn't in 355 // the save list, then don't worry about it. 356 int FI = MFI.CreateFixedSpillStackObject(4, CurOffset, true); 357 if (RegI != CSI.end()) 358 RegI->setFrameIdx(FI); 359 } else 360 MFI.setObjectOffset(RegI->getFrameIdx(), CurOffset); 361 CurOffset -= 4; 362 } 363 for (auto &I : CSI) { 364 if (I.getReg() > ARC::R12) 365 continue; 366 if (I.getFrameIdx() == 0) { 367 I.setFrameIdx(MFI.CreateFixedSpillStackObject(4, CurOffset, true)); 368 LLVM_DEBUG(dbgs() << "Creating fixed object (" << I.getFrameIdx() 369 << ") for other register at " << CurOffset << "\n"); 370 } else { 371 MFI.setObjectOffset(I.getFrameIdx(), CurOffset); 372 LLVM_DEBUG(dbgs() << "Updating fixed object (" << I.getFrameIdx() 373 << ") for other register at " << CurOffset << "\n"); 374 } 375 CurOffset -= 4; 376 } 377 return true; 378 } 379 380 bool ARCFrameLowering::spillCalleeSavedRegisters( 381 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, 382 const std::vector<CalleeSavedInfo> &CSI, 383 const TargetRegisterInfo *TRI) const { 384 LLVM_DEBUG(dbgs() << "Spill callee saved registers: " 385 << MBB.getParent()->getName() << "\n"); 386 // There are routines for saving at least 3 registers (r13 to r15, etc.) 387 unsigned Last = determineLastCalleeSave(CSI); 388 if (UseSaveRestoreFunclet && Last > ARC::R14) { 389 // Use setObjectOffset for these registers. 390 // Needs to be in or before processFunctionBeforeFrameFinalized. 391 // Or, do assignCalleeSaveSpillSlots? 392 // Will be handled in prolog. 393 return true; 394 } 395 return false; 396 } 397 398 bool ARCFrameLowering::restoreCalleeSavedRegisters( 399 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, 400 std::vector<CalleeSavedInfo> &CSI, const TargetRegisterInfo *TRI) const { 401 LLVM_DEBUG(dbgs() << "Restore callee saved registers: " 402 << MBB.getParent()->getName() << "\n"); 403 // There are routines for saving at least 3 registers (r13 to r15, etc.) 404 unsigned Last = determineLastCalleeSave(CSI); 405 if (UseSaveRestoreFunclet && Last > ARC::R14) { 406 // Will be handled in epilog. 407 return true; 408 } 409 return false; 410 } 411 412 // Adjust local variables that are 4-bytes or larger to 4-byte boundary 413 void ARCFrameLowering::processFunctionBeforeFrameFinalized( 414 MachineFunction &MF, RegScavenger *RS) const { 415 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo(); 416 LLVM_DEBUG(dbgs() << "Process function before frame finalized: " 417 << MF.getName() << "\n"); 418 MachineFrameInfo &MFI = MF.getFrameInfo(); 419 LLVM_DEBUG(dbgs() << "Current stack size: " << MFI.getStackSize() << "\n"); 420 const TargetRegisterClass *RC = &ARC::GPR32RegClass; 421 if (MFI.hasStackObjects()) { 422 int RegScavFI = MFI.CreateStackObject( 423 RegInfo->getSpillSize(*RC), RegInfo->getSpillAlignment(*RC), false); 424 RS->addScavengingFrameIndex(RegScavFI); 425 LLVM_DEBUG(dbgs() << "Created scavenging index RegScavFI=" << RegScavFI 426 << "\n"); 427 } 428 } 429 430 static void emitRegUpdate(MachineBasicBlock &MBB, 431 MachineBasicBlock::iterator &MBBI, DebugLoc dl, 432 unsigned Reg, int NumBytes, bool IsAdd, 433 const ARCInstrInfo *TII) { 434 unsigned Opc = IsAdd ? ARC::ADD_rru6 : ARC::SUB_rru6; 435 BuildMI(MBB, MBBI, dl, TII->get(Opc), Reg) 436 .addReg(Reg, RegState::Kill) 437 .addImm(NumBytes); 438 } 439 440 MachineBasicBlock::iterator ARCFrameLowering::eliminateCallFramePseudoInstr( 441 MachineFunction &MF, MachineBasicBlock &MBB, 442 MachineBasicBlock::iterator I) const { 443 LLVM_DEBUG(dbgs() << "EmitCallFramePseudo: " << MF.getName() << "\n"); 444 const ARCInstrInfo *TII = MF.getSubtarget<ARCSubtarget>().getInstrInfo(); 445 MachineInstr &Old = *I; 446 DebugLoc dl = Old.getDebugLoc(); 447 unsigned Amt = Old.getOperand(0).getImm(); 448 auto *AFI = MF.getInfo<ARCFunctionInfo>(); 449 if (!hasFP(MF)) { 450 if (Amt > AFI->MaxCallStackReq && Old.getOpcode() == ARC::ADJCALLSTACKDOWN) 451 AFI->MaxCallStackReq = Amt; 452 } else { 453 if (Amt != 0) { 454 assert((Old.getOpcode() == ARC::ADJCALLSTACKDOWN || 455 Old.getOpcode() == ARC::ADJCALLSTACKUP) && 456 "Unknown Frame Pseudo."); 457 bool IsAdd = (Old.getOpcode() == ARC::ADJCALLSTACKUP); 458 emitRegUpdate(MBB, I, dl, ARC::SP, Amt, IsAdd, TII); 459 } 460 } 461 return MBB.erase(I); 462 } 463 464 bool ARCFrameLowering::hasFP(const MachineFunction &MF) const { 465 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo(); 466 bool HasFP = MF.getTarget().Options.DisableFramePointerElim(MF) || 467 MF.getFrameInfo().hasVarSizedObjects() || 468 MF.getFrameInfo().isFrameAddressTaken() || 469 RegInfo->needsStackRealignment(MF); 470 return HasFP; 471 } 472