//
// 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.
//
//===----------------------------------------------------------------------===//
//
namespace llvm {
-class MachineInstr;
-class TargetMachine;
-class MachineCodeForInstruction;
class TargetRegisterClass;
class LiveVariables;
+class CalleeSavedInfo;
+class SDNode;
+class SelectionDAG;
-//---------------------------------------------------------------------------
-// Data types used to define information about a single machine instruction
-//---------------------------------------------------------------------------
-
-typedef short MachineOpCode;
-typedef unsigned InstrSchedClass;
-
-//---------------------------------------------------------------------------
-// struct TargetInstrDescriptor:
-// Predefined information about each machine instruction.
-// Designed to initialized statically.
-//
-
-const unsigned M_BRANCH_FLAG = 1 << 0;
-const unsigned M_CALL_FLAG = 1 << 1;
-const unsigned M_RET_FLAG = 1 << 2;
-const unsigned M_BARRIER_FLAG = 1 << 3;
-const unsigned M_DELAY_SLOT_FLAG = 1 << 4;
-const unsigned M_LOAD_FLAG = 1 << 5;
-const unsigned M_STORE_FLAG = 1 << 6;
-
-// M_CONVERTIBLE_TO_3_ADDR - This is a 2-address instruction which can be
-// changed into a 3-address instruction if the first two operands cannot be
-// assigned to the same register. The target must implement the
-// TargetInstrInfo::convertToThreeAddress method for this instruction.
-const unsigned M_CONVERTIBLE_TO_3_ADDR = 1 << 7;
-
-// This M_COMMUTABLE - is a 2- or 3-address instruction (of the form X = op Y,
-// Z), which produces the same result if Y and Z are exchanged.
-const unsigned M_COMMUTABLE = 1 << 8;
-
-// M_TERMINATOR_FLAG - Is this instruction part of the terminator for a basic
-// block? Typically this is things like return and branch instructions.
-// Various passes use this to insert code into the bottom of a basic block, but
-// before control flow occurs.
-const unsigned M_TERMINATOR_FLAG = 1 << 9;
-
-// M_USES_CUSTOM_DAG_SCHED_INSERTION - Set if this instruction requires custom
-// insertion support when the DAG scheduler is inserting it into a machine basic
-// block.
-const unsigned M_USES_CUSTOM_DAG_SCHED_INSERTION = 1 << 10;
-
-// M_VARIABLE_OPS - Set if this instruction can have a variable number of extra
-// operands in addition to the minimum number operands specified.
-const unsigned M_VARIABLE_OPS = 1 << 11;
-
-// M_PREDICABLE - Set if this instruction has a predicate operand that
-// controls execution. It may be set to 'always'.
-const unsigned M_PREDICABLE = 1 << 12;
-
-// M_REMATERIALIZIBLE - Set if this instruction can be trivally re-materialized
-// at any time, e.g. constant generation, load from constant pool.
-const unsigned M_REMATERIALIZIBLE = 1 << 13;
-
-// M_NOT_DUPLICABLE - Set if this instruction cannot be safely duplicated.
-// (e.g. instructions with unique labels attached).
-const unsigned M_NOT_DUPLICABLE = 1 << 14;
-
-// M_HAS_OPTIONAL_DEF - Set if this instruction has an optional definition, e.g.
-// ARM instructions which can set condition code if 's' bit is set.
-const unsigned M_HAS_OPTIONAL_DEF = 1 << 15;
-
-// Machine operand flags
-// M_LOOK_UP_PTR_REG_CLASS - Set if this operand is a pointer value and it
-// requires a callback to look up its register class.
-const unsigned M_LOOK_UP_PTR_REG_CLASS = 1 << 0;
-
-/// M_PREDICATE_OPERAND - Set if this is one of the operands that made up of the
-/// predicate operand that controls an M_PREDICATED instruction.
-const unsigned M_PREDICATE_OPERAND = 1 << 1;
-
-/// M_OPTIONAL_DEF_OPERAND - Set if this operand is a optional def.
-///
-const unsigned M_OPTIONAL_DEF_OPERAND = 1 << 2;
+template<class T> class SmallVectorImpl;
+//===----------------------------------------------------------------------===//
+// Machine Operand Flags and Description
+//===----------------------------------------------------------------------===//
+
namespace TOI {
// Operand constraints: only "tied_to" for now.
enum OperandConstraint {
TIED_TO = 0 // Must be allocated the same register as.
};
+
+ /// OperandFlags - These are flags set on operands, but should be considered
+ /// private, all access should go through the TargetOperandInfo accessors.
+ /// See the accessors for a description of what these are.
+ enum OperandFlags {
+ LookupPtrRegClass = 0,
+ Predicate,
+ OptionalDef
+ };
}
/// TargetOperandInfo - This holds information about one operand of a machine
/// bits are used to specify the value of constraints (4 bits each).
unsigned int Constraints;
/// Currently no other information.
+
+ /// isLookupPtrRegClass - Set if this operand is a pointer value and it
+ /// requires a callback to look up its register class.
+ bool isLookupPtrRegClass() const { return Flags&(1 <<TOI::LookupPtrRegClass);}
+
+ /// isPredicate - Set if this is one of the operands that made up of
+ /// the predicate operand that controls an isPredicable() instruction.
+ bool isPredicate() const { return Flags & (1 << TOI::Predicate); }
+
+ /// isOptionalDef - Set if this operand is a optional def.
+ ///
+ bool isOptionalDef() const { return Flags & (1 << TOI::OptionalDef); }
};
+
+//===----------------------------------------------------------------------===//
+// Machine Instruction Flags and Description
+//===----------------------------------------------------------------------===//
+
+/// TargetInstrDesc flags - These should be considered private to the
+/// implementation of the TargetInstrDesc class. Clients should use the
+/// predicate methods on TargetInstrDesc, not use these directly. These
+/// all correspond to bitfields in the TargetInstrDesc::Flags field.
+namespace TID {
+ enum {
+ Variadic = 0,
+ HasOptionalDef,
+ Return,
+ Call,
+ ImplicitDef,
+ Barrier,
+ Terminator,
+ Branch,
+ IndirectBranch,
+ Predicable,
+ NotDuplicable,
+ DelaySlot,
+ SimpleLoad,
+ MayStore,
+ NeverHasSideEffects,
+ MayHaveSideEffects,
+ Commutable,
+ ConvertibleTo3Addr,
+ UsesCustomDAGSchedInserter,
+ Rematerializable
+ };
+}
-class TargetInstrDescriptor {
+/// TargetInstrDesc - Describe properties that are true of each
+/// instruction in the target description file. This captures information about
+/// side effects, register use and many other things. There is one instance of
+/// this struct for each target instruction class, and the MachineInstr class
+/// points to this struct directly to describe itself.
+class TargetInstrDesc {
public:
- MachineOpCode Opcode; // The opcode.
- unsigned short numOperands; // Num of args (may be more if variable_ops).
- unsigned short numDefs; // Num of args that are definitions.
- const char * Name; // Assembly language mnemonic for the opcode.
- InstrSchedClass schedClass; // enum identifying instr sched class
+ unsigned short Opcode; // The opcode number.
+ unsigned short NumOperands; // Num of args (may be more if variable_ops)
+ unsigned short NumDefs; // Num of args that are definitions.
+ unsigned short SchedClass; // enum identifying instr sched class
+ const char * Name; // Name of the instruction record in td file.
unsigned Flags; // flags identifying machine instr class
unsigned TSFlags; // Target Specific Flag values
const unsigned *ImplicitUses; // Registers implicitly read by this instr
const unsigned *ImplicitDefs; // Registers implicitly defined by this instr
- const TargetOperandInfo *OpInfo; // 'numOperands' entries about operands.
+ const TargetOperandInfo *OpInfo; // 'NumOperands' entries about operands.
/// getOperandConstraint - Returns the value of the specific constraint if
/// it is set. Returns -1 if it is not set.
int getOperandConstraint(unsigned OpNum,
TOI::OperandConstraint Constraint) const {
- assert((OpNum < numOperands || (Flags & M_VARIABLE_OPS)) &&
+ assert((OpNum < NumOperands || isVariadic()) &&
"Invalid operand # of TargetInstrInfo");
- if (OpNum < numOperands &&
+ if (OpNum < NumOperands &&
(OpInfo[OpNum].Constraints & (1 << Constraint))) {
unsigned Pos = 16 + Constraint * 4;
return (int)(OpInfo[OpNum].Constraints >> Pos) & 0xf;
/// findTiedToSrcOperand - Returns the operand that is tied to the specified
/// dest operand. Returns -1 if there isn't one.
int findTiedToSrcOperand(unsigned OpNum) const;
-};
-
-
-//---------------------------------------------------------------------------
-///
-/// TargetInstrInfo - Interface to description of machine instructions
-///
-class TargetInstrInfo {
- const TargetInstrDescriptor* desc; // raw array to allow static init'n
- unsigned NumOpcodes; // number of entries in the desc array
- unsigned numRealOpCodes; // number of non-dummy op codes
-
- TargetInstrInfo(const TargetInstrInfo &); // DO NOT IMPLEMENT
- void operator=(const TargetInstrInfo &); // DO NOT IMPLEMENT
-public:
- TargetInstrInfo(const TargetInstrDescriptor *desc, unsigned NumOpcodes);
- virtual ~TargetInstrInfo();
-
- // Invariant opcodes: All instruction sets have these as their low opcodes.
- enum {
- PHI = 0,
- INLINEASM = 1,
- LABEL = 2,
- EXTRACT_SUBREG = 3,
- INSERT_SUBREG = 4
- };
-
- unsigned getNumOpcodes() const { return NumOpcodes; }
-
- /// get - Return the machine instruction descriptor that corresponds to the
- /// specified instruction opcode.
- ///
- const TargetInstrDescriptor& get(MachineOpCode Opcode) const {
- assert((unsigned)Opcode < NumOpcodes);
- return desc[Opcode];
+
+ /// getOpcode - Return the opcode number for this descriptor.
+ unsigned getOpcode() const {
+ return Opcode;
}
-
- const char *getName(MachineOpCode Opcode) const {
- return get(Opcode).Name;
+
+ /// getName - Return the name of the record in the .td file for this
+ /// instruction, for example "ADD8ri".
+ const char *getName() const {
+ return Name;
}
-
- int getNumOperands(MachineOpCode Opcode) const {
- return get(Opcode).numOperands;
+
+ /// getNumOperands - Return the number of declared MachineOperands for this
+ /// MachineInstruction. Note that variadic (isVariadic() returns true)
+ /// instructions may have additional operands at the end of the list, and note
+ /// that the machine instruction may include implicit register def/uses as
+ /// well.
+ unsigned getNumOperands() const {
+ return NumOperands;
}
-
- InstrSchedClass getSchedClass(MachineOpCode Opcode) const {
- return get(Opcode).schedClass;
+
+ /// getNumDefs - Return the number of MachineOperands that are register
+ /// definitions. Register definitions always occur at the start of the
+ /// machine operand list. This is the number of "outs" in the .td file.
+ unsigned getNumDefs() const {
+ return NumDefs;
}
-
- const unsigned *getImplicitUses(MachineOpCode Opcode) const {
- return get(Opcode).ImplicitUses;
+
+ /// isVariadic - Return true if this instruction can have a variable number of
+ /// operands. In this case, the variable operands will be after the normal
+ /// operands but before the implicit definitions and uses (if any are
+ /// present).
+ bool isVariadic() const {
+ return Flags & (1 << TID::Variadic);
}
-
- const unsigned *getImplicitDefs(MachineOpCode Opcode) const {
- return get(Opcode).ImplicitDefs;
+
+ /// hasOptionalDef - Set if this instruction has an optional definition, e.g.
+ /// ARM instructions which can set condition code if 's' bit is set.
+ bool hasOptionalDef() const {
+ return Flags & (1 << TID::HasOptionalDef);
}
-
-
- //
- // Query instruction class flags according to the machine-independent
- // flags listed above.
- //
- bool isReturn(MachineOpCode Opcode) const {
- return get(Opcode).Flags & M_RET_FLAG;
+
+ /// getImplicitUses - Return a list of machine operands that are potentially
+ /// read by any instance of this machine instruction. For example, on X86,
+ /// the "adc" instruction adds two register operands and adds the carry bit in
+ /// from the flags register. In this case, the instruction is marked as
+ /// implicitly reading the flags. Likewise, the variable shift instruction on
+ /// X86 is marked as implicitly reading the 'CL' register, which it always
+ /// does.
+ ///
+ /// This method returns null if the instruction has no implicit uses.
+ const unsigned *getImplicitUses() const {
+ return ImplicitUses;
+ }
+
+ /// getImplicitDefs - Return a list of machine operands that are potentially
+ /// written by any instance of this machine instruction. For example, on X86,
+ /// many instructions implicitly set the flags register. In this case, they
+ /// are marked as setting the FLAGS. Likewise, many instructions always
+ /// deposit their result in a physical register. For example, the X86 divide
+ /// instruction always deposits the quotient and remainder in the EAX/EDX
+ /// registers. For that instruction, this will return a list containing the
+ /// EAX/EDX/EFLAGS registers.
+ ///
+ /// This method returns null if the instruction has no implicit uses.
+ const unsigned *getImplicitDefs() const {
+ return ImplicitDefs;
}
- bool isCommutableInstr(MachineOpCode Opcode) const {
- return get(Opcode).Flags & M_COMMUTABLE;
+ /// getSchedClass - Return the scheduling class for this instruction. The
+ /// scheduling class is an index into the InstrItineraryData table. This
+ /// returns zero if there is no known scheduling information for the
+ /// instruction.
+ ///
+ unsigned getSchedClass() const {
+ return SchedClass;
}
- bool isTerminatorInstr(MachineOpCode Opcode) const {
- return get(Opcode).Flags & M_TERMINATOR_FLAG;
+
+ bool isReturn() const {
+ return Flags & (1 << TID::Return);
+ }
+
+ bool isCall() const {
+ return Flags & (1 << TID::Call);
}
- bool isBranch(MachineOpCode Opcode) const {
- return get(Opcode).Flags & M_BRANCH_FLAG;
+ /// isImplicitDef - Return true if this is an "IMPLICIT_DEF" instruction,
+ /// which defines a register to an unspecified value. These basically
+ /// correspond to x = undef.
+ bool isImplicitDef() const {
+ return Flags & (1 << TID::ImplicitDef);
}
/// isBarrier - Returns true if the specified instruction stops control flow
/// from executing the instruction immediately following it. Examples include
/// unconditional branches and return instructions.
- bool isBarrier(MachineOpCode Opcode) const {
- return get(Opcode).Flags & M_BARRIER_FLAG;
+ bool isBarrier() const {
+ return Flags & (1 << TID::Barrier);
+ }
+
+ /// isTerminator - Returns true if this instruction part of the terminator for
+ /// a basic block. Typically this is things like return and branch
+ /// instructions.
+ ///
+ /// Various passes use this to insert code into the bottom of a basic block,
+ /// but before control flow occurs.
+ bool isTerminator() const {
+ return Flags & (1 << TID::Terminator);
}
- bool isCall(MachineOpCode Opcode) const {
- return get(Opcode).Flags & M_CALL_FLAG;
+ /// isBranch - Returns true if this is a conditional, unconditional, or
+ /// indirect branch. Predicates below can be used to discriminate between
+ /// these cases, and the TargetInstrInfo::AnalyzeBranch method can be used to
+ /// get more information.
+ bool isBranch() const {
+ return Flags & (1 << TID::Branch);
}
- bool isLoad(MachineOpCode Opcode) const {
- return get(Opcode).Flags & M_LOAD_FLAG;
+
+ /// isIndirectBranch - Return true if this is an indirect branch, such as a
+ /// branch through a register.
+ bool isIndirectBranch() const {
+ return Flags & (1 << TID::IndirectBranch);
+ }
+
+ /// isConditionalBranch - Return true if this is a branch which may fall
+ /// through to the next instruction or may transfer control flow to some other
+ /// block. The TargetInstrInfo::AnalyzeBranch method can be used to get more
+ /// information about this branch.
+ bool isConditionalBranch() const {
+ return isBranch() & !isBarrier() & !isIndirectBranch();
}
- bool isStore(MachineOpCode Opcode) const {
- return get(Opcode).Flags & M_STORE_FLAG;
+
+ /// isUnconditionalBranch - Return true if this is a branch which always
+ /// transfers control flow to some other block. The
+ /// TargetInstrInfo::AnalyzeBranch method can be used to get more information
+ /// about this branch.
+ bool isUnconditionalBranch() const {
+ return isBranch() & isBarrier() & !isIndirectBranch();
+ }
+
+ // isPredicable - Return true if this instruction has a predicate operand that
+ // controls execution. It may be set to 'always', or may be set to other
+ /// values. There are various methods in TargetInstrInfo that can be used to
+ /// control and modify the predicate in this instruction.
+ bool isPredicable() const {
+ return Flags & (1 << TID::Predicable);
+ }
+
+ /// isNotDuplicable - Return true if this instruction cannot be safely
+ /// duplicated. For example, if the instruction has a unique labels attached
+ /// to it, duplicating it would cause multiple definition errors.
+ bool isNotDuplicable() const {
+ return Flags & (1 << TID::NotDuplicable);
}
/// hasDelaySlot - Returns true if the specified instruction has a delay slot
/// which must be filled by the code generator.
- bool hasDelaySlot(MachineOpCode Opcode) const {
- return get(Opcode).Flags & M_DELAY_SLOT_FLAG;
+ bool hasDelaySlot() const {
+ return Flags & (1 << TID::DelaySlot);
+ }
+
+ /// isSimpleLoad - Return true for instructions that are simple loads from
+ /// memory. This should only be set on instructions that load a value from
+ /// memory and return it in their only virtual register definition.
+ /// Instructions that return a value loaded from memory and then modified in
+ /// some way should not return true for this.
+ bool isSimpleLoad() const {
+ return Flags & (1 << TID::SimpleLoad);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Side Effect Analysis
+ //===--------------------------------------------------------------------===//
+
+ /// mayStore - 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 mayStore() const {
+ return Flags & (1 << TID::MayStore);
+ }
+
+ // TODO: mayLoad.
+
+ /// hasNoSideEffects - Return true if all instances of this instruction are
+ /// guaranteed to have no side effects other than:
+ /// 1. The register operands that are def/used by the MachineInstr.
+ /// 2. Registers that are implicitly def/used by the MachineInstr.
+ /// 3. Memory Accesses captured by mayLoad() or mayStore().
+ ///
+ /// Examples of other side effects would be calling a function, modifying
+ /// 'invisible' machine state like a control register, etc.
+ ///
+ /// If some instances of this instruction are side-effect free but others are
+ /// not, the hasConditionalSideEffects() property should return true, not this
+ /// one.
+ ///
+ /// Note that you should not call this method directly, instead, call the
+ /// TargetInstrInfo::hasUnmodelledSideEffects method, which handles analysis
+ /// of the machine instruction.
+ bool hasNoSideEffects() const {
+ return Flags & (1 << TID::NeverHasSideEffects);
+ }
+
+ /// hasConditionalSideEffects - Return true if some instances of this
+ /// instruction are guaranteed to have no side effects other than those listed
+ /// for hasNoSideEffects(). To determine whether a specific machineinstr has
+ /// side effects, the TargetInstrInfo::isReallySideEffectFree virtual method
+ /// is invoked to decide.
+ ///
+ /// Note that you should not call this method directly, instead, call the
+ /// TargetInstrInfo::hasUnmodelledSideEffects method, which handles analysis
+ /// of the machine instruction.
+ bool hasConditionalSideEffects() const {
+ return Flags & (1 << TID::MayHaveSideEffects);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Flags that indicate whether an instruction can be modified by a method.
+ //===--------------------------------------------------------------------===//
+
+ /// isCommutable - Return true if this may be a 2- or 3-address
+ /// instruction (of the form "X = op Y, Z, ..."), which produces the same
+ /// result if Y and Z are exchanged. If this flag is set, then the
+ /// TargetInstrInfo::commuteInstruction method may be used to hack on the
+ /// instruction.
+ ///
+ /// Note that this flag may be set on instructions that are only commutable
+ /// sometimes. In these cases, the call to commuteInstruction will fail.
+ /// Also note that some instructions require non-trivial modification to
+ /// commute them.
+ bool isCommutable() const {
+ return Flags & (1 << TID::Commutable);
+ }
+
+ /// isConvertibleTo3Addr - Return true if this is a 2-address instruction
+ /// which can be changed into a 3-address instruction if needed. Doing this
+ /// transformation can be profitable in the register allocator, because it
+ /// means that the instruction can use a 2-address form if possible, but
+ /// degrade into a less efficient form if the source and dest register cannot
+ /// be assigned to the same register. For example, this allows the x86
+ /// backend to turn a "shl reg, 3" instruction into an LEA instruction, which
+ /// is the same speed as the shift but has bigger code size.
+ ///
+ /// If this returns true, then the target must implement the
+ /// TargetInstrInfo::convertToThreeAddress method for this instruction, which
+ /// is allowed to fail if the transformation isn't valid for this specific
+ /// instruction (e.g. shl reg, 4 on x86).
+ ///
+ bool isConvertibleTo3Addr() const {
+ return Flags & (1 << TID::ConvertibleTo3Addr);
}
/// usesCustomDAGSchedInsertionHook - Return true if this instruction requires
/// custom insertion support when the DAG scheduler is inserting it into a
- /// machine basic block.
- bool usesCustomDAGSchedInsertionHook(MachineOpCode Opcode) const {
- return get(Opcode).Flags & M_USES_CUSTOM_DAG_SCHED_INSERTION;
+ /// machine basic block. If this is true for the instruction, it basically
+ /// means that it is a pseudo instruction used at SelectionDAG time that is
+ /// expanded out into magic code by the target when MachineInstrs are formed.
+ ///
+ /// If this is true, the TargetLoweringInfo::InsertAtEndOfBasicBlock method
+ /// is used to insert this into the MachineBasicBlock.
+ bool usesCustomDAGSchedInsertionHook() const {
+ return Flags & (1 << TID::UsesCustomDAGSchedInserter);
}
-
- bool hasVariableOperands(MachineOpCode Opcode) const {
- return get(Opcode).Flags & M_VARIABLE_OPS;
+
+ /// isRematerializable - Returns true if this instruction is a candidate for
+ /// remat. This flag is deprecated, please don't use it anymore. If this
+ /// flag is set, the isReallyTriviallyReMaterializable() method is called to
+ /// verify the instruction is really rematable.
+ bool isRematerializable() const {
+ return Flags & (1 << TID::Rematerializable);
}
+};
- bool isPredicable(MachineOpCode Opcode) const {
- return get(Opcode).Flags & M_PREDICABLE;
- }
- bool isNotDuplicable(MachineOpCode Opcode) const {
- return get(Opcode).Flags & M_NOT_DUPLICABLE;
- }
+//---------------------------------------------------------------------------
+///
+/// TargetInstrInfo - Interface to description of machine instructions
+///
+class TargetInstrInfo {
+ const TargetInstrDesc *Descriptors; // Raw array to allow static init'n
+ unsigned NumOpcodes; // Number of entries in the desc array
- bool hasOptionalDef(MachineOpCode Opcode) const {
- return get(Opcode).Flags & M_HAS_OPTIONAL_DEF;
+ TargetInstrInfo(const TargetInstrInfo &); // DO NOT IMPLEMENT
+ void operator=(const TargetInstrInfo &); // DO NOT IMPLEMENT
+public:
+ 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,
+ EXTRACT_SUBREG = 3,
+ INSERT_SUBREG = 4
+ };
+
+ unsigned getNumOpcodes() const { return NumOpcodes; }
+
+ /// get - Return the machine instruction descriptor that corresponds to the
+ /// specified instruction opcode.
+ ///
+ const TargetInstrDesc &get(unsigned Opcode) const {
+ assert(Opcode < NumOpcodes && "Invalid opcode!");
+ return Descriptors[Opcode];
}
/// 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->getInstrDescriptor()->Flags & M_REMATERIALIZIBLE) &&
+ 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 true;
}
-public:
- /// getOperandConstraint - Returns the value of the specific constraint if
- /// it is set. Returns -1 if it is not set.
- int getOperandConstraint(MachineOpCode Opcode, unsigned OpNum,
- TOI::OperandConstraint Constraint) const {
- return get(Opcode).getOperandConstraint(OpNum, Constraint);
+ /// 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.
virtual bool isMoveInstr(const MachineInstr& MI,
/// 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;
+ }
+
+ /// foldMemoryOperand - Attempt to fold a load or store of the specified stack
+ /// slot into the specified machine instruction for the specified operand(s).
+ /// If this is possible, a new instruction is returned with the specified
+ /// 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,
+ 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,
+ SmallVectorImpl<unsigned> &Ops,
+ MachineInstr* LoadMI) const {
+ return 0;
+ }
+
+ /// canFoldMemoryOperand - Returns true if the specified load / store is
+ /// folding is possible.
+ virtual
+ bool canFoldMemoryOperand(MachineInstr *MI,
+ SmallVectorImpl<unsigned> &Ops) const{
+ return false;
+ }
+
+ /// unfoldMemoryOperand - Separate a single instruction which folded a load or
+ /// a store or a load and a store into two or more instruction. If this is
+ /// 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{
+ return false;
+ }
+
+ virtual bool unfoldMemoryOperand(SelectionDAG &DAG, SDNode *N,
+ SmallVectorImpl<SDNode*> &NewNodes) 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.
+ virtual unsigned getOpcodeAfterMemoryUnfold(unsigned Opc,
+ bool UnfoldLoad, bool UnfoldStore) 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
/// 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 TargetInstrDesc *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