OpenASIP  2.0
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
 
void 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 }

◆ ~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()

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

Definition at line 129 of file TCERegisterInfo.cc.

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

References ADDIMM, assert, Application::cmdLineOptions(), llvm::TCEFrameLowering::containsCall(), llvm::TCEInstrInfo::getPointerAdjustment(), llvm::TCEFrameLowering::hasFP(), llvm::TCETargetMachine::hasOperation(), INTEGER_REG_CLASS, llvm::TCETargetMachine::opcode(), llvm::TCETargetMachine::operationName(), options, llvm::TCEFrameLowering::stackAlignment(), tfi_, THROW_EXCEPTION, tii_, 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 }

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 404 of file TCERegisterInfo.cc.

404  {
405  if (hasFP(mf)) {
406  return TCE::FP;
407  } else {
408  return 0;
409  }
410 }

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 398 of file TCERegisterInfo.cc.

398  {
399  assert(false && "Remove this assert if this is really called.");
400  return TCE::RA;
401 }

References assert, and RA.

◆ 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 }

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

Here is the call graph for this function:

◆ hasFP()

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

Definition at line 413 of file TCERegisterInfo.cc.

413  {
414  return tfi_->hasFP(MF);
415 }

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 418 of file TCERegisterInfo.cc.

418  {
419  return false;
420 }

◆ 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 80 of file TCERegisterInfo.hh.

80 { tfi_ = tfi; };

References tfi_.

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

Member Data Documentation

◆ tfi_

const TCEFrameLowering* llvm::TCERegisterInfo::tfi_
private

Definition at line 85 of file TCERegisterInfo.hh.

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

◆ tii_

const TargetInstrInfo& llvm::TCERegisterInfo::tii_
private

Definition at line 84 of file TCERegisterInfo.hh.

Referenced by eliminateFrameIndex().


The documentation for this class was generated from the following files:
llvm::TCEFrameLowering::containsCall
bool containsCall(const MachineFunction &mf) const
Definition: TCEFrameInfo.cc:146
llvm::TCEInstrInfo
Definition: TCEInstrInfo.hh:57
BitVector
Definition: BitVector.hh:44
llvm::TCETargetMachine::validStackAccessOperation
bool validStackAccessOperation(const std::string &opName) const
Definition: TCETargetMachine.hh:196
INTEGER_REG_CLASS
#define INTEGER_REG_CLASS
Definition: TCERegisterInfo.cc:72
llvm::TCEFrameLowering::hasFP
bool hasFP(const MachineFunction &MF) const override
Definition: TCEFrameInfo.cc:138
CompileError
Definition: Exception.hh:1019
llvm::TCEFrameLowering::stackAlignment
int stackAlignment() const
Definition: TCEFrameInfo.hh:95
ADDIMM
#define ADDIMM
Definition: TCERegisterInfo.cc:70
llvm::TCETargetMachine::hasOperation
bool hasOperation(TCEString operationName) const
Definition: TCETargetMachine.hh:200
assert
#define assert(condition)
Definition: Application.hh:86
llvm::TCERegisterInfo::hasFP
bool hasFP(const MachineFunction &MF) const
Definition: TCERegisterInfo.cc:413
THROW_EXCEPTION
#define THROW_EXCEPTION(exceptionType, message)
Exception wrapper macro that automatically includes file name, line number and function name where th...
Definition: Exception.hh:39
Application::cmdLineOptions
static CmdLineOptions * cmdLineOptions()
Definition: Application.cc:397
LLVMTCECmdLineOptions
Definition: LLVMTCECmdLineOptions.hh:48
options
static MachInfoCmdLineOptions options
Definition: MachInfo.cc:46
RA
#define RA()
Definition: POMGenMacros.hh:393
TCEString
Definition: TCEString.hh:53
llvm::TCERegisterInfo::setReservedVectorRegs
void setReservedVectorRegs(llvm::BitVector &reserved) const
llvm::TCEInstrInfo::getPointerAdjustment
std::tuple< int, int > getPointerAdjustment(int offset) const
Definition: TCEInstrInfo.cc:721
llvm::TCERegisterInfo::tii_
const TargetInstrInfo & tii_
Definition: TCERegisterInfo.hh:84
llvm::TCETargetMachine
Definition: TCETargetMachine.hh:106
llvm::TCETargetMachine::opcode
unsigned opcode(TCEString operationName) const
Definition: TCETargetMachine.hh:241
llvm::TCETargetMachine::operationName
std::string operationName(unsigned opc) const
Definition: TCETargetMachine.hh:188
llvm::TCERegisterInfo::tfi_
const TCEFrameLowering * tfi_
Definition: TCERegisterInfo.hh:85