From: Tim Northover Date: Fri, 2 Aug 2019 14:09:49 +0000 (+0000) Subject: GlobalISel: support swiftself attribute X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=68eef5292f4a34cb72f243af45993446400feecc;p=llvm GlobalISel: support swiftself attribute git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@367683 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/GlobalISel/CallLowering.cpp b/lib/CodeGen/GlobalISel/CallLowering.cpp index 9f950131c85..17c6b84e48a 100644 --- a/lib/CodeGen/GlobalISel/CallLowering.cpp +++ b/lib/CodeGen/GlobalISel/CallLowering.cpp @@ -45,9 +45,6 @@ bool CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, ImmutableCallSite CS, ArgInfo OrigArg{ArgRegs[i], Arg->getType(), ISD::ArgFlagsTy{}, i < NumFixedArgs}; setArgFlags(OrigArg, i + AttributeList::FirstArgIndex, DL, CS); - // We don't currently support swiftself args. - if (OrigArg.Flags.isSwiftSelf()) - return false; OrigArgs.push_back(OrigArg); ++i; } diff --git a/lib/CodeGen/GlobalISel/IRTranslator.cpp b/lib/CodeGen/GlobalISel/IRTranslator.cpp index 3dc2200d37f..8b89070cd71 100644 --- a/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -2284,18 +2284,6 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) { } } - // We don't currently support translating swifterror or swiftself functions. - for (auto &Arg : F.args()) { - if (Arg.hasSwiftSelfAttr()) { - OptimizationRemarkMissed R("gisel-irtranslator", "GISelFailure", - F.getSubprogram(), &F.getEntryBlock()); - R << "unable to lower arguments due to swiftself: " - << ore::NV("Prototype", F.getType()); - reportTranslationError(*MF, *TPC, *ORE, R); - return false; - } - } - if (!CLI->lowerFormalArguments(*EntryBuilder.get(), F, VRegArgs)) { OptimizationRemarkMissed R("gisel-irtranslator", "GISelFailure", F.getSubprogram(), &F.getEntryBlock()); diff --git a/lib/Target/AArch64/AArch64CallLowering.cpp b/lib/Target/AArch64/AArch64CallLowering.cpp index fb9b5ab7e85..c7434e5a2e4 100644 --- a/lib/Target/AArch64/AArch64CallLowering.cpp +++ b/lib/Target/AArch64/AArch64CallLowering.cpp @@ -110,6 +110,7 @@ struct FormalArgHandler : public IncomingArgHandler { : IncomingArgHandler(MIRBuilder, MRI, AssignFn) {} void markPhysRegUsed(unsigned PhysReg) override { + MIRBuilder.getMRI()->addLiveIn(PhysReg); MIRBuilder.getMBB().addLiveIn(PhysReg); } }; diff --git a/lib/Target/ARM/ARMCallLowering.cpp b/lib/Target/ARM/ARMCallLowering.cpp index 3d22a9191b4..00f21a916c6 100644 --- a/lib/Target/ARM/ARMCallLowering.cpp +++ b/lib/Target/ARM/ARMCallLowering.cpp @@ -405,6 +405,7 @@ struct FormalArgHandler : public IncomingValueHandler { : IncomingValueHandler(MIRBuilder, MRI, AssignFn) {} void markPhysRegUsed(unsigned PhysReg) override { + MIRBuilder.getMRI()->addLiveIn(PhysReg); MIRBuilder.getMBB().addLiveIn(PhysReg); } }; diff --git a/lib/Target/Mips/MipsCallLowering.cpp b/lib/Target/Mips/MipsCallLowering.cpp index 849f9558ac2..9b8a12e0e58 100644 --- a/lib/Target/Mips/MipsCallLowering.cpp +++ b/lib/Target/Mips/MipsCallLowering.cpp @@ -106,6 +106,7 @@ private: Register ArgsReg, const EVT &VT) override; virtual void markPhysRegUsed(unsigned PhysReg) { + MIRBuilder.getMRI()->addLiveIn(PhysReg); MIRBuilder.getMBB().addLiveIn(PhysReg); } diff --git a/lib/Target/X86/X86CallLowering.cpp b/lib/Target/X86/X86CallLowering.cpp index e97a28a760c..e4079d6e415 100644 --- a/lib/Target/X86/X86CallLowering.cpp +++ b/lib/Target/X86/X86CallLowering.cpp @@ -301,6 +301,7 @@ struct FormalArgHandler : public IncomingValueHandler { : IncomingValueHandler(MIRBuilder, MRI, AssignFn) {} void markPhysRegUsed(unsigned PhysReg) override { + MIRBuilder.getMRI()->addLiveIn(PhysReg); MIRBuilder.getMBB().addLiveIn(PhysReg); } }; diff --git a/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll b/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll index 9c27fb741da..ed45a6e95da 100644 --- a/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll +++ b/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll @@ -227,11 +227,3 @@ define void @nonpow2_vector_add_fewerelements() { store i64 %ex, i64* undef ret void } - -%swift_error = type {i64, i8} - -; FALLBACK-WITH-REPORT-ERR: remark: :0:0: unable to lower arguments due to swiftself: void (%swift_error**)* (in function: swiftself_param) -; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for swiftself_param -define void @swiftself_param(%swift_error** swiftself %error_ptr_ref) { - ret void -} diff --git a/test/CodeGen/AArch64/GlobalISel/swiftself.ll b/test/CodeGen/AArch64/GlobalISel/swiftself.ll new file mode 100644 index 00000000000..8ed06f23383 --- /dev/null +++ b/test/CodeGen/AArch64/GlobalISel/swiftself.ll @@ -0,0 +1,62 @@ +; RUN: llc -verify-machineinstrs -mtriple=aarch64-apple-ios -o - %s -global-isel | FileCheck %s + +; Parameter with swiftself should be allocated to x20. +; CHECK-LABEL: swiftself_param: +; CHECK: mov x0, x20 +; CHECK-NEXT: ret +define i8* @swiftself_param(i8* swiftself %addr0) { + ret i8 *%addr0 +} + +; Check that x20 is used to pass a swiftself argument. +; CHECK-LABEL: call_swiftself: +; CHECK: mov x20, x0 +; CHECK: bl {{_?}}swiftself_param +; CHECK: ret +define i8 *@call_swiftself(i8* %arg) { + %res = call i8 *@swiftself_param(i8* swiftself %arg) + ret i8 *%res +} + +; Demonstrate that we do not need any movs when calling multiple functions +; with swiftself argument. +; CHECK-LABEL: swiftself_passthrough: +; CHECK-NOT: mov{{.*}}x20 +; CHECK: bl {{_?}}swiftself_param +; CHECK-NOT: mov{{.*}}x20 +; CHECK-NEXT: bl {{_?}}swiftself_param +; CHECK: ret +define void @swiftself_passthrough(i8* swiftself %addr0) { + call i8 *@swiftself_param(i8* swiftself %addr0) + call i8 *@swiftself_param(i8* swiftself %addr0) + ret void +} + +; We can not use a tail call if the callee swiftself is not the same as the +; caller one. +; CHECK-LABEL: swiftself_notail: +; CHECK: mov x20, x0 +; CHECK: bl {{_?}}swiftself_param +; CHECK: ret +define i8* @swiftself_notail(i8* swiftself %addr0, i8* %addr1) nounwind { + %res = tail call i8* @swiftself_param(i8* swiftself %addr1) + ret i8* %res +} + +; We cannot pretend that 'x0' is alive across the thisreturn_attribute call as +; we normally would. We marked the first parameter with swiftself which means it +; will no longer be passed in x0. +declare swiftcc i8* @thisreturn_attribute(i8* returned swiftself) +; CHECK-LABEL: swiftself_nothisreturn: +; CHECK-DAG: ldr x20, [x20] +; CHECK-DAG: mov [[CSREG:x[1-9].*]], x8 +; CHECK: bl {{_?}}thisreturn_attribute +; CHECK: str x0, {{\[}}[[CSREG]] +; CHECK: ret +define hidden swiftcc void @swiftself_nothisreturn(i8** noalias nocapture sret, i8** noalias nocapture readonly swiftself) { +entry: + %2 = load i8*, i8** %1, align 8 + %3 = tail call swiftcc i8* @thisreturn_attribute(i8* swiftself %2) + store i8* %3, i8** %0, align 8 + ret void +}