diff options
author | dim <dim@FreeBSD.org> | 2010-09-17 15:48:55 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2010-09-17 15:48:55 +0000 |
commit | 5d5cc59cc77afe655b3707cb0e69e0827b444cad (patch) | |
tree | 36453626c792cccd91f783a38a169d610a6b9db9 /include/llvm/CodeGen | |
parent | 786a18553586229ad99ecb5ecde8a9d914c45e27 (diff) | |
download | FreeBSD-src-5d5cc59cc77afe655b3707cb0e69e0827b444cad.zip FreeBSD-src-5d5cc59cc77afe655b3707cb0e69e0827b444cad.tar.gz |
Vendor import of llvm r114020 (from the release_28 branch):
http://llvm.org/svn/llvm-project/llvm/branches/release_28@114020
Approved by: rpaulo (mentor)
Diffstat (limited to 'include/llvm/CodeGen')
22 files changed, 384 insertions, 191 deletions
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index 7ca6c62..b018603 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -54,6 +54,7 @@ namespace llvm { class Mangler; class TargetLoweringObjectFile; class TargetData; + class TargetMachine; class Twine; class Type; @@ -296,7 +297,7 @@ namespace llvm { MCSymbol *GetBlockAddressSymbol(const BlockAddress *BA) const; MCSymbol *GetBlockAddressSymbol(const BasicBlock *BB) const; - //===------------------------------------------------------------------===// + //===------------------------------------------------------------------===// // Emission Helper Routines. //===------------------------------------------------------------------===// public: @@ -327,6 +328,12 @@ namespace llvm { void EmitLabelOffsetDifference(const MCSymbol *Hi, uint64_t Offset, const MCSymbol *Lo, unsigned Size) const; + /// EmitLabelPlusOffset - Emit something like ".long Label+Offset" + /// where the size in bytes of the directive is specified by Size and Label + /// specifies the label. This implicitly uses .set if it is available. + void EmitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset, + unsigned Size) const; + //===------------------------------------------------------------------===// // Dwarf Emission Helper Routines //===------------------------------------------------------------------===// @@ -369,6 +376,10 @@ namespace llvm { /// operands. virtual MachineLocation getDebugValueLocation(const MachineInstr *MI) const; + /// getISAEncoding - Get the value for DW_AT_APPLE_isa. Zero if no isa + /// encoding specified. + virtual unsigned getISAEncoding() { return 0; } + //===------------------------------------------------------------------===// // Dwarf Lowering Routines //===------------------------------------------------------------------===// diff --git a/include/llvm/CodeGen/CalcSpillWeights.h b/include/llvm/CodeGen/CalcSpillWeights.h index 2fc03bd..240734f 100644 --- a/include/llvm/CodeGen/CalcSpillWeights.h +++ b/include/llvm/CodeGen/CalcSpillWeights.h @@ -12,10 +12,35 @@ #define LLVM_CODEGEN_CALCSPILLWEIGHTS_H #include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/ADT/DenseMap.h" namespace llvm { class LiveInterval; + class LiveIntervals; + class MachineLoopInfo; + + /// VirtRegAuxInfo - Calculate auxiliary information for a virtual + /// register such as its spill weight and allocation hint. + class VirtRegAuxInfo { + MachineFunction &mf_; + LiveIntervals &lis_; + const MachineLoopInfo &loops_; + DenseMap<unsigned, float> hint_; + public: + VirtRegAuxInfo(MachineFunction &mf, LiveIntervals &lis, + const MachineLoopInfo &loops) : + mf_(mf), lis_(lis), loops_(loops) {} + + /// CalculateRegClass - recompute the register class for reg from its uses. + /// Since the register class can affect the allocation hint, this function + /// should be called before CalculateWeightAndHint if both are called. + void CalculateRegClass(unsigned reg); + + /// CalculateWeightAndHint - (re)compute li's spill weight and allocation + /// hint. + void CalculateWeightAndHint(LiveInterval &li); + }; /// CalculateSpillWeights - Compute spill weights for all virtual register /// live intervals. @@ -23,11 +48,11 @@ namespace llvm { public: static char ID; - CalculateSpillWeights() : MachineFunctionPass(&ID) {} + CalculateSpillWeights() : MachineFunctionPass(ID) {} virtual void getAnalysisUsage(AnalysisUsage &au) const; - virtual bool runOnMachineFunction(MachineFunction &fn); + virtual bool runOnMachineFunction(MachineFunction &fn); private: /// Returns true if the given live interval is zero length. diff --git a/include/llvm/CodeGen/CallingConvLower.h b/include/llvm/CodeGen/CallingConvLower.h index 7911907..6fb8436 100644 --- a/include/llvm/CodeGen/CallingConvLower.h +++ b/include/llvm/CodeGen/CallingConvLower.h @@ -275,6 +275,12 @@ public: return Result; } + /// Version of AllocateStack with extra register to be shadowed. + unsigned AllocateStack(unsigned Size, unsigned Align, unsigned ShadowReg) { + MarkAllocated(ShadowReg); + return AllocateStack(Size, Align); + } + // HandleByVal - Allocate a stack slot large enough to pass an argument by // value. The size and alignment information of the argument is encoded in its // parameter attribute. diff --git a/include/llvm/CodeGen/FunctionLoweringInfo.h b/include/llvm/CodeGen/FunctionLoweringInfo.h index c49d1ed..f17fe5a 100644 --- a/include/llvm/CodeGen/FunctionLoweringInfo.h +++ b/include/llvm/CodeGen/FunctionLoweringInfo.h @@ -77,6 +77,9 @@ public: /// anywhere in the function. DenseMap<const AllocaInst*, int> StaticAllocaMap; + /// ByValArgFrameIndexMap - Keep track of frame indices for byval arguments. + DenseMap<const Argument*, int> ByValArgFrameIndexMap; + /// ArgDbgValues - A list of DBG_VALUE instructions created during isel for /// function arguments that are inserted after scheduling is completed. SmallVector<MachineInstr*, 8> ArgDbgValues; @@ -138,6 +141,13 @@ public: assert(R == 0 && "Already initialized this value register!"); return R = CreateRegs(V->getType()); } + + /// setByValArgumentFrameIndex - Record frame index for the byval + /// argument. + void setByValArgumentFrameIndex(const Argument *A, int FI); + + /// getByValArgumentFrameIndex - Get frame index for the byval argument. + int getByValArgumentFrameIndex(const Argument *A); }; /// AddCatchInfo - Extract the personality and type infos from an eh.selector diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h index 69de598..2e23f4e 100644 --- a/include/llvm/CodeGen/ISDOpcodes.h +++ b/include/llvm/CodeGen/ISDOpcodes.h @@ -603,7 +603,7 @@ namespace ISD { /// which do not reference a specific memory location should be less than /// this value. Those that do must not be less than this value, and can /// be used with SelectionDAG::getMemIntrinsicNode. - static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END+100; + static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END+150; //===--------------------------------------------------------------------===// /// MemIndexedMode enum - This enum defines the load / store indexed @@ -633,7 +633,6 @@ namespace ISD { /// (the result of the load and the result of the base +/- offset /// computation); a post-indexed store produces one value (the /// the result of the base +/- offset computation). - /// enum MemIndexedMode { UNINDEXED = 0, PRE_INC, @@ -651,10 +650,8 @@ namespace ISD { /// integer result type. /// ZEXTLOAD loads the integer operand and zero extends it to a larger /// integer result type. - /// EXTLOAD is used for three things: floating point extending loads, - /// integer extending loads [the top bits are undefined], and vector - /// extending loads [load into low elt]. - /// + /// EXTLOAD is used for two things: floating point extending loads and + /// integer extending loads [the top bits are undefined]. enum LoadExtType { NON_EXTLOAD = 0, EXTLOAD, diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h index 8d80efb..29e689a 100644 --- a/include/llvm/CodeGen/LiveInterval.h +++ b/include/llvm/CodeGen/LiveInterval.h @@ -39,7 +39,7 @@ namespace llvm { /// This class holds information about a machine level values, including /// definition and use points. /// - /// Care must be taken in interpreting the def index of the value. The + /// Care must be taken in interpreting the def index of the value. The /// following rules apply: /// /// If the isDefAccurate() method returns false then def does not contain the @@ -108,7 +108,7 @@ namespace llvm { /// For a stack interval, returns the reg which this stack interval was /// defined from. - /// For a register interval the behaviour of this method is undefined. + /// For a register interval the behaviour of this method is undefined. unsigned getReg() const { return cr.reg; } /// For a stack interval, set the defining register. /// This method should not be called on register intervals as it may lead @@ -189,7 +189,7 @@ namespace llvm { } /// containsRange - Return true if the given range, [S, E), is covered by - /// this range. + /// this range. bool containsRange(SlotIndex S, SlotIndex E) const { assert((S < E) && "Backwards interval?"); return (start <= S && S < end) && (start < E && E <= end); @@ -236,7 +236,7 @@ namespace llvm { float weight; // weight of this interval Ranges ranges; // the ranges in which this register is live VNInfoList valnos; // value#'s - + struct InstrSlots { enum { LOAD = 0, @@ -281,7 +281,7 @@ namespace llvm { while (I->end <= Pos) ++I; return I; } - + void clear() { valnos.clear(); ranges.clear(); @@ -305,7 +305,7 @@ namespace llvm { bool containsOneValue() const { return valnos.size() == 1; } unsigned getNumValNums() const { return (unsigned)valnos.size(); } - + /// getValNumInfo - Returns pointer to the specified val#. /// inline VNInfo *getValNumInfo(unsigned ValNo) { @@ -336,6 +336,11 @@ namespace llvm { return VNI; } + /// RenumberValues - Renumber all values in order of appearance and remove + /// unused values. + /// Recalculate phi-kill flags in case any phi-def values were removed. + void RenumberValues(LiveIntervals &lis); + /// isOnlyLROfValNo - Return true if the specified live range is the only /// one defined by the its val#. bool isOnlyLROfValNo(const LiveRange *LR) { @@ -346,7 +351,7 @@ namespace llvm { } return true; } - + /// MergeValueNumberInto - This method is called when two value nubmers /// are found to be equivalent. This eliminates V1, replacing all /// LiveRanges with the V1 value number with the V2 value number. This can @@ -387,7 +392,7 @@ namespace llvm { /// except for the register of the interval. void Copy(const LiveInterval &RHS, MachineRegisterInfo *MRI, VNInfo::Allocator &VNInfoAllocator); - + bool empty() const { return ranges.empty(); } /// beginIndex - Return the lowest numbered slot covered by interval. @@ -454,17 +459,19 @@ namespace llvm { iterator FindLiveRangeContaining(SlotIndex Idx); /// findDefinedVNInfo - Find the by the specified - /// index (register interval) or defined + /// index (register interval) or defined VNInfo *findDefinedVNInfoForRegInt(SlotIndex Idx) const; /// findDefinedVNInfo - Find the VNInfo that's defined by the specified /// register (stack inteval only). VNInfo *findDefinedVNInfoForStackInt(unsigned Reg) const; - + /// overlaps - Return true if the intersection of the two live intervals is /// not empty. bool overlaps(const LiveInterval& other) const { + if (other.empty()) + return false; return overlapsFrom(other, other.begin()); } @@ -514,6 +521,15 @@ namespace llvm { /// unsigned getSize() const; + /// Returns true if the live interval is zero length, i.e. no live ranges + /// span instructions. It doesn't pay to spill such an interval. + bool isZeroLength() const { + for (const_iterator i = begin(), e = end(); i != e; ++i) + if (i->end.getPrevIndex() > i->start) + return false; + return true; + } + /// isSpillable - Can this interval be spilled? bool isSpillable() const { return weight != HUGE_VALF; @@ -543,6 +559,7 @@ namespace llvm { Ranges::iterator addRangeFrom(LiveRange LR, Ranges::iterator From); void extendIntervalEndTo(Ranges::iterator I, SlotIndex NewEnd); Ranges::iterator extendIntervalStartTo(Ranges::iterator I, SlotIndex NewStr); + void markValNoForDeletion(VNInfo *V); LiveInterval& operator=(const LiveInterval& rhs); // DO NOT IMPLEMENT diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h index c136048..2918c3c2a 100644 --- a/include/llvm/CodeGen/LiveIntervalAnalysis.h +++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -42,7 +42,7 @@ namespace llvm { class TargetInstrInfo; class TargetRegisterClass; class VirtRegMap; - + class LiveIntervals : public MachineFunctionPass { MachineFunction* mf_; MachineRegisterInfo* mri_; @@ -68,7 +68,7 @@ namespace llvm { public: static char ID; // Pass identification, replacement for typeid - LiveIntervals() : MachineFunctionPass(&ID) {} + LiveIntervals() : MachineFunctionPass(ID) {} // Calculate the spill weight to assign to a single instruction. static float getSpillWeight(bool isDef, bool isUse, unsigned loopDepth); @@ -105,6 +105,12 @@ namespace llvm { return r2iMap_.count(reg); } + /// isAllocatable - is the physical register reg allocatable in the current + /// function? + bool isAllocatable(unsigned reg) const { + return allocatableRegs_.test(reg); + } + /// getScaledIntervalSize - get the size of an interval in "units," /// where every function is composed of one thousand units. This /// measure scales properly with empty index slots in the function. @@ -117,7 +123,7 @@ namespace llvm { unsigned getFuncInstructionCount() { return indexes_->getFunctionSize(); } - + /// getApproximateInstructionCount - computes an estimate of the number /// of instructions in a given LiveInterval. unsigned getApproximateInstructionCount(LiveInterval& I) { @@ -149,7 +155,7 @@ namespace llvm { /// dupInterval - Duplicate a live interval. The caller is responsible for /// managing the allocated memory. LiveInterval *dupInterval(LiveInterval *li); - + /// addLiveRangeToEndOfBlock - Given a register and an instruction, /// adds a live range from that instruction to the end of its MBB. LiveRange addLiveRangeToEndOfBlock(unsigned reg, @@ -181,7 +187,7 @@ namespace llvm { SlotIndex getInstructionIndex(const MachineInstr *instr) const { return indexes_->getInstructionIndex(instr); } - + /// Returns the instruction associated with the given index. MachineInstr* getInstructionFromIndex(SlotIndex index) const { return indexes_->getInstructionFromIndex(index); @@ -190,12 +196,32 @@ namespace llvm { /// Return the first index in the given basic block. SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const { return indexes_->getMBBStartIdx(mbb); - } + } /// Return the last index in the given basic block. SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const { return indexes_->getMBBEndIdx(mbb); - } + } + + bool isLiveInToMBB(const LiveInterval &li, + const MachineBasicBlock *mbb) const { + return li.liveAt(getMBBStartIdx(mbb)); + } + + LiveRange* findEnteringRange(LiveInterval &li, + const MachineBasicBlock *mbb) { + return li.getLiveRangeContaining(getMBBStartIdx(mbb)); + } + + bool isLiveOutOfMBB(const LiveInterval &li, + const MachineBasicBlock *mbb) const { + return li.liveAt(getMBBEndIdx(mbb).getPrevSlot()); + } + + LiveRange* findExitingRange(LiveInterval &li, + const MachineBasicBlock *mbb) { + return li.getLiveRangeContaining(getMBBEndIdx(mbb).getPrevSlot()); + } MachineBasicBlock* getMBBFromIndex(SlotIndex index) const { return indexes_->getMBBFromIndex(index); @@ -217,6 +243,10 @@ namespace llvm { indexes_->replaceMachineInstrInMaps(MI, NewMI); } + void InsertMBBInMaps(MachineBasicBlock *MBB) { + indexes_->insertMBBInMaps(MBB); + } + bool findLiveInMBBs(SlotIndex Start, SlotIndex End, SmallVectorImpl<MachineBasicBlock*> &MBBs) const { return indexes_->findLiveInMBBs(Start, End, MBBs); @@ -276,7 +306,7 @@ namespace llvm { /// within a single basic block. bool intervalIsInOneMBB(const LiveInterval &li) const; - private: + private: /// computeIntervals - Compute live intervals. void computeIntervals(); @@ -290,7 +320,7 @@ namespace llvm { /// isPartialRedef - Return true if the specified def at the specific index /// is partially re-defining the specified live interval. A common case of - /// this is a definition of the sub-register. + /// this is a definition of the sub-register. bool isPartialRedef(SlotIndex MIIdx, MachineOperand &MO, LiveInterval &interval); diff --git a/include/llvm/CodeGen/LiveStackAnalysis.h b/include/llvm/CodeGen/LiveStackAnalysis.h index c6af6a1..ad984db 100644 --- a/include/llvm/CodeGen/LiveStackAnalysis.h +++ b/include/llvm/CodeGen/LiveStackAnalysis.h @@ -39,7 +39,7 @@ namespace llvm { public: static char ID; // Pass identification, replacement for typeid - LiveStacks() : MachineFunctionPass(&ID) {} + LiveStacks() : MachineFunctionPass(ID) {} typedef SS2IntervalMap::iterator iterator; typedef SS2IntervalMap::const_iterator const_iterator; diff --git a/include/llvm/CodeGen/LiveVariables.h b/include/llvm/CodeGen/LiveVariables.h index fc5ea6f..c8182e0 100644 --- a/include/llvm/CodeGen/LiveVariables.h +++ b/include/llvm/CodeGen/LiveVariables.h @@ -46,7 +46,7 @@ class TargetRegisterInfo; class LiveVariables : public MachineFunctionPass { public: static char ID; // Pass identification, replacement for typeid - LiveVariables() : MachineFunctionPass(&ID) {} + LiveVariables() : MachineFunctionPass(ID) {} /// VarInfo - This represents the regions where a virtual register is live in /// the program. We represent this with three different pieces of diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h index 9471316..dca65ef 100644 --- a/include/llvm/CodeGen/MachineFrameInfo.h +++ b/include/llvm/CodeGen/MachineFrameInfo.h @@ -15,6 +15,7 @@ #define LLVM_CODEGEN_MACHINEFRAMEINFO_H #include "llvm/ADT/SmallVector.h" +//#include "llvm/ADT/IndexedMap.h" #include "llvm/System/DataTypes.h" #include <cassert> #include <vector> @@ -30,15 +31,15 @@ class TargetFrameInfo; class BitVector; /// The CalleeSavedInfo class tracks the information need to locate where a -/// callee saved register in the current frame. +/// callee saved register is in the current frame. class CalleeSavedInfo { unsigned Reg; int FrameIdx; - + public: explicit CalleeSavedInfo(unsigned R, int FI = 0) : Reg(R), FrameIdx(FI) {} - + // Accessors. unsigned getReg() const { return Reg; } int getFrameIdx() const { return FrameIdx; } @@ -81,7 +82,7 @@ class MachineFrameInfo { // SPOffset - The offset of this object from the stack pointer on entry to // the function. This field has no meaning for a variable sized element. int64_t SPOffset; - + // The size of this object on the stack. 0 means a variable sized object, // ~0ULL means a dead object. uint64_t Size; @@ -94,13 +95,23 @@ class MachineFrameInfo { // default, fixed objects are immutable unless marked otherwise. bool isImmutable; - // isSpillSlot - If true, the stack object is used as spill slot. It + // isSpillSlot - If true the stack object is used as spill slot. It // cannot alias any other memory objects. bool isSpillSlot; - StackObject(uint64_t Sz, unsigned Al, int64_t SP, bool IM, bool isSS) + // MayNeedSP - If true the stack object triggered the creation of the stack + // protector. We should allocate this object right after the stack + // protector. + bool MayNeedSP; + + // PreAllocated - If true, the object was mapped into the local frame + // block and doesn't need additional handling for allocation beyond that. + bool PreAllocated; + + StackObject(uint64_t Sz, unsigned Al, int64_t SP, bool IM, + bool isSS, bool NSP) : SPOffset(SP), Size(Sz), Alignment(Al), isImmutable(IM), - isSpillSlot(isSS) {} + isSpillSlot(isSS), MayNeedSP(NSP), PreAllocated(false) {} }; /// Objects - The list of stack objects allocated... @@ -132,7 +143,7 @@ class MachineFrameInfo { /// to be allocated on entry to the function. /// uint64_t StackSize; - + /// OffsetAdjustment - The amount that a frame offset needs to be adjusted to /// have the actual offset from the stack/frame pointer. The exact usage of /// this is target-dependent, but it is typically used to adjust between @@ -143,10 +154,10 @@ class MachineFrameInfo { /// TargetRegisterInfo::getFrameIndexOffset); when generating code, the /// corresponding adjustments are performed directly. int OffsetAdjustment; - - /// MaxAlignment - The prolog/epilog code inserter may process objects + + /// MaxAlignment - The prolog/epilog code inserter may process objects /// that require greater alignment than the default alignment the target - /// provides. To handle this, MaxAlignment is set to the maximum alignment + /// provides. To handle this, MaxAlignment is set to the maximum alignment /// needed by the objects on the current frame. If this is greater than the /// native alignment maintained by the compiler, dynamic alignment code will /// be needed. @@ -171,7 +182,7 @@ class MachineFrameInfo { /// insertion. /// unsigned MaxCallFrameSize; - + /// CSInfo - The prolog/epilog code inserter fills in this vector with each /// callee saved register saved in the frame. Beyond its use by the prolog/ /// epilog code inserter, this data used for debug info and exception @@ -189,8 +200,24 @@ class MachineFrameInfo { /// const TargetFrameInfo &TFI; + /// LocalFrameObjects - References to frame indices which are mapped + /// into the local frame allocation block. <FrameIdx, LocalOffset> + SmallVector<std::pair<int, int64_t>, 32> LocalFrameObjects; + + /// LocalFrameSize - Size of the pre-allocated local frame block. + int64_t LocalFrameSize; + + /// Required alignment of the local object blob, which is the strictest + /// alignment of any object in it. + unsigned LocalFrameMaxAlign; + + /// Whether the local object blob needs to be allocated together. If not, + /// PEI should ignore the isPreAllocated flags on the stack objects and + /// just allocate them normally. + bool UseLocalStackAllocationBlock; + public: - explicit MachineFrameInfo(const TargetFrameInfo &tfi) : TFI(tfi) { + explicit MachineFrameInfo(const TargetFrameInfo &tfi) : TFI(tfi) { StackSize = NumFixedObjects = OffsetAdjustment = MaxAlignment = 0; HasVarSizedObjects = false; FrameAddressTaken = false; @@ -200,6 +227,9 @@ public: StackProtectorIdx = -1; MaxCallFrameSize = 0; CSIValid = false; + LocalFrameSize = 0; + LocalFrameMaxAlign = 0; + UseLocalStackAllocationBlock = false; } /// hasStackObjects - Return true if there are any stack objects in this @@ -225,8 +255,8 @@ public: bool isFrameAddressTaken() const { return FrameAddressTaken; } void setFrameAddressIsTaken(bool T) { FrameAddressTaken = T; } - /// isReturnAddressTaken - This method may be called any time after instruction - /// selection is complete to determine if there is a call to + /// isReturnAddressTaken - This method may be called any time after + /// instruction selection is complete to determine if there is a call to /// \@llvm.returnaddress in this function. bool isReturnAddressTaken() const { return ReturnAddressTaken; } void setReturnAddressIsTaken(bool s) { ReturnAddressTaken = s; } @@ -239,13 +269,64 @@ public: /// int getObjectIndexEnd() const { return (int)Objects.size()-NumFixedObjects; } - /// getNumFixedObjects() - Return the number of fixed objects. + /// getNumFixedObjects - Return the number of fixed objects. unsigned getNumFixedObjects() const { return NumFixedObjects; } - /// getNumObjects() - Return the number of objects. + /// getNumObjects - Return the number of objects. /// unsigned getNumObjects() const { return Objects.size(); } + /// mapLocalFrameObject - Map a frame index into the local object block + void mapLocalFrameObject(int ObjectIndex, int64_t Offset) { + LocalFrameObjects.push_back(std::pair<int, int64_t>(ObjectIndex, Offset)); + Objects[ObjectIndex + NumFixedObjects].PreAllocated = true; + } + + /// getLocalFrameObjectMap - Get the local offset mapping for a for an object + std::pair<int, int64_t> getLocalFrameObjectMap(int i) { + assert (i >= 0 && (unsigned)i < LocalFrameObjects.size() && + "Invalid local object reference!"); + return LocalFrameObjects[i]; + } + + /// getLocalFrameObjectCount - Return the number of objects allocated into + /// the local object block. + int64_t getLocalFrameObjectCount() { return LocalFrameObjects.size(); } + + /// setLocalFrameSize - Set the size of the local object blob. + void setLocalFrameSize(int64_t sz) { LocalFrameSize = sz; } + + /// getLocalFrameSize - Get the size of the local object blob. + int64_t getLocalFrameSize() const { return LocalFrameSize; } + + /// setLocalFrameMaxAlign - Required alignment of the local object blob, + /// which is the strictest alignment of any object in it. + void setLocalFrameMaxAlign(unsigned Align) { LocalFrameMaxAlign = Align; } + + /// getLocalFrameMaxAlign - Return the required alignment of the local + /// object blob. + unsigned getLocalFrameMaxAlign() const { return LocalFrameMaxAlign; } + + /// getUseLocalStackAllocationBlock - Get whether the local allocation blob + /// should be allocated together or let PEI allocate the locals in it + /// directly. + bool getUseLocalStackAllocationBlock() {return UseLocalStackAllocationBlock;} + + /// setUseLocalStackAllocationBlock - Set whether the local allocation blob + /// should be allocated together or let PEI allocate the locals in it + /// directly. + void setUseLocalStackAllocationBlock(bool v) { + UseLocalStackAllocationBlock = v; + } + + /// isObjectPreAllocated - Return true if the object was pre-allocated into + /// the local block. + bool isObjectPreAllocated(int ObjectIdx) const { + assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && + "Invalid Object Idx!"); + return Objects[ObjectIdx+NumFixedObjects].PreAllocated; + } + /// getObjectSize - Return the size of the specified object. /// int64_t getObjectSize(int ObjectIdx) const { @@ -276,6 +357,14 @@ public: MaxAlignment = std::max(MaxAlignment, Align); } + /// NeedsStackProtector - Returns true if the object may need stack + /// protectors. + bool MayNeedStackProtector(int ObjectIdx) const { + assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && + "Invalid Object Idx!"); + return Objects[ObjectIdx+NumFixedObjects].MayNeedSP; + } + /// getObjectOffset - Return the assigned stack offset of the specified object /// from the incoming stack pointer. /// @@ -307,21 +396,21 @@ public: /// setStackSize - Set the size of the stack... /// void setStackSize(uint64_t Size) { StackSize = Size; } - + /// getOffsetAdjustment - Return the correction for frame offsets. /// int getOffsetAdjustment() const { return OffsetAdjustment; } - + /// setOffsetAdjustment - Set the correction for frame offsets. /// void setOffsetAdjustment(int Adj) { OffsetAdjustment = Adj; } - /// getMaxAlignment - Return the alignment in bytes that this function must be - /// aligned to, which is greater than the default stack alignment provided by + /// getMaxAlignment - Return the alignment in bytes that this function must be + /// aligned to, which is greater than the default stack alignment provided by /// the target. /// unsigned getMaxAlignment() const { return MaxAlignment; } - + /// setMaxAlignment - Set the preferred alignment. /// void setMaxAlignment(unsigned Align) { MaxAlignment = Align; } @@ -350,8 +439,8 @@ public: /// index with a negative value. /// int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool Immutable); - - + + /// isFixedObjectIndex - Returns true if the specified index corresponds to a /// fixed stack object. bool isFixedObjectIndex(int ObjectIdx) const { @@ -382,25 +471,26 @@ public: return Objects[ObjectIdx+NumFixedObjects].Size == ~0ULL; } - /// CreateStackObject - Create a new statically sized stack object, - /// returning a nonnegative identifier to represent it. + /// CreateStackObject - Create a new statically sized stack object, returning + /// a nonnegative identifier to represent it. /// - int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS) { + int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS, + bool MayNeedSP = false) { assert(Size != 0 && "Cannot allocate zero size stack objects!"); - Objects.push_back(StackObject(Size, Alignment, 0, false, isSS)); - int Index = (int)Objects.size()-NumFixedObjects-1; + Objects.push_back(StackObject(Size, Alignment, 0, false, isSS, MayNeedSP)); + int Index = (int)Objects.size() - NumFixedObjects - 1; assert(Index >= 0 && "Bad frame index!"); MaxAlignment = std::max(MaxAlignment, Alignment); return Index; } - /// CreateSpillStackObject - Create a new statically sized stack - /// object that represents a spill slot, returning a nonnegative - /// identifier to represent it. + /// CreateSpillStackObject - Create a new statically sized stack object that + /// represents a spill slot, returning a nonnegative identifier to represent + /// it. /// int CreateSpillStackObject(uint64_t Size, unsigned Alignment) { - CreateStackObject(Size, Alignment, true); - int Index = (int)Objects.size()-NumFixedObjects-1; + CreateStackObject(Size, Alignment, true, false); + int Index = (int)Objects.size() - NumFixedObjects - 1; MaxAlignment = std::max(MaxAlignment, Alignment); return Index; } @@ -417,9 +507,10 @@ public: /// variable sized object is created, whether or not the index returned is /// actually used. /// - int CreateVariableSizedObject() { + int CreateVariableSizedObject(unsigned Alignment) { HasVarSizedObjects = true; - Objects.push_back(StackObject(0, 1, 0, false, false)); + Objects.push_back(StackObject(0, Alignment, 0, false, false, true)); + MaxAlignment = std::max(MaxAlignment, Alignment); return (int)Objects.size()-NumFixedObjects-1; } @@ -431,7 +522,7 @@ public: /// setCalleeSavedInfo - Used by prolog/epilog inserter to set the function's /// callee saved information. - void setCalleeSavedInfo(const std::vector<CalleeSavedInfo> &CSI) { + void setCalleeSavedInfo(const std::vector<CalleeSavedInfo> &CSI) { CSInfo = CSI; } @@ -452,7 +543,7 @@ public: BitVector getPristineRegs(const MachineBasicBlock *MBB) const; /// print - Used by the MachineFunction printer to print information about - /// stack objects. Implemented in MachineFunction.cpp + /// stack objects. Implemented in MachineFunction.cpp /// void print(const MachineFunction &MF, raw_ostream &OS) const; diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h index 409d13ee..5bb453d 100644 --- a/include/llvm/CodeGen/MachineFunction.h +++ b/include/llvm/CodeGen/MachineFunction.h @@ -266,7 +266,7 @@ public: /// verify - Run the current MachineFunction through the machine code /// verifier, useful for debugger use. - void verify(Pass *p=NULL, bool allowDoubleDefs=false) const; + void verify(Pass *p=NULL) const; // Provide accessors for the MachineBasicBlock list... typedef BasicBlockListType::iterator iterator; diff --git a/include/llvm/CodeGen/MachineFunctionPass.h b/include/llvm/CodeGen/MachineFunctionPass.h index 685e868..b7bf0a3 100644 --- a/include/llvm/CodeGen/MachineFunctionPass.h +++ b/include/llvm/CodeGen/MachineFunctionPass.h @@ -31,8 +31,7 @@ class MachineFunction; /// override runOnMachineFunction. class MachineFunctionPass : public FunctionPass { protected: - explicit MachineFunctionPass(intptr_t ID) : FunctionPass(ID) {} - explicit MachineFunctionPass(void *ID) : FunctionPass(ID) {} + explicit MachineFunctionPass(char &ID) : FunctionPass(ID) {} /// runOnMachineFunction - This method must be overloaded to perform the /// desired machine code transformation or analysis. diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index e67b2dd..f843196 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -201,12 +201,14 @@ public: /// isLabel - Returns true if the MachineInstr represents a label. /// bool isLabel() const { - return getOpcode() == TargetOpcode::DBG_LABEL || + return getOpcode() == TargetOpcode::PROLOG_LABEL || getOpcode() == TargetOpcode::EH_LABEL || getOpcode() == TargetOpcode::GC_LABEL; } - bool isDebugLabel() const { return getOpcode() == TargetOpcode::DBG_LABEL; } + bool isPrologLabel() const { + return getOpcode() == TargetOpcode::PROLOG_LABEL; + } bool isEHLabel() const { return getOpcode() == TargetOpcode::EH_LABEL; } bool isGCLabel() const { return getOpcode() == TargetOpcode::GC_LABEL; } bool isDebugValue() const { return getOpcode() == TargetOpcode::DBG_VALUE; } diff --git a/include/llvm/CodeGen/MachineLoopInfo.h b/include/llvm/CodeGen/MachineLoopInfo.h index 3b3e31e..9760eba 100644 --- a/include/llvm/CodeGen/MachineLoopInfo.h +++ b/include/llvm/CodeGen/MachineLoopInfo.h @@ -67,7 +67,7 @@ class MachineLoopInfo : public MachineFunctionPass { public: static char ID; // Pass identification, replacement for typeid - MachineLoopInfo() : MachineFunctionPass(&ID) {} + MachineLoopInfo() : MachineFunctionPass(ID) {} LoopInfoBase<MachineBasicBlock, MachineLoop>& getBase() { return LI; } diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h index 50e38b4..0e719c8 100644 --- a/include/llvm/CodeGen/MachineModuleInfo.h +++ b/include/llvm/CodeGen/MachineModuleInfo.h @@ -344,7 +344,7 @@ public: VariableDbgInfo.push_back(std::make_pair(N, std::make_pair(Slot, Loc))); } - VariableDbgInfoMapTy &getVariableDbgInfo(); + VariableDbgInfoMapTy &getVariableDbgInfo() { return VariableDbgInfo; } }; // End class MachineModuleInfo diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index 7445ec7..4762a39 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -30,55 +30,55 @@ namespace llvm { /// createUnreachableBlockEliminationPass - The LLVM code generator does not /// work well with unreachable basic blocks (what live ranges make sense for a /// block that cannot be reached?). As such, a code generator should either - /// not instruction select unreachable blocks, or it can run this pass as it's + /// not instruction select unreachable blocks, or run this pass as its /// last LLVM modifying pass to clean up blocks that are not reachable from /// the entry block. FunctionPass *createUnreachableBlockEliminationPass(); /// MachineFunctionPrinter pass - This pass prints out the machine function to - /// the given stream, as a debugging tool. + /// the given stream as a debugging tool. MachineFunctionPass * createMachineFunctionPrinterPass(raw_ostream &OS, const std::string &Banner =""); /// MachineLoopInfo pass - This pass is a loop analysis pass. - /// - extern const PassInfo *const MachineLoopInfoID; + /// + extern char &MachineLoopInfoID; /// MachineDominators pass - This pass is a machine dominators analysis pass. - /// - extern const PassInfo *const MachineDominatorsID; + /// + extern char &MachineDominatorsID; /// PHIElimination pass - This pass eliminates machine instruction PHI nodes /// by inserting copy instructions. This destroys SSA information, but is the /// desired input for some register allocators. This pass is "required" by /// these register allocator like this: AU.addRequiredID(PHIEliminationID); /// - extern const PassInfo *const PHIEliminationID; - + extern char &PHIEliminationID; + /// StrongPHIElimination pass - This pass eliminates machine instruction PHI /// nodes by inserting copy instructions. This destroys SSA information, but /// is the desired input for some register allocators. This pass is /// "required" by these register allocator like this: /// AU.addRequiredID(PHIEliminationID); /// This pass is still in development - extern const PassInfo *const StrongPHIEliminationID; + extern char &StrongPHIEliminationID; - extern const PassInfo *const PreAllocSplittingID; + extern char &PreAllocSplittingID; /// SimpleRegisterCoalescing pass. Aggressively coalesces every register /// copy it can. /// - extern const PassInfo *const SimpleRegisterCoalescingID; + extern char &SimpleRegisterCoalescingID; /// TwoAddressInstruction pass - This pass reduces two-address instructions to /// use two operands. This destroys SSA information but it is desired by /// register allocators. - extern const PassInfo *const TwoAddressInstructionPassID; + extern char &TwoAddressInstructionPassID; /// UnreachableMachineBlockElimination pass - This pass removes unreachable /// machine basic blocks. - extern const PassInfo *const UnreachableMachineBlockElimID; + extern char &UnreachableMachineBlockElimID; /// DeadMachineInstructionElim pass - This pass removes dead machine /// instructions. @@ -114,7 +114,7 @@ namespace llvm { /// and eliminates abstract frame references. /// FunctionPass *createPrologEpilogCodeInserter(); - + /// LowerSubregs Pass - This pass lowers subregs to register-register copies /// which yields suboptimal, but correct code if the register allocator /// cannot coalesce all subreg operations during allocation. @@ -145,36 +145,36 @@ namespace llvm { /// IntrinsicLowering Pass - Performs target-independent LLVM IR /// transformations for highly portable strategies. FunctionPass *createGCLoweringPass(); - + /// MachineCodeAnalysis Pass - Target-independent pass to mark safe points in /// machine code. Must be added very late during code generation, just prior /// to output, and importantly after all CFG transformations (such as branch /// folding). FunctionPass *createGCMachineCodeAnalysisPass(); - + /// Deleter Pass - Releases GC metadata. - /// + /// FunctionPass *createGCInfoDeleter(); - + /// Creates a pass to print GC metadata. - /// + /// FunctionPass *createGCInfoPrinter(raw_ostream &OS); - + /// createMachineCSEPass - This pass performs global CSE on machine /// instructions. FunctionPass *createMachineCSEPass(); /// createMachineLICMPass - This pass performs LICM on machine instructions. - /// + /// FunctionPass *createMachineLICMPass(bool PreRegAlloc = true); /// createMachineSinkingPass - This pass performs sinking on machine /// instructions. FunctionPass *createMachineSinkingPass(); - /// createOptimizeExtsPass - This pass performs sign / zero extension - /// optimization by increasing uses of extended values. - FunctionPass *createOptimizeExtsPass(); + /// createPeepholeOptimizerPass - This pass performs peephole optimizations - + /// like extension and comparison eliminations. + FunctionPass *createPeepholeOptimizerPass(); /// createOptimizePHIsPass - This pass optimizes machine instruction PHIs /// to take advantage of opportunities created during DAG legalization. @@ -188,19 +188,23 @@ namespace llvm { /// createMachineVerifierPass - This pass verifies cenerated machine code /// instructions for correctness. - /// - /// @param allowDoubleDefs ignore double definitions of - /// registers. Useful before LiveVariables has run. - FunctionPass *createMachineVerifierPass(bool allowDoubleDefs); + FunctionPass *createMachineVerifierPass(); /// createDwarfEHPass - This pass mulches exception handling code into a form /// adapted to code generation. Required if using dwarf exception handling. - FunctionPass *createDwarfEHPass(const TargetMachine *tm, bool fast); + FunctionPass *createDwarfEHPass(const TargetMachine *tm); /// createSjLjEHPass - This pass adapts exception handling code to use /// the GCC-style builtin setjmp/longjmp (sjlj) to handling EH control flow. FunctionPass *createSjLjEHPass(const TargetLowering *tli); + /// createLocalStackSlotAllocationPass - This pass assigns local frame + /// indices to stack slots relative to one another and allocates + /// base registers to access them when it is estimated by the target to + /// be out of range of normal frame pointer or stack pointer index + /// addressing. + FunctionPass *createLocalStackSlotAllocationPass(); + } // End llvm namespace #endif diff --git a/include/llvm/CodeGen/ProcessImplicitDefs.h b/include/llvm/CodeGen/ProcessImplicitDefs.h index 30477b9..1d743c1 100644 --- a/include/llvm/CodeGen/ProcessImplicitDefs.h +++ b/include/llvm/CodeGen/ProcessImplicitDefs.h @@ -31,7 +31,7 @@ namespace llvm { public: static char ID; - ProcessImplicitDefs() : MachineFunctionPass(&ID) {} + ProcessImplicitDefs() : MachineFunctionPass(ID) {} virtual void getAnalysisUsage(AnalysisUsage &au) const; diff --git a/include/llvm/CodeGen/SchedulerRegistry.h b/include/llvm/CodeGen/SchedulerRegistry.h index 14c33e2..96573dd 100644 --- a/include/llvm/CodeGen/SchedulerRegistry.h +++ b/include/llvm/CodeGen/SchedulerRegistry.h @@ -78,12 +78,19 @@ ScheduleDAGSDNodes *createTDRRListDAGScheduler(SelectionDAGISel *IS, ScheduleDAGSDNodes *createSourceListDAGScheduler(SelectionDAGISel *IS, CodeGenOpt::Level OptLevel); -/// createHybridListDAGScheduler - This creates a bottom up hybrid register -/// usage reduction list scheduler that make use of latency information to -/// avoid stalls for long latency instructions. +/// createHybridListDAGScheduler - This creates a bottom up register pressure +/// aware list scheduler that make use of latency information to avoid stalls +/// for long latency instructions in low register pressure mode. In high +/// register pressure mode it schedules to reduce register pressure. ScheduleDAGSDNodes *createHybridListDAGScheduler(SelectionDAGISel *IS, CodeGenOpt::Level); +/// createILPListDAGScheduler - This creates a bottom up register pressure +/// aware list scheduler that tries to increase instruction level parallelism +/// in low register pressure mode. In high register pressure mode it schedules +/// to reduce register pressure. +ScheduleDAGSDNodes *createILPListDAGScheduler(SelectionDAGISel *IS, + CodeGenOpt::Level); /// createTDListDAGScheduler - This creates a top-down list scheduler with /// a hazard recognizer. ScheduleDAGSDNodes *createTDListDAGScheduler(SelectionDAGISel *IS, diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index de49d18..7723fa0 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -977,10 +977,6 @@ public: /// been verified as a debug information descriptor. bool isVerifiedDebugInfoDesc(SDValue Op) const; - /// getShuffleScalarElt - Returns the scalar element that will make up the ith - /// element of the result of the vector shuffle. - SDValue getShuffleScalarElt(const ShuffleVectorSDNode *N, unsigned Idx); - /// UnrollVectorOp - Utility function used by legalize and lowering to /// "unroll" a vector operation by splitting out the scalars and operating /// on each element individually. If the ResNE is 0, fully unroll the vector diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h index f1f047b..88044c7 100644 --- a/include/llvm/CodeGen/SlotIndexes.h +++ b/include/llvm/CodeGen/SlotIndexes.h @@ -128,7 +128,8 @@ namespace llvm { friend class SlotIndexes; friend struct DenseMapInfo<SlotIndex>; - private: + enum Slot { LOAD, USE, DEF, STORE, NUM }; + static const unsigned PHI_BIT = 1 << 2; PointerIntPair<IndexListEntry*, 3, unsigned> lie; @@ -146,6 +147,11 @@ namespace llvm { return entry().getIndex() | getSlot(); } + /// Returns the slot for this SlotIndex. + Slot getSlot() const { + return static_cast<Slot>(lie.getInt() & ~PHI_BIT); + } + static inline unsigned getHashValue(const SlotIndex &v) { IndexListEntry *ptrVal = &v.entry(); return (unsigned((intptr_t)ptrVal) >> 4) ^ @@ -153,11 +159,6 @@ namespace llvm { } public: - - // FIXME: Ugh. This is public because LiveIntervalAnalysis is still using it - // for some spill weight stuff. Fix that, then make this private. - enum Slot { LOAD, USE, DEF, STORE, NUM }; - static inline SlotIndex getEmptyKey() { return SlotIndex(IndexListEntry::getEmptyKeyEntry(), 0); } @@ -235,16 +236,31 @@ namespace llvm { return other.getIndex() - getIndex(); } - /// Returns the slot for this SlotIndex. - Slot getSlot() const { - return static_cast<Slot>(lie.getInt() & ~PHI_BIT); - } - /// Returns the state of the PHI bit. bool isPHI() const { return lie.getInt() & PHI_BIT; } + /// isLoad - Return true if this is a LOAD slot. + bool isLoad() const { + return getSlot() == LOAD; + } + + /// isDef - Return true if this is a DEF slot. + bool isDef() const { + return getSlot() == DEF; + } + + /// isUse - Return true if this is a USE slot. + bool isUse() const { + return getSlot() == USE; + } + + /// isStore - Return true if this is a STORE slot. + bool isStore() const { + return getSlot() == STORE; + } + /// Returns the base index for associated with this index. The base index /// is the one associated with the LOAD slot for the instruction pointed to /// by this index. @@ -475,7 +491,7 @@ namespace llvm { public: static char ID; - SlotIndexes() : MachineFunctionPass(&ID), indexListHead(0) {} + SlotIndexes() : MachineFunctionPass(ID), indexListHead(0) {} virtual void getAnalysisUsage(AnalysisUsage &au) const; virtual void releaseMemory(); @@ -494,6 +510,11 @@ namespace llvm { return SlotIndex(front(), 0); } + /// Returns the base index of the last slot in this analysis. + SlotIndex getLastIndex() { + return SlotIndex(back(), 0); + } + /// Returns the invalid index marker for this analysis. SlotIndex getInvalidIndex() { return getZeroIndex(); diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index 3aaab88..d8f0373 100644 --- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -105,7 +105,6 @@ class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile { const MCSection *UStringSection; const MCSection *TextCoalSection; const MCSection *ConstTextCoalSection; - const MCSection *ConstDataCoalSection; const MCSection *ConstDataSection; const MCSection *DataCoalSection; const MCSection *DataCommonSection; diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h index 6e2a102..51f324c 100644 --- a/include/llvm/CodeGen/ValueTypes.h +++ b/include/llvm/CodeGen/ValueTypes.h @@ -159,14 +159,12 @@ namespace llvm { /// getPow2VectorType - Widens the length of the given vector EVT up to /// the nearest power of 2 and returns that type. MVT getPow2VectorType() const { - if (!isPow2VectorType()) { - unsigned NElts = getVectorNumElements(); - unsigned Pow2NElts = 1 << Log2_32_Ceil(NElts); - return MVT::getVectorVT(getVectorElementType(), Pow2NElts); - } - else { + if (isPow2VectorType()) return *this; - } + + unsigned NElts = getVectorNumElements(); + unsigned Pow2NElts = 1 << Log2_32_Ceil(NElts); + return MVT::getVectorVT(getVectorElementType(), Pow2NElts); } /// getScalarType - If this is a vector type, return the element type, @@ -350,17 +348,6 @@ namespace llvm { } return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE); } - - static MVT getIntVectorWithNumElements(unsigned NumElts) { - switch (NumElts) { - default: return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE); - case 1: return MVT::v1i64; - case 2: return MVT::v2i32; - case 4: return MVT::v4i16; - case 8: return MVT::v8i8; - case 16: return MVT::v16i8; - } - } }; struct EVT { // EVT = Extended Value Type @@ -374,22 +361,16 @@ namespace llvm { EVT(MVT::SimpleValueType SVT) : V(SVT), LLVMTy(0) { } EVT(MVT S) : V(S), LLVMTy(0) {} - bool operator==(const EVT VT) const { - if (V.SimpleTy == VT.V.SimpleTy) { - if (V.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE) - return LLVMTy == VT.LLVMTy; + bool operator==(EVT VT) const { + return !(*this != VT); + } + bool operator!=(EVT VT) const { + if (V.SimpleTy != VT.V.SimpleTy) return true; - } + if (V.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE) + return LLVMTy != VT.LLVMTy; return false; } - bool operator!=(const EVT VT) const { - if (V.SimpleTy == VT.V.SimpleTy) { - if (V.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE) - return LLVMTy != VT.LLVMTy; - return false; - } - return true; - } /// getFloatingPointVT - Returns the EVT that represents a floating point /// type with the given number of bits. There are two floating point types @@ -402,30 +383,32 @@ namespace llvm { /// number of bits. static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth) { MVT M = MVT::getIntegerVT(BitWidth); - if (M.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE) - return getExtendedIntegerVT(Context, BitWidth); - else + if (M.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE) return M; + return getExtendedIntegerVT(Context, BitWidth); } /// getVectorVT - Returns the EVT that represents a vector NumElements in /// length, where each element is of type VT. static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements) { MVT M = MVT::getVectorVT(VT.V, NumElements); - if (M.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE) - return getExtendedVectorVT(Context, VT, NumElements); - else + if (M.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE) return M; + return getExtendedVectorVT(Context, VT, NumElements); } /// getIntVectorWithNumElements - Return any integer vector type that has /// the specified number of elements. static EVT getIntVectorWithNumElements(LLVMContext &C, unsigned NumElts) { - MVT M = MVT::getIntVectorWithNumElements(NumElts); - if (M.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE) - return getVectorVT(C, MVT::i8, NumElts); - else - return M; + switch (NumElts) { + default: return getVectorVT(C, MVT::i8, NumElts); + case 1: return MVT::v1i64; + case 2: return MVT::v2i32; + case 4: return MVT::v4i16; + case 8: return MVT::v8i8; + case 16: return MVT::v16i8; + } + return MVT::INVALID_SIMPLE_VALUE_TYPE; } /// isSimple - Test if the given EVT is simple (as opposed to being @@ -457,26 +440,27 @@ namespace llvm { /// is64BitVector - Return true if this is a 64-bit vector type. bool is64BitVector() const { - return isSimple() ? - (V==MVT::v8i8 || V==MVT::v4i16 || V==MVT::v2i32 || - V==MVT::v1i64 || V==MVT::v2f32) : - isExtended64BitVector(); + if (!isSimple()) + return isExtended64BitVector(); + + return (V == MVT::v8i8 || V==MVT::v4i16 || V==MVT::v2i32 || + V == MVT::v1i64 || V==MVT::v2f32); } /// is128BitVector - Return true if this is a 128-bit vector type. bool is128BitVector() const { - return isSimple() ? - (V==MVT::v16i8 || V==MVT::v8i16 || V==MVT::v4i32 || - V==MVT::v2i64 || V==MVT::v4f32 || V==MVT::v2f64) : - isExtended128BitVector(); + if (!isSimple()) + return isExtended128BitVector(); + return (V==MVT::v16i8 || V==MVT::v8i16 || V==MVT::v4i32 || + V==MVT::v2i64 || V==MVT::v4f32 || V==MVT::v2f64); } /// is256BitVector - Return true if this is a 256-bit vector type. inline bool is256BitVector() const { - return isSimple() - ? (V==MVT::v8f32 || V==MVT::v4f64 || V==MVT::v32i8 || - V==MVT::v16i16 || V==MVT::v8i32 || V==MVT::v4i64) - : isExtended256BitVector(); + if (!isSimple()) + return isExtended256BitVector(); + return (V == MVT::v8f32 || V == MVT::v4f64 || V == MVT::v32i8 || + V == MVT::v16i16 || V == MVT::v8i32 || V == MVT::v4i64); } /// is512BitVector - Return true if this is a 512-bit vector type. @@ -550,8 +534,7 @@ namespace llvm { assert(isVector() && "Invalid vector type!"); if (isSimple()) return V.getVectorElementType(); - else - return getExtendedVectorElementType(); + return getExtendedVectorElementType(); } /// getVectorNumElements - Given a vector type, return the number of @@ -560,16 +543,14 @@ namespace llvm { assert(isVector() && "Invalid vector type!"); if (isSimple()) return V.getVectorNumElements(); - else - return getExtendedVectorNumElements(); + return getExtendedVectorNumElements(); } /// getSizeInBits - Return the size of the specified value type in bits. unsigned getSizeInBits() const { if (isSimple()) return V.getSizeInBits(); - else - return getExtendedSizeInBits(); + return getExtendedSizeInBits(); } /// getStoreSize - Return the number of bytes overwritten by a store @@ -592,8 +573,7 @@ namespace llvm { unsigned BitWidth = getSizeInBits(); if (BitWidth <= 8) return EVT(MVT::i8); - else - return getIntegerVT(Context, 1 << Log2_32_Ceil(BitWidth)); + return getIntegerVT(Context, 1 << Log2_32_Ceil(BitWidth)); } /// getHalfSizedIntegerVT - Finds the smallest simple value type that is @@ -604,12 +584,10 @@ namespace llvm { assert(isInteger() && !isVector() && "Invalid integer type!"); unsigned EVTSize = getSizeInBits(); for (unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE; - IntVT <= MVT::LAST_INTEGER_VALUETYPE; - ++IntVT) { + IntVT <= MVT::LAST_INTEGER_VALUETYPE; ++IntVT) { EVT HalfVT = EVT((MVT::SimpleValueType)IntVT); - if(HalfVT.getSizeInBits() * 2 >= EVTSize) { + if (HalfVT.getSizeInBits() * 2 >= EVTSize) return HalfVT; - } } return getIntegerVT(Context, (EVTSize + 1) / 2); } |