#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
-#include "llvm/DebugInfo.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/LLVMContext.h"
case MachineOperand::MO_BlockAddress:
return getBlockAddress() == Other.getBlockAddress() &&
getOffset() == Other.getOffset();
- case MO_RegisterMask:
+ case MachineOperand::MO_RegisterMask:
+ case MachineOperand::MO_RegisterLiveOut:
return getRegMask() == Other.getRegMask();
case MachineOperand::MO_MCSymbol:
return getMCSymbol() == Other.getMCSymbol();
+ case MachineOperand::MO_CFIIndex:
+ return getCFIIndex() == Other.getCFIIndex();
case MachineOperand::MO_Metadata:
return getMetadata() == Other.getMetadata();
}
return hash_combine(MO.getType(), MO.getTargetFlags(),
MO.getBlockAddress(), MO.getOffset());
case MachineOperand::MO_RegisterMask:
+ case MachineOperand::MO_RegisterLiveOut:
return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getRegMask());
case MachineOperand::MO_Metadata:
return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMetadata());
case MachineOperand::MO_MCSymbol:
return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMCSymbol());
+ case MachineOperand::MO_CFIIndex:
+ return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCFIIndex());
}
llvm_unreachable("Invalid machine operand type");
}
break;
case MachineOperand::MO_GlobalAddress:
OS << "<ga:";
- WriteAsOperand(OS, getGlobal(), /*PrintType=*/false);
+ getGlobal()->printAsOperand(OS, /*PrintType=*/false);
if (getOffset()) OS << "+" << getOffset();
OS << '>';
break;
break;
case MachineOperand::MO_BlockAddress:
OS << '<';
- WriteAsOperand(OS, getBlockAddress(), /*PrintType=*/false);
+ getBlockAddress()->printAsOperand(OS, /*PrintType=*/false);
if (getOffset()) OS << "+" << getOffset();
OS << '>';
break;
case MachineOperand::MO_RegisterMask:
OS << "<regmask>";
break;
+ case MachineOperand::MO_RegisterLiveOut:
+ OS << "<regliveout>";
+ break;
case MachineOperand::MO_Metadata:
OS << '<';
- WriteAsOperand(OS, getMetadata(), /*PrintType=*/false);
+ getMetadata()->printAsOperand(OS, /*PrintType=*/false);
OS << '>';
break;
case MachineOperand::MO_MCSymbol:
OS << "<MCSym=" << *getMCSymbol() << '>';
break;
+ case MachineOperand::MO_CFIIndex:
+ OS << "<call frame instruction>";
+ break;
}
if (unsigned TF = getTargetFlags())
if (!MMO.getValue())
OS << "<unknown>";
else
- WriteAsOperand(OS, MMO.getValue(), /*PrintType=*/false);
+ MMO.getValue()->printAsOperand(OS, /*PrintType=*/false);
+
+ unsigned AS = MMO.getAddrSpace();
+ if (AS != 0)
+ OS << "(addrspace=" << AS << ')';
// If the alignment of the memory reference itself differs from the alignment
// of the base pointer, print the base alignment explicitly, next to the base
if (const MDNode *TBAAInfo = MMO.getTBAAInfo()) {
OS << "(tbaa=";
if (TBAAInfo->getNumOperands() > 0)
- WriteAsOperand(OS, TBAAInfo->getOperand(0), /*PrintType=*/false);
+ TBAAInfo->getOperand(0)->printAsOperand(OS, /*PrintType=*/false);
else
OS << "<unknown>";
OS << ")";
}
}
+#ifndef NDEBUG
+ bool isMetaDataOp = Op.getType() == MachineOperand::MO_Metadata;
// OpNo now points as the desired insertion point. Unless this is a variadic
// instruction, only implicit regs are allowed beyond MCID->getNumOperands().
// RegMask operands go between the explicit and implicit operands.
assert((isImpReg || Op.isRegMask() || MCID->isVariadic() ||
- OpNo < MCID->getNumOperands()) &&
+ OpNo < MCID->getNumOperands() || isMetaDataOp) &&
"Trying to add an operand to a machine instr that is already done!");
+#endif
MachineRegisterInfo *MRI = getRegInfo();
}
bool MachineInstr::hasPropertyInBundle(unsigned Mask, QueryType Type) const {
- const MachineBasicBlock *MBB = getParent();
- MachineBasicBlock::const_instr_iterator MII = *this; ++MII;
- while (MII != MBB->end() && MII->isInsideBundle()) {
+ assert(!isBundledWithPred() && "Must be called on bundle header");
+ for (MachineBasicBlock::const_instr_iterator MII = this;; ++MII) {
if (MII->getDesc().getFlags() & Mask) {
if (Type == AnyInBundle)
return true;
} else {
- if (Type == AllInBundle)
+ if (Type == AllInBundle && !MII->isBundle())
return false;
}
- ++MII;
+ // This was the last instruction in the bundle.
+ if (!MII->isBundledWithSucc())
+ return Type == AllInBundle;
}
-
- return Type == AllInBundle;
}
bool MachineInstr::isIdenticalTo(const MachineInstr *Other,
return NULL;
}
-/// getBundleSize - Return the number of instructions inside the MI bundle.
-unsigned MachineInstr::getBundleSize() const {
- assert(isBundle() && "Expecting a bundle");
+const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVReg(
+ unsigned Reg, const TargetRegisterClass *CurRC, const TargetInstrInfo *TII,
+ const TargetRegisterInfo *TRI, bool ExploreBundle) const {
+ // Check every operands inside the bundle if we have
+ // been asked to.
+ if (ExploreBundle)
+ for (ConstMIBundleOperands OpndIt(this); OpndIt.isValid() && CurRC;
+ ++OpndIt)
+ CurRC = OpndIt->getParent()->getRegClassConstraintEffectForVRegImpl(
+ OpndIt.getOperandNo(), Reg, CurRC, TII, TRI);
+ else
+ // Otherwise, just check the current operands.
+ for (ConstMIOperands OpndIt(this); OpndIt.isValid() && CurRC; ++OpndIt)
+ CurRC = getRegClassConstraintEffectForVRegImpl(OpndIt.getOperandNo(), Reg,
+ CurRC, TII, TRI);
+ return CurRC;
+}
+
+const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVRegImpl(
+ unsigned OpIdx, unsigned Reg, const TargetRegisterClass *CurRC,
+ const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const {
+ assert(CurRC && "Invalid initial register class");
+ // Check if Reg is constrained by some of its use/def from MI.
+ const MachineOperand &MO = getOperand(OpIdx);
+ if (!MO.isReg() || MO.getReg() != Reg)
+ return CurRC;
+ // If yes, accumulate the constraints through the operand.
+ return getRegClassConstraintEffect(OpIdx, CurRC, TII, TRI);
+}
- const MachineBasicBlock *MBB = getParent();
- MachineBasicBlock::const_instr_iterator I = *this, E = MBB->instr_end();
- unsigned Size = 0;
- while ((++I != E) && I->isInsideBundle()) {
- ++Size;
- }
- assert(Size > 1 && "Malformed bundle");
+const TargetRegisterClass *MachineInstr::getRegClassConstraintEffect(
+ unsigned OpIdx, const TargetRegisterClass *CurRC,
+ const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const {
+ const TargetRegisterClass *OpRC = getRegClassConstraint(OpIdx, TII, TRI);
+ const MachineOperand &MO = getOperand(OpIdx);
+ assert(MO.isReg() &&
+ "Cannot get register constraints for non-register operand");
+ assert(CurRC && "Invalid initial register class");
+ if (unsigned SubIdx = MO.getSubReg()) {
+ if (OpRC)
+ CurRC = TRI->getMatchingSuperRegClass(CurRC, OpRC, SubIdx);
+ else
+ CurRC = TRI->getSubClassWithSubReg(CurRC, SubIdx);
+ } else if (OpRC)
+ CurRC = TRI->getCommonSubClass(CurRC, OpRC);
+ return CurRC;
+}
+/// Return the number of instructions inside the MI bundle, not counting the
+/// header instruction.
+unsigned MachineInstr::getBundleSize() const {
+ MachineBasicBlock::const_instr_iterator I = this;
+ unsigned Size = 0;
+ while (I->isBundledWithSucc())
+ ++Size, ++I;
return Size;
}
return false;
}
- if (isLabel() || isDebugValue() ||
- isTerminator() || hasUnmodeledSideEffects())
+ if (isPosition() || isDebugValue() || isTerminator() ||
+ hasUnmodeledSideEffects())
return false;
// See if this instruction does a load. If so, we have to guarantee that the
return true;
}
-/// isSafeToReMat - Return true if it's safe to rematerialize the specified
-/// instruction which defined the specified register instead of copying it.
-bool MachineInstr::isSafeToReMat(const TargetInstrInfo *TII,
- AliasAnalysis *AA,
- unsigned DstReg) const {
- bool SawStore = false;
- if (!TII->isTriviallyReMaterializable(this, AA) ||
- !isSafeToMove(TII, AA, SawStore))
- return false;
- for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
- const MachineOperand &MO = getOperand(i);
- if (!MO.isReg())
- continue;
- // FIXME: For now, do not remat any instruction with register operands.
- // Later on, we can loosen the restriction is the register operands have
- // not been modified between the def and use. Note, this is different from
- // MachineSink because the code is no longer in two-address form (at least
- // partially).
- if (MO.isUse())
- return false;
- else if (!MO.isDead() && MO.getReg() != DstReg)
- return false;
- }
- return true;
-}
-
/// hasOrderedMemoryRef - Return true if this instruction may have an ordered
/// or volatile memory reference, or if the information describing the memory
/// reference is not available. Return false if it is known to have no ordered
const LLVMContext &Ctx = MF->getFunction()->getContext();
if (!DL.isUnknown()) { // Print source line info.
DIScope Scope(DL.getScope(Ctx));
+ assert((!Scope || Scope.isScope()) &&
+ "Scope of a DebugLoc should be null or a DIScope.");
// Omit the directory, because it's likely to be long and uninteresting.
- if (Scope.Verify())
+ if (Scope)
CommentOS << Scope.getFilename();
else
CommentOS << "<unknown>";
}
}
-void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM) const {
+void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM,
+ bool SkipOpers) const {
// We can be a bit tidier if we know the TargetMachine and/or MachineFunction.
const MachineFunction *MF = 0;
const MachineRegisterInfo *MRI = 0;
else
OS << "UNKNOWN";
+ if (SkipOpers)
+ return;
+
// Print the rest of the operands.
bool OmittedAnyCallClobbers = false;
bool FirstOp = true;
OS << " ";
getOperand(InlineAsm::MIOp_AsmString).print(OS, TM);
- // Print HasSideEffects, IsAlignStack
+ // Print HasSideEffects, MayLoad, MayStore, IsAlignStack
unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
if (ExtraInfo & InlineAsm::Extra_HasSideEffects)
OS << " [sideeffect]";
+ if (ExtraInfo & InlineAsm::Extra_MayLoad)
+ OS << " [mayload]";
+ if (ExtraInfo & InlineAsm::Extra_MayStore)
+ OS << " [maystore]";
if (ExtraInfo & InlineAsm::Extra_IsAlignStack)
OS << " [alignstack]";
if (getInlineAsmDialect() == InlineAsm::AD_ATT)
unsigned Reg = MO.getReg();
if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
const MachineRegisterInfo &MRI = MF->getRegInfo();
- if (MRI.use_empty(Reg) && !MRI.isLiveOut(Reg)) {
+ if (MRI.use_empty(Reg)) {
bool HasAliasLive = false;
for (MCRegAliasIterator AI(Reg, TM->getRegisterInfo(), true);
AI.isValid(); ++AI) {
unsigned AliasReg = *AI;
- if (!MRI.use_empty(AliasReg) || MRI.isLiveOut(AliasReg)) {
+ if (!MRI.use_empty(AliasReg)) {
HasAliasLive = true;
break;
}
}
bool HaveSemi = false;
- if (Flags) {
+ const unsigned PrintableFlags = FrameSetup;
+ if (Flags & PrintableFlags) {
if (!HaveSemi) OS << ";"; HaveSemi = true;
OS << " flags: ";
for (mmo_iterator i = memoperands_begin(), e = memoperands_end();
i != e; ++i) {
OS << **i;
- if (llvm::next(i) != e)
+ if (std::next(i) != e)
OS << " ";
}
}
}
}
-bool MachineInstr::addRegisterDead(unsigned IncomingReg,
+bool MachineInstr::addRegisterDead(unsigned Reg,
const TargetRegisterInfo *RegInfo,
bool AddIfNotFound) {
- bool isPhysReg = TargetRegisterInfo::isPhysicalRegister(IncomingReg);
+ bool isPhysReg = TargetRegisterInfo::isPhysicalRegister(Reg);
bool hasAliases = isPhysReg &&
- MCRegAliasIterator(IncomingReg, RegInfo, false).isValid();
+ MCRegAliasIterator(Reg, RegInfo, false).isValid();
bool Found = false;
SmallVector<unsigned,4> DeadOps;
for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
MachineOperand &MO = getOperand(i);
if (!MO.isReg() || !MO.isDef())
continue;
- unsigned Reg = MO.getReg();
- if (!Reg)
+ unsigned MOReg = MO.getReg();
+ if (!MOReg)
continue;
- if (Reg == IncomingReg) {
+ if (MOReg == Reg) {
MO.setIsDead();
Found = true;
} else if (hasAliases && MO.isDead() &&
- TargetRegisterInfo::isPhysicalRegister(Reg)) {
+ TargetRegisterInfo::isPhysicalRegister(MOReg)) {
// There exists a super-register that's marked dead.
- if (RegInfo->isSuperRegister(IncomingReg, Reg))
+ if (RegInfo->isSuperRegister(Reg, MOReg))
return true;
- if (RegInfo->isSubRegister(IncomingReg, Reg))
+ if (RegInfo->isSubRegister(Reg, MOReg))
DeadOps.push_back(i);
}
}
if (Found || !AddIfNotFound)
return Found;
- addOperand(MachineOperand::CreateReg(IncomingReg,
+ addOperand(MachineOperand::CreateReg(Reg,
true /*IsDef*/,
true /*IsImp*/,
false /*IsKill*/,
return true;
}
-void MachineInstr::addRegisterDefined(unsigned IncomingReg,
+void MachineInstr::addRegisterDefined(unsigned Reg,
const TargetRegisterInfo *RegInfo) {
- if (TargetRegisterInfo::isPhysicalRegister(IncomingReg)) {
- MachineOperand *MO = findRegisterDefOperand(IncomingReg, false, RegInfo);
+ if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
+ MachineOperand *MO = findRegisterDefOperand(Reg, false, RegInfo);
if (MO)
return;
} else {
for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
const MachineOperand &MO = getOperand(i);
- if (MO.isReg() && MO.getReg() == IncomingReg && MO.isDef() &&
+ if (MO.isReg() && MO.getReg() == Reg && MO.isDef() &&
MO.getSubReg() == 0)
return;
}
}
- addOperand(MachineOperand::CreateReg(IncomingReg,
+ addOperand(MachineOperand::CreateReg(Reg,
true /*IsDef*/,
true /*IsImp*/));
}