X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FCodeGen%2FMachineInstr.h;h=692189ee09bb4cb53284a60200f011ef26fc67cb;hb=69261a644298bff1497d46c8cd38d688670f307b;hp=4c5eb8b36f36a17f6a98e03df97dfc36c6d96c86;hpb=ff2b99afc8cbc6cfa73181072888e0f9f07deb7e;p=oota-llvm.git diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index 4c5eb8b36f3..692189ee09b 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -16,16 +16,17 @@ #ifndef LLVM_CODEGEN_MACHINEINSTR_H #define LLVM_CODEGEN_MACHINEINSTR_H -#include "llvm/CodeGen/MachineOperand.h" -#include "llvm/MC/MCInstrDesc.h" -#include "llvm/Target/TargetOpcodes.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/ilist.h" -#include "llvm/ADT/ilist_node.h" +#include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" -#include "llvm/ADT/DenseMapInfo.h" +#include "llvm/ADT/ilist.h" +#include "llvm/ADT/ilist_node.h" +#include "llvm/CodeGen/MachineOperand.h" +#include "llvm/InlineAsm.h" +#include "llvm/MC/MCInstrDesc.h" #include "llvm/Support/DebugLoc.h" +#include "llvm/Target/TargetOpcodes.h" #include namespace llvm { @@ -81,8 +82,8 @@ private: MachineBasicBlock *Parent; // Pointer to the owning basic block. DebugLoc debugLoc; // Source line information. - MachineInstr(const MachineInstr&); // DO NOT IMPLEMENT - void operator=(const MachineInstr&); // DO NOT IMPLEMENT + MachineInstr(const MachineInstr&) LLVM_DELETED_FUNCTION; + void operator=(const MachineInstr&) LLVM_DELETED_FUNCTION; // Intrusive list support friend struct ilist_traits; @@ -97,25 +98,10 @@ private: /// MCID NULL and no operands. MachineInstr(); - // The next two constructors have DebugLoc and non-DebugLoc versions; - // over time, the non-DebugLoc versions should be phased out and eventually - // removed. - - /// MachineInstr ctor - This constructor creates a MachineInstr and adds the - /// implicit operands. It reserves space for the number of operands specified - /// by the MCInstrDesc. The version with a DebugLoc should be preferred. - explicit MachineInstr(const MCInstrDesc &MCID, bool NoImp = false); - - /// MachineInstr ctor - Work exactly the same as the ctor above, except that - /// the MachineInstr is created and added to the end of the specified basic - /// block. The version with a DebugLoc should be preferred. - MachineInstr(MachineBasicBlock *MBB, const MCInstrDesc &MCID); - /// MachineInstr ctor - This constructor create a MachineInstr and add the /// implicit operands. It reserves space for number of operands specified by /// MCInstrDesc. An explicit DebugLoc is supplied. - explicit MachineInstr(const MCInstrDesc &MCID, const DebugLoc dl, - bool NoImp = false); + MachineInstr(const MCInstrDesc &MCID, const DebugLoc dl, bool NoImp = false); /// MachineInstr ctor - Work exactly the same as the ctor above, except that /// the MachineInstr is created and added to the end of the specified basic @@ -420,6 +406,12 @@ public: return hasProperty(MCID::Bitcast, Type); } + /// isSelect - Return true if this instruction is a select instruction. + /// + bool isSelect(QueryType Type = IgnoreBundle) const { + return hasProperty(MCID::Select, Type); + } + /// 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. @@ -453,6 +445,11 @@ public: /// Instructions with this flag set are not necessarily simple load /// instructions, they may load a value and modify it, for example. bool mayLoad(QueryType Type = AnyInBundle) const { + if (isInlineAsm()) { + unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); + if (ExtraInfo & InlineAsm::Extra_MayLoad) + return true; + } return hasProperty(MCID::MayLoad, Type); } @@ -462,6 +459,11 @@ public: /// instructions, they may store a modified value based on their operands, or /// may not actually modify anything, for example. bool mayStore(QueryType Type = AnyInBundle) const { + if (isInlineAsm()) { + unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); + if (ExtraInfo & InlineAsm::Extra_MayStore) + return true; + } return hasProperty(MCID::MayStore, Type); } @@ -604,6 +606,7 @@ public: bool isImplicitDef() const { return getOpcode()==TargetOpcode::IMPLICIT_DEF; } bool isInlineAsm() const { return getOpcode() == TargetOpcode::INLINEASM; } bool isStackAligningInlineAsm() const; + InlineAsm::AsmDialect getInlineAsmDialect() const; bool isInsertSubreg() const { return getOpcode() == TargetOpcode::INSERT_SUBREG; } @@ -776,16 +779,43 @@ public: const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const; + /// tieOperands - Add a tie between the register operands at DefIdx and + /// UseIdx. The tie will cause the register allocator to ensure that the two + /// operands are assigned the same physical register. + /// + /// Tied operands are managed automatically for explicit operands in the + /// MCInstrDesc. This method is for exceptional cases like inline asm. + void tieOperands(unsigned DefIdx, unsigned UseIdx); + + /// findTiedOperandIdx - Given the index of a tied register operand, find the + /// operand it is tied to. Defs are tied to uses and vice versa. Returns the + /// index of the tied operand which must exist. + unsigned findTiedOperandIdx(unsigned OpIdx) const; + /// isRegTiedToUseOperand - Given the index of a register def operand, /// check if the register def is tied to a source operand, due to either /// two-address elimination or inline assembly constraints. Returns the /// first tied use operand index by reference if UseOpIdx is not null. - bool isRegTiedToUseOperand(unsigned DefOpIdx, unsigned *UseOpIdx = 0) const; + bool isRegTiedToUseOperand(unsigned DefOpIdx, unsigned *UseOpIdx = 0) const { + const MachineOperand &MO = getOperand(DefOpIdx); + if (!MO.isReg() || !MO.isDef() || !MO.isTied()) + return false; + if (UseOpIdx) + *UseOpIdx = findTiedOperandIdx(DefOpIdx); + return true; + } /// isRegTiedToDefOperand - Return true if the use operand of the specified /// index is tied to an def operand. It also returns the def operand index by /// reference if DefOpIdx is not null. - bool isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx = 0) const; + bool isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx = 0) const { + const MachineOperand &MO = getOperand(UseOpIdx); + if (!MO.isReg() || !MO.isUse() || !MO.isTied()) + return false; + if (DefOpIdx) + *DefOpIdx = findTiedOperandIdx(UseOpIdx); + return true; + } /// clearKillInfo - Clears kill flags on all operands. /// @@ -846,11 +876,11 @@ public: bool isSafeToReMat(const TargetInstrInfo *TII, AliasAnalysis *AA, unsigned DstReg) const; - /// hasVolatileMemoryRef - Return true if this instruction may have a - /// volatile memory reference, or if the information describing the - /// memory reference is not available. Return false if it is known to - /// have no volatile memory references. - bool hasVolatileMemoryRef() const; + /// hasOrderedMemoryRef - Return true if this instruction may have an ordered + /// or volatile memory reference, or if the information describing the memory + /// reference is not available. Return false if it is known to have no + /// ordered or volatile memory references. + bool hasOrderedMemoryRef() const; /// isInvariantLoad - Return true if this instruction is loading from a /// location whose value is invariant across the function. For example, @@ -929,6 +959,15 @@ private: /// return null. MachineRegisterInfo *getRegInfo(); + /// untieRegOperand - Break any tie involving OpIdx. + void untieRegOperand(unsigned OpIdx) { + MachineOperand &MO = getOperand(OpIdx); + if (MO.isReg() && MO.isTied()) { + getOperand(findTiedOperandIdx(OpIdx)).TiedTo = 0; + MO.TiedTo = 0; + } + } + /// addImplicitDefUseOperands - Add all implicit def and use operands to /// this instruction. void addImplicitDefUseOperands();