X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FCodeGen%2FCallingConvLower.h;h=1fd4eeb46b38ac24305a456fe0d110e8fdc48206;hb=00552e3875ee5f382db6c98286a241a7d0efe1b8;hp=f824e73433a43b18967edd51354679087cc2f031;hpb=5f33cbc414937eb39cefb031c2e5b11be8dc9237;p=oota-llvm.git diff --git a/include/llvm/CodeGen/CallingConvLower.h b/include/llvm/CodeGen/CallingConvLower.h index f824e73433a..1fd4eeb46b3 100644 --- a/include/llvm/CodeGen/CallingConvLower.h +++ b/include/llvm/CodeGen/CallingConvLower.h @@ -18,31 +18,39 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/ValueTypes.h" #include "llvm/IR/CallingConv.h" +#include "llvm/MC/MCRegisterInfo.h" #include "llvm/Target/TargetCallingConv.h" namespace llvm { - class TargetRegisterInfo; - class TargetMachine; - class CCState; +class CCState; +class MVT; +class TargetMachine; +class TargetRegisterInfo; /// CCValAssign - Represent assignment of one arg/retval to a location. class CCValAssign { public: enum LocInfo { - Full, // The value fills the full location. - SExt, // The value is sign extended in the location. - 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. - FPExt, // The floating-point value is fp-extended in the location. - Indirect // The location contains pointer to the value. + Full, // The value fills the full location. + SExt, // The value is sign extended in the location. + ZExt, // The value is zero extended in the location. + AExt, // The value is extended with undefined upper bits. + SExtUpper, // The value is in the upper bits of the location and should be + // sign extended when retrieved. + ZExtUpper, // The value is in the upper bits of the location and should be + // zero extended when retrieved. + AExtUpper, // The value is in the upper bits of the location and should be + // extended with undefined upper bits when retrieved. + 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. + FPExt, // The floating-point value is fp-extended in the location. + Indirect // The location contains pointer to the value. // TODO: a subset of the value is in the location. }; + private: /// ValNo - This is the value number begin assigned (e.g. an argument number). unsigned ValNo; @@ -112,6 +120,23 @@ public: return Ret; } + // There is no need to differentiate between a pending CCValAssign and other + // kinds, as they are stored in a different list. + static CCValAssign getPending(unsigned ValNo, MVT ValVT, MVT LocVT, + LocInfo HTP, unsigned ExtraInfo = 0) { + return getReg(ValNo, ValVT, ExtraInfo, LocVT, HTP); + } + + void convertToReg(unsigned RegNo) { + Loc = RegNo; + isMem = false; + } + + void convertToMem(unsigned Offset) { + Loc = Offset; + isMem = true; + } + unsigned getValNo() const { return ValNo; } MVT getValVT() const { return ValVT; } @@ -122,6 +147,7 @@ public: unsigned getLocReg() const { assert(isRegLoc()); return Loc; } unsigned getLocMemOffset() const { assert(isMemLoc()); return Loc; } + unsigned getExtraInfo() const { return Loc; } MVT getLocVT() const { return LocVT; } LocInfo getLocInfo() const { return HTP; } @@ -129,6 +155,19 @@ public: return (HTP == AExt || HTP == SExt || HTP == ZExt); } + bool isUpperBitsInLoc() const { + return HTP == AExtUpper || HTP == SExtUpper || HTP == ZExtUpper; + } +}; + +/// Describes a register that needs to be forwarded from the prologue to a +/// musttail call. +struct ForwardedRegister { + ForwardedRegister(unsigned VReg, MCPhysReg PReg, MVT VT) + : VReg(VReg), PReg(PReg), VT(VT) {} + unsigned VReg; + MCPhysReg PReg; + MVT VT; }; /// CCAssignFn - This function assigns a location for Val, updating State to @@ -157,13 +196,13 @@ private: CallingConv::ID CallingConv; bool IsVarArg; MachineFunction &MF; - const TargetMachine &TM; const TargetRegisterInfo &TRI; SmallVectorImpl &Locs; LLVMContext &Context; unsigned StackOffset; SmallVector UsedRegs; + SmallVector PendingLocs; // ByValInfo and SmallVector ByValRegs: // @@ -190,10 +229,10 @@ private: // while "%t" goes to the stack: it wouldn't be described in ByValRegs. // // Supposed use-case for this collection: - // 1. Initially ByValRegs is empty, InRegsParamsProceed is 0. + // 1. Initially ByValRegs is empty, InRegsParamsProcessed is 0. // 2. HandleByVal fillups ByValRegs. // 3. Argument analysis (LowerFormatArguments, for example). After - // some byval argument was analyzed, InRegsParamsProceed is increased. + // some byval argument was analyzed, InRegsParamsProcessed is increased. struct ByValInfo { ByValInfo(unsigned B, unsigned E, bool IsWaste = false) : Begin(B), End(E), Waste(IsWaste) {} @@ -211,24 +250,22 @@ private: }; SmallVector ByValRegs; - // InRegsParamsProceed - shows how many instances of ByValRegs was proceed + // InRegsParamsProcessed - shows how many instances of ByValRegs was proceed // during argument analysis. - unsigned InRegsParamsProceed; + unsigned InRegsParamsProcessed; protected: ParmContext CallOrPrologue; public: CCState(CallingConv::ID CC, bool isVarArg, MachineFunction &MF, - const TargetMachine &TM, SmallVectorImpl &locs, - LLVMContext &C); + SmallVectorImpl &locs, LLVMContext &C); void addLoc(const CCValAssign &V) { Locs.push_back(V); } LLVMContext &getContext() const { return Context; } - const TargetMachine &getTarget() const { return TM; } MachineFunction &getMachineFunction() const { return MF; } CallingConv::ID getCallingConv() const { return CallingConv; } bool isVarArg() const { return IsVarArg; } @@ -277,13 +314,13 @@ public: /// produce a single value. void AnalyzeCallResult(MVT VT, CCAssignFn Fn); - /// getFirstUnallocated - Return the first unallocated register in the set, or - /// NumRegs if they are all allocated. - unsigned getFirstUnallocated(const uint16_t *Regs, unsigned NumRegs) const { - for (unsigned i = 0; i != NumRegs; ++i) + /// getFirstUnallocated - Return the index of the first unallocated register + /// in the set, or Regs.size() if they are all allocated. + unsigned getFirstUnallocated(ArrayRef Regs) const { + for (unsigned i = 0; i < Regs.size(); ++i) if (!isAllocated(Regs[i])) return i; - return NumRegs; + return Regs.size(); } /// AllocateReg - Attempt to allocate one register. If it is not available, @@ -306,9 +343,9 @@ public: /// AllocateReg - Attempt to allocate one of the specified registers. If none /// are available, return zero. Otherwise, return the first one available, /// marking it and any aliases as allocated. - unsigned AllocateReg(const uint16_t *Regs, unsigned NumRegs) { - unsigned FirstUnalloc = getFirstUnallocated(Regs, NumRegs); - if (FirstUnalloc == NumRegs) + unsigned AllocateReg(ArrayRef Regs) { + unsigned FirstUnalloc = getFirstUnallocated(Regs); + if (FirstUnalloc == Regs.size()) return 0; // Didn't find the reg. // Mark the register and any aliases as allocated. @@ -317,11 +354,39 @@ public: return Reg; } + /// AllocateRegBlock - Attempt to allocate a block of RegsRequired consecutive + /// registers. If this is not possible, return zero. Otherwise, return the first + /// register of the block that were allocated, marking the entire block as allocated. + unsigned AllocateRegBlock(ArrayRef Regs, unsigned RegsRequired) { + if (RegsRequired > Regs.size()) + return 0; + + for (unsigned StartIdx = 0; StartIdx <= Regs.size() - RegsRequired; + ++StartIdx) { + bool BlockAvailable = true; + // Check for already-allocated regs in this block + for (unsigned BlockIdx = 0; BlockIdx < RegsRequired; ++BlockIdx) { + if (isAllocated(Regs[StartIdx + BlockIdx])) { + BlockAvailable = false; + break; + } + } + if (BlockAvailable) { + // Mark the entire block as allocated + for (unsigned BlockIdx = 0; BlockIdx < RegsRequired; ++BlockIdx) { + MarkAllocated(Regs[StartIdx + BlockIdx]); + } + return Regs[StartIdx]; + } + } + // No block was available + return 0; + } + /// Version of AllocateReg with list of registers to be shadowed. - unsigned AllocateReg(const uint16_t *Regs, const uint16_t *ShadowRegs, - unsigned NumRegs) { - unsigned FirstUnalloc = getFirstUnallocated(Regs, NumRegs); - if (FirstUnalloc == NumRegs) + unsigned AllocateReg(ArrayRef Regs, const MCPhysReg *ShadowRegs) { + unsigned FirstUnalloc = getFirstUnallocated(Regs); + if (FirstUnalloc == Regs.size()) return 0; // Didn't find the reg. // Mark the register and any aliases as allocated. @@ -334,8 +399,8 @@ public: /// AllocateStack - Allocate a chunk of stack space with the specified size /// and alignment. unsigned AllocateStack(unsigned Size, unsigned Align) { - assert(Align && ((Align-1) & Align) == 0); // Align is power of 2. - StackOffset = ((StackOffset + Align-1) & ~(Align-1)); + assert(Align && ((Align - 1) & Align) == 0); // Align is power of 2. + StackOffset = ((StackOffset + Align - 1) & ~(Align - 1)); unsigned Result = StackOffset; StackOffset += Size; MF.getFrameInfo()->ensureMaxAlignment(Align); @@ -348,6 +413,15 @@ public: return AllocateStack(Size, Align); } + /// Version of AllocateStack with list of extra registers to be shadowed. + /// Note that, unlike AllocateReg, this shadows ALL of the shadow registers. + unsigned AllocateStack(unsigned Size, unsigned Align, + ArrayRef ShadowRegs) { + for (unsigned i = 0; i < ShadowRegs.size(); ++i) + MarkAllocated(ShadowRegs[i]); + return AllocateStack(Size, Align); + } + // HandleByVal - Allocate a stack slot large enough to pass an argument by // value. The size and alignment information of the argument is encoded in its // parameter attribute. @@ -360,7 +434,7 @@ public: unsigned getInRegsParamsCount() const { return ByValRegs.size(); } // Returns count of byval in-regs arguments proceed. - unsigned getInRegsParamsProceed() const { return InRegsParamsProceed; } + unsigned getInRegsParamsProcessed() const { return InRegsParamsProcessed; } // Get information about N-th byval parameter that is stored in registers. // Here "ByValParamIndex" is N. @@ -384,19 +458,42 @@ public: // Returns false, if end is reached. bool nextInRegsParam() { unsigned e = ByValRegs.size(); - if (InRegsParamsProceed < e) - ++InRegsParamsProceed; - return InRegsParamsProceed < e; + if (InRegsParamsProcessed < e) + ++InRegsParamsProcessed; + return InRegsParamsProcessed < e; } // Clear byval registers tracking info. void clearByValRegsInfo() { - InRegsParamsProceed = 0; + InRegsParamsProcessed = 0; ByValRegs.clear(); } + // Rewind byval registers tracking info. + void rewindByValRegsInfo() { + InRegsParamsProcessed = 0; + } + ParmContext getCallOrPrologue() const { return CallOrPrologue; } + // Get list of pending assignments + SmallVectorImpl &getPendingLocs() { + return PendingLocs; + } + + /// Compute the remaining unused register parameters that would be used for + /// the given value type. This is useful when varargs are passed in the + /// registers that normal prototyped parameters would be passed in, or for + /// implementing perfect forwarding. + void getRemainingRegParmsForType(SmallVectorImpl &Regs, MVT VT, + CCAssignFn Fn); + + /// Compute the set of registers that need to be preserved and forwarded to + /// any musttail calls. + void analyzeMustTailForwardedRegisters( + SmallVectorImpl &Forwards, ArrayRef RegParmTypes, + CCAssignFn Fn); + private: /// MarkAllocated - Mark a register and all of its aliases as allocated. void MarkAllocated(unsigned Reg);