diff options
Diffstat (limited to 'include/llvm/CodeGen')
-rw-r--r-- | include/llvm/CodeGen/Analysis.h | 3 | ||||
-rw-r--r-- | include/llvm/CodeGen/LexicalScopes.h | 2 | ||||
-rw-r--r-- | include/llvm/CodeGen/LiveRangeEdit.h | 207 | ||||
-rw-r--r-- | include/llvm/CodeGen/MachineFunction.h | 3 | ||||
-rw-r--r-- | include/llvm/CodeGen/MachineMemOperand.h | 7 | ||||
-rw-r--r-- | include/llvm/CodeGen/MachinePassRegistry.h | 17 | ||||
-rw-r--r-- | include/llvm/CodeGen/MachineRegisterInfo.h | 22 | ||||
-rw-r--r-- | include/llvm/CodeGen/MachineScheduler.h | 3 | ||||
-rw-r--r-- | include/llvm/CodeGen/PBQP/Graph.h | 37 | ||||
-rw-r--r-- | include/llvm/CodeGen/PBQP/Heuristics/Briggs.h | 6 | ||||
-rw-r--r-- | include/llvm/CodeGen/Passes.h | 5 | ||||
-rw-r--r-- | include/llvm/CodeGen/ScheduleDAGInstrs.h | 11 | ||||
-rw-r--r-- | include/llvm/CodeGen/SelectionDAG.h | 9 | ||||
-rw-r--r-- | include/llvm/CodeGen/SelectionDAGNodes.h | 3 | ||||
-rw-r--r-- | include/llvm/CodeGen/SlotIndexes.h | 208 |
15 files changed, 387 insertions, 156 deletions
diff --git a/include/llvm/CodeGen/Analysis.h b/include/llvm/CodeGen/Analysis.h index fda801c..0b609ed 100644 --- a/include/llvm/CodeGen/Analysis.h +++ b/include/llvm/CodeGen/Analysis.h @@ -27,6 +27,7 @@ namespace llvm { class GlobalVariable; class TargetLowering; class SDNode; +class SDValue; class SelectionDAG; /// ComputeLinearIndex - Given an LLVM IR aggregate type and a sequence @@ -89,7 +90,7 @@ bool isInTailCallPosition(ImmutableCallSite CS, Attributes CalleeRetAttr, const TargetLowering &TLI); bool isInTailCallPosition(SelectionDAG &DAG, SDNode *Node, - const TargetLowering &TLI); + SDValue &Chain, const TargetLowering &TLI); } // End llvm namespace diff --git a/include/llvm/CodeGen/LexicalScopes.h b/include/llvm/CodeGen/LexicalScopes.h index 6cb5c9e..eb01f66 100644 --- a/include/llvm/CodeGen/LexicalScopes.h +++ b/include/llvm/CodeGen/LexicalScopes.h @@ -209,7 +209,7 @@ public: Parent->closeInsnRange(NewScope); } - /// dominates - Return true if current scope dominsates given lexical scope. + /// dominates - Return true if current scope dominates given lexical scope. bool dominates(const LexicalScope *S) const { if (S == this) return true; diff --git a/include/llvm/CodeGen/LiveRangeEdit.h b/include/llvm/CodeGen/LiveRangeEdit.h new file mode 100644 index 0000000..57a6193 --- /dev/null +++ b/include/llvm/CodeGen/LiveRangeEdit.h @@ -0,0 +1,207 @@ +//===---- LiveRangeEdit.h - Basic tools for split and spill -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// The LiveRangeEdit class represents changes done to a virtual register when it +// is spilled or split. +// +// The parent register is never changed. Instead, a number of new virtual +// registers are created and added to the newRegs vector. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_LIVERANGEEDIT_H +#define LLVM_CODEGEN_LIVERANGEEDIT_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/CodeGen/LiveInterval.h" +#include "llvm/Target/TargetMachine.h" + +namespace llvm { + +class AliasAnalysis; +class LiveIntervals; +class MachineLoopInfo; +class MachineRegisterInfo; +class VirtRegMap; + +class LiveRangeEdit { +public: + /// Callback methods for LiveRangeEdit owners. + class Delegate { + virtual void anchor(); + public: + /// Called immediately before erasing a dead machine instruction. + virtual void LRE_WillEraseInstruction(MachineInstr *MI) {} + + /// Called when a virtual register is no longer used. Return false to defer + /// its deletion from LiveIntervals. + virtual bool LRE_CanEraseVirtReg(unsigned) { return true; } + + /// Called before shrinking the live range of a virtual register. + virtual void LRE_WillShrinkVirtReg(unsigned) {} + + /// Called after cloning a virtual register. + /// This is used for new registers representing connected components of Old. + virtual void LRE_DidCloneVirtReg(unsigned New, unsigned Old) {} + + virtual ~Delegate() {} + }; + +private: + LiveInterval &parent_; + SmallVectorImpl<LiveInterval*> &newRegs_; + MachineRegisterInfo &MRI; + LiveIntervals &LIS; + VirtRegMap *VRM; + const TargetInstrInfo &TII; + Delegate *const delegate_; + + /// firstNew_ - Index of the first register added to newRegs_. + const unsigned firstNew_; + + /// scannedRemattable_ - true when remattable values have been identified. + bool scannedRemattable_; + + /// remattable_ - Values defined by remattable instructions as identified by + /// tii.isTriviallyReMaterializable(). + SmallPtrSet<const VNInfo*,4> remattable_; + + /// rematted_ - Values that were actually rematted, and so need to have their + /// live range trimmed or entirely removed. + SmallPtrSet<const VNInfo*,4> rematted_; + + /// scanRemattable - Identify the parent_ values that may rematerialize. + void scanRemattable(AliasAnalysis *aa); + + /// allUsesAvailableAt - Return true if all registers used by OrigMI at + /// OrigIdx are also available with the same value at UseIdx. + bool allUsesAvailableAt(const MachineInstr *OrigMI, SlotIndex OrigIdx, + SlotIndex UseIdx); + + /// foldAsLoad - If LI has a single use and a single def that can be folded as + /// a load, eliminate the register by folding the def into the use. + bool foldAsLoad(LiveInterval *LI, SmallVectorImpl<MachineInstr*> &Dead); + +public: + /// Create a LiveRangeEdit for breaking down parent into smaller pieces. + /// @param parent The register being spilled or split. + /// @param newRegs List to receive any new registers created. This needn't be + /// empty initially, any existing registers are ignored. + /// @param MF The MachineFunction the live range edit is taking place in. + /// @param lis The collection of all live intervals in this function. + /// @param vrm Map of virtual registers to physical registers for this + /// function. If NULL, no virtual register map updates will + /// be done. This could be the case if called before Regalloc. + LiveRangeEdit(LiveInterval &parent, + SmallVectorImpl<LiveInterval*> &newRegs, + MachineFunction &MF, + LiveIntervals &lis, + VirtRegMap *vrm, + Delegate *delegate = 0) + : parent_(parent), newRegs_(newRegs), + MRI(MF.getRegInfo()), LIS(lis), VRM(vrm), + TII(*MF.getTarget().getInstrInfo()), + delegate_(delegate), + firstNew_(newRegs.size()), + scannedRemattable_(false) {} + + LiveInterval &getParent() const { return parent_; } + unsigned getReg() const { return parent_.reg; } + + /// Iterator for accessing the new registers added by this edit. + typedef SmallVectorImpl<LiveInterval*>::const_iterator iterator; + iterator begin() const { return newRegs_.begin()+firstNew_; } + iterator end() const { return newRegs_.end(); } + unsigned size() const { return newRegs_.size()-firstNew_; } + bool empty() const { return size() == 0; } + LiveInterval *get(unsigned idx) const { return newRegs_[idx+firstNew_]; } + + ArrayRef<LiveInterval*> regs() const { + return makeArrayRef(newRegs_).slice(firstNew_); + } + + /// createFrom - Create a new virtual register based on OldReg. + LiveInterval &createFrom(unsigned OldReg); + + /// create - Create a new register with the same class and original slot as + /// parent. + LiveInterval &create() { + return createFrom(getReg()); + } + + /// anyRematerializable - Return true if any parent values may be + /// rematerializable. + /// This function must be called before any rematerialization is attempted. + bool anyRematerializable(AliasAnalysis*); + + /// checkRematerializable - Manually add VNI to the list of rematerializable + /// values if DefMI may be rematerializable. + bool checkRematerializable(VNInfo *VNI, const MachineInstr *DefMI, + AliasAnalysis*); + + /// Remat - Information needed to rematerialize at a specific location. + struct Remat { + VNInfo *ParentVNI; // parent_'s value at the remat location. + MachineInstr *OrigMI; // Instruction defining ParentVNI. + explicit Remat(VNInfo *ParentVNI) : ParentVNI(ParentVNI), OrigMI(0) {} + }; + + /// canRematerializeAt - Determine if ParentVNI can be rematerialized at + /// UseIdx. It is assumed that parent_.getVNINfoAt(UseIdx) == ParentVNI. + /// When cheapAsAMove is set, only cheap remats are allowed. + bool canRematerializeAt(Remat &RM, + SlotIndex UseIdx, + bool cheapAsAMove); + + /// rematerializeAt - Rematerialize RM.ParentVNI into DestReg by inserting an + /// instruction into MBB before MI. The new instruction is mapped, but + /// liveness is not updated. + /// Return the SlotIndex of the new instruction. + SlotIndex rematerializeAt(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + unsigned DestReg, + const Remat &RM, + const TargetRegisterInfo&, + bool Late = false); + + /// markRematerialized - explicitly mark a value as rematerialized after doing + /// it manually. + void markRematerialized(const VNInfo *ParentVNI) { + rematted_.insert(ParentVNI); + } + + /// didRematerialize - Return true if ParentVNI was rematerialized anywhere. + bool didRematerialize(const VNInfo *ParentVNI) const { + return rematted_.count(ParentVNI); + } + + /// eraseVirtReg - Notify the delegate that Reg is no longer in use, and try + /// to erase it from LIS. + void eraseVirtReg(unsigned Reg); + + /// eliminateDeadDefs - Try to delete machine instructions that are now dead + /// (allDefsAreDead returns true). This may cause live intervals to be trimmed + /// and further dead efs to be eliminated. + /// RegsBeingSpilled lists registers currently being spilled by the register + /// allocator. These registers should not be split into new intervals + /// as currently those new intervals are not guaranteed to spill. + void eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead, + ArrayRef<unsigned> RegsBeingSpilled + = ArrayRef<unsigned>()); + + /// calculateRegClassAndHint - Recompute register class and hint for each new + /// register. + void calculateRegClassAndHint(MachineFunction&, + const MachineLoopInfo&); +}; + +} + +#endif diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h index fd4cac8..dda2dc7 100644 --- a/include/llvm/CodeGen/MachineFunction.h +++ b/include/llvm/CodeGen/MachineFunction.h @@ -380,7 +380,8 @@ public: MachineMemOperand *getMachineMemOperand(MachinePointerInfo PtrInfo, unsigned f, uint64_t s, unsigned base_alignment, - const MDNode *TBAAInfo = 0); + const MDNode *TBAAInfo = 0, + const MDNode *Ranges = 0); /// getMachineMemOperand - Allocate a new MachineMemOperand by copying /// an existing one, adjusting by an offset and using the given size. diff --git a/include/llvm/CodeGen/MachineMemOperand.h b/include/llvm/CodeGen/MachineMemOperand.h index eed4a76..1ac9080 100644 --- a/include/llvm/CodeGen/MachineMemOperand.h +++ b/include/llvm/CodeGen/MachineMemOperand.h @@ -84,6 +84,7 @@ class MachineMemOperand { uint64_t Size; unsigned Flags; const MDNode *TBAAInfo; + const MDNode *Ranges; public: /// Flags values. These may be or'd together. @@ -105,7 +106,8 @@ public: /// MachineMemOperand - Construct an MachineMemOperand object with the /// specified PtrInfo, flags, size, and base alignment. MachineMemOperand(MachinePointerInfo PtrInfo, unsigned flags, uint64_t s, - unsigned base_alignment, const MDNode *TBAAInfo = 0); + unsigned base_alignment, const MDNode *TBAAInfo = 0, + const MDNode *Ranges = 0); const MachinePointerInfo &getPointerInfo() const { return PtrInfo; } @@ -140,6 +142,9 @@ public: /// getTBAAInfo - Return the TBAA tag for the memory reference. const MDNode *getTBAAInfo() const { return TBAAInfo; } + /// getRanges - Return the range tag for the memory reference. + const MDNode *getRanges() const { return Ranges; } + bool isLoad() const { return Flags & MOLoad; } bool isStore() const { return Flags & MOStore; } bool isVolatile() const { return Flags & MOVolatile; } diff --git a/include/llvm/CodeGen/MachinePassRegistry.h b/include/llvm/CodeGen/MachinePassRegistry.h index c41e8e2..90ee7f4 100644 --- a/include/llvm/CodeGen/MachinePassRegistry.h +++ b/include/llvm/CodeGen/MachinePassRegistry.h @@ -26,7 +26,7 @@ namespace llvm { typedef void *(*MachinePassCtor)(); -//===----------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// /// /// MachinePassRegistryListener - Listener to adds and removals of nodes in /// registration list. @@ -42,7 +42,7 @@ public: }; -//===----------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// /// /// MachinePassRegistryNode - Machine pass node stored in registration list. /// @@ -55,7 +55,7 @@ private: const char *Name; // Name of function pass. const char *Description; // Description string. MachinePassCtor Ctor; // Function pass creator. - + public: MachinePassRegistryNode(const char *N, const char *D, MachinePassCtor C) @@ -72,11 +72,11 @@ public: const char *getDescription() const { return Description; } MachinePassCtor getCtor() const { return Ctor; } void setNext(MachinePassRegistryNode *N) { Next = N; } - + }; -//===----------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// /// /// MachinePassRegistry - Track the registration of machine passes. /// @@ -88,7 +88,7 @@ private: MachinePassRegistryNode *List; // List of registry nodes. MachinePassCtor Default; // Default function pass creator. MachinePassRegistryListener* Listener;// Listener for list adds are removes. - + public: // NO CONSTRUCTOR - we don't want static constructor ordering to mess @@ -99,6 +99,7 @@ public: MachinePassRegistryNode *getList() { return List; } MachinePassCtor getDefault() { return Default; } void setDefault(MachinePassCtor C) { Default = C; } + void setDefault(StringRef Name); void setListener(MachinePassRegistryListener *L) { Listener = L; } /// Add - Adds a function pass to the registration list. @@ -126,7 +127,7 @@ public: void initialize(cl::Option &O) { cl::parser<typename RegistryClass::FunctionPassCtor>::initialize(O); - + // Add existing passes to option. for (RegistryClass *Node = RegistryClass::getList(); Node; Node = Node->getNext()) { @@ -134,7 +135,7 @@ public: (typename RegistryClass::FunctionPassCtor)Node->getCtor(), Node->getDescription()); } - + // Make sure we listen for list changes. RegistryClass::setListener(this); } diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h index 69ce588..3272fbd 100644 --- a/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/include/llvm/CodeGen/MachineRegisterInfo.h @@ -32,6 +32,11 @@ class MachineRegisterInfo { /// registers have a single def. bool IsSSA; + /// TracksLiveness - True while register liveness is being tracked accurately. + /// Basic block live-in lists, kill flags, and implicit defs may not be + /// accurate when after this flag is cleared. + bool TracksLiveness; + /// VRegInfo - Information we keep for each virtual register. /// /// Each element in this list contains the register class of the vreg and the @@ -103,6 +108,23 @@ public: // leaveSSA - Indicates that the machine function is no longer in SSA form. void leaveSSA() { IsSSA = false; } + /// tracksLiveness - Returns true when tracking register liveness accurately. + /// + /// While this flag is true, register liveness information in basic block + /// live-in lists and machine instruction operands is accurate. This means it + /// can be used to change the code in ways that affect the values in + /// registers, for example by the register scavenger. + /// + /// When this flag is false, liveness is no longer reliable. + bool tracksLiveness() const { return TracksLiveness; } + + /// invalidateLiveness - Indicates that register liveness is no longer being + /// tracked accurately. + /// + /// This should be called by late passes that invalidate the liveness + /// information. + void invalidateLiveness() { TracksLiveness = false; } + //===--------------------------------------------------------------------===// // Register Info //===--------------------------------------------------------------------===// diff --git a/include/llvm/CodeGen/MachineScheduler.h b/include/llvm/CodeGen/MachineScheduler.h index e852009..474c95d 100644 --- a/include/llvm/CodeGen/MachineScheduler.h +++ b/include/llvm/CodeGen/MachineScheduler.h @@ -81,6 +81,9 @@ public: static void setDefault(ScheduleDAGCtor C) { Registry.setDefault((MachinePassCtor)C); } + static void setDefault(StringRef Name) { + Registry.setDefault(Name); + } static void setListener(MachinePassRegistryListener *L) { Registry.setListener(L); } diff --git a/include/llvm/CodeGen/PBQP/Graph.h b/include/llvm/CodeGen/PBQP/Graph.h index 5240729..a5d8b0d 100644 --- a/include/llvm/CodeGen/PBQP/Graph.h +++ b/include/llvm/CodeGen/PBQP/Graph.h @@ -350,6 +350,43 @@ namespace PBQP { numNodes = numEdges = 0; } + /// \brief Dump a graph to an output stream. + template <typename OStream> + void dump(OStream &os) { + os << getNumNodes() << " " << getNumEdges() << "\n"; + + for (NodeItr nodeItr = nodesBegin(), nodeEnd = nodesEnd(); + nodeItr != nodeEnd; ++nodeItr) { + const Vector& v = getNodeCosts(nodeItr); + os << "\n" << v.getLength() << "\n"; + assert(v.getLength() != 0 && "Empty vector in graph."); + os << v[0]; + for (unsigned i = 1; i < v.getLength(); ++i) { + os << " " << v[i]; + } + os << "\n"; + } + + for (EdgeItr edgeItr = edgesBegin(), edgeEnd = edgesEnd(); + edgeItr != edgeEnd; ++edgeItr) { + unsigned n1 = std::distance(nodesBegin(), getEdgeNode1(edgeItr)); + unsigned n2 = std::distance(nodesBegin(), getEdgeNode2(edgeItr)); + assert(n1 != n2 && "PBQP graphs shound not have self-edges."); + const Matrix& m = getEdgeCosts(edgeItr); + os << "\n" << n1 << " " << n2 << "\n" + << m.getRows() << " " << m.getCols() << "\n"; + assert(m.getRows() != 0 && "No rows in matrix."); + assert(m.getCols() != 0 && "No cols in matrix."); + for (unsigned i = 0; i < m.getRows(); ++i) { + os << m[i][0]; + for (unsigned j = 1; j < m.getCols(); ++j) { + os << " " << m[i][j]; + } + os << "\n"; + } + } + } + /// \brief Print a representation of this graph in DOT format. /// @param os Output stream to print on. template <typename OStream> diff --git a/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h b/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h index e96c4cb..a859e58 100644 --- a/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h +++ b/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h @@ -418,6 +418,12 @@ namespace PBQP { unsigned numRegs = getGraph().getNodeCosts(nItr).getLength() - 1; nd.numDenied = 0; + const Vector& nCosts = getGraph().getNodeCosts(nItr); + for (unsigned i = 1; i < nCosts.getLength(); ++i) { + if (nCosts[i] == std::numeric_limits<PBQPNum>::infinity()) + ++nd.numDenied; + } + nd.numSafe = numRegs; nd.unsafeDegrees.resize(numRegs, 0); diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index d6ca148e..3b38199 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -223,11 +223,6 @@ protected: /// regalloc pass. FunctionPass *createRegAllocPass(bool Optimized); - /// printNoVerify - Add a pass to dump the machine function, if debugging is - /// enabled. - /// - void printNoVerify(const char *Banner) const; - /// printAndVerify - Add a pass to dump then verify the machine function, if /// those steps are enabled. /// diff --git a/include/llvm/CodeGen/ScheduleDAGInstrs.h b/include/llvm/CodeGen/ScheduleDAGInstrs.h index a08f6cc..4fee108 100644 --- a/include/llvm/CodeGen/ScheduleDAGInstrs.h +++ b/include/llvm/CodeGen/ScheduleDAGInstrs.h @@ -181,6 +181,13 @@ namespace llvm { /// the def-side latency only. bool UnitLatencies; + /// The standard DAG builder does not normally include terminators as DAG + /// nodes because it does not create the necessary dependencies to prevent + /// reordering. A specialized scheduler can overide + /// TargetInstrInfo::isSchedulingBoundary then enable this flag to indicate + /// it has taken responsibility for scheduling the terminator correctly. + bool CanHandleTerminators; + /// State specific to the current scheduling region. /// ------------------------------------------------ @@ -296,6 +303,10 @@ namespace llvm { /// overriding enterRegion() or exitRegion(). virtual void schedule() = 0; + /// finalizeSchedule - Allow targets to perform final scheduling actions at + /// the level of the whole MachineFunction. By default does nothing. + virtual void finalizeSchedule() {} + virtual void dumpNode(const SUnit *SU) const; /// Return a label for a DAG node that points to an instruction. diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index f921ca2..6a7a87e 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -654,7 +654,7 @@ public: SDValue getLoad(EVT VT, DebugLoc dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, bool isVolatile, bool isNonTemporal, bool isInvariant, unsigned Alignment, - const MDNode *TBAAInfo = 0); + const MDNode *TBAAInfo = 0, const MDNode *Ranges = 0); SDValue getExtLoad(ISD::LoadExtType ExtType, DebugLoc dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, bool isVolatile, @@ -667,7 +667,8 @@ public: SDValue Chain, SDValue Ptr, SDValue Offset, MachinePointerInfo PtrInfo, EVT MemVT, bool isVolatile, bool isNonTemporal, bool isInvariant, - unsigned Alignment, const MDNode *TBAAInfo = 0); + unsigned Alignment, const MDNode *TBAAInfo = 0, + const MDNode *Ranges = 0); SDValue getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType, EVT VT, DebugLoc dl, SDValue Chain, SDValue Ptr, SDValue Offset, @@ -979,8 +980,8 @@ public: /// bitsets. This code only analyzes bits in Mask, in order to short-circuit /// processing. Targets can implement the computeMaskedBitsForTargetNode /// method in the TargetLowering class to allow target nodes to be understood. - void ComputeMaskedBits(SDValue Op, const APInt &Mask, APInt &KnownZero, - APInt &KnownOne, unsigned Depth = 0) const; + void ComputeMaskedBits(SDValue Op, APInt &KnownZero, APInt &KnownOne, + unsigned Depth = 0) const; /// ComputeNumSignBits - Return the number of times the sign bit of the /// register is replicated into the other bits. We know that at least 1 bit diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index da3ea2a..f8248b8 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -933,6 +933,9 @@ public: /// Returns the TBAAInfo that describes the dereference. const MDNode *getTBAAInfo() const { return MMO->getTBAAInfo(); } + /// Returns the Ranges that describes the dereference. + const MDNode *getRanges() const { return MMO->getRanges(); } + /// getMemoryVT - Return the type of the in-memory value. EVT getMemoryVT() const { return MemoryVT; } diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h index d868cb8..dfea0ac 100644 --- a/include/llvm/CodeGen/SlotIndexes.h +++ b/include/llvm/CodeGen/SlotIndexes.h @@ -23,6 +23,7 @@ #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/ilist.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/DenseMap.h" #include "llvm/Support/Allocator.h" @@ -33,8 +34,7 @@ namespace llvm { /// SlotIndexes pass. It should not be used directly. See the /// SlotIndex & SlotIndexes classes for the public interface to this /// information. - class IndexListEntry { - IndexListEntry *next, *prev; + class IndexListEntry : public ilist_node<IndexListEntry> { MachineInstr *mi; unsigned index; @@ -51,23 +51,31 @@ namespace llvm { void setIndex(unsigned index) { this->index = index; } - - IndexListEntry* getNext() { return next; } - const IndexListEntry* getNext() const { return next; } - void setNext(IndexListEntry *next) { - this->next = next; - } - IndexListEntry* getPrev() { return prev; } - const IndexListEntry* getPrev() const { return prev; } - void setPrev(IndexListEntry *prev) { - this->prev = prev; + }; + + template <> + struct ilist_traits<IndexListEntry> : public ilist_default_traits<IndexListEntry> { + private: + mutable ilist_half_node<IndexListEntry> Sentinel; + public: + IndexListEntry *createSentinel() const { + return static_cast<IndexListEntry*>(&Sentinel); } + void destroySentinel(IndexListEntry *) const {} + + IndexListEntry *provideInitialHead() const { return createSentinel(); } + IndexListEntry *ensureHead(IndexListEntry*) const { return createSentinel(); } + static void noteHead(IndexListEntry*, IndexListEntry*) {} + void deleteNode(IndexListEntry *N) {} + + private: + void createNode(const IndexListEntry &); }; // Specialize PointerLikeTypeTraits for IndexListEntry. template <> - class PointerLikeTypeTraits<IndexListEntry*> { + class PointerLikeTypeTraits<IndexListEntry*> { public: static inline void* getAsVoidPointer(IndexListEntry *p) { return p; @@ -112,13 +120,13 @@ namespace llvm { SlotIndex(IndexListEntry *entry, unsigned slot) : lie(entry, slot) {} - IndexListEntry& entry() const { + IndexListEntry* listEntry() const { assert(isValid() && "Attempt to compare reserved index."); - return *lie.getPointer(); + return lie.getPointer(); } int getIndex() const { - return entry().getIndex() | getSlot(); + return listEntry()->getIndex() | getSlot(); } /// Returns the slot for this SlotIndex. @@ -150,8 +158,7 @@ namespace llvm { SlotIndex() : lie(0, 0) {} // Construct a new slot index from the given one, and set the slot. - SlotIndex(const SlotIndex &li, Slot s) - : lie(&li.entry(), unsigned(s)) { + SlotIndex(const SlotIndex &li, Slot s) : lie(li.listEntry(), unsigned(s)) { assert(lie.getPointer() != 0 && "Attempt to construct index with 0 pointer."); } @@ -179,7 +186,7 @@ namespace llvm { bool operator!=(SlotIndex other) const { return lie != other.lie; } - + /// Compare two SlotIndex objects. Return true if the first index /// is strictly lower than the second. bool operator<(SlotIndex other) const { @@ -211,7 +218,7 @@ namespace llvm { /// isEarlierInstr - Return true if A refers to an instruction earlier than /// B. This is equivalent to A < B && !isSameInstr(A, B). static bool isEarlierInstr(SlotIndex A, SlotIndex B) { - return A.entry().getIndex() < B.entry().getIndex(); + return A.listEntry()->getIndex() < B.listEntry()->getIndex(); } /// Return the distance from this index to the given one. @@ -236,25 +243,25 @@ namespace llvm { /// is the one associated with the Slot_Block slot for the instruction /// pointed to by this index. SlotIndex getBaseIndex() const { - return SlotIndex(&entry(), Slot_Block); + return SlotIndex(listEntry(), Slot_Block); } /// Returns the boundary index for associated with this index. The boundary /// index is the one associated with the Slot_Block slot for the instruction /// pointed to by this index. SlotIndex getBoundaryIndex() const { - return SlotIndex(&entry(), Slot_Dead); + return SlotIndex(listEntry(), Slot_Dead); } /// Returns the register use/def slot in the current instruction for a /// normal or early-clobber def. SlotIndex getRegSlot(bool EC = false) const { - return SlotIndex(&entry(), EC ? Slot_EarlyClobber : Slot_Register); + return SlotIndex(listEntry(), EC ? Slot_EarlyClobber : Slot_Register); } /// Returns the dead def kill slot for the current instruction. SlotIndex getDeadSlot() const { - return SlotIndex(&entry(), Slot_Dead); + return SlotIndex(listEntry(), Slot_Dead); } /// Returns the next slot in the index list. This could be either the @@ -266,15 +273,15 @@ namespace llvm { SlotIndex getNextSlot() const { Slot s = getSlot(); if (s == Slot_Dead) { - return SlotIndex(entry().getNext(), Slot_Block); + return SlotIndex(listEntry()->getNextNode(), Slot_Block); } - return SlotIndex(&entry(), s + 1); + return SlotIndex(listEntry(), s + 1); } /// Returns the next index. This is the index corresponding to the this /// index's slot, but for the next instruction. SlotIndex getNextIndex() const { - return SlotIndex(entry().getNext(), getSlot()); + return SlotIndex(listEntry()->getNextNode(), getSlot()); } /// Returns the previous slot in the index list. This could be either the @@ -286,15 +293,15 @@ namespace llvm { SlotIndex getPrevSlot() const { Slot s = getSlot(); if (s == Slot_Block) { - return SlotIndex(entry().getPrev(), Slot_Dead); + return SlotIndex(listEntry()->getPrevNode(), Slot_Dead); } - return SlotIndex(&entry(), s - 1); + return SlotIndex(listEntry(), s - 1); } /// Returns the previous index. This is the index corresponding to this /// index's slot, but for the previous instruction. SlotIndex getPrevIndex() const { - return SlotIndex(entry().getPrev(), getSlot()); + return SlotIndex(listEntry()->getPrevNode(), getSlot()); } }; @@ -315,7 +322,7 @@ namespace llvm { return (LHS == RHS); } }; - + template <> struct isPodLike<SlotIndex> { static const bool value = true; }; @@ -346,8 +353,10 @@ namespace llvm { class SlotIndexes : public MachineFunctionPass { private: + typedef ilist<IndexListEntry> IndexList; + IndexList indexList; + MachineFunction *mf; - IndexListEntry *indexListHead; unsigned functionSize; typedef DenseMap<const MachineInstr*, SlotIndex> Mi2IndexMap; @@ -374,84 +383,18 @@ namespace llvm { return entry; } - void initList() { - assert(indexListHead == 0 && "Zero entry non-null at initialisation."); - indexListHead = createEntry(0, ~0U); - indexListHead->setNext(0); - indexListHead->setPrev(indexListHead); - } - - void clearList() { - indexListHead = 0; - ileAllocator.Reset(); - } - - IndexListEntry* getTail() { - assert(indexListHead != 0 && "Call to getTail on uninitialized list."); - return indexListHead->getPrev(); - } - - const IndexListEntry* getTail() const { - assert(indexListHead != 0 && "Call to getTail on uninitialized list."); - return indexListHead->getPrev(); - } - - // Returns true if the index list is empty. - bool empty() const { return (indexListHead == getTail()); } - - IndexListEntry* front() { - assert(!empty() && "front() called on empty index list."); - return indexListHead; - } - - const IndexListEntry* front() const { - assert(!empty() && "front() called on empty index list."); - return indexListHead; - } - - IndexListEntry* back() { - assert(!empty() && "back() called on empty index list."); - return getTail()->getPrev(); - } - - const IndexListEntry* back() const { - assert(!empty() && "back() called on empty index list."); - return getTail()->getPrev(); - } - - /// Insert a new entry before itr. - void insert(IndexListEntry *itr, IndexListEntry *val) { - assert(itr != 0 && "itr should not be null."); - IndexListEntry *prev = itr->getPrev(); - val->setNext(itr); - val->setPrev(prev); - - if (itr != indexListHead) { - prev->setNext(val); - } - else { - indexListHead = val; - } - itr->setPrev(val); - } - - /// Push a new entry on to the end of the list. - void push_back(IndexListEntry *val) { - insert(getTail(), val); - } - - /// Renumber locally after inserting newEntry. - void renumberIndexes(IndexListEntry *newEntry); + /// Renumber locally after inserting curItr. + void renumberIndexes(IndexList::iterator curItr); public: static char ID; - SlotIndexes() : MachineFunctionPass(ID), indexListHead(0) { + SlotIndexes() : MachineFunctionPass(ID) { initializeSlotIndexesPass(*PassRegistry::getPassRegistry()); } virtual void getAnalysisUsage(AnalysisUsage &au) const; - virtual void releaseMemory(); + virtual void releaseMemory(); virtual bool runOnMachineFunction(MachineFunction &fn); @@ -463,22 +406,21 @@ namespace llvm { /// Returns the zero index for this analysis. SlotIndex getZeroIndex() { - assert(front()->getIndex() == 0 && "First index is not 0?"); - return SlotIndex(front(), 0); + assert(indexList.front().getIndex() == 0 && "First index is not 0?"); + return SlotIndex(&indexList.front(), 0); } /// Returns the base index of the last slot in this analysis. SlotIndex getLastIndex() { - return SlotIndex(back(), 0); + return SlotIndex(&indexList.back(), 0); } /// Returns the distance between the highest and lowest indexes allocated /// so far. unsigned getIndexesLength() const { - assert(front()->getIndex() == 0 && + assert(indexList.front().getIndex() == 0 && "Initial index isn't zero?"); - - return back()->getIndex(); + return indexList.back().getIndex(); } /// Returns the number of instructions in the function. @@ -503,19 +445,15 @@ namespace llvm { /// Returns the instruction for the given index, or null if the given /// index has no instruction associated with it. MachineInstr* getInstructionFromIndex(SlotIndex index) const { - return index.isValid() ? index.entry().getInstr() : 0; + return index.isValid() ? index.listEntry()->getInstr() : 0; } /// Returns the next non-null index. SlotIndex getNextNonNullIndex(SlotIndex index) { - SlotIndex nextNonNull = index.getNextIndex(); - - while (&nextNonNull.entry() != getTail() && - getInstructionFromIndex(nextNonNull) == 0) { - nextNonNull = nextNonNull.getNextIndex(); - } - - return nextNonNull; + IndexList::iterator itr(index.listEntry()); + ++itr; + while (itr != indexList.end() && itr->getInstr() == 0) { ++itr; } + return SlotIndex(itr, index.getSlot()); } /// getIndexBefore - Returns the index of the last indexed instruction @@ -659,31 +597,31 @@ namespace llvm { assert(mi->getParent() != 0 && "Instr must be added to function."); // Get the entries where mi should be inserted. - IndexListEntry *prevEntry, *nextEntry; + IndexList::iterator prevItr, nextItr; if (Late) { // Insert mi's index immediately before the following instruction. - nextEntry = &getIndexAfter(mi).entry(); - prevEntry = nextEntry->getPrev(); + nextItr = getIndexAfter(mi).listEntry(); + prevItr = prior(nextItr); } else { // Insert mi's index immediately after the preceeding instruction. - prevEntry = &getIndexBefore(mi).entry(); - nextEntry = prevEntry->getNext(); + prevItr = getIndexBefore(mi).listEntry(); + nextItr = llvm::next(prevItr); } // Get a number for the new instr, or 0 if there's no room currently. // In the latter case we'll force a renumber later. - unsigned dist = ((nextEntry->getIndex() - prevEntry->getIndex())/2) & ~3u; - unsigned newNumber = prevEntry->getIndex() + dist; + unsigned dist = ((nextItr->getIndex() - prevItr->getIndex())/2) & ~3u; + unsigned newNumber = prevItr->getIndex() + dist; // Insert a new list entry for mi. - IndexListEntry *newEntry = createEntry(mi, newNumber); - insert(nextEntry, newEntry); + IndexList::iterator newItr = + indexList.insert(nextItr, createEntry(mi, newNumber)); // Renumber locally if we need to. if (dist == 0) - renumberIndexes(newEntry); + renumberIndexes(newItr); - SlotIndex newIndex(newEntry, SlotIndex::Slot_Block); + SlotIndex newIndex(&*newItr, SlotIndex::Slot_Block); mi2iMap.insert(std::make_pair(mi, newIndex)); return newIndex; } @@ -694,7 +632,7 @@ namespace llvm { // MachineInstr -> index mappings Mi2IndexMap::iterator mi2iItr = mi2iMap.find(mi); if (mi2iItr != mi2iMap.end()) { - IndexListEntry *miEntry(&mi2iItr->second.entry()); + IndexListEntry *miEntry(mi2iItr->second.listEntry()); assert(miEntry->getInstr() == mi && "Instruction indexes broken."); // FIXME: Eventually we want to actually delete these indexes. miEntry->setInstr(0); @@ -709,7 +647,7 @@ namespace llvm { if (mi2iItr == mi2iMap.end()) return; SlotIndex replaceBaseIndex = mi2iItr->second; - IndexListEntry *miEntry(&replaceBaseIndex.entry()); + IndexListEntry *miEntry(replaceBaseIndex.listEntry()); assert(miEntry->getInstr() == mi && "Mismatched instruction in index tables."); miEntry->setInstr(newMI); @@ -726,13 +664,13 @@ namespace llvm { IndexListEntry *nextEntry = 0; if (nextMBB == mbb->getParent()->end()) { - nextEntry = getTail(); + nextEntry = indexList.end(); } else { - nextEntry = &getMBBStartIdx(nextMBB).entry(); + nextEntry = getMBBStartIdx(nextMBB).listEntry(); } - insert(nextEntry, startEntry); - insert(nextEntry, stopEntry); + indexList.insert(nextEntry, startEntry); + indexList.insert(nextEntry, stopEntry); SlotIndex startIdx(startEntry, SlotIndex::Slot_Block); SlotIndex endIdx(nextEntry, SlotIndex::Slot_Block); @@ -766,4 +704,4 @@ namespace llvm { } -#endif // LLVM_CODEGEN_LIVEINDEX_H +#endif // LLVM_CODEGEN_SLOTINDEXES_H |