comparison gen/functions.cpp @ 720:e177ae483f8e

Added inreg attribute where appropriate on x86 to follow ABI docs. Removed now unnecessary temporary variable in StringExp.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Thu, 23 Oct 2008 00:34:46 +0200
parents 7261ff0f95ff
children 55f6c2e454d7
comparison
equal deleted inserted replaced
719:7261ff0f95ff 720:e177ae483f8e
169 169
170 // construct function type 170 // construct function type
171 bool isvararg = !(typesafeVararg || arrayVararg) && f->varargs; 171 bool isvararg = !(typesafeVararg || arrayVararg) && f->varargs;
172 llvm::FunctionType* functype = llvm::FunctionType::get(actualRettype, paramvec, isvararg); 172 llvm::FunctionType* functype = llvm::FunctionType::get(actualRettype, paramvec, isvararg);
173 173
174 // tell first param to be passed in a register if we can
175 // ONLY extern(D) functions !
176 if ((n > 0 || usesthis || usesnest) && f->linkage == LINKd)
177 {
178 // FIXME: Only x86 right now ...
179 if (global.params.cpu == ARCHx86)
180 {
181 // pass first param in EAX if it fits, is not floating point and is not a 3 byte struct.
182 // FIXME: struct are not passed in EAX yet
183
184 // if there is a implicit context parameter, pass it in EAX
185 if (usesthis || usesnest)
186 {
187 f->thisAttrs |= llvm::Attribute::InReg;
188 }
189 // otherwise check the first formal parameter
190 else
191 {
192 Argument* arg = Argument::getNth(f->parameters, 0);
193 Type* t = arg->type->toBasetype();
194
195 // 32bit ints, pointers, classes and static arrays are candidate for being passed in EAX
196 if ((arg->storageClass & STCin) &&
197 ((t->isscalar() && !t->isfloating()) || t->ty == Tclass || t->ty == Tsarray) &&
198 (t->size() <= PTRSIZE))
199 {
200 arg->llvmAttrs |= llvm::Attribute::InReg;
201 }
202 }
203 }
204 }
205
206 // done
174 f->retInPtr = retinptr; 207 f->retInPtr = retinptr;
175 f->usesThis = usesthis; 208 f->usesThis = usesthis;
176 f->usesNest = usesnest; 209 f->usesNest = usesnest;
177 210
178 f->ir.type = new llvm::PATypeHolder(functype); 211 f->ir.type = new llvm::PATypeHolder(functype);
345 // set sret param 378 // set sret param
346 if (f->retInPtr) 379 if (f->retInPtr)
347 { 380 {
348 PAWI.Index = 1; 381 PAWI.Index = 1;
349 PAWI.Attrs = llvm::Attribute::StructRet; 382 PAWI.Attrs = llvm::Attribute::StructRet;
383 attrs.push_back(PAWI);
384 }
385
386 // set this/nest param attrs
387 if (f->thisAttrs)
388 {
389 PAWI.Index = f->retInPtr ? 2 : 1;
390 PAWI.Attrs = f->thisAttrs;
350 attrs.push_back(PAWI); 391 attrs.push_back(PAWI);
351 } 392 }
352 393
353 // set attrs on the rest of the arguments 394 // set attrs on the rest of the arguments
354 for (; llidx <= funcNumArgs && Argument::dim(f->parameters) > k; ++llidx,++k) 395 for (; llidx <= funcNumArgs && Argument::dim(f->parameters) > k; ++llidx,++k)