const unsigned M_DELAY_SLOT_FLAG = 1 << 4;
const unsigned M_LOAD_FLAG = 1 << 5;
const unsigned M_STORE_FLAG = 1 << 6;
+const unsigned M_INDIRECT_FLAG = 1 << 7;
// 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
// 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
/// 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;
+
namespace TOI {
// Operand constraints: only "tied_to" for now.
enum OperandConstraint {
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 Flags; // flags identifying machine instr class
enum {
PHI = 0,
INLINEASM = 1,
- LABEL = 2
+ LABEL = 2,
+ EXTRACT_SUBREG = 3,
+ INSERT_SUBREG = 4
};
unsigned getNumOpcodes() const { return NumOpcodes; }
return get(Opcode).numOperands;
}
+ int getNumDefs(MachineOpCode Opcode) const {
+ return get(Opcode).numDefs;
+ }
+
InstrSchedClass getSchedClass(MachineOpCode Opcode) const {
return get(Opcode).schedClass;
}
return get(Opcode).Flags & M_RET_FLAG;
}
- bool isPredicable(MachineOpCode Opcode) const {
- return get(Opcode).Flags & M_PREDICABLE;
- }
- bool isReMaterializable(MachineOpCode Opcode) const {
- return get(Opcode).Flags & M_REMATERIALIZIBLE;
- }
bool isCommutableInstr(MachineOpCode Opcode) const {
return get(Opcode).Flags & M_COMMUTABLE;
}
- bool isTerminatorInstr(unsigned Opcode) const {
+ bool isTerminatorInstr(MachineOpCode Opcode) const {
return get(Opcode).Flags & M_TERMINATOR_FLAG;
}
return get(Opcode).Flags & M_BRANCH_FLAG;
}
+ bool isIndirectBranch(MachineOpCode Opcode) const {
+ return get(Opcode).Flags & M_INDIRECT_FLAG;
+ }
+
/// isBarrier - Returns true if the specified instruction stops control flow
/// from executing the instruction immediately following it. Examples include
/// unconditional branches and return instructions.
/// hasDelaySlot - Returns true if the specified instruction has a delay slot
/// which must be filled by the code generator.
- bool hasDelaySlot(unsigned Opcode) const {
+ bool hasDelaySlot(MachineOpCode Opcode) const {
return get(Opcode).Flags & M_DELAY_SLOT_FLAG;
}
/// usesCustomDAGSchedInsertionHook - Return true if this instruction requires
/// custom insertion support when the DAG scheduler is inserting it into a
/// machine basic block.
- bool usesCustomDAGSchedInsertionHook(unsigned Opcode) const {
+ bool usesCustomDAGSchedInsertionHook(MachineOpCode Opcode) const {
return get(Opcode).Flags & M_USES_CUSTOM_DAG_SCHED_INSERTION;
}
return get(Opcode).Flags & M_VARIABLE_OPS;
}
+ bool isPredicable(MachineOpCode Opcode) const {
+ return get(Opcode).Flags & M_PREDICABLE;
+ }
+
+ bool isNotDuplicable(MachineOpCode Opcode) const {
+ return get(Opcode).Flags & M_NOT_DUPLICABLE;
+ }
+
+ bool hasOptionalDef(MachineOpCode Opcode) const {
+ return get(Opcode).Flags & M_HAS_OPTIONAL_DEF;
+ }
+
+ /// hasNoSideEffects - Return true if the instruction is trivially
+ /// rematerializable, meaning it has no side effects and requires no operands
+ /// that aren't always available.
+ bool hasNoSideEffects(MachineInstr *MI) const {
+ return (MI->getInstrDescriptor()->Flags & M_REMATERIALIZIBLE) &&
+ isTriviallyReMaterializable(MI);
+ }
+
+protected:
+ /// isTriviallyReMaterializable - 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 isTriviallyReMaterializable(MachineInstr *MI) const {
+ 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,
/// 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 moretrue
+ /// may be able to convert a two-address instruction into one or more true
/// three-address instructions on demand. This allows the X86 target (for
/// example) to convert ADD and SHL instructions into LEA instructions if they
/// would require register copies due to two-addressness.
}
/// RemoveBranch - Remove the branching code at the end of the specific MBB.
- /// this is only invoked in cases where AnalyzeBranch returns success.
- virtual void RemoveBranch(MachineBasicBlock &MBB) const {
+ /// 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.
- virtual void InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
+ /// null, Cond is empty) needs to be inserted. It returns the number of
+ /// instructions inserted.
+ virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
MachineBasicBlock *FBB,
const std::vector<MachineOperand> &Cond) const {
assert(0 && "Target didn't implement TargetInstrInfo::InsertBranch!");
+ return 0;
}
/// BlockHasNoFallThrough - Return true if the specified block does not
abort();
}
+ /// isPredicated - Returns true if the instruction is already predicated.
+ ///
+ virtual bool isPredicated(const MachineInstr *MI) const {
+ return false;
+ }
+
+ /// isUnpredicatedTerminator - Returns true if the instruction is a
+ /// terminator instruction that has not been predicated.
+ virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const;
+
/// PredicateInstruction - Convert the instruction into a predicated
/// instruction. It returns true if the operation was successful.
- virtual bool PredicateInstruction(MachineInstr *MI,
- std::vector<MachineOperand> &Cond) const;
+ virtual
+ bool PredicateInstruction(MachineInstr *MI,
+ const std::vector<MachineOperand> &Pred) const;
+
+ /// 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 {
+ return false;
+ }
- /// getBlockSize - Calculate the size of the specified MachineBasicBlock.
- /// Note the result may not be 100% accurate especially if there are inline
- /// asm's in the block.
- virtual unsigned getBlockSize(MachineBasicBlock *MBB) const;
+ /// DefinesPredicate - If the specified instruction defines any predicate
+ /// or condition code register(s) used for predication, returns true as well
+ /// as the definition predicate(s) by reference.
+ virtual bool DefinesPredicate(MachineInstr *MI,
+ std::vector<MachineOperand> &Pred) const {
+ return false;
+ }
/// getPointerRegClass - Returns a TargetRegisterClass used for pointer
/// values.