aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/CodeGen/MachineInstr.h257
-rw-r--r--include/llvm/MC/MCInstrDesc.h183
-rw-r--r--lib/CodeGen/AggressiveAntiDepBreaker.cpp8
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp2
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfException.cpp4
-rw-r--r--lib/CodeGen/BranchFolding.cpp15
-rw-r--r--lib/CodeGen/CriticalAntiDepBreaker.cpp8
-rw-r--r--lib/CodeGen/DeadMachineInstructionElim.cpp2
-rw-r--r--lib/CodeGen/ExecutionDepsFix.cpp2
-rw-r--r--lib/CodeGen/ExpandISelPseudos.cpp3
-rw-r--r--lib/CodeGen/ExpandPostRAPseudos.cpp2
-rw-r--r--lib/CodeGen/GCStrategy.cpp2
-rw-r--r--lib/CodeGen/IfConversion.cpp12
-rw-r--r--lib/CodeGen/InlineSpiller.cpp4
-rw-r--r--lib/CodeGen/LiveDebugVariables.cpp4
-rw-r--r--lib/CodeGen/LiveIntervalAnalysis.cpp2
-rw-r--r--lib/CodeGen/LiveRangeEdit.cpp4
-rw-r--r--lib/CodeGen/LiveVariables.cpp4
-rw-r--r--lib/CodeGen/MachineBasicBlock.cpp6
-rw-r--r--lib/CodeGen/MachineCSE.cpp9
-rw-r--r--lib/CodeGen/MachineInstr.cpp41
-rw-r--r--lib/CodeGen/MachineLICM.cpp8
-rw-r--r--lib/CodeGen/MachineSink.cpp2
-rw-r--r--lib/CodeGen/MachineVerifier.cpp28
-rw-r--r--lib/CodeGen/PeepholeOptimizer.cpp10
-rw-r--r--lib/CodeGen/PostRASchedulerList.cpp2
-rw-r--r--lib/CodeGen/PrologEpilogInserter.cpp8
-rw-r--r--lib/CodeGen/RegAllocFast.cpp6
-rw-r--r--lib/CodeGen/RegisterCoalescer.cpp7
-rw-r--r--lib/CodeGen/ScheduleDAGInstrs.cpp21
-rw-r--r--lib/CodeGen/SelectionDAG/InstrEmitter.cpp2
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp2
-rw-r--r--lib/CodeGen/ShrinkWrapping.cpp2
-rw-r--r--lib/CodeGen/SplitKit.cpp2
-rw-r--r--lib/CodeGen/TailDuplication.cpp10
-rw-r--r--lib/CodeGen/TargetInstrInfoImpl.cpp25
-rw-r--r--lib/CodeGen/TwoAddressInstructionPass.cpp31
-rw-r--r--lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp2
-rw-r--r--lib/Target/ARM/ARMAsmPrinter.cpp2
-rw-r--r--lib/Target/ARM/ARMBaseInstrInfo.cpp23
-rw-r--r--lib/Target/ARM/ARMConstantIslandPass.cpp8
-rw-r--r--lib/Target/ARM/ARMFastISel.cpp3
-rw-r--r--lib/Target/ARM/ARMFrameLowering.cpp3
-rw-r--r--lib/Target/ARM/ARMHazardRecognizer.cpp6
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp8
-rw-r--r--lib/Target/ARM/ARMLoadStoreOptimizer.cpp12
-rw-r--r--lib/Target/ARM/MLxExpansionPass.cpp4
-rw-r--r--lib/Target/ARM/Thumb1RegisterInfo.cpp7
-rw-r--r--lib/Target/ARM/Thumb2ITBlockPass.cpp4
-rw-r--r--lib/Target/ARM/Thumb2SizeReduction.cpp5
-rw-r--r--lib/Target/MBlaze/MBlazeAsmPrinter.cpp4
-rw-r--r--lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp16
-rw-r--r--lib/Target/MSP430/MSP430FrameLowering.cpp2
-rw-r--r--lib/Target/MSP430/MSP430InstrInfo.cpp9
-rw-r--r--lib/Target/Mips/MipsAsmPrinter.cpp4
-rw-r--r--lib/Target/Mips/MipsCodeEmitter.cpp2
-rw-r--r--lib/Target/Mips/MipsDelaySlotFiller.cpp17
-rw-r--r--lib/Target/PTX/PTXInstrInfo.cpp15
-rw-r--r--lib/Target/PowerPC/PPCFrameLowering.cpp2
-rw-r--r--lib/Target/PowerPC/PPCISelDAGToDAG.cpp4
-rw-r--r--lib/Target/Sparc/DelaySlotFiller.cpp16
-rw-r--r--lib/Target/Sparc/SparcAsmPrinter.cpp4
-rw-r--r--lib/Target/Sparc/SparcInstrInfo.cpp2
-rw-r--r--lib/Target/TargetInstrInfo.cpp7
-rw-r--r--lib/Target/X86/X86CodeEmitter.cpp2
-rw-r--r--lib/Target/X86/X86FrameLowering.cpp2
-rw-r--r--lib/Target/X86/X86InstrInfo.cpp9
-rw-r--r--lib/Target/X86/X86RegisterInfo.cpp2
-rw-r--r--lib/Target/X86/X86VZeroUpper.cpp2
69 files changed, 595 insertions, 353 deletions
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h
index 1558c4f957..00b41e74c2 100644
--- a/include/llvm/CodeGen/MachineInstr.h
+++ b/include/llvm/CodeGen/MachineInstr.h
@@ -274,14 +274,267 @@ public:
return MemRefsEnd - MemRefs == 1;
}
- /// API for querying MachineInstr properties. These are bundle aware.
+ /// API for querying MachineInstr properties. They are the same as MCInstrDesc
+ /// queries but they are bundle aware.
+
+ /// hasProperty - Return true if the instruction (or in the case of a bundle,
+ /// the instructions inside the bundle) has the specified property.
+ /// The first argument is the property being queried.
+ /// The second argument indicates whether the query should look inside
+ /// instruction bundles.
+ /// If the third argument is true, than the query can return true when *any*
+ /// of the bundled instructions has the queried property. If it's false, then
+ /// this can return true iff *all* of the instructions have the property.
+ bool hasProperty(unsigned Flag,
+ bool PeekInBundle = true, bool IsOr = true) const;
+
+ /// 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 hasProperty(MCID::Variadic, false);
+ }
+
+ /// 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 hasProperty(MCID::HasOptionalDef, false);
+ }
+
+ /// isPseudo - Return true if this is a pseudo instruction that doesn't
+ /// correspond to a real machine instruction.
///
- bool hasProperty(unsigned short Flag) const;
+ bool isPseudo() const {
+ return hasProperty(MCID::Pseudo, false);
+ }
+
+ bool isReturn() const {
+ return hasProperty(MCID::Return);
+ }
+
+ bool isCall() const {
+ return hasProperty(MCID::Call);
+ }
+
+ /// 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() const {
+ return hasProperty(MCID::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 hasProperty(MCID::Terminator);
}
+ /// 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 hasProperty(MCID::Branch);
+ }
+
+ /// isIndirectBranch - Return true if this is an indirect branch, such as a
+ /// branch through a register.
+ bool isIndirectBranch() const {
+ return hasProperty(MCID::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();
+ }
+
+ /// 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 {
+ // If it's a bundle than all bundled instructions must be predicable for this
+ // to return true.
+ return hasProperty(MCID::Predicable, true, false);
+ }
+
+ /// isCompare - Return true if this instruction is a comparison.
+ bool isCompare() const {
+ return hasProperty(MCID::Compare, false);
+ }
+
+ /// isMoveImmediate - Return true if this instruction is a move immediate
+ /// (including conditional moves) instruction.
+ bool isMoveImmediate() const {
+ return hasProperty(MCID::MoveImm, false);
+ }
+
+ /// isBitcast - Return true if this instruction is a bitcast instruction.
+ ///
+ bool isBitcast() const {
+ return hasProperty(MCID::Bitcast, false);
+ }
+
+ /// 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 hasProperty(MCID::NotDuplicable);
+ }
+
+ /// hasDelaySlot - Returns true if the specified instruction has a delay slot
+ /// which must be filled by the code generator.
+ bool hasDelaySlot() const {
+ return hasProperty(MCID::DelaySlot);
+ }
+
+ /// canFoldAsLoad - Return true for instructions that can be folded as
+ /// memory operands in other instructions. The most common use for this
+ /// is instructions that are simple loads from memory that don't modify
+ /// the loaded value in any way, but it can also be used for instructions
+ /// that can be expressed as constant-pool loads, such as V_SETALLONES
+ /// on x86, to allow them to be folded when it is beneficial.
+ /// This should only be set on instructions that return a value in their
+ /// only virtual register definition.
+ bool canFoldAsLoad() const {
+ return hasProperty(MCID::FoldableAsLoad, false);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // 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 hasProperty(MCID::MayLoad);
+ }
+
+
+ /// 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 hasProperty(MCID::MayStore);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // 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 hasProperty(MCID::Commutable, false);
+ }
+
+ /// 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 hasProperty(MCID::ConvertibleTo3Addr, false);
+ }
+
+ /// usesCustomInsertionHook - Return true if this instruction requires
+ /// custom insertion support when the DAG scheduler is inserting it into a
+ /// 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 usesCustomInsertionHook() const {
+ return hasProperty(MCID::UsesCustomInserter, false);
+ }
+
+ /// hasPostISelHook - Return true if this instruction requires *adjustment*
+ /// after instruction selection by calling a target hook. For example, this
+ /// can be used to fill in ARM 's' optional operand depending on whether
+ /// the conditional flag register is used.
+ bool hasPostISelHook() const {
+ return hasProperty(MCID::HasPostISelHook, false);
+ }
+
+ /// 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 {
+ // It's only possible to re-mat a bundle if all bundled instructions are
+ // re-materializable.
+ return hasProperty(MCID::Rematerializable, true, false);
+ }
+
+ /// isAsCheapAsAMove - Returns true if this instruction has the same cost (or
+ /// less) than a move instruction. This is useful during certain types of
+ /// optimizations (e.g., remat during two-address conversion or machine licm)
+ /// where we would like to remat or hoist the instruction, but not if it costs
+ /// more than moving the instruction into the appropriate register. Note, we
+ /// are not marking copies from and to the same register class with this flag.
+ bool isAsCheapAsAMove() const {
+ // Only returns true for a bundle if all bundled instructions are cheap.
+ // FIXME: This probably requires a target hook.
+ return hasProperty(MCID::CheapAsAMove, true, true);
+ }
+
+ /// hasExtraSrcRegAllocReq - Returns true if this instruction source operands
+ /// have special register allocation requirements that are not captured by the
+ /// operand register classes. e.g. ARM::STRD's two source registers must be an
+ /// even / odd pair, ARM::STM registers have to be in ascending order.
+ /// Post-register allocation passes should not attempt to change allocations
+ /// for sources of instructions with this flag.
+ bool hasExtraSrcRegAllocReq() const {
+ return hasProperty(MCID::ExtraSrcRegAllocReq);
+ }
+
+ /// hasExtraDefRegAllocReq - Returns true if this instruction def operands
+ /// have special register allocation requirements that are not captured by the
+ /// operand register classes. e.g. ARM::LDRD's two def registers must be an
+ /// even / odd pair, ARM::LDM registers have to be in ascending order.
+ /// Post-register allocation passes should not attempt to change allocations
+ /// for definitions of instructions with this flag.
+ bool hasExtraDefRegAllocReq() const {
+ return hasProperty(MCID::ExtraDefRegAllocReq);
+ }
+
+
enum MICheckType {
CheckDefs, // Check all operands for equality
CheckKillDead, // Check all operands including kill / dead markers
diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h
index 6c33bfa2ec..6d71cf570a 100644
--- a/include/llvm/MC/MCInstrDesc.h
+++ b/include/llvm/MC/MCInstrDesc.h
@@ -186,7 +186,7 @@ public:
/// getFlags - Return flags of this instruction.
///
- unsigned short getFlags() const { return Flags; }
+ unsigned getFlags() const { return Flags; }
/// isVariadic - Return true if this instruction can have a variable number of
/// operands. In this case, the variable operands will be after the normal
@@ -202,84 +202,6 @@ public:
return Flags & (1 << MCID::HasOptionalDef);
}
- /// 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
- /// 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;
- }
-
- /// getNumImplicitUses - Return the number of implicit uses this instruction
- /// has.
- unsigned getNumImplicitUses() const {
- if (ImplicitUses == 0) return 0;
- unsigned i = 0;
- for (; ImplicitUses[i]; ++i) /*empty*/;
- return i;
- }
-
- /// 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
- /// 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 defs.
- const unsigned *getImplicitDefs() const {
- return ImplicitDefs;
- }
-
- /// getNumImplicitDefs - Return the number of implicit defs this instruction
- /// has.
- unsigned getNumImplicitDefs() const {
- if (ImplicitDefs == 0) return 0;
- unsigned i = 0;
- for (; ImplicitDefs[i]; ++i) /*empty*/;
- return i;
- }
-
- /// hasImplicitUseOfPhysReg - Return true if this instruction implicitly
- /// uses the specified physical register.
- bool hasImplicitUseOfPhysReg(unsigned Reg) const {
- if (const unsigned *ImpUses = ImplicitUses)
- for (; *ImpUses; ++ImpUses)
- if (*ImpUses == Reg) return true;
- return false;
- }
-
- /// hasImplicitDefOfPhysReg - Return true if this instruction implicitly
- /// defines the specified physical register.
- bool hasImplicitDefOfPhysReg(unsigned Reg) const {
- if (const unsigned *ImpDefs = ImplicitDefs)
- for (; *ImpDefs; ++ImpDefs)
- if (*ImpDefs == Reg) return true;
- return false;
- }
-
- /// 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;
- }
-
- /// getSize - Return the number of bytes in the encoding of this instruction,
- /// or zero if the encoding size cannot be known from the opcode.
- unsigned getSize() const {
- return Size;
- }
-
/// isPseudo - Return true if this is a pseudo instruction that doesn't
/// correspond to a real machine instruction.
///
@@ -302,18 +224,6 @@ public:
return Flags & (1 << MCID::Barrier);
}
- /// findFirstPredOperandIdx() - Find the index of the first operand in the
- /// operand list that is used to represent the predicate. It returns -1 if
- /// none is found.
- int findFirstPredOperandIdx() const {
- if (isPredicable()) {
- for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
- if (OpInfo[i].isPredicate())
- return i;
- }
- return -1;
- }
-
/// isTerminator - Returns true if this instruction part of the terminator for
/// a basic block. Typically this is things like return and branch
/// instructions.
@@ -534,6 +444,97 @@ public:
bool hasExtraDefRegAllocReq() const {
return Flags & (1 << MCID::ExtraDefRegAllocReq);
}
+
+
+ /// 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
+ /// 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;
+ }
+
+ /// getNumImplicitUses - Return the number of implicit uses this instruction
+ /// has.
+ unsigned getNumImplicitUses() const {
+ if (ImplicitUses == 0) return 0;
+ unsigned i = 0;
+ for (; ImplicitUses[i]; ++i) /*empty*/;
+ return i;
+ }
+
+ /// 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
+ /// 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 defs.
+ const unsigned *getImplicitDefs() const {
+ return ImplicitDefs;
+ }
+
+ /// getNumImplicitDefs - Return the number of implicit defs this instruction
+ /// has.
+ unsigned getNumImplicitDefs() const {
+ if (ImplicitDefs == 0) return 0;
+ unsigned i = 0;
+ for (; ImplicitDefs[i]; ++i) /*empty*/;
+ return i;
+ }
+
+ /// hasImplicitUseOfPhysReg - Return true if this instruction implicitly
+ /// uses the specified physical register.
+ bool hasImplicitUseOfPhysReg(unsigned Reg) const {
+ if (const unsigned *ImpUses = ImplicitUses)
+ for (; *ImpUses; ++ImpUses)
+ if (*ImpUses == Reg) return true;
+ return false;
+ }
+
+ /// hasImplicitDefOfPhysReg - Return true if this instruction implicitly
+ /// defines the specified physical register.
+ bool hasImplicitDefOfPhysReg(unsigned Reg