#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
#include "llvm/ADT/iterator_range.h"
+#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DebugLoc.h"
namespace llvm {
template <typename T> class SmallVectorImpl;
-class AliasAnalysis;
class TargetInstrInfo;
class TargetRegisterClass;
class TargetRegisterInfo;
/// MachineFunction is deleted, all the contained MachineInstrs are deallocated
/// without having their destructor called.
///
-class MachineInstr : public ilist_node<MachineInstr> {
+class MachineInstr
+ : public ilist_node_with_parent<MachineInstr, MachineBasicBlock> {
public:
typedef MachineMemOperand **mmo_iterator;
NoFlags = 0,
FrameSetup = 1 << 0, // Instruction is used as a part of
// function frame setup code.
- BundledPred = 1 << 1, // Instruction has bundled predecessors.
- BundledSucc = 1 << 2 // Instruction has bundled successors.
+ FrameDestroy = 1 << 1, // Instruction is used as a part of
+ // function frame destruction code.
+ BundledPred = 1 << 2, // Instruction has bundled predecessors.
+ BundledSucc = 1 << 3 // Instruction has bundled successors.
};
private:
const MCInstrDesc *MCID; // Instruction descriptor.
return iterator_range<const_mop_iterator>(explicit_operands().end(),
operands_end());
}
+ /// Returns a range over all explicit operands that are register definitions.
+ /// Implicit definition are not included!
iterator_range<mop_iterator> defs() {
return iterator_range<mop_iterator>(
operands_begin(), operands_begin() + getDesc().getNumDefs());
}
+ /// \copydoc defs()
iterator_range<const_mop_iterator> defs() const {
return iterator_range<const_mop_iterator>(
operands_begin(), operands_begin() + getDesc().getNumDefs());
}
+ /// Returns a range that includes all operands that are register uses.
+ /// This may include unrelated operands which are not register uses.
iterator_range<mop_iterator> uses() {
return iterator_range<mop_iterator>(
operands_begin() + getDesc().getNumDefs(), operands_end());
}
+ /// \copydoc uses()
iterator_range<const_mop_iterator> uses() const {
return iterator_range<const_mop_iterator>(
operands_begin() + getDesc().getNumDefs(), operands_end());
}
+ /// Returns the number of the operand iterator \p I points to.
+ unsigned getOperandNo(const_mop_iterator I) const {
+ return I - operands_begin();
+ }
+
/// Access to memory operands of the instruction
mmo_iterator memoperands_begin() const { return MemRefs; }
mmo_iterator memoperands_end() const { return MemRefs + NumMemRefs; }
}
/// Return true if this instruction is convergent.
- /// Convergent instructions can only be moved to locations that are
- /// control-equivalent to their initial position.
+ /// Convergent instructions can not be made control-dependent on any
+ /// additional values.
bool isConvergent(QueryType Type = AnyInBundle) const {
return hasProperty(MCID::Convergent, Type);
}
return (Idx == -1) ? nullptr : &getOperand(Idx);
}
+ const MachineOperand *findRegisterUseOperand(
+ unsigned Reg, bool isKill = false,
+ const TargetRegisterInfo *TRI = nullptr) const {
+ return const_cast<MachineInstr *>(this)->
+ findRegisterUseOperand(Reg, isKill, TRI);
+ }
+
/// Returns the operand index that is a def of the specified register or
/// -1 if it is not found. If isDead is true, defs that are not dead are
/// skipped. If Overlap is true, then it also looks for defs that merely
/// For normal instructions, this is derived from the MCInstrDesc.
/// For inline assembly it is derived from the flag words.
///
- /// Returns NULL if the static register classs constraint cannot be
+ /// Returns NULL if the static register class constraint cannot be
/// determined.
///
const TargetRegisterClass*
/// the given \p CurRC.
/// If \p ExploreBundle is set and MI is part of a bundle, all the
/// instructions inside the bundle will be taken into account. In other words,
- /// this method accumulates all the constrains of the operand of this MI and
+ /// this method accumulates all the constraints of the operand of this MI and
/// the related bundle if MI is a bundle or inside a bundle.
///
- /// Returns the register class that statisfies both \p CurRC and the
+ /// Returns the register class that satisfies both \p CurRC and the
/// constraints set by MI. Returns NULL if such a register class does not
/// exist.
///
/// \brief Applies the constraints (def/use) implied by the \p OpIdx operand
/// to the given \p CurRC.
///
- /// Returns the register class that statisfies both \p CurRC and the
+ /// Returns the register class that satisfies both \p CurRC and the
/// constraints set by \p OpIdx MI. Returns NULL if such a register class
/// does not exist.
///
/// Mark all subregister defs of register @p Reg with the undef flag.
/// This function is used when we determined to have a subregister def in an
/// otherwise undefined super register.
- void addRegisterDefReadUndef(unsigned Reg);
+ void setRegisterDefReadUndef(unsigned Reg, bool IsUndef = true);
/// We have determined MI defines a register. Make sure there is an operand
/// defining Reg.
///
bool hasUnmodeledSideEffects() const;
+ /// Returns true if it is illegal to fold a load across this instruction.
+ bool isLoadFoldBarrier() const;
+
/// Return true if all the defs of this instruction are dead.
bool allDefsAreDead() const;
// Debugging support
//
void print(raw_ostream &OS, bool SkipOpers = false) const;
+ void print(raw_ostream &OS, ModuleSlotTracker &MST,
+ bool SkipOpers = false) const;
void dump() const;
//===--------------------------------------------------------------------===//
}
}
+ /// Add all implicit def and use operands to this instruction.
+ void addImplicitDefUseOperands(MachineFunction &MF);
private:
/// If this instruction is embedded into a MachineFunction, return the
/// return null.
MachineRegisterInfo *getRegInfo();
- /// Add all implicit def and use operands to this instruction.
- void addImplicitDefUseOperands(MachineFunction &MF);
-
/// Unlink all of the register operands in this instruction from their
/// respective use lists. This requires that the operands already be on their
/// use lists.