OpenASIP 2.2
Loading...
Searching...
No Matches
Public Member Functions | Private Member Functions | Private Attributes | List of all members
llvm::TCERegisterInfo Class Reference

#include <TCERegisterInfo.hh>

Inheritance diagram for llvm::TCERegisterInfo:
Inheritance graph
Collaboration diagram for llvm::TCERegisterInfo:
Collaboration graph

Public Member Functions

 TCERegisterInfo (const TargetInstrInfo &tii)
 
virtual ~TCERegisterInfo ()
 
void eliminateCallFramePseudoInstr (MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const
 
const MCPhysReg * getCalleeSavedRegs (const MachineFunction *MF=0) const override
 
BitVector getReservedRegs (const MachineFunction &MF) const override
 
bool eliminateFrameIndex (MachineBasicBlock::iterator II, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=NULL) const override
 
unsigned getRARegister () const
 
Register getFrameRegister (const MachineFunction &mf) const override
 
bool requiresRegisterScavenging (const MachineFunction &) const override
 
int getDwarfRegNum (unsigned regNum, bool isEH) const
 
int getLLVMRegNum (unsigned int, bool) const
 
bool hasFP (const MachineFunction &MF) const
 
void setTFI (const TCEFrameLowering *tfi)
 

Private Member Functions

void setReservedVectorRegs (llvm::BitVector &reserved) const
 

Private Attributes

const TargetInstrInfo & tii_
 
const TCEFrameLoweringtfi_
 

Detailed Description

Class which handles registers in the TCE backend.

Definition at line 53 of file TCERegisterInfo.hh.

Constructor & Destructor Documentation

◆ TCERegisterInfo()

TCERegisterInfo::TCERegisterInfo ( const TargetInstrInfo &  tii)

The Constructor.

Parameters
stSubtarget architecture.
tiiTarget architecture instruction info.

Definition at line 82 of file TCERegisterInfo.cc.

83 :
84 TCEGenRegisterInfo(TCE::RA),
85 tii_(tii) {
86}
const TargetInstrInfo & tii_

◆ ~TCERegisterInfo()

virtual llvm::TCERegisterInfo::~TCERegisterInfo ( )
inlinevirtual

Definition at line 56 of file TCERegisterInfo.hh.

56{};

Member Function Documentation

◆ eliminateCallFramePseudoInstr()

void llvm::TCERegisterInfo::eliminateCallFramePseudoInstr ( MachineFunction &  MF,
MachineBasicBlock &  MBB,
MachineBasicBlock::iterator  I 
) const

◆ eliminateFrameIndex()

bool TCERegisterInfo::eliminateFrameIndex ( MachineBasicBlock::iterator  II,
int  SPAdj,
unsigned  FIOperandNum,
RegScavenger *  RS = NULL 
) const
override

Definition at line 131 of file TCERegisterInfo.cc.

135 {
136
137 MachineInstr &MI = *II;
138 const TCETargetMachine& tm =
139 dynamic_cast<const TCETargetMachine&>(
140 MI.getParent()->getParent()->getTarget());
141 // Attempt to catch stack accesses using unsupported operation.
142 auto osalOpName = tm.operationName(MI.getOpcode());
143 if (!tm.validStackAccessOperation(osalOpName)
144 && osalOpName.find("MOVE") == std::string::npos) {
146 "Error: Stack address space is not reachable with operation '"
147 + tm.operationName(MI.getOpcode()) + "'.\n"
148 + "Forgot to add the operation to the stack LSU?");
149 }
150 static int lastBypassReg = 0;
151 const TCEInstrInfo &TII = dynamic_cast<const TCEInstrInfo&>(tii_);
152 assert(SPAdj == 0 && "Unexpected");
153
154 DebugLoc dl = MI.getDebugLoc();
155 int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
156 // Addressable stack objects are accessed using neg. offsets from %fp
157 // NO THEY ARE NOT! apwards from SP!
158 MachineFunction &MF = *MI.getParent()->getParent();
159
160 auto& frameinfo = MF.getFrameInfo();
161
162 if (frameinfo.isSpillSlotObjectIndex(FrameIndex)) {
163 for (MachineInstr::mmo_iterator i = MI.memoperands_begin();
164 i != MI.memoperands_end(); i++) {
165 const PseudoSourceValue* psv = (*i)->getPseudoValue();
166 if (psv == NULL) {
167 #ifdef LLVM_OLDER_THAN_15
168 (*i)->setValue(new FixedStackPseudoSourceValue(FrameIndex, TII));
169 #else
170 (*i)->setValue(new FixedStackPseudoSourceValue(FrameIndex, tm));
171 #endif
172 }
173 }
174 if (MI.memoperands_begin() == MI.memoperands_end()) {
175 // TODO: operation and size
176 auto flags = static_cast<MachineMemOperand::Flags>(
177 MI.mayLoad() * MachineMemOperand::MOLoad
178 | MI.mayStore() * MachineMemOperand::MOStore);
179 auto mmo = new MachineMemOperand(
180 MachinePointerInfo(), flags, 0, Align(tfi_->stackAlignment()));
181 #ifdef LLVM_OLDER_THAN_15
182 mmo->setValue(new FixedStackPseudoSourceValue(FrameIndex, TII));
183 #else
184 mmo->setValue(new FixedStackPseudoSourceValue(FrameIndex, tm));
185 #endif
186 MI.addMemOperand(MF, mmo);
187 }
188 }
189
190 if (tfi_->hasFP(MF)) {
191 int Offset = frameinfo.getObjectOffset(FrameIndex);
192 int stackAlign = tfi_->stackAlignment();
193 // FP storage space increases offset by stackAlign.
194 Offset+= stackAlign;
195 // RA storage space increases offset of incoming vars
196 if (FrameIndex < 0 && frameinfo.hasCalls()
197 && tfi_->containsCall(MF)) {
198 Offset+= stackAlign;
199 }
200
201 if (Offset != 0) {
202 // try to use a combined add+ld/st operation
203 // (a base+offset load/store), if available
204 // TODO: check that an offset port width is big enough for the
205 // offset immediate.
206
207
208 TCEString baseOffsetOp = "";
209 TCEString originalOp = tm.operationName(MI.getOpcode());
210
211 // TODO: are these the same for LE? ALD8 etc.?
212 if (originalOp == "LDW" || originalOp == "LDHU" ||
213 originalOp == "LDH" || originalOp == "LDQU" ||
214 originalOp == "LDQ" || originalOp == "STW" ||
215 originalOp == "STH" || originalOp == "STQ" ||
216 originalOp == "LD32" || originalOp == "LDU16" ||
217 originalOp == "LD16" || originalOp == "LDU8" ||
218 originalOp == "LD8" || originalOp == "ST32" ||
219 originalOp == "ST16" || originalOp == "ST8") {
220 baseOffsetOp = TCEString("A") + originalOp;
221 }
222 if (baseOffsetOp != "" && tm.hasOperation(baseOffsetOp)) {
223 const bool isStore = MI.getDesc().mayStore();
224 unsigned storeDataReg = 0;
225 uint64_t storeDataImm = 0;
226
227 // the address should be always the 1st operand for the
228 // base memory ops
229 if (isStore) {
230 // operands: FI, 0, DATA
231 int storeDataOp = FIOperandNum + 2;
232 if (MI.getOperand(storeDataOp).isReg()) {
233 storeDataReg = MI.getOperand(storeDataOp).getReg();
234 } else {
235 assert(MI.getOperand(storeDataOp).isImm());
236 storeDataImm = MI.getOperand(storeDataOp).getImm();
237 }
238 }
239
240 MI.setDesc(TII.get(tm.opcode(baseOffsetOp)));
241 // now it should be safe to overwrite the 2nd operand
242 // with the stack offset
243 MI.getOperand(FIOperandNum).ChangeToRegister(TCE::FP, false);
244 MI.getOperand(FIOperandNum + 1).setImm(Offset);
245
246 if (isStore) {
247 // need to fix the 3rd input operand (the written data)
248 // for stores
249 if (storeDataReg) {
250 MI.getOperand(FIOperandNum + 2).ChangeToRegister(
251 storeDataReg, false);
252 } else {
253 MI.getOperand(FIOperandNum + 2).ChangeToImmediate(
254 storeDataImm);
255 }
256 }
257 } else { // FP, no base+offset ops
258 MI.getOperand(FIOperandNum).ChangeToRegister(
259 TCE::KLUDGE_REGISTER, false, false, true/*iskill*/);
260 //TODO clean up
261 if (Offset > 0) {
262 BuildMI(
263 *MI.getParent(), II, MI.getDebugLoc(),
264 TII.get(ADDIMM), TCE::KLUDGE_REGISTER)
265 .addReg(TCE::FP).addImm(Offset);
266 } else {
267 auto spOpcAndOffset = TII.getPointerAdjustment(Offset);
268 BuildMI(
269 *MI.getParent(), II, MI.getDebugLoc(),
270 TII.get(std::get<0>(spOpcAndOffset)),
271 TCE::KLUDGE_REGISTER)
272 .addReg(TCE::FP)
273 .addImm(std::get<1>(spOpcAndOffset));
274 }
275 }
276 } else { // FP, offset 0
277 MI.getOperand(FIOperandNum).ChangeToRegister(TCE::FP, false);
278 }
279 } else { // no FP
280 int Offset = frameinfo.getObjectOffset(FrameIndex) +
281 frameinfo.getStackSize();
282
283 if (Offset == 0) {
284 MI.getOperand(FIOperandNum).ChangeToRegister(TCE::SP, false);
285 #ifdef LLVM_OLDER_THAN_16
286 return;
287 #else
288 return false;
289 #endif
290 }
291
292 // try to use a combined add+ld/st operation (a base+offset load/store),
293 // if available
294 // TODO: check that an offset port width is big enough for the offset
295 // immediate
296 const TCETargetMachine& tm =
297 dynamic_cast<const TCETargetMachine&>(
298 MI.getParent()->getParent()->getTarget());
299
300
301 TCEString baseOffsetOp = "";
302 TCEString originalOp = tm.operationName(MI.getOpcode());
303
304 // TODO: are these the same for LE? ALD8 etc.?
305 if (originalOp == "LDW" || originalOp == "LDHU" ||
306 originalOp == "LDH" || originalOp == "LDQU" ||
307 originalOp == "LDQ" || originalOp == "STW" ||
308 originalOp == "STH" || originalOp == "STQ" ||
309 originalOp == "LD32" || originalOp == "LDU16" ||
310 originalOp == "LD16" || originalOp == "LDU8" ||
311 originalOp == "LD8" || originalOp == "ST32" ||
312 originalOp == "ST16" || originalOp == "ST8") {
313 baseOffsetOp = TCEString("A") + originalOp;
314 }
315 if (baseOffsetOp != "" && tm.hasOperation(baseOffsetOp)) {
316 const bool isStore = MI.getDesc().mayStore();
317 unsigned storeDataReg = 0;
318 uint64_t storeDataImm = 0;
319
320 // the address should be always the 1st operand for the
321 // base memory ops
322 if (isStore) {
323 // operands: FI, 0, DATA
324 int storeDataOp = FIOperandNum + 2;
325 if (MI.getOperand(storeDataOp).isReg()) {
326 storeDataReg = MI.getOperand(storeDataOp).getReg();
327 } else {
328 assert(MI.getOperand(storeDataOp).isImm());
329 storeDataImm = MI.getOperand(storeDataOp).getImm();
330 }
331 }
332
333 MI.setDesc(TII.get(tm.opcode(baseOffsetOp)));
334 // now it should be safe to overwrite the 2nd operand
335 // with the stack offset
336 MI.getOperand(FIOperandNum).ChangeToRegister(TCE::SP, false);
337 MI.getOperand(FIOperandNum + 1).setImm(Offset);
338
339 if (isStore) {
340 // need to fix the 3rd input operand (the written data)
341 // for stores
342 if (storeDataReg) {
343 MI.getOperand(FIOperandNum + 2).ChangeToRegister(
344 storeDataReg, false);
345 } else {
346 MI.getOperand(FIOperandNum + 2).ChangeToImmediate(
347 storeDataImm);
348 }
349 }
350 } else {
351 // generate the sp + offset addition before the use
352 unsigned int tmp = 0;
353
355 dynamic_cast<LLVMTCECmdLineOptions*>(
357 if (RS != NULL) {
358 tmp = RS->FindUnusedReg(&INTEGER_REG_CLASS);
359 }
360
361 if (tmp != 0) {
362 MI.getOperand(FIOperandNum).ChangeToRegister(
363 tmp, false, false, true);
364 BuildMI(
365 *MI.getParent(), II, MI.getDebugLoc(), TII.get(ADDIMM),
366 tmp).addReg(TCE::SP).addImm(Offset);
367 } else {
368 MI.getOperand(FIOperandNum).ChangeToRegister(
369 TCE::KLUDGE_REGISTER, false);
370 BuildMI(
371 *MI.getParent(), II, MI.getDebugLoc(), TII.get(ADDIMM),
372 TCE::KLUDGE_REGISTER).addReg(TCE::SP).addImm(Offset);
373 }
374 }
375 }
376 #ifdef LLVM_OLDER_THAN_16
377 return;
378 #else
379 return false;
380 #endif
381}
#define assert(condition)
#define THROW_EXCEPTION(exceptionType, message)
Exception wrapper macro that automatically includes file name, line number and function name where th...
Definition Exception.hh:39
static MachInfoCmdLineOptions options
Definition MachInfo.cc:46
#define ADDIMM
#define INTEGER_REG_CLASS
static CmdLineOptions * cmdLineOptions()
bool hasFP(const MachineFunction &MF) const override
bool containsCall(const MachineFunction &mf) const
std::tuple< int, int > getPointerAdjustment(int offset) const
const TCEFrameLowering * tfi_
std::string operationName(unsigned opc) const
bool validStackAccessOperation(const std::string &opName) const
bool hasOperation(TCEString operationName) const
unsigned opcode(TCEString operationName) const

References ADDIMM, assert, Application::cmdLineOptions(), llvm::TCEInstrInfo::getPointerAdjustment(), llvm::TCETargetMachine::hasOperation(), INTEGER_REG_CLASS, llvm::TCETargetMachine::opcode(), llvm::TCETargetMachine::operationName(), options, THROW_EXCEPTION, and llvm::TCETargetMachine::validStackAccessOperation().

Here is the call graph for this function:

◆ getCalleeSavedRegs()

const MCPhysReg * TCERegisterInfo::getCalleeSavedRegs ( const MachineFunction *  MF = 0) const
override

Returns list of callee saved registers.

Definition at line 92 of file TCERegisterInfo.cc.

92 {
93 static const uint16_t calleeSavedRegs[] = { TCE::FP, 0 };
94 if (hasFP(*MF)) {
95 return calleeSavedRegs+1; // skip first, it's reserved
96 } else {
97 return calleeSavedRegs;
98 }
99}
bool hasFP(const MachineFunction &MF) const

References hasFP().

Here is the call graph for this function:

◆ getDwarfRegNum()

int llvm::TCERegisterInfo::getDwarfRegNum ( unsigned  regNum,
bool  isEH 
) const

◆ getFrameRegister()

Register TCERegisterInfo::getFrameRegister ( const MachineFunction &  mf) const
override

Definition at line 416 of file TCERegisterInfo.cc.

416 {
417 if (hasFP(mf)) {
418 return TCE::FP;
419 } else {
420 return 0;
421 }
422}

References hasFP().

Here is the call graph for this function:

◆ getLLVMRegNum()

int llvm::TCERegisterInfo::getLLVMRegNum ( unsigned int  ,
bool   
) const

◆ getRARegister()

unsigned TCERegisterInfo::getRARegister ( ) const

Re-issue the specified 'original' instruction at the specific location targeting a new destination register.

Parameters
mbbMachine basic block of the new instruction.
iPosition of the new instruction in the basic block.
destRegNew destination register.
origOriginal instruction.

void TCERegisterInfo::reMaterialize( MachineBasicBlock& mbb, MachineBasicBlock::iterator i, unsigned destReg, const MachineInstr* orig) const { assert(false && "It really was used"); MachineInstr* mi = mbb.getParent()->CloneMachineInstr(orig); mi->getOperand(0).setReg(destReg); mbb.insert(i, mi); } Not implemented: When is this method even called?

Definition at line 410 of file TCERegisterInfo.cc.

410 {
411 assert(false && "Remove this assert if this is really called.");
412 return TCE::RA;
413}

References assert.

◆ getReservedRegs()

BitVector TCERegisterInfo::getReservedRegs ( const MachineFunction &  mf) const
override

Returns list of reserved registers.

Definition at line 105 of file TCERegisterInfo.cc.

105 {
106
109
110 assert(&mf != NULL);
111 BitVector reserved(getNumRegs());
112 reserved.set(TCE::SP);
113 reserved.set(TCE::KLUDGE_REGISTER);
114 reserved.set(TCE::RA);
115 const MachineFrameInfo* mfi = &mf.getFrameInfo();
116 if (mfi->hasCalls() && tfi_->containsCall(mf)) {
117 for (int i = 0; i < argRegCount; i++) {
118 reserved.set(ArgRegs[i]);
119 }
120 setReservedVectorRegs(reserved);
121 }
122 if (hasFP(mf)) {
123 reserved.set(TCE::FP);
124 }
125
126 return reserved;
127}
void setReservedVectorRegs(llvm::BitVector &reserved) const

References assert, Application::cmdLineOptions(), llvm::TCEFrameLowering::containsCall(), hasFP(), options, setReservedVectorRegs(), and tfi_.

Here is the call graph for this function:

◆ hasFP()

bool TCERegisterInfo::hasFP ( const MachineFunction &  MF) const

Definition at line 425 of file TCERegisterInfo.cc.

425 {
426 return tfi_->hasFP(MF);
427}

References llvm::TCEFrameLowering::hasFP(), and tfi_.

Referenced by getCalleeSavedRegs(), getFrameRegister(), and getReservedRegs().

Here is the call graph for this function:

◆ requiresRegisterScavenging()

bool TCERegisterInfo::requiresRegisterScavenging ( const MachineFunction &  ) const
override

Definition at line 430 of file TCERegisterInfo.cc.

430 {
431 return false;
432}

◆ setReservedVectorRegs()

void llvm::TCERegisterInfo::setReservedVectorRegs ( llvm::BitVector &  reserved) const
private

Referenced by getReservedRegs().

◆ setTFI()

void llvm::TCERegisterInfo::setTFI ( const TCEFrameLowering tfi)
inline

Definition at line 84 of file TCERegisterInfo.hh.

84{ tfi_ = tfi; };

References tfi_.

Referenced by llvm::TCEFrameLowering::TCEFrameLowering().

Member Data Documentation

◆ tfi_

const TCEFrameLowering* llvm::TCERegisterInfo::tfi_
private

Definition at line 89 of file TCERegisterInfo.hh.

Referenced by getReservedRegs(), hasFP(), and setTFI().

◆ tii_

const TargetInstrInfo& llvm::TCERegisterInfo::tii_
private

Definition at line 88 of file TCERegisterInfo.hh.


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