aboutsummaryrefslogtreecommitdiffstats
path: root/include/llvm/Target
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Target')
-rw-r--r--include/llvm/Target/Mangler.h7
-rw-r--r--include/llvm/Target/SubtargetFeature.h2
-rw-r--r--include/llvm/Target/Target.td59
-rw-r--r--include/llvm/Target/TargetAsmBackend.h55
-rw-r--r--include/llvm/Target/TargetAsmInfo.h75
-rw-r--r--include/llvm/Target/TargetAsmParser.h2
-rw-r--r--include/llvm/Target/TargetData.h4
-rw-r--r--include/llvm/Target/TargetFrameInfo.h112
-rw-r--r--include/llvm/Target/TargetFrameLowering.h196
-rw-r--r--include/llvm/Target/TargetInstrDesc.h13
-rw-r--r--include/llvm/Target/TargetInstrInfo.h99
-rw-r--r--include/llvm/Target/TargetInstrItineraries.h10
-rw-r--r--include/llvm/Target/TargetJITInfo.h2
-rw-r--r--include/llvm/Target/TargetLibraryInfo.h75
-rw-r--r--include/llvm/Target/TargetLowering.h159
-rw-r--r--include/llvm/Target/TargetLoweringObjectFile.h6
-rw-r--r--include/llvm/Target/TargetMachine.h22
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h195
-rw-r--r--include/llvm/Target/TargetRegistry.h24
-rw-r--r--include/llvm/Target/TargetSelectionDAG.td71
20 files changed, 791 insertions, 397 deletions
diff --git a/include/llvm/Target/Mangler.h b/include/llvm/Target/Mangler.h
index a9f3576559..c1c118b08c 100644
--- a/include/llvm/Target/Mangler.h
+++ b/include/llvm/Target/Mangler.h
@@ -15,7 +15,6 @@
#define LLVM_SUPPORT_MANGLER_H
#include "llvm/ADT/DenseMap.h"
-#include <string>
namespace llvm {
class StringRef;
@@ -69,12 +68,6 @@ public:
/// empty.
void getNameWithPrefix(SmallVectorImpl<char> &OutName, const Twine &GVName,
ManglerPrefixTy PrefixTy = Mangler::Default);
-
- /// getNameWithPrefix - Return the name of the appropriate prefix
- /// and the specified global variable's name. If the global variable doesn't
- /// have a name, this fills in a unique name for the global.
- std::string getNameWithPrefix(const GlobalValue *GV,
- bool isImplicitlyPrivate = false);
};
} // End llvm namespace
diff --git a/include/llvm/Target/SubtargetFeature.h b/include/llvm/Target/SubtargetFeature.h
index 45468714a3..6c21ae9583 100644
--- a/include/llvm/Target/SubtargetFeature.h
+++ b/include/llvm/Target/SubtargetFeature.h
@@ -22,7 +22,7 @@
#include <vector>
#include <cstring>
#include "llvm/ADT/Triple.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
class raw_ostream;
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index bd629f16e2..0f7e6aaaf2 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -1,10 +1,10 @@
//===- Target.td - Target Independent TableGen interface ---*- tablegen -*-===//
-//
+//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
//
// This file defines the target-independent interfaces which should be
@@ -47,7 +47,7 @@ class Register<string n> {
// modification of this register can potentially read or modify the aliased
// registers.
list<Register> Aliases = [];
-
+
// SubRegs - A list of registers that are parts of this register. Note these
// are "immediate" sub-registers and the registers within the list do not
// themselves overlap. e.g. For X86, EAX's SubRegs list contains only [AX],
@@ -84,7 +84,7 @@ class Register<string n> {
// need to specify sub-registers.
// List "subregs" specifies which registers are sub-registers to this one. This
// is used to populate the SubRegs and AliasSet fields of TargetRegisterDesc.
-// This allows the code generator to be careful not to put two values with
+// This allows the code generator to be careful not to put two values with
// overlapping live ranges into registers which alias.
class RegisterWithSubRegs<string n, list<Register> subregs> : Register<n> {
let SubRegs = subregs;
@@ -101,7 +101,7 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
// RegType - Specify the list ValueType of the registers in this register
// class. Note that all registers in a register class must have the same
- // ValueTypes. This is a list because some targets permit storing different
+ // ValueTypes. This is a list because some targets permit storing different
// types in same register, for example vector values with 128-bit total size,
// but different count/size of items, like SSE on x86.
//
@@ -127,13 +127,13 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
// allocation used by the register allocator.
//
list<Register> MemberList = regList;
-
+
// SubRegClasses - Specify the register class of subregisters as a list of
// dags: (RegClass SubRegIndex, SubRegindex, ...)
list<dag> SubRegClasses = [];
// MethodProtos/MethodBodies - These members can be used to insert arbitrary
- // code into a generated register class. The normal usage of this is to
+ // code into a generated register class. The normal usage of this is to
// overload virtual methods.
code MethodProtos = [{}];
code MethodBodies = [{}];
@@ -199,6 +199,7 @@ class Instruction {
bit isBranch = 0; // Is this instruction a branch instruction?
bit isIndirectBranch = 0; // Is this instruction an indirect branch?
bit isCompare = 0; // Is this instruction a comparison instruction?
+ bit isMoveImm = 0; // Is this instruction a move immediate instruction?
bit isBarrier = 0; // Can control flow fall through this instruction?
bit isCall = 0; // Is this instruction a call instruction?
bit canFoldAsLoad = 0; // Can this be folded as a simple memory operand?
@@ -244,16 +245,24 @@ class Instruction {
string DisableEncoding = "";
string PostEncoderMethod = "";
+ string DecoderMethod = "";
/// Target-specific flags. This becomes the TSFlags field in TargetInstrDesc.
bits<64> TSFlags = 0;
+
+ ///@name Assembler Parser Support
+ ///@{
+
+ string AsmMatchConverter = "";
+
+ ///@}
}
/// Predicates - These are extra conditionals which are turned into instruction
/// selector matching code. Currently each predicate is just a string.
class Predicate<string cond> {
string CondString = cond;
-
+
/// AssemblerMatcherPredicate - If this feature can be used by the assembler
/// matcher, this is true. Targets should set this by inheriting their
/// feature from the AssemblerPredicate class in addition to Predicate.
@@ -333,12 +342,18 @@ class AsmOperandClass {
/// signature should be:
/// void addFooOperands(MCInst &Inst, unsigned N) const;
string RenderMethod = ?;
+
+ /// The name of the method on the target specific operand to call to custom
+ /// handle the operand parsing. This is useful when the operands do not relate
+ /// to immediates or registers and are very instruction specific (as flags to
+ /// set in a processor register, coprocessor number, ...).
+ string ParserMethod = ?;
}
def ImmAsmOperand : AsmOperandClass {
let Name = "Imm";
}
-
+
/// Operand Types - These provide the built-in operand types that may be used
/// by a target. Targets can optionally provide their own operand types as
/// needed, though this should not be needed for RISC targets.
@@ -346,6 +361,7 @@ class Operand<ValueType ty> {
ValueType Type = ty;
string PrintMethod = "printOperand";
string EncoderMethod = "";
+ string DecoderMethod = "";
string AsmOperandLowerMethod = ?;
dag MIOperandInfo = (ops);
@@ -417,6 +433,7 @@ def INLINEASM : Instruction {
let OutOperandList = (outs);
let InOperandList = (ins variable_ops);
let AsmString = "";
+ let neverHasSideEffects = 1; // Note side effect is encoded in an operand.
}
def PROLOG_LABEL : Instruction {
let OutOperandList = (outs);
@@ -483,7 +500,7 @@ def DBG_VALUE : Instruction {
let OutOperandList = (outs);
let InOperandList = (ins variable_ops);
let AsmString = "DBG_VALUE";
- let isAsCheapAsAMove = 1;
+ let neverHasSideEffects = 1;
}
def REG_SEQUENCE : Instruction {
let OutOperandList = (outs unknown:$dst);
@@ -565,7 +582,7 @@ class AssemblerPredicate {
class MnemonicAlias<string From, string To> {
string FromMnemonic = From;
string ToMnemonic = To;
-
+
// Predicates - Predicates that must be true for this remapping to happen.
list<Predicate> Predicates = [];
}
@@ -576,7 +593,7 @@ class MnemonicAlias<string From, string To> {
class InstAlias<string Asm, dag Result> {
string AsmString = Asm; // The .s format to match the instruction with.
dag ResultInst = Result; // The MCInst to generate.
-
+
// Predicates - Predicates that must be true for this to match.
list<Predicate> Predicates = [];
}
@@ -601,15 +618,15 @@ class AsmWriter {
// will specify which alternative to use. For example "{x|y|z}" with Variant
// == 1, will expand to "y".
int Variant = 0;
-
-
+
+
// FirstOperandColumn/OperandSpacing - If the assembler syntax uses a columnar
// layout, the asmwriter can actually generate output in this columns (in
// verbose-asm mode). These two values indicate the width of the first column
// (the "opcode" area) and the width to reserve for subsequent operands. When
// verbose asm mode is enabled, operands will be indented to respect this.
int FirstOperandColumn = -1;
-
+
// OperandSpacing - Space between operand columns.
int OperandSpacing = -1;
@@ -644,15 +661,15 @@ class SubtargetFeature<string n, string a, string v, string d,
// appropriate target chip.
//
string Name = n;
-
+
// Attribute - Attribute to be set by feature.
//
string Attribute = a;
-
+
// Value - Value the attribute to be set to by feature.
//
string Value = v;
-
+
// Desc - Feature description. Used by command line (-mattr=) to display help
// information.
//
@@ -674,12 +691,12 @@ class Processor<string n, ProcessorItineraries pi, list<SubtargetFeature> f> {
// appropriate target chip.
//
string Name = n;
-
+
// ProcItin - The scheduling information for the target processor.
//
ProcessorItineraries ProcItin = pi;
-
- // Features - list of
+
+ // Features - list of
list<SubtargetFeature> Features = f;
}
diff --git a/include/llvm/Target/TargetAsmBackend.h b/include/llvm/Target/TargetAsmBackend.h
index b424dea4a5..7527298efa 100644
--- a/include/llvm/Target/TargetAsmBackend.h
+++ b/include/llvm/Target/TargetAsmBackend.h
@@ -10,18 +10,18 @@
#ifndef LLVM_TARGET_TARGETASMBACKEND_H
#define LLVM_TARGET_TARGETASMBACKEND_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/MC/MCDirectives.h"
+#include "llvm/MC/MCFixup.h"
+#include "llvm/MC/MCFixupKindInfo.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
-class MCDataFragment;
class MCFixup;
class MCInst;
-class MCObjectFormat;
class MCObjectWriter;
class MCSection;
template<typename T>
class SmallVectorImpl;
-class Target;
class raw_ostream;
/// TargetAsmBackend - Generic interface to target specific assembler backends.
@@ -29,21 +29,13 @@ class TargetAsmBackend {
TargetAsmBackend(const TargetAsmBackend &); // DO NOT IMPLEMENT
void operator=(const TargetAsmBackend &); // DO NOT IMPLEMENT
protected: // Can only create subclasses.
- TargetAsmBackend(const Target &);
-
- /// TheTarget - The Target that this machine was created for.
- const Target &TheTarget;
+ TargetAsmBackend();
unsigned HasReliableSymbolDifference : 1;
- unsigned HasScatteredSymbols : 1;
public:
virtual ~TargetAsmBackend();
- const Target &getTarget() const { return TheTarget; }
-
- virtual const MCObjectFormat &getObjectFormat() const = 0;
-
/// createObjectWriter - Create a new MCObjectWriter instance for use by the
/// assembler backend to emit the final object file.
virtual MCObjectWriter *createObjectWriter(raw_ostream &OS) const = 0;
@@ -62,16 +54,6 @@ public:
return HasReliableSymbolDifference;
}
- /// hasScatteredSymbols - Check whether this target supports scattered
- /// symbols. If so, the assembler should assume that atoms can be scattered by
- /// the linker. In particular, this means that the offsets between symbols
- /// which are in distinct atoms is not known at link time, and the assembler
- /// must generate fixups and relocations appropriately.
- ///
- /// Note that the assembler currently does not reason about atoms, instead it
- /// assumes all temporary symbols reside in the "current atom".
- bool hasScatteredSymbols() const { return HasScatteredSymbols; }
-
/// doesSectionRequireSymbols - Check whether the given section requires that
/// all symbols (even temporaries) have symbol table entries.
virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
@@ -86,19 +68,28 @@ public:
return true;
}
- /// isVirtualSection - Check whether the given section is "virtual", that is
- /// has no actual object file contents.
- virtual bool isVirtualSection(const MCSection &Section) const = 0;
+ /// @name Target Fixup Interfaces
+ /// @{
+
+ /// getNumFixupKinds - Get the number of target specific fixup kinds.
+ virtual unsigned getNumFixupKinds() const = 0;
- /// getPointerSize - Get the pointer size in bytes.
- virtual unsigned getPointerSize() const = 0;
+ /// getFixupKindInfo - Get information on a fixup kind.
+ virtual const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const;
+
+ /// @}
/// ApplyFixup - Apply the \arg Value for given \arg Fixup into the provided
/// data fragment, at the offset specified by the fixup and following the
/// fixup kind as appropriate.
- virtual void ApplyFixup(const MCFixup &Fixup, MCDataFragment &Fragment,
+ virtual void ApplyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
uint64_t Value) const = 0;
+ /// @}
+
+ /// @name Target Relaxation Interfaces
+ /// @{
+
/// MayNeedRelaxation - Check whether the given instruction may need
/// relaxation.
///
@@ -113,12 +104,18 @@ public:
/// \parm Res [output] - On return, the relaxed instruction.
virtual void RelaxInstruction(const MCInst &Inst, MCInst &Res) const = 0;
+ /// @}
+
/// WriteNopData - Write an (optimal) nop sequence of Count bytes to the given
/// output. If the target cannot generate such a sequence, it should return an
/// error.
///
/// \return - True on success.
virtual bool WriteNopData(uint64_t Count, MCObjectWriter *OW) const = 0;
+
+ /// HandleAssemblerFlag - Handle any target-specific assembler flags.
+ /// By default, do nothing.
+ virtual void HandleAssemblerFlag(MCAssemblerFlag Flag) {}
};
} // End llvm namespace
diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h
new file mode 100644
index 0000000000..98aab142b8
--- /dev/null
+++ b/include/llvm/Target/TargetAsmInfo.h
@@ -0,0 +1,75 @@
+//===-- llvm/Target/TargetAsmInfo.h -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Interface to provide the information necessary for producing assembly files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETASMINFO_H
+#define LLVM_TARGET_TARGETASMINFO_H
+
+#include "llvm/CodeGen/MachineLocation.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/Target/TargetFrameLowering.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+
+namespace llvm {
+ class MCSection;
+ class MCContext;
+ class TargetMachine;
+ class TargetLoweringObjectFile;
+
+class TargetAsmInfo {
+ unsigned PointerSize;
+ bool IsLittleEndian;
+ TargetFrameLowering::StackDirection StackDir;
+ const TargetRegisterInfo *TRI;
+ std::vector<MachineMove> InitialFrameState;
+ const TargetLoweringObjectFile *TLOF;
+
+public:
+ explicit TargetAsmInfo(const TargetMachine &TM);
+
+ /// getPointerSize - Get the pointer size in bytes.
+ unsigned getPointerSize() const {
+ return PointerSize;
+ }
+
+ /// islittleendian - True if the target is little endian.
+ bool isLittleEndian() const {
+ return IsLittleEndian;
+ }
+
+ TargetFrameLowering::StackDirection getStackGrowthDirection() const {
+ return StackDir;
+ }
+
+ const MCSection *getDwarfLineSection() const {
+ return TLOF->getDwarfLineSection();
+ }
+
+ const MCSection *getEHFrameSection() const {
+ return TLOF->getEHFrameSection();
+ }
+
+ unsigned getDwarfRARegNum(bool isEH) const {
+ return TRI->getDwarfRegNum(TRI->getRARegister(), isEH);
+ }
+
+ const std::vector<MachineMove> &getInitialFrameState() const {
+ return InitialFrameState;
+ }
+
+ int getDwarfRegNum(unsigned RegNum, bool isEH) const {
+ return TRI->getDwarfRegNum(RegNum, isEH);
+ }
+};
+
+}
+#endif
diff --git a/include/llvm/Target/TargetAsmParser.h b/include/llvm/Target/TargetAsmParser.h
index 6b38b8c7e1..9ff50cb275 100644
--- a/include/llvm/Target/TargetAsmParser.h
+++ b/include/llvm/Target/TargetAsmParser.h
@@ -42,6 +42,8 @@ public:
unsigned getAvailableFeatures() const { return AvailableFeatures; }
void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; }
+ virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) = 0;
+
/// ParseInstruction - Parse one assembly instruction.
///
/// The parser is positioned following the instruction name. The target
diff --git a/include/llvm/Target/TargetData.h b/include/llvm/Target/TargetData.h
index 5cdd114e8b..25065d30bb 100644
--- a/include/llvm/Target/TargetData.h
+++ b/include/llvm/Target/TargetData.h
@@ -22,7 +22,7 @@
#include "llvm/Pass.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
@@ -144,7 +144,7 @@ public:
std::string getStringRepresentation() const;
/// isLegalInteger - This function returns true if the specified type is
- /// known tobe a native integer type supported by the CPU. For example,
+ /// 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
/// one. This returns false if the integer width is not legal.
///
diff --git a/include/llvm/Target/TargetFrameInfo.h b/include/llvm/Target/TargetFrameInfo.h
deleted file mode 100644
index 6143f3c549..0000000000
--- a/include/llvm/Target/TargetFrameInfo.h
+++ /dev/null
@@ -1,112 +0,0 @@
-//===-- llvm/Target/TargetFrameInfo.h ---------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Interface to describe the layout of a stack frame on the target machine.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TARGET_TARGETFRAMEINFO_H
-#define LLVM_TARGET_TARGETFRAMEINFO_H
-
-#include <utility>
-
-namespace llvm {
- class MachineFunction;
- class MachineBasicBlock;
-
-/// Information about stack frame layout on the target. It holds the direction
-/// of stack growth, the known stack alignment on entry to each function, and
-/// the offset to the locals area.
-///
-/// The offset to the local area is the offset from the stack pointer on
-/// function entry to the first location where function data (local variables,
-/// spill locations) can be stored.
-class TargetFrameInfo {
-public:
- enum StackDirection {
- StackGrowsUp, // Adding to the stack increases the stack address
- StackGrowsDown // Adding to the stack decreases the stack address
- };
-
- // Maps a callee saved register to a stack slot with a fixed offset.
- struct SpillSlot {
- unsigned Reg;
- int Offset; // Offset relative to stack pointer on function entry.
- };
-private:
- StackDirection StackDir;
- unsigned StackAlignment;
- unsigned TransientStackAlignment;
- int LocalAreaOffset;
-public:
- TargetFrameInfo(StackDirection D, unsigned StackAl, int LAO,
- unsigned TransAl = 1)
- : StackDir(D), StackAlignment(StackAl), TransientStackAlignment(TransAl),
- LocalAreaOffset(LAO) {}
-
- virtual ~TargetFrameInfo();
-
- // These methods return information that describes the abstract stack layout
- // of the target machine.
-
- /// getStackGrowthDirection - Return the direction the stack grows
- ///
- StackDirection getStackGrowthDirection() const { return StackDir; }
-
- /// getStackAlignment - This method returns the number of bytes to which the
- /// stack pointer must be aligned on entry to a function. Typically, this
- /// is the largest alignment for any data object in the target.
- ///
- unsigned getStackAlignment() const { return StackAlignment; }
-
- /// getTransientStackAlignment - This method returns the number of bytes to
- /// which the stack pointer must be aligned at all times, even between
- /// calls.
- ///
- unsigned getTransientStackAlignment() const {
- return TransientStackAlignment;
- }
-
- /// getOffsetOfLocalArea - This method returns the offset of the local area
- /// from the stack pointer on entrance to a function.
- ///
- int getOffsetOfLocalArea() const { return LocalAreaOffset; }
-
- /// getCalleeSavedSpillSlots - This method returns a pointer to an array of
- /// pairs, that contains an entry for each callee saved register that must be
- /// spilled to a particular stack location if it is spilled.
- ///
- /// Each entry in this array contains a <register,offset> pair, indicating the
- /// fixed offset from the incoming stack pointer that each register should be
- /// spilled at. If a register is not listed here, the code generator is
- /// allowed to spill it anywhere it chooses.
- ///
- virtual const SpillSlot *
- getCalleeSavedSpillSlots(unsigned &NumEntries) const {
- NumEntries = 0;
- return 0;
- }
-
- /// targetHandlesStackFrameRounding - Returns true if the target is
- /// responsible for rounding up the stack frame (probably at emitPrologue
- /// time).
- virtual bool targetHandlesStackFrameRounding() const {
- return false;
- }
-
- /// emitProlog/emitEpilog - These methods insert prolog and epilog code into
- /// the function.
- virtual void emitPrologue(MachineFunction &MF) const = 0;
- virtual void emitEpilogue(MachineFunction &MF,
- MachineBasicBlock &MBB) const = 0;
-};
-
-} // End llvm namespace
-
-#endif
diff --git a/include/llvm/Target/TargetFrameLowering.h b/include/llvm/Target/TargetFrameLowering.h
new file mode 100644
index 0000000000..e104b1663f
--- /dev/null
+++ b/include/llvm/Target/TargetFrameLowering.h
@@ -0,0 +1,196 @@
+//===-- llvm/Target/TargetFrameLowering.h ---------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Interface to describe the layout of a stack frame on the target machine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETFRAMELOWERING_H
+#define LLVM_TARGET_TARGETFRAMELOWERING_H
+
+#include "llvm/CodeGen/MachineBasicBlock.h"
+
+#include <utility>
+#include <vector>
+
+namespace llvm {
+ class CalleeSavedInfo;
+ class MachineFunction;
+ class MachineBasicBlock;
+ class MachineMove;
+ class RegScavenger;
+
+/// Information about stack frame layout on the target. It holds the direction
+/// of stack growth, the known stack alignment on entry to each function, and
+/// the offset to the locals area.
+///
+/// The offset to the local area is the offset from the stack pointer on
+/// function entry to the first location where function data (local variables,
+/// spill locations) can be stored.
+class TargetFrameLowering {
+public:
+ enum StackDirection {
+ StackGrowsUp, // Adding to the stack increases the stack address
+ StackGrowsDown // Adding to the stack decreases the stack address
+ };
+
+ // Maps a callee saved register to a stack slot with a fixed offset.
+ struct SpillSlot {
+ unsigned Reg;
+ int Offset; // Offset relative to stack pointer on function entry.
+ };
+private:
+ StackDirection StackDir;
+ unsigned StackAlignment;
+ unsigned TransientStackAlignment;
+ int LocalAreaOffset;
+public:
+ TargetFrameLowering(StackDirection D, unsigned StackAl, int LAO,
+ unsigned TransAl = 1)
+ : StackDir(D), StackAlignment(StackAl), TransientStackAlignment(TransAl),
+ LocalAreaOffset(LAO) {}
+
+ virtual ~TargetFrameLowering();
+
+ // These methods return information that describes the abstract stack layout
+ // of the target machine.
+
+ /// getStackGrowthDirection - Return the direction the stack grows
+ ///
+ StackDirection getStackGrowthDirection() const { return StackDir; }
+
+ /// getStackAlignment - This method returns the number of bytes to which the
+ /// stack pointer must be aligned on entry to a function. Typically, this
+ /// is the largest alignment for any data object in the target.
+ ///
+ unsigned getStackAlignment() const { return StackAlignment; }
+
+ /// getTransientStackAlignment - This method returns the number of bytes to
+ /// which the stack pointer must be aligned at all times, even between
+ /// calls.
+ ///
+ unsigned getTransientStackAlignment() const {
+ return TransientStackAlignment;
+ }
+
+ /// getOffsetOfLocalArea - This method returns the offset of the local area
+ /// from the stack pointer on entrance to a function.
+ ///
+ int getOffsetOfLocalArea() const { return LocalAreaOffset; }
+
+ /// getCalleeSavedSpillSlots - This method returns a pointer to an array of
+ /// pairs, that contains an entry for each callee saved register that must be
+ /// spilled to a particular stack location if it is spilled.
+ ///
+ /// Each entry in this array contains a <register,offset> pair, indicating the
+ /// fixed offset from the incoming stack pointer that each register should be
+ /// spilled at. If a register is not listed here, the code generator is
+ /// allowed to spill it anywhere it chooses.
+ ///
+ virtual const SpillSlot *
+ getCalleeSavedSpillSlots(unsigned &NumEntries) const {
+ NumEntries = 0;
+ return 0;
+ }
+
+ /// targetHandlesStackFrameRounding - Returns true if the target is
+ /// responsible for rounding up the stack frame (probably at emitPrologue
+ /// time).
+ virtual bool targetHandlesStackFrameRounding() const {
+ return false;
+ }
+
+ /// emitProlog/emitEpilog - These methods insert prolog and epilog code into
+ /// the function.
+ virtual void emitPrologue(MachineFunction &MF) const = 0;
+ virtual void emitEpilogue(MachineFunction &MF,
+ MachineBasicBlock &MBB) const = 0;
+
+ /// spillCalleeSavedRegisters - Issues instruction(s) to spill all callee
+ /// saved registers and returns true if it isn't possible / profitable to do
+ /// so by issuing a series of store instructions via
+ /// storeRegToStackSlot(). Returns false otherwise.
+ virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI,
+ const std::vector<CalleeSavedInfo> &CSI,
+ const TargetRegisterInfo *TRI) const {
+ return false;
+ }
+
+ /// restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee
+ /// saved registers and returns true if it isn't possible / profitable to do
+ /// so by issuing a series of load instructions via loadRegToStackSlot().
+ /// Returns false otherwise.
+ virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI,
+ const std::vector<CalleeSavedInfo> &CSI,
+ const TargetRegisterInfo *TRI) const {
+ return false;
+ }
+
+ /// hasFP - Return true if the specified function should have a dedicated
+ /// frame pointer register. For most targets this is true only if the function
+ /// has variable sized allocas or if frame pointer elimination is disabled.
+ virtual bool hasFP(const MachineFunction &MF) const = 0;
+
+ /// hasReservedCallFrame - Under normal circumstances, when a frame pointer is
+ /// not required, we reserve argument space for call sites in the function
+ /// immediately on entry to the current function. This eliminates the need for
+ /// add/sub sp brackets around call sites. Returns true if the call frame is
+ /// included as part of the stack frame.
+ virtual bool hasReservedCallFrame(const MachineFunction &MF) const {
+ return !hasFP(MF);
+ }
+
+ /// canSimplifyCallFramePseudos - When possible, it's best to simplify the
+ /// call frame pseudo ops before doing frame index elimination. This is
+ /// possible only when frame index references between the pseudos won't
+ /// need adjusting for the call frame adjustments. Normally, that's true
+ /// if the function has a reserved call frame or a frame pointer. Some
+ /// targets (Thumb2, for example) may have more complicated criteria,
+ /// however, and can override this behavior.
+ virtual bool canSimplifyCallFramePseudos(const MachineFunction &MF) const {
+ return hasReservedCallFrame(MF) || hasFP(MF);
+ }
+
+ /// getInitialFrameState - Returns a list of machine moves that are assumed
+ /// on entry to all functions. Note that LabelID is ignored (assumed to be
+ /// the beginning of the function.)
+ virtual void getInitialFrameState(std::vector<MachineMove> &Moves) const;
+
+ /// getFrameIndexOffset - Returns the displacement from the frame register to
+ /// the stack frame of the specified index.
+ virtual int getFrameIndexOffset(const MachineFunction &MF, int FI) const;
+
+ /// getFrameIndexReference - This method should return the base register
+ /// and offset used to reference a frame index location. The offset is
+ /// returned directly, and the base register is returned via FrameReg.
+ virtual int getFrameIndexReference(const MachineFunction &MF, int FI,
+ unsigned &FrameReg) const;
+
+ /// processFunctionBeforeCalleeSavedScan - This method is called immediately
+ /// before PrologEpilogInserter scans the physical registers used to determine
+ /// what callee saved registers should be spilled. This method is optional.
+ virtual void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
+ RegScavenger *RS = NULL) const {
+
+ }
+
+ /// processFunctionBeforeFrameFinalized - This method is called immediately
+ /// before the specified function's frame layout (MF.getFrameInfo()) is
+ /// finalized. Once the frame is finalized, MO_FrameIndex operands are
+ /// replaced with direct constants. This method is optional.
+ ///
+ virtual void processFunctionBeforeFrameFinalized(MachineFunction &MF) const {
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Target/TargetInstrDesc.h b/include/llvm/Target/TargetInstrDesc.h
index a127aed8f6..8823d5a4d1 100644
--- a/include/llvm/Target/TargetInstrDesc.h
+++ b/include/llvm/Target/TargetInstrDesc.h
@@ -15,7 +15,7 @@
#ifndef LLVM_TARGET_TARGETINSTRDESC_H
#define LLVM_TARGET_TARGETINSTRDESC_H
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
@@ -103,13 +103,14 @@ namespace TID {
Terminator,
Branch,
IndirectBranch,
- Predicable,
- NotDuplicable,
Compare,
+ MoveImm,
DelaySlot,
FoldableAsLoad,
MayLoad,
MayStore,
+ Predicable,
+ NotDuplicable,
UnmodeledSideEffects,
Commutable,
ConvertibleTo3Addr,
@@ -352,6 +353,12 @@ public:
return Flags & (1 << TID::Compare);
}
+ /// isMoveImmediate - Return true if this instruction is a move immediate
+ /// (including conditional moves) instruction.
+ bool isMoveImmediate() const {
+ return Flags & (1 << TID::MoveImm);
+ }
+
/// 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.
diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h
index 2bb01f483a..c903f3153e 100644
--- a/include/llvm/Target/TargetInstrInfo.h
+++ b/include/llvm/Target/TargetInstrInfo.h
@@ -19,7 +19,6 @@
namespace llvm {
-class CalleeSavedInfo;
class InstrItineraryData;
class LiveVariables;
class MCAsmInfo;
@@ -30,6 +29,7 @@ class MCInst;
class SDNode;
class ScheduleHazardRecognizer;
class SelectionDAG;
+class ScheduleDAG;
class TargetRegisterClass;
class TargetRegisterInfo;
@@ -135,7 +135,7 @@ public:
int &FrameIndex) const {
return 0;
}
-
+
/// isStoreToStackSlot - If the specified machine instruction is a direct
/// store to a stack slot, return the virtual or physical register number of
/// the source reg along with the FrameIndex of the loaded stack slot. If
@@ -228,9 +228,12 @@ public:
/// produceSameValue - Return true if two machine instructions would produce
/// identical values. By default, this is only true when the two instructions
- /// are deemed identical except for defs.
+ /// are deemed identical except for defs. If this function is called when the
+ /// IR is still in SSA form, the caller can pass the MachineRegisterInfo for
+ /// aggressive checks.
virtual bool produceSameValue(const MachineInstr *MI0,
- const MachineInstr *MI1) const = 0;
+ const MachineInstr *MI1,
+ const MachineRegisterInfo *MRI = 0) const = 0;
/// AnalyzeBranch - Analyze the branching code at the end of MBB, returning
/// true if it cannot be understood (e.g. it's a switch dispatch or isn't
@@ -268,7 +271,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!");
+ assert(0 && "Target didn't implement TargetInstrInfo::RemoveBranch!");
return 0;
}
@@ -286,7 +289,7 @@ public:
MachineBasicBlock *FBB,
const SmallVectorImpl<MachineOperand> &Cond,
DebugLoc DL) const {
- assert(0 && "Target didn't implement TargetInstrInfo::InsertBranch!");
+ assert(0 && "Target didn't implement TargetInstrInfo::InsertBranch!");
return 0;
}
@@ -315,7 +318,7 @@ public:
float Probability, float Confidence) const {
return false;
}
-
+
/// isProfitableToIfCvt - Second variant of isProfitableToIfCvt, this one
/// checks for the case where two basic blocks from true and false path
/// of a if-then-else (diamond) are predicated on mutally exclusive
@@ -342,7 +345,7 @@ public:
float Probability, float Confidence) const {
return false;
}
-
+
/// copyPhysReg - Emit instructions to copy a pair of physical registers.
virtual void copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI, DebugLoc DL,
@@ -375,29 +378,7 @@ public:
const TargetRegisterInfo *TRI) const {
assert(0 && "Target didn't implement TargetInstrInfo::loadRegFromStackSlot!");
}
-
- /// spillCalleeSavedRegisters - Issues instruction(s) to spill all callee
- /// saved registers and returns true if it isn't possible / profitable to do
- /// so by issuing a series of store instructions via
- /// storeRegToStackSlot(). Returns false otherwise.
- virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator MI,
- const std::vector<CalleeSavedInfo> &CSI,
- const TargetRegisterInfo *TRI) const {
- return false;
- }
- /// restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee
- /// saved registers and returns true if it isn't possible / profitable to do
- /// so by issuing a series of load instructions via loadRegToStackSlot().
- /// Returns false otherwise.
- virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator MI,
- const std::vector<CalleeSavedInfo> &CSI,
- const TargetRegisterInfo *TRI) const {
- return false;
- }
-
/// emitFrameIndexDebugValue - Emit a target-dependent form of
/// DBG_VALUE encoding the address of a frame index. Addresses would
/// normally be lowered the same way as other addresses on the target,
@@ -508,7 +489,7 @@ public:
unsigned NumLoads) const {
return false;
}
-
+
/// ReverseBranchCondition - Reverses the branch condition of the specified
/// condition list, returning false on success and true if it cannot be
/// reversed.
@@ -516,19 +497,19 @@ public:
bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
return true;
}
-
+
/// insertNoop - Insert a noop into the instruction stream at the specified
/// point.
- virtual void insertNoop(MachineBasicBlock &MBB,
+ virtual void insertNoop(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const;
-
-
+
+
/// getNoopForMachoTarget - Return the noop instruction to use for a noop.
virtual void getNoopForMachoTarget(MCInst &NopInst) const {
// Default to just using 'nop' string.
}
-
-
+
+
/// isPredicated - Returns true if the instruction is already predicated.
///
virtual bool isPredicated(const MachineInstr *MI) const {
@@ -586,11 +567,19 @@ public:
virtual unsigned getInlineAsmLength(const char *Str,
const MCAsmInfo &MAI) const;
- /// CreateTargetHazardRecognizer - Allocate and return a hazard recognizer
- /// to use for this target when scheduling the machine instructions after
+ /// CreateTargetHazardRecognizer - Allocate and return a hazard recognizer to
+ /// use for this target when scheduling the machine instructions before
/// register allocation.
virtual ScheduleHazardRecognizer*
- CreateTargetPostRAHazardRecognizer(const InstrItineraryData*) const = 0;
+ CreateTargetHazardRecognizer(const TargetMachine *TM,
+ const ScheduleDAG *DAG) const = 0;
+
+ /// CreateTargetPostRAHazardRecognizer - Allocate and return a hazard
+ /// recognizer to use for this target when scheduling the machine instructions
+ /// after register allocation.
+ virtual ScheduleHazardRecognizer*
+ CreateTargetPostRAHazardRecognizer(const InstrItineraryData*,
+ const ScheduleDAG *DAG) const = 0;
/// AnalyzeCompare - For a comparison instruction, return the source register
/// in SrcReg and the value it compares against in CmpValue. Return true if
@@ -609,11 +598,26 @@ public:
return false;
}
+ /// FoldImmediate - 'Reg' is known to be defined by a move immediate
+ /// instruction, try to fold the immediate into the use instruction.
+ virtual bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI,
+ unsigned Reg, MachineRegisterInfo *MRI) const {
+ return false;
+ }
+
/// getNumMicroOps - Return the number of u-operations the given machine
/// instruction will be decoded to on the target cpu.
virtual unsigned getNumMicroOps(const InstrItineraryData *ItinData,
const MachineInstr *MI) const;
+ /// isZeroCost - Return true for pseudo instructions that don't consume any
+ /// machine resources in their current form. These are common cases that the
+ /// scheduler should consider free, rather than conservatively handling them
+ /// as instructions with no itinerary.
+ bool isZeroCost(unsigned Opcode) const {
+ return Opcode <= TargetOpcode::COPY;
+ }
+
/// getOperandLatency - Compute and return the use operand latency of a given
/// pair of def and use.
/// In most cases, the static scheduling itinerary was enough to determine the
@@ -637,6 +641,10 @@ public:
virtual int getInstrLatency(const InstrItineraryData *ItinData,
SDNode *Node) const;
+ /// isHighLatencyDef - Return true if this opcode has high latency to its
+ /// result.
+ virtual bool isHighLatencyDef(int opc) const { return false; }
+
/// hasHighOperandLatency - Compute operand latency between a def of 'Reg'
/// and an use in the current loop, return true if the target considered
/// it 'high'. This is used by optimization passes such as machine LICM to
@@ -684,13 +692,20 @@ public:
virtual MachineInstr *duplicate(MachineInstr *Orig,
MachineFunction &MF) const;
virtual bool produceSameValue(const MachineInstr *MI0,
- const MachineInstr *MI1) const;
+ const MachineInstr *MI1,
+ const MachineRegisterInfo *MRI) const;
virtual bool isSchedulingBoundary(const MachineInstr *MI,
const MachineBasicBlock *MBB,
const MachineFunction &MF) const;
+ bool usePreRAHazardRecognizer() const;
+
+ virtual ScheduleHazardRecognizer *
+ CreateTargetHazardRecognizer(const TargetMachine*, const ScheduleDAG*) const;
+
virtual ScheduleHazardRecognizer *
- CreateTargetPostRAHazardRecognizer(const InstrItineraryData*) const;
+ CreateTargetPostRAHazardRecognizer(const InstrItineraryData*,
+ const ScheduleDAG*) const;
};
} // End llvm namespace
diff --git a/include/llvm/Target/TargetInstrItineraries.h b/include/llvm/Target/TargetInstrItineraries.h
index 380147c650..a95b70f6b9 100644
--- a/include/llvm/Target/TargetInstrItineraries.h
+++ b/include/llvm/Target/TargetInstrItineraries.h
@@ -113,15 +113,17 @@ public:
const unsigned *OperandCycles; ///< Array of operand cycles selected
const unsigned *Forwardings; ///< Array of pipeline forwarding pathes
const InstrItinerary *Itineraries; ///< Array of itineraries selected
+ unsigned IssueWidth; ///< Max issue per cycle. 0=Unknown.
/// Ctors.
///
InstrItineraryData() : Stages(0), OperandCycles(0), Forwardings(0),
- Itineraries(0) {}
+ Itineraries(0), IssueWidth(0) {}
+
InstrItineraryData(const InstrStage *S, const unsigned *OS,
const unsigned *F, const InstrItinerary *I)
: Stages(S), OperandCycles(OS), Forwardings(F), Itineraries(I) {}
-
+
/// isEmpty - Returns true if there are no itineraries.
///
bool isEmpty() const { return Itineraries == 0; }
@@ -135,14 +137,14 @@ public:
}
/// beginStage - Return the first stage of the itinerary.
- ///
+ ///
const InstrStage *beginStage(unsigned ItinClassIndx) const {
unsigned StageIdx = Itineraries[ItinClassIndx].FirstStage;
return Stages + StageIdx;
}
/// endStage - Return the last+1 stage of the itinerary.
- ///
+ ///
const InstrStage *endStage(unsigned ItinClassIndx) const {
unsigned StageIdx = Itineraries[ItinClassIndx].LastStage;
return Stages + StageIdx;
diff --git a/include/llvm/Target/TargetJITInfo.h b/include/llvm/Target/TargetJITInfo.h
index 7208a8dc44..b198eb62f0 100644
--- a/include/llvm/Target/TargetJITInfo.h
+++ b/include/llvm/Target/TargetJITInfo.h
@@ -19,7 +19,7 @@
#include <cassert>
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
class Function;
diff --git a/include/llvm/Target/TargetLibraryInfo.h b/include/llvm/Target/TargetLibraryInfo.h
new file mode 100644
index 0000000000..1847a3725e
--- /dev/null
+++ b/include/llvm/Target/TargetLibraryInfo.h
@@ -0,0 +1,75 @@
+//===-- llvm/Target/TargetLibraryInfo.h - Library information ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETLIBRARYINFO_H
+#define LLVM_TARGET_TARGETLIBRARYINFO_H
+
+#include "llvm/Pass.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);
+ memcpy,
+
+ /// void memset_pattern16(void *b, const void *pattern16, size_t len);
+ memset_pattern16,
+
+ /// int iprintf(const char *format, ...);
+ iprintf,
+
+ /// int siprintf(char *str, const char *format, ...);
+ siprintf,
+
+ /// int fiprintf(FILE *stream, const char *format, ...);
+ fiprintf,
+
+ NumLibFuncs
+ };
+ }
+
+/// TargetLibraryInfo - This immutable pass captures information about what
+/// 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];
+public:
+ static char ID;
+ TargetLibraryInfo();
+ TargetLibraryInfo(const Triple &T);
+
+ /// 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;
+ }
+
+ /// 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));
+ }
+
+ void setAvailable(LibFunc::Func F) {
+ AvailableArray[F/8] |= 1 << (F&7);
+ }
+
+ /// disableAllFunctions - This disables all builtins, which is used for
+ /// options like -fno-builtin.
+ void disableAllFunctions();
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index 75e5325524..42c330f4f2 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -39,6 +39,7 @@ namespace llvm {
class AllocaInst;
class APFloat;
class CallInst;
+ class CCState;
class Function;
class FastISel;
class FunctionLoweringInfo;
@@ -111,7 +112,7 @@ public:
bool isBigEndian() const { return !IsLittleEndian; }
bool isLittleEndian() const { return IsLittleEndian; }
MVT getPointerTy() const { return PointerTy; }
- MVT getShiftAmountTy() const { return ShiftAmountTy; }
+ virtual MVT getShiftAmountTy(EVT LHSTy) const;
/// isSelectExpensive - Return true if the select operation is expensive for
/// this target.
@@ -125,6 +126,10 @@ public:
/// srl/add/sra.
bool isPow2DivCheap() const { return Pow2DivIsCheap; }
+ /// isJumpExpensive() - Return true if Flow Control is an expensive operation
+ /// that should be avoided.
+ bool isJumpExpensive() const { return JumpIsExpensive; }
+
/// getSetCCResultType - Return the ValueType of the result of SETCC
/// operations. Also used to obtain the target's preferred type for
/// the condition operand of SELECT and BRCOND nodes. In the case of
@@ -206,7 +211,7 @@ public:
/// ValueTypeActions - For each value type, keep a LegalizeAction enum
/// that indicates how instruction selection should deal with the type.
uint8_t ValueTypeActions[MVT::LAST_VALUETYPE];
-
+
LegalizeAction getExtendedTypeAction(EVT VT) const {
// Handle non-vector integers.
if (!VT.isVector()) {
@@ -217,42 +222,56 @@ public:
return Promote;
return Expand;
}
-
- // If this is a type smaller than a legal vector type, promote to that
- // type, e.g. <2 x float> -> <4 x float>.
- if (VT.getVectorElementType().isSimple() &&
- VT.getVectorNumElements() != 1) {
- MVT EltType = VT.getVectorElementType().getSimpleVT();
- unsigned NumElts = VT.getVectorNumElements();
- while (1) {
- // Round up to the nearest power of 2.
- NumElts = (unsigned)NextPowerOf2(NumElts);
-
- MVT LargerVector = MVT::getVectorVT(EltType, NumElts);
- if (LargerVector == MVT()) break;
-
- // If this the larger type is legal, promote to it.
- if (getTypeAction(LargerVector) == Legal) return Promote;
- }
+
+ // Vectors with only one element are always scalarized.
+ if (VT.getVectorNumElements() == 1)
+ return Expand;
+
+ // Vectors with a number of elements that is not a power of two are always
+ // widened, for example <3 x float> -> <4 x float>.
+ if (!VT.isPow2VectorType())
+ return Promote;
+
+ // Vectors with a crazy element type are always expanded, for example
+ // <4 x i2> is expanded into two vectors of type <2 x i2>.
+ if (!VT.getVectorElementType().isSimple())
+ return Expand;
+
+ // If this type is smaller than a legal vector type then widen it,
+ // otherwise expand it. E.g. <2 x float> -> <4 x float>.
+ MVT EltType = VT.getVectorElementType().getSimpleVT();
+ unsigned NumElts = VT.getVectorNumElements();
+ while (1) {
+ // Round up to the next power of 2.
+ NumElts = (unsigned)NextPowerOf2(NumElts);
+
+ // If there is no simple vector type with this many elements then there
+ // cannot be a larger legal vector type. Note that this assumes that
+ // there are no skipped intermediate vector types in the simple types.
+ MVT LargerVector = MVT::getVectorVT(EltType, NumElts);
+ if (LargerVector == MVT())
+ return Expand;
+
+ // If this type is legal then widen the vector.
+ if (getTypeAction(LargerVector) == Legal)
+ return Promote;
}
-
- return VT.isPow2VectorType() ? Expand : Promote;
- }
+ }
public:
ValueTypeActionImpl() {
std::fill(ValueTypeActions, array_endof(ValueTypeActions), 0);
}
-
+
LegalizeAction getTypeAction(EVT VT) const {
if (!VT.isExtended())
return getTypeAction(VT.getSimpleVT());
return getExtendedTypeAction(VT);
}
-
+
LegalizeAction getTypeAction(MVT VT) const {
return (LegalizeAction)ValueTypeActions[VT.SimpleTy];
}
-
+
void setTypeAction(EVT VT, LegalizeAction Action) {
unsigned I = VT.getSimpleVT().SimpleTy;
ValueTypeActions[I] = Action;
@@ -273,7 +292,7 @@ public:
LegalizeAction getTypeAction(MVT VT) const {
return ValueTypeActions.getTypeAction(VT);
}
-
+
/// getTypeToTransformTo - For types supported by the target, this is an
/// identity function. For types that must be promoted to larger types, this
/// returns the larger type to promote to. For integer types that are larger
@@ -306,7 +325,7 @@ public:
EVT NVT = VT.getRoundIntegerType(Context);
if (NVT == VT) // Size is a power of two - expand to half the size.
return EVT::getIntegerVT(Context, VT.getSizeInBits() / 2);
-
+
// Promote to a power of two size, avoiding multi-step promotion.
return getTypeAction(NVT) == Promote ?
getTypeToTransformTo(Context, NVT) : NVT;
@@ -638,21 +657,30 @@ public:
/// This function returns the maximum number of store operations permitted
/// to replace a call to llvm.memset. The value is set by the target at the
- /// performance threshold for such a replacement.
+ /// performance threshold for such a replacement. If OptSize is true,
+ /// return the limit for functions that have OptSize attribute.
/// @brief Get maximum # of store operations permitted for llvm.memset
- unsigned getMaxStoresPerMemset() const { return maxStoresPerMemset; }
+ unsigned getMaxStoresPerMemset(bool OptSize) const {
+ return OptSize ? maxStoresPerMemsetOptSize : maxStoresPerMemset;
+ }
/// This function returns the maximum number of store operations permitted
/// to replace a call to llvm.memcpy. The value is set by the target at the
- /// performance threshold for such a replacement.
+ /// performance threshold for such a replacement. If OptSize is true,
+ /// return the limit for functions that have OptSize attribute.
/// @brief Get maximum # of store operations permitted for llvm.memcpy
- unsigned getMaxStoresPerMemcpy() const { return maxStoresPerMemcpy; }
+ unsigned getMaxStoresPerMemcpy(bool OptSize) const {
+ return OptSize ? maxStoresPerMemcpyOptSize : maxStoresPerMemcpy;
+ }
/// This function returns the maximum number of store operations permitted
/// to replace a call to llvm.memmove. The value is set by the target at the
- /// performance threshold for such a replacement.
+ /// performance threshold for such a replacement. If OptSize is true,
+ /// return the limit for functions that have OptSize attribute.
/// @brief Get maximum # of store operations permitted for llvm.memmove
- unsigned getMaxStoresPerMemmove() const { return maxStoresPerMemmove; }
+ unsigned getMaxStoresPerMemmove(bool OptSize) const {
+ return OptSize ? maxStoresPerMemmoveOptSize : maxStoresPerMemmove;
+ }
/// This function returns true if the target allows unaligned memory accesses.
/// of the specified type. This is used, for example, in situations where an
@@ -950,6 +978,13 @@ public:
return isTypeLegal(VT);
}
+ /// isDesirableToPromoteOp - Return true if it is profitable for dag combiner
+ /// to transform a floating point op of specified opcode to a equivalent op of
+ /// an integer type. e.g. f32 load -> i32 load can be profitable on ARM.
+ virtual bool isDesirableToTransformToIntegerOp(unsigned Opc, EVT VT) const {
+ return false;
+ }
+
/// IsDesirableToPromoteOp - This method query the target whether it is
/// beneficial for dag combiner to promote the specified node. If true, it
/// should return the desired promotion type by reference.
@@ -963,10 +998,6 @@ public:
//
protected:
- /// setShiftAmountType - Describe the type that should be used for shift
- /// amounts. This type defaults to the pointer type.
- void setShiftAmountType(MVT VT) { ShiftAmountTy = VT; }
-
/// setBooleanContents - Specify how the target extends the result of a
/// boolean value from i1 to a wider type. See getBooleanContents.
void setBooleanContents(BooleanContent Ty) { BooleanContents = Ty; }
@@ -1013,7 +1044,16 @@ protected:
/// SelectIsExpensive - Tells the code generator not to expand operations
/// into sequences that use the select operations if possible.
- void setSelectIsExpensive() { SelectIsExpensive = true; }
+ void setSelectIsExpensive(bool isExpensive = true) {
+ SelectIsExpensive = isExpensive;
+ }
+
+ /// JumpIsExpensive - Tells the code generator not to expand sequence of
+ /// operations into a seperate sequences that increases the amount of
+ /// flow control.
+ void setJumpIsExpensive(bool isExpensive = true) {
+ JumpIsExpensive = isExpensive;
+ }
/// setIntDivIsCheap - Tells the code generator that integer divide is
/// expensive, and if possible, should be replaced by an alternate sequence
@@ -1219,6 +1259,9 @@ public:
return SDValue(); // this is here to silence compiler errors
}
+ /// HandleByVal - Target-specific cleanup for formal ByVal parameters.
+ virtual void HandleByVal(CCState *) const {}
+
/// CanLowerReturn - This hook should be implemented to check whether the
/// return values described by the Outs array can fit into the return
/// registers. If false is returned, an sret-demotion is performed.
@@ -1245,6 +1288,13 @@ public:
return SDValue(); // this is here to silence compiler errors
}
+ /// 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
+ /// to codegen a libcall as tail call at legalization time.
+ virtual bool isUsedByReturnOnly(SDNode *N) const {
+ return false;
+ }
+
/// LowerOperationWrapper - This callback is invoked by the type legalizer
/// to legalize nodes with an illegal operand type but legal result types.
/// It replaces the LowerOperation callback in the type Legalizer.
@@ -1319,7 +1369,7 @@ public:
CW_Good = 1, // Good weight.
CW_Better = 2, // Better weight.
CW_Best = 3, // Best weight.
-
+
// Well-known weights.
CW_SpecificReg = CW_Okay, // Specific register operands.
CW_Register = CW_Good, // Register operands.
@@ -1372,21 +1422,21 @@ public:
CallOperandVal(0), ConstraintVT(MVT::Other) {
}
};
-
+
typedef std::vector<AsmOperandInfo> AsmOperandInfoVector;
-
+
/// ParseConstraints - Split up the constraint string from the inline
/// assembly value into the specific constraints and their prefixes,
/// and also tie in the associated operand values.
/// If this returns an empty vector, and if the constraint string itself
/// isn't empty, there was an error parsing.
virtual AsmOperandInfoVector ParseConstraints(ImmutableCallSite CS) const;
-
+
/// Examine constraint type and operand type and determine a weight value.
/// The operand object must already have been set up with the operand type.
virtual ConstraintWeight getMultipleConstraintMatchWeight(
AsmOperandInfo &info, int maIndex) const;
-
+
/// Examine constraint string and operand type and determine a weight value.
/// The operand object must already have been set up with the operand type.
virtual ConstraintWeight getSingleConstraintMatchWeight(
@@ -1396,7 +1446,7 @@ public:
/// type to use for the specific AsmOperandInfo, setting
/// OpInfo.ConstraintCode and OpInfo.ConstraintType. If the actual operand
/// being passed in is available, it can be passed in as Op, otherwise an
- /// empty SDValue can be passed.
+ /// empty SDValue can be passed.
virtual void ComputeConstraintToUse(AsmOperandInfo &OpInfo,
SDValue Op,
SelectionDAG *DAG = 0) const;
@@ -1597,6 +1647,11 @@ private:
/// it.
bool Pow2DivIsCheap;
+ /// JumpIsExpensive - Tells the code generator that it shouldn't generate
+ /// extra flow control instructions and should attempt to combine flow
+ /// control instructions via predication.
+ bool JumpIsExpensive;
+
/// UseUnderscoreSetJmp - This target prefers to use _setjmp to implement
/// llvm.setjmp. Defaults to false.
bool UseUnderscoreSetJmp;
@@ -1605,10 +1660,6 @@ private:
/// llvm.longjmp. Defaults to false.
bool UseUnderscoreLongJmp;
- /// ShiftAmountTy - The type to use for shift amounts, usually i8 or whatever
- /// PointerTy is.
- MVT ShiftAmountTy;
-
/// BooleanContents - Information about the contents of the high-bits in
/// boolean values held in a type wider than i1. See getBooleanContents.
BooleanContent BooleanContents;
@@ -1751,6 +1802,10 @@ protected:
/// @brief Specify maximum number of store instructions per memset call.
unsigned maxStoresPerMemset;
+ /// Maximum number of stores operations that may be substituted for the call
+ /// to memset, used for functions with OptSize attribute.
+ unsigned maxStoresPerMemsetOptSize;
+
/// When lowering \@llvm.memcpy this field specifies the maximum number of
/// store operations that may be substituted for a call to memcpy. Targets
/// must set this value based on the cost threshold for that target. Targets
@@ -1763,6 +1818,10 @@ protected:
/// @brief Specify maximum bytes of store instructions per memcpy call.
unsigned maxStoresPerMemcpy;
+ /// Maximum number of store operations that may be substituted for a call
+ /// to memcpy, used for functions with OptSize attribute.
+ unsigned maxStoresPerMemcpyOptSize;
+
/// When lowering \@llvm.memmove this field specifies the maximum number of
/// store instructions that may be substituted for a call to memmove. Targets
/// must set this value based on the cost threshold for that target. Targets
@@ -1774,6 +1833,10 @@ protected:
/// @brief Specify maximum bytes of store instructions per memmove call.
unsigned maxStoresPerMemmove;
+ /// Maximum number of store instructions that may be substituted for a call
+ /// to memmove, used for functions with OpSize attribute.
+ unsigned maxStoresPerMemmoveOptSize;
+
/// This field specifies whether the target can benefit from code placement
/// optimization.
bool benefitFromCodePlacementOpt;
diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h
index 5456dd0700..34bf27132d 100644
--- a/include/llvm/Target/TargetLoweringObjectFile.h
+++ b/include/llvm/Target/TargetLoweringObjectFile.h
@@ -69,10 +69,6 @@ protected:
/// the section the Language Specific Data Area information is emitted to.
const MCSection *LSDASection;
- /// EHFrameSection - If exception handling is supported by the target, this is
- /// the section the EH Frame is emitted to.
- const MCSection *EHFrameSection;
-
// Dwarf sections for debug info. If a target supports debug info, these must
// be set.
const MCSection *DwarfAbbrevSection;
@@ -143,7 +139,7 @@ public:
const MCSection *getStaticCtorSection() const { return StaticCtorSection; }
const MCSection *getStaticDtorSection() const { return StaticDtorSection; }
const MCSection *getLSDASection() const { return LSDASection; }
- const MCSection *getEHFrameSection() const { return EHFrameSection; }
+ virtual const MCSection *getEHFrameSection() const = 0;
const MCSection *getDwarfAbbrevSection() const { return DwarfAbbrevSection; }
const MCSection *getDwarfInfoSection() const { return DwarfInfoSection; }
const MCSection *getDwarfLineSection() const { return DwarfLineSection; }
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index 01dc1b0c41..030bf5b89f 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -29,7 +29,7 @@ class TargetIntrinsicInfo;
class TargetJITInfo;
class TargetLowering;
class TargetSelectionDAGInfo;
-class TargetFrameInfo;
+class TargetFrameLowering;
class JITCodeEmitter;
class MCContext;
class TargetRegisterInfo;
@@ -104,6 +104,8 @@ protected: // Can only create subclasses.
const MCAsmInfo *AsmInfo;
unsigned MCRelaxAll : 1;
+ unsigned MCNoExecStack : 1;
+ unsigned MCUseLoc : 1;
public:
virtual ~TargetMachine();
@@ -116,11 +118,11 @@ public:
// -- Stack frame information
// -- Selection DAG lowering information
//
- virtual const TargetInstrInfo *getInstrInfo() const { return 0; }
- virtual const TargetFrameInfo *getFrameInfo() const { return 0; }
+ virtual const TargetInstrInfo *getInstrInfo() const { return 0; }
+ virtual const TargetFrameLowering *getFrameLowering() const { return 0; }
virtual const TargetLowering *getTargetLowering() const { return 0; }
virtual const TargetSelectionDAGInfo *getSelectionDAGInfo() const{ return 0; }
- virtual const TargetData *getTargetData() const { return 0; }
+ virtual const TargetData *getTargetData() const { return 0; }
/// getMCAsmInfo - Return target specific asm information.
///
@@ -169,6 +171,18 @@ public:
/// relaxed.
void setMCRelaxAll(bool Value) { MCRelaxAll = Value; }
+ /// hasMCNoExecStack - Check whether an executable stack is not needed.
+ bool hasMCNoExecStack() const { return MCNoExecStack; }
+
+ /// setMCNoExecStack - Set whether an executabel stack is not needed.
+ void setMCNoExecStack(bool Value) { MCNoExecStack = Value; }
+
+ /// hasMCUseLoc - Check whether we should use dwarf's .loc directive.
+ bool hasMCUseLoc() const { return MCUseLoc; }
+
+ /// setMCUseLoc - Set whether all we should use dwarf's .loc directive.
+ void setMCUseLoc(bool Value) { MCUseLoc = Value; }
+
/// getRelocationModel - Returns the code generation relocation model. The
/// choices are static, PIC, and dynamic-no-pic, and target default.
static Reloc::Model getRelocationModel();
diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h
index 9be36238a1..af10748ef4 100644
--- a/include/llvm/Target/TargetRegisterInfo.h
+++ b/include/llvm/Target/TargetRegisterInfo.h
@@ -29,21 +29,21 @@ class MachineFunction;
class MachineMove;
class RegScavenger;
template<class T> class SmallVectorImpl;
+class raw_ostream;
/// TargetRegisterDesc - This record contains all of the information known about
-/// a particular register. The AliasSet field (if not null) contains a pointer
-/// to a Zero terminated array of registers that this register aliases. This is
-/// needed for architectures like X86 which have AL alias AX alias EAX.
-/// Registers that this does not apply to simply should set this to null.
-/// The SubRegs field is a zero terminated array of registers that are
-/// sub-registers of the specific register, e.g. AL, AH are sub-registers of AX.
-/// The SuperRegs field is a zero terminated array of registers that are
+/// a particular register. The Overlaps field contains a pointer to a zero
+/// terminated array of registers that this register aliases, starting with
+/// itself. This is needed for architectures like X86 which have AL alias AX
+/// alias EAX. The SubRegs field is a zero terminated array of registers that
+/// are sub-registers of the specific register, e.g. AL, AH are sub-registers of
+/// AX. The SuperRegs field is a zero terminated array of registers that are
/// super-registers of the specific register, e.g. RAX, EAX, are super-registers
/// of AX.
///
struct TargetRegisterDesc {
const char *Name; // Printable name for the reg (for debugging)
- const unsigned *AliasSet; // Register Alias Set, described above
+ const unsigned *Overlaps; // Overlapping registers, described above
const unsigned *SubRegs; // Sub-register set, described above
const unsigned *SuperRegs; // Super-register set, described above
};
@@ -295,30 +295,68 @@ protected:
virtual ~TargetRegisterInfo();
public:
- enum { // Define some target independent constants
- /// NoRegister - This physical register is not a real target register. It
- /// is useful as a sentinal.
- NoRegister = 0,
+ // Register numbers can represent physical registers, virtual registers, and
+ // sometimes stack slots. The unsigned values are divided into these ranges:
+ //
+ // 0 Not a register, can be used as a sentinel.
+ // [1;2^30) Physical registers assigned by TableGen.
+ // [2^30;2^31) Stack slots. (Rarely used.)
+ // [2^31;2^32) Virtual registers assigned by MachineRegisterInfo.
+ //
+ // Further sentinels can be allocated from the small negative integers.
+ // DenseMapInfo<unsigned> uses -1u and -2u.
+
+ /// isStackSlot - Sometimes it is useful the be able to store a non-negative
+ /// frame index in a variable that normally holds a register. isStackSlot()
+ /// returns true if Reg is in the range used for stack slots.
+ ///
+ /// Note that isVirtualRegister() and isPhysicalRegister() cannot handle stack
+ /// slots, so if a variable may contains a stack slot, always check
+ /// isStackSlot() first.
+ ///
+ static bool isStackSlot(unsigned Reg) {
+ return int(Reg) >= (1 << 30);
+ }
- /// FirstVirtualRegister - This is the first register number that is
- /// considered to be a 'virtual' register, which is part of the SSA
- /// namespace. This must be the same for all targets, which means that each
- /// target is limited to this fixed number of registers.
- FirstVirtualRegister = 16384
- };
+ /// stackSlot2Index - Compute the frame index from a register value
+ /// representing a stack slot.
+ static int stackSlot2Index(unsigned Reg) {
+ assert(isStackSlot(Reg) && "Not a stack slot");
+ return int(Reg - (1u << 30));
+ }
+
+ /// index2StackSlot - Convert a non-negative frame index to a stack slot
+ /// register value.
+ static unsigned index2StackSlot(int FI) {
+ assert(FI >= 0 && "Cannot hold a negative frame index.");
+ return FI + (1u << 30);
+ }
/// isPhysicalRegister - Return true if the specified register number is in
/// the physical register namespace.
static bool isPhysicalRegister(unsigned Reg) {
- assert(Reg && "this is not a register!");
- return Reg < FirstVirtualRegister;
+ assert(!isStackSlot(Reg) && "Not a register! Check isStackSlot() first.");
+ return int(Reg) > 0;
}
/// isVirtualRegister - Return true if the specified register number is in
/// the virtual register namespace.
static bool isVirtualRegister(unsigned Reg) {
- assert(Reg && "this is not a register!");
- return Reg >= FirstVirtualRegister;
+ assert(!isStackSlot(Reg) && "Not a register! Check isStackSlot() first.");
+ return int(Reg) < 0;
+ }
+
+ /// virtReg2Index - Convert a virtual register number to a 0-based index.
+ /// The first virtual register in a function will get the index 0.
+ static unsigned virtReg2Index(unsigned Reg) {
+ assert(isVirtualRegister(Reg) && "Not a virtual register");
+ return Reg - (1u << 31);
+ }
+
+ /// index2VirtReg - Convert a 0-based index to a virtual register number.
+ /// This is the inverse operation of VirtReg2IndexFunctor below.
+ static unsigned index2VirtReg(unsigned Index) {
+ return Index + (1u << 31);
}
/// getMinimalPhysRegClass - Returns the Register Class of a physical
@@ -351,7 +389,17 @@ public:
/// terminated.
///
const unsigned *getAliasSet(unsigned RegNo) const {
- return get(RegNo).AliasSet;
+ // The Overlaps set always begins with Reg itself.
+ return get(RegNo).Overlaps + 1;
+ }
+
+ /// getOverlaps - Return a list of registers that overlap Reg, including
+ /// itself. This is the same as the alias set except Reg is included in the
+ /// list.
+ /// These are exactly the registers in { x | regsOverlap(x, Reg) }.
+ ///
+ const unsigned *getOverlaps(unsigned RegNo) const {
+ return get(RegNo).Overlaps;
}
/// getSubRegisters - Return the list of registers that are sub-registers of
@@ -583,6 +631,13 @@ public:
return false;
}
+ /// useFPForScavengingIndex - returns true if the target wants to use
+ /// frame pointer based accesses to spill to the scavenger emergency spill
+ /// slot.
+ virtual bool useFPForScavengingIndex(const MachineFunction &MF) const {
+ return true;
+ }
+
/// requiresFrameIndexScavenging - returns true if the target requires post
/// PEI scavenging of registers for materializing frame index constants.
virtual bool requiresFrameIndexScavenging(const MachineFunction &MF) const {
@@ -596,31 +651,6 @@ public:
return false;
}
- /// hasFP - Return true if the specified function should have a dedicated
- /// frame pointer register. For most targets this is true only if the function
- /// has variable sized allocas or if frame pointer elimination is disabled.
- virtual bool hasFP(const MachineFunction &MF) const = 0;
-
- /// hasReservedCallFrame - Under normal circumstances, when a frame pointer is
- /// not required, we reserve argument space for call sites in the function
- /// immediately on entry to the current function. This eliminates the need for
- /// add/sub sp brackets around call sites. Returns true if the call frame is
- /// included as part of the stack frame.
- virtual bool hasReservedCallFrame(const MachineFunction &MF) const {
- return !hasFP(MF);
- }
-
- /// canSimplifyCallFramePseudos - When possible, it's best to simplify the
- /// call frame pseudo ops before doing frame index elimination. This is
- /// possible only when frame index references between the pseudos won't
- /// need adjusting for the call frame adjustments. Normally, that's true
- /// if the function has a reserved call frame or a frame pointer. Some
- /// targets (Thumb2, for example) may have more complicated criteria,
- /// however, and can override this behavior.
- virtual bool canSimplifyCallFramePseudos(const MachineFunction &MF) const {
- return hasReservedCallFrame(MF) || hasFP(MF);
- }
-
/// hasReservedSpillSlot - Return true if target has reserved a spill slot in
/// the stack frame of the given function for the specified register. e.g. On
/// x86, if the frame register is required, the first fixed stack object is
@@ -640,7 +670,7 @@ public:
}
/// getFrameIndexInstrOffset - Get the offset from the referenced frame
- /// index in the instruction, if the is one.
+ /// index in the instruction, if there is one.
virtual int64_t getFrameIndexInstrOffset(const MachineInstr *MI,
int Idx) const {
return 0;
@@ -656,7 +686,7 @@ public:
/// materializeFrameBaseRegister - Insert defining instruction(s) for
/// BaseReg to be a pointer to FrameIdx before insertion point I.
- virtual void materializeFrameBaseRegister(MachineBasicBlock::iterator I,
+ virtual void materializeFrameBaseRegister(MachineBasicBlock *MBB,
unsigned BaseReg, int FrameIdx,
int64_t Offset) const {
assert(0 && "materializeFrameBaseRegister does not exist on this target");
@@ -703,21 +733,6 @@ public:
assert(0 && "Call Frame Pseudo Instructions do not exist on this target!");
}
- /// processFunctionBeforeCalleeSavedScan - This method is called immediately
- /// before PrologEpilogInserter scans the physical registers used to determine
- /// what callee saved registers should be spilled. This method is optional.
- virtual void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
- RegScavenger *RS = NULL) const {
-
- }
-
- /// processFunctionBeforeFrameFinalized - This method is called immediately
- /// before the specified function's frame layout (MF.getFrameInfo()) is
- /// finalized. Once the frame is finalized, MO_FrameIndex operands are
- /// replaced with direct constants. This method is optional.
- ///
- virtual void processFunctionBeforeFrameFinalized(MachineFunction &MF) const {
- }
/// saveScavengerRegister - Spill the register so it can be used by the
/// register scavenger. Return true if the register was spilled, false
@@ -755,37 +770,16 @@ public:
/// for values allocated in the current stack frame.
virtual unsigned getFrameRegister(const MachineFunction &MF) const = 0;
- /// getFrameIndexOffset - Returns the displacement from the frame register to
- /// the stack frame of the specified index.
- virtual int getFrameIndexOffset(const MachineFunction &MF, int FI) const;
-
- /// getFrameIndexReference - This method should return the base register
- /// and offset used to reference a frame index location. The offset is
- /// returned directly, and the base register is returned via FrameReg.
- virtual int getFrameIndexReference(const MachineFunction &MF, int FI,
- unsigned &FrameReg) const {
- // By default, assume all frame indices are referenced via whatever
- // getFrameRegister() says. The target can override this if it's doing
- // something different.
- FrameReg = getFrameRegister(MF);
- return getFrameIndexOffset(MF, FI);
- }
-
/// getRARegister - This method should return the register where the return
/// address can be found.
virtual unsigned getRARegister() const = 0;
-
- /// getInitialFrameState - Returns a list of machine moves that are assumed
- /// on entry to all functions. Note that LabelID is ignored (assumed to be
- /// the beginning of the function.)
- virtual void getInitialFrameState(std::vector<MachineMove> &Moves) const;
};
// This is useful when building IndexedMaps keyed on virtual registers
struct VirtReg2IndexFunctor : public std::unary_function<unsigned, unsigned> {
unsigned operator()(unsigned Reg) const {
- return Reg - TargetRegisterInfo::FirstVirtualRegister;
+ return TargetRegisterInfo::virtReg2Index(Reg);
}
};
@@ -794,6 +788,33 @@ struct VirtReg2IndexFunctor : public std::unary_function<unsigned, unsigned> {
const TargetRegisterClass *getCommonSubClass(const TargetRegisterClass *A,
const TargetRegisterClass *B);
+/// PrintReg - Helper class for printing registers on a raw_ostream.
+/// Prints virtual and physical registers with or without a TRI instance.
+///
+/// The format is:
+/// %noreg - NoRegister
+/// %vreg5 - a virtual register.
+/// %vreg5:sub_8bit - a virtual register with sub-register index (with TRI).
+/// %EAX - a physical register
+/// %physreg17 - a physical register when no TRI instance given.
+///
+/// Usage: OS << PrintReg(Reg, TRI) << '\n';
+///
+class PrintReg {
+ const TargetRegisterInfo *TRI;
+ unsigned Reg;
+ unsigned SubIdx;
+public:
+ PrintReg(unsigned reg, const TargetRegisterInfo *tri = 0, unsigned subidx = 0)
+ : TRI(tri), Reg(reg), SubIdx(subidx) {}
+ void print(raw_ostream&) const;
+};
+
+static inline raw_ostream &operator<<(raw_ostream &OS, const PrintReg &PR) {
+ PR.print(OS);
+ return OS;
+}
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Target/TargetRegistry.h b/include/llvm/Target/TargetRegistry.h
index abffb5852a..f851ad0a9b 100644
--- a/include/llvm/Target/TargetRegistry.h
+++ b/include/llvm/Target/TargetRegistry.h
@@ -42,9 +42,11 @@ namespace llvm {
class formatted_raw_ostream;
MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
- bool isLittleEndian, bool isVerboseAsm,
+ bool isVerboseAsm,
+ bool useLoc,
MCInstPrinter *InstPrint,
MCCodeEmitter *CE,
+ TargetAsmBackend *TAB,
bool ShowInst);
/// Target - Wrapper for Target specific information.
@@ -87,13 +89,15 @@ namespace llvm {
TargetAsmBackend &TAB,
raw_ostream &_OS,
MCCodeEmitter *_Emitter,
- bool RelaxAll);
+ bool RelaxAll,
+ bool NoExecStack);
typedef MCStreamer *(*AsmStreamerCtorTy)(MCContext &Ctx,
formatted_raw_ostream &OS,
- bool isLittleEndian,
bool isVerboseAsm,
+ bool useLoc,
MCInstPrinter *InstPrint,
MCCodeEmitter *CE,
+ TargetAsmBackend *TAB,
bool ShowInst);
private:
@@ -305,27 +309,31 @@ namespace llvm {
/// \arg _OS - The stream object.
/// \arg _Emitter - The target independent assembler object.Takes ownership.
/// \arg RelaxAll - Relax all fixups?
+ /// \arg NoExecStack - Mark file as not needing a executable stack.
MCStreamer *createObjectStreamer(const std::string &TT, MCContext &Ctx,
TargetAsmBackend &TAB,
raw_ostream &_OS,
MCCodeEmitter *_Emitter,
- bool RelaxAll) const {
+ bool RelaxAll,
+ bool NoExecStack) const {
if (!ObjectStreamerCtorFn)
return 0;
- return ObjectStreamerCtorFn(*this, TT, Ctx, TAB, _OS, _Emitter, RelaxAll);
+ return ObjectStreamerCtorFn(*this, TT, Ctx, TAB, _OS, _Emitter, RelaxAll,
+ NoExecStack);
}
/// createAsmStreamer - Create a target specific MCStreamer.
MCStreamer *createAsmStreamer(MCContext &Ctx,
formatted_raw_ostream &OS,
- bool isLittleEndian,
bool isVerboseAsm,
+ bool useLoc,
MCInstPrinter *InstPrint,
MCCodeEmitter *CE,
+ TargetAsmBackend *TAB,
bool ShowInst) const {
// AsmStreamerCtorFn is default to llvm::createAsmStreamer
- return AsmStreamerCtorFn(Ctx, OS, isLittleEndian, isVerboseAsm,
- InstPrint, CE, ShowInst);
+ return AsmStreamerCtorFn(Ctx, OS, isVerboseAsm, useLoc,
+ InstPrint, CE, TAB, ShowInst);
}
/// @}
diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td
index 7315e52ef0..c9be40d23f 100644
--- a/include/llvm/Target/TargetSelectionDAG.td
+++ b/include/llvm/Target/TargetSelectionDAG.td
@@ -1,10 +1,10 @@
//===- TargetSelectionDAG.td - Common code for DAG isels ---*- tablegen -*-===//
-//
+//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
//
// This file defines the target-independent interfaces used by SelectionDAG
@@ -61,6 +61,13 @@ class SDTCisEltOfVec<int ThisOp, int OtherOp>
int OtherOpNum = OtherOp;
}
+/// SDTCisSubVecOfVec - This indicates that ThisOp is a vector type
+/// with length less that of OtherOp, which is a vector type.
+class SDTCisSubVecOfVec<int ThisOp, int OtherOp>
+ : SDTypeConstraint<ThisOp> {
+ int OtherOpNum = OtherOp;
+}
+
//===----------------------------------------------------------------------===//
// Selection DAG Type Profile definitions.
//
@@ -123,10 +130,10 @@ def SDTFPRoundOp : SDTypeProfile<1, 1, [ // fround
def SDTFPExtendOp : SDTypeProfile<1, 1, [ // fextend
SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<1, 0>
]>;
-def SDTIntToFPOp : SDTypeProfile<1, 1, [ // [su]int_to_fp
+def SDTIntToFPOp : SDTypeProfile<1, 1, [ // [su]int_to_fp
SDTCisFP<0>, SDTCisInt<1>
]>;
-def SDTFPToIntOp : SDTypeProfile<1, 1, [ // fp_to_[su]int
+def SDTFPToIntOp : SDTypeProfile<1, 1, [ // fp_to_[su]int
SDTCisInt<0>, SDTCisFP<1>
]>;
def SDTExtInreg : SDTypeProfile<1, 2, [ // sext_inreg
@@ -138,7 +145,7 @@ def SDTSetCC : SDTypeProfile<1, 3, [ // setcc
SDTCisInt<0>, SDTCisSameAs<1, 2>, SDTCisVT<3, OtherVT>
]>;
-def SDTSelect : SDTypeProfile<1, 3, [ // select
+def SDTSelect : SDTypeProfile<1, 3, [ // select
SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3>
]>;
@@ -162,11 +169,11 @@ def SDTBrind : SDTypeProfile<0, 1, [ // brind
def SDTNone : SDTypeProfile<0, 0, []>; // ret, trap
def SDTLoad : SDTypeProfile<1, 1, [ // load
- SDTCisPtrTy<1>
+ SDTCisPtrTy<1>
]>;
def SDTStore : SDTypeProfile<0, 2, [ // store
- SDTCisPtrTy<1>
+ SDTCisPtrTy<1>
]>;
def SDTIStore : SDTypeProfile<1, 3, [ // indexed store
@@ -183,6 +190,13 @@ def SDTVecInsert : SDTypeProfile<1, 3, [ // vector insert
SDTCisEltOfVec<2, 1>, SDTCisSameAs<0, 1>, SDTCisPtrTy<3>
]>;
+def SDTSubVecExtract : SDTypeProfile<1, 2, [// subvector extract
+ SDTCisSubVecOfVec<0,1>, SDTCisInt<2>
+]>;
+def SDTSubVecInsert : SDTypeProfile<1, 3, [ // subvector insert
+ SDTCisSubVecOfVec<2, 1>, SDTCisSameAs<0,1>, SDTCisInt<3>
+]>;
+
def SDTPrefetch : SDTypeProfile<0, 3, [ // prefetch
SDTCisPtrTy<0>, SDTCisSameAs<1, 2>, SDTCisInt<1>
]>;
@@ -216,9 +230,9 @@ class SDNodeProperty;
def SDNPCommutative : SDNodeProperty; // X op Y == Y op X
def SDNPAssociative : SDNodeProperty; // (X op Y) op Z == X op (Y op Z)
def SDNPHasChain : SDNodeProperty; // R/W chain operand and result
-def SDNPOutFlag : SDNodeProperty; // Write a flag result
-def SDNPInFlag : SDNodeProperty; // Read a flag operand
-def SDNPOptInFlag : SDNodeProperty; // Optionally read a flag operand
+def SDNPOutGlue : SDNodeProperty; // Write a flag result
+def SDNPInGlue : SDNodeProperty; // Read a flag operand
+def SDNPOptInGlue : SDNodeProperty; // Optionally read a flag operand
def SDNPMayStore : SDNodeProperty; // May write to memory, sets 'mayStore'.
def SDNPMayLoad : SDNodeProperty; // May read memory, sets 'mayLoad'.
def SDNPSideEffect : SDNodeProperty; // Sets 'HasUnmodelledSideEffects'.
@@ -235,7 +249,7 @@ class SDPatternOperator;
// Selection DAG Node definitions.
//
class SDNode<string opcode, SDTypeProfile typeprof,
- list<SDNodeProperty> props = [], string sdclass = "SDNode">
+ list<SDNodeProperty> props = [], string sdclass = "SDNode">
: SDPatternOperator {
string Opcode = opcode;
string SDClass = sdclass;
@@ -312,14 +326,14 @@ def or : SDNode<"ISD::OR" , SDTIntBinOp,
def xor : SDNode<"ISD::XOR" , SDTIntBinOp,
[SDNPCommutative, SDNPAssociative]>;
def addc : SDNode<"ISD::ADDC" , SDTIntBinOp,
- [SDNPCommutative, SDNPOutFlag]>;
+ [SDNPCommutative, SDNPOutGlue]>;
def adde : SDNode<"ISD::ADDE" , SDTIntBinOp,
- [SDNPCommutative, SDNPOutFlag, SDNPInFlag]>;
+ [SDNPCommutative, SDNPOutGlue, SDNPInGlue]>;
def subc : SDNode<"ISD::SUBC" , SDTIntBinOp,
- [SDNPOutFlag]>;
+ [SDNPOutGlue]>;
def sube : SDNode<"ISD::SUBE" , SDTIntBinOp,
- [SDNPOutFlag, SDNPInFlag]>;
-
+ [SDNPOutGlue, SDNPInGlue]>;
+
def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>;
def bswap : SDNode<"ISD::BSWAP" , SDTIntUnaryOp>;
def ctlz : SDNode<"ISD::CTLZ" , SDTIntUnaryOp>;
@@ -329,11 +343,11 @@ def sext : SDNode<"ISD::SIGN_EXTEND", SDTIntExtendOp>;
def zext : SDNode<"ISD::ZERO_EXTEND", SDTIntExtendOp>;
def anyext : SDNode<"ISD::ANY_EXTEND" , SDTIntExtendOp>;
def trunc : SDNode<"ISD::TRUNCATE" , SDTIntTruncOp>;
-def bitconvert : SDNode<"ISD::BIT_CONVERT", SDTUnaryOp>;
+def bitconvert : SDNode<"ISD::BITCAST" , SDTUnaryOp>;
def extractelt : SDNode<"ISD::EXTRACT_VECTOR_ELT", SDTVecExtract>;
def insertelt : SDNode<"ISD::INSERT_VECTOR_ELT", SDTVecInsert>;
-
+
def fadd : SDNode<"ISD::FADD" , SDTFPBinOp, [SDNPCommutative]>;
def fsub : SDNode<"ISD::FSUB" , SDTFPBinOp>;
def fmul : SDNode<"ISD::FMUL" , SDTFPBinOp, [SDNPCommutative]>;
@@ -375,7 +389,8 @@ def trap : SDNode<"ISD::TRAP" , SDTNone,
[SDNPHasChain, SDNPSideEffect]>;
def prefetch : SDNode<"ISD::PREFETCH" , SDTPrefetch,
- [SDNPHasChain, SDNPMayLoad, SDNPMayStore]>;
+ [SDNPHasChain, SDNPMayLoad, SDNPMayStore,
+ SDNPMemOperand]>;
def membarrier : SDNode<"ISD::MEMBARRIER" , SDTMemBarrier,
[SDNPHasChain, SDNPSideEffect]>;
@@ -422,16 +437,26 @@ def vector_extract : SDNode<"ISD::EXTRACT_VECTOR_ELT",
SDTypeProfile<1, 2, [SDTCisPtrTy<2>]>, []>;
def vector_insert : SDNode<"ISD::INSERT_VECTOR_ELT",
SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisPtrTy<3>]>, []>;
-
+
+// This operator does not do subvector type checking. The ARM
+// backend, at least, needs it.
+def vector_extract_subvec : SDNode<"ISD::EXTRACT_SUBVECTOR",
+ SDTypeProfile<1, 2, [SDTCisInt<2>, SDTCisVec<1>, SDTCisVec<0>]>,
+ []>;
+
+// This operator does subvector type checking.
+def extract_subvector : SDNode<"ISD::EXTRACT_SUBVECTOR", SDTSubVecExtract, []>;
+def insert_subvector : SDNode<"ISD::INSERT_SUBVECTOR", SDTSubVecInsert, []>;
+
// Nodes for intrinsics, you should use the intrinsic itself and let tblgen use
// these internally. Don't reference these directly.
-def intrinsic_void : SDNode<"ISD::INTRINSIC_VOID",
+def intrinsic_void : SDNode<"ISD::INTRINSIC_VOID",
SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>,
[SDNPHasChain]>;
-def intrinsic_w_chain : SDNode<"ISD::INTRINSIC_W_CHAIN",
+def intrinsic_w_chain : SDNode<"ISD::INTRINSIC_W_CHAIN",
SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>,
[SDNPHasChain]>;
-def intrinsic_wo_chain : SDNode<"ISD::INTRINSIC_WO_CHAIN",
+def intrinsic_wo_chain : SDNode<"ISD::INTRINSIC_WO_CHAIN",
SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>, []>;
// Do not use cvt directly. Use cvt forms below