PHI = 0,
INLINEASM = 1,
LABEL = 2,
- EXTRACT_SUBREG = 3,
- INSERT_SUBREG = 4
+ DECLARE = 3,
+ EXTRACT_SUBREG = 4,
+ INSERT_SUBREG = 5,
+ IMPLICIT_DEF = 6,
+ SUBREG_TO_REG = 7
};
unsigned getNumOpcodes() const { return NumOpcodes; }
/// 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 {
+ bool isTriviallyReMaterializable(const MachineInstr *MI) const {
return MI->getDesc().isRematerializable() &&
isReallyTriviallyReMaterializable(MI);
}
- /// hasUnmodelledSideEffects - Returns true if the instruction has side
- /// effects that are not captured by any operands of the instruction or other
- /// flags.
- bool hasUnmodelledSideEffects(MachineInstr *MI) const {
- const TargetInstrDesc &TID = MI->getDesc();
- if (TID.hasNoSideEffects()) return false;
- if (!TID.hasConditionalSideEffects()) return true;
- return !isReallySideEffectFree(MI); // May have side effects
- }
protected:
/// isReallyTriviallyReMaterializable - For instructions with opcodes for
/// which the M_REMATERIALIZABLE flag is set, this function tests whether the
/// 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 {
+ virtual bool isReallyTriviallyReMaterializable(const MachineInstr *MI) const {
return true;
}
- /// isReallySideEffectFree - If the M_MAY_HAVE_SIDE_EFFECTS flag is set, this
- /// method is called to determine if the specific instance of this
- /// instruction has side effects. This is useful in cases of instructions,
- /// like loads, which generally always have side effects. A load from a
- /// constant pool doesn't have side effects, though. So we need to
- /// differentiate it from the general case.
- virtual bool isReallySideEffectFree(MachineInstr *MI) const {
- return false;
- }
public:
/// Return true if the instruction is a register to register move
/// and leave the source and dest operands in the passed parameters.
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,
+ const MachineInstr *Orig) const = 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;
+ }
+
/// 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
/// return a new machine instruction. If an instruction cannot commute, it
/// can also return null.
///
- virtual MachineInstr *commuteInstruction(MachineInstr *MI) const = 0;
+ /// If NewMI is true, then a new machine instruction must be created.
+ ///
+ 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;
/// 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
/// 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(MachineInstr* MI,
+ virtual MachineInstr* foldMemoryOperand(MachineFunction &MF,
+ MachineInstr* MI,
SmallVectorImpl<unsigned> &Ops,
int FrameIndex) const {
return 0;
/// 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(MachineInstr* MI,
+ virtual MachineInstr* foldMemoryOperand(MachineFunction &MF,
+ MachineInstr* MI,
SmallVectorImpl<unsigned> &Ops,
MachineInstr* LoadMI) const {
return 0;
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 {
+ 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;
+
};
/// TargetInstrInfoImpl - This is the default implementation of
TargetInstrInfoImpl(const TargetInstrDesc *desc, unsigned NumOpcodes)
: TargetInstrInfo(desc, NumOpcodes) {}
public:
- virtual MachineInstr *commuteInstruction(MachineInstr *MI) const;
+ virtual MachineInstr *commuteInstruction(MachineInstr *MI,
+ bool NewMI = false) const;
+ virtual bool CommuteChangesDestination(MachineInstr *MI,
+ unsigned &OpIdx) const;
virtual bool PredicateInstruction(MachineInstr *MI,
const std::vector<MachineOperand> &Pred) const;
-
+ virtual void reMaterialize(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI,
+ unsigned DestReg,
+ const MachineInstr *Orig) const;
+ virtual unsigned GetFunctionSizeInBytes(const MachineFunction &MF) const;
};
} // End llvm namespace