diff options
Diffstat (limited to 'include/llvm/CodeGen')
28 files changed, 374 insertions, 265 deletions
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index a071feb..58395ba 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -183,6 +183,10 @@ namespace llvm { /// function. void EmitFunctionBody(); + void emitPrologLabel(const MachineInstr &MI); + + bool needsCFIMoves(); + /// EmitConstantPool - Print to the current output stream assembly /// representations of the constants in the constant pool MCP. This is /// used to print out constants which have been "spilled to memory" by @@ -377,10 +381,17 @@ namespace llvm { /// operands. virtual MachineLocation getDebugValueLocation(const MachineInstr *MI) const; + /// getDwarfRegOpSize - get size required to emit given machine location + /// using dwarf encoding. + virtual unsigned getDwarfRegOpSize(const MachineLocation &MLoc) const; + /// getISAEncoding - Get the value for DW_AT_APPLE_isa. Zero if no isa /// encoding specified. virtual unsigned getISAEncoding() { return 0; } + /// EmitDwarfRegOp - Emit dwarf register operation. + virtual void EmitDwarfRegOp(const MachineLocation &MLoc) const; + //===------------------------------------------------------------------===// // Dwarf Lowering Routines //===------------------------------------------------------------------===// @@ -389,6 +400,7 @@ namespace llvm { /// frame. void EmitFrameMoves(const std::vector<MachineMove> &Moves, MCSymbol *BaseLabel, bool isEH) const; + void EmitCFIFrameMove(const MachineMove &Move) const; void EmitCFIFrameMoves(const std::vector<MachineMove> &Moves) const; //===------------------------------------------------------------------===// diff --git a/include/llvm/CodeGen/CalcSpillWeights.h b/include/llvm/CodeGen/CalcSpillWeights.h index 853ebf9..60edcc5 100644 --- a/include/llvm/CodeGen/CalcSpillWeights.h +++ b/include/llvm/CodeGen/CalcSpillWeights.h @@ -11,7 +11,7 @@ #ifndef LLVM_CODEGEN_CALCSPILLWEIGHTS_H #define LLVM_CODEGEN_CALCSPILLWEIGHTS_H -#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/SlotIndexes.h" #include "llvm/ADT/DenseMap.h" namespace llvm { @@ -29,28 +29,25 @@ namespace llvm { /// @param Size Size of live interval as returnexd by getSize() /// static inline float normalizeSpillWeight(float UseDefFreq, unsigned Size) { - // The magic constant 200 corresponds to approx. 25 instructions since - // SlotIndexes allocate 8 slots per instruction. - // - // The constant is added to avoid depending too much on accidental SlotIndex - // gaps for small intervals. The effect is that small intervals have a spill - // weight that is mostly proportional to the number of uses, while large - // intervals get a spill weight that is closer to a use density. - // - return UseDefFreq / (Size + 200); + // The constant 25 instructions is added to avoid depending too much on + // accidental SlotIndex gaps for small intervals. The effect is that small + // intervals have a spill weight that is mostly proportional to the number + // of uses, while large intervals get a spill weight that is closer to a use + // density. + return UseDefFreq / (Size + 25*SlotIndex::InstrDist); } /// 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_; + 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) {} + 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 diff --git a/include/llvm/CodeGen/CallingConvLower.h b/include/llvm/CodeGen/CallingConvLower.h index 2a9bbdf..9018ea3 100644 --- a/include/llvm/CodeGen/CallingConvLower.h +++ b/include/llvm/CodeGen/CallingConvLower.h @@ -141,6 +141,8 @@ typedef bool CCCustomFn(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State); +typedef enum { Invalid, Prologue, Call } ParmContext; + /// CCState - This class holds information needed while lowering arguments and /// return values. It captures which registers are already assigned and which /// stack slots are used. It provides accessors to allocate these values. @@ -154,6 +156,9 @@ class CCState { unsigned StackOffset; SmallVector<uint32_t, 16> UsedRegs; + unsigned FirstByValReg; + bool FirstByValRegValid; + ParmContext CallOrPrologue; public: CCState(CallingConv::ID CC, bool isVarArg, const TargetMachine &TM, SmallVector<CCValAssign, 16> &locs, LLVMContext &C); @@ -288,6 +293,16 @@ 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() { return FirstByValRegValid ? FirstByValReg : 0; } + void setFirstByValReg(unsigned r) { FirstByValReg = r; FirstByValRegValid = true; } + void clearFirstByValReg() { FirstByValReg = 0; FirstByValRegValid = false; } + bool isFirstByValRegValid() { return FirstByValRegValid; } + + ParmContext getCallOrPrologue() { return CallOrPrologue; } + void setCallOrPrologue(ParmContext pc) { CallOrPrologue = pc; } + private: /// MarkAllocated - Mark a register and all of its aliases as allocated. void MarkAllocated(unsigned Reg); diff --git a/include/llvm/CodeGen/EdgeBundles.h b/include/llvm/CodeGen/EdgeBundles.h index 2c5215a..8aab3c6 100644 --- a/include/llvm/CodeGen/EdgeBundles.h +++ b/include/llvm/CodeGen/EdgeBundles.h @@ -16,6 +16,7 @@ #ifndef LLVM_CODEGEN_EDGEBUNDLES_H #define LLVM_CODEGEN_EDGEBUNDLES_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/IntEqClasses.h" #include "llvm/CodeGen/MachineFunctionPass.h" @@ -29,6 +30,9 @@ class EdgeBundles : public MachineFunctionPass { /// 2*BB->getNumber()+1 -> Outgoing bundle. IntEqClasses EC; + /// Blocks - Map each bundle to a list of basic block numbers. + SmallVector<SmallVector<unsigned, 8>, 4> Blocks; + public: static char ID; EdgeBundles() : MachineFunctionPass(ID) {} @@ -40,6 +44,9 @@ public: /// getNumBundles - Return the total number of bundles in the CFG. unsigned getNumBundles() const { return EC.getNumClasses(); } + /// getBlocks - Return an array of blocks that are connected to Bundle. + ArrayRef<unsigned> getBlocks(unsigned Bundle) { return Blocks[Bundle]; } + /// getMachineFunction - Return the last machine function computed. const MachineFunction *getMachineFunction() const { return MF; } diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h index fbb1200..10c4c33d 100644 --- a/include/llvm/CodeGen/FastISel.h +++ b/include/llvm/CodeGen/FastISel.h @@ -8,9 +8,9 @@ //===----------------------------------------------------------------------===// // // This file defines the FastISel class. -// +// //===----------------------------------------------------------------------===// - + #ifndef LLVM_CODEGEN_FASTISEL_H #define LLVM_CODEGEN_FASTISEL_H @@ -108,7 +108,7 @@ public: const LoadInst * /*LI*/) { return false; } - + /// recomputeInsertPt - Reset InsertPt to prepare for inserting instructions /// into the current block. void recomputeInsertPt(); @@ -203,16 +203,7 @@ protected: unsigned Opcode, unsigned Op0, bool Op0IsKill, uint64_t Imm, MVT ImmType); - - /// FastEmit_rf_ - This method is a wrapper of FastEmit_rf. It first tries - /// to emit an instruction with an immediate operand using FastEmit_rf. - /// If that fails, it materializes the immediate into a register and try - /// FastEmit_rr instead. - unsigned FastEmit_rf_(MVT VT, - unsigned Opcode, - unsigned Op0, bool Op0IsKill, - const ConstantFP *FPImm, MVT ImmType); - + /// FastEmit_i - This method is called by target-independent code /// to request that an instruction with the given type, opcode, and /// immediate operand be emitted. @@ -250,14 +241,22 @@ protected: unsigned Op0, bool Op0IsKill, unsigned Op1, bool Op1IsKill); - /// FastEmitInst_ri - Emit a MachineInstr with two register operands - /// and a result register in the given register class. + /// FastEmitInst_ri - Emit a MachineInstr with a register operand, + /// an immediate, and a result register in the given register class. /// unsigned FastEmitInst_ri(unsigned MachineInstOpcode, const TargetRegisterClass *RC, unsigned Op0, bool Op0IsKill, uint64_t Imm); + /// FastEmitInst_rii - Emit a MachineInstr with one register operand + /// and two immediate operands. + /// + unsigned FastEmitInst_rii(unsigned MachineInstOpcode, + const TargetRegisterClass *RC, + unsigned Op0, bool Op0IsKill, + uint64_t Imm1, uint64_t Imm2); + /// FastEmitInst_rf - Emit a MachineInstr with two register operands /// and a result register in the given register class. /// @@ -274,13 +273,18 @@ protected: unsigned Op0, bool Op0IsKill, unsigned Op1, bool Op1IsKill, uint64_t Imm); - + /// FastEmitInst_i - Emit a MachineInstr with a single immediate /// operand, and a result register in the given register class. unsigned FastEmitInst_i(unsigned MachineInstrOpcode, const TargetRegisterClass *RC, uint64_t Imm); + /// FastEmitInst_ii - Emit a MachineInstr with a two immediate operands. + unsigned FastEmitInst_ii(unsigned MachineInstrOpcode, + const TargetRegisterClass *RC, + uint64_t Imm1, uint64_t Imm2); + /// FastEmitInst_extractsubreg - Emit a MachineInstr for an extract_subreg /// from a specified index of a superregister to a specified type. unsigned FastEmitInst_extractsubreg(MVT RetVT, @@ -300,8 +304,8 @@ protected: unsigned UpdateValueMap(const Value* I, unsigned Reg); unsigned createResultReg(const TargetRegisterClass *RC); - - /// TargetMaterializeConstant - Emit a constant in a register using + + /// TargetMaterializeConstant - Emit a constant in a register using /// target-specific logic, such as constant pool loads. virtual unsigned TargetMaterializeConstant(const Constant* C) { return 0; @@ -313,6 +317,10 @@ protected: return 0; } + virtual unsigned TargetMaterializeFloatZero(const ConstantFP* CF) { + return 0; + } + private: bool SelectBinaryOp(const User *I, unsigned ISDOpcode); @@ -323,7 +331,7 @@ private: bool SelectCall(const User *I); bool SelectBitCast(const User *I); - + bool SelectCast(const User *I, unsigned Opcode); /// HandlePHINodesInSuccessorBlocks - Handle PHI nodes in successor blocks. diff --git a/include/llvm/CodeGen/FunctionLoweringInfo.h b/include/llvm/CodeGen/FunctionLoweringInfo.h index b41f30d..4421cc0 100644 --- a/include/llvm/CodeGen/FunctionLoweringInfo.h +++ b/include/llvm/CodeGen/FunctionLoweringInfo.h @@ -187,7 +187,12 @@ public: /// InvalidatePHILiveOutRegInfo - Invalidates a PHI's LiveOutInfo, to be /// called when a block is visited before all of its predecessors. void InvalidatePHILiveOutRegInfo(const PHINode *PN) { - unsigned Reg = ValueMap[PN]; + // PHIs with no uses have no ValueMap entry. + DenseMap<const Value*, unsigned>::const_iterator It = ValueMap.find(PN); + if (It == ValueMap.end()) + return; + + unsigned Reg = It->second; LiveOutRegInfo.grow(Reg); LiveOutRegInfo[Reg].IsValid = false; } @@ -209,8 +214,9 @@ private: void AddCatchInfo(const CallInst &I, MachineModuleInfo *MMI, MachineBasicBlock *MBB); -/// CopyCatchInfo - Copy catch information from DestBB to SrcBB. -void CopyCatchInfo(const BasicBlock *SrcBB, const BasicBlock *DestBB, +/// CopyCatchInfo - Copy catch information from SuccBB (or one of its +/// successors) to LPad. +void CopyCatchInfo(const BasicBlock *SuccBB, const BasicBlock *LPad, MachineModuleInfo *MMI, FunctionLoweringInfo &FLI); } // end namespace llvm diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h index 3da11c4..f0de936 100644 --- a/include/llvm/CodeGen/ISDOpcodes.h +++ b/include/llvm/CodeGen/ISDOpcodes.h @@ -219,7 +219,7 @@ namespace ISD { // RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition. // These nodes take two operands: the normal LHS and RHS to the add. They // produce two results: the normal result of the add, and a boolean that - // indicates if an overflow occured (*not* a flag, because it may be stored + // indicates if an overflow occurred (*not* a flag, because it may be stored // to memory, etc.). If the type of the boolean is not i1 then the high // bits conform to getBooleanContents. // These nodes are generated from the llvm.[su]add.with.overflow intrinsics. diff --git a/include/llvm/CodeGen/JITCodeEmitter.h b/include/llvm/CodeGen/JITCodeEmitter.h index fea8523..88e22d6 100644 --- a/include/llvm/CodeGen/JITCodeEmitter.h +++ b/include/llvm/CodeGen/JITCodeEmitter.h @@ -23,8 +23,6 @@ #include "llvm/CodeGen/MachineCodeEmitter.h" #include "llvm/ADT/DenseMap.h" -using namespace std; - namespace llvm { class MachineBasicBlock; @@ -38,7 +36,7 @@ class GlobalValue; class Function; /// JITCodeEmitter - This class defines two sorts of methods: those for -/// emitting the actual bytes of machine code, and those for emitting auxillary +/// emitting the actual bytes of machine code, and those for emitting auxiliary /// structures, such as jump tables, relocations, etc. /// /// Emission of machine code is complicated by the fact that we don't (in diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h index 88131fb..c5285ce 100644 --- a/include/llvm/CodeGen/LiveInterval.h +++ b/include/llvm/CodeGen/LiveInterval.h @@ -286,6 +286,11 @@ namespace llvm { return valnos[ValNo]; } + /// containsValue - Returns true if VNI belongs to this interval. + bool containsValue(const VNInfo *VNI) const { + return VNI && VNI->id < getNumValNums() && VNI == getValNumInfo(VNI->id); + } + /// getNextValue - Create a new value number and return it. MIIdx specifies /// the instruction that defines the value number. VNInfo *getNextValue(SlotIndex def, MachineInstr *CopyMI, @@ -447,6 +452,11 @@ namespace llvm { addRangeFrom(LR, ranges.begin()); } + /// extendInBlock - If this interval is live before UseIdx in the basic + /// block that starts at StartIdx, extend it to be live at UseIdx and return + /// the value. If there is no live range before UseIdx, return NULL. + VNInfo *extendInBlock(SlotIndex StartIdx, SlotIndex UseIdx); + /// join - Join two live intervals (this, and other) together. This applies /// mappings to the value numbers in the LHS/RHS intervals as specified. If /// the intervals are not joinable, this aborts. @@ -543,8 +553,8 @@ namespace llvm { /// } class ConnectedVNInfoEqClasses { - LiveIntervals &lis_; - IntEqClasses eqClass_; + LiveIntervals &LIS; + IntEqClasses EqClass; // Note that values a and b are connected. void Connect(unsigned a, unsigned b); @@ -552,7 +562,7 @@ namespace llvm { unsigned Renumber(); public: - explicit ConnectedVNInfoEqClasses(LiveIntervals &lis) : lis_(lis) {} + explicit ConnectedVNInfoEqClasses(LiveIntervals &lis) : LIS(lis) {} /// Classify - Classify the values in LI into connected components. /// Return the number of connected components. @@ -560,12 +570,13 @@ namespace llvm { /// getEqClass - Classify creates equivalence classes numbered 0..N. Return /// the equivalence class assigned the VNI. - unsigned getEqClass(const VNInfo *VNI) const { return eqClass_[VNI->id]; } + unsigned getEqClass(const VNInfo *VNI) const { return EqClass[VNI->id]; } /// Distribute - Distribute values in LIV[0] into a separate LiveInterval /// for each connected component. LIV must have a LiveInterval for each /// connected component. The LiveIntervals in Liv[1..] must be empty. - void Distribute(LiveInterval *LIV[]); + /// Instructions using LIV[0] are rewritten. + void Distribute(LiveInterval *LIV[], MachineRegisterInfo &MRI); }; diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h index b09f8d1..8ca58b8 100644 --- a/include/llvm/CodeGen/LiveIntervalAnalysis.h +++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -159,7 +159,11 @@ namespace llvm { /// range to just the remaining uses. This method does not compute reaching /// defs for new uses, and it doesn't remove dead defs. /// Dead PHIDef values are marked as unused. - void shrinkToUses(LiveInterval *li); + /// New dead machine instructions are added to the dead vector. + /// Return true if the interval may have been separated into multiple + /// connected components. + bool shrinkToUses(LiveInterval *li, + SmallVectorImpl<MachineInstr*> *dead = 0); // Interval removal @@ -272,7 +276,7 @@ namespace llvm { /// (if any is created) by reference. This is temporary. std::vector<LiveInterval*> addIntervalsForSpills(const LiveInterval& i, - const SmallVectorImpl<LiveInterval*> &SpillIs, + const SmallVectorImpl<LiveInterval*> *SpillIs, const MachineLoopInfo *loopInfo, VirtRegMap& vrm); /// spillPhysRegAroundRegDefsUses - Spill the specified physical register @@ -285,7 +289,7 @@ namespace llvm { /// val# of the specified interval is re-materializable. Also returns true /// by reference if all of the defs are load instructions. bool isReMaterializable(const LiveInterval &li, - const SmallVectorImpl<LiveInterval*> &SpillIs, + const SmallVectorImpl<LiveInterval*> *SpillIs, bool &isLoad); /// isReMaterializable - Returns true if the definition MI of the specified @@ -372,7 +376,7 @@ namespace llvm { /// by reference if the def is a load. bool isReMaterializable(const LiveInterval &li, const VNInfo *ValNo, MachineInstr *MI, - const SmallVectorImpl<LiveInterval*> &SpillIs, + const SmallVectorImpl<LiveInterval*> *SpillIs, bool &isLoad); /// tryFoldMemoryOperand - Attempts to fold either a spill / restore from diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h index 1785451..ad12157 100644 --- a/include/llvm/CodeGen/MachineBasicBlock.h +++ b/include/llvm/CodeGen/MachineBasicBlock.h @@ -16,6 +16,7 @@ #include "llvm/CodeGen/MachineInstr.h" #include "llvm/ADT/GraphTraits.h" +#include <functional> namespace llvm { @@ -304,10 +305,18 @@ public: /// it returns end() iterator getFirstTerminator(); + const_iterator getFirstTerminator() const { + return const_cast<MachineBasicBlock*>(this)->getFirstTerminator(); + } + /// getLastNonDebugInstr - returns an iterator to the last non-debug /// instruction in the basic block, or end() iterator getLastNonDebugInstr(); + const_iterator getLastNonDebugInstr() const { + return const_cast<MachineBasicBlock*>(this)->getLastNonDebugInstr(); + } + /// SplitCriticalEdge - Split the critical edge from this block to the /// given successor block, and return the newly created block, or null /// if splitting is not possible. @@ -411,6 +420,14 @@ raw_ostream& operator<<(raw_ostream &OS, const MachineBasicBlock &MBB); void WriteAsOperand(raw_ostream &, const MachineBasicBlock*, bool t); +// This is useful when building IndexedMaps keyed on basic block pointers. +struct MBB2NumberFunctor : + public std::unary_function<const MachineBasicBlock*, unsigned> { + unsigned operator()(const MachineBasicBlock *MBB) const { + return MBB->getNumber(); + } +}; + //===--------------------------------------------------------------------===// // GraphTraits specializations for machine basic block graphs (machine-CFGs) //===--------------------------------------------------------------------===// diff --git a/include/llvm/CodeGen/MachineCodeEmitter.h b/include/llvm/CodeGen/MachineCodeEmitter.h index 8fc80ad..428aada 100644 --- a/include/llvm/CodeGen/MachineCodeEmitter.h +++ b/include/llvm/CodeGen/MachineCodeEmitter.h @@ -34,7 +34,7 @@ class Function; class MCSymbol; /// MachineCodeEmitter - This class defines two sorts of methods: those for -/// emitting the actual bytes of machine code, and those for emitting auxillary +/// emitting the actual bytes of machine code, and those for emitting auxiliary /// structures, such as jump tables, relocations, etc. /// /// Emission of machine code is complicated by the fact that we don't (in @@ -54,7 +54,7 @@ protected: /// allocated for this code buffer. uint8_t *BufferBegin, *BufferEnd; /// CurBufferPtr - Pointer to the next byte of memory to fill when emitting - /// code. This is guranteed to be in the range [BufferBegin,BufferEnd]. If + /// code. This is guaranteed to be in the range [BufferBegin,BufferEnd]. If /// this pointer is at BufferEnd, it will never move due to code emission, and /// all code emission requests will be ignored (this is the buffer overflow /// condition). diff --git a/include/llvm/CodeGen/MachineConstantPool.h b/include/llvm/CodeGen/MachineConstantPool.h index 5727321..beb16a2 100644 --- a/include/llvm/CodeGen/MachineConstantPool.h +++ b/include/llvm/CodeGen/MachineConstantPool.h @@ -80,7 +80,7 @@ public: } Val; /// The required alignment for this entry. The top bit is set when Val is - /// a MachineConstantPoolValue. + /// a target specific MachineConstantPoolValue. unsigned Alignment; MachineConstantPoolEntry(const Constant *V, unsigned A) @@ -93,6 +93,9 @@ public: Alignment |= 1U << (sizeof(unsigned)*CHAR_BIT-1); } + /// isMachineConstantPoolEntry - Return true if the MachineConstantPoolEntry + /// is indeed a target specific constantpool entry, not a wrapper over a + /// Constant. bool isMachineConstantPoolEntry() const { return (int)Alignment < 0; } diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h index 22a82a9..4ea6aa3 100644 --- a/include/llvm/CodeGen/MachineFrameInfo.h +++ b/include/llvm/CodeGen/MachineFrameInfo.h @@ -15,7 +15,6 @@ #define LLVM_CODEGEN_MACHINEFRAMEINFO_H #include "llvm/ADT/SmallVector.h" -//#include "llvm/ADT/IndexedMap.h" #include "llvm/Support/DataTypes.h" #include <cassert> #include <vector> diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index 82c5332..2724689 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -50,13 +50,22 @@ public: enum CommentFlag { ReloadReuse = 0x1 }; - + + enum MIFlag { + NoFlags = 0, + FrameSetup = 1 << 0 // Instruction is used as a part of + // function frame setup code. + }; private: const TargetInstrDesc *TID; // Instruction descriptor. - unsigned short NumImplicitOps; // Number of implicit operands (which + uint16_t NumImplicitOps; // Number of implicit operands (which // are determined at construction time). - unsigned short AsmPrinterFlags; // Various bits of information used by + uint8_t Flags; // Various bits of additional + // information about machine + // instruction. + + uint8_t AsmPrinterFlags; // Various bits of information used by // the AsmPrinter to emit helpful // comments. This is *not* semantic // information. Do not use this for @@ -105,13 +114,13 @@ private: /// MachineInstr ctor - This constructor create a MachineInstr and add the /// implicit operands. It reserves space for number of operands specified by /// TargetInstrDesc. An explicit DebugLoc is supplied. - explicit MachineInstr(const TargetInstrDesc &TID, const DebugLoc dl, + explicit MachineInstr(const TargetInstrDesc &TID, const DebugLoc dl, bool NoImp = false); /// MachineInstr ctor - Work exactly the same as the ctor above, except that /// the MachineInstr is created and added to the end of the specified basic /// block. - MachineInstr(MachineBasicBlock *MBB, const DebugLoc dl, + MachineInstr(MachineBasicBlock *MBB, const DebugLoc dl, const TargetInstrDesc &TID); ~MachineInstr(); @@ -125,12 +134,12 @@ public: /// getAsmPrinterFlags - Return the asm printer flags bitvector. /// - unsigned short getAsmPrinterFlags() const { return AsmPrinterFlags; } + uint8_t getAsmPrinterFlags() const { return AsmPrinterFlags; } /// clearAsmPrinterFlags - clear the AsmPrinter bitvector /// void clearAsmPrinterFlags() { AsmPrinterFlags = 0; } - + /// getAsmPrinterFlag - Return whether an AsmPrinter flag is set. /// bool getAsmPrinterFlag(CommentFlag Flag) const { @@ -140,9 +149,28 @@ public: /// setAsmPrinterFlag - Set a flag for the AsmPrinter. /// void setAsmPrinterFlag(CommentFlag Flag) { - AsmPrinterFlags |= (unsigned short)Flag; + AsmPrinterFlags |= (uint8_t)Flag; + } + + /// getFlags - Return the MI flags bitvector. + uint8_t getFlags() const { + return Flags; + } + + /// getFlag - Return whether an MI flag is set. + bool getFlag(MIFlag Flag) const { + return Flags & Flag; + } + + /// setFlag - Set a MI flag. + void setFlag(MIFlag Flag) { + Flags |= (uint8_t)Flag; + } + + void setFlags(unsigned flags) { + Flags = flags; } - + /// clearAsmPrinterFlag - clear specific AsmPrinter flags /// void clearAsmPrinterFlag(CommentFlag Flag) { @@ -152,7 +180,7 @@ public: /// getDebugLoc - Returns the debug location id of this MachineInstr. /// DebugLoc getDebugLoc() const { return debugLoc; } - + /// getDesc - Returns the target instruction descriptor of this /// MachineInstr. const TargetInstrDesc &getDesc() const { return *TID; } @@ -213,7 +241,7 @@ public: /// removeFromParent - This method unlinks 'this' from the containing basic /// block, and returns it, but does not delete it. MachineInstr *removeFromParent(); - + /// eraseFromParent - This method unlinks 'this' from the containing basic /// block and deletes it. void eraseFromParent(); @@ -225,14 +253,14 @@ public: getOpcode() == TargetOpcode::EH_LABEL || getOpcode() == TargetOpcode::GC_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; } - + bool isPHI() const { return getOpcode() == TargetOpcode::PHI; } bool isKill() const { return getOpcode() == TargetOpcode::KILL; } bool isImplicitDef() const { return getOpcode()==TargetOpcode::IMPLICIT_DEF; } @@ -329,7 +357,7 @@ public: int Idx = findRegisterUseOperandIdx(Reg, isKill, TRI); return (Idx == -1) ? NULL : &getOperand(Idx); } - + /// findRegisterDefOperandIdx() - Returns the operand index that is a def of /// the specified register or -1 if it is not found. If isDead is true, defs /// that are not dead are skipped. If Overlap is true, then it also looks for @@ -351,7 +379,7 @@ public: /// operand list that is used to represent the predicate. It returns -1 if /// none is found. int findFirstPredOperandIdx() const; - + /// isRegTiedToUseOperand - Given the index of a register def operand, /// check if the register def is tied to a source operand, due to either /// two-address elimination or inline assembly constraints. Returns the @@ -399,8 +427,8 @@ public: void addRegisterDefined(unsigned IncomingReg, const TargetRegisterInfo *RegInfo = 0); - /// setPhysRegsDeadExcept - Mark every physreg used by this instruction as dead - /// except those in the UsedRegs list. + /// setPhysRegsDeadExcept - Mark every physreg used by this instruction as + /// dead except those in the UsedRegs list. void setPhysRegsDeadExcept(const SmallVectorImpl<unsigned> &UsedRegs, const TargetRegisterInfo &TRI); @@ -462,9 +490,9 @@ public: /// addOperand - Add the specified operand to the instruction. If it is an /// implicit operand, it is added to the end of the operand list. If it is /// an explicit operand it is added at the end of the explicit operand list - /// (before the first implicit operand). + /// (before the first implicit operand). void addOperand(const MachineOperand &Op); - + /// setDesc - Replace the instruction descriptor (thus opcode) of /// the current instruction with a new one. /// @@ -501,12 +529,12 @@ private: /// addImplicitDefUseOperands - Add all implicit def and use operands to /// this instruction. void addImplicitDefUseOperands(); - + /// RemoveRegOperandsFromUseLists - Unlink all of the register operands in /// this instruction from their respective use lists. This requires that the /// operands already be on their use lists. void RemoveRegOperandsFromUseLists(); - + /// AddRegOperandsToUseLists - Add all of the register operands in /// this instruction from their respective use lists. This requires that the /// operands not be on their use lists yet. diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h index 1eb9735..967e019 100644 --- a/include/llvm/CodeGen/MachineInstrBuilder.h +++ b/include/llvm/CodeGen/MachineInstrBuilder.h @@ -48,6 +48,7 @@ public: /// Allow automatic conversion to the machine instruction we are working on. /// operator MachineInstr*() const { return MI; } + MachineInstr *operator->() const { return MI; } operator MachineBasicBlock::iterator() const { return MI; } /// addReg - Add a new virtual register operand... @@ -145,6 +146,16 @@ public: return *this; } + const MachineInstrBuilder &setMIFlags(unsigned Flags) const { + MI->setFlags(Flags); + return *this; + } + + const MachineInstrBuilder &setMIFlag(MachineInstr::MIFlag Flag) const { + MI->setFlag(Flag); + return *this; + } + // Add a displacement from an existing MachineOperand with an added offset. const MachineInstrBuilder &addDisp(const MachineOperand &Disp, int64_t off) const { diff --git a/include/llvm/CodeGen/PBQP/Graph.h b/include/llvm/CodeGen/PBQP/Graph.h index b2224cb..5240729 100644 --- a/include/llvm/CodeGen/PBQP/Graph.h +++ b/include/llvm/CodeGen/PBQP/Graph.h @@ -18,7 +18,6 @@ #include "Math.h" #include <list> -#include <vector> #include <map> namespace PBQP { diff --git a/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h b/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h index 47a287c..e96c4cb 100644 --- a/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h +++ b/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h @@ -21,7 +21,6 @@ #include "../HeuristicSolver.h" #include "../HeuristicBase.h" -#include <set> #include <limits> namespace PBQP { diff --git a/include/llvm/CodeGen/ProcessImplicitDefs.h b/include/llvm/CodeGen/ProcessImplicitDefs.h index e2ab899..6ab57f0 100644 --- a/include/llvm/CodeGen/ProcessImplicitDefs.h +++ b/include/llvm/CodeGen/ProcessImplicitDefs.h @@ -18,14 +18,20 @@ namespace llvm { class MachineInstr; class TargetInstrInfo; + class TargetRegisterInfo; + class MachineRegisterInfo; + class LiveVariables; /// Process IMPLICIT_DEF instructions and make sure there is one implicit_def /// for each use. Add isUndef marker to implicit_def defs and their uses. class ProcessImplicitDefs : public MachineFunctionPass { - private: + const TargetInstrInfo *TII; + const TargetRegisterInfo *TRI; + MachineRegisterInfo *MRI; + LiveVariables *LV; bool CanTurnIntoImplicitDef(MachineInstr *MI, unsigned Reg, - unsigned OpIdx, const TargetInstrInfo *tii_, + unsigned OpIdx, SmallSet<unsigned, 8> &ImpDefRegs); public: diff --git a/include/llvm/CodeGen/RegisterScavenging.h b/include/llvm/CodeGen/RegisterScavenging.h index 246831c..26b6773 100644 --- a/include/llvm/CodeGen/RegisterScavenging.h +++ b/include/llvm/CodeGen/RegisterScavenging.h @@ -100,7 +100,7 @@ public: /// getRegsAvailable - Return all available registers in the register class /// in Mask. - void getRegsAvailable(const TargetRegisterClass *RC, BitVector &Mask); + BitVector getRegsAvailable(const TargetRegisterClass *RC); /// FindUnusedReg - Find a unused register of the specified register class. /// Return 0 if none is found. diff --git a/include/llvm/CodeGen/RuntimeLibcalls.h b/include/llvm/CodeGen/RuntimeLibcalls.h index a51e82a..576be82 100644 --- a/include/llvm/CodeGen/RuntimeLibcalls.h +++ b/include/llvm/CodeGen/RuntimeLibcalls.h @@ -66,6 +66,16 @@ namespace RTLIB { UREM_I32, UREM_I64, UREM_I128, + SDIVREM_I8, + SDIVREM_I16, + SDIVREM_I32, + SDIVREM_I64, + SDIVREM_I128, + UDIVREM_I8, + UDIVREM_I16, + UDIVREM_I32, + UDIVREM_I64, + UDIVREM_I128, NEG_I32, NEG_I64, diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h index 3864ffd..2eb3db3 100644 --- a/include/llvm/CodeGen/ScheduleDAG.h +++ b/include/llvm/CodeGen/ScheduleDAG.h @@ -250,7 +250,9 @@ namespace llvm { unsigned NumSuccsLeft; // # of succs not scheduled. unsigned short NumRegDefsLeft; // # of reg defs with no scheduled use. unsigned short Latency; // Node latency. + bool isVRegCycle : 1; // May use and def the same vreg. bool isCall : 1; // Is a function call. + bool isCallOp : 1; // Is a function call operand. bool isTwoAddress : 1; // Is a two-address instruction. bool isCommutable : 1; // Is a commutable instruction. bool hasPhysRegDefs : 1; // Has physreg defs that are being used. @@ -259,6 +261,7 @@ namespace llvm { bool isAvailable : 1; // True once available. bool isScheduled : 1; // True once scheduled. bool isScheduleHigh : 1; // True if preferable to schedule high. + bool isScheduleLow : 1; // True if preferable to schedule low. bool isCloned : 1; // True if this node has been cloned. Sched::Preference SchedulingPref; // Scheduling preference. @@ -278,10 +281,10 @@ namespace llvm { : Node(node), Instr(0), OrigNode(0), NodeNum(nodenum), NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0), NumRegDefsLeft(0), Latency(0), - isCall(false), isTwoAddress(false), isCommutable(false), - hasPhysRegDefs(false), hasPhysRegClobbers(false), + isVRegCycle(false), isCall(false), isCallOp(false), isTwoAddress(false), + isCommutable(false), hasPhysRegDefs(false), hasPhysRegClobbers(false), isPending(false), isAvailable(false), isScheduled(false), - isScheduleHigh(false), isCloned(false), + isScheduleHigh(false), isScheduleLow(false), isCloned(false), SchedulingPref(Sched::None), isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0), CopyDstRC(NULL), CopySrcRC(NULL) {} @@ -292,10 +295,10 @@ namespace llvm { : Node(0), Instr(instr), OrigNode(0), NodeNum(nodenum), NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0), NumRegDefsLeft(0), Latency(0), - isCall(false), isTwoAddress(false), isCommutable(false), - hasPhysRegDefs(false), hasPhysRegClobbers(false), + isVRegCycle(false), isCall(false), isCallOp(false), isTwoAddress(false), + isCommutable(false), hasPhysRegDefs(false), hasPhysRegClobbers(false), isPending(false), isAvailable(false), isScheduled(false), - isScheduleHigh(false), isCloned(false), + isScheduleHigh(false), isScheduleLow(false), isCloned(false), SchedulingPref(Sched::None), isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0), CopyDstRC(NULL), CopySrcRC(NULL) {} @@ -305,10 +308,10 @@ namespace llvm { : Node(0), Instr(0), OrigNode(0), NodeNum(~0u), NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0), NumRegDefsLeft(0), Latency(0), - isCall(false), isTwoAddress(false), isCommutable(false), - hasPhysRegDefs(false), hasPhysRegClobbers(false), + isVRegCycle(false), isCall(false), isCallOp(false), isTwoAddress(false), + isCommutable(false), hasPhysRegDefs(false), hasPhysRegClobbers(false), isPending(false), isAvailable(false), isScheduled(false), - isScheduleHigh(false), isCloned(false), + isScheduleHigh(false), isScheduleLow(false), isCloned(false), SchedulingPref(Sched::None), isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0), CopyDstRC(NULL), CopySrcRC(NULL) {} @@ -356,7 +359,7 @@ namespace llvm { void removePred(const SDep &D); /// getDepth - Return the depth of this node, which is the length of the - /// maximum path up to any node with has no predecessors. + /// maximum path up to any node which has no predecessors. unsigned getDepth() const { if (!isDepthCurrent) const_cast<SUnit *>(this)->ComputeDepth(); @@ -364,7 +367,7 @@ namespace llvm { } /// getHeight - Return the height of this node, which is the length of the - /// maximum path down to any node with has no successors. + /// maximum path down to any node which has no successors. unsigned getHeight() const { if (!isHeightCurrent) const_cast<SUnit *>(this)->ComputeHeight(); @@ -690,11 +693,11 @@ namespace llvm { /// will create a cycle. bool WillCreateCycle(SUnit *SU, SUnit *TargetSU); - /// AddPred - Updates the topological ordering to accomodate an edge + /// AddPred - Updates the topological ordering to accommodate an edge /// to be added from SUnit X to SUnit Y. void AddPred(SUnit *Y, SUnit *X); - /// RemovePred - Updates the topological ordering to accomodate an + /// RemovePred - Updates the topological ordering to accommodate an /// an edge to be removed from the specified node N from the predecessors /// of the current node M. void RemovePred(SUnit *M, SUnit *N); diff --git a/include/llvm/CodeGen/ScoreboardHazardRecognizer.h b/include/llvm/CodeGen/ScoreboardHazardRecognizer.h index 8850006..118df28 100644 --- a/include/llvm/CodeGen/ScoreboardHazardRecognizer.h +++ b/include/llvm/CodeGen/ScoreboardHazardRecognizer.h @@ -21,7 +21,6 @@ #include <cassert> #include <cstring> -#include <string> namespace llvm { diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index c9de95b..92fd0c9 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -438,12 +438,12 @@ public: SDValue getConvertRndSat(EVT VT, DebugLoc dl, SDValue Val, SDValue DTy, SDValue STy, SDValue Rnd, SDValue Sat, ISD::CvtCode Code); - + /// getVectorShuffle - Return an ISD::VECTOR_SHUFFLE node. The number of /// elements in VT, which must be a vector type, must match the number of /// mask elements NumElts. A integer mask element equal to -1 is treated as /// undefined. - SDValue getVectorShuffle(EVT VT, DebugLoc dl, SDValue N1, SDValue N2, + SDValue getVectorShuffle(EVT VT, DebugLoc dl, SDValue N1, SDValue N2, const int *MaskElts); /// getSExtOrTrunc - Convert Op, which must be of integer type, to the @@ -671,10 +671,10 @@ public: /// getMDNode - Return an MDNodeSDNode which holds an MDNode. SDValue getMDNode(const MDNode *MD); - + /// getShiftAmountOperand - Return the specified value casted to /// the target's desired shift amount type. - SDValue getShiftAmountOperand(SDValue Op); + SDValue getShiftAmountOperand(EVT LHSTy, SDValue Op); /// UpdateNodeOperands - *Mutate* the specified node in-place to have the /// specified operands. If the resultant node already exists in the DAG, @@ -829,7 +829,7 @@ public: /// These functions only replace all existing uses. It's possible that as /// these replacements are being performed, CSE may cause the From node /// to be given new uses. These new uses of From are left in place, and - /// not automatically transfered to To. + /// not automatically transferred to To. /// void ReplaceAllUsesWith(SDValue From, SDValue Op, DAGUpdateListener *UpdateListener = 0); @@ -901,7 +901,7 @@ public: SmallVector<SDDbgValue*,2> &GetDbgValues(const SDNode* SD) { return DbgInfo->getSDDbgValues(SD); } - + /// TransferDbgValues - Transfer SDDbgValues. void TransferDbgValues(SDValue From, SDValue To); @@ -911,11 +911,11 @@ public: SDDbgInfo::DbgIterator DbgBegin() { return DbgInfo->DbgBegin(); } SDDbgInfo::DbgIterator DbgEnd() { return DbgInfo->DbgEnd(); } - SDDbgInfo::DbgIterator ByvalParmDbgBegin() { - return DbgInfo->ByvalParmDbgBegin(); + SDDbgInfo::DbgIterator ByvalParmDbgBegin() { + return DbgInfo->ByvalParmDbgBegin(); } - SDDbgInfo::DbgIterator ByvalParmDbgEnd() { - return DbgInfo->ByvalParmDbgEnd(); + SDDbgInfo::DbgIterator ByvalParmDbgEnd() { + return DbgInfo->ByvalParmDbgEnd(); } void dump() const; @@ -972,7 +972,7 @@ public: /// semantics as an ADD. This handles the equivalence: /// X|Cst == X+Cst iff X&Cst = 0. bool isBaseWithConstantOffset(SDValue Op) const; - + /// isKnownNeverNan - Test whether the given SDValue is known to never be NaN. bool isKnownNeverNaN(SDValue Op) const; @@ -997,8 +997,8 @@ public: /// vector op and fill the end of the resulting vector with UNDEFS. SDValue UnrollVectorOp(SDNode *N, unsigned ResNE = 0); - /// isConsecutiveLoad - Return true if LD is loading 'Bytes' bytes from a - /// location that is 'Dist' units away from the location that the 'Base' load + /// isConsecutiveLoad - Return true if LD is loading 'Bytes' bytes from a + /// location that is 'Dist' units away from the location that the 'Base' load /// is loading from. bool isConsecutiveLoad(LoadSDNode *LD, LoadSDNode *Base, unsigned Bytes, int Dist) const; @@ -1032,7 +1032,7 @@ private: std::vector<SDNode*> ValueTypeNodes; std::map<EVT, SDNode*, EVT::compareRawBits> ExtendedValueTypeNodes; StringMap<SDNode*> ExternalSymbols; - + std::map<std::pair<std::string, unsigned char>,SDNode*> TargetExternalSymbols; }; diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h index 62358e7..ecf3947 100644 --- a/include/llvm/CodeGen/SelectionDAGISel.h +++ b/include/llvm/CodeGen/SelectionDAGISel.h @@ -127,6 +127,7 @@ public: OPC_EmitInteger, OPC_EmitRegister, + OPC_EmitRegister2, OPC_EmitConvertToTarget, OPC_EmitMergeInputChains, OPC_EmitMergeInputChains1_0, @@ -257,7 +258,7 @@ public: } virtual SDValue RunSDNodeXForm(SDValue V, unsigned XFormNo) { - assert(0 && "Tblgen shoudl generate this!"); + assert(0 && "Tblgen should generate this!"); return SDValue(); } @@ -279,7 +280,8 @@ private: void PrepareEHLandingPad(); void SelectAllBasicBlocks(const Function &Fn); - bool TryToFoldFastISelLoad(const LoadInst *LI, FastISel *FastIS); + bool TryToFoldFastISelLoad(const LoadInst *LI, const Instruction *FoldInst, + FastISel *FastIS); void FinishBasicBlock(); void SelectBasicBlock(BasicBlock::const_iterator Begin, diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 6454639..9d265f1 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -838,7 +838,7 @@ public: /// HandleSDNode - This class is used to form a handle around another node that -/// is persistant and is updated across invocations of replaceAllUsesWith on its +/// is persistent and is updated across invocations of replaceAllUsesWith on its /// operand. This node should be directly created by end-users and not added to /// the AllNodes list. class HandleSDNode : public SDNode { diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h index 1da1e91be..33ce675 100644 --- a/include/llvm/CodeGen/SlotIndexes.h +++ b/include/llvm/CodeGen/SlotIndexes.h @@ -34,77 +34,35 @@ namespace llvm { /// SlotIndex & SlotIndexes classes for the public interface to this /// information. class IndexListEntry { - static const unsigned EMPTY_KEY_INDEX = ~0U & ~3U, - TOMBSTONE_KEY_INDEX = ~0U & ~7U; - IndexListEntry *next, *prev; MachineInstr *mi; unsigned index; - protected: - - typedef enum { EMPTY_KEY, TOMBSTONE_KEY } ReservedEntryType; - - // This constructor is only to be used by getEmptyKeyEntry - // & getTombstoneKeyEntry. It sets index to the given - // value and mi to zero. - IndexListEntry(ReservedEntryType r) : mi(0) { - switch(r) { - case EMPTY_KEY: index = EMPTY_KEY_INDEX; break; - case TOMBSTONE_KEY: index = TOMBSTONE_KEY_INDEX; break; - default: assert(false && "Invalid value for constructor."); - } - next = this; - prev = this; - } - public: - IndexListEntry(MachineInstr *mi, unsigned index) : mi(mi), index(index) { - assert(index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX && - "Attempt to create invalid index. " - "Available indexes may have been exhausted?."); - } - - bool isValid() const { - return (index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX); - } + IndexListEntry(MachineInstr *mi, unsigned index) : mi(mi), index(index) {} MachineInstr* getInstr() const { return mi; } void setInstr(MachineInstr *mi) { - assert(isValid() && "Attempt to modify reserved index."); this->mi = mi; } unsigned getIndex() const { return index; } void setIndex(unsigned index) { - assert(index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX && - "Attempt to set index to invalid value."); - assert(isValid() && "Attempt to reset reserved index value."); this->index = index; } IndexListEntry* getNext() { return next; } const IndexListEntry* getNext() const { return next; } void setNext(IndexListEntry *next) { - assert(isValid() && "Attempt to modify reserved index."); this->next = next; } IndexListEntry* getPrev() { return prev; } const IndexListEntry* getPrev() const { return prev; } void setPrev(IndexListEntry *prev) { - assert(isValid() && "Attempt to modify reserved index."); this->prev = prev; } - - // This function returns the index list entry that is to be used for empty - // SlotIndex keys. - static IndexListEntry* getEmptyKeyEntry(); - - // This function returns the index list entry that is to be used for - // tombstone SlotIndex keys. - static IndexListEntry* getTombstoneKeyEntry(); }; // Specialize PointerLikeTypeTraits for IndexListEntry. @@ -130,11 +88,10 @@ namespace llvm { PointerIntPair<IndexListEntry*, 2, unsigned> lie; SlotIndex(IndexListEntry *entry, unsigned slot) - : lie(entry, slot) { - assert(entry != 0 && "Attempt to construct index with 0 pointer."); - } + : lie(entry, slot) {} IndexListEntry& entry() const { + assert(isValid() && "Attempt to compare reserved index."); return *lie.getPointer(); } @@ -148,22 +105,27 @@ namespace llvm { } static inline unsigned getHashValue(const SlotIndex &v) { - IndexListEntry *ptrVal = &v.entry(); - return (unsigned((intptr_t)ptrVal) >> 4) ^ - (unsigned((intptr_t)ptrVal) >> 9); + void *ptrVal = v.lie.getOpaqueValue(); + return (unsigned((intptr_t)ptrVal)) ^ (unsigned((intptr_t)ptrVal) >> 9); } public: + enum { + /// The default distance between instructions as returned by distance(). + /// This may vary as instructions are inserted and removed. + InstrDist = 4*NUM + }; + static inline SlotIndex getEmptyKey() { - return SlotIndex(IndexListEntry::getEmptyKeyEntry(), 0); + return SlotIndex(0, 1); } static inline SlotIndex getTombstoneKey() { - return SlotIndex(IndexListEntry::getTombstoneKeyEntry(), 0); + return SlotIndex(0, 2); } /// Construct an invalid index. - SlotIndex() : lie(IndexListEntry::getEmptyKeyEntry(), 0) {} + SlotIndex() : lie(0, 0) {} // Construct a new slot index from the given one, and set the slot. SlotIndex(const SlotIndex &li, Slot s) @@ -175,8 +137,7 @@ namespace llvm { /// Returns true if this is a valid index. Invalid indicies do /// not point into an index table, and cannot be compared. bool isValid() const { - IndexListEntry *entry = lie.getPointer(); - return ((entry!= 0) && (entry->isValid())); + return lie.getPointer(); } /// Print this index to the given raw_ostream. @@ -187,11 +148,11 @@ namespace llvm { /// Compare two SlotIndex objects for equality. bool operator==(SlotIndex other) const { - return getIndex() == other.getIndex(); + return lie == other.lie; } /// Compare two SlotIndex objects for inequality. bool operator!=(SlotIndex other) const { - return getIndex() != other.getIndex(); + return lie != other.lie; } /// Compare two SlotIndex objects. Return true if the first index @@ -217,6 +178,11 @@ namespace llvm { return getIndex() >= other.getIndex(); } + /// isSameInstr - Return true if A and B refer to the same instruction. + static bool isSameInstr(SlotIndex A, SlotIndex B) { + return A.lie.getPointer() == B.lie.getPointer(); + } + /// Return the distance from this index to the given one. int distance(SlotIndex other) const { return other.getIndex() - getIndex(); @@ -376,15 +342,12 @@ namespace llvm { typedef DenseMap<const MachineInstr*, SlotIndex> Mi2IndexMap; Mi2IndexMap mi2iMap; - /// MBB2IdxMap - The indexes of the first and last instructions in the - /// specified basic block. - typedef DenseMap<const MachineBasicBlock*, - std::pair<SlotIndex, SlotIndex> > MBB2IdxMap; - MBB2IdxMap mbb2IdxMap; + /// MBBRanges - Map MBB number to (start, stop) indexes. + SmallVector<std::pair<SlotIndex, SlotIndex>, 8> MBBRanges; /// Idx2MBBMap - Sorted list of pairs of index of first instruction /// and MBB id. - std::vector<IdxMBBPair> idx2MBBMap; + SmallVector<IdxMBBPair, 8> idx2MBBMap; // IndexListEntry allocator. BumpPtrAllocator ileAllocator; @@ -466,6 +429,9 @@ namespace llvm { insert(getTail(), val); } + /// Renumber locally after inserting newEntry. + void renumberIndexes(IndexListEntry *newEntry); + public: static char ID; @@ -530,7 +496,7 @@ 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.entry().getInstr(); + return index.isValid() ? index.entry().getInstr() : 0; } /// Returns the next non-null index. @@ -545,12 +511,55 @@ namespace llvm { return nextNonNull; } + /// getIndexBefore - Returns the index of the last indexed instruction + /// before MI, or the the start index of its basic block. + /// MI is not required to have an index. + SlotIndex getIndexBefore(const MachineInstr *MI) const { + const MachineBasicBlock *MBB = MI->getParent(); + assert(MBB && "MI must be inserted inna basic block"); + MachineBasicBlock::const_iterator I = MI, B = MBB->begin(); + for (;;) { + if (I == B) + return getMBBStartIdx(MBB); + --I; + Mi2IndexMap::const_iterator MapItr = mi2iMap.find(I); + if (MapItr != mi2iMap.end()) + return MapItr->second; + } + } + + /// getIndexAfter - Returns the index of the first indexed instruction + /// after MI, or the end index of its basic block. + /// MI is not required to have an index. + SlotIndex getIndexAfter(const MachineInstr *MI) const { + const MachineBasicBlock *MBB = MI->getParent(); + assert(MBB && "MI must be inserted inna basic block"); + MachineBasicBlock::const_iterator I = MI, E = MBB->end(); + for (;;) { + ++I; + if (I == E) + return getMBBEndIdx(MBB); + Mi2IndexMap::const_iterator MapItr = mi2iMap.find(I); + if (MapItr != mi2iMap.end()) + return MapItr->second; + } + } + + /// Return the (start,end) range of the given basic block number. + const std::pair<SlotIndex, SlotIndex> & + getMBBRange(unsigned Num) const { + return MBBRanges[Num]; + } + /// Return the (start,end) range of the given basic block. const std::pair<SlotIndex, SlotIndex> & - getMBBRange(const MachineBasicBlock *mbb) const { - MBB2IdxMap::const_iterator itr = mbb2IdxMap.find(mbb); - assert(itr != mbb2IdxMap.end() && "MBB not found in maps."); - return itr->second; + getMBBRange(const MachineBasicBlock *MBB) const { + return getMBBRange(MBB->getNumber()); + } + + /// Returns the first index in the given basic block number. + SlotIndex getMBBStartIdx(unsigned Num) const { + return getMBBRange(Num).first; } /// Returns the first index in the given basic block. @@ -558,6 +567,11 @@ namespace llvm { return getMBBRange(mbb).first; } + /// Returns the last index in the given basic block number. + SlotIndex getMBBEndIdx(unsigned Num) const { + return getMBBRange(Num).second; + } + /// Returns the last index in the given basic block. SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const { return getMBBRange(mbb).second; @@ -565,10 +579,12 @@ namespace llvm { /// Returns the basic block which the given index falls in. MachineBasicBlock* getMBBFromIndex(SlotIndex index) const { - std::vector<IdxMBBPair>::const_iterator I = + if (MachineInstr *MI = getInstructionFromIndex(index)) + return MI->getParent(); + SmallVectorImpl<IdxMBBPair>::const_iterator I = std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), index); // Take the pair containing the index - std::vector<IdxMBBPair>::const_iterator J = + SmallVectorImpl<IdxMBBPair>::const_iterator J = ((I != idx2MBBMap.end() && I->first > index) || (I == idx2MBBMap.end() && idx2MBBMap.size()>0)) ? (I-1): I; @@ -580,7 +596,7 @@ namespace llvm { bool findLiveInMBBs(SlotIndex start, SlotIndex end, SmallVectorImpl<MachineBasicBlock*> &mbbs) const { - std::vector<IdxMBBPair>::const_iterator itr = + SmallVectorImpl<IdxMBBPair>::const_iterator itr = std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), start); bool resVal = false; @@ -600,7 +616,7 @@ namespace llvm { assert(start < end && "Backwards ranges not allowed."); - std::vector<IdxMBBPair>::const_iterator itr = + SmallVectorImpl<IdxMBBPair>::const_iterator itr = std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), start); if (itr == idx2MBBMap.end()) { @@ -622,95 +638,47 @@ namespace llvm { /// Insert the given machine instruction into the mapping. Returns the /// assigned index. - SlotIndex insertMachineInstrInMaps(MachineInstr *mi, - bool *deferredRenumber = 0) { + /// If Late is set and there are null indexes between mi's neighboring + /// instructions, create the new index after the null indexes instead of + /// before them. + SlotIndex insertMachineInstrInMaps(MachineInstr *mi, bool Late = false) { assert(mi2iMap.find(mi) == mi2iMap.end() && "Instr already indexed."); // Numbering DBG_VALUE instructions could cause code generation to be // affected by debug information. assert(!mi->isDebugValue() && "Cannot number DBG_VALUE instructions."); - MachineBasicBlock *mbb = mi->getParent(); - - assert(mbb != 0 && "Instr must be added to function."); + assert(mi->getParent() != 0 && "Instr must be added to function."); - MBB2IdxMap::iterator mbbRangeItr = mbb2IdxMap.find(mbb); - - assert(mbbRangeItr != mbb2IdxMap.end() && - "Instruction's parent MBB has not been added to SlotIndexes."); - - MachineBasicBlock::iterator miItr(mi); - bool needRenumber = false; - IndexListEntry *newEntry; - // Get previous index, considering that not all instructions are indexed. - IndexListEntry *prevEntry; - for (;;) { - // If mi is at the mbb beginning, get the prev index from the mbb. - if (miItr == mbb->begin()) { - prevEntry = &mbbRangeItr->second.first.entry(); - break; - } - // Otherwise rewind until we find a mapped instruction. - Mi2IndexMap::const_iterator itr = mi2iMap.find(--miItr); - if (itr != mi2iMap.end()) { - prevEntry = &itr->second.entry(); - break; - } + // Get the entries where mi should be inserted. + IndexListEntry *prevEntry, *nextEntry; + if (Late) { + // Insert mi's index immediately before the following instruction. + nextEntry = &getIndexAfter(mi).entry(); + prevEntry = nextEntry->getPrev(); + } else { + // Insert mi's index immediately after the preceeding instruction. + prevEntry = &getIndexBefore(mi).entry(); + nextEntry = prevEntry->getNext(); } - // Get next entry from previous entry. - IndexListEntry *nextEntry = prevEntry->getNext(); - // 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(); - unsigned newNumber = dist > SlotIndex::NUM ? - prevEntry->getIndex() + ((dist >> 1) & ~3U) : 0; - - if (newNumber == 0) { - needRenumber = true; - } + unsigned dist = ((nextEntry->getIndex() - prevEntry->getIndex())/2) & ~3u; + unsigned newNumber = prevEntry->getIndex() + dist; // Insert a new list entry for mi. - newEntry = createEntry(mi, newNumber); + IndexListEntry *newEntry = createEntry(mi, newNumber); insert(nextEntry, newEntry); - - SlotIndex newIndex(newEntry, SlotIndex::LOAD); - mi2iMap.insert(std::make_pair(mi, newIndex)); - - if (miItr == mbb->end()) { - // If this is the last instr in the MBB then we need to fix up the bb - // range: - mbbRangeItr->second.second = SlotIndex(newEntry, SlotIndex::STORE); - } - // Renumber if we need to. - if (needRenumber) { - if (deferredRenumber == 0) - renumberIndexes(); - else - *deferredRenumber = true; - } + // Renumber locally if we need to. + if (dist == 0) + renumberIndexes(newEntry); + SlotIndex newIndex(newEntry, SlotIndex::LOAD); + mi2iMap.insert(std::make_pair(mi, newIndex)); return newIndex; } - /// Add all instructions in the vector to the index list. This method will - /// defer renumbering until all instrs have been added, and should be - /// preferred when adding multiple instrs. - void insertMachineInstrsInMaps(SmallVectorImpl<MachineInstr*> &mis) { - bool renumber = false; - - for (SmallVectorImpl<MachineInstr*>::iterator - miItr = mis.begin(), miEnd = mis.end(); - miItr != miEnd; ++miItr) { - insertMachineInstrInMaps(*miItr, &renumber); - } - - if (renumber) - renumberIndexes(); - } - - /// Remove the given machine instruction from the mapping. void removeMachineInstrFromMaps(MachineInstr *mi) { // remove index -> MachineInstr and @@ -760,21 +728,14 @@ namespace llvm { SlotIndex startIdx(startEntry, SlotIndex::LOAD); SlotIndex endIdx(nextEntry, SlotIndex::LOAD); - mbb2IdxMap.insert( - std::make_pair(mbb, std::make_pair(startIdx, endIdx))); + assert(unsigned(mbb->getNumber()) == MBBRanges.size() && + "Blocks must be added in order"); + MBBRanges.push_back(std::make_pair(startIdx, endIdx)); idx2MBBMap.push_back(IdxMBBPair(startIdx, mbb)); - if (MachineFunction::iterator(mbb) != mbb->getParent()->begin()) { - // Have to update the end index of the previous block. - MachineBasicBlock *priorMBB = - llvm::prior(MachineFunction::iterator(mbb)); - mbb2IdxMap[priorMBB].second = startIdx; - } - renumberIndexes(); std::sort(idx2MBBMap.begin(), idx2MBBMap.end(), Idx2MBBCompare()); - } }; diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index fba3e48..829f580 100644 --- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -59,6 +59,10 @@ public: virtual const MCSection *getEHFrameSection() const; + virtual void emitPersonalityValue(MCStreamer &Streamer, + const TargetMachine &TM, + const MCSymbol *Sym) const; + const MCSection *getDataRelSection() const { return DataRelSection; } /// getSectionForConstant - Given a constant with the SectionKind, return a @@ -81,6 +85,11 @@ public: getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang, MachineModuleInfo *MMI, unsigned Encoding, MCStreamer &Streamer) const; + + // getCFIPersonalitySymbol - The symbol that gets passed to .cfi_personality. + virtual MCSymbol * + getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang, + MachineModuleInfo *MMI) const; }; @@ -94,7 +103,7 @@ class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile { /// const MCSection *TLSBSSSection; // Defaults to ".tbss". - /// TLSTLVSection - Section for thread local structure infomation. + /// TLSTLVSection - Section for thread local structure information. /// Contains the source code name of the variable, visibility and a pointer /// to the initial value (.tdata or .tbss). const MCSection *TLSTLVSection; // Defaults to ".tlv". @@ -172,9 +181,14 @@ public: MachineModuleInfo *MMI, unsigned Encoding, MCStreamer &Streamer) const; + // getCFIPersonalitySymbol - The symbol that gets passed to .cfi_personality. + virtual MCSymbol * + getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang, + MachineModuleInfo *MMI) const; + virtual unsigned getPersonalityEncoding() const; virtual unsigned getLSDAEncoding() const; - virtual unsigned getFDEEncoding() const; + virtual unsigned getFDEEncoding(bool CFI) const; virtual unsigned getTTypeEncoding() const; }; |