Skip to content

Commit 9e760bc

Browse files
authored
[Codegen] emit attributes for non-struct arguments too (#7)
1 parent 563e933 commit 9e760bc

File tree

2 files changed

+54
-7
lines changed

2 files changed

+54
-7
lines changed

src/codegen.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -398,14 +398,13 @@ llvm::AttributeList Codegen::constructAttrList(const ResolvedFunctionDecl *fn) {
398398
}
399399

400400
for (auto &&param : fn->params) {
401-
if (param->type.kind != Type::Kind::Struct)
402-
continue;
403-
404401
llvm::AttrBuilder paramAttrs(context);
405-
if (param->isMutable)
406-
paramAttrs.addByValAttr(generateType(param->type));
407-
else
408-
paramAttrs.addAttribute(llvm::Attribute::ReadOnly);
402+
if (param->type.kind == Type::Kind::Struct) {
403+
if (param->isMutable)
404+
paramAttrs.addByValAttr(generateType(param->type));
405+
else
406+
paramAttrs.addAttribute(llvm::Attribute::ReadOnly);
407+
}
409408
argsAttrSets.emplace_back(llvm::AttributeSet::get(context, paramAttrs));
410409
}
411410

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// RUN: compiler %s -llvm-dump 2>&1 | filecheck %s
2+
// RUN: compiler %s -o struct_parameter_attrs && ./struct_parameter_attrs | grep -Plzx '1\n2\n3\n2\n'
3+
struct S {
4+
x: number,
5+
}
6+
7+
fn foo(a: number, b: S, var c: number, var d: S): void {
8+
println(a);
9+
println(b.x);
10+
println(c);
11+
println(d.x);
12+
}
13+
// CHECK: define void @foo(double %a, %struct.S* readonly %b, double %c, %struct.S* byval(%struct.S) %d) {
14+
// CHECK-NEXT: entry:
15+
// CHECK-NEXT: %c1 = alloca double, align 8
16+
// CHECK-NEXT: store double %c, double* %c1, align 8
17+
// CHECK-NEXT: call void @println(double %a)
18+
// CHECK-NEXT: %0 = getelementptr inbounds %struct.S, %struct.S* %b, i32 0, i32 0
19+
// CHECK-NEXT: %1 = load double, double* %0, align 8
20+
// CHECK-NEXT: call void @println(double %1)
21+
// CHECK-NEXT: %2 = load double, double* %c1, align 8
22+
// CHECK-NEXT: call void @println(double %2)
23+
// CHECK-NEXT: %3 = getelementptr inbounds %struct.S, %struct.S* %d, i32 0, i32 0
24+
// CHECK-NEXT: %4 = load double, double* %3, align 8
25+
// CHECK-NEXT: call void @println(double %4)
26+
// CHECK-NEXT: ret void
27+
// CHECK-NEXT: }
28+
29+
fn main(): void {
30+
let s = S { x: 2 };
31+
foo(1, s, 3, s);
32+
}
33+
// CHECK: define void @__builtin_main() {
34+
// CHECK-NEXT: entry:
35+
// CHECK-NEXT: %s = alloca %struct.S, align 8
36+
// CHECK-NEXT: %S.tmp = alloca %struct.S, align 8
37+
// CHECK-NEXT: %struct.arg.tmp = alloca %struct.S, align 8
38+
// CHECK-NEXT: %0 = getelementptr inbounds %struct.S, %struct.S* %S.tmp, i32 0, i32 0
39+
// CHECK-NEXT: store double 2.000000e+00, double* %0, align 8
40+
// CHECK-NEXT: %1 = bitcast %struct.S* %s to i8*
41+
// CHECK-NEXT: %2 = bitcast %struct.S* %S.tmp to i8*
42+
// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %1, i8* align 8 %2, i64 8, i1 false)
43+
// CHECK-NEXT: %3 = bitcast %struct.S* %struct.arg.tmp to i8*
44+
// CHECK-NEXT: %4 = bitcast %struct.S* %s to i8*
45+
// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %3, i8* align 8 %4, i64 8, i1 false)
46+
// CHECK-NEXT: call void @foo(double 1.000000e+00, %struct.S* readonly %s, double 3.000000e+00, %struct.S* byval(%struct.S) %struct.arg.tmp)
47+
// CHECK-NEXT: ret void
48+
// CHECK-NEXT: }

0 commit comments

Comments
 (0)