PageRenderTime 72ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/src/freebsd/contrib/llvm/lib/Target/MBlaze/MBlazeFrameLowering.cpp

https://bitbucket.org/killerpenguinassassins/open_distrib_devel
C++ | 450 lines | 278 code | 79 blank | 93 comment | 77 complexity | bf6b371e6c1a0373f8b13bf5caadce67 MD5 | raw file
Possible License(s): CC0-1.0, MIT, LGPL-2.0, LGPL-3.0, WTFPL, GPL-2.0, BSD-2-Clause, AGPL-3.0, CC-BY-SA-3.0, MPL-2.0, JSON, BSD-3-Clause-No-Nuclear-License-2014, LGPL-2.1, CPL-1.0, AGPL-1.0, 0BSD, ISC, Apache-2.0, GPL-3.0, IPL-1.0, MPL-2.0-no-copyleft-exception, BSD-3-Clause
  1. //===- MBlazeFrameLowering.cpp - MBlaze 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 MBlaze implementation of TargetFrameLowering class.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #define DEBUG_TYPE "mblaze-frame-lowering"
  14. #include "MBlazeFrameLowering.h"
  15. #include "MBlazeInstrInfo.h"
  16. #include "MBlazeMachineFunction.h"
  17. #include "InstPrinter/MBlazeInstPrinter.h"
  18. #include "llvm/Function.h"
  19. #include "llvm/CodeGen/MachineFrameInfo.h"
  20. #include "llvm/CodeGen/MachineFunction.h"
  21. #include "llvm/CodeGen/MachineInstrBuilder.h"
  22. #include "llvm/CodeGen/MachineModuleInfo.h"
  23. #include "llvm/CodeGen/MachineRegisterInfo.h"
  24. #include "llvm/Target/TargetData.h"
  25. #include "llvm/Target/TargetOptions.h"
  26. #include "llvm/Support/CommandLine.h"
  27. #include "llvm/Support/Debug.h"
  28. #include "llvm/Support/ErrorHandling.h"
  29. #include "llvm/Support/raw_ostream.h"
  30. using namespace llvm;
  31. namespace llvm {
  32. cl::opt<bool> DisableStackAdjust(
  33. "disable-mblaze-stack-adjust",
  34. cl::init(false),
  35. cl::desc("Disable MBlaze stack layout adjustment."),
  36. cl::Hidden);
  37. }
  38. static void replaceFrameIndexes(MachineFunction &MF,
  39. SmallVector<std::pair<int,int64_t>, 16> &FR) {
  40. MachineFrameInfo *MFI = MF.getFrameInfo();
  41. MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
  42. const SmallVector<std::pair<int,int64_t>, 16>::iterator FRB = FR.begin();
  43. const SmallVector<std::pair<int,int64_t>, 16>::iterator FRE = FR.end();
  44. SmallVector<std::pair<int,int64_t>, 16>::iterator FRI = FRB;
  45. for (; FRI != FRE; ++FRI) {
  46. MFI->RemoveStackObject(FRI->first);
  47. int NFI = MFI->CreateFixedObject(4, FRI->second, true);
  48. MBlazeFI->recordReplacement(FRI->first, NFI);
  49. for (MachineFunction::iterator MB=MF.begin(), ME=MF.end(); MB!=ME; ++MB) {
  50. MachineBasicBlock::iterator MBB = MB->begin();
  51. const MachineBasicBlock::iterator MBE = MB->end();
  52. for (; MBB != MBE; ++MBB) {
  53. MachineInstr::mop_iterator MIB = MBB->operands_begin();
  54. const MachineInstr::mop_iterator MIE = MBB->operands_end();
  55. for (MachineInstr::mop_iterator MII = MIB; MII != MIE; ++MII) {
  56. if (!MII->isFI() || MII->getIndex() != FRI->first) continue;
  57. DEBUG(dbgs() << "FOUND FI#" << MII->getIndex() << "\n");
  58. MII->setIndex(NFI);
  59. }
  60. }
  61. }
  62. }
  63. }
  64. //===----------------------------------------------------------------------===//
  65. //
  66. // Stack Frame Processing methods
  67. // +----------------------------+
  68. //
  69. // The stack is allocated decrementing the stack pointer on
  70. // the first instruction of a function prologue. Once decremented,
  71. // all stack references are are done through a positive offset
  72. // from the stack/frame pointer, so the stack is considered
  73. // to grow up.
  74. //
  75. //===----------------------------------------------------------------------===//
  76. static void analyzeFrameIndexes(MachineFunction &MF) {
  77. if (DisableStackAdjust) return;
  78. MachineFrameInfo *MFI = MF.getFrameInfo();
  79. MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
  80. const MachineRegisterInfo &MRI = MF.getRegInfo();
  81. MachineRegisterInfo::livein_iterator LII = MRI.livein_begin();
  82. MachineRegisterInfo::livein_iterator LIE = MRI.livein_end();
  83. const SmallVector<int, 16> &LiveInFI = MBlazeFI->getLiveIn();
  84. SmallVector<MachineInstr*, 16> EraseInstr;
  85. SmallVector<std::pair<int,int64_t>, 16> FrameRelocate;
  86. MachineBasicBlock *MBB = MF.getBlockNumbered(0);
  87. MachineBasicBlock::iterator MIB = MBB->begin();
  88. MachineBasicBlock::iterator MIE = MBB->end();
  89. int StackAdjust = 0;
  90. int StackOffset = -28;
  91. // In this loop we are searching frame indexes that corrospond to incoming
  92. // arguments that are already in the stack. We look for instruction sequences
  93. // like the following:
  94. //
  95. // LWI REG, FI1, 0
  96. // ...
  97. // SWI REG, FI2, 0
  98. //
  99. // As long as there are no defs of REG in the ... part, we can eliminate
  100. // the SWI instruction because the value has already been stored to the
  101. // stack by the caller. All we need to do is locate FI at the correct
  102. // stack location according to the calling convensions.
  103. //
  104. // Additionally, if the SWI operation kills the def of REG then we don't
  105. // need the LWI operation so we can erase it as well.
  106. for (unsigned i = 0, e = LiveInFI.size(); i < e; ++i) {
  107. for (MachineBasicBlock::iterator I=MIB; I != MIE; ++I) {
  108. if (I->getOpcode() != MBlaze::LWI || I->getNumOperands() != 3 ||
  109. !I->getOperand(1).isFI() || !I->getOperand(0).isReg() ||
  110. I->getOperand(1).getIndex() != LiveInFI[i]) continue;
  111. unsigned FIReg = I->getOperand(0).getReg();
  112. MachineBasicBlock::iterator SI = I;
  113. for (SI++; SI != MIE; ++SI) {
  114. if (!SI->getOperand(0).isReg() ||
  115. !SI->getOperand(1).isFI() ||
  116. SI->getOpcode() != MBlaze::SWI) continue;
  117. int FI = SI->getOperand(1).getIndex();
  118. if (SI->getOperand(0).getReg() != FIReg ||
  119. MFI->isFixedObjectIndex(FI) ||
  120. MFI->getObjectSize(FI) != 4) continue;
  121. if (SI->getOperand(0).isDef()) break;
  122. if (SI->getOperand(0).isKill()) {
  123. DEBUG(dbgs() << "LWI for FI#" << I->getOperand(1).getIndex()
  124. << " removed\n");
  125. EraseInstr.push_back(I);
  126. }
  127. EraseInstr.push_back(SI);
  128. DEBUG(dbgs() << "SWI for FI#" << FI << " removed\n");
  129. FrameRelocate.push_back(std::make_pair(FI,StackOffset));
  130. DEBUG(dbgs() << "FI#" << FI << " relocated to " << StackOffset << "\n");
  131. StackOffset -= 4;
  132. StackAdjust += 4;
  133. break;
  134. }
  135. }
  136. }
  137. // In this loop we are searching for frame indexes that corrospond to
  138. // incoming arguments that are in registers. We look for instruction
  139. // sequences like the following:
  140. //
  141. // ... SWI REG, FI, 0
  142. //
  143. // As long as the ... part does not define REG and if REG is an incoming
  144. // parameter register then we know that, according to ABI convensions, the
  145. // caller has allocated stack space for it already. Instead of allocating
  146. // stack space on our frame, we record the correct location in the callers
  147. // frame.
  148. for (MachineRegisterInfo::livein_iterator LI = LII; LI != LIE; ++LI) {
  149. for (MachineBasicBlock::iterator I=MIB; I != MIE; ++I) {
  150. if (I->definesRegister(LI->first))
  151. break;
  152. if (I->getOpcode() != MBlaze::SWI || I->getNumOperands() != 3 ||
  153. !I->getOperand(1).isFI() || !I->getOperand(0).isReg() ||
  154. I->getOperand(1).getIndex() < 0) continue;
  155. if (I->getOperand(0).getReg() == LI->first) {
  156. int FI = I->getOperand(1).getIndex();
  157. MBlazeFI->recordLiveIn(FI);
  158. int FILoc = 0;
  159. switch (LI->first) {
  160. default: llvm_unreachable("invalid incoming parameter!");
  161. case MBlaze::R5: FILoc = -4; break;
  162. case MBlaze::R6: FILoc = -8; break;
  163. case MBlaze::R7: FILoc = -12; break;
  164. case MBlaze::R8: FILoc = -16; break;
  165. case MBlaze::R9: FILoc = -20; break;
  166. case MBlaze::R10: FILoc = -24; break;
  167. }
  168. StackAdjust += 4;
  169. FrameRelocate.push_back(std::make_pair(FI,FILoc));
  170. DEBUG(dbgs() << "FI#" << FI << " relocated to " << FILoc << "\n");
  171. break;
  172. }
  173. }
  174. }
  175. // Go ahead and erase all of the instructions that we determined were
  176. // no longer needed.
  177. for (int i = 0, e = EraseInstr.size(); i < e; ++i)
  178. MBB->erase(EraseInstr[i]);
  179. // Replace all of the frame indexes that we have relocated with new
  180. // fixed object frame indexes.
  181. replaceFrameIndexes(MF, FrameRelocate);
  182. }
  183. static void interruptFrameLayout(MachineFunction &MF) {
  184. const Function *F = MF.getFunction();
  185. llvm::CallingConv::ID CallConv = F->getCallingConv();
  186. // If this function is not using either the interrupt_handler
  187. // calling convention or the save_volatiles calling convention
  188. // then we don't need to do any additional frame layout.
  189. if (CallConv != llvm::CallingConv::MBLAZE_INTR &&
  190. CallConv != llvm::CallingConv::MBLAZE_SVOL)
  191. return;
  192. MachineFrameInfo *MFI = MF.getFrameInfo();
  193. const MachineRegisterInfo &MRI = MF.getRegInfo();
  194. const MBlazeInstrInfo &TII =
  195. *static_cast<const MBlazeInstrInfo*>(MF.getTarget().getInstrInfo());
  196. // Determine if the calling convention is the interrupt_handler
  197. // calling convention. Some pieces of the prologue and epilogue
  198. // only need to be emitted if we are lowering and interrupt handler.
  199. bool isIntr = CallConv == llvm::CallingConv::MBLAZE_INTR;
  200. // Determine where to put prologue and epilogue additions
  201. MachineBasicBlock &MENT = MF.front();
  202. MachineBasicBlock &MEXT = MF.back();
  203. MachineBasicBlock::iterator MENTI = MENT.begin();
  204. MachineBasicBlock::iterator MEXTI = prior(MEXT.end());
  205. DebugLoc ENTDL = MENTI != MENT.end() ? MENTI->getDebugLoc() : DebugLoc();
  206. DebugLoc EXTDL = MEXTI != MEXT.end() ? MEXTI->getDebugLoc() : DebugLoc();
  207. // Store the frame indexes generated during prologue additions for use
  208. // when we are generating the epilogue additions.
  209. SmallVector<int, 10> VFI;
  210. // Build the prologue SWI for R3 - R12 if needed. Note that R11 must
  211. // always have a SWI because it is used when processing RMSR.
  212. for (unsigned r = MBlaze::R3; r <= MBlaze::R12; ++r) {
  213. if (!MRI.isPhysRegUsed(r) && !(isIntr && r == MBlaze::R11)) continue;
  214. int FI = MFI->CreateStackObject(4,4,false,false);
  215. VFI.push_back(FI);
  216. BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), r)
  217. .addFrameIndex(FI).addImm(0);
  218. }
  219. // Build the prologue SWI for R17, R18
  220. int R17FI = MFI->CreateStackObject(4,4,false,false);
  221. int R18FI = MFI->CreateStackObject(4,4,false,false);
  222. BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), MBlaze::R17)
  223. .addFrameIndex(R17FI).addImm(0);
  224. BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), MBlaze::R18)
  225. .addFrameIndex(R18FI).addImm(0);
  226. // Buid the prologue SWI and the epilogue LWI for RMSR if needed
  227. if (isIntr) {
  228. int MSRFI = MFI->CreateStackObject(4,4,false,false);
  229. BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::MFS), MBlaze::R11)
  230. .addReg(MBlaze::RMSR);
  231. BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), MBlaze::R11)
  232. .addFrameIndex(MSRFI).addImm(0);
  233. BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), MBlaze::R11)
  234. .addFrameIndex(MSRFI).addImm(0);
  235. BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::MTS), MBlaze::RMSR)
  236. .addReg(MBlaze::R11);
  237. }
  238. // Build the epilogue LWI for R17, R18
  239. BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), MBlaze::R18)
  240. .addFrameIndex(R18FI).addImm(0);
  241. BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), MBlaze::R17)
  242. .addFrameIndex(R17FI).addImm(0);
  243. // Build the epilogue LWI for R3 - R12 if needed
  244. for (unsigned r = MBlaze::R12, i = VFI.size(); r >= MBlaze::R3; --r) {
  245. if (!MRI.isPhysRegUsed(r)) continue;
  246. BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), r)
  247. .addFrameIndex(VFI[--i]).addImm(0);
  248. }
  249. }
  250. static void determineFrameLayout(MachineFunction &MF) {
  251. MachineFrameInfo *MFI = MF.getFrameInfo();
  252. MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
  253. // Replace the dummy '0' SPOffset by the negative offsets, as explained on
  254. // LowerFORMAL_ARGUMENTS. Leaving '0' for while is necessary to avoid
  255. // the approach done by calculateFrameObjectOffsets to the stack frame.
  256. MBlazeFI->adjustLoadArgsFI(MFI);
  257. MBlazeFI->adjustStoreVarArgsFI(MFI);
  258. // Get the number of bytes to allocate from the FrameInfo
  259. unsigned FrameSize = MFI->getStackSize();
  260. DEBUG(dbgs() << "Original Frame Size: " << FrameSize << "\n" );
  261. // Get the alignments provided by the target, and the maximum alignment
  262. // (if any) of the fixed frame objects.
  263. // unsigned MaxAlign = MFI->getMaxAlignment();
  264. unsigned TargetAlign = MF.getTarget().getFrameLowering()->getStackAlignment();
  265. unsigned AlignMask = TargetAlign - 1;
  266. // Make sure the frame is aligned.
  267. FrameSize = (FrameSize + AlignMask) & ~AlignMask;
  268. MFI->setStackSize(FrameSize);
  269. DEBUG(dbgs() << "Aligned Frame Size: " << FrameSize << "\n" );
  270. }
  271. int MBlazeFrameLowering::getFrameIndexOffset(const MachineFunction &MF, int FI)
  272. const {
  273. const MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
  274. if (MBlazeFI->hasReplacement(FI))
  275. FI = MBlazeFI->getReplacement(FI);
  276. return TargetFrameLowering::getFrameIndexOffset(MF,FI);
  277. }
  278. // hasFP - Return true if the specified function should have a dedicated frame
  279. // pointer register. This is true if the function has variable sized allocas or
  280. // if frame pointer elimination is disabled.
  281. bool MBlazeFrameLowering::hasFP(const MachineFunction &MF) const {
  282. const MachineFrameInfo *MFI = MF.getFrameInfo();
  283. return DisableFramePointerElim(MF) || MFI->hasVarSizedObjects();
  284. }
  285. void MBlazeFrameLowering::emitPrologue(MachineFunction &MF) const {
  286. MachineBasicBlock &MBB = MF.front();
  287. MachineFrameInfo *MFI = MF.getFrameInfo();
  288. const MBlazeInstrInfo &TII =
  289. *static_cast<const MBlazeInstrInfo*>(MF.getTarget().getInstrInfo());
  290. MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
  291. MachineBasicBlock::iterator MBBI = MBB.begin();
  292. DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
  293. llvm::CallingConv::ID CallConv = MF.getFunction()->getCallingConv();
  294. bool requiresRA = CallConv == llvm::CallingConv::MBLAZE_INTR;
  295. // Determine the correct frame layout
  296. determineFrameLayout(MF);
  297. // Get the number of bytes to allocate from the FrameInfo.
  298. unsigned StackSize = MFI->getStackSize();
  299. // No need to allocate space on the stack.
  300. if (StackSize == 0 && !MFI->adjustsStack() && !requiresRA) return;
  301. int FPOffset = MBlazeFI->getFPStackOffset();
  302. int RAOffset = MBlazeFI->getRAStackOffset();
  303. // Adjust stack : addi R1, R1, -imm
  304. BuildMI(MBB, MBBI, DL, TII.get(MBlaze::ADDIK), MBlaze::R1)
  305. .addReg(MBlaze::R1).addImm(-StackSize);
  306. // swi R15, R1, stack_loc
  307. if (MFI->adjustsStack() || requiresRA) {
  308. BuildMI(MBB, MBBI, DL, TII.get(MBlaze::SWI))
  309. .addReg(MBlaze::R15).addReg(MBlaze::R1).addImm(RAOffset);
  310. }
  311. if (hasFP(MF)) {
  312. // swi R19, R1, stack_loc
  313. BuildMI(MBB, MBBI, DL, TII.get(MBlaze::SWI))
  314. .addReg(MBlaze::R19).addReg(MBlaze::R1).addImm(FPOffset);
  315. // add R19, R1, R0
  316. BuildMI(MBB, MBBI, DL, TII.get(MBlaze::ADD), MBlaze::R19)
  317. .addReg(MBlaze::R1).addReg(MBlaze::R0);
  318. }
  319. }
  320. void MBlazeFrameLowering::emitEpilogue(MachineFunction &MF,
  321. MachineBasicBlock &MBB) const {
  322. MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
  323. MachineFrameInfo *MFI = MF.getFrameInfo();
  324. MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
  325. const MBlazeInstrInfo &TII =
  326. *static_cast<const MBlazeInstrInfo*>(MF.getTarget().getInstrInfo());
  327. DebugLoc dl = MBBI->getDebugLoc();
  328. llvm::CallingConv::ID CallConv = MF.getFunction()->getCallingConv();
  329. bool requiresRA = CallConv == llvm::CallingConv::MBLAZE_INTR;
  330. // Get the FI's where RA and FP are saved.
  331. int FPOffset = MBlazeFI->getFPStackOffset();
  332. int RAOffset = MBlazeFI->getRAStackOffset();
  333. if (hasFP(MF)) {
  334. // add R1, R19, R0
  335. BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADD), MBlaze::R1)
  336. .addReg(MBlaze::R19).addReg(MBlaze::R0);
  337. // lwi R19, R1, stack_loc
  338. BuildMI(MBB, MBBI, dl, TII.get(MBlaze::LWI), MBlaze::R19)
  339. .addReg(MBlaze::R1).addImm(FPOffset);
  340. }
  341. // lwi R15, R1, stack_loc
  342. if (MFI->adjustsStack() || requiresRA) {
  343. BuildMI(MBB, MBBI, dl, TII.get(MBlaze::LWI), MBlaze::R15)
  344. .addReg(MBlaze::R1).addImm(RAOffset);
  345. }
  346. // Get the number of bytes from FrameInfo
  347. int StackSize = (int) MFI->getStackSize();
  348. // addi R1, R1, imm
  349. if (StackSize) {
  350. BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADDIK), MBlaze::R1)
  351. .addReg(MBlaze::R1).addImm(StackSize);
  352. }
  353. }
  354. void MBlazeFrameLowering::
  355. processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
  356. RegScavenger *RS) const {
  357. MachineFrameInfo *MFI = MF.getFrameInfo();
  358. MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
  359. llvm::CallingConv::ID CallConv = MF.getFunction()->getCallingConv();
  360. bool requiresRA = CallConv == llvm::CallingConv::MBLAZE_INTR;
  361. if (MFI->adjustsStack() || requiresRA) {
  362. MBlazeFI->setRAStackOffset(0);
  363. MFI->CreateFixedObject(4,0,true);
  364. }
  365. if (hasFP(MF)) {
  366. MBlazeFI->setFPStackOffset(4);
  367. MFI->CreateFixedObject(4,4,true);
  368. }
  369. interruptFrameLayout(MF);
  370. analyzeFrameIndexes(MF);
  371. }