HasOptionalDef,
Return,
Call,
- ImplicitDef,
Barrier,
Terminator,
Branch,
NotDuplicable,
DelaySlot,
SimpleLoad,
+ MayLoad,
MayStore,
- NeverHasSideEffects,
- MayHaveSideEffects,
+ UnmodeledSideEffects,
Commutable,
ConvertibleTo3Addr,
UsesCustomDAGSchedInserter,
- Rematerializable
+ Rematerializable,
+ CheapAsAMove
};
}
/// it is set. Returns -1 if it is not set.
int getOperandConstraint(unsigned OpNum,
TOI::OperandConstraint Constraint) const {
- assert((OpNum < NumOperands || isVariadic()) &&
- "Invalid operand # of TargetInstrInfo");
if (OpNum < NumOperands &&
(OpInfo[OpNum].Constraints & (1 << Constraint))) {
unsigned Pos = 16 + Constraint * 4;
return Flags & (1 << TID::HasOptionalDef);
}
- /// getImplicitUses - Return a list of machine operands that are potentially
+ /// getImplicitUses - Return a list of registers 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
return ImplicitUses;
}
- /// getImplicitDefs - Return a list of machine operands that are potentially
+ /// getImplicitDefs - Return a list of registers 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
/// 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.
+ /// This method returns null if the instruction has no implicit defs.
const unsigned *getImplicitDefs() const {
return ImplicitDefs;
}
return Flags & (1 << TID::Call);
}
- /// 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.
//===--------------------------------------------------------------------===//
// Side Effect Analysis
//===--------------------------------------------------------------------===//
+
+ /// mayLoad - Return true if this instruction could possibly read memory.
+ /// Instructions with this flag set are not necessarily simple load
+ /// instructions, they may load a value and modify it, for example.
+ bool mayLoad() const {
+ return Flags & (1 << TID::MayLoad);
+ }
+
/// mayStore - Return true if this instruction could possibly modify memory.
/// Instructions with this flag set are not necessarily simple store
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.
+ /// hasUnmodeledSideEffects - Return true if this instruction has side
+ /// effects that are not modeled by other flags. This does not return true
+ /// for instructions whose effects are captured by:
///
- /// If some instances of this instruction are side-effect free but others are
- /// not, the hasConditionalSideEffects() property should return true, not this
- /// one.
+ /// 1. Their operand list and implicit definition/use list. Register use/def
+ /// info is explicit for instructions.
+ /// 2. Memory accesses. Use mayLoad/mayStore.
+ /// 3. Calling, branching, returning: use isCall/isReturn/isBranch.
///
- /// 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.
+ /// Examples of side effects would be modifying 'invisible' machine state like
+ /// a control register, flushing a cache, modifying a register invisible to
+ /// LLVM, etc.
///
- /// 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);
+ bool hasUnmodeledSideEffects() const {
+ return Flags & (1 << TID::UnmodeledSideEffects);
}
//===--------------------------------------------------------------------===//
bool isRematerializable() const {
return Flags & (1 << TID::Rematerializable);
}
+
+ /// isAsCheapAsAMove - Returns true if this instruction has the same cost (or
+ /// less) than a move instruction. This is useful during certain types of
+ /// rematerializations (e.g., during two-address conversion) where we would
+ /// like to remat the instruction, but not if it costs more than moving the
+ /// instruction into the appropriate register.
+ bool isAsCheapAsAMove() const {
+ return Flags & (1 << TID::CheapAsAMove);
+ }
};
} // end namespace llvm