本文整理汇总了C++中machinebasicblock::iterator类的典型用法代码示例。如果您正苦于以下问题:C++ iterator类的具体用法?C++ iterator怎么用?C++ iterator使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了iterator类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: getEquivalentCompactForm
/// Return the corresponding compact (no delay slot) form of a branch.
unsigned MipsInstrInfo::getEquivalentCompactForm(
const MachineBasicBlock::iterator I) const {
unsigned Opcode = I->getOpcode();
bool canUseShortMicroMipsCTI = false;
if (Subtarget.inMicroMipsMode()) {
switch (Opcode) {
case Mips::BNE:
case Mips::BNE_MM:
case Mips::BEQ:
case Mips::BEQ_MM:
// microMIPS has NE,EQ branches that do not have delay slots provided one
// of the operands is zero.
if (I->getOperand(1).getReg() == Subtarget.getABI().GetZeroReg())
canUseShortMicroMipsCTI = true;
break;
// For microMIPS the PseudoReturn and PseudoIndirectBranch are always
// expanded to JR_MM, so they can be replaced with JRC16_MM.
case Mips::JR:
case Mips::PseudoReturn:
case Mips::PseudoIndirectBranch:
canUseShortMicroMipsCTI = true;
break;
}
}
// MIPSR6 forbids both operands being the zero register.
if (Subtarget.hasMips32r6() && (I->getNumOperands() > 1) &&
(I->getOperand(0).isReg() &&
(I->getOperand(0).getReg() == Mips::ZERO ||
I->getOperand(0).getReg() == Mips::ZERO_64)) &&
(I->getOperand(1).isReg() &&
(I->getOperand(1).getReg() == Mips::ZERO ||
I->getOperand(1).getReg() == Mips::ZERO_64)))
return 0;
if (Subtarget.hasMips32r6() || canUseShortMicroMipsCTI) {
switch (Opcode) {
case Mips::B:
return Mips::BC;
case Mips::BAL:
return Mips::BALC;
case Mips::BEQ:
case Mips::BEQ_MM:
if (canUseShortMicroMipsCTI)
return Mips::BEQZC_MM;
else if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
return 0;
return Mips::BEQC;
case Mips::BNE:
case Mips::BNE_MM:
if (canUseShortMicroMipsCTI)
return Mips::BNEZC_MM;
else if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
return 0;
return Mips::BNEC;
case Mips::BGE:
if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
return 0;
return Mips::BGEC;
case Mips::BGEU:
if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
return 0;
return Mips::BGEUC;
case Mips::BGEZ:
return Mips::BGEZC;
case Mips::BGTZ:
return Mips::BGTZC;
case Mips::BLEZ:
return Mips::BLEZC;
case Mips::BLT:
if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
return 0;
return Mips::BLTC;
case Mips::BLTU:
if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
return 0;
return Mips::BLTUC;
case Mips::BLTZ:
return Mips::BLTZC;
case Mips::BEQ64:
if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
return 0;
return Mips::BEQC64;
case Mips::BNE64:
if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
return 0;
return Mips::BNEC64;
case Mips::BGTZ64:
return Mips::BGTZC64;
case Mips::BGEZ64:
return Mips::BGEZC64;
case Mips::BLTZ64:
return Mips::BLTZC64;
case Mips::BLEZ64:
return Mips::BLEZC64;
// For MIPSR6, the instruction 'jic' can be used for these cases. Some
// tools will accept 'jrc reg' as an alias for 'jic 0, $reg'.
case Mips::JR:
//.........这里部分代码省略.........
示例2: expandPostRAPseudo
bool MipsSEInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const {
MachineBasicBlock &MBB = *MI->getParent();
bool isMicroMips = Subtarget.inMicroMipsMode();
unsigned Opc;
switch(MI->getDesc().getOpcode()) {
default:
return false;
case Mips::RetRA:
expandRetRA(MBB, MI);
break;
case Mips::PseudoMFHI:
Opc = isMicroMips ? Mips::MFHI16_MM : Mips::MFHI;
expandPseudoMFHiLo(MBB, MI, Opc);
break;
case Mips::PseudoMFLO:
Opc = isMicroMips ? Mips::MFLO16_MM : Mips::MFLO;
expandPseudoMFHiLo(MBB, MI, Opc);
break;
case Mips::PseudoMFHI64:
expandPseudoMFHiLo(MBB, MI, Mips::MFHI64);
break;
case Mips::PseudoMFLO64:
expandPseudoMFHiLo(MBB, MI, Mips::MFLO64);
break;
case Mips::PseudoMTLOHI:
expandPseudoMTLoHi(MBB, MI, Mips::MTLO, Mips::MTHI, false);
break;
case Mips::PseudoMTLOHI64:
expandPseudoMTLoHi(MBB, MI, Mips::MTLO64, Mips::MTHI64, false);
break;
case Mips::PseudoMTLOHI_DSP:
expandPseudoMTLoHi(MBB, MI, Mips::MTLO_DSP, Mips::MTHI_DSP, true);
break;
case Mips::PseudoCVT_S_W:
expandCvtFPInt(MBB, MI, Mips::CVT_S_W, Mips::MTC1, false);
break;
case Mips::PseudoCVT_D32_W:
expandCvtFPInt(MBB, MI, Mips::CVT_D32_W, Mips::MTC1, false);
break;
case Mips::PseudoCVT_S_L:
expandCvtFPInt(MBB, MI, Mips::CVT_S_L, Mips::DMTC1, true);
break;
case Mips::PseudoCVT_D64_W:
expandCvtFPInt(MBB, MI, Mips::CVT_D64_W, Mips::MTC1, true);
break;
case Mips::PseudoCVT_D64_L:
expandCvtFPInt(MBB, MI, Mips::CVT_D64_L, Mips::DMTC1, true);
break;
case Mips::BuildPairF64:
expandBuildPairF64(MBB, MI, false);
break;
case Mips::BuildPairF64_64:
expandBuildPairF64(MBB, MI, true);
break;
case Mips::ExtractElementF64:
expandExtractElementF64(MBB, MI, false);
break;
case Mips::ExtractElementF64_64:
expandExtractElementF64(MBB, MI, true);
break;
case Mips::MIPSeh_return32:
case Mips::MIPSeh_return64:
expandEhReturn(MBB, MI);
break;
}
MBB.erase(MI);
return true;
}
示例3: while
bool
AArch64InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB,
SmallVectorImpl<MachineOperand> &Cond,
bool AllowModify) const {
// If the block has no terminators, it just falls into the block after it.
MachineBasicBlock::iterator I = MBB.end();
if (I == MBB.begin())
return false;
--I;
while (I->isDebugValue()) {
if (I == MBB.begin())
return false;
--I;
}
if (!isUnpredicatedTerminator(I))
return false;
// Get the last instruction in the block.
MachineInstr *LastInst = I;
// If there is only one terminator instruction, process it.
unsigned LastOpc = LastInst->getOpcode();
if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
if (LastOpc == AArch64::Bimm) {
TBB = LastInst->getOperand(0).getMBB();
return false;
}
if (isCondBranch(LastOpc)) {
classifyCondBranch(LastInst, TBB, Cond);
return false;
}
return true; // Can't handle indirect branch.
}
// Get the instruction before it if it is a terminator.
MachineInstr *SecondLastInst = I;
unsigned SecondLastOpc = SecondLastInst->getOpcode();
// If AllowModify is true and the block ends with two or more unconditional
// branches, delete all but the first unconditional branch.
if (AllowModify && LastOpc == AArch64::Bimm) {
while (SecondLastOpc == AArch64::Bimm) {
LastInst->eraseFromParent();
LastInst = SecondLastInst;
LastOpc = LastInst->getOpcode();
if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
// Return now the only terminator is an unconditional branch.
TBB = LastInst->getOperand(0).getMBB();
return false;
} else {
SecondLastInst = I;
SecondLastOpc = SecondLastInst->getOpcode();
}
}
}
// If there are three terminators, we don't know what sort of block this is.
if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I))
return true;
// If the block ends with a B and a Bcc, handle it.
if (LastOpc == AArch64::Bimm) {
if (SecondLastOpc == AArch64::Bcc) {
TBB = SecondLastInst->getOperand(1).getMBB();
Cond.push_back(MachineOperand::CreateImm(AArch64::Bcc));
Cond.push_back(SecondLastInst->getOperand(0));
FBB = LastInst->getOperand(0).getMBB();
return false;
} else if (isCondBranch(SecondLastOpc)) {
classifyCondBranch(SecondLastInst, TBB, Cond);
FBB = LastInst->getOperand(0).getMBB();
return false;
}
}
// If the block ends with two unconditional branches, handle it. The second
// one is not executed, so remove it.
if (SecondLastOpc == AArch64::Bimm && LastOpc == AArch64::Bimm) {
TBB = SecondLastInst->getOperand(0).getMBB();
I = LastInst;
if (AllowModify)
I->eraseFromParent();
return false;
}
// Otherwise, can't handle this.
return true;
}
示例4: AnalyzeBranch
bool SparcInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB,
SmallVectorImpl<MachineOperand> &Cond,
bool AllowModify) const
{
MachineBasicBlock::iterator I = MBB.end();
MachineBasicBlock::iterator UnCondBrIter = MBB.end();
while (I != MBB.begin()) {
--I;
if (I->isDebugValue())
continue;
//When we see a non-terminator, we are done
if (!isUnpredicatedTerminator(I))
break;
//Terminator is not a branch
if (!I->getDesc().isBranch())
return true;
//Handle Unconditional branches
if (I->getOpcode() == SP::BA) {
UnCondBrIter = I;
if (!AllowModify) {
TBB = I->getOperand(0).getMBB();
continue;
}
while (llvm::next(I) != MBB.end())
llvm::next(I)->eraseFromParent();
Cond.clear();
FBB = 0;
if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
TBB = 0;
I->eraseFromParent();
I = MBB.end();
UnCondBrIter = MBB.end();
continue;
}
TBB = I->getOperand(0).getMBB();
continue;
}
unsigned Opcode = I->getOpcode();
if (Opcode != SP::BCOND && Opcode != SP::FBCOND)
return true; //Unknown Opcode
SPCC::CondCodes BranchCode = (SPCC::CondCodes)I->getOperand(1).getImm();
if (Cond.empty()) {
MachineBasicBlock *TargetBB = I->getOperand(0).getMBB();
if (AllowModify && UnCondBrIter != MBB.end() &&
MBB.isLayoutSuccessor(TargetBB)) {
//Transform the code
//
// brCC L1
// ba L2
// L1:
// ..
// L2:
//
// into
//
// brnCC L2
// L1:
// ...
// L2:
//
BranchCode = GetOppositeBranchCondition(BranchCode);
MachineBasicBlock::iterator OldInst = I;
BuildMI(MBB, UnCondBrIter, MBB.findDebugLoc(I), get(Opcode))
.addMBB(UnCondBrIter->getOperand(0).getMBB()).addImm(BranchCode);
BuildMI(MBB, UnCondBrIter, MBB.findDebugLoc(I), get(SP::BA))
.addMBB(TargetBB);
MBB.addSuccessor(TargetBB);
OldInst->eraseFromParent();
UnCondBrIter->eraseFromParent();
UnCondBrIter = MBB.end();
I = MBB.end();
continue;
}
FBB = TBB;
TBB = I->getOperand(0).getMBB();
Cond.push_back(MachineOperand::CreateImm(BranchCode));
continue;
}
//FIXME: Handle subsequent conditional branches
//For now, we can't handle multiple conditional branches
return true;
}
return false;
//.........这里部分代码省略.........
示例5: RemoveBranch
unsigned LembergInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
MachineBasicBlock::iterator I = MBB.end();
if (I == MBB.begin()) return 0;
--I;
if (I->getOpcode() != Lemberg::JUMP &&
I->getOpcode() != Lemberg::JUMPtrue &&
I->getOpcode() != Lemberg::JUMPfalse &&
I->getOpcode() != Lemberg::JUMPpred &&
I->getOpcode() != Lemberg::JUMPeqz &&
I->getOpcode() != Lemberg::JUMPnez &&
I->getOpcode() != Lemberg::JUMPltz &&
I->getOpcode() != Lemberg::JUMPgez &&
I->getOpcode() != Lemberg::JUMPgtz &&
I->getOpcode() != Lemberg::JUMPlez)
return 0;
// Remove the branch.
I->eraseFromParent();
I = MBB.end();
if (I == MBB.begin()) return 1;
--I;
if (I->getOpcode() != Lemberg::JUMPtrue &&
I->getOpcode() != Lemberg::JUMPfalse &&
I->getOpcode() != Lemberg::JUMPpred &&
I->getOpcode() != Lemberg::JUMPeqz &&
I->getOpcode() != Lemberg::JUMPnez &&
I->getOpcode() != Lemberg::JUMPltz &&
I->getOpcode() != Lemberg::JUMPgez &&
I->getOpcode() != Lemberg::JUMPgtz &&
I->getOpcode() != Lemberg::JUMPlez)
return 1;
// Remove the branch.
I->eraseFromParent();
return 2;
}
示例6: insertCallDefsUses
MachineBasicBlock::iterator
Filler::findDelayInstr(MachineBasicBlock &MBB,
MachineBasicBlock::iterator slot)
{
SmallSet<unsigned, 32> RegDefs;
SmallSet<unsigned, 32> RegUses;
bool sawLoad = false;
bool sawStore = false;
if (slot == MBB.begin())
return MBB.end();
if (slot->getOpcode() == SP::RET || slot->getOpcode() == SP::TLS_CALL)
return MBB.end();
if (slot->getOpcode() == SP::RETL) {
MachineBasicBlock::iterator J = slot;
--J;
if (J->getOpcode() == SP::RESTORErr
|| J->getOpcode() == SP::RESTOREri) {
// change retl to ret.
slot->setDesc(TM.getInstrInfo()->get(SP::RET));
return J;
}
}
// Call's delay filler can def some of call's uses.
if (slot->isCall())
insertCallDefsUses(slot, RegDefs, RegUses);
else
insertDefsUses(slot, RegDefs, RegUses);
bool done = false;
MachineBasicBlock::iterator I = slot;
while (!done) {
done = (I == MBB.begin());
if (!done)
--I;
// skip debug value
if (I->isDebugValue())
continue;
if (I->hasUnmodeledSideEffects() || I->isInlineAsm() || I->isPosition() ||
I->hasDelaySlot() || I->isBundledWithSucc())
break;
if (delayHasHazard(I, sawLoad, sawStore, RegDefs, RegUses)) {
insertDefsUses(I, RegDefs, RegUses);
continue;
}
return I;
}
return MBB.end();
}
示例7: killDelaySlots
bool PatmosDelaySlotKiller::killDelaySlots(MachineBasicBlock &MBB) {
bool Changed = false;
DEBUG( dbgs() << "Killing slots in BB#" << MBB.getNumber()
<< " (" << MBB.getFullName() << ")\n" );
// consider the basic block from top to bottom
for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I) {
// Control-flow instructions ("proper" delay slots)
if (I->hasDelaySlot()) {
assert( ( I->isCall() || I->isReturn() || I->isBranch() )
&& "Unexpected instruction with delay slot.");
MachineBasicBlock::instr_iterator MI = *I;
if (I->isBundle()) { ++MI; }
unsigned Opcode = MI->getOpcode();
if (Opcode == Patmos::BR ||
Opcode == Patmos::BRu ||
Opcode == Patmos::BRR ||
Opcode == Patmos::BRRu ||
Opcode == Patmos::BRT ||
Opcode == Patmos::BRTu ||
Opcode == Patmos::BRCF ||
Opcode == Patmos::BRCFu ||
Opcode == Patmos::BRCFR ||
Opcode == Patmos::BRCFRu ||
Opcode == Patmos::BRCFT ||
Opcode == Patmos::BRCFTu ||
Opcode == Patmos::CALL ||
Opcode == Patmos::CALLR ||
Opcode == Patmos::RET ||
Opcode == Patmos::XRET) {
bool onlyNops = true;
unsigned maxCount = TM.getSubtargetImpl()->getDelaySlotCycles(&*I);
unsigned count = 0;
for (MachineBasicBlock::iterator K = llvm::next(I), E = MBB.end();
K != E && count < maxCount; ++K, ++count) {
if (K->getOpcode() != Patmos::NOP) {
onlyNops = false;
}
}
if (onlyNops) {
unsigned NewOpcode = 0;
switch(Opcode) {
case Patmos::BR: NewOpcode = Patmos::BRND; break;
case Patmos::BRu: NewOpcode = Patmos::BRNDu; break;
case Patmos::BRR: NewOpcode = Patmos::BRRND; break;
case Patmos::BRRu: NewOpcode = Patmos::BRRNDu; break;
case Patmos::BRT: NewOpcode = Patmos::BRTND; break;
case Patmos::BRTu: NewOpcode = Patmos::BRTNDu; break;
case Patmos::BRCF: NewOpcode = Patmos::BRCFND; break;
case Patmos::BRCFu: NewOpcode = Patmos::BRCFNDu; break;
case Patmos::BRCFR: NewOpcode = Patmos::BRCFRND; break;
case Patmos::BRCFRu: NewOpcode = Patmos::BRCFRNDu; break;
case Patmos::BRCFT: NewOpcode = Patmos::BRCFTND; break;
case Patmos::BRCFTu: NewOpcode = Patmos::BRCFTNDu; break;
case Patmos::CALL: NewOpcode = Patmos::CALLND; break;
case Patmos::CALLR: NewOpcode = Patmos::CALLRND; break;
case Patmos::RET: NewOpcode = Patmos::RETND; break;
case Patmos::XRET: NewOpcode = Patmos::XRETND; break;
}
const MCInstrDesc &nonDelayed = TII->get(NewOpcode);
MI->setDesc(nonDelayed);
unsigned killCount = 0;
MachineBasicBlock::iterator K = llvm::next(I);
for (MachineBasicBlock::iterator E = MBB.end();
K != E && killCount < count; ++K, ++killCount) {
KilledSlots++;
}
MBB.erase(llvm::next(I), K);
}
}
Changed = true; // pass result
}
}
return Changed;
}
示例8: emitPrologue
void MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const {
MachineBasicBlock &MBB = MF.front();
MachineFrameInfo *MFI = MF.getFrameInfo();
const MipsRegisterInfo *RegInfo =
static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo());
const MipsSEInstrInfo &TII =
*static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo());
MachineBasicBlock::iterator MBBI = MBB.begin();
DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP;
unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP;
unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO;
unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu;
// First, compute final stack size.
uint64_t StackSize = MFI->getStackSize();
// No need to allocate space on the stack.
if (StackSize == 0 && !MFI->adjustsStack()) return;
MachineModuleInfo &MMI = MF.getMMI();
std::vector<MachineMove> &Moves = MMI.getFrameMoves();
MachineLocation DstML, SrcML;
// Adjust stack.
TII.adjustStackPtr(SP, -StackSize, MBB, MBBI);
// emit ".cfi_def_cfa_offset StackSize"
MCSymbol *AdjustSPLabel = MMI.getContext().CreateTempSymbol();
BuildMI(MBB, MBBI, dl,
TII.get(TargetOpcode::PROLOG_LABEL)).addSym(AdjustSPLabel);
DstML = MachineLocation(MachineLocation::VirtualFP);
SrcML = MachineLocation(MachineLocation::VirtualFP, -StackSize);
Moves.push_back(MachineMove(AdjustSPLabel, DstML, SrcML));
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
if (CSI.size()) {
// Find the instruction past the last instruction that saves a callee-saved
// register to the stack.
for (unsigned i = 0; i < CSI.size(); ++i)
++MBBI;
// Iterate over list of callee-saved registers and emit .cfi_offset
// directives.
MCSymbol *CSLabel = MMI.getContext().CreateTempSymbol();
BuildMI(MBB, MBBI, dl,
TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel);
for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(),
E = CSI.end(); I != E; ++I) {
int64_t Offset = MFI->getObjectOffset(I->getFrameIdx());
unsigned Reg = I->getReg();
// If Reg is a double precision register, emit two cfa_offsets,
// one for each of the paired single precision registers.
if (Mips::AFGR64RegClass.contains(Reg)) {
MachineLocation DstML0(MachineLocation::VirtualFP, Offset);
MachineLocation DstML1(MachineLocation::VirtualFP, Offset + 4);
MachineLocation SrcML0(RegInfo->getSubReg(Reg, Mips::sub_fpeven));
MachineLocation SrcML1(RegInfo->getSubReg(Reg, Mips::sub_fpodd));
if (!STI.isLittle())
std::swap(SrcML0, SrcML1);
Moves.push_back(MachineMove(CSLabel, DstML0, SrcML0));
Moves.push_back(MachineMove(CSLabel, DstML1, SrcML1));
} else {
// Reg is either in CPURegs or FGR32.
DstML = MachineLocation(MachineLocation::VirtualFP, Offset);
SrcML = MachineLocation(Reg);
Moves.push_back(MachineMove(CSLabel, DstML, SrcML));
}
}
}
// if framepointer enabled, set it to point to the stack pointer.
if (hasFP(MF)) {
// Insert instruction "move $fp, $sp" at this location.
BuildMI(MBB, MBBI, dl, TII.get(ADDu), FP).addReg(SP).addReg(ZERO);
// emit ".cfi_def_cfa_register $fp"
MCSymbol *SetFPLabel = MMI.getContext().CreateTempSymbol();
BuildMI(MBB, MBBI, dl,
TII.get(TargetOpcode::PROLOG_LABEL)).addSym(SetFPLabel);
DstML = MachineLocation(FP);
SrcML = MachineLocation(MachineLocation::VirtualFP);
Moves.push_back(MachineMove(SetFPLabel, DstML, SrcML));
}
}
示例9: DebugLoc
void MSP430FrameLowering::emitPrologue(MachineFunction &MF) const {
MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB
MachineFrameInfo *MFI = MF.getFrameInfo();
MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>();
const MSP430InstrInfo &TII =
*static_cast<const MSP430InstrInfo*>(MF.getTarget().getInstrInfo());
MachineBasicBlock::iterator MBBI = MBB.begin();
DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
// Get the number of bytes to allocate from the FrameInfo.
uint64_t StackSize = MFI->getStackSize();
uint64_t NumBytes = 0;
if (hasFP(MF)) {
// Calculate required stack adjustment
uint64_t FrameSize = StackSize - 2;
NumBytes = FrameSize - MSP430FI->getCalleeSavedFrameSize();
// Get the offset of the stack slot for the EBP register... which is
// guaranteed to be the last slot by processFunctionBeforeFrameFinalized.
// Update the frame offset adjustment.
MFI->setOffsetAdjustment(-NumBytes);
// Save FPW into the appropriate stack slot...
BuildMI(MBB, MBBI, DL, TII.get(MSP430::PUSH16r))
.addReg(MSP430::FPW, RegState::Kill);
// Update FPW with the new base value...
BuildMI(MBB, MBBI, DL, TII.get(MSP430::MOV16rr), MSP430::FPW)
.addReg(MSP430::SPW);
// Mark the FramePtr as live-in in every block except the entry.
for (MachineFunction::iterator I = llvm::next(MF.begin()), E = MF.end();
I != E; ++I)
I->addLiveIn(MSP430::FPW);
} else
NumBytes = StackSize - MSP430FI->getCalleeSavedFrameSize();
// Skip the callee-saved push instructions.
while (MBBI != MBB.end() && (MBBI->getOpcode() == MSP430::PUSH16r))
++MBBI;
if (MBBI != MBB.end())
DL = MBBI->getDebugLoc();
if (NumBytes) { // adjust stack pointer: SPW -= numbytes
// If there is an SUB16ri of SPW immediately before this instruction, merge
// the two.
//NumBytes -= mergeSPUpdates(MBB, MBBI, true);
// If there is an ADD16ri or SUB16ri of SPW immediately after this
// instruction, merge the two instructions.
// mergeSPUpdatesDown(MBB, MBBI, &NumBytes);
if (NumBytes) {
MachineInstr *MI =
BuildMI(MBB, MBBI, DL, TII.get(MSP430::SUB16ri), MSP430::SPW)
.addReg(MSP430::SPW).addImm(NumBytes);
// The SRW implicit def is dead.
MI->getOperand(3).setIsDead();
}
}
}
示例10: getStackAlignment
void MSP430FrameLowering::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
const MSP430InstrInfo &TII =
*static_cast<const MSP430InstrInfo*>(MF.getTarget().getInstrInfo());
unsigned StackAlign = getStackAlignment();
if (!hasReservedCallFrame(MF)) {
// If the stack pointer can be changed after prologue, turn the
// adjcallstackup instruction into a 'sub SPW, <amt>' and the
// adjcallstackdown instruction into 'add SPW, <amt>'
// TODO: consider using push / pop instead of sub + store / add
MachineInstr *Old = I;
uint64_t Amount = Old->getOperand(0).getImm();
if (Amount != 0) {
// We need to keep the stack aligned properly. To do this, we round the
// amount of space needed for the outgoing arguments up to the next
// alignment boundary.
Amount = (Amount+StackAlign-1)/StackAlign*StackAlign;
MachineInstr *New = 0;
if (Old->getOpcode() == TII.getCallFrameSetupOpcode()) {
New = BuildMI(MF, Old->getDebugLoc(),
TII.get(MSP430::SUB16ri), MSP430::SPW)
.addReg(MSP430::SPW).addImm(Amount);
} else {
assert(Old->getOpcode() == TII.getCallFrameDestroyOpcode());
// factor out the amount the callee already popped.
uint64_t CalleeAmt = Old->getOperand(1).getImm();
Amount -= CalleeAmt;
if (Amount)
New = BuildMI(MF, Old->getDebugLoc(),
TII.get(MSP430::ADD16ri), MSP430::SPW)
.addReg(MSP430::SPW).addImm(Amount);
}
if (New) {
// The SRW implicit def is dead.
New->getOperand(3).setIsDead();
// Replace the pseudo instruction with a new instruction...
MBB.insert(I, New);
}
}
} else if (I->getOpcode() == TII.getCallFrameDestroyOpcode()) {
// If we are performing frame pointer elimination and if the callee pops
// something off the stack pointer, add it back.
if (uint64_t CalleeAmt = I->getOperand(1).getImm()) {
MachineInstr *Old = I;
MachineInstr *New =
BuildMI(MF, Old->getDebugLoc(), TII.get(MSP430::SUB16ri),
MSP430::SPW).addReg(MSP430::SPW).addImm(CalleeAmt);
// The SRW implicit def is dead.
New->getOperand(3).setIsDead();
MBB.insert(I, New);
}
}
MBB.erase(I);
}
示例11: switch
void MSP430FrameLowering::emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
const MachineFrameInfo *MFI = MF.getFrameInfo();
MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>();
const MSP430InstrInfo &TII =
*static_cast<const MSP430InstrInfo*>(MF.getTarget().getInstrInfo());
MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
unsigned RetOpcode = MBBI->getOpcode();
DebugLoc DL = MBBI->getDebugLoc();
switch (RetOpcode) {
case MSP430::RET:
case MSP430::RETI:
break; // These are ok
default:
llvm_unreachable("Can only insert epilog into returning blocks");
}
// Get the number of bytes to allocate from the FrameInfo
uint64_t StackSize = MFI->getStackSize();
unsigned CSSize = MSP430FI->getCalleeSavedFrameSize();
uint64_t NumBytes = 0;
if (hasFP(MF)) {
// Calculate required stack adjustment
uint64_t FrameSize = StackSize - 2;
NumBytes = FrameSize - CSSize;
// pop FPW.
BuildMI(MBB, MBBI, DL, TII.get(MSP430::POP16r), MSP430::FPW);
} else
NumBytes = StackSize - CSSize;
// Skip the callee-saved pop instructions.
while (MBBI != MBB.begin()) {
MachineBasicBlock::iterator PI = prior(MBBI);
unsigned Opc = PI->getOpcode();
if (Opc != MSP430::POP16r && !PI->isTerminator())
break;
--MBBI;
}
DL = MBBI->getDebugLoc();
// If there is an ADD16ri or SUB16ri of SPW immediately before this
// instruction, merge the two instructions.
//if (NumBytes || MFI->hasVarSizedObjects())
// mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes);
if (MFI->hasVarSizedObjects()) {
BuildMI(MBB, MBBI, DL,
TII.get(MSP430::MOV16rr), MSP430::SPW).addReg(MSP430::FPW);
if (CSSize) {
MachineInstr *MI =
BuildMI(MBB, MBBI, DL,
TII.get(MSP430::SUB16ri), MSP430::SPW)
.addReg(MSP430::SPW).addImm(CSSize);
// The SRW implicit def is dead.
MI->getOperand(3).setIsDead();
}
} else {
// adjust stack pointer back: SPW += numbytes
if (NumBytes) {
MachineInstr *MI =
BuildMI(MBB, MBBI, DL, TII.get(MSP430::ADD16ri), MSP430::SPW)
.addReg(MSP430::SPW).addImm(NumBytes);
// The SRW implicit def is dead.
MI->getOperand(3).setIsDead();
}
}
}
示例12: switch
MachineInstrBuilder
MipsInstrInfo::genInstrWithNewOpc(unsigned NewOpc,
MachineBasicBlock::iterator I) const {
MachineInstrBuilder MIB;
// Certain branches have two forms: e.g beq $1, $zero, dest vs beqz $1, dest
// Pick the zero form of the branch for readable assembly and for greater
// branch distance in non-microMIPS mode.
// Additional MIPSR6 does not permit the use of register $zero for compact
// branches.
// FIXME: Certain atomic sequences on mips64 generate 32bit references to
// Mips::ZERO, which is incorrect. This test should be updated to use
// Subtarget.getABI().GetZeroReg() when those atomic sequences and others
// are fixed.
int ZeroOperandPosition = -1;
bool BranchWithZeroOperand = false;
if (I->isBranch() && !I->isPseudo()) {
auto TRI = I->getParent()->getParent()->getSubtarget().getRegisterInfo();
ZeroOperandPosition = I->findRegisterUseOperandIdx(Mips::ZERO, false, TRI);
BranchWithZeroOperand = ZeroOperandPosition != -1;
}
if (BranchWithZeroOperand) {
switch (NewOpc) {
case Mips::BEQC:
NewOpc = Mips::BEQZC;
break;
case Mips::BNEC:
NewOpc = Mips::BNEZC;
break;
case Mips::BGEC:
NewOpc = Mips::BGEZC;
break;
case Mips::BLTC:
NewOpc = Mips::BLTZC;
break;
case Mips::BEQC64:
NewOpc = Mips::BEQZC64;
break;
case Mips::BNEC64:
NewOpc = Mips::BNEZC64;
break;
}
}
MIB = BuildMI(*I->getParent(), I, I->getDebugLoc(), get(NewOpc));
// For MIPSR6 JI*C requires an immediate 0 as an operand, JIALC(64) an
// immediate 0 as an operand and requires the removal of it's implicit-def %ra
// implicit operand as copying the implicit operations of the instructio we're
// looking at will give us the correct flags.
if (NewOpc == Mips::JIC || NewOpc == Mips::JIALC || NewOpc == Mips::JIC64 ||
NewOpc == Mips::JIALC64) {
if (NewOpc == Mips::JIALC || NewOpc == Mips::JIALC64)
MIB->RemoveOperand(0);
for (unsigned J = 0, E = I->getDesc().getNumOperands(); J < E; ++J) {
MIB.add(I->getOperand(J));
}
MIB.addImm(0);
} else {
for (unsigned J = 0, E = I->getDesc().getNumOperands(); J < E; ++J) {
if (BranchWithZeroOperand && (unsigned)ZeroOperandPosition == J)
continue;
MIB.add(I->getOperand(J));
}
}
MIB.copyImplicitOps(*I);
MIB.setMemRefs(I->memoperands_begin(), I->memoperands_end());
return MIB;
}
示例13: if
void MipsSEInstrInfo::
loadRegFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
unsigned DestReg, int FI, const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI, int64_t Offset) const {
DebugLoc DL;
if (I != MBB.end()) DL = I->getDebugLoc();
MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOLoad);
unsigned Opc = 0;
const Function *Func = MBB.getParent()->getFunction();
bool ReqIndirectLoad = Func->hasFnAttribute("interrupt") &&
(DestReg == Mips::LO0 || DestReg == Mips::LO0_64 ||
DestReg == Mips::HI0 || DestReg == Mips::HI0_64);
if (Mips::GPR32RegClass.hasSubClassEq(RC))
Opc = Mips::LW;
else if (Mips::GPR64RegClass.hasSubClassEq(RC))
Opc = Mips::LD;
else if (Mips::ACC64RegClass.hasSubClassEq(RC))
Opc = Mips::LOAD_ACC64;
else if (Mips::ACC64DSPRegClass.hasSubClassEq(RC))
Opc = Mips::LOAD_ACC64DSP;
else if (Mips::ACC128RegClass.hasSubClassEq(RC))
Opc = Mips::LOAD_ACC128;
else if (Mips::DSPCCRegClass.hasSubClassEq(RC))
Opc = Mips::LOAD_CCOND_DSP;
else if (Mips::FGR32RegClass.hasSubClassEq(RC))
Opc = Mips::LWC1;
else if (Mips::AFGR64RegClass.hasSubClassEq(RC))
Opc = Mips::LDC1;
else if (Mips::FGR64RegClass.hasSubClassEq(RC))
Opc = Mips::LDC164;
else if (TRI->isTypeLegalForClass(*RC, MVT::v16i8))
Opc = Mips::LD_B;
else if (TRI->isTypeLegalForClass(*RC, MVT::v8i16) ||
TRI->isTypeLegalForClass(*RC, MVT::v8f16))
Opc = Mips::LD_H;
else if (TRI->isTypeLegalForClass(*RC, MVT::v4i32) ||
TRI->isTypeLegalForClass(*RC, MVT::v4f32))
Opc = Mips::LD_W;
else if (TRI->isTypeLegalForClass(*RC, MVT::v2i64) ||
TRI->isTypeLegalForClass(*RC, MVT::v2f64))
Opc = Mips::LD_D;
else if (Mips::HI32RegClass.hasSubClassEq(RC))
Opc = Mips::LW;
else if (Mips::HI64RegClass.hasSubClassEq(RC))
Opc = Mips::LD;
else if (Mips::LO32RegClass.hasSubClassEq(RC))
Opc = Mips::LW;
else if (Mips::LO64RegClass.hasSubClassEq(RC))
Opc = Mips::LD;
assert(Opc && "Register class not handled!");
if (!ReqIndirectLoad)
BuildMI(MBB, I, DL, get(Opc), DestReg)
.addFrameIndex(FI)
.addImm(Offset)
.addMemOperand(MMO);
else {
// Load HI/LO through K0. Notably the DestReg is encoded into the
// instruction itself.
unsigned Reg = Mips::K0;
unsigned LdOp = Mips::MTLO;
if (DestReg == Mips::HI0)
LdOp = Mips::MTHI;
if (Subtarget.getABI().ArePtrs64bit()) {
Reg = Mips::K0_64;
if (DestReg == Mips::HI0_64)
LdOp = Mips::MTHI64;
else
LdOp = Mips::MTLO64;
}
BuildMI(MBB, I, DL, get(Opc), Reg)
.addFrameIndex(FI)
.addImm(Offset)
.addMemOperand(MMO);
BuildMI(MBB, I, DL, get(LdOp)).addReg(Reg);
}
}
示例14: runOnMachineFunction
bool GCMachineCodeFixup::runOnMachineFunction(MachineFunction &MF) {
// Quick exit for functions that do not use GC.
if (!MF.getFunction()->hasGC())
return false;
const TargetMachine &TM = MF.getTarget();
const TargetInstrInfo *TII = TM.getInstrInfo();
GCModuleInfo &GMI = getAnalysis<GCModuleInfo>();
GCFunctionInfo &GCFI = GMI.getFunctionInfo(*MF.getFunction());
for (MachineFunction::iterator MBBI = MF.begin(),
MBBE = MF.end(); MBBI != MBBE; ++MBBI) {
for (MachineBasicBlock::iterator MII = MBBI->begin(),
MIE = MBBI->end(); MII != MIE;) {
if (!MII->isGCRegRoot() || !MII->getOperand(0).isReg()) {
++MII;
continue;
}
// Trace the register back to its location at the site of the call (either
// a physical reg or a frame index).
bool TracingReg = true;
unsigned TracedReg = MII->getOperand(0).getReg();
int FrameIndex;
MachineBasicBlock::iterator PrevII = MII;
for (--PrevII;; --PrevII) {
if (PrevII->isGCRegRoot() && PrevII->getOperand(0).isReg())
break;
if (PrevII->isCall())
break;
int FI;
// Trace back through register reloads.
unsigned Reg =
TM.getInstrInfo()->isLoadFromStackSlotPostFE(&*PrevII, FI);
if (Reg) {
// This is a reload. If we're tracing this register, start tracing the
// frame index instead.
if (TracingReg && TracedReg == Reg) {
TracingReg = false;
FrameIndex = FI;
}
continue;
}
// Trace back through spills.
if (TM.getInstrInfo()->isStoreToStackSlotPostFE(&*PrevII, FI))
continue;
// Trace back through register-to-register copies.
if (PrevII->isCopy()) {
if (TracingReg && TracedReg == PrevII->getOperand(0).getReg())
TracedReg = PrevII->getOperand(1).getReg();
continue;
}
// Trace back through non-register GC_REG_ROOT instructions.
if (PrevII->isGCRegRoot() && !PrevII->getOperand(0).isReg())
continue;
DEBUG(dbgs() << "Bad instruction: " << *PrevII);
llvm_unreachable("GC_REG_ROOT found in an unexpected location!");
}
// Now we've reached either a call or another GC_REG_ROOT instruction.
// Move the GC_REG_ROOT instruction we're considering to the right place,
// and rewrite it if necessary.
//
// Also, tell the GCFunctionInfo about the frame index, since this is
// our only chance -- the frame indices will be deleted by the time
// GCMachineCodeAnalysis runs.
++PrevII;
unsigned RootIndex = MII->getOperand(1).getImm();
MachineInstr *NewMI;
if (TracingReg) {
MachineInstrBuilder MIB = BuildMI(MF, MII->getDebugLoc(),
TII->get(TargetOpcode::GC_REG_ROOT));
MIB.addReg(TracedReg).addImm(RootIndex);
NewMI = MIB;
} else {
NewMI = TII->emitFrameIndexGCRegRoot(MF, FrameIndex, RootIndex,
MII->getDebugLoc());
GCFI.spillRegRoot(RootIndex, FrameIndex);
}
MBBI->insert(PrevII, NewMI);
MachineBasicBlock::iterator NextII = MII;
++NextII;
MII->eraseFromParent();
MII = NextII;
}
}
return true;
}
示例15: expandERet
void MipsSEInstrInfo::expandERet(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
BuildMI(MBB, I, I->getDebugLoc(), get(Mips::ERET));
}