diff options
Diffstat (limited to 'include/llvm/CodeGen')
27 files changed, 768 insertions, 449 deletions
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index 243ddbb..7ca6c62 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -64,7 +64,7 @@ namespace llvm { /// Target machine description. /// TargetMachine &TM; - + /// Target Asm Printer information. /// const MCAsmInfo *MAI; @@ -73,13 +73,13 @@ namespace llvm { /// streaming. This owns all of the global MC-related objects for the /// generated translation unit. MCContext &OutContext; - + /// OutStreamer - This is the MCStreamer object for the file we are /// generating. This contains the transient state for the current /// translation unit that we are generating (such as the current section /// etc). MCStreamer &OutStreamer; - + /// The current machine function. const MachineFunction *MF; @@ -94,30 +94,30 @@ namespace llvm { /// beginning of each call to runOnMachineFunction(). /// MCSymbol *CurrentFnSym; - + private: // GCMetadataPrinters - The garbage collection metadata printer table. void *GCMetadataPrinters; // Really a DenseMap. - + /// VerboseAsm - Emit comments in assembly output if this is true. /// bool VerboseAsm; static char ID; - + /// If VerboseAsm is set, a pointer to the loop info for this /// function. MachineLoopInfo *LI; /// DD - If the target supports dwarf debug info, this pointer is non-null. DwarfDebug *DD; - + /// DE - If the target supports dwarf exception info, this pointer is /// non-null. DwarfException *DE; - + protected: explicit AsmPrinter(TargetMachine &TM, MCStreamer &Streamer); - + public: virtual ~AsmPrinter(); @@ -128,7 +128,7 @@ namespace llvm { /// getFunctionNumber - Return a unique ID for the current function. /// unsigned getFunctionNumber() const; - + /// getObjFileLowering - Return information about object file lowering. const TargetLoweringObjectFile &getObjFileLowering() const; @@ -137,16 +137,16 @@ namespace llvm { /// getCurrentSection() - Return the current section we are emitting to. const MCSection *getCurrentSection() const; - - + + //===------------------------------------------------------------------===// // MachineFunctionPass Implementation. //===------------------------------------------------------------------===// - + /// getAnalysisUsage - Record analysis usage. - /// + /// void getAnalysisUsage(AnalysisUsage &AU) const; - + /// doInitialization - Set up the AsmPrinter when we are working on a new /// module. If your pass overrides this, it must make sure to explicitly /// call this implementation. @@ -155,7 +155,7 @@ namespace llvm { /// doFinalization - Shut down the asmprinter. If you override this in your /// pass, you must make sure to call it explicitly. bool doFinalization(Module &M); - + /// runOnMachineFunction - Emit the specified function out to the /// OutStreamer. virtual bool runOnMachineFunction(MachineFunction &MF) { @@ -163,20 +163,20 @@ namespace llvm { EmitFunctionHeader(); EmitFunctionBody(); return false; - } - + } + //===------------------------------------------------------------------===// // Coarse grained IR lowering routines. //===------------------------------------------------------------------===// - + /// SetupMachineFunction - This should be called when a new MachineFunction /// is being processed from runOnMachineFunction. void SetupMachineFunction(MachineFunction &MF); - + /// EmitFunctionHeader - This method emits the header for the current /// function. void EmitFunctionHeader(); - + /// EmitFunctionBody - This method emits the body and trailer for a /// function. void EmitFunctionBody(); @@ -187,15 +187,15 @@ namespace llvm { /// the code generator. /// virtual void EmitConstantPool(); - - /// EmitJumpTableInfo - Print assembly representations of the jump tables - /// used by the current function to the current output stream. + + /// EmitJumpTableInfo - Print assembly representations of the jump tables + /// used by the current function to the current output stream. /// void EmitJumpTableInfo(); - + /// EmitGlobalVariable - Emit the specified global variable to the .s file. virtual void EmitGlobalVariable(const GlobalVariable *GV); - + /// EmitSpecialLLVMGlobal - Check to see if the specified global is a /// special global used by LLVM. If so, emit it and return true, otherwise /// do nothing and return false. @@ -208,54 +208,54 @@ namespace llvm { /// if required for correctness. /// void EmitAlignment(unsigned NumBits, const GlobalValue *GV = 0) const; - + /// EmitBasicBlockStart - This method prints the label for the specified /// MachineBasicBlock, an alignment (if present) and a comment describing /// it if appropriate. void EmitBasicBlockStart(const MachineBasicBlock *MBB) const; - + /// EmitGlobalConstant - Print a general LLVM constant to the .s file. void EmitGlobalConstant(const Constant *CV, unsigned AddrSpace = 0); - - + + //===------------------------------------------------------------------===// // Overridable Hooks //===------------------------------------------------------------------===// - + // Targets can, or in the case of EmitInstruction, must implement these to // customize output. - + /// EmitStartOfAsmFile - This virtual method can be overridden by targets /// that want to emit something at the start of their file. virtual void EmitStartOfAsmFile(Module &) {} - + /// EmitEndOfAsmFile - This virtual method can be overridden by targets that /// want to emit something at the end of their file. virtual void EmitEndOfAsmFile(Module &) {} - + /// EmitFunctionBodyStart - Targets can override this to emit stuff before /// the first basic block in the function. virtual void EmitFunctionBodyStart() {} - + /// EmitFunctionBodyEnd - Targets can override this to emit stuff after /// the last basic block in the function. virtual void EmitFunctionBodyEnd() {} - + /// EmitInstruction - Targets should implement this to emit instructions. virtual void EmitInstruction(const MachineInstr *) { assert(0 && "EmitInstruction not implemented"); } - + virtual void EmitFunctionEntryLabel(); - + virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV); - + /// isBlockOnlyReachableByFallthough - Return true if the basic block has /// exactly one predecessor and the control transfer mechanism between /// the predecessor and this block is a fall-through. virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const; - + //===------------------------------------------------------------------===// // Symbol Lowering Routines. //===------------------------------------------------------------------===// @@ -264,23 +264,23 @@ namespace llvm { /// GetTempSymbol - Return the MCSymbol corresponding to the assembler /// temporary label with the specified stem and unique ID. MCSymbol *GetTempSymbol(StringRef Name, unsigned ID) const; - + /// GetTempSymbol - Return an assembler temporary label with the specified /// stem. MCSymbol *GetTempSymbol(StringRef Name) const; - - + + /// GetSymbolWithGlobalValueBase - Return the MCSymbol for a symbol with /// global value name as its base, with the specified suffix, and where the /// symbol is forced to have private linkage if ForcePrivate is true. MCSymbol *GetSymbolWithGlobalValueBase(const GlobalValue *GV, StringRef Suffix, bool ForcePrivate = true) const; - + /// GetExternalSymbolSymbol - Return the MCSymbol for the specified /// ExternalSymbol. MCSymbol *GetExternalSymbolSymbol(StringRef Sym) const; - + /// GetCPISymbol - Return the symbol for the specified constant pool entry. MCSymbol *GetCPISymbol(unsigned CPID) const; @@ -302,42 +302,42 @@ namespace llvm { public: /// printOffset - This is just convenient handler for printing offsets. void printOffset(int64_t Offset, raw_ostream &OS) const; - + /// EmitInt8 - Emit a byte directive and value. /// void EmitInt8(int Value) const; - + /// EmitInt16 - Emit a short directive and value. /// void EmitInt16(int Value) const; - + /// EmitInt32 - Emit a long directive and value. /// void EmitInt32(int Value) const; - + /// EmitLabelDifference - Emit something like ".long Hi-Lo" where the size /// in bytes of the directive is specified by Size and Hi/Lo specify the /// labels. This implicitly uses .set if it is available. void EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo, unsigned Size) const; - - /// EmitLabelOffsetDifference - Emit something like ".long Hi+Offset-Lo" + + /// EmitLabelOffsetDifference - Emit something like ".long Hi+Offset-Lo" /// where the size in bytes of the directive is specified by Size and Hi/Lo /// specify the labels. This implicitly uses .set if it is available. void EmitLabelOffsetDifference(const MCSymbol *Hi, uint64_t Offset, const MCSymbol *Lo, unsigned Size) const; - + //===------------------------------------------------------------------===// // Dwarf Emission Helper Routines //===------------------------------------------------------------------===// - + /// EmitSLEB128 - emit the specified signed leb128 value. void EmitSLEB128(int Value, const char *Desc = 0) const; - + /// EmitULEB128 - emit the specified unsigned leb128 value. void EmitULEB128(unsigned Value, const char *Desc = 0, unsigned PadTo = 0) const; - + /// EmitCFAByte - Emit a .byte 42 directive for a DW_CFA_xxx value. void EmitCFAByte(unsigned Val) const; @@ -346,15 +346,15 @@ namespace llvm { /// describing the encoding. Desc is a string saying what the encoding is /// specifying (e.g. "LSDA"). void EmitEncodingByte(unsigned Val, const char *Desc = 0) const; - + /// GetSizeOfEncodedValue - Return the size of the encoding in bytes. unsigned GetSizeOfEncodedValue(unsigned Encoding) const; - + /// EmitReference - Emit a reference to a label with a specified encoding. /// void EmitReference(const MCSymbol *Sym, unsigned Encoding) const; void EmitReference(const GlobalValue *GV, unsigned Encoding) const; - + /// EmitSectionOffset - 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 @@ -372,20 +372,20 @@ namespace llvm { //===------------------------------------------------------------------===// // Dwarf Lowering Routines //===------------------------------------------------------------------===// - + /// EmitFrameMoves - Emit frame instructions to describe the layout of the /// frame. - void EmitFrameMoves(const std::vector<MachineMove> &Moves, + void EmitFrameMoves(const std::vector<MachineMove> &Moves, MCSymbol *BaseLabel, bool isEH) const; - - + + //===------------------------------------------------------------------===// // Inline Asm Support //===------------------------------------------------------------------===// public: // These are hooks that targets can override to implement inline asm // support. These should probably be moved out of AsmPrinter someday. - + /// PrintSpecial - Print information related to the specified machine instr /// that is independent of the operand, and may be independent of the instr /// itself. This can be useful for portably encoding the comment character @@ -394,7 +394,7 @@ namespace llvm { /// for their own strange codes. virtual void PrintSpecial(const MachineInstr *MI, raw_ostream &OS, const char *Code) const; - + /// PrintAsmOperand - Print the specified operand of MI, an INLINEASM /// instruction, using the specified assembler variant. Targets should /// override this to format as appropriate. This method can return true if @@ -402,16 +402,16 @@ namespace llvm { virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, raw_ostream &OS); - + /// PrintAsmMemoryOperand - Print the specified operand of MI, an INLINEASM /// instruction, using the specified assembler variant as an address. /// Targets should override this to format as appropriate. This method can /// return true if the operand is erroneous. virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, + unsigned AsmVariant, const char *ExtraCode, raw_ostream &OS); - + private: /// Private state for PrintSpecial() // Assign a unique ID to this machine instruction. @@ -422,7 +422,7 @@ namespace llvm { /// EmitInlineAsm - Emit a blob of inline asm to the output streamer. void EmitInlineAsm(StringRef Str, unsigned LocCookie) const; - + /// EmitInlineAsm - This method formats and emits the specified machine /// instruction that is an inline asm. void EmitInlineAsm(const MachineInstr *MI) const; @@ -430,13 +430,13 @@ namespace llvm { //===------------------------------------------------------------------===// // Internal Implementation Details //===------------------------------------------------------------------===// - + /// EmitVisibility - This emits visibility information about symbol, if /// this is suported by the target. void EmitVisibility(MCSymbol *Sym, unsigned Visibility) const; - + void EmitLinkage(unsigned Linkage, MCSymbol *GVSym) const; - + void EmitJumpTableEntry(const MachineJumpTableInfo *MJTI, const MachineBasicBlock *MBB, unsigned uid) const; diff --git a/include/llvm/CodeGen/CallingConvLower.h b/include/llvm/CodeGen/CallingConvLower.h index 45a2757..7911907 100644 --- a/include/llvm/CodeGen/CallingConvLower.h +++ b/include/llvm/CodeGen/CallingConvLower.h @@ -17,14 +17,13 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/ValueTypes.h" -#include "llvm/CodeGen/SelectionDAGNodes.h" +#include "llvm/Target/TargetCallingConv.h" #include "llvm/CallingConv.h" namespace llvm { class TargetRegisterInfo; class TargetMachine; class CCState; - class SDNode; /// CCValAssign - Represent assignment of one arg/retval to a location. class CCValAssign { @@ -35,6 +34,9 @@ public: ZExt, // The value is zero extended in the location. AExt, // The value is extended with undefined upper bits. BCvt, // The value is bit-converted in the location. + VExt, // The value is vector-widened in the location. + // FIXME: Not implemented yet. Code that uses AExt to mean + // vector-widen should be fixed to use VExt instead. Indirect // The location contains pointer to the value. // TODO: a subset of the value is in the location. }; @@ -186,8 +188,7 @@ public: /// CheckReturn - Analyze the return values of a function, returning /// true if the return can be performed without sret-demotion, and /// false otherwise. - bool CheckReturn(const SmallVectorImpl<EVT> &OutTys, - const SmallVectorImpl<ISD::ArgFlagsTy> &ArgsFlags, + bool CheckReturn(const SmallVectorImpl<ISD::OutputArg> &ArgsFlags, CCAssignFn Fn); /// AnalyzeCallOperands - Analyze the outgoing arguments to a call, diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h index 005c7bc..7f3a7c7 100644 --- a/include/llvm/CodeGen/FastISel.h +++ b/include/llvm/CodeGen/FastISel.h @@ -19,11 +19,13 @@ #include "llvm/ADT/SmallSet.h" #endif #include "llvm/CodeGen/ValueTypes.h" +#include "llvm/CodeGen/MachineBasicBlock.h" namespace llvm { class AllocaInst; class ConstantFP; +class FunctionLoweringInfo; class Instruction; class MachineBasicBlock; class MachineConstantPool; @@ -36,22 +38,15 @@ class TargetInstrInfo; class TargetLowering; class TargetMachine; class TargetRegisterClass; +class TargetRegisterInfo; /// FastISel - This is a fast-path instruction selection class that /// generates poor code and doesn't support illegal types or non-trivial /// lowering, but runs quickly. class FastISel { protected: - MachineBasicBlock *MBB; DenseMap<const Value *, unsigned> LocalValueMap; - DenseMap<const Value *, unsigned> &ValueMap; - DenseMap<const BasicBlock *, MachineBasicBlock *> &MBBMap; - DenseMap<const AllocaInst *, int> &StaticAllocaMap; - std::vector<std::pair<MachineInstr*, unsigned> > &PHINodesToUpdate; -#ifndef NDEBUG - SmallSet<const Instruction *, 8> &CatchInfoLost; -#endif - MachineFunction &MF; + FunctionLoweringInfo &FuncInfo; MachineRegisterInfo &MRI; MachineFrameInfo &MFI; MachineConstantPool &MCP; @@ -60,23 +55,22 @@ protected: const TargetData &TD; const TargetInstrInfo &TII; const TargetLowering &TLI; - bool IsBottomUp; + const TargetRegisterInfo &TRI; + MachineInstr *LastLocalValue; public: + /// getLastLocalValue - Return the position of the last instruction + /// emitted for materializing constants for use in the current block. + MachineInstr *getLastLocalValue() { return LastLocalValue; } + + /// setLastLocalValue - Update the position of the last instruction + /// emitted for materializing constants for use in the current block. + void setLastLocalValue(MachineInstr *I) { LastLocalValue = I; } + /// startNewBlock - Set the current block to which generated machine /// instructions will be appended, and clear the local CSE map. /// - void startNewBlock(MachineBasicBlock *mbb) { - setCurrentBlock(mbb); - LocalValueMap.clear(); - } - - /// setCurrentBlock - Set the current block to which generated machine - /// instructions will be appended. - /// - void setCurrentBlock(MachineBasicBlock *mbb) { - MBB = mbb; - } + void startNewBlock(); /// getCurDebugLoc() - Return current debug location information. DebugLoc getCurDebugLoc() const { return DL; } @@ -108,18 +102,21 @@ public: /// index value. std::pair<unsigned, bool> getRegForGEPIndex(const Value *V); + /// recomputeInsertPt - Reset InsertPt to prepare for insterting instructions + /// into the current block. + void recomputeInsertPt(); + + /// enterLocalValueArea - Prepare InsertPt to begin inserting instructions + /// into the local value area and return the old insert position. + MachineBasicBlock::iterator enterLocalValueArea(); + + /// leaveLocalValueArea - Reset InsertPt to the given old insert position + void leaveLocalValueArea(MachineBasicBlock::iterator OldInsertPt); + virtual ~FastISel(); protected: - FastISel(MachineFunction &mf, - DenseMap<const Value *, unsigned> &vm, - DenseMap<const BasicBlock *, MachineBasicBlock *> &bm, - DenseMap<const AllocaInst *, int> &am, - std::vector<std::pair<MachineInstr*, unsigned> > &PHINodesToUpdate -#ifndef NDEBUG - , SmallSet<const Instruction *, 8> &cil -#endif - ); + explicit FastISel(FunctionLoweringInfo &funcInfo); /// TargetSelectInstruction - This method is called by target-independent /// code when the normal FastISel process fails to select an instruction. @@ -286,7 +283,7 @@ protected: /// FastEmitBranch - Emit an unconditional branch to the given block, /// unless it is the immediate (fall-through) successor, and update /// the CFG. - void FastEmitBranch(MachineBasicBlock *MBB); + void FastEmitBranch(MachineBasicBlock *MBB, DebugLoc DL); unsigned UpdateValueMap(const Value* I, unsigned Reg); @@ -305,6 +302,8 @@ protected: } private: + bool SelectLoad(const User *I); + bool SelectBinaryOp(const User *I, unsigned ISDOpcode); bool SelectFNeg(const User *I); diff --git a/include/llvm/CodeGen/FunctionLoweringInfo.h b/include/llvm/CodeGen/FunctionLoweringInfo.h new file mode 100644 index 0000000..c49d1ed --- /dev/null +++ b/include/llvm/CodeGen/FunctionLoweringInfo.h @@ -0,0 +1,154 @@ +//===-- FunctionLoweringInfo.h - Lower functions from LLVM IR to CodeGen --===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This implements routines for translating functions from LLVM IR into +// Machine IR. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_FUNCTIONLOWERINGINFO_H +#define LLVM_CODEGEN_FUNCTIONLOWERINGINFO_H + +#include "llvm/InlineAsm.h" +#include "llvm/Instructions.h" +#include "llvm/ADT/APInt.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallVector.h" +#ifndef NDEBUG +#include "llvm/ADT/SmallSet.h" +#endif +#include "llvm/CodeGen/ValueTypes.h" +#include "llvm/CodeGen/ISDOpcodes.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/Support/CallSite.h" +#include <vector> + +namespace llvm { + +class AllocaInst; +class BasicBlock; +class CallInst; +class Function; +class GlobalVariable; +class Instruction; +class MachineInstr; +class MachineBasicBlock; +class MachineFunction; +class MachineModuleInfo; +class MachineRegisterInfo; +class TargetLowering; +class Value; + +//===--------------------------------------------------------------------===// +/// FunctionLoweringInfo - This contains information that is global to a +/// function that is used when lowering a region of the function. +/// +class FunctionLoweringInfo { +public: + const TargetLowering &TLI; + const Function *Fn; + MachineFunction *MF; + MachineRegisterInfo *RegInfo; + + /// CanLowerReturn - true iff the function's return value can be lowered to + /// registers. + bool CanLowerReturn; + + /// DemoteRegister - if CanLowerReturn is false, DemoteRegister is a vreg + /// allocated to hold a pointer to the hidden sret parameter. + unsigned DemoteRegister; + + /// MBBMap - A mapping from LLVM basic blocks to their machine code entry. + DenseMap<const BasicBlock*, MachineBasicBlock *> MBBMap; + + /// ValueMap - Since we emit code for the function a basic block at a time, + /// we must remember which virtual registers hold the values for + /// cross-basic-block values. + DenseMap<const Value*, unsigned> ValueMap; + + /// StaticAllocaMap - Keep track of frame indices for fixed sized allocas in + /// the entry block. This allows the allocas to be efficiently referenced + /// anywhere in the function. + DenseMap<const AllocaInst*, int> StaticAllocaMap; + + /// ArgDbgValues - A list of DBG_VALUE instructions created during isel for + /// function arguments that are inserted after scheduling is completed. + SmallVector<MachineInstr*, 8> ArgDbgValues; + + /// RegFixups - Registers which need to be replaced after isel is done. + DenseMap<unsigned, unsigned> RegFixups; + + /// MBB - The current block. + MachineBasicBlock *MBB; + + /// MBB - The current insert position inside the current block. + MachineBasicBlock::iterator InsertPt; + +#ifndef NDEBUG + SmallSet<const Instruction *, 8> CatchInfoLost; + SmallSet<const Instruction *, 8> CatchInfoFound; +#endif + + struct LiveOutInfo { + unsigned NumSignBits; + APInt KnownOne, KnownZero; + LiveOutInfo() : NumSignBits(0), KnownOne(1, 0), KnownZero(1, 0) {} + }; + + /// LiveOutRegInfo - Information about live out vregs, indexed by their + /// register number offset by 'FirstVirtualRegister'. + std::vector<LiveOutInfo> LiveOutRegInfo; + + /// PHINodesToUpdate - A list of phi instructions whose operand list will + /// be updated after processing the current basic block. + /// TODO: This isn't per-function state, it's per-basic-block state. But + /// there's no other convenient place for it to live right now. + std::vector<std::pair<MachineInstr*, unsigned> > PHINodesToUpdate; + + explicit FunctionLoweringInfo(const TargetLowering &TLI); + + /// set - Initialize this FunctionLoweringInfo with the given Function + /// and its associated MachineFunction. + /// + void set(const Function &Fn, MachineFunction &MF); + + /// clear - Clear out all the function-specific state. This returns this + /// FunctionLoweringInfo to an empty state, ready to be used for a + /// different function. + void clear(); + + /// isExportedInst - Return true if the specified value is an instruction + /// exported from its block. + bool isExportedInst(const Value *V) { + return ValueMap.count(V); + } + + unsigned CreateReg(EVT VT); + + unsigned CreateRegs(const Type *Ty); + + unsigned InitializeRegForValue(const Value *V) { + unsigned &R = ValueMap[V]; + assert(R == 0 && "Already initialized this value register!"); + return R = CreateRegs(V->getType()); + } +}; + +/// AddCatchInfo - Extract the personality and type infos from an eh.selector +/// call, and add them to the specified machine basic block. +void AddCatchInfo(const CallInst &I, + MachineModuleInfo *MMI, MachineBasicBlock *MBB); + +/// CopyCatchInfo - Copy catch information from DestBB to SrcBB. +void CopyCatchInfo(const BasicBlock *SrcBB, const BasicBlock *DestBB, + MachineModuleInfo *MMI, FunctionLoweringInfo &FLI); + +} // end namespace llvm + +#endif diff --git a/include/llvm/CodeGen/GCMetadata.h b/include/llvm/CodeGen/GCMetadata.h index 6de69cd..b401068 100644 --- a/include/llvm/CodeGen/GCMetadata.h +++ b/include/llvm/CodeGen/GCMetadata.h @@ -1,4 +1,4 @@ -//===-- GCMetadata.h - Garbage collector metadata -------------------------===// +//===-- GCMetadata.h - Garbage collector metadata ---------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -14,7 +14,7 @@ // // The GCFunctionInfo class logs the data necessary to build a type accurate // stack map. The code generator outputs: -// +// // - Safe points as specified by the GCStrategy's NeededSafePoints. // - Stack offsets for GC roots, as specified by calls to llvm.gcroot // @@ -42,10 +42,10 @@ namespace llvm { class GCStrategy; class Constant; class MCSymbol; - + namespace GC { /// PointKind - The type of a collector-safe point. - /// + /// enum PointKind { Loop, //< Instr is a loop (backwards branch). Return, //< Instr is a return instruction. @@ -53,138 +53,138 @@ namespace llvm { PostCall //< Instr is the return address of a call. }; } - + /// GCPoint - Metadata for a collector-safe point in machine code. - /// + /// struct GCPoint { GC::PointKind Kind; //< The kind of the safe point. MCSymbol *Label; //< A label. - + GCPoint(GC::PointKind K, MCSymbol *L) : Kind(K), Label(L) {} }; - + /// GCRoot - Metadata for a pointer to an object managed by the garbage /// collector. struct GCRoot { int Num; //< Usually a frame index. int StackOffset; //< Offset from the stack pointer. const Constant *Metadata;//< Metadata straight from the call to llvm.gcroot. - + GCRoot(int N, const Constant *MD) : Num(N), StackOffset(-1), Metadata(MD) {} }; - - + + /// GCFunctionInfo - Garbage collection metadata for a single function. - /// + /// class GCFunctionInfo { public: typedef std::vector<GCPoint>::iterator iterator; typedef std::vector<GCRoot>::iterator roots_iterator; typedef std::vector<GCRoot>::const_iterator live_iterator; - + private: const Function &F; GCStrategy &S; uint64_t FrameSize; std::vector<GCRoot> Roots; std::vector<GCPoint> SafePoints; - + // FIXME: Liveness. A 2D BitVector, perhaps? - // + // // BitVector Liveness; - // + // // bool islive(int point, int root) = // Liveness[point * SafePoints.size() + root] - // + // // The bit vector is the more compact representation where >3.2% of roots // are live per safe point (1.5% on 64-bit hosts). - + public: GCFunctionInfo(const Function &F, GCStrategy &S); ~GCFunctionInfo(); - + /// getFunction - Return the function to which this metadata applies. - /// + /// const Function &getFunction() const { return F; } - + /// getStrategy - Return the GC strategy for the function. - /// + /// GCStrategy &getStrategy() { return S; } - + /// addStackRoot - Registers a root that lives on the stack. Num is the /// stack object ID for the alloca (if the code generator is // using MachineFrameInfo). void addStackRoot(int Num, const Constant *Metadata) { Roots.push_back(GCRoot(Num, Metadata)); } - + /// addSafePoint - Notes the existence of a safe point. Num is the ID of the - /// label just prior to the safe point (if the code generator is using + /// label just prior to the safe point (if the code generator is using /// MachineModuleInfo). void addSafePoint(GC::PointKind Kind, MCSymbol *Label) { SafePoints.push_back(GCPoint(Kind, Label)); } - + /// getFrameSize/setFrameSize - Records the function's frame size. - /// + /// uint64_t getFrameSize() const { return FrameSize; } void setFrameSize(uint64_t S) { FrameSize = S; } - + /// begin/end - Iterators for safe points. - /// + /// iterator begin() { return SafePoints.begin(); } iterator end() { return SafePoints.end(); } size_t size() const { return SafePoints.size(); } - + /// roots_begin/roots_end - Iterators for all roots in the function. - /// + /// roots_iterator roots_begin() { return Roots.begin(); } roots_iterator roots_end () { return Roots.end(); } size_t roots_size() const { return Roots.size(); } - + /// live_begin/live_end - Iterators for live roots at a given safe point. - /// + /// live_iterator live_begin(const iterator &p) { return roots_begin(); } live_iterator live_end (const iterator &p) { return roots_end(); } size_t live_size(const iterator &p) const { return roots_size(); } }; - - + + /// GCModuleInfo - Garbage collection metadata for a whole module. - /// + /// class GCModuleInfo : public ImmutablePass { typedef StringMap<GCStrategy*> strategy_map_type; typedef std::vector<GCStrategy*> list_type; typedef DenseMap<const Function*,GCFunctionInfo*> finfo_map_type; - + strategy_map_type StrategyMap; list_type StrategyList; finfo_map_type FInfoMap; - + GCStrategy *getOrCreateStrategy(const Module *M, const std::string &Name); - + public: typedef list_type::const_iterator iterator; - + static char ID; - + GCModuleInfo(); ~GCModuleInfo(); - + /// clear - Resets the pass. The metadata deleter pass calls this. - /// + /// void clear(); - + /// begin/end - Iterators for used strategies. - /// + /// iterator begin() const { return StrategyList.begin(); } iterator end() const { return StrategyList.end(); } - + /// get - Look up function metadata. - /// + /// GCFunctionInfo &getFunctionInfo(const Function &F); }; - + } #endif diff --git a/include/llvm/CodeGen/GCMetadataPrinter.h b/include/llvm/CodeGen/GCMetadataPrinter.h index 3703545..17a2653 100644 --- a/include/llvm/CodeGen/GCMetadataPrinter.h +++ b/include/llvm/CodeGen/GCMetadataPrinter.h @@ -25,49 +25,49 @@ #include "llvm/Support/Registry.h" namespace llvm { - + class GCMetadataPrinter; - + /// GCMetadataPrinterRegistry - The GC assembly printer registry uses all the /// defaults from Registry. typedef Registry<GCMetadataPrinter> GCMetadataPrinterRegistry; - + /// GCMetadataPrinter - Emits GC metadata as assembly code. - /// + /// class GCMetadataPrinter { public: typedef GCStrategy::list_type list_type; typedef GCStrategy::iterator iterator; - + private: GCStrategy *S; - + friend class AsmPrinter; - + protected: // May only be subclassed. GCMetadataPrinter(); - + // Do not implement. GCMetadataPrinter(const GCMetadataPrinter &); GCMetadataPrinter &operator=(const GCMetadataPrinter &); - + public: GCStrategy &getStrategy() { return *S; } const Module &getModule() const { return S->getModule(); } - + /// begin/end - Iterate over the collected function metadata. iterator begin() { return S->begin(); } iterator end() { return S->end(); } - + /// beginAssembly/finishAssembly - Emit module metadata as assembly code. virtual void beginAssembly(AsmPrinter &AP); - + virtual void finishAssembly(AsmPrinter &AP); - + virtual ~GCMetadataPrinter(); }; - + } #endif diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h index a5e9dd5..69de598 100644 --- a/include/llvm/CodeGen/ISDOpcodes.h +++ b/include/llvm/CodeGen/ISDOpcodes.h @@ -130,7 +130,7 @@ namespace ISD { /// This node represents a target intrinsic function with no side effects. /// The first operand is the ID number of the intrinsic from the /// llvm::Intrinsic namespace. The operands to the intrinsic follow. The - /// node has returns the result of the intrinsic. + /// node returns the result of the intrinsic. INTRINSIC_WO_CHAIN, /// RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) @@ -508,8 +508,9 @@ namespace ISD { CALLSEQ_START, // Beginning of a call sequence CALLSEQ_END, // End of a call sequence - // VAARG - VAARG has three operands: an input chain, a pointer, and a - // SRCVALUE. It returns a pair of values: the vaarg value and a new chain. + // VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, + // and the alignment. It returns a pair of values: the vaarg value and a + // new chain. VAARG, // VACOPY - VACOPY has five operands: an input chain, a destination pointer, diff --git a/include/llvm/CodeGen/LinkAllCodegenComponents.h b/include/llvm/CodeGen/LinkAllCodegenComponents.h index b4c2f2f..cd8293d 100644 --- a/include/llvm/CodeGen/LinkAllCodegenComponents.h +++ b/include/llvm/CodeGen/LinkAllCodegenComponents.h @@ -33,7 +33,6 @@ namespace { (void) llvm::createDeadMachineInstructionElimPass(); - (void) llvm::createLocalRegisterAllocator(); (void) llvm::createFastRegisterAllocator(); (void) llvm::createLinearScanRegisterAllocator(); (void) llvm::createPBQPRegisterAllocator(); diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h index 637f52b..8d80efb 100644 --- a/include/llvm/CodeGen/LiveInterval.h +++ b/include/llvm/CodeGen/LiveInterval.h @@ -53,7 +53,7 @@ namespace llvm { class VNInfo { private: enum { - HAS_PHI_KILL = 1, + HAS_PHI_KILL = 1, REDEF_BY_EC = 1 << 1, IS_PHI_DEF = 1 << 2, IS_UNUSED = 1 << 3, @@ -67,22 +67,14 @@ namespace llvm { } cr; public: - typedef SpecificBumpPtrAllocator<VNInfo> Allocator; - typedef SmallVector<SlotIndex, 4> KillSet; + typedef BumpPtrAllocator Allocator; /// The ID number of this value. unsigned id; - + /// The index of the defining instruction (if isDefAccurate() returns true). SlotIndex def; - KillSet kills; - - /* - VNInfo(LiveIntervals &li_) - : defflags(IS_UNUSED), id(~1U) { cr.copy = 0; } - */ - /// VNInfo constructor. /// d is presumed to point to the actual defining instr. If it doesn't /// setIsDefAccurate(false) should be called after construction. @@ -91,7 +83,7 @@ namespace llvm { /// VNInfo construtor, copies values from orig, except for the value number. VNInfo(unsigned i, const VNInfo &orig) - : flags(orig.flags), cr(orig.cr), id(i), def(orig.def), kills(orig.kills) + : flags(orig.flags), cr(orig.cr), id(i), def(orig.def) { } /// Copy from the parameter into this VNInfo. @@ -99,7 +91,6 @@ namespace llvm { flags = src.flags; cr = src.cr; def = src.def; - kills = src.kills; } /// Used for copying value number info. @@ -114,7 +105,7 @@ namespace llvm { /// This method should not be called on stack intervals as it may lead to /// undefined behavior. void setCopy(MachineInstr *c) { cr.copy = c; } - + /// For a stack interval, returns the reg which this stack interval was /// defined from. /// For a register interval the behaviour of this method is undefined. @@ -144,7 +135,7 @@ namespace llvm { else flags &= ~REDEF_BY_EC; } - + /// Returns true if this value is defined by a PHI instruction (or was, /// PHI instrucions may have been eliminated). bool isPHIDef() const { return flags & IS_PHI_DEF; } @@ -172,49 +163,9 @@ namespace llvm { void setIsDefAccurate(bool defAccurate) { if (defAccurate) flags |= IS_DEF_ACCURATE; - else + else flags &= ~IS_DEF_ACCURATE; } - - /// Returns true if the given index is a kill of this value. - bool isKill(SlotIndex k) const { - KillSet::const_iterator - i = std::lower_bound(kills.begin(), kills.end(), k); - return (i != kills.end() && *i == k); - } - - /// addKill - Add a kill instruction index to the specified value - /// number. - void addKill(SlotIndex k) { - if (kills.empty()) { - kills.push_back(k); - } else { - KillSet::iterator - i = std::lower_bound(kills.begin(), kills.end(), k); - kills.insert(i, k); - } - } - - /// Remove the specified kill index from this value's kills list. - /// Returns true if the value was present, otherwise returns false. - bool removeKill(SlotIndex k) { - KillSet::iterator i = std::lower_bound(kills.begin(), kills.end(), k); - if (i != kills.end() && *i == k) { - kills.erase(i); - return true; - } - return false; - } - - /// Remove all kills in the range [s, e). - void removeKills(SlotIndex s, SlotIndex e) { - KillSet::iterator - si = std::lower_bound(kills.begin(), kills.end(), s), - se = std::upper_bound(kills.begin(), kills.end(), e); - - kills.erase(si, se); - } - }; /// LiveRange structure - This represents a simple register range in the @@ -258,6 +209,8 @@ namespace llvm { LiveRange(); // DO NOT IMPLEMENT }; + template <> struct isPodLike<LiveRange> { static const bool value = true; }; + raw_ostream& operator<<(raw_ostream& os, const LiveRange &LR); @@ -366,8 +319,8 @@ namespace llvm { /// the instruction that defines the value number. VNInfo *getNextValue(SlotIndex def, MachineInstr *CopyMI, bool isDefAccurate, VNInfo::Allocator &VNInfoAllocator) { - VNInfo *VNI = VNInfoAllocator.Allocate(); - new (VNI) VNInfo((unsigned)valnos.size(), def, CopyMI); + VNInfo *VNI = + new (VNInfoAllocator) VNInfo((unsigned)valnos.size(), def, CopyMI); VNI->setIsDefAccurate(isDefAccurate); valnos.push_back(VNI); return VNI; @@ -377,23 +330,12 @@ namespace llvm { /// for the Value number. VNInfo *createValueCopy(const VNInfo *orig, VNInfo::Allocator &VNInfoAllocator) { - VNInfo *VNI = VNInfoAllocator.Allocate(); - new (VNI) VNInfo((unsigned)valnos.size(), *orig); + VNInfo *VNI = + new (VNInfoAllocator) VNInfo((unsigned)valnos.size(), *orig); valnos.push_back(VNI); return VNI; } - /// addKills - Add a number of kills into the VNInfo kill vector. If this - /// interval is live at a kill point, then the kill is not added. - void addKills(VNInfo *VNI, const VNInfo::KillSet &kills) { - for (unsigned i = 0, e = static_cast<unsigned>(kills.size()); - i != e; ++i) { - if (!liveBeforeAndAt(kills[i])) { - VNI->addKill(kills[i]); - } - } - } - /// isOnlyLROfValNo - Return true if the specified live range is the only /// one defined by the its val#. bool isOnlyLROfValNo(const LiveRange *LR) { @@ -472,6 +414,17 @@ namespace llvm { // range.If it does, then check if the previous live range ends at index-1. bool liveBeforeAndAt(SlotIndex index) const; + /// killedAt - Return true if a live range ends at index. Note that the kill + /// point is not contained in the half-open live range. It is usually the + /// getDefIndex() slot following its last use. + bool killedAt(SlotIndex index) const; + + /// killedInRange - Return true if the interval has kills in [Start,End). + /// Note that the kill point is considered the end of a live range, so it is + /// not contained in the live range. If a live range ends at End, it won't + /// be counted as a kill by this method. + bool killedInRange(SlotIndex Start, SlotIndex End) const; + /// getLiveRangeContaining - Return the live range that contains the /// specified index, or null if there is none. const LiveRange *getLiveRangeContaining(SlotIndex Idx) const { @@ -486,6 +439,12 @@ namespace llvm { return I == end() ? 0 : &*I; } + /// getVNInfoAt - Return the VNInfo that is live at Idx, or NULL. + VNInfo *getVNInfoAt(SlotIndex Idx) const { + const_iterator I = FindLiveRangeContaining(Idx); + 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. const_iterator FindLiveRangeContaining(SlotIndex Idx) const; diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h index 32fa709..5a0d81b 100644 --- a/include/llvm/CodeGen/LiveIntervalAnalysis.h +++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -133,10 +133,9 @@ namespace llvm { bool conflictsWithPhysReg(const LiveInterval &li, VirtRegMap &vrm, unsigned reg); - /// conflictsWithSubPhysRegRef - Similar to conflictsWithPhysRegRef except - /// it checks for sub-register reference and it can check use as well. - bool conflictsWithSubPhysRegRef(LiveInterval &li, unsigned Reg, - bool CheckUse, + /// conflictsWithAliasRef - Similar to conflictsWithPhysRegRef except + /// it checks for alias uses and defs. + bool conflictsWithAliasRef(LiveInterval &li, unsigned Reg, SmallPtrSet<MachineInstr*,32> &JoinedCopies); // Interval creation @@ -229,10 +228,6 @@ namespace llvm { VNInfo::Allocator& getVNInfoAllocator() { return VNInfoAllocator; } - /// getVNInfoSourceReg - Helper function that parses the specified VNInfo - /// copy field and returns the source register that defines it. - unsigned getVNInfoSourceReg(const VNInfo *VNI) const; - virtual void getAnalysisUsage(AnalysisUsage &AU) const; virtual void releaseMemory(); @@ -249,12 +244,6 @@ namespace llvm { addIntervalsForSpills(const LiveInterval& i, SmallVectorImpl<LiveInterval*> &SpillIs, const MachineLoopInfo *loopInfo, VirtRegMap& vrm); - - /// addIntervalsForSpillsFast - Quickly create new intervals for spilled - /// defs / uses without remat or splitting. - std::vector<LiveInterval*> - addIntervalsForSpillsFast(const LiveInterval &li, - const MachineLoopInfo *loopInfo, VirtRegMap &vrm); /// spillPhysRegAroundRegDefsUses - Spill the specified physical register /// around all defs and uses of the specified interval. Return true if it diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h index cc651ca..3cfc47a 100644 --- a/include/llvm/CodeGen/MachineBasicBlock.h +++ b/include/llvm/CodeGen/MachineBasicBlock.h @@ -19,6 +19,7 @@ namespace llvm { +class Pass; class BasicBlock; class MachineFunction; class MCSymbol; @@ -258,6 +259,11 @@ public: /// machine basic block (i.e., copies all the successors fromMBB and /// remove all the successors from fromMBB). void transferSuccessors(MachineBasicBlock *fromMBB); + + /// transferSuccessorsAndUpdatePHIs - Transfers all the successors, as + /// in transferSuccessors, and update PHI operands in the successor blocks + /// which refer to fromMBB to refer to this. + void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *fromMBB); /// isSuccessor - Return true if the specified MBB is a successor of this /// block. @@ -276,11 +282,26 @@ public: /// branch to do so (e.g., a table jump). True is a conservative answer. bool canFallThrough(); + /// Returns a pointer to the first instructon in this block that is not a + /// PHINode instruction. When adding instruction to the beginning of the + /// basic block, they should be added before the returned value, not before + /// the first instruction, which might be PHI. + /// Returns end() is there's no non-PHI instruction. + iterator getFirstNonPHI(); + /// getFirstTerminator - returns an iterator to the first terminator /// instruction of this basic block. If a terminator does not exist, /// it returns end() iterator getFirstTerminator(); + /// SplitCriticalEdge - Split the critical edge from this block to the + /// given successor block, and return the newly created block, or null + /// if splitting is not possible. + /// + /// This function updates LiveVariables, MachineDominatorTree, and + /// MachineLoopInfo, as applicable. + MachineBasicBlock *SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P); + void pop_front() { Insts.pop_front(); } void pop_back() { Insts.pop_back(); } void push_back(MachineInstr *MI) { Insts.push_back(MI); } diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h index fe2c298..9471316 100644 --- a/include/llvm/CodeGen/MachineFrameInfo.h +++ b/include/llvm/CodeGen/MachineFrameInfo.h @@ -33,16 +33,14 @@ class BitVector; /// callee saved register in the current frame. class CalleeSavedInfo { unsigned Reg; - const TargetRegisterClass *RegClass; int FrameIdx; public: - CalleeSavedInfo(unsigned R, const TargetRegisterClass *RC, int FI = 0) - : Reg(R), RegClass(RC), FrameIdx(FI) {} + explicit CalleeSavedInfo(unsigned R, int FI = 0) + : Reg(R), FrameIdx(FI) {} // Accessors. unsigned getReg() const { return Reg; } - const TargetRegisterClass *getRegClass() const { return RegClass; } int getFrameIdx() const { return FrameIdx; } void setFrameIdx(int FI) { FrameIdx = FI; } }; @@ -100,8 +98,7 @@ class MachineFrameInfo { // cannot alias any other memory objects. bool isSpillSlot; - StackObject(uint64_t Sz, unsigned Al, int64_t SP, bool IM, - bool isSS) + StackObject(uint64_t Sz, unsigned Al, int64_t SP, bool IM, bool isSS) : SPOffset(SP), Size(Sz), Alignment(Al), isImmutable(IM), isSpillSlot(isSS) {} }; @@ -352,8 +349,7 @@ public: /// efficiency. By default, fixed objects are immutable. This returns an /// index with a negative value. /// - int CreateFixedObject(uint64_t Size, int64_t SPOffset, - bool Immutable, bool isSS); + int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool Immutable); /// isFixedObjectIndex - Returns true if the specified index corresponds to a diff --git a/include/llvm/CodeGen/MachineFunctionPass.h b/include/llvm/CodeGen/MachineFunctionPass.h index 1a2b129..685e868 100644 --- a/include/llvm/CodeGen/MachineFunctionPass.h +++ b/include/llvm/CodeGen/MachineFunctionPass.h @@ -34,9 +34,6 @@ protected: explicit MachineFunctionPass(intptr_t ID) : FunctionPass(ID) {} explicit MachineFunctionPass(void *ID) : FunctionPass(ID) {} - /// createPrinterPass - Get a machine function printer pass. - Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const; - /// runOnMachineFunction - This method must be overloaded to perform the /// desired machine code transformation or analysis. /// @@ -51,7 +48,11 @@ protected: virtual void getAnalysisUsage(AnalysisUsage &AU) const; private: - bool runOnFunction(Function &F); + /// createPrinterPass - Get a machine function printer pass. + virtual Pass *createPrinterPass(raw_ostream &O, + const std::string &Banner) const; + + virtual bool runOnFunction(Function &F); }; } // End llvm namespace diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index cf691bb..e67b2dd 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -215,9 +215,6 @@ public: bool isKill() const { return getOpcode() == TargetOpcode::KILL; } bool isImplicitDef() const { return getOpcode()==TargetOpcode::IMPLICIT_DEF; } bool isInlineAsm() const { return getOpcode() == TargetOpcode::INLINEASM; } - bool isExtractSubreg() const { - return getOpcode() == TargetOpcode::EXTRACT_SUBREG; - } bool isInsertSubreg() const { return getOpcode() == TargetOpcode::INSERT_SUBREG; } @@ -227,7 +224,22 @@ public: bool isRegSequence() const { return getOpcode() == TargetOpcode::REG_SEQUENCE; } - + bool isCopy() const { + return getOpcode() == TargetOpcode::COPY; + } + + /// isCopyLike - Return true if the instruction behaves like a copy. + /// This does not include native copy instructions. + bool isCopyLike() const { + return isCopy() || isSubregToReg(); + } + + /// isIdentityCopy - Return true is the instruction is an identity copy. + bool isIdentityCopy() const { + return isCopy() && getOperand(0).getReg() == getOperand(1).getReg() && + getOperand(0).getSubReg() == getOperand(1).getSubReg(); + } + /// readsRegister - Return true if the MachineInstr reads the specified /// register. If TargetRegisterInfo is passed, then it also checks if there /// is a read of a super-register. @@ -339,6 +351,11 @@ public: /// copyPredicates - Copies predicate operand(s) from MI. void copyPredicates(const MachineInstr *MI); + /// substituteRegister - Replace all occurrences of FromReg with ToReg:SubIdx, + /// properly composing subreg indices where necessary. + void substituteRegister(unsigned FromReg, unsigned ToReg, unsigned SubIdx, + const TargetRegisterInfo &RegInfo); + /// addRegisterKilled - We have determined MI kills a register. Look for the /// operand that uses it and mark it as IsKill. If AddIfNotFound is true, /// add a implicit operand if it's not found. Returns true if the operand @@ -359,6 +376,11 @@ public: void addRegisterDefined(unsigned IncomingReg, const TargetRegisterInfo *RegInfo = 0); + /// setPhysRegsDeadExcept - Mark every physreg used by this instruction as dead + /// except those in the UsedRegs list. + void setPhysRegsDeadExcept(const SmallVectorImpl<unsigned> &UsedRegs, + const TargetRegisterInfo &TRI); + /// isSafeToMove - Return true if it is safe to move this instruction. If /// SawStore is set to true, it means that there is a store (or call) between /// the instruction's location and its intended destination. diff --git a/include/llvm/CodeGen/MachineJumpTableInfo.h b/include/llvm/CodeGen/MachineJumpTableInfo.h index 1b6ab2c..6264349 100644 --- a/include/llvm/CodeGen/MachineJumpTableInfo.h +++ b/include/llvm/CodeGen/MachineJumpTableInfo.h @@ -74,7 +74,7 @@ private: JTEntryKind EntryKind; std::vector<MachineJumpTableEntry> JumpTables; public: - MachineJumpTableInfo(JTEntryKind Kind): EntryKind(Kind) {} + explicit MachineJumpTableInfo(JTEntryKind Kind): EntryKind(Kind) {} JTEntryKind getEntryKind() const { return EntryKind; } diff --git a/include/llvm/CodeGen/MachineLoopInfo.h b/include/llvm/CodeGen/MachineLoopInfo.h index 8459a8d..3b3e31e 100644 --- a/include/llvm/CodeGen/MachineLoopInfo.h +++ b/include/llvm/CodeGen/MachineLoopInfo.h @@ -64,13 +64,13 @@ class MachineLoopInfo : public MachineFunctionPass { void operator=(const MachineLoopInfo &); // do not implement MachineLoopInfo(const MachineLoopInfo &); // do not implement - LoopInfoBase<MachineBasicBlock, MachineLoop>& getBase() { return LI; } - public: static char ID; // Pass identification, replacement for typeid MachineLoopInfo() : MachineFunctionPass(&ID) {} + LoopInfoBase<MachineBasicBlock, MachineLoop>& getBase() { return LI; } + /// iterator/begin/end - The interface to the top-level loops in the current /// function. /// diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h index 31858ce..afa2c29 100644 --- a/include/llvm/CodeGen/MachineOperand.h +++ b/include/llvm/CodeGen/MachineOperand.h @@ -27,6 +27,7 @@ class MachineInstr; class MachineRegisterInfo; class MDNode; class TargetMachine; +class TargetRegisterInfo; class raw_ostream; class MCSymbol; @@ -246,7 +247,20 @@ public: assert(isReg() && "Wrong MachineOperand accessor"); SubReg = (unsigned char)subReg; } - + + /// substVirtReg - Substitute the current register with the virtual + /// subregister Reg:SubReg. Take any existing SubReg index into account, + /// using TargetRegisterInfo to compose the subreg indices if necessary. + /// Reg must be a virtual register, SubIdx can be 0. + /// + void substVirtReg(unsigned Reg, unsigned SubIdx, const TargetRegisterInfo&); + + /// substPhysReg - Substitute the current register with the physical register + /// Reg, taking any existing SubReg into account. For instance, + /// substPhysReg(%EAX) will change %reg1024:sub_8bit to %AL. + /// + void substPhysReg(unsigned Reg, const TargetRegisterInfo&); + void setIsUse(bool Val = true) { assert(isReg() && "Wrong MachineOperand accessor"); assert((Val || !isDebug()) && "Marking a debug operation as def"); diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h index fa14fdc..066c91b 100644 --- a/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/include/llvm/CodeGen/MachineRegisterInfo.h @@ -35,7 +35,7 @@ class MachineRegisterInfo { /// RegClassVRegMap - This vector acts as a map from TargetRegisterClass to /// virtual registers. For each target register class, it keeps a list of /// virtual registers belonging to the class. - std::vector<std::vector<unsigned> > RegClass2VRegMap; + std::vector<unsigned> *RegClass2VRegMap; /// RegAllocHints - This vector records register allocation hints for virtual /// registers. For each virtual register, it keeps a register and hint type @@ -363,7 +363,18 @@ public: defusechain_iterator operator++(int) { // Postincrement defusechain_iterator tmp = *this; ++*this; return tmp; } - + + /// skipInstruction - move forward until reaching a different instruction. + /// Return the skipped instruction that is no longer pointed to, or NULL if + /// already pointing to end(). + MachineInstr *skipInstruction() { + if (!Op) return 0; + MachineInstr *MI = Op->getParent(); + do ++*this; + while (Op && Op->getParent() == MI); + return MI; + } + MachineOperand &getOperand() const { assert(Op && "Cannot dereference end iterator!"); return *Op; diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index 2f5d576..7445ec7 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -85,15 +85,10 @@ namespace llvm { /// FunctionPass *createDeadMachineInstructionElimPass(); - /// Creates a register allocator as the user specified on the command line. + /// Creates a register allocator as the user specified on the command line, or + /// picks one that matches OptLevel. /// - FunctionPass *createRegisterAllocator(); - - /// LocalRegisterAllocation Pass - This pass register allocates the input code - /// a basic block at a time, yielding code better than the simple register - /// allocator, but not as good as a global allocator. - /// - FunctionPass *createLocalRegisterAllocator(); + FunctionPass *createRegisterAllocator(CodeGenOpt::Level OptLevel); /// FastRegisterAllocation Pass - This pass register allocates as fast as /// possible. It is best suited for debug code where live ranges are short. @@ -147,10 +142,6 @@ namespace llvm { /// headers to target specific alignment boundary. FunctionPass *createCodePlacementOptPass(); - /// getRegisterAllocator - This creates an instance of the register allocator - /// for the Sparc. - FunctionPass *getRegisterAllocator(TargetMachine &T); - /// IntrinsicLowering Pass - Performs target-independent LLVM IR /// transformations for highly portable strategies. FunctionPass *createGCLoweringPass(); diff --git a/include/llvm/CodeGen/PostRAHazardRecognizer.h b/include/llvm/CodeGen/PostRAHazardRecognizer.h new file mode 100644 index 0000000..24d73cb --- /dev/null +++ b/include/llvm/CodeGen/PostRAHazardRecognizer.h @@ -0,0 +1,94 @@ +//=- llvm/CodeGen/PostRAHazardRecognizer.h - Scheduling Support -*- 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 the PostRAHazardRecognizer class, which +// implements hazard-avoidance heuristics for scheduling, based on the +// scheduling itineraries specified for the target. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_EXACTHAZARDRECOGNIZER_H +#define LLVM_CODEGEN_EXACTHAZARDRECOGNIZER_H + +#include "llvm/CodeGen/ScheduleHazardRecognizer.h" +#include "llvm/System/DataTypes.h" + +#include <cassert> +#include <cstring> +#include <string> + +namespace llvm { + +class InstrItineraryData; +class SUnit; + +class PostRAHazardRecognizer : public ScheduleHazardRecognizer { + // ScoreBoard to track function unit usage. ScoreBoard[0] is a + // mask of the FUs in use in the cycle currently being + // schedule. ScoreBoard[1] is a mask for the next cycle. The + // ScoreBoard is used as a circular buffer with the current cycle + // indicated by Head. + class ScoreBoard { + unsigned *Data; + + // The maximum number of cycles monitored by the Scoreboard. This + // value is determined based on the target itineraries to ensure + // that all hazards can be tracked. + size_t Depth; + // Indices into the Scoreboard that represent the current cycle. + size_t Head; + public: + ScoreBoard():Data(NULL), Depth(0), Head(0) { } + ~ScoreBoard() { + delete[] Data; + } + + size_t getDepth() const { return Depth; } + unsigned& operator[](size_t idx) const { + assert(Depth && "ScoreBoard was not initialized properly!"); + + return Data[(Head + idx) % Depth]; + } + + void reset(size_t d = 1) { + if (Data == NULL) { + Depth = d; + Data = new unsigned[Depth]; + } + + memset(Data, 0, Depth * sizeof(Data[0])); + Head = 0; + } + + void advance() { + Head = (Head + 1) % Depth; + } + + // Print the scoreboard. + void dump() const; + }; + + // Itinerary data for the target. + const InstrItineraryData &ItinData; + + ScoreBoard ReservedScoreboard; + ScoreBoard RequiredScoreboard; + +public: + PostRAHazardRecognizer(const InstrItineraryData &ItinData); + + virtual HazardType getHazardType(SUnit *SU); + virtual void Reset(); + virtual void EmitInstruction(SUnit *SU); + virtual void AdvanceCycle(); +}; + +} + +#endif diff --git a/include/llvm/CodeGen/RegisterCoalescer.h b/include/llvm/CodeGen/RegisterCoalescer.h index 1490aa0..7644433 100644 --- a/include/llvm/CodeGen/RegisterCoalescer.h +++ b/include/llvm/CodeGen/RegisterCoalescer.h @@ -25,6 +25,9 @@ namespace llvm { class RegallocQuery; class AnalysisUsage; class MachineInstr; + class TargetRegisterInfo; + class TargetRegisterClass; + class TargetInstrInfo; /// An abstract interface for register coalescers. Coalescers must /// implement this interface to be part of the coalescer analysis @@ -141,6 +144,93 @@ namespace llvm { return true; } }; + + + /// CoalescerPair - A helper class for register coalescers. When deciding if + /// two registers can be coalesced, CoalescerPair can determine if a copy + /// instruction would become an identity copy after coalescing. + class CoalescerPair { + const TargetInstrInfo &tii_; + const TargetRegisterInfo &tri_; + + /// dstReg_ - The register that will be left after coalescing. It can be a + /// virtual or physical register. + unsigned dstReg_; + + /// srcReg_ - the virtual register that will be coalesced into dstReg. + unsigned srcReg_; + + /// subReg_ - The subregister index of srcReg in dstReg_. It is possible the + /// coalesce srcReg_ into a subreg of the larger dstReg_ when dstReg_ is a + /// virtual register. + unsigned subIdx_; + + /// partial_ - True when the original copy was a partial subregister copy. + bool partial_; + + /// crossClass_ - True when both regs are virtual, and newRC is constrained. + bool crossClass_; + + /// flipped_ - True when DstReg and SrcReg are reversed from the oriignal copy + /// instruction. + bool flipped_; + + /// newRC_ - The register class of the coalesced register, or NULL if dstReg_ + /// is a physreg. + const TargetRegisterClass *newRC_; + + /// compose - Compose subreg indices a and b, either may be 0. + unsigned compose(unsigned, unsigned) const; + + /// isMoveInstr - Return true if MI is a move or subreg instruction. + bool isMoveInstr(const MachineInstr *MI, unsigned &Src, unsigned &Dst, + unsigned &SrcSub, unsigned &DstSub) const; + + public: + CoalescerPair(const TargetInstrInfo &tii, const TargetRegisterInfo &tri) + : tii_(tii), tri_(tri), dstReg_(0), srcReg_(0), subIdx_(0), + partial_(false), crossClass_(false), flipped_(false), newRC_(0) {} + + /// setRegisters - set registers to match the copy instruction MI. Return + /// false if MI is not a coalescable copy instruction. + bool setRegisters(const MachineInstr*); + + /// flip - Swap srcReg_ and dstReg_. Return false if swapping is impossible + /// because dstReg_ is a physical register, or subIdx_ is set. + bool flip(); + + /// isCoalescable - Return true if MI is a copy instruction that will become + /// an identity copy after coalescing. + bool isCoalescable(const MachineInstr*) const; + + /// isPhys - Return true if DstReg is a physical register. + bool isPhys() const { return !newRC_; } + + /// isPartial - Return true if the original copy instruction did not copy the + /// full register, but was a subreg operation. + bool isPartial() const { return partial_; } + + /// isCrossClass - Return true if DstReg is virtual and NewRC is a smaller register class than DstReg's. + bool isCrossClass() const { return crossClass_; } + + /// isFlipped - Return true when getSrcReg is the register being defined by + /// the original copy instruction. + bool isFlipped() const { return flipped_; } + + /// getDstReg - Return the register (virtual or physical) that will remain + /// after coalescing. + unsigned getDstReg() const { return dstReg_; } + + /// getSrcReg - Return the virtual register that will be coalesced away. + unsigned getSrcReg() const { return srcReg_; } + + /// getSubIdx - Return the subregister index in DstReg that SrcReg will be + /// coalesced into, or 0. + unsigned getSubIdx() const { return subIdx_; } + + /// getNewRC - Return the register class of the coalesced register. + const TargetRegisterClass *getNewRC() const { return newRC_; } + }; } // Because of the way .a files work, we must force the SimpleRC diff --git a/include/llvm/CodeGen/RegisterScavenging.h b/include/llvm/CodeGen/RegisterScavenging.h index 84b726d..246831c 100644 --- a/include/llvm/CodeGen/RegisterScavenging.h +++ b/include/llvm/CodeGen/RegisterScavenging.h @@ -98,6 +98,10 @@ public: /// getRegsUsed - return all registers currently in use in used. void getRegsUsed(BitVector &used, bool includeReserved); + /// getRegsAvailable - Return all available registers in the register class + /// in Mask. + void getRegsAvailable(const TargetRegisterClass *RC, BitVector &Mask); + /// FindUnusedReg - Find a unused register of the specified register class. /// Return 0 if none is found. unsigned FindUnusedReg(const TargetRegisterClass *RegClass) const; @@ -147,7 +151,12 @@ private: /// Add Reg and its aliases to BV. void addRegWithAliases(BitVector &BV, unsigned Reg); - unsigned findSurvivorReg(MachineBasicBlock::iterator MI, + /// findSurvivorReg - Return the candidate register that is unused for the + /// longest after StartMI. UseMI is set to the instruction where the search + /// stopped. + /// + /// No more than InstrLimit instructions are inspected. + unsigned findSurvivorReg(MachineBasicBlock::iterator StartMI, BitVector &Candidates, unsigned InstrLimit, MachineBasicBlock::iterator &UseMI); diff --git a/include/llvm/CodeGen/RuntimeLibcalls.h b/include/llvm/CodeGen/RuntimeLibcalls.h index 42ae563..a51e82a 100644 --- a/include/llvm/CodeGen/RuntimeLibcalls.h +++ b/include/llvm/CodeGen/RuntimeLibcalls.h @@ -247,6 +247,40 @@ namespace RTLIB { // EXCEPTION HANDLING UNWIND_RESUME, + // Family ATOMICs + SYNC_VAL_COMPARE_AND_SWAP_1, + SYNC_VAL_COMPARE_AND_SWAP_2, + SYNC_VAL_COMPARE_AND_SWAP_4, + SYNC_VAL_COMPARE_AND_SWAP_8, + SYNC_LOCK_TEST_AND_SET_1, + SYNC_LOCK_TEST_AND_SET_2, + SYNC_LOCK_TEST_AND_SET_4, + SYNC_LOCK_TEST_AND_SET_8, + SYNC_FETCH_AND_ADD_1, + SYNC_FETCH_AND_ADD_2, + SYNC_FETCH_AND_ADD_4, + SYNC_FETCH_AND_ADD_8, + SYNC_FETCH_AND_SUB_1, + SYNC_FETCH_AND_SUB_2, + SYNC_FETCH_AND_SUB_4, + SYNC_FETCH_AND_SUB_8, + SYNC_FETCH_AND_AND_1, + SYNC_FETCH_AND_AND_2, + SYNC_FETCH_AND_AND_4, + SYNC_FETCH_AND_AND_8, + SYNC_FETCH_AND_OR_1, + SYNC_FETCH_AND_OR_2, + SYNC_FETCH_AND_OR_4, + SYNC_FETCH_AND_OR_8, + SYNC_FETCH_AND_XOR_1, + SYNC_FETCH_AND_XOR_2, + SYNC_FETCH_AND_XOR_4, + SYNC_FETCH_AND_XOR_8, + SYNC_FETCH_AND_NAND_1, + SYNC_FETCH_AND_NAND_2, + SYNC_FETCH_AND_NAND_4, + SYNC_FETCH_AND_NAND_8, + UNKNOWN_LIBCALL }; diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index 97202bd..de49d18 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -29,7 +29,6 @@ namespace llvm { class AliasAnalysis; -class FunctionLoweringInfo; class MachineConstantPoolValue; class MachineFunction; class MDNode; @@ -134,7 +133,6 @@ class SelectionDAG { const TargetLowering &TLI; const TargetSelectionDAGInfo &TSI; MachineFunction *MF; - FunctionLoweringInfo &FLI; LLVMContext *Context; /// EntryNode - The starting token. @@ -187,7 +185,7 @@ class SelectionDAG { SelectionDAG(const SelectionDAG&); // Do not implement. public: - SelectionDAG(const TargetMachine &TM, FunctionLoweringInfo &fli); + explicit SelectionDAG(const TargetMachine &TM); ~SelectionDAG(); /// init - Prepare this SelectionDAG to process code in the given @@ -204,7 +202,6 @@ public: const TargetMachine &getTarget() const { return TM; } const TargetLowering &getTargetLoweringInfo() const { return TLI; } const TargetSelectionDAGInfo &getSelectionDAGInfo() const { return TSI; } - FunctionLoweringInfo &getFunctionLoweringInfo() const { return FLI; } LLVMContext *getContext() const {return Context; } /// viewGraph - Pop up a GraphViz/gv window with the DAG rendered using 'dot'. @@ -351,13 +348,13 @@ public: SDValue getTargetConstantFP(const ConstantFP &Val, EVT VT) { return getConstantFP(Val, VT, true); } - SDValue getGlobalAddress(const GlobalValue *GV, EVT VT, + SDValue getGlobalAddress(const GlobalValue *GV, DebugLoc DL, EVT VT, int64_t offset = 0, bool isTargetGA = false, unsigned char TargetFlags = 0); - SDValue getTargetGlobalAddress(const GlobalValue *GV, EVT VT, + SDValue getTargetGlobalAddress(const GlobalValue *GV, DebugLoc DL, EVT VT, int64_t offset = 0, unsigned char TargetFlags = 0) { - return getGlobalAddress(GV, VT, offset, true, TargetFlags); + return getGlobalAddress(GV, DL, VT, offset, true, TargetFlags); } SDValue getFrameIndex(int FI, EVT VT, bool isTarget = false); SDValue getTargetFrameIndex(int FI, EVT VT) { @@ -585,7 +582,7 @@ public: /// getVAArg - VAArg produces a result and token chain, and takes a pointer /// and a source value as input. SDValue getVAArg(EVT VT, DebugLoc dl, SDValue Chain, SDValue Ptr, - SDValue SV); + SDValue SV, unsigned Align); /// getAtomic - Gets a node for an atomic op, produces result and chain and /// takes 3 operands @@ -635,18 +632,20 @@ public: SDValue getLoad(EVT VT, DebugLoc dl, SDValue Chain, SDValue Ptr, const Value *SV, int SVOffset, bool isVolatile, bool isNonTemporal, unsigned Alignment); - SDValue getExtLoad(ISD::LoadExtType ExtType, DebugLoc dl, EVT VT, + SDValue getExtLoad(ISD::LoadExtType ExtType, EVT VT, DebugLoc dl, SDValue Chain, SDValue Ptr, const Value *SV, int SVOffset, EVT MemVT, bool isVolatile, bool isNonTemporal, unsigned Alignment); SDValue getIndexedLoad(SDValue OrigLoad, DebugLoc dl, SDValue Base, - SDValue Offset, ISD::MemIndexedMode AM); - SDValue getLoad(ISD::MemIndexedMode AM, DebugLoc dl, ISD::LoadExtType ExtType, - EVT VT, SDValue Chain, SDValue Ptr, SDValue Offset, + SDValue Offset, ISD::MemIndexedMode AM); + SDValue getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType, + EVT VT, DebugLoc dl, + SDValue Chain, SDValue Ptr, SDValue Offset, const Value *SV, int SVOffset, EVT MemVT, bool isVolatile, bool isNonTemporal, unsigned Alignment); - SDValue getLoad(ISD::MemIndexedMode AM, DebugLoc dl, ISD::LoadExtType ExtType, - EVT VT, SDValue Chain, SDValue Ptr, SDValue Offset, + SDValue getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType, + EVT VT, DebugLoc dl, + SDValue Chain, SDValue Ptr, SDValue Offset, EVT MemVT, MachineMemOperand *MMO); /// getStore - Helper function to build ISD::STORE nodes. @@ -681,15 +680,15 @@ public: /// already exists. If the resultant node does not exist in the DAG, the /// input node is returned. As a degenerate case, if you specify the same /// input operands as the node already has, the input node is returned. - SDValue UpdateNodeOperands(SDValue N, SDValue Op); - SDValue UpdateNodeOperands(SDValue N, SDValue Op1, SDValue Op2); - SDValue UpdateNodeOperands(SDValue N, SDValue Op1, SDValue Op2, + SDNode *UpdateNodeOperands(SDNode *N, SDValue Op); + SDNode *UpdateNodeOperands(SDNode *N, SDValue Op1, SDValue Op2); + SDNode *UpdateNodeOperands(SDNode *N, SDValue Op1, SDValue Op2, SDValue Op3); - SDValue UpdateNodeOperands(SDValue N, SDValue Op1, SDValue Op2, + SDNode *UpdateNodeOperands(SDNode *N, SDValue Op1, SDValue Op2, SDValue Op3, SDValue Op4); - SDValue UpdateNodeOperands(SDValue N, SDValue Op1, SDValue Op2, + SDNode *UpdateNodeOperands(SDNode *N, SDValue Op1, SDValue Op2, SDValue Op3, SDValue Op4, SDValue Op5); - SDValue UpdateNodeOperands(SDValue N, + SDNode *UpdateNodeOperands(SDNode *N, const SDValue *Ops, unsigned NumOps); /// SelectNodeTo - These are used for target selectors to *mutate* the diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h index 3817580..01d05dd 100644 --- a/include/llvm/CodeGen/SelectionDAGISel.h +++ b/include/llvm/CodeGen/SelectionDAGISel.h @@ -280,19 +280,16 @@ private: SDNode *MorphNode(SDNode *Node, unsigned TargetOpc, SDVTList VTs, const SDValue *Ops, unsigned NumOps, unsigned EmitNodeInfo); - void PrepareEHLandingPad(MachineBasicBlock *BB); + void PrepareEHLandingPad(); void SelectAllBasicBlocks(const Function &Fn); - void FinishBasicBlock(MachineBasicBlock *BB); + void FinishBasicBlock(); - MachineBasicBlock *SelectBasicBlock(MachineBasicBlock *BB, - const BasicBlock *LLVMBB, - BasicBlock::const_iterator Begin, - BasicBlock::const_iterator End, - bool &HadTailCall); - MachineBasicBlock *CodeGenAndEmitDAG(MachineBasicBlock *BB); + void SelectBasicBlock(BasicBlock::const_iterator Begin, + BasicBlock::const_iterator End, + bool &HadTailCall); + void CodeGenAndEmitDAG(); void LowerArguments(const BasicBlock *BB); - void ShrinkDemandedOps(); void ComputeLiveOutVRegInfo(); /// Create the scheduler. If a specific scheduler was specified diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index fd529b6..4cf6f36 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -549,6 +549,15 @@ public: return FoundNode; } + /// getFlaggedUser - If this node has a flag value with a user, return + /// the user (there is at most one). Otherwise return NULL. + SDNode *getFlaggedUser() const { + for (use_iterator UI = use_begin(), UE = use_end(); UI != UE; ++UI) + if (UI.getUse().get().getValueType() == MVT::Flag) + return *UI; + return 0; + } + /// getNumValues - Return the number of values defined/returned by this /// operator. /// @@ -1082,6 +1091,7 @@ public: uint64_t getZExtValue() const { return Value->getZExtValue(); } int64_t getSExtValue() const { return Value->getSExtValue(); } + bool isOne() const { return Value->isOne(); } bool isNullValue() const { return Value->isNullValue(); } bool isAllOnesValue() const { return Value->isAllOnesValue(); } @@ -1130,7 +1140,7 @@ public: } bool isExactlyValue(const APFloat& V) const; - bool isValueValidForType(EVT VT, const APFloat& Val); + static bool isValueValidForType(EVT VT, const APFloat& Val); static bool classof(const ConstantFPSDNode *) { return true; } static bool classof(const SDNode *N) { @@ -1144,7 +1154,7 @@ class GlobalAddressSDNode : public SDNode { int64_t Offset; unsigned char TargetFlags; friend class SelectionDAG; - GlobalAddressSDNode(unsigned Opc, const GlobalValue *GA, EVT VT, + GlobalAddressSDNode(unsigned Opc, DebugLoc DL, const GlobalValue *GA, EVT VT, int64_t o, unsigned char TargetFlags); public: @@ -1454,125 +1464,6 @@ public: } }; -namespace ISD { - struct ArgFlagsTy { - private: - static const uint64_t NoFlagSet = 0ULL; - static const uint64_t ZExt = 1ULL<<0; ///< Zero extended - static const uint64_t ZExtOffs = 0; - static const uint64_t SExt = 1ULL<<1; ///< Sign extended - static const uint64_t SExtOffs = 1; - static const uint64_t InReg = 1ULL<<2; ///< Passed in register - static const uint64_t InRegOffs = 2; - static const uint64_t SRet = 1ULL<<3; ///< Hidden struct-ret ptr - static const uint64_t SRetOffs = 3; - static const uint64_t ByVal = 1ULL<<4; ///< Struct passed by value - static const uint64_t ByValOffs = 4; - static const uint64_t Nest = 1ULL<<5; ///< Nested fn static chain - static const uint64_t NestOffs = 5; - static const uint64_t ByValAlign = 0xFULL << 6; //< Struct alignment - static const uint64_t ByValAlignOffs = 6; - static const uint64_t Split = 1ULL << 10; - static const uint64_t SplitOffs = 10; - static const uint64_t OrigAlign = 0x1FULL<<27; - static const uint64_t OrigAlignOffs = 27; - static const uint64_t ByValSize = 0xffffffffULL << 32; //< Struct size - static const uint64_t ByValSizeOffs = 32; - - static const uint64_t One = 1ULL; //< 1 of this type, for shifts - - uint64_t Flags; - public: - ArgFlagsTy() : Flags(0) { } - - bool isZExt() const { return Flags & ZExt; } - void setZExt() { Flags |= One << ZExtOffs; } - - bool isSExt() const { return Flags & SExt; } - void setSExt() { Flags |= One << SExtOffs; } - - bool isInReg() const { return Flags & InReg; } - void setInReg() { Flags |= One << InRegOffs; } - - bool isSRet() const { return Flags & SRet; } - void setSRet() { Flags |= One << SRetOffs; } - - bool isByVal() const { return Flags & ByVal; } - void setByVal() { Flags |= One << ByValOffs; } - - bool isNest() const { return Flags & Nest; } - void setNest() { Flags |= One << NestOffs; } - - unsigned getByValAlign() const { - return (unsigned) - ((One << ((Flags & ByValAlign) >> ByValAlignOffs)) / 2); - } - void setByValAlign(unsigned A) { - Flags = (Flags & ~ByValAlign) | - (uint64_t(Log2_32(A) + 1) << ByValAlignOffs); - } - - bool isSplit() const { return Flags & Split; } - void setSplit() { Flags |= One << SplitOffs; } - - unsigned getOrigAlign() const { - return (unsigned) - ((One << ((Flags & OrigAlign) >> OrigAlignOffs)) / 2); - } - void setOrigAlign(unsigned A) { - Flags = (Flags & ~OrigAlign) | - (uint64_t(Log2_32(A) + 1) << OrigAlignOffs); - } - - unsigned getByValSize() const { - return (unsigned)((Flags & ByValSize) >> ByValSizeOffs); - } - void setByValSize(unsigned S) { - Flags = (Flags & ~ByValSize) | (uint64_t(S) << ByValSizeOffs); - } - - /// getArgFlagsString - Returns the flags as a string, eg: "zext align:4". - std::string getArgFlagsString(); - - /// getRawBits - Represent the flags as a bunch of bits. - uint64_t getRawBits() const { return Flags; } - }; - - /// InputArg - This struct carries flags and type information about a - /// single incoming (formal) argument or incoming (from the perspective - /// of the caller) return value virtual register. - /// - struct InputArg { - ArgFlagsTy Flags; - EVT VT; - bool Used; - - InputArg() : VT(MVT::Other), Used(false) {} - InputArg(ISD::ArgFlagsTy flags, EVT vt, bool used) - : Flags(flags), VT(vt), Used(used) { - assert(VT.isSimple() && - "InputArg value type must be Simple!"); - } - }; - - /// OutputArg - This struct carries flags and a value for a - /// single outgoing (actual) argument or outgoing (from the perspective - /// of the caller) return value virtual register. - /// - struct OutputArg { - ArgFlagsTy Flags; - SDValue Val; - bool IsFixed; - - OutputArg() : IsFixed(false) {} - OutputArg(ISD::ArgFlagsTy flags, SDValue val, bool isfixed) - : Flags(flags), Val(val), IsFixed(isfixed) { - assert(Val.getValueType().isSimple() && - "OutputArg value type must be Simple!"); - } - }; -} - /// VTSDNode - This class is used to represent EVT's, which are used /// to parameterize some operations. class VTSDNode : public SDNode { diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h index 3c56d0d..f1f047b 100644 --- a/include/llvm/CodeGen/SlotIndexes.h +++ b/include/llvm/CodeGen/SlotIndexes.h @@ -23,6 +23,7 @@ #define LLVM_CODEGEN_SLOTINDEXES_H #include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/SmallVector.h" @@ -663,15 +664,20 @@ namespace llvm { MachineBasicBlock::iterator miItr(mi); bool needRenumber = false; IndexListEntry *newEntry; - + // Get previous index, considering that not all instructions are indexed. IndexListEntry *prevEntry; - if (miItr == mbb->begin()) { + for (;;) { // If mi is at the mbb beginning, get the prev index from the mbb. - prevEntry = &mbbRangeItr->second.first.entry(); - } else { - // Otherwise get it from the previous instr. - MachineBasicBlock::iterator pItr(prior(miItr)); - prevEntry = &getInstructionIndex(pItr).entry(); + if (miItr == mbb->begin()) { + prevEntry = &mbbRangeItr->second.first.entry(); + break; + } + // Otherwise rewind until we find a mapped instruction. + Mi2IndexMap::const_iterator itr = mi2iMap.find(--miItr); + if (itr != mi2iMap.end()) { + prevEntry = &itr->second.entry(); + break; + } } // Get next entry from previous entry. @@ -757,6 +763,47 @@ namespace llvm { mi2iMap.insert(std::make_pair(newMI, replaceBaseIndex)); } + /// Add the given MachineBasicBlock into the maps. + void insertMBBInMaps(MachineBasicBlock *mbb) { + MachineFunction::iterator nextMBB = + llvm::next(MachineFunction::iterator(mbb)); + IndexListEntry *startEntry = createEntry(0, 0); + IndexListEntry *terminatorEntry = createEntry(0, 0); + IndexListEntry *nextEntry = 0; + + if (nextMBB == mbb->getParent()->end()) { + nextEntry = getTail(); + } else { + nextEntry = &getMBBStartIdx(nextMBB).entry(); + } + + insert(nextEntry, startEntry); + insert(nextEntry, terminatorEntry); + + SlotIndex startIdx(startEntry, SlotIndex::LOAD); + SlotIndex terminatorIdx(terminatorEntry, SlotIndex::PHI_BIT); + SlotIndex endIdx(nextEntry, SlotIndex::LOAD); + + terminatorGaps.insert( + std::make_pair(mbb, terminatorIdx)); + + mbb2IdxMap.insert( + std::make_pair(mbb, std::make_pair(startIdx, endIdx))); + + idx2MBBMap.push_back(IdxMBBPair(startIdx, mbb)); + + if (MachineFunction::iterator(mbb) != mbb->getParent()->begin()) { + // Have to update the end index of the previous block. + MachineBasicBlock *priorMBB = + llvm::prior(MachineFunction::iterator(mbb)); + mbb2IdxMap[priorMBB].second = startIdx; + } + + renumberIndexes(); + std::sort(idx2MBBMap.begin(), idx2MBBMap.end(), Idx2MBBCompare()); + + } + }; |