//
// The LLVM Compiler Infrastructure
//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
class TargetMachine;
class TargetRegisterClass;
class LiveVariables;
+class CalleeSavedInfo;
+
+template<class T> class SmallVectorImpl;
//---------------------------------------------------------------------------
// Data types used to define information about a single machine instruction
const unsigned M_BARRIER_FLAG = 1 << 3;
const unsigned M_DELAY_SLOT_FLAG = 1 << 4;
const unsigned M_LOAD_FLAG = 1 << 5;
+
+/// M_STORE_FLAG - This flag is set to any instruction that could possibly
+/// modify memory. Instructions with this flag set are not necessarily simple
+/// store instructions, they may store a modified value based on their operands,
+/// or may not actually modify anything, for example.
const unsigned M_STORE_FLAG = 1 << 6;
+
const unsigned M_INDIRECT_FLAG = 1 << 7;
const unsigned M_IMPLICIT_DEF_FLAG = 1 << 8;
// ARM instructions which can set condition code if 's' bit is set.
const unsigned M_HAS_OPTIONAL_DEF = 1 << 17;
-// M_MAY_HAVE_SIDE_EFFECTS - Set if this instruction *might* have side effects,
-// e.g. load instructions. Note: This and M_NEVER_HAS_SIDE_EFFECTS are mutually
-// exclusive. You can't set both! If neither flag is set, then the instruction
-// *always* has side effects.
-const unsigned M_MAY_HAVE_SIDE_EFFECTS = 1 << 18;
-
-// M_NEVER_HAS_SIDE_EFFECTS - Set if this instruction *never* has side effects,
-// e.g., xor on X86. Note: This and M_MAY_HAVE_SIDE_EFFECTS are mutually
-// exclusive. You can't set both! If neither flag is set, then the instruction
-// *always* has side effects.
-const unsigned M_NEVER_HAS_SIDE_EFFECTS = 1 << 19;
+// M_NEVER_HAS_SIDE_EFFECTS - Set if this instruction has no side effects that
+// are not captured by any operands of the instruction or other flags, and when
+// *all* instances of the instruction of that opcode have no side effects.
+//
+// Note: This and M_MAY_HAVE_SIDE_EFFECTS are mutually exclusive. You can't set
+// both! If neither flag is set, then the instruction *always* has side effects.
+const unsigned M_NEVER_HAS_SIDE_EFFECTS = 1 << 18;
+
+// M_MAY_HAVE_SIDE_EFFECTS - Set if some instances of this instruction can have
+// side effects. The virtual method "isReallySideEffectFree" is called to
+// determine this. Load instructions are an example of where this is useful. In
+// general, loads always have side effects. However, loads from constant pools
+// don't. We let the specific back end make this determination.
+//
+// Note: This and M_NEVER_HAS_SIDE_EFFECTS are mutually exclusive. You can't set
+// both! If neither flag is set, then the instruction *always* has side effects.
+const unsigned M_MAY_HAVE_SIDE_EFFECTS = 1 << 19;
// Machine operand flags
// M_LOOK_UP_PTR_REG_CLASS - Set if this operand is a pointer value and it
bool isLoad(MachineOpCode Opcode) const {
return get(Opcode).Flags & M_LOAD_FLAG;
}
+
+ /// isStore - Return true if this instruction could possibly modify memory.
+ /// Instructions with this flag set are not necessarily simple store
+ /// instructions, they may store a modified value based on their operands, or
+ /// may not actually modify anything, for example.
bool isStore(MachineOpCode Opcode) const {
return get(Opcode).Flags & M_STORE_FLAG;
}
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 TargetInstrDescriptor *TID = MI->getInstrDescriptor();
+ if (TID->Flags & M_NEVER_HAS_SIDE_EFFECTS) return false;
+ if (!(TID->Flags & M_MAY_HAVE_SIDE_EFFECTS)) 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 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:
/// getOperandConstraint - Returns the value of the specific constraint if
/// it is set. Returns -1 if it is not set.
/// return a new machine instruction. If an instruction cannot commute, it
/// can also return null.
///
- virtual MachineInstr *commuteInstruction(MachineInstr *MI) const;
+ virtual MachineInstr *commuteInstruction(MachineInstr *MI) 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
return 0;
}
+ /// copyRegToReg - Add a copy between a pair of registers
+ virtual void 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!");
+ }
+
+ virtual void storeRegToStackSlot(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI,
+ unsigned SrcReg, bool isKill, int FrameIndex,
+ const TargetRegisterClass *RC) const {
+ 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!");
+ }
+
+ 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
+ /// so by issuing a series of store instructions via
+ /// storeRegToStackSlot(). Returns false otherwise.
+ virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI,
+ const std::vector<CalleeSavedInfo> &CSI) const {
+ return false;
+ }
+
+ /// restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee
+ /// saved registers and returns true if it isn't possible / profitable to do
+ /// so by issuing a series of load instructions via loadRegToStackSlot().
+ /// Returns false otherwise.
+ virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI,
+ const std::vector<CalleeSavedInfo> &CSI) const {
+ return false;
+ }
+
/// 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
/// instruction. It returns true if the operation was successful.
virtual
bool PredicateInstruction(MachineInstr *MI,
- const std::vector<MachineOperand> &Pred) const;
+ const std::vector<MachineOperand> &Pred) const = 0;
/// SubsumesPredicate - Returns true if the first specified predicate
/// subsumes the second, e.g. GE subsumes GT.
}
};
+/// TargetInstrInfoImpl - This is the default implementation of
+/// TargetInstrInfo, which just provides a couple of default implementations
+/// for various methods. This separated out because it is implemented in
+/// libcodegen, not in libtarget.
+class TargetInstrInfoImpl : public TargetInstrInfo {
+protected:
+ TargetInstrInfoImpl(const TargetInstrDescriptor *desc, unsigned NumOpcodes)
+ : TargetInstrInfo(desc, NumOpcodes) {}
+public:
+ virtual MachineInstr *commuteInstruction(MachineInstr *MI) const;
+ virtual bool PredicateInstruction(MachineInstr *MI,
+ const std::vector<MachineOperand> &Pred) const;
+
+};
+
} // End llvm namespace
#endif