//
//===----------------------------------------------------------------------===//
//
-// This file describes the target machine instructions to the code generator.
+// This file describes the target machine instruction set to the code generator.
//
//===----------------------------------------------------------------------===//
namespace llvm {
+class MCAsmInfo;
class TargetRegisterClass;
+class TargetRegisterInfo;
class LiveVariables;
class CalleeSavedInfo;
class SDNode;
class SelectionDAG;
+class MachineMemOperand;
template<class T> class SmallVectorImpl;
//---------------------------------------------------------------------------
///
-/// TargetInstrInfo - Interface to description of machine instructions
+/// TargetInstrInfo - Interface to description of machine instruction set
///
class TargetInstrInfo {
const TargetInstrDesc *Descriptors; // Raw array to allow static init'n
TargetInstrInfo(const TargetInstrDesc *desc, unsigned NumOpcodes);
virtual ~TargetInstrInfo();
- // Invariant opcodes: All instruction sets have these as their low opcodes.
- enum {
- PHI = 0,
- INLINEASM = 1,
- LABEL = 2,
- DECLARE = 3,
- EXTRACT_SUBREG = 4,
- INSERT_SUBREG = 5
- };
-
- // Target independent implict values for use with subreg insert. All targets
- // that support insert_subreg support IMPL_VAL_UNDEF. Support for the other
- // values is target dependent.
- enum ImplictVal {
- IMPL_VAL_UNDEF = 0,
- IMPL_VAL_ZERO = 1,
- LAST_IMPL_VAL = 3
- };
-
unsigned getNumOpcodes() const { return NumOpcodes; }
/// get - Return the machine instruction descriptor that corresponds to the
/// isTriviallyReMaterializable - Return true if the instruction is trivially
/// rematerializable, meaning it has no side effects and requires no operands
/// that aren't always available.
- bool isTriviallyReMaterializable(MachineInstr *MI) const {
- return MI->getDesc().isRematerializable() &&
- isReallyTriviallyReMaterializable(MI);
+ bool isTriviallyReMaterializable(const MachineInstr *MI,
+ AliasAnalysis *AA = 0) const {
+ return MI->getOpcode() == TargetOpcode::IMPLICIT_DEF ||
+ (MI->getDesc().isRematerializable() &&
+ (isReallyTriviallyReMaterializable(MI, AA) ||
+ isReallyTriviallyReMaterializableGeneric(MI, AA)));
}
protected:
/// isReallyTriviallyReMaterializable - For instructions with opcodes for
- /// which the M_REMATERIALIZABLE flag is set, this function tests whether the
- /// instruction itself is actually trivially rematerializable, considering
- /// its operands. This is used for targets that have instructions that are
- /// only trivially rematerializable for specific uses. This predicate must
- /// return false if the instruction has any side effects other than
- /// producing a value, or if it requres any address registers that are not
- /// always available.
- virtual bool isReallyTriviallyReMaterializable(MachineInstr *MI) const {
- return true;
+ /// which the M_REMATERIALIZABLE flag is set, this hook lets the target
+ /// specify whether the instruction is actually trivially rematerializable,
+ /// taking into consideration its operands. This predicate must return false
+ /// if the instruction has any side effects other than producing a value, or
+ /// if it requres any address registers that are not always available.
+ virtual bool isReallyTriviallyReMaterializable(const MachineInstr *MI,
+ AliasAnalysis *AA) const {
+ return false;
}
+private:
+ /// isReallyTriviallyReMaterializableGeneric - For instructions with opcodes
+ /// for which the M_REMATERIALIZABLE flag is set and the target hook
+ /// isReallyTriviallyReMaterializable returns false, this function does
+ /// target-independent tests to determine if the instruction is really
+ /// trivially rematerializable.
+ bool isReallyTriviallyReMaterializableGeneric(const MachineInstr *MI,
+ AliasAnalysis *AA) const;
+
public:
- /// Return true if the instruction is a register to register move
- /// and leave the source and dest operands in the passed parameters.
+ /// isMoveInstr - 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;
+ }
+
+ /// isCoalescableExtInstr - Return true if the instruction is a "coalescable"
+ /// extension instruction. That is, it's like a copy where it's legal for the
+ /// source to overlap the destination. e.g. X86::MOVSX64rr32. If this returns
+ /// true, then it's expected the pre-extension value is available as a subreg
+ /// of the result register. This also returns the sub-register index in
+ /// SubIdx.
+ virtual bool isCoalescableExtInstr(const MachineInstr &MI,
+ unsigned &SrcReg, unsigned &DstReg,
+ unsigned &SubIdx) const {
+ return false;
+ }
+
+ /// isIdentityCopy - Return true if the instruction is a copy (or
+ /// extract_subreg, insert_subreg, subreg_to_reg) where the source and
+ /// destination registers are the same.
+ bool isIdentityCopy(const MachineInstr &MI) const {
+ unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
+ if (isMoveInstr(MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) &&
+ SrcReg == DstReg)
+ return true;
+
+ if (MI.getOpcode() == TargetOpcode::EXTRACT_SUBREG &&
+ MI.getOperand(0).getReg() == MI.getOperand(1).getReg())
+ return true;
+
+ if ((MI.getOpcode() == TargetOpcode::INSERT_SUBREG ||
+ MI.getOpcode() == TargetOpcode::SUBREG_TO_REG) &&
+ MI.getOperand(0).getReg() == MI.getOperand(2).getReg())
+ return true;
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;
+ }
+
+ /// isLoadFromStackSlotPostFE - Check for post-frame ptr elimination
+ /// stack locations as well. This uses a heuristic so it isn't
+ /// reliable for correctness.
+ virtual unsigned isLoadFromStackSlotPostFE(const MachineInstr *MI,
+ int &FrameIndex) const {
+ return 0;
+ }
+
+ /// hasLoadFromStackSlot - If the specified machine instruction has
+ /// a load from a stack slot, return true along with the FrameIndex
+ /// of the loaded stack slot and the machine mem operand containing
+ /// the reference. If not, return false. Unlike
+ /// isLoadFromStackSlot, this returns true for any instructions that
+ /// loads from the stack. This is just a hint, as some cases may be
+ /// missed.
+ virtual bool hasLoadFromStackSlot(const MachineInstr *MI,
+ const MachineMemOperand *&MMO,
+ 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;
}
- /// isInvariantLoad - Return true if the specified instruction (which is
- /// marked mayLoad) is loading from a location whose value is invariant across
- /// the function. For example, loading a value from the constant pool or from
- /// 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 {
- return false;
+ /// isStoreToStackSlotPostFE - Check for post-frame ptr elimination
+ /// stack locations as well. This uses a heuristic so it isn't
+ /// reliable for correctness.
+ virtual unsigned isStoreToStackSlotPostFE(const MachineInstr *MI,
+ int &FrameIndex) const {
+ return 0;
}
-
+
+ /// hasStoreToStackSlot - If the specified machine instruction has a
+ /// store to a stack slot, return true along with the FrameIndex of
+ /// the loaded stack slot and the machine mem operand containing the
+ /// reference. If not, return false. Unlike isStoreToStackSlot,
+ /// this returns true for any instructions that loads from the
+ /// stack. This is just a hint, as some cases may be missed.
+ virtual bool hasStoreToStackSlot(const MachineInstr *MI,
+ const MachineMemOperand *&MMO,
+ int &FrameIndex) const {
+ return 0;
+ }
+
+ /// reMaterialize - Re-issue the specified 'original' instruction at the
+ /// specific location targeting a new destination register.
+ virtual void reMaterialize(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI,
+ unsigned DestReg, unsigned SubIdx,
+ const MachineInstr *Orig,
+ const TargetRegisterInfo *TRI) const = 0;
+
+ /// duplicate - Create a duplicate of the Orig instruction in MF. This is like
+ /// MachineFunction::CloneMachineInstr(), but the target may update operands
+ /// that are required to be unique.
+ ///
+ /// The instruction must be duplicable as indicated by isNotDuplicable().
+ virtual MachineInstr *duplicate(MachineInstr *Orig,
+ MachineFunction &MF) const = 0;
+
/// convertToThreeAddress - This method must be implemented by targets that
/// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target
/// may be able to convert a two-address instruction into one or more true
///
virtual MachineInstr *
convertToThreeAddress(MachineFunction::iterator &MFI,
- MachineBasicBlock::iterator &MBBI, LiveVariables &LV) const {
+ MachineBasicBlock::iterator &MBBI, LiveVariables *LV) const {
return 0;
}
/// return a new machine instruction. If an instruction cannot commute, it
/// can also return null.
///
- virtual MachineInstr *commuteInstruction(MachineInstr *MI) 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;
+ /// If NewMI is true, then a new machine instruction must be created.
+ ///
+ virtual MachineInstr *commuteInstruction(MachineInstr *MI,
+ bool NewMI = false) 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;
+
+ /// isIdentical - Return true if two instructions are identical. This differs
+ /// from MachineInstr::isIdenticalTo() in that it does not require the
+ /// virtual destination registers to be the same. This is used by MachineLICM
+ /// and other MI passes to perform CSE.
+ virtual bool isIdentical(const MachineInstr *MI,
+ const MachineInstr *Other,
+ const MachineRegisterInfo *MRI) 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
/// just return false, leaving TBB/FBB null.
/// 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
- /// 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.
+ /// 3. If this block ends with a conditional branch and it falls through to a
+ /// 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 a conditional branch followed by an
+ /// unconditional branch, 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,
- std::vector<MachineOperand> &Cond) const {
+ SmallVectorImpl<MachineOperand> &Cond,
+ bool AllowModify = false) const {
return true;
}
-
+
/// RemoveBranch - Remove the branching code at the end of the specific MBB.
- /// this is only invoked in cases where AnalyzeBranch returns success. It
+ /// This is only invoked in cases where AnalyzeBranch returns success. It
/// returns the number of instructions that were removed.
virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const {
assert(0 && "Target didn't implement TargetInstrInfo::RemoveBranch!");
return 0;
}
-
- /// InsertBranch - Insert a branch into the end of the specified
- /// MachineBasicBlock. This operands to this method are the same as those
- /// returned by AnalyzeBranch. This is invoked in cases where AnalyzeBranch
- /// 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.
+
+ /// InsertBranch - Insert branch code into the end of the specified
+ /// MachineBasicBlock. The operands to this method are the same as those
+ /// returned by AnalyzeBranch. This is only invoked in cases where
+ /// AnalyzeBranch returns success. 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 std::vector<MachineOperand> &Cond) const {
+ const SmallVectorImpl<MachineOperand> &Cond) const {
assert(0 && "Target didn't implement TargetInstrInfo::InsertBranch!");
return 0;
}
- /// copyRegToReg - Add a copy between a pair of registers
- virtual void copyRegToReg(MachineBasicBlock &MBB,
+ /// copyRegToReg - Emit instructions to copy between a pair of registers. It
+ /// returns false if the target does not how to copy between the specified
+ /// registers.
+ virtual bool copyRegToReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
unsigned DestReg, unsigned SrcReg,
const TargetRegisterClass *DestRC,
const TargetRegisterClass *SrcRC) const {
assert(0 && "Target didn't implement TargetInstrInfo::copyRegToReg!");
+ return false;
}
+ /// storeRegToStackSlot - Store the specified register of the given register
+ /// class to the specified stack frame index. The store instruction is to be
+ /// added to the given machine basic block before the specified machine
+ /// instruction. If isKill is true, the register operand is the last use and
+ /// must be marked kill.
virtual void storeRegToStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
unsigned SrcReg, bool isKill, int FrameIndex,
assert(0 && "Target didn't implement TargetInstrInfo::storeRegToStackSlot!");
}
- virtual void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill,
- SmallVectorImpl<MachineOperand> &Addr,
- const TargetRegisterClass *RC,
- SmallVectorImpl<MachineInstr*> &NewMIs) const {
- assert(0 && "Target didn't implement TargetInstrInfo::storeRegToAddr!");
- }
-
+ /// loadRegFromStackSlot - Load the specified register of the given register
+ /// class from the specified stack frame index. The load instruction is to be
+ /// added to the given machine basic block before the specified machine
+ /// instruction.
virtual void loadRegFromStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
unsigned DestReg, int FrameIndex,
const TargetRegisterClass *RC) const {
assert(0 && "Target didn't implement TargetInstrInfo::loadRegFromStackSlot!");
}
-
- virtual void loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
- SmallVectorImpl<MachineOperand> &Addr,
- const TargetRegisterClass *RC,
- SmallVectorImpl<MachineInstr*> &NewMIs) const {
- assert(0 && "Target didn't implement TargetInstrInfo::loadRegFromAddr!");
- }
/// spillCalleeSavedRegisters - Issues instruction(s) to spill all callee
/// saved registers and returns true if it isn't possible / profitable to do
/// 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,
- 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,
- SmallVectorImpl<unsigned> &Ops,
- MachineInstr* LoadMI) const {
+ const SmallVectorImpl<unsigned> &Ops,
+ 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(MachineInstr *MI,
- SmallVectorImpl<unsigned> &Ops) const{
+ bool canFoldMemoryOperand(const MachineInstr *MI,
+ const SmallVectorImpl<unsigned> &Ops) const {
return false;
}
/// 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;
}
/// getOpcodeAfterMemoryUnfold - Returns the opcode of the would be new
/// instruction after load / store are unfolded from an instruction of the
/// specified opcode. It returns zero if the specified unfolding is not
- /// possible.
+ /// possible. If LoadRegIndex is non-null, it is filled in with the operand
+ /// index of the operand which will hold the register holding the loaded
+ /// value.
virtual unsigned getOpcodeAfterMemoryUnfold(unsigned Opc,
- bool UnfoldLoad, bool UnfoldStore) const {
+ bool UnfoldLoad, bool UnfoldStore,
+ unsigned *LoadRegIndex = 0) const {
return 0;
}
-
- /// BlockHasNoFallThrough - Return true if the specified block does not
- /// fall-through into its successor block. This is primarily used when a
- /// branch is unanalyzable. It is useful for things like unconditional
- /// indirect branches (jump tables).
- virtual bool BlockHasNoFallThrough(MachineBasicBlock &MBB) const {
+
+ /// areLoadsFromSameBasePtr - This is used by the pre-regalloc scheduler
+ /// to determine if two loads are loading from the same base address. It
+ /// should only return true if the base pointers are the same and the
+ /// only differences between the two addresses are the offset. It also returns
+ /// the offsets by reference.
+ virtual bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
+ int64_t &Offset1, int64_t &Offset2) const {
+ return false;
+ }
+
+ /// shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to
+ /// determine (in conjuction with areLoadsFromSameBasePtr) if two loads should
+ /// be scheduled togther. On some targets if two loads are loading from
+ /// addresses in the same cache line, it's better if they are scheduled
+ /// together. This function takes two integers that represent the load offsets
+ /// from the common base address. It returns true if it decides it's desirable
+ /// to schedule the two loads together. "NumLoads" is the number of loads that
+ /// have already been scheduled after Load1.
+ virtual bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2,
+ int64_t Offset1, int64_t Offset2,
+ unsigned NumLoads) const {
return false;
}
/// ReverseBranchCondition - Reverses the branch condition of the specified
/// condition list, returning false on success and true if it cannot be
/// reversed.
- virtual bool ReverseBranchCondition(std::vector<MachineOperand> &Cond) const {
+ virtual
+ bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
return true;
}
/// insertNoop - Insert a noop into the instruction stream at the specified
/// point.
virtual void insertNoop(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator MI) const {
- assert(0 && "Target didn't implement insertNoop!");
- abort();
- }
-
+ MachineBasicBlock::iterator MI) const;
+
/// isPredicated - Returns true if the instruction is already predicated.
///
virtual bool isPredicated(const MachineInstr *MI) const {
/// instruction. It returns true if the operation was successful.
virtual
bool PredicateInstruction(MachineInstr *MI,
- const std::vector<MachineOperand> &Pred) const = 0;
+ const SmallVectorImpl<MachineOperand> &Pred) const = 0;
/// SubsumesPredicate - Returns true if the first specified predicate
/// subsumes the second, e.g. GE subsumes GT.
virtual
- bool SubsumesPredicate(const std::vector<MachineOperand> &Pred1,
- const std::vector<MachineOperand> &Pred2) const {
+ bool SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
+ const SmallVectorImpl<MachineOperand> &Pred2) const {
return false;
}
return false;
}
- /// 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
+ /// isPredicable - Return true if the specified instruction can be predicated.
+ /// By default, this returns true for every instruction with a
+ /// PredicateOperand.
+ virtual bool isPredicable(MachineInstr *MI) const {
+ return MI->getDesc().isPredicable();
}
+
+ /// 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;
+ }
+
+ /// GetInstSize - Returns the size of the specified Instruction.
+ ///
+ virtual unsigned GetInstSizeInBytes(const MachineInstr *MI) const {
+ assert(0 && "Target didn't implement TargetInstrInfo::GetInstSize!");
+ return 0;
+ }
+
+ /// GetFunctionSizeInBytes - Returns the size of the specified
+ /// MachineFunction.
+ ///
+ virtual unsigned GetFunctionSizeInBytes(const MachineFunction &MF) const = 0;
+
+ /// Measure the specified inline asm to determine an approximation of its
+ /// length.
+ virtual unsigned getInlineAsmLength(const char *Str,
+ const MCAsmInfo &MAI) const;
};
/// TargetInstrInfoImpl - This is the default implementation of
TargetInstrInfoImpl(const TargetInstrDesc *desc, unsigned NumOpcodes)
: TargetInstrInfo(desc, NumOpcodes) {}
public:
- virtual MachineInstr *commuteInstruction(MachineInstr *MI) const;
- virtual bool CommuteChangesDestination(MachineInstr *MI,
- unsigned &OpIdx) const;
+ virtual MachineInstr *commuteInstruction(MachineInstr *MI,
+ bool NewMI = false) const;
+ virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1,
+ unsigned &SrcOpIdx2) const;
virtual bool PredicateInstruction(MachineInstr *MI,
- const std::vector<MachineOperand> &Pred) const;
-
+ const SmallVectorImpl<MachineOperand> &Pred) const;
+ virtual void reMaterialize(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI,
+ unsigned DestReg, unsigned SubReg,
+ const MachineInstr *Orig,
+ const TargetRegisterInfo *TRI) const;
+ virtual MachineInstr *duplicate(MachineInstr *Orig,
+ MachineFunction &MF) const;
+ virtual bool isIdentical(const MachineInstr *MI,
+ const MachineInstr *Other,
+ const MachineRegisterInfo *MRI) const;
+
+ virtual unsigned GetFunctionSizeInBytes(const MachineFunction &MF) const;
};
} // End llvm namespace