#ifndef LLVM_TARGET_TARGETINSTRINFO_H
#define LLVM_TARGET_TARGETINSTRINFO_H
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Target/TargetInstrDesc.h"
#include "llvm/CodeGen/MachineFunction.h"
namespace llvm {
class TargetRegisterClass;
+class TargetRegisterInfo;
class LiveVariables;
class CalleeSavedInfo;
class SDNode;
EH_LABEL = 3,
GC_LABEL = 4,
DECLARE = 5,
+
+ /// EXTRACT_SUBREG - This instruction takes two operands: a register
+ /// that has subregisters, and a subregister index. It returns the
+ /// extracted subregister value. This is commonly used to implement
+ /// truncation operations on target architectures which support it.
EXTRACT_SUBREG = 6,
+
+ /// INSERT_SUBREG - This instruction takes three operands: a register
+ /// that has subregisters, a register providing an insert value, and a
+ /// subregister index. It returns the value of the first register with
+ /// the value of the second register inserted. The first register is
+ /// often defined by an IMPLICIT_DEF, as is commonly used to implement
+ /// anyext operations on target architectures which support it.
INSERT_SUBREG = 7,
+
+ /// IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef.
IMPLICIT_DEF = 8,
- SUBREG_TO_REG = 9
+
+ /// SUBREG_TO_REG - This instruction is similar to INSERT_SUBREG except
+ /// that the first operand is an immediate integer constant. This constant
+ /// is often zero, as is commonly used to implement zext operations on
+ /// target architectures which support it, such as with x86-64 (with
+ /// zext from i32 to i64 via implicit zero-extension).
+ SUBREG_TO_REG = 9,
+
+ /// COPY_TO_REGCLASS - This instruction is a placeholder for a plain
+ /// register-to-register copy into a specific register class. This is only
+ /// used between instruction selection and MachineInstr creation, before
+ /// virtual registers have been created for all the instructions, and it's
+ /// only needed in cases where the register classes implied by the
+ /// instructions are insufficient. The actual MachineInstrs to perform
+ /// the copy are emitted with the TargetInstrInfo::copyRegToReg hook.
+ COPY_TO_REGCLASS = 10
};
unsigned getNumOpcodes() const { return NumOpcodes; }
}
public:
- /// Return true if the instruction is a register to register move
- /// and leave the source and dest operands in the passed parameters.
+ /// Return true if the instruction is a register to register move and return
+ /// the source and dest operands and their sub-register indices by reference.
virtual bool isMoveInstr(const MachineInstr& MI,
- unsigned& sourceReg,
- unsigned& destReg) const {
+ unsigned& SrcReg, unsigned& DstReg,
+ unsigned& SrcSubIdx, unsigned& DstSubIdx) const {
return false;
}
/// the destination along with the FrameIndex of the loaded stack slot. If
/// not, return 0. This predicate must return 0 if the instruction has
/// any side effects other than loading from the stack slot.
- virtual unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const{
+ virtual unsigned isLoadFromStackSlot(const MachineInstr *MI,
+ int &FrameIndex) const {
return 0;
}
/// the source reg along with the FrameIndex of the loaded stack slot. If
/// not, return 0. This predicate must return 0 if the instruction has
/// any side effects other than storing to the stack slot.
- virtual unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const {
+ virtual unsigned isStoreToStackSlot(const MachineInstr *MI,
+ int &FrameIndex) const {
return 0;
}
/// from the argument area of a function if it does not change. This should
/// only return true of *all* loads the instruction does are invariant (if it
/// does multiple loads).
- virtual bool isInvariantLoad(MachineInstr *MI) const {
+ virtual bool isInvariantLoad(const MachineInstr *MI) const {
return false;
}
virtual MachineInstr *commuteInstruction(MachineInstr *MI,
bool NewMI = false) const = 0;
- /// CommuteChangesDestination - Return true if commuting the specified
- /// instruction will also changes the destination operand. Also return the
- /// current operand index of the would be new destination register by
- /// reference. This can happen when the commutable instruction is also a
- /// two-address instruction.
- virtual bool CommuteChangesDestination(MachineInstr *MI,
- unsigned &OpIdx) const = 0;
+ /// findCommutedOpIndices - If specified MI is commutable, return the two
+ /// operand indices that would swap value. Return true if the instruction
+ /// is not in a form which this routine understands.
+ virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1,
+ unsigned &SrcOpIdx2) const = 0;
/// AnalyzeBranch - Analyze the branching code at the end of MBB, returning
/// true if it cannot be understood (e.g. it's a switch dispatch or isn't
/// 2. If this block ends with only an unconditional branch, it sets TBB to be
/// the destination block.
/// 3. If this block ends with an conditional branch and it falls through to
- /// an successor block, it sets TBB to be the branch destination block and a
- /// list of operands that evaluate the condition. These
+ /// an successor block, it sets TBB to be the branch destination block and
+ /// a list of operands that evaluate the condition. These
/// operands can be passed to other TargetInstrInfo methods to create new
/// branches.
/// 4. If this block ends with an conditional branch and an unconditional
- /// block, it returns the 'true' destination in TBB, the 'false' destination
- /// in FBB, and a list of operands that evaluate the condition. These
- /// operands can be passed to other TargetInstrInfo methods to create new
- /// branches.
+ /// block, it returns the 'true' destination in TBB, the 'false'
+ /// destination in FBB, and a list of operands that evaluate the condition.
+ /// These operands can be passed to other TargetInstrInfo methods to create
+ /// new branches.
///
/// Note that RemoveBranch and InsertBranch must be implemented to support
/// cases where this method returns success.
///
+ /// If AllowModify is true, then this routine is allowed to modify the basic
+ /// block (e.g. delete instructions after the unconditional branch).
+ ///
virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB,
- SmallVectorImpl<MachineOperand> &Cond) const {
+ SmallVectorImpl<MachineOperand> &Cond,
+ bool AllowModify = false) const {
return true;
}
/// returns success and when an unconditional branch (TBB is non-null, FBB is
/// null, Cond is empty) needs to be inserted. It returns the number of
/// instructions inserted.
+ ///
+ /// It is also invoked by tail merging to add unconditional branches in
+ /// cases where AnalyzeBranch doesn't apply because there was no original
+ /// branch to analyze. At least this much must be implemented, else tail
+ /// merging needs to be disabled.
virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
MachineBasicBlock *FBB,
const SmallVectorImpl<MachineOperand> &Cond) const {
/// operand folded, otherwise NULL is returned. The client is responsible for
/// removing the old instruction and adding the new one in the instruction
/// stream.
- virtual MachineInstr* foldMemoryOperand(MachineFunction &MF,
- MachineInstr* MI,
- const SmallVectorImpl<unsigned> &Ops,
- int FrameIndex) const {
- return 0;
- }
+ MachineInstr* foldMemoryOperand(MachineFunction &MF,
+ MachineInstr* MI,
+ const SmallVectorImpl<unsigned> &Ops,
+ int FrameIndex) const;
/// foldMemoryOperand - Same as the previous version except it allows folding
/// of any load and store from / to any address, not just from a specific
/// stack slot.
- virtual MachineInstr* foldMemoryOperand(MachineFunction &MF,
+ MachineInstr* foldMemoryOperand(MachineFunction &MF,
+ MachineInstr* MI,
+ const SmallVectorImpl<unsigned> &Ops,
+ MachineInstr* LoadMI) const;
+
+protected:
+ /// foldMemoryOperandImpl - Target-dependent implementation for
+ /// foldMemoryOperand. Target-independent code in foldMemoryOperand will
+ /// take care of adding a MachineMemOperand to the newly created instruction.
+ virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
MachineInstr* MI,
const SmallVectorImpl<unsigned> &Ops,
- MachineInstr* LoadMI) const {
+ int FrameIndex) const {
return 0;
}
- /// canFoldMemoryOperand - Returns true if the specified load / store is
+ /// foldMemoryOperandImpl - Target-dependent implementation for
+ /// foldMemoryOperand. Target-independent code in foldMemoryOperand will
+ /// take care of adding a MachineMemOperand to the newly created instruction.
+ virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
+ MachineInstr* MI,
+ const SmallVectorImpl<unsigned> &Ops,
+ MachineInstr* LoadMI) const {
+ return 0;
+ }
+
+public:
+ /// canFoldMemoryOperand - Returns true for the specified load / store if
/// folding is possible.
virtual
bool canFoldMemoryOperand(const MachineInstr *MI,
/// possible, returns true as well as the new instructions by reference.
virtual bool unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI,
unsigned Reg, bool UnfoldLoad, bool UnfoldStore,
- SmallVectorImpl<MachineInstr*> &NewMIs) const{
+ SmallVectorImpl<MachineInstr*> &NewMIs) const{
return false;
}
/// point.
virtual void insertNoop(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const {
- assert(0 && "Target didn't implement insertNoop!");
- abort();
+ llvm_unreachable("Target didn't implement insertNoop!");
}
/// isPredicated - Returns true if the instruction is already predicated.
return false;
}
- /// IgnoreRegisterClassBarriers - Returns true if pre-register allocation
- /// live interval splitting pass should ignore barriers of the specified
- /// register class.
- virtual bool IgnoreRegisterClassBarriers(const TargetRegisterClass *RC) const{
+ /// isSafeToMoveRegClassDefs - Return true if it's safe to move a machine
+ /// instruction that defines the specified register class.
+ virtual bool isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const {
return true;
}
- /// getPointerRegClass - Returns a TargetRegisterClass used for pointer
- /// values.
- virtual const TargetRegisterClass *getPointerRegClass() const {
- assert(0 && "Target didn't implement getPointerRegClass!");
- abort();
- return 0; // Must return a value in order to compile with VS 2005
- }
-
/// GetInstSize - Returns the size of the specified Instruction.
///
virtual unsigned GetInstSizeInBytes(const MachineInstr *MI) const {
public:
virtual MachineInstr *commuteInstruction(MachineInstr *MI,
bool NewMI = false) const;
- virtual bool CommuteChangesDestination(MachineInstr *MI,
- unsigned &OpIdx) const;
+ virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1,
+ unsigned &SrcOpIdx2) const;
virtual bool PredicateInstruction(MachineInstr *MI,
const SmallVectorImpl<MachineOperand> &Pred) const;
virtual void reMaterialize(MachineBasicBlock &MBB,
virtual unsigned GetFunctionSizeInBytes(const MachineFunction &MF) const;
};
+/// getInstrOperandRegClass - Return register class of the operand of an
+/// instruction of the specified TargetInstrDesc.
+const TargetRegisterClass*
+getInstrOperandRegClass(const TargetRegisterInfo *TRI,
+ const TargetInstrDesc &II, unsigned Op);
+
} // End llvm namespace
#endif