Skip to content

Commit

Permalink
Win64 ABI: Pass/return delegates like slices - in (up to) 2 GP registers
Browse files Browse the repository at this point in the history
I expect this to be slightly more performant than the previous behavior,
where a delegate was treated like a corresponding struct, passed via
hidden pointer and returned via sret.

The primary motivation is a smooth preparation for PR ldc-developers#3578 - in order
to allow people to experiment with `-preview=in` without recompiling
druntime and Phobos, `in` slices and delegates must not be passed by-ref
with `-preview=in` (see dlang/dmd#11828). This would have required a
special case for delegates on Win64, which is IMO better handled this
way.
  • Loading branch information
kinke committed Nov 7, 2020
1 parent 6343bf0 commit 1b0c619
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 3 deletions.
7 changes: 6 additions & 1 deletion gen/abi-win64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,11 @@ struct Win64TargetABI : TargetABI {

// Remaining aggregates which can NOT be rewritten as integers (size > 8
// bytes or not a power of 2) are passed by ref to hidden copy.
return isAggregate(t) && !canRewriteAsInt(t);
// LDC-specific exceptions: slices and delegates are left alone (as non-
// rewritten IR structs) and passed/returned as 2 separate args => passed in
// up to 2 GP registers and returned in RAX & RDX.
return isAggregate(t) && !canRewriteAsInt(t) && t->ty != Tarray &&
t->ty != Tdelegate;
}

public:
Expand Down Expand Up @@ -113,6 +117,7 @@ struct Win64TargetABI : TargetABI {
// are returned in a register (RAX, or XMM0 for single float/ifloat/
// double/idouble)
// * 80-bit real/ireal are returned on the x87 stack
// * LDC-specific: slices and delegates are returned in RAX & RDX
// * all other types are returned via sret
return passPointerToHiddenCopy(rt, /*isReturnValue=*/true, tf->linkage);
}
Expand Down
4 changes: 2 additions & 2 deletions gen/dibuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1255,9 +1255,9 @@ void DIBuilder::EmitLocalVariable(llvm::Value *ll, VarDeclaration *vd,
if (isaArgument(ll) && addr.empty()) {
forceAsLocal = true;
} else {
// 2) dynamic arrays and vectors
// 2) dynamic arrays, delegates and vectors
TY ty = type->toBasetype()->ty;
if (ty == Tarray || ty == Tvector)
if (ty == Tarray || ty == Tdelegate || ty == Tvector)
forceAsLocal = true;
}
}
Expand Down

0 comments on commit 1b0c619

Please sign in to comment.