OpenASIP  2.0
Public Member Functions | Private Attributes | List of all members
llvm::TCEFrameLowering Class Reference

#include <TCEFrameInfo.hh>

Inheritance diagram for llvm::TCEFrameLowering:
Inheritance graph
Collaboration diagram for llvm::TCEFrameLowering:
Collaboration graph

Public Member Functions

 TCEFrameLowering (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 (const MachineFunction &mf) const
 

Private Attributes

int stackAlignment_
 
const TCERegisterInfotri_
 
const TCEInstrInfotii_
 

Detailed Description

!! Important !! ************* ON EVERY LLVM UPDATE CHECK THESE INTERFACES VERY CAREFULLY FROM include/llvm/Target/TargetFrameInfo.h

Compiler doesn warn or give error if parameter lists are changed. Many times also base class implementation works, but does not do very good job.

Definition at line 60 of file TCEFrameInfo.hh.

Constructor & Destructor Documentation

◆ TCEFrameLowering()

llvm::TCEFrameLowering::TCEFrameLowering ( 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.

For example, if stack realignment parameter is set to false, and stack has alignment of 4, and v4i32 vector has alignment of 16 (bytes) -> vector's alignment in stack will be demoted to 4.

Definition at line 73 of file TCEFrameInfo.hh.

76  :
77  // The -stackAlignment is local area offset.
78  // Storing RA to stack consumes one slot,
79  // so local are offset begins below it.
80  TargetFrameLowering(
81  StackGrowsDown, Align(stackAlignment), -stackAlignment),
82  tri_(tri), tii_(*tii), stackAlignment_(stackAlignment) {
83  tri->setTFI(this);
84  }

References llvm::TCERegisterInfo::setTFI().

Here is the call graph for this function:

Member Function Documentation

◆ containsCall()

bool TCEFrameLowering::containsCall ( const MachineFunction &  mf) const

Definition at line 146 of file TCEFrameInfo.cc.

146  {
147  for (MachineFunction::const_iterator i = mf.begin(); i != mf.end(); i++) {
148  const MachineBasicBlock& mbb = *i;
149  for (MachineBasicBlock::const_iterator j = mbb.begin();
150  j != mbb.end(); j++){
151  const MachineInstr& ins = *j;
152  if (ins.getOpcode() == TCE::CALL ||
153  ins.getOpcode() == TCE::CALL_MEMrr ||
154  ins.getOpcode() == TCE::CALL_MEMri) {
155  return true;
156  }
157  }
158  }
159  return false;
160 }

References TCEISD::CALL.

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

◆ eliminateCallFramePseudoInstr()

MachineBasicBlock::iterator TCEFrameLowering::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 85 of file TCEFrameInfo.cc.

87  {
88  if (hasFP(MF)) {
89  int opc = I->getOpcode();
90  // convert stack down to sub
91  if (opc == TCE::ADJCALLSTACKDOWN) {
92  MachineOperand mo1 = I->getOperand(2);
93  MachineOperand mo2 = I->getOperand(3);
94  long val = I->getOperand(0).getImm();
95 
96  if (val == 0) {
98  }
99  auto spOpcAndOffset = tii_.getPointerAdjustment(-val);
100  I->setDesc(tii_.get(std::get<0>(spOpcAndOffset)));
101  I->getOperand(0).ChangeToRegister(mo1.getReg(), mo1.isDef(),
102  false/*mo.isImplicit()*/, mo1.isKill(),
103  false/*dead*/, false/*undef*/,
104  mo1.isDebug());
105  I->getOperand(1).ChangeToRegister(mo2.getReg(), false, false, mo2.isKill(),
106  false, false, mo2.isDebug());
107  I->getOperand(2).ChangeToImmediate(std::get<1>(spOpcAndOffset));
108 
109  // convert stack up to add
110  } else if (opc == TCE::ADJCALLSTACKUP) {
111  MachineOperand mo1 = I->getOperand(2);
112  MachineOperand mo2 = I->getOperand(3);
113  long val = I->getOperand(0).getImm();
114  if (val == 0) {
116  }
117  I->setDesc(tii_.get(ADDIMM));
118  I->getOperand(0).ChangeToRegister(mo1.getReg(), mo1.isDef(),
119  false/*mo.isImplicit()*/, mo1.isKill(),
120  false/*dead*/, false/*undef*/,
121  mo1.isDebug());
122  I->getOperand(1).ChangeToRegister(mo2.getReg(), false, false, mo2.isKill(),
123  false, false, mo2.isDebug());
124  I->getOperand(2).ChangeToImmediate(val);
125  #ifdef LLVM_OLDER_THAN_15
126  I->RemoveOperand(3);
127  #else
128  I->removeOperand(3);
129  #endif
130  }
131  } else {
133  }
134  return I;
135 }

References ADDIMM, ERASE_INSTR_AND_RETURN, llvm::TCEInstrInfo::getPointerAdjustment(), hasFP(), and tii_.

Here is the call graph for this function:

◆ emitEpilogue()

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

Emits machine function epilogue to machine functions.

Definition at line 266 of file TCEFrameInfo.cc.

267  {
268 
269  MachineFrameInfo& mfi = mf.getFrameInfo();
270 
271  MachineBasicBlock::iterator mbbi = std::prev(mbb.end());
272 
273  DebugLoc dl = mbbi->getDebugLoc();
274 
275  if (mbbi->getOpcode() != TCE::RETL) {
276  assert(false && "ERROR: Inserting epilogue w/o return?");
277  }
278 
279  unsigned numBytes = mfi.getStackSize();
280  numBytes = (numBytes + (stackAlignment_-1)) & ~(stackAlignment_-1);
281  unsigned varBytes = numBytes;
282 
283  if (hasFP(mf)) {
284  varBytes -= stackAlignment_;
285  }
286 
287  // this unfortunately return true for inline asm.
288  bool hasCalls = mfi.hasCalls();
289  if (hasCalls) {
290  // so then check again. Return false if only inline asm, no calls.
291  hasCalls = containsCall(mf);
292  if (hasCalls) {
293  varBytes -= stackAlignment_;
294  }
295  }
296 
297  if (hasFP(mf)) {
298  // move FP to SP
299  BuildMI(mbb, mbbi, dl, tii_.get(MOVREG), TCE::SP)
300  .addReg(TCE::FP)
301  .setMIFlag(MachineInstr::FrameSetup);
302 
303  // restore old FP from stack
304  BuildMI(mbb, mbbi, dl, tii_.get(LDREG), TCE::FP)
305  .addReg(TCE::FP)
306  .addImm(0)
307  .setMIFlag(MachineInstr::FrameSetup);
308 
309  // Create metadata which says that this is an FP load
310  MachineBasicBlock::iterator fpLoad = mbbi; fpLoad--;
311 
312  LLVMContext& context =
313  mbb.getParent()->getFunction().getContext();
314 
315  llvm::Metadata* md = llvm::MDString::get(context, "AA_CATEGORY_FP_SAVE_SLOT");
316  MDNode* mdNode = MDNode::get(context, llvm::ArrayRef<llvm::Metadata*>(&md, 1));
317 
318  MachineOperand metaDataOperand = MachineOperand::CreateMetadata(mdNode);
319  fpLoad->addOperand(metaDataOperand);
320 
321  // then the SP adjust
322  BuildMI(mbb, mbbi, dl, tii_.get(ADDIMM), TCE::SP)
323  .addReg(TCE::SP)
324  .addImm(stackAlignment_);
325  } else {
326  // no FP
327  if (varBytes) {
328  BuildMI(mbb, mbbi, dl, tii_.get(ADDIMM), TCE::SP)
329  .addReg(TCE::SP)
330  .addImm(varBytes);
331  }
332  }
333 
334  if (hasCalls) {
335  // Restore RA from stack.
336  BuildMI(mbb, mbbi, dl, tii_.get(LDRA), TCE::RA)
337  .addReg(TCE::SP)
338  .addImm(0)
339  .setMIFlag(MachineInstr::FrameSetup);
340  // Create metadata which says that this is an RA load
341  MachineBasicBlock::iterator raLoad = mbbi; raLoad--;
342 
343  LLVMContext& context =
344  mbb.getParent()->getFunction().getContext();
345 
346  llvm::Metadata* md = llvm::MDString::get(context, "AA_CATEGORY_RA_SAVE_SLOT");
347  MDNode* mdNode = MDNode::get(context, llvm::ArrayRef<llvm::Metadata*>(&md, 1));
348 
349  MachineOperand metaDataOperand = MachineOperand::CreateMetadata(mdNode);
350  raLoad->addOperand(metaDataOperand);
351 
352  // then the SP adjust
353  BuildMI(mbb, mbbi, dl, tii_.get(ADDIMM), TCE::SP)
354  .addReg(TCE::SP)
355  .addImm(stackAlignment_);
356  }
357 }

References ADDIMM, assert, containsCall(), hasFP(), LDRA, LDREG, MOVREG, RA, stackAlignment_, and tii_.

Here is the call graph for this function:

◆ emitPrologue()

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

Emits machine function prologue to machine functions.

Definition at line 166 of file TCEFrameInfo.cc.

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

References containsCall(), llvm::TCEInstrInfo::getPointerAdjustment(), hasFP(), MOVREG, RA, stackAlignment_, STRA, STREG, and tii_.

Here is the call graph for this function:

◆ hasFP()

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

Definition at line 138 of file TCEFrameInfo.cc.

138  {
139  if (MF.getFrameInfo().hasVarSizedObjects()) {
140  return true;
141  }
142  return false;
143 }

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

◆ stackAlignment()

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

Definition at line 95 of file TCEFrameInfo.hh.

95 { return stackAlignment_; }

References stackAlignment_.

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

Member Data Documentation

◆ stackAlignment_

int llvm::TCEFrameLowering::stackAlignment_
private

Definition at line 98 of file TCEFrameInfo.hh.

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

◆ tii_

const TCEInstrInfo& llvm::TCEFrameLowering::tii_
private

Definition at line 100 of file TCEFrameInfo.hh.

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

◆ tri_

const TCERegisterInfo* llvm::TCEFrameLowering::tri_
private

Definition at line 99 of file TCEFrameInfo.hh.


The documentation for this class was generated from the following files:
ADDIMM
#define ADDIMM
Definition: TCEFrameInfo.cc:62
llvm::TCEFrameLowering::containsCall
bool containsCall(const MachineFunction &mf) const
Definition: TCEFrameInfo.cc:146
llvm::TCEFrameLowering::hasFP
bool hasFP(const MachineFunction &MF) const override
Definition: TCEFrameInfo.cc:138
llvm::TCEFrameLowering::stackAlignment
int stackAlignment() const
Definition: TCEFrameInfo.hh:95
STRA
#define STRA
Definition: TCEFrameInfo.cc:74
llvm::TCEFrameLowering::tri_
const TCERegisterInfo * tri_
Definition: TCEFrameInfo.hh:99
assert
#define assert(condition)
Definition: Application.hh:86
TCEISD::CALL
@ CALL
Definition: TCEISelLowering.hh:65
ERASE_INSTR_AND_RETURN
#define ERASE_INSTR_AND_RETURN(I)
Definition: TCEFrameInfo.cc:51
LDRA
#define LDRA
Definition: TCEFrameInfo.cc:73
MOVREG
#define MOVREG
Definition: TCEFrameInfo.cc:64
STREG
#define STREG
Definition: TCEFrameInfo.cc:71
RA
#define RA()
Definition: POMGenMacros.hh:393
llvm::TCEInstrInfo::getPointerAdjustment
std::tuple< int, int > getPointerAdjustment(int offset) const
Definition: TCEInstrInfo.cc:721
llvm::TCEFrameLowering::stackAlignment_
int stackAlignment_
Definition: TCEFrameInfo.hh:98
llvm::TCEFrameLowering::tii_
const TCEInstrInfo & tii_
Definition: TCEFrameInfo.hh:100
LDREG
#define LDREG
Definition: TCEFrameInfo.cc:72