diff options
author | dim <dim@FreeBSD.org> | 2015-12-30 13:13:10 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2015-12-30 13:13:10 +0000 |
commit | 9b5bf5c4f53d65d6a48722d7410ed7cb15f5ba3a (patch) | |
tree | b466a4817f79516eb1df8eae92bccf62ecc84003 /contrib/llvm/include/llvm/CodeGen | |
parent | f09a28d1de99fda4f5517fb12670fc36552f4927 (diff) | |
parent | e194cd6d03d91631334d9d5e55b506036f423cc8 (diff) | |
download | FreeBSD-src-9b5bf5c4f53d65d6a48722d7410ed7cb15f5ba3a.zip FreeBSD-src-9b5bf5c4f53d65d6a48722d7410ed7cb15f5ba3a.tar.gz |
Update llvm to trunk r256633.
Diffstat (limited to 'contrib/llvm/include/llvm/CodeGen')
59 files changed, 2220 insertions, 1545 deletions
diff --git a/contrib/llvm/include/llvm/CodeGen/Analysis.h b/contrib/llvm/include/llvm/CodeGen/Analysis.h index 82d1e8a..38e64ad 100644 --- a/contrib/llvm/include/llvm/CodeGen/Analysis.h +++ b/contrib/llvm/include/llvm/CodeGen/Analysis.h @@ -15,6 +15,7 @@ #define LLVM_CODEGEN_ANALYSIS_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/ISDOpcodes.h" #include "llvm/IR/CallSite.h" @@ -23,6 +24,8 @@ namespace llvm { class GlobalValue; +class MachineBasicBlock; +class MachineFunction; class TargetLoweringBase; class TargetLowering; class TargetMachine; @@ -37,7 +40,7 @@ struct EVT; /// Given an LLVM IR aggregate type and a sequence of insertvalue or /// extractvalue indices that identify a member, return the linearized index of /// the start of the member, i.e the number of element in memory before the -/// seeked one. This is disconnected from the number of bytes. +/// sought one. This is disconnected from the number of bytes. /// /// \param Ty is the type indexed by \p Indices. /// \param Indices is an optional pointer in the indices list to the current @@ -115,6 +118,9 @@ bool returnTypeIsEligibleForTailCall(const Function *F, // or we are in LTO. bool canBeOmittedFromSymbolTable(const GlobalValue *GV); +DenseMap<const MachineBasicBlock *, int> +getFuncletMembership(const MachineFunction &MF); + } // End llvm namespace #endif diff --git a/contrib/llvm/include/llvm/CodeGen/AsmPrinter.h b/contrib/llvm/include/llvm/CodeGen/AsmPrinter.h index fe7efae..f5e778b 100644 --- a/contrib/llvm/include/llvm/CodeGen/AsmPrinter.h +++ b/contrib/llvm/include/llvm/CodeGen/AsmPrinter.h @@ -165,6 +165,9 @@ public: /// Return information about data layout. const DataLayout &getDataLayout() const; + /// Return the pointer size from the TargetMachine + unsigned getPointerSize() const; + /// Return information about subtarget. const MCSubtargetInfo &getSubtargetInfo() const; @@ -233,7 +236,12 @@ public: /// Print assembly representations of the jump tables used by the current /// function to the current output stream. /// - void EmitJumpTableInfo(); + virtual void EmitJumpTableInfo(); + + /// Emit the control variable for an emulated TLS variable. + virtual void EmitEmulatedTLSControlVariable(const GlobalVariable *GV, + MCSymbol *EmittedSym, + bool AllZeroInitValue); /// Emit the specified global variable to the .s file. virtual void EmitGlobalVariable(const GlobalVariable *GV); @@ -254,7 +262,7 @@ public: const MCExpr *lowerConstant(const Constant *CV); /// \brief Print a general LLVM constant to the .s file. - void EmitGlobalConstant(const Constant *CV); + void EmitGlobalConstant(const DataLayout &DL, const Constant *CV); /// \brief Unnamed constant global variables solely contaning a pointer to /// another globals variable act like a global variable "proxy", or GOT @@ -317,7 +325,9 @@ public: /// Targets can override this to change how global constants that are part of /// a C++ static/global constructor list are emitted. - virtual void EmitXXStructor(const Constant *CV) { EmitGlobalConstant(CV); } + virtual void EmitXXStructor(const DataLayout &DL, const Constant *CV) { + EmitGlobalConstant(DL, CV); + } /// Return true if the basic block has exactly one predecessor and the control /// transfer mechanism between the predecessor and this block is a @@ -404,9 +414,6 @@ public: void EmitULEB128(uint64_t Value, const char *Desc = nullptr, unsigned PadTo = 0) const; - /// Emit a .byte 42 directive for a DW_CFA_xxx value. - void EmitCFAByte(unsigned Val) const; - /// Emit a .byte 42 directive that corresponds to an encoding. If verbose /// assembly output is enabled, we output comments describing the encoding. /// Desc is a string saying what the encoding is specifying (e.g. "LSDA"). @@ -446,7 +453,16 @@ public: void emitCFIInstruction(const MCCFIInstruction &Inst) const; /// \brief Emit Dwarf abbreviation table. - void emitDwarfAbbrevs(const std::vector<DIEAbbrev *>& Abbrevs) const; + template <typename T> void emitDwarfAbbrevs(const T &Abbrevs) const { + // For each abbreviation. + for (const auto &Abbrev : Abbrevs) + emitDwarfAbbrev(*Abbrev); + + // Mark end of abbreviations. + EmitULEB128(0, "EOM(3)"); + } + + void emitDwarfAbbrev(const DIEAbbrev &Abbrev) const; /// \brief Recursively emit Dwarf DIE tree. void emitDwarfDIE(const DIE &Die) const; @@ -532,7 +548,8 @@ private: void EmitLLVMUsedList(const ConstantArray *InitList); /// Emit llvm.ident metadata in an '.ident' directive. void EmitModuleIdents(Module &M); - void EmitXXStructorList(const Constant *List, bool isCtor); + void EmitXXStructorList(const DataLayout &DL, const Constant *List, + bool isCtor); GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy &C); }; } diff --git a/contrib/llvm/include/llvm/CodeGen/AtomicExpandUtils.h b/contrib/llvm/include/llvm/CodeGen/AtomicExpandUtils.h new file mode 100644 index 0000000..ac18eac --- /dev/null +++ b/contrib/llvm/include/llvm/CodeGen/AtomicExpandUtils.h @@ -0,0 +1,57 @@ +//===-- AtomicExpandUtils.h - Utilities for expanding atomic instructions -===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/STLExtras.h" +#include "llvm/IR/IRBuilder.h" + +namespace llvm { +class Value; +class AtomicRMWInst; + + +/// Parameters (see the expansion example below): +/// (the builder, %addr, %loaded, %new_val, ordering, +/// /* OUT */ %success, /* OUT */ %new_loaded) +typedef function_ref<void(IRBuilder<> &, Value *, Value *, Value *, + AtomicOrdering, Value *&, Value *&)> CreateCmpXchgInstFun; + +/// \brief Expand an atomic RMW instruction into a loop utilizing +/// cmpxchg. You'll want to make sure your target machine likes cmpxchg +/// instructions in the first place and that there isn't another, better, +/// transformation available (for example AArch32/AArch64 have linked loads). +/// +/// This is useful in passes which can't rewrite the more exotic RMW +/// instructions directly into a platform specific intrinsics (because, say, +/// those intrinsics don't exist). If such a pass is able to expand cmpxchg +/// instructions directly however, then, with this function, it could avoid two +/// extra module passes (avoiding passes by `-atomic-expand` and itself). A +/// specific example would be PNaCl's `RewriteAtomics` pass. +/// +/// Given: atomicrmw some_op iN* %addr, iN %incr ordering +/// +/// The standard expansion we produce is: +/// [...] +/// %init_loaded = load atomic iN* %addr +/// br label %loop +/// loop: +/// %loaded = phi iN [ %init_loaded, %entry ], [ %new_loaded, %loop ] +/// %new = some_op iN %loaded, %incr +/// ; This is what -atomic-expand will produce using this function on i686 targets: +/// %pair = cmpxchg iN* %addr, iN %loaded, iN %new_val +/// %new_loaded = extractvalue { iN, i1 } %pair, 0 +/// %success = extractvalue { iN, i1 } %pair, 1 +/// ; End callback produced IR +/// br i1 %success, label %atomicrmw.end, label %loop +/// atomicrmw.end: +/// [...] +/// +/// Returns true if the containing function was modified. +bool +expandAtomicRMWToCmpXchg(AtomicRMWInst *AI, CreateCmpXchgInstFun Factory); +} diff --git a/contrib/llvm/include/llvm/CodeGen/BasicTTIImpl.h b/contrib/llvm/include/llvm/CodeGen/BasicTTIImpl.h index 9ba2516..d99054e 100644 --- a/contrib/llvm/include/llvm/CodeGen/BasicTTIImpl.h +++ b/contrib/llvm/include/llvm/CodeGen/BasicTTIImpl.h @@ -166,7 +166,7 @@ public: } if (IID == Intrinsic::ctlz) { - if (getTLI()->isCheapToSpeculateCtlz()) + if (getTLI()->isCheapToSpeculateCtlz()) return TargetTransformInfo::TCC_Basic; return TargetTransformInfo::TCC_Expensive; } @@ -256,7 +256,7 @@ public: for (BasicBlock::iterator J = BB->begin(), JE = BB->end(); J != JE; ++J) if (isa<CallInst>(J) || isa<InvokeInst>(J)) { - ImmutableCallSite CS(J); + ImmutableCallSite CS(&*J); if (const Function *F = CS.getCalledFunction()) { if (!static_cast<T *>(this)->isLoweredToCall(F)) continue; @@ -302,12 +302,8 @@ public: if (TLI->isOperationLegalOrPromote(ISD, LT.second)) { // The operation is legal. Assume it costs 1. - // If the type is split to multiple registers, assume that there is some - // overhead to this. // TODO: Once we have extract/insert subvector cost we need to use them. - if (LT.first > 1) - return LT.first * 2 * OpCost; - return LT.first * 1 * OpCost; + return LT.first * OpCost; } if (!TLI->isOperationExpand(ISD, LT.second)) { @@ -496,13 +492,11 @@ public: // itself. Unless the corresponding extending load or truncating store is // legal, then this will scalarize. TargetLowering::LegalizeAction LA = TargetLowering::Expand; - EVT MemVT = getTLI()->getValueType(DL, Src, true); - if (MemVT.isSimple() && MemVT != MVT::Other) { - if (Opcode == Instruction::Store) - LA = getTLI()->getTruncStoreAction(LT.second, MemVT.getSimpleVT()); - else - LA = getTLI()->getLoadExtAction(ISD::EXTLOAD, LT.second, MemVT); - } + EVT MemVT = getTLI()->getValueType(DL, Src); + if (Opcode == Instruction::Store) + LA = getTLI()->getTruncStoreAction(LT.second, MemVT); + else + LA = getTLI()->getLoadExtAction(ISD::EXTLOAD, LT.second, MemVT); if (LA != TargetLowering::Legal && LA != TargetLowering::Custom) { // This is a vector load/store for some illegal type that is scalarized. @@ -530,7 +524,8 @@ public: VectorType *SubVT = VectorType::get(VT->getElementType(), NumSubElts); // Firstly, the cost of load/store operation. - unsigned Cost = getMemoryOpCost(Opcode, VecTy, Alignment, AddressSpace); + unsigned Cost = static_cast<T *>(this)->getMemoryOpCost( + Opcode, VecTy, Alignment, AddressSpace); // Then plus the cost of interleave operation. if (Opcode == Instruction::Load) { @@ -545,18 +540,20 @@ public: assert(Indices.size() <= Factor && "Interleaved memory op has too many members"); + for (unsigned Index : Indices) { assert(Index < Factor && "Invalid index for interleaved memory op"); // Extract elements from loaded vector for each sub vector. for (unsigned i = 0; i < NumSubElts; i++) - Cost += getVectorInstrCost(Instruction::ExtractElement, VT, - Index + i * Factor); + Cost += static_cast<T *>(this)->getVectorInstrCost( + Instruction::ExtractElement, VT, Index + i * Factor); } unsigned InsSubCost = 0; for (unsigned i = 0; i < NumSubElts; i++) - InsSubCost += getVectorInstrCost(Instruction::InsertElement, SubVT, i); + InsSubCost += static_cast<T *>(this)->getVectorInstrCost( + Instruction::InsertElement, SubVT, i); Cost += Indices.size() * InsSubCost; } else { @@ -571,17 +568,51 @@ public: unsigned ExtSubCost = 0; for (unsigned i = 0; i < NumSubElts; i++) - ExtSubCost += getVectorInstrCost(Instruction::ExtractElement, SubVT, i); - - Cost += Factor * ExtSubCost; + ExtSubCost += static_cast<T *>(this)->getVectorInstrCost( + Instruction::ExtractElement, SubVT, i); + Cost += ExtSubCost * Factor; for (unsigned i = 0; i < NumElts; i++) - Cost += getVectorInstrCost(Instruction::InsertElement, VT, i); + Cost += static_cast<T *>(this) + ->getVectorInstrCost(Instruction::InsertElement, VT, i); } return Cost; } + /// Get intrinsic cost based on arguments + unsigned getIntrinsicInstrCost(Intrinsic::ID IID, Type *RetTy, + ArrayRef<Value *> Args) { + switch (IID) { + default: { + SmallVector<Type *, 4> Types; + for (Value *Op : Args) + Types.push_back(Op->getType()); + return getIntrinsicInstrCost(IID, RetTy, Types); + } + case Intrinsic::masked_scatter: { + Value *Mask = Args[3]; + bool VarMask = !isa<Constant>(Mask); + unsigned Alignment = cast<ConstantInt>(Args[2])->getZExtValue(); + return + static_cast<T *>(this)->getGatherScatterOpCost(Instruction::Store, + Args[0]->getType(), + Args[1], VarMask, + Alignment); + } + case Intrinsic::masked_gather: { + Value *Mask = Args[2]; + bool VarMask = !isa<Constant>(Mask); + unsigned Alignment = cast<ConstantInt>(Args[1])->getZExtValue(); + return + static_cast<T *>(this)->getGatherScatterOpCost(Instruction::Load, + RetTy, Args[0], VarMask, + Alignment); + } + } + } + + /// Get intrinsic cost based on argument types unsigned getIntrinsicInstrCost(Intrinsic::ID IID, Type *RetTy, ArrayRef<Type *> Tys) { unsigned ISD = 0; @@ -800,7 +831,7 @@ class BasicTTIImpl : public BasicTTIImplBase<BasicTTIImpl> { const TargetLoweringBase *getTLI() const { return TLI; } public: - explicit BasicTTIImpl(const TargetMachine *ST, Function &F); + explicit BasicTTIImpl(const TargetMachine *ST, const Function &F); // Provide value semantics. MSVC requires that we spell all of these out. BasicTTIImpl(const BasicTTIImpl &Arg) diff --git a/contrib/llvm/include/llvm/CodeGen/CalcSpillWeights.h b/contrib/llvm/include/llvm/CodeGen/CalcSpillWeights.h index 91fb0a9..17c9415 100644 --- a/contrib/llvm/include/llvm/CodeGen/CalcSpillWeights.h +++ b/contrib/llvm/include/llvm/CodeGen/CalcSpillWeights.h @@ -20,6 +20,7 @@ namespace llvm { class LiveIntervals; class MachineBlockFrequencyInfo; class MachineLoopInfo; + class VirtRegMap; /// \brief Normalize the spill weight of a live interval /// @@ -51,6 +52,7 @@ namespace llvm { private: MachineFunction &MF; LiveIntervals &LIS; + VirtRegMap *VRM; const MachineLoopInfo &Loops; const MachineBlockFrequencyInfo &MBFI; DenseMap<unsigned, float> Hint; @@ -58,10 +60,10 @@ namespace llvm { public: VirtRegAuxInfo(MachineFunction &mf, LiveIntervals &lis, - const MachineLoopInfo &loops, + VirtRegMap *vrm, const MachineLoopInfo &loops, const MachineBlockFrequencyInfo &mbfi, NormalizingFn norm = normalizeSpillWeight) - : MF(mf), LIS(lis), Loops(loops), MBFI(mbfi), normalize(norm) {} + : MF(mf), LIS(lis), VRM(vrm), Loops(loops), MBFI(mbfi), normalize(norm) {} /// \brief (re)compute li's spill weight and allocation hint. void calculateSpillWeightAndHint(LiveInterval &li); @@ -70,6 +72,7 @@ namespace llvm { /// \brief Compute spill weights and allocation hints for all virtual register /// live intervals. void calculateSpillWeightsAndHints(LiveIntervals &LIS, MachineFunction &MF, + VirtRegMap *VRM, const MachineLoopInfo &MLI, const MachineBlockFrequencyInfo &MBFI, VirtRegAuxInfo::NormalizingFn norm = diff --git a/contrib/llvm/include/llvm/CodeGen/CallingConvLower.h b/contrib/llvm/include/llvm/CodeGen/CallingConvLower.h index 1fd4eeb..415abb9 100644 --- a/contrib/llvm/include/llvm/CodeGen/CallingConvLower.h +++ b/contrib/llvm/include/llvm/CodeGen/CallingConvLower.h @@ -201,6 +201,7 @@ private: LLVMContext &Context; unsigned StackOffset; + unsigned MaxStackArgAlign; SmallVector<uint32_t, 16> UsedRegs; SmallVector<CCValAssign, 4> PendingLocs; @@ -270,7 +271,18 @@ public: CallingConv::ID getCallingConv() const { return CallingConv; } bool isVarArg() const { return IsVarArg; } - unsigned getNextStackOffset() const { return StackOffset; } + /// getNextStackOffset - Return the next stack offset such that all stack + /// slots satisfy their alignment requirements. + unsigned getNextStackOffset() const { + return StackOffset; + } + + /// getAlignedCallFrameSize - Return the size of the call frame needed to + /// be able to store all arguments and such that the alignment requirement + /// of each of the arguments is satisfied. + unsigned getAlignedCallFrameSize() const { + return RoundUpToAlignment(StackOffset, MaxStackArgAlign); + } /// isAllocated - Return true if the specified register (or an alias) is /// allocated. @@ -357,7 +369,7 @@ public: /// AllocateRegBlock - Attempt to allocate a block of RegsRequired consecutive /// registers. If this is not possible, return zero. Otherwise, return the first /// register of the block that were allocated, marking the entire block as allocated. - unsigned AllocateRegBlock(ArrayRef<uint16_t> Regs, unsigned RegsRequired) { + unsigned AllocateRegBlock(ArrayRef<MCPhysReg> Regs, unsigned RegsRequired) { if (RegsRequired > Regs.size()) return 0; @@ -400,9 +412,10 @@ public: /// and alignment. unsigned AllocateStack(unsigned Size, unsigned Align) { assert(Align && ((Align - 1) & Align) == 0); // Align is power of 2. - StackOffset = ((StackOffset + Align - 1) & ~(Align - 1)); + StackOffset = RoundUpToAlignment(StackOffset, Align); unsigned Result = StackOffset; StackOffset += Size; + MaxStackArgAlign = std::max(Align, MaxStackArgAlign); MF.getFrameInfo()->ensureMaxAlignment(Align); return Result; } diff --git a/contrib/llvm/include/llvm/CodeGen/CommandFlags.h b/contrib/llvm/include/llvm/CodeGen/CommandFlags.h index bedb7d5..0d37dc0 100644 --- a/contrib/llvm/include/llvm/CodeGen/CommandFlags.h +++ b/contrib/llvm/include/llvm/CodeGen/CommandFlags.h @@ -182,6 +182,11 @@ OverrideStackAlignment("stack-alignment", cl::desc("Override default stack alignment"), cl::init(0)); +cl::opt<bool> +StackRealign("stackrealign", + cl::desc("Force align the stack to the minimum alignment"), + cl::init(false)); + cl::opt<std::string> TrapFuncName("trap-func", cl::Hidden, cl::desc("Emit a call to trap function rather than a trap instruction"), @@ -219,6 +224,10 @@ FunctionSections("function-sections", cl::desc("Emit functions into separate sections"), cl::init(false)); +cl::opt<bool> EmulatedTLS("emulated-tls", + cl::desc("Use emulated TLS model"), + cl::init(false)); + cl::opt<bool> UniqueSectionNames("unique-section-names", cl::desc("Give unique names to every section"), cl::init(true)); @@ -238,6 +247,26 @@ JTableType("jump-table-type", "Create one table per unique function type."), clEnumValEnd)); +cl::opt<llvm::EABI> EABIVersion( + "meabi", cl::desc("Set EABI type (default depends on triple):"), + cl::init(EABI::Default), + cl::values(clEnumValN(EABI::Default, "default", + "Triple default EABI version"), + clEnumValN(EABI::EABI4, "4", "EABI version 4"), + clEnumValN(EABI::EABI5, "5", "EABI version 5"), + clEnumValN(EABI::GNU, "gnu", "EABI GNU"), clEnumValEnd)); + +cl::opt<DebuggerKind> +DebuggerTuningOpt("debugger-tune", + cl::desc("Tune debug info for a particular debugger"), + cl::init(DebuggerKind::Default), + cl::values( + clEnumValN(DebuggerKind::GDB, "gdb", "gdb"), + clEnumValN(DebuggerKind::LLDB, "lldb", "lldb"), + clEnumValN(DebuggerKind::SCE, "sce", + "SCE targets (e.g. PS4)"), + clEnumValEnd)); + // Common utility function tightly tied to the options listed here. Initializes // a TargetOptions object with CodeGen flags and returns it. static inline TargetOptions InitTargetOptionsFromCodeGenFlags() { @@ -260,11 +289,14 @@ static inline TargetOptions InitTargetOptionsFromCodeGenFlags() { Options.DataSections = DataSections; Options.FunctionSections = FunctionSections; Options.UniqueSectionNames = UniqueSectionNames; + Options.EmulatedTLS = EmulatedTLS; Options.MCOptions = InitMCTargetOptionsFromFlags(); Options.JTType = JTableType; Options.ThreadModel = TMModel; + Options.EABIVersion = EABIVersion; + Options.DebuggerTuning = DebuggerTuningOpt; return Options; } @@ -325,6 +357,10 @@ static inline void setFunctionAttributes(StringRef CPU, StringRef Features, "disable-tail-calls", toStringRef(DisableTailCalls)); + if (StackRealign) + NewAttrs = NewAttrs.addAttribute(Ctx, AttributeSet::FunctionIndex, + "stackrealign"); + if (TrapFuncName.getNumOccurrences() > 0) for (auto &B : F) for (auto &I : B) diff --git a/contrib/llvm/include/llvm/CodeGen/DFAPacketizer.h b/contrib/llvm/include/llvm/CodeGen/DFAPacketizer.h index c44a7e0..40ec201 100644 --- a/contrib/llvm/include/llvm/CodeGen/DFAPacketizer.h +++ b/contrib/llvm/include/llvm/CodeGen/DFAPacketizer.h @@ -40,22 +40,51 @@ class InstrItineraryData; class DefaultVLIWScheduler; class SUnit; +// -------------------------------------------------------------------- +// Definitions shared between DFAPacketizer.cpp and DFAPacketizerEmitter.cpp + +// DFA_MAX_RESTERMS * DFA_MAX_RESOURCES must fit within sizeof DFAInput. +// This is verified in DFAPacketizer.cpp:DFAPacketizer::DFAPacketizer. +// +// e.g. terms x resource bit combinations that fit in uint32_t: +// 4 terms x 8 bits = 32 bits +// 3 terms x 10 bits = 30 bits +// 2 terms x 16 bits = 32 bits +// +// e.g. terms x resource bit combinations that fit in uint64_t: +// 8 terms x 8 bits = 64 bits +// 7 terms x 9 bits = 63 bits +// 6 terms x 10 bits = 60 bits +// 5 terms x 12 bits = 60 bits +// 4 terms x 16 bits = 64 bits <--- current +// 3 terms x 21 bits = 63 bits +// 2 terms x 32 bits = 64 bits +// +#define DFA_MAX_RESTERMS 4 // The max # of AND'ed resource terms. +#define DFA_MAX_RESOURCES 16 // The max # of resource bits in one term. + +typedef uint64_t DFAInput; +typedef int64_t DFAStateInput; +#define DFA_TBLTYPE "int64_t" // For generating DFAStateInputTable. +// -------------------------------------------------------------------- + class DFAPacketizer { private: - typedef std::pair<unsigned, unsigned> UnsignPair; + typedef std::pair<unsigned, DFAInput> UnsignPair; + const InstrItineraryData *InstrItins; int CurrentState; - const int (*DFAStateInputTable)[2]; + const DFAStateInput (*DFAStateInputTable)[2]; const unsigned *DFAStateEntryTable; // CachedTable is a map from <FromState, Input> to ToState. DenseMap<UnsignPair, unsigned> CachedTable; // ReadTable - Read the DFA transition table and update CachedTable. - void ReadTable(unsigned int state); + void ReadTable(unsigned state); public: - DFAPacketizer(const InstrItineraryData *I, const int (*SIT)[2], + DFAPacketizer(const InstrItineraryData *I, const DFAStateInput (*SIT)[2], const unsigned *SET); // Reset the current state to make all resources available. @@ -63,6 +92,12 @@ public: CurrentState = 0; } + // getInsnInput - Return the DFAInput for an instruction class. + DFAInput getInsnInput(unsigned InsnClass); + + // getInsnInput - Return the DFAInput for an instruction class input vector. + static DFAInput getInsnInput(const std::vector<unsigned> &InsnClass); + // canReserveResources - Check if the resources occupied by a MCInstrDesc // are available in the current state. bool canReserveResources(const llvm::MCInstrDesc *MID); @@ -93,6 +128,7 @@ class VLIWPacketizerList { protected: MachineFunction &MF; const TargetInstrInfo *TII; + AliasAnalysis *AA; // The VLIW Scheduler. DefaultVLIWScheduler *VLIWScheduler; @@ -106,7 +142,9 @@ protected: std::map<MachineInstr*, SUnit*> MIToSUnit; public: - VLIWPacketizerList(MachineFunction &MF, MachineLoopInfo &MLI, bool IsPostRA); + // The AliasAnalysis parameter can be nullptr. + VLIWPacketizerList(MachineFunction &MF, MachineLoopInfo &MLI, + AliasAnalysis *AA); virtual ~VLIWPacketizerList(); @@ -126,8 +164,10 @@ public: return MII; } - // endPacket - End the current packet. - void endPacket(MachineBasicBlock *MBB, MachineInstr *MI); + // End the current packet and reset the state of the packetizer. + // Overriding this function allows the target-specific packetizer + // to perform custom finalization. + virtual void endPacket(MachineBasicBlock *MBB, MachineInstr *MI); // initPacketizerState - perform initialization before packetizing // an instruction. This function is supposed to be overrided by @@ -135,14 +175,24 @@ public: virtual void initPacketizerState() { return; } // ignorePseudoInstruction - Ignore bundling of pseudo instructions. - virtual bool ignorePseudoInstruction(MachineInstr *I, - MachineBasicBlock *MBB) { + virtual bool ignorePseudoInstruction(const MachineInstr *I, + const MachineBasicBlock *MBB) { return false; } // isSoloInstruction - return true if instruction MI can not be packetized // with any other instruction, which means that MI itself is a packet. - virtual bool isSoloInstruction(MachineInstr *MI) { + virtual bool isSoloInstruction(const MachineInstr *MI) { + return true; + } + + // Check if the packetizer should try to add the given instruction to + // the current packet. One reasons for which it may not be desirable + // to include an instruction in the current packet could be that it + // would cause a stall. + // If this function returns "false", the current packet will be ended, + // and the instruction will be added to the next packet. + virtual bool shouldAddToPacket(const MachineInstr *MI) { return true; } diff --git a/contrib/llvm/include/llvm/CodeGen/DIE.h b/contrib/llvm/include/llvm/CodeGen/DIE.h index f07712a..fa612d9 100644 --- a/contrib/llvm/include/llvm/CodeGen/DIE.h +++ b/contrib/llvm/include/llvm/CodeGen/DIE.h @@ -100,10 +100,8 @@ public: /// void Emit(const AsmPrinter *AP) const; -#ifndef NDEBUG void print(raw_ostream &O); void dump(); -#endif }; //===--------------------------------------------------------------------===// @@ -143,9 +141,7 @@ public: void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; -#ifndef NDEBUG void print(raw_ostream &O) const; -#endif }; //===--------------------------------------------------------------------===// @@ -164,9 +160,7 @@ public: void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; -#ifndef NDEBUG void print(raw_ostream &O) const; -#endif }; //===--------------------------------------------------------------------===// @@ -185,9 +179,7 @@ public: void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; -#ifndef NDEBUG void print(raw_ostream &O) const; -#endif }; //===--------------------------------------------------------------------===// @@ -203,9 +195,7 @@ public: void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; -#ifndef NDEBUG void print(raw_ostream &O) const; -#endif }; //===--------------------------------------------------------------------===// @@ -223,9 +213,7 @@ public: void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; -#ifndef NDEBUG void print(raw_ostream &O) const; -#endif }; //===--------------------------------------------------------------------===// @@ -252,9 +240,7 @@ public: : sizeof(int32_t); } -#ifndef NDEBUG void print(raw_ostream &O) const; -#endif }; //===--------------------------------------------------------------------===// @@ -273,9 +259,7 @@ public: return 8; } -#ifndef NDEBUG void print(raw_ostream &O) const; -#endif }; //===--------------------------------------------------------------------===// @@ -295,9 +279,7 @@ public: void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; -#ifndef NDEBUG void print(raw_ostream &O) const; -#endif }; //===--------------------------------------------------------------------===// @@ -444,10 +426,8 @@ public: /// unsigned SizeOf(const AsmPrinter *AP) const; -#ifndef NDEBUG void print(raw_ostream &O) const; void dump() const; -#endif }; struct IntrusiveBackListNode { @@ -566,64 +546,70 @@ class DIEValueList { ListTy List; public: - bool empty() const { return List.empty(); } - - class const_iterator; - class iterator - : public iterator_adaptor_base<iterator, ListTy::iterator, + class const_value_iterator; + class value_iterator + : public iterator_adaptor_base<value_iterator, ListTy::iterator, std::forward_iterator_tag, DIEValue> { - friend class const_iterator; - typedef iterator_adaptor_base<iterator, ListTy::iterator, + friend class const_value_iterator; + typedef iterator_adaptor_base<value_iterator, ListTy::iterator, std::forward_iterator_tag, DIEValue> iterator_adaptor; public: - iterator() = default; - explicit iterator(ListTy::iterator X) : iterator_adaptor(X) {} + value_iterator() = default; + explicit value_iterator(ListTy::iterator X) : iterator_adaptor(X) {} explicit operator bool() const { return bool(wrapped()); } DIEValue &operator*() const { return wrapped()->V; } }; - class const_iterator - : public iterator_adaptor_base<const_iterator, ListTy::const_iterator, - std::forward_iterator_tag, - const DIEValue> { - typedef iterator_adaptor_base<const_iterator, ListTy::const_iterator, + class const_value_iterator : public iterator_adaptor_base< + const_value_iterator, ListTy::const_iterator, + std::forward_iterator_tag, const DIEValue> { + typedef iterator_adaptor_base<const_value_iterator, ListTy::const_iterator, std::forward_iterator_tag, const DIEValue> iterator_adaptor; public: - const_iterator() = default; - const_iterator(DIEValueList::iterator X) : iterator_adaptor(X.wrapped()) {} - explicit const_iterator(ListTy::const_iterator X) : iterator_adaptor(X) {} + const_value_iterator() = default; + const_value_iterator(DIEValueList::value_iterator X) + : iterator_adaptor(X.wrapped()) {} + explicit const_value_iterator(ListTy::const_iterator X) + : iterator_adaptor(X) {} explicit operator bool() const { return bool(wrapped()); } const DIEValue &operator*() const { return wrapped()->V; } }; - iterator insert(BumpPtrAllocator &Alloc, DIEValue V) { + typedef iterator_range<value_iterator> value_range; + typedef iterator_range<const_value_iterator> const_value_range; + + value_iterator addValue(BumpPtrAllocator &Alloc, DIEValue V) { List.push_back(*new (Alloc) Node(V)); - return iterator(ListTy::toIterator(List.back())); + return value_iterator(ListTy::toIterator(List.back())); } - template <class... Ts> - iterator emplace(BumpPtrAllocator &Alloc, Ts &&... Args) { - return insert(Alloc, DIEValue(std::forward<Ts>(Args)...)); + template <class T> + value_iterator addValue(BumpPtrAllocator &Alloc, dwarf::Attribute Attribute, + dwarf::Form Form, T &&Value) { + return addValue(Alloc, DIEValue(Attribute, Form, std::forward<T>(Value))); } - iterator begin() { return iterator(List.begin()); } - iterator end() { return iterator(List.end()); } - const_iterator begin() const { return const_iterator(List.begin()); } - const_iterator end() const { return const_iterator(List.end()); } + value_range values() { + return llvm::make_range(value_iterator(List.begin()), + value_iterator(List.end())); + } + const_value_range values() const { + return llvm::make_range(const_value_iterator(List.begin()), + const_value_iterator(List.end())); + } }; //===--------------------------------------------------------------------===// /// DIE - A structured debug information entry. Has an abbreviation which /// describes its organization. -class DIE : IntrusiveBackListNode { +class DIE : IntrusiveBackListNode, public DIEValueList { friend class IntrusiveBackList<DIE>; -protected: /// Offset - Offset in debug info section. /// unsigned Offset; @@ -643,14 +629,7 @@ protected: DIE *Parent = nullptr; - /// Attribute values. - /// - DIEValueList Values; - -protected: - DIE() : Offset(0), Size(0) {} - -private: + DIE() = delete; explicit DIE(dwarf::Tag Tag) : Offset(0), Size(0), Tag(Tag) {} public: @@ -677,20 +656,6 @@ public: return llvm::make_range(Children.begin(), Children.end()); } - typedef DIEValueList::iterator value_iterator; - typedef iterator_range<value_iterator> value_range; - - value_range values() { - return llvm::make_range(Values.begin(), Values.end()); - } - - typedef DIEValueList::const_iterator const_value_iterator; - typedef iterator_range<const_value_iterator> const_value_range; - - const_value_range values() const { - return llvm::make_range(Values.begin(), Values.end()); - } - DIE *getParent() const { return Parent; } /// Generate the abbreviation for this DIE. @@ -711,17 +676,6 @@ public: void setOffset(unsigned O) { Offset = O; } void setSize(unsigned S) { Size = S; } - /// addValue - Add a value and attributes to a DIE. - /// - value_iterator addValue(BumpPtrAllocator &Alloc, DIEValue Value) { - return Values.insert(Alloc, Value); - } - template <class T> - value_iterator addValue(BumpPtrAllocator &Alloc, dwarf::Attribute Attribute, - dwarf::Form Form, T &&Value) { - return Values.emplace(Alloc, Attribute, Form, std::forward<T>(Value)); - } - /// Add a child to the DIE. DIE &addChild(DIE *Child) { assert(!Child->getParent() && "Child should be orphaned"); @@ -736,16 +690,14 @@ public: /// gives \a DIEValue::isNone) if no such attribute exists. DIEValue findAttribute(dwarf::Attribute Attribute) const; -#ifndef NDEBUG void print(raw_ostream &O, unsigned IndentCount = 0) const; void dump(); -#endif }; //===--------------------------------------------------------------------===// /// DIELoc - Represents an expression location. // -class DIELoc : public DIE { +class DIELoc : public DIEValueList { mutable unsigned Size; // Size in bytes excluding size header. public: @@ -773,15 +725,13 @@ public: void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; -#ifndef NDEBUG void print(raw_ostream &O) const; -#endif }; //===--------------------------------------------------------------------===// /// DIEBlock - Represents a block of values. // -class DIEBlock : public DIE { +class DIEBlock : public DIEValueList { mutable unsigned Size; // Size in bytes excluding size header. public: @@ -806,9 +756,7 @@ public: void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; -#ifndef NDEBUG void print(raw_ostream &O) const; -#endif }; } // end llvm namespace diff --git a/contrib/llvm/include/llvm/CodeGen/FastISel.h b/contrib/llvm/include/llvm/CodeGen/FastISel.h index f04a7cd..cc4e370 100644 --- a/contrib/llvm/include/llvm/CodeGen/FastISel.h +++ b/contrib/llvm/include/llvm/CodeGen/FastISel.h @@ -419,11 +419,11 @@ protected: const TargetRegisterClass *RC, unsigned Op0, bool Op0IsKill, uint64_t Imm1, uint64_t Imm2); - /// \brief Emit a MachineInstr with two register operands and a result + /// \brief Emit a MachineInstr with a floating point immediate, and a result /// register in the given register class. - unsigned fastEmitInst_rf(unsigned MachineInstOpcode, - const TargetRegisterClass *RC, unsigned Op0, - bool Op0IsKill, const ConstantFP *FPImm); + unsigned fastEmitInst_f(unsigned MachineInstOpcode, + const TargetRegisterClass *RC, + const ConstantFP *FPImm); /// \brief Emit a MachineInstr with two register operands, an immediate, and a /// result register in the given register class. @@ -432,23 +432,11 @@ protected: bool Op0IsKill, unsigned Op1, bool Op1IsKill, uint64_t Imm); - /// \brief Emit a MachineInstr with two register operands, two immediates - /// operands, and a result register in the given register class. - unsigned fastEmitInst_rrii(unsigned MachineInstOpcode, - const TargetRegisterClass *RC, unsigned Op0, - bool Op0IsKill, unsigned Op1, bool Op1IsKill, - uint64_t Imm1, uint64_t Imm2); - /// \brief 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); - /// \brief Emit a MachineInstr with a two immediate operands. - unsigned fastEmitInst_ii(unsigned MachineInstrOpcode, - const TargetRegisterClass *RC, uint64_t Imm1, - uint64_t Imm2); - /// \brief Emit a MachineInstr for an extract_subreg from a specified index of /// a superregister to a specified type. unsigned fastEmitInst_extractsubreg(MVT RetVT, unsigned Op0, bool Op0IsKill, @@ -462,6 +450,11 @@ protected: /// immediate (fall-through) successor, and update the CFG. void fastEmitBranch(MachineBasicBlock *MBB, DebugLoc DL); + /// Emit an unconditional branch to \p FalseMBB, obtains the branch weight + /// and adds TrueMBB and FalseMBB to the successor list. + void finishCondBranch(const BasicBlock *BranchBB, MachineBasicBlock *TrueMBB, + MachineBasicBlock *FalseMBB); + /// \brief Update the value map to include the new mapping for this /// instruction, or insert an extra copy to get the result in a previous /// determined register. @@ -566,6 +559,9 @@ private: /// across heavy instructions like calls. void flushLocalValueMap(); + /// \brief Removes dead local value instructions after SavedLastLocalvalue. + void removeDeadLocalValueCode(MachineInstr *SavedLastLocalValue); + /// \brief Insertion point before trying to select the current instruction. MachineBasicBlock::iterator SavedInsertPt; diff --git a/contrib/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h b/contrib/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h index 82c762e..09a9991 100644 --- a/contrib/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h +++ b/contrib/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h @@ -62,6 +62,9 @@ public: /// registers. bool CanLowerReturn; + /// True if part of the CSRs will be handled via explicit copies. + bool SplitCSR; + /// DemoteRegister - if CanLowerReturn is false, DemoteRegister is a vreg /// allocated to hold a pointer to the hidden sret parameter. unsigned DemoteRegister; @@ -72,7 +75,10 @@ public: /// ValueMap - Since we emit code for the function a basic block at a time, /// we must remember which virtual registers hold the values for /// cross-basic-block values. - DenseMap<const Value*, unsigned> ValueMap; + DenseMap<const Value *, unsigned> ValueMap; + + /// Track virtual registers created for exception pointers. + DenseMap<const Value *, unsigned> CatchPadExceptionPointers; // Keep track of frame indices allocated for statepoints as they could be used // across basic block boundaries. @@ -99,7 +105,7 @@ public: /// RegFixups - Registers which need to be replaced after isel is done. DenseMap<unsigned, unsigned> RegFixups; - /// StatepointStackSlots - A list of temporary stack slots (frame indices) + /// StatepointStackSlots - A list of temporary stack slots (frame indices) /// used to spill values at a statepoint. We store them here to enable /// reuse of the same stack slots across different statepoints in different /// basic blocks. @@ -111,11 +117,6 @@ public: /// MBB - The current insert position inside the current block. MachineBasicBlock::iterator InsertPt; -#ifndef NDEBUG - SmallPtrSet<const Instruction *, 8> CatchInfoLost; - SmallPtrSet<const Instruction *, 8> CatchInfoFound; -#endif - struct LiveOutInfo { unsigned NumSignBits : 31; bool IsValid : 1; @@ -161,10 +162,13 @@ public: } unsigned CreateReg(MVT VT); - + unsigned CreateRegs(Type *Ty); - + unsigned InitializeRegForValue(const Value *V) { + // Tokens never live in vregs. + if (V->getType()->isTokenTy()) + return 0; unsigned &R = ValueMap[V]; assert(R == 0 && "Already initialized this value register!"); return R = CreateRegs(V->getType()); @@ -231,6 +235,9 @@ public: /// getArgumentFrameIndex - Get frame index for the byval argument. int getArgumentFrameIndex(const Argument *A); + unsigned getCatchPadExceptionPointerVReg(const Value *CPI, + const TargetRegisterClass *RC); + private: void addSEHHandlersForLPads(ArrayRef<const LandingPadInst *> LPads); diff --git a/contrib/llvm/include/llvm/CodeGen/GCMetadata.h b/contrib/llvm/include/llvm/CodeGen/GCMetadata.h index e883bd1..163117b 100644 --- a/contrib/llvm/include/llvm/CodeGen/GCMetadata.h +++ b/contrib/llvm/include/llvm/CodeGen/GCMetadata.h @@ -160,9 +160,9 @@ class GCModuleInfo : public ImmutablePass { public: /// Lookup the GCStrategy object associated with the given gc name. /// Objects are owned internally; No caller should attempt to delete the - /// returned objects. + /// returned objects. GCStrategy *getGCStrategy(const StringRef Name); - + /// List of per function info objects. In theory, Each of these /// may be associated with a different GC. typedef std::vector<std::unique_ptr<GCFunctionInfo>> FuncInfoVec; diff --git a/contrib/llvm/include/llvm/CodeGen/GCStrategy.h b/contrib/llvm/include/llvm/CodeGen/GCStrategy.h index a1b8e89..3088a86 100644 --- a/contrib/llvm/include/llvm/CodeGen/GCStrategy.h +++ b/contrib/llvm/include/llvm/CodeGen/GCStrategy.h @@ -117,11 +117,11 @@ public: /** @name Statepoint Specific Properties */ ///@{ - /// If the value specified can be reliably distinguished, returns true for + /// If the type specified can be reliably distinguished, returns true for /// pointers to GC managed locations and false for pointers to non-GC /// managed locations. Note a GCStrategy can always return 'None' (i.e. an /// empty optional indicating it can't reliably distinguish. - virtual Optional<bool> isGCManagedPointer(const Value *V) const { + virtual Optional<bool> isGCManagedPointer(const Type *Ty) const { return None; } ///@} diff --git a/contrib/llvm/include/llvm/CodeGen/ISDOpcodes.h b/contrib/llvm/include/llvm/CodeGen/ISDOpcodes.h index fa44301..158ff3c 100644 --- a/contrib/llvm/include/llvm/CodeGen/ISDOpcodes.h +++ b/contrib/llvm/include/llvm/CodeGen/ISDOpcodes.h @@ -108,6 +108,10 @@ namespace ISD { /// and returns an outchain. EH_SJLJ_LONGJMP, + /// OUTCHAIN = EH_SJLJ_SETUP_DISPATCH(INCHAIN) + /// The target initializes the dispatch table here. + EH_SJLJ_SETUP_DISPATCH, + /// TargetConstant* - Like Constant*, but the DAG does not do any folding, /// simplification, or lowering of the constant. They are used for constants /// which are known to fit in the immediate fields of their users, or for @@ -332,7 +336,7 @@ namespace ISD { SHL, SRA, SRL, ROTL, ROTR, /// Byte Swap and Counting operators. - BSWAP, CTTZ, CTLZ, CTPOP, + BSWAP, CTTZ, CTLZ, CTPOP, BITREVERSE, /// Bit counting operators with an undefined result for zero inputs. CTTZ_ZERO_UNDEF, CTLZ_ZERO_UNDEF, @@ -364,9 +368,14 @@ namespace ISD { /// then the result type must also be a vector type. SETCC, + /// Like SetCC, ops #0 and #1 are the LHS and RHS operands to compare, but + /// op #2 is a *carry value*. This operator checks the result of + /// "LHS - RHS - Carry", and can be used to compare two wide integers: + /// (setcce lhshi rhshi (subc lhslo rhslo) cc). Only valid for integers. + SETCCE, + /// SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded - /// integer shift operations, just like ADD/SUB_PARTS. The operation - /// ordering is: + /// integer shift operations. The operation ordering is: /// [Lo,Hi] = op [LoLHS,HiLHS], Amt SHL_PARTS, SRA_PARTS, SRL_PARTS, @@ -506,7 +515,15 @@ namespace ISD { FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW, FLOG, FLOG2, FLOG10, FEXP, FEXP2, FCEIL, FTRUNC, FRINT, FNEARBYINT, FROUND, FFLOOR, + /// FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two + /// values. + /// In the case where a single input is NaN, the non-NaN input is returned. + /// + /// The return value of (FMINNUM 0.0, -0.0) could be either 0.0 or -0.0. FMINNUM, FMAXNUM, + /// FMINNAN/FMAXNAN - Behave identically to FMINNUM/FMAXNUM, except that + /// when a single input is NaN, NaN is returned. + FMINNAN, FMAXNAN, /// FSINCOS - Compute both fsin and fcos as a single operation. FSINCOS, @@ -575,6 +592,18 @@ namespace ISD { /// take a chain as input and return a chain. EH_LABEL, + /// CATCHPAD - Represents a catchpad instruction. + CATCHPAD, + + /// CATCHRET - Represents a return from a catch block funclet. Used for + /// MSVC compatible exception handling. Takes a chain operand and a + /// destination basic block operand. + CATCHRET, + + /// CLEANUPRET - Represents a return from a cleanup block funclet. Used for + /// MSVC compatible exception handling. Takes only a chain operand. + CLEANUPRET, + /// STACKSAVE - STACKSAVE has one operand, an input chain. It produces a /// value, the same type as the pointer type for the system, and an output /// chain. @@ -618,9 +647,11 @@ namespace ISD { PCMARKER, /// READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic. - /// The only operand is a chain and a value and a chain are produced. The - /// value is the contents of the architecture specific cycle counter like - /// register (or other high accuracy low latency clock source) + /// It produces a chain and one i64 value. The only operand is a chain. + /// If i64 is not legal, the result will be expanded into smaller values. + /// Still, it returns an i64, so targets should set legality for i64. + /// The result is the content of the architecture-specific cycle + /// counter-like register (or other high accuracy low latency clock source). READCYCLECOUNTER, /// HANDLENODE node - Used as a handle for various purposes. @@ -719,6 +750,12 @@ namespace ISD { GC_TRANSITION_START, GC_TRANSITION_END, + /// GET_DYNAMIC_AREA_OFFSET - get offset from native SP to the address of + /// the most recent dynamic alloca. For most targets that would be 0, but + /// for some others (e.g. PowerPC, PowerPC64) that would be compile-time + /// known nonzero constant. The only operand here is the chain. + GET_DYNAMIC_AREA_OFFSET, + /// BUILTIN_OP_END - This must be the last enum value in this list. /// The target-specific pre-isel opcode values start here. BUILTIN_OP_END diff --git a/contrib/llvm/include/llvm/CodeGen/IntrinsicLowering.h b/contrib/llvm/include/llvm/CodeGen/IntrinsicLowering.h index 9e6ab7d..a404b9b 100644 --- a/contrib/llvm/include/llvm/CodeGen/IntrinsicLowering.h +++ b/contrib/llvm/include/llvm/CodeGen/IntrinsicLowering.h @@ -19,41 +19,40 @@ #include "llvm/IR/Intrinsics.h" namespace llvm { - class CallInst; - class Module; - class DataLayout; - - class IntrinsicLowering { - const DataLayout& DL; - - - bool Warned; - public: - explicit IntrinsicLowering(const DataLayout &DL) : - DL(DL), Warned(false) {} - - /// AddPrototypes - This method, if called, causes all of the prototypes - /// that might be needed by an intrinsic lowering implementation to be - /// inserted into the module specified. - void AddPrototypes(Module &M); - - /// LowerIntrinsicCall - This method replaces a call with the LLVM function - /// which should be used to implement the specified intrinsic function call. - /// If an intrinsic function must be implemented by the code generator - /// (such as va_start), this function should print a message and abort. - /// - /// Otherwise, if an intrinsic function call can be lowered, the code to - /// implement it (often a call to a non-intrinsic function) is inserted - /// _after_ the call instruction and the call is deleted. The caller must - /// be capable of handling this kind of change. - /// - void LowerIntrinsicCall(CallInst *CI); - - /// LowerToByteSwap - Replace a call instruction into a call to bswap - /// intrinsic. Return false if it has determined the call is not a - /// simple integer bswap. - static bool LowerToByteSwap(CallInst *CI); - }; +class CallInst; +class Module; +class DataLayout; + +class IntrinsicLowering { + const DataLayout &DL; + + bool Warned; + +public: + explicit IntrinsicLowering(const DataLayout &DL) : DL(DL), Warned(false) {} + + /// AddPrototypes - This method, if called, causes all of the prototypes + /// that might be needed by an intrinsic lowering implementation to be + /// inserted into the module specified. + void AddPrototypes(Module &M); + + /// LowerIntrinsicCall - This method replaces a call with the LLVM function + /// which should be used to implement the specified intrinsic function call. + /// If an intrinsic function must be implemented by the code generator + /// (such as va_start), this function should print a message and abort. + /// + /// Otherwise, if an intrinsic function call can be lowered, the code to + /// implement it (often a call to a non-intrinsic function) is inserted + /// _after_ the call instruction and the call is deleted. The caller must + /// be capable of handling this kind of change. + /// + void LowerIntrinsicCall(CallInst *CI); + + /// LowerToByteSwap - Replace a call instruction into a call to bswap + /// intrinsic. Return false if it has determined the call is not a + /// simple integer bswap. + static bool LowerToByteSwap(CallInst *CI); +}; } #endif diff --git a/contrib/llvm/include/llvm/CodeGen/LiveInterval.h b/contrib/llvm/include/llvm/CodeGen/LiveInterval.h index 9b8b91c..0157bf9 100644 --- a/contrib/llvm/include/llvm/CodeGen/LiveInterval.h +++ b/contrib/llvm/include/llvm/CodeGen/LiveInterval.h @@ -25,6 +25,7 @@ #include "llvm/CodeGen/SlotIndexes.h" #include "llvm/Support/AlignOf.h" #include "llvm/Support/Allocator.h" +#include "llvm/Target/TargetRegisterInfo.h" #include <cassert> #include <climits> #include <set> @@ -595,15 +596,15 @@ namespace llvm { class SubRange : public LiveRange { public: SubRange *Next; - unsigned LaneMask; + LaneBitmask LaneMask; /// Constructs a new SubRange object. - SubRange(unsigned LaneMask) + SubRange(LaneBitmask LaneMask) : Next(nullptr), LaneMask(LaneMask) { } /// Constructs a new SubRange object by copying liveness from @p Other. - SubRange(unsigned LaneMask, const LiveRange &Other, + SubRange(LaneBitmask LaneMask, const LiveRange &Other, BumpPtrAllocator &Allocator) : LiveRange(Other, Allocator), Next(nullptr), LaneMask(LaneMask) { } @@ -677,7 +678,8 @@ namespace llvm { /// Creates a new empty subregister live range. The range is added at the /// beginning of the subrange list; subrange iterators stay valid. - SubRange *createSubRange(BumpPtrAllocator &Allocator, unsigned LaneMask) { + SubRange *createSubRange(BumpPtrAllocator &Allocator, + LaneBitmask LaneMask) { SubRange *Range = new (Allocator) SubRange(LaneMask); appendSubRange(Range); return Range; @@ -685,7 +687,8 @@ namespace llvm { /// Like createSubRange() but the new range is filled with a copy of the /// liveness information in @p CopyFrom. - SubRange *createSubRangeFrom(BumpPtrAllocator &Allocator, unsigned LaneMask, + SubRange *createSubRangeFrom(BumpPtrAllocator &Allocator, + LaneBitmask LaneMask, const LiveRange &CopyFrom) { SubRange *Range = new (Allocator) SubRange(LaneMask, CopyFrom, Allocator); appendSubRange(Range); @@ -842,11 +845,6 @@ namespace llvm { LiveIntervals &LIS; IntEqClasses EqClass; - // Note that values a and b are connected. - void Connect(unsigned a, unsigned b); - - unsigned Renumber(); - public: explicit ConnectedVNInfoEqClasses(LiveIntervals &lis) : LIS(lis) {} @@ -858,12 +856,12 @@ namespace llvm { /// the equivalence class assigned the VNI. 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. - /// Instructions using LIV[0] are rewritten. - void Distribute(LiveInterval *LIV[], MachineRegisterInfo &MRI); - + /// Distribute values in \p LI into a separate LiveIntervals + /// for each connected component. LIV must have an empty LiveInterval for + /// each additional connected component. The first connected component is + /// left in \p LI. + void Distribute(LiveInterval &LI, LiveInterval *LIV[], + MachineRegisterInfo &MRI); }; } diff --git a/contrib/llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h b/contrib/llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h index 9673f80..87421e2 100644 --- a/contrib/llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h +++ b/contrib/llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -22,6 +22,7 @@ #include "llvm/ADT/IndexedMap.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/CodeGen/LiveInterval.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFunctionPass.h" @@ -36,7 +37,6 @@ namespace llvm { extern cl::opt<bool> UseSegmentSetForPhysRegs; - class AliasAnalysis; class BitVector; class BlockFrequency; class LiveRangeCalc; @@ -147,13 +147,12 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs; LiveInterval::Segment addSegmentToEndOfBlock(unsigned reg, MachineInstr* startInst); - /// shrinkToUses - After removing some uses of a register, shrink its live - /// 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. - /// New dead machine instructions are added to the dead vector. - /// Return true if the interval may have been separated into multiple - /// connected components. + /// After removing some uses of a register, shrink its live 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. New dead machine instructions + /// are added to the dead vector. Returns true if the interval may have been + /// separated into multiple connected components. bool shrinkToUses(LiveInterval *li, SmallVectorImpl<MachineInstr*> *dead = nullptr); @@ -161,6 +160,8 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs; /// shrinkToUses(LiveInterval *li, SmallVectorImpl<MachineInstr*> *dead) /// that works on a subregister live range and only looks at uses matching /// the lane mask of the subregister range. + /// This may leave the subrange empty which needs to be cleaned up with + /// LiveInterval::removeEmptySubranges() afterwards. void shrinkToUses(LiveInterval::SubRange &SR, unsigned Reg); /// extendToIndices - Extend the live range of LI to reach all points in @@ -257,11 +258,6 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs; Indexes->replaceMachineInstrInMaps(MI, NewMI); } - bool findLiveInMBBs(SlotIndex Start, SlotIndex End, - SmallVectorImpl<MachineBasicBlock*> &MBBs) const { - return Indexes->findLiveInMBBs(Start, End, MBBs); - } - VNInfo::Allocator& getVNInfoAllocator() { return VNInfoAllocator; } void getAnalysisUsage(AnalysisUsage &AU) const override; @@ -406,6 +402,10 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs; /// that start at position @p Pos. void removeVRegDefAt(LiveInterval &LI, SlotIndex Pos); + /// Split separate components in LiveInterval \p LI into separate intervals. + void splitSeparateComponents(LiveInterval &LI, + SmallVectorImpl<LiveInterval*> &SplitLIs); + private: /// Compute live intervals for all virtual registers. void computeVirtRegs(); @@ -440,7 +440,7 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs; void repairOldRegInRange(MachineBasicBlock::iterator Begin, MachineBasicBlock::iterator End, const SlotIndex endIdx, LiveRange &LR, - unsigned Reg, unsigned LaneMask = ~0u); + unsigned Reg, LaneBitmask LaneMask = ~0u); class HMEditor; }; diff --git a/contrib/llvm/include/llvm/CodeGen/LivePhysRegs.h b/contrib/llvm/include/llvm/CodeGen/LivePhysRegs.h index 6475e7b..3bdf5ae 100644 --- a/contrib/llvm/include/llvm/CodeGen/LivePhysRegs.h +++ b/contrib/llvm/include/llvm/CodeGen/LivePhysRegs.h @@ -109,7 +109,7 @@ public: /// \brief Simulates liveness when stepping forward over an /// instruction(bundle): Remove killed-uses, add defs. This is the not /// recommended way, because it depends on accurate kill flags. If possible - /// use stepBackwards() instead of this function. + /// use stepBackward() instead of this function. /// The clobbers set will be the list of registers either defined or clobbered /// by a regmask. The operand will identify whether this is a regmask or /// register operand. @@ -122,9 +122,9 @@ public: void addLiveIns(const MachineBasicBlock *MBB, bool AddPristines = false); /// \brief Adds all live-out registers of basic block @p MBB; After prologue/ - /// epilogue insertion \p AddPristines should be set to true to insert the - /// pristine registers. - void addLiveOuts(const MachineBasicBlock *MBB, bool AddPristines = false); + /// epilogue insertion \p AddPristinesAndCSRs should be set to true. + void addLiveOuts(const MachineBasicBlock *MBB, + bool AddPristinesAndCSRs = false); typedef SparseSet<unsigned>::const_iterator const_iterator; const_iterator begin() const { return LiveRegs.begin(); } diff --git a/contrib/llvm/include/llvm/CodeGen/LiveRangeEdit.h b/contrib/llvm/include/llvm/CodeGen/LiveRangeEdit.h index c97c636..2271e33 100644 --- a/contrib/llvm/include/llvm/CodeGen/LiveRangeEdit.h +++ b/contrib/llvm/include/llvm/CodeGen/LiveRangeEdit.h @@ -21,6 +21,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/CodeGen/LiveInterval.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Target/TargetMachine.h" @@ -28,7 +29,6 @@ namespace llvm { -class AliasAnalysis; class LiveIntervals; class MachineBlockFrequencyInfo; class MachineLoopInfo; diff --git a/contrib/llvm/include/llvm/CodeGen/LiveRegMatrix.h b/contrib/llvm/include/llvm/CodeGen/LiveRegMatrix.h index 86a0c7b..e169058 100644 --- a/contrib/llvm/include/llvm/CodeGen/LiveRegMatrix.h +++ b/contrib/llvm/include/llvm/CodeGen/LiveRegMatrix.h @@ -32,13 +32,11 @@ namespace llvm { class LiveInterval; class LiveIntervalAnalysis; -class MachineRegisterInfo; class TargetRegisterInfo; class VirtRegMap; class LiveRegMatrix : public MachineFunctionPass { const TargetRegisterInfo *TRI; - MachineRegisterInfo *MRI; LiveIntervals *LIS; VirtRegMap *VRM; diff --git a/contrib/llvm/include/llvm/CodeGen/LiveStackAnalysis.h b/contrib/llvm/include/llvm/CodeGen/LiveStackAnalysis.h index f495507..3ffbe3d 100644 --- a/contrib/llvm/include/llvm/CodeGen/LiveStackAnalysis.h +++ b/contrib/llvm/include/llvm/CodeGen/LiveStackAnalysis.h @@ -25,76 +25,74 @@ namespace llvm { - class LiveStacks : public MachineFunctionPass { - const TargetRegisterInfo *TRI; - - /// Special pool allocator for VNInfo's (LiveInterval val#). - /// - VNInfo::Allocator VNInfoAllocator; - - /// S2IMap - Stack slot indices to live interval mapping. - /// - typedef std::unordered_map<int, LiveInterval> SS2IntervalMap; - SS2IntervalMap S2IMap; - - /// S2RCMap - Stack slot indices to register class mapping. - std::map<int, const TargetRegisterClass*> S2RCMap; - - public: - static char ID; // Pass identification, replacement for typeid - LiveStacks() : MachineFunctionPass(ID) { - initializeLiveStacksPass(*PassRegistry::getPassRegistry()); - } - - typedef SS2IntervalMap::iterator iterator; - typedef SS2IntervalMap::const_iterator const_iterator; - const_iterator begin() const { return S2IMap.begin(); } - const_iterator end() const { return S2IMap.end(); } - iterator begin() { return S2IMap.begin(); } - iterator end() { return S2IMap.end(); } - - unsigned getNumIntervals() const { return (unsigned)S2IMap.size(); } - - LiveInterval &getOrCreateInterval(int Slot, const TargetRegisterClass *RC); - - LiveInterval &getInterval(int Slot) { - assert(Slot >= 0 && "Spill slot indice must be >= 0"); - SS2IntervalMap::iterator I = S2IMap.find(Slot); - assert(I != S2IMap.end() && "Interval does not exist for stack slot"); - return I->second; - } - - const LiveInterval &getInterval(int Slot) const { - assert(Slot >= 0 && "Spill slot indice must be >= 0"); - SS2IntervalMap::const_iterator I = S2IMap.find(Slot); - assert(I != S2IMap.end() && "Interval does not exist for stack slot"); - return I->second; - } - - bool hasInterval(int Slot) const { - return S2IMap.count(Slot); - } - - const TargetRegisterClass *getIntervalRegClass(int Slot) const { - assert(Slot >= 0 && "Spill slot indice must be >= 0"); - std::map<int, const TargetRegisterClass*>::const_iterator - I = S2RCMap.find(Slot); - assert(I != S2RCMap.end() && - "Register class info does not exist for stack slot"); - return I->second; - } - - VNInfo::Allocator& getVNInfoAllocator() { return VNInfoAllocator; } - - void getAnalysisUsage(AnalysisUsage &AU) const override; - void releaseMemory() override; - - /// runOnMachineFunction - pass entry point - bool runOnMachineFunction(MachineFunction&) override; - - /// print - Implement the dump method. - void print(raw_ostream &O, const Module* = nullptr) const override; - }; +class LiveStacks : public MachineFunctionPass { + const TargetRegisterInfo *TRI; + + /// Special pool allocator for VNInfo's (LiveInterval val#). + /// + VNInfo::Allocator VNInfoAllocator; + + /// S2IMap - Stack slot indices to live interval mapping. + /// + typedef std::unordered_map<int, LiveInterval> SS2IntervalMap; + SS2IntervalMap S2IMap; + + /// S2RCMap - Stack slot indices to register class mapping. + std::map<int, const TargetRegisterClass *> S2RCMap; + +public: + static char ID; // Pass identification, replacement for typeid + LiveStacks() : MachineFunctionPass(ID) { + initializeLiveStacksPass(*PassRegistry::getPassRegistry()); + } + + typedef SS2IntervalMap::iterator iterator; + typedef SS2IntervalMap::const_iterator const_iterator; + const_iterator begin() const { return S2IMap.begin(); } + const_iterator end() const { return S2IMap.end(); } + iterator begin() { return S2IMap.begin(); } + iterator end() { return S2IMap.end(); } + + unsigned getNumIntervals() const { return (unsigned)S2IMap.size(); } + + LiveInterval &getOrCreateInterval(int Slot, const TargetRegisterClass *RC); + + LiveInterval &getInterval(int Slot) { + assert(Slot >= 0 && "Spill slot indice must be >= 0"); + SS2IntervalMap::iterator I = S2IMap.find(Slot); + assert(I != S2IMap.end() && "Interval does not exist for stack slot"); + return I->second; + } + + const LiveInterval &getInterval(int Slot) const { + assert(Slot >= 0 && "Spill slot indice must be >= 0"); + SS2IntervalMap::const_iterator I = S2IMap.find(Slot); + assert(I != S2IMap.end() && "Interval does not exist for stack slot"); + return I->second; + } + + bool hasInterval(int Slot) const { return S2IMap.count(Slot); } + + const TargetRegisterClass *getIntervalRegClass(int Slot) const { + assert(Slot >= 0 && "Spill slot indice must be >= 0"); + std::map<int, const TargetRegisterClass *>::const_iterator I = + S2RCMap.find(Slot); + assert(I != S2RCMap.end() && + "Register class info does not exist for stack slot"); + return I->second; + } + + VNInfo::Allocator &getVNInfoAllocator() { return VNInfoAllocator; } + + void getAnalysisUsage(AnalysisUsage &AU) const override; + void releaseMemory() override; + + /// runOnMachineFunction - pass entry point + bool runOnMachineFunction(MachineFunction &) override; + + /// print - Implement the dump method. + void print(raw_ostream &O, const Module * = nullptr) const override; +}; } #endif /* LLVM_CODEGEN_LIVESTACK_ANALYSIS_H */ diff --git a/contrib/llvm/include/llvm/CodeGen/MIRParser/MIRParser.h b/contrib/llvm/include/llvm/CodeGen/MIRParser/MIRParser.h index 67b756d..a569d5e 100644 --- a/contrib/llvm/include/llvm/CodeGen/MIRParser/MIRParser.h +++ b/contrib/llvm/include/llvm/CodeGen/MIRParser/MIRParser.h @@ -1,4 +1,4 @@ -//===- MIRParser.h - MIR serialization format parser ----------------------===// +//===- MIRParser.h - MIR serialization format parser ------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -37,7 +37,7 @@ class MIRParser : public MachineFunctionInitializer { public: MIRParser(std::unique_ptr<MIRParserImpl> Impl); MIRParser(const MIRParser &) = delete; - ~MIRParser(); + ~MIRParser() override; /// Parse the optional LLVM IR module that's embedded in the MIR file. /// @@ -78,4 +78,4 @@ createMIRParser(std::unique_ptr<MemoryBuffer> Contents, LLVMContext &Context); } // end namespace llvm -#endif +#endif // LLVM_CODEGEN_MIRPARSER_MIRPARSER_H diff --git a/contrib/llvm/include/llvm/CodeGen/MIRYamlMapping.h b/contrib/llvm/include/llvm/CodeGen/MIRYamlMapping.h index 9798e5c..14d3744 100644 --- a/contrib/llvm/include/llvm/CodeGen/MIRYamlMapping.h +++ b/contrib/llvm/include/llvm/CodeGen/MIRYamlMapping.h @@ -19,6 +19,7 @@ #define LLVM_LIB_CODEGEN_MIRYAMLMAPPING_H #include "llvm/ADT/StringRef.h" +#include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/Support/YAMLTraits.h" #include <vector> @@ -72,54 +73,109 @@ template <> struct ScalarTraits<FlowStringValue> { static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); } }; +struct BlockStringValue { + StringValue Value; +}; + +template <> struct BlockScalarTraits<BlockStringValue> { + static void output(const BlockStringValue &S, void *Ctx, raw_ostream &OS) { + return ScalarTraits<StringValue>::output(S.Value, Ctx, OS); + } + + static StringRef input(StringRef Scalar, void *Ctx, BlockStringValue &S) { + return ScalarTraits<StringValue>::input(Scalar, Ctx, S.Value); + } +}; + +/// A wrapper around unsigned which contains a source range that's being set +/// during parsing. +struct UnsignedValue { + unsigned Value; + SMRange SourceRange; + + UnsignedValue() : Value(0) {} + UnsignedValue(unsigned Value) : Value(Value) {} + + bool operator==(const UnsignedValue &Other) const { + return Value == Other.Value; + } +}; + +template <> struct ScalarTraits<UnsignedValue> { + static void output(const UnsignedValue &Value, void *Ctx, raw_ostream &OS) { + return ScalarTraits<unsigned>::output(Value.Value, Ctx, OS); + } + + static StringRef input(StringRef Scalar, void *Ctx, UnsignedValue &Value) { + if (const auto *Node = + reinterpret_cast<yaml::Input *>(Ctx)->getCurrentNode()) + Value.SourceRange = Node->getSourceRange(); + return ScalarTraits<unsigned>::input(Scalar, Ctx, Value.Value); + } + + static bool mustQuote(StringRef Scalar) { + return ScalarTraits<unsigned>::mustQuote(Scalar); + } +}; + +template <> struct ScalarEnumerationTraits<MachineJumpTableInfo::JTEntryKind> { + static void enumeration(yaml::IO &IO, + MachineJumpTableInfo::JTEntryKind &EntryKind) { + IO.enumCase(EntryKind, "block-address", + MachineJumpTableInfo::EK_BlockAddress); + IO.enumCase(EntryKind, "gp-rel64-block-address", + MachineJumpTableInfo::EK_GPRel64BlockAddress); + IO.enumCase(EntryKind, "gp-rel32-block-address", + MachineJumpTableInfo::EK_GPRel32BlockAddress); + IO.enumCase(EntryKind, "label-difference32", + MachineJumpTableInfo::EK_LabelDifference32); + IO.enumCase(EntryKind, "inline", MachineJumpTableInfo::EK_Inline); + IO.enumCase(EntryKind, "custom32", MachineJumpTableInfo::EK_Custom32); + } +}; + } // end namespace yaml } // end namespace llvm LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::StringValue) LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::FlowStringValue) +LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::UnsignedValue) namespace llvm { namespace yaml { struct VirtualRegisterDefinition { - unsigned ID; + UnsignedValue ID; StringValue Class; - // TODO: Serialize the virtual register hints. + StringValue PreferredRegister; + // TODO: Serialize the target specific register hints. }; template <> struct MappingTraits<VirtualRegisterDefinition> { static void mapping(IO &YamlIO, VirtualRegisterDefinition &Reg) { YamlIO.mapRequired("id", Reg.ID); YamlIO.mapRequired("class", Reg.Class); + YamlIO.mapOptional("preferred-register", Reg.PreferredRegister, + StringValue()); // Don't print out when it's empty. } static const bool flow = true; }; -struct MachineBasicBlock { - unsigned ID; - StringValue Name; - unsigned Alignment = 0; - bool IsLandingPad = false; - bool AddressTaken = false; - // TODO: Serialize the successor weights. - std::vector<FlowStringValue> Successors; - std::vector<FlowStringValue> LiveIns; - std::vector<StringValue> Instructions; +struct MachineFunctionLiveIn { + StringValue Register; + StringValue VirtualRegister; }; -template <> struct MappingTraits<MachineBasicBlock> { - static void mapping(IO &YamlIO, MachineBasicBlock &MBB) { - YamlIO.mapRequired("id", MBB.ID); - YamlIO.mapOptional("name", MBB.Name, - StringValue()); // Don't print out an empty name. - YamlIO.mapOptional("alignment", MBB.Alignment); - YamlIO.mapOptional("isLandingPad", MBB.IsLandingPad); - YamlIO.mapOptional("addressTaken", MBB.AddressTaken); - YamlIO.mapOptional("successors", MBB.Successors); - YamlIO.mapOptional("liveins", MBB.LiveIns); - YamlIO.mapOptional("instructions", MBB.Instructions); +template <> struct MappingTraits<MachineFunctionLiveIn> { + static void mapping(IO &YamlIO, MachineFunctionLiveIn &LiveIn) { + YamlIO.mapRequired("reg", LiveIn.Register); + YamlIO.mapOptional( + "virtual-reg", LiveIn.VirtualRegister, + StringValue()); // Don't print the virtual register when it's empty. } + + static const bool flow = true; }; /// Serializable representation of stack object from the MachineFrameInfo class. @@ -128,16 +184,21 @@ template <> struct MappingTraits<MachineBasicBlock> { /// determined by the object's type and frame information flags. /// Dead stack objects aren't serialized. /// -/// TODO: Determine isPreallocated flag by mapping between objects and local -/// objects (Serialize local objects). +/// The 'isPreallocated' flag is determined by the local offset. struct MachineStackObject { enum ObjectType { DefaultType, SpillSlot, VariableSized }; - // TODO: Serialize LLVM alloca reference. - unsigned ID; + UnsignedValue ID; + StringValue Name; + // TODO: Serialize unnamed LLVM alloca reference. ObjectType Type = DefaultType; int64_t Offset = 0; uint64_t Size = 0; unsigned Alignment = 0; + StringValue CalleeSavedRegister; + Optional<int64_t> LocalOffset; + StringValue DebugVar; + StringValue DebugExpr; + StringValue DebugLoc; }; template <> struct ScalarEnumerationTraits<MachineStackObject::ObjectType> { @@ -151,6 +212,8 @@ template <> struct ScalarEnumerationTraits<MachineStackObject::ObjectType> { template <> struct MappingTraits<MachineStackObject> { static void mapping(yaml::IO &YamlIO, MachineStackObject &Object) { YamlIO.mapRequired("id", Object.ID); + YamlIO.mapOptional("name", Object.Name, + StringValue()); // Don't print out an empty name. YamlIO.mapOptional( "type", Object.Type, MachineStackObject::DefaultType); // Don't print the default type. @@ -158,6 +221,15 @@ template <> struct MappingTraits<MachineStackObject> { if (Object.Type != MachineStackObject::VariableSized) YamlIO.mapRequired("size", Object.Size); YamlIO.mapOptional("alignment", Object.Alignment); + YamlIO.mapOptional("callee-saved-register", Object.CalleeSavedRegister, + StringValue()); // Don't print it out when it's empty. + YamlIO.mapOptional("local-offset", Object.LocalOffset); + YamlIO.mapOptional("di-variable", Object.DebugVar, + StringValue()); // Don't print it out when it's empty. + YamlIO.mapOptional("di-expression", Object.DebugExpr, + StringValue()); // Don't print it out when it's empty. + YamlIO.mapOptional("di-location", Object.DebugLoc, + StringValue()); // Don't print it out when it's empty. } static const bool flow = true; @@ -167,13 +239,14 @@ template <> struct MappingTraits<MachineStackObject> { /// MachineFrameInfo class. struct FixedMachineStackObject { enum ObjectType { DefaultType, SpillSlot }; - unsigned ID; + UnsignedValue ID; ObjectType Type = DefaultType; int64_t Offset = 0; uint64_t Size = 0; unsigned Alignment = 0; bool IsImmutable = false; bool IsAliased = false; + StringValue CalleeSavedRegister; }; template <> @@ -198,22 +271,64 @@ template <> struct MappingTraits<FixedMachineStackObject> { YamlIO.mapOptional("isImmutable", Object.IsImmutable); YamlIO.mapOptional("isAliased", Object.IsAliased); } + YamlIO.mapOptional("callee-saved-register", Object.CalleeSavedRegister, + StringValue()); // Don't print it out when it's empty. } static const bool flow = true; }; +struct MachineConstantPoolValue { + UnsignedValue ID; + StringValue Value; + unsigned Alignment = 0; +}; + +template <> struct MappingTraits<MachineConstantPoolValue> { + static void mapping(IO &YamlIO, MachineConstantPoolValue &Constant) { + YamlIO.mapRequired("id", Constant.ID); + YamlIO.mapOptional("value", Constant.Value); + YamlIO.mapOptional("alignment", Constant.Alignment); + } +}; + +struct MachineJumpTable { + struct Entry { + UnsignedValue ID; + std::vector<FlowStringValue> Blocks; + }; + + MachineJumpTableInfo::JTEntryKind Kind = MachineJumpTableInfo::EK_Custom32; + std::vector<Entry> Entries; +}; + +template <> struct MappingTraits<MachineJumpTable::Entry> { + static void mapping(IO &YamlIO, MachineJumpTable::Entry &Entry) { + YamlIO.mapRequired("id", Entry.ID); + YamlIO.mapOptional("blocks", Entry.Blocks); + } +}; + } // end namespace yaml } // end namespace llvm +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineFunctionLiveIn) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::VirtualRegisterDefinition) -LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineBasicBlock) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineStackObject) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::FixedMachineStackObject) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineConstantPoolValue) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineJumpTable::Entry) namespace llvm { namespace yaml { +template <> struct MappingTraits<MachineJumpTable> { + static void mapping(IO &YamlIO, MachineJumpTable &JT) { + YamlIO.mapRequired("kind", JT.Kind); + YamlIO.mapOptional("entries", JT.Entries); + } +}; + /// Serializable representation of MachineFrameInfo. /// /// Doesn't serialize attributes like 'StackAlignment', 'IsStackRealignable' and @@ -231,14 +346,14 @@ struct MachineFrameInfo { unsigned MaxAlignment = 0; bool AdjustsStack = false; bool HasCalls = false; - // TODO: Serialize StackProtectorIdx and FunctionContextIdx + StringValue StackProtector; + // TODO: Serialize FunctionContextIdx unsigned MaxCallFrameSize = 0; - // TODO: Serialize callee saved info. - // TODO: Serialize local frame objects. bool HasOpaqueSPAdjustment = false; bool HasVAStart = false; bool HasMustTailInVarArgFunc = false; - // TODO: Serialize save and restore MBB references. + StringValue SavePoint; + StringValue RestorePoint; }; template <> struct MappingTraits<MachineFrameInfo> { @@ -252,10 +367,16 @@ template <> struct MappingTraits<MachineFrameInfo> { YamlIO.mapOptional("maxAlignment", MFI.MaxAlignment); YamlIO.mapOptional("adjustsStack", MFI.AdjustsStack); YamlIO.mapOptional("hasCalls", MFI.HasCalls); + YamlIO.mapOptional("stackProtector", MFI.StackProtector, + StringValue()); // Don't print it out when it's empty. YamlIO.mapOptional("maxCallFrameSize", MFI.MaxCallFrameSize); YamlIO.mapOptional("hasOpaqueSPAdjustment", MFI.HasOpaqueSPAdjustment); YamlIO.mapOptional("hasVAStart", MFI.HasVAStart); YamlIO.mapOptional("hasMustTailInVarArgFunc", MFI.HasMustTailInVarArgFunc); + YamlIO.mapOptional("savePoint", MFI.SavePoint, + StringValue()); // Don't print it out when it's empty. + YamlIO.mapOptional("restorePoint", MFI.RestorePoint, + StringValue()); // Don't print it out when it's empty. } }; @@ -269,14 +390,16 @@ struct MachineFunction { bool TracksRegLiveness = false; bool TracksSubRegLiveness = false; std::vector<VirtualRegisterDefinition> VirtualRegisters; + std::vector<MachineFunctionLiveIn> LiveIns; + Optional<std::vector<FlowStringValue>> CalleeSavedRegisters; // TODO: Serialize the various register masks. - // TODO: Serialize live in registers. // Frame information MachineFrameInfo FrameInfo; std::vector<FixedMachineStackObject> FixedStackObjects; std::vector<MachineStackObject> StackObjects; - - std::vector<MachineBasicBlock> BasicBlocks; + std::vector<MachineConstantPoolValue> Constants; /// Constant pool. + MachineJumpTable JumpTableInfo; + BlockStringValue Body; }; template <> struct MappingTraits<MachineFunction> { @@ -289,10 +412,15 @@ template <> struct MappingTraits<MachineFunction> { YamlIO.mapOptional("tracksRegLiveness", MF.TracksRegLiveness); YamlIO.mapOptional("tracksSubRegLiveness", MF.TracksSubRegLiveness); YamlIO.mapOptional("registers", MF.VirtualRegisters); + YamlIO.mapOptional("liveins", MF.LiveIns); + YamlIO.mapOptional("calleeSavedRegisters", MF.CalleeSavedRegisters); YamlIO.mapOptional("frameInfo", MF.FrameInfo); YamlIO.mapOptional("fixedStack", MF.FixedStackObjects); YamlIO.mapOptional("stack", MF.StackObjects); - YamlIO.mapOptional("body", MF.BasicBlocks); + YamlIO.mapOptional("constants", MF.Constants); + if (!YamlIO.outputting() || !MF.JumpTableInfo.Entries.empty()) + YamlIO.mapOptional("jumpTable", MF.JumpTableInfo); + YamlIO.mapOptional("body", MF.Body); } }; diff --git a/contrib/llvm/include/llvm/CodeGen/MachineBasicBlock.h b/contrib/llvm/include/llvm/CodeGen/MachineBasicBlock.h index 5e5f45c..3d58c49 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineBasicBlock.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineBasicBlock.h @@ -16,6 +16,8 @@ #include "llvm/ADT/GraphTraits.h" #include "llvm/CodeGen/MachineInstr.h" +#include "llvm/Support/BranchProbability.h" +#include "llvm/MC/MCRegisterInfo.h" #include "llvm/Support/DataTypes.h" #include <functional> @@ -25,11 +27,15 @@ class Pass; class BasicBlock; class MachineFunction; class MCSymbol; +class MIPrinter; class SlotIndexes; class StringRef; class raw_ostream; class MachineBranchProbabilityInfo; +// Forward declaration to avoid circular include problem with TargetRegisterInfo +typedef unsigned LaneBitmask; + template <> struct ilist_traits<MachineInstr> : public ilist_default_traits<MachineInstr> { private: @@ -52,57 +58,76 @@ public: void addNodeToList(MachineInstr* N); void removeNodeFromList(MachineInstr* N); void transferNodesFromList(ilist_traits &SrcTraits, - ilist_iterator<MachineInstr> first, - ilist_iterator<MachineInstr> last); + ilist_iterator<MachineInstr> First, + ilist_iterator<MachineInstr> Last); void deleteNode(MachineInstr *N); private: void createNode(const MachineInstr &); }; -class MachineBasicBlock : public ilist_node<MachineBasicBlock> { +class MachineBasicBlock + : public ilist_node_with_parent<MachineBasicBlock, MachineFunction> { +public: + /// Pair of physical register and lane mask. + /// This is not simply a std::pair typedef because the members should be named + /// clearly as they both have an integer type. + struct RegisterMaskPair { + public: + MCPhysReg PhysReg; + LaneBitmask LaneMask; + + RegisterMaskPair(MCPhysReg PhysReg, LaneBitmask LaneMask) + : PhysReg(PhysReg), LaneMask(LaneMask) {} + }; + +private: typedef ilist<MachineInstr> Instructions; Instructions Insts; const BasicBlock *BB; int Number; MachineFunction *xParent; - /// Predecessors/Successors - Keep track of the predecessor / successor - /// basicblocks. + /// Keep track of the predecessor / successor basic blocks. 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). - std::vector<uint32_t> Weights; - typedef std::vector<uint32_t>::iterator weight_iterator; - typedef std::vector<uint32_t>::const_iterator const_weight_iterator; + /// Keep track of the probabilities to the successors. This vector has the + /// same order as Successors, or it is empty if we don't use it (disable + /// optimization). + std::vector<BranchProbability> Probs; + typedef std::vector<BranchProbability>::iterator probability_iterator; + typedef std::vector<BranchProbability>::const_iterator + const_probability_iterator; + + /// Keep track of the physical registers that are livein of the basicblock. + typedef std::vector<RegisterMaskPair> LiveInVector; + LiveInVector LiveIns; + + /// Alignment of the basic block. Zero if the basic block does not need to be + /// aligned. The alignment is specified as log2(bytes). + unsigned Alignment = 0; - /// LiveIns - Keep track of the physical registers that are livein of - /// the basicblock. - std::vector<unsigned> LiveIns; + /// Indicate that this basic block is entered via an exception handler. + bool IsEHPad = false; - /// Alignment - Alignment of the basic block. Zero if the basic block does - /// not need to be aligned. - /// The alignment is specified as log2(bytes). - unsigned Alignment; + /// Indicate that this basic block is potentially the target of an indirect + /// branch. + bool AddressTaken = false; - /// IsLandingPad - Indicate that this basic block is entered via an - /// exception handler. - bool IsLandingPad; + /// Indicate that this basic block is the entry block of an EH funclet. + bool IsEHFuncletEntry = false; - /// AddressTaken - Indicate that this basic block is potentially the - /// target of an indirect branch. - bool AddressTaken; + /// Indicate that this basic block is the entry block of a cleanup funclet. + bool IsCleanupFuncletEntry = false; /// \brief since getSymbol is a relatively heavy-weight operation, the symbol /// is only computed once and is cached. - mutable MCSymbol *CachedMCSymbol; + mutable MCSymbol *CachedMCSymbol = nullptr; // Intrusive list support MachineBasicBlock() {} - explicit MachineBasicBlock(MachineFunction &mf, const BasicBlock *bb); + explicit MachineBasicBlock(MachineFunction &MF, const BasicBlock *BB); ~MachineBasicBlock(); @@ -110,50 +135,44 @@ class MachineBasicBlock : public ilist_node<MachineBasicBlock> { friend class MachineFunction; public: - /// getBasicBlock - Return the LLVM basic block that this instance - /// corresponded to originally. Note that this may be NULL if this instance - /// does not correspond directly to an LLVM basic block. - /// + /// Return the LLVM basic block that this instance corresponded to originally. + /// Note that this may be NULL if this instance does not correspond directly + /// to an LLVM basic block. const BasicBlock *getBasicBlock() const { return BB; } - /// getName - Return the name of the corresponding LLVM basic block, or - /// "(null)". + /// Return the name of the corresponding LLVM basic block, or "(null)". StringRef getName() const; - /// getFullName - Return a formatted string to identify this block and its - /// parent function. + /// Return a formatted string to identify this block and its parent function. std::string getFullName() const; - /// hasAddressTaken - Test whether this block is potentially the target - /// of an indirect branch. + /// Test whether this block is potentially the target of an indirect branch. bool hasAddressTaken() const { return AddressTaken; } - /// setHasAddressTaken - Set this block to reflect that it potentially - /// is the target of an indirect branch. + /// Set this block to reflect that it potentially is the target of an indirect + /// branch. void setHasAddressTaken() { AddressTaken = true; } - /// getParent - Return the MachineFunction containing this basic block. - /// + /// Return the MachineFunction containing this basic block. const MachineFunction *getParent() const { return xParent; } MachineFunction *getParent() { return xParent; } - - /// bundle_iterator - MachineBasicBlock iterator that automatically skips over - /// MIs that are inside bundles (i.e. walk top level MIs only). + /// MachineBasicBlock iterator that automatically skips over MIs that are + /// inside bundles (i.e. walk top level MIs only). template<typename Ty, typename IterTy> class bundle_iterator : public std::iterator<std::bidirectional_iterator_tag, Ty, ptrdiff_t> { IterTy MII; public: - bundle_iterator(IterTy mii) : MII(mii) {} + bundle_iterator(IterTy MI) : MII(MI) {} - bundle_iterator(Ty &mi) : MII(mi) { - assert(!mi.isBundledWithPred() && + bundle_iterator(Ty &MI) : MII(MI) { + assert(!MI.isBundledWithPred() && "It's not legal to initialize bundle_iterator with a bundled MI"); } - bundle_iterator(Ty *mi) : MII(mi) { - assert((!mi || !mi->isBundledWithPred()) && + bundle_iterator(Ty *MI) : MII(MI) { + assert((!MI || !MI->isBundledWithPred()) && "It's not legal to initialize bundle_iterator with a bundled MI"); } // Template allows conversion from const to nonconst. @@ -165,13 +184,13 @@ public: Ty &operator*() const { return *MII; } Ty *operator->() const { return &operator*(); } - operator Ty*() const { return MII; } + operator Ty *() const { return MII.getNodePtrUnchecked(); } - bool operator==(const bundle_iterator &x) const { - return MII == x.MII; + bool operator==(const bundle_iterator &X) const { + return MII == X.MII; } - bool operator!=(const bundle_iterator &x) const { - return !operator==(x); + bool operator!=(const bundle_iterator &X) const { + return !operator==(X); } // Increment and decrement operators... @@ -247,11 +266,16 @@ public: reverse_iterator rend () { return instr_rend(); } const_reverse_iterator rend () const { return instr_rend(); } + /// Support for MachineInstr::getNextNode(). + static Instructions MachineBasicBlock::*getSublistAccess(MachineInstr *) { + return &MachineBasicBlock::Insts; + } + inline iterator_range<iterator> terminators() { - return iterator_range<iterator>(getFirstTerminator(), end()); + return make_range(getFirstTerminator(), end()); } inline iterator_range<const_iterator> terminators() const { - return iterator_range<const_iterator>(getFirstTerminator(), end()); + return make_range(getFirstTerminator(), end()); } // Machine-CFG iterators @@ -301,16 +325,16 @@ public: bool succ_empty() const { return Successors.empty(); } inline iterator_range<pred_iterator> predecessors() { - return iterator_range<pred_iterator>(pred_begin(), pred_end()); + return make_range(pred_begin(), pred_end()); } inline iterator_range<const_pred_iterator> predecessors() const { - return iterator_range<const_pred_iterator>(pred_begin(), pred_end()); + return make_range(pred_begin(), pred_end()); } inline iterator_range<succ_iterator> successors() { - return iterator_range<succ_iterator>(succ_begin(), succ_end()); + return make_range(succ_begin(), succ_end()); } inline iterator_range<const_succ_iterator> successors() const { - return iterator_range<const_succ_iterator>(succ_begin(), succ_end()); + return make_range(succ_begin(), succ_end()); } // LiveIn management methods. @@ -318,131 +342,177 @@ public: /// Adds the specified register as a live in. Note that it is an error to add /// the same register to the same set more than once unless the intention is /// to call sortUniqueLiveIns after all registers are added. - void addLiveIn(unsigned Reg) { LiveIns.push_back(Reg); } + void addLiveIn(MCPhysReg PhysReg, LaneBitmask LaneMask = ~0u) { + LiveIns.push_back(RegisterMaskPair(PhysReg, LaneMask)); + } + void addLiveIn(const RegisterMaskPair &RegMaskPair) { + LiveIns.push_back(RegMaskPair); + } /// Sorts and uniques the LiveIns vector. It can be significantly faster to do /// this than repeatedly calling isLiveIn before calling addLiveIn for every /// LiveIn insertion. - void sortUniqueLiveIns() { - std::sort(LiveIns.begin(), LiveIns.end()); - LiveIns.erase(std::unique(LiveIns.begin(), LiveIns.end()), LiveIns.end()); - } + void sortUniqueLiveIns(); /// Add PhysReg as live in to this block, and ensure that there is a copy of /// PhysReg to a virtual register of class RC. Return the virtual register /// that is a copy of the live in PhysReg. - unsigned addLiveIn(unsigned PhysReg, const TargetRegisterClass *RC); + unsigned addLiveIn(MCPhysReg PhysReg, const TargetRegisterClass *RC); - /// removeLiveIn - Remove the specified register from the live in set. - /// - void removeLiveIn(unsigned Reg); + /// Remove the specified register from the live in set. + void removeLiveIn(MCPhysReg Reg, LaneBitmask LaneMask = ~0u); - /// isLiveIn - Return true if the specified register is in the live in set. - /// - bool isLiveIn(unsigned Reg) const; + /// Return true if the specified register is in the live in set. + bool isLiveIn(MCPhysReg Reg, LaneBitmask LaneMask = ~0u) const; // Iteration support for live in sets. These sets are kept in sorted // order by their register number. - typedef std::vector<unsigned>::const_iterator livein_iterator; + typedef LiveInVector::const_iterator livein_iterator; livein_iterator livein_begin() const { return LiveIns.begin(); } livein_iterator livein_end() const { return LiveIns.end(); } bool livein_empty() const { return LiveIns.empty(); } + iterator_range<livein_iterator> liveins() const { + return make_range(livein_begin(), livein_end()); + } - /// getAlignment - Return alignment of the basic block. - /// The alignment is specified as log2(bytes). - /// + /// Get the clobber mask for the start of this basic block. Funclets use this + /// to prevent register allocation across funclet transitions. + const uint32_t *getBeginClobberMask(const TargetRegisterInfo *TRI) const; + + /// Get the clobber mask for the end of the basic block. + /// \see getBeginClobberMask() + const uint32_t *getEndClobberMask(const TargetRegisterInfo *TRI) const; + + /// Return alignment of the basic block. The alignment is specified as + /// log2(bytes). unsigned getAlignment() const { return Alignment; } - /// setAlignment - Set alignment of the basic block. - /// The alignment is specified as log2(bytes). - /// + /// Set alignment of the basic block. The alignment is specified as + /// log2(bytes). void setAlignment(unsigned Align) { Alignment = Align; } - /// isLandingPad - Returns true if the block is a landing pad. That is - /// this basic block is entered via an exception handler. - bool isLandingPad() const { return IsLandingPad; } + /// Returns true if the block is a landing pad. That is this basic block is + /// entered via an exception handler. + bool isEHPad() const { return IsEHPad; } - /// setIsLandingPad - Indicates the block is a landing pad. That is - /// this basic block is entered via an exception handler. - void setIsLandingPad(bool V = true) { IsLandingPad = V; } + /// Indicates the block is a landing pad. That is this basic block is entered + /// via an exception handler. + void setIsEHPad(bool V = true) { IsEHPad = V; } - /// getLandingPadSuccessor - If this block has a successor that is a landing - /// pad, return it. Otherwise return NULL. + /// If this block has a successor that is a landing pad, return it. Otherwise + /// return NULL. const MachineBasicBlock *getLandingPadSuccessor() const; + bool hasEHPadSuccessor() const; + + /// Returns true if this is the entry block of an EH funclet. + bool isEHFuncletEntry() const { return IsEHFuncletEntry; } + + /// Indicates if this is the entry block of an EH funclet. + void setIsEHFuncletEntry(bool V = true) { IsEHFuncletEntry = V; } + + /// Returns true if this is the entry block of a cleanup funclet. + bool isCleanupFuncletEntry() const { return IsCleanupFuncletEntry; } + + /// Indicates if this is the entry block of a cleanup funclet. + void setIsCleanupFuncletEntry(bool V = true) { IsCleanupFuncletEntry = V; } + // Code Layout methods. - /// moveBefore/moveAfter - move 'this' block before or after the specified - /// block. This only moves the block, it does not modify the CFG or adjust - /// potential fall-throughs at the end of the block. + /// Move 'this' block before or after the specified block. This only moves + /// the block, it does not modify the CFG or adjust potential fall-throughs at + /// the end of the block. void moveBefore(MachineBasicBlock *NewAfter); void moveAfter(MachineBasicBlock *NewBefore); - /// updateTerminator - Update the terminator instructions in block to account - /// for changes to the layout. If the block previously used a fallthrough, - /// it may now need a branch, and if it previously used branching it may now - /// be able to use a fallthrough. + /// Update the terminator instructions in block to account for changes to the + /// layout. If the block previously used a fallthrough, it may now need a + /// branch, and if it previously used branching it may now be able to use a + /// fallthrough. void updateTerminator(); // Machine-CFG mutators - /// addSuccessor - Add succ as a successor of this MachineBasicBlock. - /// The Predecessors list of succ is automatically updated. WEIGHT - /// parameter is stored in Weights list and it may be used by - /// MachineBranchProbabilityInfo analysis to calculate branch probability. + /// Add Succ as a successor of this MachineBasicBlock. The Predecessors list + /// of Succ is automatically updated. PROB parameter is stored in + /// Probabilities list. The default probability is set as unknown. Mixing + /// known and unknown probabilities in successor list is not allowed. When all + /// successors have unknown probabilities, 1 / N is returned as the + /// probability for each successor, where N is the number of successors. /// /// Note that duplicate Machine CFG edges are not allowed. - /// - void addSuccessor(MachineBasicBlock *succ, uint32_t weight = 0); - - /// Set successor weight of a given iterator. - void setSuccWeight(succ_iterator I, uint32_t weight); - - /// removeSuccessor - Remove successor from the successors list of this - /// MachineBasicBlock. The Predecessors list of succ is automatically updated. - /// - void removeSuccessor(MachineBasicBlock *succ); - - /// removeSuccessor - Remove specified successor from the successors list of - /// this MachineBasicBlock. The Predecessors list of succ is automatically - /// updated. Return the iterator to the element after the one removed. - /// - succ_iterator removeSuccessor(succ_iterator I); - - /// replaceSuccessor - Replace successor OLD with NEW and update weight info. - /// + void addSuccessor(MachineBasicBlock *Succ, + BranchProbability Prob = BranchProbability::getUnknown()); + + /// Add Succ as a successor of this MachineBasicBlock. The Predecessors list + /// of Succ is automatically updated. The probability is not provided because + /// BPI is not available (e.g. -O0 is used), in which case edge probabilities + /// won't be used. Using this interface can save some space. + void addSuccessorWithoutProb(MachineBasicBlock *Succ); + + /// Set successor probability of a given iterator. + void setSuccProbability(succ_iterator I, BranchProbability Prob); + + /// Normalize probabilities of all successors so that the sum of them becomes + /// one. This is usually done when the current update on this MBB is done, and + /// the sum of its successors' probabilities is not guaranteed to be one. The + /// user is responsible for the correct use of this function. + /// MBB::removeSuccessor() has an option to do this automatically. + void normalizeSuccProbs() { + BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end()); + } + + /// Validate successors' probabilities and check if the sum of them is + /// approximate one. This only works in DEBUG mode. + void validateSuccProbs() const; + + /// Remove successor from the successors list of this MachineBasicBlock. The + /// Predecessors list of Succ is automatically updated. + /// If NormalizeSuccProbs is true, then normalize successors' probabilities + /// after the successor is removed. + void removeSuccessor(MachineBasicBlock *Succ, + bool NormalizeSuccProbs = false); + + /// Remove specified successor from the successors list of this + /// MachineBasicBlock. The Predecessors list of Succ is automatically updated. + /// If NormalizeSuccProbs is true, then normalize successors' probabilities + /// after the successor is removed. + /// Return the iterator to the element after the one removed. + succ_iterator removeSuccessor(succ_iterator I, + bool NormalizeSuccProbs = false); + + /// Replace successor OLD with NEW and update probability info. void replaceSuccessor(MachineBasicBlock *Old, MachineBasicBlock *New); + /// Transfers all the successors from MBB to this machine basic block (i.e., + /// copies all the successors FromMBB and remove all the successors from + /// FromMBB). + void transferSuccessors(MachineBasicBlock *FromMBB); - /// transferSuccessors - Transfers all the successors from MBB to this - /// machine basic block (i.e., copies all the successors fromMBB and - /// remove all the successors from fromMBB). - void transferSuccessors(MachineBasicBlock *fromMBB); + /// Transfers all the successors, as in transferSuccessors, and update PHI + /// operands in the successor blocks which refer to FromMBB to refer to this. + void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB); - /// transferSuccessorsAndUpdatePHIs - Transfers all the successors, as - /// in transferSuccessors, and update PHI operands in the successor blocks - /// which refer to fromMBB to refer to this. - void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *fromMBB); + /// Return true if any of the successors have probabilities attached to them. + bool hasSuccessorProbabilities() const { return !Probs.empty(); } - /// isPredecessor - Return true if the specified MBB is a predecessor of this - /// block. + /// Return true if the specified MBB is a predecessor of this block. bool isPredecessor(const MachineBasicBlock *MBB) const; - /// isSuccessor - Return true if the specified MBB is a successor of this - /// block. + /// Return true if the specified MBB is a successor of this block. bool isSuccessor(const MachineBasicBlock *MBB) const; - /// isLayoutSuccessor - Return true if the specified MBB will be emitted - /// immediately after this block, such that if this block exits by - /// falling through, control will transfer to the specified MBB. Note - /// that MBB need not be a successor at all, for example if this block - /// ends with an unconditional branch to some other block. + /// Return true if the specified MBB will be emitted immediately after this + /// block, such that if this block exits by falling through, control will + /// transfer to the specified MBB. Note that MBB need not be a successor at + /// all, for example if this block ends with an unconditional branch to some + /// other block. bool isLayoutSuccessor(const MachineBasicBlock *MBB) const; - /// canFallThrough - Return true if the block can implicitly transfer - /// control to the block after it by falling off the end of it. This should - /// return false if it can reach the block after it, but it uses an explicit - /// branch to do so (e.g., a table jump). True is a conservative answer. + /// Return true if the block can implicitly transfer control to the block + /// after it by falling off the end of it. This should return false if it can + /// reach the block after it, but it uses an explicit branch to do so (e.g., a + /// table jump). True is a conservative answer. bool canFallThrough(); /// Returns a pointer to the first instruction in this block that is not a @@ -452,40 +522,44 @@ public: /// Returns end() is there's no non-PHI instruction. iterator getFirstNonPHI(); - /// SkipPHIsAndLabels - Return the first instruction in MBB after I that is - /// not a PHI or a label. This is the correct point to insert copies at the - /// beginning of a basic block. + /// Return the first instruction in MBB after I that is not a PHI or a label. + /// This is the correct point to insert copies at the beginning of a basic + /// block. iterator SkipPHIsAndLabels(iterator I); - /// getFirstTerminator - returns an iterator to the first terminator - /// instruction of this basic block. If a terminator does not exist, - /// it returns end() + /// Returns an iterator to the first terminator instruction of this basic + /// block. If a terminator does not exist, it returns end(). iterator getFirstTerminator(); const_iterator getFirstTerminator() const { return const_cast<MachineBasicBlock *>(this)->getFirstTerminator(); } - /// getFirstInstrTerminator - Same getFirstTerminator but it ignores bundles - /// and return an instr_iterator instead. + /// Same getFirstTerminator but it ignores bundles and return an + /// instr_iterator instead. instr_iterator getFirstInstrTerminator(); - /// getFirstNonDebugInstr - returns an iterator to the first non-debug - /// instruction in the basic block, or end() + /// Returns an iterator to the first non-debug instruction in the basic block, + /// or end(). iterator getFirstNonDebugInstr(); const_iterator getFirstNonDebugInstr() const { return const_cast<MachineBasicBlock *>(this)->getFirstNonDebugInstr(); } - /// getLastNonDebugInstr - returns an iterator to the last non-debug - /// instruction in the basic block, or end() + /// 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. + /// Convenience function that returns true if the block ends in a return + /// instruction. + bool isReturnBlock() const { + return !empty() && back().isReturn(); + } + + /// 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. /// /// This function updates LiveVariables, MachineDominatorTree, and /// MachineLoopInfo, as applicable. @@ -570,7 +644,7 @@ public: /// remove_instr to remove individual instructions from a bundle. MachineInstr *remove(MachineInstr *I) { assert(!I->isBundled() && "Cannot remove bundled instructions"); - return Insts.remove(I); + return Insts.remove(instr_iterator(I)); } /// Remove the possibly bundled instruction from the instruction list @@ -605,30 +679,29 @@ public: From.getInstrIterator(), To.getInstrIterator()); } - /// removeFromParent - This method unlinks 'this' from the containing - /// function, and returns it, but does not delete it. + /// This method unlinks 'this' from the containing function, and returns it, + /// but does not delete it. MachineBasicBlock *removeFromParent(); - /// eraseFromParent - This method unlinks 'this' from the containing - /// function and deletes it. + /// This method unlinks 'this' from the containing function and deletes it. void eraseFromParent(); - /// ReplaceUsesOfBlockWith - Given a machine basic block that branched to - /// 'Old', change the code and CFG so that it branches to 'New' instead. + /// Given a machine basic block that branched to 'Old', change the code and + /// CFG so that it branches to 'New' instead. void ReplaceUsesOfBlockWith(MachineBasicBlock *Old, MachineBasicBlock *New); - /// CorrectExtraCFGEdges - Various pieces of code can cause excess edges in - /// the CFG to be inserted. If we have proven that MBB can only branch to - /// DestA and DestB, remove any other MBB successors from the CFG. DestA and - /// DestB can be null. Besides DestA and DestB, retain other edges leading - /// to LandingPads (currently there can be only one; we don't check or require - /// that here). Note it is possible that DestA and/or DestB are LandingPads. + /// Various pieces of code can cause excess edges in the CFG to be inserted. + /// If we have proven that MBB can only branch to DestA and DestB, remove any + /// other MBB successors from the CFG. DestA and DestB can be null. Besides + /// DestA and DestB, retain other edges leading to LandingPads (currently + /// there can be only one; we don't check or require that here). Note it is + /// possible that DestA and/or DestB are LandingPads. bool CorrectExtraCFGEdges(MachineBasicBlock *DestA, MachineBasicBlock *DestB, - bool isCond); + bool IsCond); - /// findDebugLoc - find the next valid DebugLoc starting at MBBI, skipping - /// any DBG_VALUE instructions. Return UnknownLoc if there is none. + /// Find the next valid DebugLoc starting at MBBI, skipping any DBG_VALUE + /// instructions. Return UnknownLoc if there is none. DebugLoc findDebugLoc(instr_iterator MBBI); DebugLoc findDebugLoc(iterator MBBI) { return findDebugLoc(MBBI.getInstrIterator()); @@ -636,12 +709,9 @@ public: /// Possible outcome of a register liveness query to computeRegisterLiveness() enum LivenessQueryResult { - LQR_Live, ///< Register is known to be live. - LQR_OverlappingLive, ///< Register itself is not live, but some overlapping - ///< register is. - LQR_Dead, ///< Register is known to be dead. - LQR_Unknown ///< Register liveness not decidable from local - ///< neighborhood. + LQR_Live, ///< Register is known to be (at least partially) live. + LQR_Dead, ///< Register is known to be fully dead. + LQR_Unknown ///< Register liveness not decidable from local neighborhood. }; /// Return whether (physical) register \p Reg has been <def>ined and not @@ -666,49 +736,43 @@ public: // Printing method used by LoopInfo. void printAsOperand(raw_ostream &OS, bool PrintType = true) const; - /// getNumber - MachineBasicBlocks are uniquely numbered at the function - /// level, unless they're not in a MachineFunction yet, in which case this - /// will return -1. - /// + /// MachineBasicBlocks are uniquely numbered at the function level, unless + /// they're not in a MachineFunction yet, in which case this will return -1. int getNumber() const { return Number; } void setNumber(int N) { Number = N; } - /// getSymbol - Return the MCSymbol for this basic block. - /// + /// Return the MCSymbol for this basic block. MCSymbol *getSymbol() const; private: - /// getWeightIterator - Return weight iterator corresponding to the I - /// successor iterator. - weight_iterator getWeightIterator(succ_iterator I); - const_weight_iterator getWeightIterator(const_succ_iterator I) const; + /// Return probability iterator corresponding to the I successor iterator. + probability_iterator getProbabilityIterator(succ_iterator I); + const_probability_iterator + getProbabilityIterator(const_succ_iterator I) const; friend class MachineBranchProbabilityInfo; + friend class MIPrinter; - /// getSuccWeight - Return weight of the edge from this block to MBB. This - /// method should NOT be called directly, but by using getEdgeWeight method - /// from MachineBranchProbabilityInfo class. - uint32_t getSuccWeight(const_succ_iterator Succ) const; - + /// Return probability of the edge from this block to MBB. This method should + /// NOT be called directly, but by using getEdgeProbability method from + /// MachineBranchProbabilityInfo class. + BranchProbability getSuccProbability(const_succ_iterator Succ) const; // Methods used to maintain doubly linked list of blocks... friend struct ilist_traits<MachineBasicBlock>; // Machine-CFG mutators - /// addPredecessor - Remove pred as a predecessor of this MachineBasicBlock. - /// Don't do this unless you know what you're doing, because it doesn't - /// update pred's successors list. Use pred->addSuccessor instead. - /// - void addPredecessor(MachineBasicBlock *pred); + /// Remove Pred as a predecessor of this MachineBasicBlock. Don't do this + /// unless you know what you're doing, because it doesn't update Pred's + /// successors list. Use Pred->addSuccessor instead. + void addPredecessor(MachineBasicBlock *Pred); - /// removePredecessor - Remove pred as a predecessor of this - /// MachineBasicBlock. Don't do this unless you know what you're - /// doing, because it doesn't update pred's successors list. Use - /// pred->removeSuccessor instead. - /// - void removePredecessor(MachineBasicBlock *pred); + /// Remove Pred as a predecessor of this MachineBasicBlock. Don't do this + /// unless you know what you're doing, because it doesn't update Pred's + /// successors list. Use Pred->removeSuccessor instead. + void removePredecessor(MachineBasicBlock *Pred); }; raw_ostream& operator<<(raw_ostream &OS, const MachineBasicBlock &MBB); @@ -726,7 +790,7 @@ struct MBB2NumberFunctor : //===--------------------------------------------------------------------===// // Provide specializations of GraphTraits to be able to treat a -// MachineFunction as a graph of MachineBasicBlocks... +// MachineFunction as a graph of MachineBasicBlocks. // template <> struct GraphTraits<MachineBasicBlock *> { @@ -756,7 +820,7 @@ template <> struct GraphTraits<const MachineBasicBlock *> { }; // Provide specializations of GraphTraits to be able to treat a -// MachineFunction as a graph of MachineBasicBlocks... and to walk it +// MachineFunction as a graph of MachineBasicBlocks and to walk it // in inverse order. Inverse order for a function is considered // to be when traversing the predecessor edges of a MBB // instead of the successor edges. diff --git a/contrib/llvm/include/llvm/CodeGen/MachineBranchProbabilityInfo.h b/contrib/llvm/include/llvm/CodeGen/MachineBranchProbabilityInfo.h index 7ba7495..81b0524 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineBranchProbabilityInfo.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineBranchProbabilityInfo.h @@ -18,6 +18,7 @@ #include "llvm/Pass.h" #include "llvm/Support/BranchProbability.h" #include <climits> +#include <numeric> namespace llvm { @@ -44,20 +45,15 @@ public: AU.setPreservesAll(); } - // Return edge weight. If we don't have any informations about it - return - // DEFAULT_WEIGHT. - uint32_t getEdgeWeight(const MachineBasicBlock *Src, - const MachineBasicBlock *Dst) const; - - // Same thing, but using a const_succ_iterator from Src. This is faster when - // the iterator is already available. - uint32_t getEdgeWeight(const MachineBasicBlock *Src, - MachineBasicBlock::const_succ_iterator Dst) const; + // Return edge probability. + BranchProbability getEdgeProbability(const MachineBasicBlock *Src, + const MachineBasicBlock *Dst) const; - // Get sum of the block successors' weights, potentially scaling them to fit - // within 32-bits. If scaling is required, sets Scale based on the necessary - // adjustment. Any edge weights used with the sum should be divided by Scale. - uint32_t getSumForBlock(const MachineBasicBlock *MBB, uint32_t &Scale) const; + // Same as above, but using a const_succ_iterator from Src. This is faster + // when the iterator is already available. + BranchProbability + getEdgeProbability(const MachineBasicBlock *Src, + MachineBasicBlock::const_succ_iterator Dst) const; // A 'Hot' edge is an edge which probability is >= 80%. bool isEdgeHot(const MachineBasicBlock *Src, @@ -67,15 +63,6 @@ public: // NB: This routine's complexity is linear on the number of successors. MachineBasicBlock *getHotSucc(MachineBasicBlock *MBB) const; - // Return a probability as a fraction between 0 (0% probability) and - // 1 (100% probability), however the value is never equal to 0, and can be 1 - // only iff SRC block has only one successor. - // NB: This routine's complexity is linear on the number of successors of - // Src. Querying sequentially for each successor's probability is a quadratic - // query pattern. - BranchProbability getEdgeProbability(const MachineBasicBlock *Src, - const MachineBasicBlock *Dst) const; - // Print value between 0 (0% probability) and 1 (100% probability), // however the value is never equal to 0, and can be 1 only iff SRC block // has only one successor. diff --git a/contrib/llvm/include/llvm/CodeGen/MachineCombinerPattern.h b/contrib/llvm/include/llvm/CodeGen/MachineCombinerPattern.h index 176af14..f389122 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineCombinerPattern.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineCombinerPattern.h @@ -17,13 +17,30 @@ namespace llvm { -/// Enumeration of instruction pattern supported by machine combiner -/// -/// -namespace MachineCombinerPattern { -// Forward declaration -enum MC_PATTERN : int; -} // end namespace MachineCombinerPattern +/// These are instruction patterns matched by the machine combiner pass. +enum class MachineCombinerPattern { + // These are commutative variants for reassociating a computation chain. See + // the comments before getMachineCombinerPatterns() in TargetInstrInfo.cpp. + REASSOC_AX_BY, + REASSOC_AX_YB, + REASSOC_XA_BY, + REASSOC_XA_YB, + + // These are multiply-add patterns matched by the AArch64 machine combiner. + MULADDW_OP1, + MULADDW_OP2, + MULSUBW_OP1, + MULSUBW_OP2, + MULADDWI_OP1, + MULSUBWI_OP1, + MULADDX_OP1, + MULADDX_OP2, + MULSUBX_OP1, + MULSUBX_OP2, + MULADDXI_OP1, + MULSUBXI_OP1 +}; + } // end namespace llvm #endif diff --git a/contrib/llvm/include/llvm/CodeGen/MachineConstantPool.h b/contrib/llvm/include/llvm/CodeGen/MachineConstantPool.h index 6284003..d2036c4 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineConstantPool.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineConstantPool.h @@ -46,13 +46,6 @@ public: /// Type *getType() const { return Ty; } - - /// getRelocationInfo - This method classifies the entry according to - /// whether or not it may generate a relocation entry. This must be - /// conservative, so if it might codegen to a relocatable entry, it should say - /// so. The return values are the same as Constant::getRelocationInfo(). - virtual unsigned getRelocationInfo() const = 0; - virtual int getExistingMachineCPValue(MachineConstantPool *CP, unsigned Alignment) = 0; @@ -67,7 +60,6 @@ inline raw_ostream &operator<<(raw_ostream &OS, V.print(OS); return OS; } - /// This class is a data container for one entry in a MachineConstantPool. /// It contains a pointer to the value and an offset from the start of @@ -90,9 +82,9 @@ public: Val.ConstVal = V; } MachineConstantPoolEntry(MachineConstantPoolValue *V, unsigned A) - : Alignment(A) { - Val.MachineCPVal = V; - Alignment |= 1U << (sizeof(unsigned)*CHAR_BIT-1); + : Alignment(A) { + Val.MachineCPVal = V; + Alignment |= 1U << (sizeof(unsigned) * CHAR_BIT - 1); } /// isMachineConstantPoolEntry - Return true if the MachineConstantPoolEntry @@ -102,28 +94,20 @@ public: return (int)Alignment < 0; } - int getAlignment() const { - return Alignment & ~(1 << (sizeof(unsigned)*CHAR_BIT-1)); + int getAlignment() const { + return Alignment & ~(1 << (sizeof(unsigned) * CHAR_BIT - 1)); } Type *getType() const; - - /// getRelocationInfo - This method classifies the entry according to - /// whether or not it may generate a relocation entry. This must be - /// conservative, so if it might codegen to a relocatable entry, it should say - /// so. The return values are: - /// - /// 0: This constant pool entry is guaranteed to never have a relocation - /// applied to it (because it holds a simple constant like '4'). - /// 1: This entry has relocations, but the entries are guaranteed to be - /// resolvable by the static linker, so the dynamic linker will never see - /// them. - /// 2: This entry may have arbitrary relocations. - unsigned getRelocationInfo() const; + + /// This method classifies the entry according to whether or not it may + /// generate a relocation entry. This must be conservative, so if it might + /// codegen to a relocatable entry, it should say so. + bool needsRelocation() const; SectionKind getSectionKind(const DataLayout *DL) const; }; - + /// The MachineConstantPool class keeps track of constants referenced by a /// function which must be spilled to memory. This is used for constants which /// are unable to be used directly as operands to instructions, which typically @@ -148,17 +132,18 @@ public: explicit MachineConstantPool(const DataLayout &DL) : PoolAlignment(1), DL(DL) {} ~MachineConstantPool(); - + /// getConstantPoolAlignment - Return the alignment required by /// the whole constant pool, of which the first element must be aligned. unsigned getConstantPoolAlignment() const { return PoolAlignment; } - + /// getConstantPoolIndex - Create a new entry in the constant pool or return /// an existing one. User must specify the minimum required alignment for /// the object. unsigned getConstantPoolIndex(const Constant *C, unsigned Alignment); - unsigned getConstantPoolIndex(MachineConstantPoolValue *V,unsigned Alignment); - + unsigned getConstantPoolIndex(MachineConstantPoolValue *V, + unsigned Alignment); + /// isEmpty - Return true if this constant pool contains no constants. bool isEmpty() const { return Constants.empty(); } diff --git a/contrib/llvm/include/llvm/CodeGen/MachineDominators.h b/contrib/llvm/include/llvm/CodeGen/MachineDominators.h index 735dd06..a69936f 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineDominators.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineDominators.h @@ -246,21 +246,29 @@ public: /// iterable by generic graph iterators. /// -template<class T> struct GraphTraits; +template <class Node, class ChildIterator> +struct MachineDomTreeGraphTraitsBase { + typedef Node NodeType; + typedef ChildIterator ChildIteratorType; -template <> struct GraphTraits<MachineDomTreeNode *> { - typedef MachineDomTreeNode NodeType; - typedef NodeType::iterator ChildIteratorType; - - static NodeType *getEntryNode(NodeType *N) { - return N; - } - static inline ChildIteratorType child_begin(NodeType* N) { + static NodeType *getEntryNode(NodeType *N) { return N; } + static inline ChildIteratorType child_begin(NodeType *N) { return N->begin(); } - static inline ChildIteratorType child_end(NodeType* N) { - return N->end(); - } + static inline ChildIteratorType child_end(NodeType *N) { return N->end(); } +}; + +template <class T> struct GraphTraits; + +template <> +struct GraphTraits<MachineDomTreeNode *> + : public MachineDomTreeGraphTraitsBase<MachineDomTreeNode, + MachineDomTreeNode::iterator> {}; + +template <> +struct GraphTraits<const MachineDomTreeNode *> + : public MachineDomTreeGraphTraitsBase<const MachineDomTreeNode, + MachineDomTreeNode::const_iterator> { }; template <> struct GraphTraits<MachineDominatorTree*> diff --git a/contrib/llvm/include/llvm/CodeGen/MachineFrameInfo.h b/contrib/llvm/include/llvm/CodeGen/MachineFrameInfo.h index cbc4e66..48e8ca7 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineFrameInfo.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineFrameInfo.h @@ -101,6 +101,13 @@ class MachineFrameInfo { // cannot alias any other memory objects. bool isSpillSlot; + /// If true, this stack slot is used to spill a value (could be deopt + /// and/or GC related) over a statepoint. We know that the address of the + /// slot can't alias any LLVM IR value. This is very similiar to a Spill + /// Slot, but is created by statepoint lowering is SelectionDAG, not the + /// register allocator. + bool isStatepointSpillSlot; + /// If this stack object is originated from an Alloca instruction /// this value saves the original IR allocation. Can be NULL. const AllocaInst *Alloca; @@ -118,13 +125,24 @@ class MachineFrameInfo { StackObject(uint64_t Sz, unsigned Al, int64_t SP, bool IM, bool isSS, const AllocaInst *Val, bool A) : SPOffset(SP), Size(Sz), Alignment(Al), isImmutable(IM), - isSpillSlot(isSS), Alloca(Val), PreAllocated(false), isAliased(A) {} + isSpillSlot(isSS), isStatepointSpillSlot(false), Alloca(Val), + PreAllocated(false), isAliased(A) {} }; /// The alignment of the stack. unsigned StackAlignment; /// Can the stack be realigned. + /// Targets that set this to false don't have the ability to overalign + /// their stack frame, and thus, overaligned allocas are all treated + /// as dynamic allocations and the target must handle them as part + /// of DYNAMIC_STACKALLOC lowering. + /// FIXME: There is room for improvement in this case, in terms of + /// grouping overaligned allocas into a "secondary stack frame" and + /// then only use a single alloca to allocate this frame and only a + /// single virtual register to access it. Currently, without such an + /// optimization, each such alloca gets it's own dynamic + /// realignment. bool StackRealignable; /// The list of stack objects allocated. @@ -168,7 +186,7 @@ class MachineFrameInfo { /// SP then OffsetAdjustment is zero; if FP is used, OffsetAdjustment is set /// to the distance between the initial SP and the value in FP. For many /// targets, this value is only used when generating debug info (via - /// TargetRegisterInfo::getFrameIndexOffset); when generating code, the + /// TargetRegisterInfo::getFrameIndexReference); when generating code, the /// corresponding adjustments are performed directly. int OffsetAdjustment; @@ -198,7 +216,7 @@ class MachineFrameInfo { /// This contains the size of the largest call frame if the target uses frame /// setup/destroy pseudo instructions (as defined in the TargetFrameInfo /// class). This information is important for frame pointer elimination. - /// If is only valid during and after prolog/epilog code insertion. + /// It is only valid during and after prolog/epilog code insertion. unsigned MaxCallFrameSize; /// The prolog/epilog code inserter fills in this vector with each @@ -288,6 +306,7 @@ public: /// Return the index for the stack protector object. int getStackProtectorIndex() const { return StackProtectorIdx; } void setStackProtectorIndex(int I) { StackProtectorIdx = I; } + bool hasStackProtectorIndex() const { return StackProtectorIdx != -1; } /// Return the index for the function context object. /// This object is used for SjLj exceptions. @@ -337,14 +356,14 @@ public: } /// Get the local offset mapping for a for an object. - std::pair<int, int64_t> getLocalFrameObjectMap(int i) { + std::pair<int, int64_t> getLocalFrameObjectMap(int i) const { assert (i >= 0 && (unsigned)i < LocalFrameObjects.size() && "Invalid local object reference!"); return LocalFrameObjects[i]; } /// Return the number of objects allocated into the local object block. - int64_t getLocalFrameObjectCount() { return LocalFrameObjects.size(); } + int64_t getLocalFrameObjectCount() const { return LocalFrameObjects.size(); } /// Set the size of the local object blob. void setLocalFrameSize(int64_t sz) { LocalFrameSize = sz; } @@ -361,7 +380,9 @@ public: /// Get whether the local allocation blob should be allocated together or /// let PEI allocate the locals in it directly. - bool getUseLocalStackAllocationBlock() {return UseLocalStackAllocationBlock;} + bool getUseLocalStackAllocationBlock() const { + return UseLocalStackAllocationBlock; + } /// setUseLocalStackAllocationBlock - Set whether the local allocation blob /// should be allocated together or let PEI allocate the locals in it @@ -534,6 +555,12 @@ public: return Objects[ObjectIdx+NumFixedObjects].isSpillSlot; } + bool isStatepointSpillSlotObjectIndex(int ObjectIdx) const { + assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && + "Invalid Object Idx!"); + return Objects[ObjectIdx+NumFixedObjects].isStatepointSpillSlot; + } + /// Returns true if the specified index corresponds to a dead object. bool isDeadObjectIndex(int ObjectIdx) const { assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && @@ -549,6 +576,13 @@ public: return Objects[ObjectIdx + NumFixedObjects].Size == 0; } + void markAsStatepointSpillSlotObjectIndex(int ObjectIdx) { + assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && + "Invalid Object Idx!"); + Objects[ObjectIdx+NumFixedObjects].isStatepointSpillSlot = true; + assert(isStatepointSpillSlotObjectIndex(ObjectIdx) && "inconsistent"); + } + /// Create a new statically sized stack object, returning /// a nonnegative identifier to represent it. int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS, diff --git a/contrib/llvm/include/llvm/CodeGen/MachineFunction.h b/contrib/llvm/include/llvm/CodeGen/MachineFunction.h index c15ee1c..82c30d3 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineFunction.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineFunction.h @@ -38,10 +38,12 @@ class MachineJumpTableInfo; class MachineModuleInfo; class MCContext; class Pass; +class PseudoSourceValueManager; class TargetMachine; class TargetSubtargetInfo; class TargetRegisterClass; struct MachinePointerInfo; +struct WinEHFuncInfo; template <> struct ilist_traits<MachineBasicBlock> @@ -102,10 +104,14 @@ class MachineFunction { // Keep track of constants which are spilled to memory MachineConstantPool *ConstantPool; - + // Keep track of jump tables for switch instructions MachineJumpTableInfo *JumpTableInfo; + // Keeps track of Windows exception handling related data. This will be null + // for functions that aren't using a funclet-based EH personality. + WinEHFuncInfo *WinEHInfo = nullptr; + // Function-level unique numbering for MachineBasicBlocks. When a // MachineBasicBlock is inserted into a MachineFunction is it automatically // numbered and this vector keeps track of the mapping from ID's to MBB's. @@ -131,7 +137,7 @@ class MachineFunction { /// this translation unit. /// unsigned FunctionNumber; - + /// Alignment - The alignment of the function. unsigned Alignment; @@ -145,6 +151,9 @@ class MachineFunction { /// True if the function includes any inline assembly. bool HasInlineAsm; + // Allocation management for pseudo source values. + std::unique_ptr<PseudoSourceValueManager> PSVManager; + MachineFunction(const MachineFunction &) = delete; void operator=(const MachineFunction&) = delete; public: @@ -155,6 +164,8 @@ public: MachineModuleInfo &getMMI() const { return MMI; } MCContext &getContext() const { return Ctx; } + PseudoSourceValueManager &getPSVManager() const { return *PSVManager; } + /// Return the DataLayout attached to the Module associated to this MF. const DataLayout &getDataLayout() const; @@ -198,7 +209,7 @@ public: MachineFrameInfo *getFrameInfo() { return FrameInfo; } const MachineFrameInfo *getFrameInfo() const { return FrameInfo; } - /// getJumpTableInfo - Return the jump table info object for the current + /// getJumpTableInfo - Return the jump table info object for the current /// function. This object contains information about jump tables in the /// current function. If the current function has no jump tables, this will /// return null. @@ -209,13 +220,18 @@ public: /// does already exist, allocate one. MachineJumpTableInfo *getOrCreateJumpTableInfo(unsigned JTEntryKind); - /// getConstantPool - Return the constant pool object for the current /// function. /// MachineConstantPool *getConstantPool() { return ConstantPool; } const MachineConstantPool *getConstantPool() const { return ConstantPool; } + /// getWinEHFuncInfo - Return information about how the current function uses + /// Windows exception handling. Returns null for functions that don't use + /// funclets for exception handling. + const WinEHFuncInfo *getWinEHFuncInfo() const { return WinEHInfo; } + WinEHFuncInfo *getWinEHFuncInfo() { return WinEHInfo; } + /// getAlignment - Return the alignment (log2, not bytes) of the function. /// unsigned getAlignment() const { return Alignment; } @@ -284,14 +300,14 @@ public: /// getNumBlockIDs - Return the number of MBB ID's allocated. /// unsigned getNumBlockIDs() const { return (unsigned)MBBNumbering.size(); } - + /// RenumberBlocks - This discards all of the MachineBasicBlock numbers and /// recomputes them. This guarantees that the MBB numbers are sequential, /// dense, and match the ordering of the blocks within the function. If a /// specific MachineBasicBlock is specified, only that block and those after /// it are renumbered. void RenumberBlocks(MachineBasicBlock *MBBFrom = nullptr); - + /// print - Print out the MachineFunction in a format suitable for debugging /// to the specified stream. /// @@ -326,6 +342,12 @@ public: typedef std::reverse_iterator<const_iterator> const_reverse_iterator; typedef std::reverse_iterator<iterator> reverse_iterator; + /// Support for MachineBasicBlock::getNextNode(). + static BasicBlockListType MachineFunction::* + getSublistAccess(MachineBasicBlock *) { + return &MachineFunction::BasicBlocks; + } + /// addLiveIn - Add the specified physical register as a live-in value and /// create a corresponding virtual register for it. unsigned addLiveIn(unsigned PReg, const TargetRegisterClass *RC); @@ -358,15 +380,21 @@ public: void splice(iterator InsertPt, iterator MBBI) { BasicBlocks.splice(InsertPt, BasicBlocks, MBBI); } + void splice(iterator InsertPt, MachineBasicBlock *MBB) { + BasicBlocks.splice(InsertPt, BasicBlocks, MBB); + } void splice(iterator InsertPt, iterator MBBI, iterator MBBE) { BasicBlocks.splice(InsertPt, BasicBlocks, MBBI, MBBE); } - void remove(iterator MBBI) { - BasicBlocks.remove(MBBI); - } - void erase(iterator MBBI) { - BasicBlocks.erase(MBBI); + void remove(iterator MBBI) { BasicBlocks.remove(MBBI); } + void remove(MachineBasicBlock *MBBI) { BasicBlocks.remove(MBBI); } + void erase(iterator MBBI) { BasicBlocks.erase(MBBI); } + void erase(MachineBasicBlock *MBBI) { BasicBlocks.erase(MBBI); } + + template <typename Comp> + void sort(Comp comp) { + BasicBlocks.sort(comp); } //===--------------------------------------------------------------------===// @@ -425,7 +453,7 @@ public: unsigned base_alignment, const AAMDNodes &AAInfo = AAMDNodes(), const MDNode *Ranges = nullptr); - + /// getMachineMemOperand - Allocate a new MachineMemOperand by copying /// an existing one, adjusting by an offset and using the given size. /// MachineMemOperands are owned by the MachineFunction and need not be @@ -475,16 +503,19 @@ public: extractStoreMemRefs(MachineInstr::mmo_iterator Begin, MachineInstr::mmo_iterator End); + /// Allocate a string and populate it with the given external symbol name. + const char *createExternalSymbolName(StringRef Name); + //===--------------------------------------------------------------------===// // Label Manipulation. // - + /// getJTISymbol - Return the MCSymbol for the specified non-empty jump table. /// If isLinkerPrivate is specified, an 'l' label is returned, otherwise a /// normal 'L' label is returned. - MCSymbol *getJTISymbol(unsigned JTI, MCContext &Ctx, + MCSymbol *getJTISymbol(unsigned JTI, MCContext &Ctx, bool isLinkerPrivate = false) const; - + /// getPICBaseSymbol - Return a function-local symbol to represent the PIC /// base. MCSymbol *getPICBaseSymbol() const; diff --git a/contrib/llvm/include/llvm/CodeGen/MachineInstr.h b/contrib/llvm/include/llvm/CodeGen/MachineInstr.h index de7e0a2..978864e 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineInstr.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineInstr.h @@ -23,6 +23,7 @@ #include "llvm/ADT/ilist.h" #include "llvm/ADT/ilist_node.h" #include "llvm/ADT/iterator_range.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/CodeGen/MachineOperand.h" #include "llvm/IR/DebugInfo.h" #include "llvm/IR/DebugLoc.h" @@ -34,7 +35,6 @@ namespace llvm { template <typename T> class SmallVectorImpl; -class AliasAnalysis; class TargetInstrInfo; class TargetRegisterClass; class TargetRegisterInfo; @@ -48,7 +48,8 @@ class MachineMemOperand; /// MachineFunction is deleted, all the contained MachineInstrs are deallocated /// without having their destructor called. /// -class MachineInstr : public ilist_node<MachineInstr> { +class MachineInstr + : public ilist_node_with_parent<MachineInstr, MachineBasicBlock> { public: typedef MachineMemOperand **mmo_iterator; @@ -64,8 +65,10 @@ public: NoFlags = 0, FrameSetup = 1 << 0, // Instruction is used as a part of // function frame setup code. - BundledPred = 1 << 1, // Instruction has bundled predecessors. - BundledSucc = 1 << 2 // Instruction has bundled successors. + FrameDestroy = 1 << 1, // Instruction is used as a part of + // function frame destruction code. + BundledPred = 1 << 2, // Instruction has bundled predecessors. + BundledSucc = 1 << 3 // Instruction has bundled successors. }; private: const MCInstrDesc *MCID; // Instruction descriptor. @@ -89,6 +92,12 @@ private: // information to AsmPrinter. uint8_t NumMemRefs; // Information on memory references. + // Note that MemRefs == nullptr, means 'don't know', not 'no memory access'. + // Calling code must treat missing information conservatively. If the number + // of memory operands required to be precise exceeds the maximum value of + // NumMemRefs - currently 256 - we remove the operands entirely. Note also + // that this is a non-owning reference to a shared copy on write buffer owned + // by the MachineFunction and created via MF.allocateMemRefsArray. mmo_iterator MemRefs; DebugLoc debugLoc; // Source line information. @@ -293,42 +302,46 @@ public: const_mop_iterator operands_end() const { return Operands + NumOperands; } iterator_range<mop_iterator> operands() { - return iterator_range<mop_iterator>(operands_begin(), operands_end()); + return make_range(operands_begin(), operands_end()); } iterator_range<const_mop_iterator> operands() const { - return iterator_range<const_mop_iterator>(operands_begin(), operands_end()); + return make_range(operands_begin(), operands_end()); } iterator_range<mop_iterator> explicit_operands() { - return iterator_range<mop_iterator>( - operands_begin(), operands_begin() + getNumExplicitOperands()); + return make_range(operands_begin(), + operands_begin() + getNumExplicitOperands()); } iterator_range<const_mop_iterator> explicit_operands() const { - return iterator_range<const_mop_iterator>( - operands_begin(), operands_begin() + getNumExplicitOperands()); + return make_range(operands_begin(), + operands_begin() + getNumExplicitOperands()); } iterator_range<mop_iterator> implicit_operands() { - return iterator_range<mop_iterator>(explicit_operands().end(), - operands_end()); + return make_range(explicit_operands().end(), operands_end()); } iterator_range<const_mop_iterator> implicit_operands() const { - return iterator_range<const_mop_iterator>(explicit_operands().end(), - operands_end()); + return make_range(explicit_operands().end(), operands_end()); } + /// Returns a range over all explicit operands that are register definitions. + /// Implicit definition are not included! iterator_range<mop_iterator> defs() { - return iterator_range<mop_iterator>( - operands_begin(), operands_begin() + getDesc().getNumDefs()); + return make_range(operands_begin(), + operands_begin() + getDesc().getNumDefs()); } + /// \copydoc defs() iterator_range<const_mop_iterator> defs() const { - return iterator_range<const_mop_iterator>( - operands_begin(), operands_begin() + getDesc().getNumDefs()); + return make_range(operands_begin(), + operands_begin() + getDesc().getNumDefs()); } + /// Returns a range that includes all operands that are register uses. + /// This may include unrelated operands which are not register uses. iterator_range<mop_iterator> uses() { - return iterator_range<mop_iterator>( - operands_begin() + getDesc().getNumDefs(), operands_end()); + return make_range(operands_begin() + getDesc().getNumDefs(), + operands_end()); } + /// \copydoc uses() iterator_range<const_mop_iterator> uses() const { - return iterator_range<const_mop_iterator>( - operands_begin() + getDesc().getNumDefs(), operands_end()); + return make_range(operands_begin() + getDesc().getNumDefs(), + operands_end()); } /// Returns the number of the operand iterator \p I points to. @@ -339,13 +352,16 @@ public: /// Access to memory operands of the instruction mmo_iterator memoperands_begin() const { return MemRefs; } mmo_iterator memoperands_end() const { return MemRefs + NumMemRefs; } + /// Return true if we don't have any memory operands which described the the + /// memory access done by this instruction. If this is true, calling code + /// must be conservative. bool memoperands_empty() const { return NumMemRefs == 0; } iterator_range<mmo_iterator> memoperands() { - return iterator_range<mmo_iterator>(memoperands_begin(), memoperands_end()); + return make_range(memoperands_begin(), memoperands_end()); } iterator_range<mmo_iterator> memoperands() const { - return iterator_range<mmo_iterator>(memoperands_begin(), memoperands_end()); + return make_range(memoperands_begin(), memoperands_end()); } /// Return true if this instruction has exactly one MachineMemOperand. @@ -489,8 +505,8 @@ public: } /// Return true if this instruction is convergent. - /// Convergent instructions can only be moved to locations that are - /// control-equivalent to their initial position. + /// Convergent instructions can not be made control-dependent on any + /// additional values. bool isConvergent(QueryType Type = AnyInBundle) const { return hasProperty(MCID::Convergent, Type); } @@ -897,6 +913,13 @@ public: return (Idx == -1) ? nullptr : &getOperand(Idx); } + const MachineOperand *findRegisterUseOperand( + unsigned Reg, bool isKill = false, + const TargetRegisterInfo *TRI = nullptr) const { + return const_cast<MachineInstr *>(this)-> + findRegisterUseOperand(Reg, isKill, TRI); + } + /// 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 defs that merely @@ -1048,7 +1071,7 @@ public: /// Mark all subregister defs of register @p Reg with the undef flag. /// This function is used when we determined to have a subregister def in an /// otherwise undefined super register. - void addRegisterDefReadUndef(unsigned Reg); + void setRegisterDefReadUndef(unsigned Reg, bool IsUndef = true); /// We have determined MI defines a register. Make sure there is an operand /// defining Reg. @@ -1094,6 +1117,9 @@ public: /// bool hasUnmodeledSideEffects() const; + /// Returns true if it is illegal to fold a load across this instruction. + bool isLoadFoldBarrier() const; + /// Return true if all the defs of this instruction are dead. bool allDefsAreDead() const; @@ -1159,8 +1185,11 @@ public: assert(NumMemRefs == NewMemRefsEnd - NewMemRefs && "Too many memrefs"); } - /// Clear this MachineInstr's memory reference descriptor list. - void clearMemRefs() { + /// Clear this MachineInstr's memory reference descriptor list. This resets + /// the memrefs to their most conservative state. This should be used only + /// as a last resort since it greatly pessimizes our knowledge of the memory + /// access performed by the instruction. + void dropMemRefs() { MemRefs = nullptr; NumMemRefs = 0; } @@ -1174,6 +1203,8 @@ public: } } + /// Add all implicit def and use operands to this instruction. + void addImplicitDefUseOperands(MachineFunction &MF); private: /// If this instruction is embedded into a MachineFunction, return the @@ -1181,9 +1212,6 @@ private: /// return null. MachineRegisterInfo *getRegInfo(); - /// Add all implicit def and use operands to this instruction. - void addImplicitDefUseOperands(MachineFunction &MF); - /// 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. diff --git a/contrib/llvm/include/llvm/CodeGen/MachineInstrBuilder.h b/contrib/llvm/include/llvm/CodeGen/MachineInstrBuilder.h index 4f68f38..aa5f4b2 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineInstrBuilder.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineInstrBuilder.h @@ -49,11 +49,10 @@ public: MachineInstrBuilder() : MF(nullptr), MI(nullptr) {} /// Create a MachineInstrBuilder for manipulating an existing instruction. - /// F must be the machine function that was used to allocate I. + /// F must be the machine function that was used to allocate I. MachineInstrBuilder(MachineFunction &F, MachineInstr *I) : MF(&F), MI(I) {} /// 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; } @@ -62,11 +61,9 @@ public: /// explicitly. MachineInstr *getInstr() const { return MI; } - /// addReg - Add a new virtual register operand... - /// - const - MachineInstrBuilder &addReg(unsigned RegNo, unsigned flags = 0, - unsigned SubReg = 0) const { + /// Add a new virtual register operand. + const MachineInstrBuilder &addReg(unsigned RegNo, unsigned flags = 0, + unsigned SubReg = 0) const { assert((flags & 0x1) == 0 && "Passing in 'true' to addReg is forbidden! Use enums instead."); MI->addOperand(*MF, MachineOperand::CreateReg(RegNo, @@ -82,8 +79,7 @@ public: return *this; } - /// addImm - Add a new immediate operand. - /// + /// Add a new immediate operand. const MachineInstrBuilder &addImm(int64_t Val) const { MI->addOperand(*MF, MachineOperand::CreateImm(Val)); return *this; @@ -204,44 +200,44 @@ public: // Add a displacement from an existing MachineOperand with an added offset. const MachineInstrBuilder &addDisp(const MachineOperand &Disp, int64_t off, unsigned char TargetFlags = 0) const { + // If caller specifies new TargetFlags then use it, otherwise the + // default behavior is to copy the target flags from the existing + // MachineOperand. This means if the caller wants to clear the + // target flags it needs to do so explicitly. + if (0 == TargetFlags) + TargetFlags = Disp.getTargetFlags(); + switch (Disp.getType()) { default: llvm_unreachable("Unhandled operand type in addDisp()"); case MachineOperand::MO_Immediate: return addImm(Disp.getImm() + off); - case MachineOperand::MO_GlobalAddress: { - // If caller specifies new TargetFlags then use it, otherwise the - // default behavior is to copy the target flags from the existing - // MachineOperand. This means if the caller wants to clear the - // target flags it needs to do so explicitly. - if (TargetFlags) - return addGlobalAddress(Disp.getGlobal(), Disp.getOffset() + off, - TargetFlags); + case MachineOperand::MO_ConstantPoolIndex: + return addConstantPoolIndex(Disp.getIndex(), Disp.getOffset() + off, + TargetFlags); + case MachineOperand::MO_GlobalAddress: return addGlobalAddress(Disp.getGlobal(), Disp.getOffset() + off, - Disp.getTargetFlags()); - } + TargetFlags); } } /// Copy all the implicit operands from OtherMI onto this one. - const MachineInstrBuilder ©ImplicitOps(const MachineInstr *OtherMI) { + const MachineInstrBuilder & + copyImplicitOps(const MachineInstr *OtherMI) const { MI->copyImplicitOps(*MF, OtherMI); return *this; } }; -/// BuildMI - Builder interface. Specify how to create the initial instruction -/// itself. -/// +/// Builder interface. Specify how to create the initial instruction itself. inline MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID) { return MachineInstrBuilder(MF, MF.CreateMachineInstr(MCID, DL)); } -/// BuildMI - This version of the builder sets up the first operand as a +/// This version of the builder sets up the first operand as a /// destination virtual register. -/// inline MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID, @@ -250,10 +246,9 @@ inline MachineInstrBuilder BuildMI(MachineFunction &MF, .addReg(DestReg, RegState::Define); } -/// BuildMI - This version of the builder inserts the newly-built -/// instruction before the given position in the given MachineBasicBlock, and -/// sets up the first operand as a destination virtual register. -/// +/// This version of the builder inserts the newly-built instruction before +/// the given position in the given MachineBasicBlock, and sets up the first +/// operand as a destination virtual register. inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, MachineBasicBlock::iterator I, DebugLoc DL, @@ -282,7 +277,7 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, const MCInstrDesc &MCID, unsigned DestReg) { if (I->isInsideBundle()) { - MachineBasicBlock::instr_iterator MII = I; + MachineBasicBlock::instr_iterator MII(I); return BuildMI(BB, MII, DL, MCID, DestReg); } @@ -290,10 +285,9 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, return BuildMI(BB, MII, DL, MCID, DestReg); } -/// BuildMI - This version of the builder inserts the newly-built -/// instruction before the given position in the given MachineBasicBlock, and -/// does NOT take a destination register. -/// +/// This version of the builder inserts the newly-built instruction before the +/// given position in the given MachineBasicBlock, and does NOT take a +/// destination register. inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, MachineBasicBlock::iterator I, DebugLoc DL, @@ -319,7 +313,7 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, DebugLoc DL, const MCInstrDesc &MCID) { if (I->isInsideBundle()) { - MachineBasicBlock::instr_iterator MII = I; + MachineBasicBlock::instr_iterator MII(I); return BuildMI(BB, MII, DL, MCID); } @@ -327,20 +321,17 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, return BuildMI(BB, MII, DL, MCID); } -/// BuildMI - This version of the builder inserts the newly-built -/// instruction at the end of the given MachineBasicBlock, and does NOT take a -/// destination register. -/// +/// This version of the builder inserts the newly-built instruction at the end +/// of the given MachineBasicBlock, and does NOT take a destination register. inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB, DebugLoc DL, const MCInstrDesc &MCID) { return BuildMI(*BB, BB->end(), DL, MCID); } -/// BuildMI - This version of the builder inserts the newly-built -/// instruction at the end of the given MachineBasicBlock, and sets up the first -/// operand as a destination virtual register. -/// +/// This version of the builder inserts the newly-built instruction at the +/// end of the given MachineBasicBlock, and sets up the first operand as a +/// destination virtual register. inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB, DebugLoc DL, const MCInstrDesc &MCID, @@ -348,11 +339,10 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB, return BuildMI(*BB, BB->end(), DL, MCID, DestReg); } -/// BuildMI - This version of the builder builds a DBG_VALUE intrinsic +/// This version of the builder builds a DBG_VALUE intrinsic /// for either a value in a register or a register-indirect+offset /// address. The convention is that a DBG_VALUE is indirect iff the /// second operand is an immediate. -/// inline MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID, bool IsIndirect, unsigned Reg, unsigned Offset, @@ -377,10 +367,9 @@ inline MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, } } -/// BuildMI - This version of the builder builds a DBG_VALUE intrinsic +/// This version of the builder builds a DBG_VALUE intrinsic /// for either a value in a register or a register-indirect+offset /// address and inserts it at position I. -/// inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, MachineBasicBlock::iterator I, DebugLoc DL, const MCInstrDesc &MCID, bool IsIndirect, @@ -476,7 +465,7 @@ public: if (I == Begin) { if (!empty()) MI->bundleWithSucc(); - Begin = MI; + Begin = MI->getIterator(); return *this; } if (I == End) { diff --git a/contrib/llvm/include/llvm/CodeGen/MachineInstrBundle.h b/contrib/llvm/include/llvm/CodeGen/MachineInstrBundle.h index 1220224..4fbe206 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineInstrBundle.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineInstrBundle.h @@ -28,7 +28,7 @@ namespace llvm { void finalizeBundle(MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI); - + /// finalizeBundle - Same functionality as the previous finalizeBundle except /// the last instruction in the bundle is not provided as an input. This is /// used in cases where bundles are pre-determined by marking instructions @@ -44,23 +44,23 @@ bool finalizeBundles(MachineFunction &MF); /// getBundleStart - Returns the first instruction in the bundle containing MI. /// inline MachineInstr *getBundleStart(MachineInstr *MI) { - MachineBasicBlock::instr_iterator I = MI; + MachineBasicBlock::instr_iterator I(MI); while (I->isBundledWithPred()) --I; - return I; + return &*I; } inline const MachineInstr *getBundleStart(const MachineInstr *MI) { - MachineBasicBlock::const_instr_iterator I = MI; + MachineBasicBlock::const_instr_iterator I(MI); while (I->isBundledWithPred()) --I; - return I; + return &*I; } /// Return an iterator pointing beyond the bundle containing MI. inline MachineBasicBlock::instr_iterator getBundleEnd(MachineInstr *MI) { - MachineBasicBlock::instr_iterator I = MI; + MachineBasicBlock::instr_iterator I(MI); while (I->isBundledWithSucc()) ++I; return ++I; @@ -69,7 +69,7 @@ getBundleEnd(MachineInstr *MI) { /// Return an iterator pointing beyond the bundle containing MI. inline MachineBasicBlock::const_instr_iterator getBundleEnd(const MachineInstr *MI) { - MachineBasicBlock::const_instr_iterator I = MI; + MachineBasicBlock::const_instr_iterator I(MI); while (I->isBundledWithSucc()) ++I; return ++I; @@ -116,10 +116,10 @@ protected: /// explicit MachineOperandIteratorBase(MachineInstr *MI, bool WholeBundle) { if (WholeBundle) { - InstrI = getBundleStart(MI); + InstrI = getBundleStart(MI)->getIterator(); InstrE = MI->getParent()->instr_end(); } else { - InstrI = InstrE = MI; + InstrI = InstrE = MI->getIterator(); ++InstrE; } OpI = InstrI->operands_begin(); @@ -164,27 +164,32 @@ public: bool Tied; }; - /// PhysRegInfo - Information about a physical register used by a set of + /// Information about how a physical register Reg is used by a set of /// operands. struct PhysRegInfo { - /// Clobbers - Reg or an overlapping register is defined, or a regmask - /// clobbers Reg. - bool Clobbers; - - /// Defines - Reg or a super-register is defined. - bool Defines; - - /// Reads - Read or a super-register is read. - bool Reads; - - /// ReadsOverlap - Reg or an overlapping register is read. - bool ReadsOverlap; - - /// DefinesDead - All defs of a Reg or a super-register are dead. - bool DefinesDead; - - /// There is a kill of Reg or a super-register. - bool Kills; + /// There is a regmask operand indicating Reg is clobbered. + /// \see MachineOperand::CreateRegMask(). + bool Clobbered; + + /// Reg or one of its aliases is defined. The definition may only cover + /// parts of the register. + bool Defined; + /// Reg or a super-register is defined. The definition covers the full + /// register. + bool FullyDefined; + + /// Reg or ont of its aliases is read. The register may only be read + /// partially. + bool Read; + /// Reg or a super-register is read. The full register is read. + bool FullyRead; + + /// Reg is FullyDefined and all defs of reg or an overlapping register are + /// dead. + bool DeadDef; + + /// There is a use operand of reg or a super-register with kill flag set. + bool Killed; }; /// analyzeVirtReg - Analyze how the current instruction or bundle uses a diff --git a/contrib/llvm/include/llvm/CodeGen/MachineMemOperand.h b/contrib/llvm/include/llvm/CodeGen/MachineMemOperand.h index a73b92f..1ca0d90 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineMemOperand.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineMemOperand.h @@ -27,6 +27,7 @@ namespace llvm { class FoldingSetNodeID; class MDNode; class raw_ostream; +class MachineFunction; class ModuleSlotTracker; /// MachinePointerInfo - This class contains a discriminated union of @@ -62,22 +63,23 @@ struct MachinePointerInfo { /// getConstantPool - Return a MachinePointerInfo record that refers to the /// constant pool. - static MachinePointerInfo getConstantPool(); + static MachinePointerInfo getConstantPool(MachineFunction &MF); /// getFixedStack - Return a MachinePointerInfo record that refers to the /// the specified FrameIndex. - static MachinePointerInfo getFixedStack(int FI, int64_t offset = 0); + static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, + int64_t Offset = 0); /// getJumpTable - Return a MachinePointerInfo record that refers to a /// jump table entry. - static MachinePointerInfo getJumpTable(); + static MachinePointerInfo getJumpTable(MachineFunction &MF); /// getGOT - Return a MachinePointerInfo record that refers to a /// GOT entry. - static MachinePointerInfo getGOT(); + static MachinePointerInfo getGOT(MachineFunction &MF); /// getStack - stack pointer relative access. - static MachinePointerInfo getStack(int64_t Offset); + static MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset); }; diff --git a/contrib/llvm/include/llvm/CodeGen/MachineModuleInfo.h b/contrib/llvm/include/llvm/CodeGen/MachineModuleInfo.h index 4cdfe24..7757112 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineModuleInfo.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineModuleInfo.h @@ -35,11 +35,12 @@ #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/Analysis/LibCallSemantics.h" +#include "llvm/Analysis/EHPersonalities.h" #include "llvm/IR/DebugLoc.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/ValueHandle.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCSymbol.h" #include "llvm/MC/MachineLocation.h" #include "llvm/Pass.h" #include "llvm/Support/DataTypes.h" @@ -59,7 +60,6 @@ class MachineFunction; class Module; class PointerType; class StructType; -struct WinEHFuncInfo; struct SEHHandler { // Filter or finally function. Null indicates a catch-all. @@ -79,13 +79,10 @@ struct LandingPadInfo { SmallVector<MCSymbol *, 1> EndLabels; // Labels after invoke. SmallVector<SEHHandler, 1> SEHHandlers; // SEH handlers active at this lpad. MCSymbol *LandingPadLabel; // Label at beginning of landing pad. - const Function *Personality; // Personality function. std::vector<int> TypeIds; // List of type ids (filters negative). - int WinEHState; // WinEH specific state number. explicit LandingPadInfo(MachineBasicBlock *MBB) - : LandingPadBlock(MBB), LandingPadLabel(nullptr), Personality(nullptr), - WinEHState(-1) {} + : LandingPadBlock(MBB), LandingPadLabel(nullptr) {} }; //===----------------------------------------------------------------------===// @@ -163,6 +160,13 @@ class MachineModuleInfo : public ImmutablePass { bool CallsEHReturn; bool CallsUnwindInit; + bool HasEHFunclets; + + // TODO: Ideally, what we'd like is to have a switch that allows emitting + // synchronous (precise at call-sites only) CFA into .eh_frame. However, + // even under this switch, we'd like .debug_frame to be precise when using. + // -g. At this moment, there's no way to specify that some CFI directives + // go into .eh_frame only, while others go into .debug_frame only. /// DbgInfoAvailable - True if debugging information is available /// in this module. @@ -182,8 +186,6 @@ class MachineModuleInfo : public ImmutablePass { EHPersonality PersonalityTypeCache; - DenseMap<const Function *, std::unique_ptr<WinEHFuncInfo>> FuncInfoMap; - public: static char ID; // Pass identification, replacement for typeid @@ -220,12 +222,6 @@ public: void setModule(const Module *M) { TheModule = M; } const Module *getModule() const { return TheModule; } - const Function *getWinEHParent(const Function *F) const; - WinEHFuncInfo &getWinEHFuncInfo(const Function *F); - bool hasWinEHFuncInfo(const Function *F) const { - return FuncInfoMap.count(getWinEHParent(F)) > 0; - } - /// getInfo - Keep track of various per-function pieces of information for /// backends that would like to do so. /// @@ -252,6 +248,9 @@ public: bool callsUnwindInit() const { return CallsUnwindInit; } void setCallsUnwindInit(bool b) { CallsUnwindInit = b; } + bool hasEHFunclets() const { return HasEHFunclets; } + void setHasEHFunclets(bool V) { HasEHFunclets = V; } + bool usesVAFloatArgument() const { return UsesVAFloatArgument; } @@ -318,16 +317,8 @@ public: /// addPersonality - Provide the personality function for the exception /// information. - void addPersonality(MachineBasicBlock *LandingPad, - const Function *Personality); void addPersonality(const Function *Personality); - void addWinEHState(MachineBasicBlock *LandingPad, int State); - - /// getPersonalityIndex - Get index of the current personality function inside - /// Personalitites array - unsigned getPersonalityIndex() const; - /// getPersonalities - Return array of personality functions ever seen. const std::vector<const Function *>& getPersonalities() const { return Personalities; @@ -426,13 +417,6 @@ public: return FilterIds; } - /// getPersonality - Return a personality function if available. The presence - /// of one is required to emit exception handling info. - const Function *getPersonality() const; - - /// Classify the personality function amongst known EH styles. - EHPersonality getPersonalityType(); - /// setVariableDbgInfo - Collect information used to emit debugging /// information of a variable. void setVariableDbgInfo(const DILocalVariable *Var, const DIExpression *Expr, diff --git a/contrib/llvm/include/llvm/CodeGen/MachineModuleInfoImpls.h b/contrib/llvm/include/llvm/CodeGen/MachineModuleInfoImpls.h index a67f9b5..e747214 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineModuleInfoImpls.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineModuleInfoImpls.h @@ -18,79 +18,71 @@ #include "llvm/CodeGen/MachineModuleInfo.h" namespace llvm { - class MCSymbol; - - /// MachineModuleInfoMachO - This is a MachineModuleInfoImpl implementation - /// for MachO targets. - class MachineModuleInfoMachO : public MachineModuleInfoImpl { - /// FnStubs - Darwin '$stub' stubs. The key is something like "Lfoo$stub", - /// the value is something like "_foo". - DenseMap<MCSymbol*, StubValueTy> FnStubs; - - /// GVStubs - Darwin '$non_lazy_ptr' stubs. The key is something like - /// "Lfoo$non_lazy_ptr", the value is something like "_foo". The extra bit - /// is true if this GV is external. - DenseMap<MCSymbol*, StubValueTy> GVStubs; - - /// HiddenGVStubs - Darwin '$non_lazy_ptr' stubs. The key is something like - /// "Lfoo$non_lazy_ptr", the value is something like "_foo". Unlike GVStubs - /// these are for things with hidden visibility. The extra bit is true if - /// this GV is external. - DenseMap<MCSymbol*, StubValueTy> HiddenGVStubs; - - virtual void anchor(); // Out of line virtual method. - public: - MachineModuleInfoMachO(const MachineModuleInfo &) {} - - StubValueTy &getFnStubEntry(MCSymbol *Sym) { - assert(Sym && "Key cannot be null"); - return FnStubs[Sym]; - } - - StubValueTy &getGVStubEntry(MCSymbol *Sym) { - assert(Sym && "Key cannot be null"); - return GVStubs[Sym]; - } - - StubValueTy &getHiddenGVStubEntry(MCSymbol *Sym) { - assert(Sym && "Key cannot be null"); - return HiddenGVStubs[Sym]; - } - - /// Accessor methods to return the set of stubs in sorted order. - SymbolListTy GetFnStubList() { - return getSortedStubs(FnStubs); - } - SymbolListTy GetGVStubList() { - return getSortedStubs(GVStubs); - } - SymbolListTy GetHiddenGVStubList() { - return getSortedStubs(HiddenGVStubs); - } - }; - - /// MachineModuleInfoELF - This is a MachineModuleInfoImpl implementation - /// for ELF targets. - class MachineModuleInfoELF : public MachineModuleInfoImpl { - /// GVStubs - These stubs are used to materialize global addresses in PIC - /// mode. - DenseMap<MCSymbol*, StubValueTy> GVStubs; - - virtual void anchor(); // Out of line virtual method. - public: - MachineModuleInfoELF(const MachineModuleInfo &) {} - - StubValueTy &getGVStubEntry(MCSymbol *Sym) { - assert(Sym && "Key cannot be null"); - return GVStubs[Sym]; - } - - /// Accessor methods to return the set of stubs in sorted order. - - SymbolListTy GetGVStubList() { - return getSortedStubs(GVStubs); - } - }; +class MCSymbol; + +/// MachineModuleInfoMachO - This is a MachineModuleInfoImpl implementation +/// for MachO targets. +class MachineModuleInfoMachO : public MachineModuleInfoImpl { + /// FnStubs - Darwin '$stub' stubs. The key is something like "Lfoo$stub", + /// the value is something like "_foo". + DenseMap<MCSymbol *, StubValueTy> FnStubs; + + /// GVStubs - Darwin '$non_lazy_ptr' stubs. The key is something like + /// "Lfoo$non_lazy_ptr", the value is something like "_foo". The extra bit + /// is true if this GV is external. + DenseMap<MCSymbol *, StubValueTy> GVStubs; + + /// HiddenGVStubs - Darwin '$non_lazy_ptr' stubs. The key is something like + /// "Lfoo$non_lazy_ptr", the value is something like "_foo". Unlike GVStubs + /// these are for things with hidden visibility. The extra bit is true if + /// this GV is external. + DenseMap<MCSymbol *, StubValueTy> HiddenGVStubs; + + virtual void anchor(); // Out of line virtual method. +public: + MachineModuleInfoMachO(const MachineModuleInfo &) {} + + StubValueTy &getFnStubEntry(MCSymbol *Sym) { + assert(Sym && "Key cannot be null"); + return FnStubs[Sym]; + } + + StubValueTy &getGVStubEntry(MCSymbol *Sym) { + assert(Sym && "Key cannot be null"); + return GVStubs[Sym]; + } + + StubValueTy &getHiddenGVStubEntry(MCSymbol *Sym) { + assert(Sym && "Key cannot be null"); + return HiddenGVStubs[Sym]; + } + + /// Accessor methods to return the set of stubs in sorted order. + SymbolListTy GetFnStubList() { return getSortedStubs(FnStubs); } + SymbolListTy GetGVStubList() { return getSortedStubs(GVStubs); } + SymbolListTy GetHiddenGVStubList() { return getSortedStubs(HiddenGVStubs); } +}; + +/// MachineModuleInfoELF - This is a MachineModuleInfoImpl implementation +/// for ELF targets. +class MachineModuleInfoELF : public MachineModuleInfoImpl { + /// GVStubs - These stubs are used to materialize global addresses in PIC + /// mode. + DenseMap<MCSymbol *, StubValueTy> GVStubs; + + virtual void anchor(); // Out of line virtual method. +public: + MachineModuleInfoELF(const MachineModuleInfo &) {} + + StubValueTy &getGVStubEntry(MCSymbol *Sym) { + assert(Sym && "Key cannot be null"); + return GVStubs[Sym]; + } + + /// Accessor methods to return the set of stubs in sorted order. + + SymbolListTy GetGVStubList() { return getSortedStubs(GVStubs); } +}; } // end namespace llvm diff --git a/contrib/llvm/include/llvm/CodeGen/MachineRegisterInfo.h b/contrib/llvm/include/llvm/CodeGen/MachineRegisterInfo.h index 5e607cd..04191bc 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineRegisterInfo.h @@ -73,7 +73,7 @@ private: /// PhysRegUseDefLists - This is an array of the head of the use/def list for /// physical registers. - std::vector<MachineOperand *> PhysRegUseDefLists; + std::unique_ptr<MachineOperand *[]> PhysRegUseDefLists; /// getRegUseDefListHead - Return the head pointer for the register use/def /// list for the specified virtual or physical register. @@ -95,20 +95,8 @@ private: return MO->Contents.Reg.Next; } - /// UsedRegUnits - This is a bit vector that is computed and set by the - /// register allocator, and must be kept up to date by passes that run after - /// register allocation (though most don't modify this). This is used - /// so that the code generator knows which callee save registers to save and - /// for other target specific uses. - /// This vector has bits set for register units that are modified in the - /// current function. It doesn't include registers clobbered by function - /// calls with register mask operands. - BitVector UsedRegUnits; - /// UsedPhysRegMask - Additional used physregs including aliases. /// This bit vector represents all the registers clobbered by function calls. - /// It can model things that UsedRegUnits can't, such as function calls that - /// clobber ymm7 but preserve the low half in xmm7. BitVector UsedPhysRegMask; /// ReservedRegs - This is a bit vector of reserved registers. The target @@ -246,7 +234,7 @@ public: static reg_iterator reg_end() { return reg_iterator(nullptr); } inline iterator_range<reg_iterator> reg_operands(unsigned Reg) const { - return iterator_range<reg_iterator>(reg_begin(Reg), reg_end()); + return make_range(reg_begin(Reg), reg_end()); } /// reg_instr_iterator/reg_instr_begin/reg_instr_end - Walk all defs and uses @@ -262,8 +250,7 @@ public: inline iterator_range<reg_instr_iterator> reg_instructions(unsigned Reg) const { - return iterator_range<reg_instr_iterator>(reg_instr_begin(Reg), - reg_instr_end()); + return make_range(reg_instr_begin(Reg), reg_instr_end()); } /// reg_bundle_iterator/reg_bundle_begin/reg_bundle_end - Walk all defs and uses @@ -278,8 +265,7 @@ public: } inline iterator_range<reg_bundle_iterator> reg_bundles(unsigned Reg) const { - return iterator_range<reg_bundle_iterator>(reg_bundle_begin(Reg), - reg_bundle_end()); + return make_range(reg_bundle_begin(Reg), reg_bundle_end()); } /// reg_empty - Return true if there are no instructions using or defining the @@ -299,8 +285,7 @@ public: inline iterator_range<reg_nodbg_iterator> reg_nodbg_operands(unsigned Reg) const { - return iterator_range<reg_nodbg_iterator>(reg_nodbg_begin(Reg), - reg_nodbg_end()); + return make_range(reg_nodbg_begin(Reg), reg_nodbg_end()); } /// reg_instr_nodbg_iterator/reg_instr_nodbg_begin/reg_instr_nodbg_end - Walk @@ -317,8 +302,7 @@ public: inline iterator_range<reg_instr_nodbg_iterator> reg_nodbg_instructions(unsigned Reg) const { - return iterator_range<reg_instr_nodbg_iterator>(reg_instr_nodbg_begin(Reg), - reg_instr_nodbg_end()); + return make_range(reg_instr_nodbg_begin(Reg), reg_instr_nodbg_end()); } /// reg_bundle_nodbg_iterator/reg_bundle_nodbg_begin/reg_bundle_nodbg_end - Walk @@ -333,10 +317,9 @@ public: return reg_bundle_nodbg_iterator(nullptr); } - inline iterator_range<reg_bundle_nodbg_iterator> + inline iterator_range<reg_bundle_nodbg_iterator> reg_nodbg_bundles(unsigned Reg) const { - return iterator_range<reg_bundle_nodbg_iterator>(reg_bundle_nodbg_begin(Reg), - reg_bundle_nodbg_end()); + return make_range(reg_bundle_nodbg_begin(Reg), reg_bundle_nodbg_end()); } /// reg_nodbg_empty - Return true if the only instructions using or defining @@ -354,7 +337,7 @@ public: static def_iterator def_end() { return def_iterator(nullptr); } inline iterator_range<def_iterator> def_operands(unsigned Reg) const { - return iterator_range<def_iterator>(def_begin(Reg), def_end()); + return make_range(def_begin(Reg), def_end()); } /// def_instr_iterator/def_instr_begin/def_instr_end - Walk all defs of the @@ -370,8 +353,7 @@ public: inline iterator_range<def_instr_iterator> def_instructions(unsigned Reg) const { - return iterator_range<def_instr_iterator>(def_instr_begin(Reg), - def_instr_end()); + return make_range(def_instr_begin(Reg), def_instr_end()); } /// def_bundle_iterator/def_bundle_begin/def_bundle_end - Walk all defs of the @@ -386,8 +368,7 @@ public: } inline iterator_range<def_bundle_iterator> def_bundles(unsigned Reg) const { - return iterator_range<def_bundle_iterator>(def_bundle_begin(Reg), - def_bundle_end()); + return make_range(def_bundle_begin(Reg), def_bundle_end()); } /// def_empty - Return true if there are no instructions defining the @@ -412,7 +393,7 @@ public: static use_iterator use_end() { return use_iterator(nullptr); } inline iterator_range<use_iterator> use_operands(unsigned Reg) const { - return iterator_range<use_iterator>(use_begin(Reg), use_end()); + return make_range(use_begin(Reg), use_end()); } /// use_instr_iterator/use_instr_begin/use_instr_end - Walk all uses of the @@ -428,8 +409,7 @@ public: inline iterator_range<use_instr_iterator> use_instructions(unsigned Reg) const { - return iterator_range<use_instr_iterator>(use_instr_begin(Reg), - use_instr_end()); + return make_range(use_instr_begin(Reg), use_instr_end()); } /// use_bundle_iterator/use_bundle_begin/use_bundle_end - Walk all uses of the @@ -444,8 +424,7 @@ public: } inline iterator_range<use_bundle_iterator> use_bundles(unsigned Reg) const { - return iterator_range<use_bundle_iterator>(use_bundle_begin(Reg), - use_bundle_end()); + return make_range(use_bundle_begin(Reg), use_bundle_end()); } /// use_empty - Return true if there are no instructions using the specified @@ -474,8 +453,7 @@ public: inline iterator_range<use_nodbg_iterator> use_nodbg_operands(unsigned Reg) const { - return iterator_range<use_nodbg_iterator>(use_nodbg_begin(Reg), - use_nodbg_end()); + return make_range(use_nodbg_begin(Reg), use_nodbg_end()); } /// use_instr_nodbg_iterator/use_instr_nodbg_begin/use_instr_nodbg_end - Walk @@ -492,8 +470,7 @@ public: inline iterator_range<use_instr_nodbg_iterator> use_nodbg_instructions(unsigned Reg) const { - return iterator_range<use_instr_nodbg_iterator>(use_instr_nodbg_begin(Reg), - use_instr_nodbg_end()); + return make_range(use_instr_nodbg_begin(Reg), use_instr_nodbg_end()); } /// use_bundle_nodbg_iterator/use_bundle_nodbg_begin/use_bundle_nodbg_end - Walk @@ -510,8 +487,7 @@ public: inline iterator_range<use_bundle_nodbg_iterator> use_nodbg_bundles(unsigned Reg) const { - return iterator_range<use_bundle_nodbg_iterator>(use_bundle_nodbg_begin(Reg), - use_bundle_nodbg_end()); + return make_range(use_bundle_nodbg_begin(Reg), use_bundle_nodbg_end()); } /// use_nodbg_empty - Return true if there are no non-Debug instructions @@ -540,7 +516,7 @@ public: /// apply sub registers to ToReg in order to obtain a final/proper physical /// register. void replaceRegWith(unsigned FromReg, unsigned ToReg); - + /// getVRegDef - Return the machine instr that defines the specified virtual /// register or null if none is found. This assumes that the code is in SSA /// form, so there should only be one definition. @@ -626,6 +602,12 @@ public: RegAllocHints[VReg].second = PrefReg; } + /// Specify the preferred register allocation hint for the specified virtual + /// register. + void setSimpleHint(unsigned VReg, unsigned PrefReg) { + setRegAllocationHint(VReg, /*Type=*/0, PrefReg); + } + /// getRegAllocationHint - Return the register allocation hint for the /// specified virtual register. std::pair<unsigned, unsigned> @@ -650,41 +632,15 @@ public: /// Return true if the specified register is modified in this function. /// This checks that no defining machine operands exist for the register or /// any of its aliases. Definitions found on functions marked noreturn are - /// ignored. + /// ignored. The register is also considered modified when it is set in the + /// UsedPhysRegMask. bool isPhysRegModified(unsigned PhysReg) const; - //===--------------------------------------------------------------------===// - // Physical Register Use Info - //===--------------------------------------------------------------------===// - - /// isPhysRegUsed - Return true if the specified register is used in this - /// function. Also check for clobbered aliases and registers clobbered by - /// function calls with register mask operands. - /// - /// This only works after register allocation. - bool isPhysRegUsed(unsigned Reg) const { - if (UsedPhysRegMask.test(Reg)) - return true; - for (MCRegUnitIterator Units(Reg, getTargetRegisterInfo()); - Units.isValid(); ++Units) - if (UsedRegUnits.test(*Units)) - return true; - return false; - } - - /// Mark the specified register unit as used in this function. - /// This should only be called during and after register allocation. - void setRegUnitUsed(unsigned RegUnit) { - UsedRegUnits.set(RegUnit); - } - - /// setPhysRegUsed - Mark the specified register used in this function. - /// This should only be called during and after register allocation. - void setPhysRegUsed(unsigned Reg) { - for (MCRegUnitIterator Units(Reg, getTargetRegisterInfo()); - Units.isValid(); ++Units) - UsedRegUnits.set(*Units); - } + /// Return true if the specified register is modified or read in this + /// function. This checks that no machine operands exist for the register or + /// any of its aliases. The register is also considered used when it is set + /// in the UsedPhysRegMask. + bool isPhysRegUsed(unsigned PhysReg) const; /// addPhysRegsUsedFromRegMask - Mark any registers not in RegMask as used. /// This corresponds to the bit mask attached to register mask operands. @@ -692,15 +648,9 @@ public: UsedPhysRegMask.setBitsNotInMask(RegMask); } - /// setPhysRegUnused - Mark the specified register unused in this function. - /// This should only be called during and after register allocation. - void setPhysRegUnused(unsigned Reg) { - UsedPhysRegMask.reset(Reg); - for (MCRegUnitIterator Units(Reg, getTargetRegisterInfo()); - Units.isValid(); ++Units) - UsedRegUnits.reset(*Units); - } + const BitVector &getUsedPhysRegsMask() const { return UsedPhysRegMask; } + void setUsedPhysRegMask(BitVector &Mask) { UsedPhysRegMask = Mask; } //===--------------------------------------------------------------------===// // Reserved Register Info @@ -797,7 +747,7 @@ public: /// Returns a mask covering all bits that can appear in lane masks of /// subregisters of the virtual register @p Reg. - unsigned getMaxLaneMaskForVReg(unsigned Reg) const; + LaneBitmask getMaxLaneMaskForVReg(unsigned Reg) const; /// defusechain_iterator - This class provides iterator support for machine /// operands in the function that use or define a specific register. If diff --git a/contrib/llvm/include/llvm/CodeGen/MachineScheduler.h b/contrib/llvm/include/llvm/CodeGen/MachineScheduler.h index e80e14e..358fd5a 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineScheduler.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineScheduler.h @@ -77,6 +77,7 @@ #ifndef LLVM_CODEGEN_MACHINESCHEDULER_H #define LLVM_CODEGEN_MACHINESCHEDULER_H +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/CodeGen/MachinePassRegistry.h" #include "llvm/CodeGen/RegisterPressure.h" #include "llvm/CodeGen/ScheduleDAGInstrs.h" @@ -87,7 +88,6 @@ namespace llvm { extern cl::opt<bool> ForceTopDown; extern cl::opt<bool> ForceBottomUp; -class AliasAnalysis; class LiveIntervals; class MachineDominatorTree; class MachineLoopInfo; @@ -156,8 +156,12 @@ struct MachineSchedPolicy { bool OnlyTopDown; bool OnlyBottomUp; + // Disable heuristic that tries to fetch nodes from long dependency chains + // first. + bool DisableLatencyHeuristic; + MachineSchedPolicy(): ShouldTrackPressure(false), OnlyTopDown(false), - OnlyBottomUp(false) {} + OnlyBottomUp(false), DisableLatencyHeuristic(false) {} }; /// MachineSchedStrategy - Interface to the scheduling algorithm used by @@ -175,6 +179,8 @@ public: MachineBasicBlock::iterator End, unsigned NumRegionInstrs) {} + virtual void dumpPolicy() {} + /// Check if pressure tracking is needed before building the DAG and /// initializing this strategy. Called after initPolicy. virtual bool shouldTrackPressure() const { return true; } @@ -222,6 +228,7 @@ public: class ScheduleDAGMI : public ScheduleDAGInstrs { protected: AliasAnalysis *AA; + LiveIntervals *LIS; std::unique_ptr<MachineSchedStrategy> SchedImpl; /// Topo - A topological ordering for SUnits which permits fast IsReachable @@ -248,11 +255,11 @@ protected: #endif public: ScheduleDAGMI(MachineSchedContext *C, std::unique_ptr<MachineSchedStrategy> S, - bool IsPostRA) - : ScheduleDAGInstrs(*C->MF, C->MLI, IsPostRA, - /*RemoveKillFlags=*/IsPostRA, C->LIS), - AA(C->AA), SchedImpl(std::move(S)), Topo(SUnits, &ExitSU), CurrentTop(), - CurrentBottom(), NextClusterPred(nullptr), NextClusterSucc(nullptr) { + bool RemoveKillFlags) + : ScheduleDAGInstrs(*C->MF, C->MLI, RemoveKillFlags), AA(C->AA), + LIS(C->LIS), SchedImpl(std::move(S)), Topo(SUnits, &ExitSU), + CurrentTop(), CurrentBottom(), NextClusterPred(nullptr), + NextClusterSucc(nullptr) { #ifndef NDEBUG NumInstrsScheduled = 0; #endif @@ -261,6 +268,9 @@ public: // Provide a vtable anchor ~ScheduleDAGMI() override; + // Returns LiveIntervals instance for use in DAG mutators and such. + LiveIntervals *getLIS() const { return LIS; } + /// Return true if this DAG supports VReg liveness and RegPressure. virtual bool hasVRegLiveness() const { return false; } @@ -380,7 +390,7 @@ protected: public: ScheduleDAGMILive(MachineSchedContext *C, std::unique_ptr<MachineSchedStrategy> S) - : ScheduleDAGMI(C, std::move(S), /*IsPostRA=*/false), + : ScheduleDAGMI(C, std::move(S), /*RemoveKillFlags=*/false), RegClassInfo(C->RegClassInfo), DFSResult(nullptr), ShouldTrackPressure(false), RPTracker(RegPressure), TopRPTracker(TopPressure), BotRPTracker(BotPressure) {} @@ -858,6 +868,8 @@ public: MachineBasicBlock::iterator End, unsigned NumRegionInstrs) override; + void dumpPolicy() override; + bool shouldTrackPressure() const override { return RegionPolicy.ShouldTrackPressure; } @@ -915,7 +927,7 @@ public: MachineBasicBlock::iterator End, unsigned NumRegionInstrs) override { /* no configurable policy */ - }; + } /// PostRA scheduling does not track pressure. bool shouldTrackPressure() const override { return false; } diff --git a/contrib/llvm/include/llvm/CodeGen/MachineValueType.h b/contrib/llvm/include/llvm/CodeGen/MachineValueType.h index a728df3..04d6ee3 100644 --- a/contrib/llvm/include/llvm/CodeGen/MachineValueType.h +++ b/contrib/llvm/include/llvm/CodeGen/MachineValueType.h @@ -56,53 +56,66 @@ class MVT { FIRST_FP_VALUETYPE = f16, LAST_FP_VALUETYPE = ppcf128, - v2i1 = 13, // 2 x i1 - v4i1 = 14, // 4 x i1 - v8i1 = 15, // 8 x i1 - v16i1 = 16, // 16 x i1 - v32i1 = 17, // 32 x i1 - v64i1 = 18, // 64 x i1 - - v1i8 = 19, // 1 x i8 - v2i8 = 20, // 2 x i8 - v4i8 = 21, // 4 x i8 - v8i8 = 22, // 8 x i8 - v16i8 = 23, // 16 x i8 - v32i8 = 24, // 32 x i8 - v64i8 = 25, // 64 x i8 - v1i16 = 26, // 1 x i16 - v2i16 = 27, // 2 x i16 - v4i16 = 28, // 4 x i16 - v8i16 = 29, // 8 x i16 - v16i16 = 30, // 16 x i16 - v32i16 = 31, // 32 x i16 - v1i32 = 32, // 1 x i32 - v2i32 = 33, // 2 x i32 - v4i32 = 34, // 4 x i32 - v8i32 = 35, // 8 x i32 - v16i32 = 36, // 16 x i32 - v1i64 = 37, // 1 x i64 - v2i64 = 38, // 2 x i64 - v4i64 = 39, // 4 x i64 - v8i64 = 40, // 8 x i64 - v16i64 = 41, // 16 x i64 - v1i128 = 42, // 1 x i128 - + v2i1 = 13, // 2 x i1 + v4i1 = 14, // 4 x i1 + v8i1 = 15, // 8 x i1 + v16i1 = 16, // 16 x i1 + v32i1 = 17, // 32 x i1 + v64i1 = 18, // 64 x i1 + v512i1 = 19, // 512 x i1 + v1024i1 = 20, // 1024 x i1 + + v1i8 = 21, // 1 x i8 + v2i8 = 22, // 2 x i8 + v4i8 = 23, // 4 x i8 + v8i8 = 24, // 8 x i8 + v16i8 = 25, // 16 x i8 + v32i8 = 26, // 32 x i8 + v64i8 = 27, // 64 x i8 + v128i8 = 28, //128 x i8 + v256i8 = 29, //256 x i8 + + v1i16 = 30, // 1 x i16 + v2i16 = 31, // 2 x i16 + v4i16 = 32, // 4 x i16 + v8i16 = 33, // 8 x i16 + v16i16 = 34, // 16 x i16 + v32i16 = 35, // 32 x i16 + v64i16 = 36, // 64 x i16 + v128i16 = 37, //128 x i16 + + v1i32 = 38, // 1 x i32 + v2i32 = 39, // 2 x i32 + v4i32 = 40, // 4 x i32 + v8i32 = 41, // 8 x i32 + v16i32 = 42, // 16 x i32 + v32i32 = 43, // 32 x i32 + v64i32 = 44, // 64 x i32 + + v1i64 = 45, // 1 x i64 + v2i64 = 46, // 2 x i64 + v4i64 = 47, // 4 x i64 + v8i64 = 48, // 8 x i64 + v16i64 = 49, // 16 x i64 + v32i64 = 50, // 32 x i64 + + v1i128 = 51, // 1 x i128 + FIRST_INTEGER_VECTOR_VALUETYPE = v2i1, LAST_INTEGER_VECTOR_VALUETYPE = v1i128, - v2f16 = 43, // 2 x f16 - v4f16 = 44, // 4 x f16 - v8f16 = 45, // 8 x f16 - v1f32 = 46, // 1 x f32 - v2f32 = 47, // 2 x f32 - v4f32 = 48, // 4 x f32 - v8f32 = 49, // 8 x f32 - v16f32 = 50, // 16 x f32 - v1f64 = 51, // 1 x f64 - v2f64 = 52, // 2 x f64 - v4f64 = 53, // 4 x f64 - v8f64 = 54, // 8 x f64 + v2f16 = 52, // 2 x f16 + v4f16 = 53, // 4 x f16 + v8f16 = 54, // 8 x f16 + v1f32 = 55, // 1 x f32 + v2f32 = 56, // 2 x f32 + v4f32 = 57, // 4 x f32 + v8f32 = 58, // 8 x f32 + v16f32 = 59, // 16 x f32 + v1f64 = 60, // 1 x f64 + v2f64 = 61, // 2 x f64 + v4f64 = 62, // 4 x f64 + v8f64 = 63, // 8 x f64 FIRST_FP_VECTOR_VALUETYPE = v2f16, LAST_FP_VECTOR_VALUETYPE = v8f64, @@ -110,23 +123,26 @@ class MVT { FIRST_VECTOR_VALUETYPE = v2i1, LAST_VECTOR_VALUETYPE = v8f64, - x86mmx = 55, // This is an X86 MMX value + x86mmx = 64, // This is an X86 MMX value - Glue = 56, // This glues nodes together during pre-RA sched + Glue = 65, // This glues nodes together during pre-RA sched - isVoid = 57, // This has no value + isVoid = 66, // This has no value - Untyped = 58, // This value takes a register, but has + Untyped = 67, // This value takes a register, but has // unspecified type. The register class // will be determined by the opcode. FIRST_VALUETYPE = 0, // This is always the beginning of the list. - LAST_VALUETYPE = 59, // This always remains at the end of the list. + LAST_VALUETYPE = 68, // This always remains at the end of the list. // This is the current maximum for LAST_VALUETYPE. // MVT::MAX_ALLOWED_VALUETYPE is used for asserts and to size bit vectors // This value must be a multiple of 32. - MAX_ALLOWED_VALUETYPE = 64, + MAX_ALLOWED_VALUETYPE = 96, + + // Token - A value of type llvm::TokenTy + token = 249, // Metadata - This is MDNode or MDString. Metadata = 250, @@ -238,14 +254,23 @@ class MVT { /// is512BitVector - Return true if this is a 512-bit vector type. bool is512BitVector() const { - return (SimpleTy == MVT::v8f64 || SimpleTy == MVT::v16f32 || - SimpleTy == MVT::v64i8 || SimpleTy == MVT::v32i16 || - SimpleTy == MVT::v8i64 || SimpleTy == MVT::v16i32); + return (SimpleTy == MVT::v16f32 || SimpleTy == MVT::v8f64 || + SimpleTy == MVT::v512i1 || SimpleTy == MVT::v64i8 || + SimpleTy == MVT::v32i16 || SimpleTy == MVT::v16i32 || + SimpleTy == MVT::v8i64); } /// is1024BitVector - Return true if this is a 1024-bit vector type. bool is1024BitVector() const { - return (SimpleTy == MVT::v16i64); + return (SimpleTy == MVT::v1024i1 || SimpleTy == MVT::v128i8 || + SimpleTy == MVT::v64i16 || SimpleTy == MVT::v32i32 || + SimpleTy == MVT::v16i64); + } + + /// is2048BitVector - Return true if this is a 1024-bit vector type. + bool is2048BitVector() const { + return (SimpleTy == MVT::v256i8 || SimpleTy == MVT::v128i16 || + SimpleTy == MVT::v64i32 || SimpleTy == MVT::v32i64); } /// isOverloaded - Return true if this is an overloaded type for TableGen. @@ -282,35 +307,44 @@ class MVT { switch (SimpleTy) { default: llvm_unreachable("Not a vector MVT!"); - case v2i1 : - case v4i1 : - case v8i1 : - case v16i1 : - case v32i1 : - case v64i1: return i1; - case v1i8 : - case v2i8 : - case v4i8 : - case v8i8 : + case v2i1: + case v4i1: + case v8i1: + case v16i1: + case v32i1: + case v64i1: + case v512i1: + case v1024i1: return i1; + case v1i8: + case v2i8: + case v4i8: + case v8i8: case v16i8: case v32i8: - case v64i8: return i8; + case v64i8: + case v128i8: + case v256i8: return i8; case v1i16: case v2i16: case v4i16: case v8i16: case v16i16: - case v32i16: return i16; + case v32i16: + case v64i16: + case v128i16: return i16; case v1i32: case v2i32: case v4i32: case v8i32: - case v16i32: return i32; + case v16i32: + case v32i32: + case v64i32: return i32; case v1i64: case v2i64: case v4i64: case v8i64: - case v16i64: return i64; + case v16i64: + case v32i64: return i64; case v1i128: return i128; case v2f16: case v4f16: @@ -331,19 +365,28 @@ class MVT { switch (SimpleTy) { default: llvm_unreachable("Not a vector MVT!"); + case v1024i1: return 1024; + case v512i1: return 512; + case v256i8: return 256; + case v128i8: + case v128i16: return 128; + case v64i1: + case v64i8: + case v64i16: + case v64i32: return 64; case v32i1: case v32i8: - case v32i16: return 32; - case v64i1: - case v64i8: return 64; + case v32i16: + case v32i32: + case v32i64: return 32; case v16i1: case v16i8: case v16i16: case v16i32: case v16i64: case v16f32: return 16; - case v8i1 : - case v8i8 : + case v8i1: + case v8i8: case v8i16: case v8i32: case v8i64: @@ -390,6 +433,9 @@ class MVT { case vAny: case Any: llvm_unreachable("Value type is overloaded."); + case token: + llvm_unreachable("Token type is a sentinel that cannot be used " + "in codegen and has no size"); case Metadata: llvm_unreachable("Value type is metadata."); case i1 : return 1; @@ -440,13 +486,22 @@ class MVT { case v4i64: case v8f32: case v4f64: return 256; + case v512i1: case v64i8: case v32i16: case v16i32: case v8i64: case v16f32: case v8f64: return 512; - case v16i64:return 1024; + case v1024i1: + case v128i8: + case v64i16: + case v32i32: + case v16i64: return 1024; + case v256i8: + case v128i16: + case v64i32: + case v32i64: return 2048; } } @@ -528,29 +583,35 @@ class MVT { default: break; case MVT::i1: - if (NumElements == 2) return MVT::v2i1; - if (NumElements == 4) return MVT::v4i1; - if (NumElements == 8) return MVT::v8i1; - if (NumElements == 16) return MVT::v16i1; - if (NumElements == 32) return MVT::v32i1; - if (NumElements == 64) return MVT::v64i1; + if (NumElements == 2) return MVT::v2i1; + if (NumElements == 4) return MVT::v4i1; + if (NumElements == 8) return MVT::v8i1; + if (NumElements == 16) return MVT::v16i1; + if (NumElements == 32) return MVT::v32i1; + if (NumElements == 64) return MVT::v64i1; + if (NumElements == 512) return MVT::v512i1; + if (NumElements == 1024) return MVT::v1024i1; break; case MVT::i8: - if (NumElements == 1) return MVT::v1i8; - if (NumElements == 2) return MVT::v2i8; - if (NumElements == 4) return MVT::v4i8; - if (NumElements == 8) return MVT::v8i8; - if (NumElements == 16) return MVT::v16i8; - if (NumElements == 32) return MVT::v32i8; - if (NumElements == 64) return MVT::v64i8; + if (NumElements == 1) return MVT::v1i8; + if (NumElements == 2) return MVT::v2i8; + if (NumElements == 4) return MVT::v4i8; + if (NumElements == 8) return MVT::v8i8; + if (NumElements == 16) return MVT::v16i8; + if (NumElements == 32) return MVT::v32i8; + if (NumElements == 64) return MVT::v64i8; + if (NumElements == 128) return MVT::v128i8; + if (NumElements == 256) return MVT::v256i8; break; case MVT::i16: - if (NumElements == 1) return MVT::v1i16; - if (NumElements == 2) return MVT::v2i16; - if (NumElements == 4) return MVT::v4i16; - if (NumElements == 8) return MVT::v8i16; - if (NumElements == 16) return MVT::v16i16; - if (NumElements == 32) return MVT::v32i16; + if (NumElements == 1) return MVT::v1i16; + if (NumElements == 2) return MVT::v2i16; + if (NumElements == 4) return MVT::v4i16; + if (NumElements == 8) return MVT::v8i16; + if (NumElements == 16) return MVT::v16i16; + if (NumElements == 32) return MVT::v32i16; + if (NumElements == 64) return MVT::v64i16; + if (NumElements == 128) return MVT::v128i16; break; case MVT::i32: if (NumElements == 1) return MVT::v1i32; @@ -558,6 +619,8 @@ class MVT { if (NumElements == 4) return MVT::v4i32; if (NumElements == 8) return MVT::v8i32; if (NumElements == 16) return MVT::v16i32; + if (NumElements == 32) return MVT::v32i32; + if (NumElements == 64) return MVT::v64i32; break; case MVT::i64: if (NumElements == 1) return MVT::v1i64; @@ -565,6 +628,7 @@ class MVT { if (NumElements == 4) return MVT::v4i64; if (NumElements == 8) return MVT::v8i64; if (NumElements == 16) return MVT::v16i64; + if (NumElements == 32) return MVT::v32i64; break; case MVT::i128: if (NumElements == 1) return MVT::v1i128; diff --git a/contrib/llvm/include/llvm/CodeGen/ParallelCG.h b/contrib/llvm/include/llvm/CodeGen/ParallelCG.h new file mode 100644 index 0000000..fa7002f --- /dev/null +++ b/contrib/llvm/include/llvm/CodeGen/ParallelCG.h @@ -0,0 +1,43 @@ +//===-- llvm/CodeGen/ParallelCG.h - Parallel code generation ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This header declares functions that can be used for parallel code generation. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_PARALLELCG_H +#define LLVM_CODEGEN_PARALLELCG_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/CodeGen.h" +#include "llvm/Target/TargetMachine.h" + +namespace llvm { + +class Module; +class TargetOptions; +class raw_pwrite_stream; + +/// Split M into OSs.size() partitions, and generate code for each. Writes +/// OSs.size() output files to the output streams in OSs. The resulting output +/// files if linked together are intended to be equivalent to the single output +/// file that would have been code generated from M. +/// +/// \returns M if OSs.size() == 1, otherwise returns std::unique_ptr<Module>(). +std::unique_ptr<Module> +splitCodeGen(std::unique_ptr<Module> M, ArrayRef<raw_pwrite_stream *> OSs, + StringRef CPU, StringRef Features, const TargetOptions &Options, + Reloc::Model RM = Reloc::Default, + CodeModel::Model CM = CodeModel::Default, + CodeGenOpt::Level OL = CodeGenOpt::Default, + TargetMachine::CodeGenFileType FT = TargetMachine::CGFT_ObjectFile); + +} // namespace llvm + +#endif diff --git a/contrib/llvm/include/llvm/CodeGen/Passes.h b/contrib/llvm/include/llvm/CodeGen/Passes.h index 5d82921..f45f0ed 100644 --- a/contrib/llvm/include/llvm/CodeGen/Passes.h +++ b/contrib/llvm/include/llvm/CodeGen/Passes.h @@ -120,9 +120,6 @@ protected: /// Default setting for -enable-tail-merge on this target. bool EnableTailMerge; - /// Default setting for -enable-shrink-wrap on this target. - bool EnableShrinkWrap; - public: TargetPassConfig(TargetMachine *tm, PassManagerBase &pm); // Dummy constructor. @@ -173,7 +170,8 @@ public: void substitutePass(AnalysisID StandardID, IdentifyingPassPtr TargetID); /// Insert InsertedPassID pass after TargetPassID pass. - void insertPass(AnalysisID TargetPassID, IdentifyingPassPtr InsertedPassID); + void insertPass(AnalysisID TargetPassID, IdentifyingPassPtr InsertedPassID, + bool VerifyAfter = true, bool PrintAfter = true); /// Allow the target to enable a specific standard pass by default. void enablePass(AnalysisID PassID) { substitutePass(PassID, PassID); } @@ -228,7 +226,7 @@ public: /// /// This can also be used to plug a new MachineSchedStrategy into an instance /// of the standard ScheduleDAGMI: - /// return new ScheduleDAGMI(C, make_unique<MyStrategy>(C), /* IsPostRA= */false) + /// return new ScheduleDAGMI(C, make_unique<MyStrategy>(C), /*RemoveKillFlags=*/false) /// /// Return NULL to select the default (generic) machine scheduler. virtual ScheduleDAGInstrs * @@ -585,6 +583,9 @@ namespace llvm { /// StackSlotColoring - This pass performs stack slot coloring. extern char &StackSlotColoringID; + /// \brief This pass lays out funclets contiguously. + extern char &FuncletLayoutID; + /// createStackProtectorPass - This pass adds stack protectors to functions. /// FunctionPass *createStackProtectorPass(const TargetMachine *TM); @@ -639,6 +640,9 @@ namespace llvm { /// the intrinsic for later emission to the StackMap. extern char &StackMapLivenessID; + /// LiveDebugValues pass + extern char &LiveDebugValuesID; + /// createJumpInstrTables - This pass creates jump-instruction tables. ModulePass *createJumpInstrTablesPass(); diff --git a/contrib/llvm/include/llvm/CodeGen/PseudoSourceValue.h b/contrib/llvm/include/llvm/CodeGen/PseudoSourceValue.h index a518b62..f675520 100644 --- a/contrib/llvm/include/llvm/CodeGen/PseudoSourceValue.h +++ b/contrib/llvm/include/llvm/CodeGen/PseudoSourceValue.h @@ -14,97 +14,170 @@ #ifndef LLVM_CODEGEN_PSEUDOSOURCEVALUE_H #define LLVM_CODEGEN_PSEUDOSOURCEVALUE_H +#include "llvm/ADT/StringMap.h" +#include "llvm/IR/GlobalValue.h" #include "llvm/IR/Value.h" +#include "llvm/IR/ValueMap.h" +#include <map> namespace llvm { - class MachineFrameInfo; - class MachineMemOperand; - class raw_ostream; - - raw_ostream &operator<<(raw_ostream &OS, const MachineMemOperand &MMO); - - /// PseudoSourceValue - Special value supplied for machine level alias - /// analysis. It indicates that a memory access references the functions - /// stack frame (e.g., a spill slot), below the stack frame (e.g., argument - /// space), or constant pool. - class PseudoSourceValue { - private: - friend class MachineMemOperand; // For printCustom(). - - /// printCustom - Implement printing for PseudoSourceValue. This is called - /// from Value::print or Value's operator<<. - /// - virtual void printCustom(raw_ostream &O) const; - - public: - /// isFixed - Whether this is a FixedStackPseudoSourceValue. - bool isFixed; - - explicit PseudoSourceValue(bool isFixed = false); - - virtual ~PseudoSourceValue(); - - /// isConstant - Test whether the memory pointed to by this - /// PseudoSourceValue has a constant value. - /// - virtual bool isConstant(const MachineFrameInfo *) const; - - /// isAliased - Test whether the memory pointed to by this - /// PseudoSourceValue may also be pointed to by an LLVM IR Value. - virtual bool isAliased(const MachineFrameInfo *) const; - - /// mayAlias - Return true if the memory pointed to by this - /// PseudoSourceValue can ever alias an LLVM IR Value. - virtual bool mayAlias(const MachineFrameInfo *) const; - - /// A pseudo source value referencing a fixed stack frame entry, - /// e.g., a spill slot. - static const PseudoSourceValue *getFixedStack(int FI); - - /// A pseudo source value referencing the area below the stack frame of - /// a function, e.g., the argument space. - static const PseudoSourceValue *getStack(); - - /// A pseudo source value referencing the global offset table - /// (or something the like). - static const PseudoSourceValue *getGOT(); - - /// A pseudo source value referencing the constant pool. Since constant - /// pools are constant, this doesn't need to identify a specific constant - /// pool entry. - static const PseudoSourceValue *getConstantPool(); - - /// A pseudo source value referencing a jump table. Since jump tables are - /// constant, this doesn't need to identify a specific jump table. - static const PseudoSourceValue *getJumpTable(); + +class MachineFrameInfo; +class MachineMemOperand; +class raw_ostream; + +raw_ostream &operator<<(raw_ostream &OS, const MachineMemOperand &MMO); + +/// Special value supplied for machine level alias analysis. It indicates that +/// a memory access references the functions stack frame (e.g., a spill slot), +/// below the stack frame (e.g., argument space), or constant pool. +class PseudoSourceValue { +public: + enum PSVKind { + Stack, + GOT, + JumpTable, + ConstantPool, + FixedStack, + GlobalValueCallEntry, + ExternalSymbolCallEntry }; - /// FixedStackPseudoSourceValue - A specialized PseudoSourceValue - /// for holding FixedStack values, which must include a frame - /// index. - class FixedStackPseudoSourceValue : public PseudoSourceValue { - const int FI; - public: - explicit FixedStackPseudoSourceValue(int fi) : - PseudoSourceValue(true), FI(fi) {} +private: + PSVKind Kind; - /// classof - Methods for support type inquiry through isa, cast, and - /// dyn_cast: - /// - static inline bool classof(const PseudoSourceValue *V) { - return V->isFixed == true; - } + friend class MachineMemOperand; // For printCustom(). - bool isConstant(const MachineFrameInfo *MFI) const override; + /// Implement printing for PseudoSourceValue. This is called from + /// Value::print or Value's operator<<. + virtual void printCustom(raw_ostream &O) const; - bool isAliased(const MachineFrameInfo *MFI) const override; +public: + explicit PseudoSourceValue(PSVKind Kind); - bool mayAlias(const MachineFrameInfo *) const override; + virtual ~PseudoSourceValue(); - void printCustom(raw_ostream &OS) const override; + PSVKind kind() const { return Kind; } - int getFrameIndex() const { return FI; } - }; -} // End llvm namespace + bool isStack() const { return Kind == Stack; } + bool isGOT() const { return Kind == GOT; } + bool isConstantPool() const { return Kind == ConstantPool; } + bool isJumpTable() const { return Kind == JumpTable; } + + /// Test whether the memory pointed to by this PseudoSourceValue has a + /// constant value. + virtual bool isConstant(const MachineFrameInfo *) const; + + /// Test whether the memory pointed to by this PseudoSourceValue may also be + /// pointed to by an LLVM IR Value. + virtual bool isAliased(const MachineFrameInfo *) const; + + /// Return true if the memory pointed to by this PseudoSourceValue can ever + /// alias an LLVM IR Value. + virtual bool mayAlias(const MachineFrameInfo *) const; +}; + +/// A specialized PseudoSourceValue for holding FixedStack values, which must +/// include a frame index. +class FixedStackPseudoSourceValue : public PseudoSourceValue { + const int FI; + +public: + explicit FixedStackPseudoSourceValue(int FI) + : PseudoSourceValue(FixedStack), FI(FI) {} + + static inline bool classof(const PseudoSourceValue *V) { + return V->kind() == FixedStack; + } + + bool isConstant(const MachineFrameInfo *MFI) const override; + + bool isAliased(const MachineFrameInfo *MFI) const override; + + bool mayAlias(const MachineFrameInfo *) const override; + + void printCustom(raw_ostream &OS) const override; + + int getFrameIndex() const { return FI; } +}; + +class CallEntryPseudoSourceValue : public PseudoSourceValue { +protected: + CallEntryPseudoSourceValue(PSVKind Kind); + +public: + bool isConstant(const MachineFrameInfo *) const override; + bool isAliased(const MachineFrameInfo *) const override; + bool mayAlias(const MachineFrameInfo *) const override; +}; + +/// A specialized pseudo soruce value for holding GlobalValue values. +class GlobalValuePseudoSourceValue : public CallEntryPseudoSourceValue { + const GlobalValue *GV; + +public: + GlobalValuePseudoSourceValue(const GlobalValue *GV); + + static inline bool classof(const PseudoSourceValue *V) { + return V->kind() == GlobalValueCallEntry; + } + + const GlobalValue *getValue() const { return GV; } +}; + +/// A specialized pseudo source value for holding external symbol values. +class ExternalSymbolPseudoSourceValue : public CallEntryPseudoSourceValue { + const char *ES; + +public: + ExternalSymbolPseudoSourceValue(const char *ES); + + static inline bool classof(const PseudoSourceValue *V) { + return V->kind() == ExternalSymbolCallEntry; + } + + const char *getSymbol() const { return ES; } +}; + +/// Manages creation of pseudo source values. +class PseudoSourceValueManager { + const PseudoSourceValue StackPSV, GOTPSV, JumpTablePSV, ConstantPoolPSV; + std::map<int, std::unique_ptr<FixedStackPseudoSourceValue>> FSValues; + StringMap<std::unique_ptr<const ExternalSymbolPseudoSourceValue>> + ExternalCallEntries; + ValueMap<const GlobalValue *, + std::unique_ptr<const GlobalValuePseudoSourceValue>> + GlobalCallEntries; + +public: + PseudoSourceValueManager(); + + /// Return a pseudo source value referencing the area below the stack frame of + /// a function, e.g., the argument space. + const PseudoSourceValue *getStack(); + + /// Return a pseudo source value referencing the global offset table + /// (or something the like). + const PseudoSourceValue *getGOT(); + + /// Return a pseudo source value referencing the constant pool. Since constant + /// pools are constant, this doesn't need to identify a specific constant + /// pool entry. + const PseudoSourceValue *getConstantPool(); + + /// Return a pseudo source value referencing a jump table. Since jump tables + /// are constant, this doesn't need to identify a specific jump table. + const PseudoSourceValue *getJumpTable(); + + /// Return a pseudo source value referencing a fixed stack frame entry, + /// e.g., a spill slot. + const PseudoSourceValue *getFixedStack(int FI); + + const PseudoSourceValue *getGlobalValueCallEntry(const GlobalValue *GV); + + const PseudoSourceValue *getExternalSymbolCallEntry(const char *ES); +}; + +} // end namespace llvm #endif diff --git a/contrib/llvm/include/llvm/CodeGen/RegAllocPBQP.h b/contrib/llvm/include/llvm/CodeGen/RegAllocPBQP.h index 6046e46..4122811 100644 --- a/contrib/llvm/include/llvm/CodeGen/RegAllocPBQP.h +++ b/contrib/llvm/include/llvm/CodeGen/RegAllocPBQP.h @@ -134,7 +134,7 @@ inline hash_code hash_value(const AllowedRegVector &OptRegs) { hash_combine_range(OStart, OEnd)); } -/// \brief Holds graph-level metadata relevent to PBQP RA problems. +/// \brief Holds graph-level metadata relevant to PBQP RA problems. class GraphMetadata { private: typedef ValuePool<AllowedRegVector> AllowedRegVecPool; diff --git a/contrib/llvm/include/llvm/CodeGen/RegAllocRegistry.h b/contrib/llvm/include/llvm/CodeGen/RegAllocRegistry.h index ca49577..5c7e999 100644 --- a/contrib/llvm/include/llvm/CodeGen/RegAllocRegistry.h +++ b/contrib/llvm/include/llvm/CodeGen/RegAllocRegistry.h @@ -33,12 +33,10 @@ public: static MachinePassRegistry Registry; RegisterRegAlloc(const char *N, const char *D, FunctionPassCtor C) - : MachinePassRegistryNode(N, D, (MachinePassCtor)C) - { - Registry.Add(this); + : MachinePassRegistryNode(N, D, (MachinePassCtor)C) { + Registry.Add(this); } ~RegisterRegAlloc() { Registry.Remove(this); } - // Accessors. // @@ -57,7 +55,6 @@ public: static void setListener(MachinePassRegistryListener *L) { Registry.setListener(L); } - }; } // end namespace llvm diff --git a/contrib/llvm/include/llvm/CodeGen/RegisterPressure.h b/contrib/llvm/include/llvm/CodeGen/RegisterPressure.h index 9d8843d..987634f 100644 --- a/contrib/llvm/include/llvm/CodeGen/RegisterPressure.h +++ b/contrib/llvm/include/llvm/CodeGen/RegisterPressure.h @@ -125,11 +125,13 @@ class PressureDiff { enum { MaxPSets = 16 }; PressureChange PressureChanges[MaxPSets]; -public: + typedef PressureChange* iterator; + iterator nonconst_begin() { return &PressureChanges[0]; } + iterator nonconst_end() { return &PressureChanges[MaxPSets]; } + +public: typedef const PressureChange* const_iterator; - iterator begin() { return &PressureChanges[0]; } - iterator end() { return &PressureChanges[MaxPSets]; } const_iterator begin() const { return &PressureChanges[0]; } const_iterator end() const { return &PressureChanges[MaxPSets]; } @@ -191,30 +193,56 @@ struct RegPressureDelta { } }; -/// \brief A set of live virtual registers and physical register units. +/// A set of live virtual registers and physical register units. /// -/// Virtual and physical register numbers require separate sparse sets, but most -/// of the RegisterPressureTracker handles them uniformly. -struct LiveRegSet { - SparseSet<unsigned> PhysRegs; - SparseSet<unsigned, VirtReg2IndexFunctor> VirtRegs; +/// This is a wrapper around a SparseSet which deals with mapping register unit +/// and virtual register indexes to an index usable by the sparse set. +class LiveRegSet { +private: + SparseSet<unsigned> Regs; + unsigned NumRegUnits; + + unsigned getSparseIndexFromReg(unsigned Reg) const { + if (TargetRegisterInfo::isVirtualRegister(Reg)) + return TargetRegisterInfo::virtReg2Index(Reg) + NumRegUnits; + assert(Reg < NumRegUnits); + return Reg; + } + unsigned getRegFromSparseIndex(unsigned SparseIndex) const { + if (SparseIndex >= NumRegUnits) + return TargetRegisterInfo::index2VirtReg(SparseIndex-NumRegUnits); + return SparseIndex; + } + +public: + void clear(); + void init(const MachineRegisterInfo &MRI); bool contains(unsigned Reg) const { - if (TargetRegisterInfo::isVirtualRegister(Reg)) - return VirtRegs.count(Reg); - return PhysRegs.count(Reg); + unsigned SparseIndex = getSparseIndexFromReg(Reg); + return Regs.count(SparseIndex); } bool insert(unsigned Reg) { - if (TargetRegisterInfo::isVirtualRegister(Reg)) - return VirtRegs.insert(Reg).second; - return PhysRegs.insert(Reg).second; + unsigned SparseIndex = getSparseIndexFromReg(Reg); + return Regs.insert(SparseIndex).second; } bool erase(unsigned Reg) { - if (TargetRegisterInfo::isVirtualRegister(Reg)) - return VirtRegs.erase(Reg); - return PhysRegs.erase(Reg); + unsigned SparseIndex = getSparseIndexFromReg(Reg); + return Regs.erase(SparseIndex); + } + + size_t size() const { + return Regs.size(); + } + + template<typename ContainerT> + void appendTo(ContainerT &To) const { + for (unsigned I : Regs) { + unsigned Reg = getRegFromSparseIndex(I); + To.push_back(Reg); + } } }; @@ -300,16 +328,12 @@ public: // position changes while pressure does not. void setPos(MachineBasicBlock::const_iterator Pos) { CurrPos = Pos; } - /// \brief Get the SlotIndex for the first nondebug instruction including or - /// after the current position. - SlotIndex getCurrSlot() const; - /// Recede across the previous instruction. - bool recede(SmallVectorImpl<unsigned> *LiveUses = nullptr, + void recede(SmallVectorImpl<unsigned> *LiveUses = nullptr, PressureDiff *PDiff = nullptr); /// Advance across the current instruction. - bool advance(); + void advance(); /// Finalize the region boundaries and recored live ins and live outs. void closeRegion(); @@ -326,17 +350,15 @@ public: ArrayRef<unsigned> getLiveThru() const { return LiveThruPressure; } /// Get the resulting register pressure over the traversed region. - /// This result is complete if either advance() or recede() has returned true, - /// or if closeRegion() was explicitly invoked. + /// This result is complete if closeRegion() was explicitly invoked. RegisterPressure &getPressure() { return P; } const RegisterPressure &getPressure() const { return P; } /// Get the register set pressure at the current position, which may be less /// than the pressure across the traversed region. - std::vector<unsigned> &getRegSetPressureAtPos() { return CurrSetPressure; } - - void discoverLiveOut(unsigned Reg); - void discoverLiveIn(unsigned Reg); + const std::vector<unsigned> &getRegSetPressureAtPos() const { + return CurrSetPressure; + } bool isTopClosed() const; bool isBottomClosed() const; @@ -412,7 +434,12 @@ public: void dump() const; protected: - const LiveRange *getLiveRange(unsigned Reg) const; + void discoverLiveOut(unsigned Reg); + void discoverLiveIn(unsigned Reg); + + /// \brief Get the SlotIndex for the first nondebug instruction including or + /// after the current position. + SlotIndex getCurrSlot() const; void increaseRegPressure(ArrayRef<unsigned> Regs); void decreaseRegPressure(ArrayRef<unsigned> Regs); diff --git a/contrib/llvm/include/llvm/CodeGen/RegisterScavenging.h b/contrib/llvm/include/llvm/CodeGen/RegisterScavenging.h index df3fd34..122c785 100644 --- a/contrib/llvm/include/llvm/CodeGen/RegisterScavenging.h +++ b/contrib/llvm/include/llvm/CodeGen/RegisterScavenging.h @@ -74,10 +74,6 @@ public: /// Start tracking liveness from the begin of the specific basic block. void enterBasicBlock(MachineBasicBlock *mbb); - /// Allow resetting register state info for multiple - /// passes over/within the same function. - void initRegState(); - /// Move the internal MBB iterator and update register states. void forward(); @@ -104,10 +100,8 @@ public: MBBI = I; } - MachineBasicBlock::iterator getCurrentPosition() const { - return MBBI; - } - + MachineBasicBlock::iterator getCurrentPosition() const { return MBBI; } + /// Return if a specific register is currently used. bool isRegUsed(unsigned Reg, bool includeReserved = true) const; @@ -152,7 +146,7 @@ public: } /// Tell the scavenger a register is used. - void setRegUsed(unsigned Reg); + void setRegUsed(unsigned Reg, LaneBitmask LaneMask = ~0u); private: /// Returns true if a register is reserved. It is never "unused". bool isReserved(unsigned Reg) const { return MRI->isReserved(Reg); } @@ -169,10 +163,10 @@ private: /// Processes the current instruction and fill the KillRegUnits and /// DefRegUnits bit vectors. void determineKillsAndDefs(); - + /// Add all Reg Units that Reg contains to BV. void addRegUnits(BitVector &BV, unsigned Reg); - + /// Return the candidate register that is unused for the longest after /// StartMI. UseMI is set to the instruction where the search stopped. /// @@ -182,6 +176,9 @@ private: unsigned InstrLimit, MachineBasicBlock::iterator &UseMI); + /// Allow resetting register state info for multiple + /// passes over/within the same function. + void initRegState(); }; } // End llvm namespace diff --git a/contrib/llvm/include/llvm/CodeGen/RuntimeLibcalls.h b/contrib/llvm/include/llvm/CodeGen/RuntimeLibcalls.h index 2be5de6..7db0345 100644 --- a/contrib/llvm/include/llvm/CodeGen/RuntimeLibcalls.h +++ b/contrib/llvm/include/llvm/CodeGen/RuntimeLibcalls.h @@ -231,13 +231,9 @@ namespace RTLIB { FPROUND_F80_F64, FPROUND_F128_F64, FPROUND_PPCF128_F64, - FPTOSINT_F32_I8, - FPTOSINT_F32_I16, FPTOSINT_F32_I32, FPTOSINT_F32_I64, FPTOSINT_F32_I128, - FPTOSINT_F64_I8, - FPTOSINT_F64_I16, FPTOSINT_F64_I32, FPTOSINT_F64_I64, FPTOSINT_F64_I128, @@ -250,13 +246,9 @@ namespace RTLIB { FPTOSINT_PPCF128_I32, FPTOSINT_PPCF128_I64, FPTOSINT_PPCF128_I128, - FPTOUINT_F32_I8, - FPTOUINT_F32_I16, FPTOUINT_F32_I32, FPTOUINT_F32_I64, FPTOUINT_F32_I128, - FPTOUINT_F64_I8, - FPTOUINT_F64_I16, FPTOUINT_F64_I32, FPTOUINT_F64_I64, FPTOUINT_F64_I128, diff --git a/contrib/llvm/include/llvm/CodeGen/ScheduleDAG.h b/contrib/llvm/include/llvm/CodeGen/ScheduleDAG.h index 8391314..bda9dbd 100644 --- a/contrib/llvm/include/llvm/CodeGen/ScheduleDAG.h +++ b/contrib/llvm/include/llvm/CodeGen/ScheduleDAG.h @@ -20,11 +20,11 @@ #include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/Target/TargetLowering.h" namespace llvm { - class AliasAnalysis; class SUnit; class MachineConstantPool; class MachineFunction; @@ -122,18 +122,7 @@ namespace llvm { } /// Return true if the specified SDep is equivalent except for latency. - bool overlaps(const SDep &Other) const { - if (Dep != Other.Dep) return false; - switch (Dep.getInt()) { - case Data: - case Anti: - case Output: - return Contents.Reg == Other.Contents.Reg; - case Order: - return Contents.OrdKind == Other.Contents.OrdKind; - } - llvm_unreachable("Invalid dependency kind!"); - } + bool overlaps(const SDep &Other) const; bool operator==(const SDep &Other) const { return overlaps(Other) && Latency == Other.Latency; @@ -157,19 +146,13 @@ namespace llvm { } //// getSUnit - Return the SUnit to which this edge points. - SUnit *getSUnit() const { - return Dep.getPointer(); - } + SUnit *getSUnit() const; //// setSUnit - Assign the SUnit to which this edge points. - void setSUnit(SUnit *SU) { - Dep.setPointer(SU); - } + void setSUnit(SUnit *SU); /// getKind - Return an enum value representing the kind of the dependence. - Kind getKind() const { - return Dep.getInt(); - } + Kind getKind() const; /// isCtrl - Shorthand for getKind() != SDep::Data. bool isCtrl() const { @@ -374,7 +357,7 @@ namespace llvm { /// correspond to schedulable entities (e.g. instructions) and do not have a /// valid ID. Consequently, always check for boundary nodes before accessing /// an assoicative data structure keyed on node ID. - bool isBoundaryNode() const { return NodeNum == BoundaryID; }; + bool isBoundaryNode() const { return NodeNum == BoundaryID; } /// setNode - Assign the representative SDNode for this SUnit. /// This may be used during pre-regalloc scheduling. @@ -490,6 +473,30 @@ namespace llvm { void ComputeHeight(); }; + /// Return true if the specified SDep is equivalent except for latency. + inline bool SDep::overlaps(const SDep &Other) const { + if (Dep != Other.Dep) + return false; + switch (Dep.getInt()) { + case Data: + case Anti: + case Output: + return Contents.Reg == Other.Contents.Reg; + case Order: + return Contents.OrdKind == Other.Contents.OrdKind; + } + llvm_unreachable("Invalid dependency kind!"); + } + + //// getSUnit - Return the SUnit to which this edge points. + inline SUnit *SDep::getSUnit() const { return Dep.getPointer(); } + + //// setSUnit - Assign the SUnit to which this edge points. + inline void SDep::setSUnit(SUnit *SU) { Dep.setPointer(SU); } + + /// getKind - Return an enum value representing the kind of the dependence. + inline SDep::Kind SDep::getKind() const { return Dep.getInt(); } + //===--------------------------------------------------------------------===// /// SchedulingPriorityQueue - This interface is used to plug different /// priorities computation algorithms into the list scheduler. It implements diff --git a/contrib/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h b/contrib/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h index b56d5ec..c574df0 100644 --- a/contrib/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h +++ b/contrib/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h @@ -26,22 +26,32 @@ namespace llvm { class MachineFrameInfo; class MachineLoopInfo; class MachineDominatorTree; - class LiveIntervals; class RegPressureTracker; class PressureDiffs; /// An individual mapping from virtual register number to SUnit. struct VReg2SUnit { unsigned VirtReg; + LaneBitmask LaneMask; SUnit *SU; - VReg2SUnit(unsigned reg, SUnit *su): VirtReg(reg), SU(su) {} + VReg2SUnit(unsigned VReg, LaneBitmask LaneMask, SUnit *SU) + : VirtReg(VReg), LaneMask(LaneMask), SU(SU) {} unsigned getSparseSetIndex() const { return TargetRegisterInfo::virtReg2Index(VirtReg); } }; + /// Mapping from virtual register to SUnit including an operand index. + struct VReg2SUnitOperIdx : public VReg2SUnit { + unsigned OperandIndex; + + VReg2SUnitOperIdx(unsigned VReg, LaneBitmask LaneMask, + unsigned OperandIndex, SUnit *SU) + : VReg2SUnit(VReg, LaneMask, SU), OperandIndex(OperandIndex) {} + }; + /// Record a physical register access. /// For non-data-dependent uses, OpIdx == -1. struct PhysRegSUOper { @@ -69,7 +79,10 @@ namespace llvm { /// Track local uses of virtual registers. These uses are gathered by the DAG /// builder and may be consulted by the scheduler to avoid iterating an entire /// vreg use list. - typedef SparseMultiSet<VReg2SUnit, VirtReg2IndexFunctor> VReg2UseMap; + typedef SparseMultiSet<VReg2SUnit, VirtReg2IndexFunctor> VReg2SUnitMultiMap; + + typedef SparseMultiSet<VReg2SUnitOperIdx, VirtReg2IndexFunctor> + VReg2SUnitOperIdxMultiMap; /// ScheduleDAGInstrs - A ScheduleDAG subclass for scheduling lists of /// MachineInstrs. @@ -78,15 +91,9 @@ namespace llvm { const MachineLoopInfo *MLI; const MachineFrameInfo *MFI; - /// Live Intervals provides reaching defs in preRA scheduling. - LiveIntervals *LIS; - /// TargetSchedModel provides an interface to the machine model. TargetSchedModel SchedModel; - /// isPostRA flag indicates vregs cannot be present. - bool IsPostRA; - /// True if the DAG builder should remove kill flags (in preparation for /// rescheduling). bool RemoveKillFlags; @@ -98,6 +105,9 @@ namespace llvm { /// it has taken responsibility for scheduling the terminator correctly. bool CanHandleTerminators; + /// Whether lane masks should get tracked. + bool TrackLaneMasks; + /// State specific to the current scheduling region. /// ------------------------------------------------ @@ -120,7 +130,7 @@ namespace llvm { /// After calling BuildSchedGraph, each vreg used in the scheduling region /// is mapped to a set of SUnits. These include all local vreg uses, not /// just the uses for a singly defined vreg. - VReg2UseMap VRegUses; + VReg2SUnitMultiMap VRegUses; /// State internal to DAG building. /// ------------------------------- @@ -132,8 +142,12 @@ namespace llvm { Reg2SUnitsMap Defs; Reg2SUnitsMap Uses; - /// Track the last instruction in this region defining each virtual register. - VReg2SUnitMap VRegDefs; + /// Tracks the last instruction(s) in this region defining each virtual + /// register. There may be multiple current definitions for a register with + /// disjunct lanemasks. + VReg2SUnitMultiMap CurrentVRegDefs; + /// Tracks the last instructions in this region using each virtual register. + VReg2SUnitOperIdxMultiMap CurrentVRegUses; /// PendingLoads - Remember where unknown loads are after the most recent /// unknown store, as we iterate. As with Defs and Uses, this is here @@ -154,17 +168,10 @@ namespace llvm { public: explicit ScheduleDAGInstrs(MachineFunction &mf, const MachineLoopInfo *mli, - bool IsPostRAFlag, - bool RemoveKillFlags = false, - LiveIntervals *LIS = nullptr); + bool RemoveKillFlags = false); ~ScheduleDAGInstrs() override {} - bool isPostRA() const { return IsPostRA; } - - /// \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; } @@ -206,7 +213,8 @@ namespace llvm { /// input. void buildSchedGraph(AliasAnalysis *AA, RegPressureTracker *RPTracker = nullptr, - PressureDiffs *PDiffs = nullptr); + PressureDiffs *PDiffs = nullptr, + bool TrackLaneMasks = false); /// addSchedBarrierDeps - Add dependencies from instructions in the current /// list of instructions being scheduled to scheduling barrier. We want to @@ -253,6 +261,12 @@ namespace llvm { /// Other adjustments may be made to the instruction if necessary. Return /// true if the operand has been deleted, false if not. bool toggleKillFlag(MachineInstr *MI, MachineOperand &MO); + + /// Returns a mask for which lanes get read/written by the given (register) + /// machine operand. + LaneBitmask getLaneMaskForMO(const MachineOperand &MO) const; + + void collectVRegUses(SUnit *SU); }; /// newSUnit - Creates a new SUnit and return a ptr to it. diff --git a/contrib/llvm/include/llvm/CodeGen/SchedulerRegistry.h b/contrib/llvm/include/llvm/CodeGen/SchedulerRegistry.h index 51ac7f2..a7a6227 100644 --- a/contrib/llvm/include/llvm/CodeGen/SchedulerRegistry.h +++ b/contrib/llvm/include/llvm/CodeGen/SchedulerRegistry.h @@ -52,12 +52,6 @@ public: static RegisterScheduler *getList() { return (RegisterScheduler *)Registry.getList(); } - static FunctionPassCtor getDefault() { - return (FunctionPassCtor)Registry.getDefault(); - } - static void setDefault(FunctionPassCtor C) { - Registry.setDefault((MachinePassCtor)C); - } static void setListener(MachinePassRegistryListener *L) { Registry.setListener(L); } diff --git a/contrib/llvm/include/llvm/CodeGen/SelectionDAG.h b/contrib/llvm/include/llvm/CodeGen/SelectionDAG.h index 1ee9238..a21e9ae 100644 --- a/contrib/llvm/include/llvm/CodeGen/SelectionDAG.h +++ b/contrib/llvm/include/llvm/CodeGen/SelectionDAG.h @@ -19,6 +19,7 @@ #include "llvm/ADT/SetVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/ilist.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/CodeGen/DAGCombine.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/SelectionDAGNodes.h" @@ -31,7 +32,6 @@ namespace llvm { -class AliasAnalysis; class MachineConstantPoolValue; class MachineFunction; class MDNode; @@ -215,6 +215,8 @@ class SelectionDAG { /// Tracks dbg_value information through SDISel. SDDbgInfo *DbgInfo; + uint16_t NextPersistentId = 0; + public: /// Clients of various APIs that cause global effects on /// the DAG can optionally implement this interface. This allows the clients @@ -324,11 +326,10 @@ public: } iterator_range<allnodes_iterator> allnodes() { - return iterator_range<allnodes_iterator>(allnodes_begin(), allnodes_end()); + return make_range(allnodes_begin(), allnodes_end()); } iterator_range<allnodes_const_iterator> allnodes() const { - return iterator_range<allnodes_const_iterator>(allnodes_begin(), - allnodes_end()); + return make_range(allnodes_begin(), allnodes_end()); } /// Return the root tag of the SelectionDAG. @@ -532,7 +533,7 @@ public: SDVTList VTs = getVTList(MVT::Other, MVT::Glue); SDValue Ops[] = { Chain, getRegister(Reg, N.getValueType()), N, Glue }; return getNode(ISD::CopyToReg, dl, VTs, - ArrayRef<SDValue>(Ops, Glue.getNode() ? 4 : 3)); + makeArrayRef(Ops, Glue.getNode() ? 4 : 3)); } // Similar to last getCopyToReg() except parameter Reg is a SDValue @@ -541,7 +542,7 @@ public: SDVTList VTs = getVTList(MVT::Other, MVT::Glue); SDValue Ops[] = { Chain, Reg, N, Glue }; return getNode(ISD::CopyToReg, dl, VTs, - ArrayRef<SDValue>(Ops, Glue.getNode() ? 4 : 3)); + makeArrayRef(Ops, Glue.getNode() ? 4 : 3)); } SDValue getCopyFromReg(SDValue Chain, SDLoc dl, unsigned Reg, EVT VT) { @@ -558,7 +559,7 @@ public: SDVTList VTs = getVTList(VT, MVT::Other, MVT::Glue); SDValue Ops[] = { Chain, getRegister(Reg, VT), Glue }; return getNode(ISD::CopyFromReg, dl, VTs, - ArrayRef<SDValue>(Ops, Glue.getNode() ? 3 : 2)); + makeArrayRef(Ops, Glue.getNode() ? 3 : 2)); } SDValue getCondCode(ISD::CondCode Cond); @@ -670,7 +671,7 @@ public: SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT, ArrayRef<SDUse> Ops); SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT, - ArrayRef<SDValue> Ops); + ArrayRef<SDValue> Ops, const SDNodeFlags *Flags = nullptr); SDValue getNode(unsigned Opcode, SDLoc DL, ArrayRef<EVT> ResultTys, ArrayRef<SDValue> Ops); SDValue getNode(unsigned Opcode, SDLoc DL, SDVTList VTs, @@ -687,7 +688,7 @@ public: SDValue N3, SDValue N4); SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT, SDValue N1, SDValue N2, SDValue N3, SDValue N4, SDValue N5); - + // Specialize again based on number of operands for nodes with a VTList // rather than a single VT. SDValue getNode(unsigned Opcode, SDLoc DL, SDVTList VTs); @@ -901,6 +902,12 @@ public: /// the target's desired shift amount type. SDValue getShiftAmountOperand(EVT LHSTy, SDValue Op); + /// Expand the specified \c ISD::VAARG node as the Legalize pass would. + SDValue expandVAArg(SDNode *Node); + + /// Expand the specified \c ISD::VACOPY node as the Legalize pass would. + SDValue expandVACopy(SDNode *Node); + /// *Mutate* the specified node in-place to have the /// specified operands. If the resultant node already exists in the DAG, /// this does not modify the specified node, instead it returns the node that @@ -1072,6 +1079,10 @@ public: // target info. switch (Opcode) { case ISD::ADD: + case ISD::SMIN: + case ISD::SMAX: + case ISD::UMIN: + case ISD::UMAX: case ISD::MUL: case ISD::MULHU: case ISD::MULHS: @@ -1088,6 +1099,8 @@ public: case ISD::ADDE: case ISD::FMINNUM: case ISD::FMAXNUM: + case ISD::FMINNAN: + case ISD::FMAXNAN: return true; default: return false; } @@ -1150,6 +1163,10 @@ public: const ConstantSDNode *Cst1, const ConstantSDNode *Cst2); + SDValue FoldConstantVectorArithmetic(unsigned Opcode, SDLoc DL, + EVT VT, ArrayRef<SDValue> Ops, + const SDNodeFlags *Flags = nullptr); + /// Constant fold a setcc to true or false. SDValue FoldSetCC(EVT VT, SDValue N1, SDValue N2, ISD::CondCode Cond, SDLoc dl); @@ -1199,6 +1216,10 @@ public: /// other positive zero. bool isEqualTo(SDValue A, SDValue B) const; + /// Return true if A and B have no common bits set. As an example, this can + /// allow an 'add' to be transformed into an 'or'. + bool haveNoCommonBitsSet(SDValue A, SDValue B) const; + /// Utility function used by legalize and lowering to /// "unroll" a vector operation by splitting out the scalars and operating /// on each element individually. If the ResNE is 0, fully unroll the vector diff --git a/contrib/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/contrib/llvm/include/llvm/CodeGen/SelectionDAGNodes.h index 4821d1a..23816bd 100644 --- a/contrib/llvm/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/contrib/llvm/include/llvm/CodeGen/SelectionDAGNodes.h @@ -44,6 +44,7 @@ class GlobalValue; class MachineBasicBlock; class MachineConstantPoolValue; class SDNode; +class BinaryWithFlagsSDNode; class Value; class MCSymbol; template <typename T> struct DenseMapInfo; @@ -81,11 +82,6 @@ namespace ISD { /// all ConstantFPSDNode or undef. bool isBuildVectorOfConstantFPSDNodes(const SDNode *N); - /// Return true if the specified node is a - /// ISD::SCALAR_TO_VECTOR node or a BUILD_VECTOR node where only the low - /// element is not an undef. - bool isScalarToVector(const SDNode *N); - /// Return true if the node has at least one operand /// and all operands of the specified node are ISD::UNDEF. bool allOperandsUndef(const SDNode *N); @@ -139,7 +135,7 @@ public: return SDValue(Node, R); } - // Return true if this node is an operand of N. + /// Return true if this node is an operand of N. bool isOperandOf(const SDNode *N) const; /// Return the ValueType of the referenced return value. @@ -167,6 +163,7 @@ public: inline bool isTargetMemoryOpcode() const; inline bool isTargetOpcode() const; inline bool isMachineOpcode() const; + inline bool isUndef() const; inline unsigned getMachineOpcode() const; inline const DebugLoc &getDebugLoc() const; inline void dump() const; @@ -318,6 +315,61 @@ template<> struct simplify_type<SDUse> { } }; +/// These are IR-level optimization flags that may be propagated to SDNodes. +/// TODO: This data structure should be shared by the IR optimizer and the +/// the backend. +struct SDNodeFlags { +private: + bool NoUnsignedWrap : 1; + bool NoSignedWrap : 1; + bool Exact : 1; + bool UnsafeAlgebra : 1; + bool NoNaNs : 1; + bool NoInfs : 1; + bool NoSignedZeros : 1; + bool AllowReciprocal : 1; + +public: + /// Default constructor turns off all optimization flags. + SDNodeFlags() { + NoUnsignedWrap = false; + NoSignedWrap = false; + Exact = false; + UnsafeAlgebra = false; + NoNaNs = false; + NoInfs = false; + NoSignedZeros = false; + AllowReciprocal = false; + } + + // These are mutators for each flag. + void setNoUnsignedWrap(bool b) { NoUnsignedWrap = b; } + void setNoSignedWrap(bool b) { NoSignedWrap = b; } + void setExact(bool b) { Exact = b; } + void setUnsafeAlgebra(bool b) { UnsafeAlgebra = b; } + void setNoNaNs(bool b) { NoNaNs = b; } + void setNoInfs(bool b) { NoInfs = b; } + void setNoSignedZeros(bool b) { NoSignedZeros = b; } + void setAllowReciprocal(bool b) { AllowReciprocal = b; } + + // These are accessors for each flag. + bool hasNoUnsignedWrap() const { return NoUnsignedWrap; } + bool hasNoSignedWrap() const { return NoSignedWrap; } + bool hasExact() const { return Exact; } + bool hasUnsafeAlgebra() const { return UnsafeAlgebra; } + bool hasNoNaNs() const { return NoNaNs; } + bool hasNoInfs() const { return NoInfs; } + bool hasNoSignedZeros() const { return NoSignedZeros; } + bool hasAllowReciprocal() const { return AllowReciprocal; } + + /// Return a raw encoding of the flags. + /// This function should only be used to add data to the NodeID value. + unsigned getRawFlags() const { + return (NoUnsignedWrap << 0) | (NoSignedWrap << 1) | (Exact << 2) | + (UnsafeAlgebra << 3) | (NoNaNs << 4) | (NoInfs << 5) | + (NoSignedZeros << 6) | (AllowReciprocal << 7); + } +}; /// Represents one node in the SelectionDAG. /// @@ -374,6 +426,10 @@ private: friend struct ilist_traits<SDNode>; public: + /// Unique and persistent id per SDNode in the DAG. + /// Used for debug printing. + uint16_t PersistentId; + //===--------------------------------------------------------------------===// // Accessors // @@ -395,6 +451,9 @@ public: return NodeType >= ISD::FIRST_TARGET_MEMORY_OPCODE; } + /// Return true if the type of the node type undefined. + bool isUndef() const { return NodeType == ISD::UNDEF; } + /// Test if this node is a memory intrinsic (with valid pointer information). /// INTRINSIC_W_CHAIN and INTRINSIC_VOID nodes are sometimes created for /// non-memory intrinsics (with chains) that are not really instances of @@ -517,10 +576,10 @@ public: static use_iterator use_end() { return use_iterator(nullptr); } inline iterator_range<use_iterator> uses() { - return iterator_range<use_iterator>(use_begin(), use_end()); + return make_range(use_begin(), use_end()); } inline iterator_range<use_iterator> uses() const { - return iterator_range<use_iterator>(use_begin(), use_end()); + return make_range(use_begin(), use_end()); } /// Return true if there are exactly NUSES uses of the indicated value. @@ -592,8 +651,8 @@ public: }; iterator_range<value_op_iterator> op_values() const { - return iterator_range<value_op_iterator>(value_op_iterator(op_begin()), - value_op_iterator(op_end())); + return make_range(value_op_iterator(op_begin()), + value_op_iterator(op_end())); } SDVTList getVTList() const { @@ -605,27 +664,11 @@ public: /// to which the glue operand points. Otherwise return NULL. SDNode *getGluedNode() const { if (getNumOperands() != 0 && - getOperand(getNumOperands()-1).getValueType() == MVT::Glue) + getOperand(getNumOperands()-1).getValueType() == MVT::Glue) return getOperand(getNumOperands()-1).getNode(); return nullptr; } - // If this is a pseudo op, like copyfromreg, look to see if there is a - // real target node glued to it. If so, return the target node. - const SDNode *getGluedMachineNode() const { - const SDNode *FoundNode = this; - - // Climb up glue edges until a machine-opcode node is found, or the - // end of the chain is reached. - while (!FoundNode->isMachineOpcode()) { - const SDNode *N = FoundNode->getGluedNode(); - if (!N) break; - FoundNode = N; - } - - return FoundNode; - } - /// If this node has a glue value with a user, return /// the user (there is at most one). Otherwise return NULL. SDNode *getGluedUser() const { @@ -635,6 +678,10 @@ public: return nullptr; } + /// This could be defined as a virtual function and implemented more simply + /// and directly, but it is not to avoid creating a vtable for this class. + const SDNodeFlags *getFlags() const; + /// Return the number of values defined/returned by this operator. unsigned getNumValues() const { return NumValues; } @@ -909,6 +956,9 @@ inline bool SDValue::isMachineOpcode() const { inline unsigned SDValue::getMachineOpcode() const { return Node->getMachineOpcode(); } +inline bool SDValue::isUndef() const { + return Node->isUndef(); +} inline bool SDValue::use_empty() const { return !Node->hasAnyUseOfValue(ResNo); } @@ -943,62 +993,6 @@ inline void SDUse::setNode(SDNode *N) { if (N) N->addUse(*this); } -/// These are IR-level optimization flags that may be propagated to SDNodes. -/// TODO: This data structure should be shared by the IR optimizer and the -/// the backend. -struct SDNodeFlags { -private: - bool NoUnsignedWrap : 1; - bool NoSignedWrap : 1; - bool Exact : 1; - bool UnsafeAlgebra : 1; - bool NoNaNs : 1; - bool NoInfs : 1; - bool NoSignedZeros : 1; - bool AllowReciprocal : 1; - -public: - /// Default constructor turns off all optimization flags. - SDNodeFlags() { - NoUnsignedWrap = false; - NoSignedWrap = false; - Exact = false; - UnsafeAlgebra = false; - NoNaNs = false; - NoInfs = false; - NoSignedZeros = false; - AllowReciprocal = false; - } - - // These are mutators for each flag. - void setNoUnsignedWrap(bool b) { NoUnsignedWrap = b; } - void setNoSignedWrap(bool b) { NoSignedWrap = b; } - void setExact(bool b) { Exact = b; } - void setUnsafeAlgebra(bool b) { UnsafeAlgebra = b; } - void setNoNaNs(bool b) { NoNaNs = b; } - void setNoInfs(bool b) { NoInfs = b; } - void setNoSignedZeros(bool b) { NoSignedZeros = b; } - void setAllowReciprocal(bool b) { AllowReciprocal = b; } - - // These are accessors for each flag. - bool hasNoUnsignedWrap() const { return NoUnsignedWrap; } - bool hasNoSignedWrap() const { return NoSignedWrap; } - bool hasExact() const { return Exact; } - bool hasUnsafeAlgebra() const { return UnsafeAlgebra; } - bool hasNoNaNs() const { return NoNaNs; } - bool hasNoInfs() const { return NoInfs; } - bool hasNoSignedZeros() const { return NoSignedZeros; } - bool hasAllowReciprocal() const { return AllowReciprocal; } - - /// Return a raw encoding of the flags. - /// This function should only be used to add data to the NodeID value. - unsigned getRawFlags() const { - return (NoUnsignedWrap << 0) | (NoSignedWrap << 1) | (Exact << 2) | - (UnsafeAlgebra << 3) | (NoNaNs << 4) | (NoInfs << 5) | - (NoSignedZeros << 6) | (AllowReciprocal << 7); - } -}; - /// This class is used for single-operand SDNodes. This is solely /// to allow co-allocation of node operands with the node itself. class UnarySDNode : public SDNode { @@ -1080,6 +1074,9 @@ class HandleSDNode : public SDNode { public: explicit HandleSDNode(SDValue X) : SDNode(ISD::HANDLENODE, 0, DebugLoc(), getSDVTList(MVT::Other)) { + // HandleSDNodes are never inserted into the DAG, so they won't be + // auto-numbered. Use ID 65535 as a sentinel. + PersistentId = 0xffff; InitOperands(&Op, X); } ~HandleSDNode(); @@ -1497,6 +1494,15 @@ public: } }; +/// Returns true if \p V is a constant integer zero. +bool isNullConstant(SDValue V); +/// Returns true if \p V is an FP constant with a value of positive zero. +bool isNullFPConstant(SDValue V); +/// Returns true if \p V is an integer constant with all bits set. +bool isAllOnesConstant(SDValue V); +/// Returns true if \p V is a constant integer one. +bool isOneConstant(SDValue V); + class GlobalAddressSDNode : public SDNode { const GlobalValue *TheGlobal; int64_t Offset; @@ -1697,6 +1703,14 @@ public: ConstantFPSDNode * getConstantFPSplatNode(BitVector *UndefElements = nullptr) const; + /// \brief If this is a constant FP splat and the splatted constant FP is an + /// exact power or 2, return the log base 2 integer value. Otherwise, + /// return -1. + /// + /// The BitWidth specifies the necessary bit precision. + int32_t getConstantFPSplatPow2ToLog2Int(BitVector *UndefElements, + uint32_t BitWidth) const; + bool isConstant() const; static inline bool classof(const SDNode *N) { @@ -2003,9 +2017,9 @@ class MaskedLoadStoreSDNode : public MemSDNode { public: friend class SelectionDAG; MaskedLoadStoreSDNode(ISD::NodeType NodeTy, unsigned Order, DebugLoc dl, - SDValue *Operands, unsigned numOperands, - SDVTList VTs, EVT MemVT, MachineMemOperand *MMO) - : MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) { + SDValue *Operands, unsigned numOperands, SDVTList VTs, + EVT MemVT, MachineMemOperand *MMO) + : MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) { InitOperands(Ops, Operands, numOperands); } @@ -2036,7 +2050,7 @@ public: ISD::LoadExtType getExtensionType() const { return ISD::LoadExtType(SubclassData & 3); - } + } const SDValue &getSrc0() const { return getOperand(3); } static bool classof(const SDNode *N) { return N->getOpcode() == ISD::MLOAD; @@ -2103,17 +2117,18 @@ public: class MaskedGatherSDNode : public MaskedGatherScatterSDNode { public: friend class SelectionDAG; - MaskedGatherSDNode(unsigned Order, DebugLoc dl, ArrayRef<SDValue> Operands, + MaskedGatherSDNode(unsigned Order, DebugLoc dl, ArrayRef<SDValue> Operands, SDVTList VTs, EVT MemVT, MachineMemOperand *MMO) : MaskedGatherScatterSDNode(ISD::MGATHER, Order, dl, Operands, VTs, MemVT, MMO) { assert(getValue().getValueType() == getValueType(0) && - "Incompatible type of the PathThru value in MaskedGatherSDNode"); - assert(getMask().getValueType().getVectorNumElements() == - getValueType(0).getVectorNumElements() && - "Vector width mismatch between mask and data"); - assert(getMask().getValueType().getScalarType() == MVT::i1 && + "Incompatible type of the PassThru value in MaskedGatherSDNode"); + assert(getMask().getValueType().getVectorNumElements() == + getValueType(0).getVectorNumElements() && "Vector width mismatch between mask and data"); + assert(getIndex().getValueType().getVectorNumElements() == + getValueType(0).getVectorNumElements() && + "Vector width mismatch between index and data"); } static bool classof(const SDNode *N) { @@ -2131,11 +2146,12 @@ public: SDVTList VTs, EVT MemVT, MachineMemOperand *MMO) : MaskedGatherScatterSDNode(ISD::MSCATTER, Order, dl, Operands, VTs, MemVT, MMO) { - assert(getMask().getValueType().getVectorNumElements() == - getValue().getValueType().getVectorNumElements() && - "Vector width mismatch between mask and data"); - assert(getMask().getValueType().getScalarType() == MVT::i1 && + assert(getMask().getValueType().getVectorNumElements() == + getValue().getValueType().getVectorNumElements() && "Vector width mismatch between mask and data"); + assert(getIndex().getValueType().getVectorNumElements() == + getValue().getValueType().getVectorNumElements() && + "Vector width mismatch between index and data"); } static bool classof(const SDNode *N) { diff --git a/contrib/llvm/include/llvm/CodeGen/SlotIndexes.h b/contrib/llvm/include/llvm/CodeGen/SlotIndexes.h index 9d6d6f5..7b621be 100644 --- a/contrib/llvm/include/llvm/CodeGen/SlotIndexes.h +++ b/contrib/llvm/include/llvm/CodeGen/SlotIndexes.h @@ -155,7 +155,7 @@ namespace llvm { "Attempt to construct index with 0 pointer."); } - /// Returns true if this is a valid index. Invalid indicies do + /// Returns true if this is a valid index. Invalid indices do /// not point into an index table, and cannot be compared. bool isValid() const { return lie.getPointer(); @@ -272,7 +272,7 @@ namespace llvm { SlotIndex getNextSlot() const { Slot s = getSlot(); if (s == Slot_Dead) { - return SlotIndex(listEntry()->getNextNode(), Slot_Block); + return SlotIndex(&*++listEntry()->getIterator(), Slot_Block); } return SlotIndex(listEntry(), s + 1); } @@ -280,7 +280,7 @@ namespace llvm { /// Returns the next index. This is the index corresponding to the this /// index's slot, but for the next instruction. SlotIndex getNextIndex() const { - return SlotIndex(listEntry()->getNextNode(), getSlot()); + return SlotIndex(&*++listEntry()->getIterator(), getSlot()); } /// Returns the previous slot in the index list. This could be either the @@ -292,7 +292,7 @@ namespace llvm { SlotIndex getPrevSlot() const { Slot s = getSlot(); if (s == Slot_Block) { - return SlotIndex(listEntry()->getPrevNode(), Slot_Dead); + return SlotIndex(&*--listEntry()->getIterator(), Slot_Dead); } return SlotIndex(listEntry(), s - 1); } @@ -300,7 +300,7 @@ namespace llvm { /// Returns the previous index. This is the index corresponding to this /// index's slot, but for the previous instruction. SlotIndex getPrevIndex() const { - return SlotIndex(listEntry()->getPrevNode(), getSlot()); + return SlotIndex(&*--listEntry()->getIterator(), getSlot()); } }; @@ -333,6 +333,8 @@ namespace llvm { /// This pass assigns indexes to each instruction. class SlotIndexes : public MachineFunctionPass { private: + // IndexListEntry allocator. + BumpPtrAllocator ileAllocator; typedef ilist<IndexListEntry> IndexList; IndexList indexList; @@ -353,9 +355,6 @@ namespace llvm { /// and MBB id. SmallVector<IdxMBBPair, 8> idx2MBBMap; - // IndexListEntry allocator. - BumpPtrAllocator ileAllocator; - IndexListEntry* createEntry(MachineInstr *mi, unsigned index) { IndexListEntry *entry = static_cast<IndexListEntry*>( @@ -377,6 +376,11 @@ namespace llvm { initializeSlotIndexesPass(*PassRegistry::getPassRegistry()); } + ~SlotIndexes() { + // The indexList's nodes are all allocated in the BumpPtrAllocator. + indexList.clearAndLeakNodesUnsafely(); + } + void getAnalysisUsage(AnalysisUsage &au) const override; void releaseMemory() override; @@ -427,11 +431,11 @@ namespace llvm { /// Returns the next non-null index, if one exists. /// Otherwise returns getLastIndex(). SlotIndex getNextNonNullIndex(SlotIndex Index) { - IndexList::iterator I = Index.listEntry(); + IndexList::iterator I = Index.listEntry()->getIterator(); IndexList::iterator E = indexList.end(); while (++I != E) if (I->getInstr()) - return SlotIndex(I, Index.getSlot()); + return SlotIndex(&*I, Index.getSlot()); // We reached the end of the function. return getLastIndex(); } @@ -502,49 +506,52 @@ namespace llvm { return getMBBRange(mbb).second; } + /// Iterator over the idx2MBBMap (sorted pairs of slot index of basic block + /// begin and basic block) + typedef SmallVectorImpl<IdxMBBPair>::const_iterator MBBIndexIterator; + /// Move iterator to the next IdxMBBPair where the SlotIndex is greater or + /// equal to \p To. + MBBIndexIterator advanceMBBIndex(MBBIndexIterator I, SlotIndex To) const { + return std::lower_bound(I, idx2MBBMap.end(), To); + } + /// Get an iterator pointing to the IdxMBBPair with the biggest SlotIndex + /// that is greater or equal to \p Idx. + MBBIndexIterator findMBBIndex(SlotIndex Idx) const { + return advanceMBBIndex(idx2MBBMap.begin(), Idx); + } + /// Returns an iterator for the begin of the idx2MBBMap. + MBBIndexIterator MBBIndexBegin() const { + return idx2MBBMap.begin(); + } + /// Return an iterator for the end of the idx2MBBMap. + MBBIndexIterator MBBIndexEnd() const { + return idx2MBBMap.end(); + } + /// Returns the basic block which the given index falls in. MachineBasicBlock* getMBBFromIndex(SlotIndex index) const { if (MachineInstr *MI = getInstructionFromIndex(index)) return MI->getParent(); - SmallVectorImpl<IdxMBBPair>::const_iterator I = - std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), index); + + MBBIndexIterator I = findMBBIndex(index); // Take the pair containing the index - SmallVectorImpl<IdxMBBPair>::const_iterator J = - ((I != idx2MBBMap.end() && I->first > index) || - (I == idx2MBBMap.end() && idx2MBBMap.size()>0)) ? (I-1): I; + MBBIndexIterator J = + ((I != MBBIndexEnd() && I->first > index) || + (I == MBBIndexEnd() && !idx2MBBMap.empty())) ? std::prev(I) : I; - assert(J != idx2MBBMap.end() && J->first <= index && + assert(J != MBBIndexEnd() && J->first <= index && index < getMBBEndIdx(J->second) && "index does not correspond to an MBB"); return J->second; } - bool findLiveInMBBs(SlotIndex start, SlotIndex end, - SmallVectorImpl<MachineBasicBlock*> &mbbs) const { - SmallVectorImpl<IdxMBBPair>::const_iterator itr = - std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), start); - bool resVal = false; - - while (itr != idx2MBBMap.end()) { - if (itr->first >= end) - break; - mbbs.push_back(itr->second); - resVal = true; - ++itr; - } - return resVal; - } - /// Returns the MBB covering the given range, or null if the range covers /// more than one basic block. MachineBasicBlock* getMBBCoveringRange(SlotIndex start, SlotIndex end) const { assert(start < end && "Backwards ranges not allowed."); - - SmallVectorImpl<IdxMBBPair>::const_iterator itr = - std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), start); - - if (itr == idx2MBBMap.end()) { + MBBIndexIterator itr = findMBBIndex(start); + if (itr == MBBIndexEnd()) { itr = std::prev(itr); return itr->second; } @@ -580,11 +587,11 @@ namespace llvm { IndexList::iterator prevItr, nextItr; if (Late) { // Insert mi's index immediately before the following instruction. - nextItr = getIndexAfter(mi).listEntry(); + nextItr = getIndexAfter(mi).listEntry()->getIterator(); prevItr = std::prev(nextItr); } else { // Insert mi's index immediately after the preceding instruction. - prevItr = getIndexBefore(mi).listEntry(); + prevItr = getIndexBefore(mi).listEntry()->getIterator(); nextItr = std::next(prevItr); } @@ -646,11 +653,11 @@ namespace llvm { if (nextMBB == mbb->getParent()->end()) { startEntry = &indexList.back(); endEntry = createEntry(nullptr, 0); - newItr = indexList.insertAfter(startEntry, endEntry); + newItr = indexList.insertAfter(startEntry->getIterator(), endEntry); } else { startEntry = createEntry(nullptr, 0); - endEntry = getMBBStartIdx(nextMBB).listEntry(); - newItr = indexList.insert(endEntry, startEntry); + endEntry = getMBBStartIdx(&*nextMBB).listEntry(); + newItr = indexList.insert(endEntry->getIterator(), startEntry); } SlotIndex startIdx(startEntry, SlotIndex::Slot_Block); diff --git a/contrib/llvm/include/llvm/CodeGen/StackMaps.h b/contrib/llvm/include/llvm/CodeGen/StackMaps.h index fdc1a91..972a616 100644 --- a/contrib/llvm/include/llvm/CodeGen/StackMaps.h +++ b/contrib/llvm/include/llvm/CodeGen/StackMaps.h @@ -13,6 +13,7 @@ #include "llvm/ADT/MapVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/MachineInstr.h" +#include "llvm/MC/MCSymbol.h" #include "llvm/Support/Debug.h" #include <map> #include <vector> diff --git a/contrib/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/contrib/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index 10c099d..2f13791 100644 --- a/contrib/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/contrib/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -41,12 +41,12 @@ public: ~TargetLoweringObjectFileELF() override {} - void emitPersonalityValue(MCStreamer &Streamer, const TargetMachine &TM, + void emitPersonalityValue(MCStreamer &Streamer, const DataLayout &TM, const MCSymbol *Sym) const override; /// Given a constant with the SectionKind, return a section that it should be /// placed in. - MCSection *getSectionForConstant(SectionKind Kind, + MCSection *getSectionForConstant(const DataLayout &DL, SectionKind Kind, const Constant *C) const override; MCSection *getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, @@ -103,7 +103,7 @@ public: Mangler &Mang, const TargetMachine &TM) const override; - MCSection *getSectionForConstant(SectionKind Kind, + MCSection *getSectionForConstant(const DataLayout &DL, SectionKind Kind, const Constant *C) const override; /// The mach-o version of this method defaults to returning a stub reference. @@ -123,6 +123,9 @@ public: const MCValue &MV, int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const override; + + void getNameWithPrefix(SmallVectorImpl<char> &OutName, const GlobalValue *GV, + Mangler &Mang, const TargetMachine &TM) const override; }; @@ -140,8 +143,7 @@ public: const TargetMachine &TM) const override; void getNameWithPrefix(SmallVectorImpl<char> &OutName, const GlobalValue *GV, - bool CannotUsePrivateLabel, Mangler &Mang, - const TargetMachine &TM) const override; + Mangler &Mang, const TargetMachine &TM) const override; MCSection *getSectionForJumpTable(const Function &F, Mangler &Mang, const TargetMachine &TM) const override; diff --git a/contrib/llvm/include/llvm/CodeGen/TargetSchedule.h b/contrib/llvm/include/llvm/CodeGen/TargetSchedule.h index 751fac4..81054ab 100644 --- a/contrib/llvm/include/llvm/CodeGen/TargetSchedule.h +++ b/contrib/llvm/include/llvm/CodeGen/TargetSchedule.h @@ -81,6 +81,12 @@ public: return nullptr; } + /// \brief Return true if this machine model includes an instruction-level + /// scheduling model or cycle-to-cycle itinerary data. + bool hasInstrSchedModelOrItineraries() const { + return hasInstrSchedModel() || hasInstrItineraries(); + } + /// \brief Identify the processor corresponding to the current subtarget. unsigned getProcessorID() const { return SchedModel.getProcessorID(); } diff --git a/contrib/llvm/include/llvm/CodeGen/ValueTypes.h b/contrib/llvm/include/llvm/CodeGen/ValueTypes.h index e1a9fd3..929eb88 100644 --- a/contrib/llvm/include/llvm/CodeGen/ValueTypes.h +++ b/contrib/llvm/include/llvm/CodeGen/ValueTypes.h @@ -89,6 +89,19 @@ namespace llvm { return VecTy; } + /// Return the type converted to an equivalently sized integer or vector + /// with integer element type. Similar to changeVectorElementTypeToInteger, + /// but also handles scalars. + EVT changeTypeToInteger() { + if (isVector()) + return changeVectorElementTypeToInteger(); + + if (isSimple()) + return MVT::getIntegerVT(getSizeInBits()); + + return changeExtendedTypeToInteger(); + } + /// isSimple - Test if the given EVT is simple (as opposed to being /// extended). bool isSimple() const { @@ -151,6 +164,11 @@ namespace llvm { return isSimple() ? V.is1024BitVector() : isExtended1024BitVector(); } + /// is2048BitVector - Return true if this is a 2048-bit vector type. + bool is2048BitVector() const { + return isSimple() ? V.is2048BitVector() : isExtended2048BitVector(); + } + /// isOverloaded - Return true if this is an overloaded type for TableGen. bool isOverloaded() const { return (V==MVT::iAny || V==MVT::fAny || V==MVT::vAny || V==MVT::iPTRAny); @@ -342,6 +360,7 @@ namespace llvm { // Methods for handling the Extended-type case in functions above. // These are all out-of-line to prevent users of this header file // from having a dependency on Type.h. + EVT changeExtendedTypeToInteger() const; EVT changeExtendedVectorElementTypeToInteger() const; static EVT getExtendedIntegerVT(LLVMContext &C, unsigned BitWidth); static EVT getExtendedVectorVT(LLVMContext &C, EVT VT, @@ -356,6 +375,7 @@ namespace llvm { bool isExtended256BitVector() const LLVM_READONLY; bool isExtended512BitVector() const LLVM_READONLY; bool isExtended1024BitVector() const LLVM_READONLY; + bool isExtended2048BitVector() const LLVM_READONLY; EVT getExtendedVectorElementType() const; unsigned getExtendedVectorNumElements() const LLVM_READONLY; unsigned getExtendedSizeInBits() const; diff --git a/contrib/llvm/include/llvm/CodeGen/ValueTypes.td b/contrib/llvm/include/llvm/CodeGen/ValueTypes.td index 2b30f14..f29ec42 100644 --- a/contrib/llvm/include/llvm/CodeGen/ValueTypes.td +++ b/contrib/llvm/include/llvm/CodeGen/ValueTypes.td @@ -33,55 +33,70 @@ def f80 : ValueType<80 , 10>; // 80-bit floating point value def f128 : ValueType<128, 11>; // 128-bit floating point value def ppcf128: ValueType<128, 12>; // PPC 128-bit floating point value -def v2i1 : ValueType<2 , 13>; // 2 x i1 vector value -def v4i1 : ValueType<4 , 14>; // 4 x i1 vector value -def v8i1 : ValueType<8 , 15>; // 8 x i1 vector value -def v16i1 : ValueType<16, 16>; // 16 x i1 vector value -def v32i1 : ValueType<32 , 17>; // 32 x i1 vector value -def v64i1 : ValueType<64 , 18>; // 64 x i1 vector value -def v1i8 : ValueType<16, 19>; // 1 x i8 vector value -def v2i8 : ValueType<16 , 20>; // 2 x i8 vector value -def v4i8 : ValueType<32 , 21>; // 4 x i8 vector value -def v8i8 : ValueType<64 , 22>; // 8 x i8 vector value -def v16i8 : ValueType<128, 23>; // 16 x i8 vector value -def v32i8 : ValueType<256, 24>; // 32 x i8 vector value -def v64i8 : ValueType<512, 25>; // 64 x i8 vector value -def v1i16 : ValueType<16 , 26>; // 1 x i16 vector value -def v2i16 : ValueType<32 , 27>; // 2 x i16 vector value -def v4i16 : ValueType<64 , 28>; // 4 x i16 vector value -def v8i16 : ValueType<128, 29>; // 8 x i16 vector value -def v16i16 : ValueType<256, 30>; // 16 x i16 vector value -def v32i16 : ValueType<512, 31>; // 32 x i16 vector value -def v1i32 : ValueType<32 , 32>; // 1 x i32 vector value -def v2i32 : ValueType<64 , 33>; // 2 x i32 vector value -def v4i32 : ValueType<128, 34>; // 4 x i32 vector value -def v8i32 : ValueType<256, 35>; // 8 x i32 vector value -def v16i32 : ValueType<512, 36>; // 16 x i32 vector value -def v1i64 : ValueType<64 , 37>; // 1 x i64 vector value -def v2i64 : ValueType<128, 38>; // 2 x i64 vector value -def v4i64 : ValueType<256, 39>; // 4 x i64 vector value -def v8i64 : ValueType<512, 40>; // 8 x i64 vector value -def v16i64 : ValueType<1024,41>; // 16 x i64 vector value -def v1i128 : ValueType<128, 42>; // 1 x i128 vector value - -def v2f16 : ValueType<32 , 43>; // 2 x f16 vector value -def v4f16 : ValueType<64 , 44>; // 4 x f16 vector value -def v8f16 : ValueType<128, 45>; // 8 x f16 vector value -def v1f32 : ValueType<32 , 46>; // 1 x f32 vector value -def v2f32 : ValueType<64 , 47>; // 2 x f32 vector value -def v4f32 : ValueType<128, 48>; // 4 x f32 vector value -def v8f32 : ValueType<256, 49>; // 8 x f32 vector value -def v16f32 : ValueType<512, 50>; // 16 x f32 vector value -def v1f64 : ValueType<64, 51>; // 1 x f64 vector value -def v2f64 : ValueType<128, 52>; // 2 x f64 vector value -def v4f64 : ValueType<256, 53>; // 4 x f64 vector value -def v8f64 : ValueType<512, 54>; // 8 x f64 vector value - - -def x86mmx : ValueType<64 , 55>; // X86 MMX value -def FlagVT : ValueType<0 , 56>; // Pre-RA sched glue -def isVoid : ValueType<0 , 57>; // Produces no value -def untyped: ValueType<8 , 58>; // Produces an untyped value +def v2i1 : ValueType<2 , 13>; // 2 x i1 vector value +def v4i1 : ValueType<4 , 14>; // 4 x i1 vector value +def v8i1 : ValueType<8 , 15>; // 8 x i1 vector value +def v16i1 : ValueType<16, 16>; // 16 x i1 vector value +def v32i1 : ValueType<32 , 17>; // 32 x i1 vector value +def v64i1 : ValueType<64 , 18>; // 64 x i1 vector value +def v512i1 : ValueType<512, 19>; // 512 x i8 vector value +def v1024i1: ValueType<1024,20>; //1024 x i8 vector value + +def v1i8 : ValueType<16, 21>; // 1 x i8 vector value +def v2i8 : ValueType<16 , 22>; // 2 x i8 vector value +def v4i8 : ValueType<32 , 23>; // 4 x i8 vector value +def v8i8 : ValueType<64 , 24>; // 8 x i8 vector value +def v16i8 : ValueType<128, 25>; // 16 x i8 vector value +def v32i8 : ValueType<256, 26>; // 32 x i8 vector value +def v64i8 : ValueType<512, 27>; // 64 x i8 vector value +def v128i8 : ValueType<1024,28>; //128 x i8 vector value +def v256i8 : ValueType<2048,29>; //256 x i8 vector value + +def v1i16 : ValueType<16 , 30>; // 1 x i16 vector value +def v2i16 : ValueType<32 , 31>; // 2 x i16 vector value +def v4i16 : ValueType<64 , 32>; // 4 x i16 vector value +def v8i16 : ValueType<128, 33>; // 8 x i16 vector value +def v16i16 : ValueType<256, 34>; // 16 x i16 vector value +def v32i16 : ValueType<512, 35>; // 32 x i16 vector value +def v64i16 : ValueType<1024,36>; // 64 x i16 vector value +def v128i16: ValueType<2048,37>; //128 x i16 vector value + +def v1i32 : ValueType<32 , 38>; // 1 x i32 vector value +def v2i32 : ValueType<64 , 39>; // 2 x i32 vector value +def v4i32 : ValueType<128, 40>; // 4 x i32 vector value +def v8i32 : ValueType<256, 41>; // 8 x i32 vector value +def v16i32 : ValueType<512, 42>; // 16 x i32 vector value +def v32i32 : ValueType<1024,43>; // 32 x i32 vector value +def v64i32 : ValueType<2048,44>; // 32 x i32 vector value + +def v1i64 : ValueType<64 , 45>; // 1 x i64 vector value +def v2i64 : ValueType<128, 46>; // 2 x i64 vector value +def v4i64 : ValueType<256, 47>; // 4 x i64 vector value +def v8i64 : ValueType<512, 48>; // 8 x i64 vector value +def v16i64 : ValueType<1024,49>; // 16 x i64 vector value +def v32i64 : ValueType<2048,50>; // 32 x i64 vector value + +def v1i128 : ValueType<128, 51>; // 1 x i128 vector value + +def v2f16 : ValueType<32 , 52>; // 2 x f16 vector value +def v4f16 : ValueType<64 , 53>; // 4 x f16 vector value +def v8f16 : ValueType<128, 54>; // 8 x f16 vector value +def v1f32 : ValueType<32 , 55>; // 1 x f32 vector value +def v2f32 : ValueType<64 , 56>; // 2 x f32 vector value +def v4f32 : ValueType<128, 57>; // 4 x f32 vector value +def v8f32 : ValueType<256, 58>; // 8 x f32 vector value +def v16f32 : ValueType<512, 59>; // 16 x f32 vector value +def v1f64 : ValueType<64, 60>; // 1 x f64 vector value +def v2f64 : ValueType<128, 61>; // 2 x f64 vector value +def v4f64 : ValueType<256, 62>; // 4 x f64 vector value +def v8f64 : ValueType<512, 63>; // 8 x f64 vector value + + +def x86mmx : ValueType<64 , 64>; // X86 MMX value +def FlagVT : ValueType<0 , 65>; // Pre-RA sched glue +def isVoid : ValueType<0 , 66>; // Produces no value +def untyped: ValueType<8 , 67>; // Produces an untyped value +def token : ValueType<0 , 249>; // TokenTy def MetadataVT: ValueType<0, 250>; // Metadata // Pseudo valuetype mapped to the current pointer size to any address space. diff --git a/contrib/llvm/include/llvm/CodeGen/WinEHFuncInfo.h b/contrib/llvm/include/llvm/CodeGen/WinEHFuncInfo.h index 75638a0..70d558f 100644 --- a/contrib/llvm/include/llvm/CodeGen/WinEHFuncInfo.h +++ b/contrib/llvm/include/llvm/CodeGen/WinEHFuncInfo.h @@ -14,145 +14,103 @@ #ifndef LLVM_CODEGEN_WINEHFUNCINFO_H #define LLVM_CODEGEN_WINEHFUNCINFO_H +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/TinyPtrVector.h" -#include "llvm/ADT/DenseMap.h" namespace llvm { +class AllocaInst; class BasicBlock; +class CatchReturnInst; class Constant; class Function; class GlobalVariable; class InvokeInst; class IntrinsicInst; class LandingPadInst; +class MCExpr; class MCSymbol; +class MachineBasicBlock; class Value; -enum ActionType { Catch, Cleanup }; - -class ActionHandler { -public: - ActionHandler(BasicBlock *BB, ActionType Type) - : StartBB(BB), Type(Type), EHState(-1), HandlerBlockOrFunc(nullptr) {} - - ActionType getType() const { return Type; } - BasicBlock *getStartBlock() const { return StartBB; } - - bool hasBeenProcessed() { return HandlerBlockOrFunc != nullptr; } +// The following structs respresent the .xdata tables for various +// Windows-related EH personalities. - void setHandlerBlockOrFunc(Constant *F) { HandlerBlockOrFunc = F; } - Constant *getHandlerBlockOrFunc() { return HandlerBlockOrFunc; } +typedef PointerUnion<const BasicBlock *, MachineBasicBlock *> MBBOrBasicBlock; - void setEHState(int State) { EHState = State; } - int getEHState() const { return EHState; } - -private: - BasicBlock *StartBB; - ActionType Type; - int EHState; - - // Can be either a BlockAddress or a Function depending on the EH personality. - Constant *HandlerBlockOrFunc; -}; - -class CatchHandler : public ActionHandler { -public: - CatchHandler(BasicBlock *BB, Constant *Selector, BasicBlock *NextBB) - : ActionHandler(BB, ActionType::Catch), Selector(Selector), - NextBB(NextBB), ExceptionObjectVar(nullptr), - ExceptionObjectIndex(-1) {} - - // Method for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const ActionHandler *H) { - return H->getType() == ActionType::Catch; - } - - Constant *getSelector() const { return Selector; } - BasicBlock *getNextBB() const { return NextBB; } - - const Value *getExceptionVar() { return ExceptionObjectVar; } - TinyPtrVector<BasicBlock *> &getReturnTargets() { return ReturnTargets; } - - void setExceptionVar(const Value *Val) { ExceptionObjectVar = Val; } - void setExceptionVarIndex(int Index) { ExceptionObjectIndex = Index; } - int getExceptionVarIndex() const { return ExceptionObjectIndex; } - void setReturnTargets(TinyPtrVector<BasicBlock *> &Targets) { - ReturnTargets = Targets; - } - -private: - Constant *Selector; - BasicBlock *NextBB; - // While catch handlers are being outlined the ExceptionObjectVar field will - // be populated with the instruction in the parent frame that corresponds - // to the exception object (or nullptr if the catch does not use an - // exception object) and the ExceptionObjectIndex field will be -1. - // When the parseEHActions function is called to populate a vector of - // instances of this class, the ExceptionObjectVar field will be nullptr - // and the ExceptionObjectIndex will be the index of the exception object in - // the parent function's localescape block. - const Value *ExceptionObjectVar; - int ExceptionObjectIndex; - TinyPtrVector<BasicBlock *> ReturnTargets; +struct CxxUnwindMapEntry { + int ToState; + MBBOrBasicBlock Cleanup; }; -class CleanupHandler : public ActionHandler { -public: - CleanupHandler(BasicBlock *BB) : ActionHandler(BB, ActionType::Cleanup) {} +/// Similar to CxxUnwindMapEntry, but supports SEH filters. +struct SEHUnwindMapEntry { + /// If unwinding continues through this handler, transition to the handler at + /// this state. This indexes into SEHUnwindMap. + int ToState = -1; - // Method for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const ActionHandler *H) { - return H->getType() == ActionType::Cleanup; - } -}; - -void parseEHActions(const IntrinsicInst *II, - SmallVectorImpl<std::unique_ptr<ActionHandler>> &Actions); + bool IsFinally = false; -// The following structs respresent the .xdata for functions using C++ -// exceptions on Windows. + /// Holds the filter expression function. + const Function *Filter = nullptr; -struct WinEHUnwindMapEntry { - int ToState; - Function *Cleanup; + /// Holds the __except or __finally basic block. + MBBOrBasicBlock Handler; }; struct WinEHHandlerType { int Adjectives; + /// The CatchObj starts out life as an LLVM alloca and is eventually turned + /// frame index. + union { + const AllocaInst *Alloca; + int FrameIndex; + } CatchObj = {}; GlobalVariable *TypeDescriptor; - int CatchObjRecoverIdx; - Function *Handler; + MBBOrBasicBlock Handler; }; struct WinEHTryBlockMapEntry { - int TryLow; - int TryHigh; + int TryLow = -1; + int TryHigh = -1; + int CatchHigh = -1; SmallVector<WinEHHandlerType, 1> HandlerArray; }; +enum class ClrHandlerType { Catch, Finally, Fault, Filter }; + +struct ClrEHUnwindMapEntry { + MBBOrBasicBlock Handler; + uint32_t TypeToken; + int Parent; + ClrHandlerType HandlerType; +}; + struct WinEHFuncInfo { - DenseMap<const Function *, const LandingPadInst *> RootLPad; - DenseMap<const Function *, const InvokeInst *> LastInvoke; - DenseMap<const Function *, int> HandlerEnclosedState; - DenseMap<const Function *, bool> LastInvokeVisited; - DenseMap<const LandingPadInst *, int> LandingPadStateMap; - DenseMap<const Function *, int> CatchHandlerParentFrameObjIdx; - DenseMap<const Function *, int> CatchHandlerParentFrameObjOffset; - DenseMap<const Function *, int> CatchHandlerMaxState; - DenseMap<const Function *, int> HandlerBaseState; - SmallVector<WinEHUnwindMapEntry, 4> UnwindMap; + DenseMap<const Instruction *, int> EHPadStateMap; + DenseMap<const FuncletPadInst *, int> FuncletBaseStateMap; + DenseMap<const InvokeInst *, int> InvokeStateMap; + DenseMap<const CatchReturnInst *, const BasicBlock *> + CatchRetSuccessorColorMap; + DenseMap<MCSymbol *, std::pair<int, MCSymbol *>> LabelToStateMap; + SmallVector<CxxUnwindMapEntry, 4> CxxUnwindMap; SmallVector<WinEHTryBlockMapEntry, 4> TryBlockMap; - SmallVector<std::pair<MCSymbol *, int>, 4> IPToStateList; + SmallVector<SEHUnwindMapEntry, 4> SEHUnwindMap; + SmallVector<ClrEHUnwindMapEntry, 4> ClrEHUnwindMap; int UnwindHelpFrameIdx = INT_MAX; - int UnwindHelpFrameOffset = -1; - unsigned NumIPToStateFuncsVisited = 0; + int PSPSymFrameIdx = INT_MAX; + + int getLastStateNumber() const { return CxxUnwindMap.size() - 1; } + + void addIPToStateRange(const InvokeInst *II, MCSymbol *InvokeBegin, + MCSymbol *InvokeEnd); - /// localescape index of the 32-bit EH registration node. Set by - /// WinEHStatePass and used indirectly by SEH filter functions of the parent. - int EHRegNodeEscapeIndex = INT_MAX; + int EHRegNodeFrameIndex = INT_MAX; + int EHRegNodeEndOffset = INT_MAX; + int SEHSetFrameOffset = INT_MAX; - WinEHFuncInfo() {} + WinEHFuncInfo(); }; /// Analyze the IR in ParentFn and it's handlers to build WinEHFuncInfo, which @@ -161,5 +119,12 @@ struct WinEHFuncInfo { void calculateWinCXXEHStateNumbers(const Function *ParentFn, WinEHFuncInfo &FuncInfo); +void calculateSEHStateNumbers(const Function *ParentFn, + WinEHFuncInfo &FuncInfo); + +void calculateClrEHStateNumbers(const Function *Fn, WinEHFuncInfo &FuncInfo); + +void calculateCatchReturnSuccessorColors(const Function *Fn, + WinEHFuncInfo &FuncInfo); } #endif // LLVM_CODEGEN_WINEHFUNCINFO_H |