CallingConvLower.h revision 210299
1//===-- llvm/CallingConvLower.h - Calling Conventions -----------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file declares the CCState and CCValAssign classes, used for lowering 11// and implementing calling conventions. 12// 13//===----------------------------------------------------------------------===// 14 15#ifndef LLVM_CODEGEN_CALLINGCONVLOWER_H 16#define LLVM_CODEGEN_CALLINGCONVLOWER_H 17 18#include "llvm/ADT/SmallVector.h" 19#include "llvm/CodeGen/ValueTypes.h" 20#include "llvm/Target/TargetCallingConv.h" 21#include "llvm/CallingConv.h" 22 23namespace llvm { 24 class TargetRegisterInfo; 25 class TargetMachine; 26 class CCState; 27 28/// CCValAssign - Represent assignment of one arg/retval to a location. 29class CCValAssign { 30public: 31 enum LocInfo { 32 Full, // The value fills the full location. 33 SExt, // The value is sign extended in the location. 34 ZExt, // The value is zero extended in the location. 35 AExt, // The value is extended with undefined upper bits. 36 BCvt, // The value is bit-converted in the location. 37 VExt, // The value is vector-widened in the location. 38 // FIXME: Not implemented yet. Code that uses AExt to mean 39 // vector-widen should be fixed to use VExt instead. 40 Indirect // The location contains pointer to the value. 41 // TODO: a subset of the value is in the location. 42 }; 43private: 44 /// ValNo - This is the value number begin assigned (e.g. an argument number). 45 unsigned ValNo; 46 47 /// Loc is either a stack offset or a register number. 48 unsigned Loc; 49 50 /// isMem - True if this is a memory loc, false if it is a register loc. 51 bool isMem : 1; 52 53 /// isCustom - True if this arg/retval requires special handling. 54 bool isCustom : 1; 55 56 /// Information about how the value is assigned. 57 LocInfo HTP : 6; 58 59 /// ValVT - The type of the value being assigned. 60 EVT ValVT; 61 62 /// LocVT - The type of the location being assigned to. 63 EVT LocVT; 64public: 65 66 static CCValAssign getReg(unsigned ValNo, EVT ValVT, 67 unsigned RegNo, EVT LocVT, 68 LocInfo HTP) { 69 CCValAssign Ret; 70 Ret.ValNo = ValNo; 71 Ret.Loc = RegNo; 72 Ret.isMem = false; 73 Ret.isCustom = false; 74 Ret.HTP = HTP; 75 Ret.ValVT = ValVT; 76 Ret.LocVT = LocVT; 77 return Ret; 78 } 79 80 static CCValAssign getCustomReg(unsigned ValNo, EVT ValVT, 81 unsigned RegNo, EVT LocVT, 82 LocInfo HTP) { 83 CCValAssign Ret; 84 Ret = getReg(ValNo, ValVT, RegNo, LocVT, HTP); 85 Ret.isCustom = true; 86 return Ret; 87 } 88 89 static CCValAssign getMem(unsigned ValNo, EVT ValVT, 90 unsigned Offset, EVT LocVT, 91 LocInfo HTP) { 92 CCValAssign Ret; 93 Ret.ValNo = ValNo; 94 Ret.Loc = Offset; 95 Ret.isMem = true; 96 Ret.isCustom = false; 97 Ret.HTP = HTP; 98 Ret.ValVT = ValVT; 99 Ret.LocVT = LocVT; 100 return Ret; 101 } 102 103 static CCValAssign getCustomMem(unsigned ValNo, EVT ValVT, 104 unsigned Offset, EVT LocVT, 105 LocInfo HTP) { 106 CCValAssign Ret; 107 Ret = getMem(ValNo, ValVT, Offset, LocVT, HTP); 108 Ret.isCustom = true; 109 return Ret; 110 } 111 112 unsigned getValNo() const { return ValNo; } 113 EVT getValVT() const { return ValVT; } 114 115 bool isRegLoc() const { return !isMem; } 116 bool isMemLoc() const { return isMem; } 117 118 bool needsCustom() const { return isCustom; } 119 120 unsigned getLocReg() const { assert(isRegLoc()); return Loc; } 121 unsigned getLocMemOffset() const { assert(isMemLoc()); return Loc; } 122 EVT getLocVT() const { return LocVT; } 123 124 LocInfo getLocInfo() const { return HTP; } 125 bool isExtInLoc() const { 126 return (HTP == AExt || HTP == SExt || HTP == ZExt); 127 } 128 129}; 130 131/// CCAssignFn - This function assigns a location for Val, updating State to 132/// reflect the change. 133typedef bool CCAssignFn(unsigned ValNo, EVT ValVT, 134 EVT LocVT, CCValAssign::LocInfo LocInfo, 135 ISD::ArgFlagsTy ArgFlags, CCState &State); 136 137/// CCCustomFn - This function assigns a location for Val, possibly updating 138/// all args to reflect changes and indicates if it handled it. It must set 139/// isCustom if it handles the arg and returns true. 140typedef bool CCCustomFn(unsigned &ValNo, EVT &ValVT, 141 EVT &LocVT, CCValAssign::LocInfo &LocInfo, 142 ISD::ArgFlagsTy &ArgFlags, CCState &State); 143 144/// CCState - This class holds information needed while lowering arguments and 145/// return values. It captures which registers are already assigned and which 146/// stack slots are used. It provides accessors to allocate these values. 147class CCState { 148 CallingConv::ID CallingConv; 149 bool IsVarArg; 150 const TargetMachine &TM; 151 const TargetRegisterInfo &TRI; 152 SmallVector<CCValAssign, 16> &Locs; 153 LLVMContext &Context; 154 155 unsigned StackOffset; 156 SmallVector<uint32_t, 16> UsedRegs; 157public: 158 CCState(CallingConv::ID CC, bool isVarArg, const TargetMachine &TM, 159 SmallVector<CCValAssign, 16> &locs, LLVMContext &C); 160 161 void addLoc(const CCValAssign &V) { 162 Locs.push_back(V); 163 } 164 165 LLVMContext &getContext() const { return Context; } 166 const TargetMachine &getTarget() const { return TM; } 167 CallingConv::ID getCallingConv() const { return CallingConv; } 168 bool isVarArg() const { return IsVarArg; } 169 170 unsigned getNextStackOffset() const { return StackOffset; } 171 172 /// isAllocated - Return true if the specified register (or an alias) is 173 /// allocated. 174 bool isAllocated(unsigned Reg) const { 175 return UsedRegs[Reg/32] & (1 << (Reg&31)); 176 } 177 178 /// AnalyzeFormalArguments - Analyze an array of argument values, 179 /// incorporating info about the formals into this state. 180 void AnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins, 181 CCAssignFn Fn); 182 183 /// AnalyzeReturn - Analyze the returned values of a return, 184 /// incorporating info about the result values into this state. 185 void AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs, 186 CCAssignFn Fn); 187 188 /// CheckReturn - Analyze the return values of a function, returning 189 /// true if the return can be performed without sret-demotion, and 190 /// false otherwise. 191 bool CheckReturn(const SmallVectorImpl<ISD::OutputArg> &ArgsFlags, 192 CCAssignFn Fn); 193 194 /// AnalyzeCallOperands - Analyze the outgoing arguments to a call, 195 /// incorporating info about the passed values into this state. 196 void AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs, 197 CCAssignFn Fn); 198 199 /// AnalyzeCallOperands - Same as above except it takes vectors of types 200 /// and argument flags. 201 void AnalyzeCallOperands(SmallVectorImpl<EVT> &ArgVTs, 202 SmallVectorImpl<ISD::ArgFlagsTy> &Flags, 203 CCAssignFn Fn); 204 205 /// AnalyzeCallResult - Analyze the return values of a call, 206 /// incorporating info about the passed values into this state. 207 void AnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins, 208 CCAssignFn Fn); 209 210 /// AnalyzeCallResult - Same as above except it's specialized for calls which 211 /// produce a single value. 212 void AnalyzeCallResult(EVT VT, CCAssignFn Fn); 213 214 /// getFirstUnallocated - Return the first unallocated register in the set, or 215 /// NumRegs if they are all allocated. 216 unsigned getFirstUnallocated(const unsigned *Regs, unsigned NumRegs) const { 217 for (unsigned i = 0; i != NumRegs; ++i) 218 if (!isAllocated(Regs[i])) 219 return i; 220 return NumRegs; 221 } 222 223 /// AllocateReg - Attempt to allocate one register. If it is not available, 224 /// return zero. Otherwise, return the register, marking it and any aliases 225 /// as allocated. 226 unsigned AllocateReg(unsigned Reg) { 227 if (isAllocated(Reg)) return 0; 228 MarkAllocated(Reg); 229 return Reg; 230 } 231 232 /// Version of AllocateReg with extra register to be shadowed. 233 unsigned AllocateReg(unsigned Reg, unsigned ShadowReg) { 234 if (isAllocated(Reg)) return 0; 235 MarkAllocated(Reg); 236 MarkAllocated(ShadowReg); 237 return Reg; 238 } 239 240 /// AllocateReg - Attempt to allocate one of the specified registers. If none 241 /// are available, return zero. Otherwise, return the first one available, 242 /// marking it and any aliases as allocated. 243 unsigned AllocateReg(const unsigned *Regs, unsigned NumRegs) { 244 unsigned FirstUnalloc = getFirstUnallocated(Regs, NumRegs); 245 if (FirstUnalloc == NumRegs) 246 return 0; // Didn't find the reg. 247 248 // Mark the register and any aliases as allocated. 249 unsigned Reg = Regs[FirstUnalloc]; 250 MarkAllocated(Reg); 251 return Reg; 252 } 253 254 /// Version of AllocateReg with list of registers to be shadowed. 255 unsigned AllocateReg(const unsigned *Regs, const unsigned *ShadowRegs, 256 unsigned NumRegs) { 257 unsigned FirstUnalloc = getFirstUnallocated(Regs, NumRegs); 258 if (FirstUnalloc == NumRegs) 259 return 0; // Didn't find the reg. 260 261 // Mark the register and any aliases as allocated. 262 unsigned Reg = Regs[FirstUnalloc], ShadowReg = ShadowRegs[FirstUnalloc]; 263 MarkAllocated(Reg); 264 MarkAllocated(ShadowReg); 265 return Reg; 266 } 267 268 /// AllocateStack - Allocate a chunk of stack space with the specified size 269 /// and alignment. 270 unsigned AllocateStack(unsigned Size, unsigned Align) { 271 assert(Align && ((Align-1) & Align) == 0); // Align is power of 2. 272 StackOffset = ((StackOffset + Align-1) & ~(Align-1)); 273 unsigned Result = StackOffset; 274 StackOffset += Size; 275 return Result; 276 } 277 278 // HandleByVal - Allocate a stack slot large enough to pass an argument by 279 // value. The size and alignment information of the argument is encoded in its 280 // parameter attribute. 281 void HandleByVal(unsigned ValNo, EVT ValVT, 282 EVT LocVT, CCValAssign::LocInfo LocInfo, 283 int MinSize, int MinAlign, ISD::ArgFlagsTy ArgFlags); 284 285private: 286 /// MarkAllocated - Mark a register and all of its aliases as allocated. 287 void MarkAllocated(unsigned Reg); 288}; 289 290 291 292} // end namespace llvm 293 294#endif 295