EnableARM3Addr("enable-arm-3-addr-conv", cl::Hidden,
cl::desc("Enable ARM 2-addr to 3-addr conv"));
-static cl::opt<bool>
-PredicateNEON("predicate-neon", cl::Hidden,
- cl::desc("Allow NEON instructions to be predicated"));
-
ARMBaseInstrInfo::ARMBaseInstrInfo(const ARMSubtarget& STI)
: TargetInstrInfoImpl(ARMInsts, array_lengthof(ARMInsts)),
Subtarget(STI) {
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() || !isUnpredicatedTerminator(--I))
+ 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.
MachineBasicBlock::iterator I = MBB.end();
if (I == MBB.begin()) return 0;
--I;
+ while (I->isDebugValue()) {
+ if (I == MBB.begin())
+ return 0;
+ --I;
+ }
if (!isUncondBranchOpcode(I->getOpcode()) &&
!isCondBranchOpcode(I->getOpcode()))
return 0;
MachineBasicBlock *FBB,
const SmallVectorImpl<MachineOperand> &Cond) const {
// FIXME this should probably have a DebugLoc argument
- DebugLoc dl = DebugLoc::getUnknownLoc();
+ DebugLoc dl;
ARMFunctionInfo *AFI = MBB.getParent()->getInfo<ARMFunctionInfo>();
int BOpc = !AFI->isThumbFunction()
if ((TID.TSFlags & ARMII::DomainMask) == ARMII::DomainNEON) {
ARMFunctionInfo *AFI =
MI->getParent()->getParent()->getInfo<ARMFunctionInfo>();
- return PredicateNEON && AFI->isThumb2Function();
+ return AFI->isThumb2Function();
}
return true;
}
-/// FIXME: Works around a gcc miscompilation with -fstrict-aliasing
+/// FIXME: Works around a gcc miscompilation with -fstrict-aliasing.
+DISABLE_INLINE
static unsigned getNumJTEntries(const std::vector<MachineJumpTableEntry> &JT,
- unsigned JTI) DISABLE_INLINE;
+ unsigned JTI);
static unsigned getNumJTEntries(const std::vector<MachineJumpTableEntry> &JT,
unsigned JTI) {
+ assert(JTI < JT.size());
return JT[JTI].MBBs.size();
}
switch (Opc) {
default:
llvm_unreachable("Unknown or unset size field for instr!");
- case TargetInstrInfo::IMPLICIT_DEF:
- case TargetInstrInfo::KILL:
- case TargetInstrInfo::DBG_LABEL:
- case TargetInstrInfo::EH_LABEL:
+ case TargetOpcode::IMPLICIT_DEF:
+ case TargetOpcode::KILL:
+ case TargetOpcode::DBG_LABEL:
+ case TargetOpcode::EH_LABEL:
+ case TargetOpcode::DBG_VALUE:
return 0;
}
break;
// operand #2.
return MI->getOperand(2).getImm();
case ARM::Int_eh_sjlj_setjmp:
+ case ARM::Int_eh_sjlj_setjmp_nofp:
return 24;
+ case ARM::tInt_eh_sjlj_setjmp:
case ARM::t2Int_eh_sjlj_setjmp:
- return 22;
+ case ARM::t2Int_eh_sjlj_setjmp_nofp:
+ return 14;
case ARM::BR_JTr:
case ARM::BR_JTm:
case ARM::BR_JTadd:
MI->getOperand(NumOps - (TID.isPredicable() ? 3 : 2));
unsigned JTI = JTOP.getIndex();
const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
+ assert(MJTI != 0);
const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
assert(JTI < JT.size());
// Thumb instructions are 2 byte aligned, but JT entries are 4 byte
ARMBaseInstrInfo::isMoveInstr(const MachineInstr &MI,
unsigned &SrcReg, unsigned &DstReg,
unsigned& SrcSubIdx, unsigned& DstSubIdx) const {
- SrcSubIdx = DstSubIdx = 0; // No sub-registers.
-
switch (MI.getOpcode()) {
default: break;
case ARM::VMOVS:
case ARM::VMOVD:
case ARM::VMOVDneon:
- case ARM::VMOVQ: {
+ case ARM::VMOVQ:
+ case ARM::VMOVQQ : {
SrcReg = MI.getOperand(1).getReg();
DstReg = MI.getOperand(0).getReg();
+ SrcSubIdx = MI.getOperand(1).getSubReg();
+ DstSubIdx = MI.getOperand(0).getSubReg();
return true;
}
case ARM::MOVr:
"Invalid ARM MOV instruction");
SrcReg = MI.getOperand(1).getReg();
DstReg = MI.getOperand(0).getReg();
+ SrcSubIdx = MI.getOperand(1).getSubReg();
+ DstSubIdx = MI.getOperand(0).getSubReg();
return true;
}
}
MachineBasicBlock::iterator I,
unsigned DestReg, unsigned SrcReg,
const TargetRegisterClass *DestRC,
- const TargetRegisterClass *SrcRC) const {
- DebugLoc DL = DebugLoc::getUnknownLoc();
- if (I != MBB.end()) DL = I->getDebugLoc();
-
- if (DestRC != SrcRC) {
- if (DestRC->getSize() != SrcRC->getSize())
- return false;
-
- // Allow DPR / DPR_VFP2 / DPR_8 cross-class copies.
- // Allow QPR / QPR_VFP2 / QPR_8 cross-class copies.
- if (DestRC->getSize() != 8 && DestRC->getSize() != 16)
- return false;
- }
+ const TargetRegisterClass *SrcRC,
+ DebugLoc DL) const {
+ // tGPR is used sometimes in ARM instructions that need to avoid using
+ // certain registers. Just treat it as GPR here.
+ if (DestRC == ARM::tGPRRegisterClass)
+ DestRC = ARM::GPRRegisterClass;
+ if (SrcRC == ARM::tGPRRegisterClass)
+ SrcRC = ARM::GPRRegisterClass;
+
+ // Allow DPR / DPR_VFP2 / DPR_8 cross-class copies.
+ if (DestRC == ARM::DPR_8RegisterClass)
+ DestRC = ARM::DPR_VFP2RegisterClass;
+ if (SrcRC == ARM::DPR_8RegisterClass)
+ SrcRC = ARM::DPR_VFP2RegisterClass;
+
+ // Allow QPR / QPR_VFP2 / QPR_8 cross-class copies.
+ if (DestRC == ARM::QPR_VFP2RegisterClass ||
+ DestRC == ARM::QPR_8RegisterClass)
+ DestRC = ARM::QPRRegisterClass;
+ if (SrcRC == ARM::QPR_VFP2RegisterClass ||
+ SrcRC == ARM::QPR_8RegisterClass)
+ SrcRC = ARM::QPRRegisterClass;
+
+ // Allow QQPR / QQPR_VFP2 / QQPR_8 cross-class copies.
+ if (DestRC == ARM::QQPR_VFP2RegisterClass ||
+ DestRC == ARM::QQPR_8RegisterClass)
+ DestRC = ARM::QQPRRegisterClass;
+ if (SrcRC == ARM::QQPR_VFP2RegisterClass ||
+ SrcRC == ARM::QQPR_8RegisterClass)
+ SrcRC = ARM::QQPRRegisterClass;
+
+ // Disallow copies of unequal sizes.
+ if (DestRC != SrcRC && DestRC->getSize() != SrcRC->getSize())
+ return false;
if (DestRC == ARM::GPRRegisterClass) {
- AddDefaultCC(AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::MOVr),
- DestReg).addReg(SrcReg)));
- } else if (DestRC == ARM::SPRRegisterClass) {
- AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VMOVS), DestReg)
- .addReg(SrcReg));
- } else if (DestRC == ARM::DPRRegisterClass) {
- AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VMOVD), DestReg)
- .addReg(SrcReg));
- } else if (DestRC == ARM::DPR_VFP2RegisterClass ||
- DestRC == ARM::DPR_8RegisterClass ||
- SrcRC == ARM::DPR_VFP2RegisterClass ||
- SrcRC == ARM::DPR_8RegisterClass) {
- // Always use neon reg-reg move if source or dest is NEON-only regclass.
- AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VMOVDneon),
- DestReg).addReg(SrcReg));
- } else if (DestRC == ARM::QPRRegisterClass ||
- DestRC == ARM::QPR_VFP2RegisterClass ||
- DestRC == ARM::QPR_8RegisterClass) {
- AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VMOVQ),
- DestReg).addReg(SrcReg));
+ if (SrcRC == ARM::SPRRegisterClass)
+ AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VMOVRS), DestReg)
+ .addReg(SrcReg));
+ else
+ AddDefaultCC(AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::MOVr),
+ DestReg).addReg(SrcReg)));
} else {
- return false;
+ unsigned Opc;
+
+ if (DestRC == ARM::SPRRegisterClass)
+ Opc = (SrcRC == ARM::GPRRegisterClass ? ARM::VMOVSR : ARM::VMOVS);
+ else if (DestRC == ARM::DPRRegisterClass)
+ Opc = ARM::VMOVD;
+ else if (DestRC == ARM::DPR_VFP2RegisterClass ||
+ SrcRC == ARM::DPR_VFP2RegisterClass)
+ // Always use neon reg-reg move if source or dest is NEON-only regclass.
+ Opc = ARM::VMOVDneon;
+ else if (DestRC == ARM::QPRRegisterClass)
+ Opc = ARM::VMOVQ;
+ else if (DestRC == ARM::QQPRRegisterClass)
+ Opc = ARM::VMOVQQ;
+ else
+ return false;
+
+ AddDefaultPred(BuildMI(MBB, I, DL, get(Opc), DestReg).addReg(SrcReg));
}
return true;
}
+static const
+MachineInstrBuilder &AddDReg(MachineInstrBuilder &MIB,
+ unsigned Reg, unsigned SubIdx, unsigned State,
+ const TargetRegisterInfo *TRI) {
+ if (!SubIdx)
+ return MIB.addReg(Reg, State);
+
+ if (TargetRegisterInfo::isPhysicalRegister(Reg))
+ return MIB.addReg(TRI->getSubReg(Reg, SubIdx), State);
+ return MIB.addReg(Reg, State, SubIdx);
+}
+
void ARMBaseInstrInfo::
storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
unsigned SrcReg, bool isKill, int FI,
- const TargetRegisterClass *RC) const {
- DebugLoc DL = DebugLoc::getUnknownLoc();
+ const TargetRegisterClass *RC,
+ const TargetRegisterInfo *TRI) const {
+ DebugLoc DL;
if (I != MBB.end()) DL = I->getDebugLoc();
MachineFunction &MF = *MBB.getParent();
MachineFrameInfo &MFI = *MF.getFrameInfo();
MFI.getObjectSize(FI),
Align);
+ // tGPR is used sometimes in ARM instructions that need to avoid using
+ // certain registers. Just treat it as GPR here.
+ if (RC == ARM::tGPRRegisterClass)
+ RC = ARM::GPRRegisterClass;
+
if (RC == ARM::GPRRegisterClass) {
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::STR))
.addReg(SrcReg, getKillRegState(isKill))
.addFrameIndex(FI).addReg(0).addImm(0).addMemOperand(MMO));
+ } else if (RC == ARM::SPRRegisterClass) {
+ AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTRS))
+ .addReg(SrcReg, getKillRegState(isKill))
+ .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
} else if (RC == ARM::DPRRegisterClass ||
RC == ARM::DPR_VFP2RegisterClass ||
RC == ARM::DPR_8RegisterClass) {
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTRD))
.addReg(SrcReg, getKillRegState(isKill))
.addFrameIndex(FI).addImm(0).addMemOperand(MMO));
- } else if (RC == ARM::SPRRegisterClass) {
- AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTRS))
- .addReg(SrcReg, getKillRegState(isKill))
- .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
- } else {
- assert((RC == ARM::QPRRegisterClass ||
- RC == ARM::QPR_VFP2RegisterClass) && "Unknown regclass!");
+ } else if (RC == ARM::QPRRegisterClass ||
+ RC == ARM::QPR_VFP2RegisterClass ||
+ RC == ARM::QPR_8RegisterClass) {
// FIXME: Neon instructions should support predicates
- if (Align >= 16
- && (getRegisterInfo().needsStackRealignment(MF))) {
- AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VST1q64))
- .addFrameIndex(FI).addImm(0).addImm(0).addImm(128)
- .addMemOperand(MMO)
- .addReg(SrcReg, getKillRegState(isKill)));
+ if (Align >= 16 && getRegisterInfo().canRealignStack(MF)) {
+ MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::VST1q64))
+ .addFrameIndex(FI).addImm(128);
+ MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_0, getKillRegState(isKill), TRI);
+ MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_1, 0, TRI);
+ AddDefaultPred(MIB.addMemOperand(MMO));
+ } else {
+ MachineInstrBuilder MIB =
+ AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTMD))
+ .addFrameIndex(FI)
+ .addImm(ARM_AM::getAM5Opc(ARM_AM::ia, 4)))
+ .addMemOperand(MMO);
+ MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_0, getKillRegState(isKill), TRI);
+ AddDReg(MIB, SrcReg, ARM::DSUBREG_1, 0, TRI);
+ }
+ } else {
+ assert((RC == ARM::QQPRRegisterClass ||
+ RC == ARM::QQPR_VFP2RegisterClass ||
+ RC == ARM::QQPR_8RegisterClass) && "Unknown regclass!");
+ if (Align >= 16 && getRegisterInfo().canRealignStack(MF)) {
+ MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::VST2q32))
+ .addFrameIndex(FI).addImm(128);
+ MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_0, getKillRegState(isKill), TRI);
+ MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_1, 0, TRI);
+ MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_2, 0, TRI);
+ MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_3, 0, TRI);
+ AddDefaultPred(MIB.addMemOperand(MMO));
} else {
- AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTRQ)).
- addReg(SrcReg, getKillRegState(isKill))
- .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
+ MachineInstrBuilder MIB =
+ AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTMD))
+ .addFrameIndex(FI)
+ .addImm(ARM_AM::getAM5Opc(ARM_AM::ia, 4)))
+ .addMemOperand(MMO);
+ MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_0, getKillRegState(isKill), TRI);
+ MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_1, 0, TRI);
+ MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_2, 0, TRI);
+ AddDReg(MIB, SrcReg, ARM::DSUBREG_3, 0, TRI);
}
}
}
void ARMBaseInstrInfo::
loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
unsigned DestReg, int FI,
- const TargetRegisterClass *RC) const {
- DebugLoc DL = DebugLoc::getUnknownLoc();
+ const TargetRegisterClass *RC,
+ const TargetRegisterInfo *TRI) const {
+ DebugLoc DL;
if (I != MBB.end()) DL = I->getDebugLoc();
MachineFunction &MF = *MBB.getParent();
MachineFrameInfo &MFI = *MF.getFrameInfo();
MFI.getObjectSize(FI),
Align);
+ // tGPR is used sometimes in ARM instructions that need to avoid using
+ // certain registers. Just treat it as GPR here.
+ if (RC == ARM::tGPRRegisterClass)
+ RC = ARM::GPRRegisterClass;
+
if (RC == ARM::GPRRegisterClass) {
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::LDR), DestReg)
.addFrameIndex(FI).addReg(0).addImm(0).addMemOperand(MMO));
+ } else if (RC == ARM::SPRRegisterClass) {
+ AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDRS), DestReg)
+ .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
} else if (RC == ARM::DPRRegisterClass ||
RC == ARM::DPR_VFP2RegisterClass ||
RC == ARM::DPR_8RegisterClass) {
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDRD), DestReg)
.addFrameIndex(FI).addImm(0).addMemOperand(MMO));
- } else if (RC == ARM::SPRRegisterClass) {
- AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDRS), DestReg)
- .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
+ } else if (RC == ARM::QPRRegisterClass ||
+ RC == ARM::QPR_VFP2RegisterClass ||
+ RC == ARM::QPR_8RegisterClass) {
+ if (Align >= 16 && getRegisterInfo().canRealignStack(MF)) {
+ MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::VLD1q64));
+ MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_0, RegState::Define, TRI);
+ MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_1, RegState::Define, TRI);
+ AddDefaultPred(MIB.addFrameIndex(FI).addImm(128).addMemOperand(MMO));
+ } else {
+ MachineInstrBuilder MIB =
+ AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDMD))
+ .addFrameIndex(FI)
+ .addImm(ARM_AM::getAM5Opc(ARM_AM::ia, 4)))
+ .addMemOperand(MMO);
+ MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_0, RegState::Define, TRI);
+ AddDReg(MIB, DestReg, ARM::DSUBREG_1, RegState::Define, TRI);
+ }
} else {
- assert((RC == ARM::QPRRegisterClass ||
- RC == ARM::QPR_VFP2RegisterClass ||
- RC == ARM::QPR_8RegisterClass) && "Unknown regclass!");
- // FIXME: Neon instructions should support predicates
- if (Align >= 16
- && (getRegisterInfo().needsStackRealignment(MF))) {
- AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLD1q64), DestReg)
- .addFrameIndex(FI).addImm(0).addImm(0).addImm(128)
- .addMemOperand(MMO));
+ assert((RC == ARM::QQPRRegisterClass ||
+ RC == ARM::QQPR_VFP2RegisterClass ||
+ RC == ARM::QQPR_8RegisterClass) && "Unknown regclass!");
+ if (Align >= 16 && getRegisterInfo().canRealignStack(MF)) {
+ MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::VLD2q32));
+ MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_0, RegState::Define, TRI);
+ MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_1, RegState::Define, TRI);
+ MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_2, RegState::Define, TRI);
+ MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_3, RegState::Define, TRI);
+ AddDefaultPred(MIB.addFrameIndex(FI).addImm(128).addMemOperand(MMO));
} else {
- AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDRQ), DestReg)
- .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
+ MachineInstrBuilder MIB =
+ AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDMD))
+ .addFrameIndex(FI)
+ .addImm(ARM_AM::getAM5Opc(ARM_AM::ia, 4)))
+ .addMemOperand(MMO);
+ MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_0, RegState::Define, TRI);
+ MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_1, RegState::Define, TRI);
+ MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_2, RegState::Define, TRI);
+ AddDReg(MIB, DestReg, ARM::DSUBREG_3, RegState::Define, TRI);
}
}
}
+MachineInstr*
+ARMBaseInstrInfo::emitFrameIndexDebugValue(MachineFunction &MF,
+ int FrameIx, uint64_t Offset,
+ const MDNode *MDPtr,
+ DebugLoc DL) const {
+ MachineInstrBuilder MIB = BuildMI(MF, DL, get(ARM::DBG_VALUE))
+ .addFrameIndex(FrameIx).addImm(0).addImm(Offset).addMetadata(MDPtr);
+ return &*MIB;
+}
+
MachineInstr *ARMBaseInstrInfo::
foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
const SmallVectorImpl<unsigned> &Ops, int FI) const {
return false;
}
+/// Create a copy of a const pool value. Update CPI to the new index and return
+/// the label UID.
+static unsigned duplicateCPV(MachineFunction &MF, unsigned &CPI) {
+ MachineConstantPool *MCP = MF.getConstantPool();
+ ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
+
+ const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPI];
+ assert(MCPE.isMachineConstantPoolEntry() &&
+ "Expecting a machine constantpool entry!");
+ ARMConstantPoolValue *ACPV =
+ static_cast<ARMConstantPoolValue*>(MCPE.Val.MachineCPVal);
+
+ unsigned PCLabelId = AFI->createConstPoolEntryUId();
+ ARMConstantPoolValue *NewCPV = 0;
+ if (ACPV->isGlobalValue())
+ NewCPV = new ARMConstantPoolValue(ACPV->getGV(), PCLabelId,
+ ARMCP::CPValue, 4);
+ else if (ACPV->isExtSymbol())
+ NewCPV = new ARMConstantPoolValue(MF.getFunction()->getContext(),
+ ACPV->getSymbol(), PCLabelId, 4);
+ else if (ACPV->isBlockAddress())
+ NewCPV = new ARMConstantPoolValue(ACPV->getBlockAddress(), PCLabelId,
+ ARMCP::CPBlockAddress, 4);
+ else
+ llvm_unreachable("Unexpected ARM constantpool value type!!");
+ CPI = MCP->getConstantPoolIndex(NewCPV, MCPE.getAlignment());
+ return PCLabelId;
+}
+
void ARMBaseInstrInfo::
reMaterialize(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
unsigned DestReg, unsigned SubIdx,
const MachineInstr *Orig,
const TargetRegisterInfo *TRI) const {
- DebugLoc dl = Orig->getDebugLoc();
-
if (SubIdx && TargetRegisterInfo::isPhysicalRegister(DestReg)) {
DestReg = TRI->getSubReg(DestReg, SubIdx);
SubIdx = 0;
case ARM::tLDRpci_pic:
case ARM::t2LDRpci_pic: {
MachineFunction &MF = *MBB.getParent();
- ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
- MachineConstantPool *MCP = MF.getConstantPool();
unsigned CPI = Orig->getOperand(1).getIndex();
- const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPI];
- assert(MCPE.isMachineConstantPoolEntry() &&
- "Expecting a machine constantpool entry!");
- ARMConstantPoolValue *ACPV =
- static_cast<ARMConstantPoolValue*>(MCPE.Val.MachineCPVal);
- unsigned PCLabelId = AFI->createConstPoolEntryUId();
- ARMConstantPoolValue *NewCPV = 0;
- if (ACPV->isGlobalValue())
- NewCPV = new ARMConstantPoolValue(ACPV->getGV(), PCLabelId,
- ARMCP::CPValue, 4);
- else if (ACPV->isExtSymbol())
- NewCPV = new ARMConstantPoolValue(MF.getFunction()->getContext(),
- ACPV->getSymbol(), PCLabelId, 4);
- else if (ACPV->isBlockAddress())
- NewCPV = new ARMConstantPoolValue(ACPV->getBlockAddress(), PCLabelId,
- ARMCP::CPBlockAddress, 4);
- else
- llvm_unreachable("Unexpected ARM constantpool value type!!");
- CPI = MCP->getConstantPoolIndex(NewCPV, MCPE.getAlignment());
+ unsigned PCLabelId = duplicateCPV(MF, CPI);
MachineInstrBuilder MIB = BuildMI(MBB, I, Orig->getDebugLoc(), get(Opcode),
DestReg)
.addConstantPoolIndex(CPI).addImm(PCLabelId);
NewMI->getOperand(0).setSubReg(SubIdx);
}
-bool ARMBaseInstrInfo::isIdentical(const MachineInstr *MI0,
- const MachineInstr *MI1,
- const MachineRegisterInfo *MRI) const {
+MachineInstr *
+ARMBaseInstrInfo::duplicate(MachineInstr *Orig, MachineFunction &MF) const {
+ MachineInstr *MI = TargetInstrInfoImpl::duplicate(Orig, MF);
+ switch(Orig->getOpcode()) {
+ case ARM::tLDRpci_pic:
+ case ARM::t2LDRpci_pic: {
+ unsigned CPI = Orig->getOperand(1).getIndex();
+ unsigned PCLabelId = duplicateCPV(MF, CPI);
+ Orig->getOperand(1).setIndex(CPI);
+ Orig->getOperand(2).setImm(PCLabelId);
+ break;
+ }
+ }
+ return MI;
+}
+
+bool ARMBaseInstrInfo::produceSameValue(const MachineInstr *MI0,
+ const MachineInstr *MI1) const {
int Opcode = MI0->getOpcode();
if (Opcode == ARM::t2LDRpci ||
Opcode == ARM::t2LDRpci_pic ||
return ACPV0->hasSameValue(ACPV1);
}
- return TargetInstrInfoImpl::isIdentical(MI0, MI1, MRI);
-}
-
-unsigned ARMBaseInstrInfo::TailDuplicationLimit(const MachineBasicBlock &MBB,
- unsigned DefaultLimit) const {
- // If the target processor can predict indirect branches, it is highly
- // desirable to duplicate them, since it can often make them predictable.
- if (!MBB.empty() && isIndirectBranchOpcode(MBB.back().getOpcode()) &&
- getSubtarget().hasBranchTargetBuffer())
- return DefaultLimit + 2;
- return DefaultLimit;
+ return MI0->isIdenticalTo(MI1, MachineInstr::IgnoreVRegDefs);
}
/// getInstrPredicate - If instruction is predicated, returns its predicate