OpenASIP 2.2
Loading...
Searching...
No Matches
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),
83 tri->setTFI(this);
84 }
const TCEInstrInfo & tii_
const TCERegisterInfo * tri_

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}

Referenced by 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}
#define ADDIMM
#define ERASE_INSTR_AND_RETURN(I)
bool hasFP(const MachineFunction &MF) const override
std::tuple< int, int > getPointerAdjustment(int offset) const

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}
#define assert(condition)
#define MOVREG
#define LDRA
#define LDREG
bool containsCall(const MachineFunction &mf) const

References ADDIMM, assert, containsCall(), hasFP(), LDRA, LDREG, MOVREG, 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}
#define STRA
#define STREG

References containsCall(), llvm::TCEInstrInfo::getPointerAdjustment(), hasFP(), MOVREG, 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(), 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_.

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: