diff options
Diffstat (limited to 'include/llvm/CodeGen')
28 files changed, 376 insertions, 711 deletions
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index ac224d8..d364012 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -16,6 +16,7 @@ #ifndef LLVM_CODEGEN_ASMPRINTER_H #define LLVM_CODEGEN_ASMPRINTER_H +#include "llvm/ADT/MapVector.h" #include "llvm/ADT/Twine.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/IR/InlineAsm.h" @@ -29,6 +30,8 @@ class ByteStreamer; class GCStrategy; class Constant; class ConstantArray; +class DIE; +class DIEAbbrev; class GCMetadataPrinter; class GlobalValue; class GlobalVariable; @@ -100,9 +103,13 @@ public: /// Map global GOT equivalent MCSymbols to GlobalVariables and keep track of /// its number of uses by other globals. typedef std::pair<const GlobalVariable *, unsigned> GOTEquivUsePair; - DenseMap<const MCSymbol *, GOTEquivUsePair> GlobalGOTEquivs; + MapVector<const MCSymbol *, GOTEquivUsePair> GlobalGOTEquivs; private: + MCSymbol *CurrentFnBegin; + MCSymbol *CurrentFnEnd; + MCSymbol *CurExceptionSym; + // The garbage collection metadata printer table. void *GCMetadataPrinters; // Really a DenseMap. @@ -146,6 +153,10 @@ public: /// unsigned getFunctionNumber() const; + MCSymbol *getFunctionBegin() const { return CurrentFnBegin; } + MCSymbol *getFunctionEnd() const { return CurrentFnEnd; } + MCSymbol *getCurExceptionSym(); + /// Return information about object file lowering. const TargetLoweringObjectFile &getObjFileLowering() const; @@ -187,7 +198,6 @@ public: /// Emit the specified function out to the OutStreamer. bool runOnMachineFunction(MachineFunction &MF) override { SetupMachineFunction(MF); - EmitFunctionHeader(); EmitFunctionBody(); return false; } @@ -200,9 +210,6 @@ public: /// runOnMachineFunction. void SetupMachineFunction(MachineFunction &MF); - /// This method emits the header for the current function. - void EmitFunctionHeader(); - /// This method emits the body and trailer for a function. void EmitFunctionBody(); @@ -324,12 +331,7 @@ public: // Symbol Lowering Routines. //===------------------------------------------------------------------===// public: - /// Return the MCSymbol corresponding to the assembler temporary label with - /// the specified stem and unique ID. - MCSymbol *GetTempSymbol(const Twine &Name, unsigned ID) const; - - /// Return an assembler temporary label with the specified stem. - MCSymbol *GetTempSymbol(const Twine &Name) const; + MCSymbol *createTempSymbol(const Twine &Name) const; /// Return the MCSymbol for a private symbol with global value name as its /// base, with the specified suffix. @@ -417,37 +419,10 @@ public: /// Emit the 4-byte offset of Label from the start of its section. This can /// be done with a special directive if the target supports it (e.g. cygwin) /// or by emitting it as an offset from a label at the start of the section. - /// - /// SectionLabel is a temporary label emitted at the start of the section - /// that Label lives in. - void EmitSectionOffset(const MCSymbol *Label, - const MCSymbol *SectionLabel) const; + void emitSectionOffset(const MCSymbol *Label) const; /// Get the value for DW_AT_APPLE_isa. Zero if no isa encoding specified. - virtual unsigned getISAEncoding(const Function *) { return 0; } - - /// Emit a dwarf register operation for describing - /// - a small value occupying only part of a register or - /// - a register representing only part of a value. - void EmitDwarfOpPiece(ByteStreamer &Streamer, unsigned SizeInBits, - unsigned OffsetInBits = 0) const; - - - /// \brief Emit a partial DWARF register operation. - /// \param MLoc the register - /// \param PieceSize size and - /// \param PieceOffset offset of the piece in bits, if this is one - /// piece of an aggregate value. - /// - /// If size and offset is zero an operation for the entire - /// register is emitted: Some targets do not provide a DWARF - /// register number for every register. If this is the case, this - /// function will attempt to emit a DWARF register by emitting a - /// piece of a super-register or by piecing together multiple - /// subregisters that alias the register. - void EmitDwarfRegOpPiece(ByteStreamer &BS, const MachineLocation &MLoc, - unsigned PieceSize = 0, - unsigned PieceOffset = 0) const; + virtual unsigned getISAEncoding() { return 0; } /// EmitDwarfRegOp - Emit a dwarf register operation. virtual void EmitDwarfRegOp(ByteStreamer &BS, @@ -460,6 +435,12 @@ public: /// \brief Emit frame instruction to describe the layout of the frame. void emitCFIInstruction(const MCCFIInstruction &Inst) const; + /// \brief Emit Dwarf abbreviation table. + void emitDwarfAbbrevs(const std::vector<DIEAbbrev *>& Abbrevs) const; + + /// \brief Recursively emit Dwarf DIE tree. + void emitDwarfDIE(const DIE &Die) const; + //===------------------------------------------------------------------===// // Inline Asm Support //===------------------------------------------------------------------===// @@ -510,11 +491,14 @@ private: mutable const MachineInstr *LastMI; mutable unsigned LastFn; mutable unsigned Counter; - mutable unsigned SetCounter; + + /// This method emits the header for the current function. + void EmitFunctionHeader(); /// Emit a blob of inline asm to the output streamer. void - EmitInlineAsm(StringRef Str, const MDNode *LocMDNode = nullptr, + EmitInlineAsm(StringRef Str, const MCSubtargetInfo &STI, + const MDNode *LocMDNode = nullptr, InlineAsm::AsmDialect AsmDialect = InlineAsm::AD_ATT) const; /// This method formats and emits the specified machine instruction that is an diff --git a/include/llvm/CodeGen/BasicTTIImpl.h b/include/llvm/CodeGen/BasicTTIImpl.h index ff85b06..e1e5112 100644 --- a/include/llvm/CodeGen/BasicTTIImpl.h +++ b/include/llvm/CodeGen/BasicTTIImpl.h @@ -21,6 +21,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetSubtargetInfo.h" +#include "llvm/Analysis/TargetLibraryInfo.h" namespace llvm { @@ -527,18 +528,29 @@ public: // Assume that we need to scalarize this intrinsic. unsigned ScalarizationCost = 0; unsigned ScalarCalls = 1; + Type *ScalarRetTy = RetTy; if (RetTy->isVectorTy()) { ScalarizationCost = getScalarizationOverhead(RetTy, true, false); ScalarCalls = std::max(ScalarCalls, RetTy->getVectorNumElements()); + ScalarRetTy = RetTy->getScalarType(); } + SmallVector<Type *, 4> ScalarTys; for (unsigned i = 0, ie = Tys.size(); i != ie; ++i) { - if (Tys[i]->isVectorTy()) { - ScalarizationCost += getScalarizationOverhead(Tys[i], false, true); - ScalarCalls = std::max(ScalarCalls, RetTy->getVectorNumElements()); + Type *Ty = Tys[i]; + if (Ty->isVectorTy()) { + ScalarizationCost += getScalarizationOverhead(Ty, false, true); + ScalarCalls = std::max(ScalarCalls, Ty->getVectorNumElements()); + Ty = Ty->getScalarType(); } + ScalarTys.push_back(Ty); } + if (ScalarCalls == 1) + return 1; // Return cost of a scalar intrinsic. Assume it to be cheap. - return ScalarCalls + ScalarizationCost; + unsigned ScalarCost = static_cast<T *>(this)->getIntrinsicInstrCost( + IID, ScalarRetTy, ScalarTys); + + return ScalarCalls * ScalarCost + ScalarizationCost; } // Look for intrinsics that can be lowered directly or turned into a scalar // intrinsic call. @@ -648,16 +660,46 @@ public: // this will emit a costly libcall, adding call overhead and spills. Make it // very expensive. if (RetTy->isVectorTy()) { - unsigned Num = RetTy->getVectorNumElements(); - unsigned Cost = static_cast<T *>(this)->getIntrinsicInstrCost( - IID, RetTy->getScalarType(), Tys); - return 10 * Cost * Num; + unsigned ScalarizationCost = getScalarizationOverhead(RetTy, true, false); + unsigned ScalarCalls = RetTy->getVectorNumElements(); + SmallVector<Type *, 4> ScalarTys; + for (unsigned i = 0, ie = Tys.size(); i != ie; ++i) { + Type *Ty = Tys[i]; + if (Ty->isVectorTy()) + Ty = Ty->getScalarType(); + ScalarTys.push_back(Ty); + } + unsigned ScalarCost = static_cast<T *>(this)->getIntrinsicInstrCost( + IID, RetTy->getScalarType(), ScalarTys); + for (unsigned i = 0, ie = Tys.size(); i != ie; ++i) { + if (Tys[i]->isVectorTy()) { + ScalarizationCost += getScalarizationOverhead(Tys[i], false, true); + ScalarCalls = std::max(ScalarCalls, Tys[i]->getVectorNumElements()); + } + } + + return ScalarCalls * ScalarCost + ScalarizationCost; } // This is going to be turned into a library call, make it expensive. return 10; } + /// \brief Compute a cost of the given call instruction. + /// + /// Compute the cost of calling function F with return type RetTy and + /// argument types Tys. F might be nullptr, in this case the cost of an + /// arbitrary call with the specified signature will be returned. + /// This is used, for instance, when we estimate call of a vector + /// counterpart of the given function. + /// \param F Called function, might be nullptr. + /// \param RetTy Return value types. + /// \param Tys Argument types. + /// \returns The cost of Call instruction. + unsigned getCallInstrCost(Function *F, Type *RetTy, ArrayRef<Type *> Tys) { + return 10; + } + unsigned getNumberOfParts(Type *Tp) { std::pair<unsigned, MVT> LT = getTLI()->getTypeLegalizationCost(Tp); return LT.first; diff --git a/include/llvm/CodeGen/DIE.h b/include/llvm/CodeGen/DIE.h index e310aef..7803898 100644 --- a/include/llvm/CodeGen/DIE.h +++ b/include/llvm/CodeGen/DIE.h @@ -95,7 +95,7 @@ public: /// Emit - Print the abbreviation using the specified asm printer. /// - void Emit(AsmPrinter *AP) const; + void Emit(const AsmPrinter *AP) const; #ifndef NDEBUG void print(raw_ostream &O); @@ -230,11 +230,11 @@ public: /// EmitValue - Emit value via the Dwarf writer. /// - virtual void EmitValue(AsmPrinter *AP, dwarf::Form Form) const = 0; + virtual void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const = 0; /// SizeOf - Return the size of a value in bytes. /// - virtual unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const = 0; + virtual unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const = 0; #ifndef NDEBUG virtual void print(raw_ostream &O) const = 0; @@ -275,13 +275,14 @@ public: /// EmitValue - Emit integer of appropriate size. /// - void EmitValue(AsmPrinter *AP, dwarf::Form Form) const override; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override; uint64_t getValue() const { return Integer; } + void setValue(uint64_t Val) { Integer = Val; } /// SizeOf - Determine size of integer value in bytes. /// - unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const override; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override; // Implement isa/cast/dyncast. static bool classof(const DIEValue *I) { return I->getType() == isInteger; } @@ -302,7 +303,7 @@ public: /// EmitValue - Emit expression value. /// - void EmitValue(AsmPrinter *AP, dwarf::Form Form) const override; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override; /// getValue - Get MCExpr. /// @@ -310,7 +311,7 @@ public: /// SizeOf - Determine size of expression value in bytes. /// - unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const override; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override; // Implement isa/cast/dyncast. static bool classof(const DIEValue *E) { return E->getType() == isExpr; } @@ -331,7 +332,7 @@ public: /// EmitValue - Emit label value. /// - void EmitValue(AsmPrinter *AP, dwarf::Form Form) const override; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override; /// getValue - Get MCSymbol. /// @@ -339,7 +340,7 @@ public: /// SizeOf - Determine size of label value in bytes. /// - unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const override; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override; // Implement isa/cast/dyncast. static bool classof(const DIEValue *L) { return L->getType() == isLabel; } @@ -362,11 +363,11 @@ public: /// EmitValue - Emit delta value. /// - void EmitValue(AsmPrinter *AP, dwarf::Form Form) const override; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override; /// SizeOf - Determine size of delta value in bytes. /// - unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const override; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override; // Implement isa/cast/dyncast. static bool classof(const DIEValue *D) { return D->getType() == isDelta; } @@ -392,11 +393,11 @@ public: /// EmitValue - Emit delta value. /// - void EmitValue(AsmPrinter *AP, dwarf::Form Form) const override; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override; /// SizeOf - Determine size of delta value in bytes. /// - unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const override; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override; // Implement isa/cast/dyncast. static bool classof(const DIEValue *D) { return D->getType() == isString; } @@ -421,17 +422,17 @@ public: /// EmitValue - Emit debug information entry offset. /// - void EmitValue(AsmPrinter *AP, dwarf::Form Form) const override; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override; /// SizeOf - Determine size of debug information entry in bytes. /// - unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const override { + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override { return Form == dwarf::DW_FORM_ref_addr ? getRefAddrSize(AP) : sizeof(int32_t); } /// Returns size of a ref_addr entry. - static unsigned getRefAddrSize(AsmPrinter *AP); + static unsigned getRefAddrSize(const AsmPrinter *AP); // Implement isa/cast/dyncast. static bool classof(const DIEValue *E) { return E->getType() == isEntry; } @@ -451,10 +452,10 @@ public: : DIEValue(isTypeSignature), Unit(Unit) {} /// \brief Emit type unit signature. - void EmitValue(AsmPrinter *Asm, dwarf::Form Form) const override; + void EmitValue(const AsmPrinter *Asm, dwarf::Form Form) const override; /// Returns size of a ref_sig8 entry. - unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const override { + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override { assert(Form == dwarf::DW_FORM_ref_sig8); return 8; } @@ -479,7 +480,7 @@ public: /// ComputeSize - Calculate the size of the location expression. /// - unsigned ComputeSize(AsmPrinter *AP) const; + unsigned ComputeSize(const AsmPrinter *AP) const; /// BestForm - Choose the best form for data. /// @@ -498,11 +499,11 @@ public: /// EmitValue - Emit location data. /// - void EmitValue(AsmPrinter *AP, dwarf::Form Form) const override; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override; /// SizeOf - Determine size of location data in bytes. /// - unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const override; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override; // Implement isa/cast/dyncast. static bool classof(const DIEValue *E) { return E->getType() == isLoc; } @@ -522,7 +523,7 @@ public: /// ComputeSize - Calculate the size of the location expression. /// - unsigned ComputeSize(AsmPrinter *AP) const; + unsigned ComputeSize(const AsmPrinter *AP) const; /// BestForm - Choose the best form for data. /// @@ -538,11 +539,11 @@ public: /// EmitValue - Emit location data. /// - void EmitValue(AsmPrinter *AP, dwarf::Form Form) const override; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override; /// SizeOf - Determine size of location data in bytes. /// - unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const override; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override; // Implement isa/cast/dyncast. static bool classof(const DIEValue *E) { return E->getType() == isBlock; } @@ -568,11 +569,11 @@ public: /// EmitValue - Emit location data. /// - void EmitValue(AsmPrinter *AP, dwarf::Form Form) const override; + void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override; /// SizeOf - Determine size of location data in bytes. /// - unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const override; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override; // Implement isa/cast/dyncast. static bool classof(const DIEValue *E) { return E->getType() == isLocList; } diff --git a/include/llvm/CodeGen/ForwardControlFlowIntegrity.h b/include/llvm/CodeGen/ForwardControlFlowIntegrity.h deleted file mode 100644 index ec8e2ef..0000000 --- a/include/llvm/CodeGen/ForwardControlFlowIntegrity.h +++ /dev/null @@ -1,122 +0,0 @@ -//===-- ForwardControlFlowIntegrity.h: Forward-Edge CFI ---------*- C++ -*-===// -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This pass instruments indirect calls with checks to ensure that these calls -// pass through the appropriate jump-instruction table generated by -// JumpInstrTables. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CODEGEN_FORWARDCONTROLFLOWINTEGRITY_H -#define LLVM_CODEGEN_FORWARDCONTROLFLOWINTEGRITY_H - -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/Pass.h" -#include "llvm/Target/TargetOptions.h" -#include <string> - -namespace llvm { - -class AnalysisUsage; -class BasicBlock; -class Constant; -class Function; -class Instruction; -class Module; -class Value; - -/// ForwardControlFlowIntegrity uses the information from JumpInstrTableInfo to -/// prepend checks to indirect calls to make sure that these calls target valid -/// locations. -class ForwardControlFlowIntegrity : public ModulePass { -public: - static char ID; - - ForwardControlFlowIntegrity(); - ForwardControlFlowIntegrity(JumpTable::JumpTableType JTT, - CFIntegrity CFIType, - bool CFIEnforcing, std::string CFIFuncName); - ~ForwardControlFlowIntegrity() override; - - /// Runs the CFI pass on a given module. This works best if the module in - /// question is the result of link-time optimization (see lib/LTO). - bool runOnModule(Module &M) override; - const char *getPassName() const override { - return "Forward Control-Flow Integrity"; - } - void getAnalysisUsage(AnalysisUsage &AU) const override; - -private: - typedef SmallVector<Instruction *, 64> CallSet; - - /// A structure that is used to keep track of constant table information. - struct CFIConstants { - Constant *StartValue; - Constant *MaskValue; - Constant *Size; - }; - - /// A map from function type to the base of the table for this type and a mask - /// for the table - typedef DenseMap<FunctionType *, CFIConstants> CFITables; - - CallSet IndirectCalls; - - /// The type of jumptable implementation. - JumpTable::JumpTableType JTType; - - /// The type of CFI check to add before each indirect call. - CFIntegrity CFIType; - - /// A value that controls whether or not CFI violations cause a halt. - bool CFIEnforcing; - - /// The name of the function to call in case of a CFI violation when - /// CFIEnforcing is false. There is a default function that ignores - /// violations. - std::string CFIFuncName; - - /// The alignment of each entry in the table, from JumpInstrTableInfo. The - /// JumpInstrTableInfo class always makes this a power of two. - uint64_t ByteAlignment; - - /// The base-2 logarithm of ByteAlignment, needed for some of the transforms - /// (like CFIntegrity::Ror) - unsigned LogByteAlignment; - - /// Adds checks to each indirect call site to make sure that it is calling a - /// function in our jump table. - void updateIndirectCalls(Module &M, CFITables &CFIT); - - /// Walks the instructions to find all the indirect calls. - void getIndirectCalls(Module &M); - - /// Adds a function that handles violations in non-enforcing mode - /// (!CFIEnforcing). The default warning function simply returns, since the - /// exact details of how to handle CFI violations depend on the application. - void addWarningFunction(Module &M); - - /// Rewrites a function pointer in a call/invoke instruction to force it into - /// a table. - void rewriteFunctionPointer(Module &M, Instruction *I, Value *FunPtr, - Constant *JumpTableStart, Constant *JumpTableMask, - Constant *JumpTableSize); - - /// Inserts a check and a call to a warning function at a given instruction - /// that must be an indirect call. - void insertWarning(Module &M, BasicBlock *Block, Instruction *I, - Value *FunPtr); -}; - -ModulePass * -createForwardControlFlowIntegrityPass(JumpTable::JumpTableType JTT, - CFIntegrity CFIType, - bool CFIEnforcing, StringRef CFIFuncName); -} - -#endif // LLVM_CODEGEN_FORWARDCONTROLFLOWINTEGRITY_H diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h index 8a31f7e..2d1c8cd 100644 --- a/include/llvm/CodeGen/ISDOpcodes.h +++ b/include/llvm/CodeGen/ISDOpcodes.h @@ -689,8 +689,6 @@ namespace ISD { // Masked load and store MLOAD, MSTORE, - // Masked gather and scatter - MGATHER, MSCATTER, /// This corresponds to the llvm.lifetime.* intrinsics. The first operand /// is the chain and the second operand is the alloca pointer. diff --git a/include/llvm/CodeGen/JumpInstrTables.h b/include/llvm/CodeGen/JumpInstrTables.h deleted file mode 100644 index 005bc1e..0000000 --- a/include/llvm/CodeGen/JumpInstrTables.h +++ /dev/null @@ -1,105 +0,0 @@ -//===-- JumpInstrTables.h: Jump-Instruction Tables --------------*- C++ -*-===// -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// \brief An implementation of tables consisting of jump instructions -/// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CODEGEN_JUMPINSTRTABLES_H -#define LLVM_CODEGEN_JUMPINSTRTABLES_H - -#include "llvm/ADT/DenseMap.h" -#include "llvm/Pass.h" -#include "llvm/Target/TargetOptions.h" - -namespace llvm { -class Constant; -class Function; -class FunctionType; -class JumpInstrTableInfo; -class Module; - -/// A class to manage a set of jump tables indexed on function type. It looks at -/// each function in the module to find all the functions that have the -/// jumptable attribute set. For each such function, it creates a new -/// jump-instruction-table function and stores the mapping in the ImmutablePass -/// JumpInstrTableInfo. -/// -/// These special functions get lowered in AsmPrinter to assembly of the form: -/// \verbatim -/// .globl f -/// .type f,@function -/// .align 8,0x90 -/// f: -/// jmp f_orig@PLT -/// \endverbatim -/// -/// Support for an architecture depends on three functions in TargetInstrInfo: -/// getUnconditionalBranch, getTrap, and getJumpInstrTableEntryBound. AsmPrinter -/// uses these to generate the appropriate instructions for the jump statement -/// (an unconditional branch) and for padding to make the table have a size that -/// is a power of two. This padding uses a trap instruction to ensure that calls -/// to this area halt the program. The default implementations of these -/// functions call llvm_unreachable, except for getJumpInstrTableEntryBound, -/// which returns 0 by default. -class JumpInstrTables : public ModulePass { -public: - static char ID; - - JumpInstrTables(); - JumpInstrTables(JumpTable::JumpTableType JTT); - virtual ~JumpInstrTables(); - bool runOnModule(Module &M) override; - const char *getPassName() const override { return "Jump-Instruction Tables"; } - void getAnalysisUsage(AnalysisUsage &AU) const override; - - /// Creates a jump-instruction table function for the Target and adds it to - /// the tables. - Function *insertEntry(Module &M, Function *Target); - - /// Checks to see if there is already a table for the given FunctionType. - bool hasTable(FunctionType *FunTy); - - /// Maps the function into a subset of function types, depending on the - /// jump-instruction table style selected from JumpTableTypes in - /// JumpInstrTables.cpp. The choice of mapping determines the number of - /// jump-instruction tables generated by this pass. E.g., the simplest mapping - /// converts every function type into void f(); so, all functions end up in a - /// single table. - static FunctionType *transformType(JumpTable::JumpTableType JTT, - FunctionType *FunTy); -private: - /// The metadata used while a jump table is being built - struct TableMeta { - /// The number of this table - unsigned TableNum; - - /// The current number of jump entries in the table. - unsigned Count; - }; - - typedef DenseMap<FunctionType *, struct TableMeta> JumpMap; - - /// The current state of functions and jump entries in the table(s). - JumpMap Metadata; - - /// The ImmutablePass that stores information about the generated tables. - JumpInstrTableInfo *JITI; - - /// The total number of tables. - unsigned TableCount; - - /// The type of tables to build. - JumpTable::JumpTableType JTType; -}; - -/// Creates a JumpInstrTables pass for the given type of jump table. -ModulePass *createJumpInstrTablesPass(JumpTable::JumpTableType JTT); -} - -#endif /* LLVM_CODEGEN_JUMPINSTRTABLES_H */ diff --git a/include/llvm/CodeGen/LatencyPriorityQueue.h b/include/llvm/CodeGen/LatencyPriorityQueue.h index cf601ae..f347f66 100644 --- a/include/llvm/CodeGen/LatencyPriorityQueue.h +++ b/include/llvm/CodeGen/LatencyPriorityQueue.h @@ -83,8 +83,6 @@ namespace llvm { void remove(SUnit *SU) override; - void dump(ScheduleDAG* DAG) const override; - // scheduledNode - As nodes are scheduled, we look to see if there are any // successor nodes that have a single unscheduled predecessor. If so, that // single predecessor has a higher priority, since scheduling it will make diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h index 21634cb..9b8b91c 100644 --- a/include/llvm/CodeGen/LiveInterval.h +++ b/include/llvm/CodeGen/LiveInterval.h @@ -199,7 +199,7 @@ namespace llvm { // of live ranges of physical registers in computeRegUnitRange. // After that the set is flushed to the segment vector and deleted. typedef std::set<Segment> SegmentSet; - SegmentSet *segmentSet; + std::unique_ptr<SegmentSet> segmentSet; typedef Segments::iterator iterator; iterator begin() { return segments.begin(); } @@ -218,15 +218,13 @@ namespace llvm { const_vni_iterator vni_end() const { return valnos.end(); } /// Constructs a new LiveRange object. - LiveRange(bool UseSegmentSet = false) : segmentSet(nullptr) { - if (UseSegmentSet) - segmentSet = new SegmentSet(); - } + LiveRange(bool UseSegmentSet = false) + : segmentSet(UseSegmentSet ? llvm::make_unique<SegmentSet>() + : nullptr) {} /// Constructs a new LiveRange object by copying segments and valnos from /// another LiveRange. - LiveRange(const LiveRange &Other, BumpPtrAllocator &Allocator) - : segmentSet(nullptr) { + LiveRange(const LiveRange &Other, BumpPtrAllocator &Allocator) { assert(Other.segmentSet == nullptr && "Copying of LiveRanges with active SegmentSets is not supported"); @@ -240,8 +238,6 @@ namespace llvm { } } - ~LiveRange() { delete segmentSet; } - /// advanceTo - Advance the specified iterator to point to the Segment /// containing the specified position, or end() if the position is past the /// end of the range. If no Segment contains this position, but the @@ -745,8 +741,6 @@ namespace llvm { #endif private: - LiveInterval& operator=(const LiveInterval& rhs) = delete; - /// Appends @p Range to SubRanges list. void appendSubRange(SubRange *Range) { Range->Next = SubRanges; diff --git a/include/llvm/CodeGen/LivePhysRegs.h b/include/llvm/CodeGen/LivePhysRegs.h index 4aa53a9..f44d627 100644 --- a/include/llvm/CodeGen/LivePhysRegs.h +++ b/include/llvm/CodeGen/LivePhysRegs.h @@ -57,9 +57,9 @@ public: } /// \brief Clear and initialize the LivePhysRegs set. - void init(const TargetRegisterInfo *_TRI) { - assert(_TRI && "Invalid TargetRegisterInfo pointer."); - TRI = _TRI; + void init(const TargetRegisterInfo *TRI) { + assert(TRI && "Invalid TargetRegisterInfo pointer."); + this->TRI = TRI; LiveRegs.clear(); LiveRegs.setUniverse(TRI->getNumRegs()); } diff --git a/include/llvm/CodeGen/LiveStackAnalysis.h b/include/llvm/CodeGen/LiveStackAnalysis.h index df68398..f495507 100644 --- a/include/llvm/CodeGen/LiveStackAnalysis.h +++ b/include/llvm/CodeGen/LiveStackAnalysis.h @@ -21,6 +21,7 @@ #include "llvm/Support/Allocator.h" #include "llvm/Target/TargetRegisterInfo.h" #include <map> +#include <unordered_map> namespace llvm { @@ -33,7 +34,7 @@ namespace llvm { /// S2IMap - Stack slot indices to live interval mapping. /// - typedef std::map<int, LiveInterval> SS2IntervalMap; + typedef std::unordered_map<int, LiveInterval> SS2IntervalMap; SS2IntervalMap S2IMap; /// S2RCMap - Stack slot indices to register class mapping. diff --git a/include/llvm/CodeGen/MachineDominators.h b/include/llvm/CodeGen/MachineDominators.h index a6980a6..19f4e2d 100644 --- a/include/llvm/CodeGen/MachineDominators.h +++ b/include/llvm/CodeGen/MachineDominators.h @@ -45,9 +45,6 @@ class MachineDominatorTree : public MachineFunctionPass { MachineBasicBlock *FromBB; MachineBasicBlock *ToBB; MachineBasicBlock *NewBB; - CriticalEdge(MachineBasicBlock *FromBB, MachineBasicBlock *ToBB, - MachineBasicBlock *NewBB) - : FromBB(FromBB), ToBB(ToBB), NewBB(NewBB) {} }; /// \brief Pile up all the critical edges to be split. @@ -67,74 +64,7 @@ class MachineDominatorTree : public MachineFunctionPass { /// the fast query path of DT as much as possible. /// /// \post CriticalEdgesToSplit.empty(). - void applySplitCriticalEdges() const { - // Bail out early if there is nothing to do. - if (CriticalEdgesToSplit.empty()) - return; - - // For each element in CriticalEdgesToSplit, remember whether or - // not element is the new immediate domminator of its successor. - // The mapping is done by index, i.e., the information for the ith - // element of CriticalEdgesToSplit is the ith element of IsNewIDom. - SmallVector<bool, 32> IsNewIDom; - IsNewIDom.resize(CriticalEdgesToSplit.size()); - size_t Idx = 0; - - // Collect all the dominance properties info, before invalidating - // the underlying DT. - for (CriticalEdge &Edge : CriticalEdgesToSplit) { - // Update dominator information. - MachineBasicBlock *Succ = Edge.ToBB; - MachineDomTreeNode *SucccDTNode = DT->getNode(Succ); - - IsNewIDom[Idx] = true; - for (MachineBasicBlock *PredBB : Succ->predecessors()) { - if (PredBB == Edge.NewBB) - continue; - // If we are in this situation: - // FromBB1 FromBB2 - // + + - // + + + + - // + + + + - // ... Split1 Split2 ... - // + + - // + + - // + - // Succ - // Instead of checking the domiance property with Split2, we - // check it with FromBB2 since Split2 is still unknown of the - // underlying DT structure. - if (NewBBs.count(PredBB)) { - assert(PredBB->pred_size() == 1 && "A basic block resulting from a " - "critical edge split has more " - "than one predecessor!"); - PredBB = *PredBB->pred_begin(); - } - if (!DT->dominates(SucccDTNode, DT->getNode(PredBB))) { - IsNewIDom[Idx] = false; - break; - } - } - ++Idx; - } - - // Now, update DT with the collected dominance properties info. - Idx = 0; - for (CriticalEdge &Edge : CriticalEdgesToSplit) { - // We know FromBB dominates NewBB. - MachineDomTreeNode *NewDTNode = DT->addNewBlock(Edge.NewBB, Edge.FromBB); - MachineDomTreeNode *SucccDTNode = DT->getNode(Edge.ToBB); - - // If all the other predecessors of "Succ" are dominated by "Succ" itself - // then the new block is the new immediate dominator of "Succ". Otherwise, - // the new block doesn't dominate anything. - if (IsNewIDom[Idx]) - DT->changeImmediateDominator(SucccDTNode, NewDTNode); - ++Idx; - } - NewBBs.clear(); - CriticalEdgesToSplit.clear(); - } + void applySplitCriticalEdges() const; public: static char ID; // Pass ID, replacement for typeid @@ -307,7 +237,7 @@ public: (void)Inserted; assert(Inserted && "A basic block inserted via edge splitting cannot appear twice"); - CriticalEdgesToSplit.push_back(CriticalEdge(FromBB, ToBB, NewBB)); + CriticalEdgesToSplit.push_back({FromBB, ToBB, NewBB}); } }; diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index 4ba4a97..333dcdb 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -257,9 +257,7 @@ public: /// this DBG_VALUE instruction. DIExpression getDebugExpression() const { assert(isDebugValue() && "not a DBG_VALUE"); - DIExpression Expr(getOperand(3).getMetadata()); - assert(Expr.Verify() && "not a DIExpression"); - return Expr; + return cast<MDExpression>(getOperand(3).getMetadata()); } /// emitError - Emit an error referring to the source location of this @@ -1113,8 +1111,7 @@ public: // // Debugging support // - void print(raw_ostream &OS, const TargetMachine *TM = nullptr, - bool SkipOpers = false) const; + void print(raw_ostream &OS, bool SkipOpers = false) const; void dump() const; //===--------------------------------------------------------------------===// @@ -1170,6 +1167,12 @@ public: assert(NumMemRefs == NewMemRefsEnd - NewMemRefs && "Too many memrefs"); } + /// clearMemRefs - Clear this MachineInstr's memory reference descriptor list. + void clearMemRefs() { + MemRefs = nullptr; + NumMemRefs = 0; + } + private: /// getRegInfo - If this instruction is embedded into a MachineFunction, /// return the MachineRegisterInfo object for the current function, otherwise diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h index 8859b6a..e6cb494 100644 --- a/include/llvm/CodeGen/MachineInstrBuilder.h +++ b/include/llvm/CodeGen/MachineInstrBuilder.h @@ -356,7 +356,7 @@ inline MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, unsigned Reg, unsigned Offset, const MDNode *Variable, const MDNode *Expr) { assert(DIVariable(Variable).Verify() && "not a DIVariable"); - assert(DIExpression(Expr).Verify() && "not a DIExpression"); + assert(DIExpression(Expr)->isValid() && "not a DIExpression"); if (IsIndirect) return BuildMI(MF, DL, MCID) .addReg(Reg, RegState::Debug) @@ -383,7 +383,7 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, unsigned Reg, unsigned Offset, const MDNode *Variable, const MDNode *Expr) { assert(DIVariable(Variable).Verify() && "not a DIVariable"); - assert(DIExpression(Expr).Verify() && "not a DIExpression"); + assert(DIExpression(Expr)->isValid() && "not a DIExpression"); MachineFunction &MF = *BB.getParent(); MachineInstr *MI = BuildMI(MF, DL, MCID, IsIndirect, Reg, Offset, Variable, Expr); diff --git a/include/llvm/CodeGen/MachineMemOperand.h b/include/llvm/CodeGen/MachineMemOperand.h index eb5086c..a16c294 100644 --- a/include/llvm/CodeGen/MachineMemOperand.h +++ b/include/llvm/CodeGen/MachineMemOperand.h @@ -199,6 +199,24 @@ public: /// Profile - Gather unique data for the object. /// void Profile(FoldingSetNodeID &ID) const; + + friend bool operator==(const MachineMemOperand &LHS, + const MachineMemOperand &RHS) { + return LHS.getValue() == RHS.getValue() && + LHS.getPseudoValue() == RHS.getPseudoValue() && + LHS.getSize() == RHS.getSize() && + LHS.getOffset() == RHS.getOffset() && + LHS.getFlags() == RHS.getFlags() && + LHS.getAAInfo() == RHS.getAAInfo() && + LHS.getRanges() == RHS.getRanges() && + LHS.getAlignment() == RHS.getAlignment() && + LHS.getAddrSpace() == RHS.getAddrSpace(); + } + + friend bool operator!=(const MachineMemOperand &LHS, + const MachineMemOperand &RHS) { + return !(LHS == RHS); + } }; raw_ostream &operator<<(raw_ostream &OS, const MachineMemOperand &MRO); diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h index eed1e57..04d5361 100644 --- a/include/llvm/CodeGen/MachineOperand.h +++ b/include/llvm/CodeGen/MachineOperand.h @@ -217,7 +217,7 @@ public: /// void clearParent() { ParentMI = nullptr; } - void print(raw_ostream &os, const TargetMachine *TM = nullptr) const; + void print(raw_ostream &os, const TargetRegisterInfo *TRI = nullptr) const; //===--------------------------------------------------------------------===// // Accessors that tell you what kind of MachineOperand you're looking at. diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h index abb04de..001d09f 100644 --- a/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/include/llvm/CodeGen/MachineRegisterInfo.h @@ -182,7 +182,18 @@ public: /// information. void invalidateLiveness() { TracksLiveness = false; } - bool tracksSubRegLiveness() const { return TracksSubRegLiveness; } + /// Returns true if liveness for register class @p RC should be tracked at + /// the subregister level. + bool shouldTrackSubRegLiveness(const TargetRegisterClass &RC) const { + return subRegLivenessEnabled() && RC.HasDisjunctSubRegs; + } + bool shouldTrackSubRegLiveness(unsigned VReg) const { + assert(TargetRegisterInfo::isVirtualRegister(VReg) && "Must pass a VReg"); + return shouldTrackSubRegLiveness(*getRegClass(VReg)); + } + bool subRegLivenessEnabled() const { + return TracksSubRegLiveness; + } void enableSubRegLiveness(bool Enable = true) { TracksSubRegLiveness = Enable; @@ -829,7 +840,6 @@ public: typedef std::iterator<std::forward_iterator_tag, MachineInstr, ptrdiff_t>::pointer pointer; - defusechain_iterator(const defusechain_iterator &I) : Op(I.Op) {} defusechain_iterator() : Op(nullptr) {} bool operator==(const defusechain_iterator &x) const { @@ -932,7 +942,6 @@ public: typedef std::iterator<std::forward_iterator_tag, MachineInstr, ptrdiff_t>::pointer pointer; - defusechain_instr_iterator(const defusechain_instr_iterator &I) : Op(I.Op){} defusechain_instr_iterator() : Op(nullptr) {} bool operator==(const defusechain_instr_iterator &x) const { diff --git a/include/llvm/CodeGen/MachineValueType.h b/include/llvm/CodeGen/MachineValueType.h index 7ad782f..3eb4d0b 100644 --- a/include/llvm/CodeGen/MachineValueType.h +++ b/include/llvm/CodeGen/MachineValueType.h @@ -161,8 +161,8 @@ namespace llvm { SimpleValueType SimpleTy; - MVT() : SimpleTy((SimpleValueType)(INVALID_SIMPLE_VALUE_TYPE)) {} - MVT(SimpleValueType SVT) : SimpleTy(SVT) { } + LLVM_CONSTEXPR MVT() : SimpleTy(INVALID_SIMPLE_VALUE_TYPE) {} + LLVM_CONSTEXPR MVT(SimpleValueType SVT) : SimpleTy(SVT) { } bool operator>(const MVT& S) const { return SimpleTy > S.SimpleTy; } bool operator<(const MVT& S) const { return SimpleTy < S.SimpleTy; } diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index 65b17d3..48e1f21 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -612,13 +612,13 @@ namespace llvm { ModulePass *createForwardControlFlowIntegrityPass(); } // End llvm namespace -/// This initializer registers TargetMachine constructor, so the pass being -/// initialized can use target dependent interfaces. Please do not move this -/// macro to be together with INITIALIZE_PASS, which is a complete target -/// independent initializer, and we don't want to make libScalarOpts depend -/// on libCodeGen. -#define INITIALIZE_TM_PASS(passName, arg, name, cfg, analysis) \ - static void* initialize##passName##PassOnce(PassRegistry &Registry) { \ +/// Target machine pass initializer for passes with dependencies. Use with +/// INITIALIZE_TM_PASS_END. +#define INITIALIZE_TM_PASS_BEGIN INITIALIZE_PASS_BEGIN + +/// Target machine pass initializer for passes with dependencies. Use with +/// INITIALIZE_TM_PASS_BEGIN. +#define INITIALIZE_TM_PASS_END(passName, arg, name, cfg, analysis) \ PassInfo *PI = new PassInfo(name, arg, & passName ::ID, \ PassInfo::NormalCtor_t(callDefaultCtor< passName >), cfg, analysis, \ PassInfo::TargetMachineCtor_t(callTargetMachineCtor< passName >)); \ @@ -629,4 +629,13 @@ namespace llvm { CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \ } +/// This initializer registers TargetMachine constructor, so the pass being +/// initialized can use target dependent interfaces. Please do not move this +/// macro to be together with INITIALIZE_PASS, which is a complete target +/// independent initializer, and we don't want to make libScalarOpts depend +/// on libCodeGen. +#define INITIALIZE_TM_PASS(passName, arg, name, cfg, analysis) \ + INITIALIZE_TM_PASS_BEGIN(passName, arg, name, cfg, analysis) \ + INITIALIZE_TM_PASS_END(passName, arg, name, cfg, analysis) + #endif diff --git a/include/llvm/CodeGen/RegAllocPBQP.h b/include/llvm/CodeGen/RegAllocPBQP.h index c7bb07b..6046e46 100644 --- a/include/llvm/CodeGen/RegAllocPBQP.h +++ b/include/llvm/CodeGen/RegAllocPBQP.h @@ -544,8 +544,10 @@ private: public: SpillCostComparator(const Graph& G) : G(G) {} bool operator()(NodeId N1Id, NodeId N2Id) { - PBQPNum N1SC = G.getNodeCosts(N1Id)[0] / G.getNodeDegree(N1Id); - PBQPNum N2SC = G.getNodeCosts(N2Id)[0] / G.getNodeDegree(N2Id); + PBQPNum N1SC = G.getNodeCosts(N1Id)[0]; + PBQPNum N2SC = G.getNodeCosts(N2Id)[0]; + if (N1SC == N2SC) + return G.getNodeDegree(N1Id) < G.getNodeDegree(N2Id); return N1SC < N2SC; } private: diff --git a/include/llvm/CodeGen/ResourcePriorityQueue.h b/include/llvm/CodeGen/ResourcePriorityQueue.h index 114fe7c..0097e04 100644 --- a/include/llvm/CodeGen/ResourcePriorityQueue.h +++ b/include/llvm/CodeGen/ResourcePriorityQueue.h @@ -64,7 +64,7 @@ namespace llvm { /// ResourcesModel - Represents VLIW state. /// Not limited to VLIW targets per say, but assumes /// definition of DFA by a target. - DFAPacketizer *ResourcesModel; + std::unique_ptr<DFAPacketizer> ResourcesModel; /// Resource model - packet/bundle model. Purely /// internal at the time. @@ -77,10 +77,6 @@ namespace llvm { public: ResourcePriorityQueue(SelectionDAGISel *IS); - ~ResourcePriorityQueue() { - delete ResourcesModel; - } - bool isBottomUp() const override { return false; } void initNodes(std::vector<SUnit> &sunits) override; @@ -124,8 +120,6 @@ namespace llvm { void remove(SUnit *SU) override; - void dump(ScheduleDAG* DAG) const override; - /// scheduledNode - Main resource tracking point. void scheduledNode(SUnit *Node) override; bool isResourceAvailable(SUnit *SU); diff --git a/include/llvm/CodeGen/RuntimeLibcalls.h b/include/llvm/CodeGen/RuntimeLibcalls.h index 64c9c47..2be5de6 100644 --- a/include/llvm/CodeGen/RuntimeLibcalls.h +++ b/include/llvm/CodeGen/RuntimeLibcalls.h @@ -425,6 +425,10 @@ namespace RTLIB { /// getUINTTOFP - Return the UINTTOFP_*_* value for the given types, or /// UNKNOWN_LIBCALL if there is none. Libcall getUINTTOFP(EVT OpVT, EVT RetVT); + + /// Return the SYNC_FETCH_AND_* value for the given opcode and type, or + /// UNKNOWN_LIBCALL if there is none. + Libcall getATOMIC(unsigned Opc, MVT VT); } } diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h index 80aee8c..8391314 100644 --- a/include/llvm/CodeGen/ScheduleDAG.h +++ b/include/llvm/CodeGen/ScheduleDAG.h @@ -628,12 +628,6 @@ namespace llvm { } bool operator!=(const SUnitIterator& x) const { return !operator==(x); } - const SUnitIterator &operator=(const SUnitIterator &I) { - assert(I.Node==Node && "Cannot assign iterators to two different nodes!"); - Operand = I.Operand; - return *this; - } - pointer operator*() const { return Node->Preds[Operand].getSUnit(); } diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h index d53e66d..7acdfc7 100644 --- a/include/llvm/CodeGen/SelectionDAGISel.h +++ b/include/llvm/CodeGen/SelectionDAGISel.h @@ -80,12 +80,12 @@ public: virtual SDNode *Select(SDNode *N) = 0; /// SelectInlineAsmMemoryOperand - Select the specified address as a target - /// addressing mode, according to the specified constraint code. If this does + /// addressing mode, according to the specified constraint. If this does /// not match or is not implemented, return true. The resultant operands /// (which will appear in the machine instruction) should be added to the /// OutOps vector. virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, - char ConstraintCode, + unsigned ConstraintID, std::vector<SDValue> &OutOps) { return true; } diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 0b6240f..2b3e08c 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -50,8 +50,7 @@ template <typename T> struct DenseMapInfo; template <typename T> struct simplify_type; template <typename T> struct ilist_traits; -/// isBinOpWithFlags - Returns true if the opcode is a binary operation -/// with flags. +/// Returns true if the opcode is a binary operation with flags. static bool isBinOpWithFlags(unsigned Opcode) { switch (Opcode) { case ISD::SDIV: @@ -71,7 +70,7 @@ static bool isBinOpWithFlags(unsigned Opcode) { void checkForCycles(const SDNode *N, const SelectionDAG *DAG = nullptr, bool force = false); -/// SDVTList - This represents a list of ValueType's that has been intern'd by +/// This represents a list of ValueType's that has been intern'd by /// a SelectionDAG. Instances of this simple value class are returned by /// SelectionDAG::getVTList(...). /// @@ -83,11 +82,11 @@ struct SDVTList { namespace ISD { /// Node predicates - /// isBuildVectorAllOnes - Return true if the specified node is a + /// Return true if the specified node is a /// BUILD_VECTOR where all of the elements are ~0 or undef. bool isBuildVectorAllOnes(const SDNode *N); - /// isBuildVectorAllZeros - Return true if the specified node is a + /// Return true if the specified node is a /// BUILD_VECTOR where all of the elements are 0 or undef. bool isBuildVectorAllZeros(const SDNode *N); @@ -95,18 +94,22 @@ namespace ISD { /// all ConstantSDNode or undef. bool isBuildVectorOfConstantSDNodes(const SDNode *N); - /// isScalarToVector - Return true if the specified node is a + /// \brief Return true if the specified node is a BUILD_VECTOR node of + /// 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); - /// allOperandsUndef - Return true if the node has at least one operand + /// 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); } // end llvm:ISD namespace //===----------------------------------------------------------------------===// -/// SDValue - Unlike LLVM values, Selection DAG nodes may return multiple +/// Unlike LLVM values, Selection DAG nodes may return multiple /// values as the result of a computation. Many nodes return multiple values, /// from loads (which define a token and a return value) to ADDC (which returns /// a result and a carry value), to calls (which may return an arbitrary number @@ -153,11 +156,10 @@ public: return SDValue(Node, R); } - // isOperandOf - Return true if this node is an operand of N. + // Return true if this node is an operand of N. bool isOperandOf(SDNode *N) const; - /// getValueType - Return the ValueType of the referenced return value. - /// + /// Return the ValueType of the referenced return value. inline EVT getValueType() const; /// Return the simple ValueType of the referenced return value. @@ -165,8 +167,7 @@ public: return getValueType().getSimpleVT(); } - /// getValueSizeInBits - Returns the size of the value in bits. - /// + /// Returns the size of the value in bits. unsigned getValueSizeInBits() const { return getValueType().getSizeInBits(); } @@ -188,22 +189,18 @@ public: inline void dump() const; inline void dumpr() const; - /// reachesChainWithoutSideEffects - Return true if this operand (which must - /// be a chain) reaches the specified operand without crossing any - /// side-effecting instructions. In practice, this looks through token - /// factors and non-volatile loads. In order to remain efficient, this only + /// Return true if this operand (which must be a chain) reaches the + /// specified operand without crossing any side-effecting instructions. + /// In practice, this looks through token factors and non-volatile loads. + /// In order to remain efficient, this only /// looks a couple of nodes in, it does not do an exhaustive search. bool reachesChainWithoutSideEffects(SDValue Dest, unsigned Depth = 2) const; - /// use_empty - Return true if there are no nodes using value ResNo - /// of Node. - /// + /// Return true if there are no nodes using value ResNo of Node. inline bool use_empty() const; - /// hasOneUse - Return true if there is exactly one node using value - /// ResNo of Node. - /// + /// Return true if there is exactly one node using value ResNo of Node. inline bool hasOneUse() const; }; @@ -230,7 +227,7 @@ template<> struct DenseMapInfo<SDValue> { template <> struct isPodLike<SDValue> { static const bool value = true; }; -/// simplify_type specializations - Allow casting operators to work directly on +/// Allow casting operators to work directly on /// SDValues as if they were SDNode*'s. template<> struct simplify_type<SDValue> { typedef SDNode* SimpleType; @@ -245,7 +242,7 @@ template<> struct simplify_type<const SDValue> { } }; -/// SDUse - Represents a use of a SDNode. This class holds an SDValue, +/// Represents a use of a SDNode. This class holds an SDValue, /// which records the SDNode being used and the result number, a /// pointer to the SDNode using the value, and Next and Prev pointers, /// which link together all the uses of an SDNode. @@ -272,30 +269,30 @@ public: /// the SDValue. const SDValue &get() const { return Val; } - /// getUser - This returns the SDNode that contains this Use. + /// This returns the SDNode that contains this Use. SDNode *getUser() { return User; } - /// getNext - Get the next SDUse in the use list. + /// Get the next SDUse in the use list. SDUse *getNext() const { return Next; } - /// getNode - Convenience function for get().getNode(). + /// Convenience function for get().getNode(). SDNode *getNode() const { return Val.getNode(); } - /// getResNo - Convenience function for get().getResNo(). + /// Convenience function for get().getResNo(). unsigned getResNo() const { return Val.getResNo(); } - /// getValueType - Convenience function for get().getValueType(). + /// Convenience function for get().getValueType(). EVT getValueType() const { return Val.getValueType(); } - /// operator== - Convenience function for get().operator== + /// Convenience function for get().operator== bool operator==(const SDValue &V) const { return Val == V; } - /// operator!= - Convenience function for get().operator!= + /// Convenience function for get().operator!= bool operator!=(const SDValue &V) const { return Val != V; } - /// operator< - Convenience function for get().operator< + /// Convenience function for get().operator< bool operator<(const SDValue &V) const { return Val < V; } @@ -306,13 +303,13 @@ private: void setUser(SDNode *p) { User = p; } - /// set - Remove this use from its existing use list, assign it the + /// Remove this use from its existing use list, assign it the /// given value, and add it to the new value's node's use list. inline void set(const SDValue &V); - /// setInitial - like set, but only supports initializing a newly-allocated + /// Like set, but only supports initializing a newly-allocated /// SDUse with a non-null value. inline void setInitial(const SDValue &V); - /// setNode - like set, but only sets the Node portion of the value, + /// Like set, but only sets the Node portion of the value, /// leaving the ResNo portion unmodified. inline void setNode(SDNode *N); @@ -339,47 +336,45 @@ template<> struct simplify_type<SDUse> { }; -/// SDNode - Represents one node in the SelectionDAG. +/// Represents one node in the SelectionDAG. /// class SDNode : public FoldingSetNode, public ilist_node<SDNode> { private: - /// NodeType - The operation that this node performs. - /// + /// The operation that this node performs. int16_t NodeType; - /// OperandsNeedDelete - This is true if OperandList was new[]'d. If true, + /// This is true if OperandList was new[]'d. If true, /// then they will be delete[]'d when the node is destroyed. uint16_t OperandsNeedDelete : 1; - /// HasDebugValue - This tracks whether this node has one or more dbg_value + /// This tracks whether this node has one or more dbg_value /// nodes corresponding to it. uint16_t HasDebugValue : 1; protected: - /// SubclassData - This member is defined by this class, but is not used for + /// This member is defined by this class, but is not used for /// anything. Subclasses can use it to hold whatever state they find useful. /// This field is initialized to zero by the ctor. uint16_t SubclassData : 14; private: - /// NodeId - Unique id per SDNode in the DAG. + /// Unique id per SDNode in the DAG. int NodeId; - /// OperandList - The values that are used by this operation. - /// + /// The values that are used by this operation. SDUse *OperandList; - /// ValueList - The types of the values this node defines. SDNode's may + /// The types of the values this node defines. SDNode's may /// define multiple values simultaneously. const EVT *ValueList; - /// UseList - List of uses for this SDNode. + /// List of uses for this SDNode. SDUse *UseList; - /// NumOperands/NumValues - The number of entries in the Operand/Value list. + /// The number of entries in the Operand/Value list. unsigned short NumOperands, NumValues; - /// debugLoc - source line information. + /// Source line information. DebugLoc debugLoc; // The ordering of the SDNodes. It roughly corresponds to the ordering of the @@ -389,7 +384,7 @@ private: // this ordering. unsigned IROrder; - /// getValueTypeList - Return a pointer to the specified value type. + /// Return a pointer to the specified value type. static const EVT *getValueTypeList(EVT VT); friend class SelectionDAG; @@ -400,17 +395,17 @@ public: // Accessors // - /// getOpcode - Return the SelectionDAG opcode value for this node. For + /// Return the SelectionDAG opcode value for this node. For /// pre-isel nodes (those for which isMachineOpcode returns false), these /// are the opcode values in the ISD and <target>ISD namespaces. For /// post-isel opcodes, see getMachineOpcode. unsigned getOpcode() const { return (unsigned short)NodeType; } - /// isTargetOpcode - Test if this node has a target-specific opcode (in the + /// Test if this node has a target-specific opcode (in the /// \<target\>ISD namespace). bool isTargetOpcode() const { return NodeType >= ISD::BUILTIN_OP_END; } - /// isTargetMemoryOpcode - Test if this node has a target-specific + /// Test if this node has a target-specific /// memory-referencing opcode (in the \<target\>ISD namespace and /// greater than FIRST_TARGET_MEMORY_OPCODE). bool isTargetMemoryOpcode() const { @@ -427,11 +422,11 @@ public: NodeType == ISD::INTRINSIC_VOID) && ((SubclassData >> 13) & 1); } - /// isMachineOpcode - Test if this node has a post-isel opcode, directly + /// Test if this node has a post-isel opcode, directly /// corresponding to a MachineInstr opcode. bool isMachineOpcode() const { return NodeType < 0; } - /// getMachineOpcode - This may only be called if isMachineOpcode returns + /// This may only be called if isMachineOpcode returns /// true. It returns the MachineInstr opcode value that the node's opcode /// corresponds to. unsigned getMachineOpcode() const { @@ -439,50 +434,44 @@ public: return ~NodeType; } - /// getHasDebugValue - get this bit. + /// Get this bit. bool getHasDebugValue() const { return HasDebugValue; } - /// setHasDebugValue - set this bit. + /// Set this bit. void setHasDebugValue(bool b) { HasDebugValue = b; } - /// use_empty - Return true if there are no uses of this node. - /// + /// Return true if there are no uses of this node. bool use_empty() const { return UseList == nullptr; } - /// hasOneUse - Return true if there is exactly one use of this node. - /// + /// Return true if there is exactly one use of this node. bool hasOneUse() const { return !use_empty() && std::next(use_begin()) == use_end(); } - /// use_size - Return the number of uses of this node. This method takes + /// Return the number of uses of this node. This method takes /// time proportional to the number of uses. - /// size_t use_size() const { return std::distance(use_begin(), use_end()); } - /// getNodeId - Return the unique node id. - /// + /// Return the unique node id. int getNodeId() const { return NodeId; } - /// setNodeId - Set unique node id. + /// Set unique node id. void setNodeId(int Id) { NodeId = Id; } - /// getIROrder - Return the node ordering. - /// + /// Return the node ordering. unsigned getIROrder() const { return IROrder; } - /// setIROrder - Set the node ordering. - /// + /// Set the node ordering. void setIROrder(unsigned Order) { IROrder = Order; } - /// getDebugLoc - Return the source location info. + /// Return the source location info. const DebugLoc &getDebugLoc() const { return debugLoc; } - /// setDebugLoc - Set source location info. Try to avoid this, putting + /// Set source location info. Try to avoid this, putting /// it in the constructor is preferable. void setDebugLoc(DebugLoc dl) { debugLoc = std::move(dl); } - /// use_iterator - This class provides iterator support for SDUse + /// This class provides iterator support for SDUse /// operands that use a specific SDNode. class use_iterator : public std::iterator<std::forward_iterator_tag, SDUse, ptrdiff_t> { @@ -506,7 +495,7 @@ public: return !operator==(x); } - /// atEnd - return true if this iterator is at the end of uses list. + /// Return true if this iterator is at the end of uses list. bool atEnd() const { return Op == nullptr; } // Iterator traversal: forward iteration only. @@ -530,17 +519,14 @@ public: SDUse &getUse() const { return *Op; } - /// getOperandNo - Retrieve the operand # of this use in its user. - /// + /// Retrieve the operand # of this use in its user. unsigned getOperandNo() const { assert(Op && "Cannot dereference end iterator!"); return (unsigned)(Op - Op->getUser()->OperandList); } }; - /// use_begin/use_end - Provide iteration support to walk over all uses - /// of an SDNode. - + /// Provide iteration support to walk over all uses of an SDNode. use_iterator use_begin() const { return use_iterator(UseList); } @@ -554,37 +540,34 @@ public: return iterator_range<use_iterator>(use_begin(), use_end()); } - /// hasNUsesOfValue - Return true if there are exactly NUSES uses of the - /// indicated value. This method ignores uses of other values defined by this - /// operation. + /// Return true if there are exactly NUSES uses of the indicated value. + /// This method ignores uses of other values defined by this operation. bool hasNUsesOfValue(unsigned NUses, unsigned Value) const; - /// hasAnyUseOfValue - Return true if there are any use of the indicated - /// value. This method ignores uses of other values defined by this operation. + /// Return true if there are any use of the indicated value. + /// This method ignores uses of other values defined by this operation. bool hasAnyUseOfValue(unsigned Value) const; - /// isOnlyUserOf - Return true if this node is the only use of N. - /// + /// Return true if this node is the only use of N. bool isOnlyUserOf(SDNode *N) const; - /// isOperandOf - Return true if this node is an operand of N. - /// + /// Return true if this node is an operand of N. bool isOperandOf(SDNode *N) const; - /// isPredecessorOf - Return true if this node is a predecessor of N. + /// Return true if this node is a predecessor of N. /// NOTE: Implemented on top of hasPredecessor and every bit as /// expensive. Use carefully. bool isPredecessorOf(const SDNode *N) const { return N->hasPredecessor(this); } - /// hasPredecessor - Return true if N is a predecessor of this node. + /// Return true if N is a predecessor of this node. /// N is either an operand of this node, or can be reached by recursively /// traversing up the operands. /// NOTE: This is an expensive method. Use it carefully. bool hasPredecessor(const SDNode *N) const; - /// hasPredecesorHelper - Return true if N is a predecessor of this node. + /// Return true if N is a predecessor of this node. /// N is either an operand of this node, or can be reached by recursively /// traversing up the operands. /// In this helper the Visited and worklist sets are held externally to @@ -597,12 +580,10 @@ public: SmallPtrSetImpl<const SDNode *> &Visited, SmallVectorImpl<const SDNode *> &Worklist) const; - /// getNumOperands - Return the number of values used by this operation. - /// + /// Return the number of values used by this operation. unsigned getNumOperands() const { return NumOperands; } - /// getConstantOperandVal - Helper method returns the integer value of a - /// ConstantSDNode operand. + /// Helper method returns the integer value of a ConstantSDNode operand. uint64_t getConstantOperandVal(unsigned Num) const; const SDValue &getOperand(unsigned Num) const { @@ -620,7 +601,7 @@ public: return X; } - /// getGluedNode - If this node has a glue operand, return the node + /// If this node has a glue operand, return the node /// to which the glue operand points. Otherwise return NULL. SDNode *getGluedNode() const { if (getNumOperands() != 0 && @@ -645,7 +626,7 @@ public: return FoundNode; } - /// getGluedUser - If this node has a glue value with a user, return + /// If this node has a glue value with a user, return /// the user (there is at most one). Otherwise return NULL. SDNode *getGluedUser() const { for (use_iterator UI = use_begin(), UE = use_end(); UI != UE; ++UI) @@ -654,26 +635,21 @@ public: return nullptr; } - /// getNumValues - Return the number of values defined/returned by this - /// operator. - /// + /// Return the number of values defined/returned by this operator. unsigned getNumValues() const { return NumValues; } - /// getValueType - Return the type of a specified result. - /// + /// Return the type of a specified result. EVT getValueType(unsigned ResNo) const { assert(ResNo < NumValues && "Illegal result number!"); return ValueList[ResNo]; } /// Return the type of a specified result as a simple type. - /// MVT getSimpleValueType(unsigned ResNo) const { return getValueType(ResNo).getSimpleVT(); } - /// getValueSizeInBits - Returns MVT::getSizeInBits(getValueType(ResNo)). - /// + /// Returns MVT::getSizeInBits(getValueType(ResNo)). unsigned getValueSizeInBits(unsigned ResNo) const { return getValueType(ResNo).getSizeInBits(); } @@ -682,8 +658,7 @@ public: value_iterator value_begin() const { return ValueList; } value_iterator value_end() const { return ValueList+NumValues; } - /// getOperationName - Return the opcode of this operation for printing. - /// + /// Return the opcode of this operation for printing. std::string getOperationName(const SelectionDAG *G = nullptr) const; static const char* getIndexedModeName(ISD::MemIndexedMode AM); void print_types(raw_ostream &OS, const SelectionDAG *G) const; @@ -691,7 +666,7 @@ public: void print(raw_ostream &OS, const SelectionDAG *G = nullptr) const; void printr(raw_ostream &OS, const SelectionDAG *G = nullptr) const; - /// printrFull - Print a SelectionDAG node and all children down to + /// Print a SelectionDAG node and all children down to /// the leaves. The given SelectionDAG allows target-specific nodes /// to be printed in human-readable form. Unlike printr, this will /// print the whole DAG, including children that appear multiple @@ -699,7 +674,7 @@ public: /// void printrFull(raw_ostream &O, const SelectionDAG *G = nullptr) const; - /// printrWithDepth - Print a SelectionDAG node and children up to + /// Print a SelectionDAG node and children up to /// depth "depth." The given SelectionDAG allows target-specific /// nodes to be printed in human-readable form. Unlike printr, this /// will print children that appear multiple times wherever they are @@ -709,30 +684,29 @@ public: unsigned depth = 100) const; - /// dump - Dump this node, for debugging. + /// Dump this node, for debugging. void dump() const; - /// dumpr - Dump (recursively) this node and its use-def subgraph. + /// Dump (recursively) this node and its use-def subgraph. void dumpr() const; - /// dump - Dump this node, for debugging. + /// Dump this node, for debugging. /// The given SelectionDAG allows target-specific nodes to be printed /// in human-readable form. void dump(const SelectionDAG *G) const; - /// dumpr - Dump (recursively) this node and its use-def subgraph. + /// Dump (recursively) this node and its use-def subgraph. /// The given SelectionDAG allows target-specific nodes to be printed /// in human-readable form. void dumpr(const SelectionDAG *G) const; - /// dumprFull - printrFull to dbgs(). The given SelectionDAG allows + /// printrFull to dbgs(). The given SelectionDAG allows /// target-specific nodes to be printed in human-readable form. /// Unlike dumpr, this will print the whole DAG, including children /// that appear multiple times. - /// void dumprFull(const SelectionDAG *G = nullptr) const; - /// dumprWithDepth - printrWithDepth to dbgs(). The given + /// printrWithDepth to dbgs(). The given /// SelectionDAG allows target-specific nodes to be printed in /// human-readable form. Unlike dumpr, this will print children /// that appear multiple times wherever they are used. @@ -740,12 +714,10 @@ public: void dumprWithDepth(const SelectionDAG *G = nullptr, unsigned depth = 100) const; - /// Profile - Gather unique data for the node. - /// + /// Gather unique data for the node. void Profile(FoldingSetNodeID &ID) const; - /// addUse - This method should only be used by the SDUse class. - /// + /// This method should only be used by the SDUse class. void addUse(SDUse &U) { U.addToList(&UseList); } protected: @@ -786,7 +758,7 @@ protected: "NumValues wasn't wide enough for its operands!"); } - /// InitOperands - Initialize the operands list of this with 1 operand. + /// Initialize the operands list of this with 1 operand. void InitOperands(SDUse *Ops, const SDValue &Op0) { Ops[0].setUser(this); Ops[0].setInitial(Op0); @@ -795,7 +767,7 @@ protected: checkForCycles(this); } - /// InitOperands - Initialize the operands list of this with 2 operands. + /// Initialize the operands list of this with 2 operands. void InitOperands(SDUse *Ops, const SDValue &Op0, const SDValue &Op1) { Ops[0].setUser(this); Ops[0].setInitial(Op0); @@ -806,7 +778,7 @@ protected: checkForCycles(this); } - /// InitOperands - Initialize the operands list of this with 3 operands. + /// Initialize the operands list of this with 3 operands. void InitOperands(SDUse *Ops, const SDValue &Op0, const SDValue &Op1, const SDValue &Op2) { Ops[0].setUser(this); @@ -820,7 +792,7 @@ protected: checkForCycles(this); } - /// InitOperands - Initialize the operands list of this with 4 operands. + /// Initialize the operands list of this with 4 operands. void InitOperands(SDUse *Ops, const SDValue &Op0, const SDValue &Op1, const SDValue &Op2, const SDValue &Op3) { Ops[0].setUser(this); @@ -836,7 +808,7 @@ protected: checkForCycles(this); } - /// InitOperands - Initialize the operands list of this with N operands. + /// Initialize the operands list of this with N operands. void InitOperands(SDUse *Ops, const SDValue *Vals, unsigned N) { for (unsigned i = 0; i != N; ++i) { Ops[i].setUser(this); @@ -849,8 +821,7 @@ protected: checkForCycles(this); } - /// DropOperands - Release the operands and set this node to have - /// zero operands. + /// Release the operands and set this node to have zero operands. void DropOperands(); }; @@ -972,7 +943,7 @@ inline void SDUse::setNode(SDNode *N) { if (N) N->addUse(*this); } -/// UnarySDNode - This class is used for single-operand SDNodes. This is solely +/// 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 { SDUse Op; @@ -984,7 +955,7 @@ public: } }; -/// BinarySDNode - This class is used for two-operand SDNodes. This is solely +/// This class is used for two-operand SDNodes. This is solely /// to allow co-allocation of node operands with the node itself. class BinarySDNode : public SDNode { SDUse Ops[2]; @@ -996,7 +967,7 @@ public: } }; -/// BinaryWithFlagsSDNode - This class is an extension of BinarySDNode +/// This class is an extension of BinarySDNode /// used from those opcodes that have associated extra flags. class BinaryWithFlagsSDNode : public BinarySDNode { enum { NUW = (1 << 0), NSW = (1 << 1), EXACT = (1 << 2) }; @@ -1005,8 +976,7 @@ public: BinaryWithFlagsSDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs, SDValue X, SDValue Y) : BinarySDNode(Opc, Order, dl, VTs, X, Y) {} - /// getRawSubclassData - Return the SubclassData value, which contains an - /// encoding of the flags. + /// Return the SubclassData value, which contains an encoding of the flags. /// This function should be used to add subclass data to the NodeID value. unsigned getRawSubclassData() const { return SubclassData; } void setHasNoUnsignedWrap(bool b) { @@ -1026,7 +996,7 @@ public: } }; -/// TernarySDNode - This class is used for three-operand SDNodes. This is solely +/// This class is used for three-operand SDNodes. This is solely /// to allow co-allocation of node operands with the node itself. class TernarySDNode : public SDNode { SDUse Ops[3]; @@ -1039,7 +1009,7 @@ public: }; -/// HandleSDNode - This class is used to form a handle around another node that +/// This class is used to form a handle around another node that /// is persistent and is updated across invocations of replaceAllUsesWith on its /// operand. This node should be directly created by end-users and not added to /// the AllNodes list. @@ -1074,11 +1044,11 @@ public: /// Abstact virtual class for operations for memory operations class MemSDNode : public SDNode { private: - // MemoryVT - VT of in-memory value. + // VT of in-memory value. EVT MemoryVT; protected: - /// MMO - Memory reference information. + /// Memory reference information. MachineMemOperand *MMO; public: @@ -1099,7 +1069,7 @@ public: return MMO->getAlignment(); } - /// getRawSubclassData - Return the SubclassData value, which contains an + /// Return the SubclassData value, which contains an /// encoding of the volatile flag, as well as bits used by subclasses. This /// function should only be used to compute a FoldingSetNodeID value. unsigned getRawSubclassData() const { @@ -1128,10 +1098,10 @@ public: /// Returns the Ranges that describes the dereference. const MDNode *getRanges() const { return MMO->getRanges(); } - /// getMemoryVT - Return the type of the in-memory value. + /// Return the type of the in-memory value. EVT getMemoryVT() const { return MemoryVT; } - /// getMemOperand - Return a MachineMemOperand object describing the memory + /// Return a MachineMemOperand object describing the memory /// reference performed by operation. MachineMemOperand *getMemOperand() const { return MMO; } @@ -1139,12 +1109,12 @@ public: return MMO->getPointerInfo(); } - /// getAddressSpace - Return the address space for the associated pointer + /// Return the address space for the associated pointer unsigned getAddressSpace() const { return getPointerInfo().getAddrSpace(); } - /// refineAlignment - Update this MemSDNode's MachineMemOperand information + /// Update this MemSDNode's MachineMemOperand information /// to reflect the alignment of NewMMO, if it has a greater alignment. /// This must only be used when the new alignment applies to all users of /// this MachineMemOperand. @@ -1186,8 +1156,7 @@ public: } }; -/// AtomicSDNode - A SDNode reprenting atomic operations. -/// +/// A SDNode reprenting atomic operations. class AtomicSDNode : public MemSDNode { SDUse Ops[4]; @@ -1300,7 +1269,7 @@ public: } }; -/// MemIntrinsicSDNode - This SDNode is used for target intrinsics that touch +/// This SDNode is used for target intrinsics that touch /// memory and need an associated MachineMemOperand. Its opcode may be /// INTRINSIC_VOID, INTRINSIC_W_CHAIN, PREFETCH, or a target-specific opcode /// with a value not less than FIRST_TARGET_MEMORY_OPCODE. @@ -1323,7 +1292,7 @@ public: } }; -/// ShuffleVectorSDNode - This SDNode is used to implement the code generator +/// This SDNode is used to implement the code generator /// support for the llvm IR shufflevector instruction. It combines elements /// from two input vectors into a new input vector, with the selection and /// ordering of elements determined by an array of integers, referred to as @@ -1367,6 +1336,21 @@ public: } static bool isSplatMask(const int *Mask, EVT VT); + /// Change values in a shuffle permute mask assuming + /// the two vector operands have swapped position. + static void commuteMask(SmallVectorImpl<int> &Mask) { + unsigned NumElems = Mask.size(); + for (unsigned i = 0; i != NumElems; ++i) { + int idx = Mask[i]; + if (idx < 0) + continue; + else if (idx < (int)NumElems) + Mask[i] = idx + NumElems; + else + Mask[i] = idx - NumElems; + } + } + static bool classof(const SDNode *N) { return N->getOpcode() == ISD::VECTOR_SHUFFLE; } @@ -1411,19 +1395,19 @@ public: const APFloat& getValueAPF() const { return Value->getValueAPF(); } const ConstantFP *getConstantFPValue() const { return Value; } - /// isZero - Return true if the value is positive or negative zero. + /// Return true if the value is positive or negative zero. bool isZero() const { return Value->isZero(); } - /// isNaN - Return true if the value is a NaN. + /// Return true if the value is a NaN. bool isNaN() const { return Value->isNaN(); } - /// isInfinity - Return true if the value is an infinity + /// Return true if the value is an infinity bool isInfinity() const { return Value->isInfinity(); } - /// isNegative - Return true if the value is negative. + /// Return true if the value is negative. bool isNegative() const { return Value->isNegative(); } - /// isExactlyValue - We don't rely on operator== working on double values, as + /// We don't rely on operator== working on double values, as /// it returns true for things that are clearly not equal, like -0.0 and 0.0. /// As such, this method can be used to do an exact bit-for-bit comparison of /// two floating point values. @@ -1607,13 +1591,12 @@ public: } }; -/// BuildVectorSDNode - A "pseudo-class" with methods for operating on -/// BUILD_VECTORs. +/// A "pseudo-class" with methods for operating on BUILD_VECTORs. class BuildVectorSDNode : public SDNode { // These are constructed as SDNodes and then cast to BuildVectorSDNodes. explicit BuildVectorSDNode() = delete; public: - /// isConstantSplat - Check if this is a constant splat, and if so, find the + /// Check if this is a constant splat, and if so, find the /// smallest element size that splats the vector. If MinSplatBits is /// nonzero, the element size must be at least that large. Note that the /// splat element may be the entire vector (i.e., a one element vector). @@ -1656,7 +1639,7 @@ public: } }; -/// SrcValueSDNode - An SDNode that holds an arbitrary LLVM IR Value. This is +/// An SDNode that holds an arbitrary LLVM IR Value. This is /// used when the SelectionDAG needs to make a simple reference to something /// in the LLVM IR representation. /// @@ -1668,7 +1651,7 @@ class SrcValueSDNode : public SDNode { : SDNode(ISD::SRCVALUE, 0, DebugLoc(), getSDVTList(MVT::Other)), V(v) {} public: - /// getValue - return the contained Value. + /// Return the contained Value. const Value *getValue() const { return V; } static bool classof(const SDNode *N) { @@ -1795,7 +1778,7 @@ public: } }; -/// CvtRndSatSDNode - NOTE: avoid using this node as this may disappear in the +/// NOTE: avoid using this node as this may disappear in the /// future and most targets don't support it. class CvtRndSatSDNode : public SDNode { ISD::CvtCode CvtCode; @@ -1814,7 +1797,7 @@ public: } }; -/// VTSDNode - This class is used to represent EVT's, which are used +/// This class is used to represent EVT's, which are used /// to parameterize some operations. class VTSDNode : public SDNode { EVT ValueType; @@ -1832,8 +1815,7 @@ public: } }; -/// LSBaseSDNode - Base class for LoadSDNode and StoreSDNode -/// +/// Base class for LoadSDNode and StoreSDNode class LSBaseSDNode : public MemSDNode { //! Operand array for load and store /*! @@ -1859,16 +1841,16 @@ public: return getOperand(getOpcode() == ISD::LOAD ? 2 : 3); } - /// getAddressingMode - Return the addressing mode for this load or store: + /// Return the addressing mode for this load or store: /// unindexed, pre-inc, pre-dec, post-inc, or post-dec. ISD::MemIndexedMode getAddressingMode() const { return ISD::MemIndexedMode((SubclassData >> 2) & 7); } - /// isIndexed - Return true if this is a pre/post inc/dec load/store. + /// Return true if this is a pre/post inc/dec load/store. bool isIndexed() const { return getAddressingMode() != ISD::UNINDEXED; } - /// isUnindexed - Return true if this is NOT a pre/post inc/dec load/store. + /// Return true if this is NOT a pre/post inc/dec load/store. bool isUnindexed() const { return getAddressingMode() == ISD::UNINDEXED; } static bool classof(const SDNode *N) { @@ -1877,8 +1859,7 @@ public: } }; -/// LoadSDNode - This class is used to represent ISD::LOAD nodes. -/// +/// This class is used to represent ISD::LOAD nodes. class LoadSDNode : public LSBaseSDNode { friend class SelectionDAG; LoadSDNode(SDValue *ChainPtrOff, unsigned Order, DebugLoc dl, SDVTList VTs, @@ -1892,7 +1873,7 @@ class LoadSDNode : public LSBaseSDNode { } public: - /// getExtensionType - Return whether this is a plain node, + /// Return whether this is a plain node, /// or one of the varieties of value-extending loads. ISD::LoadExtType getExtensionType() const { return ISD::LoadExtType(SubclassData & 3); @@ -1906,8 +1887,7 @@ public: } }; -/// StoreSDNode - This class is used to represent ISD::STORE nodes. -/// +/// This class is used to represent ISD::STORE nodes. class StoreSDNode : public LSBaseSDNode { friend class SelectionDAG; StoreSDNode(SDValue *ChainValuePtrOff, unsigned Order, DebugLoc dl, @@ -1922,7 +1902,7 @@ class StoreSDNode : public LSBaseSDNode { } public: - /// isTruncatingStore - Return true if the op does a truncation before store. + /// Return true if the op does a truncation before store. /// For integers this is the same as doing a TRUNCATE and storing the result. /// For floats, it is the same as doing an FP_ROUND and storing the result. bool isTruncatingStore() const { return SubclassData & 1; } @@ -1936,9 +1916,7 @@ public: } }; -/// MaskedLoadStoreSDNode - This is a base class is used to represent MLOAD and -/// MSTORE nodes -/// +/// This base class is used to represent MLOAD and MSTORE nodes class MaskedLoadStoreSDNode : public MemSDNode { // Operands SDUse Ops[4]; @@ -1964,8 +1942,7 @@ public: } }; -/// MaskedLoadSDNode - This class is used to represent an MLOAD node -/// +/// This class is used to represent an MLOAD node class MaskedLoadSDNode : public MaskedLoadStoreSDNode { public: friend class SelectionDAG; @@ -1986,8 +1963,7 @@ public: } }; -/// MaskedStoreSDNode - This class is used to represent an MSTORE node -/// +/// This class is used to represent an MSTORE node class MaskedStoreSDNode : public MaskedLoadStoreSDNode { public: @@ -1999,7 +1975,7 @@ public: VTs, MemVT, MMO) { SubclassData |= (unsigned short)isTrunc; } - /// isTruncatingStore - Return true if the op does a truncation before store. + /// Return true if the op does a truncation before store. /// For integers this is the same as doing a TRUNCATE and storing the result. /// For floats, it is the same as doing an FP_ROUND and storing the result. bool isTruncatingStore() const { return SubclassData & 1; } @@ -2011,10 +1987,9 @@ public: } }; -/// MachineSDNode - An SDNode that represents everything that will be needed +/// An SDNode that represents everything that will be needed /// to construct a MachineInstr. These nodes are created during the /// instruction selection proper phase. -/// class MachineSDNode : public SDNode { public: typedef MachineMemOperand **mmo_iterator; @@ -2024,11 +1999,11 @@ private: MachineSDNode(unsigned Opc, unsigned Order, const DebugLoc DL, SDVTList VTs) : SDNode(Opc, Order, DL, VTs), MemRefs(nullptr), MemRefsEnd(nullptr) {} - /// LocalOperands - Operands for this instruction, if they fit here. If + /// Operands for this instruction, if they fit here. If /// they don't, this field is unused. SDUse LocalOperands[4]; - /// MemRefs - Memory reference descriptions for this instruction. + /// Memory reference descriptions for this instruction. mmo_iterator MemRefs; mmo_iterator MemRefsEnd; @@ -2037,7 +2012,7 @@ public: mmo_iterator memoperands_end() const { return MemRefsEnd; } bool memoperands_empty() const { return MemRefsEnd == MemRefs; } - /// setMemRefs - Assign this MachineSDNodes's memory reference descriptor + /// Assign this MachineSDNodes's memory reference descriptor /// list. This does not transfer ownership. void setMemRefs(mmo_iterator NewMemRefs, mmo_iterator NewMemRefsEnd) { for (mmo_iterator MMI = NewMemRefs, MME = NewMemRefsEnd; MMI != MME; ++MMI) @@ -2063,12 +2038,6 @@ public: } bool operator!=(const SDNodeIterator& x) const { return !operator==(x); } - const SDNodeIterator &operator=(const SDNodeIterator &I) { - assert(I.Node == Node && "Cannot assign iterators to two different nodes!"); - Operand = I.Operand; - return *this; - } - pointer operator*() const { return Node->getOperand(Operand).getNode(); } @@ -2108,60 +2077,51 @@ template <> struct GraphTraits<SDNode*> { } }; -/// LargestSDNode - The largest SDNode class. -/// +/// The largest SDNode class. typedef AtomicSDNode LargestSDNode; -/// MostAlignedSDNode - The SDNode class with the greatest alignment -/// requirement. -/// +/// The SDNode class with the greatest alignment requirement. typedef GlobalAddressSDNode MostAlignedSDNode; namespace ISD { - /// isNormalLoad - Returns true if the specified node is a non-extending - /// and unindexed load. + /// Returns true if the specified node is a non-extending and unindexed load. inline bool isNormalLoad(const SDNode *N) { const LoadSDNode *Ld = dyn_cast<LoadSDNode>(N); return Ld && Ld->getExtensionType() == ISD::NON_EXTLOAD && Ld->getAddressingMode() == ISD::UNINDEXED; } - /// isNON_EXTLoad - Returns true if the specified node is a non-extending - /// load. + /// Returns true if the specified node is a non-extending load. inline bool isNON_EXTLoad(const SDNode *N) { return isa<LoadSDNode>(N) && cast<LoadSDNode>(N)->getExtensionType() == ISD::NON_EXTLOAD; } - /// isEXTLoad - Returns true if the specified node is a EXTLOAD. - /// + /// Returns true if the specified node is a EXTLOAD. inline bool isEXTLoad(const SDNode *N) { return isa<LoadSDNode>(N) && cast<LoadSDNode>(N)->getExtensionType() == ISD::EXTLOAD; } - /// isSEXTLoad - Returns true if the specified node is a SEXTLOAD. - /// + /// Returns true if the specified node is a SEXTLOAD. inline bool isSEXTLoad(const SDNode *N) { return isa<LoadSDNode>(N) && cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD; } - /// isZEXTLoad - Returns true if the specified node is a ZEXTLOAD. - /// + /// Returns true if the specified node is a ZEXTLOAD. inline bool isZEXTLoad(const SDNode *N) { return isa<LoadSDNode>(N) && cast<LoadSDNode>(N)->getExtensionType() == ISD::ZEXTLOAD; } - /// isUNINDEXEDLoad - Returns true if the specified node is an unindexed load. - /// + /// Returns true if the specified node is an unindexed load. inline bool isUNINDEXEDLoad(const SDNode *N) { return isa<LoadSDNode>(N) && cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED; } - /// isNormalStore - Returns true if the specified node is a non-truncating + /// Returns true if the specified node is a non-truncating /// and unindexed store. inline bool isNormalStore(const SDNode *N) { const StoreSDNode *St = dyn_cast<StoreSDNode>(N); @@ -2169,20 +2129,17 @@ namespace ISD { St->getAddressingMode() == ISD::UNINDEXED; } - /// isNON_TRUNCStore - Returns true if the specified node is a non-truncating - /// store. + /// Returns true if the specified node is a non-truncating store. inline bool isNON_TRUNCStore(const SDNode *N) { return isa<StoreSDNode>(N) && !cast<StoreSDNode>(N)->isTruncatingStore(); } - /// isTRUNCStore - Returns true if the specified node is a truncating - /// store. + /// Returns true if the specified node is a truncating store. inline bool isTRUNCStore(const SDNode *N) { return isa<StoreSDNode>(N) && cast<StoreSDNode>(N)->isTruncatingStore(); } - /// isUNINDEXEDStore - Returns true if the specified node is an - /// unindexed store. + /// Returns true if the specified node is an unindexed store. inline bool isUNINDEXEDStore(const SDNode *N) { return isa<StoreSDNode>(N) && cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED; diff --git a/include/llvm/CodeGen/StackMapLivenessAnalysis.h b/include/llvm/CodeGen/StackMapLivenessAnalysis.h deleted file mode 100644 index f67a6e9..0000000 --- a/include/llvm/CodeGen/StackMapLivenessAnalysis.h +++ /dev/null @@ -1,64 +0,0 @@ -//===--- StackMapLivenessAnalysis - StackMap Liveness Analysis --*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This pass calculates the liveness for each basic block in a function and -// attaches the register live-out information to a patchpoint intrinsic (if -// present). -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CODEGEN_STACKMAPLIVENESSANALYSIS_H -#define LLVM_CODEGEN_STACKMAPLIVENESSANALYSIS_H - -#include "llvm/CodeGen/LivePhysRegs.h" -#include "llvm/CodeGen/MachineFunctionPass.h" - - -namespace llvm { - -/// \brief This pass calculates the liveness information for each basic block in -/// a function and attaches the register live-out information to a patchpoint -/// intrinsic if present. -/// -/// This pass can be disabled via the -enable-patchpoint-liveness=false flag. -/// The pass skips functions that don't have any patchpoint intrinsics. The -/// information provided by this pass is optional and not required by the -/// aformentioned intrinsic to function. -class StackMapLiveness : public MachineFunctionPass { - MachineFunction *MF; - const TargetRegisterInfo *TRI; - LivePhysRegs LiveRegs; -public: - static char ID; - - /// \brief Default construct and initialize the pass. - StackMapLiveness(); - - /// \brief Tell the pass manager which passes we depend on and what - /// information we preserve. - void getAnalysisUsage(AnalysisUsage &AU) const override; - - /// \brief Calculate the liveness information for the given machine function. - bool runOnMachineFunction(MachineFunction &MF) override; - -private: - /// \brief Performs the actual liveness calculation for the function. - bool calculateLiveness(); - - /// \brief Add the current register live set to the instruction. - void addLiveOutSetToMI(MachineInstr &MI); - - /// \brief Create a register mask and initialize it with the registers from - /// the register live set. - uint32_t *createRegisterMask() const; -}; - -} // llvm namespace - -#endif diff --git a/include/llvm/CodeGen/StackMaps.h b/include/llvm/CodeGen/StackMaps.h index 4e48afe..caec994 100644 --- a/include/llvm/CodeGen/StackMaps.h +++ b/include/llvm/CodeGen/StackMaps.h @@ -14,6 +14,7 @@ #include "llvm/ADT/MapVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/MachineInstr.h" +#include "llvm/Support/Debug.h" #include <map> #include <vector> @@ -245,7 +246,10 @@ private: void emitConstantPoolEntries(MCStreamer &OS); /// \brief Emit the callsite info for each stackmap/patchpoint intrinsic call. - void emitCallsiteEntries(MCStreamer &OS, const TargetRegisterInfo *TRI); + void emitCallsiteEntries(MCStreamer &OS); + + void print(raw_ostream &OS); + void debug() { print(dbgs()); } }; } diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index 348c634..75920a3 100644 --- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -88,6 +88,7 @@ public: class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile { public: virtual ~TargetLoweringObjectFileMachO() {} + TargetLoweringObjectFileMachO(); /// Extract the dependent library name from a linker option string. Returns /// StringRef() if the option does not specify a library. @@ -122,6 +123,12 @@ public: MCSymbol *getCFIPersonalitySymbol(const GlobalValue *GV, Mangler &Mang, const TargetMachine &TM, MachineModuleInfo *MMI) const override; + + /// Get MachO PC relative GOT entry relocation + const MCExpr *getIndirectSymViaGOTPCRel(const MCSymbol *Sym, + const MCValue &MV, int64_t Offset, + MachineModuleInfo *MMI, + MCStreamer &Streamer) const override; }; @@ -140,6 +147,14 @@ public: SectionKind Kind, Mangler &Mang, const TargetMachine &TM) const override; + void getNameWithPrefix(SmallVectorImpl<char> &OutName, const GlobalValue *GV, + bool CannotUsePrivateLabel, Mangler &Mang, + const TargetMachine &TM) const override; + + const MCSection * + getSectionForJumpTable(const Function &F, Mangler &Mang, + const TargetMachine &TM) const override; + /// Extract the dependent library name from a linker option string. Returns /// StringRef() if the option does not specify a library. StringRef getDepLibFromLinkerOpt(StringRef LinkerOption) const override; diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h index 4e93940..e1a9fd3 100644 --- a/include/llvm/CodeGen/ValueTypes.h +++ b/include/llvm/CodeGen/ValueTypes.h @@ -34,10 +34,9 @@ namespace llvm { Type *LLVMTy; public: - EVT() : V((MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE)), - LLVMTy(nullptr) {} - EVT(MVT::SimpleValueType SVT) : V(SVT), LLVMTy(nullptr) { } - EVT(MVT S) : V(S), LLVMTy(nullptr) {} + LLVM_CONSTEXPR EVT() : V(MVT::INVALID_SIMPLE_VALUE_TYPE), LLVMTy(nullptr) {} + LLVM_CONSTEXPR EVT(MVT::SimpleValueType SVT) : V(SVT), LLVMTy(nullptr) {} + LLVM_CONSTEXPR EVT(MVT S) : V(S), LLVMTy(nullptr) {} bool operator==(EVT VT) const { return !(*this != VT); |