summaryrefslogtreecommitdiffstats
path: root/include/llvm/Target
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Target')
-rw-r--r--include/llvm/Target/CostTable.h64
-rw-r--r--include/llvm/Target/Mangler.h6
-rw-r--r--include/llvm/Target/Target.td10
-rw-r--r--include/llvm/Target/TargetFrameLowering.h34
-rw-r--r--include/llvm/Target/TargetInstrInfo.h161
-rw-r--r--include/llvm/Target/TargetJITInfo.h2
-rw-r--r--include/llvm/Target/TargetLibraryInfo.h279
-rw-r--r--include/llvm/Target/TargetLowering.h1492
-rw-r--r--include/llvm/Target/TargetLoweringObjectFile.h17
-rw-r--r--include/llvm/Target/TargetMachine.h31
-rw-r--r--include/llvm/Target/TargetOptions.h18
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h106
-rw-r--r--include/llvm/Target/TargetSchedule.td6
-rw-r--r--include/llvm/Target/TargetSubtargetInfo.h11
-rw-r--r--include/llvm/Target/TargetTransformImpl.h98
15 files changed, 1319 insertions, 1016 deletions
diff --git a/include/llvm/Target/CostTable.h b/include/llvm/Target/CostTable.h
new file mode 100644
index 0000000..a974b56
--- /dev/null
+++ b/include/llvm/Target/CostTable.h
@@ -0,0 +1,64 @@
+//===-- CostTable.h - Instruction Cost Table handling -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Cost tables and simple lookup functions
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_COSTTABLE_H_
+#define LLVM_TARGET_COSTTABLE_H_
+
+namespace llvm {
+
+/// Cost Table Entry
+template <class TypeTy>
+struct CostTblEntry {
+ int ISD;
+ TypeTy Type;
+ unsigned Cost;
+};
+
+/// Find in cost table, TypeTy must be comparable by ==
+template <class TypeTy>
+int CostTableLookup(const CostTblEntry<TypeTy> *Tbl,
+ unsigned len, int ISD, TypeTy Ty) {
+ for (unsigned int i = 0; i < len; ++i)
+ if (Tbl[i].ISD == ISD && Tbl[i].Type == Ty)
+ return i;
+
+ // Could not find an entry.
+ return -1;
+}
+
+/// Type Conversion Cost Table
+template <class TypeTy>
+struct TypeConversionCostTblEntry {
+ int ISD;
+ TypeTy Dst;
+ TypeTy Src;
+ unsigned Cost;
+};
+
+/// Find in type conversion cost table, TypeTy must be comparable by ==
+template <class TypeTy>
+int ConvertCostTableLookup(const TypeConversionCostTblEntry<TypeTy> *Tbl,
+ unsigned len, int ISD, TypeTy Dst, TypeTy Src) {
+ for (unsigned int i = 0; i < len; ++i)
+ if (Tbl[i].ISD == ISD && Tbl[i].Src == Src && Tbl[i].Dst == Dst)
+ return i;
+
+ // Could not find an entry.
+ return -1;
+}
+
+} // namespace llvm
+
+
+#endif /* LLVM_TARGET_COSTTABLE_H_ */
diff --git a/include/llvm/Target/Mangler.h b/include/llvm/Target/Mangler.h
index a50f54a..9500f1c 100644
--- a/include/llvm/Target/Mangler.h
+++ b/include/llvm/Target/Mangler.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_MANGLER_H
-#define LLVM_SUPPORT_MANGLER_H
+#ifndef LLVM_TARGET_MANGLER_H
+#define LLVM_TARGET_MANGLER_H
#include "llvm/ADT/DenseMap.h"
@@ -69,4 +69,4 @@ public:
} // End llvm namespace
-#endif // LLVM_SUPPORT_MANGLER_H
+#endif // LLVM_TARGET_MANGLER_H
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index 12f5c0e..deee2eb 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -13,7 +13,7 @@
//===----------------------------------------------------------------------===//
// Include all information about LLVM intrinsics.
-include "llvm/Intrinsics.td"
+include "llvm/IR/Intrinsics.td"
//===----------------------------------------------------------------------===//
// Register file description - These classes are used to fill in the target
@@ -367,8 +367,9 @@ class Instruction {
// hasSideEffects - The instruction has side effects that are not
// captured by any operands of the instruction or other flags.
//
- // neverHasSideEffects - Set on an instruction with no pattern if it has no
- // side effects.
+ // neverHasSideEffects (deprecated) - Set on an instruction with no pattern
+ // if it has no side effects. This is now equivalent to setting
+ // "hasSideEffects = 0".
bit hasSideEffects = ?;
bit neverHasSideEffects = 0;
@@ -396,6 +397,9 @@ class Instruction {
InstrItinClass Itinerary = NoItinerary;// Execution steps used for scheduling.
+ // Scheduling information from TargetSchedule.td.
+ list<SchedReadWrite> SchedRW;
+
string Constraints = ""; // OperandConstraint, e.g. $src = $dst.
/// DisableEncoding - List of operand names (e.g. "$op1,$op2") that should not
diff --git a/include/llvm/Target/TargetFrameLowering.h b/include/llvm/Target/TargetFrameLowering.h
index d56db7b..d5f30f4 100644
--- a/include/llvm/Target/TargetFrameLowering.h
+++ b/include/llvm/Target/TargetFrameLowering.h
@@ -15,7 +15,6 @@
#define LLVM_TARGET_TARGETFRAMELOWERING_H
#include "llvm/CodeGen/MachineBasicBlock.h"
-
#include <utility>
#include <vector>
@@ -48,11 +47,12 @@ private:
unsigned StackAlignment;
unsigned TransientStackAlignment;
int LocalAreaOffset;
+ bool StackRealignable;
public:
TargetFrameLowering(StackDirection D, unsigned StackAl, int LAO,
- unsigned TransAl = 1)
+ unsigned TransAl = 1, bool StackReal = true)
: StackDir(D), StackAlignment(StackAl), TransientStackAlignment(TransAl),
- LocalAreaOffset(LAO) {}
+ LocalAreaOffset(LAO), StackRealignable(StackReal) {}
virtual ~TargetFrameLowering();
@@ -77,6 +77,12 @@ public:
return TransientStackAlignment;
}
+ /// isStackRealignable - This method returns whether the stack can be
+ /// realigned.
+ bool isStackRealignable() const {
+ return StackRealignable;
+ }
+
/// getOffsetOfLocalArea - This method returns the offset of the local area
/// from the stack pointer on entrance to a function.
///
@@ -114,6 +120,10 @@ public:
/// by adding a check even before the "normal" function prologue.
virtual void adjustForSegmentedStacks(MachineFunction &MF) const { }
+ /// Adjust the prologue to add Erlang Run-Time System (ERTS) specific code in
+ /// the assembly prologue to explicitly handle the stack.
+ virtual void adjustForHiPEPrologue(MachineFunction &MF) const { }
+
/// 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
@@ -184,7 +194,23 @@ public:
/// finalized. Once the frame is finalized, MO_FrameIndex operands are
/// replaced with direct constants. This method is optional.
///
- virtual void processFunctionBeforeFrameFinalized(MachineFunction &MF) const {
+ virtual void processFunctionBeforeFrameFinalized(MachineFunction &MF,
+ RegScavenger *RS = NULL) const {
+ }
+
+ /// eliminateCallFramePseudoInstr - This method is called during prolog/epilog
+ /// code insertion to eliminate call frame setup and destroy pseudo
+ /// instructions (but only if the Target is using them). It is responsible
+ /// for eliminating these instructions, replacing them with concrete
+ /// instructions. This method need only be implemented if using call frame
+ /// setup/destroy pseudo instructions.
+ ///
+ virtual void
+ eliminateCallFramePseudoInstr(MachineFunction &MF,
+ MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI) const {
+ llvm_unreachable("Call Frame Pseudo Instructions do not exist on this "
+ "target!");
}
};
diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h
index 4570813..0ba75e5 100644
--- a/include/llvm/Target/TargetInstrInfo.h
+++ b/include/llvm/Target/TargetInstrInfo.h
@@ -15,9 +15,9 @@
#define LLVM_TARGET_TARGETINSTRINFO_H
#include "llvm/ADT/SmallSet.h"
-#include "llvm/MC/MCInstrInfo.h"
#include "llvm/CodeGen/DFAPacketizer.h"
#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/MC/MCInstrInfo.h"
namespace llvm {
@@ -143,9 +143,7 @@ public:
/// missed.
virtual bool hasLoadFromStackSlot(const MachineInstr *MI,
const MachineMemOperand *&MMO,
- int &FrameIndex) const {
- return 0;
- }
+ int &FrameIndex) const;
/// isStoreToStackSlot - If the specified machine instruction is a direct
/// store to a stack slot, return the virtual or physical register number of
@@ -173,9 +171,7 @@ public:
/// stack. This is just a hint, as some cases may be missed.
virtual bool hasStoreToStackSlot(const MachineInstr *MI,
const MachineMemOperand *&MMO,
- int &FrameIndex) const {
- return 0;
- }
+ int &FrameIndex) const;
/// reMaterialize - Re-issue the specified 'original' instruction at the
/// specific location targeting a new destination register.
@@ -186,7 +182,7 @@ public:
MachineBasicBlock::iterator MI,
unsigned DestReg, unsigned SubIdx,
const MachineInstr *Orig,
- const TargetRegisterInfo &TRI) const = 0;
+ const TargetRegisterInfo &TRI) const;
/// duplicate - Create a duplicate of the Orig instruction in MF. This is like
/// MachineFunction::CloneMachineInstr(), but the target may update operands
@@ -194,7 +190,7 @@ public:
///
/// The instruction must be duplicable as indicated by isNotDuplicable().
virtual MachineInstr *duplicate(MachineInstr *Orig,
- MachineFunction &MF) const = 0;
+ MachineFunction &MF) const;
/// convertToThreeAddress - This method must be implemented by targets that
/// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target
@@ -221,13 +217,13 @@ public:
/// method for a non-commutable instruction, but there may be some cases
/// where this method fails and returns null.
virtual MachineInstr *commuteInstruction(MachineInstr *MI,
- bool NewMI = false) const = 0;
+ bool NewMI = false) const;
/// findCommutedOpIndices - If specified MI is commutable, return the two
/// operand indices that would swap value. Return false if the instruction
/// is not in a form which this routine understands.
virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1,
- unsigned &SrcOpIdx2) const = 0;
+ unsigned &SrcOpIdx2) const;
/// produceSameValue - Return true if two machine instructions would produce
/// identical values. By default, this is only true when the two instructions
@@ -236,7 +232,7 @@ public:
/// aggressive checks.
virtual bool produceSameValue(const MachineInstr *MI0,
const MachineInstr *MI1,
- const MachineRegisterInfo *MRI = 0) const = 0;
+ const MachineRegisterInfo *MRI = 0) const;
/// 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
@@ -298,7 +294,7 @@ public:
/// after it, replacing it with an unconditional branch to NewDest. This is
/// used by the tail merging pass.
virtual void ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail,
- MachineBasicBlock *NewDest) const = 0;
+ MachineBasicBlock *NewDest) const;
/// isLegalToSplitMBBAt - Return true if it's legal to split the given basic
/// block at the specified instruction (i.e. instruction would be the start
@@ -368,11 +364,10 @@ public:
/// condition code in Cond.
///
/// When successful, also return the latency in cycles from TrueReg,
- /// FalseReg, and Cond to the destination register. The Cond latency should
- /// compensate for a conditional branch being removed. For example, if a
- /// conditional branch has a 3 cycle latency from the condition code read,
- /// and a cmov instruction has a 2 cycle latency from the condition code
- /// read, CondCycles should be returned as -1.
+ /// FalseReg, and Cond to the destination register. In most cases, a select
+ /// instruction will be 1 cycle, so CondCycles = TrueCycles = FalseCycles = 1
+ ///
+ /// Some x86 implementations have 2-cycle cmov instructions.
///
/// @param MBB Block where select instruction would be inserted.
/// @param Cond Condition returned by AnalyzeBranch.
@@ -435,7 +430,7 @@ public:
SmallVectorImpl<MachineOperand> &Cond,
unsigned &TrueOp, unsigned &FalseOp,
bool &Optimizable) const {
- assert(MI && MI->isSelect() && "MI must be a select instruction");
+ assert(MI && MI->getDesc().isSelect() && "MI must be a select instruction");
return true;
}
@@ -569,7 +564,7 @@ public:
/// folding is possible.
virtual
bool canFoldMemoryOperand(const MachineInstr *MI,
- const SmallVectorImpl<unsigned> &Ops) const =0;
+ const SmallVectorImpl<unsigned> &Ops) const;
/// unfoldMemoryOperand - Separate a single instruction which folded a load or
/// a store or a load and a store into two or more instruction. If this is
@@ -621,6 +616,26 @@ public:
return false;
}
+ /// \brief Get the base register and byte offset of a load/store instr.
+ virtual bool getLdStBaseRegImmOfs(MachineInstr *LdSt,
+ unsigned &BaseReg, unsigned &Offset,
+ const TargetRegisterInfo *TRI) const {
+ return false;
+ }
+
+ virtual bool shouldClusterLoads(MachineInstr *FirstLdSt,
+ MachineInstr *SecondLdSt,
+ unsigned NumLoads) const {
+ return false;
+ }
+
+ /// \brief Can this target fuse the given instructions if they are scheduled
+ /// adjacent.
+ virtual bool shouldScheduleAdjacent(MachineInstr* First,
+ MachineInstr *Second) const {
+ return false;
+ }
+
/// ReverseBranchCondition - Reverses the branch condition of the specified
/// condition list, returning false on success and true if it cannot be
/// reversed.
@@ -649,13 +664,13 @@ public:
/// isUnpredicatedTerminator - Returns true if the instruction is a
/// terminator instruction that has not been predicated.
- virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const = 0;
+ virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const;
/// PredicateInstruction - Convert the instruction into a predicated
/// instruction. It returns true if the operation was successful.
virtual
bool PredicateInstruction(MachineInstr *MI,
- const SmallVectorImpl<MachineOperand> &Pred) const = 0;
+ const SmallVectorImpl<MachineOperand> &Pred) const;
/// SubsumesPredicate - Returns true if the first specified predicate
/// subsumes the second, e.g. GE subsumes GT.
@@ -691,7 +706,7 @@ public:
/// terminators.
virtual bool isSchedulingBoundary(const MachineInstr *MI,
const MachineBasicBlock *MBB,
- const MachineFunction &MF) const = 0;
+ const MachineFunction &MF) const;
/// Measure the specified inline asm to determine an approximation of its
/// length.
@@ -703,21 +718,25 @@ public:
/// register allocation.
virtual ScheduleHazardRecognizer*
CreateTargetHazardRecognizer(const TargetMachine *TM,
- const ScheduleDAG *DAG) const = 0;
+ const ScheduleDAG *DAG) const;
/// CreateTargetMIHazardRecognizer - Allocate and return a hazard recognizer
/// to use for this target when scheduling the machine instructions before
/// register allocation.
virtual ScheduleHazardRecognizer*
CreateTargetMIHazardRecognizer(const InstrItineraryData*,
- const ScheduleDAG *DAG) const = 0;
+ const ScheduleDAG *DAG) const;
/// 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;
+ const ScheduleDAG *DAG) const;
+
+ /// Provide a global flag for disabling the PreRA hazard recognizer that
+ /// targets may choose to honor.
+ bool usePreRAHazardRecognizer() const;
/// analyzeCompare - For a comparison instruction, return the source registers
/// in SrcReg and SrcReg2 if having two register operands, and the value it
@@ -765,7 +784,7 @@ public:
/// IssueWidth is the number of microops that can be dispatched each
/// cycle. An instruction with zero microops takes no dispatch resources.
virtual unsigned getNumMicroOps(const InstrItineraryData *ItinData,
- const MachineInstr *MI) const = 0;
+ 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
@@ -777,7 +796,7 @@ public:
virtual int getOperandLatency(const InstrItineraryData *ItinData,
SDNode *DefNode, unsigned DefIdx,
- SDNode *UseNode, unsigned UseIdx) const = 0;
+ SDNode *UseNode, unsigned UseIdx) const;
/// getOperandLatency - Compute and return the use operand latency of a given
/// pair of def and use.
@@ -790,7 +809,7 @@ public:
virtual int getOperandLatency(const InstrItineraryData *ItinData,
const MachineInstr *DefMI, unsigned DefIdx,
const MachineInstr *UseMI,
- unsigned UseIdx) const = 0;
+ unsigned UseIdx) const;
/// computeOperandLatency - Compute and return the latency of the given data
/// dependent def and use when the operand indices are already known.
@@ -806,10 +825,10 @@ public:
/// PredCost.
virtual unsigned getInstrLatency(const InstrItineraryData *ItinData,
const MachineInstr *MI,
- unsigned *PredCost = 0) const = 0;
+ unsigned *PredCost = 0) const;
virtual int getInstrLatency(const InstrItineraryData *ItinData,
- SDNode *Node) const = 0;
+ SDNode *Node) const;
/// Return the default expected latency for a def based on it's opcode.
unsigned defaultDefLatency(const MCSchedModel *SchedModel,
@@ -839,7 +858,7 @@ public:
/// if the target considered it 'low'.
virtual
bool hasLowDefLatency(const InstrItineraryData *ItinData,
- const MachineInstr *DefMI, unsigned DefIdx) const = 0;
+ const MachineInstr *DefMI, unsigned DefIdx) const;
/// verifyInstruction - Perform target specific instruction verification.
virtual
@@ -956,84 +975,6 @@ private:
int CallFrameSetupOpcode, CallFrameDestroyOpcode;
};
-/// TargetInstrInfoImpl - This is the default implementation of
-/// TargetInstrInfo, which just provides a couple of default implementations
-/// for various methods. This separated out because it is implemented in
-/// libcodegen, not in libtarget.
-class TargetInstrInfoImpl : public TargetInstrInfo {
-protected:
- TargetInstrInfoImpl(int CallFrameSetupOpcode = -1,
- int CallFrameDestroyOpcode = -1)
- : TargetInstrInfo(CallFrameSetupOpcode, CallFrameDestroyOpcode) {}
-public:
- virtual void ReplaceTailWithBranchTo(MachineBasicBlock::iterator OldInst,
- MachineBasicBlock *NewDest) const;
- virtual MachineInstr *commuteInstruction(MachineInstr *MI,
- bool NewMI = false) const;
- virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1,
- unsigned &SrcOpIdx2) const;
- virtual bool canFoldMemoryOperand(const MachineInstr *MI,
- const SmallVectorImpl<unsigned> &Ops) const;
- virtual bool hasLoadFromStackSlot(const MachineInstr *MI,
- const MachineMemOperand *&MMO,
- int &FrameIndex) const;
- 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,
- MachineBasicBlock::iterator MI,
- unsigned DestReg, unsigned SubReg,
- const MachineInstr *Orig,
- const TargetRegisterInfo &TRI) const;
- virtual MachineInstr *duplicate(MachineInstr *Orig,
- MachineFunction &MF) const;
- virtual bool produceSameValue(const MachineInstr *MI0,
- const MachineInstr *MI1,
- const MachineRegisterInfo *MRI) const;
- virtual bool isSchedulingBoundary(const MachineInstr *MI,
- const MachineBasicBlock *MBB,
- const MachineFunction &MF) const;
-
- virtual int getOperandLatency(const InstrItineraryData *ItinData,
- SDNode *DefNode, unsigned DefIdx,
- SDNode *UseNode, unsigned UseIdx) const;
-
- virtual int getInstrLatency(const InstrItineraryData *ItinData,
- SDNode *Node) const;
-
- virtual unsigned getNumMicroOps(const InstrItineraryData *ItinData,
- const MachineInstr *MI) const;
-
- virtual unsigned getInstrLatency(const InstrItineraryData *ItinData,
- const MachineInstr *MI,
- unsigned *PredCost = 0) const;
-
- virtual
- bool hasLowDefLatency(const InstrItineraryData *ItinData,
- const MachineInstr *DefMI, unsigned DefIdx) const;
-
- virtual int getOperandLatency(const InstrItineraryData *ItinData,
- const MachineInstr *DefMI, unsigned DefIdx,
- const MachineInstr *UseMI,
- unsigned UseIdx) const;
-
- bool usePreRAHazardRecognizer() const;
-
- virtual ScheduleHazardRecognizer *
- CreateTargetHazardRecognizer(const TargetMachine*, const ScheduleDAG*) const;
-
- virtual ScheduleHazardRecognizer *
- CreateTargetMIHazardRecognizer(const InstrItineraryData*,
- const ScheduleDAG*) const;
-
- virtual ScheduleHazardRecognizer *
- CreateTargetPostRAHazardRecognizer(const InstrItineraryData*,
- const ScheduleDAG*) const;
-};
-
} // End llvm namespace
#endif
diff --git a/include/llvm/Target/TargetJITInfo.h b/include/llvm/Target/TargetJITInfo.h
index 044afd9..f9bd0fb 100644
--- a/include/llvm/Target/TargetJITInfo.h
+++ b/include/llvm/Target/TargetJITInfo.h
@@ -17,8 +17,8 @@
#ifndef LLVM_TARGET_TARGETJITINFO_H
#define LLVM_TARGET_TARGETJITINFO_H
-#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
#include <cassert>
namespace llvm {
diff --git a/include/llvm/Target/TargetLibraryInfo.h b/include/llvm/Target/TargetLibraryInfo.h
index a2c97d7..5f01c8d 100644
--- a/include/llvm/Target/TargetLibraryInfo.h
+++ b/include/llvm/Target/TargetLibraryInfo.h
@@ -10,14 +10,18 @@
#ifndef LLVM_TARGET_TARGETLIBRARYINFO_H
#define LLVM_TARGET_TARGETLIBRARYINFO_H
-#include "llvm/Pass.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/Pass.h"
namespace llvm {
class Triple;
namespace LibFunc {
enum Func {
+ /// int _IO_getc(_IO_FILE * __fp);
+ under_IO_getc,
+ /// int _IO_putc(int __c, _IO_FILE * __fp);
+ under_IO_putc,
/// void operator delete[](void*);
ZdaPv,
/// void operator delete(void*);
@@ -47,8 +51,22 @@ namespace llvm {
cxa_guard_acquire,
/// void __cxa_guard_release(guard_t *guard);
cxa_guard_release,
+ /// int __isoc99_scanf (const char *format, ...)
+ dunder_isoc99_scanf,
+ /// int __isoc99_sscanf(const char *s, const char *format, ...)
+ dunder_isoc99_sscanf,
/// void *__memcpy_chk(void *s1, const void *s2, size_t n, size_t s1size);
memcpy_chk,
+ /// char * __strdup(const char *s);
+ dunder_strdup,
+ /// char *__strndup(const char *s, size_t n);
+ dunder_strndup,
+ /// char * __strtok_r(char *s, const char *delim, char **save_ptr);
+ dunder_strtok_r,
+ /// int abs(int j);
+ abs,
+ /// int access(const char *path, int amode);
+ access,
/// double acos(double x);
acos,
/// float acosf(float x);
@@ -91,6 +109,20 @@ namespace llvm {
atanhl,
/// long double atanl(long double x);
atanl,
+ /// double atof(const char *str);
+ atof,
+ /// int atoi(const char *str);
+ atoi,
+ /// long atol(const char *str);
+ atol,
+ /// long long atoll(const char *nptr);
+ atoll,
+ /// int bcmp(const void *s1, const void *s2, size_t n);
+ bcmp,
+ /// void bcopy(const void *s1, void *s2, size_t n);
+ bcopy,
+ /// void bzero(void *s, size_t n);
+ bzero,
/// void *calloc(size_t count, size_t size);
calloc,
/// double cbrt(double x);
@@ -105,6 +137,14 @@ namespace llvm {
ceilf,
/// long double ceill(long double x);
ceill,
+ /// int chmod(const char *path, mode_t mode);
+ chmod,
+ /// int chown(const char *path, uid_t owner, gid_t group);
+ chown,
+ /// void clearerr(FILE *stream);
+ clearerr,
+ /// int closedir(DIR *dirp);
+ closedir,
/// double copysign(double x, double y);
copysign,
/// float copysignf(float x, float y);
@@ -123,6 +163,8 @@ namespace llvm {
coshl,
/// long double cosl(long double x);
cosl,
+ /// char *ctermid(char *s);
+ ctermid,
/// double exp(double x);
exp,
/// double exp10(double x);
@@ -153,8 +195,34 @@ namespace llvm {
fabsf,
/// long double fabsl(long double x);
fabsl,
+ /// int fclose(FILE *stream);
+ fclose,
+ /// FILE *fdopen(int fildes, const char *mode);
+ fdopen,
+ /// int feof(FILE *stream);
+ feof,
+ /// int ferror(FILE *stream);
+ ferror,
+ /// int fflush(FILE *stream);
+ fflush,
+ /// int ffs(int i);
+ ffs,
+ /// int ffsl(long int i);
+ ffsl,
+ /// int ffsll(long long int i);
+ ffsll,
+ /// int fgetc(FILE *stream);
+ fgetc,
+ /// int fgetpos(FILE *stream, fpos_t *pos);
+ fgetpos,
+ /// char *fgets(char *s, int n, FILE *stream);
+ fgets,
+ /// int fileno(FILE *stream);
+ fileno,
/// int fiprintf(FILE *stream, const char *format, ...);
fiprintf,
+ /// void flockfile(FILE *file);
+ flockfile,
/// double floor(double x);
floor,
/// float floorf(float x);
@@ -167,17 +235,89 @@ namespace llvm {
fmodf,
/// long double fmodl(long double x, long double y);
fmodl,
+ /// FILE *fopen(const char *filename, const char *mode);
+ fopen,
+ /// FILE *fopen64(const char *filename, const char *opentype)
+ fopen64,
+ /// int fprintf(FILE *stream, const char *format, ...);
+ fprintf,
/// int fputc(int c, FILE *stream);
fputc,
/// int fputs(const char *s, FILE *stream);
fputs,
+ /// size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream);
+ fread,
/// void free(void *ptr);
free,
+ /// double frexp(double num, int *exp);
+ frexp,
+ /// float frexpf(float num, int *exp);
+ frexpf,
+ /// long double frexpl(long double num, int *exp);
+ frexpl,
+ /// int fscanf(FILE *stream, const char *format, ... );
+ fscanf,
+ /// int fseek(FILE *stream, long offset, int whence);
+ fseek,
+ /// int fseeko(FILE *stream, off_t offset, int whence);
+ fseeko,
+ /// int fseeko64(FILE *stream, off64_t offset, int whence)
+ fseeko64,
+ /// int fsetpos(FILE *stream, const fpos_t *pos);
+ fsetpos,
+ /// int fstat(int fildes, struct stat *buf);
+ fstat,
+ /// int fstat64(int filedes, struct stat64 *buf)
+ fstat64,
+ /// int fstatvfs(int fildes, struct statvfs *buf);
+ fstatvfs,
+ /// int fstatvfs64(int fildes, struct statvfs64 *buf);
+ fstatvfs64,
+ /// long ftell(FILE *stream);
+ ftell,
+ /// off_t ftello(FILE *stream);
+ ftello,
+ /// off64_t ftello64(FILE *stream)
+ ftello64,
+ /// int ftrylockfile(FILE *file);
+ ftrylockfile,
+ /// void funlockfile(FILE *file);
+ funlockfile,
/// size_t fwrite(const void *ptr, size_t size, size_t nitems,
/// FILE *stream);
fwrite,
+ /// int getc(FILE *stream);
+ getc,
+ /// int getc_unlocked(FILE *stream);
+ getc_unlocked,
+ /// int getchar(void);
+ getchar,
+ /// char *getenv(const char *name);
+ getenv,
+ /// int getitimer(int which, struct itimerval *value);
+ getitimer,
+ /// int getlogin_r(char *name, size_t namesize);
+ getlogin_r,
+ /// struct passwd *getpwnam(const char *name);
+ getpwnam,
+ /// char *gets(char *s);
+ gets,
+ /// uint32_t htonl(uint32_t hostlong);
+ htonl,
+ /// uint16_t htons(uint16_t hostshort);
+ htons,
/// int iprintf(const char *format, ...);
iprintf,
+ /// int isascii(int c);
+ isascii,
+ /// int isdigit(int c);
+ isdigit,
+ /// long int labs(long int j);
+ labs,
+ /// int lchown(const char *path, uid_t owner, gid_t group);
+ lchown,
+ /// long long int llabs(long long int j);
+ llabs,
/// double log(double x);
log,
/// double log10(double x);
@@ -208,8 +348,16 @@ namespace llvm {
logf,
/// long double logl(long double x);
logl,
+ /// int lstat(const char *path, struct stat *buf);
+ lstat,
+ /// int lstat64(const char *path, struct stat64 *buf);
+ lstat64,
/// void *malloc(size_t size);
malloc,
+ /// void *memalign(size_t boundary, size_t size);
+ memalign,
+ /// void *memccpy(void *s1, const void *s2, int c, size_t n);
+ memccpy,
/// void *memchr(const void *s, int c, size_t n);
memchr,
/// int memcmp(const void *s1, const void *s2, size_t n);
@@ -218,16 +366,44 @@ namespace llvm {
memcpy,
/// void *memmove(void *s1, const void *s2, size_t n);
memmove,
+ // void *memrchr(const void *s, int c, size_t n);
+ memrchr,
/// void *memset(void *b, int c, size_t len);
memset,
/// void memset_pattern16(void *b, const void *pattern16, size_t len);
memset_pattern16,
+ /// int mkdir(const char *path, mode_t mode);
+ mkdir,
+ /// time_t mktime(struct tm *timeptr);
+ mktime,
+ /// double modf(double x, double *iptr);
+ modf,
+ /// float modff(float, float *iptr);
+ modff,
+ /// long double modfl(long double value, long double *iptr);
+ modfl,
/// double nearbyint(double x);
nearbyint,
/// float nearbyintf(float x);
nearbyintf,
/// long double nearbyintl(long double x);
nearbyintl,
+ /// uint32_t ntohl(uint32_t netlong);
+ ntohl,
+ /// uint16_t ntohs(uint16_t netshort);
+ ntohs,
+ /// int open(const char *path, int oflag, ... );
+ open,
+ /// int open64(const char *filename, int flags[, mode_t mode])
+ open64,
+ /// DIR *opendir(const char *dirname);
+ opendir,
+ /// int pclose(FILE *stream);
+ pclose,
+ /// void perror(const char *s);
+ perror,
+ /// FILE *popen(const char *command, const char *mode);
+ popen,
/// int posix_memalign(void **memptr, size_t alignment, size_t size);
posix_memalign,
/// double pow(double x, double y);
@@ -236,26 +412,61 @@ namespace llvm {
powf,
/// long double powl(long double x, long double y);
powl,
+ /// ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset);
+ pread,
+ /// int printf(const char *format, ...);
+ printf,
+ /// int putc(int c, FILE *stream);
+ putc,
/// int putchar(int c);
putchar,
/// int puts(const char *s);
puts,
+ /// ssize_t pwrite(int fildes, const void *buf, size_t nbyte,
+ /// off_t offset);
+ pwrite,
+ /// void qsort(void *base, size_t nel, size_t width,
+ /// int (*compar)(const void *, const void *));
+ qsort,
+ /// ssize_t read(int fildes, void *buf, size_t nbyte);
+ read,
+ /// ssize_t readlink(const char *path, char *buf, size_t bufsize);
+ readlink,
/// void *realloc(void *ptr, size_t size);
realloc,
/// void *reallocf(void *ptr, size_t size);
reallocf,
+ /// char *realpath(const char *file_name, char *resolved_name);
+ realpath,
+ /// int remove(const char *path);
+ remove,
+ /// int rename(const char *old, const char *new);
+ rename,
+ /// void rewind(FILE *stream);
+ rewind,
/// double rint(double x);
rint,
/// float rintf(float x);
rintf,
/// long double rintl(long double x);
rintl,
+ /// int rmdir(const char *path);
+ rmdir,
/// double round(double x);
round,
/// float roundf(float x);
roundf,
/// long double roundl(long double x);
roundl,
+ /// int scanf(const char *restrict format, ... );
+ scanf,
+ /// void setbuf(FILE *stream, char *buf);
+ setbuf,
+ /// int setitimer(int which, const struct itimerval *value,
+ /// struct itimerval *ovalue);
+ setitimer,
+ /// int setvbuf(FILE *stream, char *buf, int type, size_t size);
+ setvbuf,
/// double sin(double x);
sin,
/// float sinf(float x);
@@ -270,20 +481,40 @@ namespace llvm {
sinl,
/// int siprintf(char *str, const char *format, ...);
siprintf,
+ /// int snprintf(char *s, size_t n, const char *format, ...);
+ snprintf,
+ /// int sprintf(char *str, const char *format, ...);
+ sprintf,
/// double sqrt(double x);
sqrt,
/// float sqrtf(float x);
sqrtf,
/// long double sqrtl(long double x);
sqrtl,
+ /// int sscanf(const char *s, const char *format, ... );
+ sscanf,
+ /// int stat(const char *path, struct stat *buf);
+ stat,
+ /// int stat64(const char *path, struct stat64 *buf);
+ stat64,
+ /// int statvfs(const char *path, struct statvfs *buf);
+ statvfs,
+ /// int statvfs64(const char *path, struct statvfs64 *buf)
+ statvfs64,
/// char *stpcpy(char *s1, const char *s2);
stpcpy,
+ /// char *stpncpy(char *s1, const char *s2, size_t n);
+ stpncpy,
+ /// int strcasecmp(const char *s1, const char *s2);
+ strcasecmp,
/// char *strcat(char *s1, const char *s2);
strcat,
/// char *strchr(const char *s, int c);
strchr,
/// int strcmp(const char *s1, const char *s2);
strcmp,
+ /// int strcoll(const char *s1, const char *s2);
+ strcoll,
/// char *strcpy(char *s1, const char *s2);
strcpy,
/// size_t strcspn(const char *s1, const char *s2);
@@ -292,6 +523,8 @@ namespace llvm {
strdup,
/// size_t strlen(const char *s);
strlen,
+ /// int strncasecmp(const char *s1, const char *s2, size_t n);
+ strncasecmp,
/// char *strncat(char *s1, const char *s2, size_t n);
strncat,
/// int strncmp(const char *s1, const char *s2, size_t n);
@@ -314,6 +547,10 @@ namespace llvm {
strtod,
/// float strtof(const char *nptr, char **endptr);
strtof,
+ // char *strtok(char *s1, const char *s2);
+ strtok,
+ // char *strtok_r(char *s, const char *sep, char **lasts);
+ strtok_r,
/// long int strtol(const char *nptr, char **endptr, int base);
strtol,
/// long double strtold(const char *nptr, char **endptr);
@@ -325,6 +562,10 @@ namespace llvm {
/// unsigned long long int strtoull(const char *nptr, char **endptr,
/// int base);
strtoull,
+ /// size_t strxfrm(char *s1, const char *s2, size_t n);
+ strxfrm,
+ /// int system(const char *command);
+ system,
/// double tan(double x);
tan,
/// float tanf(float x);
@@ -337,14 +578,50 @@ namespace llvm {
tanhl,
/// long double tanl(long double x);
tanl,
+ /// clock_t times(struct tms *buffer);
+ times,
+ /// FILE *tmpfile(void);
+ tmpfile,
+ /// FILE *tmpfile64(void)
+ tmpfile64,
+ /// int toascii(int c);
+ toascii,
/// double trunc(double x);
trunc,
/// float truncf(float x);
truncf,
/// long double truncl(long double x);
truncl,
+ /// int uname(struct utsname *name);
+ uname,
+ /// int ungetc(int c, FILE *stream);
+ ungetc,
+ /// int unlink(const char *path);
+ unlink,
+ /// int unsetenv(const char *name);
+ unsetenv,
+ /// int utime(const char *path, const struct utimbuf *times);
+ utime,
+ /// int utimes(const char *path, const struct timeval times[2]);
+ utimes,
/// void *valloc(size_t size);
valloc,
+ /// int vfprintf(FILE *stream, const char *format, va_list ap);
+ vfprintf,
+ /// int vfscanf(FILE *stream, const char *format, va_list arg);
+ vfscanf,
+ /// int vprintf(const char *restrict format, va_list ap);
+ vprintf,
+ /// int vscanf(const char *format, va_list arg);
+ vscanf,
+ /// int vsnprintf(char *s, size_t n, const char *format, va_list ap);
+ vsnprintf,
+ /// int vsprintf(char *s, const char *format, va_list ap);
+ vsprintf,
+ /// int vsscanf(const char *s, const char *format, va_list arg);
+ vsscanf,
+ /// ssize_t write(int fildes, const void *buf, size_t nbyte);
+ write,
NumLibFuncs
};
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index 580a30f..1786bd2 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -22,14 +22,14 @@
#ifndef LLVM_TARGET_TARGETLOWERING_H
#define LLVM_TARGET_TARGETLOWERING_H
-#include "llvm/AddressingMode.h"
-#include "llvm/CallingConv.h"
-#include "llvm/InlineAsm.h"
-#include "llvm/Attributes.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/Support/CallSite.h"
-#include "llvm/CodeGen/SelectionDAGNodes.h"
+#include "llvm/CodeGen/DAGCombine.h"
#include "llvm/CodeGen/RuntimeLibcalls.h"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/CallingConv.h"
+#include "llvm/IR/InlineAsm.h"
+#include "llvm/Support/CallSite.h"
#include "llvm/Support/DebugLoc.h"
#include "llvm/Target/TargetCallingConv.h"
#include "llvm/Target/TargetMachine.h"
@@ -68,18 +68,12 @@ namespace llvm {
};
}
+/// TargetLoweringBase - This base class for TargetLowering contains the
+/// SelectionDAG-independent parts that can be used from the rest of CodeGen.
+class TargetLoweringBase {
+ TargetLoweringBase(const TargetLoweringBase&) LLVM_DELETED_FUNCTION;
+ void operator=(const TargetLoweringBase&) LLVM_DELETED_FUNCTION;
-//===----------------------------------------------------------------------===//
-/// TargetLowering - This class defines information used to lower LLVM code to
-/// legal SelectionDAG operators that the target instruction selector can accept
-/// natively.
-///
-/// This class also defines callbacks that targets must implement to lower
-/// target-specific constructs to SelectionDAG operators.
-///
-class TargetLowering {
- TargetLowering(const TargetLowering&) LLVM_DELETED_FUNCTION;
- void operator=(const TargetLowering&) LLVM_DELETED_FUNCTION;
public:
/// LegalizeAction - This enum indicates whether operations are valid for a
/// target, and if not, what action should be used to make them valid.
@@ -137,9 +131,9 @@ public:
}
/// NOTE: The constructor takes ownership of TLOF.
- explicit TargetLowering(const TargetMachine &TM,
- const TargetLoweringObjectFile *TLOF);
- virtual ~TargetLowering();
+ explicit TargetLoweringBase(const TargetMachine &TM,
+ const TargetLoweringObjectFile *TLOF);
+ virtual ~TargetLoweringBase();
const TargetMachine &getTargetMachine() const { return TM; }
const DataLayout *getDataLayout() const { return TD; }
@@ -151,7 +145,9 @@ public:
// the pointer type from the data layout.
// FIXME: The default needs to be removed once all the code is updated.
virtual MVT getPointerTy(uint32_t AS = 0) const { return PointerTy; }
- virtual MVT getShiftAmountTy(EVT LHSTy) const;
+ virtual MVT getScalarShiftAmountTy(EVT LHSTy) const;
+
+ EVT getShiftAmountTy(EVT LHSTy) const;
/// isSelectExpensive - Return true if the select operation is expensive for
/// this target.
@@ -159,6 +155,11 @@ public:
virtual bool isSelectSupported(SelectSupportKind kind) const { return true; }
+ /// shouldSplitVectorElementType - Return true if a vector of the given type
+ /// should be split (TypeSplitVector) instead of promoted
+ /// (TypePromoteInteger) during type legalization.
+ virtual bool shouldSplitVectorElementType(EVT VT) const { return false; }
+
/// isIntDivCheap() - Return true if integer divide is usually cheaper than
/// a sequence of several shifts, adds, and multiplies for this target.
bool isIntDivCheap() const { return IntDivIsCheap; }
@@ -184,7 +185,7 @@ public:
/// isPredictableSelectExpensive - Return true if selects are only cheaper
/// than branches if the branch is unlikely to be predicted right.
bool isPredictableSelectExpensive() const {
- return predictableSelectIsExpensive;
+ return PredictableSelectIsExpensive;
}
/// getSetCCResultType - Return the ValueType of the result of SETCC
@@ -227,9 +228,8 @@ public:
/// getRegClassFor - Return the register class that should be used for the
/// specified value type.
- virtual const TargetRegisterClass *getRegClassFor(EVT VT) const {
- assert(VT.isSimple() && "getRegClassFor called on illegal type!");
- const TargetRegisterClass *RC = RegClassForVT[VT.getSimpleVT().SimpleTy];
+ virtual const TargetRegisterClass *getRegClassFor(MVT VT) const {
+ const TargetRegisterClass *RC = RegClassForVT[VT.SimpleTy];
assert(RC && "This value type is not natively supported!");
return RC;
}
@@ -239,17 +239,15 @@ public:
/// legal super-reg register class for the register class of the value type.
/// For example, on i386 the rep register class for i8, i16, and i32 are GR32;
/// while the rep register class is GR64 on x86_64.
- virtual const TargetRegisterClass *getRepRegClassFor(EVT VT) const {
- assert(VT.isSimple() && "getRepRegClassFor called on illegal type!");
- const TargetRegisterClass *RC = RepRegClassForVT[VT.getSimpleVT().SimpleTy];
+ virtual const TargetRegisterClass *getRepRegClassFor(MVT VT) const {
+ const TargetRegisterClass *RC = RepRegClassForVT[VT.SimpleTy];
return RC;
}
/// getRepRegClassCostFor - Return the cost of the 'representative' register
/// class for the specified value type.
- virtual uint8_t getRepRegClassCostFor(EVT VT) const {
- assert(VT.isSimple() && "getRepRegClassCostFor called on illegal type!");
- return RepRegClassCostForVT[VT.getSimpleVT().SimpleTy];
+ virtual uint8_t getRepRegClassCostFor(MVT VT) const {
+ return RepRegClassCostForVT[VT.SimpleTy];
}
/// isTypeLegal - Return true if the target has native support for the
@@ -275,8 +273,8 @@ public:
return (LegalizeTypeAction)ValueTypeActions[VT.SimpleTy];
}
- void setTypeAction(EVT VT, LegalizeTypeAction Action) {
- unsigned I = VT.getSimpleVT().SimpleTy;
+ void setTypeAction(MVT VT, LegalizeTypeAction Action) {
+ unsigned I = VT.SimpleTy;
ValueTypeActions[I] = Action;
}
};
@@ -337,7 +335,7 @@ public:
unsigned getVectorTypeBreakdown(LLVMContext &Context, EVT VT,
EVT &IntermediateVT,
unsigned &NumIntermediates,
- EVT &RegisterVT) const;
+ MVT &RegisterVT) const;
/// getTgtMemIntrinsic: Given an intrinsic, checks if on the target the
/// intrinsic will need to map to a MemIntrinsicNode (touches memory). If
@@ -411,6 +409,15 @@ public:
getOperationAction(Op, VT) == Custom);
}
+ /// isOperationLegalOrPromote - Return true if the specified operation is
+ /// legal on this target or can be made legal using promotion. This
+ /// is used to help guide high-level lowering decisions.
+ bool isOperationLegalOrPromote(unsigned Op, EVT VT) const {
+ return (VT == MVT::Other || isTypeLegal(VT)) &&
+ (getOperationAction(Op, VT) == Legal ||
+ getOperationAction(Op, VT) == Promote);
+ }
+
/// isOperationExpand - Return true if the specified operation is illegal on
/// this target or unlikely to be made legal with custom lowering. This is
/// used to help guide high-level lowering decisions.
@@ -429,36 +436,35 @@ public:
/// either it is legal, needs to be promoted to a larger size, needs to be
/// expanded to some other code sequence, or the target has a custom expander
/// for it.
- LegalizeAction getLoadExtAction(unsigned ExtType, EVT VT) const {
- assert(ExtType < ISD::LAST_LOADEXT_TYPE &&
- VT.getSimpleVT() < MVT::LAST_VALUETYPE &&
+ LegalizeAction getLoadExtAction(unsigned ExtType, MVT VT) const {
+ assert(ExtType < ISD::LAST_LOADEXT_TYPE && VT < MVT::LAST_VALUETYPE &&
"Table isn't big enough!");
- return (LegalizeAction)LoadExtActions[VT.getSimpleVT().SimpleTy][ExtType];
+ return (LegalizeAction)LoadExtActions[VT.SimpleTy][ExtType];
}
/// isLoadExtLegal - Return true if the specified load with extension is legal
/// on this target.
bool isLoadExtLegal(unsigned ExtType, EVT VT) const {
- return VT.isSimple() && getLoadExtAction(ExtType, VT) == Legal;
+ return VT.isSimple() &&
+ getLoadExtAction(ExtType, VT.getSimpleVT()) == Legal;
}
/// getTruncStoreAction - Return how this store with truncation should be
/// treated: either it is legal, needs to be promoted to a larger size, needs
/// to be expanded to some other code sequence, or the target has a custom
/// expander for it.
- LegalizeAction getTruncStoreAction(EVT ValVT, EVT MemVT) const {
- assert(ValVT.getSimpleVT() < MVT::LAST_VALUETYPE &&
- MemVT.getSimpleVT() < MVT::LAST_VALUETYPE &&
+ LegalizeAction getTruncStoreAction(MVT ValVT, MVT MemVT) const {
+ assert(ValVT < MVT::LAST_VALUETYPE && MemVT < MVT::LAST_VALUETYPE &&
"Table isn't big enough!");
- return (LegalizeAction)TruncStoreActions[ValVT.getSimpleVT().SimpleTy]
- [MemVT.getSimpleVT().SimpleTy];
+ return (LegalizeAction)TruncStoreActions[ValVT.SimpleTy]
+ [MemVT.SimpleTy];
}
/// isTruncStoreLegal - Return true if the specified store with truncation is
/// legal on this target.
bool isTruncStoreLegal(EVT ValVT, EVT MemVT) const {
return isTypeLegal(ValVT) && MemVT.isSimple() &&
- getTruncStoreAction(ValVT, MemVT) == Legal;
+ getTruncStoreAction(ValVT.getSimpleVT(), MemVT.getSimpleVT()) == Legal;
}
/// getIndexedLoadAction - Return how the indexed load should be treated:
@@ -466,11 +472,10 @@ public:
/// expanded to some other code sequence, or the target has a custom expander
/// for it.
LegalizeAction
- getIndexedLoadAction(unsigned IdxMode, EVT VT) const {
- assert(IdxMode < ISD::LAST_INDEXED_MODE &&
- VT.getSimpleVT() < MVT::LAST_VALUETYPE &&
+ getIndexedLoadAction(unsigned IdxMode, MVT VT) const {
+ assert(IdxMode < ISD::LAST_INDEXED_MODE && VT < MVT::LAST_VALUETYPE &&
"Table isn't big enough!");
- unsigned Ty = (unsigned)VT.getSimpleVT().SimpleTy;
+ unsigned Ty = (unsigned)VT.SimpleTy;
return (LegalizeAction)((IndexedModeActions[Ty][IdxMode] & 0xf0) >> 4);
}
@@ -478,8 +483,8 @@ public:
/// on this target.
bool isIndexedLoadLegal(unsigned IdxMode, EVT VT) const {
return VT.isSimple() &&
- (getIndexedLoadAction(IdxMode, VT) == Legal ||
- getIndexedLoadAction(IdxMode, VT) == Custom);
+ (getIndexedLoadAction(IdxMode, VT.getSimpleVT()) == Legal ||
+ getIndexedLoadAction(IdxMode, VT.getSimpleVT()) == Custom);
}
/// getIndexedStoreAction - Return how the indexed store should be treated:
@@ -487,11 +492,10 @@ public:
/// expanded to some other code sequence, or the target has a custom expander
/// for it.
LegalizeAction
- getIndexedStoreAction(unsigned IdxMode, EVT VT) const {
- assert(IdxMode < ISD::LAST_INDEXED_MODE &&
- VT.getSimpleVT() < MVT::LAST_VALUETYPE &&
+ getIndexedStoreAction(unsigned IdxMode, MVT VT) const {
+ assert(IdxMode < ISD::LAST_INDEXED_MODE && VT < MVT::LAST_VALUETYPE &&
"Table isn't big enough!");
- unsigned Ty = (unsigned)VT.getSimpleVT().SimpleTy;
+ unsigned Ty = (unsigned)VT.SimpleTy;
return (LegalizeAction)(IndexedModeActions[Ty][IdxMode] & 0x0f);
}
@@ -499,54 +503,54 @@ public:
/// on this target.
bool isIndexedStoreLegal(unsigned IdxMode, EVT VT) const {
return VT.isSimple() &&
- (getIndexedStoreAction(IdxMode, VT) == Legal ||
- getIndexedStoreAction(IdxMode, VT) == Custom);
+ (getIndexedStoreAction(IdxMode, VT.getSimpleVT()) == Legal ||
+ getIndexedStoreAction(IdxMode, VT.getSimpleVT()) == Custom);
}
/// getCondCodeAction - Return how the condition code should be treated:
/// either it is legal, needs to be expanded to some other code sequence,
/// or the target has a custom expander for it.
LegalizeAction
- getCondCodeAction(ISD::CondCode CC, EVT VT) const {
+ getCondCodeAction(ISD::CondCode CC, MVT VT) const {
assert((unsigned)CC < array_lengthof(CondCodeActions) &&
- (unsigned)VT.getSimpleVT().SimpleTy < sizeof(CondCodeActions[0])*4 &&
+ (unsigned)VT.SimpleTy < sizeof(CondCodeActions[0])*4 &&
"Table isn't big enough!");
/// The lower 5 bits of the SimpleTy index into Nth 2bit set from the 64bit
/// value and the upper 27 bits index into the second dimension of the
/// array to select what 64bit value to use.
LegalizeAction Action = (LegalizeAction)
- ((CondCodeActions[CC][VT.getSimpleVT().SimpleTy >> 5]
- >> (2*(VT.getSimpleVT().SimpleTy & 0x1F))) & 3);
+ ((CondCodeActions[CC][VT.SimpleTy >> 5] >> (2*(VT.SimpleTy & 0x1F))) & 3);
assert(Action != Promote && "Can't promote condition code!");
return Action;
}
/// isCondCodeLegal - Return true if the specified condition code is legal
/// on this target.
- bool isCondCodeLegal(ISD::CondCode CC, EVT VT) const {
- return getCondCodeAction(CC, VT) == Legal ||
- getCondCodeAction(CC, VT) == Custom;
+ bool isCondCodeLegal(ISD::CondCode CC, MVT VT) const {
+ return
+ getCondCodeAction(CC, VT) == Legal ||
+ getCondCodeAction(CC, VT) == Custom;
}
/// getTypeToPromoteTo - If the action for this operation is to promote, this
/// method returns the ValueType to promote to.
- EVT getTypeToPromoteTo(unsigned Op, EVT VT) const {
+ MVT getTypeToPromoteTo(unsigned Op, MVT VT) const {
assert(getOperationAction(Op, VT) == Promote &&
"This operation isn't promoted!");
// See if this has an explicit type specified.
std::map<std::pair<unsigned, MVT::SimpleValueType>,
MVT::SimpleValueType>::const_iterator PTTI =
- PromoteToType.find(std::make_pair(Op, VT.getSimpleVT().SimpleTy));
+ PromoteToType.find(std::make_pair(Op, VT.SimpleTy));
if (PTTI != PromoteToType.end()) return PTTI->second;
assert((VT.isInteger() || VT.isFloatingPoint()) &&
"Cannot autopromote this type, add it with AddPromotedToType.");
- EVT NVT = VT;
+ MVT NVT = VT;
do {
- NVT = (MVT::SimpleValueType)(NVT.getSimpleVT().SimpleTy+1);
+ NVT = (MVT::SimpleValueType)(NVT.SimpleTy+1);
assert(NVT.isInteger() == VT.isInteger() && NVT != MVT::isVoid &&
"Didn't find type to promote to!");
} while (!isTypeLegal(NVT) ||
@@ -573,7 +577,11 @@ public:
}
return EVT::getEVT(Ty, AllowUnknown);
}
-
+
+ /// Return the MVT corresponding to this LLVM type. See getValueType.
+ MVT getSimpleValueType(Type *Ty, bool AllowUnknown = false) const {
+ return getValueType(Ty, AllowUnknown).getSimpleVT();
+ }
/// getByValTypeAlignment - Return the desired alignment for ByVal aggregate
/// function arguments in the caller parameter area. This is the actual
@@ -582,21 +590,22 @@ public:
/// getRegisterType - Return the type of registers that this ValueType will
/// eventually require.
- EVT getRegisterType(MVT VT) const {
+ MVT getRegisterType(MVT VT) const {
assert((unsigned)VT.SimpleTy < array_lengthof(RegisterTypeForVT));
return RegisterTypeForVT[VT.SimpleTy];
}
/// getRegisterType - Return the type of registers that this ValueType will
/// eventually require.
- EVT getRegisterType(LLVMContext &Context, EVT VT) const {
+ MVT getRegisterType(LLVMContext &Context, EVT VT) const {
if (VT.isSimple()) {
assert((unsigned)VT.getSimpleVT().SimpleTy <
array_lengthof(RegisterTypeForVT));
return RegisterTypeForVT[VT.getSimpleVT().SimpleTy];
}
if (VT.isVector()) {
- EVT VT1, RegisterVT;
+ EVT VT1;
+ MVT RegisterVT;
unsigned NumIntermediates;
(void)getVectorTypeBreakdown(Context, VT, VT1,
NumIntermediates, RegisterVT);
@@ -621,7 +630,8 @@ public:
return NumRegistersForVT[VT.getSimpleVT().SimpleTy];
}
if (VT.isVector()) {
- EVT VT1, VT2;
+ EVT VT1;
+ MVT VT2;
unsigned NumIntermediates;
return getVectorTypeBreakdown(Context, VT, VT1, NumIntermediates, VT2);
}
@@ -651,7 +661,7 @@ public:
/// return the limit for functions that have OptSize attribute.
/// @brief Get maximum # of store operations permitted for llvm.memset
unsigned getMaxStoresPerMemset(bool OptSize) const {
- return OptSize ? maxStoresPerMemsetOptSize : maxStoresPerMemset;
+ return OptSize ? MaxStoresPerMemsetOptSize : MaxStoresPerMemset;
}
/// This function returns the maximum number of store operations permitted
@@ -660,7 +670,7 @@ public:
/// return the limit for functions that have OptSize attribute.
/// @brief Get maximum # of store operations permitted for llvm.memcpy
unsigned getMaxStoresPerMemcpy(bool OptSize) const {
- return OptSize ? maxStoresPerMemcpyOptSize : maxStoresPerMemcpy;
+ return OptSize ? MaxStoresPerMemcpyOptSize : MaxStoresPerMemcpy;
}
/// This function returns the maximum number of store operations permitted
@@ -669,46 +679,51 @@ public:
/// return the limit for functions that have OptSize attribute.
/// @brief Get maximum # of store operations permitted for llvm.memmove
unsigned getMaxStoresPerMemmove(bool OptSize) const {
- return OptSize ? maxStoresPerMemmoveOptSize : maxStoresPerMemmove;
+ 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
- /// array copy/move/set is converted to a sequence of store operations. It's
- /// use helps to ensure that such replacements don't generate code that causes
- /// an alignment error (trap) on the target machine.
+ /// of the specified type. If true, it also returns whether the unaligned
+ /// memory access is "fast" in the second argument by reference. This is used,
+ /// for example, in situations where an array copy/move/set is converted to a
+ /// sequence of store operations. It's use helps to ensure that such
+ /// replacements don't generate code that causes an alignment error (trap) on
+ /// the target machine.
/// @brief Determine if the target supports unaligned memory accesses.
- virtual bool allowsUnalignedMemoryAccesses(EVT) const {
+ virtual bool allowsUnalignedMemoryAccesses(EVT, bool *Fast = 0) const {
return false;
}
- /// This function returns true if the target would benefit from code placement
- /// optimization.
- /// @brief Determine if the target should perform code placement optimization.
- bool shouldOptimizeCodePlacement() const {
- return benefitFromCodePlacementOpt;
- }
-
/// getOptimalMemOpType - Returns the target specific optimal type for load
/// and store operations as a result of memset, memcpy, and memmove
/// lowering. If DstAlign is zero that means it's safe to destination
/// 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
- /// '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.
+ /// probably because the source does not need to be loaded. If 'IsMemset' is
+ /// true, that means it's expanding a memset. If 'ZeroMemset' is true, that
+ /// means it's a memset of zero. 'MemcpyStrSrc' indicates whether the memcpy
+ /// source is constant so it does not need to be loaded.
/// It returns EVT::Other if the type should be determined using generic
/// target-independent logic.
virtual EVT getOptimalMemOpType(uint64_t /*Size*/,
unsigned /*DstAlign*/, unsigned /*SrcAlign*/,
- bool /*IsZeroVal*/,
+ bool /*IsMemset*/,
+ bool /*ZeroMemset*/,
bool /*MemcpyStrSrc*/,
MachineFunction &/*MF*/) const {
return MVT::Other;
}
+ /// isSafeMemOpType - Returns true if it's safe to use load / store of the
+ /// specified type to expand memcpy / memset inline. This is mostly true
+ /// for all types except for some special cases. For example, on X86
+ /// targets without SSE2 f64 load / store are done with fldl / fstpl which
+ /// also does type conversion. Note the specified type doesn't have to be
+ /// legal as the hook is used before type legalization.
+ virtual bool isSafeMemOpType(MVT VT) const {
+ return true;
+ }
+
/// usesUnderscoreSetJmp - Determine if we should use _setjmp or setjmp
/// to implement llvm.setjmp.
bool usesUnderscoreSetJmp() const {
@@ -804,55 +819,6 @@ public:
return InsertFencesForAtomic;
}
- /// getPreIndexedAddressParts - returns true by value, base pointer and
- /// offset pointer and addressing mode by reference if the node's address
- /// can be legally represented as pre-indexed load / store address.
- virtual bool getPreIndexedAddressParts(SDNode * /*N*/, SDValue &/*Base*/,
- SDValue &/*Offset*/,
- ISD::MemIndexedMode &/*AM*/,
- SelectionDAG &/*DAG*/) const {
- return false;
- }
-
- /// getPostIndexedAddressParts - returns true by value, base pointer and
- /// offset pointer and addressing mode by reference if this node can be
- /// combined with a load / store to form a post-indexed load / store.
- virtual bool getPostIndexedAddressParts(SDNode * /*N*/, SDNode * /*Op*/,
- SDValue &/*Base*/, SDValue &/*Offset*/,
- ISD::MemIndexedMode &/*AM*/,
- SelectionDAG &/*DAG*/) const {
- return false;
- }
-
- /// getJumpTableEncoding - Return the entry encoding for a jump table in the
- /// current function. The returned value is a member of the
- /// MachineJumpTableInfo::JTEntryKind enum.
- virtual unsigned getJumpTableEncoding() const;
-
- virtual const MCExpr *
- LowerCustomJumpTableEntry(const MachineJumpTableInfo * /*MJTI*/,
- const MachineBasicBlock * /*MBB*/, unsigned /*uid*/,
- MCContext &/*Ctx*/) const {
- llvm_unreachable("Need to implement this hook if target has custom JTIs");
- }
-
- /// getPICJumpTableRelocaBase - Returns relocation base for the given PIC
- /// jumptable.
- virtual SDValue getPICJumpTableRelocBase(SDValue Table,
- SelectionDAG &DAG) const;
-
- /// getPICJumpTableRelocBaseExpr - This returns the relocation base for the
- /// given PIC jumptable, the same as getPICJumpTableRelocBase, but as an
- /// MCExpr.
- virtual const MCExpr *
- getPICJumpTableRelocBaseExpr(const MachineFunction *MF,
- unsigned JTI, MCContext &Ctx) const;
-
- /// isOffsetFoldingLegal - Return true if folding a constant offset
- /// with the given GlobalAddress is legal. It is frequently not legal in
- /// PIC relocation models.
- virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
-
/// getStackCookieLocation - Return true if the target stores stack
/// protector cookies at a fixed offset in some non-standard address
/// space, and populates the address space and offset as
@@ -869,148 +835,16 @@ public:
}
//===--------------------------------------------------------------------===//
- // TargetLowering Optimization Methods
- //
-
- /// TargetLoweringOpt - A convenience struct that encapsulates a DAG, and two
- /// SDValues for returning information from TargetLowering to its clients
- /// that want to combine
- struct TargetLoweringOpt {
- SelectionDAG &DAG;
- bool LegalTys;
- bool LegalOps;
- SDValue Old;
- SDValue New;
-
- explicit TargetLoweringOpt(SelectionDAG &InDAG,
- bool LT, bool LO) :
- DAG(InDAG), LegalTys(LT), LegalOps(LO) {}
-
- bool LegalTypes() const { return LegalTys; }
- bool LegalOperations() const { return LegalOps; }
-
- bool CombineTo(SDValue O, SDValue N) {
- Old = O;
- New = N;
- return true;
- }
-
- /// ShrinkDemandedConstant - Check to see if the specified operand of the
- /// specified instruction is a constant integer. If so, check to see if
- /// there are any bits set in the constant that are not demanded. If so,
- /// shrink the constant and return true.
- bool ShrinkDemandedConstant(SDValue Op, const APInt &Demanded);
-
- /// ShrinkDemandedOp - Convert x+y to (VT)((SmallVT)x+(SmallVT)y) if the
- /// casts are free. This uses isZExtFree and ZERO_EXTEND for the widening
- /// cast, but it could be generalized for targets with other types of
- /// implicit widening casts.
- bool ShrinkDemandedOp(SDValue Op, unsigned BitWidth, const APInt &Demanded,
- DebugLoc dl);
- };
-
- /// SimplifyDemandedBits - Look at Op. At this point, we know that only the
- /// DemandedMask bits of the result of Op are ever used downstream. If we can
- /// use this information to simplify Op, create a new simplified DAG node and
- /// return true, returning the original and new nodes in Old and New.
- /// Otherwise, analyze the expression and return a mask of KnownOne and
- /// KnownZero bits for the expression (used to simplify the caller).
- /// The KnownZero/One bits may only be accurate for those bits in the
- /// DemandedMask.
- bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedMask,
- APInt &KnownZero, APInt &KnownOne,
- TargetLoweringOpt &TLO, unsigned Depth = 0) const;
-
- /// computeMaskedBitsForTargetNode - Determine which of the bits specified in
- /// Mask are known to be either zero or one and return them in the
- /// KnownZero/KnownOne bitsets.
- virtual void computeMaskedBitsForTargetNode(const SDValue Op,
- APInt &KnownZero,
- APInt &KnownOne,
- const SelectionDAG &DAG,
- unsigned Depth = 0) const;
-
- /// ComputeNumSignBitsForTargetNode - This method can be implemented by
- /// targets that want to expose additional information about sign bits to the
- /// DAG Combiner.
- virtual unsigned ComputeNumSignBitsForTargetNode(SDValue Op,
- unsigned Depth = 0) const;
-
- struct DAGCombinerInfo {
- void *DC; // The DAG Combiner object.
- bool BeforeLegalize;
- bool BeforeLegalizeOps;
- bool CalledByLegalizer;
- public:
- SelectionDAG &DAG;
-
- DAGCombinerInfo(SelectionDAG &dag, bool bl, bool blo, bool cl, void *dc)
- : DC(dc), BeforeLegalize(bl), BeforeLegalizeOps(blo),
- CalledByLegalizer(cl), DAG(dag) {}
+ /// \name Helpers for TargetTransformInfo implementations
+ /// @{
- bool isBeforeLegalize() const { return BeforeLegalize; }
- bool isBeforeLegalizeOps() const { return BeforeLegalizeOps; }
- bool isCalledByLegalizer() const { return CalledByLegalizer; }
+ /// Get the ISD node that corresponds to the Instruction class opcode.
+ int InstructionOpcodeToISD(unsigned Opcode) const;
- void AddToWorklist(SDNode *N);
- void RemoveFromWorklist(SDNode *N);
- SDValue CombineTo(SDNode *N, const std::vector<SDValue> &To,
- bool AddTo = true);
- SDValue CombineTo(SDNode *N, SDValue Res, bool AddTo = true);
- SDValue CombineTo(SDNode *N, SDValue Res0, SDValue Res1, bool AddTo = true);
-
- void CommitTargetLoweringOpt(const TargetLoweringOpt &TLO);
- };
-
- /// SimplifySetCC - Try to simplify a setcc built with the specified operands
- /// and cc. If it is unable to simplify it, return a null SDValue.
- SDValue SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
- ISD::CondCode Cond, bool foldBooleans,
- DAGCombinerInfo &DCI, DebugLoc dl) const;
+ /// Estimate the cost of type-legalization and the legalized type.
+ std::pair<unsigned, MVT> getTypeLegalizationCost(Type *Ty) const;
- /// isGAPlusOffset - Returns true (and the GlobalValue and the offset) if the
- /// node is a GlobalAddress + offset.
- virtual bool
- isGAPlusOffset(SDNode *N, const GlobalValue* &GA, int64_t &Offset) const;
-
- /// PerformDAGCombine - This method will be invoked for all target nodes and
- /// for any target-independent nodes that the target has registered with
- /// invoke it for.
- ///
- /// The semantics are as follows:
- /// Return Value:
- /// SDValue.Val == 0 - No change was made
- /// SDValue.Val == N - N was replaced, is dead, and is already handled.
- /// otherwise - N should be replaced by the returned Operand.
- ///
- /// In addition, methods provided by DAGCombinerInfo may be used to perform
- /// more complex transformations.
- ///
- virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
-
- /// isTypeDesirableForOp - Return true if the target has native support for
- /// the specified value type and it is 'desirable' to use the type for the
- /// given node type. e.g. On x86 i16 is legal, but undesirable since i16
- /// instruction encodings are longer and some i16 instructions are slow.
- virtual bool isTypeDesirableForOp(unsigned /*Opc*/, EVT VT) const {
- // By default, assume all legal types are desirable.
- 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.
- virtual bool IsDesirableToPromoteOp(SDValue /*Op*/, EVT &/*PVT*/) const {
- return false;
- }
+ /// @}
//===--------------------------------------------------------------------===//
// TargetLowering Configuration Methods - These methods should be invoked by
@@ -1111,16 +945,23 @@ 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, const TargetRegisterClass *RC) {
- assert((unsigned)VT.getSimpleVT().SimpleTy < array_lengthof(RegClassForVT));
+ void addRegisterClass(MVT VT, const TargetRegisterClass *RC) {
+ assert((unsigned)VT.SimpleTy < array_lengthof(RegClassForVT));
AvailableRegClasses.push_back(std::make_pair(VT, RC));
- RegClassForVT[VT.getSimpleVT().SimpleTy] = RC;
+ RegClassForVT[VT.SimpleTy] = RC;
+ }
+
+ /// clearRegisterClasses - remove all register classes
+ void clearRegisterClasses() {
+ for (unsigned i = 0 ; i<array_lengthof(RegClassForVT); i++)
+ RegClassForVT[i] = 0;
+ AvailableRegClasses.clear();
}
/// findRepresentativeClass - Return the largest legal super-reg register class
/// of the register class for the specified type and its associated "cost".
virtual std::pair<const TargetRegisterClass*, uint8_t>
- findRepresentativeClass(EVT VT) const;
+ findRepresentativeClass(MVT VT) const;
/// computeRegisterProperties - Once all of the register classes are added,
/// this allows us to compute derived properties we expose.
@@ -1263,387 +1104,6 @@ protected:
public:
//===--------------------------------------------------------------------===//
- // Lowering methods - These methods must be implemented by targets so that
- // the SelectionDAGBuilder code knows how to lower these.
- //
-
- /// LowerFormalArguments - This hook must be implemented to lower the
- /// incoming (formal) arguments, described by the Ins array, into the
- /// specified DAG. The implementation should fill in the InVals array
- /// with legal-type argument values, and return the resulting token
- /// chain value.
- ///
- virtual SDValue
- LowerFormalArguments(SDValue /*Chain*/, CallingConv::ID /*CallConv*/,
- bool /*isVarArg*/,
- const SmallVectorImpl<ISD::InputArg> &/*Ins*/,
- DebugLoc /*dl*/, SelectionDAG &/*DAG*/,
- SmallVectorImpl<SDValue> &/*InVals*/) const {
- llvm_unreachable("Not Implemented");
- }
-
- struct ArgListEntry {
- SDValue Node;
- Type* Ty;
- bool isSExt : 1;
- bool isZExt : 1;
- bool isInReg : 1;
- bool isSRet : 1;
- bool isNest : 1;
- bool isByVal : 1;
- uint16_t Alignment;
-
- ArgListEntry() : isSExt(false), isZExt(false), isInReg(false),
- isSRet(false), isNest(false), isByVal(false), Alignment(0) { }
- };
- typedef std::vector<ArgListEntry> ArgListTy;
-
- /// CallLoweringInfo - This structure contains all information that is
- /// necessary for lowering calls. It is passed to TLI::LowerCallTo when the
- /// SelectionDAG builder needs to lower a call, and targets will see this
- /// struct in their LowerCall implementation.
- struct CallLoweringInfo {
- SDValue Chain;
- Type *RetTy;
- bool RetSExt : 1;
- bool RetZExt : 1;
- bool IsVarArg : 1;
- bool IsInReg : 1;
- bool DoesNotReturn : 1;
- bool IsReturnValueUsed : 1;
-
- // IsTailCall should be modified by implementations of
- // TargetLowering::LowerCall that perform tail call conversions.
- bool IsTailCall;
-
- unsigned NumFixedArgs;
- CallingConv::ID CallConv;
- SDValue Callee;
- ArgListTy &Args;
- SelectionDAG &DAG;
- DebugLoc DL;
- ImmutableCallSite *CS;
- SmallVector<ISD::OutputArg, 32> Outs;
- SmallVector<SDValue, 32> OutVals;
- SmallVector<ISD::InputArg, 32> Ins;
-
-
- /// CallLoweringInfo - Constructs a call lowering context based on the
- /// ImmutableCallSite \p cs.
- CallLoweringInfo(SDValue chain, Type *retTy,
- FunctionType *FTy, bool isTailCall, SDValue callee,
- ArgListTy &args, SelectionDAG &dag, DebugLoc dl,
- ImmutableCallSite &cs)
- : Chain(chain), RetTy(retTy), RetSExt(cs.paramHasAttr(0, Attributes::SExt)),
- RetZExt(cs.paramHasAttr(0, Attributes::ZExt)), IsVarArg(FTy->isVarArg()),
- IsInReg(cs.paramHasAttr(0, Attributes::InReg)),
- DoesNotReturn(cs.doesNotReturn()),
- IsReturnValueUsed(!cs.getInstruction()->use_empty()),
- IsTailCall(isTailCall), NumFixedArgs(FTy->getNumParams()),
- CallConv(cs.getCallingConv()), Callee(callee), Args(args), DAG(dag),
- DL(dl), CS(&cs) {}
-
- /// CallLoweringInfo - Constructs a call lowering context based on the
- /// provided call information.
- CallLoweringInfo(SDValue chain, Type *retTy, bool retSExt, bool retZExt,
- bool isVarArg, bool isInReg, unsigned numFixedArgs,
- CallingConv::ID callConv, bool isTailCall,
- bool doesNotReturn, bool isReturnValueUsed, SDValue callee,
- ArgListTy &args, SelectionDAG &dag, DebugLoc dl)
- : Chain(chain), RetTy(retTy), RetSExt(retSExt), RetZExt(retZExt),
- IsVarArg(isVarArg), IsInReg(isInReg), DoesNotReturn(doesNotReturn),
- IsReturnValueUsed(isReturnValueUsed), IsTailCall(isTailCall),
- NumFixedArgs(numFixedArgs), CallConv(callConv), Callee(callee),
- Args(args), DAG(dag), DL(dl), CS(NULL) {}
- };
-
- /// LowerCallTo - This function lowers an abstract call to a function into an
- /// actual call. This returns a pair of operands. The first element is the
- /// return value for the function (if RetTy is not VoidTy). The second
- /// element is the outgoing token chain. It calls LowerCall to do the actual
- /// lowering.
- std::pair<SDValue, SDValue> LowerCallTo(CallLoweringInfo &CLI) const;
-
- /// LowerCall - This hook must be implemented to lower calls into the
- /// the specified DAG. The outgoing arguments to the call are described
- /// by the Outs array, and the values to be returned by the call are
- /// described by the Ins array. The implementation should fill in the
- /// InVals array with legal-type return values from the call, and return
- /// the resulting token chain value.
- virtual SDValue
- LowerCall(CallLoweringInfo &/*CLI*/,
- SmallVectorImpl<SDValue> &/*InVals*/) const {
- llvm_unreachable("Not Implemented");
- }
-
- /// HandleByVal - Target-specific cleanup for formal ByVal parameters.
- virtual void HandleByVal(CCState *, unsigned &, unsigned) 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.
- ///
- virtual bool CanLowerReturn(CallingConv::ID /*CallConv*/,
- MachineFunction &/*MF*/, bool /*isVarArg*/,
- const SmallVectorImpl<ISD::OutputArg> &/*Outs*/,
- LLVMContext &/*Context*/) const
- {
- // Return true by default to get preexisting behavior.
- return true;
- }
-
- /// LowerReturn - This hook must be implemented to lower outgoing
- /// return values, described by the Outs array, into the specified
- /// DAG. The implementation should return the resulting token chain
- /// value.
- ///
- virtual SDValue
- LowerReturn(SDValue /*Chain*/, CallingConv::ID /*CallConv*/,
- bool /*isVarArg*/,
- const SmallVectorImpl<ISD::OutputArg> &/*Outs*/,
- const SmallVectorImpl<SDValue> &/*OutVals*/,
- DebugLoc /*dl*/, SelectionDAG &/*DAG*/) const {
- llvm_unreachable("Not Implemented");
- }
-
- /// isUsedByReturnOnly - Return true if result of the specified node is used
- /// 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 *, SDValue &Chain) const {
- return false;
- }
-
- /// mayBeEmittedAsTailCall - Return true if the target may be able emit the
- /// call instruction as a tail call. This is used by optimization passes to
- /// determine if it's profitable to duplicate return instructions to enable
- /// tailcall optimization.
- virtual bool mayBeEmittedAsTailCall(CallInst *) const {
- return false;
- }
-
- /// getTypeForExtArgOrReturn - Return the type that should be used to zero or
- /// sign extend a zeroext/signext integer argument or return value.
- /// FIXME: Most C calling convention requires the return type to be promoted,
- /// but this is not true all the time, e.g. i1 on x86-64. It is also not
- /// necessary for non-C calling conventions. The frontend should handle this
- /// and include all of the necessary information.
- virtual EVT getTypeForExtArgOrReturn(LLVMContext &Context, EVT VT,
- ISD::NodeType /*ExtendKind*/) const {
- EVT MinVT = getRegisterType(Context, MVT::i32);
- return VT.bitsLT(MinVT) ? MinVT : VT;
- }
-
- /// 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.
- /// The reason we can not do away with LowerOperation entirely is that
- /// LegalizeDAG isn't yet ready to use this callback.
- /// TODO: Consider merging with ReplaceNodeResults.
-
- /// The target places new result values for the node in Results (their number
- /// and types must exactly match those of the original return values of
- /// the node), or leaves Results empty, which indicates that the node is not
- /// to be custom lowered after all.
- /// The default implementation calls LowerOperation.
- virtual void LowerOperationWrapper(SDNode *N,
- SmallVectorImpl<SDValue> &Results,
- SelectionDAG &DAG) const;
-
- /// LowerOperation - This callback is invoked for operations that are
- /// unsupported by the target, which are registered to use 'custom' lowering,
- /// and whose defined values are all legal.
- /// If the target has no operations that require custom lowering, it need not
- /// implement this. The default implementation of this aborts.
- virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const;
-
- /// ReplaceNodeResults - This callback is invoked when a node result type is
- /// illegal for the target, and the operation was registered to use 'custom'
- /// lowering for that result type. The target places new result values for
- /// the node in Results (their number and types must exactly match those of
- /// the original return values of the node), or leaves Results empty, which
- /// indicates that the node is not to be custom lowered after all.
- ///
- /// If the target has no operations that require custom lowering, it need not
- /// implement this. The default implementation aborts.
- virtual void ReplaceNodeResults(SDNode * /*N*/,
- SmallVectorImpl<SDValue> &/*Results*/,
- SelectionDAG &/*DAG*/) const {
- llvm_unreachable("ReplaceNodeResults not implemented for this target!");
- }
-
- /// getTargetNodeName() - This method returns the name of a target specific
- /// DAG node.
- virtual const char *getTargetNodeName(unsigned Opcode) const;
-
- /// createFastISel - This method returns a target specific FastISel object,
- /// or null if the target does not support "fast" ISel.
- virtual FastISel *createFastISel(FunctionLoweringInfo &,
- const TargetLibraryInfo *) const {
- return 0;
- }
-
- //===--------------------------------------------------------------------===//
- // Inline Asm Support hooks
- //
-
- /// ExpandInlineAsm - This hook allows the target to expand an inline asm
- /// call to be explicit llvm code if it wants to. This is useful for
- /// turning simple inline asms into LLVM intrinsics, which gives the
- /// compiler more information about the behavior of the code.
- virtual bool ExpandInlineAsm(CallInst *) const {
- return false;
- }
-
- enum ConstraintType {
- C_Register, // Constraint represents specific register(s).
- C_RegisterClass, // Constraint represents any of register(s) in class.
- C_Memory, // Memory constraint.
- C_Other, // Something else.
- C_Unknown // Unsupported constraint.
- };
-
- enum ConstraintWeight {
- // Generic weights.
- CW_Invalid = -1, // No match.
- CW_Okay = 0, // Acceptable.
- 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.
- CW_Memory = CW_Better, // Memory operands.
- CW_Constant = CW_Best, // Constant operand.
- CW_Default = CW_Okay // Default or don't know type.
- };
-
- /// AsmOperandInfo - This contains information for each constraint that we are
- /// lowering.
- struct AsmOperandInfo : public InlineAsm::ConstraintInfo {
- /// ConstraintCode - This contains the actual string for the code, like "m".
- /// TargetLowering picks the 'best' code from ConstraintInfo::Codes that
- /// most closely matches the operand.
- std::string ConstraintCode;
-
- /// ConstraintType - Information about the constraint code, e.g. Register,
- /// RegisterClass, Memory, Other, Unknown.
- TargetLowering::ConstraintType ConstraintType;
-
- /// CallOperandval - If this is the result output operand or a
- /// clobber, this is null, otherwise it is the incoming operand to the
- /// CallInst. This gets modified as the asm is processed.
- Value *CallOperandVal;
-
- /// ConstraintVT - The ValueType for the operand value.
- EVT ConstraintVT;
-
- /// isMatchingInputConstraint - Return true of this is an input operand that
- /// is a matching constraint like "4".
- bool isMatchingInputConstraint() const;
-
- /// getMatchedOperand - If this is an input matching constraint, this method
- /// returns the output operand it matches.
- unsigned getMatchedOperand() const;
-
- /// Copy constructor for copying from an AsmOperandInfo.
- AsmOperandInfo(const AsmOperandInfo &info)
- : InlineAsm::ConstraintInfo(info),
- ConstraintCode(info.ConstraintCode),
- ConstraintType(info.ConstraintType),
- CallOperandVal(info.CallOperandVal),
- ConstraintVT(info.ConstraintVT) {
- }
-
- /// Copy constructor for copying from a ConstraintInfo.
- AsmOperandInfo(const InlineAsm::ConstraintInfo &info)
- : InlineAsm::ConstraintInfo(info),
- ConstraintType(TargetLowering::C_Unknown),
- 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(
- AsmOperandInfo &info, const char *constraint) const;
-
- /// ComputeConstraintToUse - Determines the constraint code and constraint
- /// 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.
- virtual void ComputeConstraintToUse(AsmOperandInfo &OpInfo,
- SDValue Op,
- SelectionDAG *DAG = 0) const;
-
- /// getConstraintType - Given a constraint, return the type of constraint it
- /// is for this target.
- virtual ConstraintType getConstraintType(const std::string &Constraint) const;
-
- /// getRegForInlineAsmConstraint - Given a physical register constraint (e.g.
- /// {edx}), return the register number and the register class for the
- /// register.
- ///
- /// Given a register class constraint, like 'r', if this corresponds directly
- /// to an LLVM register class, return a register of 0 and the register class
- /// pointer.
- ///
- /// This should only be used for C_Register constraints. On error,
- /// this returns a register number of 0 and a null register class pointer..
- virtual std::pair<unsigned, const TargetRegisterClass*>
- getRegForInlineAsmConstraint(const std::string &Constraint,
- EVT VT) const;
-
- /// LowerXConstraint - try to replace an X constraint, which matches anything,
- /// with another that has more specific requirements based on the type of the
- /// corresponding operand. This returns null if there is no replacement to
- /// make.
- virtual const char *LowerXConstraint(EVT ConstraintVT) const;
-
- /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
- /// vector. If it is invalid, don't add anything to Ops.
- virtual void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint,
- std::vector<SDValue> &Ops,
- SelectionDAG &DAG) const;
-
- //===--------------------------------------------------------------------===//
- // Instruction Emitting Hooks
- //
-
- // EmitInstrWithCustomInserter - This method should be implemented by targets
- // that mark instructions with the 'usesCustomInserter' flag. These
- // instructions are special in various ways, which require special support to
- // insert. The specified MachineInstr is created but not inserted into any
- // basic blocks, and this method is called to expand it into a sequence of
- // instructions, potentially also creating new basic blocks and control flow.
- virtual MachineBasicBlock *
- EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const;
-
- /// AdjustInstrPostInstrSelection - This method should be implemented by
- /// targets that mark instructions with the 'hasPostISelHook' flag. These
- /// instructions must be adjusted after instruction selection by target hooks.
- /// e.g. To fill in optional defs for ARM 's' setting instructions.
- virtual void
- AdjustInstrPostInstrSelection(MachineInstr *MI, SDNode *Node) const;
-
- //===--------------------------------------------------------------------===//
// Addressing mode description hooks (used by LSR etc).
//
@@ -1658,6 +1118,22 @@ public:
return false;
}
+ /// AddrMode - This represents an addressing mode of:
+ /// BaseGV + BaseOffs + BaseReg + Scale*ScaleReg
+ /// If BaseGV is null, there is no BaseGV.
+ /// If BaseOffs is zero, there is no base offset.
+ /// If HasBaseReg is false, there is no base register.
+ /// If Scale is zero, there is no ScaleReg. Scale of 1 indicates a reg with
+ /// no scale.
+ ///
+ struct AddrMode {
+ GlobalValue *BaseGV;
+ int64_t BaseOffs;
+ bool HasBaseReg;
+ int64_t Scale;
+ AddrMode() : BaseGV(0), BaseOffs(0), HasBaseReg(false), Scale(0) {}
+ };
+
/// 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
@@ -1708,6 +1184,13 @@ public:
return false;
}
+ /// isZExtFree - Return true if zero-extending the specific node Val to type
+ /// VT2 is free (either because it's implicitly zero-extended such as ARM
+ /// ldrb / ldrh or because it's folded such as X86 zero-extending loads).
+ virtual bool isZExtFree(SDValue Val, EVT VT2) const {
+ return isZExtFree(Val.getValueType(), VT2);
+ }
+
/// 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 {
@@ -1736,17 +1219,6 @@ public:
}
//===--------------------------------------------------------------------===//
- // Div utility functions
- //
- SDValue BuildExactSDIV(SDValue Op1, SDValue Op2, DebugLoc dl,
- SelectionDAG &DAG) const;
- SDValue BuildSDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization,
- std::vector<SDNode*>* Created) const;
- SDValue BuildUDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization,
- std::vector<SDNode*>* Created) const;
-
-
- //===--------------------------------------------------------------------===//
// Runtime Library hooks
//
@@ -1909,7 +1381,7 @@ private:
/// each ValueType the target supports natively.
const TargetRegisterClass *RegClassForVT[MVT::LAST_VALUETYPE];
unsigned char NumRegistersForVT[MVT::LAST_VALUETYPE];
- EVT RegisterTypeForVT[MVT::LAST_VALUETYPE];
+ MVT RegisterTypeForVT[MVT::LAST_VALUETYPE];
/// RepRegClassForVT - This indicates the "representative" register class to
/// use for each ValueType the target supports natively. This information is
@@ -1929,7 +1401,7 @@ private:
/// contains one step of the expand (e.g. i64 -> i32), even if there are
/// multiple steps required (e.g. i64 -> i16). For types natively supported
/// by the system, this holds the same type (e.g. i32 -> i32).
- EVT TransformToType[MVT::LAST_VALUETYPE];
+ MVT TransformToType[MVT::LAST_VALUETYPE];
/// OpActions - For each operation and each value type, keep a LegalizeAction
/// that indicates how instruction selection should deal with the operation.
@@ -1970,19 +1442,22 @@ public:
getTypeConversion(LLVMContext &Context, EVT VT) const {
// If this is a simple type, use the ComputeRegisterProp mechanism.
if (VT.isSimple()) {
- assert((unsigned)VT.getSimpleVT().SimpleTy <
- array_lengthof(TransformToType));
- EVT NVT = TransformToType[VT.getSimpleVT().SimpleTy];
- LegalizeTypeAction LA = ValueTypeActions.getTypeAction(VT.getSimpleVT());
+ MVT SVT = VT.getSimpleVT();
+ assert((unsigned)SVT.SimpleTy < array_lengthof(TransformToType));
+ MVT NVT = TransformToType[SVT.SimpleTy];
+ LegalizeTypeAction LA = ValueTypeActions.getTypeAction(SVT);
assert(
- (!(NVT.isSimple() && LA != TypeLegal) ||
- ValueTypeActions.getTypeAction(NVT.getSimpleVT()) != TypePromoteInteger)
+ (LA == TypeLegal ||
+ ValueTypeActions.getTypeAction(NVT) != TypePromoteInteger)
&& "Promote may not follow Expand or Promote");
if (LA == TypeSplitVector)
- NVT = EVT::getVectorVT(Context, VT.getVectorElementType(),
- VT.getVectorNumElements() / 2);
+ return LegalizeKind(LA, EVT::getVectorVT(Context,
+ SVT.getVectorElementType(),
+ SVT.getVectorNumElements()/2));
+ if (LA == TypeScalarizeVector)
+ return LegalizeKind(LA, SVT.getVectorElementType());
return LegalizeKind(LA, NVT);
}
@@ -2086,7 +1561,7 @@ public:
}
private:
- std::vector<std::pair<EVT, const TargetRegisterClass*> > AvailableRegClasses;
+ std::vector<std::pair<MVT, const TargetRegisterClass*> > AvailableRegClasses;
/// TargetDAGCombineArray - Targets can specify ISD nodes that they would
/// like PerformDAGCombine callbacks for by calling setTargetDAGCombine(),
@@ -2125,11 +1600,11 @@ protected:
/// with 16-bit alignment would result in four 2-byte stores and one 1-byte
/// store. This only applies to setting a constant array of a constant size.
/// @brief Specify maximum number of store instructions per memset call.
- unsigned maxStoresPerMemset;
+ unsigned MaxStoresPerMemset;
/// Maximum number of stores operations that may be substituted for the call
/// to memset, used for functions with OptSize attribute.
- unsigned maxStoresPerMemsetOptSize;
+ 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
@@ -2141,11 +1616,11 @@ protected:
/// and one 1-byte store. This only applies to copying a constant array of
/// constant size.
/// @brief Specify maximum bytes of store instructions per memcpy call.
- unsigned maxStoresPerMemcpy;
+ unsigned MaxStoresPerMemcpy;
/// Maximum number of store operations that may be substituted for a call
/// to memcpy, used for functions with OptSize attribute.
- unsigned maxStoresPerMemcpyOptSize;
+ 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
@@ -2156,30 +1631,641 @@ protected:
/// with 8-bit alignment would result in nine 1-byte stores. This only
/// applies to copying a constant array of constant size.
/// @brief Specify maximum bytes of store instructions per memmove call.
- unsigned maxStoresPerMemmove;
+ 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;
+ unsigned MaxStoresPerMemmoveOptSize;
- /// predictableSelectIsExpensive - Tells the code generator that select is
+ /// PredictableSelectIsExpensive - Tells the code generator that select is
/// more expensive than a branch if the branch is usually predicted right.
- bool predictableSelectIsExpensive;
+ bool PredictableSelectIsExpensive;
-private:
+protected:
/// isLegalRC - Return true if the value types that can be represented by the
/// specified register class are all legal.
bool isLegalRC(const TargetRegisterClass *RC) const;
};
+//===----------------------------------------------------------------------===//
+/// TargetLowering - This class defines information used to lower LLVM code to
+/// legal SelectionDAG operators that the target instruction selector can accept
+/// natively.
+///
+/// This class also defines callbacks that targets must implement to lower
+/// target-specific constructs to SelectionDAG operators.
+///
+class TargetLowering : public TargetLoweringBase {
+ TargetLowering(const TargetLowering&) LLVM_DELETED_FUNCTION;
+ void operator=(const TargetLowering&) LLVM_DELETED_FUNCTION;
+
+public:
+ /// NOTE: The constructor takes ownership of TLOF.
+ explicit TargetLowering(const TargetMachine &TM,
+ const TargetLoweringObjectFile *TLOF);
+
+ /// getPreIndexedAddressParts - returns true by value, base pointer and
+ /// offset pointer and addressing mode by reference if the node's address
+ /// can be legally represented as pre-indexed load / store address.
+ virtual bool getPreIndexedAddressParts(SDNode * /*N*/, SDValue &/*Base*/,
+ SDValue &/*Offset*/,
+ ISD::MemIndexedMode &/*AM*/,
+ SelectionDAG &/*DAG*/) const {
+ return false;
+ }
+
+ /// getPostIndexedAddressParts - returns true by value, base pointer and
+ /// offset pointer and addressing mode by reference if this node can be
+ /// combined with a load / store to form a post-indexed load / store.
+ virtual bool getPostIndexedAddressParts(SDNode * /*N*/, SDNode * /*Op*/,
+ SDValue &/*Base*/, SDValue &/*Offset*/,
+ ISD::MemIndexedMode &/*AM*/,
+ SelectionDAG &/*DAG*/) const {
+ return false;
+ }
+
+ /// getJumpTableEncoding - Return the entry encoding for a jump table in the
+ /// current function. The returned value is a member of the
+ /// MachineJumpTableInfo::JTEntryKind enum.
+ virtual unsigned getJumpTableEncoding() const;
+
+ virtual const MCExpr *
+ LowerCustomJumpTableEntry(const MachineJumpTableInfo * /*MJTI*/,
+ const MachineBasicBlock * /*MBB*/, unsigned /*uid*/,
+ MCContext &/*Ctx*/) const {
+ llvm_unreachable("Need to implement this hook if target has custom JTIs");
+ }
+
+ /// getPICJumpTableRelocaBase - Returns relocation base for the given PIC
+ /// jumptable.
+ virtual SDValue getPICJumpTableRelocBase(SDValue Table,
+ SelectionDAG &DAG) const;
+
+ /// getPICJumpTableRelocBaseExpr - This returns the relocation base for the
+ /// given PIC jumptable, the same as getPICJumpTableRelocBase, but as an
+ /// MCExpr.
+ virtual const MCExpr *
+ getPICJumpTableRelocBaseExpr(const MachineFunction *MF,
+ unsigned JTI, MCContext &Ctx) const;
+
+ /// isOffsetFoldingLegal - Return true if folding a constant offset
+ /// with the given GlobalAddress is legal. It is frequently not legal in
+ /// PIC relocation models.
+ virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
+
+ bool isInTailCallPosition(SelectionDAG &DAG, SDNode *Node,
+ SDValue &Chain) const;
+
+ void softenSetCCOperands(SelectionDAG &DAG, EVT VT,
+ SDValue &NewLHS, SDValue &NewRHS,
+ ISD::CondCode &CCCode, DebugLoc DL) const;
+
+ SDValue makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT,
+ const SDValue *Ops, unsigned NumOps,
+ bool isSigned, DebugLoc dl) const;
+
+ //===--------------------------------------------------------------------===//
+ // TargetLowering Optimization Methods
+ //
+
+ /// TargetLoweringOpt - A convenience struct that encapsulates a DAG, and two
+ /// SDValues for returning information from TargetLowering to its clients
+ /// that want to combine
+ struct TargetLoweringOpt {
+ SelectionDAG &DAG;
+ bool LegalTys;
+ bool LegalOps;
+ SDValue Old;
+ SDValue New;
+
+ explicit TargetLoweringOpt(SelectionDAG &InDAG,
+ bool LT, bool LO) :
+ DAG(InDAG), LegalTys(LT), LegalOps(LO) {}
+
+ bool LegalTypes() const { return LegalTys; }
+ bool LegalOperations() const { return LegalOps; }
+
+ bool CombineTo(SDValue O, SDValue N) {
+ Old = O;
+ New = N;
+ return true;
+ }
+
+ /// ShrinkDemandedConstant - Check to see if the specified operand of the
+ /// specified instruction is a constant integer. If so, check to see if
+ /// there are any bits set in the constant that are not demanded. If so,
+ /// shrink the constant and return true.
+ bool ShrinkDemandedConstant(SDValue Op, const APInt &Demanded);
+
+ /// ShrinkDemandedOp - Convert x+y to (VT)((SmallVT)x+(SmallVT)y) if the
+ /// casts are free. This uses isZExtFree and ZERO_EXTEND for the widening
+ /// cast, but it could be generalized for targets with other types of
+ /// implicit widening casts.
+ bool ShrinkDemandedOp(SDValue Op, unsigned BitWidth, const APInt &Demanded,
+ DebugLoc dl);
+ };
+
+ /// SimplifyDemandedBits - Look at Op. At this point, we know that only the
+ /// DemandedMask bits of the result of Op are ever used downstream. If we can
+ /// use this information to simplify Op, create a new simplified DAG node and
+ /// return true, returning the original and new nodes in Old and New.
+ /// Otherwise, analyze the expression and return a mask of KnownOne and
+ /// KnownZero bits for the expression (used to simplify the caller).
+ /// The KnownZero/One bits may only be accurate for those bits in the
+ /// DemandedMask.
+ bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedMask,
+ APInt &KnownZero, APInt &KnownOne,
+ TargetLoweringOpt &TLO, unsigned Depth = 0) const;
+
+ /// computeMaskedBitsForTargetNode - Determine which of the bits specified in
+ /// Mask are known to be either zero or one and return them in the
+ /// KnownZero/KnownOne bitsets.
+ virtual void computeMaskedBitsForTargetNode(const SDValue Op,
+ APInt &KnownZero,
+ APInt &KnownOne,
+ const SelectionDAG &DAG,
+ unsigned Depth = 0) const;
+
+ /// ComputeNumSignBitsForTargetNode - This method can be implemented by
+ /// targets that want to expose additional information about sign bits to the
+ /// DAG Combiner.
+ virtual unsigned ComputeNumSignBitsForTargetNode(SDValue Op,
+ unsigned Depth = 0) const;
+
+ struct DAGCombinerInfo {
+ void *DC; // The DAG Combiner object.
+ CombineLevel Level;
+ bool CalledByLegalizer;
+ public:
+ SelectionDAG &DAG;
+
+ DAGCombinerInfo(SelectionDAG &dag, CombineLevel level, bool cl, void *dc)
+ : DC(dc), Level(level), CalledByLegalizer(cl), DAG(dag) {}
+
+ bool isBeforeLegalize() const { return Level == BeforeLegalizeTypes; }
+ bool isBeforeLegalizeOps() const { return Level < AfterLegalizeVectorOps; }
+ bool isAfterLegalizeVectorOps() const {
+ return Level == AfterLegalizeDAG;
+ }
+ CombineLevel getDAGCombineLevel() { return Level; }
+ bool isCalledByLegalizer() const { return CalledByLegalizer; }
+
+ void AddToWorklist(SDNode *N);
+ void RemoveFromWorklist(SDNode *N);
+ SDValue CombineTo(SDNode *N, const std::vector<SDValue> &To,
+ bool AddTo = true);
+ SDValue CombineTo(SDNode *N, SDValue Res, bool AddTo = true);
+ SDValue CombineTo(SDNode *N, SDValue Res0, SDValue Res1, bool AddTo = true);
+
+ void CommitTargetLoweringOpt(const TargetLoweringOpt &TLO);
+ };
+
+ /// SimplifySetCC - Try to simplify a setcc built with the specified operands
+ /// and cc. If it is unable to simplify it, return a null SDValue.
+ SDValue SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
+ ISD::CondCode Cond, bool foldBooleans,
+ DAGCombinerInfo &DCI, DebugLoc dl) const;
+
+ /// isGAPlusOffset - Returns true (and the GlobalValue and the offset) if the
+ /// node is a GlobalAddress + offset.
+ virtual bool
+ isGAPlusOffset(SDNode *N, const GlobalValue* &GA, int64_t &Offset) const;
+
+ /// PerformDAGCombine - This method will be invoked for all target nodes and
+ /// for any target-independent nodes that the target has registered with
+ /// invoke it for.
+ ///
+ /// The semantics are as follows:
+ /// Return Value:
+ /// SDValue.Val == 0 - No change was made
+ /// SDValue.Val == N - N was replaced, is dead, and is already handled.
+ /// otherwise - N should be replaced by the returned Operand.
+ ///
+ /// In addition, methods provided by DAGCombinerInfo may be used to perform
+ /// more complex transformations.
+ ///
+ virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
+
+ /// isTypeDesirableForOp - Return true if the target has native support for
+ /// the specified value type and it is 'desirable' to use the type for the
+ /// given node type. e.g. On x86 i16 is legal, but undesirable since i16
+ /// instruction encodings are longer and some i16 instructions are slow.
+ virtual bool isTypeDesirableForOp(unsigned /*Opc*/, EVT VT) const {
+ // By default, assume all legal types are desirable.
+ 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.
+ virtual bool IsDesirableToPromoteOp(SDValue /*Op*/, EVT &/*PVT*/) const {
+ return false;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Lowering methods - These methods must be implemented by targets so that
+ // the SelectionDAGBuilder code knows how to lower these.
+ //
+
+ /// LowerFormalArguments - This hook must be implemented to lower the
+ /// incoming (formal) arguments, described by the Ins array, into the
+ /// specified DAG. The implementation should fill in the InVals array
+ /// with legal-type argument values, and return the resulting token
+ /// chain value.
+ ///
+ virtual SDValue
+ LowerFormalArguments(SDValue /*Chain*/, CallingConv::ID /*CallConv*/,
+ bool /*isVarArg*/,
+ const SmallVectorImpl<ISD::InputArg> &/*Ins*/,
+ DebugLoc /*dl*/, SelectionDAG &/*DAG*/,
+ SmallVectorImpl<SDValue> &/*InVals*/) const {
+ llvm_unreachable("Not Implemented");
+ }
+
+ struct ArgListEntry {
+ SDValue Node;
+ Type* Ty;
+ bool isSExt : 1;
+ bool isZExt : 1;
+ bool isInReg : 1;
+ bool isSRet : 1;
+ bool isNest : 1;
+ bool isByVal : 1;
+ uint16_t Alignment;
+
+ ArgListEntry() : isSExt(false), isZExt(false), isInReg(false),
+ isSRet(false), isNest(false), isByVal(false), Alignment(0) { }
+ };
+ typedef std::vector<ArgListEntry> ArgListTy;
+
+ /// CallLoweringInfo - This structure contains all information that is
+ /// necessary for lowering calls. It is passed to TLI::LowerCallTo when the
+ /// SelectionDAG builder needs to lower a call, and targets will see this
+ /// struct in their LowerCall implementation.
+ struct CallLoweringInfo {
+ SDValue Chain;
+ Type *RetTy;
+ bool RetSExt : 1;
+ bool RetZExt : 1;
+ bool IsVarArg : 1;
+ bool IsInReg : 1;
+ bool DoesNotReturn : 1;
+ bool IsReturnValueUsed : 1;
+
+ // IsTailCall should be modified by implementations of
+ // TargetLowering::LowerCall that perform tail call conversions.
+ bool IsTailCall;
+
+ unsigned NumFixedArgs;
+ CallingConv::ID CallConv;
+ SDValue Callee;
+ ArgListTy &Args;
+ SelectionDAG &DAG;
+ DebugLoc DL;
+ ImmutableCallSite *CS;
+ SmallVector<ISD::OutputArg, 32> Outs;
+ SmallVector<SDValue, 32> OutVals;
+ SmallVector<ISD::InputArg, 32> Ins;
+
+
+ /// CallLoweringInfo - Constructs a call lowering context based on the
+ /// ImmutableCallSite \p cs.
+ CallLoweringInfo(SDValue chain, Type *retTy,
+ FunctionType *FTy, bool isTailCall, SDValue callee,
+ ArgListTy &args, SelectionDAG &dag, DebugLoc dl,
+ ImmutableCallSite &cs)
+ : Chain(chain), RetTy(retTy), RetSExt(cs.paramHasAttr(0, Attribute::SExt)),
+ RetZExt(cs.paramHasAttr(0, Attribute::ZExt)), IsVarArg(FTy->isVarArg()),
+ IsInReg(cs.paramHasAttr(0, Attribute::InReg)),
+ DoesNotReturn(cs.doesNotReturn()),
+ IsReturnValueUsed(!cs.getInstruction()->use_empty()),
+ IsTailCall(isTailCall), NumFixedArgs(FTy->getNumParams()),
+ CallConv(cs.getCallingConv()), Callee(callee), Args(args), DAG(dag),
+ DL(dl), CS(&cs) {}
+
+ /// CallLoweringInfo - Constructs a call lowering context based on the
+ /// provided call information.
+ CallLoweringInfo(SDValue chain, Type *retTy, bool retSExt, bool retZExt,
+ bool isVarArg, bool isInReg, unsigned numFixedArgs,
+ CallingConv::ID callConv, bool isTailCall,
+ bool doesNotReturn, bool isReturnValueUsed, SDValue callee,
+ ArgListTy &args, SelectionDAG &dag, DebugLoc dl)
+ : Chain(chain), RetTy(retTy), RetSExt(retSExt), RetZExt(retZExt),
+ IsVarArg(isVarArg), IsInReg(isInReg), DoesNotReturn(doesNotReturn),
+ IsReturnValueUsed(isReturnValueUsed), IsTailCall(isTailCall),
+ NumFixedArgs(numFixedArgs), CallConv(callConv), Callee(callee),
+ Args(args), DAG(dag), DL(dl), CS(NULL) {}
+ };
+
+ /// LowerCallTo - This function lowers an abstract call to a function into an
+ /// actual call. This returns a pair of operands. The first element is the
+ /// return value for the function (if RetTy is not VoidTy). The second
+ /// element is the outgoing token chain. It calls LowerCall to do the actual
+ /// lowering.
+ std::pair<SDValue, SDValue> LowerCallTo(CallLoweringInfo &CLI) const;
+
+ /// LowerCall - This hook must be implemented to lower calls into the
+ /// the specified DAG. The outgoing arguments to the call are described
+ /// by the Outs array, and the values to be returned by the call are
+ /// described by the Ins array. The implementation should fill in the
+ /// InVals array with legal-type return values from the call, and return
+ /// the resulting token chain value.
+ virtual SDValue
+ LowerCall(CallLoweringInfo &/*CLI*/,
+ SmallVectorImpl<SDValue> &/*InVals*/) const {
+ llvm_unreachable("Not Implemented");
+ }
+
+ /// HandleByVal - Target-specific cleanup for formal ByVal parameters.
+ virtual void HandleByVal(CCState *, unsigned &, unsigned) 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.
+ ///
+ virtual bool CanLowerReturn(CallingConv::ID /*CallConv*/,
+ MachineFunction &/*MF*/, bool /*isVarArg*/,
+ const SmallVectorImpl<ISD::OutputArg> &/*Outs*/,
+ LLVMContext &/*Context*/) const
+ {
+ // Return true by default to get preexisting behavior.
+ return true;
+ }
+
+ /// LowerReturn - This hook must be implemented to lower outgoing
+ /// return values, described by the Outs array, into the specified
+ /// DAG. The implementation should return the resulting token chain
+ /// value.
+ ///
+ virtual SDValue
+ LowerReturn(SDValue /*Chain*/, CallingConv::ID /*CallConv*/,
+ bool /*isVarArg*/,
+ const SmallVectorImpl<ISD::OutputArg> &/*Outs*/,
+ const SmallVectorImpl<SDValue> &/*OutVals*/,
+ DebugLoc /*dl*/, SelectionDAG &/*DAG*/) const {
+ llvm_unreachable("Not Implemented");
+ }
+
+ /// isUsedByReturnOnly - Return true if result of the specified node is used
+ /// 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 *, SDValue &Chain) const {
+ return false;
+ }
+
+ /// mayBeEmittedAsTailCall - Return true if the target may be able emit the
+ /// call instruction as a tail call. This is used by optimization passes to
+ /// determine if it's profitable to duplicate return instructions to enable
+ /// tailcall optimization.
+ virtual bool mayBeEmittedAsTailCall(CallInst *) const {
+ return false;
+ }
+
+ /// getTypeForExtArgOrReturn - Return the type that should be used to zero or
+ /// sign extend a zeroext/signext integer argument or return value.
+ /// FIXME: Most C calling convention requires the return type to be promoted,
+ /// but this is not true all the time, e.g. i1 on x86-64. It is also not
+ /// necessary for non-C calling conventions. The frontend should handle this
+ /// and include all of the necessary information.
+ virtual MVT getTypeForExtArgOrReturn(MVT VT,
+ ISD::NodeType /*ExtendKind*/) const {
+ MVT MinVT = getRegisterType(MVT::i32);
+ return VT.bitsLT(MinVT) ? MinVT : VT;
+ }
+
+ /// 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.
+ /// The reason we can not do away with LowerOperation entirely is that
+ /// LegalizeDAG isn't yet ready to use this callback.
+ /// TODO: Consider merging with ReplaceNodeResults.
+
+ /// The target places new result values for the node in Results (their number
+ /// and types must exactly match those of the original return values of
+ /// the node), or leaves Results empty, which indicates that the node is not
+ /// to be custom lowered after all.
+ /// The default implementation calls LowerOperation.
+ virtual void LowerOperationWrapper(SDNode *N,
+ SmallVectorImpl<SDValue> &Results,
+ SelectionDAG &DAG) const;
+
+ /// LowerOperation - This callback is invoked for operations that are
+ /// unsupported by the target, which are registered to use 'custom' lowering,
+ /// and whose defined values are all legal.
+ /// If the target has no operations that require custom lowering, it need not
+ /// implement this. The default implementation of this aborts.
+ virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const;
+
+ /// ReplaceNodeResults - This callback is invoked when a node result type is
+ /// illegal for the target, and the operation was registered to use 'custom'
+ /// lowering for that result type. The target places new result values for
+ /// the node in Results (their number and types must exactly match those of
+ /// the original return values of the node), or leaves Results empty, which
+ /// indicates that the node is not to be custom lowered after all.
+ ///
+ /// If the target has no operations that require custom lowering, it need not
+ /// implement this. The default implementation aborts.
+ virtual void ReplaceNodeResults(SDNode * /*N*/,
+ SmallVectorImpl<SDValue> &/*Results*/,
+ SelectionDAG &/*DAG*/) const {
+ llvm_unreachable("ReplaceNodeResults not implemented for this target!");
+ }
+
+ /// getTargetNodeName() - This method returns the name of a target specific
+ /// DAG node.
+ virtual const char *getTargetNodeName(unsigned Opcode) const;
+
+ /// createFastISel - This method returns a target specific FastISel object,
+ /// or null if the target does not support "fast" ISel.
+ virtual FastISel *createFastISel(FunctionLoweringInfo &,
+ const TargetLibraryInfo *) const {
+ return 0;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Inline Asm Support hooks
+ //
+
+ /// ExpandInlineAsm - This hook allows the target to expand an inline asm
+ /// call to be explicit llvm code if it wants to. This is useful for
+ /// turning simple inline asms into LLVM intrinsics, which gives the
+ /// compiler more information about the behavior of the code.
+ virtual bool ExpandInlineAsm(CallInst *) const {
+ return false;
+ }
+
+ enum ConstraintType {
+ C_Register, // Constraint represents specific register(s).
+ C_RegisterClass, // Constraint represents any of register(s) in class.
+ C_Memory, // Memory constraint.
+ C_Other, // Something else.
+ C_Unknown // Unsupported constraint.
+ };
+
+ enum ConstraintWeight {
+ // Generic weights.
+ CW_Invalid = -1, // No match.
+ CW_Okay = 0, // Acceptable.
+ 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.
+ CW_Memory = CW_Better, // Memory operands.
+ CW_Constant = CW_Best, // Constant operand.
+ CW_Default = CW_Okay // Default or don't know type.
+ };
+
+ /// AsmOperandInfo - This contains information for each constraint that we are
+ /// lowering.
+ struct AsmOperandInfo : public InlineAsm::ConstraintInfo {
+ /// ConstraintCode - This contains the actual string for the code, like "m".
+ /// TargetLowering picks the 'best' code from ConstraintInfo::Codes that
+ /// most closely matches the operand.
+ std::string ConstraintCode;
+
+ /// ConstraintType - Information about the constraint code, e.g. Register,
+ /// RegisterClass, Memory, Other, Unknown.
+ TargetLowering::ConstraintType ConstraintType;
+
+ /// CallOperandval - If this is the result output operand or a
+ /// clobber, this is null, otherwise it is the incoming operand to the
+ /// CallInst. This gets modified as the asm is processed.
+ Value *CallOperandVal;
+
+ /// ConstraintVT - The ValueType for the operand value.
+ MVT ConstraintVT;
+
+ /// isMatchingInputConstraint - Return true of this is an input operand that
+ /// is a matching constraint like "4".
+ bool isMatchingInputConstraint() const;
+
+ /// getMatchedOperand - If this is an input matching constraint, this method
+ /// returns the output operand it matches.
+ unsigned getMatchedOperand() const;
+
+ /// Copy constructor for copying from an AsmOperandInfo.
+ AsmOperandInfo(const AsmOperandInfo &info)
+ : InlineAsm::ConstraintInfo(info),
+ ConstraintCode(info.ConstraintCode),
+ ConstraintType(info.ConstraintType),
+ CallOperandVal(info.CallOperandVal),
+ ConstraintVT(info.ConstraintVT) {
+ }
+
+ /// Copy constructor for copying from a ConstraintInfo.
+ AsmOperandInfo(const InlineAsm::ConstraintInfo &info)
+ : InlineAsm::ConstraintInfo(info),
+ ConstraintType(TargetLowering::C_Unknown),
+ 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(
+ AsmOperandInfo &info, const char *constraint) const;
+
+ /// ComputeConstraintToUse - Determines the constraint code and constraint
+ /// 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.
+ virtual void ComputeConstraintToUse(AsmOperandInfo &OpInfo,
+ SDValue Op,
+ SelectionDAG *DAG = 0) const;
+
+ /// getConstraintType - Given a constraint, return the type of constraint it
+ /// is for this target.
+ virtual ConstraintType getConstraintType(const std::string &Constraint) const;
+
+ /// getRegForInlineAsmConstraint - Given a physical register constraint (e.g.
+ /// {edx}), return the register number and the register class for the
+ /// register.
+ ///
+ /// Given a register class constraint, like 'r', if this corresponds directly
+ /// to an LLVM register class, return a register of 0 and the register class
+ /// pointer.
+ ///
+ /// This should only be used for C_Register constraints. On error,
+ /// this returns a register number of 0 and a null register class pointer..
+ virtual std::pair<unsigned, const TargetRegisterClass*>
+ getRegForInlineAsmConstraint(const std::string &Constraint,
+ EVT VT) const;
+
+ /// LowerXConstraint - try to replace an X constraint, which matches anything,
+ /// with another that has more specific requirements based on the type of the
+ /// corresponding operand. This returns null if there is no replacement to
+ /// make.
+ virtual const char *LowerXConstraint(EVT ConstraintVT) const;
+
+ /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
+ /// vector. If it is invalid, don't add anything to Ops.
+ virtual void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint,
+ std::vector<SDValue> &Ops,
+ SelectionDAG &DAG) const;
+
+ //===--------------------------------------------------------------------===//
+ // Div utility functions
+ //
+ SDValue BuildExactSDIV(SDValue Op1, SDValue Op2, DebugLoc dl,
+ SelectionDAG &DAG) const;
+ SDValue BuildSDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization,
+ std::vector<SDNode*> *Created) const;
+ SDValue BuildUDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization,
+ std::vector<SDNode*> *Created) const;
+
+ //===--------------------------------------------------------------------===//
+ // Instruction Emitting Hooks
+ //
+
+ // EmitInstrWithCustomInserter - This method should be implemented by targets
+ // that mark instructions with the 'usesCustomInserter' flag. These
+ // instructions are special in various ways, which require special support to
+ // insert. The specified MachineInstr is created but not inserted into any
+ // basic blocks, and this method is called to expand it into a sequence of
+ // instructions, potentially also creating new basic blocks and control flow.
+ virtual MachineBasicBlock *
+ EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const;
+
+ /// AdjustInstrPostInstrSelection - This method should be implemented by
+ /// targets that mark instructions with the 'hasPostISelHook' flag. These
+ /// instructions must be adjusted after instruction selection by target hooks.
+ /// e.g. To fill in optional defs for ARM 's' setting instructions.
+ virtual void
+ AdjustInstrPostInstrSelection(MachineInstr *MI, SDNode *Node) const;
+};
+
/// GetReturnInfo - Given an LLVM IR type and return type attributes,
/// compute the return value EVTs and flags, and optionally also
/// the offsets, if the return value is being lowered to memory.
-void GetReturnInfo(Type* ReturnType, Attributes attr,
+void GetReturnInfo(Type* ReturnType, AttributeSet attr,
SmallVectorImpl<ISD::OutputArg> &Outs,
const TargetLowering &TLI);
diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h
index 13a6fe3..9958755 100644
--- a/include/llvm/Target/TargetLoweringObjectFile.h
+++ b/include/llvm/Target/TargetLoweringObjectFile.h
@@ -15,10 +15,10 @@
#ifndef LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H
#define LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H
-#include "llvm/Module.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/IR/Module.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/SectionKind.h"
-#include "llvm/ADT/ArrayRef.h"
namespace llvm {
class MachineModuleInfo;
@@ -27,6 +27,7 @@ namespace llvm {
class MCExpr;
class MCSection;
class MCSymbol;
+ class MCSymbolRefExpr;
class MCStreamer;
class GlobalValue;
class TargetMachine;
@@ -108,13 +109,13 @@ public:
return 0;
}
- /// getExprForDwarfGlobalReference - Return an MCExpr to use for a reference
+ /// getTTypeGlobalReference - Return an MCExpr to use for a reference
/// to the specified global variable from exception handling information.
///
virtual const MCExpr *
- getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI, unsigned Encoding,
- MCStreamer &Streamer) const;
+ getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang,
+ MachineModuleInfo *MMI, unsigned Encoding,
+ MCStreamer &Streamer) const;
// getCFIPersonalitySymbol - The symbol that gets passed to .cfi_personality.
virtual MCSymbol *
@@ -123,8 +124,8 @@ public:
///
const MCExpr *
- getExprForDwarfReference(const MCSymbol *Sym, unsigned Encoding,
- MCStreamer &Streamer) const;
+ getTTypeReference(const MCSymbolRefExpr *Sym, unsigned Encoding,
+ MCStreamer &Streamer) const;
virtual const MCSection *
getStaticCtorSection(unsigned Priority = 65535) const {
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index 5006647..66f3a3c 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -14,12 +14,10 @@
#ifndef LLVM_TARGET_TARGETMACHINE_H
#define LLVM_TARGET_TARGETMACHINE_H
+#include "llvm/ADT/StringRef.h"
#include "llvm/Pass.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Target/TargetOptions.h"
-#include "llvm/TargetTransformInfo.h"
-#include "llvm/Target/TargetTransformImpl.h"
-#include "llvm/ADT/StringRef.h"
#include <cassert>
#include <string>
@@ -43,6 +41,8 @@ class TargetPassConfig;
class TargetRegisterInfo;
class TargetSelectionDAGInfo;
class TargetSubtargetInfo;
+class ScalarTargetTransformInfo;
+class VectorTargetTransformInfo;
class formatted_raw_ostream;
class raw_ostream;
@@ -59,10 +59,6 @@ protected: // Can only create subclasses.
TargetMachine(const Target &T, StringRef TargetTriple,
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.
- virtual const TargetSubtargetInfo *getSubtargetImpl() const { return 0; }
-
/// TheTarget - The Target that this machine was created for.
const Target &TheTarget;
@@ -95,7 +91,14 @@ public:
const StringRef getTargetCPU() const { return TargetCPU; }
const StringRef getTargetFeatureString() const { return TargetFS; }
- TargetOptions Options;
+ /// getSubtargetImpl - virtual method implemented by subclasses that returns
+ /// a reference to that target's TargetSubtargetInfo-derived member variable.
+ virtual const TargetSubtargetInfo *getSubtargetImpl() const { return 0; }
+
+ mutable TargetOptions Options;
+
+ /// \brief Reset the target options based on the function's attributes.
+ void resetTargetOptions(const MachineFunction *MF) const;
// Interfaces to the major aspects of target machine information:
// -- Instruction opcode and operand information
@@ -108,10 +111,6 @@ public:
virtual const TargetLowering *getTargetLowering() const { return 0; }
virtual const TargetSelectionDAGInfo *getSelectionDAGInfo() const{ return 0; }
virtual const DataLayout *getDataLayout() const { return 0; }
- virtual const ScalarTargetTransformInfo*
- getScalarTargetTransformInfo() const { return 0; }
- virtual const VectorTargetTransformInfo*
- getVectorTargetTransformInfo() const { return 0; }
/// getMCAsmInfo - Return target specific asm information.
///
@@ -232,6 +231,9 @@ public:
/// sections.
static void setFunctionSections(bool);
+ /// \brief Register analysis passes for this target with a pass manager.
+ virtual void addAnalysisPasses(PassManagerBase &) {}
+
/// CodeGenFileType - These enums are meant to be passed into
/// addPassesToEmitFile to indicate what type of file to emit, and returned by
/// it to indicate what type of file could actually be made.
@@ -290,6 +292,11 @@ protected: // Can only create subclasses.
CodeGenOpt::Level OL);
public:
+ /// \brief Register analysis passes for this target with a pass manager.
+ ///
+ /// This registers target independent analysis passes.
+ virtual void addAnalysisPasses(PassManagerBase &PM);
+
/// createPassConfig - Create a pass configuration object to be used by
/// addPassToEmitX methods for generating a pipeline of CodeGen passes.
virtual TargetPassConfig *createPassConfig(PassManagerBase &PM);
diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h
index 68ca567..c31db24 100644
--- a/include/llvm/Target/TargetOptions.h
+++ b/include/llvm/Target/TargetOptions.h
@@ -24,7 +24,7 @@ namespace llvm {
// Possible float ABI settings. Used with FloatABIType in TargetOptions.h.
namespace FloatABI {
enum ABIType {
- Default, // Target-specific (either soft or hard depending on triple, etc).
+ Default, // Target-specific (either soft or hard depending on triple,etc).
Soft, // Soft float.
Hard // Hard float.
};
@@ -48,10 +48,10 @@ namespace llvm {
UseSoftFloat(false), NoZerosInBSS(false), JITExceptionHandling(false),
JITEmitDebugInfo(false), JITEmitDebugInfoToDisk(false),
GuaranteedTailCallOpt(false), DisableTailCalls(false),
- StackAlignmentOverride(0), RealignStack(true), EnableFastISel(false),
- PositionIndependentExecutable(false), EnableSegmentedStacks(false),
- UseInitArray(false), TrapFuncName(""), FloatABIType(FloatABI::Default),
- AllowFPOpFusion(FPOpFusion::Standard)
+ StackAlignmentOverride(0), RealignStack(true), SSPBufferSize(0),
+ EnableFastISel(false), PositionIndependentExecutable(false),
+ EnableSegmentedStacks(false), UseInitArray(false), TrapFuncName(""),
+ FloatABIType(FloatABI::Default), AllowFPOpFusion(FPOpFusion::Standard)
{}
/// PrintMachineCode - This flag is enabled when the -print-machineinstrs
@@ -202,10 +202,10 @@ namespace llvm {
/// Strict mode - allow fusion only if/when it can be proven that the excess
/// precision won't effect the result.
///
- /// Note: This option only controls formation of fused ops by the optimizers.
- /// Fused operations that are explicitly specified (e.g. FMA via the
- /// llvm.fma.* intrinsic) will always be honored, regardless of the value of
- /// this option.
+ /// Note: This option only controls formation of fused ops by the
+ /// optimizers. Fused operations that are explicitly specified (e.g. FMA
+ /// via the llvm.fma.* intrinsic) will always be honored, regardless of
+ /// the value of this option.
FPOpFusion::FPOpFusionMode AllowFPOpFusion;
};
diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h
index afa2ee2..6b1e70b 100644
--- a/include/llvm/Target/TargetRegisterInfo.h
+++ b/include/llvm/Target/TargetRegisterInfo.h
@@ -16,11 +16,11 @@
#ifndef LLVM_TARGET_TARGETREGISTERINFO_H
#define LLVM_TARGET_TARGETREGISTERINFO_H
-#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/ValueTypes.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/CallingConv.h"
+#include "llvm/IR/CallingConv.h"
+#include "llvm/MC/MCRegisterInfo.h"
#include <cassert>
#include <functional>
@@ -30,12 +30,13 @@ class BitVector;
class MachineFunction;
class RegScavenger;
template<class T> class SmallVectorImpl;
+class VirtRegMap;
class raw_ostream;
class TargetRegisterClass {
public:
- typedef const uint16_t* iterator;
- typedef const uint16_t* const_iterator;
+ typedef const MCPhysReg* iterator;
+ typedef const MCPhysReg* const_iterator;
typedef const MVT::SimpleValueType* vt_iterator;
typedef const TargetRegisterClass* const * sc_iterator;
@@ -45,7 +46,7 @@ public:
const uint32_t *SubClassMask;
const uint16_t *SuperRegIndices;
const sc_iterator SuperClasses;
- ArrayRef<uint16_t> (*OrderFunc)(const MachineFunction&);
+ ArrayRef<MCPhysReg> (*OrderFunc)(const MachineFunction&);
/// getID() - Return the register class ID number.
///
@@ -190,7 +191,7 @@ public:
///
/// By default, this method returns all registers in the class.
///
- ArrayRef<uint16_t> getRawAllocationOrder(const MachineFunction &MF) const {
+ ArrayRef<MCPhysReg> getRawAllocationOrder(const MachineFunction &MF) const {
return OrderFunc ? OrderFunc(MF) : makeArrayRef(begin(), getNumRegs());
}
};
@@ -387,27 +388,12 @@ public:
return false;
}
- /// isSubRegister - Returns true if regB is a sub-register of regA.
- ///
- bool isSubRegister(unsigned regA, unsigned regB) const {
- return isSuperRegister(regB, regA);
- }
-
- /// isSuperRegister - Returns true if regB is a super-register of regA.
- ///
- bool isSuperRegister(unsigned RegA, unsigned RegB) const {
- for (MCSuperRegIterator I(RegA, this); I.isValid(); ++I)
- if (*I == RegB)
- return true;
- return false;
- }
-
/// 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
/// closest to the incoming stack pointer if stack grows down, and vice versa.
///
- virtual const uint16_t* getCalleeSavedRegs(const MachineFunction *MF = 0)
+ virtual const MCPhysReg* getCalleeSavedRegs(const MachineFunction *MF = 0)
const = 0;
/// getCallPreservedMask - Return a mask of call-preserved registers for the
@@ -594,10 +580,13 @@ public:
return 0;
}
-// Get the weight in units of pressure for this register class.
+ /// Get the weight in units of pressure for this register class.
virtual const RegClassWeight &getRegClassWeight(
const TargetRegisterClass *RC) const = 0;
+ /// Get the weight in units of pressure for this register unit.
+ virtual unsigned getRegUnitWeight(unsigned RegUnit) const = 0;
+
/// Get the number of dimensions of register pressure.
virtual unsigned getNumRegPressureSets() const = 0;
@@ -613,27 +602,29 @@ public:
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<uint16_t>
- getRawAllocationOrder(const TargetRegisterClass *RC,
- unsigned HintType, unsigned HintReg,
- const MachineFunction &MF) const {
- return RC->getRawAllocationOrder(MF);
- }
-
- /// ResolveRegAllocHint - Resolves the specified register allocation hint
- /// to a physical register. Returns the physical register if it is successful.
- virtual unsigned ResolveRegAllocHint(unsigned Type, unsigned Reg,
- const MachineFunction &MF) const {
- if (Type == 0 && Reg && isPhysicalRegister(Reg))
- return Reg;
- return 0;
- }
+ /// Get the dimensions of register pressure impacted by this register unit.
+ /// Returns a -1 terminated array of pressure set IDs.
+ virtual const int *getRegUnitPressureSets(unsigned RegUnit) const = 0;
+
+ /// Get a list of 'hint' registers that the register allocator should try
+ /// first when allocating a physical register for the virtual register
+ /// VirtReg. These registers are effectively moved to the front of the
+ /// allocation order.
+ ///
+ /// The Order argument is the allocation order for VirtReg's register class
+ /// as returned from RegisterClassInfo::getOrder(). The hint registers must
+ /// come from Order, and they must not be reserved.
+ ///
+ /// The default implementation of this function can resolve
+ /// target-independent hints provided to MRI::setRegAllocationHint with
+ /// HintType == 0. Targets that override this function should defer to the
+ /// default implementation if they have no reason to change the allocation
+ /// order for VirtReg. There may be target-independent hints.
+ virtual void getRegAllocationHints(unsigned VirtReg,
+ ArrayRef<MCPhysReg> Order,
+ SmallVectorImpl<MCPhysReg> &Hints,
+ const MachineFunction &MF,
+ const VirtRegMap *VRM = 0) const;
/// avoidWriteAfterWrite - Return true if the register allocator should avoid
/// writing a register from RC in two consecutive instructions.
@@ -742,21 +733,6 @@ public:
llvm_unreachable("isFrameOffsetLegal does not exist on this target");
}
- /// eliminateCallFramePseudoInstr - This method is called during prolog/epilog
- /// code insertion to eliminate call frame setup and destroy pseudo
- /// instructions (but only if the Target is using them). It is responsible
- /// for eliminating these instructions, replacing them with concrete
- /// instructions. This method need only be implemented if using call frame
- /// setup/destroy pseudo instructions.
- ///
- virtual void
- eliminateCallFramePseudoInstr(MachineFunction &MF,
- MachineBasicBlock &MBB,
- MachineBasicBlock::iterator MI) const {
- llvm_unreachable("Call Frame Pseudo Instructions do not exist on this "
- "target!");
- }
-
/// saveScavengerRegister - Spill the register so it can be used by the
/// register scavenger. Return true if the register was spilled, false
@@ -776,10 +752,11 @@ public:
/// referenced by the iterator contains an MO_FrameIndex operand which must be
/// eliminated by this method. This method may modify or replace the
/// specified instruction, as long as it keeps the iterator pointing at the
- /// finished product. SPAdj is the SP adjustment due to call frame setup
- /// instruction.
+ /// finished product. SPAdj is the SP adjustment due to call frame setup
+ /// instruction. FIOperandNum is the FI operand number.
virtual void eliminateFrameIndex(MachineBasicBlock::iterator MI,
- int SPAdj, RegScavenger *RS=NULL) const = 0;
+ int SPAdj, unsigned FIOperandNum,
+ RegScavenger *RS = NULL) const = 0;
//===--------------------------------------------------------------------===//
/// Debug information queries.
@@ -876,7 +853,8 @@ class PrintReg {
unsigned Reg;
unsigned SubIdx;
public:
- PrintReg(unsigned reg, const TargetRegisterInfo *tri = 0, unsigned subidx = 0)
+ explicit PrintReg(unsigned reg, const TargetRegisterInfo *tri = 0,
+ unsigned subidx = 0)
: TRI(tri), Reg(reg), SubIdx(subidx) {}
void print(raw_ostream&) const;
};
diff --git a/include/llvm/Target/TargetSchedule.td b/include/llvm/Target/TargetSchedule.td
index 0da82fd..660d2c4 100644
--- a/include/llvm/Target/TargetSchedule.td
+++ b/include/llvm/Target/TargetSchedule.td
@@ -76,6 +76,7 @@ class SchedMachineModel {
int IssueWidth = -1; // Max micro-ops that may be scheduled per cycle.
int MinLatency = -1; // Determines which instrucions are allowed in a group.
// (-1) inorder (0) ooo, (1): inorder +var latencies.
+ int ILPWindow = -1; // Cycles of latency likely hidden by hardware buffers.
int LoadLatency = -1; // Cycles for loads to access the cache.
int HighLatency = -1; // Approximation of cycles for "high latency" ops.
int MispredictPenalty = -1; // Extra cycles for a mispredicted branch.
@@ -132,6 +133,11 @@ def EponymousProcResourceKind : ProcResourceKind;
class ProcResource<int num> : ProcResourceKind,
ProcResourceUnits<EponymousProcResourceKind, num>;
+class ProcResGroup<list<ProcResource> resources> : ProcResourceKind {
+ list<ProcResource> Resources = resources;
+ SchedMachineModel SchedModel = ?;
+}
+
// A target architecture may define SchedReadWrite types and associate
// them with instruction operands.
class SchedReadWrite;
diff --git a/include/llvm/Target/TargetSubtargetInfo.h b/include/llvm/Target/TargetSubtargetInfo.h
index 6db96d9..b2d405d 100644
--- a/include/llvm/Target/TargetSubtargetInfo.h
+++ b/include/llvm/Target/TargetSubtargetInfo.h
@@ -19,6 +19,7 @@
namespace llvm {
+class MachineFunction;
class MachineInstr;
class SDep;
class SUnit;
@@ -54,6 +55,13 @@ public:
return 0;
}
+ /// \brief True if the subtarget should run MachineScheduler after aggressive
+ /// coalescing.
+ ///
+ /// This currently replaces the SelectionDAG scheduler with the "source" order
+ /// scheduler. It does not yet disable the postRA scheduler.
+ virtual bool enableMachineScheduler() const;
+
// enablePostRAScheduler - If the target can benefit from post-regalloc
// scheduling and the specified optimization level meets the requirement
// return true to enable post-register-allocation scheduling. In
@@ -66,6 +74,9 @@ public:
// the latency of a schedule dependency.
virtual void adjustSchedDependency(SUnit *def, SUnit *use,
SDep& dep) const { }
+
+ /// \brief Reset the features for the subtarget.
+ virtual void resetSubtargetFeatures(const MachineFunction *MF) { }
};
} // End llvm namespace
diff --git a/include/llvm/Target/TargetTransformImpl.h b/include/llvm/Target/TargetTransformImpl.h
deleted file mode 100644
index 7ea2396..0000000
--- a/include/llvm/Target/TargetTransformImpl.h
+++ /dev/null
@@ -1,98 +0,0 @@
-//=- llvm/Target/TargetTransformImpl.h - Target Loop Trans Info----*- C++ -*-=//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains the target-specific implementations of the
-// TargetTransform interfaces.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TARGET_TARGET_TRANSFORMATION_IMPL_H
-#define LLVM_TARGET_TARGET_TRANSFORMATION_IMPL_H
-
-#include "llvm/TargetTransformInfo.h"
-#include "llvm/CodeGen/ValueTypes.h"
-
-namespace llvm {
-
-class TargetLowering;
-
-/// ScalarTargetTransformInfo - This is a default implementation for the
-/// ScalarTargetTransformInfo interface. Different targets can implement
-/// this interface differently.
-class ScalarTargetTransformImpl : public ScalarTargetTransformInfo {
-private:
- const TargetLowering *TLI;
-
-public:
- /// Ctor
- explicit ScalarTargetTransformImpl(const TargetLowering *TL) : TLI(TL) {}
-
- virtual bool isLegalAddImmediate(int64_t imm) const;
-
- virtual bool isLegalICmpImmediate(int64_t imm) const;
-
- virtual bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) const;
-
- virtual bool isTruncateFree(Type *Ty1, Type *Ty2) const;
-
- virtual bool isTypeLegal(Type *Ty) const;
-
- virtual unsigned getJumpBufAlignment() const;
-
- virtual unsigned getJumpBufSize() const;
-
- virtual bool shouldBuildLookupTables() const;
-};
-
-class VectorTargetTransformImpl : public VectorTargetTransformInfo {
-protected:
- const TargetLowering *TLI;
-
- /// Estimate the cost of type-legalization and the legalized type.
- std::pair<unsigned, MVT> getTypeLegalizationCost(Type *Ty) const;
-
- /// Estimate the overhead of scalarizing an instruction. Insert and Extract
- /// are set if the result needs to be inserted and/or extracted from vectors.
- unsigned getScalarizationOverhead(Type *Ty, bool Insert, bool Extract) const;
-
- // Get the ISD node that corresponds to the Instruction class opcode.
- int InstructionOpcodeToISD(unsigned Opcode) const;
-
-public:
- explicit VectorTargetTransformImpl(const TargetLowering *TL) : TLI(TL) {}
-
- virtual ~VectorTargetTransformImpl() {}
-
- virtual unsigned getInstrCost(unsigned Opcode, Type *Ty1, Type *Ty2) const;
-
- virtual unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty) const;
-
- virtual unsigned getBroadcastCost(Type *Tp) const;
-
- virtual unsigned getCastInstrCost(unsigned Opcode, Type *Dst,
- Type *Src) const;
-
- virtual unsigned getCFInstrCost(unsigned Opcode) const;
-
- virtual unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy,
- Type *CondTy) const;
-
- virtual unsigned getVectorInstrCost(unsigned Opcode, Type *Val,
- unsigned Index) const;
-
- virtual unsigned getMemoryOpCost(unsigned Opcode, Type *Src,
- unsigned Alignment,
- unsigned AddressSpace) const;
-
- virtual unsigned getNumberOfParts(Type *Tp) const;
-};
-
-} // end llvm namespace
-
-#endif
OpenPOWER on IntegriCloud