TCE  1.21
Public Member Functions | Private Attributes | List of all members
llvm::TCEFrameInfo Class Reference

#include <TCEFrameInfo.hh>

Inheritance diagram for llvm::TCEFrameInfo:
Inheritance graph
Collaboration diagram for llvm::TCEFrameInfo:
Collaboration graph

Public Member Functions

 TCEFrameInfo (TCERegisterInfo *tri, const TCEInstrInfo *tii, int stackAlignment)
 
MachineBasicBlock::iterator eliminateCallFramePseudoInstr (MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const override
 
void emitPrologue (MachineFunction &mf, MachineBasicBlock &MBB) const override
 
void emitEpilogue (MachineFunction &mf, MachineBasicBlock &MBB) const override
 
bool hasFP (const MachineFunction &MF) const override
 
int stackAlignment () const
 
bool containsCall (MachineFunction &mf) const
 

Private Attributes

int stackAlignment_
 
const TCERegisterInfotri_
 
const TCEInstrInfotii_
 

Detailed Description

Definition at line 67 of file TCEFrameInfo.hh.

Constructor & Destructor Documentation

◆ TCEFrameInfo()

llvm::TCEFrameInfo::TCEFrameInfo ( TCERegisterInfo tri,
const TCEInstrInfo tii,
int  stackAlignment 
)
inline

!! Important !! ************* If the last boolean parameter of the constructor is set to false, stack realignment is not allowed. This means, that every stack object having a bigger alignment than the stack's own alignment, will be reduced to have the stack's alignment.

Definition at line 76 of file TCEFrameInfo.hh.

References eliminateCallFramePseudoInstr(), emitEpilogue(), emitPrologue(), hasFP(), and llvm::TCERegisterInfo::setTFI().

76  :
77 #ifdef LLVM_OLDER_THAN_10
78  TargetFrameLowering(
79  TargetFrameLowering::StackGrowsDown,
82  1,
83  true /*false*/),
84 #else
85  // The -stackAlignment is local area offset.
86  // Storing RA to stack consumes one slot,
87  // so local are offset begins below it.
88  TargetFrameLowering(
89  StackGrowsDown, Align(stackAlignment), -stackAlignment),
90 #endif
91  tri_(tri), tii_(*tii), stackAlignment_(stackAlignment) {
92  tri->setTFI(this); }
const TCEInstrInfo & tii_
const TCERegisterInfo * tri_
int stackAlignment() const
Here is the call graph for this function:

Member Function Documentation

◆ containsCall()

bool TCEFrameInfo::containsCall ( MachineFunction &  mf) const

Definition at line 140 of file TCEFrameInfo.cc.

References TCEISD::CALL, and emitPrologue().

Referenced by llvm::TCERegisterInfo::eliminateFrameIndex(), emitEpilogue(), emitPrologue(), and stackAlignment().

140  {
141  for (MachineFunction::iterator i = mf.begin(); i != mf.end(); i++) {
142  const MachineBasicBlock& mbb = *i;
143  for (MachineBasicBlock::const_iterator j = mbb.begin();
144  j != mbb.end(); j++){
145  const MachineInstr& ins = *j;
146  if (ins.getOpcode() == TCE::CALL ||
147  ins.getOpcode() == TCE::CALL_MEMrr ||
148  ins.getOpcode() == TCE::CALL_MEMri) {
149  return true;
150  }
151  }
152  }
153  return false;
154 }
Here is the call graph for this function:

◆ eliminateCallFramePseudoInstr()

MachineBasicBlock::iterator TCEFrameInfo::eliminateCallFramePseudoInstr ( MachineFunction &  MF,
MachineBasicBlock &  MBB,
MachineBasicBlock::iterator  I 
) const
override

Eliminates call frame pseudo instructions.

Stack space is already reserved in caller stack.

Definition at line 71 of file TCEFrameInfo.cc.

References ERASE_INSTR_AND_RETURN, hasFP(), and tii_.

Referenced by TCEFrameInfo().

73  {
74  if (hasFP(MF)) {
75  int opc = I->getOpcode();
76  // convert stack down to sub
77  if (opc == TCE::ADJCALLSTACKDOWN) {
78 #ifdef LLVM_OLDER_THAN_5_0
79  MachineOperand mo1 = I->getOperand(1);
80  MachineOperand mo2 = I->getOperand(2);
81 #else
82  MachineOperand mo1 = I->getOperand(2);
83  MachineOperand mo2 = I->getOperand(3);
84 #endif
85  long val = I->getOperand(0).getImm();
86 
87  if (val == 0) {
89  }
90  I->setDesc(tii_.get(TCE::SUBrri));
91  I->getOperand(0).ChangeToRegister(mo1.getReg(), mo1.isDef(),
92  false/*mo.isImplicit()*/, mo1.isKill(),
93  false/*dead*/, false/*undef*/,
94  mo1.isDebug());
95  I->getOperand(1).ChangeToRegister(mo2.getReg(), false, false, mo2.isKill(),
96  false, false, mo2.isDebug());
97  I->getOperand(2).ChangeToImmediate(val);
98 
99  // convert stack up to add
100  } else if (opc == TCE::ADJCALLSTACKUP) {
101  MachineOperand mo1 = I->getOperand(2);
102  MachineOperand mo2 = I->getOperand(3);
103  long val = I->getOperand(0).getImm();
104  if (val == 0) {
106  }
107  I->setDesc(tii_.get(TCE::ADDrri));
108  I->getOperand(0).ChangeToRegister(mo1.getReg(), mo1.isDef(),
109  false/*mo.isImplicit()*/, mo1.isKill(),
110  false/*dead*/, false/*undef*/,
111  mo1.isDebug());
112  I->getOperand(1).ChangeToRegister(mo2.getReg(), false, false, mo2.isKill(),
113  false, false, mo2.isDebug());
114  I->getOperand(2).ChangeToImmediate(val);
115  I->RemoveOperand(3);
116  }
117  } else {
119  }
120 #ifndef LLVM_OLDER_THAN_3_9
121  // LLVM 3.9 wants an iterator pointing to the instruction after
122  // the replaced one.
123  return I++;
124 #endif
125 }
const TCEInstrInfo & tii_
bool hasFP(const MachineFunction &MF) const override
#define ERASE_INSTR_AND_RETURN(I)
Definition: TCEFrameInfo.cc:58
Here is the call graph for this function:

◆ emitEpilogue()

void TCEFrameInfo::emitEpilogue ( MachineFunction &  mf,
MachineBasicBlock &  mbb 
) const
override

Emits machine function epilogue to machine functions.

Definition at line 291 of file TCEFrameInfo.cc.

References assert, containsCall(), hasFP(), RA, stackAlignment_, and tii_.

Referenced by TCEFrameInfo().

292  {
293 
294 #if LLVM_OLDER_THAN_4_0
295  MachineFrameInfo& mfi = *mf.getFrameInfo();
296 #else
297  MachineFrameInfo& mfi = mf.getFrameInfo();
298 #endif
299 
300  MachineBasicBlock::iterator mbbi = std::prev(mbb.end());
301 
302  DebugLoc dl = mbbi->getDebugLoc();
303 
304  if (mbbi->getOpcode() != TCE::RETL) {
305  assert(false && "ERROR: Inserting epilogue w/o return?");
306  }
307 
308  unsigned numBytes = mfi.getStackSize();
309  unsigned varBytes = numBytes;
310 
311  if (hasFP(mf)) {
312  varBytes -= stackAlignment_;
313  }
314 
315  // this unfortunately return true for inline asm.
316  bool hasCalls = mfi.hasCalls();
317  if (hasCalls) {
318  // so then check again. Return false if only inline asm, no calls.
319  hasCalls = containsCall(mf);
320  if (hasCalls) {
321  varBytes -= stackAlignment_;
322  }
323  }
324 
325  if (hasFP(mf)) {
326  // move FP to SP
327  BuildMI(mbb, mbbi, dl, tii_.get(TCE::MOVI32rr), TCE::SP)
328  .addReg(TCE::FP)
329  .setMIFlag(MachineInstr::FrameSetup);
330 
331  // restore old FP from stack
332 #ifdef LITTLE_ENDIAN_TARGET
333  BuildMI(mbb, mbbi, dl, tii_.get(TCE::LD32rr), TCE::FP)
334  .addReg(TCE::FP)
335  .addImm(0)
336  .setMIFlag(MachineInstr::FrameSetup);
337 #else
338  BuildMI(mbb, mbbi, dl, tii_.get(TCE::LDWrr), TCE::FP)
339  .addReg(TCE::FP)
340  .addImm(0)
341  .setMIFlag(MachineInstr::FrameSetup);
342 #endif
343 
344  // Create metadata which says that this is an FP load
345  MachineBasicBlock::iterator fpLoad = mbbi; fpLoad--;
346 
347 #ifdef LLVM_OLDER_THAN_6_0
348  LLVMContext& context =
349  mbb.getParent()->getFunction()->getContext();
350 #else
351  LLVMContext& context =
352  mbb.getParent()->getFunction().getContext();
353 #endif
354 
355  llvm::Metadata* md = llvm::MDString::get(context, "AA_CATEGORY_FP_SAVE_SLOT");
356  MDNode* mdNode = MDNode::get(context, llvm::ArrayRef<llvm::Metadata*>(&md, 1));
357 
358  MachineOperand metaDataOperand = MachineOperand::CreateMetadata(mdNode);
359  fpLoad->addOperand(metaDataOperand);
360 
361  // then the SP adjust
362  BuildMI(mbb, mbbi, dl, tii_.get(TCE::ADDrri), TCE::SP)
363  .addReg(TCE::SP)
364  .addImm(stackAlignment_);
365  } else {
366  // no FP
367  if (varBytes) {
368  BuildMI(mbb, mbbi, dl, tii_.get(TCE::ADDrri), TCE::SP)
369  .addReg(TCE::SP)
370  .addImm(varBytes);
371  }
372  }
373 
374  if (hasCalls) {
375  // Restore RA from stack.
376 #ifdef LITTLE_ENDIAN_TARGET
377  BuildMI(mbb, mbbi, dl, tii_.get(TCE::LD32RAr), TCE::RA)
378  .addReg(TCE::SP)
379  .addImm(0)
380  .setMIFlag(MachineInstr::FrameSetup);
381 #else
382  BuildMI(mbb, mbbi, dl, tii_.get(TCE::LDWRAr), TCE::RA)
383  .addReg(TCE::SP)
384  .addImm(0)
385  .setMIFlag(MachineInstr::FrameSetup);
386 #endif
387 
388  // Create metadata which says that this is an RA load
389  MachineBasicBlock::iterator raLoad = mbbi; raLoad--;
390 
391 
392 #ifdef LLVM_OLDER_THAN_6_0
393  LLVMContext& context =
394  mbb.getParent()->getFunction()->getContext();
395 #else
396  LLVMContext& context =
397  mbb.getParent()->getFunction().getContext();
398 #endif
399 
400  llvm::Metadata* md = llvm::MDString::get(context, "AA_CATEGORY_RA_SAVE_SLOT");
401  MDNode* mdNode = MDNode::get(context, llvm::ArrayRef<llvm::Metadata*>(&md, 1));
402 
403  MachineOperand metaDataOperand = MachineOperand::CreateMetadata(mdNode);
404  raLoad->addOperand(metaDataOperand);
405 
406  // then the SP adjust
407  BuildMI(mbb, mbbi, dl, tii_.get(TCE::ADDrri), TCE::SP)
408  .addReg(TCE::SP)
409  .addImm(stackAlignment_);
410  }
411 }
const TCEInstrInfo & tii_
bool hasFP(const MachineFunction &MF) const override
bool containsCall(MachineFunction &mf) const
#define RA()
#define assert(condition)
Definition: Application.hh:80
Here is the call graph for this function:

◆ emitPrologue()

void TCEFrameInfo::emitPrologue ( MachineFunction &  mf,
MachineBasicBlock &  MBB 
) const
override

Emits machine function prologue to machine functions.

Definition at line 163 of file TCEFrameInfo.cc.

References containsCall(), hasFP(), RA, stackAlignment_, and tii_.

Referenced by containsCall(), and TCEFrameInfo().

165  {
166  MachineBasicBlock& mbb = mf.front();
167 #if LLVM_OLDER_THAN_4_0
168  MachineFrameInfo& mfi = *mf.getFrameInfo();
169 #else
170  MachineFrameInfo& mfi = mf.getFrameInfo();
171 #endif
172  int numBytes = (int)mfi.getStackSize();
173 
174  // this unfortunately return true for inline asm.
175  bool hasCalls = mfi.hasCalls();
176  if (hasCalls) {
177  // so then check again. Return false if only inline asm, no calls.
178  hasCalls = containsCall(mf);
179  }
180 
181  // stack size alignment
182  numBytes = (numBytes + (stackAlignment_-1)) & ~(stackAlignment_-1);
183 
184  // stack size without RA/FP storage
185  int varBytes = numBytes;
186 
187  MachineBasicBlock::iterator ii = mbb.begin();
188 
189  DebugLoc dl = (ii != mbb.end() ?
190  ii->getDebugLoc() : DebugLoc());
191 
192  // No need to save RA if does not call anything or does no return
193  // if (hasCalls && !mf.getFunction()->doesNotReturn()) {
194  // However, there is a bug elsewhere and this triggers it.
195  if (hasCalls) {
196  BuildMI(mbb, ii, dl, tii_.get(TCE::SUBrri), TCE::SP)
197  .addReg(TCE::SP)
198  .addImm(stackAlignment_);
199 
200  // Save RA to stack.
201 #ifdef LITTLE_ENDIAN_TARGET
202  BuildMI(mbb, ii, dl, tii_.get(TCE::ST32RArr))
203  .addReg(TCE::SP)
204  .addImm(0)
205  .addReg(TCE::RA)
206  .setMIFlag(MachineInstr::FrameSetup);
207 #else
208  BuildMI(mbb, ii, dl, tii_.get(TCE::STWRArr))
209  .addReg(TCE::SP)
210  .addImm(0)
211  .addReg(TCE::RA)
212  .setMIFlag(MachineInstr::FrameSetup);
213 #endif
214  numBytes += stackAlignment_;
215 
216  // Create metadata which says that this is an RA save
217  MachineBasicBlock::iterator raStore = ii; raStore--;
218 #ifdef LLVM_OLDER_THAN_6_0
219  LLVMContext& context = mbb.getParent()->getFunction()->getContext();
220 #else
221  LLVMContext& context = mbb.getParent()->getFunction().getContext();
222 #endif
223  llvm::Metadata* md =
224  llvm::MDString::get(context, "AA_CATEGORY_RA_SAVE_SLOT");
225  MDNode* mdNode =
226  MDNode::get(context, llvm::ArrayRef<llvm::Metadata*>(&md, 1));
227 
228  MachineOperand metaDataOperand = MachineOperand::CreateMetadata(mdNode);
229  raStore->addOperand(metaDataOperand);
230  }
231 
232  if (hasFP(mf)) {
233  // only need to save old FP if this function may return
234 #ifdef LLVM_OLDER_THAN_6_0
235  if (!mf.getFunction()->doesNotReturn()) {
236 #else
237  if (!mf.getFunction().doesNotReturn()) {
238 #endif
239  BuildMI(mbb, ii, dl, tii_.get(TCE::SUBrri), TCE::SP)
240  .addReg(TCE::SP)
241  .addImm(stackAlignment_);
242 
243 #ifdef LITTLE_ENDIAN_TARGET
244  BuildMI(mbb, ii, dl, tii_.get(TCE::ST32rr))
245  .addReg(TCE::SP)
246  .addImm(0)
247  .addReg(TCE::FP)
248  .setMIFlag(MachineInstr::FrameSetup);
249 #else
250  BuildMI(mbb, ii, dl, tii_.get(TCE::STWrr))
251  .addReg(TCE::SP)
252  .addImm(0)
253  .addReg(TCE::FP)
254  .setMIFlag(MachineInstr::FrameSetup);
255 #endif
256  numBytes += stackAlignment_;
257  // Create metadata which says that this is an FP save
258  MachineBasicBlock::iterator fpStore = ii; fpStore--;
259 #ifdef LLVM_OLDER_THAN_6_0
260  LLVMContext& context = mbb.getParent()->getFunction()->getContext();
261 #else
262  LLVMContext& context = mbb.getParent()->getFunction().getContext();
263 #endif
264  llvm::Metadata* md =
265  llvm::MDString::get(context, "AA_CATEGORY_FP_SAVE_SLOT");
266  MDNode* mdNode =
267  MDNode::get(context, llvm::ArrayRef<llvm::Metadata*>(&md, 1));
268 
269  MachineOperand metaDataOperand = MachineOperand::CreateMetadata(mdNode);
270  fpStore->addOperand(metaDataOperand);
271  }
272  // if FP used by this function, move SP to FP
273  BuildMI(mbb, ii, dl, tii_.get(TCE::MOVI32rr), TCE::FP).addReg(TCE::SP)
274  .setMIFlag(MachineInstr::FrameSetup);
275  }
276 
277  mfi.setStackSize(numBytes);
278 
279  // Adjust stack pointer
280  if (varBytes != 0) {
281  BuildMI(mbb, ii, dl, tii_.get(TCE::SUBrri), TCE::SP)
282  .addReg(TCE::SP)
283  .addImm(varBytes);
284  }
285 }
const TCEInstrInfo & tii_
bool hasFP(const MachineFunction &MF) const override
bool containsCall(MachineFunction &mf) const
#define RA()
Here is the call graph for this function:

◆ hasFP()

bool TCEFrameInfo::hasFP ( const MachineFunction &  MF) const
override

Definition at line 128 of file TCEFrameInfo.cc.

Referenced by eliminateCallFramePseudoInstr(), llvm::TCERegisterInfo::eliminateFrameIndex(), emitEpilogue(), emitPrologue(), llvm::TCERegisterInfo::hasFP(), and TCEFrameInfo().

128  {
129 #if LLVM_OLDER_THAN_4_0
130  if (MF.getFrameInfo()->hasVarSizedObjects()) {
131 #else
132  if (MF.getFrameInfo().hasVarSizedObjects()) {
133 #endif
134  return true;
135  }
136  return false;
137 }

◆ stackAlignment()

int llvm::TCEFrameInfo::stackAlignment ( ) const
inline

Definition at line 111 of file TCEFrameInfo.hh.

References containsCall(), and stackAlignment_.

Referenced by llvm::TCERegisterInfo::eliminateFrameIndex().

111 { return stackAlignment_; }
Here is the call graph for this function:

Member Data Documentation

◆ stackAlignment_

int llvm::TCEFrameInfo::stackAlignment_
private

Definition at line 114 of file TCEFrameInfo.hh.

Referenced by emitEpilogue(), emitPrologue(), and stackAlignment().

◆ tii_

const TCEInstrInfo& llvm::TCEFrameInfo::tii_
private

Definition at line 116 of file TCEFrameInfo.hh.

Referenced by eliminateCallFramePseudoInstr(), emitEpilogue(), and emitPrologue().

◆ tri_

const TCERegisterInfo* llvm::TCEFrameInfo::tri_
private

Definition at line 115 of file TCEFrameInfo.hh.


The documentation for this class was generated from the following files: