summaryrefslogtreecommitdiffstats
path: root/include/llvm/Target
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Target')
-rw-r--r--include/llvm/Target/Mangler.h4
-rw-r--r--include/llvm/Target/Target.td62
-rw-r--r--include/llvm/Target/TargetCallingConv.h4
-rw-r--r--include/llvm/Target/TargetCallingConv.td11
-rw-r--r--include/llvm/Target/TargetData.h34
-rw-r--r--include/llvm/Target/TargetELFWriterInfo.h3
-rw-r--r--include/llvm/Target/TargetFrameLowering.h4
-rw-r--r--include/llvm/Target/TargetInstrInfo.h128
-rw-r--r--include/llvm/Target/TargetJITInfo.h21
-rw-r--r--include/llvm/Target/TargetLibraryInfo.h248
-rw-r--r--include/llvm/Target/TargetLowering.h138
-rw-r--r--include/llvm/Target/TargetLoweringObjectFile.h30
-rw-r--r--include/llvm/Target/TargetMachine.h138
-rw-r--r--include/llvm/Target/TargetOpcodes.h7
-rw-r--r--include/llvm/Target/TargetOptions.h294
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h124
-rw-r--r--include/llvm/Target/TargetSelectionDAG.td47
-rw-r--r--include/llvm/Target/TargetSubtargetInfo.h4
18 files changed, 880 insertions, 421 deletions
diff --git a/include/llvm/Target/Mangler.h b/include/llvm/Target/Mangler.h
index c1c118b..d5e165e 100644
--- a/include/llvm/Target/Mangler.h
+++ b/include/llvm/Target/Mangler.h
@@ -17,11 +17,9 @@
#include "llvm/ADT/DenseMap.h"
namespace llvm {
-class StringRef;
class Twine;
-class Value;
class GlobalValue;
-template <typename T> class SmallVectorImpl;
+template <typename T> class SmallVectorImpl;
class MCContext;
class MCSymbol;
class TargetData;
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index aa9a4f5..fa1ec55 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -22,8 +22,12 @@ include "llvm/Intrinsics.td"
class RegisterClass; // Forward def
// SubRegIndex - Use instances of SubRegIndex to identify subregisters.
-class SubRegIndex {
+class SubRegIndex<list<SubRegIndex> comps = []> {
string Namespace = "";
+
+ // ComposedOf - A list of two SubRegIndex instances, [A, B].
+ // This indicates that this SubRegIndex is the result of composing A and B.
+ list<SubRegIndex> ComposedOf = comps;
}
// RegAltNameIndex - The alternate name set to use for register operands of
@@ -83,9 +87,15 @@ class Register<string n, list<string> altNames = []> {
// CostPerUse - Additional cost of instructions using this register compared
// to other registers in its class. The register allocator will try to
// minimize the number of instructions using a register with a CostPerUse.
- // This is used by the x86-64 and ARM Thumb targets where some registers
+ // This is used by the x86-64 and ARM Thumb targets where some registers
// require larger instruction encodings.
int CostPerUse = 0;
+
+ // CoveredBySubRegs - When this bit is set, the value of this register is
+ // completely determined by the value of its sub-registers. For example, the
+ // x86 register AX is covered by its sub-registers AL and AH, but EAX is not
+ // covered by its sub-register AX.
+ bit CoveredBySubRegs = 0;
}
// RegisterWithSubRegs - This can be used to define instances of Register which
@@ -194,12 +204,15 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
//
// (decimate GPR, 2) - Pick every N'th element, starting with the first.
//
+// (interleave A, B, ...) - Interleave the elements from each argument list.
+//
// All of these operators work on ordered sets, not lists. That means
// duplicates are removed from sub-expressions.
// Set operators. The rest is defined in TargetSelectionDAG.td.
def sequence;
def decimate;
+def interleave;
// RegisterTuples - Automatically generate super-registers by forming tuples of
// sub-registers. This is useful for modeling register sequence constraints
@@ -356,6 +369,15 @@ class Instruction {
// associated with them. Once we've migrated all of them over to true
// pseudo-instructions that are lowered to real instructions prior to
// the printer/emitter, we can remove this attribute and just use isPseudo.
+ //
+ // The intended use is:
+ // isPseudo: Does not have encoding information and should be expanded,
+ // at the latest, during lowering to MCInst.
+ //
+ // isCodeGenOnly: Does have encoding information and can go through to the
+ // CodeEmitter unchanged, but duplicates a canonical instruction
+ // definition's encoding and should be ignored when constructing the
+ // assembler match tables.
bit isCodeGenOnly = 0;
// Is this instruction a pseudo instruction for use by the assembler parser.
@@ -414,7 +436,7 @@ class Predicate<string cond> {
/// NoHonorSignDependentRounding - This predicate is true if support for
/// sign-dependent-rounding is not enabled.
def NoHonorSignDependentRounding
- : Predicate<"!HonorSignDependentRoundingFPMath()">;
+ : Predicate<"!TM.Options.HonorSignDependentRoundingFPMath()">;
class Requires<list<Predicate> preds> {
list<Predicate> Predicates = preds;
@@ -679,6 +701,11 @@ def COPY : Instruction {
let neverHasSideEffects = 1;
let isAsCheapAsAMove = 1;
}
+def BUNDLE : Instruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins variable_ops);
+ let AsmString = "BUNDLE";
+}
}
//===----------------------------------------------------------------------===//
@@ -698,7 +725,15 @@ class AsmParser {
// function of the AsmParser class to call on every matched instruction.
// This can be used to perform target specific instruction post-processing.
string AsmParserInstCleanup = "";
+}
+def DefaultAsmParser : AsmParser;
+//===----------------------------------------------------------------------===//
+// AsmParserVariant - Subtargets can have multiple different assembly parsers
+// (e.g. AT&T vs Intel syntax on X86 for example). This class can be
+// implemented by targets to describe such variants.
+//
+class AsmParserVariant {
// Variant - AsmParsers can be of multiple different variants. Variants are
// used to support targets that need to parser multiple formats for the
// assembly language.
@@ -715,7 +750,7 @@ class AsmParser {
// purposes of matching.
string RegisterPrefix = "";
}
-def DefaultAsmParser : AsmParser;
+def DefaultAsmParserVariant : AsmParserVariant;
/// AssemblerPredicate - This is a Predicate that can be used when the assembler
/// matches instructions and aliases.
@@ -724,7 +759,20 @@ class AssemblerPredicate<string cond> {
string AssemblerCondString = cond;
}
-
+/// TokenAlias - This class allows targets to define assembler token
+/// operand aliases. That is, a token literal operand which is equivalent
+/// to another, canonical, token literal. For example, ARM allows:
+/// vmov.u32 s4, #0 -> vmov.i32, #0
+/// 'u32' is a more specific designator for the 32-bit integer type specifier
+/// and is legal for any instruction which accepts 'i32' as a datatype suffix.
+/// def : TokenAlias<".u32", ".i32">;
+///
+/// This works by marking the match class of 'From' as a subclass of the
+/// match class of 'To'.
+class TokenAlias<string From, string To> {
+ string FromToken = From;
+ string ToToken = To;
+}
/// MnemonicAlias - This class allows targets to define assembler mnemonic
/// aliases. This should be used when all forms of one mnemonic are accepted
@@ -813,6 +861,10 @@ class Target {
// AssemblyParsers - The AsmParser instances available for this target.
list<AsmParser> AssemblyParsers = [DefaultAsmParser];
+ /// AssemblyParserVariants - The AsmParserVariant instances available for
+ /// this target.
+ list<AsmParserVariant> AssemblyParserVariants = [DefaultAsmParserVariant];
+
// AssemblyWriters - The AsmWriter instances available for this target.
list<AsmWriter> AssemblyWriters = [DefaultAsmWriter];
}
diff --git a/include/llvm/Target/TargetCallingConv.h b/include/llvm/Target/TargetCallingConv.h
index 275957e..a6251e7 100644
--- a/include/llvm/Target/TargetCallingConv.h
+++ b/include/llvm/Target/TargetCallingConv.h
@@ -14,6 +14,10 @@
#ifndef LLVM_TARGET_TARGETCALLINGCONV_H
#define LLVM_TARGET_TARGETCALLINGCONV_H
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/MathExtras.h"
+#include <string>
+
namespace llvm {
namespace ISD {
diff --git a/include/llvm/Target/TargetCallingConv.td b/include/llvm/Target/TargetCallingConv.td
index 6da3ba1..a53ed29 100644
--- a/include/llvm/Target/TargetCallingConv.td
+++ b/include/llvm/Target/TargetCallingConv.td
@@ -133,3 +133,14 @@ class CCDelegateTo<CallingConv cc> : CCAction {
class CallingConv<list<CCAction> actions> {
list<CCAction> Actions = actions;
}
+
+/// CalleeSavedRegs - A list of callee saved registers for a given calling
+/// convention. The order of registers is used by PrologEpilogInsertion when
+/// allocation stack slots for saved registers.
+///
+/// For each CalleeSavedRegs def, TableGen will emit a FOO_SaveList array for
+/// returning from getCalleeSavedRegs(), and a FOO_RegMask bit mask suitable for
+/// returning from getCallPreservedMask().
+class CalleeSavedRegs<dag saves> {
+ dag SaveList = saves;
+}
diff --git a/include/llvm/Target/TargetData.h b/include/llvm/Target/TargetData.h
index 26fd187..d116f39 100644
--- a/include/llvm/Target/TargetData.h
+++ b/include/llvm/Target/TargetData.h
@@ -44,7 +44,7 @@ enum AlignTypeEnum {
AGGREGATE_ALIGN = 'a', ///< Aggregate alignment
STACK_ALIGN = 's' ///< Stack objects alignment
};
-
+
/// Target alignment element.
///
/// Stores the alignment data associated with a given alignment type (pointer,
@@ -80,7 +80,7 @@ private:
unsigned StackNaturalAlign; ///< Stack natural alignment
SmallVector<unsigned char, 8> LegalIntWidths; ///< Legal Integers.
-
+
/// Alignments- Where the primitive type alignment data is stored.
///
/// @sa init().
@@ -88,7 +88,7 @@ private:
/// pointers vs. 64-bit pointers by extending TargetAlignment, but for now,
/// we don't.
SmallVector<TargetAlignElem, 16> Alignments;
-
+
/// InvalidAlignmentElem - This member is a signal that a requested alignment
/// type and bit width were not found in the SmallVector.
static const TargetAlignElem InvalidAlignmentElem;
@@ -112,19 +112,30 @@ private:
return &align != &InvalidAlignmentElem;
}
+ /// Initialise a TargetData object with default values, ensure that the
+ /// target data pass is registered.
+ void init();
+
public:
/// Default ctor.
///
/// @note This has to exist, because this is a pass, but it should never be
/// used.
TargetData();
-
+
/// Constructs a TargetData from a specification string. See init().
explicit TargetData(StringRef TargetDescription)
: ImmutablePass(ID) {
- init(TargetDescription);
+ std::string errMsg = parseSpecifier(TargetDescription, this);
+ assert(errMsg == "" && "Invalid target data layout string.");
+ (void)errMsg;
}
+ /// Parses a target data specification string. Returns an error message
+ /// if the string is malformed, or the empty string on success. Optionally
+ /// initialises a TargetData object if passed a non-null pointer.
+ static std::string parseSpecifier(StringRef TargetDescription, TargetData* td = 0);
+
/// Initialize target data from properties stored in the module.
explicit TargetData(const Module *M);
@@ -141,9 +152,6 @@ public:
~TargetData(); // Not virtual, do not subclass this class
- //! Parse a target data layout string and initialize TargetData alignments.
- void init(StringRef TargetDescription);
-
/// Target endianness...
bool isLittleEndian() const { return LittleEndian; }
bool isBigEndian() const { return !LittleEndian; }
@@ -152,7 +160,7 @@ public:
/// TargetData. This representation is in the same format accepted by the
/// string constructor above.
std::string getStringRepresentation() const;
-
+
/// isLegalInteger - This function returns true if the specified type is
/// known to be a native integer type supported by the CPU. For example,
/// i64 is not native on most 32-bit CPUs and i37 is not native on any known
@@ -166,7 +174,7 @@ public:
return true;
return false;
}
-
+
bool isIllegalInteger(unsigned Width) const {
return !isLegalInteger(Width);
}
@@ -251,11 +259,11 @@ public:
/// getABITypeAlignment - Return the minimum ABI-required alignment for the
/// specified type.
unsigned getABITypeAlignment(Type *Ty) const;
-
+
/// getABIIntegerTypeAlignment - Return the minimum ABI-required alignment for
/// an integer type of the specified bitwidth.
unsigned getABIIntegerTypeAlignment(unsigned BitWidth) const;
-
+
/// getCallFrameTypeAlignment - Return the minimum ABI-required alignment
/// for the specified type when it is part of a call frame.
@@ -305,7 +313,7 @@ public:
assert((Alignment & (Alignment-1)) == 0 && "Alignment must be power of 2!");
return (Val + (Alignment-1)) & ~UIntTy(Alignment-1);
}
-
+
static char ID; // Pass identification, replacement for typeid
};
diff --git a/include/llvm/Target/TargetELFWriterInfo.h b/include/llvm/Target/TargetELFWriterInfo.h
index b97f3e2..114295e 100644
--- a/include/llvm/Target/TargetELFWriterInfo.h
+++ b/include/llvm/Target/TargetELFWriterInfo.h
@@ -15,9 +15,6 @@
#define LLVM_TARGET_TARGETELFWRITERINFO_H
namespace llvm {
- class Function;
- class TargetData;
- class TargetMachine;
//===--------------------------------------------------------------------===//
// TargetELFWriterInfo
diff --git a/include/llvm/Target/TargetFrameLowering.h b/include/llvm/Target/TargetFrameLowering.h
index 4c759b2..d56db7b 100644
--- a/include/llvm/Target/TargetFrameLowering.h
+++ b/include/llvm/Target/TargetFrameLowering.h
@@ -15,8 +15,6 @@
#define LLVM_TARGET_TARGETFRAMELOWERING_H
#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/MC/MCDwarf.h"
-#include "llvm/ADT/ArrayRef.h"
#include <utility>
#include <vector>
@@ -24,8 +22,6 @@
namespace llvm {
class CalleeSavedInfo;
class MachineFunction;
- class MachineBasicBlock;
- class MachineMove;
class RegScavenger;
/// Information about stack frame layout on the target. It holds the direction
diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h
index 07f614d..d1e380c 100644
--- a/include/llvm/Target/TargetInstrInfo.h
+++ b/include/llvm/Target/TargetInstrInfo.h
@@ -15,6 +15,7 @@
#define LLVM_TARGET_TARGETINSTRINFO_H
#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/CodeGen/DFAPacketizer.h"
#include "llvm/CodeGen/MachineFunction.h"
namespace llvm {
@@ -278,8 +279,7 @@ public:
/// 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;
+ llvm_unreachable("Target didn't implement TargetInstrInfo::RemoveBranch!");
}
/// InsertBranch - Insert branch code into the end of the specified
@@ -296,8 +296,7 @@ public:
MachineBasicBlock *FBB,
const SmallVectorImpl<MachineOperand> &Cond,
DebugLoc DL) const {
- assert(0 && "Target didn't implement TargetInstrInfo::InsertBranch!");
- return 0;
+ llvm_unreachable("Target didn't implement TargetInstrInfo::InsertBranch!");
}
/// ReplaceTailWithBranchTo - Delete the instruction OldInst and everything
@@ -353,12 +352,28 @@ public:
return false;
}
+ /// isProfitableToUnpredicate - Return true if it's profitable to unpredicate
+ /// one side of a 'diamond', i.e. two sides of if-else predicated on mutually
+ /// exclusive predicates.
+ /// e.g.
+ /// subeq r0, r1, #1
+ /// addne r0, r1, #1
+ /// =>
+ /// sub r0, r1, #1
+ /// addne r0, r1, #1
+ ///
+ /// This may be profitable is conditional instructions are always executed.
+ virtual bool isProfitableToUnpredicate(MachineBasicBlock &TMBB,
+ MachineBasicBlock &FMBB) const {
+ return false;
+ }
+
/// copyPhysReg - Emit instructions to copy a pair of physical registers.
virtual void copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI, DebugLoc DL,
unsigned DestReg, unsigned SrcReg,
bool KillSrc) const {
- assert(0 && "Target didn't implement TargetInstrInfo::copyPhysReg!");
+ llvm_unreachable("Target didn't implement TargetInstrInfo::copyPhysReg!");
}
/// storeRegToStackSlot - Store the specified register of the given register
@@ -371,7 +386,8 @@ public:
unsigned SrcReg, bool isKill, int FrameIndex,
const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const {
- assert(0 && "Target didn't implement TargetInstrInfo::storeRegToStackSlot!");
+ llvm_unreachable("Target didn't implement "
+ "TargetInstrInfo::storeRegToStackSlot!");
}
/// loadRegFromStackSlot - Load the specified register of the given register
@@ -383,7 +399,8 @@ public:
unsigned DestReg, int FrameIndex,
const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const {
- assert(0 && "Target didn't implement TargetInstrInfo::loadRegFromStackSlot!");
+ llvm_unreachable("Target didn't implement "
+ "TargetInstrInfo::loadRegFromStackSlot!");
}
/// expandPostRAPseudo - This function is called for all pseudo instructions
@@ -535,7 +552,7 @@ public:
/// isUnpredicatedTerminator - Returns true if the instruction is a
/// terminator instruction that has not been predicated.
- virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const;
+ virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const = 0;
/// PredicateInstruction - Convert the instruction into a predicated
/// instruction. It returns true if the operation was successful.
@@ -646,7 +663,16 @@ public:
virtual int getOperandLatency(const InstrItineraryData *ItinData,
SDNode *DefNode, unsigned DefIdx,
- SDNode *UseNode, unsigned UseIdx) const;
+ SDNode *UseNode, unsigned UseIdx) const = 0;
+
+ /// getOutputLatency - Compute and return the output dependency latency of a
+ /// a given pair of defs which both target the same register. This is usually
+ /// one.
+ virtual unsigned getOutputLatency(const InstrItineraryData *ItinData,
+ const MachineInstr *DefMI, unsigned DefIdx,
+ const MachineInstr *DepMI) const {
+ return 1;
+ }
/// getInstrLatency - Compute the instruction latency of a given instruction.
/// If the instruction has higher cost when predicated, it's returned via
@@ -656,7 +682,7 @@ public:
unsigned *PredCost = 0) const;
virtual int getInstrLatency(const InstrItineraryData *ItinData,
- SDNode *Node) const;
+ SDNode *Node) const = 0;
/// isHighLatencyDef - Return true if this opcode has high latency to its
/// result.
@@ -718,6 +744,80 @@ public:
///
virtual void setExecutionDomain(MachineInstr *MI, unsigned Domain) const {}
+
+ /// getPartialRegUpdateClearance - Returns the preferred minimum clearance
+ /// before an instruction with an unwanted partial register update.
+ ///
+ /// Some instructions only write part of a register, and implicitly need to
+ /// read the other parts of the register. This may cause unwanted stalls
+ /// preventing otherwise unrelated instructions from executing in parallel in
+ /// an out-of-order CPU.
+ ///
+ /// For example, the x86 instruction cvtsi2ss writes its result to bits
+ /// [31:0] of the destination xmm register. Bits [127:32] are unaffected, so
+ /// the instruction needs to wait for the old value of the register to become
+ /// available:
+ ///
+ /// addps %xmm1, %xmm0
+ /// movaps %xmm0, (%rax)
+ /// cvtsi2ss %rbx, %xmm0
+ ///
+ /// In the code above, the cvtsi2ss instruction needs to wait for the addps
+ /// instruction before it can issue, even though the high bits of %xmm0
+ /// probably aren't needed.
+ ///
+ /// This hook returns the preferred clearance before MI, measured in
+ /// instructions. Other defs of MI's operand OpNum are avoided in the last N
+ /// instructions before MI. It should only return a positive value for
+ /// unwanted dependencies. If the old bits of the defined register have
+ /// useful values, or if MI is determined to otherwise read the dependency,
+ /// the hook should return 0.
+ ///
+ /// The unwanted dependency may be handled by:
+ ///
+ /// 1. Allocating the same register for an MI def and use. That makes the
+ /// unwanted dependency identical to a required dependency.
+ ///
+ /// 2. Allocating a register for the def that has no defs in the previous N
+ /// instructions.
+ ///
+ /// 3. Calling breakPartialRegDependency() with the same arguments. This
+ /// allows the target to insert a dependency breaking instruction.
+ ///
+ virtual unsigned
+ getPartialRegUpdateClearance(const MachineInstr *MI, unsigned OpNum,
+ const TargetRegisterInfo *TRI) const {
+ // The default implementation returns 0 for no partial register dependency.
+ return 0;
+ }
+
+ /// breakPartialRegDependency - Insert a dependency-breaking instruction
+ /// before MI to eliminate an unwanted dependency on OpNum.
+ ///
+ /// If it wasn't possible to avoid a def in the last N instructions before MI
+ /// (see getPartialRegUpdateClearance), this hook will be called to break the
+ /// unwanted dependency.
+ ///
+ /// On x86, an xorps instruction can be used as a dependency breaker:
+ ///
+ /// addps %xmm1, %xmm0
+ /// movaps %xmm0, (%rax)
+ /// xorps %xmm0, %xmm0
+ /// cvtsi2ss %rbx, %xmm0
+ ///
+ /// An <imp-kill> operand should be added to MI if an instruction was
+ /// inserted. This ties the instructions together in the post-ra scheduler.
+ ///
+ virtual void
+ breakPartialRegDependency(MachineBasicBlock::iterator MI, unsigned OpNum,
+ const TargetRegisterInfo *TRI) const {}
+
+ /// Create machine specific model for scheduling.
+ virtual DFAPacketizer*
+ CreateTargetScheduleState(const TargetMachine*, const ScheduleDAG*) const {
+ return NULL;
+ }
+
private:
int CallFrameSetupOpcode, CallFrameDestroyOpcode;
};
@@ -746,6 +846,7 @@ public:
virtual bool hasStoreToStackSlot(const MachineInstr *MI,
const MachineMemOperand *&MMO,
int &FrameIndex) const;
+ virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const;
virtual bool PredicateInstruction(MachineInstr *MI,
const SmallVectorImpl<MachineOperand> &Pred) const;
virtual void reMaterialize(MachineBasicBlock &MBB,
@@ -761,6 +862,13 @@ public:
virtual bool isSchedulingBoundary(const MachineInstr *MI,
const MachineBasicBlock *MBB,
const MachineFunction &MF) const;
+ using TargetInstrInfo::getOperandLatency;
+ virtual int getOperandLatency(const InstrItineraryData *ItinData,
+ SDNode *DefNode, unsigned DefIdx,
+ SDNode *UseNode, unsigned UseIdx) const;
+ using TargetInstrInfo::getInstrLatency;
+ virtual int getInstrLatency(const InstrItineraryData *ItinData,
+ SDNode *Node) const;
bool usePreRAHazardRecognizer() const;
diff --git a/include/llvm/Target/TargetJITInfo.h b/include/llvm/Target/TargetJITInfo.h
index b198eb6..044afd9 100644
--- a/include/llvm/Target/TargetJITInfo.h
+++ b/include/llvm/Target/TargetJITInfo.h
@@ -17,9 +17,9 @@
#ifndef LLVM_TARGET_TARGETJITINFO_H
#define LLVM_TARGET_TARGETJITINFO_H
-#include <cassert>
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/DataTypes.h"
+#include <cassert>
namespace llvm {
class Function;
@@ -30,6 +30,7 @@ namespace llvm {
/// TargetJITInfo - Target specific information required by the Just-In-Time
/// code generator.
class TargetJITInfo {
+ virtual void anchor();
public:
virtual ~TargetJITInfo() {}
@@ -45,8 +46,8 @@ namespace llvm {
/// ptr.
virtual void *emitGlobalValueIndirectSym(const GlobalValue* GV, void *ptr,
JITCodeEmitter &JCE) {
- assert(0 && "This target doesn't implement emitGlobalValueIndirectSym!");
- return 0;
+ llvm_unreachable("This target doesn't implement "
+ "emitGlobalValueIndirectSym!");
}
/// Records the required size and alignment for a call stub in bytes.
@@ -57,8 +58,6 @@ namespace llvm {
/// Returns the maximum size and alignment for a call stub on this target.
virtual StubLayout getStubLayout() {
llvm_unreachable("This target doesn't implement getStubLayout!");
- StubLayout Result = {0, 0};
- return Result;
}
/// emitFunctionStub - Use the specified JITCodeEmitter object to emit a
@@ -68,15 +67,13 @@ namespace llvm {
/// aligned from the address the JCE was set up to emit at.
virtual void *emitFunctionStub(const Function* F, void *Target,
JITCodeEmitter &JCE) {
- assert(0 && "This target doesn't implement emitFunctionStub!");
- return 0;
+ llvm_unreachable("This target doesn't implement emitFunctionStub!");
}
/// getPICJumpTableEntry - Returns the value of the jumptable entry for the
/// specific basic block.
virtual uintptr_t getPICJumpTableEntry(uintptr_t BB, uintptr_t JTBase) {
- assert(0 && "This target doesn't implement getPICJumpTableEntry!");
- return 0;
+ llvm_unreachable("This target doesn't implement getPICJumpTableEntry!");
}
/// LazyResolverFn - This typedef is used to represent the function that
@@ -97,8 +94,7 @@ namespace llvm {
/// function, and giving the JIT the target function used to do the lazy
/// resolving.
virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn) {
- assert(0 && "Not implemented for this target!");
- return 0;
+ llvm_unreachable("Not implemented for this target!");
}
/// relocate - Before the JIT can run a block of code that has been emitted,
@@ -114,8 +110,7 @@ namespace llvm {
/// handling thread local variables. This method returns a value only
/// meaningful to the target.
virtual char* allocateThreadLocalMemory(size_t size) {
- assert(0 && "This target does not implement thread local storage!");
- return 0;
+ llvm_unreachable("This target does not implement thread local storage!");
}
/// needsGOT - Allows a target to specify that it would like the
diff --git a/include/llvm/Target/TargetLibraryInfo.h b/include/llvm/Target/TargetLibraryInfo.h
index 02a1a3c..70e26bf 100644
--- a/include/llvm/Target/TargetLibraryInfo.h
+++ b/include/llvm/Target/TargetLibraryInfo.h
@@ -11,33 +11,204 @@
#define LLVM_TARGET_TARGETLIBRARYINFO_H
#include "llvm/Pass.h"
+#include "llvm/ADT/DenseMap.h"
namespace llvm {
class Triple;
namespace LibFunc {
enum Func {
- /// void *memset(void *b, int c, size_t len);
- memset,
-
- // void *memcpy(void *s1, const void *s2, size_t n);
+ /// double acos(double x);
+ acos,
+ /// long double acosl(long double x);
+ acosl,
+ /// float acosf(float x);
+ acosf,
+ /// double asin(double x);
+ asin,
+ /// long double asinl(long double x);
+ asinl,
+ /// float asinf(float x);
+ asinf,
+ /// double atan(double x);
+ atan,
+ /// long double atanl(long double x);
+ atanl,
+ /// float atanf(float x);
+ atanf,
+ /// double atan2(double y, double x);
+ atan2,
+ /// long double atan2l(long double y, long double x);
+ atan2l,
+ /// float atan2f(float y, float x);
+ atan2f,
+ /// double ceil(double x);
+ ceil,
+ /// long double ceill(long double x);
+ ceill,
+ /// float ceilf(float x);
+ ceilf,
+ /// double copysign(double x, double y);
+ copysign,
+ /// float copysignf(float x, float y);
+ copysignf,
+ /// long double copysignl(long double x, long double y);
+ copysignl,
+ /// double cos(double x);
+ cos,
+ /// long double cosl(long double x);
+ cosl,
+ /// float cosf(float x);
+ cosf,
+ /// double cosh(double x);
+ cosh,
+ /// long double coshl(long double x);
+ coshl,
+ /// float coshf(float x);
+ coshf,
+ /// double exp(double x);
+ exp,
+ /// long double expl(long double x);
+ expl,
+ /// float expf(float x);
+ expf,
+ /// double exp2(double x);
+ exp2,
+ /// long double exp2l(long double x);
+ exp2l,
+ /// float exp2f(float x);
+ exp2f,
+ /// double expm1(double x);
+ expm1,
+ /// long double expm1l(long double x);
+ expm1l,
+ /// float expm1f(float x);
+ expl1f,
+ /// double fabs(double x);
+ fabs,
+ /// long double fabsl(long double x);
+ fabsl,
+ /// float fabsf(float x);
+ fabsf,
+ /// double floor(double x);
+ floor,
+ /// long double floorl(long double x);
+ floorl,
+ /// float floorf(float x);
+ floorf,
+ /// int fiprintf(FILE *stream, const char *format, ...);
+ fiprintf,
+ /// double fmod(double x, double y);
+ fmod,
+ /// long double fmodl(long double x, long double y);
+ fmodl,
+ /// float fmodf(float x, float y);
+ fmodf,
+ /// int fputs(const char *s, FILE *stream);
+ fputs,
+ /// size_t fwrite(const void *ptr, size_t size, size_t nitems,
+ /// FILE *stream);
+ fwrite,
+ /// int iprintf(const char *format, ...);
+ iprintf,
+ /// double log(double x);
+ log,
+ /// long double logl(long double x);
+ logl,
+ /// float logf(float x);
+ logf,
+ /// double log2(double x);
+ log2,
+ /// double long double log2l(long double x);
+ log2l,
+ /// float log2f(float x);
+ log2f,
+ /// double log10(double x);
+ log10,
+ /// long double log10l(long double x);
+ log10l,
+ /// float log10f(float x);
+ log10f,
+ /// double log1p(double x);
+ log1p,
+ /// long double log1pl(long double x);
+ log1pl,
+ /// float log1pf(float x);
+ log1pf,
+ /// void *memcpy(void *s1, const void *s2, size_t n);
memcpy,
-
- // void *memmove(void *s1, const void *s2, size_t n);
+ /// void *memmove(void *s1, const void *s2, size_t n);
memmove,
-
+ /// void *memset(void *b, int c, size_t len);
+ memset,
/// void memset_pattern16(void *b, const void *pattern16, size_t len);
memset_pattern16,
-
- /// int iprintf(const char *format, ...);
- iprintf,
-
+ /// double nearbyint(double x);
+ nearbyint,
+ /// float nearbyintf(float x);
+ nearbyintf,
+ /// long double nearbyintl(long double x);
+ nearbyintl,
+ /// double pow(double x, double y);
+ pow,
+ /// float powf(float x, float y);
+ powf,
+ /// long double powl(long double x, long double y);
+ powl,
+ /// double rint(double x);
+ rint,
+ /// float rintf(float x);
+ rintf,
+ /// long dobule rintl(long double x);
+ rintl,
+ /// double sin(double x);
+ sin,
+ /// long double sinl(long double x);
+ sinl,
+ /// float sinf(float x);
+ sinf,
+ /// double sinh(double x);
+ sinh,
+ /// long double sinhl(long double x);
+ sinhl,
+ /// float sinhf(float x);
+ sinhf,
/// int siprintf(char *str, const char *format, ...);
siprintf,
-
- /// int fiprintf(FILE *stream, const char *format, ...);
- fiprintf,
-
+ /// double sqrt(double x);
+ sqrt,
+ /// long double sqrtl(long double x);
+ sqrtl,
+ /// float sqrtf(float x);
+ sqrtf,
+ /// double tan(double x);
+ tan,
+ /// long double tanl(long double x);
+ tanl,
+ /// float tanf(float x);
+ tanf,
+ /// double tanh(double x);
+ tanh,
+ /// long double tanhl(long double x);
+ tanhl,
+ /// float tanhf(float x);
+ tanhf,
+ /// double trunc(double x);
+ trunc,
+ /// float truncf(float x);
+ truncf,
+ /// long double truncl(long double x);
+ truncl,
+ /// int __cxa_atexit(void (*f)(void *), void *p, void *d);
+ cxa_atexit,
+ /// void __cxa_guard_abort(guard_t *guard);
+ /// guard_t is int64_t in Itanium ABI or int32_t on ARM eabi.
+ cxa_guard_abort,
+ /// int __cxa_guard_acquire(guard_t *guard);
+ cxa_guard_acquire,
+ /// void __cxa_guard_release(guard_t *guard);
+ cxa_guard_release,
+
NumLibFuncs
};
}
@@ -46,7 +217,24 @@ namespace llvm {
/// library functions are available for the current target, and allows a
/// frontend to disable optimizations through -fno-builtin etc.
class TargetLibraryInfo : public ImmutablePass {
- unsigned char AvailableArray[(LibFunc::NumLibFuncs+7)/8];
+ virtual void anchor();
+ unsigned char AvailableArray[(LibFunc::NumLibFuncs+3)/4];
+ llvm::DenseMap<unsigned, std::string> CustomNames;
+ static const char* StandardNames[LibFunc::NumLibFuncs];
+
+ enum AvailabilityState {
+ StandardName = 3, // (memset to all ones)
+ CustomName = 1,
+ Unavailable = 0 // (memset to all zeros)
+ };
+ void setState(LibFunc::Func F, AvailabilityState State) {
+ AvailableArray[F/4] &= ~(3 << 2*(F&3));
+ AvailableArray[F/4] |= State << 2*(F&3);
+ }
+ AvailabilityState getState(LibFunc::Func F) const {
+ return static_cast<AvailabilityState>((AvailableArray[F/4] >> 2*(F&3)) & 3);
+ }
+
public:
static char ID;
TargetLibraryInfo();
@@ -56,19 +244,39 @@ public:
/// has - This function is used by optimizations that want to match on or form
/// a given library function.
bool has(LibFunc::Func F) const {
- return (AvailableArray[F/8] & (1 << (F&7))) != 0;
+ return getState(F) != Unavailable;
+ }
+
+ StringRef getName(LibFunc::Func F) const {
+ AvailabilityState State = getState(F);
+ if (State == Unavailable)
+ return StringRef();
+ if (State == StandardName)
+ return StandardNames[F];
+ assert(State == CustomName);
+ return CustomNames.find(F)->second;
}
/// setUnavailable - this can be used by whatever sets up TargetLibraryInfo to
/// ban use of specific library functions.
void setUnavailable(LibFunc::Func F) {
- AvailableArray[F/8] &= ~(1 << (F&7));
+ setState(F, Unavailable);
}
void setAvailable(LibFunc::Func F) {
- AvailableArray[F/8] |= 1 << (F&7);
+ setState(F, StandardName);
}
-
+
+ void setAvailableWithName(LibFunc::Func F, StringRef Name) {
+ if (StandardNames[F] != Name) {
+ setState(F, CustomName);
+ CustomNames[F] = Name;
+ assert(CustomNames.find(F) != CustomNames.end());
+ } else {
+ setState(F, StandardName);
+ }
+ }
+
/// disableAllFunctions - This disables all builtins, which is used for
/// options like -fno-builtin.
void disableAllFunctions();
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index 013e70a..720c9df 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -25,7 +25,6 @@
#include "llvm/CallingConv.h"
#include "llvm/InlineAsm.h"
#include "llvm/Attributes.h"
-#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/CodeGen/RuntimeLibcalls.h"
#include "llvm/Support/DebugLoc.h"
@@ -36,41 +35,34 @@
#include <vector>
namespace llvm {
- class AllocaInst;
- class APFloat;
class CallInst;
class CCState;
- class Function;
class FastISel;
class FunctionLoweringInfo;
class ImmutableCallSite;
+ class IntrinsicInst;
class MachineBasicBlock;
class MachineFunction;
- class MachineFrameInfo;
class MachineInstr;
class MachineJumpTableInfo;
class MCContext;
class MCExpr;
- class SDNode;
- class SDValue;
- class SelectionDAG;
template<typename T> class SmallVectorImpl;
class TargetData;
- class TargetMachine;
class TargetRegisterClass;
class TargetLoweringObjectFile;
class Value;
- // FIXME: should this be here?
- namespace TLSModel {
- enum Model {
- GeneralDynamic,
- LocalDynamic,
- InitialExec,
- LocalExec
+ namespace Sched {
+ enum Preference {
+ None, // No preference
+ Source, // Follow source order.
+ RegPressure, // Scheduling for lowest register pressure.
+ Hybrid, // Scheduling for both latency and register pressure.
+ ILP, // Scheduling for ILP in low register pressure mode.
+ VLIW // Scheduling for VLIW targets.
};
}
- TLSModel::Model getTLSModel(const GlobalValue *GV, Reloc::Model reloc);
//===----------------------------------------------------------------------===//
@@ -94,7 +86,7 @@ public:
Custom // Use the LowerOperation hook to implement custom lowering.
};
- /// LegalizeAction - This enum indicates whether a types are legal for a
+ /// LegalizeTypeAction - This enum indicates whether a types are legal for a
/// target, and if not, what action should be used to make them valid.
enum LegalizeTypeAction {
TypeLegal, // The target natively supports this type.
@@ -115,8 +107,6 @@ public:
static ISD::NodeType getExtendForContent(BooleanContent Content) {
switch (Content) {
- default:
- assert(false && "Unknown BooleanContent!");
case UndefinedBooleanContent:
// Extend by adding rubbish bits.
return ISD::ANY_EXTEND;
@@ -127,6 +117,7 @@ public:
// Extend by copying the sign bit.
return ISD::SIGN_EXTEND;
}
+ llvm_unreachable("Invalid content kind");
}
/// NOTE: The constructor takes ownership of TLOF.
@@ -199,9 +190,9 @@ public:
/// getRegClassFor - Return the register class that should be used for the
/// specified value type.
- virtual TargetRegisterClass *getRegClassFor(EVT VT) const {
+ virtual const TargetRegisterClass *getRegClassFor(EVT VT) const {
assert(VT.isSimple() && "getRegClassFor called on illegal type!");
- TargetRegisterClass *RC = RegClassForVT[VT.getSimpleVT().SimpleTy];
+ const TargetRegisterClass *RC = RegClassForVT[VT.getSimpleVT().SimpleTy];
assert(RC && "This value type is not natively supported!");
return RC;
}
@@ -292,11 +283,9 @@ public:
VT = getTypeToTransformTo(Context, VT);
break;
default:
- assert(false && "Type is not legal nor is it to be expanded!");
- return VT;
+ llvm_unreachable("Type is not legal nor is it to be expanded!");
}
}
- return VT;
}
/// getVectorTypeBreakdown - Vector types are broken down into some number of
@@ -520,8 +509,19 @@ public:
/// AllowUnknown is true, this will return MVT::Other for types with no EVT
/// counterpart (e.g. structs), otherwise it will assert.
EVT getValueType(Type *Ty, bool AllowUnknown = false) const {
- EVT VT = EVT::getEVT(Ty, AllowUnknown);
- return VT == MVT::iPTR ? PointerTy : VT;
+ // Lower scalar pointers to native pointer types.
+ if (Ty->isPointerTy()) return PointerTy;
+
+ if (Ty->isVectorTy()) {
+ VectorType *VTy = cast<VectorType>(Ty);
+ Type *Elm = VTy->getElementType();
+ // Lower vectors of pointers to native pointer types.
+ if (Elm->isPointerTy())
+ Elm = EVT(PointerTy).getTypeForEVT(Ty->getContext());
+ return EVT::getVectorVT(Ty->getContext(), EVT::getEVT(Elm, false),
+ VTy->getNumElements());
+ }
+ return EVT::getEVT(Ty, AllowUnknown);
}
/// getByValTypeAlignment - Return the desired alignment for ByVal aggregate
@@ -554,8 +554,7 @@ public:
if (VT.isInteger()) {
return getRegisterType(Context, getTypeToTransformTo(Context, VT));
}
- assert(0 && "Unsupported extended type!");
- return EVT(MVT::Other); // Not reached
+ llvm_unreachable("Unsupported extended type!");
}
/// getNumRegisters - Return the number of registers that this ValueType will
@@ -580,8 +579,7 @@ public:
unsigned RegWidth = getRegisterType(Context, VT).getSizeInBits();
return (BitWidth + RegWidth - 1) / RegWidth;
}
- assert(0 && "Unsupported extended type!");
- return 0; // Not reached
+ llvm_unreachable("Unsupported extended type!");
}
/// ShouldShrinkFPConstant - If true, then instruction selection should
@@ -646,7 +644,7 @@ public:
/// alignment can satisfy any constraint. Similarly if SrcAlign is zero it
/// means there isn't a need to check it against alignment requirement,
/// probably because the source does not need to be loaded. If
- /// 'NonScalarIntSafe' is true, that means it's safe to return a
+ /// 'IsZeroVal' is true, that means it's safe to return a
/// non-scalar-integer type, e.g. empty string source, constant, or loaded
/// from memory. 'MemcpyStrSrc' indicates whether the memcpy source is
/// constant so it does not need to be loaded.
@@ -654,7 +652,7 @@ public:
/// target-independent logic.
virtual EVT getOptimalMemOpType(uint64_t /*Size*/,
unsigned /*DstAlign*/, unsigned /*SrcAlign*/,
- bool /*NonScalarIntSafe*/,
+ bool /*IsZeroVal*/,
bool /*MemcpyStrSrc*/,
MachineFunction &/*MF*/) const {
return MVT::Other;
@@ -679,10 +677,10 @@ public:
return StackPointerRegisterToSaveRestore;
}
- /// getExceptionAddressRegister - If a physical register, this returns
+ /// getExceptionPointerRegister - If a physical register, this returns
/// the register that receives the exception address on entry to a landing
/// pad.
- unsigned getExceptionAddressRegister() const {
+ unsigned getExceptionPointerRegister() const {
return ExceptionPointerRegister;
}
@@ -772,8 +770,7 @@ public:
LowerCustomJumpTableEntry(const MachineJumpTableInfo * /*MJTI*/,
const MachineBasicBlock * /*MBB*/, unsigned /*uid*/,
MCContext &/*Ctx*/) const {
- assert(0 && "Need to implement this hook if target has custom JTIs");
- return 0;
+ llvm_unreachable("Need to implement this hook if target has custom JTIs");
}
/// getPICJumpTableRelocaBase - Returns relocation base for the given PIC
@@ -865,7 +862,6 @@ public:
/// Mask are known to be either zero or one and return them in the
/// KnownZero/KnownOne bitsets.
virtual void computeMaskedBitsForTargetNode(const SDValue Op,
- const APInt &Mask,
APInt &KnownZero,
APInt &KnownOne,
const SelectionDAG &DAG,
@@ -1035,7 +1031,7 @@ protected:
/// addRegisterClass - Add the specified register class as an available
/// regclass for the specified value type. This indicates the selector can
/// handle values of that class natively.
- void addRegisterClass(EVT VT, TargetRegisterClass *RC) {
+ void addRegisterClass(EVT VT, const TargetRegisterClass *RC) {
assert((unsigned)VT.getSimpleVT().SimpleTy < array_lengthof(RegClassForVT));
AvailableRegClasses.push_back(std::make_pair(VT, RC));
RegClassForVT[VT.getSimpleVT().SimpleTy] = RC;
@@ -1141,26 +1137,28 @@ protected:
JumpBufAlignment = Align;
}
- /// setMinFunctionAlignment - Set the target's minimum function alignment.
+ /// setMinFunctionAlignment - Set the target's minimum function alignment (in
+ /// log2(bytes))
void setMinFunctionAlignment(unsigned Align) {
MinFunctionAlignment = Align;
}
/// setPrefFunctionAlignment - Set the target's preferred function alignment.
/// This should be set if there is a performance benefit to
- /// higher-than-minimum alignment
+ /// higher-than-minimum alignment (in log2(bytes))
void setPrefFunctionAlignment(unsigned Align) {
PrefFunctionAlignment = Align;
}
/// setPrefLoopAlignment - Set the target's preferred loop alignment. Default
/// alignment is zero, it means the target does not care about loop alignment.
+ /// The alignment is specified in log2(bytes).
void setPrefLoopAlignment(unsigned Align) {
PrefLoopAlignment = Align;
}
/// setMinStackArgumentAlignment - Set the minimum stack alignment of an
- /// argument.
+ /// argument (in log2(bytes)).
void setMinStackArgumentAlignment(unsigned Align) {
MinStackArgumentAlignment = Align;
}
@@ -1196,8 +1194,7 @@ public:
const SmallVectorImpl<ISD::InputArg> &/*Ins*/,
DebugLoc /*dl*/, SelectionDAG &/*DAG*/,
SmallVectorImpl<SDValue> &/*InVals*/) const {
- assert(0 && "Not Implemented");
- return SDValue(); // this is here to silence compiler errors
+ llvm_unreachable("Not Implemented");
}
/// LowerCallTo - This function lowers an abstract call to a function into an
@@ -1224,7 +1221,8 @@ public:
LowerCallTo(SDValue Chain, Type *RetTy, bool RetSExt, bool RetZExt,
bool isVarArg, bool isInreg, unsigned NumFixedArgs,
CallingConv::ID CallConv, bool isTailCall,
- bool isReturnValueUsed, SDValue Callee, ArgListTy &Args,
+ bool doesNotRet, bool isReturnValueUsed,
+ SDValue Callee, ArgListTy &Args,
SelectionDAG &DAG, DebugLoc dl) const;
/// LowerCall - This hook must be implemented to lower calls into the
@@ -1236,14 +1234,13 @@ public:
virtual SDValue
LowerCall(SDValue /*Chain*/, SDValue /*Callee*/,
CallingConv::ID /*CallConv*/, bool /*isVarArg*/,
- bool &/*isTailCall*/,
+ bool /*doesNotRet*/, bool &/*isTailCall*/,
const SmallVectorImpl<ISD::OutputArg> &/*Outs*/,
const SmallVectorImpl<SDValue> &/*OutVals*/,
const SmallVectorImpl<ISD::InputArg> &/*Ins*/,
DebugLoc /*dl*/, SelectionDAG &/*DAG*/,
SmallVectorImpl<SDValue> &/*InVals*/) const {
- assert(0 && "Not Implemented");
- return SDValue(); // this is here to silence compiler errors
+ llvm_unreachable("Not Implemented");
}
/// HandleByVal - Target-specific cleanup for formal ByVal parameters.
@@ -1273,14 +1270,15 @@ public:
const SmallVectorImpl<ISD::OutputArg> &/*Outs*/,
const SmallVectorImpl<SDValue> &/*OutVals*/,
DebugLoc /*dl*/, SelectionDAG &/*DAG*/) const {
- assert(0 && "Not Implemented");
- return SDValue(); // this is here to silence compiler errors
+ llvm_unreachable("Not Implemented");
}
/// isUsedByReturnOnly - Return true if result of the specified node is used
- /// by a return node only. This is used to determine whether it is possible
+ /// by a return node only. It also compute and return the input chain for the
+ /// tail call.
+ /// This is used to determine whether it is possible
/// to codegen a libcall as tail call at legalization time.
- virtual bool isUsedByReturnOnly(SDNode *) const {
+ virtual bool isUsedByReturnOnly(SDNode *, SDValue &Chain) const {
return false;
}
@@ -1339,7 +1337,7 @@ public:
virtual void ReplaceNodeResults(SDNode * /*N*/,
SmallVectorImpl<SDValue> &/*Results*/,
SelectionDAG &/*DAG*/) const {
- assert(0 && "ReplaceNodeResults not implemented for this target!");
+ llvm_unreachable("ReplaceNodeResults not implemented for this target!");
}
/// getTargetNodeName() - This method returns the name of a target specific
@@ -1531,6 +1529,17 @@ public:
AddrMode() : BaseGV(0), BaseOffs(0), HasBaseReg(false), Scale(0) {}
};
+ /// GetAddrModeArguments - CodeGenPrepare sinks address calculations into the
+ /// same BB as Load/Store instructions reading the address. This allows as
+ /// much computation as possible to be done in the address mode for that
+ /// operand. This hook lets targets also pass back when this should be done
+ /// on intrinsics which load/store.
+ virtual bool GetAddrModeArguments(IntrinsicInst *I,
+ SmallVectorImpl<Value*> &Ops,
+ Type *&AccessTy) const {
+ return false;
+ }
+
/// isLegalAddressingMode - Return true if the addressing mode represented by
/// AM is legal for this target, for a load/store of the specified type.
/// The type may be VoidTy, in which case only return true if the addressing
@@ -1581,6 +1590,18 @@ public:
return false;
}
+ /// isFNegFree - Return true if an fneg operation is free to the point where
+ /// it is never worthwhile to replace it with a bitwise operation.
+ virtual bool isFNegFree(EVT) const {
+ return false;
+ }
+
+ /// isFAbsFree - Return true if an fneg operation is free to the point where
+ /// it is never worthwhile to replace it with a bitwise operation.
+ virtual bool isFAbsFree(EVT) const {
+ return false;
+ }
+
/// isNarrowingProfitable - Return true if it's profitable to narrow
/// operations of type VT1 to VT2. e.g. on x86, it's profitable to narrow
/// from i32 to i8 but not from i32 to i16.
@@ -1593,9 +1614,9 @@ public:
//
SDValue BuildExactSDIV(SDValue Op1, SDValue Op2, DebugLoc dl,
SelectionDAG &DAG) const;
- SDValue BuildSDIV(SDNode *N, SelectionDAG &DAG,
+ SDValue BuildSDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization,
std::vector<SDNode*>* Created) const;
- SDValue BuildUDIV(SDNode *N, SelectionDAG &DAG,
+ SDValue BuildUDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization,
std::vector<SDNode*>* Created) const;
@@ -1753,7 +1774,7 @@ private:
/// RegClassForVT - This indicates the default register class to use for
/// each ValueType the target supports natively.
- TargetRegisterClass *RegClassForVT[MVT::LAST_VALUETYPE];
+ const TargetRegisterClass *RegClassForVT[MVT::LAST_VALUETYPE];
unsigned char NumRegistersForVT[MVT::LAST_VALUETYPE];
EVT RegisterTypeForVT[MVT::LAST_VALUETYPE];
@@ -1925,12 +1946,9 @@ private:
// Vectors with illegal element types are expanded.
EVT NVT = EVT::getVectorVT(Context, EltVT, VT.getVectorNumElements() / 2);
return LegalizeKind(TypeSplitVector, NVT);
-
- assert(false && "Unable to handle this kind of vector type");
- return LegalizeKind(TypeLegal, VT);
}
- std::vector<std::pair<EVT, TargetRegisterClass*> > AvailableRegClasses;
+ std::vector<std::pair<EVT, const TargetRegisterClass*> > AvailableRegClasses;
/// TargetDAGCombineArray - Targets can specify ISD nodes that they would
/// like PerformDAGCombine callbacks for by calling setTargetDAGCombine(),
diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h
index 7d06cec..d631f58 100644
--- a/include/llvm/Target/TargetLoweringObjectFile.h
+++ b/include/llvm/Target/TargetLoweringObjectFile.h
@@ -15,18 +15,17 @@
#ifndef LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H
#define LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H
-#include "llvm/ADT/StringRef.h"
+#include "llvm/Module.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/SectionKind.h"
+#include "llvm/ADT/ArrayRef.h"
namespace llvm {
class MachineModuleInfo;
class Mangler;
- class MCAsmInfo;
class MCContext;
class MCExpr;
class MCSection;
- class MCSectionMachO;
class MCSymbol;
class MCStreamer;
class GlobalValue;
@@ -53,7 +52,13 @@ public:
virtual void emitPersonalityValue(MCStreamer &Streamer,
const TargetMachine &TM,
const MCSymbol *Sym) const;
-
+
+ /// emitModuleFlags - Emit the module flags that the platform cares about.
+ virtual void emitModuleFlags(MCStreamer &,
+ ArrayRef<Module::ModuleFlagEntry>,
+ Mangler *, const TargetMachine &) const {
+ }
+
/// shouldEmitUsedDirectiveFor - This hook allows targets to selectively
/// decide not to emit the UsedDirective for some symbols in llvm.used.
/// FIXME: REMOVE this (rdar://7071300)
@@ -86,9 +91,7 @@ public:
const TargetMachine &TM) const {
return SectionForGlobal(GV, getKindForGlobal(GV, TM), Mang, TM);
}
-
-
-
+
/// getExplicitSectionGlobal - Targets should implement this method to assign
/// a section to globals with an explicit section specfied. The
/// implementation of this method can assume that GV->hasSection() is true.
@@ -121,7 +124,18 @@ public:
const MCExpr *
getExprForDwarfReference(const MCSymbol *Sym, unsigned Encoding,
MCStreamer &Streamer) const;
-
+
+ virtual const MCSection *
+ getStaticCtorSection(unsigned Priority = 65535) const {
+ (void)Priority;
+ return StaticCtorSection;
+ }
+ virtual const MCSection *
+ getStaticDtorSection(unsigned Priority = 65535) const {
+ (void)Priority;
+ return StaticDtorSection;
+ }
+
protected:
virtual const MCSection *
SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index 8a8d142..1a05604 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -14,7 +14,8 @@
#ifndef LLVM_TARGET_TARGETMACHINE_H
#define LLVM_TARGET_TARGETMACHINE_H
-#include "llvm/MC/MCCodeGenInfo.h"
+#include "llvm/Support/CodeGen.h"
+#include "llvm/Target/TargetOptions.h"
#include "llvm/ADT/StringRef.h"
#include <cassert>
#include <string>
@@ -23,11 +24,10 @@ namespace llvm {
class InstrItineraryData;
class JITCodeEmitter;
+class GlobalValue;
class MCAsmInfo;
class MCCodeGenInfo;
class MCContext;
-class Pass;
-class PassManager;
class PassManagerBase;
class Target;
class TargetData;
@@ -37,32 +37,13 @@ class TargetInstrInfo;
class TargetIntrinsicInfo;
class TargetJITInfo;
class TargetLowering;
+class TargetPassConfig;
class TargetRegisterInfo;
class TargetSelectionDAGInfo;
class TargetSubtargetInfo;
class formatted_raw_ostream;
class raw_ostream;
-// Code generation optimization level.
-namespace CodeGenOpt {
- enum Level {
- None, // -O0
- Less, // -O1
- Default, // -O2, -Os
- Aggressive // -O3
- };
-}
-
-namespace Sched {
- enum Preference {
- None, // No preference
- Latency, // Scheduling for shortest total latency.
- RegPressure, // Scheduling for lowest register pressure.
- Hybrid, // Scheduling for both latency and register pressure.
- ILP // Scheduling for ILP in low register pressure mode.
- };
-}
-
//===----------------------------------------------------------------------===//
///
/// TargetMachine - Primary interface to the complete machine description for
@@ -74,7 +55,7 @@ class TargetMachine {
void operator=(const TargetMachine &); // DO NOT IMPLEMENT
protected: // Can only create subclasses.
TargetMachine(const Target &T, StringRef TargetTriple,
- StringRef CPU, StringRef FS);
+ StringRef CPU, StringRef FS, const TargetOptions &Options);
/// getSubtargetImpl - virtual method implemented by subclasses that returns
/// a reference to that target's TargetSubtargetInfo-derived member variable.
@@ -101,6 +82,7 @@ protected: // Can only create subclasses.
unsigned MCSaveTempLabels : 1;
unsigned MCUseLoc : 1;
unsigned MCUseCFI : 1;
+ unsigned MCUseDwarfDirectory : 1;
public:
virtual ~TargetMachine();
@@ -111,6 +93,8 @@ public:
const StringRef getTargetCPU() const { return TargetCPU; }
const StringRef getTargetFeatureString() const { return TargetFS; }
+ TargetOptions Options;
+
// Interfaces to the major aspects of target machine information:
// -- Instruction opcode and operand information
// -- Pipelines and scheduling information
@@ -196,6 +180,14 @@ public:
/// setMCUseCFI - Set whether all we should use dwarf's .cfi_* directives.
void setMCUseCFI(bool Value) { MCUseCFI = Value; }
+ /// hasMCUseDwarfDirectory - Check whether we should use .file directives with
+ /// explicit directories.
+ bool hasMCUseDwarfDirectory() const { return MCUseDwarfDirectory; }
+
+ /// setMCUseDwarfDirectory - Set whether all we should use .file directives
+ /// with explicit directories.
+ void setMCUseDwarfDirectory(bool Value) { MCUseDwarfDirectory = Value; }
+
/// getRelocationModel - Returns the code generation relocation model. The
/// choices are static, PIC, and dynamic-no-pic, and target default.
Reloc::Model getRelocationModel() const;
@@ -204,6 +196,18 @@ public:
/// medium, large, and target default.
CodeModel::Model getCodeModel() const;
+ /// getTLSModel - Returns the TLS model which should be used for the given
+ /// global variable.
+ TLSModel::Model getTLSModel(const GlobalValue *GV) const;
+
+ /// getOptLevel - Returns the optimization level: None, Less,
+ /// Default, or Aggressive.
+ CodeGenOpt::Level getOptLevel() const;
+
+ void setFastISel(bool Enable) { Options.EnableFastISel = Enable; }
+
+ bool shouldPrintMachineCode() const { return Options.PrintMachineCode; }
+
/// getAsmVerbosityDefault - Returns the default value of asm verbosity.
///
static bool getAsmVerbosityDefault();
@@ -236,10 +240,6 @@ public:
CGFT_Null // Do not emit any output.
};
- /// getEnableTailMergeDefault - the default setting for -enable-tail-merge
- /// on this target. User flag overrides.
- virtual bool getEnableTailMergeDefault() const { return true; }
-
/// addPassesToEmitFile - Add passes to the specified pass manager to get the
/// specified file emitted. Typically this will involve several steps of code
/// generation. This method should return true if emission of this file type
@@ -247,8 +247,7 @@ public:
virtual bool addPassesToEmitFile(PassManagerBase &,
formatted_raw_ostream &,
CodeGenFileType,
- CodeGenOpt::Level,
- bool = true) {
+ bool /*DisableVerify*/ = true) {
return true;
}
@@ -260,8 +259,7 @@ public:
///
virtual bool addPassesToEmitMachineCode(PassManagerBase &,
JITCodeEmitter &,
- CodeGenOpt::Level,
- bool = true) {
+ bool /*DisableVerify*/ = true) {
return true;
}
@@ -273,8 +271,7 @@ public:
virtual bool addPassesToEmitMC(PassManagerBase &,
MCContext *&,
raw_ostream &,
- CodeGenOpt::Level,
- bool = true) {
+ bool /*DisableVerify*/ = true) {
return true;
}
};
@@ -285,25 +282,21 @@ public:
class LLVMTargetMachine : public TargetMachine {
protected: // Can only create subclasses.
LLVMTargetMachine(const Target &T, StringRef TargetTriple,
- StringRef CPU, StringRef FS,
- Reloc::Model RM, CodeModel::Model CM);
-
-private:
- /// addCommonCodeGenPasses - Add standard LLVM codegen passes used for
- /// both emitting to assembly files or machine code output.
- ///
- bool addCommonCodeGenPasses(PassManagerBase &, CodeGenOpt::Level,
- bool DisableVerify, MCContext *&OutCtx);
+ StringRef CPU, StringRef FS, TargetOptions Options,
+ Reloc::Model RM, CodeModel::Model CM,
+ CodeGenOpt::Level OL);
public:
+ /// createPassConfig - Create a pass configuration object to be used by
+ /// addPassToEmitX methods for generating a pipeline of CodeGen passes.
+ virtual TargetPassConfig *createPassConfig(PassManagerBase &PM);
+
/// addPassesToEmitFile - Add passes to the specified pass manager to get the
/// specified file emitted. Typically this will involve several steps of code
- /// generation. If OptLevel is None, the code generator should emit code as
- /// fast as possible, though the generated code may be less efficient.
+ /// generation.
virtual bool addPassesToEmitFile(PassManagerBase &PM,
formatted_raw_ostream &Out,
CodeGenFileType FileType,
- CodeGenOpt::Level,
bool DisableVerify = true);
/// addPassesToEmitMachineCode - Add passes to the specified pass manager to
@@ -314,7 +307,6 @@ public:
///
virtual bool addPassesToEmitMachineCode(PassManagerBase &PM,
JITCodeEmitter &MCE,
- CodeGenOpt::Level,
bool DisableVerify = true);
/// addPassesToEmitMC - Add passes to the specified pass manager to get
@@ -325,65 +317,15 @@ public:
virtual bool addPassesToEmitMC(PassManagerBase &PM,
MCContext *&Ctx,
raw_ostream &OS,
- CodeGenOpt::Level OptLevel,
bool DisableVerify = true);
- /// Target-Independent Code Generator Pass Configuration Options.
-
- /// addPreISelPasses - This method should add any "last minute" LLVM->LLVM
- /// passes (which are run just before instruction selector).
- virtual bool addPreISel(PassManagerBase &, CodeGenOpt::Level) {
- return true;
- }
-
- /// addInstSelector - This method should install an instruction selector pass,
- /// which converts from LLVM code to machine instructions.
- virtual bool addInstSelector(PassManagerBase &, CodeGenOpt::Level) {
- return true;
- }
-
- /// addPreRegAlloc - This method may be implemented by targets that want to
- /// run passes immediately before register allocation. This should return
- /// true if -print-machineinstrs should print after these passes.
- virtual bool addPreRegAlloc(PassManagerBase &, CodeGenOpt::Level) {
- return false;
- }
-
- /// addPostRegAlloc - This method may be implemented by targets that want
- /// to run passes after register allocation but before prolog-epilog
- /// insertion. This should return true if -print-machineinstrs should print
- /// after these passes.
- virtual bool addPostRegAlloc(PassManagerBase &, CodeGenOpt::Level) {
- return false;
- }
-
- /// addPreSched2 - This method may be implemented by targets that want to
- /// run passes after prolog-epilog insertion and before the second instruction
- /// scheduling pass. This should return true if -print-machineinstrs should
- /// print after these passes.
- virtual bool addPreSched2(PassManagerBase &, CodeGenOpt::Level) {
- return false;
- }
-
- /// addPreEmitPass - This pass may be implemented by targets that want to run
- /// passes immediately before machine code is emitted. This should return
- /// true if -print-machineinstrs should print out the code after the passes.
- virtual bool addPreEmitPass(PassManagerBase &, CodeGenOpt::Level) {
- return false;
- }
-
-
/// addCodeEmitter - This pass should be overridden by the target to add a
/// code emitter, if supported. If this is not supported, 'true' should be
/// returned.
- virtual bool addCodeEmitter(PassManagerBase &, CodeGenOpt::Level,
+ virtual bool addCodeEmitter(PassManagerBase &,
JITCodeEmitter &) {
return true;
}
-
- /// getEnableTailMergeDefault - the default setting for -enable-tail-merge
- /// on this target. User flag overrides.
- virtual bool getEnableTailMergeDefault() const { return true; }
};
} // End llvm namespace
diff --git a/include/llvm/Target/TargetOpcodes.h b/include/llvm/Target/TargetOpcodes.h
index 37f7b2f..f0b181e 100644
--- a/include/llvm/Target/TargetOpcodes.h
+++ b/include/llvm/Target/TargetOpcodes.h
@@ -82,7 +82,12 @@ namespace TargetOpcode {
/// COPY - Target-independent register copy. This instruction can also be
/// used to copy between subregisters of virtual registers.
- COPY = 13
+ COPY = 13,
+
+ /// BUNDLE - This instruction represents an instruction bundle. Instructions
+ /// which immediately follow a BUNDLE instruction which are marked with
+ /// 'InsideBundle' flag are inside the bundle.
+ BUNDLE
};
} // end namespace TargetOpcode
} // end namespace llvm
diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h
index e07e8c1..12a2757 100644
--- a/include/llvm/Target/TargetOptions.h
+++ b/include/llvm/Target/TargetOptions.h
@@ -15,151 +15,177 @@
#ifndef LLVM_TARGET_TARGETOPTIONS_H
#define LLVM_TARGET_TARGETOPTIONS_H
+#include <string>
+
namespace llvm {
class MachineFunction;
+ class StringRef;
// Possible float ABI settings. Used with FloatABIType in TargetOptions.h.
namespace FloatABI {
enum ABIType {
- Default, // Target-specific (either soft of hard depending on triple, etc).
+ Default, // Target-specific (either soft or hard depending on triple, etc).
Soft, // Soft float.
Hard // Hard float.
};
}
-
- /// PrintMachineCode - This flag is enabled when the -print-machineinstrs
- /// option is specified on the command line, and should enable debugging
- /// output from the code generator.
- extern bool PrintMachineCode;
-
- /// NoFramePointerElim - This flag is enabled when the -disable-fp-elim is
- /// specified on the command line. If the target supports the frame pointer
- /// elimination optimization, this option should disable it.
- extern bool NoFramePointerElim;
-
- /// NoFramePointerElimNonLeaf - This flag is enabled when the
- /// -disable-non-leaf-fp-elim is specified on the command line. If the target
- /// supports the frame pointer elimination optimization, this option should
- /// disable it for non-leaf functions.
- extern bool NoFramePointerElimNonLeaf;
-
- /// DisableFramePointerElim - This returns true if frame pointer elimination
- /// optimization should be disabled for the given machine function.
- extern bool DisableFramePointerElim(const MachineFunction &MF);
-
- /// LessPreciseFPMAD - This flag is enabled when the
- /// -enable-fp-mad is specified on the command line. When this flag is off
- /// (the default), the code generator is not allowed to generate mad
- /// (multiply add) if the result is "less precise" than doing those operations
- /// individually.
- extern bool LessPreciseFPMADOption;
- extern bool LessPreciseFPMAD();
-
- /// NoExcessFPPrecision - This flag is enabled when the
- /// -disable-excess-fp-precision flag is specified on the command line. When
- /// this flag is off (the default), the code generator is allowed to produce
- /// results that are "more precise" than IEEE allows. This includes use of
- /// FMA-like operations and use of the X86 FP registers without rounding all
- /// over the place.
- extern bool NoExcessFPPrecision;
-
- /// UnsafeFPMath - This flag is enabled when the
- /// -enable-unsafe-fp-math flag is specified on the command line. When
- /// this flag is off (the default), the code generator is not allowed to
- /// produce results that are "less precise" than IEEE allows. This includes
- /// use of X86 instructions like FSIN and FCOS instead of libcalls.
- /// UnsafeFPMath implies LessPreciseFPMAD.
- extern bool UnsafeFPMath;
-
- /// NoInfsFPMath - This flag is enabled when the
- /// -enable-no-infs-fp-math flag is specified on the command line. When
- /// this flag is off (the default), the code generator is not allowed to
- /// assume the FP arithmetic arguments and results are never +-Infs.
- extern bool NoInfsFPMath;
-
- /// NoNaNsFPMath - This flag is enabled when the
- /// -enable-no-nans-fp-math flag is specified on the command line. When
- /// this flag is off (the default), the code generator is not allowed to
- /// assume the FP arithmetic arguments and results are never NaNs.
- extern bool NoNaNsFPMath;
-
- /// HonorSignDependentRoundingFPMath - This returns true when the
- /// -enable-sign-dependent-rounding-fp-math is specified. If this returns
- /// false (the default), the code generator is allowed to assume that the
- /// rounding behavior is the default (round-to-zero for all floating point to
- /// integer conversions, and round-to-nearest for all other arithmetic
- /// truncations). If this is enabled (set to true), the code generator must
- /// assume that the rounding mode may dynamically change.
- extern bool HonorSignDependentRoundingFPMathOption;
- extern bool HonorSignDependentRoundingFPMath();
-
- /// UseSoftFloat - This flag is enabled when the -soft-float flag is specified
- /// on the command line. When this flag is on, the code generator will
- /// generate libcalls to the software floating point library instead of
- /// target FP instructions.
- extern bool UseSoftFloat;
-
- /// FloatABIType - This setting is set by -float-abi=xxx option is specfied
- /// on the command line. This setting may either be Default, Soft, or Hard.
- /// Default selects the target's default behavior. Soft selects the ABI for
- /// UseSoftFloat, but does not inidcate that FP hardware may not be used.
- /// Such a combination is unfortunately popular (e.g. arm-apple-darwin).
- /// Hard presumes that the normal FP ABI is used.
- extern FloatABI::ABIType FloatABIType;
-
- /// NoZerosInBSS - By default some codegens place zero-initialized data to
- /// .bss section. This flag disables such behaviour (necessary, e.g. for
- /// crt*.o compiling).
- extern bool NoZerosInBSS;
-
- /// JITExceptionHandling - This flag indicates that the JIT should emit
- /// exception handling information.
- extern bool JITExceptionHandling;
-
- /// JITEmitDebugInfo - This flag indicates that the JIT should try to emit
- /// debug information and notify a debugger about it.
- extern bool JITEmitDebugInfo;
-
- /// JITEmitDebugInfoToDisk - This flag indicates that the JIT should write
- /// the object files generated by the JITEmitDebugInfo flag to disk. This
- /// flag is hidden and is only for debugging the debug info.
- extern bool JITEmitDebugInfoToDisk;
-
- /// GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is
- /// specified on the commandline. When the flag is on, participating targets
- /// will perform tail call optimization on all calls which use the fastcc
- /// calling convention and which satisfy certain target-independent
- /// criteria (being at the end of a function, having the same return type
- /// as their parent function, etc.), using an alternate ABI if necessary.
- extern bool GuaranteedTailCallOpt;
-
- /// StackAlignmentOverride - Override default stack alignment for target.
- extern unsigned StackAlignmentOverride;
-
- /// RealignStack - This flag indicates whether the stack should be
- /// automatically realigned, if needed.
- extern bool RealignStack;
-
- /// DisableJumpTables - This flag indicates jump tables should not be
- /// generated.
- extern bool DisableJumpTables;
-
- /// EnableFastISel - This flag enables fast-path instruction selection
- /// which trades away generated code quality in favor of reducing
- /// compile time.
- extern bool EnableFastISel;
-
- /// StrongPHIElim - This flag enables more aggressive PHI elimination
- /// wth earlier copy coalescing.
- extern bool StrongPHIElim;
-
- /// getTrapFunctionName - If this returns a non-empty string, this means isel
- /// should lower Intrinsic::trap to a call to the specified function name
- /// instead of an ISD::TRAP node.
- extern StringRef getTrapFunctionName();
-
- extern bool EnableSegmentedStacks;
+ class TargetOptions {
+ public:
+ TargetOptions()
+ : PrintMachineCode(false), NoFramePointerElim(false),
+ NoFramePointerElimNonLeaf(false), LessPreciseFPMADOption(false),
+ NoExcessFPPrecision(false), UnsafeFPMath(false), NoInfsFPMath(false),
+ NoNaNsFPMath(false), HonorSignDependentRoundingFPMathOption(false),
+ UseSoftFloat(false), NoZerosInBSS(false), JITExceptionHandling(false),
+ JITEmitDebugInfo(false), JITEmitDebugInfoToDisk(false),
+ GuaranteedTailCallOpt(false), DisableTailCalls(false),
+ StackAlignmentOverride(0), RealignStack(true),
+ DisableJumpTables(false), EnableFastISel(false),
+ PositionIndependentExecutable(false), EnableSegmentedStacks(false),
+ TrapFuncName(""), FloatABIType(FloatABI::Default)
+ {}
+
+ /// PrintMachineCode - This flag is enabled when the -print-machineinstrs
+ /// option is specified on the command line, and should enable debugging
+ /// output from the code generator.
+ unsigned PrintMachineCode : 1;
+
+ /// NoFramePointerElim - This flag is enabled when the -disable-fp-elim is
+ /// specified on the command line. If the target supports the frame pointer
+ /// elimination optimization, this option should disable it.
+ unsigned NoFramePointerElim : 1;
+
+ /// NoFramePointerElimNonLeaf - This flag is enabled when the
+ /// -disable-non-leaf-fp-elim is specified on the command line. If the
+ /// target supports the frame pointer elimination optimization, this option
+ /// should disable it for non-leaf functions.
+ unsigned NoFramePointerElimNonLeaf : 1;
+
+ /// DisableFramePointerElim - This returns true if frame pointer elimination
+ /// optimization should be disabled for the given machine function.
+ bool DisableFramePointerElim(const MachineFunction &MF) const;
+
+ /// LessPreciseFPMAD - This flag is enabled when the
+ /// -enable-fp-mad is specified on the command line. When this flag is off
+ /// (the default), the code generator is not allowed to generate mad
+ /// (multiply add) if the result is "less precise" than doing those
+ /// operations individually.
+ unsigned LessPreciseFPMADOption : 1;
+ bool LessPreciseFPMAD() const;
+
+ /// NoExcessFPPrecision - This flag is enabled when the
+ /// -disable-excess-fp-precision flag is specified on the command line.
+ /// When this flag is off (the default), the code generator is allowed to
+ /// produce results that are "more precise" than IEEE allows. This includes
+ /// use of FMA-like operations and use of the X86 FP registers without
+ /// rounding all over the place.
+ unsigned NoExcessFPPrecision : 1;
+
+ /// UnsafeFPMath - This flag is enabled when the
+ /// -enable-unsafe-fp-math flag is specified on the command line. When
+ /// this flag is off (the default), the code generator is not allowed to
+ /// produce results that are "less precise" than IEEE allows. This includes
+ /// use of X86 instructions like FSIN and FCOS instead of libcalls.
+ /// UnsafeFPMath implies LessPreciseFPMAD.
+ unsigned UnsafeFPMath : 1;
+
+ /// NoInfsFPMath - This flag is enabled when the
+ /// -enable-no-infs-fp-math flag is specified on the command line. When
+ /// this flag is off (the default), the code generator is not allowed to
+ /// assume the FP arithmetic arguments and results are never +-Infs.
+ unsigned NoInfsFPMath : 1;
+
+ /// NoNaNsFPMath - This flag is enabled when the
+ /// -enable-no-nans-fp-math flag is specified on the command line. When
+ /// this flag is off (the default), the code generator is not allowed to
+ /// assume the FP arithmetic arguments and results are never NaNs.
+ unsigned NoNaNsFPMath : 1;
+
+ /// HonorSignDependentRoundingFPMath - This returns true when the
+ /// -enable-sign-dependent-rounding-fp-math is specified. If this returns
+ /// false (the default), the code generator is allowed to assume that the
+ /// rounding behavior is the default (round-to-zero for all floating point
+ /// to integer conversions, and round-to-nearest for all other arithmetic
+ /// truncations). If this is enabled (set to true), the code generator must
+ /// assume that the rounding mode may dynamically change.
+ unsigned HonorSignDependentRoundingFPMathOption : 1;
+ bool HonorSignDependentRoundingFPMath() const;
+
+ /// UseSoftFloat - This flag is enabled when the -soft-float flag is
+ /// specified on the command line. When this flag is on, the code generator
+ /// will generate libcalls to the software floating point library instead of
+ /// target FP instructions.
+ unsigned UseSoftFloat : 1;
+
+ /// NoZerosInBSS - By default some codegens place zero-initialized data to
+ /// .bss section. This flag disables such behaviour (necessary, e.g. for
+ /// crt*.o compiling).
+ unsigned NoZerosInBSS : 1;
+
+ /// JITExceptionHandling - This flag indicates that the JIT should emit
+ /// exception handling information.
+ unsigned JITExceptionHandling : 1;
+
+ /// JITEmitDebugInfo - This flag indicates that the JIT should try to emit
+ /// debug information and notify a debugger about it.
+ unsigned JITEmitDebugInfo : 1;
+
+ /// JITEmitDebugInfoToDisk - This flag indicates that the JIT should write
+ /// the object files generated by the JITEmitDebugInfo flag to disk. This
+ /// flag is hidden and is only for debugging the debug info.
+ unsigned JITEmitDebugInfoToDisk : 1;
+
+ /// GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is
+ /// specified on the commandline. When the flag is on, participating targets
+ /// will perform tail call optimization on all calls which use the fastcc
+ /// calling convention and which satisfy certain target-independent
+ /// criteria (being at the end of a function, having the same return type
+ /// as their parent function, etc.), using an alternate ABI if necessary.
+ unsigned GuaranteedTailCallOpt : 1;
+
+ /// DisableTailCalls - This flag controls whether we will use tail calls.
+ /// Disabling them may be useful to maintain a correct call stack.
+ unsigned DisableTailCalls : 1;
+
+ /// StackAlignmentOverride - Override default stack alignment for target.
+ unsigned StackAlignmentOverride;
+
+ /// RealignStack - This flag indicates whether the stack should be
+ /// automatically realigned, if needed.
+ unsigned RealignStack : 1;
+
+ /// DisableJumpTables - This flag indicates jump tables should not be
+ /// generated.
+ unsigned DisableJumpTables : 1;
+
+ /// EnableFastISel - This flag enables fast-path instruction selection
+ /// which trades away generated code quality in favor of reducing
+ /// compile time.
+ unsigned EnableFastISel : 1;
+
+ /// PositionIndependentExecutable - This flag indicates whether the code
+ /// will eventually be linked into a single executable, despite the PIC
+ /// relocation model being in use. It's value is undefined (and irrelevant)
+ /// if the relocation model is anything other than PIC.
+ unsigned PositionIndependentExecutable : 1;
+
+ unsigned EnableSegmentedStacks : 1;
+
+ /// getTrapFunctionName - If this returns a non-empty string, this means
+ /// isel should lower Intrinsic::trap to a call to the specified function
+ /// name instead of an ISD::TRAP node.
+ std::string TrapFuncName;
+ StringRef getTrapFunctionName() const;
+
+ /// FloatABIType - This setting is set by -float-abi=xxx option is specfied
+ /// on the command line. This setting may either be Default, Soft, or Hard.
+ /// Default selects the target's default behavior. Soft selects the ABI for
+ /// UseSoftFloat, but does not indicate that FP hardware may not be used.
+ /// Such a combination is unfortunately popular (e.g. arm-apple-darwin).
+ /// Hard presumes that the normal FP ABI is used.
+ FloatABI::ABIType FloatABIType;
+ };
} // End llvm namespace
#endif
diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h
index 682aa50..7d8a46b 100644
--- a/include/llvm/Target/TargetRegisterInfo.h
+++ b/include/llvm/Target/TargetRegisterInfo.h
@@ -20,6 +20,7 @@
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/CallingConv.h"
#include <cassert>
#include <functional>
@@ -33,25 +34,18 @@ class raw_ostream;
class TargetRegisterClass {
public:
- typedef const unsigned* iterator;
- typedef const unsigned* const_iterator;
- typedef const EVT* vt_iterator;
+ typedef const uint16_t* iterator;
+ typedef const uint16_t* const_iterator;
+ typedef const MVT::SimpleValueType* vt_iterator;
typedef const TargetRegisterClass* const * sc_iterator;
-private:
+
+ // Instance variables filled by tablegen, do not use!
const MCRegisterClass *MC;
const vt_iterator VTs;
const unsigned *SubClassMask;
const sc_iterator SuperClasses;
const sc_iterator SuperRegClasses;
-public:
- TargetRegisterClass(const MCRegisterClass *MC, const EVT *vts,
- const unsigned *subcm,
- const TargetRegisterClass * const *supcs,
- const TargetRegisterClass * const *superregcs)
- : MC(MC), VTs(vts), SubClassMask(subcm), SuperClasses(supcs),
- SuperRegClasses(superregcs) {}
-
- virtual ~TargetRegisterClass() {} // Allow subclasses
+ ArrayRef<uint16_t> (*OrderFunc)(const MachineFunction&);
/// getID() - Return the register class ID number.
///
@@ -108,7 +102,7 @@ public:
///
bool hasType(EVT vt) const {
for(int i = 0; VTs[i] != MVT::Other; ++i)
- if (VTs[i] == vt)
+ if (EVT(VTs[i]) == vt)
return true;
return false;
}
@@ -165,7 +159,7 @@ public:
/// getSubClassMask - Returns a bit vector of subclasses, including this one.
/// The vector is indexed by class IDs, see hasSubClassEq() above for how to
/// use it.
- const unsigned *getSubClassMask() const {
+ const uint32_t *getSubClassMask() const {
return SubClassMask;
}
@@ -196,9 +190,8 @@ public:
///
/// By default, this method returns all registers in the class.
///
- virtual
- ArrayRef<unsigned> getRawAllocationOrder(const MachineFunction &MF) const {
- return makeArrayRef(begin(), getNumRegs());
+ ArrayRef<uint16_t> getRawAllocationOrder(const MachineFunction &MF) const {
+ return OrderFunc ? OrderFunc(MF) : makeArrayRef(begin(), getNumRegs());
}
};
@@ -209,6 +202,13 @@ struct TargetRegisterInfoDesc {
bool inAllocatableClass; // Register belongs to an allocatable regclass.
};
+/// Each TargetRegisterClass has a per register weight, and weight
+/// limit which must be less than the limits of its pressure sets.
+struct RegClassWeight {
+ unsigned RegWeigt;
+ unsigned WeightLimit;
+};
+
/// TargetRegisterInfo base class - We assume that the target defines a static
/// array of TargetRegisterDesc objects that represent all of the machine
/// registers that the target has. As such, we simply have to track a pointer
@@ -332,7 +332,7 @@ public:
if (regA == regB) return true;
if (isVirtualRegister(regA) || isVirtualRegister(regB))
return false;
- for (const unsigned *regList = getOverlaps(regA)+1; *regList; ++regList) {
+ for (const uint16_t *regList = getOverlaps(regA)+1; *regList; ++regList) {
if (*regList == regB) return true;
}
return false;
@@ -347,7 +347,7 @@ public:
/// isSuperRegister - Returns true if regB is a super-register of regA.
///
bool isSuperRegister(unsigned regA, unsigned regB) const {
- for (const unsigned *regList = getSuperRegisters(regA); *regList;++regList){
+ for (const uint16_t *regList = getSuperRegisters(regA); *regList;++regList){
if (*regList == regB) return true;
}
return false;
@@ -356,10 +356,33 @@ public:
/// getCalleeSavedRegs - Return a null-terminated list of all of the
/// callee saved registers on this target. The register should be in the
/// order of desired callee-save stack frame offset. The first register is
- /// closed to the incoming stack pointer if stack grows down, and vice versa.
- virtual const unsigned* getCalleeSavedRegs(const MachineFunction *MF = 0)
+ /// closest to the incoming stack pointer if stack grows down, and vice versa.
+ ///
+ virtual const uint16_t* getCalleeSavedRegs(const MachineFunction *MF = 0)
const = 0;
+ /// getCallPreservedMask - Return a mask of call-preserved registers for the
+ /// given calling convention on the current sub-target. The mask should
+ /// include all call-preserved aliases. This is used by the register
+ /// allocator to determine which registers can be live across a call.
+ ///
+ /// The mask is an array containing (TRI::getNumRegs()+31)/32 entries.
+ /// A set bit indicates that all bits of the corresponding register are
+ /// preserved across the function call. The bit mask is expected to be
+ /// sub-register complete, i.e. if A is preserved, so are all its
+ /// sub-registers.
+ ///
+ /// Bits are numbered from the LSB, so the bit for physical register Reg can
+ /// be found as (Mask[Reg / 32] >> Reg % 32) & 1.
+ ///
+ /// A NULL pointer means that no register mask will be used, and call
+ /// instructions should use implicit-def operands to indicate call clobbered
+ /// registers.
+ ///
+ virtual const uint32_t *getCallPreservedMask(CallingConv::ID) const {
+ // The default mask clobbers everything. All targets should override.
+ return 0;
+ }
/// getReservedRegs - Returns a bitset indexed by physical register number
/// indicating if a register is a special register that has particular uses
@@ -367,24 +390,11 @@ public:
/// used by register scavenger to determine what registers are free.
virtual BitVector getReservedRegs(const MachineFunction &MF) const = 0;
- /// getSubReg - Returns the physical register number of sub-register "Index"
- /// for physical register RegNo. Return zero if the sub-register does not
- /// exist.
- virtual unsigned getSubReg(unsigned RegNo, unsigned Index) const = 0;
-
- /// getSubRegIndex - For a given register pair, return the sub-register index
- /// if the second register is a sub-register of the first. Return zero
- /// otherwise.
- virtual unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const = 0;
-
/// getMatchingSuperReg - Return a super-register of the specified register
/// Reg so its sub-register of index SubIdx is Reg.
unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx,
const TargetRegisterClass *RC) const {
- for (const unsigned *SRs = getSuperRegisters(Reg); unsigned SR = *SRs;++SRs)
- if (Reg == getSubReg(SR, SubIdx) && RC->contains(SR))
- return SR;
- return 0;
+ return MCRegisterInfo::getMatchingSuperReg(Reg, SubIdx, RC->MC);
}
/// canCombineSubRegIndices - Given a register class and a list of
@@ -402,11 +412,11 @@ public:
/// getMatchingSuperRegClass - Return a subclass of the specified register
/// class A so that each register in it has a sub-register of the
/// specified sub-register index which is in the specified register class B.
+ ///
+ /// TableGen will synthesize missing A sub-classes.
virtual const TargetRegisterClass *
getMatchingSuperRegClass(const TargetRegisterClass *A,
- const TargetRegisterClass *B, unsigned Idx) const {
- return 0;
- }
+ const TargetRegisterClass *B, unsigned Idx) const =0;
/// getSubClassWithSubReg - Returns the largest legal sub-class of RC that
/// supports the sub-register index Idx.
@@ -419,6 +429,7 @@ public:
/// supported by the full GR32 register class in 64-bit mode, but only by the
/// GR32_ABCD regiister class in 32-bit mode.
///
+ /// TableGen will synthesize missing RC sub-classes.
virtual const TargetRegisterClass *
getSubClassWithSubReg(const TargetRegisterClass *RC, unsigned Idx) const =0;
@@ -469,8 +480,7 @@ public:
/// values. If a target supports multiple different pointer register classes,
/// kind specifies which one is indicated.
virtual const TargetRegisterClass *getPointerRegClass(unsigned Kind=0) const {
- assert(0 && "Target didn't implement getPointerRegClass!");
- return 0; // Must return a value in order to compile with VS 2005
+ llvm_unreachable("Target didn't implement getPointerRegClass!");
}
/// getCrossCopyRegClass - Returns a legal register class to copy a register
@@ -497,18 +507,37 @@ public:
/// getRegPressureLimit - Return the register pressure "high water mark" for
/// the specific register class. The scheduler is in high register pressure
/// mode (for the specific register class) if it goes over the limit.
+ ///
+ /// Note: this is the old register pressure model that relies on a manually
+ /// specified representative register class per value type.
virtual unsigned getRegPressureLimit(const TargetRegisterClass *RC,
MachineFunction &MF) const {
return 0;
}
+ /// Get the weight in units of pressure for this register class.
+ virtual const RegClassWeight &getRegClassWeight(
+ const TargetRegisterClass *RC) const = 0;
+
+ /// Get the number of dimensions of register pressure.
+ virtual unsigned getNumRegPressureSets() const = 0;
+
+ /// Get the register unit pressure limit for this dimension.
+ /// This limit must be adjusted dynamically for reserved registers.
+ virtual unsigned getRegPressureSetLimit(unsigned Idx) const = 0;
+
+ /// Get the dimensions of register pressure impacted by this register class.
+ /// Returns a -1 terminated array of pressure set IDs.
+ virtual const int *getRegClassPressureSets(
+ const TargetRegisterClass *RC) const = 0;
+
/// getRawAllocationOrder - Returns the register allocation order for a
/// specified register class with a target-dependent hint. The returned list
/// may contain reserved registers that cannot be allocated.
///
/// Register allocators need only call this function to resolve
/// target-dependent hints, but it should work without hinting as well.
- virtual ArrayRef<unsigned>
+ virtual ArrayRef<uint16_t>
getRawAllocationOrder(const TargetRegisterClass *RC,
unsigned HintType, unsigned HintReg,
const MachineFunction &MF) const {
@@ -607,22 +636,22 @@ public:
virtual void materializeFrameBaseRegister(MachineBasicBlock *MBB,
unsigned BaseReg, int FrameIdx,
int64_t Offset) const {
- assert(0 && "materializeFrameBaseRegister does not exist on this target");
+ llvm_unreachable("materializeFrameBaseRegister does not exist on this "
+ "target");
}
/// resolveFrameIndex - Resolve a frame index operand of an instruction
/// to reference the indicated base register plus offset instead.
virtual void resolveFrameIndex(MachineBasicBlock::iterator I,
unsigned BaseReg, int64_t Offset) const {
- assert(0 && "resolveFrameIndex does not exist on this target");
+ llvm_unreachable("resolveFrameIndex does not exist on this target");
}
/// isFrameOffsetLegal - Determine whether a given offset immediate is
/// encodable to resolve a frame index.
virtual bool isFrameOffsetLegal(const MachineInstr *MI,
int64_t Offset) const {
- assert(0 && "isFrameOffsetLegal does not exist on this target");
- return false; // Must return a value in order to compile with VS 2005
+ llvm_unreachable("isFrameOffsetLegal does not exist on this target");
}
/// eliminateCallFramePseudoInstr - This method is called during prolog/epilog
@@ -636,7 +665,8 @@ public:
eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const {
- assert(0 && "Call Frame Pseudo Instructions do not exist on this target!");
+ llvm_unreachable("Call Frame Pseudo Instructions do not exist on this "
+ "target!");
}
diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td
index 612635e..f55cf0e 100644
--- a/include/llvm/Target/TargetSelectionDAG.td
+++ b/include/llvm/Target/TargetSelectionDAG.td
@@ -352,6 +352,8 @@ def bswap : SDNode<"ISD::BSWAP" , SDTIntUnaryOp>;
def ctlz : SDNode<"ISD::CTLZ" , SDTIntUnaryOp>;
def cttz : SDNode<"ISD::CTTZ" , SDTIntUnaryOp>;
def ctpop : SDNode<"ISD::CTPOP" , SDTIntUnaryOp>;
+def ctlz_zero_undef : SDNode<"ISD::CTLZ_ZERO_UNDEF", SDTIntUnaryOp>;
+def cttz_zero_undef : SDNode<"ISD::CTTZ_ZERO_UNDEF", SDTIntUnaryOp>;
def sext : SDNode<"ISD::SIGN_EXTEND", SDTIntExtendOp>;
def zext : SDNode<"ISD::ZERO_EXTEND", SDTIntExtendOp>;
def anyext : SDNode<"ISD::ANY_EXTEND" , SDTIntExtendOp>;
@@ -655,6 +657,51 @@ def zextloadi32 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32;
}]>;
+def extloadvi1 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i1;
+}]>;
+def extloadvi8 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i8;
+}]>;
+def extloadvi16 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i16;
+}]>;
+def extloadvi32 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i32;
+}]>;
+def extloadvf32 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::f32;
+}]>;
+def extloadvf64 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::f64;
+}]>;
+
+def sextloadvi1 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i1;
+}]>;
+def sextloadvi8 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i8;
+}]>;
+def sextloadvi16 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i16;
+}]>;
+def sextloadvi32 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i32;
+}]>;
+
+def zextloadvi1 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i1;
+}]>;
+def zextloadvi8 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i8;
+}]>;
+def zextloadvi16 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i16;
+}]>;
+def zextloadvi32 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i32;
+}]>;
+
// store fragments.
def unindexedstore : PatFrag<(ops node:$val, node:$ptr),
(st node:$val, node:$ptr), [{
diff --git a/include/llvm/Target/TargetSubtargetInfo.h b/include/llvm/Target/TargetSubtargetInfo.h
index 9556c7a..fc23b2c 100644
--- a/include/llvm/Target/TargetSubtargetInfo.h
+++ b/include/llvm/Target/TargetSubtargetInfo.h
@@ -15,7 +15,7 @@
#define LLVM_TARGET_TARGETSUBTARGETINFO_H
#include "llvm/MC/MCSubtargetInfo.h"
-#include "llvm/Target/TargetMachine.h"
+#include "llvm/Support/CodeGen.h"
namespace llvm {
@@ -39,7 +39,7 @@ public:
// AntiDepBreakMode - Type of anti-dependence breaking that should
// be performed before post-RA scheduling.
typedef enum { ANTIDEP_NONE, ANTIDEP_CRITICAL, ANTIDEP_ALL } AntiDepBreakMode;
- typedef SmallVectorImpl<TargetRegisterClass*> RegClassVector;
+ typedef SmallVectorImpl<const TargetRegisterClass*> RegClassVector;
virtual ~TargetSubtargetInfo();
OpenPOWER on IntegriCloud