comparison gen/abi.cpp @ 1359:34f2fd925de3

Intrinsics shouldn't see struct padding, so use a special TargetABI for them that removes it. This unbreaks the `llvm_*_with_overflow` intrinsics.
author Frits van Bommel <fvbommel wxs.nl>
date Sat, 16 May 2009 13:06:49 +0200
parents 15e9762bb620
children c363d131c1ef
comparison
equal deleted inserted replaced
1357:48747003a5de 1359:34f2fd925de3
8 #include "gen/llvmhelpers.h" 8 #include "gen/llvmhelpers.h"
9 #include "gen/tollvm.h" 9 #include "gen/tollvm.h"
10 #include "gen/abi.h" 10 #include "gen/abi.h"
11 #include "gen/logger.h" 11 #include "gen/logger.h"
12 #include "gen/dvalue.h" 12 #include "gen/dvalue.h"
13 #include "gen/abi-generic.h"
13 14
14 #include "ir/irfunction.h" 15 #include "ir/irfunction.h"
15 16
16 ////////////////////////////////////////////////////////////////////////////// 17 //////////////////////////////////////////////////////////////////////////////
17 18
309 default: 310 default:
310 Logger::cout() << "WARNING: Unknown ABI, guessing...\n"; 311 Logger::cout() << "WARNING: Unknown ABI, guessing...\n";
311 return new UnknownTargetABI; 312 return new UnknownTargetABI;
312 } 313 }
313 } 314 }
315
316 //////////////////////////////////////////////////////////////////////////////
317 //////////////////////////////////////////////////////////////////////////////
318 //////////////////////////////////////////////////////////////////////////////
319 //////////////////////////////////////////////////////////////////////////////
320 //////////////////////////////////////////////////////////////////////////////
321
322 // A simple ABI for LLVM intrinsics.
323 struct IntrinsicABI : TargetABI
324 {
325 RemoveStructPadding remove_padding;
326
327 bool returnInArg(TypeFunction* tf)
328 {
329 return false;
330 }
331
332 bool passByVal(Type* t)
333 {
334 return false;
335 }
336
337 void fixup(IrFuncTyArg& arg) {
338 assert(arg.type->ty == Tstruct);
339 // TODO: Check that no unions are passed in or returned.
340
341 LLType* abiTy = DtoUnpaddedStructType(arg.type);
342
343 if (abiTy && abiTy != arg.ltype) {
344 arg.ltype = abiTy;
345 arg.rewrite = &remove_padding;
346 }
347 }
348
349 void rewriteFunctionType(TypeFunction* tf)
350 {
351 assert(tf->linkage == LINKintrinsic);
352
353 IrFuncTy& fty = tf->fty;
354
355 if (!fty.arg_sret) {
356 Type* rt = fty.ret->type->toBasetype();
357 if (rt->ty == Tstruct) {
358 Logger::println("Intrinsic ABI: Transforming return type");
359 fixup(*fty.ret);
360 }
361 }
362
363 Logger::println("Intrinsic ABI: Transforming arguments");
364 LOG_SCOPE;
365
366 for (IrFuncTy::ArgIter I = fty.args.begin(), E = fty.args.end(); I != E; ++I) {
367 IrFuncTyArg& arg = **I;
368
369 if (Logger::enabled())
370 Logger::cout() << "Arg: " << arg.type->toChars() << '\n';
371
372 // Arguments that are in memory are of no interest to us.
373 if (arg.byref)
374 continue;
375
376 Type* ty = arg.type->toBasetype();
377 if (ty->ty == Tstruct)
378 fixup(arg);
379
380 if (Logger::enabled())
381 Logger::cout() << "New arg type: " << *arg.ltype << '\n';
382 }
383 }
384 };
385
386 TargetABI * TargetABI::getIntrinsic()
387 {
388 static IntrinsicABI iabi;
389 return &iabi;
390 }