diff options
author | dim <dim@FreeBSD.org> | 2011-10-20 21:10:27 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2011-10-20 21:10:27 +0000 |
commit | 7b3392326c40c3c20697816acae597ba7b3144eb (patch) | |
tree | 2cbcf22585e99f8a87d12d5ff94f392c0d266819 /include/llvm/CodeGen | |
parent | 1176aa52646fe641a4243a246aa7f960c708a274 (diff) | |
download | FreeBSD-src-7b3392326c40c3c20697816acae597ba7b3144eb.zip FreeBSD-src-7b3392326c40c3c20697816acae597ba7b3144eb.tar.gz |
Vendor import of llvm release_30 branch r142614:
http://llvm.org/svn/llvm-project/llvm/branches/release_30@142614
Diffstat (limited to 'include/llvm/CodeGen')
24 files changed, 639 insertions, 352 deletions
diff --git a/include/llvm/CodeGen/Analysis.h b/include/llvm/CodeGen/Analysis.h index f8a7029..d8e6407 100644 --- a/include/llvm/CodeGen/Analysis.h +++ b/include/llvm/CodeGen/Analysis.h @@ -33,12 +33,12 @@ class SelectionDAG; /// of insertvalue or extractvalue indices that identify a member, return /// the linearized index of the start of the member. /// -unsigned ComputeLinearIndex(const Type *Ty, +unsigned ComputeLinearIndex(Type *Ty, const unsigned *Indices, const unsigned *IndicesEnd, unsigned CurIndex = 0); -inline unsigned ComputeLinearIndex(const Type *Ty, +inline unsigned ComputeLinearIndex(Type *Ty, ArrayRef<unsigned> Indices, unsigned CurIndex = 0) { return ComputeLinearIndex(Ty, Indices.begin(), Indices.end(), CurIndex); @@ -51,7 +51,7 @@ inline unsigned ComputeLinearIndex(const Type *Ty, /// If Offsets is non-null, it points to a vector to be filled in /// with the in-memory offsets of each of the individual values. /// -void ComputeValueVTs(const TargetLowering &TLI, const Type *Ty, +void ComputeValueVTs(const TargetLowering &TLI, Type *Ty, SmallVectorImpl<EVT> &ValueVTs, SmallVectorImpl<uint64_t> *Offsets = 0, uint64_t StartingOffset = 0); diff --git a/include/llvm/CodeGen/CalcSpillWeights.h b/include/llvm/CodeGen/CalcSpillWeights.h index 60edcc5..2f76a6c 100644 --- a/include/llvm/CodeGen/CalcSpillWeights.h +++ b/include/llvm/CodeGen/CalcSpillWeights.h @@ -49,11 +49,6 @@ namespace llvm { const MachineLoopInfo &loops) : MF(mf), LIS(lis), Loops(loops) {} - /// CalculateRegClass - recompute the register class for reg from its uses. - /// Since the register class can affect the allocation hint, this function - /// should be called before CalculateWeightAndHint if both are called. - void CalculateRegClass(unsigned reg); - /// CalculateWeightAndHint - (re)compute li's spill weight and allocation /// hint. void CalculateWeightAndHint(LiveInterval &li); diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h index 962a4e2..18202d9 100644 --- a/include/llvm/CodeGen/FastISel.h +++ b/include/llvm/CodeGen/FastISel.h @@ -54,8 +54,18 @@ protected: const TargetInstrInfo &TII; const TargetLowering &TLI; const TargetRegisterInfo &TRI; + + /// The position of the last instruction for materializing constants + /// for use in the current block. It resets to EmitStartPt when it + /// makes sense (for example, it's usually profitable to avoid function + /// calls between the definition and the use) MachineInstr *LastLocalValue; + /// The top most instruction in the current block that is allowed for + /// emitting local variables. LastLocalValue resets to EmitStartPt when + /// it makes sense (for example, on function calls) + MachineInstr *EmitStartPt; + public: /// getLastLocalValue - Return the position of the last instruction /// emitted for materializing constants for use in the current block. @@ -63,7 +73,10 @@ public: /// setLastLocalValue - Update the position of the last instruction /// emitted for materializing constants for use in the current block. - void setLastLocalValue(MachineInstr *I) { LastLocalValue = I; } + void setLastLocalValue(MachineInstr *I) { + EmitStartPt = I; + LastLocalValue = I; + } /// startNewBlock - Set the current block to which generated machine /// instructions will be appended, and clear the local CSE map. @@ -358,6 +371,11 @@ private: /// be materialized with new instructions. unsigned materializeRegForValue(const Value *V, MVT VT); + /// flushLocalValueMap - clears LocalValueMap and moves the area for the + /// new local variables to the beginning of the block. It helps to avoid + /// spilling cached variables across heavy instructions like calls. + void flushLocalValueMap(); + /// hasTrivialKill - Test whether the given value has exactly one use. bool hasTrivialKill(const Value *V) const; }; diff --git a/include/llvm/CodeGen/FunctionLoweringInfo.h b/include/llvm/CodeGen/FunctionLoweringInfo.h index 84bbf48..09dac85 100644 --- a/include/llvm/CodeGen/FunctionLoweringInfo.h +++ b/include/llvm/CodeGen/FunctionLoweringInfo.h @@ -19,6 +19,7 @@ #include "llvm/Instructions.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/IndexedMap.h" #include "llvm/ADT/SmallVector.h" #ifndef NDEBUG @@ -139,7 +140,7 @@ public: unsigned CreateReg(EVT VT); - unsigned CreateRegs(const Type *Ty); + unsigned CreateRegs(Type *Ty); unsigned InitializeRegForValue(const Value *V) { unsigned &R = ValueMap[V]; @@ -198,12 +199,12 @@ public: LiveOutRegInfo[Reg].IsValid = false; } - /// setByValArgumentFrameIndex - Record frame index for the byval + /// setArgumentFrameIndex - Record frame index for the byval /// argument. - void setByValArgumentFrameIndex(const Argument *A, int FI); + void setArgumentFrameIndex(const Argument *A, int FI); - /// getByValArgumentFrameIndex - Get frame index for the byval argument. - int getByValArgumentFrameIndex(const Argument *A); + /// getArgumentFrameIndex - Get frame index for the byval argument. + int getArgumentFrameIndex(const Argument *A); private: /// LiveOutRegInfo - Information about live out vregs. @@ -220,6 +221,11 @@ void AddCatchInfo(const CallInst &I, void CopyCatchInfo(const BasicBlock *SuccBB, const BasicBlock *LPad, MachineModuleInfo *MMI, FunctionLoweringInfo &FLI); +/// AddLandingPadInfo - Extract the exception handling information from the +/// landingpad instruction and add them to the specified machine module info. +void AddLandingPadInfo(const LandingPadInst &I, MachineModuleInfo &MMI, + MachineBasicBlock *MBB); + } // end namespace llvm #endif diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h index 459cecd..184e96d 100644 --- a/include/llvm/CodeGen/ISDOpcodes.h +++ b/include/llvm/CodeGen/ISDOpcodes.h @@ -95,7 +95,7 @@ namespace ISD { // execution to HANDLER. Many platform-related details also :) EH_RETURN, - // OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) + // RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) // This corresponds to the eh.sjlj.setjmp intrinsic. // It takes an input chain and a pointer to the jump buffer as inputs // and returns an outchain. @@ -323,6 +323,12 @@ namespace ISD { // i1 then the high bits must conform to getBooleanContents. SELECT, + // Select with a vector condition (op #0) and two vector operands (ops #1 + // and #2), returning a vector result. All vectors have the same length. + // Much like the scalar select and setcc, each bit in the condition selects + // whether the corresponding result element is taken from op #1 or op #2. + VSELECT, + // Select with condition operator - This selects between a true value and // a false value (ops #2 and #3) based on the boolean result of comparing // the lhs and rhs (ops #0 and #1) of a conditional expression with the @@ -333,16 +339,10 @@ namespace ISD { // true. If the result value type is not i1 then the high bits conform // to getBooleanContents. The operands to this are the left and right // operands to compare (ops #0, and #1) and the condition code to compare - // them with (op #2) as a CondCodeSDNode. + // them with (op #2) as a CondCodeSDNode. If the operands are vector types + // then the result type must also be a vector type. SETCC, - // RESULT = VSETCC(LHS, RHS, COND) operator - This evaluates to a vector of - // integer elements with all bits of the result elements set to true if the - // comparison is true or all cleared if the comparison is false. The - // operands to this are the left and right operands to compare (LHS/RHS) and - // the condition code to compare them with (COND) as a CondCodeSDNode. - VSETCC, - // SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded // integer shift operations, just like ADD/SUB_PARTS. The operation // ordering is: @@ -566,14 +566,19 @@ namespace ISD { // HANDLENODE node - Used as a handle for various purposes. HANDLENODE, - // TRAMPOLINE - This corresponds to the init_trampoline intrinsic. - // It takes as input a token chain, the pointer to the trampoline, - // the pointer to the nested function, the pointer to pass for the - // 'nest' parameter, a SRCVALUE for the trampoline and another for - // the nested function (allowing targets to access the original - // Function*). It produces the result of the intrinsic and a token - // chain as output. - TRAMPOLINE, + // INIT_TRAMPOLINE - This corresponds to the init_trampoline intrinsic. It + // takes as input a token chain, the pointer to the trampoline, the pointer + // to the nested function, the pointer to pass for the 'nest' parameter, a + // SRCVALUE for the trampoline and another for the nested function (allowing + // targets to access the original Function*). It produces a token chain as + // output. + INIT_TRAMPOLINE, + + // ADJUST_TRAMPOLINE - This corresponds to the adjust_trampoline intrinsic. + // It takes a pointer to the trampoline and produces a (possibly) new + // pointer to the same trampoline with platform-specific adjustments + // applied. The pointer it returns points to an executable block of code. + ADJUST_TRAMPOLINE, // TRAP - Trapping instruction TRAP, @@ -592,22 +597,27 @@ namespace ISD { // and produces an output chain. MEMBARRIER, + // OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) + // This corresponds to the fence instruction. It takes an input chain, and + // two integer constants: an AtomicOrdering and a SynchronizationScope. + ATOMIC_FENCE, + + // Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) + // This corresponds to "load atomic" instruction. + ATOMIC_LOAD, + + // OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr, val) + // This corresponds to "store atomic" instruction. + ATOMIC_STORE, + // Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) - // this corresponds to the atomic.lcs intrinsic. - // cmp is compared to *ptr, and if equal, swap is stored in *ptr. - // the return is always the original value in *ptr + // This corresponds to the cmpxchg instruction. ATOMIC_CMP_SWAP, // Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) - // this corresponds to the atomic.swap intrinsic. - // amt is stored to *ptr atomically. - // the return is always the original value in *ptr - ATOMIC_SWAP, - // Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN, ptr, amt) - // this corresponds to the atomic.load.[OpName] intrinsic. - // op(*ptr, amt) is stored to *ptr atomically. - // the return is always the original value in *ptr + // These correspond to the atomicrmw instruction. + ATOMIC_SWAP, ATOMIC_LOAD_ADD, ATOMIC_LOAD_SUB, ATOMIC_LOAD_AND, diff --git a/include/llvm/CodeGen/LexicalScopes.h b/include/llvm/CodeGen/LexicalScopes.h new file mode 100644 index 0000000..0271c5d --- /dev/null +++ b/include/llvm/CodeGen/LexicalScopes.h @@ -0,0 +1,248 @@ +//===- LexicalScopes.cpp - Collecting lexical scope info -*- C++ -*--------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements LexicalScopes analysis. +// +// This pass collects lexical scope information and maps machine instructions +// to respective lexical scopes. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_LEXICALSCOPES_H +#define LLVM_CODEGEN_LEXICALSCOPES_H + +#include "llvm/Metadata.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/DebugLoc.h" +#include "llvm/Support/ValueHandle.h" +#include <utility> +namespace llvm { + +class MachineInstr; +class MachineBasicBlock; +class MachineFunction; +class LexicalScope; + +//===----------------------------------------------------------------------===// +/// InsnRange - This is used to track range of instructions with identical +/// lexical scope. +/// +typedef std::pair<const MachineInstr *, const MachineInstr *> InsnRange; + +//===----------------------------------------------------------------------===// +/// LexicalScopes - This class provides interface to collect and use lexical +/// scoping information from machine instruction. +/// +class LexicalScopes { +public: + LexicalScopes() : MF(NULL), CurrentFnLexicalScope(NULL) { } + virtual ~LexicalScopes(); + + /// initialize - Scan machine function and constuct lexical scope nest. + virtual void initialize(const MachineFunction &); + + /// releaseMemory - release memory. + virtual void releaseMemory(); + + /// empty - Return true if there is any lexical scope information available. + bool empty() { return CurrentFnLexicalScope == NULL; } + + /// isCurrentFunctionScope - Return true if given lexical scope represents + /// current function. + bool isCurrentFunctionScope(const LexicalScope *LS) { + return LS == CurrentFnLexicalScope; + } + + /// getCurrentFunctionScope - Return lexical scope for the current function. + LexicalScope *getCurrentFunctionScope() const { return CurrentFnLexicalScope;} + + /// getMachineBasicBlocks - Populate given set using machine basic blocks + /// which have machine instructions that belong to lexical scope identified by + /// DebugLoc. + void getMachineBasicBlocks(DebugLoc DL, + SmallPtrSet<const MachineBasicBlock*, 4> &MBBs); + + /// dominates - Return true if DebugLoc's lexical scope dominates at least one + /// machine instruction's lexical scope in a given machine basic block. + bool dominates(DebugLoc DL, MachineBasicBlock *MBB); + + /// findLexicalScope - Find lexical scope, either regular or inlined, for the + /// given DebugLoc. Return NULL if not found. + LexicalScope *findLexicalScope(DebugLoc DL); + + /// getAbstractScopesList - Return a reference to list of abstract scopes. + ArrayRef<LexicalScope *> getAbstractScopesList() const { + return AbstractScopesList; + } + + /// findAbstractScope - Find an abstract scope or return NULL. + LexicalScope *findAbstractScope(const MDNode *N) { + return AbstractScopeMap.lookup(N); + } + + /// findInlinedScope - Find an inlined scope for the given DebugLoc or return + /// NULL. + LexicalScope *findInlinedScope(DebugLoc DL) { + return InlinedLexicalScopeMap.lookup(DL); + } + + /// findLexicalScope - Find regular lexical scope or return NULL. + LexicalScope *findLexicalScope(const MDNode *N) { + return LexicalScopeMap.lookup(N); + } + + /// dump - Print data structures to dbgs(). + void dump(); + +private: + + /// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If + /// not available then create new lexical scope. + LexicalScope *getOrCreateLexicalScope(DebugLoc DL); + + /// getOrCreateRegularScope - Find or create a regular lexical scope. + LexicalScope *getOrCreateRegularScope(MDNode *Scope); + + /// getOrCreateInlinedScope - Find or create an inlined lexical scope. + LexicalScope *getOrCreateInlinedScope(MDNode *Scope, MDNode *InlinedAt); + + /// getOrCreateAbstractScope - Find or create an abstract lexical scope. + LexicalScope *getOrCreateAbstractScope(const MDNode *N); + + /// extractLexicalScopes - Extract instruction ranges for each lexical scopes + /// for the given machine function. + void extractLexicalScopes(SmallVectorImpl<InsnRange> &MIRanges, + DenseMap<const MachineInstr *, LexicalScope *> &M); + void constructScopeNest(LexicalScope *Scope); + void assignInstructionRanges(SmallVectorImpl<InsnRange> &MIRanges, + DenseMap<const MachineInstr *, LexicalScope *> &M); + +private: + const MachineFunction *MF; + + /// LexicalScopeMap - Tracks the scopes in the current function. Owns the + /// contained LexicalScope*s. + DenseMap<const MDNode *, LexicalScope *> LexicalScopeMap; + + /// InlinedLexicalScopeMap - Tracks inlined function scopes in current function. + DenseMap<DebugLoc, LexicalScope *> InlinedLexicalScopeMap; + + /// AbstractScopeMap - These scopes are not included LexicalScopeMap. + /// AbstractScopes owns its LexicalScope*s. + DenseMap<const MDNode *, LexicalScope *> AbstractScopeMap; + + /// AbstractScopesList - Tracks abstract scopes constructed while processing + /// a function. + SmallVector<LexicalScope *, 4>AbstractScopesList; + + /// CurrentFnLexicalScope - Top level scope for the current function. + /// + LexicalScope *CurrentFnLexicalScope; +}; + +//===----------------------------------------------------------------------===// +/// LexicalScope - This class is used to track scope information. +/// +class LexicalScope { + +public: + LexicalScope(LexicalScope *P, const MDNode *D, const MDNode *I, bool A) + : Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(A), + LastInsn(0), FirstInsn(0), DFSIn(0), DFSOut(0), IndentLevel(0) { + if (Parent) + Parent->addChild(this); + } + + virtual ~LexicalScope() {} + + // Accessors. + LexicalScope *getParent() const { return Parent; } + const MDNode *getDesc() const { return Desc; } + const MDNode *getInlinedAt() const { return InlinedAtLocation; } + const MDNode *getScopeNode() const { return Desc; } + bool isAbstractScope() const { return AbstractScope; } + SmallVector<LexicalScope *, 4> &getChildren() { return Children; } + SmallVector<InsnRange, 4> &getRanges() { return Ranges; } + + /// addChild - Add a child scope. + void addChild(LexicalScope *S) { Children.push_back(S); } + + /// openInsnRange - This scope covers instruction range starting from MI. + void openInsnRange(const MachineInstr *MI) { + if (!FirstInsn) + FirstInsn = MI; + + if (Parent) + Parent->openInsnRange(MI); + } + + /// extendInsnRange - Extend the current instruction range covered by + /// this scope. + void extendInsnRange(const MachineInstr *MI) { + assert (FirstInsn && "MI Range is not open!"); + LastInsn = MI; + if (Parent) + Parent->extendInsnRange(MI); + } + + /// closeInsnRange - Create a range based on FirstInsn and LastInsn collected + /// until now. This is used when a new scope is encountered while walking + /// machine instructions. + void closeInsnRange(LexicalScope *NewScope = NULL) { + assert (LastInsn && "Last insn missing!"); + Ranges.push_back(InsnRange(FirstInsn, LastInsn)); + FirstInsn = NULL; + LastInsn = NULL; + // If Parent dominates NewScope then do not close Parent's instruction + // range. + if (Parent && (!NewScope || !Parent->dominates(NewScope))) + Parent->closeInsnRange(NewScope); + } + + /// dominates - Return true if current scope dominsates given lexical scope. + bool dominates(const LexicalScope *S) const { + if (S == this) + return true; + if (DFSIn < S->getDFSIn() && DFSOut > S->getDFSOut()) + return true; + return false; + } + + // Depth First Search support to walk and manipulate LexicalScope hierarchy. + unsigned getDFSOut() const { return DFSOut; } + void setDFSOut(unsigned O) { DFSOut = O; } + unsigned getDFSIn() const { return DFSIn; } + void setDFSIn(unsigned I) { DFSIn = I; } + + /// dump - print lexical scope. + void dump() const; + +private: + LexicalScope *Parent; // Parent to this scope. + AssertingVH<const MDNode> Desc; // Debug info descriptor. + AssertingVH<const MDNode> InlinedAtLocation; // Location at which this + // scope is inlined. + bool AbstractScope; // Abstract Scope + SmallVector<LexicalScope *, 4> Children; // Scopes defined in scope. + // Contents not owned. + SmallVector<InsnRange, 4> Ranges; + + const MachineInstr *LastInsn; // Last instruction of this scope. + const MachineInstr *FirstInsn; // First instruction of this scope. + unsigned DFSIn, DFSOut; // In & Out Depth use to determine + // scope nesting. + mutable unsigned IndentLevel; // Private state for dump() +}; + +} // end llvm namespace + +#endif diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h index 5fd4d3d..2288c1a 100644 --- a/include/llvm/CodeGen/LiveInterval.h +++ b/include/llvm/CodeGen/LiveInterval.h @@ -100,6 +100,7 @@ namespace llvm { bool isDefByCopy() const { return copy != 0; } /// Returns true if one or more kills are PHI nodes. + /// Obsolete, do not use! bool hasPHIKill() const { return flags & HAS_PHI_KILL; } /// Set the PHI kill flag on this value. void setHasPHIKill(bool hasKill) { @@ -313,7 +314,6 @@ namespace llvm { /// RenumberValues - Renumber all values in order of appearance and remove /// unused values. - /// Recalculate phi-kill flags in case any phi-def values were removed. void RenumberValues(LiveIntervals &lis); /// isOnlyLROfValNo - Return true if the specified live range is the only @@ -411,6 +411,14 @@ namespace llvm { return I == end() ? 0 : I->valno; } + /// getVNInfoBefore - Return the VNInfo that is live up to but not + /// necessarilly including Idx, or NULL. Use this to find the reaching def + /// used by an instruction at this SlotIndex position. + VNInfo *getVNInfoBefore(SlotIndex Idx) const { + const_iterator I = FindLiveRangeContaining(Idx.getPrevSlot()); + return I == end() ? 0 : I->valno; + } + /// FindLiveRangeContaining - Return an iterator to the live range that /// contains the specified index, or end() if there is none. iterator FindLiveRangeContaining(SlotIndex Idx) { @@ -452,10 +460,10 @@ namespace llvm { addRangeFrom(LR, ranges.begin()); } - /// extendInBlock - If this interval is live before UseIdx in the basic - /// block that starts at StartIdx, extend it to be live at UseIdx and return - /// the value. If there is no live range before UseIdx, return NULL. - VNInfo *extendInBlock(SlotIndex StartIdx, SlotIndex UseIdx); + /// extendInBlock - If this interval is live before Kill in the basic block + /// that starts at StartIdx, extend it to be live up to Kill, and return + /// the value. If there is no live range before Kill, return NULL. + VNInfo *extendInBlock(SlotIndex StartIdx, SlotIndex Kill); /// join - Join two live intervals (this, and other) together. This applies /// mappings to the value numbers in the LHS/RHS intervals as specified. If diff --git a/include/llvm/CodeGen/LiveStackAnalysis.h b/include/llvm/CodeGen/LiveStackAnalysis.h index 8a8dcaf..86c4d7c 100644 --- a/include/llvm/CodeGen/LiveStackAnalysis.h +++ b/include/llvm/CodeGen/LiveStackAnalysis.h @@ -25,6 +25,8 @@ namespace llvm { class LiveStacks : public MachineFunctionPass { + const TargetRegisterInfo *TRI; + /// Special pool allocator for VNInfo's (LiveInterval val#). /// VNInfo::Allocator VNInfoAllocator; diff --git a/include/llvm/CodeGen/LiveVariables.h b/include/llvm/CodeGen/LiveVariables.h index f9b81b1..7ba901f 100644 --- a/include/llvm/CodeGen/LiveVariables.h +++ b/include/llvm/CodeGen/LiveVariables.h @@ -231,6 +231,7 @@ public: } assert(Removed && "Register is not used by this instruction!"); + (void)Removed; return true; } @@ -265,6 +266,7 @@ public: } } assert(Removed && "Register is not defined by this instruction!"); + (void)Removed; return true; } diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h index 397e59e..5a20e95 100644 --- a/include/llvm/CodeGen/MachineBasicBlock.h +++ b/include/llvm/CodeGen/MachineBasicBlock.h @@ -232,7 +232,7 @@ public: /// setIsLandingPad - Indicates the block is a landing pad. That is /// this basic block is entered via an exception handler. - void setIsLandingPad() { IsLandingPad = true; } + void setIsLandingPad(bool V = true) { IsLandingPad = V; } /// getLandingPadSuccessor - If this block has a successor that is a landing /// pad, return it. Otherwise return NULL. diff --git a/include/llvm/CodeGen/MachineBlockFrequency.h b/include/llvm/CodeGen/MachineBlockFrequencyInfo.h index 25bf1f0..416d40b 100644 --- a/include/llvm/CodeGen/MachineBlockFrequency.h +++ b/include/llvm/CodeGen/MachineBlockFrequencyInfo.h @@ -1,4 +1,4 @@ -//====----- MachineBlockFrequency.h - MachineBlock Frequency Analysis ----====// +//====----- MachineBlockFrequencyInfo.h - MachineBlock Frequency Analysis ----====// // // The LLVM Compiler Infrastructure // @@ -11,10 +11,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CODEGEN_MACHINEBLOCKFREQUENCY_H -#define LLVM_CODEGEN_MACHINEBLOCKFREQUENCY_H +#ifndef LLVM_CODEGEN_MACHINEBLOCKFREQUENCYINFO_H +#define LLVM_CODEGEN_MACHINEBLOCKFREQUENCYINFO_H #include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/Support/BlockFrequency.h" #include <climits> namespace llvm { @@ -23,29 +24,29 @@ class MachineBranchProbabilityInfo; template<class BlockT, class FunctionT, class BranchProbInfoT> class BlockFrequencyImpl; -/// MachineBlockFrequency pass uses BlockFrequencyImpl implementation to estimate +/// MachineBlockFrequencyInfo pass uses BlockFrequencyImpl implementation to estimate /// machine basic block frequencies. -class MachineBlockFrequency : public MachineFunctionPass { +class MachineBlockFrequencyInfo : public MachineFunctionPass { BlockFrequencyImpl<MachineBasicBlock, MachineFunction, MachineBranchProbabilityInfo> *MBFI; public: static char ID; - MachineBlockFrequency(); + MachineBlockFrequencyInfo(); - ~MachineBlockFrequency(); + ~MachineBlockFrequencyInfo(); void getAnalysisUsage(AnalysisUsage &AU) const; bool runOnMachineFunction(MachineFunction &F); - /// getblockFreq - Return block frequency. Never return 0, value must be - /// positive. Please note that initial frequency is equal to 1024. It means + /// getblockFreq - Return block frequency. Return 0 if we don't have the + /// information. Please note that initial frequency is equal to 1024. It means /// that we should not rely on the value itself, but only on the comparison to - /// the other block frequencies. We do this to avoid using of the floating - /// points. - uint32_t getBlockFreq(MachineBasicBlock *MBB); + /// the other block frequencies. We do this to avoid using of floating points. + /// + BlockFrequency getBlockFreq(MachineBasicBlock *MBB) const; }; } diff --git a/include/llvm/CodeGen/MachineConstantPool.h b/include/llvm/CodeGen/MachineConstantPool.h index beb16a2..29f4f44 100644 --- a/include/llvm/CodeGen/MachineConstantPool.h +++ b/include/llvm/CodeGen/MachineConstantPool.h @@ -34,15 +34,15 @@ class raw_ostream; /// Abstract base class for all machine specific constantpool value subclasses. /// class MachineConstantPoolValue { - const Type *Ty; + Type *Ty; public: - explicit MachineConstantPoolValue(const Type *ty) : Ty(ty) {} + explicit MachineConstantPoolValue(Type *ty) : Ty(ty) {} virtual ~MachineConstantPoolValue() {} /// getType - get type of this MachineConstantPoolValue. /// - const Type *getType() const { return Ty; } + Type *getType() const { return Ty; } /// getRelocationInfo - This method classifies the entry according to @@ -54,7 +54,7 @@ public: virtual int getExistingMachineCPValue(MachineConstantPool *CP, unsigned Alignment) = 0; - virtual void AddSelectionDAGCSEId(FoldingSetNodeID &ID) = 0; + virtual void addSelectionDAGCSEId(FoldingSetNodeID &ID) = 0; /// print - Implement operator<< virtual void print(raw_ostream &O) const = 0; @@ -104,7 +104,7 @@ public: return Alignment & ~(1 << (sizeof(unsigned)*CHAR_BIT-1)); } - const Type *getType() const; + Type *getType() const; /// getRelocationInfo - This method classifies the entry according to /// whether or not it may generate a relocation entry. This must be diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h index 4ea6aa3..b347ca8 100644 --- a/include/llvm/CodeGen/MachineFrameInfo.h +++ b/include/llvm/CodeGen/MachineFrameInfo.h @@ -174,6 +174,10 @@ class MachineFrameInfo { /// StackProtectorIdx - The frame index for the stack protector. int StackProtectorIdx; + /// FunctionContextIdx - The frame index for the function context. Used for + /// SjLj exceptions. + int FunctionContextIdx; + /// MaxCallFrameSize - 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 @@ -220,6 +224,7 @@ public: AdjustsStack = false; HasCalls = false; StackProtectorIdx = -1; + FunctionContextIdx = -1; MaxCallFrameSize = 0; CSIValid = false; LocalFrameSize = 0; @@ -244,6 +249,11 @@ public: int getStackProtectorIndex() const { return StackProtectorIdx; } void setStackProtectorIndex(int I) { StackProtectorIdx = I; } + /// getFunctionContextIndex/setFunctionContextIndex - Return the index for the + /// function context object. This object is used for SjLj exceptions. + int getFunctionContextIndex() const { return FunctionContextIdx; } + void setFunctionContextIndex(int I) { FunctionContextIdx = I; } + /// isFrameAddressTaken - This method may be called any time after instruction /// selection is complete to determine if there is a call to /// \@llvm.frameaddress in this function. diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index 5b3d3ea..cae38f3 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -32,6 +32,7 @@ namespace llvm { template <typename T> class SmallVectorImpl; class AliasAnalysis; class TargetInstrInfo; +class TargetRegisterClass; class TargetRegisterInfo; class MachineFunction; class MachineMemOperand; @@ -58,8 +59,6 @@ public: }; private: const MCInstrDesc *MCID; // Instruction descriptor. - uint16_t NumImplicitOps; // Number of implicit operands (which - // are determined at construction time). uint8_t Flags; // Various bits of additional // information about machine @@ -78,9 +77,6 @@ private: MachineBasicBlock *Parent; // Pointer to the owning basic block. DebugLoc debugLoc; // Source line information. - // OperandComplete - Return true if it's illegal to add a new operand - bool OperandsComplete() const; - MachineInstr(const MachineInstr&); // DO NOT IMPLEMENT void operator=(const MachineInstr&); // DO NOT IMPLEMENT @@ -393,6 +389,30 @@ public: /// none is found. int findFirstPredOperandIdx() const; + /// findInlineAsmFlagIdx() - Find the index of the flag word operand that + /// corresponds to operand OpIdx on an inline asm instruction. Returns -1 if + /// getOperand(OpIdx) does not belong to an inline asm operand group. + /// + /// If GroupNo is not NULL, it will receive the number of the operand group + /// containing OpIdx. + /// + /// The flag operand is an immediate that can be decoded with methods like + /// InlineAsm::hasRegClassConstraint(). + /// + int findInlineAsmFlagIdx(unsigned OpIdx, unsigned *GroupNo = 0) const; + + /// getRegClassConstraint - Compute the static register class constraint for + /// operand OpIdx. For normal instructions, this is derived from the + /// MCInstrDesc. For inline assembly it is derived from the flag words. + /// + /// Returns NULL if the static register classs constraint cannot be + /// determined. + /// + const TargetRegisterClass* + getRegClassConstraint(unsigned OpIdx, + const TargetInstrInfo *TII, + const TargetRegisterInfo *TRI) const; + /// isRegTiedToUseOperand - Given the index of a register def operand, /// check if the register def is tied to a source operand, due to either /// two-address elimination or inline assembly constraints. Returns the diff --git a/include/llvm/CodeGen/MachineLocation.h b/include/llvm/CodeGen/MachineLocation.h deleted file mode 100644 index 21951b6..0000000 --- a/include/llvm/CodeGen/MachineLocation.h +++ /dev/null @@ -1,98 +0,0 @@ -//===-- llvm/CodeGen/MachineLocation.h --------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// The MachineLocation class is used to represent a simple location in a machine -// frame. Locations will be one of two forms; a register or an address formed -// from a base address plus an offset. Register indirection can be specified by -// using an offset of zero. -// -// The MachineMove class is used to represent abstract move operations in the -// prolog/epilog of a compiled function. A collection of these objects can be -// used by a debug consumer to track the location of values when unwinding stack -// frames. -//===----------------------------------------------------------------------===// - - -#ifndef LLVM_CODEGEN_MACHINELOCATION_H -#define LLVM_CODEGEN_MACHINELOCATION_H - -namespace llvm { - class MCSymbol; - -class MachineLocation { -private: - bool IsRegister; // True if location is a register. - unsigned Register; // gcc/gdb register number. - int Offset; // Displacement if not register. -public: - enum { - // The target register number for an abstract frame pointer. The value is - // an arbitrary value that doesn't collide with any real target register. - VirtualFP = ~0U - }; - MachineLocation() - : IsRegister(false), Register(0), Offset(0) {} - explicit MachineLocation(unsigned R) - : IsRegister(true), Register(R), Offset(0) {} - MachineLocation(unsigned R, int O) - : IsRegister(false), Register(R), Offset(O) {} - - bool operator==(const MachineLocation &Other) const { - return IsRegister == Other.IsRegister && Register == Other.Register && - Offset == Other.Offset; - } - - // Accessors - bool isReg() const { return IsRegister; } - unsigned getReg() const { return Register; } - int getOffset() const { return Offset; } - void setIsRegister(bool Is) { IsRegister = Is; } - void setRegister(unsigned R) { Register = R; } - void setOffset(int O) { Offset = O; } - void set(unsigned R) { - IsRegister = true; - Register = R; - Offset = 0; - } - void set(unsigned R, int O) { - IsRegister = false; - Register = R; - Offset = O; - } - -#ifndef NDEBUG - void dump(); -#endif -}; - -/// MachineMove - This class represents the save or restore of a callee saved -/// register that exception or debug info needs to know about. -class MachineMove { -private: - /// Label - Symbol for post-instruction address when result of move takes - /// effect. - MCSymbol *Label; - - // Move to & from location. - MachineLocation Destination, Source; -public: - MachineMove() : Label(0) {} - - MachineMove(MCSymbol *label, const MachineLocation &D, - const MachineLocation &S) - : Label(label), Destination(D), Source(S) {} - - // Accessors - MCSymbol *getLabel() const { return Label; } - const MachineLocation &getDestination() const { return Destination; } - const MachineLocation &getSource() const { return Source; } -}; - -} // End llvm namespace - -#endif diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h index fa185c4..2bf7f17 100644 --- a/include/llvm/CodeGen/MachineModuleInfo.h +++ b/include/llvm/CodeGen/MachineModuleInfo.h @@ -34,7 +34,7 @@ #include "llvm/Pass.h" #include "llvm/GlobalValue.h" #include "llvm/Metadata.h" -#include "llvm/CodeGen/MachineLocation.h" +#include "llvm/MC/MachineLocation.h" #include "llvm/MC/MCContext.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/DebugLoc.h" @@ -107,36 +107,42 @@ class MachineModuleInfo : public ImmutablePass { /// want. MachineModuleInfoImpl *ObjFileMMI; - // FrameMoves - List of moves done by a function's prolog. Used to construct - // frame maps by debug and exception handling consumers. + /// FrameMoves - List of moves done by a function's prolog. Used to construct + /// frame maps by debug and exception handling consumers. std::vector<MachineMove> FrameMoves; - // LandingPads - List of LandingPadInfo describing the landing pad information - // in the current function. + /// CompactUnwindEncoding - If the target supports it, this is the compact + /// unwind encoding. It replaces a function's CIE and FDE. + uint32_t CompactUnwindEncoding; + + /// LandingPads - List of LandingPadInfo describing the landing pad + /// information in the current function. std::vector<LandingPadInfo> LandingPads; - // Map of invoke call site index values to associated begin EH_LABEL for - // the current function. + /// LPadToCallSiteMap - Map a landing pad's EH symbol to the call site + /// indexes. + DenseMap<MCSymbol*, SmallVector<unsigned, 4> > LPadToCallSiteMap; + + /// CallSiteMap - Map of invoke call site index values to associated begin + /// EH_LABEL for the current function. DenseMap<MCSymbol*, unsigned> CallSiteMap; - // The current call site index being processed, if any. 0 if none. + /// CurCallSite - The current call site index being processed, if any. 0 if + /// none. unsigned CurCallSite; - // TypeInfos - List of C++ TypeInfo used in the current function. - // + /// TypeInfos - List of C++ TypeInfo used in the current function. std::vector<const GlobalVariable *> TypeInfos; - // FilterIds - List of typeids encoding filters used in the current function. - // + /// FilterIds - List of typeids encoding filters used in the current function. std::vector<unsigned> FilterIds; - // FilterEnds - List of the indices in FilterIds corresponding to filter - // terminators. - // + /// FilterEnds - List of the indices in FilterIds corresponding to filter + /// terminators. std::vector<unsigned> FilterEnds; - // Personalities - Vector of all personality functions ever seen. Used to emit - // common EH frames. + /// Personalities - Vector of all personality functions ever seen. Used to + /// emit common EH frames. std::vector<const Function *> Personalities; /// UsedFunctions - The functions in the @llvm.used list in a more easily @@ -144,7 +150,6 @@ class MachineModuleInfo : public ImmutablePass { /// llvm.compiler.used. SmallPtrSet<const Function *, 32> UsedFunctions; - /// AddrLabelSymbols - This map keeps track of which symbol is being used for /// the specified basic block's address of label. MMIAddrLabelMap *AddrLabelSymbols; @@ -156,8 +161,9 @@ class MachineModuleInfo : public ImmutablePass { /// in this module. bool DbgInfoAvailable; - /// True if this module calls VarArg function with floating point arguments. - /// This is used to emit an undefined reference to fltused on Windows targets. + /// CallsExternalVAFunctionWithFloatingPointArguments - True if this module + /// calls VarArg function with floating point arguments. This is used to emit + /// an undefined reference to fltused on Windows targets. bool CallsExternalVAFunctionWithFloatingPointArguments; public: @@ -170,7 +176,8 @@ public: MachineModuleInfo(); // DUMMY CONSTRUCTOR, DO NOT CALL. // Real constructor. - MachineModuleInfo(const MCAsmInfo &MAI, const TargetAsmInfo *TAI); + MachineModuleInfo(const MCAsmInfo &MAI, const MCRegisterInfo &MRI, + const MCObjectFileInfo *MOFI); ~MachineModuleInfo(); bool doInitialization(); @@ -229,6 +236,15 @@ public: /// handling comsumers. std::vector<MachineMove> &getFrameMoves() { return FrameMoves; } + /// getCompactUnwindEncoding - Returns the compact unwind encoding for a + /// function if the target supports the encoding. This encoding replaces a + /// function's CIE and FDE. + uint32_t getCompactUnwindEncoding() const { return CompactUnwindEncoding; } + + /// setCompactUnwindEncoding - Set the compact unwind encoding for a function + /// if the target supports the encoding. + void setCompactUnwindEncoding(uint32_t Enc) { CompactUnwindEncoding = Enc; } + /// getAddrLabelSymbol - Return the symbol to be used for the specified basic /// block when its address is taken. This cannot be its normal LBB label /// because the block may be accessed outside its containing function. @@ -286,12 +302,12 @@ public: /// addCatchTypeInfo - Provide the catch typeinfo for a landing pad. /// void addCatchTypeInfo(MachineBasicBlock *LandingPad, - std::vector<const GlobalVariable *> &TyInfo); + ArrayRef<const GlobalVariable *> TyInfo); /// addFilterTypeInfo - Provide the filter typeinfo for a landing pad. /// void addFilterTypeInfo(MachineBasicBlock *LandingPad, - std::vector<const GlobalVariable *> &TyInfo); + ArrayRef<const GlobalVariable *> TyInfo); /// addCleanup - Add a cleanup action for a landing pad. /// @@ -315,18 +331,42 @@ public: return LandingPads; } - /// setCallSiteBeginLabel - Map the begin label for a call site + /// setCallSiteLandingPad - Map the landing pad's EH symbol to the call + /// site indexes. + void setCallSiteLandingPad(MCSymbol *Sym, ArrayRef<unsigned> Sites); + + /// getCallSiteLandingPad - Get the call site indexes for a landing pad EH + /// symbol. + SmallVectorImpl<unsigned> &getCallSiteLandingPad(MCSymbol *Sym) { + assert(hasCallSiteLandingPad(Sym) && + "missing call site number for landing pad!"); + return LPadToCallSiteMap[Sym]; + } + + /// hasCallSiteLandingPad - Return true if the landing pad Eh symbol has an + /// associated call site. + bool hasCallSiteLandingPad(MCSymbol *Sym) { + return !LPadToCallSiteMap[Sym].empty(); + } + + /// setCallSiteBeginLabel - Map the begin label for a call site. void setCallSiteBeginLabel(MCSymbol *BeginLabel, unsigned Site) { CallSiteMap[BeginLabel] = Site; } - /// getCallSiteBeginLabel - Get the call site number for a begin label + /// getCallSiteBeginLabel - Get the call site number for a begin label. unsigned getCallSiteBeginLabel(MCSymbol *BeginLabel) { - assert(CallSiteMap.count(BeginLabel) && + assert(hasCallSiteBeginLabel(BeginLabel) && "Missing call site number for EH_LABEL!"); return CallSiteMap[BeginLabel]; } + /// hasCallSiteBeginLabel - Return true if the begin label has a call site + /// number associated with it. + bool hasCallSiteBeginLabel(MCSymbol *BeginLabel) { + return CallSiteMap[BeginLabel] != 0; + } + /// setCurrentCallSite - Set the call site currently being processed. void setCurrentCallSite(unsigned Site) { CurCallSite = Site; } diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h index fdef574..5440a63 100644 --- a/include/llvm/CodeGen/MachineOperand.h +++ b/include/llvm/CodeGen/MachineOperand.h @@ -83,8 +83,23 @@ private: /// This is only valid on definitions of registers. bool IsDead : 1; - /// IsUndef - True if this is a register def / use of "undef", i.e. register - /// defined by an IMPLICIT_DEF. This is only valid on registers. + /// IsUndef - True if this register operand reads an "undef" value, i.e. the + /// read value doesn't matter. This flag can be set on both use and def + /// operands. On a sub-register def operand, it refers to the part of the + /// register that isn't written. On a full-register def operand, it is a + /// noop. See readsReg(). + /// + /// This is only valid on registers. + /// + /// Note that an instruction may have multiple <undef> operands referring to + /// the same register. In that case, the instruction may depend on those + /// operands reading the same dont-care value. For example: + /// + /// %vreg1<def> = XOR %vreg2<undef>, %vreg2<undef> + /// + /// Any register can be used for %vreg2, and its value doesn't matter, but + /// the two operands must be the same register. + /// bool IsUndef : 1; /// IsEarlyClobber - True if this MO_Register 'def' operand is written to @@ -253,6 +268,15 @@ public: return IsDebug; } + /// readsReg - Returns true if this operand reads the previous value of its + /// register. A use operand with the <undef> flag set doesn't read its + /// register. A sub-register def implicitly reads the other parts of the + /// register being redefined unless the <undef> flag is set. + bool readsReg() const { + assert(isReg() && "Wrong MachineOperand accessor"); + return !isUndef() && (isUse() || getSubReg()); + } + /// getNextOperandForReg - Return the next MachineOperand in the function that /// uses or defines this register. MachineOperand *getNextOperandForReg() const { diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h index 1079726..3866b26 100644 --- a/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/include/llvm/CodeGen/MachineRegisterInfo.h @@ -25,6 +25,12 @@ namespace llvm { /// registers, including vreg register classes, use/def chains for registers, /// etc. class MachineRegisterInfo { + const TargetRegisterInfo *const TRI; + + /// IsSSA - True when the machine function is in SSA form and virtual + /// registers have a single def. + bool IsSSA; + /// VRegInfo - Information we keep for each virtual register. /// /// Each element in this list contains the register class of the vreg and the @@ -65,7 +71,23 @@ class MachineRegisterInfo { public: explicit MachineRegisterInfo(const TargetRegisterInfo &TRI); ~MachineRegisterInfo(); - + + //===--------------------------------------------------------------------===// + // Function State + //===--------------------------------------------------------------------===// + + // isSSA - Returns true when the machine function is in SSA form. Early + // passes require the machine function to be in SSA form where every virtual + // register has a single defining instruction. + // + // The TwoAddressInstructionPass and PHIElimination passes take the machine + // function out of SSA form when they introduce multiple defs per virtual + // register. + bool isSSA() const { return IsSSA; } + + // leaveSSA - Indicates that the machine function is no longer in SSA form. + void leaveSSA() { IsSSA = false; } + //===--------------------------------------------------------------------===// // Register Info //===--------------------------------------------------------------------===// @@ -195,12 +217,25 @@ public: void setRegClass(unsigned Reg, const TargetRegisterClass *RC); /// constrainRegClass - Constrain the register class of the specified virtual - /// register to be a common subclass of RC and the current register class. - /// Return the new register class, or NULL if no such class exists. + /// register to be a common subclass of RC and the current register class, + /// but only if the new class has at least MinNumRegs registers. Return the + /// new register class, or NULL if no such class exists. /// This should only be used when the constraint is known to be trivial, like /// GR32 -> GR32_NOSP. Beware of increasing register pressure. + /// const TargetRegisterClass *constrainRegClass(unsigned Reg, - const TargetRegisterClass *RC); + const TargetRegisterClass *RC, + unsigned MinNumRegs = 0); + + /// recomputeRegClass - Try to find a legal super-class of Reg's register + /// class that still satisfies the constraints from the instructions using + /// Reg. Returns true if Reg was upgraded. + /// + /// This method can be used after constraints have been removed from a + /// virtual register, for example after removing instructions or splitting + /// the live range. + /// + bool recomputeRegClass(unsigned Reg, const TargetMachine&); /// createVirtualRegister - Create and return a new virtual register in the /// function with the specified register class. diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index e7928cb..7a03ce9 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -24,7 +24,7 @@ namespace llvm { class MachineFunctionPass; class PassInfo; class TargetLowering; - class RegisterCoalescer; + class TargetRegisterClass; class raw_ostream; /// createUnreachableBlockEliminationPass - The LLVM code generator does not @@ -81,6 +81,9 @@ namespace llvm { /// register allocators. extern char &TwoAddressInstructionPassID; + /// RegisteCoalescer pass - This pass merges live ranges to eliminate copies. + extern char &RegisterCoalescerPassID; + /// SpillPlacement analysis. Suggest optimal placement of spill code between /// basic blocks. /// @@ -125,21 +128,15 @@ namespace llvm { /// FunctionPass *createDefaultPBQPRegisterAllocator(); - /// RegisterCoalescer Pass - Coalesce all copies possible. Can run - /// independently of the register allocator. - /// - RegisterCoalescer *createRegisterCoalescer(); - /// PrologEpilogCodeInserter Pass - This pass inserts prolog and epilog code, /// and eliminates abstract frame references. /// FunctionPass *createPrologEpilogCodeInserter(); - /// LowerSubregs Pass - This pass lowers subregs to register-register copies - /// which yields suboptimal, but correct code if the register allocator - /// cannot coalesce all subreg operations during allocation. + /// ExpandPostRAPseudos Pass - This pass expands pseudo instructions after + /// register allocation. /// - FunctionPass *createLowerSubregsPass(); + FunctionPass *createExpandPostRAPseudosPass(); /// createPostRAScheduler - This pass performs post register allocation /// scheduling. @@ -229,6 +226,14 @@ namespace llvm { /// FunctionPass *createExpandISelPseudosPass(); + /// createExecutionDependencyFixPass - This pass fixes execution time + /// problems with dependent instructions, such as switching execution + /// domains to match. + /// + /// The pass will examine instructions using and defining registers in RC. + /// + FunctionPass *createExecutionDependencyFixPass(const TargetRegisterClass *RC); + } // End llvm namespace #endif diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index 3ec5ada..132983c 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -450,6 +450,10 @@ public: SDValue getVectorShuffle(EVT VT, DebugLoc dl, SDValue N1, SDValue N2, const int *MaskElts); + /// getAnyExtOrTrunc - Convert Op, which must be of integer type, to the + /// integer type VT, by either any-extending or truncating it. + SDValue getAnyExtOrTrunc(SDValue Op, DebugLoc DL, EVT VT); + /// getSExtOrTrunc - Convert Op, which must be of integer type, to the /// integer type VT, by either sign-extending or truncating it. SDValue getSExtOrTrunc(SDValue Op, DebugLoc DL, EVT VT); @@ -560,17 +564,13 @@ public: /// SDValue getSetCC(DebugLoc DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond) { + assert(LHS.getValueType().isVector() == RHS.getValueType().isVector() && + "Cannot compare scalars to vectors"); + assert(LHS.getValueType().isVector() == VT.isVector() && + "Cannot compare scalars to vectors"); return getNode(ISD::SETCC, DL, VT, LHS, RHS, getCondCode(Cond)); } - /// getVSetCC - Helper function to make it easier to build VSetCC's nodes - /// if you just have an ISD::CondCode instead of an SDValue. - /// - SDValue getVSetCC(DebugLoc DL, EVT VT, SDValue LHS, SDValue RHS, - ISD::CondCode Cond) { - return getNode(ISD::VSETCC, DL, VT, LHS, RHS, getCondCode(Cond)); - } - /// getSelectCC - Helper function to make it easier to build SelectCC's if you /// just have an ISD::CondCode instead of an SDValue. /// @@ -589,19 +589,37 @@ public: /// takes 3 operands SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, SDValue Chain, SDValue Ptr, SDValue Cmp, SDValue Swp, - MachinePointerInfo PtrInfo, unsigned Alignment=0); + MachinePointerInfo PtrInfo, unsigned Alignment, + AtomicOrdering Ordering, + SynchronizationScope SynchScope); SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, SDValue Chain, SDValue Ptr, SDValue Cmp, SDValue Swp, - MachineMemOperand *MMO); + MachineMemOperand *MMO, + AtomicOrdering Ordering, + SynchronizationScope SynchScope); - /// getAtomic - Gets a node for an atomic op, produces result and chain and - /// takes 2 operands. + /// getAtomic - Gets a node for an atomic op, produces result (if relevant) + /// and chain and takes 2 operands. SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, SDValue Chain, SDValue Ptr, SDValue Val, const Value* PtrVal, - unsigned Alignment = 0); + unsigned Alignment, AtomicOrdering Ordering, + SynchronizationScope SynchScope); SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, SDValue Chain, - SDValue Ptr, SDValue Val, - MachineMemOperand *MMO); + SDValue Ptr, SDValue Val, MachineMemOperand *MMO, + AtomicOrdering Ordering, + SynchronizationScope SynchScope); + + /// getAtomic - Gets a node for an atomic op, produces result and chain and + /// takes 1 operand. + SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, EVT VT, + SDValue Chain, SDValue Ptr, const Value* PtrVal, + unsigned Alignment, + AtomicOrdering Ordering, + SynchronizationScope SynchScope); + SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, EVT VT, + SDValue Chain, SDValue Ptr, MachineMemOperand *MMO, + AtomicOrdering Ordering, + SynchronizationScope SynchScope); /// getMemIntrinsicNode - Creates a MemIntrinsicNode that may produce a /// result and takes a list of operands. Opcode may be INTRINSIC_VOID, diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index a5c4201..6c7be69 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -20,6 +20,7 @@ #define LLVM_CODEGEN_SELECTIONDAGNODES_H #include "llvm/Constants.h" +#include "llvm/Instructions.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/ilist_node.h" @@ -917,6 +918,13 @@ public: bool isVolatile() const { return (SubclassData >> 5) & 1; } bool isNonTemporal() const { return (SubclassData >> 6) & 1; } + AtomicOrdering getOrdering() const { + return AtomicOrdering((SubclassData >> 7) & 15); + } + SynchronizationScope getSynchScope() const { + return SynchronizationScope((SubclassData >> 11) & 1); + } + /// Returns the SrcValue and offset that describes the location of the access const Value *getSrcValue() const { return MMO->getValue(); } int64_t getSrcValueOffset() const { return MMO->getOffset(); } @@ -968,6 +976,8 @@ public: N->getOpcode() == ISD::ATOMIC_LOAD_MAX || N->getOpcode() == ISD::ATOMIC_LOAD_UMIN || N->getOpcode() == ISD::ATOMIC_LOAD_UMAX || + N->getOpcode() == ISD::ATOMIC_LOAD || + N->getOpcode() == ISD::ATOMIC_STORE || N->isTargetMemoryOpcode(); } }; @@ -977,6 +987,23 @@ public: class AtomicSDNode : public MemSDNode { SDUse Ops[4]; + void InitAtomic(AtomicOrdering Ordering, SynchronizationScope SynchScope) { + // This must match encodeMemSDNodeFlags() in SelectionDAG.cpp. + assert((Ordering & 15) == Ordering && + "Ordering may not require more than 4 bits!"); + assert((SynchScope & 1) == SynchScope && + "SynchScope may not require more than 1 bit!"); + SubclassData |= Ordering << 7; + SubclassData |= SynchScope << 11; + assert(getOrdering() == Ordering && "Ordering encoding error!"); + assert(getSynchScope() == SynchScope && "Synch-scope encoding error!"); + + assert((readMem() || getOrdering() <= Monotonic) && + "Acquire/Release MachineMemOperand must be a load!"); + assert((writeMem() || getOrdering() <= Monotonic) && + "Acquire/Release MachineMemOperand must be a store!"); + } + public: // Opc: opcode for atomic // VTL: value type list @@ -988,20 +1015,28 @@ public: // Align: alignment of memory AtomicSDNode(unsigned Opc, DebugLoc dl, SDVTList VTL, EVT MemVT, SDValue Chain, SDValue Ptr, - SDValue Cmp, SDValue Swp, MachineMemOperand *MMO) + SDValue Cmp, SDValue Swp, MachineMemOperand *MMO, + AtomicOrdering Ordering, SynchronizationScope SynchScope) : MemSDNode(Opc, dl, VTL, MemVT, MMO) { - assert(readMem() && "Atomic MachineMemOperand is not a load!"); - assert(writeMem() && "Atomic MachineMemOperand is not a store!"); + InitAtomic(Ordering, SynchScope); InitOperands(Ops, Chain, Ptr, Cmp, Swp); } AtomicSDNode(unsigned Opc, DebugLoc dl, SDVTList VTL, EVT MemVT, SDValue Chain, SDValue Ptr, - SDValue Val, MachineMemOperand *MMO) + SDValue Val, MachineMemOperand *MMO, + AtomicOrdering Ordering, SynchronizationScope SynchScope) : MemSDNode(Opc, dl, VTL, MemVT, MMO) { - assert(readMem() && "Atomic MachineMemOperand is not a load!"); - assert(writeMem() && "Atomic MachineMemOperand is not a store!"); + InitAtomic(Ordering, SynchScope); InitOperands(Ops, Chain, Ptr, Val); } + AtomicSDNode(unsigned Opc, DebugLoc dl, SDVTList VTL, EVT MemVT, + SDValue Chain, SDValue Ptr, + MachineMemOperand *MMO, + AtomicOrdering Ordering, SynchronizationScope SynchScope) + : MemSDNode(Opc, dl, VTL, MemVT, MMO) { + InitAtomic(Ordering, SynchScope); + InitOperands(Ops, Chain, Ptr); + } const SDValue &getBasePtr() const { return getOperand(1); } const SDValue &getVal() const { return getOperand(2); } @@ -1025,7 +1060,9 @@ public: N->getOpcode() == ISD::ATOMIC_LOAD_MIN || N->getOpcode() == ISD::ATOMIC_LOAD_MAX || N->getOpcode() == ISD::ATOMIC_LOAD_UMIN || - N->getOpcode() == ISD::ATOMIC_LOAD_UMAX; + N->getOpcode() == ISD::ATOMIC_LOAD_UMAX || + N->getOpcode() == ISD::ATOMIC_LOAD || + N->getOpcode() == ISD::ATOMIC_STORE; } }; @@ -1291,7 +1328,7 @@ public: unsigned getAlignment() const { return Alignment; } unsigned char getTargetFlags() const { return TargetFlags; } - const Type *getType() const; + Type *getType() const; static bool classof(const ConstantPoolSDNode *) { return true; } static bool classof(const SDNode *N) { diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h index 6eb3180..2d98864 100644 --- a/include/llvm/CodeGen/SlotIndexes.h +++ b/include/llvm/CodeGen/SlotIndexes.h @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This file implements SlotIndex and related classes. The purpuse of SlotIndex +// This file implements SlotIndex and related classes. The purpose of SlotIndex // is to describe a position at which a register can become live, or cease to // be live. // diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index 711280e..ca40ccf 100644 --- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -33,42 +33,13 @@ namespace llvm { class TargetLoweringObjectFileELF : public TargetLoweringObjectFile { -protected: - /// TLSDataSection - Section directive for Thread Local data. - /// - const MCSection *TLSDataSection; // Defaults to ".tdata". - - /// TLSBSSSection - Section directive for Thread Local uninitialized data. - /// Null if this target doesn't support a BSS section. - /// - const MCSection *TLSBSSSection; // Defaults to ".tbss". - - const MCSection *DataRelSection; - const MCSection *DataRelLocalSection; - const MCSection *DataRelROSection; - const MCSection *DataRelROLocalSection; - - const MCSection *MergeableConst4Section; - const MCSection *MergeableConst8Section; - const MCSection *MergeableConst16Section; public: - TargetLoweringObjectFileELF(); - ~TargetLoweringObjectFileELF() {} - - virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); - - virtual const MCSection *getEHFrameSection() const; - virtual const MCSection *getWin64EHFuncTableSection(StringRef) const { - return NULL; - } - virtual const MCSection *getWin64EHTableSection(StringRef) const{return NULL;} + virtual ~TargetLoweringObjectFileELF() {} virtual void emitPersonalityValue(MCStreamer &Streamer, const TargetMachine &TM, const MCSymbol *Sym) const; - const MCSection *getDataRelSection() const { return DataRelSection; } - /// getSectionForConstant - Given a constant with the SectionKind, return a /// section that it should be placed in. virtual const MCSection *getSectionForConstant(SectionKind Kind) const; @@ -99,48 +70,8 @@ public: class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile { - /// TLSDataSection - Section for thread local data. - /// - const MCSection *TLSDataSection; // Defaults to ".tdata". - - /// TLSBSSSection - Section for thread local uninitialized data. - /// - const MCSection *TLSBSSSection; // Defaults to ".tbss". - - /// TLSTLVSection - Section for thread local structure information. - /// Contains the source code name of the variable, visibility and a pointer - /// to the initial value (.tdata or .tbss). - const MCSection *TLSTLVSection; // Defaults to ".tlv". - - /// TLSThreadInitSection - Section for thread local data initialization - /// functions. - const MCSection *TLSThreadInitSection; // Defaults to ".thread_init_func". - - const MCSection *CStringSection; - const MCSection *UStringSection; - const MCSection *TextCoalSection; - const MCSection *ConstTextCoalSection; - const MCSection *ConstDataSection; - const MCSection *DataCoalSection; - const MCSection *DataCommonSection; - const MCSection *DataBSSSection; - const MCSection *FourByteConstantSection; - const MCSection *EightByteConstantSection; - const MCSection *SixteenByteConstantSection; - - const MCSection *LazySymbolPointerSection; - const MCSection *NonLazySymbolPointerSection; public: - TargetLoweringObjectFileMachO(); - ~TargetLoweringObjectFileMachO() {} - - virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); - - virtual const MCSection *getEHFrameSection() const; - virtual const MCSection *getWin64EHFuncTableSection(StringRef) const { - return NULL; - } - virtual const MCSection *getWin64EHTableSection(StringRef) const{return NULL;} + virtual ~TargetLoweringObjectFileMachO() {} virtual const MCSection * SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, @@ -158,30 +89,6 @@ public: virtual bool shouldEmitUsedDirectiveFor(const GlobalValue *GV, Mangler *) const; - /// getTextCoalSection - Return the "__TEXT,__textcoal_nt" section we put weak - /// text symbols into. - const MCSection *getTextCoalSection() const { - return TextCoalSection; - } - - /// getConstTextCoalSection - Return the "__TEXT,__const_coal" section - /// we put weak read-only symbols into. - const MCSection *getConstTextCoalSection() const { - return ConstTextCoalSection; - } - - /// getLazySymbolPointerSection - Return the section corresponding to - /// the .lazy_symbol_pointer directive. - const MCSection *getLazySymbolPointerSection() const { - return LazySymbolPointerSection; - } - - /// getNonLazySymbolPointerSection - Return the section corresponding to - /// the .non_lazy_symbol_pointer directive. - const MCSection *getNonLazySymbolPointerSection() const { - return NonLazySymbolPointerSection; - } - /// getExprForDwarfGlobalReference - The mach-o version of this method /// defaults to returning a stub reference. virtual const MCExpr * @@ -193,30 +100,13 @@ public: virtual MCSymbol * getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang, MachineModuleInfo *MMI) const; - - virtual unsigned getPersonalityEncoding() const; - virtual unsigned getLSDAEncoding() const; - virtual unsigned getFDEEncoding(bool CFI) const; - virtual unsigned getTTypeEncoding() const; }; class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile { - const MCSection *DrectveSection; - const MCSection *PDataSection; - const MCSection *XDataSection; public: - TargetLoweringObjectFileCOFF(); - ~TargetLoweringObjectFileCOFF() {} - - virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); - - virtual const MCSection *getEHFrameSection() const; - virtual const MCSection *getWin64EHFuncTableSection(StringRef) const; - virtual const MCSection *getWin64EHTableSection(StringRef) const; - - virtual const MCSection *getDrectveSection() const { return DrectveSection; } + virtual ~TargetLoweringObjectFileCOFF() {} virtual const MCSection * getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h index 424721b..cae0bcb 100644 --- a/include/llvm/CodeGen/ValueTypes.h +++ b/include/llvm/CodeGen/ValueTypes.h @@ -144,14 +144,14 @@ namespace llvm { /// isFloatingPoint - Return true if this is a FP, or a vector FP type. bool isFloatingPoint() const { return ((SimpleTy >= MVT::f32 && SimpleTy <= MVT::ppcf128) || - (SimpleTy >= MVT::v2f32 && SimpleTy <= MVT::v4f64)); + (SimpleTy >= MVT::v2f32 && SimpleTy <= MVT::v4f64)); } /// isInteger - Return true if this is an integer, or a vector integer type. bool isInteger() const { return ((SimpleTy >= MVT::FIRST_INTEGER_VALUETYPE && SimpleTy <= MVT::LAST_INTEGER_VALUETYPE) || - (SimpleTy >= MVT::v2i8 && SimpleTy <= MVT::v8i64)); + (SimpleTy >= MVT::v2i8 && SimpleTy <= MVT::v8i64)); } /// isVector - Return true if this is a vector value type. @@ -380,7 +380,7 @@ namespace llvm { struct EVT { private: MVT V; - const Type *LLVMTy; + Type *LLVMTy; public: EVT() : V((MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE)), @@ -438,6 +438,21 @@ namespace llvm { return MVT::INVALID_SIMPLE_VALUE_TYPE; } + /// changeVectorElementTypeToInteger - Return a vector with the same number + /// of elements as this vector, but with the element type converted to an + /// integer type with the same bitwidth. + EVT changeVectorElementTypeToInteger() const { + if (!isSimple()) + return changeExtendedVectorElementTypeToInteger(); + MVT EltTy = getSimpleVT().getVectorElementType(); + unsigned BitWidth = EltTy.getSizeInBits(); + MVT IntTy = MVT::getIntegerVT(BitWidth); + MVT VecTy = MVT::getVectorVT(IntTy, getVectorNumElements()); + assert(VecTy != MVT::INVALID_SIMPLE_VALUE_TYPE && + "Simple vector VT not representable by simple integer vector VT!"); + return VecTy; + } + /// isSimple - Test if the given EVT is simple (as opposed to being /// extended). bool isSimple() const { @@ -645,12 +660,12 @@ namespace llvm { /// getTypeForEVT - This method returns an LLVM type corresponding to the /// specified EVT. For integer types, this returns an unsigned type. Note /// that this will abort for types that cannot be represented. - const Type *getTypeForEVT(LLVMContext &Context) const; + Type *getTypeForEVT(LLVMContext &Context) const; /// getEVT - Return the value type corresponding to the specified type. /// This returns all pointers as iPTR. If HandleUnknown is true, unknown /// types are returned as Other, otherwise they are invalid. - static EVT getEVT(const Type *Ty, bool HandleUnknown = false); + static EVT getEVT(Type *Ty, bool HandleUnknown = false); intptr_t getRawBits() { if (isSimple()) @@ -674,6 +689,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 changeExtendedVectorElementTypeToInteger() const; static EVT getExtendedIntegerVT(LLVMContext &C, unsigned BitWidth); static EVT getExtendedVectorVT(LLVMContext &C, EVT VT, unsigned NumElements); |