diff options
Diffstat (limited to 'include/llvm/CodeGen')
21 files changed, 317 insertions, 103 deletions
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index e0a6e3f..c2fd6ce 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -25,6 +25,7 @@ namespace llvm { class BlockAddress; class GCStrategy; class Constant; + class ConstantArray; class GCMetadataPrinter; class GlobalValue; class GlobalVariable; @@ -134,6 +135,9 @@ namespace llvm { /// getDataLayout - Return information about data layout. const DataLayout &getDataLayout() const; + /// getTargetTriple - Return the target triple string. + StringRef getTargetTriple() const; + /// getCurrentSection() - Return the current section we are emitting to. const MCSection *getCurrentSection() const; @@ -480,7 +484,7 @@ namespace llvm { void EmitJumpTableEntry(const MachineJumpTableInfo *MJTI, const MachineBasicBlock *MBB, unsigned uid) const; - void EmitLLVMUsedList(const Constant *List); + void EmitLLVMUsedList(const ConstantArray *InitList); void EmitXXStructorList(const Constant *List, bool isCtor); GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy *C); }; diff --git a/include/llvm/CodeGen/CallingConvLower.h b/include/llvm/CodeGen/CallingConvLower.h index c035e07..fa9d60f 100644 --- a/include/llvm/CodeGen/CallingConvLower.h +++ b/include/llvm/CodeGen/CallingConvLower.h @@ -163,8 +163,56 @@ private: unsigned StackOffset; SmallVector<uint32_t, 16> UsedRegs; - unsigned FirstByValReg; - bool FirstByValRegValid; + + // ByValInfo and SmallVector<ByValInfo, 4> ByValRegs: + // + // Vector of ByValInfo instances (ByValRegs) is introduced for byval registers + // tracking. + // Or, in another words it tracks byval parameters that are stored in + // general purpose registers. + // + // For 4 byte stack alignment, + // instance index means byval parameter number in formal + // arguments set. Assume, we have some "struct_type" with size = 4 bytes, + // then, for function "foo": + // + // i32 foo(i32 %p, %struct_type* %r, i32 %s, %struct_type* %t) + // + // ByValRegs[0] describes how "%r" is stored (Begin == r1, End == r2) + // ByValRegs[1] describes how "%t" is stored (Begin == r3, End == r4). + // + // In case of 8 bytes stack alignment, + // ByValRegs may also contain information about wasted registers. + // In function shown above, r3 would be wasted according to AAPCS rules. + // And in that case ByValRegs[1].Waste would be "true". + // ByValRegs vector size still would be 2, + // while "%t" goes to the stack: it wouldn't be described in ByValRegs. + // + // Supposed use-case for this collection: + // 1. Initially ByValRegs is empty, InRegsParamsProceed is 0. + // 2. HandleByVal fillups ByValRegs. + // 3. Argument analysis (LowerFormatArguments, for example). After + // some byval argument was analyzed, InRegsParamsProceed is increased. + struct ByValInfo { + ByValInfo(unsigned B, unsigned E, bool IsWaste = false) : + Begin(B), End(E), Waste(IsWaste) {} + // First register allocated for current parameter. + unsigned Begin; + + // First after last register allocated for current parameter. + unsigned End; + + // Means that current range of registers doesn't belong to any + // parameters. It was wasted due to stack alignment rules. + // For more information see: + // AAPCS, 5.5 Parameter Passing, Stage C, C.3. + bool Waste; + }; + SmallVector<ByValInfo, 4 > ByValRegs; + + // InRegsParamsProceed - shows how many instances of ByValRegs was proceed + // during argument analysis. + unsigned InRegsParamsProceed; protected: ParmContext CallOrPrologue; @@ -306,12 +354,45 @@ public: MVT LocVT, CCValAssign::LocInfo LocInfo, int MinSize, int MinAlign, ISD::ArgFlagsTy ArgFlags); - // First GPR that carries part of a byval aggregate that's split - // between registers and memory. - unsigned getFirstByValReg() const { return FirstByValRegValid ? FirstByValReg : 0; } - void setFirstByValReg(unsigned r) { FirstByValReg = r; FirstByValRegValid = true; } - void clearFirstByValReg() { FirstByValReg = 0; FirstByValRegValid = false; } - bool isFirstByValRegValid() const { return FirstByValRegValid; } + // Returns count of byval arguments that are to be stored (even partly) + // in registers. + unsigned getInRegsParamsCount() const { return ByValRegs.size(); } + + // Returns count of byval in-regs arguments proceed. + unsigned getInRegsParamsProceed() const { return InRegsParamsProceed; } + + // Get information about N-th byval parameter that is stored in registers. + // Here "ByValParamIndex" is N. + void getInRegsParamInfo(unsigned InRegsParamRecordIndex, + unsigned& BeginReg, unsigned& EndReg) const { + assert(InRegsParamRecordIndex < ByValRegs.size() && + "Wrong ByVal parameter index"); + + const ByValInfo& info = ByValRegs[InRegsParamRecordIndex]; + BeginReg = info.Begin; + EndReg = info.End; + } + + // Add information about parameter that is kept in registers. + void addInRegsParamInfo(unsigned RegBegin, unsigned RegEnd) { + ByValRegs.push_back(ByValInfo(RegBegin, RegEnd)); + } + + // Goes either to next byval parameter (excluding "waste" record), or + // to the end of collection. + // Returns false, if end is reached. + bool nextInRegsParam() { + unsigned e = ByValRegs.size(); + if (InRegsParamsProceed < e) + ++InRegsParamsProceed; + return InRegsParamsProceed < e; + } + + // Clear byval registers tracking info. + void clearByValRegsInfo() { + InRegsParamsProceed = 0; + ByValRegs.clear(); + } ParmContext getCallOrPrologue() const { return CallOrPrologue; } diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h index 705db7e..471e9bf 100644 --- a/include/llvm/CodeGen/FastISel.h +++ b/include/llvm/CodeGen/FastISel.h @@ -123,12 +123,28 @@ public: /// index value. std::pair<unsigned, bool> getRegForGEPIndex(const Value *V); - /// TryToFoldLoad - The specified machine instr operand is a vreg, and that + /// \brief We're checking to see if we can fold \p LI into \p FoldInst. + /// Note that we could have a sequence where multiple LLVM IR instructions + /// are folded into the same machineinstr. For example we could have: + /// A: x = load i32 *P + /// B: y = icmp A, 42 + /// C: br y, ... + /// + /// In this scenario, \p LI is "A", and \p FoldInst is "C". We know + /// about "B" (and any other folded instructions) because it is between + /// A and C. + /// + /// If we succeed folding, return true. + /// + bool tryToFoldLoad(const LoadInst *LI, const Instruction *FoldInst); + + /// \brief The specified machine instr operand is a vreg, and that /// vreg is being provided by the specified load instruction. If possible, /// try to fold the load as an operand to the instruction, returning true if /// possible. - virtual bool TryToFoldLoad(MachineInstr * /*MI*/, unsigned /*OpNo*/, - const LoadInst * /*LI*/) { + /// This method should be implemented by targets. + virtual bool tryToFoldLoadIntoMI(MachineInstr * /*MI*/, unsigned /*OpNo*/, + const LoadInst * /*LI*/) { return false; } diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h index 442729b..0fd211b 100644 --- a/include/llvm/CodeGen/ISDOpcodes.h +++ b/include/llvm/CodeGen/ISDOpcodes.h @@ -602,14 +602,6 @@ namespace ISD { /// specifier. PREFETCH, - /// OUTCHAIN = MEMBARRIER(INCHAIN, load-load, load-store, store-load, - /// store-store, device) - /// This corresponds to the memory.barrier intrinsic. - /// it takes an input chain, 4 operands to specify the type of barrier, an - /// operand specifying if the barrier applies to device and uncached memory - /// and produces an output chain. - MEMBARRIER, - /// OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) /// This corresponds to the fence instruction. It takes an input chain, and /// two integer constants: an AtomicOrdering and a SynchronizationScope. diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h index 244be9c..cb09a49 100644 --- a/include/llvm/CodeGen/LiveInterval.h +++ b/include/llvm/CodeGen/LiveInterval.h @@ -399,6 +399,15 @@ namespace llvm { return r != end() && r->containsRange(Start, End); } + /// True iff this live range is a single segment that lies between the + /// specified boundaries, exclusively. Vregs live across a backedge are not + /// considered local. The boundaries are expected to lie within an extended + /// basic block, so vregs that are not live out should contain no holes. + bool isLocal(SlotIndex Start, SlotIndex End) const { + return beginIndex() > Start.getBaseIndex() && + endIndex() < End.getBoundaryIndex(); + } + /// removeRange - Remove the specified range from this interval. Note that /// the range must be a single LiveRange in its entirety. void removeRange(SlotIndex Start, SlotIndex End, diff --git a/include/llvm/CodeGen/LiveRangeEdit.h b/include/llvm/CodeGen/LiveRangeEdit.h index 8a32a3c..e59276f 100644 --- a/include/llvm/CodeGen/LiveRangeEdit.h +++ b/include/llvm/CodeGen/LiveRangeEdit.h @@ -196,8 +196,7 @@ public: /// 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>()); + ArrayRef<unsigned> RegsBeingSpilled = None); /// calculateRegClassAndHint - Recompute register class and hint for each new /// register. diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h index 492a3ff..0f2f874 100644 --- a/include/llvm/CodeGen/MachineBasicBlock.h +++ b/include/llvm/CodeGen/MachineBasicBlock.h @@ -71,7 +71,6 @@ class MachineBasicBlock : public ilist_node<MachineBasicBlock> { std::vector<MachineBasicBlock *> Predecessors; std::vector<MachineBasicBlock *> Successors; - /// Weights - Keep track of the weights to the successors. This vector /// has the same order as Successors, or it is empty if we don't use it /// (disable optimization). @@ -96,6 +95,10 @@ class MachineBasicBlock : public ilist_node<MachineBasicBlock> { /// target of an indirect branch. bool AddressTaken; + /// \brief since getSymbol is a relatively heavy-weight operation, the symbol + /// is only computed once and is cached. + mutable MCSymbol *CachedMCSymbol; + // Intrusive list support MachineBasicBlock() {} diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h index 82c4cd6..c886e25 100644 --- a/include/llvm/CodeGen/MachineFunction.h +++ b/include/llvm/CodeGen/MachineFunction.h @@ -352,8 +352,8 @@ public: // Internal functions used to automatically number MachineBasicBlocks // - /// getNextMBBNumber - Returns the next unique number to be assigned - /// to a MachineBasicBlock in this MachineFunction. + /// \brief Adds the MBB to the internal numbering. Returns the unique number + /// assigned to the MBB. /// unsigned addToMBBNumbering(MachineBasicBlock *MBB) { MBBNumbering.push_back(MBB); diff --git a/include/llvm/CodeGen/MachineMemOperand.h b/include/llvm/CodeGen/MachineMemOperand.h index ddb1271..00a55b5 100644 --- a/include/llvm/CodeGen/MachineMemOperand.h +++ b/include/llvm/CodeGen/MachineMemOperand.h @@ -34,22 +34,22 @@ struct MachinePointerInfo { /// If this is null, then the access is to a pointer in the default address /// space. const Value *V; - + /// Offset - This is an offset from the base Value*. int64_t Offset; - + explicit MachinePointerInfo(const Value *v = 0, int64_t offset = 0) : V(v), Offset(offset) {} - + MachinePointerInfo getWithOffset(int64_t O) const { if (V == 0) return MachinePointerInfo(0, 0); return MachinePointerInfo(V, Offset+O); } - + /// getAddrSpace - Return the LLVM IR address space number that this pointer /// points into. unsigned getAddrSpace() const; - + /// getConstantPool - Return a MachinePointerInfo record that refers to the /// constant pool. static MachinePointerInfo getConstantPool(); @@ -57,20 +57,20 @@ struct MachinePointerInfo { /// getFixedStack - Return a MachinePointerInfo record that refers to the /// the specified FrameIndex. static MachinePointerInfo getFixedStack(int FI, int64_t offset = 0); - + /// getJumpTable - Return a MachinePointerInfo record that refers to a /// jump table entry. static MachinePointerInfo getJumpTable(); - + /// getGOT - Return a MachinePointerInfo record that refers to a /// GOT entry. static MachinePointerInfo getGOT(); - + /// getStack - stack pointer relative access. static MachinePointerInfo getStack(int64_t Offset); }; - - + + //===----------------------------------------------------------------------===// /// MachineMemOperand - A description of a memory reference used in the backend. /// Instead of holding a StoreInst or LoadInst, this class holds the address @@ -99,8 +99,11 @@ public: MONonTemporal = 8, /// The memory access is invariant. MOInvariant = 16, + // Target hints allow target passes to annotate memory operations. + MOTargetStartBit = 5, + MOTargetNumBits = 3, // This is the number of bits we need to represent flags. - MOMaxBits = 5 + MOMaxBits = 8 }; /// MachineMemOperand - Construct an MachineMemOperand object with the @@ -110,7 +113,7 @@ public: const MDNode *Ranges = 0); const MachinePointerInfo &getPointerInfo() const { return PtrInfo; } - + /// getValue - Return the base address of the memory access. This may either /// be a normal LLVM IR Value, or one of the special values used in CodeGen. /// Special values are those obtained via @@ -123,6 +126,9 @@ public: /// getFlags - Return the raw flags of the source value, \see MemOperandFlags. unsigned int getFlags() const { return Flags & ((1 << MOMaxBits) - 1); } + /// Bitwise OR the current flags with the given flags. + void setFlags(unsigned f) { Flags |= (f & ((1 << MOMaxBits) - 1)); } + /// getOffset - For normal values, this is a byte offset added to the base /// address. For PseudoSourceValue::FPRel values, this is the FrameIndex /// number. diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h index 4b43cc1..24ba7bb 100644 --- a/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/include/llvm/CodeGen/MachineRegisterInfo.h @@ -157,6 +157,12 @@ public: // Strictly for use by MachineInstr.cpp. void moveOperands(MachineOperand *Dst, MachineOperand *Src, unsigned NumOps); + /// Verify the sanity of the use list for Reg. + void verifyUseList(unsigned Reg) const; + + /// Verify the use list of all registers. + void verifyUseLists() const; + /// reg_begin/reg_end - Provide iteration support to walk over all definitions /// and uses of a register within the MachineFunction that corresponds to this /// MachineRegisterInfo object. diff --git a/include/llvm/CodeGen/MachineScheduler.h b/include/llvm/CodeGen/MachineScheduler.h index 57febe7..769e4b4 100644 --- a/include/llvm/CodeGen/MachineScheduler.h +++ b/include/llvm/CodeGen/MachineScheduler.h @@ -274,6 +274,10 @@ public: Mutations.push_back(Mutation); } + /// \brief True if an edge can be added from PredSU to SuccSU without creating + /// a cycle. + bool canAddEdge(SUnit *SuccSU, SUnit *PredSU); + /// \brief Add a DAG edge to the given SU with the given predecessor /// dependence data. /// @@ -297,6 +301,10 @@ public: /// reorderable instructions. virtual void schedule(); + /// Change the position of an instruction within the basic block and update + /// live ranges and region boundary iterators. + void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator InsertPos); + /// Get current register pressure for the top scheduled instructions. const IntervalPressure &getTopPressure() const { return TopPressure; } const RegPressureTracker &getTopRPTracker() const { return TopRPTracker; } @@ -362,7 +370,6 @@ protected: void updateScheduledPressure(const std::vector<unsigned> &NewMaxPressure); - void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator InsertPos); bool checkSchedLimit(); void findRootsAndBiasEdges(SmallVectorImpl<SUnit*> &TopRoots, diff --git a/include/llvm/CodeGen/MachineTraceMetrics.h b/include/llvm/CodeGen/MachineTraceMetrics.h index 2775a04..9794707 100644 --- a/include/llvm/CodeGen/MachineTraceMetrics.h +++ b/include/llvm/CodeGen/MachineTraceMetrics.h @@ -260,9 +260,12 @@ public: /// independent, exposing the maximum instruction-level parallelism. /// /// Any blocks in Extrablocks are included as if they were part of the - /// trace. - unsigned getResourceLength(ArrayRef<const MachineBasicBlock*> Extrablocks = - ArrayRef<const MachineBasicBlock*>()) const; + /// trace. Likewise, extra resources required by the specified scheduling + /// classes are included. For the caller to account for extra machine + /// instructions, it must first resolve each instruction's scheduling class. + unsigned getResourceLength( + ArrayRef<const MachineBasicBlock*> Extrablocks = None, + ArrayRef<const MCSchedClassDesc*> ExtraInstrs = None) const; /// Return the length of the (data dependency) critical path through the /// trace. diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index fc8aa75..b02f63e 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -35,6 +35,48 @@ namespace llvm { class PassConfigImpl; +/// Discriminated union of Pass ID types. +/// +/// The PassConfig API prefers dealing with IDs because they are safer and more +/// efficient. IDs decouple configuration from instantiation. This way, when a +/// pass is overriden, it isn't unnecessarily instantiated. It is also unsafe to +/// refer to a Pass pointer after adding it to a pass manager, which deletes +/// redundant pass instances. +/// +/// However, it is convient to directly instantiate target passes with +/// non-default ctors. These often don't have a registered PassInfo. Rather than +/// force all target passes to implement the pass registry boilerplate, allow +/// the PassConfig API to handle either type. +/// +/// AnalysisID is sadly char*, so PointerIntPair won't work. +class IdentifyingPassPtr { + union { + AnalysisID ID; + Pass *P; + }; + bool IsInstance; +public: + IdentifyingPassPtr() : P(0), IsInstance(false) {} + IdentifyingPassPtr(AnalysisID IDPtr) : ID(IDPtr), IsInstance(false) {} + IdentifyingPassPtr(Pass *InstancePtr) : P(InstancePtr), IsInstance(true) {} + + bool isValid() const { return P; } + bool isInstance() const { return IsInstance; } + + AnalysisID getID() const { + assert(!IsInstance && "Not a Pass ID"); + return ID; + } + Pass *getInstance() const { + assert(IsInstance && "Not a Pass Instance"); + return P; + } +}; + +template <> struct isPodLike<IdentifyingPassPtr> { + static const bool value = true; +}; + /// Target-Independent Code Generator Pass Configuration Options. /// /// This is an ImmutablePass solely for the purpose of exposing CodeGen options @@ -117,20 +159,22 @@ public: /// Allow the target to override a specific pass without overriding the pass /// pipeline. When passes are added to the standard pipeline at the /// point where StandardID is expected, add TargetID in its place. - void substitutePass(AnalysisID StandardID, AnalysisID TargetID); + void substitutePass(AnalysisID StandardID, IdentifyingPassPtr TargetID); /// Insert InsertedPassID pass after TargetPassID pass. - void insertPass(AnalysisID TargetPassID, AnalysisID InsertedPassID); + void insertPass(AnalysisID TargetPassID, IdentifyingPassPtr InsertedPassID); /// Allow the target to enable a specific standard pass by default. void enablePass(AnalysisID PassID) { substitutePass(PassID, PassID); } /// Allow the target to disable a specific standard pass by default. - void disablePass(AnalysisID PassID) { substitutePass(PassID, 0); } + void disablePass(AnalysisID PassID) { + substitutePass(PassID, IdentifyingPassPtr()); + } /// Return the pass substituted for StandardID by the target. /// If no substitution exists, return StandardID. - AnalysisID getPassSubstitution(AnalysisID StandardID) const; + IdentifyingPassPtr getPassSubstitution(AnalysisID StandardID) const; /// Return true if the optimized regalloc pipeline is enabled. bool getOptimizeRegAlloc() const; @@ -222,17 +266,6 @@ protected: return false; } - /// addFinalizeRegAlloc - This method may be implemented by targets that want - /// to run passes within the regalloc pipeline, immediately after the register - /// allocation pass itself. These passes run as soon as virtual regisiters - /// have been rewritten to physical registers but before and other postRA - /// optimization happens. Targets that have marked instructions for bundling - /// must have finalized those bundles by the time these passes have run, - /// because subsequent passes are not guaranteed to be bundle-aware. - virtual bool addFinalizeRegAlloc() { - return false; - } - /// addPostRegAlloc - This method may be implemented by targets that want to /// run passes after register allocation pass pipeline but before /// prolog-epilog insertion. This should return true if -print-machineinstrs diff --git a/include/llvm/CodeGen/RegAllocPBQP.h b/include/llvm/CodeGen/RegAllocPBQP.h index b617c14..8b8e3d9 100644 --- a/include/llvm/CodeGen/RegAllocPBQP.h +++ b/include/llvm/CodeGen/RegAllocPBQP.h @@ -29,6 +29,7 @@ namespace llvm { class MachineFunction; class MachineLoopInfo; class TargetRegisterInfo; + template<class T> class OwningPtr; /// This class wraps up a PBQP instance representing a register allocation /// problem, plus the structures necessary to map back from the PBQP solution @@ -123,11 +124,9 @@ namespace llvm { /// Build a PBQP instance to represent the register allocation problem for /// the given MachineFunction. - virtual std::auto_ptr<PBQPRAProblem> build( - MachineFunction *mf, - const LiveIntervals *lis, - const MachineLoopInfo *loopInfo, - const RegSet &vregs); + virtual PBQPRAProblem *build(MachineFunction *mf, const LiveIntervals *lis, + const MachineLoopInfo *loopInfo, + const RegSet &vregs); private: void addSpillCosts(PBQP::Vector &costVec, PBQP::PBQPNum spillCost); @@ -144,11 +143,9 @@ namespace llvm { /// Build a PBQP instance to represent the register allocation problem for /// the given MachineFunction. - virtual std::auto_ptr<PBQPRAProblem> build( - MachineFunction *mf, - const LiveIntervals *lis, - const MachineLoopInfo *loopInfo, - const RegSet &vregs); + virtual PBQPRAProblem *build(MachineFunction *mf, const LiveIntervals *lis, + const MachineLoopInfo *loopInfo, + const RegSet &vregs); private: @@ -161,7 +158,7 @@ namespace llvm { PBQP::PBQPNum benefit); }; - FunctionPass* createPBQPRegisterAllocator(std::auto_ptr<PBQPBuilder> builder, + FunctionPass* createPBQPRegisterAllocator(OwningPtr<PBQPBuilder> &builder, char *customPassID=0); } diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h index 8c959da..7cff27e 100644 --- a/include/llvm/CodeGen/ScheduleDAG.h +++ b/include/llvm/CodeGen/ScheduleDAG.h @@ -302,6 +302,7 @@ namespace llvm { bool isCallOp : 1; // Is a function call operand. bool isTwoAddress : 1; // Is a two-address instruction. bool isCommutable : 1; // Is a commutable instruction. + bool hasPhysRegUses : 1; // Has physreg uses. bool hasPhysRegDefs : 1; // Has physreg defs that are being used. bool hasPhysRegClobbers : 1; // Has any physreg defs, used or not. bool isPending : 1; // True once pending. @@ -331,10 +332,10 @@ namespace llvm { NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0), NumRegDefsLeft(0), Latency(0), isVRegCycle(false), isCall(false), isCallOp(false), - isTwoAddress(false), isCommutable(false), hasPhysRegDefs(false), - hasPhysRegClobbers(false), isPending(false), isAvailable(false), - isScheduled(false), isScheduleHigh(false), isScheduleLow(false), - isCloned(false), SchedulingPref(Sched::None), + isTwoAddress(false), isCommutable(false), hasPhysRegUses(false), + hasPhysRegDefs(false), hasPhysRegClobbers(false), isPending(false), + isAvailable(false), isScheduled(false), isScheduleHigh(false), + isScheduleLow(false), isCloned(false), SchedulingPref(Sched::None), isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0), TopReadyCycle(0), BotReadyCycle(0), CopyDstRC(NULL), CopySrcRC(NULL) {} @@ -345,10 +346,10 @@ namespace llvm { NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0), NumRegDefsLeft(0), Latency(0), isVRegCycle(false), isCall(false), isCallOp(false), - isTwoAddress(false), isCommutable(false), hasPhysRegDefs(false), - hasPhysRegClobbers(false), isPending(false), isAvailable(false), - isScheduled(false), isScheduleHigh(false), isScheduleLow(false), - isCloned(false), SchedulingPref(Sched::None), + isTwoAddress(false), isCommutable(false), hasPhysRegUses(false), + hasPhysRegDefs(false), hasPhysRegClobbers(false), isPending(false), + isAvailable(false), isScheduled(false), isScheduleHigh(false), + isScheduleLow(false), isCloned(false), SchedulingPref(Sched::None), isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0), TopReadyCycle(0), BotReadyCycle(0), CopyDstRC(NULL), CopySrcRC(NULL) {} @@ -358,10 +359,10 @@ namespace llvm { NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0), NumRegDefsLeft(0), Latency(0), isVRegCycle(false), isCall(false), isCallOp(false), - isTwoAddress(false), isCommutable(false), hasPhysRegDefs(false), - hasPhysRegClobbers(false), isPending(false), isAvailable(false), - isScheduled(false), isScheduleHigh(false), isScheduleLow(false), - isCloned(false), SchedulingPref(Sched::None), + isTwoAddress(false), isCommutable(false), hasPhysRegUses(false), + hasPhysRegDefs(false), hasPhysRegClobbers(false), isPending(false), + isAvailable(false), isScheduled(false), isScheduleHigh(false), + isScheduleLow(false), isCloned(false), SchedulingPref(Sched::None), isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0), TopReadyCycle(0), BotReadyCycle(0), CopyDstRC(NULL), CopySrcRC(NULL) {} @@ -726,9 +727,8 @@ namespace llvm { /// IsReachable - Checks if SU is reachable from TargetSU. bool IsReachable(const SUnit *SU, const SUnit *TargetSU); - /// WillCreateCycle - Returns true if adding an edge from SU to TargetSU - /// will create a cycle. - bool WillCreateCycle(SUnit *SU, SUnit *TargetSU); + /// WillCreateCycle - Return true if addPred(TargetSU, SU) creates a cycle. + bool WillCreateCycle(SUnit *TargetSU, SUnit *SU); /// AddPred - Updates the topological ordering to accommodate an edge /// to be added from SUnit X to SUnit Y. diff --git a/include/llvm/CodeGen/ScheduleDAGInstrs.h b/include/llvm/CodeGen/ScheduleDAGInstrs.h index 2219520..990cac6 100644 --- a/include/llvm/CodeGen/ScheduleDAGInstrs.h +++ b/include/llvm/CodeGen/ScheduleDAGInstrs.h @@ -105,6 +105,10 @@ namespace llvm { MachineBasicBlock::iterator RegionEnd; /// The index in BB of RegionEnd. + /// + /// This is the instruction number from the top of the current block, not + /// the SlotIndex. It is only used by the AntiDepBreaker and should be + /// removed once that client is obsolete. unsigned EndIndex; /// After calling BuildSchedGraph, each machine instruction in the current @@ -146,6 +150,9 @@ namespace llvm { virtual ~ScheduleDAGInstrs() {} + /// \brief Expose LiveIntervals for use in DAG mutators and such. + LiveIntervals *getLIS() const { return LIS; } + /// \brief Get the machine model for instruction scheduling. const TargetSchedModel *getSchedModel() const { return &SchedModel; } diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index e5adf67..8c064bf 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -810,31 +810,32 @@ public: MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT, SDValue Op1, SDValue Op2); MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT, - SDValue Op1, SDValue Op2, SDValue Op3); + SDValue Op1, SDValue Op2, SDValue Op3); MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT, - const SDValue *Ops, unsigned NumOps); + ArrayRef<SDValue> Ops); MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2); MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2, - SDValue Op1); - MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, - EVT VT2, SDValue Op1, SDValue Op2); - MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, - EVT VT2, SDValue Op1, SDValue Op2, SDValue Op3); + SDValue Op1); + MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2, + SDValue Op1, SDValue Op2); + MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2, + SDValue Op1, SDValue Op2, SDValue Op3); MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2, - const SDValue *Ops, unsigned NumOps); + ArrayRef<SDValue> Ops); MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2, - EVT VT3, SDValue Op1, SDValue Op2); + EVT VT3, SDValue Op1, SDValue Op2); MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2, - EVT VT3, SDValue Op1, SDValue Op2, SDValue Op3); + EVT VT3, SDValue Op1, SDValue Op2, + SDValue Op3); MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2, - EVT VT3, const SDValue *Ops, unsigned NumOps); + EVT VT3, ArrayRef<SDValue> Ops); MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2, - EVT VT3, EVT VT4, const SDValue *Ops, unsigned NumOps); + EVT VT3, EVT VT4, ArrayRef<SDValue> Ops); MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, - ArrayRef<EVT> ResultTys, const SDValue *Ops, - unsigned NumOps); + ArrayRef<EVT> ResultTys, + ArrayRef<SDValue> Ops); MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, SDVTList VTs, - const SDValue *Ops, unsigned NumOps); + ArrayRef<SDValue> Ops); /// getTargetExtractSubreg - A convenience function for creating /// TargetInstrInfo::EXTRACT_SUBREG nodes. diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h index 5f503de..a4721db 100644 --- a/include/llvm/CodeGen/SelectionDAGISel.h +++ b/include/llvm/CodeGen/SelectionDAGISel.h @@ -259,9 +259,6 @@ private: void SelectBasicBlock(BasicBlock::const_iterator Begin, BasicBlock::const_iterator End, bool &HadTailCall); - - bool TryToFoldFastISelLoad(const LoadInst *LI, const Instruction *FoldInst, - FastISel *FastIS); void FinishBasicBlock(); void CodeGenAndEmitDAG(); diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h index a277080..26d0433 100644 --- a/include/llvm/CodeGen/SlotIndexes.h +++ b/include/llvm/CodeGen/SlotIndexes.h @@ -53,6 +53,20 @@ namespace llvm { this->index = index; } +#ifdef EXPENSIVE_CHECKS + // When EXPENSIVE_CHECKS is defined, "erased" index list entries will + // actually be moved to a "graveyard" list, and have their pointers + // poisoned, so that dangling SlotIndex access can be reliably detected. + void setPoison() { + intptr_t tmp = reinterpret_cast<intptr_t>(mi); + assert(((tmp & 0x1) == 0x0) && "Pointer already poisoned?"); + tmp |= 0x1; + mi = reinterpret_cast<MachineInstr*>(tmp); + } + + bool isPoisoned() const { return (reinterpret_cast<intptr_t>(mi) & 0x1) == 0x1; } +#endif // EXPENSIVE_CHECKS + }; template <> @@ -109,6 +123,10 @@ namespace llvm { IndexListEntry* listEntry() const { assert(isValid() && "Attempt to compare reserved index."); +#ifdef EXPENSIVE_CHECKS + assert(!lie.getPointer()->isPoisoned() && + "Attempt to access deleted list-entry."); +#endif // EXPENSIVE_CHECKS return lie.getPointer(); } @@ -282,7 +300,6 @@ namespace llvm { template <> struct isPodLike<SlotIndex> { static const bool value = true; }; - inline raw_ostream& operator<<(raw_ostream &os, SlotIndex li) { li.print(os); return os; @@ -313,6 +330,10 @@ namespace llvm { typedef ilist<IndexListEntry> IndexList; IndexList indexList; +#ifdef EXPENSIVE_CHECKS + IndexList graveyardList; +#endif // EXPENSIVE_CHECKS + MachineFunction *mf; typedef DenseMap<const MachineInstr*, SlotIndex> Mi2IndexMap; @@ -643,6 +664,32 @@ namespace llvm { std::sort(idx2MBBMap.begin(), idx2MBBMap.end(), Idx2MBBCompare()); } + /// \brief Free the resources that were required to maintain a SlotIndex. + /// + /// Once an index is no longer needed (for instance because the instruction + /// at that index has been moved), the resources required to maintain the + /// index can be relinquished to reduce memory use and improve renumbering + /// performance. Any remaining SlotIndex objects that point to the same + /// index are left 'dangling' (much the same as a dangling pointer to a + /// freed object) and should not be accessed, except to destruct them. + /// + /// Like dangling pointers, access to dangling SlotIndexes can cause + /// painful-to-track-down bugs, especially if the memory for the index + /// previously pointed to has been re-used. To detect dangling SlotIndex + /// bugs, build with EXPENSIVE_CHECKS=1. This will cause "erased" indexes to + /// be retained in a graveyard instead of being freed. Operations on indexes + /// in the graveyard will trigger an assertion. + void eraseIndex(SlotIndex index) { + IndexListEntry *entry = index.listEntry(); +#ifdef EXPENSIVE_CHECKS + indexList.remove(entry); + graveyardList.push_back(entry); + entry->setPoison(); +#else + indexList.erase(entry); +#endif + } + }; diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index e7098e4..5b22c9c 100644 --- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -128,6 +128,12 @@ public: virtual const MCSection * SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, Mangler *Mang, const TargetMachine &TM) const; + + /// emitModuleFlags - Emit Obj-C garbage collection and linker options. Only + /// linker option emission is implemented for COFF. + virtual void emitModuleFlags(MCStreamer &Streamer, + ArrayRef<Module::ModuleFlagEntry> ModuleFlags, + Mangler *Mang, const TargetMachine &TM) const; }; } // end namespace llvm diff --git a/include/llvm/CodeGen/ValueTypes.td b/include/llvm/CodeGen/ValueTypes.td index 76df6ac..da26985 100644 --- a/include/llvm/CodeGen/ValueTypes.td +++ b/include/llvm/CodeGen/ValueTypes.td @@ -44,13 +44,13 @@ def v4i8 : ValueType<32 , 20>; // 4 x i8 vector value def v8i8 : ValueType<64 , 21>; // 8 x i8 vector value def v16i8 : ValueType<128, 22>; // 16 x i8 vector value def v32i8 : ValueType<256, 23>; // 32 x i8 vector value -def v64i8 : ValueType<256, 24>; // 64 x i8 vector value +def v64i8 : ValueType<512, 24>; // 64 x i8 vector value def v1i16 : ValueType<16 , 25>; // 1 x i16 vector value def v2i16 : ValueType<32 , 26>; // 2 x i16 vector value def v4i16 : ValueType<64 , 27>; // 4 x i16 vector value def v8i16 : ValueType<128, 28>; // 8 x i16 vector value def v16i16 : ValueType<256, 29>; // 16 x i16 vector value -def v32i16 : ValueType<256, 30>; // 32 x i16 vector value +def v32i16 : ValueType<512, 30>; // 32 x i16 vector value def v1i32 : ValueType<32 , 31>; // 1 x i32 vector value def v2i32 : ValueType<64 , 32>; // 2 x i32 vector value def v4i32 : ValueType<128, 33>; // 4 x i32 vector value |