// operands in addition to the minimum number operands specified.
const unsigned M_VARIABLE_OPS = 1 << 11;
-// M_PREDICATED - Set if this instruction has a predicate that controls its
-// execution.
-const unsigned M_PREDICATED = 1 << 12;
+// 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_CLOBBERS_PRED - Set if this instruction may clobbers the condition code
+// register and / or registers that are used to predicate instructions.
+const unsigned M_CLOBBERS_PRED = 1 << 14;
+
+// M_NOT_DUPLICABLE - Set if this instruction cannot be safely duplicated.
+// (e.g. instructions with unique labels attached).
+const unsigned M_NOT_DUPLICABLE = 1 << 15;
// Machine operand flags
// M_LOOK_UP_PTR_REG_CLASS - Set if this operand is a pointer value and it
return get(Opcode).Flags & M_RET_FLAG;
}
- bool isPredicated(MachineOpCode Opcode) const {
- return get(Opcode).Flags & M_PREDICATED;
- }
- 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;
}
/// 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 isReMaterializable(MachineOpCode Opcode) const {
+ return get(Opcode).Flags & M_REMATERIALIZIBLE;
+ }
+
+ bool clobbersPredicate(MachineOpCode Opcode) const {
+ return get(Opcode).Flags & M_CLOBBERS_PRED;
+ }
+
+ bool isNotDuplicable(MachineOpCode Opcode) const {
+ return get(Opcode).Flags & M_NOT_DUPLICABLE;
+ }
+
/// 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,
return 0;
}
+ /// isOtherReMaterializableLoad - If the specified machine instruction is a
+ /// direct load that is trivially rematerializable, not counting loads from
+ /// stack slots, return true. If not, return false. This predicate must
+ /// return false if the instruction has any side effects other than
+ /// producing the value from the load, or if it requres any address
+ /// registers that are not always available.
+ virtual bool isOtherReMaterializableLoad(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 moretrue
/// 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, 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 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.
///
/// Note that RemoveBranch and InsertBranch must be implemented to support
/// cases where this method returns success.
}
/// 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();
}
- /// isPredicatable - True if the instruction can be converted into a
- /// predicated instruction.
- virtual bool isPredicatable(MachineInstr *MI) const {
+ /// 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.
- virtual void PredicateInstruction(MachineInstr *MI,
- std::vector<MachineOperand> &Cond) const {
- assert(0 && "Target didn't implement PredicateInstruction!");
- abort();
+ /// instruction. It returns true if the operation was successful.
+ 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;
}
/// getPointerRegClass - Returns a TargetRegisterClass used for pointer